You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: [SCSI] qla1280: retain firmware for error recovery [SCSI] attirbute_container: Initialize sysfs attributes with sysfs_attr_init [SCSI] advansys: fix regression with request_firmware change [SCSI] qla2xxx: Updated version number to 8.03.02-k2. [SCSI] qla2xxx: Prevent sending mbx commands from sysfs during isp reset. [SCSI] qla2xxx: Disable MSI on qla24xx chips other than QLA2432. [SCSI] qla2xxx: Check to make sure multique and CPU affinity support is not enabled at the same time. [SCSI] qla2xxx: Correct vp_idx checking during PORT_UPDATE processing. [SCSI] qla2xxx: Honour "Extended BB credits" bit for CNAs. [SCSI] scsi_transport_fc: Make sure commands are completed when rport is offline [SCSI] libiscsi: Fix recovery slowdown regression
This commit is contained in:
+109
-52
@@ -17,9 +17,11 @@
|
||||
* General Public License for more details.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define QLA1280_VERSION "3.27"
|
||||
#define QLA1280_VERSION "3.27.1"
|
||||
/*****************************************************************************
|
||||
Revision History:
|
||||
Rev 3.27.1, February 8, 2010, Michael Reed
|
||||
- Retain firmware image for error recovery.
|
||||
Rev 3.27, February 10, 2009, Michael Reed
|
||||
- General code cleanup.
|
||||
- Improve error recovery.
|
||||
@@ -537,9 +539,9 @@ __setup("qla1280=", qla1280_setup);
|
||||
/*****************************************/
|
||||
|
||||
struct qla_boards {
|
||||
unsigned char name[9]; /* Board ID String */
|
||||
char *name; /* Board ID String */
|
||||
int numPorts; /* Number of SCSI ports */
|
||||
char *fwname; /* firmware name */
|
||||
int fw_index; /* index into qla1280_fw_tbl for firmware */
|
||||
};
|
||||
|
||||
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
|
||||
@@ -560,15 +562,30 @@ static struct pci_device_id qla1280_pci_tbl[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
|
||||
|
||||
DEFINE_MUTEX(qla1280_firmware_mutex);
|
||||
|
||||
struct qla_fw {
|
||||
char *fwname;
|
||||
const struct firmware *fw;
|
||||
};
|
||||
|
||||
#define QL_NUM_FW_IMAGES 3
|
||||
|
||||
struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
|
||||
{"qlogic/1040.bin", NULL}, /* image 0 */
|
||||
{"qlogic/1280.bin", NULL}, /* image 1 */
|
||||
{"qlogic/12160.bin", NULL}, /* image 2 */
|
||||
};
|
||||
|
||||
/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */
|
||||
static struct qla_boards ql1280_board_tbl[] = {
|
||||
/* Name , Number of ports, FW details */
|
||||
{"QLA12160", 2, "qlogic/12160.bin"},
|
||||
{"QLA1040", 1, "qlogic/1040.bin"},
|
||||
{"QLA1080", 1, "qlogic/1280.bin"},
|
||||
{"QLA1240", 2, "qlogic/1280.bin"},
|
||||
{"QLA1280", 2, "qlogic/1280.bin"},
|
||||
{"QLA10160", 1, "qlogic/12160.bin"},
|
||||
{" ", 0, " "},
|
||||
{.name = "QLA12160", .numPorts = 2, .fw_index = 2},
|
||||
{.name = "QLA1040" , .numPorts = 1, .fw_index = 0},
|
||||
{.name = "QLA1080" , .numPorts = 1, .fw_index = 1},
|
||||
{.name = "QLA1240" , .numPorts = 2, .fw_index = 1},
|
||||
{.name = "QLA1280" , .numPorts = 2, .fw_index = 1},
|
||||
{.name = "QLA10160", .numPorts = 1, .fw_index = 2},
|
||||
{.name = " ", .numPorts = 0, .fw_index = -1},
|
||||
};
|
||||
|
||||
static int qla1280_verbose = 1;
|
||||
@@ -1510,6 +1527,63 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla1280_request_firmware
|
||||
* Acquire firmware for chip. Retain in memory
|
||||
* for error recovery.
|
||||
*
|
||||
* Input:
|
||||
* ha = adapter block pointer.
|
||||
*
|
||||
* Returns:
|
||||
* Pointer to firmware image or an error code
|
||||
* cast to pointer via ERR_PTR().
|
||||
*/
|
||||
static const struct firmware *
|
||||
qla1280_request_firmware(struct scsi_qla_host *ha)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
int err;
|
||||
int index;
|
||||
char *fwname;
|
||||
|
||||
spin_unlock_irq(ha->host->host_lock);
|
||||
mutex_lock(&qla1280_firmware_mutex);
|
||||
|
||||
index = ql1280_board_tbl[ha->devnum].fw_index;
|
||||
fw = qla1280_fw_tbl[index].fw;
|
||||
if (fw)
|
||||
goto out;
|
||||
|
||||
fwname = qla1280_fw_tbl[index].fwname;
|
||||
err = request_firmware(&fw, fwname, &ha->pdev->dev);
|
||||
|
||||
if (err) {
|
||||
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
|
||||
fwname, err);
|
||||
fw = ERR_PTR(err);
|
||||
goto unlock;
|
||||
}
|
||||
if ((fw->size % 2) || (fw->size < 6)) {
|
||||
printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n",
|
||||
fw->size, fwname);
|
||||
release_firmware(fw);
|
||||
fw = ERR_PTR(-EINVAL);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
qla1280_fw_tbl[index].fw = fw;
|
||||
|
||||
out:
|
||||
ha->fwver1 = fw->data[0];
|
||||
ha->fwver2 = fw->data[1];
|
||||
ha->fwver3 = fw->data[2];
|
||||
unlock:
|
||||
mutex_unlock(&qla1280_firmware_mutex);
|
||||
spin_lock_irq(ha->host->host_lock);
|
||||
return fw;
|
||||
}
|
||||
|
||||
/*
|
||||
* Chip diagnostics
|
||||
* Test chip for proper operation.
|
||||
@@ -1633,30 +1707,18 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
|
||||
static int
|
||||
qla1280_load_firmware_pio(struct scsi_qla_host *ha)
|
||||
{
|
||||
/* enter with host_lock acquired */
|
||||
|
||||
const struct firmware *fw;
|
||||
const __le16 *fw_data;
|
||||
uint16_t risc_address, risc_code_size;
|
||||
uint16_t mb[MAILBOX_REGISTER_COUNT], i;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
fw = qla1280_request_firmware(ha);
|
||||
if (IS_ERR(fw))
|
||||
return PTR_ERR(fw);
|
||||
|
||||
spin_unlock_irq(ha->host->host_lock);
|
||||
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
|
||||
&ha->pdev->dev);
|
||||
spin_lock_irq(ha->host->host_lock);
|
||||
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]);
|
||||
|
||||
@@ -1674,11 +1736,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
|
||||
if (err) {
|
||||
printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
|
||||
ha->host_no);
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1686,6 +1747,7 @@ out:
|
||||
static int
|
||||
qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
{
|
||||
/* enter with host_lock acquired */
|
||||
const struct firmware *fw;
|
||||
const __le16 *fw_data;
|
||||
uint16_t risc_address, risc_code_size;
|
||||
@@ -1700,24 +1762,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
spin_unlock_irq(ha->host->host_lock);
|
||||
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
|
||||
&ha->pdev->dev);
|
||||
spin_lock_irq(ha->host->host_lock);
|
||||
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 = qla1280_request_firmware(ha);
|
||||
if (IS_ERR(fw))
|
||||
return PTR_ERR(fw);
|
||||
|
||||
fw_data = (const __le16 *)&fw->data[0];
|
||||
ha->fwstart = __le16_to_cpu(fw_data[2]);
|
||||
|
||||
@@ -1802,7 +1850,6 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
#if DUMP_IT_BACK
|
||||
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
|
||||
#endif
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1841,6 +1888,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
|
||||
static int
|
||||
qla1280_load_firmware(struct scsi_qla_host *ha)
|
||||
{
|
||||
/* enter with host_lock taken */
|
||||
int err;
|
||||
|
||||
err = qla1280_chip_diag(ha);
|
||||
@@ -4419,7 +4467,16 @@ qla1280_init(void)
|
||||
static void __exit
|
||||
qla1280_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pci_unregister_driver(&qla1280_pci_driver);
|
||||
/* release any allocated firmware images */
|
||||
for (i = 0; i < QL_NUM_FW_IMAGES; i++) {
|
||||
if (qla1280_fw_tbl[i].fw) {
|
||||
release_firmware(qla1280_fw_tbl[i].fw);
|
||||
qla1280_fw_tbl[i].fw = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module_init(qla1280_init);
|
||||
|
||||
Reference in New Issue
Block a user