aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-31 05:28:11 -0400
committerTejun Heo <htejun@gmail.com>2006-05-31 05:28:11 -0400
commit3e706399b03bd237d087d731d4b1b029e546b33d (patch)
tree51a5de83f8493d1b78cc16b0fa0abcac2b37cebc /drivers/scsi/libata-core.c
parentccf68c3405fca11386004674377d951b9b18e756 (diff)
[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,
5419 5419
5420 DPRINTK("ENTER\n"); 5420 DPRINTK("ENTER\n");
5421 5421
5422 if (!ent->port_ops->probe_reset && 5422 if (!ent->port_ops->probe_reset && !ent->port_ops->error_handler &&
5423 !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { 5423 !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
5424 printk(KERN_ERR "ata%u: no reset mechanism available\n", 5424 printk(KERN_ERR "ata%u: no reset mechanism available\n",
5425 port_no); 5425 port_no);
@@ -5465,7 +5465,6 @@ err_out:
5465 * RETURNS: 5465 * RETURNS:
5466 * Number of ports registered. Zero on error (no ports registered). 5466 * Number of ports registered. Zero on error (no ports registered).
5467 */ 5467 */
5468
5469int ata_device_add(const struct ata_probe_ent *ent) 5468int ata_device_add(const struct ata_probe_ent *ent)
5470{ 5469{
5471 unsigned int count = 0, i; 5470 unsigned int count = 0, i;
@@ -5542,19 +5541,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
5542 } 5541 }
5543 ap->sata_spd_limit = ap->hw_sata_spd_limit; 5542 ap->sata_spd_limit = ap->hw_sata_spd_limit;
5544 5543
5545 DPRINTK("ata%u: bus probe begin\n", ap->id);
5546 rc = ata_bus_probe(ap);
5547 DPRINTK("ata%u: bus probe end\n", ap->id);
5548
5549 if (rc) {
5550 /* FIXME: do something useful here?
5551 * Current libata behavior will
5552 * tear down everything when
5553 * the module is removed
5554 * or the h/w is unplugged.
5555 */
5556 }
5557
5558 rc = scsi_add_host(ap->host, dev); 5544 rc = scsi_add_host(ap->host, dev);
5559 if (rc) { 5545 if (rc) {
5560 ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n"); 5546 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)
5564 * at the very least 5550 * at the very least
5565 */ 5551 */
5566 } 5552 }
5553
5554 if (!ap->ops->probe_reset) {
5555 unsigned long flags;
5556
5557 ata_port_probe(ap);
5558
5559 /* kick EH for boot probing */
5560 spin_lock_irqsave(&ap->host_set->lock, flags);
5561
5562 ap->eh_info.probe_mask = (1 << ATA_MAX_DEVICES) - 1;
5563 ap->eh_info.action |= ATA_EH_SOFTRESET;
5564
5565 ap->flags |= ATA_FLAG_LOADING;
5566 ata_port_schedule_eh(ap);
5567
5568 spin_unlock_irqrestore(&ap->host_set->lock, flags);
5569
5570 /* wait for EH to finish */
5571 ata_port_wait_eh(ap);
5572 } else {
5573 DPRINTK("ata%u: bus probe begin\n", ap->id);
5574 rc = ata_bus_probe(ap);
5575 DPRINTK("ata%u: bus probe end\n", ap->id);
5576
5577 if (rc) {
5578 /* FIXME: do something useful here?
5579 * Current libata behavior will
5580 * tear down everything when
5581 * the module is removed
5582 * or the h/w is unplugged.
5583 */
5584 }
5585 }
5567 } 5586 }
5568 5587
5569 /* probes are done, now scan each port's disk(s) */ 5588 /* probes are done, now scan each port's disk(s) */