Loading drivers/scsi/qla4xxx/ql4_fw.h +1 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ union external_hw_config_reg { #define MBOX_CMD_ABOUT_FW 0x0009 #define MBOX_CMD_PING 0x000B #define MBOX_CMD_LUN_RESET 0x0016 #define MBOX_CMD_TARGET_WARM_RESET 0x0017 #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E #define MBOX_CMD_GET_FW_STATUS 0x001F #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 Loading drivers/scsi/qla4xxx/ql4_glbl.h +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ int qla4xxx_relogin_device(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry); int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, int lun); int qla4xxx_reset_target(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry); int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, uint32_t offset, uint32_t len); int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); Loading drivers/scsi/qla4xxx/ql4_mbx.c +39 −0 Original line number Diff line number Diff line Loading @@ -713,6 +713,45 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, return status; } /** * qla4xxx_reset_target - issues target Reset * @ha: Pointer to host adapter structure. * @db_entry: Pointer to device database entry * @un_entry: Pointer to lun entry structure * * This routine performs a TARGET RESET on the specified target. * The caller must ensure that the ddb_entry pointers * are valid before calling this routine. **/ int qla4xxx_reset_target(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; int status = QLA_SUCCESS; DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, ddb_entry->os_target_id)); /* * Send target reset command to ISP, so that the ISP will return all * outstanding requests with RESET status */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; mbox_cmd[1] = ddb_entry->fw_ddb_index; mbox_cmd[5] = 0x01; /* Immediate Command Enable */ qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && mbox_sts[0] != MBOX_STS_COMMAND_ERROR) status = QLA_ERROR; return status; } int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, uint32_t offset, uint32_t len) Loading drivers/scsi/qla4xxx/ql4_os.c +63 −19 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *)); static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd); static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); static int qla4xxx_slave_alloc(struct scsi_device *device); static int qla4xxx_slave_configure(struct scsi_device *device); Loading @@ -84,6 +85,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .queuecommand = qla4xxx_queuecommand, .eh_device_reset_handler = qla4xxx_eh_device_reset, .eh_target_reset_handler = qla4xxx_eh_target_reset, .eh_host_reset_handler = qla4xxx_eh_host_reset, .slave_configure = qla4xxx_slave_configure, Loading Loading @@ -1482,7 +1484,7 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) } /** * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. * qla4xxx_eh_wait_for_commands - wait for active cmds to finish. * @ha: pointer to to HBA * @t: target id * @l: lun id Loading @@ -1490,20 +1492,22 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) * This function waits for all outstanding commands to a lun to complete. It * returns 0 if all pending commands are returned and 1 otherwise. **/ static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, int t, int l) static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha, struct scsi_target *stgt, struct scsi_device *sdev) { int cnt; int status = 0; struct scsi_cmnd *cmd; /* * Waiting for all commands for the designated target in the active * array * Waiting for all commands for the designated target or dev * in the active array */ for (cnt = 0; cnt < ha->host->can_queue; cnt++) { cmd = scsi_host_find_tag(ha->host, cnt); if (cmd && cmd->device->id == t && cmd->device->lun == l) { if (cmd && stgt == scsi_target(cmd->device) && (!sdev || sdev == cmd->device)) { if (!qla4xxx_eh_wait_on_command(ha, cmd)) { status++; break; Loading Loading @@ -1551,20 +1555,13 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) /* Send marker. */ ha->marker_needed = 1; /* * If we are coming down the EH path, wait for all commands to complete * for the device. */ if (cmd->device->host->shost_state == SHOST_RECOVERY) { if (qla4xxx_eh_wait_for_active_target_commands(ha, cmd->device->id, cmd->device->lun)){ if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), cmd->device)) { dev_info(&ha->pdev->dev, "DEVICE RESET FAILED - waiting for " "commands.\n"); goto eh_dev_reset_done; } } dev_info(&ha->pdev->dev, "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", Loading @@ -1578,6 +1575,53 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) return ret; } /** * qla4xxx_eh_target_reset - callback for target reset. * @cmd: Pointer to Linux's SCSI command structure * * This routine is called by the Linux OS to reset the target. **/ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) { struct scsi_qla_host *ha = to_qla_host(cmd->device->host); struct ddb_entry *ddb_entry = cmd->device->hostdata; int stat; if (!ddb_entry) return FAILED; starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET ISSUED.\n"); DEBUG2(printk(KERN_INFO "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ, ha->dpc_flags, cmd->result, cmd->allowed)); stat = qla4xxx_reset_target(ha, ddb_entry); if (stat != QLA_SUCCESS) { starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET FAILED.\n"); return FAILED; } /* Send marker. */ ha->marker_needed = 1; if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), NULL)) { starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET DEVICE RESET FAILED - " "waiting for commands.\n"); return FAILED; } starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET SUCCEEDED.\n"); return SUCCESS; } /** * qla4xxx_eh_host_reset - kernel callback * @cmd: Pointer to Linux's SCSI command structure Loading Loading
drivers/scsi/qla4xxx/ql4_fw.h +1 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ union external_hw_config_reg { #define MBOX_CMD_ABOUT_FW 0x0009 #define MBOX_CMD_PING 0x000B #define MBOX_CMD_LUN_RESET 0x0016 #define MBOX_CMD_TARGET_WARM_RESET 0x0017 #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E #define MBOX_CMD_GET_FW_STATUS 0x001F #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 Loading
drivers/scsi/qla4xxx/ql4_glbl.h +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ int qla4xxx_relogin_device(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry); int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, int lun); int qla4xxx_reset_target(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry); int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, uint32_t offset, uint32_t len); int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); Loading
drivers/scsi/qla4xxx/ql4_mbx.c +39 −0 Original line number Diff line number Diff line Loading @@ -713,6 +713,45 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, return status; } /** * qla4xxx_reset_target - issues target Reset * @ha: Pointer to host adapter structure. * @db_entry: Pointer to device database entry * @un_entry: Pointer to lun entry structure * * This routine performs a TARGET RESET on the specified target. * The caller must ensure that the ddb_entry pointers * are valid before calling this routine. **/ int qla4xxx_reset_target(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; int status = QLA_SUCCESS; DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, ddb_entry->os_target_id)); /* * Send target reset command to ISP, so that the ISP will return all * outstanding requests with RESET status */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; mbox_cmd[1] = ddb_entry->fw_ddb_index; mbox_cmd[5] = 0x01; /* Immediate Command Enable */ qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && mbox_sts[0] != MBOX_STS_COMMAND_ERROR) status = QLA_ERROR; return status; } int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, uint32_t offset, uint32_t len) Loading
drivers/scsi/qla4xxx/ql4_os.c +63 −19 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *)); static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd); static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); static int qla4xxx_slave_alloc(struct scsi_device *device); static int qla4xxx_slave_configure(struct scsi_device *device); Loading @@ -84,6 +85,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .queuecommand = qla4xxx_queuecommand, .eh_device_reset_handler = qla4xxx_eh_device_reset, .eh_target_reset_handler = qla4xxx_eh_target_reset, .eh_host_reset_handler = qla4xxx_eh_host_reset, .slave_configure = qla4xxx_slave_configure, Loading Loading @@ -1482,7 +1484,7 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) } /** * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. * qla4xxx_eh_wait_for_commands - wait for active cmds to finish. * @ha: pointer to to HBA * @t: target id * @l: lun id Loading @@ -1490,20 +1492,22 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) * This function waits for all outstanding commands to a lun to complete. It * returns 0 if all pending commands are returned and 1 otherwise. **/ static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, int t, int l) static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha, struct scsi_target *stgt, struct scsi_device *sdev) { int cnt; int status = 0; struct scsi_cmnd *cmd; /* * Waiting for all commands for the designated target in the active * array * Waiting for all commands for the designated target or dev * in the active array */ for (cnt = 0; cnt < ha->host->can_queue; cnt++) { cmd = scsi_host_find_tag(ha->host, cnt); if (cmd && cmd->device->id == t && cmd->device->lun == l) { if (cmd && stgt == scsi_target(cmd->device) && (!sdev || sdev == cmd->device)) { if (!qla4xxx_eh_wait_on_command(ha, cmd)) { status++; break; Loading Loading @@ -1551,20 +1555,13 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) /* Send marker. */ ha->marker_needed = 1; /* * If we are coming down the EH path, wait for all commands to complete * for the device. */ if (cmd->device->host->shost_state == SHOST_RECOVERY) { if (qla4xxx_eh_wait_for_active_target_commands(ha, cmd->device->id, cmd->device->lun)){ if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), cmd->device)) { dev_info(&ha->pdev->dev, "DEVICE RESET FAILED - waiting for " "commands.\n"); goto eh_dev_reset_done; } } dev_info(&ha->pdev->dev, "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", Loading @@ -1578,6 +1575,53 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) return ret; } /** * qla4xxx_eh_target_reset - callback for target reset. * @cmd: Pointer to Linux's SCSI command structure * * This routine is called by the Linux OS to reset the target. **/ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) { struct scsi_qla_host *ha = to_qla_host(cmd->device->host); struct ddb_entry *ddb_entry = cmd->device->hostdata; int stat; if (!ddb_entry) return FAILED; starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET ISSUED.\n"); DEBUG2(printk(KERN_INFO "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ, ha->dpc_flags, cmd->result, cmd->allowed)); stat = qla4xxx_reset_target(ha, ddb_entry); if (stat != QLA_SUCCESS) { starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET FAILED.\n"); return FAILED; } /* Send marker. */ ha->marker_needed = 1; if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), NULL)) { starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET DEVICE RESET FAILED - " "waiting for commands.\n"); return FAILED; } starget_printk(KERN_INFO, scsi_target(cmd->device), "WARM TARGET RESET SUCCEEDED.\n"); return SUCCESS; } /** * qla4xxx_eh_host_reset - kernel callback * @cmd: Pointer to Linux's SCSI command structure Loading