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

📄 mptctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			pScsiReq->SenseBufferLowAddr =				cpu_to_le32(ioc->sense_buf_low_dma				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));			if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {				if (hd->Targets)					pTarget = hd->Targets[target];			}			if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))				qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;			/* Have the IOCTL driver set the direction based			 * on the dataOutSize (ordering issue with Sparc).			 */			if (karg.dataOutSize > 0) {				scsidir = MPI_SCSIIO_CONTROL_WRITE;				dataSize = karg.dataOutSize;			} else {				scsidir = MPI_SCSIIO_CONTROL_READ;				dataSize = karg.dataInSize;			}			pScsiReq->Control = cpu_to_le32(scsidir | qtag);			pScsiReq->DataLength = cpu_to_le32(dataSize);			ioc->ioctl->reset = MPTCTL_RESET_OK;			ioc->ioctl->target = target;		} else {			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "				"SCSI driver is not loaded. \n",					__FILE__, __LINE__);			rc = -EFAULT;			goto done_free_mem;		}		break;	case MPI_FUNCTION_RAID_ACTION:		/* Just add a SGE		 */		break;	case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:		if (ioc->sh) {			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;			int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;			int scsidir = MPI_SCSIIO_CONTROL_READ;			int dataSize;			pScsiReq->MsgFlags = mpt_msg_flags();			/* verify that app has not requested			 *	more sense data than driver			 *	can provide, if so, reset this parameter			 * set the sense buffer pointer low address			 * update the control field to specify Q type			 */			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;			else				pScsiReq->SenseBufferLength = karg.maxSenseBytes;			pScsiReq->SenseBufferLowAddr =				cpu_to_le32(ioc->sense_buf_low_dma				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));			/* All commands to physical devices are tagged			 */			/* Have the IOCTL driver set the direction based			 * on the dataOutSize (ordering issue with Sparc).			 */			if (karg.dataOutSize > 0) {				scsidir = MPI_SCSIIO_CONTROL_WRITE;				dataSize = karg.dataOutSize;			} else {				scsidir = MPI_SCSIIO_CONTROL_READ;				dataSize = karg.dataInSize;			}			pScsiReq->Control = cpu_to_le32(scsidir | qtag);			pScsiReq->DataLength = cpu_to_le32(dataSize);			ioc->ioctl->reset = MPTCTL_RESET_OK;			ioc->ioctl->target = pScsiReq->TargetID;		} else {			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "				"SCSI driver is not loaded. \n",					__FILE__, __LINE__);			rc = -EFAULT;			goto done_free_mem;		}		break;	case MPI_FUNCTION_SCSI_TASK_MGMT:		{			MPT_SCSI_HOST *hd = NULL;			if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) {				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "					"SCSI driver not loaded or SCSI host not found. \n",					__FILE__, __LINE__);				rc = -EFAULT;				goto done_free_mem;			} else if (mptctl_set_tm_flags(hd) != 0) {				rc = -EPERM;				goto done_free_mem;			}		}		break;	case MPI_FUNCTION_IOC_INIT:		{			IOCInit_t	*pInit = (IOCInit_t *) mf;			u32		high_addr, sense_high;			/* Verify that all entries in the IOC INIT match			 * existing setup (and in LE format).			 */			if (sizeof(dma_addr_t) == sizeof(u64)) {				high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));				sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));			} else {				high_addr = 0;				sense_high= 0;			}			if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||				(pInit->MaxBuses != ioc->facts.MaxBuses) ||				(pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||				(pInit->HostMfaHighAddr != high_addr) ||				(pInit->SenseBufferHighAddr != sense_high)) {				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "					"IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",					__FILE__, __LINE__);				rc = -EFAULT;				goto done_free_mem;			}		}		break;	default:		/*		 * MPI_FUNCTION_PORT_ENABLE		 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST		 * MPI_FUNCTION_TARGET_ASSIST		 * MPI_FUNCTION_TARGET_STATUS_SEND		 * MPI_FUNCTION_TARGET_MODE_ABORT		 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET		 * MPI_FUNCTION_IO_UNIT_RESET		 * MPI_FUNCTION_HANDSHAKE		 * MPI_FUNCTION_REPLY_FRAME_REMOVAL		 * MPI_FUNCTION_EVENT_NOTIFICATION		 *  (driver handles event notification)		 * MPI_FUNCTION_EVENT_ACK		 */		/*  What to do with these???  CHECK ME!!!			MPI_FUNCTION_FC_LINK_SRVC_BUF_POST			MPI_FUNCTION_FC_LINK_SRVC_RSP			MPI_FUNCTION_FC_ABORT			MPI_FUNCTION_LAN_SEND			MPI_FUNCTION_LAN_RECEIVE		 	MPI_FUNCTION_LAN_RESET		*/		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "			"Illegal request (function 0x%x) \n",			__FILE__, __LINE__, hdr->Function);		rc = -EFAULT;		goto done_free_mem;	}	/* Add the SGL ( at most one data in SGE and one data out SGE )	 * In the case of two SGE's - the data out (write) will always	 * preceede the data in (read) SGE. psgList is used to free the	 * allocated memory.	 */	psge = (char *) (((int *) mf) + karg.dataSgeOffset);	flagsLength = 0;	/* bufIn and bufOut are used for user to kernel space transfers	 */	bufIn.kptr = bufOut.kptr = NULL;	bufIn.len = bufOut.len = 0;	if (karg.dataOutSize > 0)		sgSize ++;	if (karg.dataInSize > 0)		sgSize ++;	if (sgSize > 0) {		/* Set up the dataOut memory allocation */		if (karg.dataOutSize > 0) {			if (karg.dataInSize > 0) {				flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |						MPI_SGE_FLAGS_END_OF_BUFFER |						MPI_SGE_FLAGS_DIRECTION |						mpt_addr_size() )						<< MPI_SGE_FLAGS_SHIFT;			} else {				flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;			}			flagsLength |= karg.dataOutSize;			bufOut.len = karg.dataOutSize;			bufOut.kptr = pci_alloc_consistent(					ioc->pcidev, bufOut.len, &dma_addr_out);			if (bufOut.kptr == NULL) {				rc = -ENOMEM;				goto done_free_mem;			} else {				/* Set up this SGE.				 * Copy to MF and to sglbuf				 */				mpt_add_sge(psge, flagsLength, dma_addr_out);				psge += (sizeof(u32) + sizeof(dma_addr_t));				/* Copy user data to kernel space.				 */				if (copy_from_user(bufOut.kptr,						karg.dataOutBufPtr,						bufOut.len)) {					printk(KERN_ERR						"%s@%d::mptctl_do_mpt_command - Unable "						"to read user data "						"struct @ %p\n",						__FILE__, __LINE__,karg.dataOutBufPtr);					rc =  -EFAULT;					goto done_free_mem;				}			}		}		if (karg.dataInSize > 0) {			flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;			flagsLength |= karg.dataInSize;			bufIn.len = karg.dataInSize;			bufIn.kptr = pci_alloc_consistent(ioc->pcidev,					bufIn.len, &dma_addr_in);			if (bufIn.kptr == NULL) {				rc = -ENOMEM;				goto done_free_mem;			} else {				/* Set up this SGE				 * Copy to MF and to sglbuf				 */				mpt_add_sge(psge, flagsLength, dma_addr_in);			}		}	} else  {		/* Add a NULL SGE		 */		mpt_add_sge(psge, flagsLength, (dma_addr_t) -1);	}	ioc->ioctl->wait_done = 0;	if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {		DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);		if (mpt_send_handshake_request(mptctl_id, ioc,			sizeof(SCSITaskMgmt_t), (u32*)mf,			CAN_SLEEP) != 0) {			dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"				" (ioc %p, mf %p) \n", ioc->name,				ioc, mf));			mptctl_free_tm_flags(ioc);			rc = -ENODATA;			goto done_free_mem;		}	} else		mpt_put_msg_frame(mptctl_id, ioc, mf);	/* Now wait for the command to complete */	timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;	timeout = wait_event_interruptible_timeout(mptctl_wait,	     ioc->ioctl->wait_done == 1,	     HZ*timeout);	if(timeout <=0 && (ioc->ioctl->wait_done != 1 )) {	/* Now we need to reset the board */		if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT)			mptctl_free_tm_flags(ioc);		mptctl_timeout_expired(ioc->ioctl);		rc = -ENODATA;		goto done_free_mem;	}	mf = NULL;	/* If a valid reply frame, copy to the user.	 * Offset 2: reply length in U32's	 */	if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {		if (karg.maxReplyBytes < ioc->reply_sz) {			 sz = min(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);		} else {			 sz = min(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);		}		if (sz > 0) {			if (copy_to_user(karg.replyFrameBufPtr,				 &ioc->ioctl->ReplyFrame, sz)){				 printk(KERN_ERR				     "%s@%d::mptctl_do_mpt_command - "				 "Unable to write out reply frame %p\n",				 __FILE__, __LINE__, karg.replyFrameBufPtr);				 rc =  -ENODATA;				 goto done_free_mem;			}		}	}	/* If valid sense data, copy to user.	 */	if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {		sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);		if (sz > 0) {			if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "				"Unable to write sense data to user %p\n",				__FILE__, __LINE__,				karg.senseDataPtr);				rc =  -ENODATA;				goto done_free_mem;			}		}	}	/* If the overall status is _GOOD and data in, copy data	 * to user.	 */	if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&				(karg.dataInSize > 0) && (bufIn.kptr)) {		if (copy_to_user(karg.dataInBufPtr,				 bufIn.kptr, karg.dataInSize)) {			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "				"Unable to write data to user %p\n",				__FILE__, __LINE__,				karg.dataInBufPtr);			rc =  -ENODATA;		}	}done_free_mem:	ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_COMMAND_GOOD |		MPT_IOCTL_STATUS_SENSE_VALID |		MPT_IOCTL_STATUS_RF_VALID );	/* Free the allocated memory.	 */	if (bufOut.kptr != NULL) {		pci_free_consistent(ioc->pcidev,			bufOut.len, (void *) bufOut.kptr, dma_addr_out);	}	if (bufIn.kptr != NULL) {		pci_free_consistent(ioc->pcidev,			bufIn.len, (void *) bufIn.kptr, dma_addr_in);	}	/* mf is null if command issued successfully	 * otherwise, failure occured after mf acquired.	 */	if (mf)		mpt_free_msg_frame(ioc, mf);	return rc;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* Prototype Routine for the HP HOST INFO command. * * Outputs:	None. * Return:	0 if successful *		-EFAULT if data unavailable *		-EBUSY  if previous command timout and IOC reset is not complete. *		-ENODEV if no such device/adapter *		-ETIME	if timer expires *		-ENOMEM if memory allocation error */static intmptctl_hp_hostinfo(unsigned long arg, unsigned int data_size){	hp_host_info_t	__user *uarg = (void __user *) arg;	MPT_ADAPTER		*ioc;	struct pci_dev		*pdev;	char			*pbuf;	dma_addr_t		buf_dma;	hp_host_info_t		karg;	CONFIGPARMS		cfg;	ConfigPageHeader_t	hdr;	int			iocnum;	int			rc, cim_rev;	dctlprintk((": mptctl_hp_hostinfo called.\n"));	/* Reset long to int. Should affect IA64 and SPARC only	 */	if (data_size == sizeof(hp_host_info_t))		cim_rev = 1;	else if (data_size == sizeof(hp_host_info_rev0_t))		cim_rev = 0;	/* obsolete */	else		return -EFAULT;	if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {		printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "			"Unable to read in hp_host_info struct @ %p\n",				__FILE__, __LINE__, uarg);		return -EFAULT;	}	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||	    (ioc == NULL)) {		dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	/* Fill in the data and return the structure to the calling	 * program	 */	pdev = (struct pci_dev *) ioc->pcidev;	karg.vendor = pdev->vendor;	karg.device = pdev->device;	karg.subsystem_id = pdev->subsystem_device;	karg.subsystem_vendor = pdev->subsystem_vendor;	karg.devfn = pdev->devfn;	karg.bus = pdev->bus->number;	/* Save the SCSI host no. if	 * SCSI driver loaded	 */	if (ioc->sh != NULL)		karg.host_no = ioc->sh->host_no;	else		karg.host_no =  -1;	/* Reformat the fw_version into a string	 */	karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?		((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';	karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';	karg.fw_version[2] = '.';	karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?		((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';	karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';	karg.fw_version[5] = '.';	karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?		((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';	karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';	karg.fw_version[8] = '.';	karg.fw_version[9] = ioc->facts.FWVersion.Stru

⌨️ 快捷键说明

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