diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/Kconfig | 69 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 24 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 189 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 156 |
7 files changed, 348 insertions, 98 deletions
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index c1c1c687bcbd..5205c4e7d6ff 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -1,55 +1,70 @@ | |||
1 | config SCSI_QLA2XXX | 1 | config SCSI_QLA2XXX |
2 | tristate | 2 | tristate "QLogic QLA2XXX Fibre Channel Support" |
3 | default (SCSI && PCI) | 3 | depends on PCI && SCSI |
4 | depends on SCSI && PCI | 4 | select SCSI_FC_ATTRS |
5 | select FW_LOADER | ||
6 | ---help--- | ||
7 | This qla2xxx driver supports all QLogic Fibre Channel | ||
8 | PCI and PCIe host adapters. | ||
5 | 9 | ||
6 | config SCSI_QLA21XX | 10 | By default, firmware for the ISP parts will be loaded |
7 | tristate "QLogic ISP2100 host adapter family support" | 11 | via the Firmware Loader interface. |
12 | |||
13 | ISP Firmware Filename | ||
14 | ---------- ----------------- | ||
15 | 21xx ql2100_fw.bin | ||
16 | 22xx ql2200_fw.bin | ||
17 | 2300, 2312 ql2300_fw.bin | ||
18 | 2322 ql2322_fw.bin | ||
19 | 6312, 6322 ql6312_fw.bin | ||
20 | 24xx ql2400_fw.bin | ||
21 | |||
22 | Upon request, the driver caches the firmware image until | ||
23 | the driver is unloaded. | ||
24 | |||
25 | NOTE: The original method of building firmware-loader | ||
26 | modules has been deprecated as the firmware-images will | ||
27 | be removed from the kernel sources. | ||
28 | |||
29 | config SCSI_QLA2XXX_EMBEDDED_FIRMWARE | ||
30 | bool " Use firmware-loader modules (DEPRECATED)" | ||
8 | depends on SCSI_QLA2XXX | 31 | depends on SCSI_QLA2XXX |
9 | select SCSI_FC_ATTRS | 32 | |
10 | select FW_LOADER | 33 | config SCSI_QLA21XX |
34 | tristate " Build QLogic ISP2100 firmware-module" | ||
35 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE | ||
11 | ---help--- | 36 | ---help--- |
12 | This driver supports the QLogic 21xx (ISP2100) host adapter family. | 37 | This driver supports the QLogic 21xx (ISP2100) host adapter family. |
13 | 38 | ||
14 | config SCSI_QLA22XX | 39 | config SCSI_QLA22XX |
15 | tristate "QLogic ISP2200 host adapter family support" | 40 | tristate " Build QLogic ISP2200 firmware-module" |
16 | depends on SCSI_QLA2XXX | 41 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE |
17 | select SCSI_FC_ATTRS | ||
18 | select FW_LOADER | ||
19 | ---help--- | 42 | ---help--- |
20 | This driver supports the QLogic 22xx (ISP2200) host adapter family. | 43 | This driver supports the QLogic 22xx (ISP2200) host adapter family. |
21 | 44 | ||
22 | config SCSI_QLA2300 | 45 | config SCSI_QLA2300 |
23 | tristate "QLogic ISP2300 host adapter family support" | 46 | tristate " Build QLogic ISP2300 firmware-module" |
24 | depends on SCSI_QLA2XXX | 47 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE |
25 | select SCSI_FC_ATTRS | ||
26 | select FW_LOADER | ||
27 | ---help--- | 48 | ---help--- |
28 | This driver supports the QLogic 2300 (ISP2300 and ISP2312) host | 49 | This driver supports the QLogic 2300 (ISP2300 and ISP2312) host |
29 | adapter family. | 50 | adapter family. |
30 | 51 | ||
31 | config SCSI_QLA2322 | 52 | config SCSI_QLA2322 |
32 | tristate "QLogic ISP2322 host adapter family support" | 53 | tristate " Build QLogic ISP2322 firmware-module" |
33 | depends on SCSI_QLA2XXX | 54 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE |
34 | select SCSI_FC_ATTRS | ||
35 | select FW_LOADER | ||
36 | ---help--- | 55 | ---help--- |
37 | This driver supports the QLogic 2322 (ISP2322) host adapter family. | 56 | This driver supports the QLogic 2322 (ISP2322) host adapter family. |
38 | 57 | ||
39 | config SCSI_QLA6312 | 58 | config SCSI_QLA6312 |
40 | tristate "QLogic ISP63xx host adapter family support" | 59 | tristate " Build QLogic ISP63xx firmware-module" |
41 | depends on SCSI_QLA2XXX | 60 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE |
42 | select SCSI_FC_ATTRS | ||
43 | select FW_LOADER | ||
44 | ---help--- | 61 | ---help--- |
45 | This driver supports the QLogic 63xx (ISP6312 and ISP6322) host | 62 | This driver supports the QLogic 63xx (ISP6312 and ISP6322) host |
46 | adapter family. | 63 | adapter family. |
47 | 64 | ||
48 | config SCSI_QLA24XX | 65 | config SCSI_QLA24XX |
49 | tristate "QLogic ISP24xx host adapter family support" | 66 | tristate " Build QLogic ISP24xx firmware-module" |
50 | depends on SCSI_QLA2XXX | 67 | depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE |
51 | select SCSI_FC_ATTRS | ||
52 | select FW_LOADER | ||
53 | ---help--- | 68 | ---help--- |
54 | This driver supports the QLogic 24xx (ISP2422 and ISP2432) host | 69 | This driver supports the QLogic 24xx (ISP2422 and ISP2432) host |
55 | adapter family. | 70 | adapter family. |
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index b169687d08ff..549dfe410208 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile | |||
@@ -3,6 +3,8 @@ EXTRA_CFLAGS += -DUNIQUE_FW_NAME | |||
3 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ | 3 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ |
4 | qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o | 4 | qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o |
5 | 5 | ||
6 | obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx.o | ||
7 | |||
6 | qla2100-y := ql2100.o ql2100_fw.o | 8 | qla2100-y := ql2100.o ql2100_fw.o |
7 | qla2200-y := ql2200.o ql2200_fw.o | 9 | qla2200-y := ql2200.o ql2200_fw.o |
8 | qla2300-y := ql2300.o ql2300_fw.o | 10 | qla2300-y := ql2300.o ql2300_fw.o |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 48e460eef05a..2efca52dff50 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -232,7 +232,7 @@ static ssize_t | |||
232 | qla2x00_isp_name_show(struct class_device *cdev, char *buf) | 232 | qla2x00_isp_name_show(struct class_device *cdev, char *buf) |
233 | { | 233 | { |
234 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 234 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); |
235 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name); | 235 | return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); |
236 | } | 236 | } |
237 | 237 | ||
238 | static ssize_t | 238 | static ssize_t |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7096945ea234..ce0d88bbaa06 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/firmware.h> | ||
25 | #include <asm/semaphore.h> | 26 | #include <asm/semaphore.h> |
26 | 27 | ||
27 | #include <scsi/scsi.h> | 28 | #include <scsi/scsi.h> |
@@ -29,6 +30,7 @@ | |||
29 | #include <scsi/scsi_device.h> | 30 | #include <scsi/scsi_device.h> |
30 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
31 | 32 | ||
33 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
32 | #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) | 34 | #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) |
33 | #define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100) | 35 | #define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100) |
34 | #else | 36 | #else |
@@ -79,9 +81,23 @@ | |||
79 | #define IS_QLA2522(ha) 0 | 81 | #define IS_QLA2522(ha) 0 |
80 | #endif | 82 | #endif |
81 | 83 | ||
84 | #else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ | ||
85 | |||
86 | #define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100) | ||
87 | #define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200) | ||
88 | #define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300) | ||
89 | #define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312) | ||
90 | #define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322) | ||
91 | #define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312) | ||
92 | #define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322) | ||
93 | #define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422) | ||
94 | #define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) | ||
95 | #define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512) | ||
96 | #define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522) | ||
97 | #endif | ||
98 | |||
82 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 99 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
83 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 100 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
84 | |||
85 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) | 101 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) |
86 | #define IS_QLA25XX(ha) (IS_QLA2512(ha) || IS_QLA2522(ha)) | 102 | #define IS_QLA25XX(ha) (IS_QLA2512(ha) || IS_QLA2522(ha)) |
87 | 103 | ||
@@ -2124,6 +2140,12 @@ struct qla_board_info { | |||
2124 | struct scsi_host_template *sht; | 2140 | struct scsi_host_template *sht; |
2125 | }; | 2141 | }; |
2126 | 2142 | ||
2143 | struct fw_blob { | ||
2144 | char *name; | ||
2145 | uint32_t segs[4]; | ||
2146 | const struct firmware *fw; | ||
2147 | }; | ||
2148 | |||
2127 | /* Return data from MBC_GET_ID_LIST call. */ | 2149 | /* Return data from MBC_GET_ID_LIST call. */ |
2128 | struct gid_list_info { | 2150 | struct gid_list_info { |
2129 | uint8_t al_pa; | 2151 | uint8_t al_pa; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index fedcb0d3fc72..bec81adcf4fd 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -33,8 +33,8 @@ extern int qla24xx_nvram_config(struct scsi_qla_host *); | |||
33 | extern void qla2x00_update_fw_options(struct scsi_qla_host *); | 33 | extern void qla2x00_update_fw_options(struct scsi_qla_host *); |
34 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); | 34 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); |
35 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); | 35 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); |
36 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); | ||
36 | extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *); | 37 | extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *); |
37 | extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *); | ||
38 | 38 | ||
39 | extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t); | 39 | extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t); |
40 | 40 | ||
@@ -76,6 +76,8 @@ extern void qla2x00_blink_led(scsi_qla_host_t *); | |||
76 | 76 | ||
77 | extern int qla2x00_down_timeout(struct semaphore *, unsigned long); | 77 | extern int qla2x00_down_timeout(struct semaphore *, unsigned long); |
78 | 78 | ||
79 | extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); | ||
80 | |||
79 | /* | 81 | /* |
80 | * Global Function Prototypes in qla_iocb.c source file. | 82 | * Global Function Prototypes in qla_iocb.c source file. |
81 | */ | 83 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 2d720121a0d3..13e2aaf56769 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/vmalloc.h> | 10 | #include <linux/vmalloc.h> |
11 | #include <linux/firmware.h> | ||
12 | #include <scsi/scsi_transport_fc.h> | 11 | #include <scsi/scsi_transport_fc.h> |
13 | 12 | ||
14 | #include "qla_devtbl.h" | 13 | #include "qla_devtbl.h" |
@@ -3484,17 +3483,16 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3484 | return (rval); | 3483 | return (rval); |
3485 | } | 3484 | } |
3486 | 3485 | ||
3486 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
3487 | |||
3487 | int | 3488 | int |
3488 | qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3489 | qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
3489 | { | 3490 | { |
3490 | int rval; | 3491 | int rval, num, i; |
3491 | uint16_t cnt; | 3492 | uint32_t cnt; |
3492 | uint16_t *risc_code; | 3493 | uint16_t *risc_code; |
3493 | unsigned long risc_address; | 3494 | uint32_t risc_addr, risc_size; |
3494 | unsigned long risc_code_size; | 3495 | uint16_t *req_ring; |
3495 | int num; | ||
3496 | int i; | ||
3497 | uint16_t *req_ring; | ||
3498 | struct qla_fw_info *fw_iter; | 3496 | struct qla_fw_info *fw_iter; |
3499 | 3497 | ||
3500 | rval = QLA_SUCCESS; | 3498 | rval = QLA_SUCCESS; |
@@ -3504,37 +3502,29 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3504 | *srisc_addr = *ha->brd_info->fw_info->fwstart; | 3502 | *srisc_addr = *ha->brd_info->fw_info->fwstart; |
3505 | while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) { | 3503 | while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) { |
3506 | risc_code = fw_iter->fwcode; | 3504 | risc_code = fw_iter->fwcode; |
3507 | risc_code_size = *fw_iter->fwlen; | 3505 | risc_size = *fw_iter->fwlen; |
3508 | 3506 | if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) | |
3509 | if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) { | 3507 | risc_addr = *fw_iter->fwstart; |
3510 | risc_address = *fw_iter->fwstart; | 3508 | else |
3511 | } else { | 3509 | risc_addr = *fw_iter->lfwstart; |
3512 | /* Extended address */ | ||
3513 | risc_address = *fw_iter->lfwstart; | ||
3514 | } | ||
3515 | 3510 | ||
3516 | num = 0; | 3511 | num = 0; |
3517 | rval = 0; | 3512 | rval = 0; |
3518 | while (risc_code_size > 0 && !rval) { | 3513 | while (risc_size > 0 && !rval) { |
3519 | cnt = (uint16_t)(ha->fw_transfer_size >> 1); | 3514 | cnt = (uint16_t)(ha->fw_transfer_size >> 1); |
3520 | if (cnt > risc_code_size) | 3515 | if (cnt > risc_size) |
3521 | cnt = risc_code_size; | 3516 | cnt = risc_size; |
3522 | 3517 | ||
3523 | DEBUG7(printk("scsi(%ld): Loading risc segment@ " | 3518 | DEBUG7(printk("scsi(%ld): Loading risc segment@ " |
3524 | "addr %p, number of bytes 0x%x, offset 0x%lx.\n", | 3519 | "addr %p, number of bytes 0x%x, offset 0x%lx.\n", |
3525 | ha->host_no, risc_code, cnt, risc_address)); | 3520 | ha->host_no, risc_code, cnt, risc_addr)); |
3526 | 3521 | ||
3527 | req_ring = (uint16_t *)ha->request_ring; | 3522 | req_ring = (uint16_t *)ha->request_ring; |
3528 | for (i = 0; i < cnt; i++) | 3523 | for (i = 0; i < cnt; i++) |
3529 | req_ring[i] = cpu_to_le16(risc_code[i]); | 3524 | req_ring[i] = cpu_to_le16(risc_code[i]); |
3530 | 3525 | ||
3531 | if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) { | 3526 | rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr, |
3532 | rval = qla2x00_load_ram(ha, ha->request_dma, | 3527 | cnt); |
3533 | risc_address, cnt); | ||
3534 | } else { | ||
3535 | rval = qla2x00_load_ram_ext(ha, | ||
3536 | ha->request_dma, risc_address, cnt); | ||
3537 | } | ||
3538 | if (rval) { | 3528 | if (rval) { |
3539 | DEBUG(printk("scsi(%ld): [ERROR] Failed to " | 3529 | DEBUG(printk("scsi(%ld): [ERROR] Failed to " |
3540 | "load segment %d of firmware\n", | 3530 | "load segment %d of firmware\n", |
@@ -3548,16 +3538,15 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3548 | } | 3538 | } |
3549 | 3539 | ||
3550 | risc_code += cnt; | 3540 | risc_code += cnt; |
3551 | risc_address += cnt; | 3541 | risc_addr += cnt; |
3552 | risc_code_size -= cnt; | 3542 | risc_size -= cnt; |
3553 | num++; | 3543 | num++; |
3554 | } | 3544 | } |
3555 | 3545 | ||
3556 | /* Next firmware sequence */ | 3546 | /* Next firmware sequence */ |
3557 | fw_iter++; | 3547 | fw_iter++; |
3558 | } | 3548 | } |
3559 | 3549 | return rval; | |
3560 | return (rval); | ||
3561 | } | 3550 | } |
3562 | 3551 | ||
3563 | int | 3552 | int |
@@ -3642,8 +3631,108 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3642 | return rval; | 3631 | return rval; |
3643 | } | 3632 | } |
3644 | 3633 | ||
3634 | #else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ | ||
3635 | |||
3645 | int | 3636 | int |
3646 | qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3637 | qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
3638 | { | ||
3639 | int rval; | ||
3640 | int i, fragment; | ||
3641 | uint16_t *wcode, *fwcode; | ||
3642 | uint32_t risc_addr, risc_size, fwclen, wlen, *seg; | ||
3643 | struct fw_blob *blob; | ||
3644 | |||
3645 | /* Load firmware blob. */ | ||
3646 | blob = qla2x00_request_firmware(ha); | ||
3647 | if (!blob) { | ||
3648 | qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n"); | ||
3649 | return QLA_FUNCTION_FAILED; | ||
3650 | } | ||
3651 | |||
3652 | rval = QLA_SUCCESS; | ||
3653 | |||
3654 | wcode = (uint16_t *)ha->request_ring; | ||
3655 | *srisc_addr = 0; | ||
3656 | fwcode = (uint16_t *)blob->fw->data; | ||
3657 | fwclen = 0; | ||
3658 | |||
3659 | /* Validate firmware image by checking version. */ | ||
3660 | if (blob->fw->size < 8 * sizeof(uint16_t)) { | ||
3661 | qla_printk(KERN_WARNING, ha, | ||
3662 | "Unable to verify integrity of firmware image (%Zd)!\n", | ||
3663 | blob->fw->size); | ||
3664 | goto fail_fw_integrity; | ||
3665 | } | ||
3666 | for (i = 0; i < 4; i++) | ||
3667 | wcode[i] = be16_to_cpu(fwcode[i + 4]); | ||
3668 | if ((wcode[0] == 0xffff && wcode[1] == 0xffff && wcode[2] == 0xffff && | ||
3669 | wcode[3] == 0xffff) || (wcode[0] == 0 && wcode[1] == 0 && | ||
3670 | wcode[2] == 0 && wcode[3] == 0)) { | ||
3671 | qla_printk(KERN_WARNING, ha, | ||
3672 | "Unable to verify integrity of firmware image!\n"); | ||
3673 | qla_printk(KERN_WARNING, ha, | ||
3674 | "Firmware data: %04x %04x %04x %04x!\n", wcode[0], | ||
3675 | wcode[1], wcode[2], wcode[3]); | ||
3676 | goto fail_fw_integrity; | ||
3677 | } | ||
3678 | |||
3679 | seg = blob->segs; | ||
3680 | while (*seg && rval == QLA_SUCCESS) { | ||
3681 | risc_addr = *seg; | ||
3682 | *srisc_addr = *srisc_addr == 0 ? *seg : *srisc_addr; | ||
3683 | risc_size = be16_to_cpu(fwcode[3]); | ||
3684 | |||
3685 | /* Validate firmware image size. */ | ||
3686 | fwclen += risc_size * sizeof(uint16_t); | ||
3687 | if (blob->fw->size < fwclen) { | ||
3688 | qla_printk(KERN_WARNING, ha, | ||
3689 | "Unable to verify integrity of firmware image " | ||
3690 | "(%Zd)!\n", blob->fw->size); | ||
3691 | goto fail_fw_integrity; | ||
3692 | } | ||
3693 | |||
3694 | fragment = 0; | ||
3695 | while (risc_size > 0 && rval == QLA_SUCCESS) { | ||
3696 | wlen = (uint16_t)(ha->fw_transfer_size >> 1); | ||
3697 | if (wlen > risc_size) | ||
3698 | wlen = risc_size; | ||
3699 | |||
3700 | DEBUG7(printk("scsi(%ld): Loading risc segment@ risc " | ||
3701 | "addr %x, number of words 0x%x.\n", ha->host_no, | ||
3702 | risc_addr, wlen)); | ||
3703 | |||
3704 | for (i = 0; i < wlen; i++) | ||
3705 | wcode[i] = swab16(fwcode[i]); | ||
3706 | |||
3707 | rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr, | ||
3708 | wlen); | ||
3709 | if (rval) { | ||
3710 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " | ||
3711 | "segment %d of firmware\n", ha->host_no, | ||
3712 | fragment)); | ||
3713 | qla_printk(KERN_WARNING, ha, | ||
3714 | "[ERROR] Failed to load segment %d of " | ||
3715 | "firmware\n", fragment); | ||
3716 | break; | ||
3717 | } | ||
3718 | |||
3719 | fwcode += wlen; | ||
3720 | risc_addr += wlen; | ||
3721 | risc_size -= wlen; | ||
3722 | fragment++; | ||
3723 | } | ||
3724 | |||
3725 | /* Next segment. */ | ||
3726 | seg++; | ||
3727 | } | ||
3728 | return rval; | ||
3729 | |||
3730 | fail_fw_integrity: | ||
3731 | return QLA_FUNCTION_FAILED; | ||
3732 | } | ||
3733 | |||
3734 | int | ||
3735 | qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | ||
3647 | { | 3736 | { |
3648 | int rval; | 3737 | int rval; |
3649 | int segments, fragment; | 3738 | int segments, fragment; |
@@ -3651,14 +3740,13 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3651 | uint32_t risc_addr; | 3740 | uint32_t risc_addr; |
3652 | uint32_t risc_size; | 3741 | uint32_t risc_size; |
3653 | uint32_t i; | 3742 | uint32_t i; |
3654 | const struct firmware *fw_entry; | 3743 | struct fw_blob *blob; |
3655 | uint32_t *fwcode, fwclen; | 3744 | uint32_t *fwcode, fwclen; |
3656 | 3745 | ||
3657 | if (request_firmware(&fw_entry, ha->brd_info->fw_fname, | 3746 | /* Load firmware blob. */ |
3658 | &ha->pdev->dev)) { | 3747 | blob = qla2x00_request_firmware(ha); |
3659 | qla_printk(KERN_ERR, ha, | 3748 | if (!blob) { |
3660 | "Firmware image file not available: '%s'\n", | 3749 | qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n"); |
3661 | ha->brd_info->fw_fname); | ||
3662 | return QLA_FUNCTION_FAILED; | 3750 | return QLA_FUNCTION_FAILED; |
3663 | } | 3751 | } |
3664 | 3752 | ||
@@ -3667,14 +3755,14 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3667 | segments = FA_RISC_CODE_SEGMENTS; | 3755 | segments = FA_RISC_CODE_SEGMENTS; |
3668 | dcode = (uint32_t *)ha->request_ring; | 3756 | dcode = (uint32_t *)ha->request_ring; |
3669 | *srisc_addr = 0; | 3757 | *srisc_addr = 0; |
3670 | fwcode = (uint32_t *)fw_entry->data; | 3758 | fwcode = (uint32_t *)blob->fw->data; |
3671 | fwclen = 0; | 3759 | fwclen = 0; |
3672 | 3760 | ||
3673 | /* Validate firmware image by checking version. */ | 3761 | /* Validate firmware image by checking version. */ |
3674 | if (fw_entry->size < 8 * sizeof(uint32_t)) { | 3762 | if (blob->fw->size < 8 * sizeof(uint32_t)) { |
3675 | qla_printk(KERN_WARNING, ha, | 3763 | qla_printk(KERN_WARNING, ha, |
3676 | "Unable to verify integrity of flash firmware image " | 3764 | "Unable to verify integrity of firmware image (%Zd)!\n", |
3677 | "(%Zd)!\n", fw_entry->size); | 3765 | blob->fw->size); |
3678 | goto fail_fw_integrity; | 3766 | goto fail_fw_integrity; |
3679 | } | 3767 | } |
3680 | for (i = 0; i < 4; i++) | 3768 | for (i = 0; i < 4; i++) |
@@ -3684,7 +3772,7 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3684 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | 3772 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && |
3685 | dcode[3] == 0)) { | 3773 | dcode[3] == 0)) { |
3686 | qla_printk(KERN_WARNING, ha, | 3774 | qla_printk(KERN_WARNING, ha, |
3687 | "Unable to verify integrity of flash firmware image!\n"); | 3775 | "Unable to verify integrity of firmware image!\n"); |
3688 | qla_printk(KERN_WARNING, ha, | 3776 | qla_printk(KERN_WARNING, ha, |
3689 | "Firmware data: %08x %08x %08x %08x!\n", dcode[0], | 3777 | "Firmware data: %08x %08x %08x %08x!\n", dcode[0], |
3690 | dcode[1], dcode[2], dcode[3]); | 3778 | dcode[1], dcode[2], dcode[3]); |
@@ -3698,10 +3786,11 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3698 | 3786 | ||
3699 | /* Validate firmware image size. */ | 3787 | /* Validate firmware image size. */ |
3700 | fwclen += risc_size * sizeof(uint32_t); | 3788 | fwclen += risc_size * sizeof(uint32_t); |
3701 | if (fw_entry->size < fwclen) { | 3789 | if (blob->fw->size < fwclen) { |
3702 | qla_printk(KERN_WARNING, ha, | 3790 | qla_printk(KERN_WARNING, ha, |
3703 | "Unable to verify integrity of flash firmware " | 3791 | "Unable to verify integrity of firmware image " |
3704 | "image (%Zd)!\n", fw_entry->size); | 3792 | "(%Zd)!\n", blob->fw->size); |
3793 | |||
3705 | goto fail_fw_integrity; | 3794 | goto fail_fw_integrity; |
3706 | } | 3795 | } |
3707 | 3796 | ||
@@ -3739,13 +3828,9 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3739 | /* Next segment. */ | 3828 | /* Next segment. */ |
3740 | segments--; | 3829 | segments--; |
3741 | } | 3830 | } |
3742 | |||
3743 | release_firmware(fw_entry); | ||
3744 | return rval; | 3831 | return rval; |
3745 | 3832 | ||
3746 | fail_fw_integrity: | 3833 | fail_fw_integrity: |
3747 | |||
3748 | release_firmware(fw_entry); | ||
3749 | return QLA_FUNCTION_FAILED; | 3834 | return QLA_FUNCTION_FAILED; |
3750 | |||
3751 | } | 3835 | } |
3836 | #endif | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c58c9d97b041..47db029b2fce 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -54,11 +54,6 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); | |||
54 | MODULE_PARM_DESC(ql2xloginretrycount, | 54 | MODULE_PARM_DESC(ql2xloginretrycount, |
55 | "Specify an alternate value for the NVRAM login retry count."); | 55 | "Specify an alternate value for the NVRAM login retry count."); |
56 | 56 | ||
57 | int ql2xfwloadbin=1; | ||
58 | module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR); | ||
59 | MODULE_PARM_DESC(ql2xfwloadbin, | ||
60 | "Load ISP2xxx firmware image via hotplug."); | ||
61 | |||
62 | static void qla2x00_free_device(scsi_qla_host_t *); | 57 | static void qla2x00_free_device(scsi_qla_host_t *); |
63 | 58 | ||
64 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | 59 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); |
@@ -1261,12 +1256,16 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1261 | char pci_info[20]; | 1256 | char pci_info[20]; |
1262 | char fw_str[30]; | 1257 | char fw_str[30]; |
1263 | fc_port_t *fcport; | 1258 | fc_port_t *fcport; |
1259 | struct scsi_host_template *sht; | ||
1264 | 1260 | ||
1265 | if (pci_enable_device(pdev)) | 1261 | if (pci_enable_device(pdev)) |
1266 | goto probe_out; | 1262 | goto probe_out; |
1267 | 1263 | ||
1268 | host = scsi_host_alloc(brd_info->sht ? brd_info->sht: | 1264 | sht = &qla2x00_driver_template; |
1269 | &qla2x00_driver_template, sizeof(scsi_qla_host_t)); | 1265 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1266 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) | ||
1267 | sht = &qla24xx_driver_template; | ||
1268 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); | ||
1270 | if (host == NULL) { | 1269 | if (host == NULL) { |
1271 | printk(KERN_WARNING | 1270 | printk(KERN_WARNING |
1272 | "qla2xxx: Couldn't allocate host from scsi layer!\n"); | 1271 | "qla2xxx: Couldn't allocate host from scsi layer!\n"); |
@@ -1291,8 +1290,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1291 | goto probe_failed; | 1290 | goto probe_failed; |
1292 | 1291 | ||
1293 | qla_printk(KERN_INFO, ha, | 1292 | qla_printk(KERN_INFO, ha, |
1294 | "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name, | 1293 | "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq, |
1295 | pdev->irq, ha->iobase); | 1294 | ha->iobase); |
1296 | 1295 | ||
1297 | spin_lock_init(&ha->hardware_lock); | 1296 | spin_lock_init(&ha->hardware_lock); |
1298 | 1297 | ||
@@ -1368,9 +1367,11 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1368 | ha->isp_ops.reset_adapter = qla24xx_reset_adapter; | 1367 | ha->isp_ops.reset_adapter = qla24xx_reset_adapter; |
1369 | ha->isp_ops.nvram_config = qla24xx_nvram_config; | 1368 | ha->isp_ops.nvram_config = qla24xx_nvram_config; |
1370 | ha->isp_ops.update_fw_options = qla24xx_update_fw_options; | 1369 | ha->isp_ops.update_fw_options = qla24xx_update_fw_options; |
1370 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
1371 | ha->isp_ops.load_risc = qla24xx_load_risc_flash; | 1371 | ha->isp_ops.load_risc = qla24xx_load_risc_flash; |
1372 | if (ql2xfwloadbin) | 1372 | #else |
1373 | ha->isp_ops.load_risc = qla24xx_load_risc_hotplug; | 1373 | ha->isp_ops.load_risc = qla24xx_load_risc; |
1374 | #endif | ||
1374 | ha->isp_ops.pci_info_str = qla24xx_pci_info_str; | 1375 | ha->isp_ops.pci_info_str = qla24xx_pci_info_str; |
1375 | ha->isp_ops.fw_version_str = qla24xx_fw_version_str; | 1376 | ha->isp_ops.fw_version_str = qla24xx_fw_version_str; |
1376 | ha->isp_ops.intr_handler = qla24xx_intr_handler; | 1377 | ha->isp_ops.intr_handler = qla24xx_intr_handler; |
@@ -1531,11 +1532,12 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1531 | qla_printk(KERN_INFO, ha, "\n" | 1532 | qla_printk(KERN_INFO, ha, "\n" |
1532 | " QLogic Fibre Channel HBA Driver: %s\n" | 1533 | " QLogic Fibre Channel HBA Driver: %s\n" |
1533 | " QLogic %s - %s\n" | 1534 | " QLogic %s - %s\n" |
1534 | " %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str, | 1535 | " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n", |
1535 | ha->model_number, ha->model_desc ? ha->model_desc: "", | 1536 | qla2x00_version_str, ha->model_number, |
1536 | ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info), | 1537 | ha->model_desc ? ha->model_desc: "", pdev->device, |
1537 | pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-', | 1538 | ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev), |
1538 | ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str)); | 1539 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, |
1540 | ha->isp_ops.fw_version_str(ha, fw_str)); | ||
1539 | 1541 | ||
1540 | /* Go with fc_rport registration. */ | 1542 | /* Go with fc_rport registration. */ |
1541 | list_for_each_entry(fcport, &ha->fcports, list) | 1543 | list_for_each_entry(fcport, &ha->fcports, list) |
@@ -2483,6 +2485,10 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) | |||
2483 | return -ETIMEDOUT; | 2485 | return -ETIMEDOUT; |
2484 | } | 2486 | } |
2485 | 2487 | ||
2488 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
2489 | |||
2490 | #define qla2x00_release_firmware() do { } while (0) | ||
2491 | |||
2486 | static struct qla_board_info qla_board_tbl[] = { | 2492 | static struct qla_board_info qla_board_tbl[] = { |
2487 | { | 2493 | { |
2488 | .drv_name = "qla2400", | 2494 | .drv_name = "qla2400", |
@@ -2530,8 +2536,122 @@ qla2xxx_remove_one(struct pci_dev *pdev) | |||
2530 | qla2x00_remove_one(pdev); | 2536 | qla2x00_remove_one(pdev); |
2531 | } | 2537 | } |
2532 | 2538 | ||
2539 | #else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ | ||
2540 | |||
2541 | /* Firmware interface routines. */ | ||
2542 | |||
2543 | #define FW_BLOBS 6 | ||
2544 | #define FW_ISP21XX 0 | ||
2545 | #define FW_ISP22XX 1 | ||
2546 | #define FW_ISP2300 2 | ||
2547 | #define FW_ISP2322 3 | ||
2548 | #define FW_ISP63XX 4 | ||
2549 | #define FW_ISP24XX 5 | ||
2550 | |||
2551 | static DECLARE_MUTEX(qla_fw_lock); | ||
2552 | |||
2553 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | ||
2554 | { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, }, | ||
2555 | { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, }, | ||
2556 | { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, }, | ||
2557 | { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, | ||
2558 | { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, }, | ||
2559 | { .name = "ql2400_fw.bin", }, | ||
2560 | }; | ||
2561 | |||
2562 | struct fw_blob * | ||
2563 | qla2x00_request_firmware(scsi_qla_host_t *ha) | ||
2564 | { | ||
2565 | struct fw_blob *blob; | ||
2566 | |||
2567 | blob = NULL; | ||
2568 | if (IS_QLA2100(ha)) { | ||
2569 | blob = &qla_fw_blobs[FW_ISP21XX]; | ||
2570 | } else if (IS_QLA2200(ha)) { | ||
2571 | blob = &qla_fw_blobs[FW_ISP22XX]; | ||
2572 | } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) { | ||
2573 | blob = &qla_fw_blobs[FW_ISP2300]; | ||
2574 | } else if (IS_QLA2322(ha)) { | ||
2575 | blob = &qla_fw_blobs[FW_ISP2322]; | ||
2576 | } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) { | ||
2577 | blob = &qla_fw_blobs[FW_ISP63XX]; | ||
2578 | } else if (IS_QLA24XX(ha)) { | ||
2579 | blob = &qla_fw_blobs[FW_ISP24XX]; | ||
2580 | } | ||
2581 | |||
2582 | down(&qla_fw_lock); | ||
2583 | if (blob->fw) | ||
2584 | goto out; | ||
2585 | |||
2586 | if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { | ||
2587 | DEBUG2(printk("scsi(%ld): Failed to load firmware image " | ||
2588 | "(%s).\n", ha->host_no, blob->name)); | ||
2589 | blob->fw = NULL; | ||
2590 | blob = NULL; | ||
2591 | goto out; | ||
2592 | } | ||
2593 | |||
2594 | out: | ||
2595 | up(&qla_fw_lock); | ||
2596 | return blob; | ||
2597 | } | ||
2598 | |||
2599 | static void | ||
2600 | qla2x00_release_firmware(void) | ||
2601 | { | ||
2602 | int idx; | ||
2603 | |||
2604 | down(&qla_fw_lock); | ||
2605 | for (idx = 0; idx < FW_BLOBS; idx++) | ||
2606 | if (qla_fw_blobs[idx].fw) | ||
2607 | release_firmware(qla_fw_blobs[idx].fw); | ||
2608 | up(&qla_fw_lock); | ||
2609 | } | ||
2610 | |||
2611 | static struct qla_board_info qla_board_tbl = { | ||
2612 | .drv_name = "qla2xxx", | ||
2613 | }; | ||
2614 | |||
2615 | static struct pci_device_id qla2xxx_pci_tbl[] = { | ||
2616 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100, | ||
2617 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2618 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200, | ||
2619 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2620 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300, | ||
2621 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2622 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312, | ||
2623 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2624 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322, | ||
2625 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2626 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312, | ||
2627 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2628 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322, | ||
2629 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2630 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422, | ||
2631 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2632 | { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432, | ||
2633 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
2634 | { 0 }, | ||
2635 | }; | ||
2636 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | ||
2637 | |||
2638 | static int __devinit | ||
2639 | qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
2640 | { | ||
2641 | return qla2x00_probe_one(pdev, &qla_board_tbl); | ||
2642 | } | ||
2643 | |||
2644 | static void __devexit | ||
2645 | qla2xxx_remove_one(struct pci_dev *pdev) | ||
2646 | { | ||
2647 | qla2x00_remove_one(pdev); | ||
2648 | } | ||
2649 | |||
2650 | #endif | ||
2651 | |||
2533 | static struct pci_driver qla2xxx_pci_driver = { | 2652 | static struct pci_driver qla2xxx_pci_driver = { |
2534 | .name = "qla2xxx", | 2653 | .name = "qla2xxx", |
2654 | .owner = THIS_MODULE, | ||
2535 | .id_table = qla2xxx_pci_tbl, | 2655 | .id_table = qla2xxx_pci_tbl, |
2536 | .probe = qla2xxx_probe_one, | 2656 | .probe = qla2xxx_probe_one, |
2537 | .remove = __devexit_p(qla2xxx_remove_one), | 2657 | .remove = __devexit_p(qla2xxx_remove_one), |
@@ -2556,6 +2676,9 @@ qla2x00_module_init(void) | |||
2556 | 2676 | ||
2557 | /* Derive version string. */ | 2677 | /* Derive version string. */ |
2558 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); | 2678 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); |
2679 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
2680 | strcat(qla2x00_version_str, "-fw"); | ||
2681 | #endif | ||
2559 | #if DEBUG_QLA2100 | 2682 | #if DEBUG_QLA2100 |
2560 | strcat(qla2x00_version_str, "-debug"); | 2683 | strcat(qla2x00_version_str, "-debug"); |
2561 | #endif | 2684 | #endif |
@@ -2580,6 +2703,7 @@ static void __exit | |||
2580 | qla2x00_module_exit(void) | 2703 | qla2x00_module_exit(void) |
2581 | { | 2704 | { |
2582 | pci_unregister_driver(&qla2xxx_pci_driver); | 2705 | pci_unregister_driver(&qla2xxx_pci_driver); |
2706 | qla2x00_release_firmware(); | ||
2583 | kmem_cache_destroy(srb_cachep); | 2707 | kmem_cache_destroy(srb_cachep); |
2584 | fc_release_transport(qla2xxx_transport_template); | 2708 | fc_release_transport(qla2xxx_transport_template); |
2585 | } | 2709 | } |