示例#1
0
/**
 *	piusb_ioctl
 */
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		       unsigned long arg)
{
	struct device_extension *pdx;
	char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned long devRB = 0;
	int i = 0;
	int err = 0;
	int retval = 0;
	struct ioctl_struct ctrl;
	unsigned char *uBuf;
	int numbytes = 0;
	unsigned short controlData = 0;

	pdx = (struct device_extension *)file->private_data;
	/* verify that the device wasn't unplugged */
	if (!pdx->present) {
		dbg("No Device Present\n");
		return -ENODEV;
	}
	/* fill in your device specific stuff here */
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if (err) {
		dev_err(&pdx->udev->dev, "return with error = %d\n", err);
		return -EFAULT;
	}
	switch (cmd) {
	case PIUSB_GETVNDCMD:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd);
		retval =
		    usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
				    ctrl.cmd, USB_DIR_IN, 0, 0, &devRB,
				    ctrl.numbytes, HZ * 10);
		if (ctrl.cmd == 0xF1) {
			dbg("FW Version returned from HW = %ld.%ld",
			    (devRB >> 8), (devRB & 0xFF));
		}
		return devRB;
	case PIUSB_SETVNDCMD:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
//            dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd );
		controlData = ctrl.pData[0];
		controlData |= (ctrl.pData[1] << 8);
//            dbg( "%s %d", "Vendor Data =",controlData );
		retval = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), ctrl.cmd, (USB_DIR_OUT | USB_TYPE_VENDOR),	/* | USB_RECIP_ENDPOINT), */
					 controlData,
					 0,
					 &dummyCtlBuf, ctrl.numbytes, HZ * 10);
		return retval;
		break;
	case PIUSB_ISHIGHSPEED:
		return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);
		break;
	case PIUSB_WRITEPIPE:
		if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd)))
			info("copy_from_user WRITE_DUMMY failed\n");
		if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
			dbg("can't access pData");
			return 0;
		}
		piusb_output(&ctrl, ctrl.pData /*uBuf */ , ctrl.numbytes, pdx);
		return ctrl.numbytes;
		break;
	case PIUSB_USERBUFFER:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		return MapUserBuffer((struct ioctl_struct *) & ctrl, pdx);
		break;
	case PIUSB_UNMAP_USERBUFFER:
		UnMapUserBuffer(pdx);
		return 0;
		break;
	case PIUSB_READPIPE:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		switch (ctrl.endpoint) {
		case 0:	//ST133 Pixel Data or PIXIS IO
			if (pdx->iama == PIXIS_PID) {
				unsigned int numToRead = 0;
				unsigned int totalRead = 0;
				uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
				if (!uBuf) {
					dbg("Alloc for uBuf failed");
					return 0;
				}
				numbytes = ctrl.numbytes;
				numToRead = numbytes;
				dbg("numbytes to read = %d", numbytes);
				dbg("endpoint # %d", ctrl.endpoint);
				if (copy_from_user(uBuf, ctrl.pData, numbytes))
					dbg("copying ctrl.pData to dummyBuf failed");
				do {
					i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint], (uBuf + totalRead), (numToRead > 64) ? 64 : numToRead, &numbytes, HZ * 10);	//EP0 can only handle 64 bytes at a time
					if (i) {
						dbg("CMD = %s, Address = 0x%02X", ((uBuf[3] == 0x02) ? "WRITE" : "READ"), uBuf[1]);
						dbg("Number of bytes Attempted to read = %d", (int)ctrl.numbytes);
						dbg("Blocking ReadI/O Failed with status %d", i);
						kfree(uBuf);
						return -1;
					} else {
						dbg("Pixis EP0 Read %d bytes",
						    numbytes);
						totalRead += numbytes;
						numToRead -= numbytes;
					}
				}
				while (numToRead);
				memcpy(ctrl.pData, uBuf, totalRead);
				dbg("Total Bytes Read from PIXIS EP0 = %d",
				    totalRead);
				ctrl.numbytes = totalRead;
				if (copy_to_user
				    ((struct ioctl_struct *) arg, &ctrl,
				     sizeof(struct ioctl_struct)))
					dbg("copy_to_user failed in IORB");
				kfree(uBuf);
				return ctrl.numbytes;
			} else	//ST133 Pixel Data
			{
				if (!pdx->gotPixelData)
					return 0;
				else {
					pdx->gotPixelData = 0;
					ctrl.numbytes =
					    pdx->bulk_in_size_returned;
					pdx->bulk_in_size_returned -=
					    pdx->frameSize;
					for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
						SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
					pdx->active_frame =
					    ((pdx->active_frame +
					      1) % pdx->num_frames);
					return ctrl.numbytes;
				}
			}
			break;
		case 1:	//ST133IO
		case 4:	//PIXIS IO
			uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
			if (!uBuf) {
				dbg("Alloc for uBuf failed");
				return 0;
			}
			numbytes = ctrl.numbytes;
//                                      dbg( "numbytes to read = %d", numbytes );
			if (copy_from_user(uBuf, ctrl.pData, numbytes))
				dbg("copying ctrl.pData to dummyBuf failed");
			i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint],
					 uBuf, numbytes, &numbytes, HZ * 10);
			if (i) {
				dbg("Blocking ReadI/O Failed with status %d",
				    i);
				kfree(uBuf);
				return -1;
			} else {
				ctrl.numbytes = numbytes;
				memcpy(ctrl.pData, uBuf, numbytes);
				if (copy_to_user
				    ((struct ioctl_struct *) arg, &ctrl,
				     sizeof(struct ioctl_struct)))
					dbg("copy_to_user failed in IORB");
				kfree(uBuf);
				return ctrl.numbytes;
			}
			break;

		case 2:	//PIXIS Ping
		case 3:	//PIXIS Pong
			if (!pdx->gotPixelData)
				return 0;
			else {
				pdx->gotPixelData = 0;
				ctrl.numbytes = pdx->bulk_in_size_returned;
				pdx->bulk_in_size_returned -= pdx->frameSize;
				for (i = 0;
				     i <
				     pdx->maplist_numPagesMapped[pdx->
								 active_frame];
				     i++)
					SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
				pdx->active_frame =
				    ((pdx->active_frame + 1) % pdx->num_frames);
				return ctrl.numbytes;
			}
			break;
		}
		break;
	case PIUSB_WHATCAMERA:
		return pdx->iama;
	case PIUSB_SETFRAMESIZE:
		dbg("PIUSB_SETFRAMESIZE");
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		pdx->frameSize = ctrl.numbytes;
		pdx->num_frames = ctrl.numFrames;
		if (!pdx->sgl)
			pdx->sgl =
			    kmalloc(sizeof(struct scatterlist *) *
				    pdx->num_frames, GFP_KERNEL);
		if (!pdx->sgEntries)
			pdx->sgEntries =
			    kmalloc(sizeof(unsigned int) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->PixelUrb)
			pdx->PixelUrb =
			    kmalloc(sizeof(struct urb **) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->maplist_numPagesMapped)
			pdx->maplist_numPagesMapped =
			    vmalloc(sizeof(unsigned int) * pdx->num_frames);
		if (!pdx->pendedPixelUrbs)
			pdx->pendedPixelUrbs =
			    kmalloc(sizeof(char *) * pdx->num_frames,
				    GFP_KERNEL);
		return 0;
	default:
		dbg("%s\n", "No IOCTL found");
		break;

	}
示例#2
0
/**
 *	piusb_ioctl
 */
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		       unsigned long arg)
{
	struct device_extension *pdx;
	char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned long devRB = 0;
	int err = 0;
	int retval = 0;
	struct ioctl_struct ctrl;
	unsigned short controlData = 0;

	pdx = (struct device_extension *)file->private_data;
	/* verify that the device wasn't unplugged */
	if (!pdx->present) {
		dbg("No Device Present\n");
		return -ENODEV;
	}
	/* fill in your device specific stuff here */
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg,
				_IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user *)arg,
			       _IOC_SIZE(cmd));
	if (err) {
		dev_err(&pdx->udev->dev, "return with error = %d\n", err);
		return -EFAULT;
	}
	switch (cmd) {
	case PIUSB_GETVNDCMD:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd);
		retval =
		    usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
				    ctrl.cmd, USB_DIR_IN, 0, 0, &devRB,
				    ctrl.numbytes, HZ * 10);
		if (ctrl.cmd == 0xF1) {
			dbg("FW Version returned from HW = %ld.%ld",
			    (devRB >> 8), (devRB & 0xFF));
		}
		if (retval >= 0)
			retval = (int)devRB;
		return retval;

	case PIUSB_SETVNDCMD:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		/* dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); */
		controlData = ctrl.pData[0];
		controlData |= (ctrl.pData[1] << 8);
		/* dbg( "%s %d", "Vendor Data =",controlData ); */
		retval = usb_control_msg(pdx->udev,
				usb_sndctrlpipe(pdx->udev, 0),
				ctrl.cmd,
				(USB_DIR_OUT | USB_TYPE_VENDOR
				 /* | USB_RECIP_ENDPOINT */),
				controlData, 0,
				&dummyCtlBuf, ctrl.numbytes, HZ * 10);
		return retval;

	case PIUSB_ISHIGHSPEED:
		return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);

	case PIUSB_WRITEPIPE:
		if (__copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) {
			dev_err(&pdx->udev->dev,
					"copy_from_user WRITE_DUMMY failed\n");
			return -EFAULT;
		}
		if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
			dbg("can't access pData");
			return 0;
		}
		piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx);
		return ctrl.numbytes;

	case PIUSB_USERBUFFER:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);

	case PIUSB_UNMAP_USERBUFFER:
		retval = UnMapUserBuffer(pdx);
		return retval;

	case PIUSB_READPIPE:
		if (__copy_from_user(&ctrl, (void __user *)arg,
					sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		if (((0 == ctrl.endpoint) && (PIXIS_PID == pdx->iama)) ||
				(1 == ctrl.endpoint) ||	/* ST133IO */
				(4 == ctrl.endpoint))	/* PIXIS IO */
			return pixis_io(&ctrl, pdx,
					(struct ioctl_struct *)arg);
		else if ((0 == ctrl.endpoint) || /* ST133 Pixel Data */
				(2 == ctrl.endpoint) || /* PIXIS Ping */
				(3 == ctrl.endpoint))	/* PIXIS Pong */
			return pixel_data(&ctrl, pdx);

		break;

	case PIUSB_WHATCAMERA:
		return pdx->iama;

	case PIUSB_SETFRAMESIZE:
		dbg("PIUSB_SETFRAMESIZE");
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		pdx->frameSize = ctrl.numbytes;
		pdx->num_frames = ctrl.numFrames;
		if (!pdx->sgl)
			pdx->sgl =
			    kmalloc(sizeof(struct scatterlist *) *
				    pdx->num_frames, GFP_KERNEL);
		if (!pdx->sgEntries)
			pdx->sgEntries =
			    kmalloc(sizeof(unsigned int) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->PixelUrb)
			pdx->PixelUrb =
			    kmalloc(sizeof(struct urb **) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->maplist_numPagesMapped)
			pdx->maplist_numPagesMapped =
			    vmalloc(sizeof(unsigned int) * pdx->num_frames);
		if (!pdx->pendedPixelUrbs)
			pdx->pendedPixelUrbs =
			    kmalloc(sizeof(char *) * pdx->num_frames,
				    GFP_KERNEL);
		return 0;

	default:
		dbg("%s\n", "No IOCTL found");
		break;

	}