qla_os.c
来自「linux 内核源代码」· C语言 代码 · 共 2,525 行 · 第 1/5 页
C
2,525 行
return ret; qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, id, lun); if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) goto eh_host_reset_lock; /* * Fixme-may be dpc thread is active and processing * loop_resync,so wait a while for it to * be completed and then issue big hammer.Otherwise * it may cause I/O failure as big hammer marks the * devices as lost kicking of the port_down_timer * while dpc is stuck for the mailbox to complete. */ qla2x00_wait_for_loop_ready(ha); set_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); if (qla2x00_abort_isp(pha)) { clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); /* failed. schedule dpc to try */ set_bit(ISP_ABORT_NEEDED, &pha->dpc_flags); if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) goto eh_host_reset_lock; } clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); /* Waiting for our command in done_queue to be returned to OS.*/ if (qla2x00_eh_wait_for_pending_commands(pha)) ret = SUCCESS; if (ha->parent) qla2x00_vp_abort_isp(ha);eh_host_reset_lock: qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, (ret == FAILED) ? "failed" : "succeded"); return ret;}/** qla2x00_loop_reset* Issue loop reset.** Input:* ha = adapter block pointer.** Returns:* 0 = success*/static intqla2x00_loop_reset(scsi_qla_host_t *ha){ int ret; struct fc_port *fcport; if (ha->flags.enable_lip_full_login) { ret = qla2x00_full_login_lip(ha); if (ret != QLA_SUCCESS) { DEBUG2_3(printk("%s(%ld): bus_reset failed: " "full_login_lip=%d.\n", __func__, ha->host_no, ret)); } atomic_set(&ha->loop_state, LOOP_DOWN); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); qla2x00_mark_all_devices_lost(ha, 0); qla2x00_wait_for_loop_ready(ha); } if (ha->flags.enable_lip_reset) { ret = qla2x00_lip_reset(ha); if (ret != QLA_SUCCESS) { DEBUG2_3(printk("%s(%ld): bus_reset failed: " "lip_reset=%d.\n", __func__, ha->host_no, ret)); } qla2x00_wait_for_loop_ready(ha); } if (ha->flags.enable_target_reset) { list_for_each_entry(fcport, &ha->fcports, list) { if (fcport->port_type != FCT_TARGET) continue; ret = qla2x00_device_reset(ha, fcport); if (ret != QLA_SUCCESS) { DEBUG2_3(printk("%s(%ld): bus_reset failed: " "target_reset=%d d_id=%x.\n", __func__, ha->host_no, ret, fcport->d_id.b24)); } } } /* Issue marker command only when we are going to start the I/O */ ha->marker_needed = 1; return QLA_SUCCESS;}/* * 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 = shost_priv(sdev->host); struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) scsi_activate_tcq(sdev, ha->max_q_depth); else scsi_deactivate_tcq(sdev, ha->max_q_depth); 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 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);}static struct isp_operations qla2100_isp_ops = { .pci_config = qla2100_pci_config, .reset_chip = qla2x00_reset_chip, .chip_diag = qla2x00_chip_diag, .config_rings = qla2x00_config_rings, .reset_adapter = qla2x00_reset_adapter, .nvram_config = qla2x00_nvram_config, .update_fw_options = qla2x00_update_fw_options, .load_risc = qla2x00_load_risc, .pci_info_str = qla2x00_pci_info_str, .fw_version_str = qla2x00_fw_version_str, .intr_handler = qla2100_intr_handler, .enable_intrs = qla2x00_enable_intrs, .disable_intrs = qla2x00_disable_intrs, .abort_command = qla2x00_abort_command, .abort_target = qla2x00_abort_target, .fabric_login = qla2x00_login_fabric, .fabric_logout = qla2x00_fabric_logout, .calc_req_entries = qla2x00_calc_iocbs_32, .build_iocbs = qla2x00_build_scsi_iocbs_32, .prep_ms_iocb = qla2x00_prep_ms_iocb, .prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb, .read_nvram = qla2x00_read_nvram_data, .write_nvram = qla2x00_write_nvram_data, .fw_dump = qla2100_fw_dump, .beacon_on = NULL, .beacon_off = NULL, .beacon_blink = NULL, .read_optrom = qla2x00_read_optrom_data, .write_optrom = qla2x00_write_optrom_data, .get_flash_version = qla2x00_get_flash_version,};static struct isp_operations qla2300_isp_ops = { .pci_config = qla2300_pci_config, .reset_chip = qla2x00_reset_chip, .chip_diag = qla2x00_chip_diag, .config_rings = qla2x00_config_rings, .reset_adapter = qla2x00_reset_adapter, .nvram_config = qla2x00_nvram_config, .update_fw_options = qla2x00_update_fw_options, .load_risc = qla2x00_load_risc, .pci_info_str = qla2x00_pci_info_str, .fw_version_str = qla2x00_fw_version_str, .intr_handler = qla2300_intr_handler, .enable_intrs = qla2x00_enable_intrs, .disable_intrs = qla2x00_disable_intrs, .abort_command = qla2x00_abort_command, .abort_target = qla2x00_abort_target, .fabric_login = qla2x00_login_fabric, .fabric_logout = qla2x00_fabric_logout, .calc_req_entries = qla2x00_calc_iocbs_32, .build_iocbs = qla2x00_build_scsi_iocbs_32, .prep_ms_iocb = qla2x00_prep_ms_iocb, .prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb, .read_nvram = qla2x00_read_nvram_data, .write_nvram = qla2x00_write_nvram_data, .fw_dump = qla2300_fw_dump, .beacon_on = qla2x00_beacon_on, .beacon_off = qla2x00_beacon_off, .beacon_blink = qla2x00_beacon_blink, .read_optrom = qla2x00_read_optrom_data, .write_optrom = qla2x00_write_optrom_data, .get_flash_version = qla2x00_get_flash_version,};static struct isp_operations qla24xx_isp_ops = { .pci_config = qla24xx_pci_config, .reset_chip = qla24xx_reset_chip, .chip_diag = qla24xx_chip_diag, .config_rings = qla24xx_config_rings, .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla24xx_nvram_config, .update_fw_options = qla24xx_update_fw_options, .load_risc = qla24xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, .intr_handler = qla24xx_intr_handler, .enable_intrs = qla24xx_enable_intrs, .disable_intrs = qla24xx_disable_intrs, .abort_command = qla24xx_abort_command, .abort_target = qla24xx_abort_target, .fabric_login = qla24xx_login_fabric, .fabric_logout = qla24xx_fabric_logout, .calc_req_entries = NULL, .build_iocbs = NULL, .prep_ms_iocb = qla24xx_prep_ms_iocb, .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, .read_nvram = qla24xx_read_nvram_data, .write_nvram = qla24xx_write_nvram_data, .fw_dump = qla24xx_fw_dump, .beacon_on = qla24xx_beacon_on, .beacon_off = qla24xx_beacon_off, .beacon_blink = qla24xx_beacon_blink, .read_optrom = qla24xx_read_optrom_data, .write_optrom = qla24xx_write_optrom_data, .get_flash_version = qla24xx_get_flash_version,};static struct isp_operations qla25xx_isp_ops = { .pci_config = qla25xx_pci_config, .reset_chip = qla24xx_reset_chip, .chip_diag = qla24xx_chip_diag, .config_rings = qla24xx_config_rings, .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla24xx_nvram_config, .update_fw_options = qla24xx_update_fw_options, .load_risc = qla24xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, .intr_handler = qla24xx_intr_handler, .enable_intrs = qla24xx_enable_intrs, .disable_intrs = qla24xx_disable_intrs, .abort_command = qla24xx_abort_command, .abort_target = qla24xx_abort_target, .fabric_login = qla24xx_login_fabric, .fabric_logout = qla24xx_fabric_logout, .calc_req_entries = NULL, .build_iocbs = NULL, .prep_ms_iocb = qla24xx_prep_ms_iocb, .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, .read_nvram = qla25xx_read_nvram_data, .write_nvram = qla25xx_write_nvram_data, .fw_dump = qla25xx_fw_dump, .beacon_on = qla24xx_beacon_on, .beacon_off = qla24xx_beacon_off, .beacon_blink = qla24xx_beacon_blink, .read_optrom = qla25xx_read_optrom_data, .write_optrom = qla24xx_write_optrom_data, .get_flash_version = qla24xx_get_flash_version,};static inline voidqla2x00_set_isp_flags(scsi_qla_host_t *ha){ ha->device_type = DT_EXTENDED_IDS; switch (ha->pdev->device) { case PCI_DEVICE_ID_QLOGIC_ISP2100: ha->device_type |= DT_ISP2100; ha->device_type &= ~DT_EXTENDED_IDS; ha->fw_srisc_address = RISC_START_ADDRESS_2100; break; case PCI_DEVICE_ID_QLOGIC_ISP2200: ha->device_type |= DT_ISP2200; ha->device_type &= ~DT_EXTENDED_IDS; ha->fw_srisc_address = RISC_START_ADDRESS_2100; break; case PCI_DEVICE_ID_QLOGIC_ISP2300: ha->device_type |= DT_ISP2300; ha->device_type |= DT_ZIO_SUPPORTED; ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2312: ha->device_type |= DT_ISP2312; ha->device_type |= DT_ZIO_SUPPORTED; ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2322: ha->device_type |= DT_ISP2322; ha->device_type |= DT_ZIO_SUPPORTED; if (ha->pdev->subsystem_vendor == 0x1028 && ha->pdev->subsystem_device == 0x0170) ha->device_type |= DT_OEM_001; ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP6312: ha->device_type |= DT_ISP6312; ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP6322: ha->device_type |= DT_ISP6322; ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2422: ha->device_type |= DT_ISP2422; ha->device_type |= DT_ZIO_SUPPORTED; ha->device_type |= DT_FWI2; ha->device_type |= DT_IIDMA; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP2432: ha->device_type |= DT_ISP2432; ha->device_type |= DT_ZIO_SUPPORTED; ha->device_type |= DT_FWI2; ha->device_type |= DT_IIDMA; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP5422: ha->device_type |= DT_ISP5422; ha->device_type |= DT_FWI2; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP5432: ha->device_type |= DT_ISP5432; ha->device_type |= DT_FWI2; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP2532: ha->device_type |= DT_ISP2532; ha->device_type |= DT_ZIO_SUPPORTED; ha->device_type |= DT_FWI2; ha->device_type |= DT_IIDMA; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; }}static intqla2x00_iospace_config(scsi_qla_host_t *ha){ unsigned long pio, pio_len, pio_flags; unsigned long mmio, mmio_len, mmio_flags; if (pci_request_selected_regions(ha->pdev, ha->bars, QLA2XXX_DRIVER_NAME)) { qla_printk(KERN_WARNING, ha, "Failed to reserve PIO/MMIO regions (%s)\n", pci_name(ha->pdev)); goto iospace_error_exit; } if (!(ha->bars & 1)) goto skip_pio; /* 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; } ha->pio_address = pio; ha->pio_length = pio_len;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?