]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-taskfile.c
ide: merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr()
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-taskfile.c
index aeddbbd69e862e6526ee25d7a83e6143e1c5468f..a4c2d91179b36647e53a362ddea4e2354b4e7daa 100644 (file)
@@ -44,18 +44,15 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
        memset(&args, 0, sizeof(ide_task_t));
        args.tf.nsect = 0x01;
        if (drive->media == ide_disk)
-               args.tf.command = WIN_IDENTIFY;
+               args.tf.command = ATA_CMD_ID_ATA;
        else
-               args.tf.command = WIN_PIDENTIFY;
+               args.tf.command = ATA_CMD_ID_ATAPI;
        args.tf_flags   = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
        args.data_phase = TASKFILE_IN;
        return ide_raw_taskfile(drive, &args, buf, 1);
 }
 
 static ide_startstop_t task_no_data_intr(ide_drive_t *);
-static ide_startstop_t set_geometry_intr(ide_drive_t *);
-static ide_startstop_t recal_intr(ide_drive_t *);
-static ide_startstop_t set_multmode_intr(ide_drive_t *);
 static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
 static ide_startstop_t task_in_intr(ide_drive_t *);
 
@@ -79,6 +76,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
        if (task->tf_flags & IDE_TFLAG_FLAGGED)
                task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
 
+       memcpy(&hwif->task, task, sizeof(*task));
+
        if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
                ide_tf_dump(drive->name, tf);
                tp_ops->set_irq(hwif, 1);
@@ -99,19 +98,12 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
        case TASKFILE_NO_DATA:
                if (handler == NULL)
                        handler = task_no_data_intr;
-               /* WIN_{SPECIFY,RESTORE,SETMULT} use custom handlers */
-               if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) {
-                       switch (tf->command) {
-                       case WIN_SPECIFY: handler = set_geometry_intr;  break;
-                       case WIN_RESTORE: handler = recal_intr;         break;
-                       case WIN_SETMULT: handler = set_multmode_intr;  break;
-                       }
-               }
                ide_execute_command(drive, tf->command, handler,
                                    WAIT_WORSTCASE, NULL);
                return ide_started;
        default:
-               if (drive->using_dma == 0 || dma_ops->dma_setup(drive))
+               if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+                   dma_ops->dma_setup(drive))
                        return ide_stopped;
                dma_ops->dma_exec_cmd(drive, tf->command);
                dma_ops->dma_start(drive);
@@ -121,80 +113,47 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 EXPORT_SYMBOL_GPL(do_rw_taskfile);
 
 /*
- * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
- */
-static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 stat = hwif->tp_ops->read_status(hwif);
-
-       if (OK_STAT(stat, READY_STAT, BAD_STAT))
-               drive->mult_count = drive->mult_req;
-       else {
-               drive->mult_req = drive->mult_count = 0;
-               drive->special.b.recalibrate = 1;
-               (void) ide_dump_status(drive, "set_multmode", stat);
-       }
-       return ide_stopped;
-}
-
-/*
- * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
+ * Handler for commands without a data phase
  */
-static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
+static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       int retries = 5;
+       ide_task_t *task = &hwif->task;
+       struct ide_taskfile *tf = &task->tf;
+       int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
+       int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
        u8 stat;
 
+       local_irq_enable_in_hardirq();
+
        while (1) {
                stat = hwif->tp_ops->read_status(hwif);
-               if ((stat & BUSY_STAT) == 0 || retries-- == 0)
+               if ((stat & ATA_BUSY) == 0 || retries-- == 0)
                        break;
                udelay(10);
        };
 
-       if (OK_STAT(stat, READY_STAT, BAD_STAT))
-               return ide_stopped;
-
-       if (stat & (ERR_STAT|DRQ_STAT))
-               return ide_error(drive, "set_geometry_intr", stat);
-
-       ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
-       return ide_started;
-}
-
-/*
- * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
- */
-static ide_startstop_t recal_intr(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 stat = hwif->tp_ops->read_status(hwif);
-
-       if (!OK_STAT(stat, READY_STAT, BAD_STAT))
-               return ide_error(drive, "recal_intr", stat);
-       return ide_stopped;
-}
-
-/*
- * Handler for commands without a data phase
- */
-static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       ide_task_t *args = hwif->hwgroup->rq->special;
-       u8 stat;
-
-       local_irq_enable_in_hardirq();
-       stat = hwif->tp_ops->read_status(hwif);
-
-       if (!OK_STAT(stat, READY_STAT, BAD_STAT))
+       if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
+               if (custom && tf->command == ATA_CMD_SET_MULTI) {
+                       drive->mult_req = drive->mult_count = 0;
+                       drive->special.b.recalibrate = 1;
+                       (void)ide_dump_status(drive, __func__, stat);
+                       return ide_stopped;
+               } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
+                       if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
+                               ide_set_handler(drive, &task_no_data_intr,
+                                               WAIT_WORSTCASE, NULL);
+                               return ide_started;
+                       }
+               }
                return ide_error(drive, "task_no_data_intr", stat);
                /* calls ide_end_drive_cmd */
+       }
 
-       if (args)
+       if (!custom)
                ide_end_drive_cmd(drive, stat, ide_read_error(drive));
+       else if (tf->command == ATA_CMD_SET_MULTI)
+               drive->mult_count = drive->mult_req;
 
        return ide_stopped;
 }
@@ -212,13 +171,13 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
        for (retries = 0; retries < 1000; retries++) {
                stat = hwif->tp_ops->read_status(hwif);
 
-               if (stat & BUSY_STAT)
+               if (stat & ATA_BUSY)
                        udelay(10);
                else
                        break;
        }
 
-       if (stat & BUSY_STAT)
+       if (stat & ATA_BUSY)
                printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
 
        return stat;
@@ -377,7 +336,7 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
 {
        /* Command all done? */
-       if (OK_STAT(stat, READY_STAT, BUSY_STAT)) {
+       if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
                task_end_request(drive, rq, stat);
                return ide_stopped;
        }
@@ -397,11 +356,11 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
        u8 stat = hwif->tp_ops->read_status(hwif);
 
        /* Error? */
-       if (stat & ERR_STAT)
+       if (stat & ATA_ERR)
                return task_error(drive, rq, __func__, stat);
 
        /* Didn't want any data? Odd. */
-       if (!(stat & DRQ_STAT))
+       if ((stat & ATA_DRQ) == 0)
                return task_in_unexpected(drive, rq, stat);
 
        ide_pio_datablock(drive, rq, 0);
@@ -434,7 +393,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)
                return task_error(drive, rq, __func__, stat);
 
        /* Deal with unexpected ATA data phase. */
-       if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft)
+       if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
                return task_error(drive, rq, __func__, stat);
 
        if (!hwif->nleft) {
@@ -453,16 +412,15 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
 {
        ide_startstop_t startstop;
 
-       if (ide_wait_stat(&startstop, drive, DRQ_STAT,
+       if (ide_wait_stat(&startstop, drive, ATA_DRQ,
                          drive->bad_wstat, WAIT_DRQ)) {
                printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
-                               drive->name,
-                               drive->hwif->data_phase ? "MULT" : "",
-                               drive->addressing ? "_EXT" : "");
+                       drive->name, drive->hwif->data_phase ? "MULT" : "",
+                       (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
                return startstop;
        }
 
-       if (!drive->unmask)
+       if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
                local_irq_disable();
 
        ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
@@ -578,7 +536,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
                        IDE_TFLAG_IN_TF;
-       if (drive->addressing == 1)
+       if (drive->dev_flags & IDE_DFLAG_LBA48)
                args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
 
        if (req_task->out_flags.all) {
@@ -681,7 +639,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
        if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
            req_task->in_flags.all == 0) {
                req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
-               if (drive->addressing == 1)
+               if (drive->dev_flags & IDE_DFLAG_LBA48)
                        req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
        }
 
@@ -713,110 +671,3 @@ abort:
        return err;
 }
 #endif
-
-int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
-{
-       u8 *buf = NULL;
-       int bufsize = 0, err = 0;
-       u8 args[4], xfer_rate = 0;
-       ide_task_t tfargs;
-       struct ide_taskfile *tf = &tfargs.tf;
-       struct hd_driveid *id = drive->id;
-
-       if (NULL == (void *) arg) {
-               struct request *rq;
-
-               rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-               rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
-               err = blk_execute_rq(drive->queue, NULL, rq, 0);
-               blk_put_request(rq);
-
-               return err;
-       }
-
-       if (copy_from_user(args, (void __user *)arg, 4))
-               return -EFAULT;
-
-       memset(&tfargs, 0, sizeof(ide_task_t));
-       tf->feature = args[2];
-       if (args[0] == WIN_SMART) {
-               tf->nsect = args[3];
-               tf->lbal  = args[1];
-               tf->lbam  = 0x4f;
-               tf->lbah  = 0xc2;
-               tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
-       } else {
-               tf->nsect = args[1];
-               tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
-                                 IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
-       }
-       tf->command = args[0];
-       tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
-
-       if (args[3]) {
-               tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
-               bufsize = SECTOR_WORDS * 4 * args[3];
-               buf = kzalloc(bufsize, GFP_KERNEL);
-               if (buf == NULL)
-                       return -ENOMEM;
-       }
-
-       if (tf->command == WIN_SETFEATURES &&
-           tf->feature == SETFEATURES_XFER &&
-           tf->nsect >= XFER_SW_DMA_0 &&
-           (id->dma_ultra || id->dma_mword || id->dma_1word)) {
-               xfer_rate = args[1];
-               if (tf->nsect > XFER_UDMA_2 && !eighty_ninty_three(drive)) {
-                       printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
-                                           "be set\n", drive->name);
-                       goto abort;
-               }
-       }
-
-       err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
-
-       args[0] = tf->status;
-       args[1] = tf->error;
-       args[2] = tf->nsect;
-
-       if (!err && xfer_rate) {
-               /* active-retuning-calls future */
-               ide_set_xfer_rate(drive, xfer_rate);
-               ide_driveid_update(drive);
-       }
-abort:
-       if (copy_to_user((void __user *)arg, &args, 4))
-               err = -EFAULT;
-       if (buf) {
-               if (copy_to_user((void __user *)(arg + 4), buf, bufsize))
-                       err = -EFAULT;
-               kfree(buf);
-       }
-       return err;
-}
-
-int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
-{
-       void __user *p = (void __user *)arg;
-       int err = 0;
-       u8 args[7];
-       ide_task_t task;
-
-       if (copy_from_user(args, p, 7))
-               return -EFAULT;
-
-       memset(&task, 0, sizeof(task));
-       memcpy(&task.tf_array[7], &args[1], 6);
-       task.tf.command = args[0];
-       task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-
-       err = ide_no_data_taskfile(drive, &task);
-
-       args[0] = task.tf.command;
-       memcpy(&args[1], &task.tf_array[7], 6);
-
-       if (copy_to_user(p, args, 7))
-               err = -EFAULT;
-
-       return err;
-}