aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_mbx.c
diff options
context:
space:
mode:
authorHarihara Kadayam <harihara.kadayam@qlogic.com>2008-04-03 16:13:26 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 13:19:15 -0400
commit4d4df1932b6b116aecc81039066fec27f2050762 (patch)
treeee02f449a0bb456e40fcdb5287609b98e8e8f62f /drivers/scsi/qla2xxx/qla_mbx.c
parentb93480e319654b8921364b49528532dff4822a45 (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.c125
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 */
684int 684int
685qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, 685qla2x00_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
721int
722qla2x00_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 */
1210int 1218int
1211qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) 1219qla2x00_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
2953struct cs84xx_mgmt_cmd {
2954 union {
2955 struct verify_chip_entry_84xx req;
2956 struct verify_chip_rsp_84xx rsp;
2957 } p;
2958};
2959
2960int
2961qla84xx_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
3039verify_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}