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

📄 mptctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",				__FILE__, __LINE__, uarg);		kfree(pmem);		return -EFAULT;	}	/* Copy the remaining data from kernel memory to user memory	 */	if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",				__FILE__, __LINE__, pdata);		kfree(pmem);		return -EFAULT;	}	kfree(pmem);	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* MPT IOCTL Test function. * * Outputs:	None. * Return:	0 if successful *		-EFAULT if data unavailable *		-ENODEV  if no such device/adapter */static intmptctl_readtest (unsigned long arg){	struct mpt_ioctl_test __user *uarg = (void __user *) arg;	struct mpt_ioctl_test	 karg;	MPT_ADAPTER *ioc;	int iocnum;	dctlprintk(("mptctl_readtest called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {		printk(KERN_ERR "%s@%d::mptctl_readtest - "			"Unable to read in mpt_ioctl_test 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_readtest() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	/* Fill in the data and return the structure to the calling	 * program	 */#ifdef MFCNT	karg.chip_type = ioc->mfcnt;#else	karg.chip_type = ioc->pcidev->device;#endif	strncpy (karg.name, ioc->name, MPT_MAX_NAME);	karg.name[MPT_MAX_NAME-1]='\0';	strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);	karg.product[MPT_PRODUCT_LENGTH-1]='\0';	/* Copy the data from kernel memory to user memory	 */	if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {		printk(KERN_ERR "%s@%d::mptctl_readtest - "			"Unable to write out mpt_ioctl_test struct @ %p\n",				__FILE__, __LINE__, uarg);		return -EFAULT;	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptctl_eventquery - Query the host adapter for the event types *	that are being logged. *	@arg: User space argument * * Outputs:	None. * Return:	0 if successful *		-EFAULT if data unavailable *		-ENODEV  if no such device/adapter */static intmptctl_eventquery (unsigned long arg){	struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;	struct mpt_ioctl_eventquery	 karg;	MPT_ADAPTER *ioc;	int iocnum;	dctlprintk(("mptctl_eventquery called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {		printk(KERN_ERR "%s@%d::mptctl_eventquery - "			"Unable to read in mpt_ioctl_eventquery 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_eventquery() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	karg.eventEntries = ioc->eventLogSize;	karg.eventTypes = ioc->eventTypes;	/* Copy the data from kernel memory to user memory	 */	if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {		printk(KERN_ERR "%s@%d::mptctl_eventquery - "			"Unable to write out mpt_ioctl_eventquery struct @ %p\n",				__FILE__, __LINE__, uarg);		return -EFAULT;	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmptctl_eventenable (unsigned long arg){	struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;	struct mpt_ioctl_eventenable	 karg;	MPT_ADAPTER *ioc;	int iocnum;	dctlprintk(("mptctl_eventenable called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {		printk(KERN_ERR "%s@%d::mptctl_eventenable - "			"Unable to read in mpt_ioctl_eventenable 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_eventenable() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	if (ioc->events == NULL) {		/* Have not yet allocated memory - do so now.		 */		int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);		ioc->events = kmalloc(sz, GFP_KERNEL);		if (ioc->events == NULL) {			printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");			return -ENOMEM;		}		memset(ioc->events, 0, sz);		ioc->alloc_total += sz;		ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;		ioc->eventContext = 0;        }	/* Update the IOC event logging flag.	 */	ioc->eventTypes = karg.eventTypes;	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmptctl_eventreport (unsigned long arg){	struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;	struct mpt_ioctl_eventreport	 karg;	MPT_ADAPTER		 *ioc;	int			 iocnum;	int			 numBytes, maxEvents, max;	dctlprintk(("mptctl_eventreport called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {		printk(KERN_ERR "%s@%d::mptctl_eventreport - "			"Unable to read in mpt_ioctl_eventreport 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_eventreport() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);	maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);	max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;	/* If fewer than 1 event is requested, there must have	 * been some type of error.	 */	if ((max < 1) || !ioc->events)		return -ENODATA;	/* Copy the data from kernel memory to user memory	 */	numBytes = max * sizeof(MPT_IOCTL_EVENTS);	if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {		printk(KERN_ERR "%s@%d::mptctl_eventreport - "			"Unable to write out mpt_ioctl_eventreport struct @ %p\n",				__FILE__, __LINE__, ioc->events);		return -EFAULT;	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmptctl_replace_fw (unsigned long arg){	struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;	struct mpt_ioctl_replace_fw	 karg;	MPT_ADAPTER		 *ioc;	int			 iocnum;	int			 newFwSize;	dctlprintk(("mptctl_replace_fw called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "			"Unable to read in mpt_ioctl_replace_fw 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_replace_fw() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	/* If caching FW, Free the old FW image	 */	if (ioc->cached_fw == NULL)		return 0;	mpt_free_fw_memory(ioc);	/* Allocate memory for the new FW image	 */	newFwSize = karg.newImageSize;	if (newFwSize & 0x01)		newFwSize += 1;	if (newFwSize & 0x02)		newFwSize += 2;	mpt_alloc_fw_memory(ioc, newFwSize);	if (ioc->cached_fw == NULL)		return -ENOMEM;	/* Copy the data from user memory to kernel space	 */	if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "				"Unable to read in mpt_ioctl_replace_fw image "				"@ %p\n", __FILE__, __LINE__, uarg);		mpt_free_fw_memory(ioc);		return -EFAULT;	}	/* Update IOCFactsReply	 */	ioc->facts.FWImageSize = newFwSize;	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* MPT IOCTL MPTCOMMAND function. * Cast the arg into the mpt_ioctl_mpt_command structure. * * Outputs:	None. * Return:	0 if successful *		-EBUSY  if previous command timout and IOC reset is not complete. *		-EFAULT if data unavailable *		-ENODEV if no such device/adapter *		-ETIME	if timer expires *		-ENOMEM if memory allocation error */static intmptctl_mpt_command (unsigned long arg){	struct mpt_ioctl_command __user *uarg = (void __user *) arg;	struct mpt_ioctl_command  karg;	MPT_ADAPTER	*ioc;	int		iocnum;	int		rc;	dctlprintk(("mptctl_command called.\n"));	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {		printk(KERN_ERR "%s@%d::mptctl_mpt_command - "			"Unable to read in mpt_ioctl_command 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_mpt_command() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	rc = mptctl_do_mpt_command (karg, &uarg->MF);	return rc;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands. * * Outputs:	None. * Return:	0 if successful *		-EBUSY  if previous command timout and IOC reset is not complete. *		-EFAULT if data unavailable *		-ENODEV if no such device/adapter *		-ETIME	if timer expires *		-ENOMEM if memory allocation error *		-EPERM if SCSI I/O and target is untagged */static intmptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr){	MPT_ADAPTER	*ioc;	MPT_FRAME_HDR	*mf = NULL;	MPIHeader_t	*hdr;	char		*psge;	struct buflist	bufIn;	/* data In buffer */	struct buflist	bufOut; /* data Out buffer */	dma_addr_t	dma_addr_in;	dma_addr_t	dma_addr_out;	int		sgSize = 0;	/* Num SG elements */	int		iocnum, flagsLength;	int		sz, rc = 0;	int		msgContext;	u16		req_idx;	ulong 		timeout;	dctlprintk(("mptctl_do_mpt_command called.\n"));	bufIn.kptr = bufOut.kptr = NULL;	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||	    (ioc == NULL)) {		dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",				__FILE__, __LINE__, iocnum));		return -ENODEV;	}	if (!ioc->ioctl) {		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "			"No memory available during driver init.\n",				__FILE__, __LINE__);		return -ENOMEM;	} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "			"Busy with IOC Reset \n", __FILE__, __LINE__);		return -EBUSY;	}	/* Verify that the final request frame will not be too large.	 */	sz = karg.dataSgeOffset * 4;	if (karg.dataInSize > 0)		sz += sizeof(dma_addr_t) + sizeof(u32);	if (karg.dataOutSize > 0)		sz += sizeof(dma_addr_t) + sizeof(u32);	if (sz > ioc->req_sz) {		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "			"Request frame too large (%d) maximum (%d)\n",				__FILE__, __LINE__, sz, ioc->req_sz);		return -EFAULT;	}	/* Get a free request frame and save the message context.	 */        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)                return -EAGAIN;	hdr = (MPIHeader_t *) mf;	msgContext = le32_to_cpu(hdr->MsgContext);	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);	/* Copy the request frame	 * Reset the saved message context.	 * Request frame in user space	 */	if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "			"Unable to read MF from mpt_ioctl_command struct @ %p\n",			__FILE__, __LINE__, mfPtr);		rc = -EFAULT;		goto done_free_mem;	}	hdr->MsgContext = cpu_to_le32(msgContext);	/* Verify that this request is allowed.	 */	switch (hdr->Function) {	case MPI_FUNCTION_IOC_FACTS:	case MPI_FUNCTION_PORT_FACTS:		karg.dataOutSize  = karg.dataInSize = 0;		break;	case MPI_FUNCTION_CONFIG:	case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:	case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:	case MPI_FUNCTION_FW_UPLOAD:	case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:	case MPI_FUNCTION_FW_DOWNLOAD:	case MPI_FUNCTION_FC_PRIMITIVE_SEND:		break;	case MPI_FUNCTION_SCSI_IO_REQUEST:		if (ioc->sh) {			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;			VirtDevice	*pTarget = NULL;			MPT_SCSI_HOST	*hd = NULL;			int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;			int scsidir = 0;			int target = (int) pScsiReq->TargetID;			int dataSize;			if ((target < 0) || (target >= ioc->sh->max_id)) {				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "					"Target ID out of bounds. \n",					__FILE__, __LINE__);				rc = -ENODEV;				goto done_free_mem;			}			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;

⌨️ 快捷键说明

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