Commit f894e74d authored by Jaswinder Singh Rajput's avatar Jaswinder Singh Rajput Committed by James Bottomley

[SCSI] qlogicpti: use request_firmware

Firmware blob is little endian

Thanks to Stephen Rothwell for fixing typos
Signed-off-by: default avatarJaswinder Singh Rajput <jaswinderrajput@gmail.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 989bb5f5
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/firmware.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -53,8 +54,6 @@ ...@@ -53,8 +54,6 @@
#define DEFAULT_LOOP_COUNT 10000 #define DEFAULT_LOOP_COUNT 10000
#include "qlogicpti_asm.c"
static struct qlogicpti *qptichain = NULL; static struct qlogicpti *qptichain = NULL;
static DEFINE_SPINLOCK(qptichain_lock); static DEFINE_SPINLOCK(qptichain_lock);
...@@ -465,16 +464,32 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) ...@@ -465,16 +464,32 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
{ {
const struct firmware *fw;
const char fwname[] = "qlogic/isp1000.bin";
const __le16 *fw_data;
struct Scsi_Host *host = qpti->qhost; struct Scsi_Host *host = qpti->qhost;
unsigned short csum = 0; unsigned short csum = 0;
unsigned short param[6]; unsigned short param[6];
unsigned short *risc_code, risc_code_addr, risc_code_length; unsigned short risc_code_addr, risc_code_length;
int err;
unsigned long flags; unsigned long flags;
int i, timeout; int i, timeout;
risc_code = &sbus_risc_code01[0]; err = request_firmware(&fw, fwname, &qpti->op->dev);
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fwname, err);
return err;
}
if (fw->size % 2) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, fwname);
err = -EINVAL;
goto outfirm;
}
fw_data = (const __le16 *)&fw->data[0];
risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */ risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */
risc_code_length = sbus_risc_code_length01; risc_code_length = fw->size / 2;
spin_lock_irqsave(host->host_lock, flags); spin_lock_irqsave(host->host_lock, flags);
...@@ -482,12 +497,12 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -482,12 +497,12 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
* afterwards via the mailbox commands. * afterwards via the mailbox commands.
*/ */
for (i = 0; i < risc_code_length; i++) for (i = 0; i < risc_code_length; i++)
csum += risc_code[i]; csum += __le16_to_cpu(fw_data[i]);
if (csum) { if (csum) {
spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!", printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
qpti->qpti_id); qpti->qpti_id);
return 1; err = 1;
goto out;
} }
sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL); sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL); sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
...@@ -496,9 +511,9 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -496,9 +511,9 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET)) while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
udelay(20); udelay(20);
if (!timeout) { if (!timeout) {
spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id); printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
return 1; err = 1;
goto out;
} }
sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL); sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
...@@ -536,21 +551,21 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -536,21 +551,21 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
if (qlogicpti_mbox_command(qpti, param, 1)) { if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n", printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
qpti->qpti_id); qpti->qpti_id);
spin_unlock_irqrestore(host->host_lock, flags); err = 1;
return 1; goto out;
} }
/* Load it up.. */ /* Load it up.. */
for (i = 0; i < risc_code_length; i++) { for (i = 0; i < risc_code_length; i++) {
param[0] = MBOX_WRITE_RAM_WORD; param[0] = MBOX_WRITE_RAM_WORD;
param[1] = risc_code_addr + i; param[1] = risc_code_addr + i;
param[2] = risc_code[i]; param[2] = __le16_to_cpu(fw_data[i]);
if (qlogicpti_mbox_command(qpti, param, 1) || if (qlogicpti_mbox_command(qpti, param, 1) ||
param[0] != MBOX_COMMAND_COMPLETE) { param[0] != MBOX_COMMAND_COMPLETE) {
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n", printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
qpti->qpti_id); qpti->qpti_id);
spin_unlock_irqrestore(host->host_lock, flags); err = 1;
return 1; goto out;
} }
} }
...@@ -569,8 +584,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -569,8 +584,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) { (param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n", printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
qpti->qpti_id); qpti->qpti_id);
spin_unlock_irqrestore(host->host_lock, flags); err = 1;
return 1; goto out;
} }
/* Start using newly downloaded firmware. */ /* Start using newly downloaded firmware. */
...@@ -583,8 +598,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -583,8 +598,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) { (param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n", printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
qpti->qpti_id); qpti->qpti_id);
spin_unlock_irqrestore(host->host_lock, flags); err = 1;
return 1; goto out;
} }
/* Snag the major and minor revisions from the result. */ /* Snag the major and minor revisions from the result. */
...@@ -599,8 +614,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -599,8 +614,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) { (param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n", printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
qpti->qpti_id); qpti->qpti_id);
spin_unlock_irqrestore(host->host_lock, flags); err = 1;
return 1; goto out;
} }
if (qpti->is_pti != 0) { if (qpti->is_pti != 0) {
...@@ -616,8 +631,11 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) ...@@ -616,8 +631,11 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
qlogicpti_mbox_command(qpti, param, 1); qlogicpti_mbox_command(qpti, param, 1);
} }
out:
spin_unlock_irqrestore(host->host_lock, flags); spin_unlock_irqrestore(host->host_lock, flags);
return 0; outfirm:
release_firmware(fw);
return err;
} }
static int qlogicpti_verify_tmon(struct qlogicpti *qpti) static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
...@@ -1458,6 +1476,7 @@ MODULE_DESCRIPTION("QlogicISP SBUS driver"); ...@@ -1458,6 +1476,7 @@ MODULE_DESCRIPTION("QlogicISP SBUS driver");
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("2.1"); MODULE_VERSION("2.1");
MODULE_FIRMWARE("qlogic/isp1000.bin");
module_init(qpti_init); module_init(qpti_init);
module_exit(qpti_exit); module_exit(qpti_exit);
This diff is collapsed.
...@@ -45,6 +45,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ ...@@ -45,6 +45,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
advansys/3550.bin advansys/38C0800.bin advansys/3550.bin advansys/38C0800.bin
fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
qlogic/12160.bin qlogic/12160.bin
fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.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 \
......
...@@ -569,3 +569,13 @@ Licence: Allegedly GPL, but no source visible. Marked: ...@@ -569,3 +569,13 @@ Licence: Allegedly GPL, but no source visible. Marked:
Found in hex form in kernel source. Found in hex form in kernel source.
-------------------------------------------------------------------------- --------------------------------------------------------------------------
Driver: SCSI_QLOGICPTI - PTI Qlogic, ISP Driver
File: qlogic/isp1000.bin
Licence: Unknown
Found in hex form in kernel source.
--------------------------------------------------------------------------
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment