Merge branch 'post-2.6.15' of git://brick.kernel.dk/data/git/linux-2.6-block
[sfrench/cifs-2.6.git] / drivers / scsi / libata-core.c
index 9f27e8d0e774b5ab3a4df243dbba97b16153a815..f55b9b3f7b37f1e8b4ad71e8c9950d8a1f3a9797 100644 (file)
@@ -562,16 +562,28 @@ static const u8 ata_rw_cmds[] = {
        ATA_CMD_WRITE_MULTI,
        ATA_CMD_READ_MULTI_EXT,
        ATA_CMD_WRITE_MULTI_EXT,
+       0,
+       0,
+       0,
+       ATA_CMD_WRITE_MULTI_FUA_EXT,
        /* pio */
        ATA_CMD_PIO_READ,
        ATA_CMD_PIO_WRITE,
        ATA_CMD_PIO_READ_EXT,
        ATA_CMD_PIO_WRITE_EXT,
+       0,
+       0,
+       0,
+       0,
        /* dma */
        ATA_CMD_READ,
        ATA_CMD_WRITE,
        ATA_CMD_READ_EXT,
-       ATA_CMD_WRITE_EXT
+       ATA_CMD_WRITE_EXT,
+       0,
+       0,
+       0,
+       ATA_CMD_WRITE_FUA_EXT
 };
 
 /**
@@ -584,28 +596,35 @@ static const u8 ata_rw_cmds[] = {
  *     LOCKING:
  *     caller.
  */
-void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
+int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
 {
        struct ata_taskfile *tf = &qc->tf;
        struct ata_device *dev = qc->dev;
+       u8 cmd;
 
-       int index, lba48, write;
+       int index, fua, lba48, write;
  
+       fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
        lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
        write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
 
        if (dev->flags & ATA_DFLAG_PIO) {
                tf->protocol = ATA_PROT_PIO;
-               index = dev->multi_count ? 0 : 4;
+               index = dev->multi_count ? 0 : 8;
        } else {
                tf->protocol = ATA_PROT_DMA;
-               index = 8;
+               index = 16;
        }
 
-       tf->command = ata_rw_cmds[index + lba48 + write];
+       cmd = ata_rw_cmds[index + fua + lba48 + write];
+       if (cmd) {
+               tf->command = cmd;
+               return 0;
+       }
+       return -1;
 }
 
-static const char * xfer_mode_str[] = {
+static const char * const xfer_mode_str[] = {
        "UDMA/16",
        "UDMA/25",
        "UDMA/33",
@@ -1046,28 +1065,103 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
        return modes;
 }
 
-static int ata_qc_wait_err(struct ata_queued_cmd *qc,
-                          struct completion *wait)
+struct ata_exec_internal_arg {
+       unsigned int err_mask;
+       struct ata_taskfile *tf;
+       struct completion *waiting;
+};
+
+int ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
-       int rc = 0;
+       struct ata_exec_internal_arg *arg = qc->private_data;
+       struct completion *waiting = arg->waiting;
 
-       if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
-               /* timeout handling */
-               unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+       if (!(qc->err_mask & ~AC_ERR_DEV))
+               qc->ap->ops->tf_read(qc->ap, arg->tf);
+       arg->err_mask = qc->err_mask;
+       arg->waiting = NULL;
+       complete(waiting);
 
-               if (!err_mask) {
-                       printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
-                              qc->ap->id, qc->tf.command);
-               } else {
-                       printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
-                              qc->ap->id, qc->tf.command);
-                       rc = -EIO;
+       return 0;
+}
+
+/**
+ *     ata_exec_internal - execute libata internal command
+ *     @ap: Port to which the command is sent
+ *     @dev: Device to which the command is sent
+ *     @tf: Taskfile registers for the command and the result
+ *     @dma_dir: Data tranfer direction of the command
+ *     @buf: Data buffer of the command
+ *     @buflen: Length of data buffer
+ *
+ *     Executes libata internal command with timeout.  @tf contains
+ *     command on entry and result on return.  Timeout and error
+ *     conditions are reported via return value.  No recovery action
+ *     is taken after a command times out.  It's caller's duty to
+ *     clean up after timeout.
+ *
+ *     LOCKING:
+ *     None.  Should be called with kernel context, might sleep.
+ */
+
+static unsigned
+ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+                 struct ata_taskfile *tf,
+                 int dma_dir, void *buf, unsigned int buflen)
+{
+       u8 command = tf->command;
+       struct ata_queued_cmd *qc;
+       DECLARE_COMPLETION(wait);
+       unsigned long flags;
+       struct ata_exec_internal_arg arg;
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+
+       qc = ata_qc_new_init(ap, dev);
+       BUG_ON(qc == NULL);
+
+       qc->tf = *tf;
+       qc->dma_dir = dma_dir;
+       if (dma_dir != DMA_NONE) {
+               ata_sg_init_one(qc, buf, buflen);
+               qc->nsect = buflen / ATA_SECT_SIZE;
+       }
+
+       arg.waiting = &wait;
+       arg.tf = tf;
+       qc->private_data = &arg;
+       qc->complete_fn = ata_qc_complete_internal;
+
+       if (ata_qc_issue(qc))
+               goto issue_fail;
+
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
+               spin_lock_irqsave(&ap->host_set->lock, flags);
+
+               /* We're racing with irq here.  If we lose, the
+                * following test prevents us from completing the qc
+                * again.  If completion irq occurs after here but
+                * before the caller cleans up, it will result in a
+                * spurious interrupt.  We can live with that.
+                */
+               if (arg.waiting) {
+                       qc->err_mask = AC_ERR_OTHER;
+                       ata_qc_complete(qc);
+                       printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
+                              ap->id, command);
                }
 
-               ata_qc_complete(qc, err_mask);
+               spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 
-       return rc;
+       return arg.err_mask;
+
+ issue_fail:
+       ata_qc_free(qc);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       return AC_ERR_OTHER;
 }
 
 /**
@@ -1099,9 +1193,8 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
        u16 tmp;
        unsigned long xfer_modes;
        unsigned int using_edd;
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       unsigned long flags;
+       struct ata_taskfile tf;
+       unsigned int err_mask;
        int rc;
 
        if (!ata_dev_present(dev)) {
@@ -1122,40 +1215,26 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
 
        ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-       qc->dma_dir = DMA_FROM_DEVICE;
-       qc->tf.protocol = ATA_PROT_PIO;
-       qc->nsect = 1;
-
 retry:
+       ata_tf_init(ap, &tf, device);
+
        if (dev->class == ATA_DEV_ATA) {
-               qc->tf.command = ATA_CMD_ID_ATA;
+               tf.command = ATA_CMD_ID_ATA;
                DPRINTK("do ATA identify\n");
        } else {
-               qc->tf.command = ATA_CMD_ID_ATAPI;
+               tf.command = ATA_CMD_ID_ATAPI;
                DPRINTK("do ATAPI identify\n");
        }
 
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       tf.protocol = ATA_PROT_PIO;
 
-       if (rc)
-               goto err_out;
-       else
-               ata_qc_wait_err(qc, &wait);
+       err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+                                    dev->id, sizeof(dev->id));
 
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       ap->ops->tf_read(ap, &qc->tf);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       if (err_mask) {
+               if (err_mask & ~AC_ERR_DEV)
+                       goto err_out;
 
-       if (qc->tf.command & ATA_ERR) {
                /*
                 * arg!  EDD works for all test cases, but seems to return
                 * the ATA signature for some ATAPI devices.  Until the
@@ -1168,13 +1247,9 @@ retry:
                 * to have this problem.
                 */
                if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
-                       u8 err = qc->tf.feature;
+                       u8 err = tf.feature;
                        if (err & ATA_ABORTED) {
                                dev->class = ATA_DEV_ATAPI;
-                               qc->cursg = 0;
-                               qc->cursg_ofs = 0;
-                               qc->cursect = 0;
-                               qc->nsect = 1;
                                goto retry;
                        }
                }
@@ -2083,7 +2158,7 @@ static void ata_pr_blacklisted(const struct ata_port *ap,
                ap->id, dev->devno);
 }
 
-static const char * ata_dma_blacklist [] = {
+static const char * const ata_dma_blacklist [] = {
        "WDC AC11000H",
        "WDC AC22100H",
        "WDC AC32500H",
@@ -2278,34 +2353,23 @@ static int ata_choose_xfer_mode(const struct ata_port *ap,
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       int rc;
-       unsigned long flags;
+       struct ata_taskfile tf;
 
        /* set up set-features taskfile */
        DPRINTK("set features - xfer mode\n");
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       qc->tf.command = ATA_CMD_SET_FEATURES;
-       qc->tf.feature = SETFEATURES_XFER;
-       qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_NODATA;
-       qc->tf.nsect = dev->xfer_mode;
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       ata_tf_init(ap, &tf, dev->devno);
+       tf.command = ATA_CMD_SET_FEATURES;
+       tf.feature = SETFEATURES_XFER;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = dev->xfer_mode;
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+               printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n",
+                      ap->id);
                ata_port_disable(ap);
-       else
-               ata_qc_wait_err(qc, &wait);
+       }
 
        DPRINTK("EXIT\n");
 }
@@ -2320,41 +2384,25 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 
 static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       unsigned long flags;
-       int rc;
-
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
+       struct ata_taskfile tf;
 
-       ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-       qc->dma_dir = DMA_FROM_DEVICE;
+       ata_tf_init(ap, &tf, dev->devno);
 
        if (dev->class == ATA_DEV_ATA) {
-               qc->tf.command = ATA_CMD_ID_ATA;
+               tf.command = ATA_CMD_ID_ATA;
                DPRINTK("do ATA identify\n");
        } else {
-               qc->tf.command = ATA_CMD_ID_ATAPI;
+               tf.command = ATA_CMD_ID_ATAPI;
                DPRINTK("do ATAPI identify\n");
        }
 
-       qc->tf.flags |= ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_PIO;
-       qc->nsect = 1;
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       tf.flags |= ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_PIO;
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+                             dev->id, sizeof(dev->id)))
                goto err_out;
 
-       ata_qc_wait_err(qc, &wait);
-
        swap_buf_le16(dev->id, ATA_ID_WORDS);
 
        ata_dump_id(dev);
@@ -2363,6 +2411,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 
        return;
 err_out:
+       printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
        ata_port_disable(ap);
 }
 
@@ -2376,10 +2425,7 @@ err_out:
 
 static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       int rc;
-       unsigned long flags;
+       struct ata_taskfile tf;
        u16 sectors = dev->id[6];
        u16 heads   = dev->id[3];
 
@@ -2390,26 +2436,18 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
-       qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_NODATA;
-       qc->tf.nsect = sectors;
-       qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       ata_tf_init(ap, &tf, dev->devno);
+       tf.command = ATA_CMD_INIT_DEV_PARAMS;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = sectors;
+       tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+               printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
+                      ap->id);
                ata_port_disable(ap);
-       else
-               ata_qc_wait_err(qc, &wait);
+       }
 
        DPRINTK("EXIT\n");
 }
@@ -2455,7 +2493,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
                        struct scatterlist *psg = &qc->pad_sgent;
                        void *addr = kmap_atomic(psg->page, KM_IRQ0);
                        memcpy(addr + psg->offset, pad_buf, qc->pad_len);
-                       kunmap_atomic(psg->page, KM_IRQ0);
+                       kunmap_atomic(addr, KM_IRQ0);
                }
        } else {
                if (sg_dma_len(&sg[0]) > 0)
@@ -2729,7 +2767,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
                if (qc->tf.flags & ATA_TFLAG_WRITE) {
                        void *addr = kmap_atomic(psg->page, KM_IRQ0);
                        memcpy(pad_buf, addr + psg->offset, qc->pad_len);
-                       kunmap_atomic(psg->page, KM_IRQ0);
+                       kunmap_atomic(addr, KM_IRQ0);
                }
 
                sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
@@ -2777,7 +2815,7 @@ skip_map:
  *     None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        unsigned long flags;
@@ -2785,7 +2823,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        ap->flags &= ~ATA_FLAG_NOINTR;
        ata_irq_on(ap);
-       ata_qc_complete(qc, err_mask);
+       ata_qc_complete(qc);
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2802,10 +2840,14 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 
 static unsigned long ata_pio_poll(struct ata_port *ap)
 {
+       struct ata_queued_cmd *qc;
        u8 status;
        unsigned int poll_state = HSM_ST_UNKNOWN;
        unsigned int reg_state = HSM_ST_UNKNOWN;
 
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       assert(qc != NULL);
+
        switch (ap->hsm_task_state) {
        case HSM_ST:
        case HSM_ST_POLL:
@@ -2825,6 +2867,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
+                       qc->err_mask |= AC_ERR_ATA_BUS;
                        ap->hsm_task_state = HSM_ST_TMOUT;
                        return 0;
                }
@@ -2859,29 +2902,31 @@ static int ata_pio_complete (struct ata_port *ap)
         * msecs, then chk-status again.  If still busy, fall back to
         * HSM_ST_POLL state.
         */
-       drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-       if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+       drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+       if (drv_stat & ATA_BUSY) {
                msleep(2);
-               drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-               if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+               drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+               if (drv_stat & ATA_BUSY) {
                        ap->hsm_task_state = HSM_ST_LAST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
                        return 0;
                }
        }
 
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       assert(qc != NULL);
+
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
+               qc->err_mask |= __ac_err_mask(drv_stat);
                ap->hsm_task_state = HSM_ST_ERR;
                return 0;
        }
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
-
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, 0);
+       assert(qc->err_mask == 0);
+       ata_poll_qc_complete(qc);
 
        /* another command may start at this point */
 
@@ -3189,6 +3234,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
 err_out:
        printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
              ap->id, dev->devno);
+       qc->err_mask |= AC_ERR_ATA_BUS;
        ap->hsm_task_state = HSM_ST_ERR;
 }
 
@@ -3227,8 +3273,16 @@ static void ata_pio_block(struct ata_port *ap)
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
+       /* check error */
+       if (status & (ATA_ERR | ATA_DF)) {
+               qc->err_mask |= AC_ERR_DEV;
+               ap->hsm_task_state = HSM_ST_ERR;
+               return;
+       }
+
+       /* transfer data if any */
        if (is_atapi_taskfile(&qc->tf)) {
-               /* no more data to transfer or unsupported ATAPI command */
+               /* DRQ=0 means no more data to transfer */
                if ((status & ATA_DRQ) == 0) {
                        ap->hsm_task_state = HSM_ST_LAST;
                        return;
@@ -3238,6 +3292,7 @@ static void ata_pio_block(struct ata_port *ap)
        } else {
                /* handle BSY=0, DRQ=0 as error */
                if ((status & ATA_DRQ) == 0) {
+                       qc->err_mask |= AC_ERR_ATA_BUS;
                        ap->hsm_task_state = HSM_ST_ERR;
                        return;
                }
@@ -3255,9 +3310,14 @@ static void ata_pio_error(struct ata_port *ap)
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
+       /* make sure qc->err_mask is available to 
+        * know what's wrong and recover
+        */
+       assert(qc->err_mask);
+
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
+       ata_poll_qc_complete(qc);
 }
 
 static void ata_pio_task(void *_data)
@@ -3359,7 +3419,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
                       ap->id, qc->tf.command, drv_stat, host_stat);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, ac_err_mask(drv_stat));
+               qc->err_mask |= ac_err_mask(drv_stat);
+               ata_qc_complete(qc);
                break;
        }
 
@@ -3458,15 +3519,10 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
        return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
-{
-       return 0;
-}
-
 static void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       unsigned int tag, do_clear = 0;
+       unsigned int tag;
 
        qc->flags = 0;
        tag = qc->tag;
@@ -3474,17 +3530,8 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
                if (tag == ap->active_tag)
                        ap->active_tag = ATA_TAG_POISON;
                qc->tag = ATA_TAG_POISON;
-               do_clear = 1;
-       }
-
-       if (qc->waiting) {
-               struct completion *waiting = qc->waiting;
-               qc->waiting = NULL;
-               complete(waiting);
-       }
-
-       if (likely(do_clear))
                clear_bit(tag, &ap->qactive);
+       }
 }
 
 /**
@@ -3500,7 +3547,6 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
 void ata_qc_free(struct ata_queued_cmd *qc)
 {
        assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
-       assert(qc->waiting == NULL);    /* nothing should be waiting */
 
        __ata_qc_complete(qc);
 }
@@ -3517,7 +3563,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_qc_complete(struct ata_queued_cmd *qc)
 {
        int rc;
 
@@ -3534,7 +3580,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* call completion callback */
-       rc = qc->complete_fn(qc, err_mask);
+       rc = qc->complete_fn(qc);
 
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@ -3972,7 +4018,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
                ap->ops->irq_clear(ap);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, ac_err_mask(status));
+               qc->err_mask |= ac_err_mask(status);
+               ata_qc_complete(qc);
                break;
 
        default:
@@ -4066,13 +4113,17 @@ static void atapi_packet_task(void *_data)
 
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
-       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-               goto err_out_status;
+       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+               qc->err_mask |= AC_ERR_ATA_BUS;
+               goto err_out;
+       }
 
        /* make sure DRQ is set */
        status = ata_chk_status(ap);
-       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
+       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+               qc->err_mask |= AC_ERR_ATA_BUS;
                goto err_out;
+       }
 
        /* send SCSI cdb */
        DPRINTK("send cdb\n");
@@ -4104,10 +4155,8 @@ static void atapi_packet_task(void *_data)
 
        return;
 
-err_out_status:
-       status = ata_chk_status(ap);
 err_out:
-       ata_poll_qc_complete(qc, __ac_err_mask(status));
+       ata_poll_qc_complete(qc);
 }
 
 
@@ -4124,6 +4173,96 @@ err_out:
  *     Inherited from caller.
  */
 
+/*
+ * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
+ * without filling any other registers
+ */
+static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
+                            u8 cmd)
+{
+       struct ata_taskfile tf;
+       int err;
+
+       ata_tf_init(ap, &tf, dev->devno);
+
+       tf.command = cmd;
+       tf.flags |= ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+
+       err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+       if (err)
+               printk(KERN_ERR "%s: ata command failed: %d\n",
+                               __FUNCTION__, err);
+
+       return err;
+}
+
+static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+{
+       u8 cmd;
+
+       if (!ata_try_flush_cache(dev))
+               return 0;
+
+       if (ata_id_has_flush_ext(dev->id))
+               cmd = ATA_CMD_FLUSH_EXT;
+       else
+               cmd = ATA_CMD_FLUSH;
+
+       return ata_do_simple_cmd(ap, dev, cmd);
+}
+
+static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+{
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+}
+
+static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+{
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+}
+
+/**
+ *     ata_device_resume - wakeup a previously suspended devices
+ *
+ *     Kick the drive back into action, by sending it an idle immediate
+ *     command and making sure its transfer mode matches between drive
+ *     and host.
+ *
+ */
+int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+{
+       if (ap->flags & ATA_FLAG_SUSPENDED) {
+               ap->flags &= ~ATA_FLAG_SUSPENDED;
+               ata_set_mode(ap);
+       }
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_start_drive(ap, dev);
+
+       return 0;
+}
+
+/**
+ *     ata_device_suspend - prepare a device for suspend
+ *
+ *     Flush the cache on the drive, if appropriate, then issue a
+ *     standbynow command.
+ *
+ */
+int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
+{
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_flush_cache(ap, dev);
+
+       ata_standby_drive(ap, dev);
+       ap->flags |= ATA_FLAG_SUSPENDED;
+       return 0;
+}
+
 int ata_port_start (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
@@ -4872,6 +5011,23 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
 
        return (tmp == bits->val) ? 1 : 0;
 }
+
+int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+       return 0;
+}
+
+int ata_pci_device_resume(struct pci_dev *pdev)
+{
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
+       return 0;
+}
 #endif /* CONFIG_PCI */
 
 
@@ -4975,4 +5131,11 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+EXPORT_SYMBOL_GPL(ata_pci_device_resume);
 #endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL_GPL(ata_device_suspend);
+EXPORT_SYMBOL_GPL(ata_device_resume);
+EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
+EXPORT_SYMBOL_GPL(ata_scsi_device_resume);