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

📄 qla_os.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	scsi_qla_host_t *ha;	srb_t *sp;	int rval = FAILED;	ha = (scsi_qla_host_t *) cmd->device->host->hostdata;	sp = (srb_t *) CMD_SP(cmd);	qla_printk(KERN_INFO, ha,	    "scsi(%ld:%d:%d:%d): LOOP RESET ISSUED.\n", ha->host_no,	    cmd->device->channel, cmd->device->id, cmd->device->lun);	spin_unlock_irq(ha->host->host_lock);	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {		DEBUG2(printk("%s failed:board disabled\n",__func__));		spin_lock_irq(ha->host->host_lock);		return FAILED;	}	if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) {		if (qla2x00_loop_reset(ha) == QLA_SUCCESS) 			rval = SUCCESS;	}	spin_lock_irq(ha->host->host_lock);	if (rval == FAILED)		goto out;	/* Waiting for our command in done_queue to be returned to OS.*/	if (cmd->device->host->eh_active)		if (!qla2x00_eh_wait_for_pending_commands(ha))			rval = FAILED; out:	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,			(rval == FAILED) ? "failed" : "succeded");	return rval;}/*************************************************************************** qla2xxx_eh_host_reset** Description:*    The reset function will reset the Adapter.** Input:*      cmd = Linux SCSI command packet of the command that cause the*            adapter reset.** Returns:*      Either SUCCESS or FAILED.** Note:**************************************************************************/intqla2xxx_eh_host_reset(struct scsi_cmnd *cmd){	scsi_qla_host_t *ha = (scsi_qla_host_t *)cmd->device->host->hostdata;	int		rval = SUCCESS;	/* Display which one we're actually resetting for debug. */	DEBUG(printk("qla2xxx_eh_host_reset:Resetting scsi(%ld).\n",	    ha->host_no));	/*	 *  Now issue reset.	 */	qla_printk(KERN_INFO, ha,	    "scsi(%ld:%d:%d:%d): ADAPTER RESET issued.\n", ha->host_no,	    cmd->device->channel, cmd->device->id, cmd->device->lun);	spin_unlock_irq(ha->host->host_lock);	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)		goto board_disabled;	/*	 * 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.	 */	/* Blocking call-Does context switching if loop is Not Ready */	qla2x00_wait_for_loop_ready(ha);	set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);	if (qla2x00_abort_isp(ha)) {		clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);		/* failed. schedule dpc to try */		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);		if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)			goto board_disabled;	} 	clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);	spin_lock_irq(ha->host->host_lock);	if (rval == FAILED)		goto out;	/* Waiting for our command in done_queue to be returned to OS.*/	if (!qla2x00_eh_wait_for_pending_commands(ha))		rval = FAILED; out:	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,			(rval == FAILED) ? "failed" : "succeded");	return rval; board_disabled:	spin_lock_irq(ha->host->host_lock);	qla_printk(KERN_INFO, ha, "%s: failed:board disabled\n", __func__);	return FAILED;}/** qla2x00_loop_reset*      Issue loop reset.** Input:*      ha = adapter block pointer.** Returns:*      0 = success*/static intqla2x00_loop_reset(scsi_qla_host_t *ha){	int status = QLA_SUCCESS;	uint16_t t;	os_tgt_t        *tq;	if (ha->flags.enable_lip_reset) {		status = qla2x00_lip_reset(ha);	}	if (status == QLA_SUCCESS && ha->flags.enable_target_reset) {		for (t = 0; t < MAX_FIBRE_DEVICES; t++) {			if ((tq = TGT_Q(ha, t)) == NULL)				continue;			if (tq->fcport == NULL)				continue;			status = qla2x00_target_reset(ha, 0, t);			if (status != QLA_SUCCESS) {				break;			}		}	}	if (status == QLA_SUCCESS &&		((!ha->flags.enable_target_reset && 		  !ha->flags.enable_lip_reset) ||		ha->flags.enable_lip_full_login)) {		status = qla2x00_full_login_lip(ha);	}	/* Issue marker command only when we are going to start the I/O */	ha->marker_needed = 1;	if (status) {		/* Empty */		DEBUG2_3(printk("%s(%ld): **** FAILED ****\n",				__func__,				ha->host_no);)	} else {		/* Empty */		DEBUG3(printk("%s(%ld): exiting normally.\n",				__func__,				ha->host_no);)	}	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 qla2x00_abort_target(reset_fcport);}/*************************************************************************** qla2xxx_slave_configure** Description:**************************************************************************/intqla2xxx_slave_configure(struct scsi_device *sdev){	scsi_qla_host_t *ha = to_qla_host(sdev->host);	int queue_depth;	if (IS_QLA2100(ha) || IS_QLA2200(ha))		queue_depth = 16;	else		queue_depth = 32;	if (sdev->tagged_supported) {		if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)			queue_depth = ql2xmaxqdepth;		ql2xmaxqdepth = queue_depth;		scsi_activate_tcq(sdev, queue_depth);		qla_printk(KERN_INFO, ha,		    "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue "		    "depth %d.\n",		    sdev->host->host_no, sdev->channel, sdev->id, sdev->lun,		    sdev->queue_depth);	} else {		 scsi_adjust_queue_depth(sdev, 0 /* TCQ off */,		     sdev->host->hostt->cmd_per_lun /* 3 */);	}	return (0);}/** * 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 32bit DMA address */	ha->flags.enable_64bit_addressing = 0;	ha->calc_request_entries = qla2x00_calc_iocbs_32;	ha->build_scsi_iocbs = qla2x00_build_scsi_iocbs_32;	/*	 * Given the two variants pci_set_dma_mask(), allow the compiler to	 * assist in setting the proper dma mask.	 */	if (sizeof(dma_addr_t) > 4) {		if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {			ha->flags.enable_64bit_addressing = 1;			ha->calc_request_entries = qla2x00_calc_iocbs_64;			ha->build_scsi_iocbs = qla2x00_build_scsi_iocbs_64;			if (pci_set_consistent_dma_mask(ha->pdev,			    DMA_64BIT_MASK)) {				qla_printk(KERN_DEBUG, ha, 				    "Failed to set 64 bit PCI consistent mask; "				    "using 32 bit.\n");				pci_set_consistent_dma_mask(ha->pdev,				    DMA_32BIT_MASK);			}		} else {			qla_printk(KERN_DEBUG, ha,			    "Failed to set 64 bit PCI DMA mask, falling back "			    "to 32 bit MASK.\n");			pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);		}	} else {		pci_set_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",			    ha->pdev->slot_name);			pio = 0;		}	} else {		qla_printk(KERN_WARNING, ha,		    "region #0 not a PIO resource (%s)...\n",		    ha->pdev->slot_name);		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",		    ha->pdev->slot_name);		goto iospace_error_exit;	}	if (mmio_len < MIN_IOBASE_LEN) {		qla_printk(KERN_ERR, ha,		    "Invalid PCI mem region size (%s), aborting\n",		    ha->pdev->slot_name);		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", 		    ha->pdev->slot_name);		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", ha->pdev->slot_name);		goto iospace_error_exit;	}	return (0);iospace_error_exit:	return (-ENOMEM);}/* * PCI driver interface */int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info){	int	ret;	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];	if (pci_enable_device(pdev))		return -1;	host = scsi_host_alloc(&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);	/* Configure PCI I/O space */	ret = qla2x00_iospace_config(ha);	if (ret != 0) {		goto probe_failed;	}	/* Sanitize the information from PCI BIOS. */	host->irq = pdev->irq;	qla_printk(KERN_INFO, ha,	    "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,	    host->irq, ha->iobase);	spin_lock_init(&ha->hardware_lock);	/* 4.23 Initialize /proc/scsi/qla2x00 counters */	ha->actthreads = 0;	ha->qthreads   = 0;	ha->total_isr_cnt = 0;	ha->total_isp_aborts = 0;	ha->total_lip_cnt = 0;	ha->total_dev_errs = 0;	ha->total_ios = 0;	ha->total_bytes = 0;	ha->prev_topology = 0;	ha->ports = MAX_BUSES;	if (IS_QLA2100(ha)) {		ha->max_targets = 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;	} else if (IS_QLA2200(ha)) {		ha->max_targets = 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;	} else /*if (IS_QLA2300(ha))*/ {		ha->max_targets = 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;	}	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);	INIT_LIST_HEAD(&ha->done_queue);	INIT_LIST_HEAD(&ha->retry_queue);	INIT_LIST_HEAD(&ha->scsi_retry_queue);	INIT_LIST_HEAD(&ha->pending_queue);	/*	 * 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);	spin_lock_init(&ha->list_lock);	ha->dpc_pid = -1;	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");		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));		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");		goto probe_failed;	}	wait_for_completion(&ha->dpc_inited);	host->this_id = 255;	host->cmd_per_lun = 3;	host->max_cmd_len = MAX_CMDSZ;	host->max_channel = ha->ports - 1;	host->max_lun = ha->max_luns;	BUG_ON(qla2xxx_transport_template == NULL);	host->transportt = qla2xxx_transport_template;	host->unique_id = ha->instance;	host->max_id = ha->max_targets;	if (IS_QLA2100(ha) || IS_QLA2200(ha))		ret = request_irq(host->irq, qla2100_intr_handler,		    SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);	else		ret = request_irq(host->irq, qla2300_intr_handler,		    SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);	if (ret != 0) {		qla_printk(KERN_WARNING, ha,		    "Failed to reserve interrupt %d already in use.\n",		    host->irq);		goto probe_failed;

⌨️ 快捷键说明

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