📄 qla_mbx.c
字号:
* * Context: * Kernel context. */intqla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, uint8_t area, uint8_t al_pa){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", ha->host_no);) mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; mcp->out_mb = MBX_1|MBX_0; if (HAS_EXTENDED_IDS(ha)) { mcp->mb[1] = loop_id; mcp->mb[10] = 0; mcp->out_mb |= MBX_10; } else { mcp->mb[1] = loop_id << 8; } mcp->in_mb = MBX_1|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);) } else { /*EMPTY*/ DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", ha->host_no);) } return rval;}/* * qla2x00_full_login_lip * Issue full login LIP mailbox command. * * Input: * ha = adapter block pointer. * TARGET_QUEUE_LOCK must be released. * ADAPTER_STATE_LOCK must be released. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_full_login_lip(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", ha->host_no);) mcp->mb[0] = MBC_LIP_FULL_LOGIN; mcp->mb[1] = 0; mcp->mb[2] = 0xff; mcp->mb[3] = 0; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", ha->host_no, rval);) } else { /*EMPTY*/ DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", ha->host_no);) } return rval;}/* * qla2x00_get_id_list * * Input: * ha = adapter block pointer. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, uint16_t *entries){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", ha->host_no);) if (id_list == NULL) return QLA_FUNCTION_FAILED; mcp->mb[0] = MBC_GET_ID_LIST; mcp->out_mb = MBX_0; if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[2] = MSW(id_list_dma); mcp->mb[3] = LSW(id_list_dma); mcp->mb[6] = MSW(MSD(id_list_dma)); mcp->mb[7] = LSW(MSD(id_list_dma)); mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2; } else { mcp->mb[1] = MSW(id_list_dma); mcp->mb[2] = LSW(id_list_dma); mcp->mb[3] = MSW(MSD(id_list_dma)); mcp->mb[6] = LSW(MSD(id_list_dma)); mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; } mcp->in_mb = MBX_1|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", ha->host_no, rval);) } else { *entries = mcp->mb[1]; DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", ha->host_no);) } return rval;}/* * qla2x00_get_resource_cnts * Get current firmware resource counts. * * Input: * ha = adapter block pointer. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; mcp->out_mb = MBX_0; mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, ha->host_no, mcp->mb[0]);) } else { DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " "mb7=%x mb10=%x.\n", __func__, ha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10])); if (cur_xchg_cnt) *cur_xchg_cnt = mcp->mb[3]; if (orig_xchg_cnt) *orig_xchg_cnt = mcp->mb[6]; if (cur_iocb_cnt) *cur_iocb_cnt = mcp->mb[7]; if (orig_iocb_cnt) *orig_iocb_cnt = mcp->mb[10]; } return (rval);}#if defined(QL_DEBUG_LEVEL_3)/* * qla2x00_get_fcal_position_map * Get FCAL (LILP) position map using mailbox command * * Input: * ha = adapter state pointer. * pos_map = buffer pointer (can be NULL). * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; char *pmap; dma_addr_t pmap_dma; pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma); if (pmap == NULL) { DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****", __func__, ha->host_no)); return QLA_MEMORY_ALLOC_FAILED; } memset(pmap, 0, FCAL_MAP_SIZE); mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; mcp->mb[2] = MSW(pmap_dma); mcp->mb[3] = LSW(pmap_dma); mcp->mb[6] = MSW(MSD(pmap_dma)); mcp->mb[7] = LSW(MSD(pmap_dma)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; mcp->in_mb = MBX_1|MBX_0; mcp->buf_size = FCAL_MAP_SIZE; mcp->flags = MBX_DMA_IN; mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); rval = qla2x00_mailbox_command(ha, mcp); if (rval == QLA_SUCCESS) { DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map " "size (%x)\n", __func__, ha->host_no, mcp->mb[0], mcp->mb[1], (unsigned)pmap[0])); DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1)); if (pos_map) memcpy(pos_map, pmap, FCAL_MAP_SIZE); } dma_pool_free(ha->s_dma_pool, pmap, pmap_dma); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}uint8_tqla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, uint16_t *status){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; uint32_t *sbuf, *siter; dma_addr_t sbuf_dma; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) if (dwords > (DMA_POOL_SIZE / 4)) { DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " "(max %d).\n", __func__, ha->host_no, dwords, DMA_POOL_SIZE / 4)); return BIT_0; } sbuf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &sbuf_dma); if (sbuf == NULL) { DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", __func__, ha->host_no)); return BIT_0; } memset(sbuf, 0, DMA_POOL_SIZE); mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; mcp->mb[2] = MSW(sbuf_dma); mcp->mb[3] = LSW(sbuf_dma); mcp->mb[6] = MSW(MSD(sbuf_dma)); mcp->mb[7] = LSW(MSD(sbuf_dma)); mcp->mb[8] = dwords; mcp->mb[10] = 0; mcp->out_mb = MBX_10|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; mcp->in_mb = MBX_2|MBX_1|MBX_0; mcp->tov = 30; mcp->flags = IOCTL_CMD; rval = qla2x00_mailbox_command(ha, mcp); if (rval == QLA_SUCCESS) { if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", __func__, ha->host_no, mcp->mb[0])); status[0] = mcp->mb[0]; rval = BIT_1; } else { /* Copy over data -- firmware data is LE. */ siter = sbuf; while (dwords--) *dwbuf++ = le32_to_cpu(*siter++); } } else { /* Failed. */ DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); rval = BIT_1; } dma_pool_free(ha->s_dma_pool, sbuf, sbuf_dma); return rval;}#endifintqla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp){ int rval; fc_port_t *fcport; unsigned long flags = 0; struct abort_entry_24xx *abt; dma_addr_t abt_dma; uint32_t handle; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) fcport = sp->fcport; spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { if (ha->outstanding_cmds[handle] == sp) break; } spin_unlock_irqrestore(&ha->hardware_lock, flags); if (handle == MAX_OUTSTANDING_COMMANDS) { /* Command not found. */ return QLA_FUNCTION_FAILED; } abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma); if (abt == NULL) { DEBUG2_3(printk("%s(%ld): failed to allocate Abort IOCB.\n", __func__, ha->host_no)); return QLA_MEMORY_ALLOC_FAILED; } memset(abt, 0, sizeof(struct abort_entry_24xx)); abt->entry_type = ABORT_IOCB_TYPE; abt->entry_count = 1; abt->nport_handle = cpu_to_le16(fcport->loop_id); abt->handle_to_abort = handle; abt->port_id[0] = fcport->d_id.b.al_pa; abt->port_id[1] = fcport->d_id.b.area; abt->port_id[2] = fcport->d_id.b.domain; rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", __func__, ha->host_no, rval);) } else if (abt->entry_status != 0) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- error status (%x).\n", __func__, ha->host_no, abt->entry_status)); rval = QLA_FUNCTION_FAILED; } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- completion status (%x).\n", __func__, ha->host_no, le16_to_cpu(abt->nport_handle));) rval = QLA_FUNCTION_FAILED; } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) sp->flags |= SRB_ABORT_PENDING; } dma_pool_free(ha->s_dma_pool, abt, abt_dma); return rval;}struct tsk_mgmt_cmd { union { struct tsk_mgmt_entry tsk; struct sts_entry_24xx sts; } p;};intqla24xx_abort_target(fc_port_t *fcport){ int rval; struct tsk_mgmt_cmd *tsk; dma_addr_t tsk_dma; scsi_qla_host_t *ha; if (fcport == NULL) return 0; DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) ha = fcport->ha; tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); if (tsk == NULL) { DEBUG2_3(printk("%s(%ld): failed to allocate Task Management " "IOCB.\n", __func__, ha->host_no)); return QLA_MEMORY_ALLOC_FAILED; } memset(tsk, 0, sizeof(struct tsk_mgmt_cmd)); tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; tsk->p.tsk.entry_count = 1; tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); tsk->p.tsk.timeout = __constant_cpu_to_le16(25); tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; tsk->p.tsk.port_id[1] = fcport->d_id.b.area; tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " "(%x).\n", __func__, ha->host_no, rval);) goto atarget_done; } else if (tsk->p.sts.entry_status != 0) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- error status (%x).\n", __func__, ha->host_no, tsk->p.sts.entry_status)); rval = QLA_FUNCTION_FAILED; goto atarget_done; } else if (tsk->p.sts.comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- completion status (%x).\n", __func__, ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));) rval = QLA_FUNCTION_FAILED; goto atarget_done; } /* Issue marker IOCB. */ rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " "(%x).\n", __func__, ha->host_no, rval);) } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) }atarget_done: dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); return rval;}intqla2x00_system_error(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) return QLA_FUNCTION_FAILED; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; mcp->out_mb = MBX_0; mcp->in_mb = MBX_0; mcp->tov = 5; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}/** * qla2x00_get_serdes_params() - * @ha: HA context * * Returns */intqla2x00_get_serdes_params(scsi_qla_host_t *ha, uint16_t *sw_em_1g, uint16_t *sw_em_2g, uint16_t *sw_em_4g){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); mcp->mb[0] = MBC_SERDES_PARAMS; mcp->mb[1] = 0; mcp->out_mb = MBX_1|MBX_0; mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, ha->host_no, rval, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); if (sw_em_1g) *sw_em_1g = mcp->mb[2]; if (sw_em_2g) *sw_em_2g = mcp->mb[3]; if (sw_em_4g) *sw_em_4g = mcp->mb[4]; } return rval;}/** * qla2x00_set_serdes_params() - * @ha: HA context * * Returns */intqla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, uint16_t sw_em_2g, uint16_t sw_em_4g){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); mcp->mb[0] = MBC_SERDES_PARAMS; mcp->mb[1] = BIT_0; mcp->mb[2] = sw_em_1g; mcp->mb[3] = sw_em_2g; mcp->mb[4] = sw_em_4g; mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, ha->host_no, rval, mcp->mb[0])); } else { /*EMPTY*/ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}intqla2x00_stop_firmware(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) return QLA_FUNCTION_FAILED; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); mcp->mb[0] = MBC_STOP_FIRMWARE; mcp->out_mb = MBX_0; mcp->in_mb = MBX_0; mcp->tov = 5; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -