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

📄 qla_os.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	/* 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));	reg = ha->iobase;	/* Disable ISP interrupts. */	qla2x00_disable_intrs(ha);	/* Ensure mailbox registers are free. */	spin_lock_irqsave(&ha->hardware_lock, flags);	WRT_REG_WORD(&reg->semaphore, 0);	WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);	WRT_REG_WORD(&reg->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->hccr, (HCCR_ENABLE_PARITY + 0x1));		else			/* SRAM, Instruction RAM and GP RAM parity */			WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x7));	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);	/* Enable chip interrupts. */	qla2x00_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++;	/* List the target we have found */	if (displayConfig) {		qla2x00_display_fc_names(ha);	}	if (scsi_add_host(host, &pdev->dev))		goto probe_failed;	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);	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, qla2x00_get_pci_info_str(ha, pci_info),	    pci_name(ha->pdev), ha->flags.enable_64bit_addressing ? '+': '-',	    ha->host_no, qla2x00_get_fw_version_str(ha, fw_str));	if (ql2xdoinitscan)		scsi_scan_host(host);	return 0;probe_failed:	qla2x00_free_device(ha);	scsi_host_put(host);probe_disable_device:	pci_disable_device(pdev);	return -1;}EXPORT_SYMBOL_GPL(qla2x00_probe_one);void qla2x00_remove_one(struct pci_dev *pdev){	scsi_qla_host_t *ha;	ha = pci_get_drvdata(pdev);	sysfs_remove_bin_file(&ha->host->shost_gendev.kobj,	    &sysfs_fw_dump_attr);	sysfs_remove_bin_file(&ha->host->shost_gendev.kobj, &sysfs_nvram_attr);	scsi_remove_host(ha->host);	qla2x00_free_device(ha);	scsi_host_put(ha->host);	pci_set_drvdata(pdev, NULL);}EXPORT_SYMBOL_GPL(qla2x00_remove_one);static voidqla2x00_free_device(scsi_qla_host_t *ha){	int ret;	/* Abort any outstanding IO descriptors. */	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))		qla2x00_cancel_io_descriptors(ha);	/* turn-off interrupts on the card */	if (ha->interrupts_on)		qla2x00_disable_intrs(ha);	/* Disable timer */	if (ha->timer_active)		qla2x00_stop_timer(ha);	/* Kill the kernel thread for this host */	if (ha->dpc_pid >= 0) {		ha->dpc_should_die = 1;		wmb();		ret = kill_proc(ha->dpc_pid, SIGHUP, 1);		if (ret) {			qla_printk(KERN_ERR, ha,			    "Unable to signal DPC thread -- (%d)\n", ret);			/* TODO: SOMETHING MORE??? */		} else {			wait_for_completion(&ha->dpc_exited);		}	}	qla2x00_mem_free(ha);	ha->flags.online = 0;	/* Detach interrupts */	if (ha->pdev->irq)		free_irq(ha->pdev->irq, ha);	/* release io space registers  */	if (ha->iobase)		iounmap(ha->iobase);	pci_release_regions(ha->pdev);	pci_disable_device(ha->pdev);}/* * The following support functions are adopted to handle * the re-entrant qla2x00_proc_info correctly. */static voidcopy_mem_info(struct info_str *info, char *data, int len){	if (info->pos + len > info->offset + info->length)		len = info->offset + info->length - info->pos;	if (info->pos + len < info->offset) {		info->pos += len;		return;	} 	if (info->pos < info->offset) {		off_t partial; 		partial = info->offset - info->pos;		data += partial;		info->pos += partial;		len  -= partial;	} 	if (len > 0) {		memcpy(info->buffer, data, len);		info->pos += len;		info->buffer += len;	}}static intcopy_info(struct info_str *info, char *fmt, ...){	va_list args;	char buf[256];	int len; 	va_start(args, fmt);	len = vsprintf(buf, fmt, args);	va_end(args); 	copy_mem_info(info, buf, len);	return (len);}/************************************************************************** qla2x00_proc_info** Description:*   Return information to handle /proc support for the driver.** inout : decides the direction of the dataflow and the meaning of the*         variables* buffer: If inout==0 data is being written to it else read from it*         (ptr to a page buffer)* *start: If inout==0 start of the valid data in the buffer* offset: If inout==0 starting offset from the beginning of all*         possible data to return.* length: If inout==0 max number of bytes to be written into the buffer*         else number of bytes in "buffer"* Returns:*         < 0:  error. errno value.*         >= 0: sizeof data returned.*************************************************************************/intqla2x00_proc_info(struct Scsi_Host *shost, char *buffer,    char **start, off_t offset, int length, int inout){	struct info_str	info;	int             retval = -EINVAL;	os_lun_t	*up;	os_tgt_t	*tq;	unsigned int	t, l;	uint32_t        tmp_sn;	uint32_t	*flags;	uint8_t		*loop_state;	scsi_qla_host_t *ha;	char fw_info[30]; 	DEBUG3(printk(KERN_INFO	    "Entering proc_info buff_in=%p, offset=0x%lx, length=0x%x\n",	    buffer, offset, length);)	ha = (scsi_qla_host_t *) shost->hostdata;	if (inout) {		/* Has data been written to the file? */		DEBUG3(printk(		    "%s: has data been written to the file. \n",		    __func__);)		return -ENOSYS;	}	if (start) {		*start = buffer;	}	info.buffer = buffer;	info.length = length;	info.offset = offset;	info.pos    = 0;	/* start building the print buffer */	copy_info(&info,	    "QLogic PCI to Fibre Channel Host Adapter for %s:\n"	    "        Firmware version %s, ",	    ha->model_number, qla2x00_get_fw_version_str(ha, fw_info));	copy_info(&info, "Driver version %s\n", qla2x00_version_str);	tmp_sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | 	    ha->serial1;	copy_info(&info, "ISP: %s, Serial# %c%05d\n",	    ha->brd_info->isp_name, ('A' + tmp_sn/100000), (tmp_sn%100000));	copy_info(&info,	    "Request Queue = 0x%llx, Response Queue = 0x%llx\n",		(unsigned long long)ha->request_dma,		(unsigned long long)ha->response_dma);	copy_info(&info,	    "Request Queue count = %d, Response Queue count = %d\n",	    ha->request_q_length, ha->response_q_length);	copy_info(&info,	    "Total number of active commands = %ld\n",	    ha->actthreads);	copy_info(&info,	    "Total number of interrupts = %ld\n",	    (long)ha->total_isr_cnt);	copy_info(&info,	    "    Device queue depth = 0x%x\n",	    (ql2xmaxqdepth == 0) ? 16 : ql2xmaxqdepth);	copy_info(&info,	    "Number of free request entries = %d\n", ha->req_q_cnt);	copy_info(&info,	    "Number of mailbox timeouts = %ld\n", ha->total_mbx_timeout);	copy_info(&info,	    "Number of ISP aborts = %ld\n", ha->total_isp_aborts);	copy_info(&info,	    "Number of loop resyncs = %ld\n", ha->total_loop_resync);	copy_info(&info,	    "Number of retries for empty slots = %ld\n",	    qla2x00_stats.outarray_full);	copy_info(&info,	    "Number of reqs in pending_q= %ld, retry_q= %d, "	    "done_q= %ld, scsi_retry_q= %d\n",	    ha->qthreads, ha->retry_q_cnt,	    ha->done_q_cnt, ha->scsi_retry_q_cnt);	flags = (uint32_t *) &ha->flags;	if (atomic_read(&ha->loop_state) == LOOP_DOWN) {		loop_state = "DOWN";	} else if (atomic_read(&ha->loop_state) == LOOP_UP) {		loop_state = "UP";	} else if (atomic_read(&ha->loop_state) == LOOP_READY) {		loop_state = "READY";	} else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT) {		loop_state = "TIMEOUT";	} else if (atomic_read(&ha->loop_state) == LOOP_UPDATE) {		loop_state = "UPDATE";	} else {		loop_state = "UNKNOWN";	}	copy_info(&info, 	    "Host adapter:loop state = <%s>, flags = 0x%lx\n",	    loop_state , *flags);	copy_info(&info, "Dpc flags = 0x%lx\n", ha->dpc_flags);	copy_info(&info, "MBX flags = 0x%x\n", ha->mbx_flags);	copy_info(&info, "Link down Timeout = %3.3d\n",	    ha->link_down_timeout);	copy_info(&info, "Port down retry = %3.3d\n",	    ha->port_down_retry_count);	copy_info(&info, "Login retry count = %3.3d\n",	    ha->login_retry_count);	copy_info(&info,	    "Commands retried with dropped frame(s) = %d\n",	    ha->dropped_frame_error_cnt);	copy_info(&info,	    "Product ID = %04x %04x %04x %04x\n", ha->product_id[0],	    ha->product_id[1], ha->product_id[2], ha->product_id[3]);	copy_info(&info, "\n");	/* 2.25 node/port display to proc */	/* Display the node name for adapter */	copy_info(&info, "\nSCSI Device Information:\n");	copy_info(&info,	    "scsi-qla%d-adapter-node="	    "%02x%02x%02x%02x%02x%02x%02x%02x;\n",	    (int)ha->instance,	    ha->init_cb->node_name[0],	    ha->init_cb->node_name[1],	    ha->init_cb->node_name[2],	    ha->init_cb->node_name[3],	    ha->init_cb->node_name[4],	    ha->init_cb->node_name[5],	    ha->init_cb->node_name[6],	    ha->init_cb->node_name[7]);	/* display the port name for adapter */	copy_info(&info,	    "scsi-qla%d-adapter-port="	    "%02x%02x%02x%02x%02x%02x%02x%02x;\n",	    (int)ha->instance,	    ha->init_cb->port_name[0],	    ha->init_cb->port_name[1],	    ha->init_cb->port_name[2],	    ha->init_cb->port_name[3],	    ha->init_cb->port_name[4],	    ha->init_cb->port_name[5],	    ha->init_cb->port_name[6],	    ha->init_cb->port_name[7]);	/* Print out device port names */	for (t = 0; t < MAX_FIBRE_DEVICES; t++) {		if ((tq = TGT_Q(ha, t)) == NULL)			continue;		copy_info(&info,		    "scsi-qla%d-target-%d="		    "%02x%02x%02x%02x%02x%02x%02x%02x;\n",		    (int)ha->instance, t,		    tq->port_name[0], tq->port_name[1],		    tq->port_name[2], tq->port_name[3],		    tq->port_name[4], tq->port_name[5],		    tq->port_name[6], tq->port_name[7]);	}	copy_info(&info, "\nSCSI LUN Information:\n");	copy_info(&info,	    "(Id:Lun)  * - indicates lun is not registered with the OS.\n");	/* scan for all equipment stats */	for (t = 0; t < MAX_FIBRE_DEVICES; t++) {		/* scan all luns */		for (l = 0; l < ha->max_luns; l++) {			up = (os_lun_t *) GET_LU_Q(ha, t, l);			if (up == NULL) {				continue;			}			if (up->fclun == NULL) {				continue;			}			copy_info(&info,			    "(%2d:%2d): Total reqs %ld,",			    t,l,up->io_cnt);			copy_info(&info,			    " Pending reqs %ld,",			    up->out_cnt);			if (up->io_cnt < 4) {				copy_info(&info,				    " flags 0x%x*,",				    (int)up->q_flag);			} else {				copy_info(&info,				    " flags 0x%x,",				    (int)up->q_flag);			}			copy_info(&info, 			    " %ld:%d:%02x %02x",			    up->fclun->fcport->ha->instance,			    up->fclun->fcport->cur_path,			    up->fclun->fcport->loop_id,			    up->fclun->device_type);			copy_info(&info, "\n");			if (info.pos >= info.offset + info.length) {				/* No need to continue */				goto profile_stop;			}		}		if (info.pos >= info.offset + info.length) {			/* No need to continue */			break;		}	}profile_stop:	retval = info.pos > info.offset ? info.pos - info.offset : 0;	DEBUG3(printk(KERN_INFO 	    "Exiting proc_info: info.pos=%d, offset=0x%lx, "	    "length=0x%x\n", info.pos, offset, length);)	return (retval);}/** qla2x00_display_fc_names*      This routine will the node names of the different devices found*      after port inquiry.** Input:*      cmd = SCSI command structure** Returns:*      None.*/static voidqla2x00_display_fc_names(scsi_qla_host_t *ha) {	uint16_t	tgt;	os_tgt_t	*tq;	/* Display the node name for adapter */	qla_printk(KERN_INFO, ha,	    "scsi-qla%d-adapter-node=%02x%02x%02x%02x%02x%02x%02x%02x\\;\n",	    (int)ha->instance,	    ha->init_cb->node_name[0],	    ha->init_cb->node_name[1],	    ha->init_cb->node_name[2],	    ha->init_cb->node_name[3],	    ha->init_cb->node_name[4],	    ha->init_cb->node_name[5],	    ha->init_cb->node_name[6],	    ha->init_cb->node_name[7]);	/* display the port name for adapter */	qla_printk(KERN_INFO, ha,	    "scsi-qla%d-adapter-port=%02x%02x%02x%02x%02x%02x%02x%02x\\;\n",	    (int)ha->instance,	    ha->init_cb->port_name[0],	    ha->init_cb->port_name[1],	    ha->init_cb->port_name[2],	    ha->init_cb->port_name[3],	    ha->init_cb->port_name[4],	    ha->

⌨️ 快捷键说明

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