Staging: rspiusb: clean rspiusb code

This first patch makes checkpatch happier

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Richard Genoud 2009-05-17 13:06:30 +02:00 committed by Greg Kroah-Hartman
parent 6546f08d21
commit f2d46e248a
2 changed files with 241 additions and 191 deletions

View file

@ -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"
@ -63,52 +67,58 @@ static DECLARE_MUTEX(disconnect_sem);
/* Structure to hold all of our device specific stuff */
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 */
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
*/
size_t bulk_in_size_returned;
int bulk_in_byte_trk;
struct urb ***PixelUrb;
int frameIdx;
int urbIdx;
unsigned int *maplist_numPagesMapped;
int open; /* if the port is open or not */
int present; /* if the device is not disconnected */
int userBufMapped; /* has the user buffer been mapped? */
struct scatterlist **sgl; /* scatter-gather list for user buffer */
int open; /* if the port is open or not */
int present; /* if the device is not disconnected */
int userBufMapped; /* has the user buffer been mapped ? */
struct scatterlist **sgl; /* scatter-gather list for user buffer */
unsigned int *sgEntries;
struct kref kref;
int gotPixelData;
int pendingWrite;
char **pendedPixelUrbs;
int iama; /*PIXIS or ST133 */
int num_frames; /* the number of frames that will fit in the user buffer */
int iama; /* PIXIS or ST133 */
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 )
#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 */
static struct usb_device_id pi_device_table[] = {
{USB_DEVICE(VENDOR_ID, ST133_PID)},
{USB_DEVICE(VENDOR_ID, PIXIS_PID)},
{0, } /* Terminating entry */
{0, } /* Terminating entry */
};
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,25 +153,29 @@ 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:
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,
&dummyCtlBuf, ctrl.numbytes, HZ * 10);
/* 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);
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;
return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);
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);
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);
@ -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
{
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
/* ST133 Pixel Data */
if (!pdx->gotPixelData)
return 0;
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;
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,
sizeof(struct ioctl_struct)))
dbg("copy_to_user failed in IORB");
kfree(uBuf);
return ctrl.numbytes;
}
break;
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;
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++)
SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
pdx->active_frame =
((pdx->active_frame + 1) % pdx->num_frames);
return ctrl.numbytes;
}
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;
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;
@ -436,7 +452,7 @@ static void piusb_write_bulk_callback(struct urb *urb)
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 urb *urb = NULL;
@ -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,26 +554,25 @@ 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
if (i) {
errCnt++;
if (i != lastErr) {
dbg("submit urb in callback failed with error code %d", i);
lastErr = i;
}
} else {
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;
pdx->bulk_in_byte_trk = 0;
pdx->gotPixelData = 1;
pdx->frameIdx =
((pdx->frameIdx +
1) % pdx->num_frames);
pdx->urbIdx = 0;
}
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);
lastErr = i;
}
} else {
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;
pdx->bulk_in_byte_trk = 0;
pdx->gotPixelData = 1;
pdx->frameIdx =
((pdx->frameIdx +
1) % pdx->num_frames);
pdx->urbIdx = 0;
}
}
}
@ -566,24 +580,37 @@ 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) {
@ -807,7 +840,7 @@ static int piusb_probe(struct usb_interface *interface,
dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor);
return 0;
error:
error:
if (pdx)
kref_put(&pdx->kref, piusb_delete);
return retval;
@ -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;
}
printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
DRIVER_VERSION);
return 0;
": usb_register failed. Error number %d\n",
result);
else
printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
DRIVER_VERSION);
return result;
}
/**

View file

@ -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;