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

📄 mptctl.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",				__FILE__, __LINE__);		return -ENOMEM;	}	/* Fill in the data and return the structure to the calling	 * program	 */	/* struct mpt_ioctl_targetinfo does not contain sufficient space	 * for the target structures so when the IOCTL is called, there is	 * not sufficient stack space for the structure. Allocate memory,	 * populate the memory, copy back to the user, then free memory.	 * targetInfo format:	 * bits 31-24: reserved	 *      23-16: LUN	 *      15- 8: Bus Number	 *       7- 0: Target ID	 */	pmem = kmalloc(numBytes, GFP_KERNEL);	if (pmem == NULL) {		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",				__FILE__, __LINE__);		return -ENOMEM;	}	memset(pmem, 0, numBytes);	pdata =  (int *) pmem;	/* Get number of devices         */	if ((sh = ioc->sh) != NULL) {		max_id = sh->max_id - 1;		hd = (MPT_SCSI_HOST *) sh->hostdata;		/* Check all of the target structures.		 * Save the Id and increment the counter,		 * if ptr non-null.		 * sh->max_id = maximum target ID + 1		 */		if (hd && hd->Targets) {			mpt_findImVolumes(ioc);			pIoc2 = ioc->spi_data.pIocPg2;			for ( id = 0; id <= max_id; ) {				if ( pIoc2 && pIoc2->NumActiveVolumes ) {					if ( id == pIoc2->RaidVolume[0].VolumeID ) {						if (maxWordsLeft <= 0) {							printk(KERN_ERR "mptctl_gettargetinfo - "			"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);							goto data_space_full;						}						if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )                        				devType = 0x80;                    				else                        				devType = 0xC0;						bus_id = pIoc2->RaidVolume[0].VolumeBus;	            				numDevices++;                    				*pdata = ( (devType << 24) | (bus_id << 8) | id );						dctlprintk((KERN_ERR "mptctl_gettargetinfo - "		"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));                    				pdata++;						--maxWordsLeft;						goto next_id;					} else {						pIoc3 = ioc->spi_data.pIocPg3;            					for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {                    					if ( pIoc3->PhysDisk[jj].PhysDiskID == id )								goto next_id;						}					}				}				if ( (vdev = hd->Targets[id]) ) {					for (jj = 0; jj <= MPT_LAST_LUN; jj++) {						lun_index = (jj >> 5);						indexed_lun = (jj % 32);						lun = (1 << indexed_lun);						if (vdev->luns[lun_index] & lun) {							if (maxWordsLeft <= 0) {								printk(KERN_ERR "mptctl_gettargetinfo - "			"buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);								goto data_space_full;							}							bus_id = vdev->bus_id;							numDevices++;                            				*pdata = ( (jj << 16) | (bus_id << 8) | id );							dctlprintk((KERN_ERR "mptctl_gettargetinfo - "		"target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));							pdata++;							--maxWordsLeft;						}					}				}next_id:				id++;			}		}	}data_space_full:	karg.numDevices = numDevices;	/* Copy part of the data from kernel memory to user memory	 */	if (copy_to_user((char __user *)arg, &karg,				sizeof(struct mpt_ioctl_targetinfo))) {		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 */

⌨️ 快捷键说明

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