forked from Minki/linux
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:
parent
6546f08d21
commit
f2d46e248a
@ -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(¤t->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(¤t->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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user