summaryrefslogtreecommitdiff
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c915
1 files changed, 598 insertions, 317 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 5d38a6cc5736..c859b96b891a 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -61,13 +61,10 @@
#include "libata.h"
-static unsigned int ata_dev_init_params(struct ata_port *ap,
- struct ata_device *dev,
- u16 heads,
- u16 sectors);
-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);
+static unsigned int ata_dev_init_params(struct ata_device *dev,
+ u16 heads, u16 sectors);
+static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
+static void ata_dev_xfermask(struct ata_device *dev);
static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq;
@@ -412,11 +409,10 @@ static const char *sata_spd_string(unsigned int spd)
return spd_str[spd - 1];
}
-void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
+void ata_dev_disable(struct ata_device *dev)
{
if (ata_dev_enabled(dev)) {
- printk(KERN_WARNING "ata%u: dev %u disabled\n",
- ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_WARNING, "disabled\n");
dev->class++;
}
}
@@ -955,13 +951,11 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
{
struct completion *waiting = qc->private_data;
- qc->ap->ops->tf_read(qc->ap, &qc->tf);
complete(waiting);
}
/**
* ata_exec_internal - execute libata internal command
- * @ap: Port to which the command is sent
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
@@ -979,24 +973,57 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* None. Should be called with kernel context, might sleep.
*/
-unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen)
{
+ struct ata_port *ap = dev->ap;
u8 command = tf->command;
struct ata_queued_cmd *qc;
+ unsigned int tag, preempted_tag;
DECLARE_COMPLETION(wait);
unsigned long flags;
unsigned int err_mask;
+ int rc;
spin_lock_irqsave(&ap->host_set->lock, flags);
- qc = ata_qc_new_init(ap, dev);
- BUG_ON(qc == NULL);
+ /* no internal command while frozen */
+ if (ap->flags & ATA_FLAG_FROZEN) {
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ return AC_ERR_SYSTEM;
+ }
+
+ /* initialize internal qc */
+
+ /* XXX: Tag 0 is used for drivers with legacy EH as some
+ * drivers choke if any other tag is given. This breaks
+ * ata_tag_internal() test for those drivers. Don't use new
+ * EH stuff without converting to it.
+ */
+ if (ap->ops->error_handler)
+ tag = ATA_TAG_INTERNAL;
+ else
+ tag = 0;
+
+ if (test_and_set_bit(tag, &ap->qactive))
+ BUG();
+ qc = __ata_qc_from_tag(ap, tag);
+
+ qc->tag = tag;
+ qc->scsicmd = NULL;
+ qc->ap = ap;
+ qc->dev = dev;
+ ata_qc_reinit(qc);
+ preempted_tag = ap->active_tag;
+ ap->active_tag = ATA_TAG_POISON;
+
+ /* prepare & issue qc */
qc->tf = *tf;
if (cdb)
memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+ qc->flags |= ATA_QCFLAG_RESULT_TF;
qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) {
ata_sg_init_one(qc, buf, buflen);
@@ -1010,31 +1037,51 @@ unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
spin_unlock_irqrestore(&ap->host_set->lock, flags);
- if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
- ata_port_flush_task(ap);
+ rc = wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL);
+
+ ata_port_flush_task(ap);
+ if (!rc) {
spin_lock_irqsave(&ap->host_set->lock, flags);
/* We're racing with irq here. If we lose, the
* following test prevents us from completing the qc
- * again. If completion irq occurs after here but
- * before the caller cleans up, it will result in a
- * spurious interrupt. We can live with that.
+ * twice. If we win, the port is frozen and will be
+ * cleaned up by ->post_internal_cmd().
*/
if (qc->flags & ATA_QCFLAG_ACTIVE) {
- qc->err_mask = AC_ERR_TIMEOUT;
- ata_qc_complete(qc);
- printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
- ap->id, command);
+ qc->err_mask |= AC_ERR_TIMEOUT;
+
+ if (ap->ops->error_handler)
+ ata_port_freeze(ap);
+ else
+ ata_qc_complete(qc);
+
+ ata_dev_printk(dev, KERN_WARNING,
+ "qc timeout (cmd 0x%x)\n", command);
}
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
- *tf = qc->tf;
+ /* do post_internal_cmd */
+ if (ap->ops->post_internal_cmd)
+ ap->ops->post_internal_cmd(qc);
+
+ if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) {
+ ata_dev_printk(dev, KERN_WARNING, "zero err_mask for failed "
+ "internal command, assuming AC_ERR_OTHER\n");
+ qc->err_mask |= AC_ERR_OTHER;
+ }
+
+ /* finish up */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+
+ *tf = qc->result_tf;
err_mask = qc->err_mask;
ata_qc_free(qc);
+ ap->active_tag = preempted_tag;
/* XXX - Some LLDDs (sata_mv) disable port on command failure.
* Until those drivers are fixed, we detect the condition
@@ -1052,6 +1099,8 @@ unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
ata_port_probe(ap);
}
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
return err_mask;
}
@@ -1090,11 +1139,10 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
/**
* ata_dev_read_id - Read ID data from the specified device
- * @ap: port on which target device resides
* @dev: target device
* @p_class: pointer to class of the target device (may be changed)
* @post_reset: is this read ID post-reset?
- * @p_id: read IDENTIFY page (newly allocated)
+ * @id: buffer to read IDENTIFY data into
*
* Read ID data from the specified device. ATA_CMD_ID_ATA is
* performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
@@ -1107,13 +1155,13 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
- unsigned int *p_class, int post_reset, u16 **p_id)
+static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
+ int post_reset, u16 *id)
{
+ struct ata_port *ap = dev->ap;
unsigned int class = *p_class;
struct ata_taskfile tf;
unsigned int err_mask = 0;
- u16 *id;
const char *reason;
int rc;
@@ -1121,15 +1169,8 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
- id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
- if (id == NULL) {
- rc = -ENOMEM;
- reason = "out of memory";
- goto err_out;
- }
-
retry:
- ata_tf_init(ap, &tf, dev->devno);
+ ata_tf_init(dev, &tf);
switch (class) {
case ATA_DEV_ATA:
@@ -1146,7 +1187,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, NULL, DMA_FROM_DEVICE,
+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS);
if (err_mask) {
rc = -EIO;
@@ -1173,7 +1214,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
* Some drives were very specific about that exact sequence.
*/
if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
- err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
+ err_mask = ata_dev_init_params(dev, id[3], id[6]);
if (err_mask) {
rc = -EIO;
reason = "INIT_DEV_PARAMS failed";
@@ -1189,25 +1230,22 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
}
*p_class = class;
- *p_id = id;
+
return 0;
err_out:
- printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
- ap->id, dev->devno, reason);
- kfree(id);
+ ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY "
+ "(%s, err_mask=0x%x)\n", reason, err_mask);
return rc;
}
-static inline u8 ata_dev_knobble(const struct ata_port *ap,
- struct ata_device *dev)
+static inline u8 ata_dev_knobble(struct ata_device *dev)
{
- return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
+ return ((dev->ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
}
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
- * @ap: Port on which target device resides
* @dev: Target device to configure
* @print_info: Enable device info printout
*
@@ -1220,9 +1258,9 @@ static inline u8 ata_dev_knobble(const struct ata_port *ap,
* RETURNS:
* 0 on success, -errno otherwise
*/
-static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
- int print_info)
+static int ata_dev_configure(struct ata_device *dev, int print_info)
{
+ struct ata_port *ap = dev->ap;
const u16 *id = dev->id;
unsigned int xfer_mask;
int i, rc;
@@ -1237,10 +1275,10 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
/* print device capabilities */
if (print_info)
- printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x "
- "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
- ap->id, dev->devno, id[49], id[82], id[83],
- id[84], id[85], id[86], id[87], id[88]);
+ ata_dev_printk(dev, KERN_DEBUG, "cfg 49:%04x 82:%04x 83:%04x "
+ "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
+ id[49], id[82], id[83], id[84],
+ id[85], id[86], id[87], id[88]);
/* initialize to-be-configured parameters */
dev->flags &= ~ATA_DFLAG_CFG_MASK;
@@ -1276,13 +1314,12 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
/* print device info to dmesg */
if (print_info)
- printk(KERN_INFO "ata%u: dev %u ATA-%d, "
- "max %s, %Lu sectors: %s\n",
- ap->id, dev->devno,
- ata_id_major_version(id),
- ata_mode_string(xfer_mask),
- (unsigned long long)dev->n_sectors,
- lba_desc);
+ ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+ "max %s, %Lu sectors: %s\n",
+ ata_id_major_version(id),
+ ata_mode_string(xfer_mask),
+ (unsigned long long)dev->n_sectors,
+ lba_desc);
} else {
/* CHS */
@@ -1300,13 +1337,12 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
/* print device info to dmesg */
if (print_info)
- printk(KERN_INFO "ata%u: dev %u ATA-%d, "
- "max %s, %Lu sectors: CHS %u/%u/%u\n",
- ap->id, dev->devno,
- ata_id_major_version(id),
- ata_mode_string(xfer_mask),
- (unsigned long long)dev->n_sectors,
- dev->cylinders, dev->heads, dev->sectors);
+ ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+ "max %s, %Lu sectors: CHS %u/%u/%u\n",
+ ata_id_major_version(id),
+ ata_mode_string(xfer_mask),
+ (unsigned long long)dev->n_sectors,
+ dev->cylinders, dev->heads, dev->sectors);
}
if (dev->id[59] & 0x100) {
@@ -1324,7 +1360,8 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
rc = atapi_cdb_len(id);
if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
- printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
+ ata_dev_printk(dev, KERN_WARNING,
+ "unsupported CDB len\n");
rc = -EINVAL;
goto err_out_nosup;
}
@@ -1337,9 +1374,9 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
/* print device info to dmesg */
if (print_info)
- printk(KERN_INFO "ata%u: dev %u ATAPI, max %s%s\n",
- ap->id, dev->devno, ata_mode_string(xfer_mask),
- cdb_intr_string);
+ ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
+ ata_mode_string(xfer_mask),
+ cdb_intr_string);
}
ap->host->max_cmd_len = 0;
@@ -1349,10 +1386,10 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
ap->device[i].cdb_len);
/* limit bridge transfers to udma5, 200 sectors */
- if (ata_dev_knobble(ap, dev)) {
+ if (ata_dev_knobble(dev)) {
if (print_info)
- printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
- ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_INFO,
+ "applying bridge limits\n");
dev->udma_mask &= ATA_UDMA5;
dev->max_sectors = ATA_MAX_SECTORS;
}
@@ -1405,15 +1442,18 @@ static int ata_bus_probe(struct ata_port *ap)
if (ap->ops->probe_reset) {
rc = ap->ops->probe_reset(ap, classes);
if (rc) {
- printk("ata%u: reset failed (errno=%d)\n", ap->id, rc);
+ ata_port_printk(ap, KERN_ERR,
+ "reset failed (errno=%d)\n", rc);
return rc;
}
} else {
ap->ops->phy_reset(ap);
- if (!(ap->flags & ATA_FLAG_DISABLED))
- for (i = 0; i < ATA_MAX_DEVICES; i++)
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ if (!(ap->flags & ATA_FLAG_DISABLED))
classes[i] = ap->device[i].class;
+ ap->device[i].class = ATA_DEV_UNKNOWN;
+ }
ata_port_probe(ap);
}
@@ -1432,32 +1472,17 @@ static int ata_bus_probe(struct ata_port *ap)
if (!ata_dev_enabled(dev))
continue;
- kfree(dev->id);
- dev->id = NULL;
- rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
+ rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
if (rc)
goto fail;
- rc = ata_dev_configure(ap, dev, 1);
+ rc = ata_dev_configure(dev, 1);
if (rc)
goto fail;
}
/* 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);
-
+ rc = ata_set_mode(ap, &dev);
if (rc) {
down_xfermask = 1;
goto fail;
@@ -1479,18 +1504,18 @@ static int ata_bus_probe(struct ata_port *ap)
tries[dev->devno] = 0;
break;
case -EIO:
- ata_down_sata_spd_limit(ap);
+ sata_down_spd_limit(ap);
/* fall through */
default:
tries[dev->devno]--;
if (down_xfermask &&
- ata_down_xfermask_limit(ap, dev, tries[dev->devno] == 1))
+ ata_down_xfermask_limit(dev, tries[dev->devno] == 1))
tries[dev->devno] = 0;
}
if (!tries[dev->devno]) {
- ata_down_xfermask_limit(ap, dev, 1);
- ata_dev_disable(ap, dev);
+ ata_down_xfermask_limit(dev, 1);
+ ata_dev_disable(dev);
}
goto retry;
@@ -1525,21 +1550,19 @@ static void sata_print_link_status(struct ata_port *ap)
{
u32 sstatus, scontrol, tmp;
- if (!ap->ops->scr_read)
+ if (sata_scr_read(ap, SCR_STATUS, &sstatus))
return;
+ sata_scr_read(ap, SCR_CONTROL, &scontrol);
- sstatus = scr_read(ap, SCR_STATUS);
- scontrol = scr_read(ap, SCR_CONTROL);
-
- if (sata_dev_present(ap)) {
+ if (ata_port_online(ap)) {
tmp = (sstatus >> 4) & 0xf;
- printk(KERN_INFO
- "ata%u: SATA link up %s (SStatus %X SControl %X)\n",
- ap->id, sata_spd_string(tmp), sstatus, scontrol);
+ ata_port_printk(ap, KERN_INFO,
+ "SATA link up %s (SStatus %X SControl %X)\n",
+ sata_spd_string(tmp), sstatus, scontrol);
} else {
- printk(KERN_INFO
- "ata%u: SATA link down (SStatus %X SControl %X)\n",
- ap->id, sstatus, scontrol);
+ ata_port_printk(ap, KERN_INFO,
+ "SATA link down (SStatus %X SControl %X)\n",
+ sstatus, scontrol);
}
}
@@ -1562,17 +1585,18 @@ void __sata_phy_reset(struct ata_port *ap)
if (ap->flags & ATA_FLAG_SATA_RESET) {
/* issue phy wake/reset */
- scr_write_flush(ap, SCR_CONTROL, 0x301);
+ sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
/* Couldn't find anything in SATA I/II specs, but
* AHCI-1.1 10.4.2 says at least 1 ms. */
mdelay(1);
}
- scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
+ /* phy wake/clear reset */
+ sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
/* wait for phy to become ready, if necessary */
do {
msleep(200);
- sstatus = scr_read(ap, SCR_STATUS);
+ sata_scr_read(ap, SCR_STATUS, &sstatus);
if ((sstatus & 0xf) != 1)
break;
} while (time_before(jiffies, timeout));
@@ -1581,7 +1605,7 @@ void __sata_phy_reset(struct ata_port *ap)
sata_print_link_status(ap);
/* TODO: phy layer with polling, timeouts, etc. */
- if (sata_dev_present(ap))
+ if (!ata_port_offline(ap))
ata_port_probe(ap);
else
ata_port_disable(ap);
@@ -1618,15 +1642,15 @@ void sata_phy_reset(struct ata_port *ap)
/**
* ata_dev_pair - return other device on cable
- * @ap: port
* @adev: device
*
* Obtain the other device on the same cable, or if none is
* present NULL is returned
*/
-struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev)
+struct ata_device *ata_dev_pair(struct ata_device *adev)
{
+ struct ata_port *ap = adev->ap;
struct ata_device *pair = &ap->device[1 - adev->devno];
if (!ata_dev_enabled(pair))
return NULL;
@@ -1654,12 +1678,12 @@ void ata_port_disable(struct ata_port *ap)
}
/**
- * ata_down_sata_spd_limit - adjust SATA spd limit downward
+ * sata_down_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().
+ * using sata_set_spd().
*
* LOCKING:
* Inherited from caller.
@@ -1667,13 +1691,14 @@ void ata_port_disable(struct ata_port *ap)
* RETURNS:
* 0 on success, negative errno on failure
*/
-int ata_down_sata_spd_limit(struct ata_port *ap)
+int sata_down_spd_limit(struct ata_port *ap)
{
- u32 spd, mask;
- int highbit;
+ u32 sstatus, spd, mask;
+ int rc, highbit;
- if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
- return -EOPNOTSUPP;
+ rc = sata_scr_read(ap, SCR_STATUS, &sstatus);
+ if (rc)
+ return rc;
mask = ap->sata_spd_limit;
if (mask <= 1)
@@ -1681,7 +1706,7 @@ int ata_down_sata_spd_limit(struct ata_port *ap)
highbit = fls(mask) - 1;
mask &= ~(1 << highbit);
- spd = (scr_read(ap, SCR_STATUS) >> 4) & 0xf;
+ spd = (sstatus >> 4) & 0xf;
if (spd <= 1)
return -EINVAL;
spd--;
@@ -1691,13 +1716,13 @@ int ata_down_sata_spd_limit(struct ata_port *ap)
ap->sata_spd_limit = mask;
- printk(KERN_WARNING "ata%u: limiting SATA link speed to %s\n",
- ap->id, sata_spd_string(fls(mask)));
+ ata_port_printk(ap, KERN_WARNING, "limiting SATA link speed to %s\n",
+ sata_spd_string(fls(mask)));
return 0;
}
-static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
+static int __sata_set_spd_needed(struct ata_port *ap, u32 *scontrol)
{
u32 spd, limit;
@@ -1713,7 +1738,7 @@ static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
}
/**
- * ata_set_sata_spd_needed - is SATA spd configuration needed
+ * sata_set_spd_needed - is SATA spd configuration needed
* @ap: Port in question
*
* Test whether the spd limit in SControl matches
@@ -1727,20 +1752,18 @@ static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
* RETURNS:
* 1 if SATA spd configuration is needed, 0 otherwise.
*/
-int ata_set_sata_spd_needed(struct ata_port *ap)
+int sata_set_spd_needed(struct ata_port *ap)
{
u32 scontrol;
- if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
+ if (sata_scr_read(ap, SCR_CONTROL, &scontrol))
return 0;
- scontrol = scr_read(ap, SCR_CONTROL);
-
- return __ata_set_sata_spd_needed(ap, &scontrol);
+ return __sata_set_spd_needed(ap, &scontrol);
}
/**
- * ata_set_sata_spd - set SATA spd according to spd limit
+ * sata_set_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.
@@ -1750,20 +1773,22 @@ int ata_set_sata_spd_needed(struct ata_port *ap)
*
* RETURNS:
* 0 if spd doesn't need to be changed, 1 if spd has been
- * changed. -EOPNOTSUPP if SCR registers are inaccessible.
+ * changed. Negative errno if SCR registers are inaccessible.
*/
-int ata_set_sata_spd(struct ata_port *ap)
+int sata_set_spd(struct ata_port *ap)
{
u32 scontrol;
+ int rc;
- if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
- return -EOPNOTSUPP;
+ if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+ return rc;
- scontrol = scr_read(ap, SCR_CONTROL);
- if (!__ata_set_sata_spd_needed(ap, &scontrol))
+ if (!__sata_set_spd_needed(ap, &scontrol))
return 0;
- scr_write(ap, SCR_CONTROL, scontrol);
+ if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+ return rc;
+
return 1;
}
@@ -1917,7 +1942,6 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
/**
* 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
*
@@ -1931,8 +1955,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
* RETURNS:
* 0 on success, negative errno on failure
*/
-int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
- int force_pio0)
+int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
{
unsigned long xfer_mask;
int highbit;
@@ -1956,8 +1979,8 @@ int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
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));
+ ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n",
+ ata_mode_string(xfer_mask));
return 0;
@@ -1965,7 +1988,7 @@ int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
return -EINVAL;
}
-static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
+static int ata_dev_set_mode(struct ata_device *dev)
{
unsigned int err_mask;
int rc;
@@ -1974,24 +1997,22 @@ static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
if (dev->xfer_shift == ATA_SHIFT_PIO)
dev->flags |= ATA_DFLAG_PIO;
- err_mask = ata_dev_set_xfermode(ap, dev);
+ err_mask = ata_dev_set_xfermode(dev);
if (err_mask) {
- printk(KERN_ERR
- "ata%u: failed to set xfermode (err_mask=0x%x)\n",
- ap->id, err_mask);
+ ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
+ "(err_mask=0x%x)\n", err_mask);
return -EIO;
}
- rc = ata_dev_revalidate(ap, dev, 0);
+ rc = ata_dev_revalidate(dev, 0);
if (rc)
return rc;
DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
dev->xfer_shift, (int)dev->xfer_mode);
- printk(KERN_INFO "ata%u: dev %u configured for %s\n",
- ap->id, dev->devno,
- ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
+ ata_dev_printk(dev, KERN_INFO, "configured for %s\n",
+ ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
return 0;
}
@@ -2015,6 +2036,20 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
struct ata_device *dev;
int i, rc = 0, used_dma = 0, found = 0;
+ /* has private set_mode? */
+ if (ap->ops->set_mode) {
+ /* FIXME: make ->set_mode handle no device case and
+ * return error code and failing device on failure.
+ */
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ if (ata_dev_enabled(&ap->device[i])) {
+ ap->ops->set_mode(ap);
+ break;
+ }
+ }
+ return 0;
+ }
+
/* step 1: calculate xfer_mask */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
unsigned int pio_mask, dma_mask;
@@ -2024,7 +2059,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
if (!ata_dev_enabled(dev))
continue;
- ata_dev_xfermask(ap, dev);
+ ata_dev_xfermask(dev);
pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
@@ -2045,8 +2080,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
continue;
if (!dev->pio_mode) {
- printk(KERN_WARNING "ata%u: dev %u no PIO support\n",
- ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_WARNING, "no PIO support\n");
rc = -EINVAL;
goto out;
}
@@ -2077,7 +2111,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
if (!ata_dev_enabled(dev))
continue;
- rc = ata_dev_set_mode(ap, dev);
+ rc = ata_dev_set_mode(dev);
if (rc)
goto out;
}
@@ -2145,8 +2179,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
}
if (status & ATA_BUSY)
- printk(KERN_WARNING "ata%u is slow to respond, "
- "please be patient\n", ap->id);
+ ata_port_printk(ap, KERN_WARNING,
+ "port is slow to respond, please be patient\n");
timeout = timer_start + tmout;
while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
@@ -2155,8 +2189,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
}
if (status & ATA_BUSY) {
- printk(KERN_ERR "ata%u failed to respond (%lu secs)\n",
- ap->id, tmout / HZ);
+ ata_port_printk(ap, KERN_ERR, "port failed to respond "
+ "(%lu secs)\n", tmout / HZ);
return 1;
}
@@ -2249,7 +2283,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
* pulldown resistor.
*/
if (ata_check_status(ap) == 0xFF) {
- printk(KERN_ERR "ata%u: SRST failed (status 0xFF)\n", ap->id);
+ ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
return AC_ERR_OTHER;
}
@@ -2343,7 +2377,7 @@ void ata_bus_reset(struct ata_port *ap)
return;
err_out:
- printk(KERN_ERR "ata%u: disabling port\n", ap->id);
+ ata_port_printk(ap, KERN_ERR, "disabling port\n");
ap->ops->port_disable(ap);
DPRINTK("EXIT\n");
@@ -2353,20 +2387,26 @@ static int sata_phy_resume(struct ata_port *ap)
{
unsigned long timeout = jiffies + (HZ * 5);
u32 scontrol, sstatus;
+ int rc;
+
+ if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+ return rc;
- scontrol = scr_read(ap, SCR_CONTROL);
scontrol = (scontrol & 0x0f0) | 0x300;
- scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+ if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+ return rc;
/* Wait for phy to become ready, if necessary. */
do {
msleep(200);
- sstatus = scr_read(ap, SCR_STATUS);
+ if ((rc = sata_scr_read(ap, SCR_STATUS, &sstatus)))
+ return rc;
if ((sstatus & 0xf) != 1)
return 0;
} while (time_before(jiffies, timeout));
- return -1;
+ return -EBUSY;
}
/**
@@ -2384,22 +2424,20 @@ static int sata_phy_resume(struct ata_port *ap)
*/
void ata_std_probeinit(struct ata_port *ap)
{
- if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
- u32 spd;
-
- /* set cable type and resume link */
- ap->cbl = ATA_CBL_SATA;
- sata_phy_resume(ap);
+ u32 scontrol;
- /* init sata_spd_limit to the current value */
- spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
- if (spd)
- ap->sata_spd_limit &= (1 << spd) - 1;
+ /* resume link */
+ sata_phy_resume(ap);
- /* wait for device */
- if (sata_dev_present(ap))
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ /* init sata_spd_limit to the current value */
+ if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
+ int spd = (scontrol >> 4) & 0xf;
+ ap->sata_spd_limit &= (1 << spd) - 1;
}
+
+ /* wait for device */
+ if (ata_port_online(ap))
+ ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
}
/**
@@ -2424,7 +2462,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
DPRINTK("ENTER\n");
- if (ap->ops->scr_read && !sata_dev_present(ap)) {
+ if (ata_port_offline(ap)) {
classes[0] = ATA_DEV_NONE;
goto out;
}
@@ -2442,8 +2480,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
DPRINTK("about to softreset, devmask=%x\n", devmask);
err_mask = ata_bus_softreset(ap, devmask);
if (err_mask) {
- printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
- ap->id, err_mask);
+ ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
+ err_mask);
return -EIO;
}
@@ -2475,26 +2513,35 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
{
u32 scontrol;
+ int rc;
DPRINTK("ENTER\n");
- if (ata_set_sata_spd_needed(ap)) {
+ if (sata_set_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);
+ if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+ return rc;
+
scontrol = (scontrol & 0x0f0) | 0x302;
- scr_write_flush(ap, SCR_CONTROL, scontrol);
- ata_set_sata_spd(ap);
+ if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+ return rc;
+
+ sata_set_spd(ap);
}
/* issue phy wake/reset */
- scontrol = scr_read(ap, SCR_CONTROL);
+ if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+ return rc;
+
scontrol = (scontrol & 0x0f0) | 0x301;
- scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+ if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
+ return rc;
/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
* 10.4.2 says at least 1 ms.
@@ -2505,15 +2552,15 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
sata_phy_resume(ap);
/* TODO: phy layer with polling, timeouts, etc. */
- if (!sata_dev_present(ap)) {
+ if (ata_port_offline(ap)) {
*class = ATA_DEV_NONE;
DPRINTK("EXIT, link offline\n");
return 0;
}
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
- printk(KERN_ERR
- "ata%u: COMRESET failed (device not ready)\n", ap->id);
+ ata_port_printk(ap, KERN_ERR,
+ "COMRESET failed (device not ready)\n");
return -EIO;
}
@@ -2542,15 +2589,23 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
*/
void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
{
+ u32 serror;
+
DPRINTK("ENTER\n");
/* print link status */
- if (ap->cbl == ATA_CBL_SATA)
- sata_print_link_status(ap);
+ sata_print_link_status(ap);
+
+ /* clear SError */
+ if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
+ sata_scr_write(ap, SCR_ERROR, serror);
/* re-enable interrupts */
- if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
- ata_irq_on(ap);
+ if (!ap->ops->error_handler) {
+ /* FIXME: hack. create a hook instead */
+ if (ap->ioaddr.ctl_addr)
+ ata_irq_on(ap);
+ }
/* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE)
@@ -2593,7 +2648,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
ata_reset_fn_t hardreset;
hardreset = NULL;
- if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
+ if (sata_scr_valid(ap))
hardreset = sata_std_hardreset;
return ata_drive_probe_reset(ap, ata_std_probeinit,
@@ -2602,7 +2657,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
}
int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
- ata_postreset_fn_t postreset, unsigned int *classes)
+ unsigned int *classes)
{
int i, rc;
@@ -2626,9 +2681,6 @@ int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
if (classes[i] == ATA_DEV_UNKNOWN)
classes[i] = ATA_DEV_NONE;
- if (postreset)
- postreset(ap, classes);
-
return 0;
}
@@ -2668,15 +2720,17 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
{
int rc = -EINVAL;
+ ata_eh_freeze_port(ap);
+
if (probeinit)
probeinit(ap);
- if (softreset && !ata_set_sata_spd_needed(ap)) {
- rc = ata_do_reset(ap, softreset, postreset, classes);
+ if (softreset && !sata_set_spd_needed(ap)) {
+ rc = ata_do_reset(ap, softreset, 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);
+ ata_port_printk(ap, KERN_INFO, "softreset failed, "
+ "will try hardreset in 5 secs\n");
ssleep(5);
}
@@ -2684,39 +2738,45 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
goto done;
while (1) {
- rc = ata_do_reset(ap, hardreset, postreset, classes);
+ rc = ata_do_reset(ap, hardreset, classes);
if (rc == 0) {
if (classes[0] != ATA_DEV_UNKNOWN)
goto done;
break;
}
- if (ata_down_sata_spd_limit(ap))
+ if (sata_down_spd_limit(ap))
goto done;
- printk(KERN_INFO "ata%u: hardreset failed, will retry "
- "in 5 secs\n", ap->id);
+ ata_port_printk(ap, KERN_INFO, "hardreset failed, "
+ "will retry in 5 secs\n");
ssleep(5);
}
if (softreset) {
- printk(KERN_INFO "ata%u: hardreset succeeded without "
- "classification, will retry softreset in 5 secs\n",
- ap->id);
+ ata_port_printk(ap, KERN_INFO,
+ "hardreset succeeded without classification, "
+ "will retry softreset in 5 secs\n");
ssleep(5);
- rc = ata_do_reset(ap, softreset, postreset, classes);
+ rc = ata_do_reset(ap, softreset, classes);
}
done:
- if (rc == 0 && classes[0] == ATA_DEV_UNKNOWN)
- rc = -ENODEV;
+ if (rc == 0) {
+ if (postreset)
+ postreset(ap, classes);
+<