Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into tmp
[safe/jmp/linux-2.6] / drivers / scsi / libata-core.c
index ac19505..b046ffa 100644 (file)
@@ -62,7 +62,9 @@
 #include "libata.h"
 
 static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev);
+                                       struct ata_device *dev,
+                                       u16 heads,
+                                       u16 sectors);
 static void ata_set_mode(struct ata_port *ap);
 static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
                                         struct ata_device *dev);
@@ -276,7 +278,7 @@ static void ata_unpack_xfermask(unsigned int xfer_mask,
 }
 
 static const struct ata_xfer_ent {
-       unsigned int shift, bits;
+       int shift, bits;
        u8 base;
 } ata_xfer_tbl[] = {
        { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
@@ -862,6 +864,9 @@ static unsigned int ata_id_xfermask(const u16 *id)
 /**
  *     ata_port_queue_task - Queue port_task
  *     @ap: The ata_port to queue port_task for
+ *     @fn: workqueue function to be scheduled
+ *     @data: data value to pass to workqueue function
+ *     @delay: delay time for workqueue function
  *
  *     Schedule @fn(@data) for execution after @delay jiffies using
  *     port_task.  There is one port_task per port and it's the
@@ -987,9 +992,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
        qc->private_data = &wait;
        qc->complete_fn = ata_qc_complete_internal;
 
-       qc->err_mask = ata_qc_issue(qc);
-       if (qc->err_mask)
-               ata_qc_complete(qc);
+       ata_qc_issue(qc);
 
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
@@ -1156,7 +1159,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
                 * Some drives were very specific about that exact sequence.
                 */
                if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
-                       err_mask = ata_dev_init_params(ap, dev);
+                       err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
                        if (err_mask) {
                                rc = -EIO;
                                reason = "INIT_DEV_PARAMS failed";
@@ -2739,6 +2742,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
  *     ata_dev_init_params - Issue INIT DEV PARAMS command
  *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
+ *     @heads: Number of heads (taskfile parameter)
+ *     @sectors: Number of sectors (taskfile parameter)
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -2748,16 +2753,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
  */
 
 static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev)
+                                       struct ata_device *dev,
+                                       u16 heads,
+                                       u16 sectors)
 {
        struct ata_taskfile tf;
        unsigned int err_mask;
-       u16 sectors = dev->id[6];
-       u16 heads   = dev->id[3];
 
        /* Number of sectors per track 1-255. Number of heads 1-16 */
        if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
-               return 0;
+               return AC_ERR_INVALID;
 
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
@@ -3638,6 +3643,8 @@ static void ata_pio_block(struct ata_port *ap)
 
                ata_pio_sector(qc);
        }
+
+       ata_altstatus(ap); /* flush */
 }
 
 static void ata_pio_error(struct ata_port *ap)
@@ -3754,11 +3761,14 @@ static void atapi_packet_task(void *_data)
                spin_lock_irqsave(&ap->host_set->lock, flags);
                ap->flags &= ~ATA_FLAG_NOINTR;
                ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+               ata_altstatus(ap); /* flush */
+
                if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
                        ap->ops->bmdma_start(qc);       /* initiate bmdma */
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        } else {
                ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+               ata_altstatus(ap); /* flush */
 
                /* PIO commands are handled by polling */
                ap->hsm_task_state = HSM_ST;
@@ -3995,15 +4005,14 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
- *
- *     RETURNS:
- *     Zero on success, AC_ERR_* mask on failure
  */
-
-unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
+void ata_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
+       qc->ap->active_tag = qc->tag;
+       qc->flags |= ATA_QCFLAG_ACTIVE;
+
        if (ata_should_dma_map(qc)) {
                if (qc->flags & ATA_QCFLAG_SG) {
                        if (ata_sg_setup(qc))
@@ -4018,17 +4027,18 @@ unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
 
        ap->ops->qc_prep(qc);
 
-       qc->ap->active_tag = qc->tag;
-       qc->flags |= ATA_QCFLAG_ACTIVE;
-
-       return ap->ops->qc_issue(qc);
+       qc->err_mask |= ap->ops->qc_issue(qc);
+       if (unlikely(qc->err_mask))
+               goto err;
+       return;
 
 sg_err:
        qc->flags &= ~ATA_QCFLAG_DMAMAP;
-       return AC_ERR_SYSTEM;
+       qc->err_mask |= AC_ERR_SYSTEM;
+err:
+       ata_qc_complete(qc);
 }
 
-
 /**
  *     ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
  *     @qc: command to issue to device
@@ -4287,6 +4297,7 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
 int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
 {
        if (ap->flags & ATA_FLAG_SUSPENDED) {
+               ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000);
                ap->flags &= ~ATA_FLAG_SUSPENDED;
                ata_set_mode(ap);
        }
@@ -4302,6 +4313,7 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
  *     ata_device_suspend - prepare a device for suspend
  *     @ap: port the device is connected to
  *     @dev: the device to suspend
+ *     @state: target power management state
  *
  *     Flush the cache on the drive, if appropriate, then issue a
  *     standbynow command.
@@ -4938,7 +4950,6 @@ EXPORT_SYMBOL_GPL(ata_busy_sleep);
 EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
-EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);