aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/scsi/libata-core.c49
-rw-r--r--drivers/scsi/libata-eh.c27
2 files changed, 52 insertions, 24 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) */
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 733dfa532977..70c132bef68e 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -287,11 +287,14 @@ void ata_scsi_error(struct Scsi_Host *host)
287 /* clean up */ 287 /* clean up */
288 spin_lock_irqsave(hs_lock, flags); 288 spin_lock_irqsave(hs_lock, flags);
289 289
290 if (ap->flags & ATA_FLAG_SCSI_HOTPLUG) 290 if (ap->flags & ATA_FLAG_LOADING) {
291 queue_work(ata_aux_wq, &ap->hotplug_task); 291 ap->flags &= ~ATA_FLAG_LOADING;
292 292 } else {
293 if (ap->flags & ATA_FLAG_RECOVERED) 293 if (ap->flags & ATA_FLAG_SCSI_HOTPLUG)
294 ata_port_printk(ap, KERN_INFO, "EH complete\n"); 294 queue_work(ata_aux_wq, &ap->hotplug_task);
295 if (ap->flags & ATA_FLAG_RECOVERED)
296 ata_port_printk(ap, KERN_INFO, "EH complete\n");
297 }
295 298
296 ap->flags &= ~(ATA_FLAG_SCSI_HOTPLUG | ATA_FLAG_RECOVERED); 299 ap->flags &= ~(ATA_FLAG_SCSI_HOTPLUG | ATA_FLAG_RECOVERED);
297 300
@@ -1367,6 +1370,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
1367 struct ata_eh_context *ehc = &ap->eh_context; 1370 struct ata_eh_context *ehc = &ap->eh_context;
1368 unsigned int *classes = ehc->classes; 1371 unsigned int *classes = ehc->classes;
1369 int tries = ATA_EH_RESET_TRIES; 1372 int tries = ATA_EH_RESET_TRIES;
1373 int verbose = !(ap->flags & ATA_FLAG_LOADING);
1370 unsigned int action; 1374 unsigned int action;
1371 ata_reset_fn_t reset; 1375 ata_reset_fn_t reset;
1372 int i, did_followup_srst, rc; 1376 int i, did_followup_srst, rc;
@@ -1414,8 +1418,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
1414 } 1418 }
1415 1419
1416 retry: 1420 retry:
1417 ata_port_printk(ap, KERN_INFO, "%s resetting port\n", 1421 /* shut up during boot probing */
1418 reset == softreset ? "soft" : "hard"); 1422 if (verbose)
1423 ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
1424 reset == softreset ? "soft" : "hard");
1419 1425
1420 /* reset */ 1426 /* reset */
1421 ata_eh_about_to_do(ap, ATA_EH_RESET_MASK); 1427 ata_eh_about_to_do(ap, ATA_EH_RESET_MASK);
@@ -1799,8 +1805,11 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
1799 ata_reset_fn_t softreset, ata_reset_fn_t hardreset, 1805 ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
1800 ata_postreset_fn_t postreset) 1806 ata_postreset_fn_t postreset)
1801{ 1807{
1802 ata_eh_autopsy(ap); 1808 if (!(ap->flags & ATA_FLAG_LOADING)) {
1803 ata_eh_report(ap); 1809 ata_eh_autopsy(ap);
1810 ata_eh_report(ap);
1811 }
1812
1804 ata_eh_recover(ap, prereset, softreset, hardreset, postreset); 1813 ata_eh_recover(ap, prereset, softreset, hardreset, postreset);
1805 ata_eh_finish(ap); 1814 ata_eh_finish(ap);
1806} 1815}