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);
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)");
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++;
* @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
* 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;
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);
*
* 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);
}
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;
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;
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;
* 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;
} 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;
/* 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;
}
/**
void ata_port_probe(struct ata_port *ap)
{
- ap->flags &= ~ATA_FLAG_PORT_DISABLED;
+ ap->flags &= ~ATA_FLAG_DISABLED;
}
/**
*/
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);
}
}
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)) {
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);
}
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;
}
{
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;
}
/*
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;
}
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);
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;
}
/**
* 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)
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 {
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);
}
*/
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. */
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;
if (postreset)
postreset(ap, classes);
- return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+ return 0;
}
/**
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;
+
+ 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, 0, classes);
+ }
+ done:
+ if (rc == 0 && classes[0] == ATA_DEV_UNKNOWN)
+ rc = -ENODEV;
return rc;
}
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);
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",
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))
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);
}
/**
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;
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;
/**
* 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)
* 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:
/**
* 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)
* 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;
/*
}
}
- 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);
/**
* 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;
/*
}
}
- 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;
}
}
-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
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;
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.
* 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)) {
/* 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;
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
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:
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);
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);
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);
*/
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);
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;
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;
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);
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);
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);