Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Staging: add princeton instruments usb camera driver

Adds the driver for the Princeton Instruments USB camera.

Needs a lot of work...

TODO:
- make checkpatch.pl clean
- coding style fixups (typedefs, etc.)
- get it to build properly
- audit ioctls
- remove ioctls if possible
- assign proper minor number
- remove dbg() macro
- lots of general cleanups
- review locking

Cc: Judd Montgomery <judd@jpilot.org>
Cc: Jeff Frontz <jeff.frontz@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

+944
+2
drivers/staging/Kconfig
··· 83 83 84 84 source "drivers/staging/rtl8187se/Kconfig" 85 85 86 + source "drivers/staging/rspiusb/Kconfig" 87 + 86 88 endif # !STAGING_EXCLUDE_BUILD 87 89 endif # STAGING
+1
drivers/staging/Makefile
··· 24 24 obj-$(CONFIG_PANEL) += panel/ 25 25 obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ 26 26 obj-$(CONFIG_RTL8187SE) += rtl8187se/ 27 + obj-$(CONFIG_USB_RSPI) += rspiusb/
+6
drivers/staging/rspiusb/Kconfig
··· 1 + config USB_RSPI 2 + tristate "Princeton Instruments USB camera support" 3 + default n 4 + depends on USB && BROKEN 5 + help 6 + This driver is for the Princeton Instruments USB camera device.
+1
drivers/staging/rspiusb/Makefile
··· 1 + obj-$(CONFIG_USB_RSPI) += rspiusb.o
+22
drivers/staging/rspiusb/TODO
··· 1 + This driver is for the Princeton Instruments USB camera. 2 + 3 + It needs lots of work to get it into the main drivers/usb/ subdirectory: 4 + 5 + Any patches to do any of the following changes are greatly appreciated: 6 + 7 + - make checkpatch.pl clean 8 + - coding style fixups (typedefs, etc.) 9 + - get it to build properly 10 + - audit ioctls 11 + - remove ioctls if possible 12 + - assign proper minor number 13 + - remove dbg() macro 14 + - lots of general cleanups 15 + - review locking 16 + 17 + Please send patches to: 18 + Greg Kroah-Hartman <gregkh@suse.de> 19 + and CC: 20 + Judd Montgomery <judd@jpilot.org> 21 + Jeff Frontz <jeff.frontz@gmail.com> 22 + as they have this device and can test any needed changes.
+887
drivers/staging/rspiusb/rspiusb.c
··· 1 + /* 2 + * rspiusb.c 3 + * 4 + * Copyright (C) 2005, 2006 Princeton Instruments 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation version 2 of the License 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/vmalloc.h> 21 + #include <linux/kernel.h> 22 + #include <linux/errno.h> 23 + #include <linux/init.h> 24 + #include <linux/slab.h> 25 + #include <linux/module.h> 26 + #include <linux/smp_lock.h> 27 + #include <linux/completion.h> 28 + #include <linux/scatterlist.h> 29 + #include <linux/usb.h> 30 + #include <linux/mm.h> 31 + #include <linux/pagemap.h> 32 + #include <linux/ioctl.h> 33 + #include "rspiusb.h" 34 + 35 + #ifdef CONFIG_USB_DEBUG 36 + static int debug = 1; 37 + #else 38 + static int debug; 39 + #endif 40 + /* Use our own dbg macro */ 41 + #undef dbg 42 + #define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) 43 + 44 + /* Version Information */ 45 + #define DRIVER_VERSION "V1.0.1" 46 + #define DRIVER_AUTHOR "Princeton Instruments" 47 + #define DRIVER_DESC "PI USB2.0 Device Driver for Linux" 48 + 49 + /* Define these values to match your devices */ 50 + #define VENDOR_ID 0x0BD7 51 + #define ST133_PID 0xA010 52 + #define PIXIS_PID 0xA026 53 + 54 + /* Get a minor range for your devices from the usb maintainer */ 55 + #ifdef CONFIG_USB_DYNAMIC_MINORS 56 + #define PIUSB_MINOR_BASE 0 57 + #else 58 + #define PIUSB_MINOR_BASE 192 59 + #endif 60 + 61 + /* prevent races between open() and disconnect() */ 62 + static DECLARE_MUTEX(disconnect_sem); 63 + 64 + /* Structure to hold all of our device specific stuff */ 65 + struct device_extension { 66 + struct usb_device *udev; /* save off the usb device pointer */ 67 + struct usb_interface *interface; /* the interface for this device */ 68 + unsigned char minor; /* the starting minor number for this device */ 69 + size_t bulk_in_size_returned; 70 + int bulk_in_byte_trk; 71 + struct urb ***PixelUrb; 72 + int frameIdx; 73 + int urbIdx; 74 + unsigned int *maplist_numPagesMapped; 75 + int open; /* if the port is open or not */ 76 + int present; /* if the device is not disconnected */ 77 + int userBufMapped; /* has the user buffer been mapped? */ 78 + struct scatterlist **sgl; /* scatter-gather list for user buffer */ 79 + unsigned int *sgEntries; 80 + struct kref kref; 81 + int gotPixelData; 82 + int pendingWrite; 83 + char **pendedPixelUrbs; 84 + int iama; /*PIXIS or ST133 */ 85 + int num_frames; /* the number of frames that will fit in the user buffer */ 86 + int active_frame; 87 + unsigned long frameSize; 88 + struct semaphore sem; 89 + //FX2 specific endpoints 90 + unsigned int hEP[8]; 91 + }; 92 + #define to_pi_dev(d) container_of( d, struct device_extension, kref ) 93 + 94 + static int MapUserBuffer(struct ioctl_struct *, struct device_extension *); 95 + static int UnMapUserBuffer(struct device_extension *); 96 + static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 97 + unsigned long arg); 98 + static int piusb_output(struct ioctl_struct *, unsigned char *, int, struct device_extension *); 99 + static struct usb_driver piusb_driver; 100 + 101 + /* table of devices that work with this driver */ 102 + static struct usb_device_id pi_device_table[] = { 103 + {USB_DEVICE(VENDOR_ID, ST133_PID)}, 104 + {USB_DEVICE(VENDOR_ID, PIXIS_PID)}, 105 + {0, } /* Terminating entry */ 106 + }; 107 + 108 + MODULE_DEVICE_TABLE(usb, pi_device_table); 109 + 110 + static int lastErr = 0; 111 + static int errCnt = 0; 112 + 113 + static void piusb_delete(struct kref *kref) 114 + { 115 + struct device_extension *pdx = to_pi_dev(kref); 116 + 117 + dev_dbg(&pdx->udev->dev, "%s\n", __func__); 118 + usb_put_dev(pdx->udev); 119 + kfree(pdx); 120 + } 121 + 122 + static int piusb_open(struct inode *inode, struct file *file) 123 + { 124 + struct device_extension *pdx = NULL; 125 + struct usb_interface *interface; 126 + int subminor; 127 + int retval = 0; 128 + 129 + dbg("Piusb_Open()"); 130 + subminor = iminor(inode); 131 + interface = usb_find_interface(&piusb_driver, subminor); 132 + if (!interface) { 133 + printk(KERN_ERR "%s - error, can't find device for minor %d\n", 134 + __func__, subminor); 135 + retval = -ENODEV; 136 + goto exit_no_device; 137 + } 138 + 139 + pdx = usb_get_intfdata(interface); 140 + if (!pdx) { 141 + retval = -ENODEV; 142 + goto exit_no_device; 143 + } 144 + dbg("Alternate Setting = %d", interface->num_altsetting); 145 + 146 + pdx->frameIdx = pdx->urbIdx = 0; 147 + pdx->gotPixelData = 0; 148 + pdx->pendingWrite = 0; 149 + pdx->frameSize = 0; 150 + pdx->num_frames = 0; 151 + pdx->active_frame = 0; 152 + pdx->bulk_in_byte_trk = 0; 153 + pdx->userBufMapped = 0; 154 + pdx->pendedPixelUrbs = NULL; 155 + pdx->sgEntries = NULL; 156 + pdx->sgl = NULL; 157 + pdx->maplist_numPagesMapped = NULL; 158 + pdx->PixelUrb = NULL; 159 + pdx->bulk_in_size_returned = 0; 160 + /* increment our usage count for the device */ 161 + kref_get(&pdx->kref); 162 + /* save our object in the file's private structure */ 163 + file->private_data = pdx; 164 + exit_no_device: 165 + return retval; 166 + } 167 + 168 + static int piusb_release(struct inode *inode, struct file *file) 169 + { 170 + struct device_extension *pdx; 171 + int retval = 0; 172 + 173 + dbg("Piusb_Release()"); 174 + pdx = (struct device_extension *)file->private_data; 175 + if (pdx == NULL) { 176 + dbg("%s - object is NULL", __func__); 177 + return -ENODEV; 178 + } 179 + /* decrement the count on our device */ 180 + kref_put(&pdx->kref, piusb_delete); 181 + return retval; 182 + } 183 + 184 + /** 185 + * piusb_ioctl 186 + */ 187 + static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 188 + unsigned long arg) 189 + { 190 + struct device_extension *pdx; 191 + char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 192 + unsigned long devRB = 0; 193 + int i = 0; 194 + int err = 0; 195 + int retval = 0; 196 + struct ioctl_struct ctrl; 197 + unsigned char *uBuf; 198 + int numbytes = 0; 199 + unsigned short controlData = 0; 200 + 201 + pdx = (struct device_extension *)file->private_data; 202 + /* verify that the device wasn't unplugged */ 203 + if (!pdx->present) { 204 + dbg("No Device Present\n"); 205 + return -ENODEV; 206 + } 207 + /* fill in your device specific stuff here */ 208 + if (_IOC_DIR(cmd) & _IOC_READ) 209 + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); 210 + else if (_IOC_DIR(cmd) & _IOC_WRITE) 211 + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); 212 + if (err) { 213 + dev_err(&pdx->udev->dev, "return with error = %d\n", err); 214 + return -EFAULT; 215 + } 216 + switch (cmd) { 217 + case PIUSB_GETVNDCMD: 218 + if (copy_from_user 219 + (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 220 + info("copy_from_user failed\n"); 221 + dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd); 222 + retval = 223 + usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), 224 + ctrl.cmd, USB_DIR_IN, 0, 0, &devRB, 225 + ctrl.numbytes, HZ * 10); 226 + if (ctrl.cmd == 0xF1) { 227 + dbg("FW Version returned from HW = %ld.%ld", 228 + (devRB >> 8), (devRB & 0xFF)); 229 + } 230 + return devRB; 231 + case PIUSB_SETVNDCMD: 232 + if (copy_from_user 233 + (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 234 + info("copy_from_user failed\n"); 235 + // dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); 236 + controlData = ctrl.pData[0]; 237 + controlData |= (ctrl.pData[1] << 8); 238 + // dbg( "%s %d", "Vendor Data =",controlData ); 239 + retval = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), ctrl.cmd, (USB_DIR_OUT | USB_TYPE_VENDOR), /* | USB_RECIP_ENDPOINT), */ 240 + controlData, 241 + 0, 242 + &dummyCtlBuf, ctrl.numbytes, HZ * 10); 243 + return retval; 244 + break; 245 + case PIUSB_ISHIGHSPEED: 246 + return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0); 247 + break; 248 + case PIUSB_WRITEPIPE: 249 + if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) 250 + info("copy_from_user WRITE_DUMMY failed\n"); 251 + if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) { 252 + dbg("can't access pData"); 253 + return 0; 254 + } 255 + piusb_output(&ctrl, ctrl.pData /*uBuf */ , ctrl.numbytes, pdx); 256 + return ctrl.numbytes; 257 + break; 258 + case PIUSB_USERBUFFER: 259 + if (copy_from_user 260 + (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 261 + info("copy_from_user failed\n"); 262 + return MapUserBuffer((struct ioctl_struct *) & ctrl, pdx); 263 + break; 264 + case PIUSB_UNMAP_USERBUFFER: 265 + UnMapUserBuffer(pdx); 266 + return 0; 267 + break; 268 + case PIUSB_READPIPE: 269 + if (copy_from_user 270 + (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 271 + info("copy_from_user failed\n"); 272 + switch (ctrl.endpoint) { 273 + case 0: //ST133 Pixel Data or PIXIS IO 274 + if (pdx->iama == PIXIS_PID) { 275 + unsigned int numToRead = 0; 276 + unsigned int totalRead = 0; 277 + uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL); 278 + if (!uBuf) { 279 + dbg("Alloc for uBuf failed"); 280 + return 0; 281 + } 282 + numbytes = ctrl.numbytes; 283 + numToRead = numbytes; 284 + dbg("numbytes to read = %d", numbytes); 285 + dbg("endpoint # %d", ctrl.endpoint); 286 + if (copy_from_user(uBuf, ctrl.pData, numbytes)) 287 + dbg("copying ctrl.pData to dummyBuf failed"); 288 + do { 289 + 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 290 + if (i) { 291 + dbg("CMD = %s, Address = 0x%02X", ((uBuf[3] == 0x02) ? "WRITE" : "READ"), uBuf[1]); 292 + dbg("Number of bytes Attempted to read = %d", (int)ctrl.numbytes); 293 + dbg("Blocking ReadI/O Failed with status %d", i); 294 + kfree(uBuf); 295 + return -1; 296 + } else { 297 + dbg("Pixis EP0 Read %d bytes", 298 + numbytes); 299 + totalRead += numbytes; 300 + numToRead -= numbytes; 301 + } 302 + } 303 + while (numToRead); 304 + memcpy(ctrl.pData, uBuf, totalRead); 305 + dbg("Total Bytes Read from PIXIS EP0 = %d", 306 + totalRead); 307 + ctrl.numbytes = totalRead; 308 + if (copy_to_user 309 + ((struct ioctl_struct *) arg, &ctrl, 310 + sizeof(struct ioctl_struct))) 311 + dbg("copy_to_user failed in IORB"); 312 + kfree(uBuf); 313 + return ctrl.numbytes; 314 + } else //ST133 Pixel Data 315 + { 316 + if (!pdx->gotPixelData) 317 + return 0; 318 + else { 319 + pdx->gotPixelData = 0; 320 + ctrl.numbytes = 321 + pdx->bulk_in_size_returned; 322 + pdx->bulk_in_size_returned -= 323 + pdx->frameSize; 324 + for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++) 325 + SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link); 326 + pdx->active_frame = 327 + ((pdx->active_frame + 328 + 1) % pdx->num_frames); 329 + return ctrl.numbytes; 330 + } 331 + } 332 + break; 333 + case 1: //ST133IO 334 + case 4: //PIXIS IO 335 + uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL); 336 + if (!uBuf) { 337 + dbg("Alloc for uBuf failed"); 338 + return 0; 339 + } 340 + numbytes = ctrl.numbytes; 341 + // dbg( "numbytes to read = %d", numbytes ); 342 + if (copy_from_user(uBuf, ctrl.pData, numbytes)) 343 + dbg("copying ctrl.pData to dummyBuf failed"); 344 + i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint], 345 + uBuf, numbytes, &numbytes, HZ * 10); 346 + if (i) { 347 + dbg("Blocking ReadI/O Failed with status %d", 348 + i); 349 + kfree(uBuf); 350 + return -1; 351 + } else { 352 + ctrl.numbytes = numbytes; 353 + memcpy(ctrl.pData, uBuf, numbytes); 354 + if (copy_to_user 355 + ((struct ioctl_struct *) arg, &ctrl, 356 + sizeof(struct ioctl_struct))) 357 + dbg("copy_to_user failed in IORB"); 358 + kfree(uBuf); 359 + return ctrl.numbytes; 360 + } 361 + break; 362 + 363 + case 2: //PIXIS Ping 364 + case 3: //PIXIS Pong 365 + if (!pdx->gotPixelData) 366 + return 0; 367 + else { 368 + pdx->gotPixelData = 0; 369 + ctrl.numbytes = pdx->bulk_in_size_returned; 370 + pdx->bulk_in_size_returned -= pdx->frameSize; 371 + for (i = 0; 372 + i < 373 + pdx->maplist_numPagesMapped[pdx-> 374 + active_frame]; 375 + i++) 376 + SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link); 377 + pdx->active_frame = 378 + ((pdx->active_frame + 1) % pdx->num_frames); 379 + return ctrl.numbytes; 380 + } 381 + break; 382 + } 383 + break; 384 + case PIUSB_WHATCAMERA: 385 + return pdx->iama; 386 + case PIUSB_SETFRAMESIZE: 387 + dbg("PIUSB_SETFRAMESIZE"); 388 + if (copy_from_user 389 + (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 390 + info("copy_from_user failed\n"); 391 + pdx->frameSize = ctrl.numbytes; 392 + pdx->num_frames = ctrl.numFrames; 393 + if (!pdx->sgl) 394 + pdx->sgl = 395 + kmalloc(sizeof(struct scatterlist *) * 396 + pdx->num_frames, GFP_KERNEL); 397 + if (!pdx->sgEntries) 398 + pdx->sgEntries = 399 + kmalloc(sizeof(unsigned int) * pdx->num_frames, 400 + GFP_KERNEL); 401 + if (!pdx->PixelUrb) 402 + pdx->PixelUrb = 403 + kmalloc(sizeof(struct urb **) * pdx->num_frames, 404 + GFP_KERNEL); 405 + if (!pdx->maplist_numPagesMapped) 406 + pdx->maplist_numPagesMapped = 407 + vmalloc(sizeof(unsigned int) * pdx->num_frames); 408 + if (!pdx->pendedPixelUrbs) 409 + pdx->pendedPixelUrbs = 410 + kmalloc(sizeof(char *) * pdx->num_frames, 411 + GFP_KERNEL); 412 + return 0; 413 + default: 414 + dbg("%s\n", "No IOCTL found"); 415 + break; 416 + 417 + } 418 + /* return that we did not understand this ioctl call */ 419 + dbg("Returning -ENOTTY"); 420 + return -ENOTTY; 421 + } 422 + 423 + static void piusb_write_bulk_callback(struct urb *urb) 424 + { 425 + struct device_extension *pdx = urb->context; 426 + int status = urb->status; 427 + 428 + /* sync/async unlink faults aren't errors */ 429 + if (status && !(status == -ENOENT || status == -ECONNRESET)) 430 + dev_dbg(&urb->dev->dev, 431 + "%s - nonzero write bulk status received: %d", 432 + __func__, status); 433 + 434 + pdx->pendingWrite = 0; 435 + usb_buffer_free(urb->dev, urb->transfer_buffer_length, 436 + urb->transfer_buffer, urb->transfer_dma); 437 + } 438 + 439 + int piusb_output(struct ioctl_struct * io, unsigned char *uBuf, int len, 440 + struct device_extension *pdx) 441 + { 442 + struct urb *urb = NULL; 443 + int err = 0; 444 + unsigned char *kbuf = NULL; 445 + 446 + urb = usb_alloc_urb(0, GFP_KERNEL); 447 + if (urb != NULL) { 448 + kbuf = 449 + usb_buffer_alloc(pdx->udev, len, GFP_KERNEL, 450 + &urb->transfer_dma); 451 + if (!kbuf) { 452 + info("buffer_alloc failed\n"); 453 + return -ENOMEM; 454 + } 455 + memcpy(kbuf, uBuf, len); 456 + usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, 457 + len, piusb_write_bulk_callback, pdx); 458 + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 459 + err = usb_submit_urb(urb, GFP_KERNEL); 460 + if (err) { 461 + dev_err(&pdx->udev->dev, 462 + "WRITE ERROR:submit urb error = %d\n", err); 463 + } 464 + pdx->pendingWrite = 1; 465 + usb_free_urb(urb); 466 + } 467 + return -EINPROGRESS; 468 + } 469 + 470 + static int UnMapUserBuffer(struct device_extension *pdx) 471 + { 472 + int i = 0; 473 + int k = 0; 474 + unsigned int epAddr; 475 + for (k = 0; k < pdx->num_frames; k++) { 476 + dbg("Killing Urbs for Frame %d", k); 477 + for (i = 0; i < pdx->sgEntries[k]; i++) { 478 + usb_kill_urb(pdx->PixelUrb[k][i]); 479 + usb_free_urb(pdx->PixelUrb[k][i]); 480 + pdx->pendedPixelUrbs[k][i] = 0; 481 + } 482 + dbg("Urb error count = %d", errCnt); 483 + errCnt = 0; 484 + dbg("Urbs free'd and Killed for Frame %d", k); 485 + } 486 + 487 + for (k = 0; k < pdx->num_frames; k++) { 488 + if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to 489 + { 490 + if (k % 2) //check to see if this should use EP4(PONG) 491 + { 492 + epAddr = pdx->hEP[3]; //PONG, odd frames 493 + } else { 494 + epAddr = pdx->hEP[2]; //PING, even frames and zero 495 + } 496 + } else //ST133 only has 1 endpoint for Pixel data transfer 497 + { 498 + epAddr = pdx->hEP[0]; 499 + } 500 + usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k], 501 + pdx->maplist_numPagesMapped[k]); 502 + for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++) { 503 + page_cache_release(pdx->sgl[k][i].page_link); 504 + } 505 + kfree(pdx->sgl[k]); 506 + kfree(pdx->PixelUrb[k]); 507 + kfree(pdx->pendedPixelUrbs[k]); 508 + pdx->sgl[k] = NULL; 509 + pdx->PixelUrb[k] = NULL; 510 + pdx->pendedPixelUrbs[k] = NULL; 511 + } 512 + kfree(pdx->sgEntries); 513 + vfree(pdx->maplist_numPagesMapped); 514 + pdx->sgEntries = NULL; 515 + pdx->maplist_numPagesMapped = NULL; 516 + kfree(pdx->sgl); 517 + kfree(pdx->pendedPixelUrbs); 518 + kfree(pdx->PixelUrb); 519 + pdx->sgl = NULL; 520 + pdx->pendedPixelUrbs = NULL; 521 + pdx->PixelUrb = NULL; 522 + return 0; 523 + } 524 + 525 + static void piusb_readPIXEL_callback(struct urb *urb) 526 + { 527 + int i = 0; 528 + struct device_extension *pdx = urb->context; 529 + int status = urb->status; 530 + 531 + if (status && !(status == -ENOENT || status == -ECONNRESET)) { 532 + dbg("%s - nonzero read bulk status received: %d", __func__, 533 + status); 534 + dbg("Error in read EP2 callback"); 535 + dbg("FrameIndex = %d", pdx->frameIdx); 536 + dbg("Bytes received before problem occurred = %d", 537 + pdx->bulk_in_byte_trk); 538 + dbg("Urb Idx = %d", pdx->urbIdx); 539 + pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0; 540 + } else { 541 + pdx->bulk_in_byte_trk += urb->actual_length; 542 + { 543 + i = usb_submit_urb(urb, GFP_ATOMIC); //resubmit the URB 544 + if (i) { 545 + errCnt++; 546 + if (i != lastErr) { 547 + dbg("submit urb in callback failed with error code %d", i); 548 + lastErr = i; 549 + } 550 + } else { 551 + pdx->urbIdx++; //point to next URB when we callback 552 + if (pdx->bulk_in_byte_trk >= pdx->frameSize) { 553 + pdx->bulk_in_size_returned = 554 + pdx->bulk_in_byte_trk; 555 + pdx->bulk_in_byte_trk = 0; 556 + pdx->gotPixelData = 1; 557 + pdx->frameIdx = 558 + ((pdx->frameIdx + 559 + 1) % pdx->num_frames); 560 + pdx->urbIdx = 0; 561 + } 562 + } 563 + } 564 + } 565 + } 566 + 567 + /* MapUserBuffer( 568 + inputs: 569 + struct ioctl_struct *io - structure containing user address, frame #, and size 570 + struct device_extension *pdx - the PIUSB device extension 571 + returns: 572 + int - status of the task 573 + Notes: 574 + MapUserBuffer maps a buffer passed down through an ioctl. The user buffer is Page Aligned by the app 575 + and then passed down. The function get_free_pages(...) does the actual mapping of the buffer from user space to 576 + kernel space. From there a scatterlist is created from all the pages. The next function called is to usb_buffer_map_sg 577 + which allocated DMA addresses for each page, even coalescing them if possible. The DMA address is placed in the scatterlist 578 + structure. The function returns the number of DMA addresses. This may or may not be equal to the number of pages that 579 + the user buffer uses. We then build an URB for each DMA address and then submit them. 580 + */ 581 + //int MapUserBuffer( unsigned long uaddr, unsigned long numbytes, unsigned long frameInfo, struct device_extension *pdx ) 582 + static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) 583 + { 584 + unsigned long uaddr; 585 + unsigned long numbytes; 586 + int frameInfo; //which frame we're mapping 587 + unsigned int epAddr = 0; 588 + unsigned long count = 0; 589 + int i = 0; 590 + int k = 0; 591 + int err = 0; 592 + struct page **maplist_p; 593 + int numPagesRequired; 594 + frameInfo = io->numFrames; 595 + uaddr = (unsigned long)io->pData; 596 + numbytes = io->numbytes; 597 + 598 + if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to 599 + { 600 + if (frameInfo % 2) //check to see if this should use EP4(PONG) 601 + { 602 + epAddr = pdx->hEP[3]; //PONG, odd frames 603 + } else { 604 + epAddr = pdx->hEP[2]; //PING, even frames and zero 605 + } 606 + dbg("Pixis Frame #%d: EP=%d", frameInfo, 607 + (epAddr == pdx->hEP[2]) ? 2 : 4); 608 + } else //ST133 only has 1 endpoint for Pixel data transfer 609 + { 610 + epAddr = pdx->hEP[0]; 611 + dbg("ST133 Frame #%d: EP=2", frameInfo); 612 + } 613 + count = numbytes; 614 + dbg("UserAddress = 0x%08lX", uaddr); 615 + dbg("numbytes = %d", (int)numbytes); 616 + //number of pages to map the entire user space DMA buffer 617 + numPagesRequired = 618 + ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; 619 + dbg("Number of pages needed = %d", numPagesRequired); 620 + maplist_p = vmalloc(numPagesRequired * sizeof(struct page)); //, GFP_ATOMIC); 621 + if (!maplist_p) { 622 + dbg("Can't Allocate Memory for maplist_p"); 623 + return -ENOMEM; 624 + } 625 + //map the user buffer to kernel memory 626 + down_write(&current->mm->mmap_sem); 627 + pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current, current->mm, (uaddr & PAGE_MASK), numPagesRequired, WRITE, 0, //Don't Force 628 + maplist_p, 629 + NULL); 630 + up_write(&current->mm->mmap_sem); 631 + dbg("Number of pages mapped = %d", 632 + pdx->maplist_numPagesMapped[frameInfo]); 633 + for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++) 634 + flush_dcache_page(maplist_p[i]); 635 + if (!pdx->maplist_numPagesMapped[frameInfo]) { 636 + dbg("get_user_pages() failed"); 637 + vfree(maplist_p); 638 + return -ENOMEM; 639 + } 640 + //need to create a scatterlist that spans each frame that can fit into the mapped buffer 641 + pdx->sgl[frameInfo] = 642 + kmalloc((pdx->maplist_numPagesMapped[frameInfo] * 643 + sizeof(struct scatterlist)), GFP_ATOMIC); 644 + if (!pdx->sgl[frameInfo]) { 645 + vfree(maplist_p); 646 + dbg("can't allocate mem for sgl"); 647 + return -ENOMEM; 648 + } 649 + pdx->sgl[frameInfo][0].page_link = maplist_p[0]; 650 + pdx->sgl[frameInfo][0].offset = uaddr & ~PAGE_MASK; 651 + if (pdx->maplist_numPagesMapped[frameInfo] > 1) { 652 + pdx->sgl[frameInfo][0].length = 653 + PAGE_SIZE - pdx->sgl[frameInfo][0].offset; 654 + count -= pdx->sgl[frameInfo][0].length; 655 + for (k = 1; k < pdx->maplist_numPagesMapped[frameInfo]; k++) { 656 + pdx->sgl[frameInfo][k].offset = 0; 657 + pdx->sgl[frameInfo][k].page_link = maplist_p[k]; 658 + pdx->sgl[frameInfo][k].length = 659 + (count < PAGE_SIZE) ? count : PAGE_SIZE; 660 + count -= PAGE_SIZE; //example had PAGE_SIZE here; 661 + } 662 + } else { 663 + pdx->sgl[frameInfo][0].length = count; 664 + } 665 + pdx->sgEntries[frameInfo] = 666 + usb_buffer_map_sg(pdx->udev, epAddr, pdx->sgl[frameInfo], 667 + pdx->maplist_numPagesMapped[frameInfo]); 668 + dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]); 669 + pdx->userBufMapped = 1; 670 + vfree(maplist_p); 671 + //Create and Send the URB's for each s/g entry 672 + pdx->PixelUrb[frameInfo] = 673 + kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *), 674 + GFP_KERNEL); 675 + if (!pdx->PixelUrb[frameInfo]) { 676 + dbg("Can't Allocate Memory for Urb"); 677 + return -ENOMEM; 678 + } 679 + for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { 680 + pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL); //0 because we're using BULK transfers 681 + usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], 682 + pdx->udev, 683 + epAddr, 684 + (dma_addr_t *) sg_dma_address(&pdx-> 685 + sgl[frameInfo] 686 + [i]), 687 + sg_dma_len(&pdx->sgl[frameInfo][i]), 688 + piusb_readPIXEL_callback, (void *)pdx); 689 + pdx->PixelUrb[frameInfo][i]->transfer_dma = 690 + sg_dma_address(&pdx->sgl[frameInfo][i]); 691 + pdx->PixelUrb[frameInfo][i]->transfer_flags = 692 + URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; 693 + } 694 + pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT; //only interrupt when last URB completes 695 + pdx->pendedPixelUrbs[frameInfo] = 696 + kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL); 697 + if (!pdx->pendedPixelUrbs[frameInfo]) 698 + dbg("Can't allocate Memory for pendedPixelUrbs"); 699 + for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { 700 + err = usb_submit_urb(pdx->PixelUrb[frameInfo][i], GFP_ATOMIC); 701 + if (err) { 702 + dbg("%s %d\n", "submit urb error =", err); 703 + pdx->pendedPixelUrbs[frameInfo][i] = 0; 704 + return err; 705 + } else 706 + pdx->pendedPixelUrbs[frameInfo][i] = 1;; 707 + } 708 + return 0; 709 + } 710 + 711 + static struct file_operations piusb_fops = { 712 + .owner = THIS_MODULE, 713 + .ioctl = piusb_ioctl, 714 + .open = piusb_open, 715 + .release = piusb_release, 716 + }; 717 + 718 + static struct usb_class_driver piusb_class = { 719 + .name = "usb/rspiusb%d", 720 + .fops = &piusb_fops, 721 + .minor_base = PIUSB_MINOR_BASE, 722 + }; 723 + 724 + /** 725 + * piusb_probe 726 + * 727 + * Called by the usb core when a new device is connected that it thinks 728 + * this driver might be interested in. 729 + */ 730 + static int piusb_probe(struct usb_interface *interface, 731 + const struct usb_device_id *id) 732 + { 733 + struct device_extension *pdx = NULL; 734 + struct usb_host_interface *iface_desc; 735 + struct usb_endpoint_descriptor *endpoint; 736 + int i; 737 + int retval = -ENOMEM; 738 + 739 + dev_dbg(&interface->dev, "%s - Looking for PI USB Hardware", __func__); 740 + 741 + pdx = kzalloc(sizeof(struct device_extension), GFP_KERNEL); 742 + if (pdx == NULL) { 743 + dev_err(&interface->dev, "Out of memory\n"); 744 + goto error; 745 + } 746 + kref_init(&pdx->kref); 747 + pdx->udev = usb_get_dev(interface_to_usbdev(interface)); 748 + pdx->interface = interface; 749 + iface_desc = interface->cur_altsetting; 750 + 751 + /* See if the device offered us matches what we can accept */ 752 + if ((pdx->udev->descriptor.idVendor != VENDOR_ID) 753 + || ((pdx->udev->descriptor.idProduct != PIXIS_PID) 754 + && (pdx->udev->descriptor.idProduct != ST133_PID))) { 755 + return -ENODEV; 756 + } 757 + pdx->iama = pdx->udev->descriptor.idProduct; 758 + 759 + if (debug) { 760 + if (pdx->udev->descriptor.idProduct == PIXIS_PID) 761 + dbg("PIUSB:Pixis Camera Found"); 762 + else 763 + dbg("PIUSB:ST133 USB Controller Found"); 764 + if (pdx->udev->speed == USB_SPEED_HIGH) 765 + dbg("Highspeed(USB2.0) Device Attached"); 766 + else 767 + dbg("Lowspeed (USB1.1) Device Attached"); 768 + 769 + dbg("NumEndpoints in Configuration: %d", 770 + iface_desc->desc.bNumEndpoints); 771 + } 772 + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 773 + endpoint = &iface_desc->endpoint[i].desc; 774 + if (debug) { 775 + dbg("Endpoint[%d]->bDescriptorType = %d", i, 776 + endpoint->bDescriptorType); 777 + dbg("Endpoint[%d]->bEndpointAddress = 0x%02X", i, 778 + endpoint->bEndpointAddress); 779 + dbg("Endpoint[%d]->bbmAttributes = %d", i, 780 + endpoint->bmAttributes); 781 + dbg("Endpoint[%d]->MaxPacketSize = %d\n", i, 782 + endpoint->wMaxPacketSize); 783 + } 784 + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 785 + USB_ENDPOINT_XFER_BULK) { 786 + if (endpoint->bEndpointAddress & USB_DIR_IN) 787 + pdx->hEP[i] = 788 + usb_rcvbulkpipe(pdx->udev, 789 + endpoint->bEndpointAddress); 790 + else 791 + pdx->hEP[i] = 792 + usb_sndbulkpipe(pdx->udev, 793 + endpoint->bEndpointAddress); 794 + } 795 + } 796 + usb_set_intfdata(interface, pdx); 797 + retval = usb_register_dev(interface, &piusb_class); 798 + if (retval) { 799 + err("Not able to get a minor for this device."); 800 + usb_set_intfdata(interface, NULL); 801 + goto error; 802 + } 803 + pdx->present = 1; 804 + 805 + /* we can register the device now, as it is ready */ 806 + pdx->minor = interface->minor; 807 + /* let the user know what node this device is now attached to */ 808 + dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor); 809 + return 0; 810 + 811 + error: 812 + if (pdx) 813 + kref_put(&pdx->kref, piusb_delete); 814 + return retval; 815 + } 816 + 817 + /** 818 + * piusb_disconnect 819 + * 820 + * Called by the usb core when the device is removed from the system. 821 + * 822 + * This routine guarantees that the driver will not submit any more urbs 823 + * by clearing pdx->udev. It is also supposed to terminate any currently 824 + * active urbs. Unfortunately, usb_bulk_msg(), used in piusb_read(), does 825 + * not provide any way to do this. But at least we can cancel an active 826 + * write. 827 + */ 828 + static void piusb_disconnect(struct usb_interface *interface) 829 + { 830 + struct device_extension *pdx; 831 + int minor = interface->minor; 832 + lock_kernel(); 833 + pdx = usb_get_intfdata(interface); 834 + usb_set_intfdata(interface, NULL); 835 + /* give back our minor */ 836 + usb_deregister_dev(interface, &piusb_class); 837 + unlock_kernel(); 838 + /* prevent device read, write and ioctl */ 839 + pdx->present = 0; 840 + kref_put(&pdx->kref, piusb_delete); 841 + dbg("PI USB2.0 device #%d now disconnected\n", minor); 842 + } 843 + 844 + static struct usb_driver piusb_driver = { 845 + .name = "sub", 846 + .probe = piusb_probe, 847 + .disconnect = piusb_disconnect, 848 + .id_table = pi_device_table, 849 + }; 850 + 851 + /** 852 + * piusb_init 853 + */ 854 + static int __init piusb_init(void) 855 + { 856 + int result; 857 + /* register this driver with the USB subsystem */ 858 + result = usb_register(&piusb_driver); 859 + if (result) { 860 + printk(KERN_ERR KBUILD_MODNAME 861 + ": usb_register failed. Error number %d\n", result); 862 + return result; 863 + } 864 + printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC, 865 + DRIVER_VERSION); 866 + return 0; 867 + } 868 + 869 + /** 870 + * piusb_exit 871 + */ 872 + static void __exit piusb_exit(void) 873 + { 874 + /* deregister this driver with the USB subsystem */ 875 + usb_deregister(&piusb_driver); 876 + } 877 + 878 + module_init(piusb_init); 879 + module_exit(piusb_exit); 880 + 881 + /* Module parameters */ 882 + module_param(debug, int, 0); 883 + MODULE_PARM_DESC(debug, "Debug enabled or not"); 884 + 885 + MODULE_AUTHOR(DRIVER_AUTHOR); 886 + MODULE_DESCRIPTION(DRIVER_DESC); 887 + MODULE_LICENSE("GPL v2");
+25
drivers/staging/rspiusb/rspiusb.h
··· 1 + #ifndef __RSPIUSB_H 2 + #define __RSPIUSB_H 3 + 4 + #define PIUSB_MAGIC 'm' 5 + #define PIUSB_IOCTL_BASE 192 6 + #define PIUSB_GETVNDCMD _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 1, struct ioctl_struct) 7 + #define PIUSB_SETVNDCMD _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 2, struct ioctl_struct) 8 + #define PIUSB_WRITEPIPE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 3, struct ioctl_struct) 9 + #define PIUSB_READPIPE _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 4, struct ioctl_struct) 10 + #define PIUSB_SETFRAMESIZE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 5, struct ioctl_struct) 11 + #define PIUSB_WHATCAMERA _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 6) 12 + #define PIUSB_USERBUFFER _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 7, struct ioctl_struct) 13 + #define PIUSB_ISHIGHSPEED _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 8) 14 + #define PIUSB_UNMAP_USERBUFFER _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 9, struct ioctl_struct) 15 + 16 + struct ioctl_struct { 17 + unsigned char cmd; 18 + unsigned long numbytes; 19 + unsigned char dir; //1=out;0=in 20 + int endpoint; 21 + int numFrames; 22 + unsigned char *pData; 23 + }; 24 + 25 + #endif