|
@@ -54,11 +54,6 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
|
|
|
MODULE_PARM_DESC(ql2xloginretrycount,
|
|
|
"Specify an alternate value for the NVRAM login retry count.");
|
|
|
|
|
|
-int ql2xfwloadbin=1;
|
|
|
-module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
|
|
|
-MODULE_PARM_DESC(ql2xfwloadbin,
|
|
|
- "Load ISP2xxx firmware image via hotplug.");
|
|
|
-
|
|
|
static void qla2x00_free_device(scsi_qla_host_t *);
|
|
|
|
|
|
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)
|
|
|
char pci_info[20];
|
|
|
char fw_str[30];
|
|
|
fc_port_t *fcport;
|
|
|
+ struct scsi_host_template *sht;
|
|
|
|
|
|
if (pci_enable_device(pdev))
|
|
|
goto probe_out;
|
|
|
|
|
|
- host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
|
|
|
- &qla2x00_driver_template, sizeof(scsi_qla_host_t));
|
|
|
+ sht = &qla2x00_driver_template;
|
|
|
+ if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
|
|
|
+ pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
|
|
|
+ sht = &qla24xx_driver_template;
|
|
|
+ host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
|
|
|
if (host == NULL) {
|
|
|
printk(KERN_WARNING
|
|
|
"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)
|
|
|
goto probe_failed;
|
|
|
|
|
|
qla_printk(KERN_INFO, ha,
|
|
|
- "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
|
|
|
- pdev->irq, ha->iobase);
|
|
|
+ "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
|
|
|
+ ha->iobase);
|
|
|
|
|
|
spin_lock_init(&ha->hardware_lock);
|
|
|
|
|
@@ -1368,9 +1367,11 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
|
|
ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
|
|
|
ha->isp_ops.nvram_config = qla24xx_nvram_config;
|
|
|
ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
|
|
|
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
|
|
|
ha->isp_ops.load_risc = qla24xx_load_risc_flash;
|
|
|
- if (ql2xfwloadbin)
|
|
|
- ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
|
|
|
+#else
|
|
|
+ ha->isp_ops.load_risc = qla24xx_load_risc;
|
|
|
+#endif
|
|
|
ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
|
|
|
ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
|
|
|
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)
|
|
|
qla_printk(KERN_INFO, ha, "\n"
|
|
|
" QLogic Fibre Channel HBA Driver: %s\n"
|
|
|
" QLogic %s - %s\n"
|
|
|
- " %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
|
|
|
- ha->model_number, ha->model_desc ? ha->model_desc: "",
|
|
|
- ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
|
|
|
- pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
|
|
|
- ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
|
|
|
+ " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
|
|
|
+ qla2x00_version_str, ha->model_number,
|
|
|
+ ha->model_desc ? ha->model_desc: "", pdev->device,
|
|
|
+ ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
|
|
|
+ ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
|
|
|
+ ha->isp_ops.fw_version_str(ha, fw_str));
|
|
|
|
|
|
/* Go with fc_rport registration. */
|
|
|
list_for_each_entry(fcport, &ha->fcports, list)
|
|
@@ -2483,6 +2485,10 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
|
|
|
return -ETIMEDOUT;
|
|
|
}
|
|
|
|
|
|
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
|
|
|
+
|
|
|
+#define qla2x00_release_firmware() do { } while (0)
|
|
|
+
|
|
|
static struct qla_board_info qla_board_tbl[] = {
|
|
|
{
|
|
|
.drv_name = "qla2400",
|
|
@@ -2530,8 +2536,122 @@ qla2xxx_remove_one(struct pci_dev *pdev)
|
|
|
qla2x00_remove_one(pdev);
|
|
|
}
|
|
|
|
|
|
+#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
|
|
|
+
|
|
|
+/* Firmware interface routines. */
|
|
|
+
|
|
|
+#define FW_BLOBS 6
|
|
|
+#define FW_ISP21XX 0
|
|
|
+#define FW_ISP22XX 1
|
|
|
+#define FW_ISP2300 2
|
|
|
+#define FW_ISP2322 3
|
|
|
+#define FW_ISP63XX 4
|
|
|
+#define FW_ISP24XX 5
|
|
|
+
|
|
|
+static DECLARE_MUTEX(qla_fw_lock);
|
|
|
+
|
|
|
+static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
|
|
|
+ { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
|
|
|
+ { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
|
|
|
+ { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
|
|
|
+ { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
|
|
|
+ { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
|
|
|
+ { .name = "ql2400_fw.bin", },
|
|
|
+};
|
|
|
+
|
|
|
+struct fw_blob *
|
|
|
+qla2x00_request_firmware(scsi_qla_host_t *ha)
|
|
|
+{
|
|
|
+ struct fw_blob *blob;
|
|
|
+
|
|
|
+ blob = NULL;
|
|
|
+ if (IS_QLA2100(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP21XX];
|
|
|
+ } else if (IS_QLA2200(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP22XX];
|
|
|
+ } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP2300];
|
|
|
+ } else if (IS_QLA2322(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP2322];
|
|
|
+ } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP63XX];
|
|
|
+ } else if (IS_QLA24XX(ha)) {
|
|
|
+ blob = &qla_fw_blobs[FW_ISP24XX];
|
|
|
+ }
|
|
|
+
|
|
|
+ down(&qla_fw_lock);
|
|
|
+ if (blob->fw)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
|
|
|
+ DEBUG2(printk("scsi(%ld): Failed to load firmware image "
|
|
|
+ "(%s).\n", ha->host_no, blob->name));
|
|
|
+ blob->fw = NULL;
|
|
|
+ blob = NULL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+out:
|
|
|
+ up(&qla_fw_lock);
|
|
|
+ return blob;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+qla2x00_release_firmware(void)
|
|
|
+{
|
|
|
+ int idx;
|
|
|
+
|
|
|
+ down(&qla_fw_lock);
|
|
|
+ for (idx = 0; idx < FW_BLOBS; idx++)
|
|
|
+ if (qla_fw_blobs[idx].fw)
|
|
|
+ release_firmware(qla_fw_blobs[idx].fw);
|
|
|
+ up(&qla_fw_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static struct qla_board_info qla_board_tbl = {
|
|
|
+ .drv_name = "qla2xxx",
|
|
|
+};
|
|
|
+
|
|
|
+static struct pci_device_id qla2xxx_pci_tbl[] = {
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID, },
|
|
|
+ { 0 },
|
|
|
+};
|
|
|
+MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
|
|
+
|
|
|
+static int __devinit
|
|
|
+qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
+{
|
|
|
+ return qla2x00_probe_one(pdev, &qla_board_tbl);
|
|
|
+}
|
|
|
+
|
|
|
+static void __devexit
|
|
|
+qla2xxx_remove_one(struct pci_dev *pdev)
|
|
|
+{
|
|
|
+ qla2x00_remove_one(pdev);
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
static struct pci_driver qla2xxx_pci_driver = {
|
|
|
.name = "qla2xxx",
|
|
|
+ .owner = THIS_MODULE,
|
|
|
.id_table = qla2xxx_pci_tbl,
|
|
|
.probe = qla2xxx_probe_one,
|
|
|
.remove = __devexit_p(qla2xxx_remove_one),
|
|
@@ -2556,6 +2676,9 @@ qla2x00_module_init(void)
|
|
|
|
|
|
/* Derive version string. */
|
|
|
strcpy(qla2x00_version_str, QLA2XXX_VERSION);
|
|
|
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
|
|
|
+ strcat(qla2x00_version_str, "-fw");
|
|
|
+#endif
|
|
|
#if DEBUG_QLA2100
|
|
|
strcat(qla2x00_version_str, "-debug");
|
|
|
#endif
|
|
@@ -2580,6 +2703,7 @@ static void __exit
|
|
|
qla2x00_module_exit(void)
|
|
|
{
|
|
|
pci_unregister_driver(&qla2xxx_pci_driver);
|
|
|
+ qla2x00_release_firmware();
|
|
|
kmem_cache_destroy(srb_cachep);
|
|
|
fc_release_transport(qla2xxx_transport_template);
|
|
|
}
|