📄 qla1280.c
字号:
* the bytes would be pairwise reversed. Since most of the * firmware quantites are, in fact, bytes, we do an extra * le16_to_cpu() in the firmware read routine. * * The upshot of all this is that the bytes in the firmware * are in the correct places, but the 16 and 32 bit quantites * are still in little endian format. We fix that up below by * doing extra reverses on them */ nv->isp_parameter = cpu_to_le16(nv->isp_parameter); nv->firmware_feature.w = cpu_to_le16(nv->firmware_feature.w); for(i = 0; i < MAX_BUSES; i++) { nv->bus[i].selection_timeout = cpu_to_le16(nv->bus[i].selection_timeout); nv->bus[i].max_queue_depth = cpu_to_le16(nv->bus[i].max_queue_depth); } dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n"); LEAVE("qla1280_read_nvram"); return chksum;}/************************************************************************** * qla1280_info * Return a string describing the driver. **************************************************************************/static const char *qla1280_info(struct Scsi_Host *host){ static char qla1280_scsi_name_buffer[125]; char *bp; struct scsi_qla_host *ha; struct qla_boards *bdp; bp = &qla1280_scsi_name_buffer[0]; ha = (struct scsi_qla_host *)host->hostdata; bdp = &ql1280_board_tbl[ha->devnum]; memset(bp, 0, sizeof(qla1280_scsi_name_buffer)); sprintf (bp, "QLogic %s PCI to SCSI Host Adapter\n" " Firmware version: %2d.%02d.%02d, Driver version %s", &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], QLA1280_VERSION); return bp;}/************************************************************************** * qla1200_queuecommand * Queue a command to the controller. * * Note: * The mid-level driver tries to ensures that queuecommand never gets invoked * concurrently with itself or the interrupt handler (although the * interrupt handler may call this routine as part of request-completion * handling). Unfortunely, it sometimes calls the scheduler in interrupt * context which is a big NO! NO!. **************************************************************************/static intqla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)){ struct Scsi_Host *host = cmd->device->host; struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; struct srb *sp = (struct srb *)&cmd->SCp; int status; cmd->scsi_done = fn; sp->cmd = cmd; sp->flags = 0; qla1280_print_scsi_cmd(5, cmd);#ifdef QLA_64BIT_PTR /* * Using 64 bit commands if the PCI bridge doesn't support it is a * bit wasteful, however this should really only happen if one's * PCI controller is completely broken, like the BCM1250. For * sane hardware this is not an issue. */ status = qla1280_64bit_start_scsi(ha, sp);#else status = qla1280_32bit_start_scsi(ha, sp);#endif return status;}enum action { ABORT_COMMAND, ABORT_DEVICE, DEVICE_RESET, BUS_RESET, ADAPTER_RESET, FAIL};/* timer action for error action processor */static void qla1280_error_wait_timeout(unsigned long __data){ struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data; struct srb *sp = (struct srb *)CMD_SP(cmd); complete(sp->wait);}static void qla1280_mailbox_timeout(unsigned long __data){ struct scsi_qla_host *ha = (struct scsi_qla_host *)__data; struct device_reg *reg; reg = ha->iobase; ha->mailbox_out[0] = RD_REG_WORD(®->mailbox0); printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, " "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0], RD_REG_WORD(®->ictrl), RD_REG_WORD(®->istatus)); complete(ha->mailbox_wait);}/************************************************************************** * qla1200_error_action * The function will attempt to perform a specified error action and * wait for the results (or time out). * * Input: * cmd = Linux SCSI command packet of the command that cause the * bus reset. * action = error action to take (see action_t) * * Returns: * SUCCESS or FAILED * * Note: * Resetting the bus always succeeds - is has to, otherwise the * kernel will panic! Try a surgical technique - sending a BUS * DEVICE RESET message - on the offending target before pulling * the SCSI bus reset line. **************************************************************************/static intqla1280_error_action(struct scsi_cmnd *cmd, enum action action){ struct scsi_qla_host *ha; int bus, target, lun; struct srb *sp; uint16_t data; unsigned char *handle; int result, i; DECLARE_COMPLETION(wait); struct timer_list timer; ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata); 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: ha->flags.in_reset = 1; 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); ha->flags.in_reset = 1; if (qla1280_device_reset(ha, bus, target) == 0) result = SUCCESS; break; case BUS_RESET: if (qla1280_verbose) printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " "DEVICE RESET\n", ha->host_no, bus); ha->flags.in_reset = 1; 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); ha->flags.in_reset = 0; /* 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(HOST_LOCK); wait_for_completion(&wait); del_timer_sync(&timer); spin_lock_irq(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){ return qla1280_error_action(cmd, ABORT_COMMAND);}/************************************************************************** * qla1280_device_reset * Reset the specified SCSI device **************************************************************************/static intqla1280_eh_device_reset(struct scsi_cmnd *cmd){ return qla1280_error_action(cmd, DEVICE_RESET);}/************************************************************************** * qla1280_bus_reset * Reset the specified bus. **************************************************************************/static intqla1280_eh_bus_reset(struct scsi_cmnd *cmd){ return qla1280_error_action(cmd, BUS_RESET);}/************************************************************************** * qla1280_adapter_reset * Reset the specified adapter (both channels) **************************************************************************/static intqla1280_eh_adapter_reset(struct scsi_cmnd *cmd){ return qla1280_error_action(cmd, ADAPTER_RESET);}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;}#if LINUX_VERSION_CODE < 0x020600static intqla1280_detect(Scsi_Host_Template *template){ struct pci_device_id *id = &qla1280_pci_tbl[0]; struct pci_dev *pdev = NULL; int num_hosts = 0; if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { printk(KERN_WARNING "qla1280: struct srb too big, aborting\n"); return 0; } if ((DMA_BIDIRECTIONAL != PCI_DMA_BIDIRECTIONAL) || (DMA_TO_DEVICE != PCI_DMA_TODEVICE) || (DMA_FROM_DEVICE != PCI_DMA_FROMDEVICE) || (DMA_NONE != PCI_DMA_NONE)) { printk(KERN_WARNING
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -