diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:11 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:11 -0400 |
commit | 3e706399b03bd237d087d731d4b1b029e546b33d (patch) | |
tree | 51a5de83f8493d1b78cc16b0fa0abcac2b37cebc /drivers/scsi/libata-core.c | |
parent | ccf68c3405fca11386004674377d951b9b18e756 (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.c | 49 |
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 | |||
5469 | int ata_device_add(const struct ata_probe_ent *ent) | 5468 | int 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) */ |