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

📄 mptscsih.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct scsi_cmnd *sc;	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",			target, lun, max));	for (ii=0; ii < max; ii++) {		if ((sc = hd->ScsiLookup[ii]) != NULL) {			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));			if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))				continue;			/* Cleanup			 */			hd->ScsiLookup[ii] = NULL;			mptscsih_freeChainBuffers(hd->ioc, ii);			mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);			if (sc->use_sg) {				pci_unmap_sg(hd->ioc->pcidev,				(struct scatterlist *) sc->request_buffer,					sc->use_sg,					sc->sc_data_direction);			} else if (sc->request_bufflen) {				pci_unmap_single(hd->ioc->pcidev,					sc->SCp.dma_handle,					sc->request_bufflen,					sc->sc_data_direction);			}			sc->host_scribble = NULL;			sc->result = DID_NO_CONNECT << 16;			sc->scsi_done(sc);		}	}	return;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_report_queue_full - Report QUEUE_FULL status returned *	from a SCSI target device. *	@sc: Pointer to scsi_cmnd structure *	@pScsiReply: Pointer to SCSIIOReply_t *	@pScsiReq: Pointer to original SCSI request * *	This routine periodically reports QUEUE_FULL status returned from a *	SCSI target device.  It reports this to the console via kernel *	printk() API call, not more than once every 10 seconds. */static voidmptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq){	long time = jiffies;	MPT_SCSI_HOST		*hd;	if (sc->device == NULL)		return;	if (sc->device->host == NULL)		return;	if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)		return;	if (time - hd->last_queue_full > 10 * HZ) {		dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",				hd->ioc->name, 0, sc->device->id, sc->device->lun));		hd->last_queue_full = time;	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_remove - Removed scsi devices *	@pdev: Pointer to pci_dev structure * * */voidmptscsih_remove(struct pci_dev *pdev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	int 		 	count;	unsigned long	 	flags;	int sz1;	if(!host) {		mpt_detach(pdev);		return;	}	scsi_remove_host(host);	if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)		return;#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION	/* Check DV thread active */	count = 10 * HZ;	spin_lock_irqsave(&dvtaskQ_lock, flags);	if (dvtaskQ_active) {		spin_unlock_irqrestore(&dvtaskQ_lock, flags);		while(dvtaskQ_active && --count)			schedule_timeout_interruptible(1);	} else {		spin_unlock_irqrestore(&dvtaskQ_lock, flags);	}	if (!count)		printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)	else		printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);#endif#endif	mptscsih_shutdown(pdev);	sz1=0;	if (hd->ScsiLookup != NULL) {		sz1 = hd->ioc->req_depth * sizeof(void *);		kfree(hd->ScsiLookup);		hd->ScsiLookup = NULL;	}	/*	 * Free pointer array.	 */	kfree(hd->Targets);	hd->Targets = NULL;	dprintk((MYIOC_s_INFO_FMT	    "Free'd ScsiLookup (%d) memory\n",	    hd->ioc->name, sz1));	kfree(hd->info_kbuf);	/* NULL the Scsi_Host pointer	 */	hd->ioc->sh = NULL;	scsi_host_put(host);	mpt_detach(pdev);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_shutdown - reboot notifier * */voidmptscsih_shutdown(struct pci_dev *pdev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	if(!host)		return;	hd = (MPT_SCSI_HOST *)host->hostdata;	/* Flush the cache of this adapter	 */	if(hd != NULL)		mptscsih_synchronize_cache(hd, 0);}#ifdef CONFIG_PM/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_suspend - Fusion MPT scsi driver suspend routine. * * */intmptscsih_suspend(struct pci_dev *pdev, pm_message_t state){	mptscsih_shutdown(pdev);	return mpt_suspend(pdev,state);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_resume - Fusion MPT scsi driver resume routine. * * */intmptscsih_resume(struct pci_dev *pdev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	mpt_resume(pdev);	if(!host)		return 0;	hd = (MPT_SCSI_HOST *)host->hostdata;	if(!hd)		return 0;#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION	{	unsigned long lflags;	spin_lock_irqsave(&dvtaskQ_lock, lflags);	if (!dvtaskQ_active) {		dvtaskQ_active = 1;		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);		INIT_WORK(&dvTaskQ_task,		  mptscsih_domainValidation, (void *) hd);		schedule_work(&dvTaskQ_task);	} else {		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);	}	}#endif	return 0;}#endif/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_info - Return information about MPT adapter *	@SChost: Pointer to Scsi_Host structure * *	(linux scsi_host_template.info routine) * *	Returns pointer to buffer where information was written. */const char *mptscsih_info(struct Scsi_Host *SChost){	MPT_SCSI_HOST *h;	int size = 0;	h = (MPT_SCSI_HOST *)SChost->hostdata;	if (h) {		if (h->info_kbuf == NULL)			if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)				return h->info_kbuf;		h->info_kbuf[0] = '\0';		mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);		h->info_kbuf[size-1] = '\0';	}	return h->info_kbuf;}struct info_str {	char *buffer;	int   length;	int   offset;	int   pos;};static voidmptscsih_copy_mem_info(struct info_str *info, char *data, int len){	if (info->pos + len > info->length)		len = info->length - info->pos;	if (info->pos + len < info->offset) {		info->pos += len;		return;	}	if (info->pos < info->offset) {	        data += (info->offset - info->pos);	        len  -= (info->offset - info->pos);	}	if (len > 0) {                memcpy(info->buffer + info->pos, data, len);                info->pos += len;	}}static intmptscsih_copy_info(struct info_str *info, char *fmt, ...){	va_list args;	char buf[81];	int len;	va_start(args, fmt);	len = vsprintf(buf, fmt, args);	va_end(args);	mptscsih_copy_mem_info(info, buf, len);	return len;}static intmptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len){	struct info_str info;	info.buffer	= pbuf;	info.length	= len;	info.offset	= offset;	info.pos	= 0;	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);	return ((info.pos > info.offset) ? info.pos - info.offset : 0);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_proc_info - Return information about MPT adapter * *	(linux scsi_host_template.info routine) * * 	buffer: if write, user data; if read, buffer for user * 	length: if write, return length; * 	offset: if write, 0; if read, the current offset into the buffer from * 		the previous read. * 	hostno: scsi host number *	func:   if write = 1; if read = 0 */intmptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,			int length, int func){	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)host->hostdata;	MPT_ADAPTER	*ioc = hd->ioc;	int size = 0;	if (func) {		/*		 * write is not supported		 */	} else {		if (start)			*start = buffer;		size = mptscsih_host_info(ioc, buffer, offset, length);	}	return size;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/#define ADD_INDEX_LOG(req_ent)	do { } while(0)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine. *	@SCpnt: Pointer to scsi_cmnd structure *	@done: Pointer SCSI mid-layer IO completion function * *	(linux scsi_host_template.queuecommand routine) *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest *	from a linux scsi_cmnd request and send it to the IOC. * *	Returns 0. (rtn value discarded by linux scsi mid-layer) */intmptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)){	MPT_SCSI_HOST		*hd;	MPT_FRAME_HDR		*mf;	SCSIIORequest_t		*pScsiReq;	VirtDevice		*pTarget = SCpnt->device->hostdata;	int	 lun;	u32	 datalen;	u32	 scsictl;	u32	 scsidir;	u32	 cmd_len;	int	 my_idx;	int	 ii;	hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;	lun = SCpnt->device->lun;	SCpnt->scsi_done = done;	dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));	if (hd->resetPending) {		dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));		return SCSI_MLQUEUE_HOST_BUSY;	}	/*	 *  Put together a MPT SCSI request...	 */	if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {		dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",				hd->ioc->name));		return SCSI_MLQUEUE_HOST_BUSY;	}	pScsiReq = (SCSIIORequest_t *) mf;	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);	ADD_INDEX_LOG(my_idx);	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!	 *    Seems we may receive a buffer (datalen>0) even when there	 *    will be no data transfer!  GRRRRR...	 */	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {		datalen = SCpnt->request_bufflen;		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {		datalen = SCpnt->request_bufflen;		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */	} else {		datalen = 0;		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;	}	/* Default to untagged. Once a target structure has been allocated,	 * use the Inquiry data to determine if device supports tagged.	 */	if (pTarget	    && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)	    && (SCpnt->device->tagged_supported)) {		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;	} else {		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;	}	/* Use the above information to set up the message frame	 */	pScsiReq->TargetID = (u8) pTarget->target_id;	pScsiReq->Bus = pTarget->bus_id;	pScsiReq->ChainOffset = 0;	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;	pScsiReq->CDBLength = SCpnt->cmd_len;	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;	pScsiReq->Reserved = 0;	pScsiReq->MsgFlags = mpt_msg_flags();	pScsiReq->LUN[0] = 0;

⌨️ 快捷键说明

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