提交 1bfa11db 编写于 作者: J Jaswinder Singh Rajput 提交者: James Bottomley

[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: NJaswinder Singh Rajput <jaswinderrajput@gmail.com>
Signed-off-by: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 fd6e1c14
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -348,6 +348,7 @@ ...@@ -348,6 +348,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -384,11 +385,7 @@ ...@@ -384,11 +385,7 @@
#define MEMORY_MAPPED_IO 1 #define MEMORY_MAPPED_IO 1
#endif #endif
#define UNIQUE_FW_NAME
#include "qla1280.h" #include "qla1280.h"
#include "ql12160_fw.h" /* ISP RISC codes */
#include "ql1280_fw.h"
#include "ql1040_fw.h"
#ifndef BITS_PER_LONG #ifndef BITS_PER_LONG
#error "BITS_PER_LONG not defined!" #error "BITS_PER_LONG not defined!"
...@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup); ...@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup);
struct qla_boards { struct qla_boards {
unsigned char name[9]; /* Board ID String */ unsigned char name[9]; /* Board ID String */
int numPorts; /* Number of SCSI ports */ int numPorts; /* Number of SCSI ports */
unsigned short *fwcode; /* pointer to FW array */ char *fwname; /* firmware name */
unsigned short *fwlen; /* number of words in array */
unsigned short *fwstart; /* start address for F/W */
unsigned char *fwver; /* Ptr to F/W version array */
}; };
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ /* 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,19 +561,13 @@ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
static struct qla_boards ql1280_board_tbl[] = { static struct qla_boards ql1280_board_tbl[] = {
/* Name , Number of ports, FW details */ /* Name , Number of ports, FW details */
{"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01, {"QLA12160", 2, "qlogic/12160.bin"},
&fw12160i_addr01, &fw12160i_version_str[0]}, {"QLA1040", 1, "qlogic/1040.bin"},
{"QLA1040", 1, &risc_code01[0], &risc_code_length01, {"QLA1080", 1, "qlogic/1280.bin"},
&risc_code_addr01, &firmware_version[0]}, {"QLA1240", 2, "qlogic/1280.bin"},
{"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01, {"QLA1280", 2, "qlogic/1280.bin"},
&fw1280ei_addr01, &fw1280ei_version_str[0]}, {"QLA10160", 1, "qlogic/12160.bin"},
{"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01, {" ", 0, " "},
&fw1280ei_addr01, &fw1280ei_version_str[0]},
{"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
{"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,
&fw12160i_addr01, &fw12160i_version_str[0]},
{" ", 0}
}; };
static int qla1280_verbose = 1; static int qla1280_verbose = 1;
...@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host) ...@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host)
sprintf (bp, sprintf (bp,
"QLogic %s PCI to SCSI Host Adapter\n" "QLogic %s PCI to SCSI Host Adapter\n"
" Firmware version: %2d.%02d.%02d, Driver version %s", " Firmware version: %2d.%02d.%02d, Driver version %s",
&bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], &bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3,
QLA1280_VERSION); QLA1280_VERSION);
return bp; return bp;
} }
...@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha) ...@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
static int static int
qla1280_load_firmware_pio(struct scsi_qla_host *ha) qla1280_load_firmware_pio(struct scsi_qla_host *ha)
{ {
uint16_t risc_address, *risc_code_address, risc_code_size; const struct firmware *fw;
const __le16 *fw_data;
uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], i; uint16_t mb[MAILBOX_REGISTER_COUNT], i;
int err; int err;
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
&ha->pdev->dev);
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
ql1280_board_tbl[ha->devnum].fwname, err);
return err;
}
if ((fw->size % 2) || (fw->size < 6)) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, ql1280_board_tbl[ha->devnum].fwname);
err = -EINVAL;
goto out;
}
ha->fwver1 = fw->data[0];
ha->fwver2 = fw->data[1];
ha->fwver3 = fw->data[2];
fw_data = (const __le16 *)&fw->data[0];
ha->fwstart = __le16_to_cpu(fw_data[2]);
/* Load RISC code. */ /* Load RISC code. */
risc_address = *ql1280_board_tbl[ha->devnum].fwstart; risc_address = ha->fwstart;
risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; fw_data = (const __le16 *)&fw->data[4];
risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; risc_code_size = (fw->size - 6) / 2;
for (i = 0; i < risc_code_size; i++) { for (i = 0; i < risc_code_size; i++) {
mb[0] = MBC_WRITE_RAM_WORD; mb[0] = MBC_WRITE_RAM_WORD;
mb[1] = risc_address + i; mb[1] = risc_address + i;
mb[2] = risc_code_address[i]; mb[2] = __le16_to_cpu(fw_data[i]);
err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb); err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
if (err) { if (err) {
printk(KERN_ERR "scsi(%li): Failed to load firmware\n", printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
ha->host_no); ha->host_no);
return err; goto out;
} }
} }
out:
return 0; release_firmware(fw);
return err;
} }
#define DUMP_IT_BACK 0 /* for debug of RISC loading */ #define DUMP_IT_BACK 0 /* for debug of RISC loading */
static int static int
qla1280_load_firmware_dma(struct scsi_qla_host *ha) qla1280_load_firmware_dma(struct scsi_qla_host *ha)
{ {
uint16_t risc_address, *risc_code_address, risc_code_size; const struct firmware *fw;
const __le16 *fw_data;
uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], cnt; uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
int err = 0, num, i; int err = 0, num, i;
#if DUMP_IT_BACK #if DUMP_IT_BACK
...@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) ...@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
return -ENOMEM; return -ENOMEM;
#endif #endif
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
&ha->pdev->dev);
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
ql1280_board_tbl[ha->devnum].fwname, err);
return err;
}
if ((fw->size % 2) || (fw->size < 6)) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, ql1280_board_tbl[ha->devnum].fwname);
err = -EINVAL;
goto out;
}
ha->fwver1 = fw->data[0];
ha->fwver2 = fw->data[1];
ha->fwver3 = fw->data[2];
fw_data = (const __le16 *)&fw->data[0];
ha->fwstart = __le16_to_cpu(fw_data[2]);
/* Load RISC code. */ /* Load RISC code. */
risc_address = *ql1280_board_tbl[ha->devnum].fwstart; risc_address = ha->fwstart;
risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; fw_data = (const __le16 *)&fw->data[4];
risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; risc_code_size = (fw->size - 6) / 2;
dprintk(1, "%s: DMA RISC code (%i) words\n", dprintk(1, "%s: DMA RISC code (%i) words\n",
__func__, risc_code_size); __func__, risc_code_size);
...@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) ...@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p),"
"%d,%d(0x%x)\n", "%d,%d(0x%x)\n",
risc_code_address, cnt, num, risc_address); fw_data, cnt, num, risc_address);
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
((__le16 *)ha->request_ring)[i] = ((__le16 *)ha->request_ring)[i] = fw_data[i];
cpu_to_le16(risc_code_address[i]);
mb[0] = MBC_LOAD_RAM; mb[0] = MBC_LOAD_RAM;
mb[1] = risc_address; mb[1] = risc_address;
...@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) ...@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#endif #endif
risc_address += cnt; risc_address += cnt;
risc_code_size = risc_code_size - cnt; risc_code_size = risc_code_size - cnt;
risc_code_address = risc_code_address + cnt; fw_data = fw_data + cnt;
num++; num++;
} }
...@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) ...@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#if DUMP_IT_BACK #if DUMP_IT_BACK
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
#endif #endif
release_firmware(fw);
return err; return err;
} }
...@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) ...@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Verify checksum of loaded RISC code. */ /* Verify checksum of loaded RISC code. */
mb[0] = MBC_VERIFY_CHECKSUM; mb[0] = MBC_VERIFY_CHECKSUM;
/* mb[1] = ql12_risc_code_addr01; */ /* mb[1] = ql12_risc_code_addr01; */
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb); err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
if (err) { if (err) {
printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no); 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,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Start firmware execution. */ /* Start firmware execution. */
dprintk(1, "%s: start firmware running.\n", __func__); dprintk(1, "%s: start firmware running.\n", __func__);
mb[0] = MBC_EXECUTE_FIRMWARE; mb[0] = MBC_EXECUTE_FIRMWARE;
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
if (err) { if (err) {
printk(KERN_ERR "scsi(%li): Failed to start firmware\n", printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
...@@ -4450,6 +4481,9 @@ module_exit(qla1280_exit); ...@@ -4450,6 +4481,9 @@ module_exit(qla1280_exit);
MODULE_AUTHOR("Qlogic & Jes Sorensen"); MODULE_AUTHOR("Qlogic & Jes Sorensen");
MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_FIRMWARE("qlogic/1040.bin");
MODULE_FIRMWARE("qlogic/1280.bin");
MODULE_FIRMWARE("qlogic/12160.bin");
MODULE_VERSION(QLA1280_VERSION); MODULE_VERSION(QLA1280_VERSION);
/* /*
......
...@@ -1069,6 +1069,12 @@ struct scsi_qla_host { ...@@ -1069,6 +1069,12 @@ struct scsi_qla_host {
struct nvram nvram; struct nvram nvram;
int nvram_valid; int nvram_valid;
/* Firmware Info */
unsigned short fwstart; /* start address for F/W */
unsigned char fwver1; /* F/W version first char */
unsigned char fwver2; /* F/W version second char */
unsigned char fwver3; /* F/W version third char */
}; };
#endif /* _QLA1280_H */ #endif /* _QLA1280_H */
...@@ -41,6 +41,8 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin ...@@ -41,6 +41,8 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
e100/d102e_ucode.bin e100/d102e_ucode.bin
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
qlogic/12160.bin
fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin
fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
......
...@@ -45,6 +45,19 @@ Found alsa-firmware package in hex form, with the following comment: ...@@ -45,6 +45,19 @@ Found alsa-firmware package in hex form, with the following comment:
-------------------------------------------------------------------------- --------------------------------------------------------------------------
Driver: SCSI_QLOGIC_1280 - Qlogic QLA 1240/1x80/1x160 SCSI support
File: qlogic/1040.bin
File: qlogic/1280.bin
File: qlogic/12160.bin
Licence: Allegedly GPLv2+, but no source visible. Marked:
QLOGIC LINUX SOFTWARE
QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
Copyright (C) 2001 Qlogic Corporation (www.qlogic.com)
--------------------------------------------------------------------------
Driver: smctr -- SMC ISA/MCA Token Ring adapter Driver: smctr -- SMC ISA/MCA Token Ring adapter
File: tr_smctr.bin File: tr_smctr.bin
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册