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(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);	RD_REG_WORD(&reg->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(&reg->ictrl, 0);	RD_REG_WORD(&reg->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(&reg->ictrl, ICRX_EN_RISC_INT);	RD_REG_DWORD(&reg->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(&reg->ictrl, 0);	RD_REG_DWORD(&reg->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 + -
显示快捷键?