Commit 3e706399b03bd237d087d731d4b1b029e546b33d

Authored by Tejun Heo
1 parent ccf68c3405

[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>

Showing 2 changed files with 52 additions and 24 deletions Side-by-side Diff

drivers/scsi/libata-core.c
... ... @@ -5419,7 +5419,7 @@
5419 5419  
5420 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 5423 !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
5424 5424 printk(KERN_ERR "ata%u: no reset mechanism available\n",
5425 5425 port_no);
... ... @@ -5465,7 +5465,6 @@
5465 5465 * RETURNS:
5466 5466 * Number of ports registered. Zero on error (no ports registered).
5467 5467 */
5468   -
5469 5468 int ata_device_add(const struct ata_probe_ent *ent)
5470 5469 {
5471 5470 unsigned int count = 0, i;
... ... @@ -5542,19 +5541,6 @@
5542 5541 }
5543 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 5544 rc = scsi_add_host(ap->host, dev);
5559 5545 if (rc) {
5560 5546 ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
... ... @@ -5563,6 +5549,39 @@
5563 5549 * scsi_scan_host and ata_host_remove, below,
5564 5550 * at the very least
5565 5551 */
  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 + }
5566 5585 }
5567 5586 }
5568 5587  
drivers/scsi/libata-eh.c
... ... @@ -287,12 +287,15 @@
287 287 /* clean up */
288 288 spin_lock_irqsave(hs_lock, flags);
289 289  
290   - if (ap->flags & ATA_FLAG_SCSI_HOTPLUG)
291   - queue_work(ata_aux_wq, &ap->hotplug_task);
  290 + if (ap->flags & ATA_FLAG_LOADING) {
  291 + ap->flags &= ~ATA_FLAG_LOADING;
  292 + } else {
  293 + if (ap->flags & ATA_FLAG_SCSI_HOTPLUG)
  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 + }
292 298  
293   - if (ap->flags & ATA_FLAG_RECOVERED)
294   - ata_port_printk(ap, KERN_INFO, "EH complete\n");
295   -
296 299 ap->flags &= ~(ATA_FLAG_SCSI_HOTPLUG | ATA_FLAG_RECOVERED);
297 300  
298 301 /* tell wait_eh that we're done */
... ... @@ -1367,6 +1370,7 @@
1367 1370 struct ata_eh_context *ehc = &ap->eh_context;
1368 1371 unsigned int *classes = ehc->classes;
1369 1372 int tries = ATA_EH_RESET_TRIES;
  1373 + int verbose = !(ap->flags & ATA_FLAG_LOADING);
1370 1374 unsigned int action;
1371 1375 ata_reset_fn_t reset;
1372 1376 int i, did_followup_srst, rc;
... ... @@ -1414,8 +1418,10 @@
1414 1418 }
1415 1419  
1416 1420 retry:
1417   - ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
1418   - reset == softreset ? "soft" : "hard");
  1421 + /* shut up during boot probing */
  1422 + if (verbose)
  1423 + ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
  1424 + reset == softreset ? "soft" : "hard");
1419 1425  
1420 1426 /* reset */
1421 1427 ata_eh_about_to_do(ap, ATA_EH_RESET_MASK);
... ... @@ -1799,8 +1805,11 @@
1799 1805 ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
1800 1806 ata_postreset_fn_t postreset)
1801 1807 {
1802   - ata_eh_autopsy(ap);
1803   - ata_eh_report(ap);
  1808 + if (!(ap->flags & ATA_FLAG_LOADING)) {
  1809 + ata_eh_autopsy(ap);
  1810 + ata_eh_report(ap);
  1811 + }
  1812 +
1804 1813 ata_eh_recover(ap, prereset, softreset, hardreset, postreset);
1805 1814 ata_eh_finish(ap);
1806 1815 }