aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-11-09 18:49:04 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-13 20:11:16 -0500
commit5433383ef33ed40c9c8a86a4355da344234af2a5 (patch)
tree8d82c620fe6faadfa805fb465d5beb67946133c7 /drivers/scsi/qla2xxx/qla_init.c
parent26a68019c86e1d1782984a7a5babff762cde1501 (diff)
[SCSI] qla2xxx: Add full firmware(-request) hotplug support for all ISPs.
Transition driver to exclusively use the request_firmware() interfaces to retrieve firmware-blobs from user-space. This will be the default behaviour going forward until the embedded firmware-binary images are removed from the upstream kernel. Upon request, the driver caches the firmware image until the driver is unloaded. NOTE: The option is present to allow the user to continue to use the firmware-loader modules, but, should be considered deprecated. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Rejections fixed up and Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c189
1 files changed, 137 insertions, 52 deletions
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
3487int 3488int
3488qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) 3489qla2x00_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
3563int 3552int
@@ -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
3645int 3636int
3646qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr) 3637qla2x00_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
3730fail_fw_integrity:
3731 return QLA_FUNCTION_FAILED;
3732}
3733
3734int
3735qla24xx_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
3746fail_fw_integrity: 3833fail_fw_integrity:
3747
3748 release_firmware(fw_entry);
3749 return QLA_FUNCTION_FAILED; 3834 return QLA_FUNCTION_FAILED;
3750
3751} 3835}
3836#endif