aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/ahci.c2
-rw-r--r--drivers/scsi/ata_piix.c2
-rw-r--r--drivers/scsi/libata-core.c795
-rw-r--r--drivers/scsi/libata-eh.c264
-rw-r--r--drivers/scsi/libata-scsi.c176
-rw-r--r--drivers/scsi/libata.h19
-rw-r--r--drivers/scsi/pdc_adma.c6
-rw-r--r--drivers/scsi/sata_mv.c4
-rw-r--r--drivers/scsi/sata_nv.c4
-rw-r--r--drivers/scsi/sata_promise.c6
-rw-r--r--drivers/scsi/sata_qstor.c6
-rw-r--r--drivers/scsi/sata_sil.c8
-rw-r--r--drivers/scsi/sata_sil24.c4
-rw-r--r--drivers/scsi/sata_sis.c2
-rw-r--r--drivers/scsi/sata_svw.c2
-rw-r--r--drivers/scsi/sata_sx4.c8
-rw-r--r--drivers/scsi/sata_uli.c2
-rw-r--r--drivers/scsi/sata_via.c2
-rw-r--r--drivers/scsi/sata_vsc.c2
-rw-r--r--include/linux/libata.h106
21 files changed, 866 insertions, 556 deletions
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index e513c3158ad..503f189dab3 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -165,7 +165,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
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 1bd82c4e52a..0c5f0c844d2 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -48,7 +48,7 @@
#include <asm/io.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "1.2"
+#define DRV_VERSION "1.3"
enum {
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 24e71b55517..83839706f5e 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -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 */
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index e63c1ff1e10..966be3034bf 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -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);
@@ -397,9 +396,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)
{
- if (ata_dev_present(dev)) {
+ 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_enabled(dev)) {
printk(KERN_WARNING "ata%u: dev %u disabled\n",
ap->id, dev->devno);
dev->class++;
@@ -949,6 +960,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 +975,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 +991,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 +1043,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 +1142,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 +1223,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 +1239,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 +1362,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 +1393,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 +1406,74 @@ 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 (!ata_dev_present(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;
+ if (!tries[i]) {
+ ata_down_xfermask_limit(ap, dev, 1);
+ ata_dev_disable(ap, dev);
}
- if (ata_dev_configure(ap, dev, 1)) {
- ata_dev_disable(ap, dev);
+ if (!ata_dev_enabled(dev))
continue;
- }
- found = 1;
+ kfree(dev->id);
+ dev->id = NULL;
+ rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
+ if (rc)
+ goto fail;
+
+ rc = ata_dev_configure(ap, dev, 1);
+ if (rc)
+ goto fail;
}
- if (!found)
- goto err_out_disable;
+ /* 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 (ap->ops->set_mode)
- ap->ops->set_mode(ap);
- else
- ata_set_mode(ap);
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ if (ata_dev_enabled(&ap->device[i]))
+ return 0;
- if (ap->flags & ATA_FLAG_PORT_DISABLED)
- goto err_out_disable;
+ /* no device present, disable port */
+ ata_port_disable(ap);
+ ap->ops->port_disable(ap);
+ return -ENODEV;
- return 0;
+ 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;
+ }
-err_out_disable:
- ap->ops->port_disable(ap);
- return -1;
+ goto retry;
}
/**
@@ -1437,7 +1489,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 +1503,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 +1566,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 +1591,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 +1608,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 +1630,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.
+ */
+static 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 +1895,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 +1963,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 +1975,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;
}
/**
@@ -2055,7 +2253,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 +2330,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 +2363,14 @@ 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;
+
sata_phy_resume(ap);
+
+ spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
+ if (spd)
+ ap->sata_spd_limit &= (1 << spd) - 1;
+
if (sata_dev_present(ap))
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
}
@@ -2247,18 +2454,34 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
*/
int sata_std_hardreset(struct ata_port *ap, int verbose, 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);
- /*
- * Couldn't find anything in SATA I/II specs, but AHCI-1.1
+ ata_set_sata_spd(ap);
+ }
+
+ /* 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. */
@@ -2365,16 +2588,16 @@ 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,
+ int verbose, 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, verbose, classes);
if (rc)
return rc;
@@ -2394,7 +2617,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;
}
/**
@@ -2438,22 +2661,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, 0, 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, 0, classes);
+ if (rc == 0) {
+ if (classes[0] != ATA_DEV_UNKNOWN)
+ goto done;
+ break;
+ }
+
+ if (ata_down_sata_spd_limit(ap))
+ goto done;
- if (softreset)
- rc = do_probe_reset(ap, softreset, postreset, classes);
+ 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);
+
+ rc = ata_do_reset(ap, softreset, postreset, 0, classes);
+ }
+ done:
+ if (rc == 0 && classes[0] == ATA_DEV_UNKNOWN)
+ rc = -ENODEV;
return rc;
}
@@ -2537,15 +2784,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 +2808,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 +2912,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;
- xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask,
- d->udma_mask);
+
+ 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_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 +2950,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 +2989,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 +3029,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 +3417,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 +3425,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 +3465,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 +3473,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 +3496,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 +3831,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 +3860,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 +3888,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 +3908,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 +3922,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 +3959,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 +4004,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;
@@ -3772,99 +4014,6 @@ err_out:
}
/**
- * 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
* @dev: Device from whom we request an available command structure
@@ -4068,26 +4217,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 +4358,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 +4390,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 +4436,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 +4459,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 +4579,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 +4594,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;
@@ -4898,7 +5050,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);
@@ -4938,15 +5089,12 @@ EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
-EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
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);
@@ -4968,3 +5116,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
index 00000000000..e73f5612aea
--- /dev/null
+++ b/drivers/scsi/libata-eh.c
@@ -0,0 +1,264 @@
+/*
+ * 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 = (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)
+ *
+ * RETURNS:
+ * Zero.
+ */
+int ata_scsi_error(struct Scsi_Host *host)
+{
+ struct ata_port *ap = (struct ata_port *)&host->hostdata[0];
+
+ 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");
+ return 0;
+}
+
+/**
+ * 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);
+}
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 53f5b0d9161..745fc263fee 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -53,7 +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);
-enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
#define RW_RECOVERY_MPAGE 0x1
#define RW_RECOVERY_MPAGE_LEN 12
@@ -546,16 +545,11 @@ 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;
@@ -621,16 +615,11 @@ 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;
@@ -724,141 +713,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
}
/**
- * 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)
- *
- * RETURNS:
- * Zero.
- */
-
-int 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");
- return 0;
-}
-
-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
* @scsicmd: SCSI command to translate
@@ -1197,6 +1051,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 ||
@@ -1343,11 +1198,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
@@ -2139,13 +1997,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);
@@ -2213,17 +2073,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)) {
@@ -2349,7 +2207,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)) {
@@ -2737,13 +2595,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);
}
}
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 1c755b14521..e3bd1ddb538 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -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;
@@ -45,7 +45,20 @@ 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,
+ int verbose, 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);
@@ -60,7 +73,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct scsi_transport_template ata_scsi_transport_template;
extern void ata_scsi_scan_host(struct ata_port *ap);
-extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
@@ -90,4 +102,7 @@ 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);
+
#endif /* __LIBATA_H__ */
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 3c85c4b66e1..1364b1da9e2 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -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))
@@ -456,7 +456,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)
@@ -481,7 +481,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)
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index fa901fd6508..e9152f85000 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1397,7 +1397,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);
@@ -1991,7 +1991,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);
}
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index f77bf183dfa..c92fbd0989b 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -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,
@@ -280,7 +280,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);
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index cc928c68a47..000844a4129 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -534,7 +534,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);
@@ -677,10 +677,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;
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 9ffe1ef0d20..0b5446ada5c 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -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,
@@ -396,7 +396,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)
@@ -429,7 +429,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)
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 18c296c5689..f29c3e733a0 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_sil"
-#define DRV_VERSION "0.9"
+#define DRV_VERSION "1.0"
enum {
/*
@@ -264,7 +264,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 */
@@ -391,10 +391,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;
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 068c98a4111..646756abb10 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -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
@@ -770,7 +770,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
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index acc8439dea2..eb3cf5b534d 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -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,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 724f0ed6a52..a20bc815475 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -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 */
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index ae70f60c7c0..801ac3787d5 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -46,7 +46,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
-#define DRV_VERSION "0.8"
+#define DRV_VERSION "0.9"
enum {
@@ -834,7 +834,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);
@@ -1376,10 +1376,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;
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 7ac5a5f5a90..513dd78ea6f 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -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,
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 791bf652ba6..de4e0eb224b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -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,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 836bbbb26ff..cecc1f76256 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -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);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 0d61357604d..75bdee09c30 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -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 {
@@ -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];
@@ -523,9 +531,6 @@ extern void ata_host_set_remove(struct ata_host_set *host_set);
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
-extern int ata_scsi_error(struct Scsi_Host *host);
-extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
-extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
extern int ata_scsi_release(struct Scsi_Host *host);
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
extern int ata_scsi_device_resume(struct scsi_device *);
@@ -574,7 +579,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 *));
@@ -629,6 +633,14 @@ 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 int ata_scsi_error(struct Scsi_Host *host);
+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)
@@ -672,14 +684,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_disabled(dev->class);
+}
+
+static inline unsigned int ata_dev_absent(const struct ata_device *dev)
{
- return ata_class_present(dev->class);
+ return ata_class_absent(dev->class);
}
static inline u8 ata_chk_status(struct ata_port *ap)