Loading drivers/scsi/arcmsr/arcmsr_hba.c +75 −184 Original line number Diff line number Diff line Loading @@ -3671,6 +3671,39 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) msleep(1000); return; } static bool arcmsr_reset_in_progress(struct AdapterControlBlock *acb) { bool rtn = true; switch(acb->adapter_type) { case ACB_ADAPTER_TYPE_A:{ struct MessageUnit_A __iomem *reg = acb->pmuA; rtn = ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) ? true : false; } break; case ACB_ADAPTER_TYPE_B:{ struct MessageUnit_B *reg = acb->pmuB; rtn = ((readl(reg->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0) ? true : false; } break; case ACB_ADAPTER_TYPE_C:{ struct MessageUnit_C __iomem *reg = acb->pmuC; rtn = (readl(®->host_diagnostic) & 0x04) ? true : false; } break; case ACB_ADAPTER_TYPE_D:{ struct MessageUnit_D *reg = acb->pmuD; rtn = ((readl(reg->sample_at_reset) & 0x80) == 0) ? true : false; } break; } return rtn; } static void arcmsr_iop_init(struct AdapterControlBlock *acb) { uint32_t intmask_org; Loading Loading @@ -3725,142 +3758,16 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) static int arcmsr_bus_reset(struct scsi_cmnd *cmd) { struct AdapterControlBlock *acb; uint32_t intmask_org, outbound_doorbell; int retry_count = 0; int rtn = FAILED; acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts); pr_notice("arcmsr: executing bus reset eh.....num_resets = %d," " num_aborts = %d \n", acb->num_resets, acb->num_aborts); acb->num_resets++; switch(acb->adapter_type){ case ACB_ADAPTER_TYPE_A:{ if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); if (timeout) { return SUCCESS; } } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_A __iomem *reg; reg = acb->pmuA; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; sleep_again: ssleep(ARCMSR_SLEEPTIME); if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto sleep_again; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); /* clear Qbuffer if door bell ringed */ outbound_doorbell = readl(®->outbound_doorbell); writel(outbound_doorbell, ®->outbound_doorbell); /*clear interrupt */ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); /* enable outbound Post Queue,outbound doorbell Interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_B:{ acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = FAILED; } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_C:{ if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); if (timeout) { return SUCCESS; } } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_C __iomem *reg; reg = acb->pmuC; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; sleep: ssleep(ARCMSR_SLEEPTIME); if ((readl(®->host_diagnostic) & 0x04) != 0) { printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto sleep; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); /* clear Qbuffer if door bell ringed */ arcmsr_clear_doorbell_queue_buffer(acb); /* enable outbound Post Queue,outbound doorbell Interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_D: { if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; pr_notice("arcmsr: there is an bus reset" " eh proceeding.......\n"); pr_notice("arcmsr: there is an bus reset eh proceeding...\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220 * HZ); if (timeout) Loading @@ -3868,55 +3775,39 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_D *reg; reg = acb->pmuD; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; nap: wait_reset_done: ssleep(ARCMSR_SLEEPTIME); if ((readl(reg->sample_at_reset) & 0x80) != 0) { pr_err("arcmsr%d: waiting for " "hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (arcmsr_reset_in_progress(acb)) { if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; pr_err("arcmsr%d: waiting for hw bus" " reset return, " "RETRY TERMINATED!!\n", pr_notice("arcmsr%d: waiting for hw bus reset" " return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto nap; goto wait_reset_done; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); arcmsr_clear_doorbell_queue_buffer(acb); arcmsr_enable_outbound_ints(acb, intmask_org); arcmsr_iop_init(acb); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; pr_err("arcmsr: scsi bus reset " "eh returns with success\n"); pr_notice("arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); rtn = SUCCESS; } break; } } return rtn; } Loading Loading
drivers/scsi/arcmsr/arcmsr_hba.c +75 −184 Original line number Diff line number Diff line Loading @@ -3671,6 +3671,39 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) msleep(1000); return; } static bool arcmsr_reset_in_progress(struct AdapterControlBlock *acb) { bool rtn = true; switch(acb->adapter_type) { case ACB_ADAPTER_TYPE_A:{ struct MessageUnit_A __iomem *reg = acb->pmuA; rtn = ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) ? true : false; } break; case ACB_ADAPTER_TYPE_B:{ struct MessageUnit_B *reg = acb->pmuB; rtn = ((readl(reg->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0) ? true : false; } break; case ACB_ADAPTER_TYPE_C:{ struct MessageUnit_C __iomem *reg = acb->pmuC; rtn = (readl(®->host_diagnostic) & 0x04) ? true : false; } break; case ACB_ADAPTER_TYPE_D:{ struct MessageUnit_D *reg = acb->pmuD; rtn = ((readl(reg->sample_at_reset) & 0x80) == 0) ? true : false; } break; } return rtn; } static void arcmsr_iop_init(struct AdapterControlBlock *acb) { uint32_t intmask_org; Loading Loading @@ -3725,142 +3758,16 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) static int arcmsr_bus_reset(struct scsi_cmnd *cmd) { struct AdapterControlBlock *acb; uint32_t intmask_org, outbound_doorbell; int retry_count = 0; int rtn = FAILED; acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts); pr_notice("arcmsr: executing bus reset eh.....num_resets = %d," " num_aborts = %d \n", acb->num_resets, acb->num_aborts); acb->num_resets++; switch(acb->adapter_type){ case ACB_ADAPTER_TYPE_A:{ if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); if (timeout) { return SUCCESS; } } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_A __iomem *reg; reg = acb->pmuA; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; sleep_again: ssleep(ARCMSR_SLEEPTIME); if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto sleep_again; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); /* clear Qbuffer if door bell ringed */ outbound_doorbell = readl(®->outbound_doorbell); writel(outbound_doorbell, ®->outbound_doorbell); /*clear interrupt */ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); /* enable outbound Post Queue,outbound doorbell Interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_B:{ acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = FAILED; } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_C:{ if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); if (timeout) { return SUCCESS; } } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_C __iomem *reg; reg = acb->pmuC; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; sleep: ssleep(ARCMSR_SLEEPTIME); if ((readl(®->host_diagnostic) & 0x04) != 0) { printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto sleep; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); /* clear Qbuffer if door bell ringed */ arcmsr_clear_doorbell_queue_buffer(acb); /* enable outbound Post Queue,outbound doorbell Interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); rtn = SUCCESS; } break; } case ACB_ADAPTER_TYPE_D: { if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; pr_notice("arcmsr: there is an bus reset" " eh proceeding.......\n"); pr_notice("arcmsr: there is an bus reset eh proceeding...\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220 * HZ); if (timeout) Loading @@ -3868,55 +3775,39 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) } acb->acb_flags |= ACB_F_BUS_RESET; if (!arcmsr_iop_reset(acb)) { struct MessageUnit_D *reg; reg = acb->pmuD; arcmsr_hardware_reset(acb); acb->acb_flags &= ~ACB_F_IOP_INITED; nap: wait_reset_done: ssleep(ARCMSR_SLEEPTIME); if ((readl(reg->sample_at_reset) & 0x80) != 0) { pr_err("arcmsr%d: waiting for " "hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); if (arcmsr_reset_in_progress(acb)) { if (retry_count > ARCMSR_RETRYCOUNT) { acb->fw_flag = FW_DEADLOCK; pr_err("arcmsr%d: waiting for hw bus" " reset return, " "RETRY TERMINATED!!\n", pr_notice("arcmsr%d: waiting for hw bus reset" " return, RETRY TERMINATED!!\n", acb->host->host_no); return FAILED; } retry_count++; goto nap; goto wait_reset_done; } acb->acb_flags |= ACB_F_IOP_INITED; /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_get_firmware_spec(acb); arcmsr_start_adapter_bgrb(acb); arcmsr_clear_doorbell_queue_buffer(acb); arcmsr_enable_outbound_ints(acb, intmask_org); arcmsr_iop_init(acb); atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); acb->acb_flags &= ~ACB_F_BUS_RESET; rtn = SUCCESS; pr_err("arcmsr: scsi bus reset " "eh returns with success\n"); pr_notice("arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; atomic_set(&acb->rq_map_token, 16); atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); rtn = SUCCESS; } break; } } return rtn; } Loading