aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:53:22 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:16 -0400
commit47a8617c7df6cc8b8617a3deb5a36bbae1997d13 (patch)
treeba592dbafd7f3144e3ed0a210cefe7ed89b96058
parentebdbe65f07bb26baf69fcb0ee332702064888018 (diff)
[SCSI] lpfc 8.1.12 : Add support for async scanning
Add support for async scanning Notes: This is the async scan patch to our driver from Matthew Wilcox. The async scan logic is still subject to errors in insmod/rmmod, as the async scan threads don't get shutdown when the module unloads underneath them. See http://marc.info/?l=linux-scsi&m=117551999925582&w=2 Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c305
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
3 files changed, 160 insertions, 150 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 9f70b5bc0950..e4454bc37782 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -200,6 +200,9 @@ void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
200 200
201/* Function prototypes. */ 201/* Function prototypes. */
202const char* lpfc_info(struct Scsi_Host *); 202const char* lpfc_info(struct Scsi_Host *);
203void lpfc_scan_start(struct Scsi_Host *);
204int lpfc_scan_finished(struct Scsi_Host *, unsigned long);
205
203void lpfc_get_cfgparam(struct lpfc_hba *); 206void lpfc_get_cfgparam(struct lpfc_hba *);
204int lpfc_alloc_sysfs_attr(struct lpfc_hba *); 207int lpfc_alloc_sysfs_attr(struct lpfc_hba *);
205void lpfc_free_sysfs_attr(struct lpfc_hba *); 208void lpfc_free_sysfs_attr(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5e9a839111d2..7cb92c7531ba 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -418,33 +418,6 @@ lpfc_config_port_post(struct lpfc_hba * phba)
418 return (0); 418 return (0);
419} 419}
420 420
421static int
422lpfc_discovery_wait(struct lpfc_hba *phba)
423{
424 int i = 0;
425
426 while ((phba->hba_state != LPFC_HBA_READY) ||
427 (phba->num_disc_nodes) || (phba->fc_prli_sent) ||
428 ((phba->fc_map_cnt == 0) && (i<2)) ||
429 (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
430 /* Check every second for 30 retries. */
431 i++;
432 if (i > 30) {
433 return -ETIMEDOUT;
434 }
435 if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) {
436 /* The link is down. Set linkdown timeout */
437 return -ETIMEDOUT;
438 }
439
440 /* Delay for 1 second to give discovery time to complete. */
441 msleep(1000);
442
443 }
444
445 return 0;
446}
447
448/************************************************************************/ 421/************************************************************************/
449/* */ 422/* */
450/* lpfc_hba_down_prep */ 423/* lpfc_hba_down_prep */
@@ -1362,6 +1335,156 @@ lpfc_scsi_free(struct lpfc_hba * phba)
1362 return 0; 1335 return 0;
1363} 1336}
1364 1337
1338void lpfc_remove_device(struct lpfc_hba *phba)
1339{
1340 unsigned long iflag;
1341
1342 lpfc_free_sysfs_attr(phba);
1343
1344 spin_lock_irqsave(phba->host->host_lock, iflag);
1345 phba->fc_flag |= FC_UNLOADING;
1346
1347 spin_unlock_irqrestore(phba->host->host_lock, iflag);
1348
1349 fc_remove_host(phba->host);
1350 scsi_remove_host(phba->host);
1351
1352 kthread_stop(phba->worker_thread);
1353
1354 /*
1355 * Bring down the SLI Layer. This step disable all interrupts,
1356 * clears the rings, discards all mailbox commands, and resets
1357 * the HBA.
1358 */
1359 lpfc_sli_hba_down(phba);
1360 lpfc_sli_brdrestart(phba);
1361
1362 /* Release the irq reservation */
1363 free_irq(phba->pcidev->irq, phba);
1364 pci_disable_msi(phba->pcidev);
1365
1366 lpfc_cleanup(phba);
1367 lpfc_stop_timer(phba);
1368 phba->work_hba_events = 0;
1369
1370 /*
1371 * Call scsi_free before mem_free since scsi bufs are released to their
1372 * corresponding pools here.
1373 */
1374 lpfc_scsi_free(phba);
1375 lpfc_mem_free(phba);
1376
1377 /* Free resources associated with SLI2 interface */
1378 dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
1379 phba->slim2p, phba->slim2p_mapping);
1380
1381 /* unmap adapter SLIM and Control Registers */
1382 iounmap(phba->ctrl_regs_memmap_p);
1383 iounmap(phba->slim_memmap_p);
1384
1385 pci_release_regions(phba->pcidev);
1386 pci_disable_device(phba->pcidev);
1387
1388 idr_remove(&lpfc_hba_index, phba->brd_no);
1389 scsi_host_put(phba->host);
1390}
1391
1392void lpfc_scan_start(struct Scsi_Host *host)
1393{
1394 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
1395
1396 if (lpfc_alloc_sysfs_attr(phba))
1397 goto error;
1398
1399 phba->MBslimaddr = phba->slim_memmap_p;
1400 phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
1401 phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
1402 phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
1403 phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
1404
1405 if (lpfc_sli_hba_setup(phba))
1406 goto error;
1407
1408 /*
1409 * hba setup may have changed the hba_queue_depth so we need to adjust
1410 * the value of can_queue.
1411 */
1412 host->can_queue = phba->cfg_hba_queue_depth - 10;
1413 return;
1414
1415error:
1416 lpfc_remove_device(phba);
1417}
1418
1419int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
1420{
1421 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
1422
1423 if (!phba->host)
1424 return 1;
1425 if (time >= 30 * HZ)
1426 goto finished;
1427
1428 if (phba->hba_state != LPFC_HBA_READY)
1429 return 0;
1430 if (phba->num_disc_nodes || phba->fc_prli_sent)
1431 return 0;
1432 if ((phba->fc_map_cnt == 0) && (time < 2 * HZ))
1433 return 0;
1434 if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)
1435 return 0;
1436 if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ))
1437 return 0;
1438
1439finished:
1440 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
1441 spin_lock_irq(shost->host_lock);
1442 lpfc_poll_start_timer(phba);
1443 spin_unlock_irq(shost->host_lock);
1444 }
1445
1446 /*
1447 * set fixed host attributes
1448 * Must done after lpfc_sli_hba_setup()
1449 */
1450
1451 fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn);
1452 fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn);
1453 fc_host_supported_classes(shost) = FC_COS_CLASS3;
1454
1455 memset(fc_host_supported_fc4s(shost), 0,
1456 sizeof(fc_host_supported_fc4s(shost)));
1457 fc_host_supported_fc4s(shost)[2] = 1;
1458 fc_host_supported_fc4s(shost)[7] = 1;
1459
1460 lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost));
1461
1462 fc_host_supported_speeds(shost) = 0;
1463 if (phba->lmt & LMT_10Gb)
1464 fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
1465 if (phba->lmt & LMT_4Gb)
1466 fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
1467 if (phba->lmt & LMT_2Gb)
1468 fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
1469 if (phba->lmt & LMT_1Gb)
1470 fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
1471
1472 fc_host_maxframe_size(shost) =
1473 ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
1474 (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb);
1475
1476 /* This value is also unchanging */
1477 memset(fc_host_active_fc4s(shost), 0,
1478 sizeof(fc_host_active_fc4s(shost)));
1479 fc_host_active_fc4s(shost)[2] = 1;
1480 fc_host_active_fc4s(shost)[7] = 1;
1481
1482 spin_lock_irq(shost->host_lock);
1483 phba->fc_flag &= ~FC_LOADING;
1484 spin_unlock_irq(shost->host_lock);
1485
1486 return 1;
1487}
1365 1488
1366static int __devinit 1489static int __devinit
1367lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) 1490lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
@@ -1552,13 +1675,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1552 1675
1553 host->transportt = lpfc_transport_template; 1676 host->transportt = lpfc_transport_template;
1554 pci_set_drvdata(pdev, host); 1677 pci_set_drvdata(pdev, host);
1555 error = scsi_add_host(host, &pdev->dev);
1556 if (error)
1557 goto out_kthread_stop;
1558
1559 error = lpfc_alloc_sysfs_attr(phba);
1560 if (error)
1561 goto out_remove_host;
1562 1678
1563 if (phba->cfg_use_msi) { 1679 if (phba->cfg_use_msi) {
1564 error = pci_enable_msi(phba->pcidev); 1680 error = pci_enable_msi(phba->pcidev);
@@ -1574,73 +1690,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1574 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1690 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1575 "%d:0451 Enable interrupt handler failed\n", 1691 "%d:0451 Enable interrupt handler failed\n",
1576 phba->brd_no); 1692 phba->brd_no);
1577 goto out_free_sysfs_attr; 1693 goto out_kthread_stop;
1578 } 1694 }
1579 phba->MBslimaddr = phba->slim_memmap_p;
1580 phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
1581 phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
1582 phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
1583 phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
1584 1695
1585 error = lpfc_sli_hba_setup(phba); 1696 error = scsi_add_host(host, &pdev->dev);
1586 if (error) { 1697 if (error)
1587 error = -ENODEV;
1588 goto out_free_irq; 1698 goto out_free_irq;
1589 }
1590
1591 /*
1592 * hba setup may have changed the hba_queue_depth so we need to adjust
1593 * the value of can_queue.
1594 */
1595 host->can_queue = phba->cfg_hba_queue_depth - 10;
1596
1597 lpfc_discovery_wait(phba);
1598
1599 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
1600 spin_lock_irq(phba->host->host_lock);
1601 lpfc_poll_start_timer(phba);
1602 spin_unlock_irq(phba->host->host_lock);
1603 }
1604 1699
1605 /* 1700 scsi_scan_host(host);
1606 * set fixed host attributes
1607 * Must done after lpfc_sli_hba_setup()
1608 */
1609
1610 fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.u.wwn);
1611 fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.u.wwn);
1612 fc_host_supported_classes(host) = FC_COS_CLASS3;
1613
1614 memset(fc_host_supported_fc4s(host), 0,
1615 sizeof(fc_host_supported_fc4s(host)));
1616 fc_host_supported_fc4s(host)[2] = 1;
1617 fc_host_supported_fc4s(host)[7] = 1;
1618
1619 lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host));
1620
1621 fc_host_supported_speeds(host) = 0;
1622 if (phba->lmt & LMT_10Gb)
1623 fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT;
1624 if (phba->lmt & LMT_4Gb)
1625 fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT;
1626 if (phba->lmt & LMT_2Gb)
1627 fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT;
1628 if (phba->lmt & LMT_1Gb)
1629 fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT;
1630
1631 fc_host_maxframe_size(host) =
1632 ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
1633 (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb);
1634
1635 /* This value is also unchanging */
1636 memset(fc_host_active_fc4s(host), 0,
1637 sizeof(fc_host_active_fc4s(host)));
1638 fc_host_active_fc4s(host)[2] = 1;
1639 fc_host_active_fc4s(host)[7] = 1;
1640 1701
1641 spin_lock_irq(phba->host->host_lock);
1642 phba->fc_flag &= ~FC_LOADING;
1643 spin_unlock_irq(phba->host->host_lock);
1644 return 0; 1702 return 0;
1645 1703
1646out_free_irq: 1704out_free_irq:
@@ -1648,11 +1706,6 @@ out_free_irq:
1648 phba->work_hba_events = 0; 1706 phba->work_hba_events = 0;
1649 free_irq(phba->pcidev->irq, phba); 1707 free_irq(phba->pcidev->irq, phba);
1650 pci_disable_msi(phba->pcidev); 1708 pci_disable_msi(phba->pcidev);
1651out_free_sysfs_attr:
1652 lpfc_free_sysfs_attr(phba);
1653out_remove_host:
1654 fc_remove_host(phba->host);
1655 scsi_remove_host(phba->host);
1656out_kthread_stop: 1709out_kthread_stop:
1657 kthread_stop(phba->worker_thread); 1710 kthread_stop(phba->worker_thread);
1658out_free_iocbq: 1711out_free_iocbq:
@@ -1690,56 +1743,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
1690{ 1743{
1691 struct Scsi_Host *host = pci_get_drvdata(pdev); 1744 struct Scsi_Host *host = pci_get_drvdata(pdev);
1692 struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; 1745 struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
1693 unsigned long iflag;
1694
1695 lpfc_free_sysfs_attr(phba);
1696
1697 spin_lock_irqsave(phba->host->host_lock, iflag);
1698 phba->fc_flag |= FC_UNLOADING;
1699
1700 spin_unlock_irqrestore(phba->host->host_lock, iflag);
1701
1702 fc_remove_host(phba->host);
1703 scsi_remove_host(phba->host);
1704
1705 kthread_stop(phba->worker_thread);
1706
1707 /*
1708 * Bring down the SLI Layer. This step disable all interrupts,
1709 * clears the rings, discards all mailbox commands, and resets
1710 * the HBA.
1711 */
1712 lpfc_sli_hba_down(phba);
1713 lpfc_sli_brdrestart(phba);
1714 1746
1715 /* Release the irq reservation */ 1747 lpfc_remove_device(phba);
1716 free_irq(phba->pcidev->irq, phba);
1717 pci_disable_msi(phba->pcidev);
1718
1719 lpfc_cleanup(phba);
1720 lpfc_stop_timer(phba);
1721 phba->work_hba_events = 0;
1722
1723 /*
1724 * Call scsi_free before mem_free since scsi bufs are released to their
1725 * corresponding pools here.
1726 */
1727 lpfc_scsi_free(phba);
1728 lpfc_mem_free(phba);
1729
1730 /* Free resources associated with SLI2 interface */
1731 dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
1732 phba->slim2p, phba->slim2p_mapping);
1733
1734 /* unmap adapter SLIM and Control Registers */
1735 iounmap(phba->ctrl_regs_memmap_p);
1736 iounmap(phba->slim_memmap_p);
1737
1738 pci_release_regions(phba->pcidev);
1739 pci_disable_device(phba->pcidev);
1740
1741 idr_remove(&lpfc_hba_index, phba->brd_no);
1742 scsi_host_put(phba->host);
1743 1748
1744 pci_set_drvdata(pdev, NULL); 1749 pci_set_drvdata(pdev, NULL);
1745} 1750}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index cc0f845d8b38..f09f3d211438 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1351,6 +1351,8 @@ struct scsi_host_template lpfc_template = {
1351 .slave_alloc = lpfc_slave_alloc, 1351 .slave_alloc = lpfc_slave_alloc,
1352 .slave_configure = lpfc_slave_configure, 1352 .slave_configure = lpfc_slave_configure,
1353 .slave_destroy = lpfc_slave_destroy, 1353 .slave_destroy = lpfc_slave_destroy,
1354 .scan_finished = lpfc_scan_finished,
1355 .scan_start = lpfc_scan_start,
1354 .this_id = -1, 1356 .this_id = -1,
1355 .sg_tablesize = LPFC_SG_SEG_CNT, 1357 .sg_tablesize = LPFC_SG_SEG_CNT,
1356 .cmd_per_lun = LPFC_CMD_PER_LUN, 1358 .cmd_per_lun = LPFC_CMD_PER_LUN,