IDE: Fix HDIO_DRIVE_RESET handling
[pandora-kernel.git] / drivers / ide / ide-io.c
index c22a337..2b33c12 100644 (file)
@@ -437,7 +437,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
 
        if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+               hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
                               hwif->io_ports.command_addr);
 
        if (rq->errors >= ERROR_MAX) {
@@ -766,6 +766,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
        return ide_stopped;
 }
 
+static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
+{
+       switch (rq->cmd[0]) {
+       case REQ_DRIVE_RESET:
+               return ide_do_reset(drive);
+       default:
+               blk_dump_rq_flags(rq, "ide_special_rq - bad request");
+               ide_end_request(drive, 0, 0);
+               return ide_stopped;
+       }
+}
+
 static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
 {
        struct request_pm_state *pm = rq->data;
@@ -869,7 +881,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
                            pm->pm_step == ide_pm_state_completed)
                                ide_complete_pm_request(drive, rq);
                        return startstop;
-               }
+               } else if (!rq->rq_disk && blk_special_request(rq))
+                       /*
+                        * TODO: Once all ULDs have been modified to
+                        * check for specific op codes rather than
+                        * blindly accepting any special request, the
+                        * check for ->rq_disk above may be replaced
+                        * by a more suitable mechanism or even
+                        * dropped entirely.
+                        */
+                       return ide_special_rq(drive, rq);
 
                drv = *(ide_driver_t **)rq->rq_disk->private_data;
                return drv->do_request(drive, rq, block);
@@ -1520,49 +1541,27 @@ irqreturn_t ide_intr (int irq, void *dev_id)
  *     ide_do_drive_cmd        -       issue IDE special command
  *     @drive: device to issue command
  *     @rq: request to issue
- *     @action: action for processing
  *
  *     This function issues a special IDE device request
  *     onto the request queue.
  *
- *     If action is ide_wait, then the rq is queued at the end of the
- *     request queue, and the function sleeps until it has been processed.
- *     This is for use when invoked from an ioctl handler.
- *
- *     If action is ide_preempt, then the rq is queued at the head of
- *     the request queue, displacing the currently-being-processed
- *     request and this function returns immediately without waiting
- *     for the new rq to be completed.  This is VERY DANGEROUS, and is
- *     intended for careful use by the ATAPI tape/cdrom driver code.
- *
- *     If action is ide_end, then the rq is queued at the end of the
- *     request queue, and the function returns immediately without waiting
- *     for the new rq to be completed. This is again intended for careful
- *     use by the ATAPI tape/cdrom driver code.
+ *     the rq is queued at the head of the request queue, displacing
+ *     the currently-being-processed request and this function
+ *     returns immediately without waiting for the new rq to be
+ *     completed.  This is VERY DANGEROUS, and is intended for
+ *     careful use by the ATAPI tape/cdrom driver code.
  */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+
+void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
 {
        unsigned long flags;
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
-       int where = ELEVATOR_INSERT_BACK;
-
-       rq->errors = 0;
-
-       if (action == ide_preempt)
-               where = ELEVATOR_INSERT_FRONT;
 
        spin_lock_irqsave(&ide_lock, flags);
-       if (action == ide_preempt)
-               hwgroup->rq = NULL;
-       __elv_add_request(drive->queue, rq, where, 1);
+       hwgroup->rq = NULL;
+       __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1);
        __generic_unplug_device(drive->queue);
-       /* the queue is stopped so it won't be plugged+unplugged */
-       if (blk_pm_resume_request(rq))
-               do_ide_request(drive->queue);
        spin_unlock_irqrestore(&ide_lock, flags);
-
-       return 0;
 }
 
 EXPORT_SYMBOL(ide_do_drive_cmd);
@@ -1579,6 +1578,8 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
        task.tf.lbah    = (bcount >> 8) & 0xff;
 
        ide_tf_dump(drive->name, &task.tf);
+       ide_set_irq(drive, 1);
+       SELECT_MASK(drive, 0);
        drive->hwif->tf_load(drive, &task);
 }