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

📄 mptscsih.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
						sc->target,						pScsiReq->LUN[1],						sc->buffer,						xfer_cnt);			}			if (hd->is_spi)				mptscsih_set_dvflags(hd, pScsiReq, sc->buffer);			break;		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */			sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;			clear_sense_flag(hd, pScsiReq);			if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {				/*				 * If running agains circa 200003dd 909 MPT f/w,				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL				 * (QUEUE_FULL) returned from device! --> get 0x0000?128				 * and with SenseBytes set to 0.				 */				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);#ifndef MPT_SCSI_USE_NEW_EH				/* ADDED 20011120 -sralston				 * Scsi mid-layer (old_eh) doesn't seem to like it				 * when RAID returns SCSIStatus=02 (CHECK CONDITION),				 * SenseKey=01 (RECOVERED ERROR), ASC/ASCQ=95/01.				 * Seems to be * treating this as a IO error:-(				 *				 * So just lie about it altogether here.				 *				 * NOTE: It still gets reported to syslog via				 * mpt_ScsiHost_ErrorReport from copy_sense_data				 * call far above.				 */				if (    pScsiReply->SCSIStatus == STS_CHECK_CONDITION				     && SD_Sense_Key(sc->sense_buffer) == SK_RECOVERED_ERROR				   ) {					sc->result = 0;				}#endif			}			else if (pScsiReply->SCSIState &			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)			   ) {				/*				 * What to do?				 */				sc->result = DID_SOFT_ERROR << 16;			}			else if (pScsiReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {				/*  Not real sure here either...  */				sc->result = DID_RESET << 16;			}			else if (pScsiReply->SCSIState & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {				/* Device Inq. data indicates that it supports				 * QTags, but rejects QTag messages.				 * This command completed OK.				 *				 * Not real sure here either so do nothing...  */			}			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);			/* Add handling of:			 * Reservation Conflict, Busy,			 * Command Terminated, CHECK			 */			/* If regular Inquiry cmd - save inquiry data			 */			xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);			if (    sc->result == (DID_OK << 16)			     && pScsiReq->CDB[0] == INQUIRY			     && !(pScsiReq->CDB[1] & 0x3)			     && xfer_cnt >= SCSI_STD_INQUIRY_BYTES			   ) {				mptscsih_initTarget(hd,						hd->port,						sc->target,						pScsiReq->LUN[1],						sc->buffer,						xfer_cnt);			}			if (hd->is_spi)				mptscsih_set_dvflags(hd, pScsiReq, sc->buffer);			break;		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */			if (pScsiReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {				/*  Not real sure here either...  */				sc->result = DID_RESET << 16;			} else				sc->result = DID_SOFT_ERROR << 16;			break;		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */		default:			/*			 * What to do?			 */			sc->result = DID_SOFT_ERROR << 16;			break;		}	/* switch(status) */		dprintk((KERN_NOTICE "  sc->result set to %08xh\n", sc->result));	} /* end of address reply case */	/* Unmap the DMA buffers, if any. */	if (sc->use_sg) {		pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,			    sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction));	} else if (sc->request_bufflen) {		scPrivate	*my_priv;		my_priv = (scPrivate *) &sc->SCp;		pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,			   sc->request_bufflen,			   scsi_to_pci_dma_dir(sc->sc_data_direction));	}	hd->ScsiLookup[req_idx] = NULL;	sc->host_scribble = NULL;	/* CHECKME! - Do we need to clear this??? */	spin_lock_irqsave(&io_request_lock, flags);	sc->scsi_done(sc);		/* Issue the command callback */	spin_unlock_irqrestore(&io_request_lock, flags);	/* Free Chain buffers */	mptscsih_freeChainBuffers(hd, req_idx);	return 1;}#ifndef MPT_SCSI_USE_NEW_EH	/* { *//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	search_taskQ - Search SCSI task mgmt request queue for specific *	request type. *	@remove: (Boolean) Should request be removed if found? *	@sc: Pointer to Scsi_Cmnd structure *	@task_type: Task type to search for * *	Returns pointer to MPT request frame if found, or %NULL if request *	was not found. */static MPT_FRAME_HDR *search_taskQ(int remove, Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, u8 task_type){	MPT_FRAME_HDR *mf = NULL;	unsigned long flags;	int count = 0;	int list_sz;	dprintk((KERN_INFO MYNAM ": search_taskQ(%d,sc=%p,%d) called\n",			remove, sc, task_type));	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);	list_sz = hd->taskQcnt;	if (! Q_IS_EMPTY(&hd->taskQ)) {		mf = hd->taskQ.head;		do {			count++;			if (mf->u.frame.linkage.argp1 == sc &&			    mf->u.frame.linkage.arg1 == task_type) {				if (remove) {					Q_DEL_ITEM(&mf->u.frame.linkage);					hd->taskQcnt--;					atomic_dec(&mpt_taskQdepth);					/* Don't save mf into nextmf because					 * exit after command has been deleted.					 */					/* Place the MF back on the FreeQ */					Q_ADD_TAIL(&hd->ioc->FreeQ,						&mf->u.frame.linkage,						MPT_FRAME_HDR);#ifdef MFCNT					hd->ioc->mfcnt--;#endif				}				break;			}		} while ((mf = mf->u.frame.linkage.forw) != (MPT_FRAME_HDR*)&hd->taskQ);		if (mf == (MPT_FRAME_HDR*)&hd->taskQ) {			mf = NULL;		}	}	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);	if (list_sz) {		dprintk((KERN_INFO "  Results=%p (%sFOUND%s)!\n",				   mf,				   mf ? "" : "NOT_",				   (mf && remove) ? "+REMOVED" : "" ));		dprintk((KERN_INFO "  (searched thru %d of %d items on taskQ)\n",				   count,				   list_sz ));	}	return mf;}/* *	clean_taskQ - Clean the  SCSI task mgmt request for *			this SCSI host instance. *	@hd: MPT_SCSI_HOST pointer * *	Returns: None. */static voidclean_taskQ(MPT_SCSI_HOST *hd){	MPT_FRAME_HDR *mf = NULL;	MPT_FRAME_HDR *nextmf = NULL;	MPT_ADAPTER *ioc = hd->ioc;	unsigned long flags;	dprintk((KERN_INFO MYNAM ": clean_taskQ called\n"));	spin_lock_irqsave(&ioc->FreeQlock, flags);	if (! Q_IS_EMPTY(&hd->taskQ)) {		mf = hd->taskQ.head;		do {			Q_DEL_ITEM(&mf->u.frame.linkage);			hd->taskQcnt--;			atomic_dec(&mpt_taskQdepth);			nextmf = mf->u.frame.linkage.forw;			/* Place the MF back on the FreeQ */			Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage,				MPT_FRAME_HDR);#ifdef MFCNT			hd->ioc->mfcnt--;#endif		} while ((mf = nextmf) != (MPT_FRAME_HDR*)&hd->taskQ);	}	spin_unlock_irqrestore(&ioc->FreeQlock, flags);	return;}/* *	search_taskQ_for_cmd - Search the  SCSI task mgmt request queue for *			the specified command. If found, delete *	@hd: MPT_SCSI_HOST pointer * *	Returns: None. */static voidsearch_taskQ_for_cmd(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd){	MPT_FRAME_HDR *mf = NULL;	unsigned long flags;	int count = 0;	dprintk((KERN_INFO MYNAM ": search_taskQ_for_cmd(sc=%p) called\n", sc));	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);	if (! Q_IS_EMPTY(&hd->taskQ)) {		mf = hd->taskQ.head;		do {			count++;			if (mf->u.frame.linkage.argp1 == sc) {				Q_DEL_ITEM(&mf->u.frame.linkage);				hd->taskQcnt--;				atomic_dec(&mpt_taskQdepth);				dprintk((KERN_INFO MYNAM					": Cmd %p found! Deleting.\n", sc));				/* Don't save mf into nextmf because				 * exit after command has been deleted.				 */				/* Place the MF back on the FreeQ */				Q_ADD_TAIL(&hd->ioc->FreeQ,					&mf->u.frame.linkage,					MPT_FRAME_HDR);#ifdef MFCNT				hd->ioc->mfcnt--;#endif				break;			}		} while ((mf = mf->u.frame.linkage.forw) != (MPT_FRAME_HDR*)&hd->taskQ);	}	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);	return;}#endif		/* } MPT_SCSI_USE_NEW_EH *//* * Flush all commands on the doneQ. * Lock Q when deleting/adding members * Lock io_request_lock for OS callback. */static voidflush_doneQ(MPT_SCSI_HOST *hd){	MPT_DONE_Q	*buffer;	Scsi_Cmnd	*SCpnt;	unsigned long	 flags;	/* Flush the doneQ.	 */	dprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));	while (1) {		spin_lock_irqsave(&hd->freedoneQlock, flags);		if (Q_IS_EMPTY(&hd->doneQ)) {			spin_unlock_irqrestore(&hd->freedoneQlock, flags);			break;		}		buffer = hd->doneQ.head;		/* Delete from Q		 */		Q_DEL_ITEM(buffer);		/* Set the Scsi_Cmnd pointer		 */		SCpnt = (Scsi_Cmnd *) buffer->argp;		buffer->argp = NULL;		/* Add to the freeQ		 */		Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);		spin_unlock_irqrestore(&hd->freedoneQlock, flags);		/* Do the OS callback.		 */		spin_lock_irqsave(&io_request_lock, flags);		SCpnt->scsi_done(SCpnt);		spin_unlock_irqrestore(&io_request_lock, flags);	}	return;}/* * Search the doneQ for a specific command. If found, delete from Q. * Calling function will finish processing. */static voidsearch_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt){	unsigned long	 flags;	MPT_DONE_Q	*buffer;	spin_lock_irqsave(&hd->freedoneQlock, flags);	if (!Q_IS_EMPTY(&hd->doneQ)) {		buffer = hd->doneQ.head;		do {			Scsi_Cmnd *sc = (Scsi_Cmnd *) buffer->argp;			if (SCpnt == sc) {				Q_DEL_ITEM(buffer);				SCpnt->result = sc->result;				/* Set the Scsi_Cmnd pointer				 */				buffer->argp = NULL;				/* Add to the freeQ				 */				Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);				break;			}		} while ((buffer = buffer->forw) != (MPT_DONE_Q *) &hd->doneQ);	}	spin_unlock_irqrestore(&hd->freedoneQlock, flags);	return;}/* *	mptscsih_flush_running_cmds - For each command found, search *		Scsi_Host instance taskQ and reply to OS. *		Called only if recovering from a FW reload. *	@hd: Pointer to a SCSI HOST structure * *	Returns: None. * *	Must be called while new I/Os are being queued. */static voidmptscsih_flush_running_cmds(MPT_SCSI_HOST *hd){	Scsi_Cmnd	*SCpnt = NULL;	MPT_FRAME_HDR	*mf = NULL;	int		 ii;	int		 max = hd->ioc->req_depth;	unsigned long	 flags;	dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));	for (ii= 0; ii < max; ii++) {		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {			/* Command found.			 */#ifndef MPT_SCSI_USE_NEW_EH			/* Search taskQ, if found, delete.			 */			search_taskQ_for_cmd(SCpnt, hd);#endif			/* Search pendingQ, if found, 			 * delete from Q. If found, do not decrement			 * queue_depth, command never posted.			 */			if (mptscsih_search_pendingQ(hd, ii) == NULL)				atomic_dec(&queue_depth);			/* Null ScsiLookup index			 */			hd->ScsiLookup[ii] = NULL;			mf = MPT_INDEX_2_MFPTR(hd->ioc, ii);			dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",					mf, SCpnt));			/* Set status			 * Do OS callback			 * Free chain buffers			 * Free message frame			 */			SCpnt->result = DID_RESET << 16;			SCpnt->host_scribble = NULL;			spin_lock_irqsave(&io_request_lock, flags);			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */			spin_unlock_irqrestore(&io_request_lock, flags);			/* Free Chain buffers */			mptscsih_freeChainBuffers(hd, ii);			/* Free Message frames */			mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);		}	}	return;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_initChainBuffers - Allocate memory for and initialize *	chain buffers, chain buffer control arrays and spinlock. *	@hd: Pointer to MPT_SCSI_HOST structure *	@init: If set, initialize the spin lock. */static intmptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init){

⌨️ 快捷键说明

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