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

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
...@@ -39,7 +39,11 @@ static int debug; ...@@ -39,7 +39,11 @@ static int debug;
#endif #endif
/* Use our own dbg macro */ /* Use our own dbg macro */
#undef dbg #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 */ /* Version Information */
#define DRIVER_VERSION "V1.0.1" #define DRIVER_VERSION "V1.0.1"
...@@ -65,7 +69,9 @@ static DECLARE_MUTEX(disconnect_sem); ...@@ -65,7 +69,9 @@ static DECLARE_MUTEX(disconnect_sem);
struct device_extension { struct device_extension {
struct usb_device *udev; /* save off the usb device pointer */ struct usb_device *udev; /* save off the usb device pointer */
struct usb_interface *interface; /* the interface for this device */ 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; size_t bulk_in_size_returned;
int bulk_in_byte_trk; int bulk_in_byte_trk;
struct urb ***PixelUrb; struct urb ***PixelUrb;
...@@ -74,28 +80,32 @@ struct device_extension { ...@@ -74,28 +80,32 @@ struct device_extension {
unsigned int *maplist_numPagesMapped; unsigned int *maplist_numPagesMapped;
int open; /* if the port is open or not */ int open; /* if the port is open or not */
int present; /* if the device is not disconnected */ int present; /* if the device is not disconnected */
int userBufMapped; /* has the user buffer been mapped? */ int userBufMapped; /* has the user buffer been mapped ? */
struct scatterlist **sgl; /* scatter-gather list for user buffer */ struct scatterlist **sgl; /* scatter-gather list for user buffer */
unsigned int *sgEntries; unsigned int *sgEntries;
struct kref kref; struct kref kref;
int gotPixelData; int gotPixelData;
int pendingWrite; int pendingWrite;
char **pendedPixelUrbs; char **pendedPixelUrbs;
int iama; /*PIXIS or ST133 */ 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; int active_frame;
unsigned long frameSize; unsigned long frameSize;
struct semaphore sem; struct semaphore sem;
//FX2 specific endpoints unsigned int hEP[8]; /* FX2 specific endpoints */
unsigned int hEP[8];
}; };
#define to_pi_dev(d) container_of( d, struct device_extension, kref )
#define to_pi_dev(d) container_of(d, struct device_extension, kref)
/* Prototypes */
static int MapUserBuffer(struct ioctl_struct *, struct device_extension *); static int MapUserBuffer(struct ioctl_struct *, struct device_extension *);
static int UnMapUserBuffer(struct device_extension *); static int UnMapUserBuffer(struct device_extension *);
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg); 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; static struct usb_driver piusb_driver;
/* table of devices that work with this driver */ /* table of devices that work with this driver */
...@@ -107,8 +117,8 @@ static struct usb_device_id pi_device_table[] = { ...@@ -107,8 +117,8 @@ static struct usb_device_id pi_device_table[] = {
MODULE_DEVICE_TABLE(usb, pi_device_table); MODULE_DEVICE_TABLE(usb, pi_device_table);
static int lastErr = 0; static int lastErr;
static int errCnt = 0; static int errCnt;
static void piusb_delete(struct kref *kref) static void piusb_delete(struct kref *kref)
{ {
...@@ -143,25 +153,29 @@ static int piusb_open(struct inode *inode, struct file *file) ...@@ -143,25 +153,29 @@ static int piusb_open(struct inode *inode, struct file *file)
} }
dbg("Alternate Setting = %d", interface->num_altsetting); 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->gotPixelData = 0;
pdx->pendingWrite = 0; pdx->pendingWrite = 0;
pdx->frameSize = 0; pdx->pendedPixelUrbs = NULL;
pdx->num_frames = 0; pdx->num_frames = 0;
pdx->active_frame = 0; pdx->active_frame = 0;
pdx->bulk_in_byte_trk = 0; pdx->frameSize = 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;
/* increment our usage count for the device */ /* increment our usage count for the device */
kref_get(&pdx->kref); kref_get(&pdx->kref);
/* save our object in the file's private structure */ /* save our object in the file's private structure */
file->private_data = pdx; file->private_data = pdx;
exit_no_device:
exit_no_device:
return retval; return retval;
} }
...@@ -174,10 +188,13 @@ static int piusb_release(struct inode *inode, struct file *file) ...@@ -174,10 +188,13 @@ static int piusb_release(struct inode *inode, struct file *file)
pdx = (struct device_extension *)file->private_data; pdx = (struct device_extension *)file->private_data;
if (pdx == NULL) { if (pdx == NULL) {
dbg("%s - object is NULL", __func__); dbg("%s - object is NULL", __func__);
return -ENODEV; retval = -ENODEV;
goto object_null;
} }
/* decrement the count on our device */ /* decrement the count on our device */
kref_put(&pdx->kref, piusb_delete); kref_put(&pdx->kref, piusb_delete);
object_null:
return retval; return retval;
} }
...@@ -206,9 +223,11 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -206,9 +223,11 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} }
/* fill in your device specific stuff here */ /* fill in your device specific stuff here */
if (_IOC_DIR(cmd) & _IOC_READ) 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) 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) { if (err) {
dev_err(&pdx->udev->dev, "return with error = %d\n", err); dev_err(&pdx->udev->dev, "return with error = %d\n", err);
return -EFAULT; return -EFAULT;
...@@ -227,50 +246,57 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -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", dbg("FW Version returned from HW = %ld.%ld",
(devRB >> 8), (devRB & 0xFF)); (devRB >> 8), (devRB & 0xFF));
} }
return devRB; if (retval >= 0)
retval = (int)devRB;
return retval;
case PIUSB_SETVNDCMD: case PIUSB_SETVNDCMD:
if (copy_from_user if (copy_from_user
(&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
dev_err(&pdx->udev->dev, "copy_from_user failed\n"); 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[0];
controlData |= (ctrl.pData[1] << 8); controlData |= (ctrl.pData[1] << 8);
// dbg( "%s %d", "Vendor Data =",controlData ); /* 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), */ retval = usb_control_msg(pdx->udev,
controlData, usb_sndctrlpipe(pdx->udev, 0),
0, ctrl.cmd,
(USB_DIR_OUT | USB_TYPE_VENDOR
/* | USB_RECIP_ENDPOINT */),
controlData, 0,
&dummyCtlBuf, ctrl.numbytes, HZ * 10); &dummyCtlBuf, ctrl.numbytes, HZ * 10);
return retval; return retval;
break;
case PIUSB_ISHIGHSPEED: case PIUSB_ISHIGHSPEED:
return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0); return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);
break;
case PIUSB_WRITEPIPE: case PIUSB_WRITEPIPE:
if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) 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)) { if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
dbg("can't access pData"); dbg("can't access pData");
return 0; return 0;
} }
piusb_output(&ctrl, ctrl.pData /*uBuf */ , ctrl.numbytes, pdx); piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx);
return ctrl.numbytes; return ctrl.numbytes;
break;
case PIUSB_USERBUFFER: case PIUSB_USERBUFFER:
if (copy_from_user if (copy_from_user
(&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
dev_err(&pdx->udev->dev, "copy_from_user failed\n"); dev_err(&pdx->udev->dev, "copy_from_user failed\n");
return MapUserBuffer((struct ioctl_struct *) & ctrl, pdx); return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);
break;
case PIUSB_UNMAP_USERBUFFER: case PIUSB_UNMAP_USERBUFFER:
UnMapUserBuffer(pdx); retval = UnMapUserBuffer(pdx);
return 0; return retval;
break;
case PIUSB_READPIPE: case PIUSB_READPIPE:
if (copy_from_user if (copy_from_user
(&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
dev_err(&pdx->udev->dev, "copy_from_user failed\n"); dev_err(&pdx->udev->dev, "copy_from_user failed\n");
switch (ctrl.endpoint) { switch (ctrl.endpoint) {
case 0: //ST133 Pixel Data or PIXIS IO case 0: /* ST133 Pixel Data or PIXIS IO */
if (pdx->iama == PIXIS_PID) { if (pdx->iama == PIXIS_PID) {
unsigned int numToRead = 0; unsigned int numToRead = 0;
unsigned int totalRead = 0; unsigned int totalRead = 0;
...@@ -286,21 +312,19 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -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)) if (copy_from_user(uBuf, ctrl.pData, numbytes))
dbg("copying ctrl.pData to dummyBuf failed"); dbg("copying ctrl.pData to dummyBuf failed");
do { 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) { if (i) {
dbg("CMD = %s, Address = 0x%02X", ((uBuf[3] == 0x02) ? "WRITE" : "READ"), uBuf[1]); 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("Number of bytes Attempted to read = %d", (int)ctrl.numbytes);
dbg("Blocking ReadI/O Failed with status %d", i); dbg("Blocking ReadI/O Failed with status %d", i);
kfree(uBuf); kfree(uBuf);
return -1; return -1;
} else { }
dbg("Pixis EP0 Read %d bytes", dbg("Pixis EP0 Read %d bytes",
numbytes); numbytes);
totalRead += numbytes; totalRead += numbytes;
numToRead -= numbytes; numToRead -= numbytes;
} } while (numToRead);
}
while (numToRead);
memcpy(ctrl.pData, uBuf, totalRead); memcpy(ctrl.pData, uBuf, totalRead);
dbg("Total Bytes Read from PIXIS EP0 = %d", dbg("Total Bytes Read from PIXIS EP0 = %d",
totalRead); totalRead);
...@@ -311,34 +335,29 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -311,34 +335,29 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
dbg("copy_to_user failed in IORB"); dbg("copy_to_user failed in IORB");
kfree(uBuf); kfree(uBuf);
return ctrl.numbytes; return ctrl.numbytes;
} else //ST133 Pixel Data }
{ /* ST133 Pixel Data */
if (!pdx->gotPixelData) if (!pdx->gotPixelData)
return 0; return 0;
else {
pdx->gotPixelData = 0; pdx->gotPixelData = 0;
ctrl.numbytes = ctrl.numbytes = pdx->bulk_in_size_returned;
pdx->bulk_in_size_returned; pdx->bulk_in_size_returned -= pdx->frameSize;
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); SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
pdx->active_frame = pdx->active_frame = ((pdx->active_frame + 1)
((pdx->active_frame + % pdx->num_frames);
1) % pdx->num_frames);
return ctrl.numbytes; return ctrl.numbytes;
}
} case 1: /* ST133IO */
break; /* fall through */
case 1: //ST133IO case 4: /* PIXIS IO */
case 4: //PIXIS IO
uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL); uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
if (!uBuf) { if (!uBuf) {
dbg("Alloc for uBuf failed"); dbg("Alloc for uBuf failed");
return 0; return 0;
} }
numbytes = ctrl.numbytes; numbytes = ctrl.numbytes;
// dbg( "numbytes to read = %d", numbytes ); /* dbg( "numbytes to read = %d", numbytes ); */
if (copy_from_user(uBuf, ctrl.pData, numbytes)) if (copy_from_user(uBuf, ctrl.pData, numbytes))
dbg("copying ctrl.pData to dummyBuf failed"); dbg("copying ctrl.pData to dummyBuf failed");
i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint], 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, ...@@ -348,41 +367,37 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
i); i);
kfree(uBuf); kfree(uBuf);
return -1; return -1;
} else { }
ctrl.numbytes = numbytes; ctrl.numbytes = numbytes;
memcpy(ctrl.pData, uBuf, numbytes); memcpy(ctrl.pData, uBuf, numbytes);
if (copy_to_user if (copy_to_user((struct ioctl_struct *) arg, &ctrl,
((struct ioctl_struct *) arg, &ctrl,
sizeof(struct ioctl_struct))) sizeof(struct ioctl_struct)))
dbg("copy_to_user failed in IORB"); dbg("copy_to_user failed in IORB");
kfree(uBuf); kfree(uBuf);
return ctrl.numbytes; return ctrl.numbytes;
}
break;
case 2: //PIXIS Ping case 2: /* PIXIS Ping */
case 3: //PIXIS Pong /* fall through */
case 3: /* PIXIS Pong */
if (!pdx->gotPixelData) if (!pdx->gotPixelData)
return 0; return 0;
else {
pdx->gotPixelData = 0; pdx->gotPixelData = 0;
ctrl.numbytes = pdx->bulk_in_size_returned; ctrl.numbytes = pdx->bulk_in_size_returned;
pdx->bulk_in_size_returned -= pdx->frameSize; pdx->bulk_in_size_returned -= pdx->frameSize;
for (i = 0; for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
i <
pdx->maplist_numPagesMapped[pdx->
active_frame];
i++)
SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link); SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
pdx->active_frame = pdx->active_frame =
((pdx->active_frame + 1) % pdx->num_frames); ((pdx->active_frame + 1) % pdx->num_frames);
return ctrl.numbytes; return ctrl.numbytes;
}
default:
break; break;
} }
break; break;
case PIUSB_WHATCAMERA: case PIUSB_WHATCAMERA:
return pdx->iama; return pdx->iama;
case PIUSB_SETFRAMESIZE: case PIUSB_SETFRAMESIZE:
dbg("PIUSB_SETFRAMESIZE"); dbg("PIUSB_SETFRAMESIZE");
if (copy_from_user if (copy_from_user
...@@ -410,6 +425,7 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -410,6 +425,7 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
kmalloc(sizeof(char *) * pdx->num_frames, kmalloc(sizeof(char *) * pdx->num_frames,
GFP_KERNEL); GFP_KERNEL);
return 0; return 0;
default: default:
dbg("%s\n", "No IOCTL found"); dbg("%s\n", "No IOCTL found");
break; break;
...@@ -436,7 +452,7 @@ static void piusb_write_bulk_callback(struct urb *urb) ...@@ -436,7 +452,7 @@ static void piusb_write_bulk_callback(struct urb *urb)
urb->transfer_buffer, urb->transfer_dma); urb->transfer_buffer, urb->transfer_dma);
} }
int piusb_output(struct ioctl_struct * io, unsigned char *uBuf, int len, int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
struct device_extension *pdx) struct device_extension *pdx)
{ {
struct urb *urb = NULL; struct urb *urb = NULL;
...@@ -472,6 +488,7 @@ static int UnMapUserBuffer(struct device_extension *pdx) ...@@ -472,6 +488,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
int i = 0; int i = 0;
int k = 0; int k = 0;
unsigned int epAddr; unsigned int epAddr;
for (k = 0; k < pdx->num_frames; k++) { for (k = 0; k < pdx->num_frames; k++) {
dbg("Killing Urbs for Frame %d", k); dbg("Killing Urbs for Frame %d", k);
for (i = 0; i < pdx->sgEntries[k]; i++) { for (i = 0; i < pdx->sgEntries[k]; i++) {
...@@ -485,23 +502,19 @@ static int UnMapUserBuffer(struct device_extension *pdx) ...@@ -485,23 +502,19 @@ static int UnMapUserBuffer(struct device_extension *pdx)
} }
for (k = 0; k < pdx->num_frames; k++) { for (k = 0; k < pdx->num_frames; k++) {
if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to if (pdx->iama == PIXIS_PID)
{ /* which EP should we map this frame to ? */
if (k % 2) //check to see if this should use EP4(PONG) /* PONG, odd frames: hEP[3] */
{ /* PING, even frames and zero hEP[2] */
epAddr = pdx->hEP[3]; //PONG, odd frames epAddr = (k % 2) ? pdx->hEP[3] : pdx->hEP[2];
} else { else
epAddr = pdx->hEP[2]; //PING, even frames and zero /* ST133 only has 1 endpoint for Pixel data transfer */
}
} else //ST133 only has 1 endpoint for Pixel data transfer
{
epAddr = pdx->hEP[0]; epAddr = pdx->hEP[0];
}
usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k], usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k],
pdx->maplist_numPagesMapped[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); page_cache_release(pdx->sgl[k][i].page_link);
}
kfree(pdx->sgl[k]); kfree(pdx->sgl[k]);
kfree(pdx->PixelUrb[k]); kfree(pdx->PixelUrb[k]);
kfree(pdx->pendedPixelUrbs[k]); kfree(pdx->pendedPixelUrbs[k]);
...@@ -509,6 +522,7 @@ static int UnMapUserBuffer(struct device_extension *pdx) ...@@ -509,6 +522,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
pdx->PixelUrb[k] = NULL; pdx->PixelUrb[k] = NULL;
pdx->pendedPixelUrbs[k] = NULL; pdx->pendedPixelUrbs[k] = NULL;
} }
kfree(pdx->sgEntries); kfree(pdx->sgEntries);
vfree(pdx->maplist_numPagesMapped); vfree(pdx->maplist_numPagesMapped);
pdx->sgEntries = NULL; pdx->sgEntries = NULL;
...@@ -519,6 +533,7 @@ static int UnMapUserBuffer(struct device_extension *pdx) ...@@ -519,6 +533,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
pdx->sgl = NULL; pdx->sgl = NULL;
pdx->pendedPixelUrbs = NULL; pdx->pendedPixelUrbs = NULL;
pdx->PixelUrb = NULL; pdx->PixelUrb = NULL;
return 0; return 0;
} }
...@@ -539,16 +554,16 @@ static void piusb_readPIXEL_callback(struct urb *urb) ...@@ -539,16 +554,16 @@ static void piusb_readPIXEL_callback(struct urb *urb)
pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0; pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0;
} else { } else {
pdx->bulk_in_byte_trk += urb->actual_length; 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) { if (i) {
errCnt++; errCnt++;
if (i != lastErr) { 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; lastErr = i;
} }
} else { } 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) { if (pdx->bulk_in_byte_trk >= pdx->frameSize) {
pdx->bulk_in_size_returned = pdx->bulk_in_size_returned =
pdx->bulk_in_byte_trk; pdx->bulk_in_byte_trk;
...@@ -561,29 +576,41 @@ static void piusb_readPIXEL_callback(struct urb *urb) ...@@ -561,29 +576,41 @@ static void piusb_readPIXEL_callback(struct urb *urb)
} }
} }
} }
}
} }
/* MapUserBuffer( /* MapUserBuffer(
inputs: 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 struct device_extension *pdx - the PIUSB device extension
returns: returns:
int - status of the task int - status of the task
Notes: Notes:
MapUserBuffer maps a buffer passed down through an ioctl. The user buffer is Page Aligned by the app MapUserBuffer maps a buffer passed down through an ioctl.
and then passed down. The function get_free_pages(...) does the actual mapping of the buffer from user space to The user buffer is Page Aligned by the app and then passed down.
kernel space. From there a scatterlist is created from all the pages. The next function called is to usb_buffer_map_sg The function get_free_pages(...) does the actual mapping of the buffer
which allocated DMA addresses for each page, even coalescing them if possible. The DMA address is placed in the scatterlist from user space to kernel space.
structure. The function returns the number of DMA addresses. This may or may not be equal to the number of pages that From there a scatterlist is created from all the pages.
the user buffer uses. We then build an URB for each DMA address and then submit them. 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) static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
{ {
unsigned long uaddr; unsigned long uaddr;
unsigned long numbytes; unsigned long numbytes;
int frameInfo; //which frame we're mapping int frameInfo; /* which frame we're mapping */
unsigned int epAddr = 0; unsigned int epAddr = 0;
unsigned long count = 0; unsigned long count = 0;
int i = 0; int i = 0;
...@@ -591,45 +618,45 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -591,45 +618,45 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
int err = 0; int err = 0;
struct page **maplist_p; struct page **maplist_p;
int numPagesRequired; int numPagesRequired;
frameInfo = io->numFrames; frameInfo = io->numFrames;
uaddr = (unsigned long)io->pData; uaddr = (unsigned long)io->pData;
numbytes = io->numbytes; numbytes = io->numbytes;
if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to if (pdx->iama == PIXIS_PID) {
{ /* which EP should we map this frame to ? */
if (frameInfo % 2) //check to see if this should use EP4(PONG) /* PONG, odd frames: hEP[3] */
{ /* PING, even frames and zero hEP[2] */
epAddr = pdx->hEP[3]; //PONG, odd frames epAddr = (frameInfo % 2) ? pdx->hEP[3] : pdx->hEP[2];
} else {
epAddr = pdx->hEP[2]; //PING, even frames and zero
}
dbg("Pixis Frame #%d: EP=%d", frameInfo, dbg("Pixis Frame #%d: EP=%d", frameInfo,
(epAddr == pdx->hEP[2]) ? 2 : 4); (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]; epAddr = pdx->hEP[0];
dbg("ST133 Frame #%d: EP=2", frameInfo); dbg("ST133 Frame #%d: EP=2", frameInfo);
} }
count = numbytes; count = numbytes;
dbg("UserAddress = 0x%08lX", uaddr); dbg("UserAddress = 0x%08lX", uaddr);
dbg("numbytes = %d", (int)numbytes); 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 = numPagesRequired =
((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
dbg("Number of pages needed = %d", numPagesRequired); 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) { if (!maplist_p) {
dbg("Can't Allocate Memory for maplist_p"); dbg("Can't Allocate Memory for maplist_p");
return -ENOMEM; return -ENOMEM;
} }
//map the user buffer to kernel memory
/* map the user buffer to kernel memory */
down_write(&current->mm->mmap_sem); 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 pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current,
maplist_p, current->mm, (uaddr & PAGE_MASK), numPagesRequired,
NULL); WRITE, 0 /* Don't Force*/, maplist_p, NULL);
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
dbg("Number of pages mapped = %d", dbg("Number of pages mapped = %d",
pdx->maplist_numPagesMapped[frameInfo]); pdx->maplist_numPagesMapped[frameInfo]);
for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++) for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++)
flush_dcache_page(maplist_p[i]); flush_dcache_page(maplist_p[i]);
if (!pdx->maplist_numPagesMapped[frameInfo]) { if (!pdx->maplist_numPagesMapped[frameInfo]) {
...@@ -637,7 +664,10 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -637,7 +664,10 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
vfree(maplist_p); vfree(maplist_p);
return -ENOMEM; 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] = pdx->sgl[frameInfo] =
kmalloc((pdx->maplist_numPagesMapped[frameInfo] * kmalloc((pdx->maplist_numPagesMapped[frameInfo] *
sizeof(struct scatterlist)), GFP_ATOMIC); sizeof(struct scatterlist)), GFP_ATOMIC);
...@@ -657,7 +687,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -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].page_link = maplist_p[k];
pdx->sgl[frameInfo][k].length = pdx->sgl[frameInfo][k].length =
(count < PAGE_SIZE) ? count : PAGE_SIZE; (count < PAGE_SIZE) ? count : PAGE_SIZE;
count -= PAGE_SIZE; //example had PAGE_SIZE here; count -= PAGE_SIZE; /* example had PAGE_SIZE here */
} }
} else { } else {
pdx->sgl[frameInfo][0].length = count; pdx->sgl[frameInfo][0].length = count;
...@@ -668,7 +698,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -668,7 +698,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]); dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]);
pdx->userBufMapped = 1; pdx->userBufMapped = 1;
vfree(maplist_p); 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] = pdx->PixelUrb[frameInfo] =
kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *), kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *),
GFP_KERNEL); GFP_KERNEL);
...@@ -677,7 +708,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -677,7 +708,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { 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], usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i],
pdx->udev, pdx->udev,
epAddr, epAddr,
...@@ -691,7 +723,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -691,7 +723,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
pdx->PixelUrb[frameInfo][i]->transfer_flags = pdx->PixelUrb[frameInfo][i]->transfer_flags =
URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; 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] = pdx->pendedPixelUrbs[frameInfo] =
kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL); kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL);
if (!pdx->pendedPixelUrbs[frameInfo]) if (!pdx->pendedPixelUrbs[frameInfo])
...@@ -702,13 +735,13 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) ...@@ -702,13 +735,13 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
dbg("%s %d\n", "submit urb error =", err); dbg("%s %d\n", "submit urb error =", err);
pdx->pendedPixelUrbs[frameInfo][i] = 0; pdx->pendedPixelUrbs[frameInfo][i] = 0;
return err; return err;
} else }
pdx->pendedPixelUrbs[frameInfo][i] = 1;; pdx->pendedPixelUrbs[frameInfo][i] = 1;
} }
return 0; return 0;
} }
static struct file_operations piusb_fops = { static const struct file_operations piusb_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.ioctl = piusb_ioctl, .ioctl = piusb_ioctl,
.open = piusb_open, .open = piusb_open,
...@@ -751,9 +784,9 @@ static int piusb_probe(struct usb_interface *interface, ...@@ -751,9 +784,9 @@ static int piusb_probe(struct usb_interface *interface,
/* See if the device offered us matches what we can accept */ /* See if the device offered us matches what we can accept */
if ((pdx->udev->descriptor.idVendor != VENDOR_ID) if ((pdx->udev->descriptor.idVendor != VENDOR_ID)
|| ((pdx->udev->descriptor.idProduct != PIXIS_PID) || ((pdx->udev->descriptor.idProduct != PIXIS_PID)
&& (pdx->udev->descriptor.idProduct != ST133_PID))) { && (pdx->udev->descriptor.idProduct != ST133_PID)))
return -ENODEV; return -ENODEV;
}
pdx->iama = pdx->udev->descriptor.idProduct; pdx->iama = pdx->udev->descriptor.idProduct;
if (debug) { if (debug) {
...@@ -807,7 +840,7 @@ static int piusb_probe(struct usb_interface *interface, ...@@ -807,7 +840,7 @@ static int piusb_probe(struct usb_interface *interface,
dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor); dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor);
return 0; return 0;
error: error:
if (pdx) if (pdx)
kref_put(&pdx->kref, piusb_delete); kref_put(&pdx->kref, piusb_delete);
return retval; return retval;
...@@ -828,12 +861,17 @@ static void piusb_disconnect(struct usb_interface *interface) ...@@ -828,12 +861,17 @@ static void piusb_disconnect(struct usb_interface *interface)
{ {
struct device_extension *pdx; struct device_extension *pdx;
int minor = interface->minor; int minor = interface->minor;
lock_kernel(); lock_kernel();
pdx = usb_get_intfdata(interface); pdx = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
/* give back our minor */ /* give back our minor */
usb_deregister_dev(interface, &piusb_class); usb_deregister_dev(interface, &piusb_class);
unlock_kernel(); unlock_kernel();
/* prevent device read, write and ioctl */ /* prevent device read, write and ioctl */
pdx->present = 0; pdx->present = 0;
kref_put(&pdx->kref, piusb_delete); kref_put(&pdx->kref, piusb_delete);
...@@ -853,16 +891,20 @@ static struct usb_driver piusb_driver = { ...@@ -853,16 +891,20 @@ static struct usb_driver piusb_driver = {
static int __init piusb_init(void) static int __init piusb_init(void)
{ {
int result; int result;
lastErr = 0;
errCnt = 0;
/* register this driver with the USB subsystem */ /* register this driver with the USB subsystem */
result = usb_register(&piusb_driver); result = usb_register(&piusb_driver);
if (result) { if (result)
printk(KERN_ERR KBUILD_MODNAME printk(KERN_ERR KBUILD_MODNAME
": usb_register failed. Error number %d\n", result); ": usb_register failed. Error number %d\n",
return result; result);
} else
printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC, printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
DRIVER_VERSION); DRIVER_VERSION);
return 0; return result;
} }
/** /**
......
...@@ -3,20 +3,28 @@ ...@@ -3,20 +3,28 @@
#define PIUSB_MAGIC 'm' #define PIUSB_MAGIC 'm'
#define PIUSB_IOCTL_BASE 192 #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_IOR(offset) \
#define PIUSB_WRITEPIPE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 3, struct ioctl_struct) _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
#define PIUSB_READPIPE _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 4, struct ioctl_struct) #define PIUSB_IOW(offset) \
#define PIUSB_SETFRAMESIZE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 5, struct ioctl_struct) _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
#define PIUSB_WHATCAMERA _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 6) #define PIUSB_IO(offset) \
#define PIUSB_USERBUFFER _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 7, struct ioctl_struct) _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset)
#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_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 { struct ioctl_struct {
unsigned char cmd; unsigned char cmd;
unsigned long numbytes; unsigned long numbytes;
unsigned char dir; //1=out;0=in unsigned char dir; /* 1=out; 0=in */
int endpoint; int endpoint;
int numFrames; int numFrames;
unsigned char *pData; unsigned char *pData;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment