📄 qla1280.c
字号:
dprintk(4, "error_action %i, istatus 0x%04x\n", action, RD_REG_WORD(&ha->iobase->istatus)); dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n", RD_REG_WORD(&ha->iobase->host_cmd), RD_REG_WORD(&ha->iobase->ictrl), jiffies); ENTER("qla1280_error_action"); if (qla1280_verbose) printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, " "Handle=0x%p, action=0x%x\n", ha->host_no, cmd, CMD_HANDLE(cmd), action); if (cmd == NULL) { printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL " "si_Cmnd pointer, failing.\n"); LEAVE("qla1280_error_action"); return FAILED; } ha = (struct scsi_qla_host *)cmd->device->host->hostdata; sp = (struct srb *)CMD_SP(cmd); handle = CMD_HANDLE(cmd); /* Check for pending interrupts. */ data = qla1280_debounce_register(&ha->iobase->istatus); /* * The io_request_lock is held when the reset handler is called, hence * the interrupt handler cannot be running in parallel as it also * grabs the lock. /Jes */ if (data & RISC_INT) qla1280_isr(ha, &ha->done_q); /* * Determine the suggested action that the mid-level driver wants * us to perform. */ if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) { if(action == ABORT_COMMAND) { /* we never got this command */ printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); return SUCCESS; /* no action - we don't have command */ } } else { sp->wait = &wait; } bus = SCSI_BUS_32(cmd); target = SCSI_TCN_32(cmd); lun = SCSI_LUN_32(cmd); /* Overloading result. Here it means the success or fail of the * *issue* of the action. When we return from the routine, it must * mean the actual success or fail of the action */ result = FAILED; switch (action) { case FAIL: break; case ABORT_COMMAND: if ((sp->flags & SRB_ABORT_PENDING)) { printk(KERN_WARNING "scsi(): Command has a pending abort " "message - ABORT_PENDING.\n"); /* This should technically be impossible since we * now wait for abort completion */ break; } for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { if (sp == ha->outstanding_cmds[i]) { dprintk(1, "qla1280: RISC aborting command\n"); if (qla1280_abort_command(ha, sp, i) == 0) result = SUCCESS; else { /* * Since we don't know what might * have happend to the command, it * is unsafe to remove it from the * device's queue at this point. * Wait and let the escalation * process take care of it. */ printk(KERN_WARNING "scsi(%li:%i:%i:%i): Unable" " to abort command!\n", ha->host_no, bus, target, lun); } } } break; case ABORT_DEVICE: if (qla1280_verbose) printk(KERN_INFO "scsi(%ld:%d:%d:%d): Queueing abort device " "command.\n", ha->host_no, bus, target, lun); if (qla1280_abort_device(ha, bus, target, lun) == 0) result = SUCCESS; break; case DEVICE_RESET: if (qla1280_verbose) printk(KERN_INFO "scsi(%ld:%d:%d:%d): Queueing device reset " "command.\n", ha->host_no, bus, target, lun); if (qla1280_device_reset(ha, bus, target) == 0) result = SUCCESS; break; case BUS_RESET: if (qla1280_verbose) printk(KERN_INFO "qla1280(%ld:%d): Issued bus " "reset.\n", ha->host_no, bus); if (qla1280_bus_reset(ha, bus) == 0) result = SUCCESS; break; case ADAPTER_RESET: default: if (qla1280_verbose) { printk(KERN_INFO "scsi(%ld): Issued ADAPTER RESET\n", ha->host_no); printk(KERN_INFO "scsi(%ld): I/O processing will " "continue automatically\n", ha->host_no); } ha->flags.reset_active = 1; /* * We restarted all of the commands automatically, so the * mid-level code can expect completions momentitarily. */ if (qla1280_abort_isp(ha) == 0) result = SUCCESS; ha->flags.reset_active = 0; } if (!list_empty(&ha->done_q)) qla1280_done(ha); /* If we didn't manage to issue the action, or we have no * command to wait for, exit here */ if (result == FAILED || handle == NULL || handle == (unsigned char *)INVALID_HANDLE) { /* * Clear completion queue to avoid qla1280_done() trying * to complete the command at a later stage after we * have exited the current context */ sp->wait = NULL; goto leave; } /* set up a timer just in case we're really jammed */ init_timer(&timer); timer.expires = jiffies + 4*HZ; timer.data = (unsigned long)cmd; timer.function = qla1280_error_wait_timeout; add_timer(&timer); /* wait for the action to complete (or the timer to expire) */ spin_unlock_irq(ha->host->host_lock); wait_for_completion(&wait); del_timer_sync(&timer); spin_lock_irq(ha->host->host_lock); sp->wait = NULL; /* the only action we might get a fail for is abort */ if (action == ABORT_COMMAND) { if(sp->flags & SRB_ABORTED) result = SUCCESS; else result = FAILED; } leave: dprintk(1, "RESET returning %d\n", result); LEAVE("qla1280_error_action"); return result;}/************************************************************************** * qla1280_abort * Abort the specified SCSI command(s). **************************************************************************/static intqla1280_eh_abort(struct scsi_cmnd * cmd){ int rc; spin_lock_irq(cmd->device->host->host_lock); rc = qla1280_error_action(cmd, ABORT_COMMAND); spin_unlock_irq(cmd->device->host->host_lock); return rc;}/************************************************************************** * qla1280_device_reset * Reset the specified SCSI device **************************************************************************/static intqla1280_eh_device_reset(struct scsi_cmnd *cmd){ int rc; spin_lock_irq(cmd->device->host->host_lock); rc = qla1280_error_action(cmd, DEVICE_RESET); spin_unlock_irq(cmd->device->host->host_lock); return rc;}/************************************************************************** * qla1280_bus_reset * Reset the specified bus. **************************************************************************/static intqla1280_eh_bus_reset(struct scsi_cmnd *cmd){ int rc; spin_lock_irq(cmd->device->host->host_lock); rc = qla1280_error_action(cmd, BUS_RESET); spin_unlock_irq(cmd->device->host->host_lock); return rc;}/************************************************************************** * qla1280_adapter_reset * Reset the specified adapter (both channels) **************************************************************************/static intqla1280_eh_adapter_reset(struct scsi_cmnd *cmd){ int rc; spin_lock_irq(cmd->device->host->host_lock); rc = qla1280_error_action(cmd, ADAPTER_RESET); spin_unlock_irq(cmd->device->host->host_lock); return rc;}static intqla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]){ int heads, sectors, cylinders; heads = 64; sectors = 32; cylinders = (unsigned long)capacity / (heads * sectors); if (cylinders > 1024) { heads = 255; sectors = 63; cylinders = (unsigned long)capacity / (heads * sectors); /* if (cylinders > 1023) cylinders = 1023; */ } geom[0] = heads; geom[1] = sectors; geom[2] = cylinders; return 0;} /* disable risc and host interrupts */static inline voidqla1280_disable_intrs(struct scsi_qla_host *ha){ WRT_REG_WORD(&ha->iobase->ictrl, 0); RD_REG_WORD(&ha->iobase->ictrl); /* PCI Posted Write flush */}/* enable risc and host interrupts */static inline voidqla1280_enable_intrs(struct scsi_qla_host *ha){ WRT_REG_WORD(&ha->iobase->ictrl, (ISP_EN_INT | ISP_EN_RISC)); RD_REG_WORD(&ha->iobase->ictrl); /* PCI Posted Write flush */}/************************************************************************** * qla1280_intr_handler * Handles the H/W interrupt **************************************************************************/static irqreturn_tqla1280_intr_handler(int irq, void *dev_id){ struct scsi_qla_host *ha; struct device_reg __iomem *reg; u16 data; int handled = 0; ENTER_INTR ("qla1280_intr_handler"); ha = (struct scsi_qla_host *)dev_id; spin_lock(ha->host->host_lock); ha->isr_count++; reg = ha->iobase; qla1280_disable_intrs(ha); data = qla1280_debounce_register(®->istatus); /* Check for pending interrupts. */ if (data & RISC_INT) { qla1280_isr(ha, &ha->done_q); handled = 1; } if (!list_empty(&ha->done_q)) qla1280_done(ha); spin_unlock(ha->host->host_lock); qla1280_enable_intrs(ha); LEAVE_INTR("qla1280_intr_handler"); return IRQ_RETVAL(handled);}static intqla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target){ uint8_t mr; uint16_t mb[MAILBOX_REGISTER_COUNT]; struct nvram *nv; int status, lun; nv = &ha->nvram; mr = BIT_3 | BIT_2 | BIT_1 | BIT_0; /* Set Target Parameters. */ mb[0] = MBC_SET_TARGET_PARAMETERS; mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8); mb[2] = nv->bus[bus].target[target].parameter.renegotiate_on_error << 8; mb[2] |= nv->bus[bus].target[target].parameter.stop_queue_on_check << 9; mb[2] |= nv->bus[bus].target[target].parameter.auto_request_sense << 10; mb[2] |= nv->bus[bus].target[target].parameter.tag_queuing << 11; mb[2] |= nv->bus[bus].target[target].parameter.enable_sync << 12; mb[2] |= nv->bus[bus].target[target].parameter.enable_wide << 13; mb[2] |= nv->bus[bus].target[target].parameter.parity_checking << 14; mb[2] |= nv->bus[bus].target[target].parameter.disconnect_allowed << 15; if (IS_ISP1x160(ha)) { mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5; mb[3] = (nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8); mb[6] = (nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8) | nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width; mr |= BIT_6; } else { mb[3] = (nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8); } mb[3] |= nv->bus[bus].target[target].sync_period; status = qla1280_mailbox_command(ha, mr, mb); /* Set Device Queue Parameters. */ for (lun = 0; lun < MAX_LUNS; lun++) { mb[0] = MBC_SET_DEVICE_QUEUE; mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8); mb[1] |= lun; mb[2] = nv->bus[bus].max_queue_depth; mb[3] = nv->bus[bus].target[target].execution_throttle; status |= qla1280_mailbox_command(ha, 0x0f, mb); } if (status) printk(KERN_WARNING "scsi(%ld:%i:%i): " "qla1280_set_target_parameters() failed\n", ha->host_no, bus, target); return status;}/************************************************************************** * qla1280_slave_configure * * Description: * Determines the queue depth for a given device. There are two ways * a queue depth can be obtained for a tagged queueing device. One * way is the default queue depth which is determined by whether * If it is defined, then it is used * as the default queue depth. Otherwise, we use either 4 or 8 as the * default queue depth (dependent on the number of hardware SCBs). **************************************************************************/static intqla1280_slave_configure(struct scsi_device *device){ struct scsi_qla_host *ha; int default_depth = 3; int bus = device->channel; int target = device->id; int status = 0; struct nvram *nv; unsigned long flags; ha = (struct scsi_qla_host *)device->host->hostdata; nv = &ha->nvram;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -