aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla1280.c
diff options
context:
space:
mode:
authorMichael Reed <mdr@sgi.com>2010-03-23 16:00:58 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-03-27 15:20:16 -0400
commit421e33d0045ac0aa119c033b78742e0fbf4c3b21 (patch)
tree70cb2358ce9ad1d2e534098ee4088dd24278d873 /drivers/scsi/qla1280.c
parentebd09ec93c90c8ec571d7e166832fb1fc705bf5e (diff)
[SCSI] qla1280: retain firmware for error recovery
The qla1280 driver acquires its firmware via udev. During boot the firmware is located in the initrd. If, after root is mounted, the adapter needs to reload firmware (host reset), the firmware load may fail if the root device is on the adapter being reset. This patch modifies qla1280 to retain the firmware loaded via the initial request_firmware() for use during error recovery. [jejb: fix up checkpatch issues] Signed-off-by: Michael Reed <mdr@sgi.com> Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla1280.c')
-rw-r--r--drivers/scsi/qla1280.c161
1 files changed, 109 insertions, 52 deletions
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 49ac4148493b..66e2dd43008a 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -17,9 +17,11 @@
17* General Public License for more details. 17* General Public License for more details.
18* 18*
19******************************************************************************/ 19******************************************************************************/
20#define QLA1280_VERSION "3.27" 20#define QLA1280_VERSION "3.27.1"
21/***************************************************************************** 21/*****************************************************************************
22 Revision History: 22 Revision History:
23 Rev 3.27.1, February 8, 2010, Michael Reed
24 - Retain firmware image for error recovery.
23 Rev 3.27, February 10, 2009, Michael Reed 25 Rev 3.27, February 10, 2009, Michael Reed
24 - General code cleanup. 26 - General code cleanup.
25 - Improve error recovery. 27 - Improve error recovery.
@@ -538,9 +540,9 @@ __setup("qla1280=", qla1280_setup);
538/*****************************************/ 540/*****************************************/
539 541
540struct qla_boards { 542struct qla_boards {
541 unsigned char name[9]; /* Board ID String */ 543 char *name; /* Board ID String */
542 int numPorts; /* Number of SCSI ports */ 544 int numPorts; /* Number of SCSI ports */
543 char *fwname; /* firmware name */ 545 int fw_index; /* index into qla1280_fw_tbl for firmware */
544}; 546};
545 547
546/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ 548/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -561,15 +563,30 @@ static struct pci_device_id qla1280_pci_tbl[] = {
561}; 563};
562MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); 564MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
563 565
566DEFINE_MUTEX(qla1280_firmware_mutex);
567
568struct qla_fw {
569 char *fwname;
570 const struct firmware *fw;
571};
572
573#define QL_NUM_FW_IMAGES 3
574
575struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
576 {"qlogic/1040.bin", NULL}, /* image 0 */
577 {"qlogic/1280.bin", NULL}, /* image 1 */
578 {"qlogic/12160.bin", NULL}, /* image 2 */
579};
580
581/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */
564static struct qla_boards ql1280_board_tbl[] = { 582static struct qla_boards ql1280_board_tbl[] = {
565 /* Name , Number of ports, FW details */ 583 {.name = "QLA12160", .numPorts = 2, .fw_index = 2},
566 {"QLA12160", 2, "qlogic/12160.bin"}, 584 {.name = "QLA1040" , .numPorts = 1, .fw_index = 0},
567 {"QLA1040", 1, "qlogic/1040.bin"}, 585 {.name = "QLA1080" , .numPorts = 1, .fw_index = 1},
568 {"QLA1080", 1, "qlogic/1280.bin"}, 586 {.name = "QLA1240" , .numPorts = 2, .fw_index = 1},
569 {"QLA1240", 2, "qlogic/1280.bin"}, 587 {.name = "QLA1280" , .numPorts = 2, .fw_index = 1},
570 {"QLA1280", 2, "qlogic/1280.bin"}, 588 {.name = "QLA10160", .numPorts = 1, .fw_index = 2},
571 {"QLA10160", 1, "qlogic/12160.bin"}, 589 {.name = " ", .numPorts = 0, .fw_index = -1},
572 {" ", 0, " "},
573}; 590};
574 591
575static int qla1280_verbose = 1; 592static int qla1280_verbose = 1;
@@ -1512,6 +1529,63 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
1512} 1529}
1513 1530
1514/* 1531/*
1532 * qla1280_request_firmware
1533 * Acquire firmware for chip. Retain in memory
1534 * for error recovery.
1535 *
1536 * Input:
1537 * ha = adapter block pointer.
1538 *
1539 * Returns:
1540 * Pointer to firmware image or an error code
1541 * cast to pointer via ERR_PTR().
1542 */
1543static const struct firmware *
1544qla1280_request_firmware(struct scsi_qla_host *ha)
1545{
1546 const struct firmware *fw;
1547 int err;
1548 int index;
1549 char *fwname;
1550
1551 spin_unlock_irq(ha->host->host_lock);
1552 mutex_lock(&qla1280_firmware_mutex);
1553
1554 index = ql1280_board_tbl[ha->devnum].fw_index;
1555 fw = qla1280_fw_tbl[index].fw;
1556 if (fw)
1557 goto out;
1558
1559 fwname = qla1280_fw_tbl[index].fwname;
1560 err = request_firmware(&fw, fwname, &ha->pdev->dev);
1561
1562 if (err) {
1563 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
1564 fwname, err);
1565 fw = ERR_PTR(err);
1566 goto unlock;
1567 }
1568 if ((fw->size % 2) || (fw->size < 6)) {
1569 printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n",
1570 fw->size, fwname);
1571 release_firmware(fw);
1572 fw = ERR_PTR(-EINVAL);
1573 goto unlock;
1574 }
1575
1576 qla1280_fw_tbl[index].fw = fw;
1577
1578 out:
1579 ha->fwver1 = fw->data[0];
1580 ha->fwver2 = fw->data[1];
1581 ha->fwver3 = fw->data[2];
1582 unlock:
1583 mutex_unlock(&qla1280_firmware_mutex);
1584 spin_lock_irq(ha->host->host_lock);
1585 return fw;
1586}
1587
1588/*
1515 * Chip diagnostics 1589 * Chip diagnostics
1516 * Test chip for proper operation. 1590 * Test chip for proper operation.
1517 * 1591 *
@@ -1634,30 +1708,18 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
1634static int 1708static int
1635qla1280_load_firmware_pio(struct scsi_qla_host *ha) 1709qla1280_load_firmware_pio(struct scsi_qla_host *ha)
1636{ 1710{
1711 /* enter with host_lock acquired */
1712
1637 const struct firmware *fw; 1713 const struct firmware *fw;
1638 const __le16 *fw_data; 1714 const __le16 *fw_data;
1639 uint16_t risc_address, risc_code_size; 1715 uint16_t risc_address, risc_code_size;
1640 uint16_t mb[MAILBOX_REGISTER_COUNT], i; 1716 uint16_t mb[MAILBOX_REGISTER_COUNT], i;
1641 int err; 1717 int err = 0;
1718
1719 fw = qla1280_request_firmware(ha);
1720 if (IS_ERR(fw))
1721 return PTR_ERR(fw);
1642 1722
1643 spin_unlock_irq(ha->host->host_lock);
1644 err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
1645 &ha->pdev->dev);
1646 spin_lock_irq(ha->host->host_lock);
1647 if (err) {
1648 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
1649 ql1280_board_tbl[ha->devnum].fwname, err);
1650 return err;
1651 }
1652 if ((fw->size % 2) || (fw->size < 6)) {
1653 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
1654 fw->size, ql1280_board_tbl[ha->devnum].fwname);
1655 err = -EINVAL;
1656 goto out;
1657 }
1658 ha->fwver1 = fw->data[0];
1659 ha->fwver2 = fw->data[1];
1660 ha->fwver3 = fw->data[2];
1661 fw_data = (const __le16 *)&fw->data[0]; 1723 fw_data = (const __le16 *)&fw->data[0];
1662 ha->fwstart = __le16_to_cpu(fw_data[2]); 1724 ha->fwstart = __le16_to_cpu(fw_data[2]);
1663 1725
@@ -1675,11 +1737,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
1675 if (err) { 1737 if (err) {
1676 printk(KERN_ERR "scsi(%li): Failed to load firmware\n", 1738 printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
1677 ha->host_no); 1739 ha->host_no);
1678 goto out; 1740 break;
1679 } 1741 }
1680 } 1742 }
1681out: 1743
1682 release_firmware(fw);
1683 return err; 1744 return err;
1684} 1745}
1685 1746
@@ -1687,6 +1748,7 @@ out:
1687static int 1748static int
1688qla1280_load_firmware_dma(struct scsi_qla_host *ha) 1749qla1280_load_firmware_dma(struct scsi_qla_host *ha)
1689{ 1750{
1751 /* enter with host_lock acquired */
1690 const struct firmware *fw; 1752 const struct firmware *fw;
1691 const __le16 *fw_data; 1753 const __le16 *fw_data;
1692 uint16_t risc_address, risc_code_size; 1754 uint16_t risc_address, risc_code_size;
@@ -1701,24 +1763,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
1701 return -ENOMEM; 1763 return -ENOMEM;
1702#endif 1764#endif
1703 1765
1704 spin_unlock_irq(ha->host->host_lock); 1766 fw = qla1280_request_firmware(ha);
1705 err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, 1767 if (IS_ERR(fw))
1706 &ha->pdev->dev); 1768 return PTR_ERR(fw);
1707 spin_lock_irq(ha->host->host_lock); 1769
1708 if (err) {
1709 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
1710 ql1280_board_tbl[ha->devnum].fwname, err);
1711 return err;
1712 }
1713 if ((fw->size % 2) || (fw->size < 6)) {
1714 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
1715 fw->size, ql1280_board_tbl[ha->devnum].fwname);
1716 err = -EINVAL;
1717 goto out;
1718 }
1719 ha->fwver1 = fw->data[0];
1720 ha->fwver2 = fw->data[1];
1721 ha->fwver3 = fw->data[2];
1722 fw_data = (const __le16 *)&fw->data[0]; 1770 fw_data = (const __le16 *)&fw->data[0];
1723 ha->fwstart = __le16_to_cpu(fw_data[2]); 1771 ha->fwstart = __le16_to_cpu(fw_data[2]);
1724 1772
@@ -1803,7 +1851,6 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
1803#if DUMP_IT_BACK 1851#if DUMP_IT_BACK
1804 pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); 1852 pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
1805#endif 1853#endif
1806 release_firmware(fw);
1807 return err; 1854 return err;
1808} 1855}
1809 1856
@@ -1842,6 +1889,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
1842static int 1889static int
1843qla1280_load_firmware(struct scsi_qla_host *ha) 1890qla1280_load_firmware(struct scsi_qla_host *ha)
1844{ 1891{
1892 /* enter with host_lock taken */
1845 int err; 1893 int err;
1846 1894
1847 err = qla1280_chip_diag(ha); 1895 err = qla1280_chip_diag(ha);
@@ -4420,7 +4468,16 @@ qla1280_init(void)
4420static void __exit 4468static void __exit
4421qla1280_exit(void) 4469qla1280_exit(void)
4422{ 4470{
4471 int i;
4472
4423 pci_unregister_driver(&qla1280_pci_driver); 4473 pci_unregister_driver(&qla1280_pci_driver);
4474 /* release any allocated firmware images */
4475 for (i = 0; i < QL_NUM_FW_IMAGES; i++) {
4476 if (qla1280_fw_tbl[i].fw) {
4477 release_firmware(qla1280_fw_tbl[i].fw);
4478 qla1280_fw_tbl[i].fw = NULL;
4479 }
4480 }
4424} 4481}
4425 4482
4426module_init(qla1280_init); 4483module_init(qla1280_init);