⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qla_os.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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(&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);}/* * 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;	if (pci_enable_device(pdev))		goto probe_out;	host = scsi_host_alloc(brd_info->sht ? brd_info->sht:	    &qla2x00_driver_template, 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 %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,	    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;	/* 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;	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->gid_list_info_size = 6;	} 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_flash;		if (ql2xfwloadbin)			ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;		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->gid_list_info_size = 8;	}	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(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);	} else {		WRT_REG_WORD(&reg->isp.semaphore, 0);		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);		WRT_REG_WORD(&reg->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(&reg->isp.hccr,				    (HCCR_ENABLE_PARITY + 0x1));			else				/* SRAM, Instruction RAM and GP RAM parity */				WRT_REG_WORD(&reg->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);	}	pci_set_drvdata(pdev, ha);	ha->flags.init_done = 1;	num_hosts++;	ret = scsi_add_host(host, &pdev->dev);	if (ret)		goto probe_failed;	qla2x00_alloc_sysfs_attr(ha);	qla2x00_init_host_attr(ha);	qla_printk(KERN_INFO, ha, "\n"	    " QLogic Fibre Channel HBA Driver: %s\n"	    "  QLogic %s - %s\n"	    "  %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,	    ha->model_number, ha->model_desc ? ha->model_desc: "",	    ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),	    pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',	    ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));	/* Go with fc_rport registration. */	list_for_each_entry(fcport, &ha->fcports, list)		qla2x00_reg_remote_port(ha, fcport);	return 0;probe_failed:	qla2x00_free_device(ha);	scsi_host_put(host);probe_disable_device:	pci_disable_device(pdev);probe_out:	return ret;}EXPORT_SYMBOL_GPL(qla2x00_probe_one);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -