Merge branch 'master'
authorJeff Garzik <jeff@garzik.org>
Thu, 20 Apr 2006 22:36:05 +0000 (18:36 -0400)
committerJeff Garzik <jeff@garzik.org>
Thu, 20 Apr 2006 22:36:05 +0000 (18:36 -0400)
21 files changed:
drivers/scsi/Makefile
drivers/scsi/ahci.c
drivers/scsi/ata_piix.c
drivers/scsi/libata-core.c
drivers/scsi/libata-eh.c [new file with mode: 0644]
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/scsi/pdc_adma.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_nv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_qstor.c
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sis.c
drivers/scsi/sata_svw.c
drivers/scsi/sata_sx4.c
drivers/scsi/sata_uli.c
drivers/scsi/sata_via.c
drivers/scsi/sata_vsc.c
include/linux/libata.h

index 81803a1..669ff6b 100644 (file)
@@ -164,7 +164,7 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
 CFLAGS_ncr53c8xx.o     := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
 zalon7xx-objs  := zalon.o ncr53c8xx.o
 NCR_Q720_mod-objs      := NCR_Q720.o ncr53c8xx.o
-libata-objs    := libata-core.o libata-scsi.o libata-bmdma.o
+libata-objs    := libata-core.o libata-scsi.o libata-bmdma.o libata-eh.o
 oktagon_esp_mod-objs   := oktagon_esp.o oktagon_io.o
 
 # Files generated that shall be removed upon make clean
index b4f8fb1..1b8429c 100644 (file)
@@ -48,7 +48,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ahci"
-#define DRV_VERSION    "1.2"
+#define DRV_VERSION    "1.3"
 
 
 enum {
@@ -516,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
        pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
 }
 
-static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val,
-                             unsigned long interval_msec,
-                             unsigned long timeout_msec)
-{
-       unsigned long timeout;
-       u32 tmp;
-
-       timeout = jiffies + (timeout_msec * HZ) / 1000;
-       do {
-               tmp = readl(reg);
-               if ((tmp & mask) == val)
-                       return 0;
-               msleep(interval_msec);
-       } while (time_before(jiffies, timeout));
-
-       return -1;
-}
-
-static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_softreset(struct ata_port *ap, unsigned int *class)
 {
        struct ahci_host_priv *hpriv = ap->host_set->private_data;
        struct ahci_port_priv *pp = ap->private_data;
@@ -543,11 +525,18 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
        const u32 cmd_fis_len = 5; /* five dwords */
        const char *reason = NULL;
        struct ata_taskfile tf;
+       u32 tmp;
        u8 *fis;
        int rc;
 
        DPRINTK("ENTER\n");
 
+       if (!sata_dev_present(ap)) {
+               DPRINTK("PHY reports no device\n");
+               *class = ATA_DEV_NONE;
+               return 0;
+       }
+
        /* prepare for SRST (AHCI-1.1 10.4.1) */
        rc = ahci_stop_engine(ap);
        if (rc) {
@@ -558,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
        /* check BUSY/DRQ, perform Command List Override if necessary */
        ahci_tf_read(ap, &tf);
        if (tf.command & (ATA_BUSY | ATA_DRQ)) {
-               u32 tmp;
-
                if (!(hpriv->cap & HOST_CAP_CLO)) {
                        rc = -EIO;
                        reason = "port busy but no CLO";
@@ -569,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
                tmp = readl(port_mmio + PORT_CMD);
                tmp |= PORT_CMD_CLO;
                writel(tmp, port_mmio + PORT_CMD);
-               readl(port_mmio + PORT_CMD); /* flush */
 
-               if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0,
-                                      1, 500)) {
+               tmp = ata_wait_register(port_mmio + PORT_CMD,
+                                       PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
+               if (tmp & PORT_CMD_CLO) {
                        rc = -EIO;
                        reason = "CLO failed";
                        goto fail_restart;
@@ -593,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
        fis[1] &= ~(1 << 7);    /* turn off Command FIS bit */
 
        writel(1, port_mmio + PORT_CMD_ISSUE);
-       readl(port_mmio + PORT_CMD_ISSUE);      /* flush */
 
-       if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) {
+       tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
+       if (tmp & 0x1) {
                rc = -EIO;
                reason = "1st FIS failed";
                goto fail;
@@ -640,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
  fail_restart:
        ahci_start_engine(ap);
  fail:
-       if (verbose)
-               printk(KERN_ERR "ata%u: softreset failed (%s)\n",
-                      ap->id, reason);
-       else
-               DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason);
+       printk(KERN_ERR "ata%u: softreset failed (%s)\n",
+              ap->id, reason);
        return rc;
 }
 
-static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
 {
        int rc;
 
        DPRINTK("ENTER\n");
 
        ahci_stop_engine(ap);
-       rc = sata_std_hardreset(ap, verbose, class);
+       rc = sata_std_hardreset(ap, class);
        ahci_start_engine(ap);
 
        if (rc == 0)
index 6dc8814..62dabf7 100644 (file)
@@ -93,7 +93,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "ata_piix"
-#define DRV_VERSION    "1.05"
+#define DRV_VERSION    "1.10"
 
 enum {
        PIIX_IOCFG              = 0x54, /* IDE I/O configuration register */
index bd14720..509178c 100644 (file)
@@ -65,7 +65,6 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
                                        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);
 static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);
@@ -77,6 +76,10 @@ int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
 MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
 
+int atapi_dmadir = 0;
+module_param(atapi_dmadir, int, 0444);
+MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
+
 int libata_fua = 0;
 module_param_named(fua, libata_fua, int, 0444);
 MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
@@ -397,9 +400,21 @@ static const char *ata_mode_string(unsigned int xfer_mask)
        return "<n/a>";
 }
 
-static void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
+static const char *sata_spd_string(unsigned int spd)
+{
+       static const char * const spd_str[] = {
+               "1.5 Gbps",
+               "3.0 Gbps",
+       };
+
+       if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
+               return "<unknown>";
+       return spd_str[spd - 1];
+}
+
+void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
 {
-       if (ata_dev_present(dev)) {
+       if (ata_dev_enabled(dev)) {
                printk(KERN_WARNING "ata%u: dev %u disabled\n",
                       ap->id, dev->devno);
                dev->class++;
@@ -949,6 +964,7 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *     @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
+ *     @cdb: CDB for packet command
  *     @dma_dir: Data tranfer direction of the command
  *     @buf: Data buffer of the command
  *     @buflen: Length of data buffer
@@ -963,10 +979,9 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *     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)
+unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+                          struct ata_taskfile *tf, const u8 *cdb,
+                          int dma_dir, void *buf, unsigned int buflen)
 {
        u8 command = tf->command;
        struct ata_queued_cmd *qc;
@@ -980,6 +995,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
        BUG_ON(qc == NULL);
 
        qc->tf = *tf;
+       if (cdb)
+               memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
        qc->dma_dir = dma_dir;
        if (dma_dir != DMA_NONE) {
                ata_sg_init_one(qc, buf, buflen);
@@ -1030,7 +1047,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
         *
         * Kill the following code as soon as those drivers are fixed.
         */
-       if (ap->flags & ATA_FLAG_PORT_DISABLED) {
+       if (ap->flags & ATA_FLAG_DISABLED) {
                err_mask |= AC_ERR_SYSTEM;
                ata_port_probe(ap);
        }
@@ -1129,7 +1146,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        tf.protocol = ATA_PROT_PIO;
 
-       err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_FROM_DEVICE,
                                     id, sizeof(id[0]) * ATA_ID_WORDS);
        if (err_mask) {
                rc = -EIO;
@@ -1210,7 +1227,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
        unsigned int xfer_mask;
        int i, rc;
 
-       if (!ata_dev_present(dev)) {
+       if (!ata_dev_enabled(dev)) {
                DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
                        ap->id, dev->devno);
                return 0;
@@ -1226,7 +1243,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                       id[84], id[85], id[86], id[87], id[88]);
 
        /* initialize to-be-configured parameters */
-       dev->flags = 0;
+       dev->flags &= ~ATA_DFLAG_CFG_MASK;
        dev->max_sectors = 0;
        dev->cdb_len = 0;
        dev->n_sectors = 0;
@@ -1349,16 +1366,24 @@ err_out_nosup:
  *     PCI/etc. bus probe sem.
  *
  *     RETURNS:
- *     Zero on success, non-zero on error.
+ *     Zero on success, negative errno otherwise.
  */
 
 static int ata_bus_probe(struct ata_port *ap)
 {
        unsigned int classes[ATA_MAX_DEVICES];
-       unsigned int i, rc, found = 0;
+       int tries[ATA_MAX_DEVICES];
+       int i, rc, down_xfermask;
+       struct ata_device *dev;
 
        ata_port_probe(ap);
 
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               tries[i] = ATA_PROBE_MAX_TRIES;
+
+ retry:
+       down_xfermask = 0;
+
        /* reset and determine device classes */
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                classes[i] = ATA_DEV_UNKNOWN;
@@ -1372,7 +1397,7 @@ static int ata_bus_probe(struct ata_port *ap)
        } else {
                ap->ops->phy_reset(ap);
 
-               if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+               if (!(ap->flags & ATA_FLAG_DISABLED))
                        for (i = 0; i < ATA_MAX_DEVICES; i++)
                                classes[i] = ap->device[i].class;
 
@@ -1385,43 +1410,76 @@ static int ata_bus_probe(struct ata_port *ap)
 
        /* read IDENTIFY page and configure devices */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
+               dev = &ap->device[i];
 
-               dev->class = classes[i];
+               if (tries[i])
+                       dev->class = classes[i];
 
-               if (!ata_dev_present(dev))
+               if (!ata_dev_enabled(dev))
                        continue;
 
-               WARN_ON(dev->id != NULL);
-               if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) {
-                       dev->class = ATA_DEV_NONE;
-                       continue;
-               }
+               kfree(dev->id);
+               dev->id = NULL;
+               rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
+               if (rc)
+                       goto fail;
 
-               if (ata_dev_configure(ap, dev, 1)) {
-                       ata_dev_disable(ap, dev);
-                       continue;
-               }
+               rc = ata_dev_configure(ap, dev, 1);
+               if (rc)
+                       goto fail;
+       }
 
-               found = 1;
+       /* configure transfer mode */
+       if (ap->ops->set_mode) {
+               /* FIXME: make ->set_mode handle no device case and
+                * return error code and failing device on failure as
+                * ata_set_mode() does.
+                */
+               for (i = 0; i < ATA_MAX_DEVICES; i++)
+                       if (ata_dev_enabled(&ap->device[i])) {
+                               ap->ops->set_mode(ap);
+                               break;
+                       }
+               rc = 0;
+       } else
+               rc = ata_set_mode(ap, &dev);
+
+       if (rc) {
+               down_xfermask = 1;
+               goto fail;
        }
 
-       if (!found)
-               goto err_out_disable;
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               if (ata_dev_enabled(&ap->device[i]))
+                       return 0;
 
-       if (ap->ops->set_mode)
-               ap->ops->set_mode(ap);
-       else
-               ata_set_mode(ap);
+       /* no device present, disable port */
+       ata_port_disable(ap);
+       ap->ops->port_disable(ap);
+       return -ENODEV;
 
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
-               goto err_out_disable;
+ fail:
+       switch (rc) {
+       case -EINVAL:
+       case -ENODEV:
+               tries[dev->devno] = 0;
+               break;
+       case -EIO:
+               ata_down_sata_spd_limit(ap);
+               /* fall through */
+       default:
+               tries[dev->devno]--;
+               if (down_xfermask &&
+                   ata_down_xfermask_limit(ap, dev, tries[dev->devno] == 1))
+                       tries[dev->devno] = 0;
+       }
 
-       return 0;
+       if (!tries[dev->devno]) {
+               ata_down_xfermask_limit(ap, dev, 1);
+               ata_dev_disable(ap, dev);
+       }
 
-err_out_disable:
-       ap->ops->port_disable(ap);
-       return -1;
+       goto retry;
 }
 
 /**
@@ -1437,7 +1495,7 @@ err_out_disable:
 
 void ata_port_probe(struct ata_port *ap)
 {
-       ap->flags &= ~ATA_FLAG_PORT_DISABLED;
+       ap->flags &= ~ATA_FLAG_DISABLED;
 }
 
 /**
@@ -1451,27 +1509,23 @@ void ata_port_probe(struct ata_port *ap)
  */
 static void sata_print_link_status(struct ata_port *ap)
 {
-       u32 sstatus, tmp;
-       const char *speed;
+       u32 sstatus, scontrol, tmp;
 
        if (!ap->ops->scr_read)
                return;
 
        sstatus = scr_read(ap, SCR_STATUS);
+       scontrol = scr_read(ap, SCR_CONTROL);
 
        if (sata_dev_present(ap)) {
                tmp = (sstatus >> 4) & 0xf;
-               if (tmp & (1 << 0))
-                       speed = "1.5";
-               else if (tmp & (1 << 1))
-                       speed = "3.0";
-               else
-                       speed = "<unknown>";
-               printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
-                      ap->id, speed, sstatus);
+               printk(KERN_INFO
+                      "ata%u: SATA link up %s (SStatus %X SControl %X)\n",
+                      ap->id, sata_spd_string(tmp), sstatus, scontrol);
        } else {
-               printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
-                      ap->id, sstatus);
+               printk(KERN_INFO
+                      "ata%u: SATA link down (SStatus %X SControl %X)\n",
+                      ap->id, sstatus, scontrol);
        }
 }
 
@@ -1518,7 +1572,7 @@ void __sata_phy_reset(struct ata_port *ap)
        else
                ata_port_disable(ap);
 
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
+       if (ap->flags & ATA_FLAG_DISABLED)
                return;
 
        if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
@@ -1543,7 +1597,7 @@ void __sata_phy_reset(struct ata_port *ap)
 void sata_phy_reset(struct ata_port *ap)
 {
        __sata_phy_reset(ap);
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
+       if (ap->flags & ATA_FLAG_DISABLED)
                return;
        ata_bus_reset(ap);
 }
@@ -1560,7 +1614,7 @@ void sata_phy_reset(struct ata_port *ap)
 struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev)
 {
        struct ata_device *pair = &ap->device[1 - adev->devno];
-       if (!ata_dev_present(pair))
+       if (!ata_dev_enabled(pair))
                return NULL;
        return pair;
 }
@@ -1582,7 +1636,121 @@ void ata_port_disable(struct ata_port *ap)
 {
        ap->device[0].class = ATA_DEV_NONE;
        ap->device[1].class = ATA_DEV_NONE;
-       ap->flags |= ATA_FLAG_PORT_DISABLED;
+       ap->flags |= ATA_FLAG_DISABLED;
+}
+
+/**
+ *     ata_down_sata_spd_limit - adjust SATA spd limit downward
+ *     @ap: Port to adjust SATA spd limit for
+ *
+ *     Adjust SATA spd limit of @ap downward.  Note that this
+ *     function only adjusts the limit.  The change must be applied
+ *     using ata_set_sata_spd().
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno on failure
+ */
+int ata_down_sata_spd_limit(struct ata_port *ap)
+{
+       u32 spd, mask;
+       int highbit;
+
+       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
+               return -EOPNOTSUPP;
+
+       mask = ap->sata_spd_limit;
+       if (mask <= 1)
+               return -EINVAL;
+       highbit = fls(mask) - 1;
+       mask &= ~(1 << highbit);
+
+       spd = (scr_read(ap, SCR_STATUS) >> 4) & 0xf;
+       if (spd <= 1)
+               return -EINVAL;
+       spd--;
+       mask &= (1 << spd) - 1;
+       if (!mask)
+               return -EINVAL;
+
+       ap->sata_spd_limit = mask;
+
+       printk(KERN_WARNING "ata%u: limiting SATA link speed to %s\n",
+              ap->id, sata_spd_string(fls(mask)));
+
+       return 0;
+}
+
+static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
+{
+       u32 spd, limit;
+
+       if (ap->sata_spd_limit == UINT_MAX)
+               limit = 0;
+       else
+               limit = fls(ap->sata_spd_limit);
+
+       spd = (*scontrol >> 4) & 0xf;
+       *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4);
+
+       return spd != limit;
+}
+
+/**
+ *     ata_set_sata_spd_needed - is SATA spd configuration needed
+ *     @ap: Port in question
+ *
+ *     Test whether the spd limit in SControl matches
+ *     @ap->sata_spd_limit.  This function is used to determine
+ *     whether hardreset is necessary to apply SATA spd
+ *     configuration.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ *
+ *     RETURNS:
+ *     1 if SATA spd configuration is needed, 0 otherwise.
+ */
+int ata_set_sata_spd_needed(struct ata_port *ap)
+{
+       u32 scontrol;
+
+       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
+               return 0;
+
+       scontrol = scr_read(ap, SCR_CONTROL);
+
+       return __ata_set_sata_spd_needed(ap, &scontrol);
+}
+
+/**
+ *     ata_set_sata_spd - set SATA spd according to spd limit
+ *     @ap: Port to set SATA spd for
+ *
+ *     Set SATA spd of @ap according to sata_spd_limit.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ *
+ *     RETURNS:
+ *     0 if spd doesn't need to be changed, 1 if spd has been
+ *     changed.  -EOPNOTSUPP if SCR registers are inaccessible.
+ */
+int ata_set_sata_spd(struct ata_port *ap)
+{
+       u32 scontrol;
+
+       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
+               return -EOPNOTSUPP;
+
+       scontrol = scr_read(ap, SCR_CONTROL);
+       if (!__ata_set_sata_spd_needed(ap, &scontrol))
+               return 0;
+
+       scr_write(ap, SCR_CONTROL, scontrol);
+       return 1;
 }
 
 /*
@@ -1733,11 +1901,62 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
        return 0;
 }
 
+/**
+ *     ata_down_xfermask_limit - adjust dev xfer masks downward
+ *     @ap: Port associated with device @dev
+ *     @dev: Device to adjust xfer masks
+ *     @force_pio0: Force PIO0
+ *
+ *     Adjust xfer masks of @dev downward.  Note that this function
+ *     does not apply the change.  Invoking ata_set_mode() afterwards
+ *     will apply the limit.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno on failure
+ */
+int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
+                           int force_pio0)
+{
+       unsigned long xfer_mask;
+       int highbit;
+
+       xfer_mask = ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask,
+                                     dev->udma_mask);
+
+       if (!xfer_mask)
+               goto fail;
+       /* don't gear down to MWDMA from UDMA, go directly to PIO */
+       if (xfer_mask & ATA_MASK_UDMA)
+               xfer_mask &= ~ATA_MASK_MWDMA;
+
+       highbit = fls(xfer_mask) - 1;
+       xfer_mask &= ~(1 << highbit);
+       if (force_pio0)
+               xfer_mask &= 1 << ATA_SHIFT_PIO;
+       if (!xfer_mask)
+               goto fail;
+
+       ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
+                           &dev->udma_mask);
+
+       printk(KERN_WARNING "ata%u: dev %u limiting speed to %s\n",
+              ap->id, dev->devno, ata_mode_string(xfer_mask));
+
+       return 0;
+
+ fail:
+       return -EINVAL;
+}
+
 static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
 {
        unsigned int err_mask;
        int rc;
 
+       dev->flags &= ~ATA_DFLAG_PIO;
        if (dev->xfer_shift == ATA_SHIFT_PIO)
                dev->flags |= ATA_DFLAG_PIO;
 
@@ -1750,12 +1969,8 @@ static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
        }
 
        rc = ata_dev_revalidate(ap, dev, 0);
-       if (rc) {
-               printk(KERN_ERR
-                      "ata%u: failed to revalidate after set xfermode\n",
-                      ap->id);
+       if (rc)
                return rc;
-       }
 
        DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
                dev->xfer_shift, (int)dev->xfer_mode);
@@ -1766,118 +1981,107 @@ static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
        return 0;
 }
 
-static int ata_host_set_pio(struct ata_port *ap)
-{
-       int i;
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
-
-               if (!ata_dev_present(dev))
-                       continue;
-
-               if (!dev->pio_mode) {
-                       printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i);
-                       return -1;
-               }
-
-               dev->xfer_mode = dev->pio_mode;
-               dev->xfer_shift = ATA_SHIFT_PIO;
-               if (ap->ops->set_piomode)
-                       ap->ops->set_piomode(ap, dev);
-       }
-
-       return 0;
-}
-
-static void ata_host_set_dma(struct ata_port *ap)
-{
-       int i;
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
-
-               if (!ata_dev_present(dev) || !dev->dma_mode)
-                       continue;
-
-               dev->xfer_mode = dev->dma_mode;
-               dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode);
-               if (ap->ops->set_dmamode)
-                       ap->ops->set_dmamode(ap, dev);
-       }
-}
-
 /**
  *     ata_set_mode - Program timings and issue SET FEATURES - XFER
  *     @ap: port on which timings will be programmed
+ *     @r_failed_dev: out paramter for failed device
  *
- *     Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
+ *     Set ATA device disk transfer mode (PIO3, UDMA6, etc.).  If
+ *     ata_set_mode() fails, pointer to the failing device is
+ *     returned in @r_failed_dev.
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno otherwise
  */
-static void ata_set_mode(struct ata_port *ap)
+int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
 {
-       int i, rc, used_dma = 0;
+       struct ata_device *dev;
+       int i, rc = 0, used_dma = 0, found = 0;
 
        /* step 1: calculate xfer_mask */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
                unsigned int pio_mask, dma_mask;
 
-               if (!ata_dev_present(dev))
+               dev = &ap->device[i];
+
+               if (!ata_dev_enabled(dev))
                        continue;
 
                ata_dev_xfermask(ap, dev);
 
-               /* TODO: let LLDD filter dev->*_mask here */
-
                pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
                dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
                dev->pio_mode = ata_xfer_mask2mode(pio_mask);
                dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
+               found = 1;
                if (dev->dma_mode)
                        used_dma = 1;
        }
+       if (!found)
+               goto out;
 
        /* step 2: always set host PIO timings */
-       rc = ata_host_set_pio(ap);
-       if (rc)
-               goto err_out;
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
+               if (!ata_dev_enabled(dev))
+                       continue;
+
+               if (!dev->pio_mode) {
+                       printk(KERN_WARNING "ata%u: dev %u no PIO support\n",
+                              ap->id, dev->devno);
+                       rc = -EINVAL;
+                       goto out;
+               }
+
+               dev->xfer_mode = dev->pio_mode;
+               dev->xfer_shift = ATA_SHIFT_PIO;
+               if (ap->ops->set_piomode)
+                       ap->ops->set_piomode(ap, dev);
+       }
 
        /* step 3: set host DMA timings */
-       ata_host_set_dma(ap);
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
+
+               if (!ata_dev_enabled(dev) || !dev->dma_mode)
+                       continue;
+
+               dev->xfer_mode = dev->dma_mode;
+               dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode);
+               if (ap->ops->set_dmamode)
+                       ap->ops->set_dmamode(ap, dev);
+       }
 
        /* step 4: update devices' xfer mode */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
+               dev = &ap->device[i];
 
-               if (!ata_dev_present(dev))
+               if (!ata_dev_enabled(dev))
                        continue;
 
-               if (ata_dev_set_mode(ap, dev))
-                       goto err_out;
+               rc = ata_dev_set_mode(ap, dev);
+               if (rc)
+                       goto out;
        }
 
-       /*
-        *      Record simplex status. If we selected DMA then the other
-        *      host channels are not permitted to do so.
+       /* Record simplex status. If we selected DMA then the other
+        * host channels are not permitted to do so.
         */
-
        if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX))
                ap->host_set->simplex_claimed = 1;
 
-       /*
-        *      Chip specific finalisation
-        */
+       /* step5: chip specific finalisation */
        if (ap->ops->post_set_mode)
                ap->ops->post_set_mode(ap);
 
-       return;
-
-err_out:
-       ata_port_disable(ap);
+ out:
+       if (rc)
+               *r_failed_dev = dev;
+       return rc;
 }
 
 /**
@@ -2030,8 +2234,10 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         * the bus shows 0xFF because the odd clown forgets the D7
         * pulldown resistor.
         */
-       if (ata_check_status(ap) == 0xFF)
+       if (ata_check_status(ap) == 0xFF) {
+               printk(KERN_ERR "ata%u: SRST failed (status 0xFF)\n", ap->id);
                return AC_ERR_OTHER;
+       }
 
        ata_bus_post_reset(ap, devmask);
 
@@ -2055,7 +2261,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
  *     Obtains host_set lock.
  *
  *     SIDE EFFECTS:
- *     Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
+ *     Sets ATA_FLAG_DISABLED if bus reset fails.
  */
 
 void ata_bus_reset(struct ata_port *ap)
@@ -2132,9 +2338,11 @@ err_out:
 static int sata_phy_resume(struct ata_port *ap)
 {
        unsigned long timeout = jiffies + (HZ * 5);
-       u32 sstatus;
+       u32 scontrol, sstatus;
 
-       scr_write_flush(ap, SCR_CONTROL, 0x300);
+       scontrol = scr_read(ap, SCR_CONTROL);
+       scontrol = (scontrol & 0x0f0) | 0x300;
+       scr_write_flush(ap, SCR_CONTROL, scontrol);
 
        /* Wait for phy to become ready, if necessary. */
        do {
@@ -2163,7 +2371,18 @@ static int sata_phy_resume(struct ata_port *ap)
 void ata_std_probeinit(struct ata_port *ap)
 {
        if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
+               u32 spd;
+
+               /* set cable type and resume link */
+               ap->cbl = ATA_CBL_SATA;
                sata_phy_resume(ap);
+
+               /* init sata_spd_limit to the current value */
+               spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
+               if (spd)
+                       ap->sata_spd_limit &= (1 << spd) - 1;
+
+               /* wait for device */
                if (sata_dev_present(ap))
                        ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
        }
@@ -2172,7 +2391,6 @@ void ata_std_probeinit(struct ata_port *ap)
 /**
  *     ata_std_softreset - reset host port via ATA SRST
  *     @ap: port to reset
- *     @verbose: fail verbosely
  *     @classes: resulting classes of attached devices
  *
  *     Reset host port using ATA SRST.  This function is to be used
@@ -2184,7 +2402,7 @@ void ata_std_probeinit(struct ata_port *ap)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
 {
        unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
        unsigned int devmask = 0, err_mask;
@@ -2210,12 +2428,8 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
        DPRINTK("about to softreset, devmask=%x\n", devmask);
        err_mask = ata_bus_softreset(ap, devmask);
        if (err_mask) {
-               if (verbose)
-                       printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
-                              ap->id, err_mask);
-               else
-                       DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
-                               err_mask);
+               printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+                      ap->id, err_mask);
                return -EIO;
        }
 
@@ -2232,7 +2446,6 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
 /**
  *     sata_std_hardreset - reset host port via SATA phy reset
  *     @ap: port to reset
- *     @verbose: fail verbosely
  *     @class: resulting class of attached device
  *
  *     SATA phy-reset host port using DET bits of SControl register.
@@ -2245,20 +2458,36 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
 {
+       u32 scontrol;
+
        DPRINTK("ENTER\n");
 
-       /* Issue phy wake/reset */
-       scr_write_flush(ap, SCR_CONTROL, 0x301);
+       if (ata_set_sata_spd_needed(ap)) {
+               /* SATA spec says nothing about how to reconfigure
+                * spd.  To be on the safe side, turn off phy during
+                * reconfiguration.  This works for at least ICH7 AHCI
+                * and Sil3124.
+                */
+               scontrol = scr_read(ap, SCR_CONTROL);
+               scontrol = (scontrol & 0x0f0) | 0x302;
+               scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+               ata_set_sata_spd(ap);
+       }
 
-       /*
-        * Couldn't find anything in SATA I/II specs, but AHCI-1.1
+       /* issue phy wake/reset */
+       scontrol = scr_read(ap, SCR_CONTROL);
+       scontrol = (scontrol & 0x0f0) | 0x301;
+       scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+       /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
         * 10.4.2 says at least 1 ms.
         */
        msleep(1);
 
-       /* Bring phy back */
+       /* bring phy back */
        sata_phy_resume(ap);
 
        /* TODO: phy layer with polling, timeouts, etc. */
@@ -2269,11 +2498,8 @@ int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
        }
 
        if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
-               if (verbose)
-                       printk(KERN_ERR "ata%u: COMRESET failed "
-                              "(device not ready)\n", ap->id);
-               else
-                       DPRINTK("EXIT, device not ready\n");
+               printk(KERN_ERR
+                      "ata%u: COMRESET failed (device not ready)\n", ap->id);
                return -EIO;
        }
 
@@ -2304,10 +2530,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
 {
        DPRINTK("ENTER\n");
 
-       /* set cable type if it isn't already set */
-       if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
-               ap->cbl = ATA_CBL_SATA;
-
        /* print link status */
        if (ap->cbl == ATA_CBL_SATA)
                sata_print_link_status(ap);
@@ -2357,7 +2579,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
        ata_reset_fn_t hardreset;
 
        hardreset = NULL;
-       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+       if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
                hardreset = sata_std_hardreset;
 
        return ata_drive_probe_reset(ap, ata_std_probeinit,
@@ -2365,16 +2587,15 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
                                     ata_std_postreset, classes);
 }
 
-static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
-                         ata_postreset_fn_t postreset,
-                         unsigned int *classes)
+int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+                ata_postreset_fn_t postreset, unsigned int *classes)
 {
        int i, rc;
 
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                classes[i] = ATA_DEV_UNKNOWN;
 
-       rc = reset(ap, 0, classes);
+       rc = reset(ap, classes);
        if (rc)
                return rc;
 
@@ -2394,7 +2615,7 @@ static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
        if (postreset)
                postreset(ap, classes);
 
-       return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+       return 0;
 }
 
 /**
@@ -2418,8 +2639,6 @@ static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
  *     - If classification is supported, fill classes[] with
  *       recognized class codes.
  *     - If classification is not supported, leave classes[] alone.
- *     - If verbose is non-zero, print error message on failure;
- *       otherwise, shut up.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -2438,22 +2657,46 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
        if (probeinit)
                probeinit(ap);
 
-       if (softreset) {
-               rc = do_probe_reset(ap, softreset, postreset, classes);
-               if (rc == 0)
-                       return 0;
+       if (softreset && !ata_set_sata_spd_needed(ap)) {
+               rc = ata_do_reset(ap, softreset, postreset, classes);
+               if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN)
+                       goto done;
+               printk(KERN_INFO "ata%u: softreset failed, will try "
+                      "hardreset in 5 secs\n", ap->id);
+               ssleep(5);
        }
 
        if (!hardreset)
-               return rc;
+               goto done;
 
-       rc = do_probe_reset(ap, hardreset, postreset, classes);
-       if (rc == 0 || rc != -ENODEV)
-               return rc;
+       while (1) {
+               rc = ata_do_reset(ap, hardreset, postreset, classes);
+               if (rc == 0) {
+                       if (classes[0] != ATA_DEV_UNKNOWN)
+                               goto done;
+                       break;
+               }
+
+               if (ata_down_sata_spd_limit(ap))
+                       goto done;
+
+               printk(KERN_INFO "ata%u: hardreset failed, will retry "
+                      "in 5 secs\n", ap->id);
+               ssleep(5);
+       }
+
+       if (softreset) {
+               printk(KERN_INFO "ata%u: hardreset succeeded without "
+                      "classification, will retry softreset in 5 secs\n",
+                      ap->id);
+               ssleep(5);
 
-       if (softreset)
-               rc = do_probe_reset(ap, softreset, postreset, classes);
+               rc = ata_do_reset(ap, softreset, postreset, classes);
+       }
 
+ done:
+       if (rc == 0 && classes[0] == ATA_DEV_UNKNOWN)
+               rc = -ENODEV;
        return rc;
 }
 
@@ -2537,15 +2780,14 @@ static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
 int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
                       int post_reset)
 {
-       unsigned int class;
-       u16 *id;
+       unsigned int class = dev->class;
+       u16 *id = NULL;
        int rc;
 
-       if (!ata_dev_present(dev))
-               return -ENODEV;
-
-       class = dev->class;
-       id = NULL;
+       if (!ata_dev_enabled(dev)) {
+               rc = -ENODEV;
+               goto fail;
+       }
 
        /* allocate & read ID data */
        rc = ata_dev_read_id(ap, dev, &class, post_reset, &id);
@@ -2562,7 +2804,9 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
        dev->id = id;
 
        /* configure device according to the new ID */
-       return ata_dev_configure(ap, dev, 0);
+       rc = ata_dev_configure(ap, dev, 0);
+       if (rc == 0)
+               return 0;
 
  fail:
        printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n",
@@ -2664,23 +2908,34 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
        unsigned long xfer_mask;
        int i;
 
-       xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
-                                     ap->udma_mask);
+       xfer_mask = ata_pack_xfermask(ap->pio_mask,
+                                     ap->mwdma_mask, ap->udma_mask);
+
+       /* Apply cable rule here.  Don't apply it early because when
+        * we handle hot plug the cable type can itself change.
+        */
+       if (ap->cbl == ATA_CBL_PATA40)
+               xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
 
        /* FIXME: Use port-wide xfermask for now */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *d = &ap->device[i];
-               if (!ata_dev_present(d))
+
+               if (ata_dev_absent(d))
+                       continue;
+
+               if (ata_dev_disabled(d)) {
+                       /* to avoid violating device selection timing */
+                       xfer_mask &= ata_pack_xfermask(d->pio_mask,
+                                                      UINT_MAX, UINT_MAX);
                        continue;
-               xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask,
-                                              d->udma_mask);
+               }
+
+               xfer_mask &= ata_pack_xfermask(d->pio_mask,
+                                              d->mwdma_mask, d->udma_mask);
                xfer_mask &= ata_id_xfermask(d->id);
                if (ata_dma_blacklisted(d))
                        xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
-               /* Apply cable rule here. Don't apply it early because when
-                  we handle hot plug the cable type can itself change */
-               if (ap->cbl == ATA_CBL_PATA40)
-                       xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
        }
 
        if (ata_dma_blacklisted(dev))
@@ -2691,11 +2946,12 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
                if (hs->simplex_claimed)
                        xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
        }
+
        if (ap->ops->mode_filter)
                xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
 
-       ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
-                           &dev->udma_mask);
+       ata_unpack_xfermask(xfer_mask, &dev->pio_mask,
+                           &dev->mwdma_mask, &dev->udma_mask);
 }
 
 /**
@@ -2729,7 +2985,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = dev->xfer_mode;
 
-       err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -2769,7 +3025,7 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
        tf.nsect = sectors;
        tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -3157,7 +3413,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 
 /**
  *     ata_pio_poll - poll using PIO, depending on current state
- *     @ap: the target ata_port
+ *     @qc: qc in progress
  *
  *     LOCKING:
  *     None.  (executing in kernel thread context)
@@ -3165,17 +3421,13 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc)
  *     RETURNS:
  *     timeout value to use
  */
-
-static unsigned long ata_pio_poll(struct ata_port *ap)
+static unsigned long ata_pio_poll(struct ata_queued_cmd *qc)
 {
-       struct ata_queued_cmd *qc;
+       struct ata_port *ap = qc->ap;
        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);
-       WARN_ON(qc == NULL);
-
        switch (ap->hsm_task_state) {
        case HSM_ST:
        case HSM_ST_POLL:
@@ -3209,7 +3461,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
 
 /**
  *     ata_pio_complete - check if drive is busy or idle
- *     @ap: the target ata_port
+ *     @qc: qc to complete
  *
  *     LOCKING:
  *     None.  (executing in kernel thread context)
@@ -3217,10 +3469,9 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
  *     RETURNS:
  *     Non-zero if qc completed, zero otherwise.
  */
-
-static int ata_pio_complete (struct ata_port *ap)
+static int ata_pio_complete(struct ata_queued_cmd *qc)
 {
-       struct ata_queued_cmd *qc;
+       struct ata_port *ap = qc->ap;
        u8 drv_stat;
 
        /*
@@ -3241,9 +3492,6 @@ static int ata_pio_complete (struct ata_port *ap)
                }
        }
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       WARN_ON(qc == NULL);
-
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
                qc->err_mask |= __ac_err_mask(drv_stat);
@@ -3579,15 +3827,14 @@ err_out:
 
 /**
  *     ata_pio_block - start PIO on a block
- *     @ap: the target ata_port
+ *     @qc: qc to transfer block for
  *
  *     LOCKING:
  *     None.  (executing in kernel thread context)
  */
-
-static void ata_pio_block(struct ata_port *ap)
+static void ata_pio_block(struct ata_queued_cmd *qc)
 {
-       struct ata_queued_cmd *qc;
+       struct ata_port *ap = qc->ap;
        u8 status;
 
        /*
@@ -3609,9 +3856,6 @@ static void ata_pio_block(struct ata_port *ap)
                }
        }
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       WARN_ON(qc == NULL);
-
        /* check error */
        if (status & (ATA_ERR | ATA_DF)) {
                qc->err_mask |= AC_ERR_DEV;
@@ -3640,15 +3884,13 @@ static void ata_pio_block(struct ata_port *ap)
        }
 }
 
-static void ata_pio_error(struct ata_port *ap)
+static void ata_pio_error(struct ata_queued_cmd *qc)
 {
-       struct ata_queued_cmd *qc;
-
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       WARN_ON(qc == NULL);
+       struct ata_port *ap = qc->ap;
 
        if (qc->tf.command != ATA_CMD_PACKET)
-               printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
+               printk(KERN_WARNING "ata%u: dev %u PIO error\n",
+                      ap->id, qc->dev->devno);
 
        /* make sure qc->err_mask is available to
         * know what's wrong and recover
@@ -3662,7 +3904,8 @@ static void ata_pio_error(struct ata_port *ap)
 
 static void ata_pio_task(void *_data)
 {
-       struct ata_port *ap = _data;
+       struct ata_queued_cmd *qc = _data;
+       struct ata_port *ap = qc->ap;
        unsigned long timeout;
        int qc_completed;
 
@@ -3675,33 +3918,33 @@ fsm_start:
                return;
 
        case HSM_ST:
-               ata_pio_block(ap);
+               ata_pio_block(qc);
                break;
 
        case HSM_ST_LAST:
-               qc_completed = ata_pio_complete(ap);
+               qc_completed = ata_pio_complete(qc);
                break;
 
        case HSM_ST_POLL:
        case HSM_ST_LAST_POLL:
-               timeout = ata_pio_poll(ap);
+               timeout = ata_pio_poll(qc);
                break;
 
        case HSM_ST_TMOUT:
        case HSM_ST_ERR:
-               ata_pio_error(ap);
+               ata_pio_error(qc);
                return;
        }
 
        if (timeout)
-               ata_port_queue_task(ap, ata_pio_task, ap, timeout);
+               ata_port_queue_task(ap, ata_pio_task, qc, timeout);
        else if (!qc_completed)
                goto fsm_start;
 }
 
 /**
  *     atapi_packet_task - Write CDB bytes to hardware
- *     @_data: Port to which ATAPI device is attached.
+ *     @_data: qc in progress
  *
  *     When device has indicated its readiness to accept
  *     a CDB, this function is called.  Send the CDB.
@@ -3712,17 +3955,12 @@ fsm_start:
  *     LOCKING:
  *     Kernel thread context (may sleep)
  */
-
 static void atapi_packet_task(void *_data)
 {
-       struct ata_port *ap = _data;
-       struct ata_queued_cmd *qc;
+       struct ata_queued_cmd *qc = _data;
+       struct ata_port *ap = qc->ap;
        u8 status;
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       WARN_ON(qc == NULL);
-       WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
-
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
        if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
@@ -3762,7 +4000,7 @@ static void atapi_packet_task(void *_data)
 
                /* PIO commands are handled by polling */
                ap->hsm_task_state = HSM_ST;
-               ata_port_queue_task(ap, ata_pio_task, ap, 0);
+               ata_port_queue_task(ap, ata_pio_task, qc, 0);
        }
 
        return;
@@ -3771,99 +4009,6 @@ err_out:
        ata_poll_qc_complete(qc);
 }
 
-/**
- *     ata_qc_timeout - Handle timeout of queued command
- *     @qc: Command that timed out
- *
- *     Some part of the kernel (currently, only the SCSI layer)
- *     has noticed that the active command on port @ap has not
- *     completed after a specified length of time.  Handle this
- *     condition by disabling DMA (if necessary) and completing
- *     transactions, with error if necessary.
- *
- *     This also handles the case of the "lost interrupt", where
- *     for some reason (possibly hardware bug, possibly driver bug)
- *     an interrupt was not delivered to the driver, even though the
- *     transaction completed successfully.
- *
- *     LOCKING:
- *     Inherited from SCSI layer (none, can sleep)
- */
-
-static void ata_qc_timeout(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct ata_host_set *host_set = ap->host_set;
-       u8 host_stat = 0, drv_stat;
-       unsigned long flags;
-
-       DPRINTK("ENTER\n");
-
-       ap->hsm_task_state = HSM_ST_IDLE;
-
-       spin_lock_irqsave(&host_set->lock, flags);
-
-       switch (qc->tf.protocol) {
-
-       case ATA_PROT_DMA:
-       case ATA_PROT_ATAPI_DMA:
-               host_stat = ap->ops->bmdma_status(ap);
-
-               /* before we do anything else, clear DMA-Start bit */
-               ap->ops->bmdma_stop(qc);
-
-               /* fall through */
-
-       default:
-               ata_altstatus(ap);
-               drv_stat = ata_chk_status(ap);
-
-               /* ack bmdma irq events */
-               ap->ops->irq_clear(ap);
-
-               printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
-                      ap->id, qc->tf.command, drv_stat, host_stat);
-
-               /* complete taskfile transaction */
-               qc->err_mask |= ac_err_mask(drv_stat);
-               break;
-       }
-
-       spin_unlock_irqrestore(&host_set->lock, flags);
-
-       ata_eh_qc_complete(qc);
-
-       DPRINTK("EXIT\n");
-}
-
-/**
- *     ata_eng_timeout - Handle timeout of queued command
- *     @ap: Port on which timed-out command is active
- *
- *     Some part of the kernel (currently, only the SCSI layer)
- *     has noticed that the active command on port @ap has not
- *     completed after a specified length of time.  Handle this
- *     condition by disabling DMA (if necessary) and completing
- *     transactions, with error if necessary.
- *
- *     This also handles the case of the "lost interrupt", where
- *     for some reason (possibly hardware bug, possibly driver bug)
- *     an interrupt was not delivered to the driver, even though the
- *     transaction completed successfully.
- *
- *     LOCKING:
- *     Inherited from SCSI layer (none, can sleep)
- */
-
-void ata_eng_timeout(struct ata_port *ap)
-{
-       DPRINTK("ENTER\n");
-
-       ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
-
-       DPRINTK("EXIT\n");
-}
-
 /**
  *     ata_qc_new - Request an available ATA command, for queueing
  *     @ap: Port associated with device @dev
@@ -4068,26 +4213,26 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
                ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
                ap->hsm_task_state = HSM_ST;
-               ata_port_queue_task(ap, ata_pio_task, ap, 0);
+               ata_port_queue_task(ap, ata_pio_task, qc, 0);
                break;
 
        case ATA_PROT_ATAPI:
                ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
-               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+               ata_port_queue_task(ap, atapi_packet_task, qc, 0);
                break;
 
        case ATA_PROT_ATAPI_NODATA:
                ap->flags |= ATA_FLAG_NOINTR;
                ata_tf_to_host(ap, &qc->tf);
-               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+               ata_port_queue_task(ap, atapi_packet_task, qc, 0);
                break;
 
        case ATA_PROT_ATAPI_DMA:
                ap->flags |= ATA_FLAG_NOINTR;
                ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+               ata_port_queue_task(ap, atapi_packet_task, qc, 0);
                break;
 
        default:
@@ -4209,7 +4354,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
 
                ap = host_set->ports[i];
                if (ap &&
-                   !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
+                   !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->active_tag);
@@ -4241,7 +4386,7 @@ static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
        tf.flags |= ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
 
-       err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+       err = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
        if (err)
                printk(KERN_ERR "%s: ata command failed: %d\n",
                                __FUNCTION__, err);
@@ -4287,10 +4432,12 @@ 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) {
+               struct ata_device *failed_dev;
                ap->flags &= ~ATA_FLAG_SUSPENDED;
-               ata_set_mode(ap);
+               while (ata_set_mode(ap, &failed_dev))
+                       ata_dev_disable(ap, failed_dev);
        }
-       if (!ata_dev_present(dev))
+       if (!ata_dev_enabled(dev))
                return 0;
        if (dev->class == ATA_DEV_ATA)
                ata_start_drive(ap, dev);
@@ -4308,7 +4455,7 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
  */
 int ata_device_suspend(struct ata_port *ap, struct ata_device *dev, pm_message_t state)
 {
-       if (!ata_dev_present(dev))
+       if (!ata_dev_enabled(dev))
                return 0;
        if (dev->class == ATA_DEV_ATA)
                ata_flush_cache(ap, dev);
@@ -4428,7 +4575,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        host->unique_id = ata_unique_id++;
        host->max_cmd_len = 12;
 
-       ap->flags = ATA_FLAG_PORT_DISABLED;
+       ap->flags = ATA_FLAG_DISABLED;
        ap->id = host->unique_id;
        ap->host = host;
        ap->ctl = ATA_DEVCTL_OBS;
@@ -4443,6 +4590,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        ap->flags |= ent->host_flags;
        ap->ops = ent->port_ops;
        ap->cbl = ATA_CBL_NONE;
+       ap->sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
 
@@ -4503,7 +4651,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
 
        host->transportt = &ata_scsi_transport_template;
 
-       ap = (struct ata_port *) &host->hostdata[0];
+       ap = ata_shost_to_port(host);
 
        ata_host_init(ap, host, host_set, ent, port_no);
 
@@ -4716,7 +4864,7 @@ void ata_host_set_remove(struct ata_host_set *host_set)
 
 int ata_scsi_release(struct Scsi_Host *host)
 {
-       struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+       struct ata_port *ap = ata_shost_to_port(host);
        int i;
 
        DPRINTK("ENTER\n");
@@ -4883,6 +5031,52 @@ int ata_ratelimit(void)
        return rc;
 }
 
+/**
+ *     ata_wait_register - wait until register value changes
+ *     @reg: IO-mapped register
+ *     @mask: Mask to apply to read register value
+ *     @val: Wait condition
+ *     @interval_msec: polling interval in milliseconds
+ *     @timeout_msec: timeout in milliseconds
+ *
+ *     Waiting for some bits of register to change is a common
+ *     operation for ATA controllers.  This function reads 32bit LE
+ *     IO-mapped register @reg and tests for the following condition.
+ *
+ *     (*@reg & mask) != val
+ *
+ *     If the condition is met, it returns; otherwise, the process is
+ *     repeated after @interval_msec until timeout.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     The final register value.
+ */
+u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+                     unsigned long interval_msec,
+                     unsigned long timeout_msec)
+{
+       unsigned long timeout;
+       u32 tmp;
+
+       tmp = ioread32(reg);
+
+       /* Calculate timeout _after_ the first read to make sure
+        * preceding writes reach the controller before starting to
+        * eat away the timeout.
+        */
+       timeout = jiffies + (timeout_msec * HZ) / 1000;
+
+       while ((tmp & mask) == val && time_before(jiffies, timeout)) {
+               msleep(interval_msec);
+               tmp = ioread32(reg);
+       }
+
+       return tmp;
+}
+
 /*
  * libata is essentially a library of internal helper functions for
  * low-level ATA host controller drivers.  As such, the API/ABI is
@@ -4898,7 +5092,6 @@ EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
 EXPORT_SYMBOL_GPL(__ata_qc_complete);
 EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
-EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_tf_load);
 EXPORT_SYMBOL_GPL(ata_tf_read);
 EXPORT_SYMBOL_GPL(ata_noop_dev_select);
@@ -4920,6 +5113,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
 EXPORT_SYMBOL_GPL(ata_bmdma_status);
 EXPORT_SYMBOL_GPL(ata_bmdma_stop);
 EXPORT_SYMBOL_GPL(ata_port_probe);
+EXPORT_SYMBOL_GPL(ata_set_sata_spd);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
@@ -4934,6 +5128,7 @@ EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
+EXPORT_SYMBOL_GPL(ata_wait_register);
 EXPORT_SYMBOL_GPL(ata_busy_sleep);
 EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
@@ -4944,8 +5139,6 @@ EXPORT_SYMBOL_GPL(ata_host_intr);
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
-EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
-EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
 EXPORT_SYMBOL_GPL(ata_timing_compute);
@@ -4967,3 +5160,8 @@ 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);
+
+EXPORT_SYMBOL_GPL(ata_scsi_error);
+EXPORT_SYMBOL_GPL(ata_eng_timeout);
+EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
+EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
new file mode 100644 (file)
index 0000000..c31b13f
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ *  libata-eh.c - libata error handling
+ *
+ *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *                 Please ALWAYS copy linux-ide@vger.kernel.org
+ *                 on emails.
+ *
+ *  Copyright 2006 Tejun Heo <htejun@gmail.com>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License as
+ *  published by the Free Software Foundation; either version 2, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ *  USA.
+ *
+ *
+ *  libata documentation is available via 'make {ps|pdf}docs',
+ *  as Documentation/DocBook/libata.*
+ *
+ *  Hardware documentation available from http://www.t13.org/ and
+ *  http://www.sata-io.org/
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+
+#include <linux/libata.h>
+
+#include "libata.h"
+
+/**
+ *     ata_scsi_timed_out - SCSI layer time out callback
+ *     @cmd: timed out SCSI command
+ *
+ *     Handles SCSI layer timeout.  We race with normal completion of
+ *     the qc for @cmd.  If the qc is already gone, we lose and let
+ *     the scsi command finish (EH_HANDLED).  Otherwise, the qc has
+ *     timed out and EH should be invoked.  Prevent ata_qc_complete()
+ *     from finishing it by setting EH_SCHEDULED and return
+ *     EH_NOT_HANDLED.
+ *
+ *     LOCKING:
+ *     Called from timer context
+ *
+ *     RETURNS:
+ *     EH_HANDLED or EH_NOT_HANDLED
+ */
+enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
+{
+       struct Scsi_Host *host = cmd->device->host;
+       struct ata_port *ap = ata_shost_to_port(host);
+       unsigned long flags;
+       struct ata_queued_cmd *qc;
+       enum scsi_eh_timer_return ret = EH_HANDLED;
+
+       DPRINTK("ENTER\n");
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       if (qc) {
+               WARN_ON(qc->scsicmd != cmd);
+               qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
+               qc->err_mask |= AC_ERR_TIMEOUT;
+               ret = EH_NOT_HANDLED;
+       }
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       DPRINTK("EXIT, ret=%d\n", ret);
+       return ret;
+}
+
+/**
+ *     ata_scsi_error - SCSI layer error handler callback
+ *     @host: SCSI host on which error occurred
+ *
+ *     Handles SCSI-layer-thrown error events.
+ *
+ *     LOCKING:
+ *     Inherited from SCSI layer (none, can sleep)
+ *
+ *     RETURNS:
+ *     Zero.
+ */
+void ata_scsi_error(struct Scsi_Host *host)
+{
+       struct ata_port *ap = ata_shost_to_port(host);
+
+       DPRINTK("ENTER\n");
+
+       /* synchronize with IRQ handler and port task */
+       spin_unlock_wait(&ap->host_set->lock);
+       ata_port_flush_task(ap);
+
+       WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
+
+       ap->ops->eng_timeout(ap);
+
+       WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
+
+       scsi_eh_flush_done_q(&ap->eh_done_q);
+
+       DPRINTK("EXIT\n");
+}
+
+/**
+ *     ata_qc_timeout - Handle timeout of queued command
+ *     @qc: Command that timed out
+ *
+ *     Some part of the kernel (currently, only the SCSI layer)
+ *     has noticed that the active command on port @ap has not
+ *     completed after a specified length of time.  Handle this
+ *     condition by disabling DMA (if necessary) and completing
+ *     transactions, with error if necessary.
+ *
+ *     This also handles the case of the "lost interrupt", where
+ *     for some reason (possibly hardware bug, possibly driver bug)
+ *     an interrupt was not delivered to the driver, even though the
+ *     transaction completed successfully.
+ *
+ *     LOCKING:
+ *     Inherited from SCSI layer (none, can sleep)
+ */
+static void ata_qc_timeout(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_host_set *host_set = ap->host_set;
+       u8 host_stat = 0, drv_stat;
+       unsigned long flags;
+
+       DPRINTK("ENTER\n");
+
+       ap->hsm_task_state = HSM_ST_IDLE;
+
+       spin_lock_irqsave(&host_set->lock, flags);
+
+       switch (qc->tf.protocol) {
+
+       case ATA_PROT_DMA:
+       case ATA_PROT_ATAPI_DMA:
+               host_stat = ap->ops->bmdma_status(ap);
+
+               /* before we do anything else, clear DMA-Start bit */
+               ap->ops->bmdma_stop(qc);
+
+               /* fall through */
+
+       default:
+               ata_altstatus(ap);
+               drv_stat = ata_chk_status(ap);
+
+               /* ack bmdma irq events */
+               ap->ops->irq_clear(ap);
+
+               printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
+                      ap->id, qc->tf.command, drv_stat, host_stat);
+
+               /* complete taskfile transaction */
+               qc->err_mask |= ac_err_mask(drv_stat);
+               break;
+       }
+
+       spin_unlock_irqrestore(&host_set->lock, flags);
+
+       ata_eh_qc_complete(qc);
+
+       DPRINTK("EXIT\n");
+}
+
+/**
+ *     ata_eng_timeout - Handle timeout of queued command
+ *     @ap: Port on which timed-out command is active
+ *
+ *     Some part of the kernel (currently, only the SCSI layer)
+ *     has noticed that the active command on port @ap has not
+ *     completed after a specified length of time.  Handle this
+ *     condition by disabling DMA (if necessary) and completing
+ *     transactions, with error if necessary.
+ *
+ *     This also handles the case of the "lost interrupt", where
+ *     for some reason (possibly hardware bug, possibly driver bug)
+ *     an interrupt was not delivered to the driver, even though the
+ *     transaction completed successfully.
+ *
+ *     LOCKING:
+ *     Inherited from SCSI layer (none, can sleep)
+ */
+void ata_eng_timeout(struct ata_port *ap)
+{
+       DPRINTK("ENTER\n");
+
+       ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
+
+       DPRINTK("EXIT\n");
+}
+
+static void ata_eh_scsidone(struct scsi_cmnd *scmd)
+{
+       /* nada */
+}
+
+static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       qc->scsidone = ata_eh_scsidone;
+       __ata_qc_complete(qc);
+       WARN_ON(ata_tag_valid(qc->tag));
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
+}
+
+/**
+ *     ata_eh_qc_complete - Complete an active ATA command from EH
+ *     @qc: Command to complete
+ *
+ *     Indicate to the mid and upper layers that an ATA command has
+ *     completed.  To be used from EH.
+ */
+void ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       scmd->retries = scmd->allowed;
+       __ata_eh_qc_complete(qc);
+}
+
+/**
+ *     ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
+ *     @qc: Command to retry
+ *
+ *     Indicate to the mid and upper layers that an ATA command
+ *     should be retried.  To be used from EH.
+ *
+ *     SCSI midlayer limits the number of retries to scmd->allowed.
+ *     scmd->retries is decremented for commands which get retried
+ *     due to unrelated failures (qc->err_mask is zero).
+ */
+void ata_eh_qc_retry(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       if (!qc->err_mask && scmd->retries)
+               scmd->retries--;
+       __ata_eh_qc_complete(qc);
+}
index a0289ec..9871f82 100644 (file)
@@ -53,8 +53,6 @@
 typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
 static struct ata_device *
 ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
-static void ata_scsi_error(struct Scsi_Host *host);
-enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
 
 #define RW_RECOVERY_MPAGE 0x1
 #define RW_RECOVERY_MPAGE_LEN 12
@@ -397,7 +395,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
 
 int ata_scsi_device_resume(struct scsi_device *sdev)
 {
-       struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+       struct ata_port *ap = ata_shost_to_port(sdev->host);
        struct ata_device *dev = &ap->device[sdev->id];
 
        return ata_device_resume(ap, dev);
@@ -405,7 +403,7 @@ int ata_scsi_device_resume(struct scsi_device *sdev)
 
 int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state)
 {
-       struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+       struct ata_port *ap = ata_shost_to_port(sdev->host);
        struct ata_device *dev = &ap->device[sdev->id];
 
        return ata_device_suspend(ap, dev, state);
@@ -547,17 +545,12 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
 
        cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
-       /*
-        * Read the controller registers.
-        */
-       WARN_ON(qc->ap->ops->tf_read == NULL);
-       qc->ap->ops->tf_read(qc->ap, tf);
-
        /*
         * Use ata_to_sense_error() to map status register bits
         * onto sense key, asc & ascq.
         */
-       if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+       if (qc->err_mask ||
+           tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
                                   &sb[1], &sb[2], &sb[3]);
                sb[1] &= 0x0f;
@@ -622,17 +615,12 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
 
        cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
-       /*
-        * Read the controller registers.
-        */
-       WARN_ON(qc->ap->ops->tf_read == NULL);
-       qc->ap->ops->tf_read(qc->ap, tf);
-
        /*
         * Use ata_to_sense_error() to map status register bits
         * onto sense key, asc & ascq.
         */
-       if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+       if (qc->err_mask ||
+           tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
                                   &sb[2], &sb[12], &sb[13]);
                sb[2] &= 0x0f;
@@ -716,7 +704,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
                struct ata_port *ap;
                struct ata_device *dev;
 
-               ap = (struct ata_port *) &sdev->host->hostdata[0];
+               ap = ata_shost_to_port(sdev->host);
                dev = &ap->device[sdev->id];
 
                ata_scsi_dev_config(sdev, dev);
@@ -725,137 +713,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
        return 0;       /* scsi layer doesn't check return value, sigh */
 }
 
-/**
- *     ata_scsi_timed_out - SCSI layer time out callback
- *     @cmd: timed out SCSI command
- *
- *     Handles SCSI layer timeout.  We race with normal completion of
- *     the qc for @cmd.  If the qc is already gone, we lose and let
- *     the scsi command finish (EH_HANDLED).  Otherwise, the qc has
- *     timed out and EH should be invoked.  Prevent ata_qc_complete()
- *     from finishing it by setting EH_SCHEDULED and return
- *     EH_NOT_HANDLED.
- *
- *     LOCKING:
- *     Called from timer context
- *
- *     RETURNS:
- *     EH_HANDLED or EH_NOT_HANDLED
- */
-enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
-{
-       struct Scsi_Host *host = cmd->device->host;
-       struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
-       unsigned long flags;
-       struct ata_queued_cmd *qc;
-       enum scsi_eh_timer_return ret = EH_HANDLED;
-
-       DPRINTK("ENTER\n");
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (qc) {
-               WARN_ON(qc->scsicmd != cmd);
-               qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
-               qc->err_mask |= AC_ERR_TIMEOUT;
-               ret = EH_NOT_HANDLED;
-       }
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       DPRINTK("EXIT, ret=%d\n", ret);
-       return ret;
-}
-
-/**
- *     ata_scsi_error - SCSI layer error handler callback
- *     @host: SCSI host on which error occurred
- *
- *     Handles SCSI-layer-thrown error events.
- *
- *     LOCKING:
- *     Inherited from SCSI layer (none, can sleep)
- */
-
-static void ata_scsi_error(struct Scsi_Host *host)
-{
-       struct ata_port *ap;
-       unsigned long flags;
-
-       DPRINTK("ENTER\n");
-
-       ap = (struct ata_port *) &host->hostdata[0];
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       WARN_ON(ap->flags & ATA_FLAG_IN_EH);
-       ap->flags |= ATA_FLAG_IN_EH;
-       WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       ata_port_flush_task(ap);
-
-       ap->ops->eng_timeout(ap);
-
-       WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
-
-       scsi_eh_flush_done_q(&ap->eh_done_q);
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       ap->flags &= ~ATA_FLAG_IN_EH;
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       DPRINTK("EXIT\n");
-}
-
-static void ata_eh_scsidone(struct scsi_cmnd *scmd)
-{
-       /* nada */
-}
-
-static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct scsi_cmnd *scmd = qc->scsicmd;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       qc->scsidone = ata_eh_scsidone;
-       __ata_qc_complete(qc);
-       WARN_ON(ata_tag_valid(qc->tag));
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
-}
-
-/**
- *     ata_eh_qc_complete - Complete an active ATA command from EH
- *     @qc: Command to complete
- *
- *     Indicate to the mid and upper layers that an ATA command has
- *     completed.  To be used from EH.
- */
-void ata_eh_qc_complete(struct ata_queued_cmd *qc)
-{
-       struct scsi_cmnd *scmd = qc->scsicmd;
-       scmd->retries = scmd->allowed;
-       __ata_eh_qc_complete(qc);
-}
-
-/**
- *     ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
- *     @qc: Command to retry
- *
- *     Indicate to the mid and upper layers that an ATA command
- *     should be retried.  To be used from EH.
- *
- *     SCSI midlayer limits the number of retries to scmd->allowed.
- *     This function might need to adjust scmd->retries for commands
- *     which get retried due to unrelated NCQ failures.
- */
-void ata_eh_qc_retry(struct ata_queued_cmd *qc)
-{
-       __ata_eh_qc_complete(qc);
-}
-
 /**
  *     ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *     @qc: Storage for translated ATA taskfile
@@ -1195,6 +1052,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
        u64 block;
        u32 n_block;
 
+       qc->flags |= ATA_QCFLAG_IO;
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 
        if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
@@ -1341,11 +1199,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
         */
        if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
            ((cdb[2] & 0x20) || need_sense)) {
+               qc->ap->ops->tf_read(qc->ap, &qc->tf);
                ata_gen_ata_desc_sense(qc);
        } else {
                if (!need_sense) {
                        cmd->result = SAM_STAT_GOOD;
                } else {
+                       qc->ap->ops->tf_read(qc->ap, &qc->tf);
+
                        /* TODO: decide which descriptor format to use
                         * for 48b LBA devices and call that here
                         * instead of the fixed desc, which is only
@@ -2137,13 +1998,15 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
 
 static void atapi_sense_complete(struct ata_queued_cmd *qc)
 {
-       if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
+       if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) {
                /* FIXME: not quite right; we don't want the
                 * translation of taskfile registers into
                 * a sense descriptors, since that's only
                 * correct for ATA, not ATAPI
                 */
+               qc->ap->ops->tf_read(qc->ap, &qc->tf);
                ata_gen_ata_desc_sense(qc);
+       }
 
        qc->scsidone(qc->scsicmd);
        ata_qc_free(qc);
@@ -2211,17 +2074,15 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                cmd->result = SAM_STAT_CHECK_CONDITION;
                atapi_request_sense(qc);
                return;
-       }
-
-       else if (unlikely(err_mask))
+       } else if (unlikely(err_mask)) {
                /* FIXME: not quite right; we don't want the
                 * translation of taskfile registers into
                 * a sense descriptors, since that's only
                 * correct for ATA, not ATAPI
                 */
+               qc->ap->ops->tf_read(qc->ap, &qc->tf);
                ata_gen_ata_desc_sense(qc);
-
-       else {
+       } else {
                u8 *scsicmd = cmd->cmnd;
 
                if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
@@ -2303,11 +2164,9 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
 
-#ifdef ATAPI_ENABLE_DMADIR
-               /* some SATA bridges need us to indicate data xfer direction */
-               if (cmd->sc_data_direction != DMA_TO_DEVICE)
+               if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+                       /* some SATA bridges need us to indicate data xfer direction */
                        qc->tf.feature |= ATAPI_DMADIR;
-#endif
        }
 
        qc->nbytes = cmd->bufflen;
@@ -2347,7 +2206,7 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
                     (scsidev->lun != 0)))
                return NULL;
 
-       if (unlikely(!ata_dev_present(dev)))
+       if (unlikely(!ata_dev_enabled(dev)))
                return NULL;
 
        if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) {
@@ -2619,7 +2478,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        struct scsi_device *scsidev = cmd->device;
        struct Scsi_Host *shost = scsidev->host;
 
-       ap = (struct ata_port *) &shost->hostdata[0];
+       ap = ata_shost_to_port(shost);
 
        spin_unlock(shost->host_lock);
        spin_lock(&ap->host_set->lock);
@@ -2735,13 +2594,13 @@ void ata_scsi_scan_host(struct ata_port *ap)
        struct ata_device *dev;
        unsigned int i;
 
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
+       if (ap->flags & ATA_FLAG_DISABLED)
                return;
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                dev = &ap->device[i];
 
-               if (ata_dev_present(dev))
+               if (ata_dev_enabled(dev))
                        scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
        }
 }
index bac8cba..3f8b0a8 100644 (file)
@@ -29,7 +29,7 @@
 #define __LIBATA_H__
 
 #define DRV_NAME       "libata"
-#define DRV_VERSION    "1.20"  /* must be exactly four chars */
+#define DRV_VERSION    "1.30"  /* must be exactly four chars */
 
 struct ata_scsi_args {
        struct ata_port         *ap;
@@ -41,11 +41,23 @@ struct ata_scsi_args {
 
 /* libata-core.c */
 extern int atapi_enabled;
+extern int atapi_dmadir;
 extern int libata_fua;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
                                      struct ata_device *dev);
 extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+extern void ata_dev_disable(struct ata_port *ap, struct ata_device *dev);
 extern void ata_port_flush_task(struct ata_port *ap);
+extern unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+                                 struct ata_taskfile *tf, const u8 *cdb,
+                                 int dma_dir, void *buf, unsigned int buflen);
+extern int ata_down_sata_spd_limit(struct ata_port *ap);
+extern int ata_set_sata_spd_needed(struct ata_port *ap);
+extern int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
+                                  int force_pio0);
+extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
+extern int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+                       ata_postreset_fn_t postreset, unsigned int *classes);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
@@ -89,4 +101,8 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
                         unsigned int (*actor) (struct ata_scsi_args *args,
                                            u8 *rbuf, unsigned int buflen));
 
+/* libata-eh.c */
+extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
+extern void ata_scsi_error(struct Scsi_Host *host);
+
 #endif /* __LIBATA_H__ */
index 5cda16c..b9a3c56 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pdc_adma"
-#define DRV_VERSION    "0.03"
+#define DRV_VERSION    "0.04"
 
 /* macro to calculate base address for ATA regs */
 #define ADMA_ATA_REGS(base,port_no)    ((base) + ((port_no) * 0x40))
@@ -455,7 +455,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
                        continue;
                handled = 1;
                adma_enter_reg_mode(ap);
-               if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
+               if (ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))
                        continue;
                pp = ap->private_data;
                if (!pp || pp->state != adma_state_pkt)
@@ -480,7 +480,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
        for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
                struct ata_port *ap;
                ap = host_set->ports[port_no];
-               if (ap && (!(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))) {
+               if (ap && (!(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR)))) {
                        struct ata_queued_cmd *qc;
                        struct adma_port_priv *pp = ap->private_data;
                        if (!pp || pp->state != adma_state_mmio)
index d5fdcb9..181917a 100644 (file)
@@ -1396,7 +1396,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                        }
                }
 
-               if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
+               if (ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))
                        continue;
 
                err_mask = ac_err_mask(ata_status);
@@ -1990,7 +1990,7 @@ comreset_retry:
        tf.nsect = readb((void __iomem *) ap->ioaddr.nsect_addr);
 
        dev->class = ata_dev_classify(&tf);
-       if (!ata_dev_present(dev)) {
+       if (!ata_dev_enabled(dev)) {
                VPRINTK("Port disabled post-sig: No device present.\n");
                ata_port_disable(ap);
        }
index 9f55308..3a70875 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME                       "sata_nv"
-#define DRV_VERSION                    "0.8"
+#define DRV_VERSION                    "0.9"
 
 enum {
        NV_PORTS                        = 2,
@@ -279,7 +279,7 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
 
                ap = host_set->ports[i];
                if (ap &&
-                   !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
+                   !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->active_tag);
index 7eb67a6..ddbc0c6 100644 (file)
@@ -533,7 +533,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
                ap = host_set->ports[i];
                tmp = mask & (1 << (i + 1));
                if (tmp && ap &&
-                   !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
+                   !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->active_tag);
@@ -676,10 +676,6 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       /*
-        * If this driver happens to only be useful on Apple's K2, then
-        * we should check that here as it has a normal Serverworks ID
-        */
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
index 886f344..259c2de 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_qstor"
-#define DRV_VERSION    "0.05"
+#define DRV_VERSION    "0.06"
 
 enum {
        QS_PORTS                = 4,
@@ -395,7 +395,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
                                        sff1, sff0, port_no, sHST, sDST);
                        handled = 1;
                        if (ap && !(ap->flags &
-                                   (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
+                                   (ATA_FLAG_DISABLED|ATA_FLAG_NOINTR))) {
                                struct ata_queued_cmd *qc;
                                struct qs_port_priv *pp = ap->private_data;
                                if (!pp || pp->state != qs_state_pkt)
@@ -428,7 +428,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
                struct ata_port *ap;
                ap = host_set->ports[port_no];
                if (ap &&
-                   !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
+                   !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
                        struct ata_queued_cmd *qc;
                        struct qs_port_priv *pp = ap->private_data;
                        if (!pp || pp->state != qs_state_mmio)
index 1066272..c933357 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_sil"
-#define DRV_VERSION    "0.9"
+#define DRV_VERSION    "1.0"
 
 enum {
        /*
@@ -263,7 +263,7 @@ static void sil_post_set_mode (struct ata_port *ap)
 
        for (i = 0; i < 2; i++) {
                dev = &ap->device[i];
-               if (!ata_dev_present(dev))
+               if (!ata_dev_enabled(dev))
                        dev_mode[i] = 0;        /* PIO0/1/2 */
                else if (dev->flags & ATA_DFLAG_PIO)
                        dev_mode[i] = 1;        /* PIO3/4 */
@@ -390,10 +390,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       /*
-        * If this driver happens to only be useful on Apple's K2, then
-        * we should check that here as it has a normal Serverworks ID
-        */
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
index f7264fd..e9fd869 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_sil24"
-#define DRV_VERSION    "0.23"
+#define DRV_VERSION    "0.24"
 
 /*
  * Port request block (PRB) 32 bytes
@@ -86,6 +86,13 @@ enum {
        /* HOST_SLOT_STAT bits */
        HOST_SSTAT_ATTN         = (1 << 31),
 
+       /* HOST_CTRL bits */
+       HOST_CTRL_M66EN         = (1 << 16), /* M66EN PCI bus signal */
+       HOST_CTRL_TRDY          = (1 << 17), /* latched PCI TRDY */
+       HOST_CTRL_STOP          = (1 << 18), /* latched PCI STOP */
+       HOST_CTRL_DEVSEL        = (1 << 19), /* latched PCI DEVSEL */
+       HOST_CTRL_REQ64         = (1 << 20), /* latched PCI REQ64 */
+
        /*
         * Port registers
         * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
@@ -142,8 +149,12 @@ enum {
        PORT_IRQ_PWR_CHG        = (1 << 3), /* power management change */
        PORT_IRQ_PHYRDY_CHG     = (1 << 4), /* PHY ready change */
        PORT_IRQ_COMWAKE        = (1 << 5), /* COMWAKE received */
-       PORT_IRQ_UNK_FIS        = (1 << 6), /* Unknown FIS received */
-       PORT_IRQ_SDB_FIS        = (1 << 11), /* SDB FIS received */
+       PORT_IRQ_UNK_FIS        = (1 << 6), /* unknown FIS received */
+       PORT_IRQ_DEV_XCHG       = (1 << 7), /* device exchanged */
+       PORT_IRQ_8B10B          = (1 << 8), /* 8b/10b decode error threshold */
+       PORT_IRQ_CRC            = (1 << 9), /* CRC error threshold */
+       PORT_IRQ_HANDSHAKE      = (1 << 10), /* handshake error threshold */
+       PORT_IRQ_SDB_NOTIFY     = (1 << 11), /* SDB notify received */
 
        /* bits[27:16] are unmasked (raw) */
        PORT_IRQ_RAW_SHIFT      = 16,
@@ -174,7 +185,7 @@ enum {
        PORT_CERR_CMD_PCIPERR   = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
        PORT_CERR_XFR_UNDEF     = 32, /* PSD ecode 00 - undefined */
        PORT_CERR_XFR_TGTABRT   = 33, /* PSD ecode 01 - target abort */
-       PORT_CERR_XFR_MSGABRT   = 34, /* PSD ecode 10 - master abort */
+       PORT_CERR_XFR_MSTABRT   = 34, /* PSD ecode 10 - master abort */
        PORT_CERR_XFR_PCIPERR   = 35, /* PSD ecode 11 - PCI prity err during transfer */
        PORT_CERR_SENDSERVICE   = 36, /* FIS received while sending service */
 
@@ -207,6 +218,11 @@ enum {
        BID_SIL3132             = 1,
        BID_SIL3131             = 2,
 
+       /* host flags */
+       SIL24_COMMON_FLAGS      = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
+       SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
+
        IRQ_STAT_4PORTS         = 0xf,
 };
 
@@ -333,9 +349,8 @@ static struct ata_port_info sil24_port_info[] = {
        /* sil_3124 */
        {
                .sht            = &sil24_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 SIL24_NPORTS2FLAG(4),
+               .host_flags     = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
+                                 SIL24_FLAG_PCIX_IRQ_WOC,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -344,9 +359,7 @@ static struct ata_port_info sil24_port_info[] = {
        /* sil_3132 */
        {
                .sht            = &sil24_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 SIL24_NPORTS2FLAG(2),
+               .host_flags     = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -355,9 +368,7 @@ static struct ata_port_info sil24_port_info[] = {
        /* sil_3131/sil_3531 */
        {
                .sht            = &sil24_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 SIL24_NPORTS2FLAG(1),
+               .host_flags     = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -426,15 +437,30 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
        *tf = pp->tf;
 }
 
-static int sil24_softreset(struct ata_port *ap, int verbose,
-                          unsigned int *class)
+static int sil24_init_port(struct ata_port *ap)
+{
+       void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+       u32 tmp;
+
+       writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+       ata_wait_register(port + PORT_CTRL_STAT,
+                         PORT_CS_INIT, PORT_CS_INIT, 10, 100);
+       tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                               PORT_CS_RDY, 0, 10, 100);
+
+       if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
+               return -EIO;
+       return 0;
+}
+
+static int sil24_softreset(struct ata_port *ap, unsigned int *class)
 {
        void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
        struct sil24_port_priv *pp = ap->private_data;
        struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
        dma_addr_t paddr = pp->cmd_block_dma;
-       unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ;
-       u32 irq_enable, irq_stat;
+       u32 mask, irq_enable, irq_stat;
+       const char *reason;
 
        DPRINTK("ENTER\n");
 
@@ -448,34 +474,35 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
        irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
        writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
 
-       /*
-        * XXX: Not sure whether the following sleep is needed or not.
-        * The original driver had it.  So....
-        */
-       msleep(10);
+       /* put the port into known state */
+       if (sil24_init_port(ap)) {
+               reason ="port not ready";
+               goto err;
+       }
 
-       prb->ctrl = PRB_CTRL_SRST;
+       /* do SRST */
+       prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
        prb->fis[1] = 0; /* no PM yet */
 
        writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+       writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
 
-       do {
-               irq_stat = readl(port + PORT_IRQ_STAT);
-               writel(irq_stat, port + PORT_IRQ_STAT);         /* clear irq */
-
-               irq_stat >>= PORT_IRQ_RAW_SHIFT;
-               if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
-                       break;
+       mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
+       irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0,
+                                    100, ATA_TMOUT_BOOT / HZ * 1000);
 
-               msleep(100);
-       } while (time_before(jiffies, timeout));
+       writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */
+       irq_stat >>= PORT_IRQ_RAW_SHIFT;
 
        /* restore IRQs */
        writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
 
        if (!(irq_stat & PORT_IRQ_COMPLETE)) {
-               DPRINTK("EXIT, srst failed\n");
-               return -EIO;
+               if (irq_stat & PORT_IRQ_ERROR)
+                       reason = "SRST command error";
+               else
+                       reason = "timeout";
+               goto err;
        }
 
        sil24_update_tf(ap);
@@ -487,15 +514,55 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
  out:
        DPRINTK("EXIT, class=%u\n", *class);
        return 0;
+
+ err:
+       printk(KERN_ERR "ata%u: softreset failed (%s)\n", ap->id, reason);
+       return -EIO;
 }
 
-static int sil24_hardreset(struct ata_port *ap, int verbose,
-                          unsigned int *class)
+static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
 {
-       unsigned int dummy_class;
+       void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+       const char *reason;
+       int tout_msec;
+       u32 tmp;
+
+       /* sil24 does the right thing(tm) without any protection */
+       ata_set_sata_spd(ap);
+
+       tout_msec = 100;
+       if (sata_dev_present(ap))
+               tout_msec = 5000;
 
-       /* sil24 doesn't report device signature after hard reset */
-       return sata_std_hardreset(ap, verbose, &dummy_class);
+       writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
+       tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                               PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
+
+       /* SStatus oscillates between zero and valid status for short
+        * duration after DEV_RST, give it time to settle.
+        */
+       msleep(100);
+
+       if (tmp & PORT_CS_DEV_RST) {
+               if (!sata_dev_present(ap))
+                       return 0;
+               reason = "link not ready";
+               goto err;
+       }
+
+       if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+               reason = "device not ready";
+               goto err;
+       }
+
+       /* sil24 doesn't report device class code after hardreset,
+        * leave *class alone.
+        */
+       return 0;
+
+ err:
+       printk(KERN_ERR "ata%u: hardreset failed (%s)\n", ap->id, reason);
+       return -EIO;
 }
 
 static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)
@@ -531,6 +598,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
        union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
        struct sil24_prb *prb;
        struct sil24_sge *sge;
+       u16 ctrl = 0;
 
        switch (qc->tf.protocol) {
        case ATA_PROT_PIO:
@@ -538,7 +606,6 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
        case ATA_PROT_NODATA:
                prb = &cb->ata.prb;
                sge = cb->ata.sge;
-               prb->ctrl = 0;
                break;
 
        case ATA_PROT_ATAPI:
@@ -551,12 +618,10 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
 
                if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
                        if (qc->tf.flags & ATA_TFLAG_WRITE)
-                               prb->ctrl = PRB_CTRL_PACKET_WRITE;
+                               ctrl = PRB_CTRL_PACKET_WRITE;
                        else
-                               prb->ctrl = PRB_CTRL_PACKET_READ;
-               } else
-                       prb->ctrl = 0;
-
+                               ctrl = PRB_CTRL_PACKET_READ;
+               }
                break;
 
        default:
@@ -565,6 +630,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
                BUG();
        }
 
+       prb->ctrl = cpu_to_le16(ctrl);
        ata_tf_to_fis(&qc->tf, prb->fis, 0);
 
        if (qc->flags & ATA_QCFLAG_DMAMAP)
@@ -579,6 +645,8 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
        dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
 
        writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+       writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
+
        return 0;
 }
 
@@ -727,6 +795,10 @@ static inline void sil24_host_intr(struct ata_port *ap)
        slot_stat = readl(port + PORT_SLOT_STAT);
        if (!(slot_stat & HOST_SSTAT_ATTN)) {
                struct sil24_port_priv *pp = ap->private_data;
+
+               if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
+                       writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT);
+
                /*
                 * !HOST_SSAT_ATTN guarantees successful completion,
                 * so reading back tf registers is unnecessary for
@@ -769,7 +841,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *
        for (i = 0; i < host_set->n_ports; i++)
                if (status & (1 << i)) {
                        struct ata_port *ap = host_set->ports[i];
-                       if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
+                       if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
                                sil24_host_intr(host_set->ports[i]);
                                handled++;
                        } else
@@ -858,6 +930,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        void __iomem *host_base = NULL;
        void __iomem *port_base = NULL;
        int i, rc;
+       u32 tmp;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -910,35 +983,51 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        /*
         * Configure the device
         */
-       /*
-        * FIXME: This device is certainly 64-bit capable.  We just
-        * don't know how to use it.  After fixing 32bit activation in
-        * this function, enable 64bit masks here.
-        */
-       rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-       if (rc) {
-               dev_printk(KERN_ERR, &pdev->dev,
-                          "32-bit DMA enable failed\n");
-               goto out_free;
-       }
-       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-       if (rc) {
-               dev_printk(KERN_ERR, &pdev->dev,
-                          "32-bit consistent DMA enable failed\n");
-               goto out_free;
+       if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+               rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               if (rc) {
+                       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       if (rc) {
+                               dev_printk(KERN_ERR, &pdev->dev,
+                                          "64-bit DMA enable failed\n");
+                               goto out_free;
+                       }
+               }
+       } else {
+               rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               if (rc) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit DMA enable failed\n");
+                       goto out_free;
+               }
+               rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+               if (rc) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit consistent DMA enable failed\n");
+                       goto out_free;
+               }
        }
 
        /* GPIO off */
        writel(0, host_base + HOST_FLASH_CMD);
 
-       /* Mask interrupts during initialization */
+       /* Apply workaround for completion IRQ loss on PCI-X errata */
+       if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
+               tmp = readl(host_base + HOST_CTRL);
+               if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Applying completion IRQ loss on PCI-X "
+                                  "errata fix\n");
+               else
+                       probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
+       }
+
+       /* clear global reset & mask interrupts during initialization */
        writel(0, host_base + HOST_CTRL);
 
        for (i = 0; i < probe_ent->n_ports; i++) {
                void __iomem *port = port_base + i * PORT_REGS_SIZE;
                unsigned long portu = (unsigned long)port;
-               u32 tmp;
-               int cnt;
 
                probe_ent->port[i].cmd_addr = portu + PORT_PRB;
                probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
@@ -952,18 +1041,20 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                tmp = readl(port + PORT_CTRL_STAT);
                if (tmp & PORT_CS_PORT_RST) {
                        writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
-                       readl(port + PORT_CTRL_STAT);   /* sync */
-                       for (cnt = 0; cnt < 10; cnt++) {
-                               msleep(10);
-                               tmp = readl(port + PORT_CTRL_STAT);
-                               if (!(tmp & PORT_CS_PORT_RST))
-                                       break;
-                       }
+                       tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                                               PORT_CS_PORT_RST,
+                                               PORT_CS_PORT_RST, 10, 100);
                        if (tmp & PORT_CS_PORT_RST)
                                dev_printk(KERN_ERR, &pdev->dev,
                                           "failed to clear port RST\n");
                }
 
+               /* Configure IRQ WoC */
+               if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC)
+                       writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
+               else
+                       writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
                /* Zero error counters. */
                writel(0x8000, port + PORT_DECODE_ERR_THRESH);
                writel(0x8000, port + PORT_CRC_ERR_THRESH);
@@ -972,14 +1063,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                writel(0x0000, port + PORT_CRC_ERR_CNT);
                writel(0x0000, port + PORT_HSHK_ERR_CNT);
 
-               /* FIXME: 32bit activation? */
-               writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
-               writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
+               /* Always use 64bit activation */
+               writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
 
                /* Configure interrupts */
                writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
-               writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
-                      port + PORT_IRQ_ENABLE_SET);
+               writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
+                      PORT_IRQ_SDB_NOTIFY, port + PORT_IRQ_ENABLE_SET);
 
                /* Clear interrupts */
                writel(0x0fff0fff, port + PORT_IRQ_STAT);
@@ -987,11 +1077,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                /* Clear port multiplier enable and resume bits */
                writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
-
-               /* Reset itself */
-               if (__sil24_reset_controller(port))
-                       dev_printk(KERN_ERR, &pdev->dev,
-                                  "failed to reset controller\n");
        }
 
        /* Turn on interrupts */
index 728530d..3097821 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_sis"
-#define DRV_VERSION    "0.5"
+#define DRV_VERSION    "0.6"
 
 enum {
        sis_180                 = 0,
index 53b0d5c..d5eb537 100644 (file)
@@ -54,7 +54,7 @@
 #endif /* CONFIG_PPC_OF */
 
 #define DRV_NAME       "sata_svw"
-#define DRV_VERSION    "1.07"
+#define DRV_VERSION    "1.8"
 
 enum {
        /* Taskfile registers offsets */
@@ -257,7 +257,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
        int len, index;
 
        /* Find  the ata_port */
-       ap = (struct ata_port *) &shost->hostdata[0];
+       ap = ata_shost_to_port(shost);
        if (ap == NULL)
                return 0;
 
index 4139ad4..a669d05 100644 (file)
@@ -46,7 +46,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_sx4"
-#define DRV_VERSION    "0.8"
+#define DRV_VERSION    "0.9"
 
 
 enum {
@@ -833,7 +833,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
                tmp = mask & (1 << i);
                VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp);
                if (tmp && ap &&
-                   !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
+                   !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->active_tag);
@@ -1375,10 +1375,6 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       /*
-        * If this driver happens to only be useful on Apple's K2, then
-        * we should check that here as it has a normal Serverworks ID
-        */
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
index 38b52bd..15f81bf 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_uli"
-#define DRV_VERSION    "0.5"
+#define DRV_VERSION    "0.6"
 
 enum {
        uli_5289                = 0,
index 9e7ae4e..17aefab 100644 (file)
@@ -47,7 +47,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_via"
-#define DRV_VERSION    "1.1"
+#define DRV_VERSION    "1.2"
 
 enum board_ids_enum {
        vt6420,
index 8a29ce3..9646c39 100644 (file)
@@ -222,7 +222,7 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
                        ap = host_set->ports[i];
 
                        if (ap && !(ap->flags &
-                                   (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
+                                   (ATA_FLAG_DISABLED|ATA_FLAG_NOINTR))) {
                                struct ata_queued_cmd *qc;
 
                                qc = ata_qc_from_tag(ap, ap->active_tag);
index b80d2e7..d35b1e3 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/io.h>
 #include <linux/ata.h>
 #include <linux/workqueue.h>
+#include <scsi/scsi_host.h>
 
 /*
  * compile-time options: to be removed as soon as all the drivers are
@@ -44,7 +45,6 @@
 #undef ATA_NDEBUG              /* define to disable quick runtime checks */
 #undef ATA_ENABLE_PATA         /* define to enable PATA support in some
                                 * low-level drivers */
-#undef ATAPI_ENABLE_DMADIR     /* enables ATAPI DMADIR bridge support */
 
 
 /* note: prints function name for you */
@@ -120,9 +120,11 @@ enum {
        ATA_SHT_USE_CLUSTERING  = 1,
 
        /* struct ata_device stuff */
-       ATA_DFLAG_LBA48         = (1 << 0), /* device supports LBA48 */
-       ATA_DFLAG_PIO           = (1 << 1), /* device currently in PIO mode */
-       ATA_DFLAG_LBA           = (1 << 2), /* device supports LBA */
+       ATA_DFLAG_LBA           = (1 << 0), /* device supports LBA */
+       ATA_DFLAG_LBA48         = (1 << 1), /* device supports LBA48 */
+       ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
+
+       ATA_DFLAG_PIO           = (1 << 8), /* device currently in PIO mode */
 
        ATA_DEV_UNKNOWN         = 0,    /* unknown device */
        ATA_DEV_ATA             = 1,    /* ATA device */
@@ -132,33 +134,35 @@ enum {
        ATA_DEV_NONE            = 5,    /* no device */
 
        /* struct ata_port flags */
-       ATA_FLAG_SLAVE_POSS     = (1 << 1), /* host supports slave dev */
+       ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
                                            /* (doesn't imply presence) */
-       ATA_FLAG_PORT_DISABLED  = (1 << 2), /* port is disabled, ignore it */
-       ATA_FLAG_SATA           = (1 << 3),
-       ATA_FLAG_NO_LEGACY      = (1 << 4), /* no legacy mode check */
-       ATA_FLAG_SRST           = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */
-       ATA_FLAG_MMIO           = (1 << 6), /* use MMIO, not PIO */
-       ATA_FLAG_SATA_RESET     = (1 << 7), /* (obsolete) use COMRESET */
-       ATA_FLAG_PIO_DMA        = (1 << 8), /* PIO cmds via DMA */
-       ATA_FLAG_NOINTR         = (1 << 9), /* FIXME: Remove this once
-                                            * proper HSM is in place. */
-       ATA_FLAG_DEBUGMSG       = (1 << 10),
-       ATA_FLAG_NO_ATAPI       = (1 << 11), /* No ATAPI support */
-
-       ATA_FLAG_SUSPENDED      = (1 << 12), /* port is suspended */
-
-       ATA_FLAG_PIO_LBA48      = (1 << 13), /* Host DMA engine is LBA28 only */
-       ATA_FLAG_IRQ_MASK       = (1 << 14), /* Mask IRQ in PIO xfers */
-
-       ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */
-       ATA_FLAG_IN_EH          = (1 << 16), /* EH in progress */
-
-       ATA_QCFLAG_ACTIVE       = (1 << 1), /* cmd not yet ack'd to scsi lyer */
-       ATA_QCFLAG_SG           = (1 << 3), /* have s/g table? */
-       ATA_QCFLAG_SINGLE       = (1 << 4), /* no s/g, just a single buffer */
+       ATA_FLAG_SATA           = (1 << 1),
+       ATA_FLAG_NO_LEGACY      = (1 << 2), /* no legacy mode check */
+       ATA_FLAG_MMIO           = (1 << 3), /* use MMIO, not PIO */
+       ATA_FLAG_SRST           = (1 << 4), /* (obsolete) use ATA SRST, not E.D.D. */
+       ATA_FLAG_SATA_RESET     = (1 << 5), /* (obsolete) use COMRESET */
+       ATA_FLAG_NO_ATAPI       = (1 << 6), /* No ATAPI support */
+       ATA_FLAG_PIO_DMA        = (1 << 7), /* PIO cmds via DMA */
+       ATA_FLAG_PIO_LBA48      = (1 << 8), /* Host DMA engine is LBA28 only */
+       ATA_FLAG_IRQ_MASK       = (1 << 9), /* Mask IRQ in PIO xfers */
+
+       ATA_FLAG_NOINTR         = (1 << 16), /* FIXME: Remove this once
+                                             * proper HSM is in place. */
+       ATA_FLAG_DEBUGMSG       = (1 << 17),
+       ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */
+
+       ATA_FLAG_DISABLED       = (1 << 19), /* port is disabled, ignore it */
+       ATA_FLAG_SUSPENDED      = (1 << 20), /* port is suspended */
+
+       /* bits 24:31 of ap->flags are reserved for LLDD specific flags */
+
+       /* struct ata_queued_cmd flags */
+       ATA_QCFLAG_ACTIVE       = (1 << 0), /* cmd not yet ack'd to scsi lyer */
+       ATA_QCFLAG_SG           = (1 << 1), /* have s/g table? */
+       ATA_QCFLAG_SINGLE       = (1 << 2), /* no s/g, just a single buffer */
        ATA_QCFLAG_DMAMAP       = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
-       ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */
+       ATA_QCFLAG_IO           = (1 << 3), /* standard IO command */
+       ATA_QCFLAG_EH_SCHEDULED = (1 << 4), /* EH scheduled */
 
        /* host set flags */
        ATA_HOST_SIMPLEX        = (1 << 0),     /* Host is simplex, one DMA channel per host_set only */
@@ -207,10 +211,13 @@ enum {
        /* size of buffer to pad xfers ending on unaligned boundaries */
        ATA_DMA_PAD_SZ          = 4,
        ATA_DMA_PAD_BUF_SZ      = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
-       
-       /* Masks for port functions */
+
+       /* masks for port functions */
        ATA_PORT_PRIMARY        = (1 << 0),
        ATA_PORT_SECONDARY      = (1 << 1),
+
+       /* how hard are we gonna try to probe/recover devices */
+       ATA_PROBE_MAX_TRIES     = 3,
 };
 
 enum hsm_task_states {
@@ -245,7 +252,7 @@ struct ata_queued_cmd;
 /* typedefs */
 typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
 typedef void (*ata_probeinit_fn_t)(struct ata_port *);
-typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
+typedef int (*ata_reset_fn_t)(struct ata_port *, unsigned int *);
 typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);
 
 struct ata_ioports {
@@ -397,6 +404,7 @@ struct ata_port {
        unsigned int            mwdma_mask;
        unsigned int            udma_mask;
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
+       unsigned int            sata_spd_limit; /* SATA PHY speed limit */
 
        struct ata_device       device[ATA_MAX_DEVICES];
 
@@ -496,15 +504,14 @@ extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
 extern void ata_bus_reset(struct ata_port *ap);
+extern int ata_set_sata_spd(struct ata_port *ap);
 extern int ata_drive_probe_reset(struct ata_port *ap,
                        ata_probeinit_fn_t probeinit,
                        ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
                        ata_postreset_fn_t postreset, unsigned int *classes);
 extern void ata_std_probeinit(struct ata_port *ap);
-extern int ata_std_softreset(struct ata_port *ap, int verbose,
-                            unsigned int *classes);
-extern int sata_std_hardreset(struct ata_port *ap, int verbose,
-                             unsigned int *class);
+extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
+extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
 extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
 extern int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
                              int post_reset);
@@ -537,6 +544,9 @@ extern unsigned int ata_busy_sleep(struct ata_port *ap,
                                   unsigned long timeout);
 extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
                                void *data, unsigned long delay);
+extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+                            unsigned long interval_msec,
+                            unsigned long timeout_msec);
 
 /*
  * Default driver ops implementations
@@ -573,7 +583,6 @@ extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
-extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
                              struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *));
@@ -628,6 +637,13 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit
 extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
 
+/*
+ * EH
+ */
+extern void ata_eng_timeout(struct ata_port *ap);
+extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
+extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
+
 
 static inline int
 ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
@@ -671,14 +687,34 @@ static inline unsigned int ata_tag_valid(unsigned int tag)
        return (tag < ATA_MAX_QUEUE) ? 1 : 0;
 }
 
-static inline unsigned int ata_class_present(unsigned int class)
+static inline unsigned int ata_class_enabled(unsigned int class)
 {
        return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;
 }
 
-static inline unsigned int ata_dev_present(const struct ata_device *dev)
+static inline unsigned int ata_class_disabled(unsigned int class)
+{
+       return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP;
+}
+
+static inline unsigned int ata_class_absent(unsigned int class)
+{
+       return !ata_class_enabled(class) && !ata_class_disabled(class);
+}
+
+static inline unsigned int ata_dev_enabled(const struct ata_device *dev)
+{
+       return ata_class_enabled(dev->class);
+}
+
+static inline unsigned int ata_dev_disabled(const struct ata_device *dev)
 {
-       return ata_class_present(dev->class);
+       return ata_class_disabled(dev->class);
+}
+
+static inline unsigned int ata_dev_absent(const struct ata_device *dev)
+{
+       return ata_class_absent(dev->class);
 }
 
 static inline u8 ata_chk_status(struct ata_port *ap)
@@ -944,4 +980,9 @@ static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
        dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
 }
 
+static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
+{
+       return (struct ata_port *) &host->hostdata[0];
+}
+
 #endif /* __LINUX_LIBATA_H__ */