Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2d46e24 authored by Richard Genoud's avatar Richard Genoud Committed by Greg Kroah-Hartman
Browse files

Staging: rspiusb: clean rspiusb code



This first patch makes checkpatch happier

Signed-off-by: default avatarRichard Genoud <richard.genoud@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6546f08d
Loading
Loading
Loading
Loading
+224 −182
Original line number Diff line number Diff line
@@ -39,7 +39,11 @@ static int debug;
#endif
/* Use our own dbg macro */
#undef dbg
#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
#define dbg(format, arg...) \
	do { \
		if (debug) \
			printk(KERN_DEBUG __FILE__ ": " format "\n" , ##arg); \
	} while (0)

/* Version Information */
#define DRIVER_VERSION "V1.0.1"
@@ -65,7 +69,9 @@ static DECLARE_MUTEX(disconnect_sem);
struct device_extension {
	struct usb_device *udev;	 /* save off the usb device pointer */
	struct usb_interface *interface; /* the interface for this device */
	unsigned char minor;	/* the starting minor number for this device */
	unsigned char minor;		 /* the starting minor number
					  * for this device
					  */
	size_t bulk_in_size_returned;
	int bulk_in_byte_trk;
	struct urb ***PixelUrb;
@@ -82,20 +88,24 @@ struct device_extension {
	int pendingWrite;
	char **pendedPixelUrbs;
	int iama;		 /* PIXIS or ST133 */
	int num_frames;		/* the number of frames that will fit in the user buffer */
	int num_frames;		 /* the number of frames that will fit
				  * in the user buffer
				  */
	int active_frame;
	unsigned long frameSize;
	struct semaphore sem;
	//FX2 specific endpoints
	unsigned int hEP[8];
	unsigned int hEP[8];	 /* FX2 specific endpoints */
};

#define to_pi_dev(d) container_of(d, struct device_extension, kref)

/* Prototypes */
static int MapUserBuffer(struct ioctl_struct *, struct device_extension *);
static int UnMapUserBuffer(struct device_extension *);
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		       unsigned long arg);
static int piusb_output(struct ioctl_struct *, unsigned char *, int, struct device_extension *);
static int piusb_output(struct ioctl_struct *, unsigned char *, int,
		struct device_extension *);
static struct usb_driver piusb_driver;

/* table of devices that work with this driver */
@@ -107,8 +117,8 @@ static struct usb_device_id pi_device_table[] = {

MODULE_DEVICE_TABLE(usb, pi_device_table);

static int lastErr = 0;
static int errCnt = 0;
static int lastErr;
static int errCnt;

static void piusb_delete(struct kref *kref)
{
@@ -143,24 +153,28 @@ static int piusb_open(struct inode *inode, struct file *file)
	}
	dbg("Alternate Setting = %d", interface->num_altsetting);

	pdx->frameIdx = pdx->urbIdx = 0;
	pdx->bulk_in_size_returned = 0;
	pdx->bulk_in_byte_trk = 0;
	pdx->PixelUrb = NULL;
	pdx->frameIdx = 0;
	pdx->urbIdx = 0;
	pdx->maplist_numPagesMapped = NULL;
	pdx->userBufMapped = 0;
	pdx->sgl = NULL;
	pdx->sgEntries = NULL;
	pdx->gotPixelData = 0;
	pdx->pendingWrite = 0;
	pdx->frameSize = 0;
	pdx->pendedPixelUrbs = NULL;
	pdx->num_frames = 0;
	pdx->active_frame = 0;
	pdx->bulk_in_byte_trk = 0;
	pdx->userBufMapped = 0;
	pdx->pendedPixelUrbs = NULL;
	pdx->sgEntries = NULL;
	pdx->sgl = NULL;
	pdx->maplist_numPagesMapped = NULL;
	pdx->PixelUrb = NULL;
	pdx->bulk_in_size_returned = 0;
	pdx->frameSize = 0;

	/* increment our usage count for the device */
	kref_get(&pdx->kref);

	/* save our object in the file's private structure */
	file->private_data = pdx;

exit_no_device:
	return retval;
}
@@ -174,10 +188,13 @@ static int piusb_release(struct inode *inode, struct file *file)
	pdx = (struct device_extension *)file->private_data;
	if (pdx == NULL) {
		dbg("%s - object is NULL", __func__);
		return -ENODEV;
		retval = -ENODEV;
		goto object_null;
	}
	/* decrement the count on our device */
	kref_put(&pdx->kref, piusb_delete);

object_null:
	return retval;
}

@@ -206,9 +223,11 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	}
	/* fill in your device specific stuff here */
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
		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));
		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;
@@ -227,50 +246,57 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
			dbg("FW Version returned from HW = %ld.%ld",
			    (devRB >> 8), (devRB & 0xFF));
		}
		return devRB;
		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");
//            dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd );
		/* 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,
		/* 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)))
			dev_err(&pdx->udev->dev, "copy_from_user WRITE_DUMMY failed\n");
			dev_err(&pdx->udev->dev,
					"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)))
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
		return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);
		break;

	case PIUSB_UNMAP_USERBUFFER:
		UnMapUserBuffer(pdx);
		return 0;
		break;
		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");
		switch (ctrl.endpoint) {
		case 0:	//ST133 Pixel Data or PIXIS IO
		case 0:	/* ST133 Pixel Data or PIXIS IO */
			if (pdx->iama == PIXIS_PID) {
				unsigned int numToRead = 0;
				unsigned int totalRead = 0;
@@ -286,21 +312,19 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
				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
					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);
				} while (numToRead);
				memcpy(ctrl.pData, uBuf, totalRead);
				dbg("Total Bytes Read from PIXIS EP0 = %d",
				    totalRead);
@@ -311,34 +335,29 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
					dbg("copy_to_user failed in IORB");
				kfree(uBuf);
				return ctrl.numbytes;
			} else	//ST133 Pixel Data
			{
			}
			/* 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;
			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);
			pdx->active_frame = ((pdx->active_frame + 1)
					% pdx->num_frames);
			return ctrl.numbytes;
				}
			}
			break;
		case 1:	//ST133IO
		case 4:	//PIXIS IO

		case 1:	/* ST133IO */
			/* fall through */
		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 );
			/* 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],
@@ -348,41 +367,37 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
				    i);
				kfree(uBuf);
				return -1;
			} else {
			}
			ctrl.numbytes = numbytes;
			memcpy(ctrl.pData, uBuf, numbytes);
				if (copy_to_user
				    ((struct ioctl_struct *) arg, &ctrl,
			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
		case 2:	/* PIXIS Ping */
			/* fall through */
		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++)
			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;
			}

		default:
			break;
		}
		break;

	case PIUSB_WHATCAMERA:
		return pdx->iama;

	case PIUSB_SETFRAMESIZE:
		dbg("PIUSB_SETFRAMESIZE");
		if (copy_from_user
@@ -410,6 +425,7 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
			    kmalloc(sizeof(char *) * pdx->num_frames,
				    GFP_KERNEL);
		return 0;

	default:
		dbg("%s\n", "No IOCTL found");
		break;
@@ -472,6 +488,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
	int i = 0;
	int k = 0;
	unsigned int epAddr;

	for (k = 0; k < pdx->num_frames; k++) {
		dbg("Killing Urbs for Frame %d", k);
		for (i = 0; i < pdx->sgEntries[k]; i++) {
@@ -485,23 +502,19 @@ static int UnMapUserBuffer(struct device_extension *pdx)
	}

	for (k = 0; k < pdx->num_frames; k++) {
		if (pdx->iama == PIXIS_PID)	//if so, which EP should we map this frame to
		{
			if (k % 2)	//check to see if this should use EP4(PONG)
			{
				epAddr = pdx->hEP[3];	//PONG, odd frames
			} else {
				epAddr = pdx->hEP[2];	//PING, even frames and zero
			}
		} else		//ST133 only has 1 endpoint for Pixel data transfer
		{
		if (pdx->iama == PIXIS_PID)
			/* which EP should we map this frame to ? */
			/* PONG, odd frames: hEP[3] */
			/* PING, even frames and zero hEP[2] */
			epAddr = (k % 2) ? pdx->hEP[3] : pdx->hEP[2];
		else
			/* ST133 only has 1 endpoint for Pixel data transfer */
			epAddr = pdx->hEP[0];
		}

		usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k],
				    pdx->maplist_numPagesMapped[k]);
		for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++) {
		for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++)
			page_cache_release(pdx->sgl[k][i].page_link);
		}
		kfree(pdx->sgl[k]);
		kfree(pdx->PixelUrb[k]);
		kfree(pdx->pendedPixelUrbs[k]);
@@ -509,6 +522,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
		pdx->PixelUrb[k] = NULL;
		pdx->pendedPixelUrbs[k] = NULL;
	}

	kfree(pdx->sgEntries);
	vfree(pdx->maplist_numPagesMapped);
	pdx->sgEntries = NULL;
@@ -519,6 +533,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
	pdx->sgl = NULL;
	pdx->pendedPixelUrbs = NULL;
	pdx->PixelUrb = NULL;

	return 0;
}

@@ -539,16 +554,16 @@ static void piusb_readPIXEL_callback(struct urb *urb)
		pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0;
	} else {
		pdx->bulk_in_byte_trk += urb->actual_length;
		{
			i = usb_submit_urb(urb, GFP_ATOMIC);	//resubmit the URB
		i = usb_submit_urb(urb, GFP_ATOMIC);	/* resubmit the URB */
		if (i) {
			errCnt++;
			if (i != lastErr) {
					dbg("submit urb in callback failed with error code %d", i);
				dbg("submit urb in callback failed "
						"with error code %d", i);
				lastErr = i;
			}
		} else {
				pdx->urbIdx++;	//point to next URB when we callback
			pdx->urbIdx++; /* point to next URB when we callback */
			if (pdx->bulk_in_byte_trk >= pdx->frameSize) {
				pdx->bulk_in_size_returned =
					pdx->bulk_in_byte_trk;
@@ -562,28 +577,40 @@ static void piusb_readPIXEL_callback(struct urb *urb)
		}
	}
}
}

/* MapUserBuffer(
	inputs:
	struct ioctl_struct *io - structure containing user address, frame #, and size
	struct ioctl_struct *io - structure containing user address,
				frame #, and size
	struct device_extension *pdx - the PIUSB device extension

	returns:
	int - status of the task

	Notes:
	MapUserBuffer maps a buffer passed down through an ioctl.  The user buffer is Page Aligned by the app
	and then passed down.  The function get_free_pages(...) does the actual mapping of the buffer from user space to
	kernel space.  From there a scatterlist is created from all the pages.  The next function called is to usb_buffer_map_sg
	which allocated DMA addresses for each page, even coalescing them if possible.  The DMA address is placed in the scatterlist
	structure.  The function returns the number of DMA addresses.  This may or may not be equal to the number of pages that
	the user buffer uses.  We then build an URB for each DMA address and then submit them.
	MapUserBuffer maps a buffer passed down through an ioctl.
	The user buffer is Page Aligned by the app and then passed down.
	The function get_free_pages(...) does the actual mapping of the buffer
	from user space to kernel space.
	From there a scatterlist is created from all the pages.
	The next function called is to usb_buffer_map_sg which allocated
	DMA addresses for each page, even coalescing them if possible.
	The DMA address is placed in the scatterlist structure.
	The function returns the number of DMA addresses.
	This may or may not be equal to the number of pages that
	the user buffer uses.
	We then build an URB for each DMA address and then submit them.
*/

/*
int MapUserBuffer(unsigned long uaddr, unsigned long numbytes,
		unsigned long frameInfo, struct device_extension *pdx)
*/
//int MapUserBuffer( unsigned long uaddr, unsigned long numbytes, unsigned long frameInfo, struct device_extension *pdx )
static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
{
	unsigned long uaddr;
	unsigned long numbytes;
	int frameInfo;		//which frame we're mapping
	int frameInfo;	/* which frame we're mapping */
	unsigned int epAddr = 0;
	unsigned long count = 0;
	int i = 0;
@@ -591,45 +618,45 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
	int err = 0;
	struct page **maplist_p;
	int numPagesRequired;

	frameInfo = io->numFrames;
	uaddr = (unsigned long)io->pData;
	numbytes = io->numbytes;

	if (pdx->iama == PIXIS_PID)	//if so, which EP should we map this frame to
	{
		if (frameInfo % 2)	//check to see if this should use EP4(PONG)
		{
			epAddr = pdx->hEP[3];	//PONG, odd frames
		} else {
			epAddr = pdx->hEP[2];	//PING, even frames and zero
		}
	if (pdx->iama == PIXIS_PID) {
		/* which EP should we map this frame to ? */
		/* PONG, odd frames: hEP[3] */
		/* PING, even frames and zero hEP[2] */
		epAddr = (frameInfo % 2) ? pdx->hEP[3] : pdx->hEP[2];
		dbg("Pixis Frame #%d: EP=%d", frameInfo,
		    (epAddr == pdx->hEP[2]) ? 2 : 4);
	} else			//ST133 only has 1 endpoint for Pixel data transfer
	{
	} else { /* ST133 only has 1 endpoint for Pixel data transfer */
		epAddr = pdx->hEP[0];
		dbg("ST133 Frame #%d: EP=2", frameInfo);
	}
	count = numbytes;
	dbg("UserAddress = 0x%08lX", uaddr);
	dbg("numbytes = %d", (int)numbytes);
	//number of pages to map the entire user space DMA buffer

	/* number of pages to map the entire user space DMA buffer */
	numPagesRequired =
	    ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
	dbg("Number of pages needed = %d", numPagesRequired);
	maplist_p = vmalloc(numPagesRequired * sizeof(struct page));	//, GFP_ATOMIC);
	maplist_p = vmalloc(numPagesRequired * sizeof(struct page));
	if (!maplist_p) {
		dbg("Can't Allocate Memory for maplist_p");
		return -ENOMEM;
	}
	//map the user buffer to kernel memory

	/* map the user buffer to kernel memory */
	down_write(&current->mm->mmap_sem);
	pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current, current->mm, (uaddr & PAGE_MASK), numPagesRequired, WRITE, 0,	//Don't Force
								maplist_p,
								NULL);
	pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current,
			current->mm, (uaddr & PAGE_MASK), numPagesRequired,
			WRITE, 0 /* Don't Force*/, maplist_p, NULL);
	up_write(&current->mm->mmap_sem);
	dbg("Number of pages mapped = %d",
	    pdx->maplist_numPagesMapped[frameInfo]);

	for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++)
		flush_dcache_page(maplist_p[i]);
	if (!pdx->maplist_numPagesMapped[frameInfo]) {
@@ -637,7 +664,10 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
		vfree(maplist_p);
		return -ENOMEM;
	}
	//need to create a scatterlist that spans each frame that can fit into the mapped buffer

	/* need to create a scatterlist that spans each frame
	 * that can fit into the mapped buffer
	 */
	pdx->sgl[frameInfo] =
	    kmalloc((pdx->maplist_numPagesMapped[frameInfo] *
		     sizeof(struct scatterlist)), GFP_ATOMIC);
@@ -657,7 +687,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
			pdx->sgl[frameInfo][k].page_link = maplist_p[k];
			pdx->sgl[frameInfo][k].length =
			    (count < PAGE_SIZE) ? count : PAGE_SIZE;
			count -= PAGE_SIZE;	//example had PAGE_SIZE here;
			count -= PAGE_SIZE; /* example had PAGE_SIZE here */
		}
	} else {
		pdx->sgl[frameInfo][0].length = count;
@@ -668,7 +698,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
	dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]);
	pdx->userBufMapped = 1;
	vfree(maplist_p);
	//Create and Send the URB's for each s/g entry

	/* Create and Send the URB's for each s/g entry */
	pdx->PixelUrb[frameInfo] =
	    kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *),
		    GFP_KERNEL);
@@ -677,7 +708,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
		return -ENOMEM;
	}
	for (i = 0; i < pdx->sgEntries[frameInfo]; i++) {
		pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL);	//0 because we're using BULK transfers
		/* 0 iso packets because we're using BULK transfers */
		pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL);
		usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i],
				  pdx->udev,
				  epAddr,
@@ -691,7 +723,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
		pdx->PixelUrb[frameInfo][i]->transfer_flags =
		    URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
	}
	pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT;	//only interrupt when last URB completes
	/* only interrupt when last URB completes */
	pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT;
	pdx->pendedPixelUrbs[frameInfo] =
	    kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL);
	if (!pdx->pendedPixelUrbs[frameInfo])
@@ -702,13 +735,13 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
			dbg("%s %d\n", "submit urb error =", err);
			pdx->pendedPixelUrbs[frameInfo][i] = 0;
			return err;
		} else
			pdx->pendedPixelUrbs[frameInfo][i] = 1;;
		}
		pdx->pendedPixelUrbs[frameInfo][i] = 1;
	}
	return 0;
}

static struct file_operations piusb_fops = {
static const struct file_operations piusb_fops = {
	.owner = THIS_MODULE,
	.ioctl = piusb_ioctl,
	.open = piusb_open,
@@ -751,9 +784,9 @@ static int piusb_probe(struct usb_interface *interface,
	/* See if the device offered us matches what we can accept */
	if ((pdx->udev->descriptor.idVendor != VENDOR_ID)
	    || ((pdx->udev->descriptor.idProduct != PIXIS_PID)
		&& (pdx->udev->descriptor.idProduct != ST133_PID))) {
		&& (pdx->udev->descriptor.idProduct != ST133_PID)))
		return -ENODEV;
	}

	pdx->iama = pdx->udev->descriptor.idProduct;

	if (debug) {
@@ -828,12 +861,17 @@ static void piusb_disconnect(struct usb_interface *interface)
{
	struct device_extension *pdx;
	int minor = interface->minor;

	lock_kernel();

	pdx = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	/* give back our minor */
	usb_deregister_dev(interface, &piusb_class);

	unlock_kernel();

	/* prevent device read, write and ioctl */
	pdx->present = 0;
	kref_put(&pdx->kref, piusb_delete);
@@ -853,16 +891,20 @@ static struct usb_driver piusb_driver = {
static int __init piusb_init(void)
{
	int result;

	lastErr = 0;
	errCnt = 0;

	/* register this driver with the USB subsystem */
	result = usb_register(&piusb_driver);
	if (result) {
	if (result)
		printk(KERN_ERR KBUILD_MODNAME
		       ": usb_register failed. Error number %d\n", result);
		return result;
	}
				": usb_register failed. Error number %d\n",
				result);
	else
		printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
				DRIVER_VERSION);
	return 0;
	return result;
}

/**
+18 −10
Original line number Diff line number Diff line
@@ -3,20 +3,28 @@

#define PIUSB_MAGIC		'm'
#define PIUSB_IOCTL_BASE	192
#define PIUSB_GETVNDCMD		_IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 1, struct ioctl_struct)
#define PIUSB_SETVNDCMD		_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 2, struct ioctl_struct)
#define PIUSB_WRITEPIPE		_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 3, struct ioctl_struct)
#define PIUSB_READPIPE		_IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 4, struct ioctl_struct)
#define PIUSB_SETFRAMESIZE	_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 5, struct ioctl_struct)
#define PIUSB_WHATCAMERA	_IO(PIUSB_MAGIC,  PIUSB_IOCTL_BASE + 6)
#define PIUSB_USERBUFFER	_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 7, struct ioctl_struct)
#define PIUSB_ISHIGHSPEED	_IO(PIUSB_MAGIC,  PIUSB_IOCTL_BASE + 8)
#define PIUSB_UNMAP_USERBUFFER	_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 9, struct ioctl_struct)

#define PIUSB_IOR(offset) \
	_IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
#define PIUSB_IOW(offset) \
	_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
#define PIUSB_IO(offset) \
	_IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset)

#define PIUSB_GETVNDCMD		PIUSB_IOR(1)
#define PIUSB_SETVNDCMD		PIUSB_IOW(2)
#define PIUSB_WRITEPIPE		PIUSB_IOW(3)
#define PIUSB_READPIPE		PIUSB_IOR(4)
#define PIUSB_SETFRAMESIZE	PIUSB_IOW(5)
#define PIUSB_WHATCAMERA	PIUSB_IO(6)
#define PIUSB_USERBUFFER	PIUSB_IOW(7)
#define PIUSB_ISHIGHSPEED	PIUSB_IO(8)
#define PIUSB_UNMAP_USERBUFFER	PIUSB_IOW(9)

struct ioctl_struct {
	unsigned char cmd;
	unsigned long numbytes;
	unsigned char dir;	//1=out;0=in
	unsigned char dir;	/* 1=out; 0=in */
	int endpoint;
	int numFrames;
	unsigned char *pData;