📄 qla_mbx.c
字号:
/* * qla2x00_execute_fw * Start adapter firmware. * * 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_execute_fw(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_execute_fw(%ld): entered.\n", ha->host_no);) mcp->mb[0] = MBC_EXECUTE_FIRMWARE; mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart; mcp->out_mb = MBX_1|MBX_0; if (IS_QLA2322(ha) || IS_QLA6322(ha)) { mcp->mb[2] = 0; mcp->out_mb |= MBX_2; } mcp->in_mb = MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); DEBUG11(printk("qla2x00_execute_fw(%ld): done.\n", ha->host_no);) return rval;}/* * qla2x00_get_fw_version * Get firmware version. * * Input: * ha: adapter state pointer. * major: pointer for major number. * minor: pointer for minor number. * subminor: pointer for subminor number. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */voidqla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, uint16_t *subminor, uint16_t *attributes, uint32_t *memory){ 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_FIRMWARE_VERSION; mcp->out_mb = MBX_0; mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->flags = 0; mcp->tov = 30; rval = qla2x00_mailbox_command(ha, mcp); /* Return mailbox data. */ *major = mcp->mb[1]; *minor = mcp->mb[2]; *subminor = mcp->mb[3]; *attributes = mcp->mb[6]; if (IS_QLA2100(ha) || IS_QLA2200(ha)) *memory = 0x1FFFF; /* Defaults to 128KB. */ else *memory = (mcp->mb[5] << 16) | mcp->mb[4]; if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); } else { /*EMPTY*/ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); }}/* * qla2x00_get_fw_options * Set firmware options. * * Input: * ha = adapter block pointer. * fwopt = pointer for firmware options. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts){ 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_FIRMWARE_OPTION; mcp->out_mb = MBX_0; mcp->in_mb = 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, rval)); } else { fwopts[1] = mcp->mb[1]; fwopts[2] = mcp->mb[2]; fwopts[3] = mcp->mb[3]; DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}/* * qla2x00_set_fw_options * Set firmware options. * * Input: * ha = adapter block pointer. * fwopt = pointer for firmware options. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts){ 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_SET_FIRMWARE_OPTION; mcp->mb[1] = fwopts[1]; mcp->mb[2] = fwopts[2]; mcp->mb[3] = fwopts[3]; mcp->mb[10] = fwopts[10]; mcp->mb[11] = fwopts[11]; mcp->mb[12] = 0; /* Undocumented, but used */ mcp->out_mb = MBX_12|MBX_11|MBX_10|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.\n", __func__, ha->host_no, rval)); } else { /*EMPTY*/ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval;}/* * qla2x00_mbx_reg_test * Mailbox register wrap test. * * 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_mbx_reg_test(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);) mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; mcp->mb[1] = 0xAAAA; mcp->mb[2] = 0x5555; mcp->mb[3] = 0xAA55; mcp->mb[4] = 0x55AA; mcp->mb[5] = 0xA5A5; mcp->mb[6] = 0x5A5A; mcp->mb[7] = 0x2525; mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval == QLA_SUCCESS) { if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 || mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) rval = QLA_FUNCTION_FAILED; if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || mcp->mb[7] != 0x2525) rval = QLA_FUNCTION_FAILED; } if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", ha->host_no, rval);) } else { /*EMPTY*/ DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", ha->host_no);) } return rval;}/* * qla2x00_verify_checksum * Verify firmware checksum. * * 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_verify_checksum(scsi_qla_host_t *ha){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_verify_checksum(%ld): entered.\n", ha->host_no);) mcp->mb[0] = MBC_VERIFY_CHECKSUM; mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart; mcp->out_mb = MBX_1|MBX_0; mcp->in_mb = 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("qla2x00_verify_checksum(%ld): failed=%x.\n", ha->host_no, rval);) } else { /*EMPTY*/ DEBUG11(printk("qla2x00_verify_checksum(%ld): done.\n", ha->host_no);) } return rval;}/* * qla2x00_issue_iocb * Issue IOCB using mailbox command * * Input: * ha = adapter state pointer. * buffer = buffer pointer. * phys_addr = physical address of buffer. * size = size of buffer. * TARGET_QUEUE_LOCK must be released. * ADAPTER_STATE_LOCK must be released. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, size_t size){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; mcp->mb[0] = MBC_IOCB_COMMAND_A64; mcp->mb[1] = 0; mcp->mb[2] = MSW(phys_addr); mcp->mb[3] = LSW(phys_addr); mcp->mb[6] = MSW(MSD(phys_addr)); mcp->mb[7] = LSW(MSD(phys_addr)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_2|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x", ha->host_no,rval);) DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x", ha->host_no,rval);) } else { /*EMPTY*/ } return rval;}/* * qla2x00_abort_command * Abort command aborts a specified IOCB. * * Input: * ha = adapter block pointer. * sp = SB structure pointer. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp){ unsigned long flags = 0; fc_port_t *fcport; int rval; uint32_t handle; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) fcport = sp->fclun->fcport; if (atomic_read(&ha->loop_state) == LOOP_DOWN || atomic_read(&fcport->state) == FCS_DEVICE_LOST) { return 1; } 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; } mcp->mb[0] = MBC_ABORT_COMMAND; if (HAS_EXTENDED_IDS(ha)) mcp->mb[1] = fcport->loop_id; else mcp->mb[1] = fcport->loop_id << 8; mcp->mb[2] = (uint16_t)handle; mcp->mb[3] = (uint16_t)(handle >> 16); mcp->mb[6] = (uint16_t)sp->fclun->lun; mcp->out_mb = MBX_6|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) { DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", ha->host_no, rval);) } else { sp->flags |= SRB_ABORT_PENDING; DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", ha->host_no);) } return rval;}#if USE_ABORT_TGT/* * qla2x00_abort_target * Issue abort target mailbox command. * * Input: * ha = adapter block pointer. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */intqla2x00_abort_target(fc_port_t *fcport){ int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("qla2x00_abort_target(%ld): entered.\n", fcport->ha->host_no);) if (fcport == NULL) { /* no target to abort */ return 0; } mcp->mb[0] = MBC_ABORT_TARGET; mcp->out_mb = MBX_2|MBX_1|MBX_0; if (HAS_EXTENDED_IDS(fcport->ha)) { mcp->mb[1] = fcport->loop_id; mcp->mb[10] = 0; mcp->out_mb |= MBX_10; } else { mcp->mb[1] = fcport->loop_id << 8; } mcp->mb[2] = fcport->ha->loop_reset_delay; mcp->in_mb = MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(fcport->ha, mcp); /* Issue marker command. */ fcport->ha->marker_needed = 1; if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", fcport->ha->host_no, rval);) } else { /*EMPTY*/ DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", fcport->ha->host_no);) } return rval;}#endif/* * qla2x00_target_reset * Issue target reset mailbox command. * * Input: * ha = adapter block pointer. * TARGET_QUEUE_LOCK must be released. * ADAPTER_STATE_LOCK must be released. * * Returns:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -