summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-31 18:28:11 +0900
committerTejun Heo <htejun@gmail.com>2006-05-31 18:28:11 +0900
commit3e706399b03bd237d087d731d4b1b029e546b33d (patch)
tree51a5de83f8493d1b78cc16b0fa0abcac2b37cebc /drivers/scsi/libata-core.c
parentccf68c3405fca11386004674377d951b9b18e756 (diff)
downloadlinux-3e706399b03bd237d087d731d4b1b029e546b33d.tar.bz2
[PATCH] libata-hp: implement bootplug
Implement bootplug - boot probing via hotplug path. While loading, ata_host_add() simply schedules probing and invokes EH. After EH completes, ata_host_add() scans and assicates them with SCSI devices. EH path is slightly modified to handle this (e.g. no autopsy during bootplug). The SCSI part is left in ata_host_add() because it's shared with legacy path and to keep probing order as before (ATA scan all ports in host_set then attach all). Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index c61cfc742388..a42877e6b865 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5419,7 +5419,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
DPRINTK("ENTER\n");
- if (!ent->port_ops->probe_reset &&
+ if (!ent->port_ops->probe_reset && !ent->port_ops->error_handler &&
!(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
printk(KERN_ERR "ata%u: no reset mechanism available\n",
port_no);
@@ -5465,7 +5465,6 @@ err_out:
* RETURNS:
* Number of ports registered. Zero on error (no ports registered).
*/
-
int ata_device_add(const struct ata_probe_ent *ent)
{
unsigned int count = 0, i;
@@ -5542,19 +5541,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
}
ap->sata_spd_limit = ap->hw_sata_spd_limit;
- DPRINTK("ata%u: bus probe begin\n", ap->id);
- rc = ata_bus_probe(ap);
- DPRINTK("ata%u: bus probe end\n", ap->id);
-
- if (rc) {
- /* FIXME: do something useful here?
- * Current libata behavior will
- * tear down everything when
- * the module is removed
- * or the h/w is unplugged.
- */
- }
-
rc = scsi_add_host(ap->host, dev);
if (rc) {
ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
@@ -5564,6 +5550,39 @@ int ata_device_add(const struct ata_probe_ent *ent)
* at the very least
*/
}
+
+ if (!ap->ops->probe_reset) {
+ unsigned long flags;
+
+ ata_port_probe(ap);
+
+ /* kick EH for boot probing */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+
+ ap->eh_info.probe_mask = (1 << ATA_MAX_DEVICES) - 1;
+ ap->eh_info.action |= ATA_EH_SOFTRESET;
+
+ ap->flags |= ATA_FLAG_LOADING;
+ ata_port_schedule_eh(ap);
+
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ /* wait for EH to finish */
+ ata_port_wait_eh(ap);
+ } else {
+ DPRINTK("ata%u: bus probe begin\n", ap->id);
+ rc = ata_bus_probe(ap);
+ DPRINTK("ata%u: bus probe end\n", ap->id);
+
+ if (rc) {
+ /* FIXME: do something useful here?
+ * Current libata behavior will
+ * tear down everything when
+ * the module is removed
+ * or the h/w is unplugged.
+ */
+ }
+ }
}
/* probes are done, now scan each port's disk(s) */