diff options
author | Harihara Kadayam <harihara.kadayam@qlogic.com> | 2008-04-03 16:13:26 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:19:15 -0400 |
commit | 4d4df1932b6b116aecc81039066fec27f2050762 (patch) | |
tree | ee02f449a0bb456e40fcdb5287609b98e8e8f62f /drivers/scsi/qla2xxx/qla_mbx.c | |
parent | b93480e319654b8921364b49528532dff4822a45 (diff) |
[SCSI] qla2xxx: Add ISP84XX support.
Signed-off-by: Ravi Anand <ravi.anand@qlogic.com>
Additional cleanups and
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 125 |
1 files changed, 118 insertions, 7 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index beff743c536b..7d0a8a4c7719 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -682,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
682 | * Kernel context. | 682 | * Kernel context. |
683 | */ | 683 | */ |
684 | int | 684 | int |
685 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | 685 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, |
686 | size_t size) | 686 | dma_addr_t phys_addr, size_t size, uint32_t tov) |
687 | { | 687 | { |
688 | int rval; | 688 | int rval; |
689 | mbx_cmd_t mc; | 689 | mbx_cmd_t mc; |
@@ -697,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
697 | mcp->mb[7] = LSW(MSD(phys_addr)); | 697 | mcp->mb[7] = LSW(MSD(phys_addr)); |
698 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 698 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
699 | mcp->in_mb = MBX_2|MBX_0; | 699 | mcp->in_mb = MBX_2|MBX_0; |
700 | mcp->tov = MBX_TOV_SECONDS; | 700 | mcp->tov = tov; |
701 | mcp->flags = 0; | 701 | mcp->flags = 0; |
702 | rval = qla2x00_mailbox_command(ha, mcp); | 702 | rval = qla2x00_mailbox_command(ha, mcp); |
703 | 703 | ||
@@ -718,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
718 | return rval; | 718 | return rval; |
719 | } | 719 | } |
720 | 720 | ||
721 | int | ||
722 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, | ||
723 | size_t size) | ||
724 | { | ||
725 | return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, | ||
726 | MBX_TOV_SECONDS); | ||
727 | } | ||
728 | |||
721 | /* | 729 | /* |
722 | * qla2x00_abort_command | 730 | * qla2x00_abort_command |
723 | * Abort command aborts a specified IOCB. | 731 | * Abort command aborts a specified IOCB. |
@@ -1208,7 +1216,7 @@ gpd_error_out: | |||
1208 | * Kernel context. | 1216 | * Kernel context. |
1209 | */ | 1217 | */ |
1210 | int | 1218 | int |
1211 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | 1219 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states) |
1212 | { | 1220 | { |
1213 | int rval; | 1221 | int rval; |
1214 | mbx_cmd_t mc; | 1222 | mbx_cmd_t mc; |
@@ -1219,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1219 | 1227 | ||
1220 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1228 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1221 | mcp->out_mb = MBX_0; | 1229 | mcp->out_mb = MBX_0; |
1222 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1230 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1223 | mcp->tov = MBX_TOV_SECONDS; | 1231 | mcp->tov = MBX_TOV_SECONDS; |
1224 | mcp->flags = 0; | 1232 | mcp->flags = 0; |
1225 | rval = qla2x00_mailbox_command(ha, mcp); | 1233 | rval = qla2x00_mailbox_command(ha, mcp); |
1226 | 1234 | ||
1227 | /* Return firmware state. */ | 1235 | /* Return firmware states. */ |
1228 | *dptr = mcp->mb[1]; | 1236 | states[0] = mcp->mb[1]; |
1237 | states[1] = mcp->mb[2]; | ||
1238 | states[2] = mcp->mb[3]; | ||
1229 | 1239 | ||
1230 | if (rval != QLA_SUCCESS) { | 1240 | if (rval != QLA_SUCCESS) { |
1231 | /*EMPTY*/ | 1241 | /*EMPTY*/ |
@@ -2937,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2937 | 2947 | ||
2938 | return rval; | 2948 | return rval; |
2939 | } | 2949 | } |
2950 | |||
2951 | /* 84XX Support **************************************************************/ | ||
2952 | |||
2953 | struct cs84xx_mgmt_cmd { | ||
2954 | union { | ||
2955 | struct verify_chip_entry_84xx req; | ||
2956 | struct verify_chip_rsp_84xx rsp; | ||
2957 | } p; | ||
2958 | }; | ||
2959 | |||
2960 | int | ||
2961 | qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) | ||
2962 | { | ||
2963 | int rval, retry; | ||
2964 | struct cs84xx_mgmt_cmd *mn; | ||
2965 | dma_addr_t mn_dma; | ||
2966 | uint16_t options; | ||
2967 | unsigned long flags; | ||
2968 | |||
2969 | DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2970 | |||
2971 | mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); | ||
2972 | if (mn == NULL) { | ||
2973 | DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " | ||
2974 | "IOCB.\n", __func__, ha->host_no)); | ||
2975 | return QLA_MEMORY_ALLOC_FAILED; | ||
2976 | } | ||
2977 | |||
2978 | /* Force Update? */ | ||
2979 | options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; | ||
2980 | /* Diagnostic firmware? */ | ||
2981 | /* options |= MENLO_DIAG_FW; */ | ||
2982 | /* We update the firmware with only one data sequence. */ | ||
2983 | options |= VCO_END_OF_DATA; | ||
2984 | |||
2985 | retry = 0; | ||
2986 | do { | ||
2987 | memset(mn, 0, sizeof(*mn)); | ||
2988 | mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; | ||
2989 | mn->p.req.entry_count = 1; | ||
2990 | mn->p.req.options = cpu_to_le16(options); | ||
2991 | |||
2992 | DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, | ||
2993 | ha->host_no)); | ||
2994 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
2995 | sizeof(*mn))); | ||
2996 | |||
2997 | rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); | ||
2998 | if (rval != QLA_SUCCESS) { | ||
2999 | DEBUG2_16(printk("%s(%ld): failed to issue Verify " | ||
3000 | "IOCB (%x).\n", __func__, ha->host_no, rval)); | ||
3001 | goto verify_done; | ||
3002 | } | ||
3003 | |||
3004 | DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, | ||
3005 | ha->host_no)); | ||
3006 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
3007 | sizeof(*mn))); | ||
3008 | |||
3009 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); | ||
3010 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? | ||
3011 | le16_to_cpu(mn->p.rsp.failure_code) : 0; | ||
3012 | DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__, | ||
3013 | ha->host_no, status[0], status[1])); | ||
3014 | |||
3015 | if (status[0] != CS_COMPLETE) { | ||
3016 | rval = QLA_FUNCTION_FAILED; | ||
3017 | if (!(options & VCO_DONT_UPDATE_FW)) { | ||
3018 | DEBUG2_16(printk("%s(%ld): Firmware update " | ||
3019 | "failed. Retrying without update " | ||
3020 | "firmware.\n", __func__, ha->host_no)); | ||
3021 | options |= VCO_DONT_UPDATE_FW; | ||
3022 | options &= ~VCO_FORCE_UPDATE; | ||
3023 | retry = 1; | ||
3024 | } | ||
3025 | } else { | ||
3026 | DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n", | ||
3027 | __func__, ha->host_no, | ||
3028 | le32_to_cpu(mn->p.rsp.fw_ver))); | ||
3029 | |||
3030 | /* NOTE: we only update OP firmware. */ | ||
3031 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
3032 | ha->cs84xx->op_fw_version = | ||
3033 | le32_to_cpu(mn->p.rsp.fw_ver); | ||
3034 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, | ||
3035 | flags); | ||
3036 | } | ||
3037 | } while (retry); | ||
3038 | |||
3039 | verify_done: | ||
3040 | dma_pool_free(ha->s_dma_pool, mn, mn_dma); | ||
3041 | |||
3042 | if (rval != QLA_SUCCESS) { | ||
3043 | DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, | ||
3044 | ha->host_no, rval)); | ||
3045 | } else { | ||
3046 | DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3047 | } | ||
3048 | |||
3049 | return rval; | ||
3050 | } | ||