aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-08-21 17:04:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:34 -0500
commit28397ffef14255ba45b99570d366fcd2b454c8f3 (patch)
tree919b6651cf9f4fb31fc436600a285c847b03c6cd /drivers
parent88a1e909da60cd3adf159bc337ede09d4ac93e3e (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rspiusb/Kconfig6
-rw-r--r--drivers/staging/rspiusb/Makefile1
-rw-r--r--drivers/staging/rspiusb/TODO22
-rw-r--r--drivers/staging/rspiusb/rspiusb.c887
-rw-r--r--drivers/staging/rspiusb/rspiusb.h25
7 files changed, 944 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 53404a4018fe..fe3b23e43567 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -83,5 +83,7 @@ source "drivers/staging/altpciechdma/Kconfig"
83 83
84source "drivers/staging/rtl8187se/Kconfig" 84source "drivers/staging/rtl8187se/Kconfig"
85 85
86source "drivers/staging/rspiusb/Kconfig"
87
86endif # !STAGING_EXCLUDE_BUILD 88endif # !STAGING_EXCLUDE_BUILD
87endif # STAGING 89endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 170789f3c4ca..bd4cb9285a2f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_ASUS_OLED) += asus_oled/
24obj-$(CONFIG_PANEL) += panel/ 24obj-$(CONFIG_PANEL) += panel/
25obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ 25obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
26obj-$(CONFIG_RTL8187SE) += rtl8187se/ 26obj-$(CONFIG_RTL8187SE) += rtl8187se/
27obj-$(CONFIG_USB_RSPI) += rspiusb/
diff --git a/drivers/staging/rspiusb/Kconfig b/drivers/staging/rspiusb/Kconfig
new file mode 100644
index 000000000000..d225f6794d02
--- /dev/null
+++ b/drivers/staging/rspiusb/Kconfig
@@ -0,0 +1,6 @@
1config 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.
diff --git a/drivers/staging/rspiusb/Makefile b/drivers/staging/rspiusb/Makefile
new file mode 100644
index 000000000000..cc7aed92b0e3
--- /dev/null
+++ b/drivers/staging/rspiusb/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_USB_RSPI) += rspiusb.o
diff --git a/drivers/staging/rspiusb/TODO b/drivers/staging/rspiusb/TODO
new file mode 100644
index 000000000000..cd6336a9254d
--- /dev/null
+++ b/drivers/staging/rspiusb/TODO
@@ -0,0 +1,22 @@
1This driver is for the Princeton Instruments USB camera.
2
3It needs lots of work to get it into the main drivers/usb/ subdirectory:
4
5Any 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
17Please send patches to:
18 Greg Kroah-Hartman <gregkh@suse.de>
19and CC:
20 Judd Montgomery <judd@jpilot.org>
21 Jeff Frontz <jeff.frontz@gmail.com>
22as they have this device and can test any needed changes.
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
new file mode 100644
index 000000000000..ca281d6cbd7a
--- /dev/null
+++ b/drivers/staging/rspiusb/rspiusb.c
@@ -0,0 +1,887 @@
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
36static int debug = 1;
37#else
38static 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() */
62static DECLARE_MUTEX(disconnect_sem);
63
64/* Structure to hold all of our device specific stuff */
65struct 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
94static int MapUserBuffer(struct ioctl_struct *, struct device_extension *);
95static int UnMapUserBuffer(struct device_extension *);
96static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
97 unsigned long arg);
98static int piusb_output(struct ioctl_struct *, unsigned char *, int, struct device_extension *);
99static struct usb_driver piusb_driver;
100
101/* table of devices that work with this driver */
102static 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
108MODULE_DEVICE_TABLE(usb, pi_device_table);
109
110static int lastErr = 0;
111static int errCnt = 0;
112
113static 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
122static 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
168static 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 */
187static 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
423static 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
439int 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
470static 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
525static 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 )
582static 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
711static struct file_operations piusb_fops = {
712 .owner = THIS_MODULE,
713 .ioctl = piusb_ioctl,
714 .open = piusb_open,
715 .release = piusb_release,
716};
717
718static 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 */
730static 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 */
828static 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
844static 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 */
854static 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 */
872static void __exit piusb_exit(void)
873{
874 /* deregister this driver with the USB subsystem */
875 usb_deregister(&piusb_driver);
876}
877
878module_init(piusb_init);
879module_exit(piusb_exit);
880
881/* Module parameters */
882module_param(debug, int, 0);
883MODULE_PARM_DESC(debug, "Debug enabled or not");
884
885MODULE_AUTHOR(DRIVER_AUTHOR);
886MODULE_DESCRIPTION(DRIVER_DESC);
887MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/rspiusb/rspiusb.h b/drivers/staging/rspiusb/rspiusb.h
new file mode 100644
index 000000000000..965cd2d8c194
--- /dev/null
+++ b/drivers/staging/rspiusb/rspiusb.h
@@ -0,0 +1,25 @@
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
16struct 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