qla_os.c
来自「linux2.6.16版本」· C语言 代码 · 共 2,593 行 · 第 1/5 页
C
2,593 行
return(status);}/* * qla2x00_device_reset * Issue bus device reset message to the target. * * Input: * ha = adapter block pointer. * t = SCSI ID. * TARGET_QUEUE_LOCK must be released. * ADAPTER_STATE_LOCK must be released. * * Context: * Kernel context. */static intqla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport){ /* Abort Target command will clear Reservation */ return ha->isp_ops.abort_target(reset_fcport);}static intqla2xxx_slave_alloc(struct scsi_device *sdev){ struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; sdev->hostdata = *(fc_port_t **)rport->dd_data; return 0;}static intqla2xxx_slave_configure(struct scsi_device *sdev){ scsi_qla_host_t *ha = to_qla_host(sdev->host); struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) scsi_activate_tcq(sdev, 32); else scsi_deactivate_tcq(sdev, 32); rport->dev_loss_tmo = ha->port_down_retry_count + 5; return 0;}static voidqla2xxx_slave_destroy(struct scsi_device *sdev){ sdev->hostdata = NULL;}static intqla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth){ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); return sdev->queue_depth;}static intqla2x00_change_queue_type(struct scsi_device *sdev, int tag_type){ if (sdev->tagged_supported) { scsi_set_tag_type(sdev, tag_type); if (tag_type) scsi_activate_tcq(sdev, sdev->queue_depth); else scsi_deactivate_tcq(sdev, sdev->queue_depth); } else tag_type = 0; return tag_type;}/** * qla2x00_config_dma_addressing() - Configure OS DMA addressing method. * @ha: HA context * * At exit, the @ha's flags.enable_64bit_addressing set to indicated * supported addressing method. */static voidqla2x00_config_dma_addressing(scsi_qla_host_t *ha){ /* Assume a 32bit DMA mask. */ ha->flags.enable_64bit_addressing = 0; if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) { /* Any upper-dword bits set? */ if (MSD(dma_get_required_mask(&ha->pdev->dev)) && !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { /* Ok, a 64bit DMA mask is applicable. */ ha->flags.enable_64bit_addressing = 1; ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64; ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64; return; } } dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK); pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);}static intqla2x00_iospace_config(scsi_qla_host_t *ha){ unsigned long pio, pio_len, pio_flags; unsigned long mmio, mmio_len, mmio_flags; /* We only need PIO for Flash operations on ISP2312 v2 chips. */ pio = pci_resource_start(ha->pdev, 0); pio_len = pci_resource_len(ha->pdev, 0); pio_flags = pci_resource_flags(ha->pdev, 0); if (pio_flags & IORESOURCE_IO) { if (pio_len < MIN_IOBASE_LEN) { qla_printk(KERN_WARNING, ha, "Invalid PCI I/O region size (%s)...\n", pci_name(ha->pdev)); pio = 0; } } else { qla_printk(KERN_WARNING, ha, "region #0 not a PIO resource (%s)...\n", pci_name(ha->pdev)); pio = 0; } /* Use MMIO operations for all accesses. */ mmio = pci_resource_start(ha->pdev, 1); mmio_len = pci_resource_len(ha->pdev, 1); mmio_flags = pci_resource_flags(ha->pdev, 1); if (!(mmio_flags & IORESOURCE_MEM)) { qla_printk(KERN_ERR, ha, "region #0 not an MMIO resource (%s), aborting\n", pci_name(ha->pdev)); goto iospace_error_exit; } if (mmio_len < MIN_IOBASE_LEN) { qla_printk(KERN_ERR, ha, "Invalid PCI mem region size (%s), aborting\n", pci_name(ha->pdev)); goto iospace_error_exit; } if (pci_request_regions(ha->pdev, ha->brd_info->drv_name)) { qla_printk(KERN_WARNING, ha, "Failed to reserve PIO/MMIO regions (%s)\n", pci_name(ha->pdev)); goto iospace_error_exit; } ha->pio_address = pio; ha->pio_length = pio_len; ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); if (!ha->iobase) { qla_printk(KERN_ERR, ha, "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev)); goto iospace_error_exit; } return (0);iospace_error_exit: return (-ENOMEM);}static voidqla2x00_enable_intrs(scsi_qla_host_t *ha){ unsigned long flags = 0; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; spin_lock_irqsave(&ha->hardware_lock, flags); ha->interrupts_on = 1; /* enable risc and host interrupts */ WRT_REG_WORD(®->ictrl, ICR_EN_INT | ICR_EN_RISC); RD_REG_WORD(®->ictrl); spin_unlock_irqrestore(&ha->hardware_lock, flags);}static voidqla2x00_disable_intrs(scsi_qla_host_t *ha){ unsigned long flags = 0; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; spin_lock_irqsave(&ha->hardware_lock, flags); ha->interrupts_on = 0; /* disable risc and host interrupts */ WRT_REG_WORD(®->ictrl, 0); RD_REG_WORD(®->ictrl); spin_unlock_irqrestore(&ha->hardware_lock, flags);}static voidqla24xx_enable_intrs(scsi_qla_host_t *ha){ unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; spin_lock_irqsave(&ha->hardware_lock, flags); ha->interrupts_on = 1; WRT_REG_DWORD(®->ictrl, ICRX_EN_RISC_INT); RD_REG_DWORD(®->ictrl); spin_unlock_irqrestore(&ha->hardware_lock, flags);}static voidqla24xx_disable_intrs(scsi_qla_host_t *ha){ unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; spin_lock_irqsave(&ha->hardware_lock, flags); ha->interrupts_on = 0; WRT_REG_DWORD(®->ictrl, 0); RD_REG_DWORD(®->ictrl); spin_unlock_irqrestore(&ha->hardware_lock, flags);}/* * PCI driver interface */int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info){ int ret = -ENODEV; device_reg_t __iomem *reg; struct Scsi_Host *host; scsi_qla_host_t *ha; unsigned long flags = 0; unsigned long wait_switch = 0; char pci_info[20]; char fw_str[30]; fc_port_t *fcport; struct scsi_host_template *sht; if (pci_enable_device(pdev)) goto probe_out; sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) sht = &qla24xx_driver_template; host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); if (host == NULL) { printk(KERN_WARNING "qla2xxx: Couldn't allocate host from scsi layer!\n"); goto probe_disable_device; } /* Clear our data area */ ha = (scsi_qla_host_t *)host->hostdata; memset(ha, 0, sizeof(scsi_qla_host_t)); ha->pdev = pdev; ha->host = host; ha->host_no = host->host_no; ha->brd_info = brd_info; sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); ha->dpc_pid = -1; /* Configure PCI I/O space */ ret = qla2x00_iospace_config(ha); if (ret) goto probe_failed; qla_printk(KERN_INFO, ha, "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq, ha->iobase); spin_lock_init(&ha->hardware_lock); ha->prev_topology = 0; ha->ports = MAX_BUSES; ha->init_cb_size = sizeof(init_cb_t); ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; ha->link_data_rate = LDR_UNKNOWN; ha->optrom_size = OPTROM_SIZE_2300; /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; ha->isp_ops.reset_chip = qla2x00_reset_chip; ha->isp_ops.chip_diag = qla2x00_chip_diag; ha->isp_ops.config_rings = qla2x00_config_rings; ha->isp_ops.reset_adapter = qla2x00_reset_adapter; ha->isp_ops.nvram_config = qla2x00_nvram_config; ha->isp_ops.update_fw_options = qla2x00_update_fw_options; ha->isp_ops.load_risc = qla2x00_load_risc; ha->isp_ops.pci_info_str = qla2x00_pci_info_str; ha->isp_ops.fw_version_str = qla2x00_fw_version_str; ha->isp_ops.intr_handler = qla2100_intr_handler; ha->isp_ops.enable_intrs = qla2x00_enable_intrs; ha->isp_ops.disable_intrs = qla2x00_disable_intrs; ha->isp_ops.abort_command = qla2x00_abort_command; ha->isp_ops.abort_target = qla2x00_abort_target; ha->isp_ops.fabric_login = qla2x00_login_fabric; ha->isp_ops.fabric_logout = qla2x00_fabric_logout; ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_32; ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_32; ha->isp_ops.prep_ms_iocb = qla2x00_prep_ms_iocb; ha->isp_ops.prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb; ha->isp_ops.read_nvram = qla2x00_read_nvram_data; ha->isp_ops.write_nvram = qla2x00_write_nvram_data; ha->isp_ops.fw_dump = qla2100_fw_dump; ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; ha->isp_ops.read_optrom = qla2x00_read_optrom_data; ha->isp_ops.write_optrom = qla2x00_write_optrom_data; if (IS_QLA2100(ha)) { host->max_id = MAX_TARGETS_2100; ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; ha->request_q_length = REQUEST_ENTRY_CNT_2100; ha->response_q_length = RESPONSE_ENTRY_CNT_2100; ha->last_loop_id = SNS_LAST_LOOP_ID_2100; host->sg_tablesize = 32; ha->gid_list_info_size = 4; } else if (IS_QLA2200(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; ha->request_q_length = REQUEST_ENTRY_CNT_2200; ha->response_q_length = RESPONSE_ENTRY_CNT_2100; ha->last_loop_id = SNS_LAST_LOOP_ID_2100; ha->gid_list_info_size = 4; } else if (IS_QLA23XX(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; ha->request_q_length = REQUEST_ENTRY_CNT_2200; ha->response_q_length = RESPONSE_ENTRY_CNT_2300; ha->last_loop_id = SNS_LAST_LOOP_ID_2300; ha->isp_ops.pci_config = qla2300_pci_config; ha->isp_ops.intr_handler = qla2300_intr_handler; ha->isp_ops.fw_dump = qla2300_fw_dump; ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; ha->isp_ops.beacon_on = qla2x00_beacon_on; ha->isp_ops.beacon_off = qla2x00_beacon_off; ha->isp_ops.beacon_blink = qla2x00_beacon_blink; ha->gid_list_info_size = 6; if (IS_QLA2322(ha) || IS_QLA6322(ha)) ha->optrom_size = OPTROM_SIZE_2322; } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; ha->request_q_length = REQUEST_ENTRY_CNT_24XX; ha->response_q_length = RESPONSE_ENTRY_CNT_2300; ha->last_loop_id = SNS_LAST_LOOP_ID_2300; ha->init_cb_size = sizeof(struct init_cb_24xx); ha->mgmt_svr_loop_id = 10; ha->isp_ops.pci_config = qla24xx_pci_config; ha->isp_ops.reset_chip = qla24xx_reset_chip; ha->isp_ops.chip_diag = qla24xx_chip_diag; ha->isp_ops.config_rings = qla24xx_config_rings; ha->isp_ops.reset_adapter = qla24xx_reset_adapter; ha->isp_ops.nvram_config = qla24xx_nvram_config; ha->isp_ops.update_fw_options = qla24xx_update_fw_options; ha->isp_ops.load_risc = qla24xx_load_risc;#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) if (ql2xfwloadflash) ha->isp_ops.load_risc = qla24xx_load_risc_flash;#endif ha->isp_ops.pci_info_str = qla24xx_pci_info_str; ha->isp_ops.fw_version_str = qla24xx_fw_version_str; ha->isp_ops.intr_handler = qla24xx_intr_handler; ha->isp_ops.enable_intrs = qla24xx_enable_intrs; ha->isp_ops.disable_intrs = qla24xx_disable_intrs; ha->isp_ops.abort_command = qla24xx_abort_command; ha->isp_ops.abort_target = qla24xx_abort_target; ha->isp_ops.fabric_login = qla24xx_login_fabric; ha->isp_ops.fabric_logout = qla24xx_fabric_logout; ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb; ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb; ha->isp_ops.read_nvram = qla24xx_read_nvram_data; ha->isp_ops.write_nvram = qla24xx_write_nvram_data; ha->isp_ops.fw_dump = qla24xx_fw_dump; ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; ha->isp_ops.read_optrom = qla24xx_read_optrom_data; ha->isp_ops.write_optrom = qla24xx_write_optrom_data; ha->isp_ops.beacon_on = qla24xx_beacon_on; ha->isp_ops.beacon_off = qla24xx_beacon_off; ha->isp_ops.beacon_blink = qla24xx_beacon_blink; ha->gid_list_info_size = 8; ha->optrom_size = OPTROM_SIZE_24XX; } host->can_queue = ha->request_q_length + 128; /* load the F/W, read paramaters, and init the H/W */ ha->instance = num_hosts; init_MUTEX(&ha->mbx_cmd_sem); init_MUTEX_LOCKED(&ha->mbx_intr_sem); INIT_LIST_HEAD(&ha->list); INIT_LIST_HEAD(&ha->fcports); INIT_LIST_HEAD(&ha->rscn_fcports); /* * These locks are used to prevent more than one CPU * from modifying the queue at the same time. The * higher level "host_lock" will reduce most * contention for these locks. */ spin_lock_init(&ha->mbx_reg_lock); init_completion(&ha->dpc_inited); init_completion(&ha->dpc_exited); qla2x00_config_dma_addressing(ha); if (qla2x00_mem_alloc(ha)) { qla_printk(KERN_WARNING, ha, "[ERROR] Failed to allocate memory for adapter\n"); ret = -ENOMEM; goto probe_failed; } if (qla2x00_initialize_adapter(ha) && !(ha->device_flags & DFLG_NO_CABLE)) { qla_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); DEBUG2(printk("scsi(%ld): Failed to initialize adapter - " "Adapter flags %x.\n", ha->host_no, ha->device_flags)); ret = -ENODEV; goto probe_failed; } /* * Startup the kernel thread for this host adapter */ ha->dpc_should_die = 0; ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0); if (ha->dpc_pid < 0) { qla_printk(KERN_WARNING, ha, "Unable to start DPC thread!\n"); ret = -ENODEV; goto probe_failed; } wait_for_completion(&ha->dpc_inited); host->this_id = 255; host->cmd_per_lun = 3; host->unique_id = ha->instance; host->max_cmd_len = MAX_CMDSZ; host->max_channel = ha->ports - 1; host->max_lun = MAX_LUNS; host->transportt = qla2xxx_transport_template; ret = request_irq(pdev->irq, ha->isp_ops.intr_handler, SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); if (ret) { qla_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d already in use.\n", pdev->irq); goto probe_failed; } host->irq = pdev->irq; /* Initialized the timer */ qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL); DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", ha->host_no, ha)); ha->isp_ops.disable_intrs(ha); spin_lock_irqsave(&ha->hardware_lock, flags); reg = ha->iobase; if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); } else { WRT_REG_WORD(®->isp.semaphore, 0); WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); /* Enable proper parity */ if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) { if (IS_QLA2300(ha)) /* SRAM parity */ WRT_REG_WORD(®->isp.hccr, (HCCR_ENABLE_PARITY + 0x1)); else /* SRAM, Instruction RAM and GP RAM parity */ WRT_REG_WORD(®->isp.hccr, (HCCR_ENABLE_PARITY + 0x7)); } } spin_unlock_irqrestore(&ha->hardware_lock, flags); ha->isp_ops.enable_intrs(ha); /* v2.19.5b6 */ /* * Wait around max loop_reset_delay secs for the devices to come * on-line. We don't want Linux scanning before we are ready. * */ for (wait_switch = jiffies + (ha->loop_reset_delay * HZ); time_before(jiffies,wait_switch) && !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES)) && (ha->device_flags & SWITCH_FOUND) ;) { qla2x00_check_fabric_devices(ha); msleep(10);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?