ide: add struct ide_taskfile (take 2)

* Don't set write-only ide_task_t.hobRegister[6] and ide_task_t.hobRegister[7]
  in idedisk_set_max_address_ext().

* Add struct ide_taskfile and use it in ide_task_t instead of tfRegister[]
  and hobRegister[].

* Remove no longer needed IDE_CONTROL_OFFSET_HOB define.

* Add #ifndef/#endif __KERNEL__ around definitions of {task,hob}_struct_t.

While at it:

* Use ATA_LBA define for LBA bit (0x40) as suggested by Tejun Heo.

v2:
* Add missing newlines. (Noticed by Sergei)

* Use ~ATA_LBA instead of 0xBF. (Noticed by Sergei)

* Use unnamed unions for error/feature and status/command.
  (Suggested by Sergei).

There should be no functionality changes caused by this patch.
Acked-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Tejun Heo <htejun@gmail.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent cd2a2d96
...@@ -388,13 +388,7 @@ static int taskfile_load_raw(ide_drive_t *drive, ...@@ -388,13 +388,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
args.handler = &task_no_data_intr; args.handler = &task_no_data_intr;
/* convert gtf to IDE Taskfile */ /* convert gtf to IDE Taskfile */
args.tfRegister[1] = gtf->tfa[0]; /* 0x1f1 */ memcpy(&args.tf_array[7], &gtf->tfa, 7);
args.tfRegister[2] = gtf->tfa[1]; /* 0x1f2 */
args.tfRegister[3] = gtf->tfa[2]; /* 0x1f3 */
args.tfRegister[4] = gtf->tfa[3]; /* 0x1f4 */
args.tfRegister[5] = gtf->tfa[4]; /* 0x1f5 */
args.tfRegister[6] = gtf->tfa[5]; /* 0x1f6 */
args.tfRegister[7] = gtf->tfa[6]; /* 0x1f7 */
if (ide_noacpitfs) { if (ide_noacpitfs) {
DEBPRINT("_GTF execution disabled\n"); DEBPRINT("_GTF execution disabled\n");
......
This diff is collapsed.
...@@ -189,15 +189,15 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -189,15 +189,15 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
return ide_stopped; return ide_stopped;
} }
if (ide_id_has_flush_cache_ext(drive->id)) if (ide_id_has_flush_cache_ext(drive->id))
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; args->tf.command = WIN_FLUSH_CACHE_EXT;
else else
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; args->tf.command = WIN_FLUSH_CACHE;
args->command_type = IDE_DRIVE_TASK_NO_DATA; args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = &task_no_data_intr; args->handler = &task_no_data_intr;
return do_rw_taskfile(drive, args); return do_rw_taskfile(drive, args);
case idedisk_pm_standby: /* Suspend step 2 (standby) */ case idedisk_pm_standby: /* Suspend step 2 (standby) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1; args->tf.command = WIN_STANDBYNOW1;
args->command_type = IDE_DRIVE_TASK_NO_DATA; args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = &task_no_data_intr; args->handler = &task_no_data_intr;
return do_rw_taskfile(drive, args); return do_rw_taskfile(drive, args);
...@@ -214,7 +214,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -214,7 +214,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
return ide_stopped; return ide_stopped;
case idedisk_pm_idle: /* Resume step 2 (idle) */ case idedisk_pm_idle: /* Resume step 2 (idle) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; args->tf.command = WIN_IDLEIMMEDIATE;
args->command_type = IDE_DRIVE_TASK_NO_DATA; args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = task_no_data_intr; args->handler = task_no_data_intr;
return do_rw_taskfile(drive, args); return do_rw_taskfile(drive, args);
...@@ -354,28 +354,31 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -354,28 +354,31 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
if (args) { if (args) {
struct ide_taskfile *tf = &args->tf;
if (args->tf_in_flags.b.data) { if (args->tf_in_flags.b.data) {
u16 data = hwif->INW(IDE_DATA_REG); u16 data = hwif->INW(IDE_DATA_REG);
args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF;
args->hobRegister[IDE_DATA_OFFSET] = (data >> 8) & 0xFF; tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
} }
args->tfRegister[IDE_ERROR_OFFSET] = err; tf->error = err;
/* be sure we're looking at the low order bits */ /* be sure we're looking at the low order bits */
hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG); tf->nsect = hwif->INB(IDE_NSECTOR_REG);
args->tfRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG); tf->lbal = hwif->INB(IDE_SECTOR_REG);
args->tfRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG); tf->lbam = hwif->INB(IDE_LCYL_REG);
args->tfRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG); tf->lbah = hwif->INB(IDE_HCYL_REG);
args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG); tf->device = hwif->INB(IDE_SELECT_REG);
args->tfRegister[IDE_STATUS_OFFSET] = stat; tf->status = stat;
if (drive->addressing == 1) { if (drive->addressing == 1) {
hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG); hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
args->hobRegister[IDE_FEATURE_OFFSET] = hwif->INB(IDE_FEATURE_REG); tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
args->hobRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG); tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG);
args->hobRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG); tf->hob_lbal = hwif->INB(IDE_SECTOR_REG);
args->hobRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG); tf->hob_lbam = hwif->INB(IDE_LCYL_REG);
args->hobRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG); tf->hob_lbah = hwif->INB(IDE_HCYL_REG);
} }
} }
} else if (blk_pm_request(rq)) { } else if (blk_pm_request(rq)) {
...@@ -675,28 +678,28 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) ...@@ -675,28 +678,28 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task) static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task)
{ {
task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; task->tf.nsect = drive->sect;
task->tfRegister[IDE_SECTOR_OFFSET] = drive->sect; task->tf.lbal = drive->sect;
task->tfRegister[IDE_LCYL_OFFSET] = drive->cyl; task->tf.lbam = drive->cyl;
task->tfRegister[IDE_HCYL_OFFSET] = drive->cyl>>8; task->tf.lbah = drive->cyl >> 8;
task->tfRegister[IDE_SELECT_OFFSET] = ((drive->head-1)|drive->select.all)&0xBF; task->tf.device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA;
task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY; task->tf.command = WIN_SPECIFY;
task->handler = &set_geometry_intr; task->handler = &set_geometry_intr;
} }
static void ide_init_restore_cmd(ide_drive_t *drive, ide_task_t *task) static void ide_init_restore_cmd(ide_drive_t *drive, ide_task_t *task)
{ {
task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; task->tf.nsect = drive->sect;
task->tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE; task->tf.command = WIN_RESTORE;
task->handler = &recal_intr; task->handler = &recal_intr;
} }
static void ide_init_setmult_cmd(ide_drive_t *drive, ide_task_t *task) static void ide_init_setmult_cmd(ide_drive_t *drive, ide_task_t *task)
{ {
task->tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req; task->tf.nsect = drive->mult_req;
task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT; task->tf.command = WIN_SETMULT;
task->handler = &set_multmode_intr; task->handler = &set_multmode_intr;
} }
......
...@@ -642,9 +642,9 @@ u8 eighty_ninty_three (ide_drive_t *drive) ...@@ -642,9 +642,9 @@ u8 eighty_ninty_three (ide_drive_t *drive)
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
{ {
if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && if (args->tf.command == WIN_SETFEATURES &&
(args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && args->tf.lbal > XFER_UDMA_2 &&
(args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { args->tf.feature == SETFEATURES_XFER) {
if (eighty_ninty_three(drive) == 0) { if (eighty_ninty_three(drive) == 0) {
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
"be set\n", drive->name); "be set\n", drive->name);
...@@ -662,9 +662,9 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) ...@@ -662,9 +662,9 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
*/ */
int set_transfer (ide_drive_t *drive, ide_task_t *args) int set_transfer (ide_drive_t *drive, ide_task_t *args)
{ {
if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && if (args->tf.command == WIN_SETFEATURES &&
(args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && args->tf.lbal >= XFER_SW_DMA_0 &&
(args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && args->tf.feature == SETFEATURES_XFER &&
(drive->id->dma_ultra || (drive->id->dma_ultra ||
drive->id->dma_mword || drive->id->dma_mword ||
drive->id->dma_1word)) drive->id->dma_1word))
......
...@@ -468,8 +468,7 @@ static void ide_dump_opcode(ide_drive_t *drive) ...@@ -468,8 +468,7 @@ static void ide_dump_opcode(ide_drive_t *drive)
} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
if (args) { if (args) {
task_struct_t *tf = (task_struct_t *) args->tfRegister; opcode = args->tf.command;
opcode = tf->command;
found = 1; found = 1;
} }
} }
......
...@@ -66,12 +66,13 @@ static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) ...@@ -66,12 +66,13 @@ static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
{ {
ide_task_t args; ide_task_t args;
memset(&args, 0, sizeof(ide_task_t)); memset(&args, 0, sizeof(ide_task_t));
args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; args.tf.nsect = 0x01;
if (drive->media == ide_disk) if (drive->media == ide_disk)
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; args.tf.command = WIN_IDENTIFY;
else else
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; args.tf.command = WIN_PIDENTIFY;
args.command_type = IDE_DRIVE_TASK_IN; args.command_type = IDE_DRIVE_TASK_IN;
args.data_phase = TASKFILE_IN; args.data_phase = TASKFILE_IN;
args.handler = &task_in_intr; args.handler = &task_in_intr;
...@@ -81,8 +82,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) ...@@ -81,8 +82,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister; struct ide_taskfile *tf = &task->tf;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF;
/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
...@@ -93,35 +93,35 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -93,35 +93,35 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
if (drive->addressing == 1) { if (drive->addressing == 1) {
hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG);
hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
} }
hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); hwif->OUTB(tf->feature, IDE_FEATURE_REG);
hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); hwif->OUTB(tf->lbam, IDE_LCYL_REG);
hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); hwif->OUTB(tf->lbah, IDE_HCYL_REG);
hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG);
if (task->handler != NULL) { if (task->handler != NULL) {
if (task->prehandler != NULL) { if (task->prehandler != NULL) {
hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
ndelay(400); /* FIXME */ ndelay(400); /* FIXME */
return task->prehandler(drive, task->rq); return task->prehandler(drive, task->rq);
} }
ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
return ide_started; return ide_started;
} }
if (!drive->using_dma) if (!drive->using_dma)
return ide_stopped; return ide_stopped;
switch (taskfile->command) { switch (tf->command) {
case WIN_WRITEDMA_ONCE: case WIN_WRITEDMA_ONCE:
case WIN_WRITEDMA: case WIN_WRITEDMA:
case WIN_WRITEDMA_EXT: case WIN_WRITEDMA_EXT:
...@@ -130,7 +130,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -130,7 +130,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
case WIN_READDMA_EXT: case WIN_READDMA_EXT:
case WIN_IDENTIFY_DMA: case WIN_IDENTIFY_DMA:
if (!hwif->dma_setup(drive)) { if (!hwif->dma_setup(drive)) {
hwif->dma_exec_cmd(drive, taskfile->command); hwif->dma_exec_cmd(drive, tf->command);
hwif->dma_start(drive); hwif->dma_start(drive);
return ide_started; return ide_started;
} }
...@@ -483,7 +483,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long ...@@ -483,7 +483,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
*/ */
if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
if (data_size == 0) if (data_size == 0)
rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
else else
rq.nr_sectors = data_size / SECTOR_SIZE; rq.nr_sectors = data_size / SECTOR_SIZE;
...@@ -519,8 +519,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -519,8 +519,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
ide_task_t args; ide_task_t args;
u8 *outbuf = NULL; u8 *outbuf = NULL;
u8 *inbuf = NULL; u8 *inbuf = NULL;
u8 *argsptr = args.tfRegister;
u8 *hobsptr = args.hobRegister;
int err = 0; int err = 0;
int tasksize = sizeof(struct ide_task_request_s); int tasksize = sizeof(struct ide_task_request_s);
unsigned int taskin = 0; unsigned int taskin = 0;
...@@ -572,9 +570,9 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -572,9 +570,9 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
} }
memset(&args, 0, sizeof(ide_task_t)); memset(&args, 0, sizeof(ide_task_t));
memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);
memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
args.tf_in_flags = req_task->in_flags; args.tf_in_flags = req_task->in_flags;
args.tf_out_flags = req_task->out_flags; args.tf_out_flags = req_task->out_flags;
args.data_phase = req_task->data_phase; args.data_phase = req_task->data_phase;
...@@ -628,8 +626,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -628,8 +626,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
goto abort; goto abort;
} }
memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
req_task->in_flags = args.tf_in_flags; req_task->in_flags = args.tf_in_flags;
req_task->out_flags = args.tf_out_flags; req_task->out_flags = args.tf_out_flags;
...@@ -688,6 +686,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -688,6 +686,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
u8 xfer_rate = 0; u8 xfer_rate = 0;
int argsize = 4; int argsize = 4;
ide_task_t tfargs; ide_task_t tfargs;
struct ide_taskfile *tf = &tfargs.tf;
if (NULL == (void *) arg) { if (NULL == (void *) arg) {
struct request rq; struct request rq;
...@@ -699,13 +698,10 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -699,13 +698,10 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
return -EFAULT; return -EFAULT;
memset(&tfargs, 0, sizeof(ide_task_t)); memset(&tfargs, 0, sizeof(ide_task_t));
tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; tf->feature = args[2];
tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; tf->nsect = args[3];
tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; tf->lbal = args[1];
tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; tf->command = args[0];
tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00;
tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00;
tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
if (args[3]) { if (args[3]) {
argsize = 4 + (SECTOR_WORDS * 4 * args[3]); argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
...@@ -767,8 +763,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -767,8 +763,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister; struct ide_taskfile *tf = &task->tf;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
if (task->data_phase == TASKFILE_MULTI_IN || if (task->data_phase == TASKFILE_MULTI_IN ||
task->data_phase == TASKFILE_MULTI_OUT) { task->data_phase == TASKFILE_MULTI_OUT) {
...@@ -798,34 +793,32 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -798,34 +793,32 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
if (task->tf_out_flags.b.data) { if (task->tf_out_flags.b.data)
u16 data = taskfile->data + (hobfile->data << 8); hwif->OUTW((tf->hob_data << 8) | tf->data, IDE_DATA_REG);
hwif->OUTW(data, IDE_DATA_REG);
}
/* (ks) send hob registers first */ /* (ks) send hob registers first */
if (task->tf_out_flags.b.nsector_hob) if (task->tf_out_flags.b.nsector_hob)
hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
if (task->tf_out_flags.b.sector_hob) if (task->tf_out_flags.b.sector_hob)
hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
if (task->tf_out_flags.b.lcyl_hob) if (task->tf_out_flags.b.lcyl_hob)
hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
if (task->tf_out_flags.b.hcyl_hob) if (task->tf_out_flags.b.hcyl_hob)
hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
/* (ks) Send now the standard registers */ /* (ks) Send now the standard registers */
if (task->tf_out_flags.b.error_feature) if (task->tf_out_flags.b.error_feature)
hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); hwif->OUTB(tf->feature, IDE_FEATURE_REG);
/* refers to number of sectors to transfer */ /* refers to number of sectors to transfer */
if (task->tf_out_flags.b.nsector) if (task->tf_out_flags.b.nsector)
hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
/* refers to sector offset or start sector */ /* refers to sector offset or start sector */
if (task->tf_out_flags.b.sector) if (task->tf_out_flags.b.sector)
hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
if (task->tf_out_flags.b.lcyl) if (task->tf_out_flags.b.lcyl)
hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); hwif->OUTB(tf->lbam, IDE_LCYL_REG);
if (task->tf_out_flags.b.hcyl) if (task->tf_out_flags.b.hcyl)
hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); hwif->OUTB(tf->lbah, IDE_HCYL_REG);
/* /*
* (ks) In the flagged taskfile approch, we will use all specified * (ks) In the flagged taskfile approch, we will use all specified
...@@ -833,7 +826,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -833,7 +826,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
* select bit (master/slave) in the drive_head register. We must make * select bit (master/slave) in the drive_head register. We must make
* sure that the desired drive is selected. * sure that the desired drive is selected.
*/ */
hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG); hwif->OUTB(tf->device | drive->select.all, IDE_SELECT_REG);
switch(task->data_phase) { switch(task->data_phase) {
case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMAQ:
...@@ -844,7 +837,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -844,7 +837,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
break; break;
if (!hwif->dma_setup(drive)) { if (!hwif->dma_setup(drive)) {
hwif->dma_exec_cmd(drive, taskfile->command); hwif->dma_exec_cmd(drive, tf->command);
hwif->dma_start(drive); hwif->dma_start(drive);
return ide_started; return ide_started;
} }
...@@ -856,11 +849,11 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -856,11 +849,11 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
/* Issue the command */ /* Issue the command */
if (task->prehandler) { if (task->prehandler) {
hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
ndelay(400); /* FIXME */ ndelay(400); /* FIXME */
return task->prehandler(drive, task->rq); return task->prehandler(drive, task->rq);
} }
ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
return ide_started; return ide_started;
} }
......
...@@ -117,7 +117,7 @@ typedef union ide_reg_valid_s { ...@@ -117,7 +117,7 @@ typedef union ide_reg_valid_s {
typedef struct ide_task_request_s { typedef struct ide_task_request_s {
__u8 io_ports[8]; __u8 io_ports[8];
__u8 hob_ports[8]; __u8 hob_ports[8]; /* bytes 6 and 7 are unused */
ide_reg_valid_t out_flags; ide_reg_valid_t out_flags;
ide_reg_valid_t in_flags; ide_reg_valid_t in_flags;
int data_phase; int data_phase;
...@@ -139,6 +139,7 @@ struct hd_drive_cmd_hdr { ...@@ -139,6 +139,7 @@ struct hd_drive_cmd_hdr {
__u8 sector_count; __u8 sector_count;
}; };
#ifndef __KERNEL__
typedef struct hd_drive_task_hdr { typedef struct hd_drive_task_hdr {
__u8 data; __u8 data;
__u8 feature; __u8 feature;
...@@ -160,6 +161,7 @@ typedef struct hd_drive_hob_hdr { ...@@ -160,6 +161,7 @@ typedef struct hd_drive_hob_hdr {
__u8 device_head; __u8 device_head;
__u8 control; __u8 control;
} hob_struct_t; } hob_struct_t;
#endif
#define TASKFILE_INVALID 0x7fff #define TASKFILE_INVALID 0x7fff
#define TASKFILE_48 0x8000 #define TASKFILE_48 0x8000
......
...@@ -103,8 +103,6 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -103,8 +103,6 @@ typedef unsigned char byte; /* used everywhere */
#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET #define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET
#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
#define IDE_CONTROL_OFFSET_HOB (7)
#define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) #define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET])
#define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) #define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
#define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) #define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
...@@ -1062,15 +1060,40 @@ extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); ...@@ -1062,15 +1060,40 @@ extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
*/ */
extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
struct ide_taskfile {
u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */
u8 hob_feature; /* 1-5: additional data to support LBA48 */
u8 hob_nsect;
u8 hob_lbal;
u8 hob_lbam;
u8 hob_lbah;
u8 data; /* 6: low data byte (for TASKFILE IOCTL) */
union { /*  7: */
u8 error; /* read: error */
u8 feature; /* write: feature */
};
u8 nsect; /* 8: number of sectors */
u8 lbal; /* 9: LBA low */
u8 lbam; /* 10: LBA mid */
u8 lbah; /* 11: LBA high */
u8 device; /* 12: device select */
union { /* 13: */
u8 status; /*  read: status  */
u8 command; /* write: command */
};
};
typedef struct ide_task_s { typedef struct ide_task_s {
/* union {
* struct hd_drive_task_hdr tf; struct ide_taskfile tf;
* task_struct_t tf; u8 tf_array[14];
* struct hd_drive_hob_hdr hobf; };
* hob_struct_t hobf;
*/
u8 tfRegister[8];
u8 hobRegister[8];
ide_reg_valid_t tf_out_flags; ide_reg_valid_t tf_out_flags;
ide_reg_valid_t tf_in_flags; ide_reg_valid_t tf_in_flags;
int data_phase; int data_phase;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment