diff options
author | Jaswinder Singh Rajput <jaswinderrajput@gmail.com> | 2009-04-02 01:43:17 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-03 10:24:42 -0400 |
commit | 1bfa11db712cbf4af1ae037cd25fd4f781f0c215 (patch) | |
tree | 83a023e0e07a1b7e85b0e764740d120047b6ace3 /drivers/scsi/qla1280.c | |
parent | fd6e1c14b73dbab89cb76af895d5612e4a8b5522 (diff) |
[SCSI] qla1280: use request_firmware
Firmware blob is little endian looks like this...
unsigned char Version1
unsigned char Version2
unsigned char Version3
unsigned char Padding
unsigned short start_address
unsigned short data
Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla1280.c')
-rw-r--r-- | drivers/scsi/qla1280.c | 114 |
1 files changed, 74 insertions, 40 deletions
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index df09820e8916..351b56ced925 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -348,6 +348,7 @@ | |||
348 | #include <linux/interrupt.h> | 348 | #include <linux/interrupt.h> |
349 | #include <linux/init.h> | 349 | #include <linux/init.h> |
350 | #include <linux/dma-mapping.h> | 350 | #include <linux/dma-mapping.h> |
351 | #include <linux/firmware.h> | ||
351 | 352 | ||
352 | #include <asm/io.h> | 353 | #include <asm/io.h> |
353 | #include <asm/irq.h> | 354 | #include <asm/irq.h> |
@@ -384,11 +385,7 @@ | |||
384 | #define MEMORY_MAPPED_IO 1 | 385 | #define MEMORY_MAPPED_IO 1 |
385 | #endif | 386 | #endif |
386 | 387 | ||
387 | #define UNIQUE_FW_NAME | ||
388 | #include "qla1280.h" | 388 | #include "qla1280.h" |
389 | #include "ql12160_fw.h" /* ISP RISC codes */ | ||
390 | #include "ql1280_fw.h" | ||
391 | #include "ql1040_fw.h" | ||
392 | 389 | ||
393 | #ifndef BITS_PER_LONG | 390 | #ifndef BITS_PER_LONG |
394 | #error "BITS_PER_LONG not defined!" | 391 | #error "BITS_PER_LONG not defined!" |
@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup); | |||
541 | struct qla_boards { | 538 | struct qla_boards { |
542 | unsigned char name[9]; /* Board ID String */ | 539 | unsigned char name[9]; /* Board ID String */ |
543 | int numPorts; /* Number of SCSI ports */ | 540 | int numPorts; /* Number of SCSI ports */ |
544 | unsigned short *fwcode; /* pointer to FW array */ | 541 | char *fwname; /* firmware name */ |
545 | unsigned short *fwlen; /* number of words in array */ | ||
546 | unsigned short *fwstart; /* start address for F/W */ | ||
547 | unsigned char *fwver; /* Ptr to F/W version array */ | ||
548 | }; | 542 | }; |
549 | 543 | ||
550 | /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ | 544 | /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ |
@@ -567,19 +561,13 @@ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); | |||
567 | 561 | ||
568 | static struct qla_boards ql1280_board_tbl[] = { | 562 | static struct qla_boards ql1280_board_tbl[] = { |
569 | /* Name , Number of ports, FW details */ | 563 | /* Name , Number of ports, FW details */ |
570 | {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01, | 564 | {"QLA12160", 2, "qlogic/12160.bin"}, |
571 | &fw12160i_addr01, &fw12160i_version_str[0]}, | 565 | {"QLA1040", 1, "qlogic/1040.bin"}, |
572 | {"QLA1040", 1, &risc_code01[0], &risc_code_length01, | 566 | {"QLA1080", 1, "qlogic/1280.bin"}, |
573 | &risc_code_addr01, &firmware_version[0]}, | 567 | {"QLA1240", 2, "qlogic/1280.bin"}, |
574 | {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01, | 568 | {"QLA1280", 2, "qlogic/1280.bin"}, |
575 | &fw1280ei_addr01, &fw1280ei_version_str[0]}, | 569 | {"QLA10160", 1, "qlogic/12160.bin"}, |
576 | {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01, | 570 | {" ", 0, " "}, |
577 | &fw1280ei_addr01, &fw1280ei_version_str[0]}, | ||
578 | {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01, | ||
579 | &fw1280ei_addr01, &fw1280ei_version_str[0]}, | ||
580 | {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01, | ||
581 | &fw12160i_addr01, &fw12160i_version_str[0]}, | ||
582 | {" ", 0} | ||
583 | }; | 571 | }; |
584 | 572 | ||
585 | static int qla1280_verbose = 1; | 573 | static int qla1280_verbose = 1; |
@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host) | |||
704 | sprintf (bp, | 692 | sprintf (bp, |
705 | "QLogic %s PCI to SCSI Host Adapter\n" | 693 | "QLogic %s PCI to SCSI Host Adapter\n" |
706 | " Firmware version: %2d.%02d.%02d, Driver version %s", | 694 | " Firmware version: %2d.%02d.%02d, Driver version %s", |
707 | &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], | 695 | &bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3, |
708 | QLA1280_VERSION); | 696 | QLA1280_VERSION); |
709 | return bp; | 697 | return bp; |
710 | } | 698 | } |
@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha) | |||
1648 | static int | 1636 | static int |
1649 | qla1280_load_firmware_pio(struct scsi_qla_host *ha) | 1637 | qla1280_load_firmware_pio(struct scsi_qla_host *ha) |
1650 | { | 1638 | { |
1651 | uint16_t risc_address, *risc_code_address, risc_code_size; | 1639 | const struct firmware *fw; |
1640 | const __le16 *fw_data; | ||
1641 | uint16_t risc_address, risc_code_size; | ||
1652 | uint16_t mb[MAILBOX_REGISTER_COUNT], i; | 1642 | uint16_t mb[MAILBOX_REGISTER_COUNT], i; |
1653 | int err; | 1643 | int err; |
1654 | 1644 | ||
1645 | err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, | ||
1646 | &ha->pdev->dev); | ||
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]; | ||
1662 | ha->fwstart = __le16_to_cpu(fw_data[2]); | ||
1663 | |||
1655 | /* Load RISC code. */ | 1664 | /* Load RISC code. */ |
1656 | risc_address = *ql1280_board_tbl[ha->devnum].fwstart; | 1665 | risc_address = ha->fwstart; |
1657 | risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; | 1666 | fw_data = (const __le16 *)&fw->data[4]; |
1658 | risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; | 1667 | risc_code_size = (fw->size - 6) / 2; |
1659 | 1668 | ||
1660 | for (i = 0; i < risc_code_size; i++) { | 1669 | for (i = 0; i < risc_code_size; i++) { |
1661 | mb[0] = MBC_WRITE_RAM_WORD; | 1670 | mb[0] = MBC_WRITE_RAM_WORD; |
1662 | mb[1] = risc_address + i; | 1671 | mb[1] = risc_address + i; |
1663 | mb[2] = risc_code_address[i]; | 1672 | mb[2] = __le16_to_cpu(fw_data[i]); |
1664 | 1673 | ||
1665 | err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb); | 1674 | err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb); |
1666 | if (err) { | 1675 | if (err) { |
1667 | printk(KERN_ERR "scsi(%li): Failed to load firmware\n", | 1676 | printk(KERN_ERR "scsi(%li): Failed to load firmware\n", |
1668 | ha->host_no); | 1677 | ha->host_no); |
1669 | return err; | 1678 | goto out; |
1670 | } | 1679 | } |
1671 | } | 1680 | } |
1672 | 1681 | out: | |
1673 | return 0; | 1682 | release_firmware(fw); |
1683 | return err; | ||
1674 | } | 1684 | } |
1675 | 1685 | ||
1676 | #define DUMP_IT_BACK 0 /* for debug of RISC loading */ | 1686 | #define DUMP_IT_BACK 0 /* for debug of RISC loading */ |
1677 | static int | 1687 | static int |
1678 | qla1280_load_firmware_dma(struct scsi_qla_host *ha) | 1688 | qla1280_load_firmware_dma(struct scsi_qla_host *ha) |
1679 | { | 1689 | { |
1680 | uint16_t risc_address, *risc_code_address, risc_code_size; | 1690 | const struct firmware *fw; |
1691 | const __le16 *fw_data; | ||
1692 | uint16_t risc_address, risc_code_size; | ||
1681 | uint16_t mb[MAILBOX_REGISTER_COUNT], cnt; | 1693 | uint16_t mb[MAILBOX_REGISTER_COUNT], cnt; |
1682 | int err = 0, num, i; | 1694 | int err = 0, num, i; |
1683 | #if DUMP_IT_BACK | 1695 | #if DUMP_IT_BACK |
@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1689 | return -ENOMEM; | 1701 | return -ENOMEM; |
1690 | #endif | 1702 | #endif |
1691 | 1703 | ||
1704 | err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, | ||
1705 | &ha->pdev->dev); | ||
1706 | if (err) { | ||
1707 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | ||
1708 | ql1280_board_tbl[ha->devnum].fwname, err); | ||
1709 | return err; | ||
1710 | } | ||
1711 | if ((fw->size % 2) || (fw->size < 6)) { | ||
1712 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", | ||
1713 | fw->size, ql1280_board_tbl[ha->devnum].fwname); | ||
1714 | err = -EINVAL; | ||
1715 | goto out; | ||
1716 | } | ||
1717 | ha->fwver1 = fw->data[0]; | ||
1718 | ha->fwver2 = fw->data[1]; | ||
1719 | ha->fwver3 = fw->data[2]; | ||
1720 | fw_data = (const __le16 *)&fw->data[0]; | ||
1721 | ha->fwstart = __le16_to_cpu(fw_data[2]); | ||
1722 | |||
1692 | /* Load RISC code. */ | 1723 | /* Load RISC code. */ |
1693 | risc_address = *ql1280_board_tbl[ha->devnum].fwstart; | 1724 | risc_address = ha->fwstart; |
1694 | risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; | 1725 | fw_data = (const __le16 *)&fw->data[4]; |
1695 | risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; | 1726 | risc_code_size = (fw->size - 6) / 2; |
1696 | 1727 | ||
1697 | dprintk(1, "%s: DMA RISC code (%i) words\n", | 1728 | dprintk(1, "%s: DMA RISC code (%i) words\n", |
1698 | __func__, risc_code_size); | 1729 | __func__, risc_code_size); |
@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1708 | 1739 | ||
1709 | dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," | 1740 | dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," |
1710 | "%d,%d(0x%x)\n", | 1741 | "%d,%d(0x%x)\n", |
1711 | risc_code_address, cnt, num, risc_address); | 1742 | fw_data, cnt, num, risc_address); |
1712 | for(i = 0; i < cnt; i++) | 1743 | for(i = 0; i < cnt; i++) |
1713 | ((__le16 *)ha->request_ring)[i] = | 1744 | ((__le16 *)ha->request_ring)[i] = fw_data[i]; |
1714 | cpu_to_le16(risc_code_address[i]); | ||
1715 | 1745 | ||
1716 | mb[0] = MBC_LOAD_RAM; | 1746 | mb[0] = MBC_LOAD_RAM; |
1717 | mb[1] = risc_address; | 1747 | mb[1] = risc_address; |
@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1763 | #endif | 1793 | #endif |
1764 | risc_address += cnt; | 1794 | risc_address += cnt; |
1765 | risc_code_size = risc_code_size - cnt; | 1795 | risc_code_size = risc_code_size - cnt; |
1766 | risc_code_address = risc_code_address + cnt; | 1796 | fw_data = fw_data + cnt; |
1767 | num++; | 1797 | num++; |
1768 | } | 1798 | } |
1769 | 1799 | ||
@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1771 | #if DUMP_IT_BACK | 1801 | #if DUMP_IT_BACK |
1772 | pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); | 1802 | pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); |
1773 | #endif | 1803 | #endif |
1804 | release_firmware(fw); | ||
1774 | return err; | 1805 | return err; |
1775 | } | 1806 | } |
1776 | 1807 | ||
@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) | |||
1786 | /* Verify checksum of loaded RISC code. */ | 1817 | /* Verify checksum of loaded RISC code. */ |
1787 | mb[0] = MBC_VERIFY_CHECKSUM; | 1818 | mb[0] = MBC_VERIFY_CHECKSUM; |
1788 | /* mb[1] = ql12_risc_code_addr01; */ | 1819 | /* mb[1] = ql12_risc_code_addr01; */ |
1789 | mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; | 1820 | mb[1] = ha->fwstart; |
1790 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb); | 1821 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb); |
1791 | if (err) { | 1822 | if (err) { |
1792 | printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no); | 1823 | printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no); |
@@ -1796,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) | |||
1796 | /* Start firmware execution. */ | 1827 | /* Start firmware execution. */ |
1797 | dprintk(1, "%s: start firmware running.\n", __func__); | 1828 | dprintk(1, "%s: start firmware running.\n", __func__); |
1798 | mb[0] = MBC_EXECUTE_FIRMWARE; | 1829 | mb[0] = MBC_EXECUTE_FIRMWARE; |
1799 | mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; | 1830 | mb[1] = ha->fwstart; |
1800 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); | 1831 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); |
1801 | if (err) { | 1832 | if (err) { |
1802 | printk(KERN_ERR "scsi(%li): Failed to start firmware\n", | 1833 | printk(KERN_ERR "scsi(%li): Failed to start firmware\n", |
@@ -4450,6 +4481,9 @@ module_exit(qla1280_exit); | |||
4450 | MODULE_AUTHOR("Qlogic & Jes Sorensen"); | 4481 | MODULE_AUTHOR("Qlogic & Jes Sorensen"); |
4451 | MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); | 4482 | MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); |
4452 | MODULE_LICENSE("GPL"); | 4483 | MODULE_LICENSE("GPL"); |
4484 | MODULE_FIRMWARE("qlogic/1040.bin"); | ||
4485 | MODULE_FIRMWARE("qlogic/1280.bin"); | ||
4486 | MODULE_FIRMWARE("qlogic/12160.bin"); | ||
4453 | MODULE_VERSION(QLA1280_VERSION); | 4487 | MODULE_VERSION(QLA1280_VERSION); |
4454 | 4488 | ||
4455 | /* | 4489 | /* |