aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Genoud <richard.genoud@gmail.com>2009-05-17 07:06:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-19 14:00:54 -0400
commitf2d46e248a8a825506c21f972fff11e423ff1eea (patch)
treecf706c91c48d8431346771c0b5a36ef9bb621fa0
parent6546f08d21921ee13b6265493bebcff750090791 (diff)
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>
-rw-r--r--drivers/staging/rspiusb/rspiusb.c406
-rw-r--r--drivers/staging/rspiusb/rspiusb.h28
2 files changed, 242 insertions, 192 deletions
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
index b2339724a315..72241f28bde4 100644
--- a/drivers/staging/rspiusb/rspiusb.c
+++ b/drivers/staging/rspiusb/rspiusb.c
@@ -39,7 +39,11 @@ static int debug;
39#endif 39#endif
40/* Use our own dbg macro */ 40/* Use our own dbg macro */
41#undef dbg 41#undef dbg
42#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) 42#define dbg(format, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_DEBUG __FILE__ ": " format "\n" , ##arg); \
46 } while (0)
43 47
44/* Version Information */ 48/* Version Information */
45#define DRIVER_VERSION "V1.0.1" 49#define DRIVER_VERSION "V1.0.1"
@@ -63,52 +67,58 @@ static DECLARE_MUTEX(disconnect_sem);
63 67
64/* Structure to hold all of our device specific stuff */ 68/* Structure to hold all of our device specific stuff */
65struct device_extension { 69struct device_extension {
66 struct usb_device *udev; /* save off the usb device pointer */ 70 struct usb_device *udev; /* save off the usb device pointer */
67 struct usb_interface *interface; /* the interface for this device */ 71 struct usb_interface *interface; /* the interface for this device */
68 unsigned char minor; /* the starting minor number for this device */ 72 unsigned char minor; /* the starting minor number
73 * for this device
74 */
69 size_t bulk_in_size_returned; 75 size_t bulk_in_size_returned;
70 int bulk_in_byte_trk; 76 int bulk_in_byte_trk;
71 struct urb ***PixelUrb; 77 struct urb ***PixelUrb;
72 int frameIdx; 78 int frameIdx;
73 int urbIdx; 79 int urbIdx;
74 unsigned int *maplist_numPagesMapped; 80 unsigned int *maplist_numPagesMapped;
75 int open; /* if the port is open or not */ 81 int open; /* if the port is open or not */
76 int present; /* if the device is not disconnected */ 82 int present; /* if the device is not disconnected */
77 int userBufMapped; /* has the user buffer been mapped? */ 83 int userBufMapped; /* has the user buffer been mapped ? */
78 struct scatterlist **sgl; /* scatter-gather list for user buffer */ 84 struct scatterlist **sgl; /* scatter-gather list for user buffer */
79 unsigned int *sgEntries; 85 unsigned int *sgEntries;
80 struct kref kref; 86 struct kref kref;
81 int gotPixelData; 87 int gotPixelData;
82 int pendingWrite; 88 int pendingWrite;
83 char **pendedPixelUrbs; 89 char **pendedPixelUrbs;
84 int iama; /*PIXIS or ST133 */ 90 int iama; /* PIXIS or ST133 */
85 int num_frames; /* the number of frames that will fit in the user buffer */ 91 int num_frames; /* the number of frames that will fit
92 * in the user buffer
93 */
86 int active_frame; 94 int active_frame;
87 unsigned long frameSize; 95 unsigned long frameSize;
88 struct semaphore sem; 96 struct semaphore sem;
89 //FX2 specific endpoints 97 unsigned int hEP[8]; /* FX2 specific endpoints */
90 unsigned int hEP[8];
91}; 98};
92#define to_pi_dev(d) container_of( d, struct device_extension, kref )
93 99
100#define to_pi_dev(d) container_of(d, struct device_extension, kref)
101
102/* Prototypes */
94static int MapUserBuffer(struct ioctl_struct *, struct device_extension *); 103static int MapUserBuffer(struct ioctl_struct *, struct device_extension *);
95static int UnMapUserBuffer(struct device_extension *); 104static int UnMapUserBuffer(struct device_extension *);
96static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 105static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
97 unsigned long arg); 106 unsigned long arg);
98static int piusb_output(struct ioctl_struct *, unsigned char *, int, struct device_extension *); 107static int piusb_output(struct ioctl_struct *, unsigned char *, int,
108 struct device_extension *);
99static struct usb_driver piusb_driver; 109static struct usb_driver piusb_driver;
100 110
101/* table of devices that work with this driver */ 111/* table of devices that work with this driver */
102static struct usb_device_id pi_device_table[] = { 112static struct usb_device_id pi_device_table[] = {
103 {USB_DEVICE(VENDOR_ID, ST133_PID)}, 113 {USB_DEVICE(VENDOR_ID, ST133_PID)},
104 {USB_DEVICE(VENDOR_ID, PIXIS_PID)}, 114 {USB_DEVICE(VENDOR_ID, PIXIS_PID)},
105 {0, } /* Terminating entry */ 115 {0, } /* Terminating entry */
106}; 116};
107 117
108MODULE_DEVICE_TABLE(usb, pi_device_table); 118MODULE_DEVICE_TABLE(usb, pi_device_table);
109 119
110static int lastErr = 0; 120static int lastErr;
111static int errCnt = 0; 121static int errCnt;
112 122
113static void piusb_delete(struct kref *kref) 123static void piusb_delete(struct kref *kref)
114{ 124{
@@ -143,25 +153,29 @@ static int piusb_open(struct inode *inode, struct file *file)
143 } 153 }
144 dbg("Alternate Setting = %d", interface->num_altsetting); 154 dbg("Alternate Setting = %d", interface->num_altsetting);
145 155
146 pdx->frameIdx = pdx->urbIdx = 0; 156 pdx->bulk_in_size_returned = 0;
157 pdx->bulk_in_byte_trk = 0;
158 pdx->PixelUrb = NULL;
159 pdx->frameIdx = 0;
160 pdx->urbIdx = 0;
161 pdx->maplist_numPagesMapped = NULL;
162 pdx->userBufMapped = 0;
163 pdx->sgl = NULL;
164 pdx->sgEntries = NULL;
147 pdx->gotPixelData = 0; 165 pdx->gotPixelData = 0;
148 pdx->pendingWrite = 0; 166 pdx->pendingWrite = 0;
149 pdx->frameSize = 0; 167 pdx->pendedPixelUrbs = NULL;
150 pdx->num_frames = 0; 168 pdx->num_frames = 0;
151 pdx->active_frame = 0; 169 pdx->active_frame = 0;
152 pdx->bulk_in_byte_trk = 0; 170 pdx->frameSize = 0;
153 pdx->userBufMapped = 0; 171
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 */ 172 /* increment our usage count for the device */
161 kref_get(&pdx->kref); 173 kref_get(&pdx->kref);
174
162 /* save our object in the file's private structure */ 175 /* save our object in the file's private structure */
163 file->private_data = pdx; 176 file->private_data = pdx;
164 exit_no_device: 177
178exit_no_device:
165 return retval; 179 return retval;
166} 180}
167 181
@@ -174,10 +188,13 @@ static int piusb_release(struct inode *inode, struct file *file)
174 pdx = (struct device_extension *)file->private_data; 188 pdx = (struct device_extension *)file->private_data;
175 if (pdx == NULL) { 189 if (pdx == NULL) {
176 dbg("%s - object is NULL", __func__); 190 dbg("%s - object is NULL", __func__);
177 return -ENODEV; 191 retval = -ENODEV;
192 goto object_null;
178 } 193 }
179 /* decrement the count on our device */ 194 /* decrement the count on our device */
180 kref_put(&pdx->kref, piusb_delete); 195 kref_put(&pdx->kref, piusb_delete);
196
197object_null:
181 return retval; 198 return retval;
182} 199}
183 200
@@ -206,9 +223,11 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
206 } 223 }
207 /* fill in your device specific stuff here */ 224 /* fill in your device specific stuff here */
208 if (_IOC_DIR(cmd) & _IOC_READ) 225 if (_IOC_DIR(cmd) & _IOC_READ)
209 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); 226 err = !access_ok(VERIFY_WRITE, (void __user *)arg,
227 _IOC_SIZE(cmd));
210 else if (_IOC_DIR(cmd) & _IOC_WRITE) 228 else if (_IOC_DIR(cmd) & _IOC_WRITE)
211 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); 229 err = !access_ok(VERIFY_READ, (void __user *)arg,
230 _IOC_SIZE(cmd));
212 if (err) { 231 if (err) {
213 dev_err(&pdx->udev->dev, "return with error = %d\n", err); 232 dev_err(&pdx->udev->dev, "return with error = %d\n", err);
214 return -EFAULT; 233 return -EFAULT;
@@ -227,50 +246,57 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
227 dbg("FW Version returned from HW = %ld.%ld", 246 dbg("FW Version returned from HW = %ld.%ld",
228 (devRB >> 8), (devRB & 0xFF)); 247 (devRB >> 8), (devRB & 0xFF));
229 } 248 }
230 return devRB; 249 if (retval >= 0)
250 retval = (int)devRB;
251 return retval;
252
231 case PIUSB_SETVNDCMD: 253 case PIUSB_SETVNDCMD:
232 if (copy_from_user 254 if (copy_from_user
233 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 255 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
234 dev_err(&pdx->udev->dev, "copy_from_user failed\n"); 256 dev_err(&pdx->udev->dev, "copy_from_user failed\n");
235// dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); 257 /* dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); */
236 controlData = ctrl.pData[0]; 258 controlData = ctrl.pData[0];
237 controlData |= (ctrl.pData[1] << 8); 259 controlData |= (ctrl.pData[1] << 8);
238// dbg( "%s %d", "Vendor Data =",controlData ); 260 /* 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), */ 261 retval = usb_control_msg(pdx->udev,
240 controlData, 262 usb_sndctrlpipe(pdx->udev, 0),
241 0, 263 ctrl.cmd,
242 &dummyCtlBuf, ctrl.numbytes, HZ * 10); 264 (USB_DIR_OUT | USB_TYPE_VENDOR
265 /* | USB_RECIP_ENDPOINT */),
266 controlData, 0,
267 &dummyCtlBuf, ctrl.numbytes, HZ * 10);
243 return retval; 268 return retval;
244 break; 269
245 case PIUSB_ISHIGHSPEED: 270 case PIUSB_ISHIGHSPEED:
246 return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0); 271 return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);
247 break; 272
248 case PIUSB_WRITEPIPE: 273 case PIUSB_WRITEPIPE:
249 if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) 274 if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd)))
250 dev_err(&pdx->udev->dev, "copy_from_user WRITE_DUMMY failed\n"); 275 dev_err(&pdx->udev->dev,
276 "copy_from_user WRITE_DUMMY failed\n");
251 if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) { 277 if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
252 dbg("can't access pData"); 278 dbg("can't access pData");
253 return 0; 279 return 0;
254 } 280 }
255 piusb_output(&ctrl, ctrl.pData /*uBuf */ , ctrl.numbytes, pdx); 281 piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx);
256 return ctrl.numbytes; 282 return ctrl.numbytes;
257 break; 283
258 case PIUSB_USERBUFFER: 284 case PIUSB_USERBUFFER:
259 if (copy_from_user 285 if (copy_from_user
260 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 286 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
261 dev_err(&pdx->udev->dev, "copy_from_user failed\n"); 287 dev_err(&pdx->udev->dev, "copy_from_user failed\n");
262 return MapUserBuffer((struct ioctl_struct *) & ctrl, pdx); 288 return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);
263 break; 289
264 case PIUSB_UNMAP_USERBUFFER: 290 case PIUSB_UNMAP_USERBUFFER:
265 UnMapUserBuffer(pdx); 291 retval = UnMapUserBuffer(pdx);
266 return 0; 292 return retval;
267 break; 293
268 case PIUSB_READPIPE: 294 case PIUSB_READPIPE:
269 if (copy_from_user 295 if (copy_from_user
270 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) 296 (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
271 dev_err(&pdx->udev->dev, "copy_from_user failed\n"); 297 dev_err(&pdx->udev->dev, "copy_from_user failed\n");
272 switch (ctrl.endpoint) { 298 switch (ctrl.endpoint) {
273 case 0: //ST133 Pixel Data or PIXIS IO 299 case 0: /* ST133 Pixel Data or PIXIS IO */
274 if (pdx->iama == PIXIS_PID) { 300 if (pdx->iama == PIXIS_PID) {
275 unsigned int numToRead = 0; 301 unsigned int numToRead = 0;
276 unsigned int totalRead = 0; 302 unsigned int totalRead = 0;
@@ -286,21 +312,19 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
286 if (copy_from_user(uBuf, ctrl.pData, numbytes)) 312 if (copy_from_user(uBuf, ctrl.pData, numbytes))
287 dbg("copying ctrl.pData to dummyBuf failed"); 313 dbg("copying ctrl.pData to dummyBuf failed");
288 do { 314 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 315 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) { 316 if (i) {
291 dbg("CMD = %s, Address = 0x%02X", ((uBuf[3] == 0x02) ? "WRITE" : "READ"), uBuf[1]); 317 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); 318 dbg("Number of bytes Attempted to read = %d", (int)ctrl.numbytes);
293 dbg("Blocking ReadI/O Failed with status %d", i); 319 dbg("Blocking ReadI/O Failed with status %d", i);
294 kfree(uBuf); 320 kfree(uBuf);
295 return -1; 321 return -1;
296 } else {
297 dbg("Pixis EP0 Read %d bytes",
298 numbytes);
299 totalRead += numbytes;
300 numToRead -= numbytes;
301 } 322 }
302 } 323 dbg("Pixis EP0 Read %d bytes",
303 while (numToRead); 324 numbytes);
325 totalRead += numbytes;
326 numToRead -= numbytes;
327 } while (numToRead);
304 memcpy(ctrl.pData, uBuf, totalRead); 328 memcpy(ctrl.pData, uBuf, totalRead);
305 dbg("Total Bytes Read from PIXIS EP0 = %d", 329 dbg("Total Bytes Read from PIXIS EP0 = %d",
306 totalRead); 330 totalRead);
@@ -311,34 +335,29 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
311 dbg("copy_to_user failed in IORB"); 335 dbg("copy_to_user failed in IORB");
312 kfree(uBuf); 336 kfree(uBuf);
313 return ctrl.numbytes; 337 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 } 338 }
332 break; 339 /* ST133 Pixel Data */
333 case 1: //ST133IO 340 if (!pdx->gotPixelData)
334 case 4: //PIXIS IO 341 return 0;
342 pdx->gotPixelData = 0;
343 ctrl.numbytes = pdx->bulk_in_size_returned;
344 pdx->bulk_in_size_returned -= pdx->frameSize;
345 for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
346 SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
347 pdx->active_frame = ((pdx->active_frame + 1)
348 % pdx->num_frames);
349 return ctrl.numbytes;
350
351 case 1: /* ST133IO */
352 /* fall through */
353 case 4: /* PIXIS IO */
335 uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL); 354 uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
336 if (!uBuf) { 355 if (!uBuf) {
337 dbg("Alloc for uBuf failed"); 356 dbg("Alloc for uBuf failed");
338 return 0; 357 return 0;
339 } 358 }
340 numbytes = ctrl.numbytes; 359 numbytes = ctrl.numbytes;
341// dbg( "numbytes to read = %d", numbytes ); 360 /* dbg( "numbytes to read = %d", numbytes ); */
342 if (copy_from_user(uBuf, ctrl.pData, numbytes)) 361 if (copy_from_user(uBuf, ctrl.pData, numbytes))
343 dbg("copying ctrl.pData to dummyBuf failed"); 362 dbg("copying ctrl.pData to dummyBuf failed");
344 i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint], 363 i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint],
@@ -348,41 +367,37 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
348 i); 367 i);
349 kfree(uBuf); 368 kfree(uBuf);
350 return -1; 369 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 } 370 }
361 break; 371 ctrl.numbytes = numbytes;
362 372 memcpy(ctrl.pData, uBuf, numbytes);
363 case 2: //PIXIS Ping 373 if (copy_to_user((struct ioctl_struct *) arg, &ctrl,
364 case 3: //PIXIS Pong 374 sizeof(struct ioctl_struct)))
375 dbg("copy_to_user failed in IORB");
376 kfree(uBuf);
377 return ctrl.numbytes;
378
379 case 2: /* PIXIS Ping */
380 /* fall through */
381 case 3: /* PIXIS Pong */
365 if (!pdx->gotPixelData) 382 if (!pdx->gotPixelData)
366 return 0; 383 return 0;
367 else { 384 pdx->gotPixelData = 0;
368 pdx->gotPixelData = 0; 385 ctrl.numbytes = pdx->bulk_in_size_returned;
369 ctrl.numbytes = pdx->bulk_in_size_returned; 386 pdx->bulk_in_size_returned -= pdx->frameSize;
370 pdx->bulk_in_size_returned -= pdx->frameSize; 387 for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
371 for (i = 0; 388 SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
372 i < 389 pdx->active_frame =
373 pdx->maplist_numPagesMapped[pdx-> 390 ((pdx->active_frame + 1) % pdx->num_frames);
374 active_frame]; 391 return ctrl.numbytes;
375 i++) 392
376 SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link); 393 default:
377 pdx->active_frame =
378 ((pdx->active_frame + 1) % pdx->num_frames);
379 return ctrl.numbytes;
380 }
381 break; 394 break;
382 } 395 }
383 break; 396 break;
397
384 case PIUSB_WHATCAMERA: 398 case PIUSB_WHATCAMERA:
385 return pdx->iama; 399 return pdx->iama;
400
386 case PIUSB_SETFRAMESIZE: 401 case PIUSB_SETFRAMESIZE:
387 dbg("PIUSB_SETFRAMESIZE"); 402 dbg("PIUSB_SETFRAMESIZE");
388 if (copy_from_user 403 if (copy_from_user
@@ -410,6 +425,7 @@ static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
410 kmalloc(sizeof(char *) * pdx->num_frames, 425 kmalloc(sizeof(char *) * pdx->num_frames,
411 GFP_KERNEL); 426 GFP_KERNEL);
412 return 0; 427 return 0;
428
413 default: 429 default:
414 dbg("%s\n", "No IOCTL found"); 430 dbg("%s\n", "No IOCTL found");
415 break; 431 break;
@@ -436,7 +452,7 @@ static void piusb_write_bulk_callback(struct urb *urb)
436 urb->transfer_buffer, urb->transfer_dma); 452 urb->transfer_buffer, urb->transfer_dma);
437} 453}
438 454
439int piusb_output(struct ioctl_struct * io, unsigned char *uBuf, int len, 455int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
440 struct device_extension *pdx) 456 struct device_extension *pdx)
441{ 457{
442 struct urb *urb = NULL; 458 struct urb *urb = NULL;
@@ -472,6 +488,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
472 int i = 0; 488 int i = 0;
473 int k = 0; 489 int k = 0;
474 unsigned int epAddr; 490 unsigned int epAddr;
491
475 for (k = 0; k < pdx->num_frames; k++) { 492 for (k = 0; k < pdx->num_frames; k++) {
476 dbg("Killing Urbs for Frame %d", k); 493 dbg("Killing Urbs for Frame %d", k);
477 for (i = 0; i < pdx->sgEntries[k]; i++) { 494 for (i = 0; i < pdx->sgEntries[k]; i++) {
@@ -485,23 +502,19 @@ static int UnMapUserBuffer(struct device_extension *pdx)
485 } 502 }
486 503
487 for (k = 0; k < pdx->num_frames; k++) { 504 for (k = 0; k < pdx->num_frames; k++) {
488 if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to 505 if (pdx->iama == PIXIS_PID)
489 { 506 /* which EP should we map this frame to ? */
490 if (k % 2) //check to see if this should use EP4(PONG) 507 /* PONG, odd frames: hEP[3] */
491 { 508 /* PING, even frames and zero hEP[2] */
492 epAddr = pdx->hEP[3]; //PONG, odd frames 509 epAddr = (k % 2) ? pdx->hEP[3] : pdx->hEP[2];
493 } else { 510 else
494 epAddr = pdx->hEP[2]; //PING, even frames and zero 511 /* ST133 only has 1 endpoint for Pixel data transfer */
495 }
496 } else //ST133 only has 1 endpoint for Pixel data transfer
497 {
498 epAddr = pdx->hEP[0]; 512 epAddr = pdx->hEP[0];
499 } 513
500 usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k], 514 usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k],
501 pdx->maplist_numPagesMapped[k]); 515 pdx->maplist_numPagesMapped[k]);
502 for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++) { 516 for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++)
503 page_cache_release(pdx->sgl[k][i].page_link); 517 page_cache_release(pdx->sgl[k][i].page_link);
504 }
505 kfree(pdx->sgl[k]); 518 kfree(pdx->sgl[k]);
506 kfree(pdx->PixelUrb[k]); 519 kfree(pdx->PixelUrb[k]);
507 kfree(pdx->pendedPixelUrbs[k]); 520 kfree(pdx->pendedPixelUrbs[k]);
@@ -509,6 +522,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
509 pdx->PixelUrb[k] = NULL; 522 pdx->PixelUrb[k] = NULL;
510 pdx->pendedPixelUrbs[k] = NULL; 523 pdx->pendedPixelUrbs[k] = NULL;
511 } 524 }
525
512 kfree(pdx->sgEntries); 526 kfree(pdx->sgEntries);
513 vfree(pdx->maplist_numPagesMapped); 527 vfree(pdx->maplist_numPagesMapped);
514 pdx->sgEntries = NULL; 528 pdx->sgEntries = NULL;
@@ -519,6 +533,7 @@ static int UnMapUserBuffer(struct device_extension *pdx)
519 pdx->sgl = NULL; 533 pdx->sgl = NULL;
520 pdx->pendedPixelUrbs = NULL; 534 pdx->pendedPixelUrbs = NULL;
521 pdx->PixelUrb = NULL; 535 pdx->PixelUrb = NULL;
536
522 return 0; 537 return 0;
523} 538}
524 539
@@ -539,26 +554,25 @@ static void piusb_readPIXEL_callback(struct urb *urb)
539 pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0; 554 pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0;
540 } else { 555 } else {
541 pdx->bulk_in_byte_trk += urb->actual_length; 556 pdx->bulk_in_byte_trk += urb->actual_length;
542 { 557 i = usb_submit_urb(urb, GFP_ATOMIC); /* resubmit the URB */
543 i = usb_submit_urb(urb, GFP_ATOMIC); //resubmit the URB 558 if (i) {
544 if (i) { 559 errCnt++;
545 errCnt++; 560 if (i != lastErr) {
546 if (i != lastErr) { 561 dbg("submit urb in callback failed "
547 dbg("submit urb in callback failed with error code %d", i); 562 "with error code %d", i);
548 lastErr = i; 563 lastErr = i;
549 } 564 }
550 } else { 565 } else {
551 pdx->urbIdx++; //point to next URB when we callback 566 pdx->urbIdx++; /* point to next URB when we callback */
552 if (pdx->bulk_in_byte_trk >= pdx->frameSize) { 567 if (pdx->bulk_in_byte_trk >= pdx->frameSize) {
553 pdx->bulk_in_size_returned = 568 pdx->bulk_in_size_returned =
554 pdx->bulk_in_byte_trk; 569 pdx->bulk_in_byte_trk;
555 pdx->bulk_in_byte_trk = 0; 570 pdx->bulk_in_byte_trk = 0;
556 pdx->gotPixelData = 1; 571 pdx->gotPixelData = 1;
557 pdx->frameIdx = 572 pdx->frameIdx =
558 ((pdx->frameIdx + 573 ((pdx->frameIdx +
559 1) % pdx->num_frames); 574 1) % pdx->num_frames);
560 pdx->urbIdx = 0; 575 pdx->urbIdx = 0;
561 }
562 } 576 }
563 } 577 }
564 } 578 }
@@ -566,24 +580,37 @@ static void piusb_readPIXEL_callback(struct urb *urb)
566 580
567/* MapUserBuffer( 581/* MapUserBuffer(
568 inputs: 582 inputs:
569 struct ioctl_struct *io - structure containing user address, frame #, and size 583 struct ioctl_struct *io - structure containing user address,
584 frame #, and size
570 struct device_extension *pdx - the PIUSB device extension 585 struct device_extension *pdx - the PIUSB device extension
586
571 returns: 587 returns:
572 int - status of the task 588 int - status of the task
589
573 Notes: 590 Notes:
574 MapUserBuffer maps a buffer passed down through an ioctl. The user buffer is Page Aligned by the app 591 MapUserBuffer maps a buffer passed down through an ioctl.
575 and then passed down. The function get_free_pages(...) does the actual mapping of the buffer from user space to 592 The user buffer is Page Aligned by the app and then passed down.
576 kernel space. From there a scatterlist is created from all the pages. The next function called is to usb_buffer_map_sg 593 The function get_free_pages(...) does the actual mapping of the buffer
577 which allocated DMA addresses for each page, even coalescing them if possible. The DMA address is placed in the scatterlist 594 from user space to kernel space.
578 structure. The function returns the number of DMA addresses. This may or may not be equal to the number of pages that 595 From there a scatterlist is created from all the pages.
579 the user buffer uses. We then build an URB for each DMA address and then submit them. 596 The next function called is to usb_buffer_map_sg which allocated
597 DMA addresses for each page, even coalescing them if possible.
598 The DMA address is placed in the scatterlist structure.
599 The function returns the number of DMA addresses.
600 This may or may not be equal to the number of pages that
601 the user buffer uses.
602 We then build an URB for each DMA address and then submit them.
603*/
604
605/*
606int MapUserBuffer(unsigned long uaddr, unsigned long numbytes,
607 unsigned long frameInfo, struct device_extension *pdx)
580*/ 608*/
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) 609static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
583{ 610{
584 unsigned long uaddr; 611 unsigned long uaddr;
585 unsigned long numbytes; 612 unsigned long numbytes;
586 int frameInfo; //which frame we're mapping 613 int frameInfo; /* which frame we're mapping */
587 unsigned int epAddr = 0; 614 unsigned int epAddr = 0;
588 unsigned long count = 0; 615 unsigned long count = 0;
589 int i = 0; 616 int i = 0;
@@ -591,45 +618,45 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
591 int err = 0; 618 int err = 0;
592 struct page **maplist_p; 619 struct page **maplist_p;
593 int numPagesRequired; 620 int numPagesRequired;
621
594 frameInfo = io->numFrames; 622 frameInfo = io->numFrames;
595 uaddr = (unsigned long)io->pData; 623 uaddr = (unsigned long)io->pData;
596 numbytes = io->numbytes; 624 numbytes = io->numbytes;
597 625
598 if (pdx->iama == PIXIS_PID) //if so, which EP should we map this frame to 626 if (pdx->iama == PIXIS_PID) {
599 { 627 /* which EP should we map this frame to ? */
600 if (frameInfo % 2) //check to see if this should use EP4(PONG) 628 /* PONG, odd frames: hEP[3] */
601 { 629 /* PING, even frames and zero hEP[2] */
602 epAddr = pdx->hEP[3]; //PONG, odd frames 630 epAddr = (frameInfo % 2) ? pdx->hEP[3] : pdx->hEP[2];
603 } else {
604 epAddr = pdx->hEP[2]; //PING, even frames and zero
605 }
606 dbg("Pixis Frame #%d: EP=%d", frameInfo, 631 dbg("Pixis Frame #%d: EP=%d", frameInfo,
607 (epAddr == pdx->hEP[2]) ? 2 : 4); 632 (epAddr == pdx->hEP[2]) ? 2 : 4);
608 } else //ST133 only has 1 endpoint for Pixel data transfer 633 } else { /* ST133 only has 1 endpoint for Pixel data transfer */
609 {
610 epAddr = pdx->hEP[0]; 634 epAddr = pdx->hEP[0];
611 dbg("ST133 Frame #%d: EP=2", frameInfo); 635 dbg("ST133 Frame #%d: EP=2", frameInfo);
612 } 636 }
613 count = numbytes; 637 count = numbytes;
614 dbg("UserAddress = 0x%08lX", uaddr); 638 dbg("UserAddress = 0x%08lX", uaddr);
615 dbg("numbytes = %d", (int)numbytes); 639 dbg("numbytes = %d", (int)numbytes);
616 //number of pages to map the entire user space DMA buffer 640
641 /* number of pages to map the entire user space DMA buffer */
617 numPagesRequired = 642 numPagesRequired =
618 ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; 643 ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
619 dbg("Number of pages needed = %d", numPagesRequired); 644 dbg("Number of pages needed = %d", numPagesRequired);
620 maplist_p = vmalloc(numPagesRequired * sizeof(struct page)); //, GFP_ATOMIC); 645 maplist_p = vmalloc(numPagesRequired * sizeof(struct page));
621 if (!maplist_p) { 646 if (!maplist_p) {
622 dbg("Can't Allocate Memory for maplist_p"); 647 dbg("Can't Allocate Memory for maplist_p");
623 return -ENOMEM; 648 return -ENOMEM;
624 } 649 }
625 //map the user buffer to kernel memory 650
651 /* map the user buffer to kernel memory */
626 down_write(&current->mm->mmap_sem); 652 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 653 pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current,
628 maplist_p, 654 current->mm, (uaddr & PAGE_MASK), numPagesRequired,
629 NULL); 655 WRITE, 0 /* Don't Force*/, maplist_p, NULL);
630 up_write(&current->mm->mmap_sem); 656 up_write(&current->mm->mmap_sem);
631 dbg("Number of pages mapped = %d", 657 dbg("Number of pages mapped = %d",
632 pdx->maplist_numPagesMapped[frameInfo]); 658 pdx->maplist_numPagesMapped[frameInfo]);
659
633 for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++) 660 for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++)
634 flush_dcache_page(maplist_p[i]); 661 flush_dcache_page(maplist_p[i]);
635 if (!pdx->maplist_numPagesMapped[frameInfo]) { 662 if (!pdx->maplist_numPagesMapped[frameInfo]) {
@@ -637,7 +664,10 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
637 vfree(maplist_p); 664 vfree(maplist_p);
638 return -ENOMEM; 665 return -ENOMEM;
639 } 666 }
640 //need to create a scatterlist that spans each frame that can fit into the mapped buffer 667
668 /* need to create a scatterlist that spans each frame
669 * that can fit into the mapped buffer
670 */
641 pdx->sgl[frameInfo] = 671 pdx->sgl[frameInfo] =
642 kmalloc((pdx->maplist_numPagesMapped[frameInfo] * 672 kmalloc((pdx->maplist_numPagesMapped[frameInfo] *
643 sizeof(struct scatterlist)), GFP_ATOMIC); 673 sizeof(struct scatterlist)), GFP_ATOMIC);
@@ -657,7 +687,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
657 pdx->sgl[frameInfo][k].page_link = maplist_p[k]; 687 pdx->sgl[frameInfo][k].page_link = maplist_p[k];
658 pdx->sgl[frameInfo][k].length = 688 pdx->sgl[frameInfo][k].length =
659 (count < PAGE_SIZE) ? count : PAGE_SIZE; 689 (count < PAGE_SIZE) ? count : PAGE_SIZE;
660 count -= PAGE_SIZE; //example had PAGE_SIZE here; 690 count -= PAGE_SIZE; /* example had PAGE_SIZE here */
661 } 691 }
662 } else { 692 } else {
663 pdx->sgl[frameInfo][0].length = count; 693 pdx->sgl[frameInfo][0].length = count;
@@ -668,7 +698,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
668 dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]); 698 dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]);
669 pdx->userBufMapped = 1; 699 pdx->userBufMapped = 1;
670 vfree(maplist_p); 700 vfree(maplist_p);
671 //Create and Send the URB's for each s/g entry 701
702 /* Create and Send the URB's for each s/g entry */
672 pdx->PixelUrb[frameInfo] = 703 pdx->PixelUrb[frameInfo] =
673 kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *), 704 kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *),
674 GFP_KERNEL); 705 GFP_KERNEL);
@@ -677,7 +708,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
677 return -ENOMEM; 708 return -ENOMEM;
678 } 709 }
679 for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { 710 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 711 /* 0 iso packets because we're using BULK transfers */
712 pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL);
681 usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], 713 usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i],
682 pdx->udev, 714 pdx->udev,
683 epAddr, 715 epAddr,
@@ -691,7 +723,8 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
691 pdx->PixelUrb[frameInfo][i]->transfer_flags = 723 pdx->PixelUrb[frameInfo][i]->transfer_flags =
692 URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; 724 URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
693 } 725 }
694 pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT; //only interrupt when last URB completes 726 /* only interrupt when last URB completes */
727 pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT;
695 pdx->pendedPixelUrbs[frameInfo] = 728 pdx->pendedPixelUrbs[frameInfo] =
696 kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL); 729 kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL);
697 if (!pdx->pendedPixelUrbs[frameInfo]) 730 if (!pdx->pendedPixelUrbs[frameInfo])
@@ -702,13 +735,13 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
702 dbg("%s %d\n", "submit urb error =", err); 735 dbg("%s %d\n", "submit urb error =", err);
703 pdx->pendedPixelUrbs[frameInfo][i] = 0; 736 pdx->pendedPixelUrbs[frameInfo][i] = 0;
704 return err; 737 return err;
705 } else 738 }
706 pdx->pendedPixelUrbs[frameInfo][i] = 1;; 739 pdx->pendedPixelUrbs[frameInfo][i] = 1;
707 } 740 }
708 return 0; 741 return 0;
709} 742}
710 743
711static struct file_operations piusb_fops = { 744static const struct file_operations piusb_fops = {
712 .owner = THIS_MODULE, 745 .owner = THIS_MODULE,
713 .ioctl = piusb_ioctl, 746 .ioctl = piusb_ioctl,
714 .open = piusb_open, 747 .open = piusb_open,
@@ -751,9 +784,9 @@ static int piusb_probe(struct usb_interface *interface,
751 /* See if the device offered us matches what we can accept */ 784 /* See if the device offered us matches what we can accept */
752 if ((pdx->udev->descriptor.idVendor != VENDOR_ID) 785 if ((pdx->udev->descriptor.idVendor != VENDOR_ID)
753 || ((pdx->udev->descriptor.idProduct != PIXIS_PID) 786 || ((pdx->udev->descriptor.idProduct != PIXIS_PID)
754 && (pdx->udev->descriptor.idProduct != ST133_PID))) { 787 && (pdx->udev->descriptor.idProduct != ST133_PID)))
755 return -ENODEV; 788 return -ENODEV;
756 } 789
757 pdx->iama = pdx->udev->descriptor.idProduct; 790 pdx->iama = pdx->udev->descriptor.idProduct;
758 791
759 if (debug) { 792 if (debug) {
@@ -807,7 +840,7 @@ static int piusb_probe(struct usb_interface *interface,
807 dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor); 840 dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor);
808 return 0; 841 return 0;
809 842
810 error: 843error:
811 if (pdx) 844 if (pdx)
812 kref_put(&pdx->kref, piusb_delete); 845 kref_put(&pdx->kref, piusb_delete);
813 return retval; 846 return retval;
@@ -828,12 +861,17 @@ static void piusb_disconnect(struct usb_interface *interface)
828{ 861{
829 struct device_extension *pdx; 862 struct device_extension *pdx;
830 int minor = interface->minor; 863 int minor = interface->minor;
864
831 lock_kernel(); 865 lock_kernel();
866
832 pdx = usb_get_intfdata(interface); 867 pdx = usb_get_intfdata(interface);
833 usb_set_intfdata(interface, NULL); 868 usb_set_intfdata(interface, NULL);
869
834 /* give back our minor */ 870 /* give back our minor */
835 usb_deregister_dev(interface, &piusb_class); 871 usb_deregister_dev(interface, &piusb_class);
872
836 unlock_kernel(); 873 unlock_kernel();
874
837 /* prevent device read, write and ioctl */ 875 /* prevent device read, write and ioctl */
838 pdx->present = 0; 876 pdx->present = 0;
839 kref_put(&pdx->kref, piusb_delete); 877 kref_put(&pdx->kref, piusb_delete);
@@ -853,16 +891,20 @@ static struct usb_driver piusb_driver = {
853static int __init piusb_init(void) 891static int __init piusb_init(void)
854{ 892{
855 int result; 893 int result;
894
895 lastErr = 0;
896 errCnt = 0;
897
856 /* register this driver with the USB subsystem */ 898 /* register this driver with the USB subsystem */
857 result = usb_register(&piusb_driver); 899 result = usb_register(&piusb_driver);
858 if (result) { 900 if (result)
859 printk(KERN_ERR KBUILD_MODNAME 901 printk(KERN_ERR KBUILD_MODNAME
860 ": usb_register failed. Error number %d\n", result); 902 ": usb_register failed. Error number %d\n",
861 return result; 903 result);
862 } 904 else
863 printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC, 905 printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
864 DRIVER_VERSION); 906 DRIVER_VERSION);
865 return 0; 907 return result;
866} 908}
867 909
868/** 910/**
diff --git a/drivers/staging/rspiusb/rspiusb.h b/drivers/staging/rspiusb/rspiusb.h
index 965cd2d8c194..3fc1db7b1c4c 100644
--- a/drivers/staging/rspiusb/rspiusb.h
+++ b/drivers/staging/rspiusb/rspiusb.h
@@ -3,20 +3,28 @@
3 3
4#define PIUSB_MAGIC 'm' 4#define PIUSB_MAGIC 'm'
5#define PIUSB_IOCTL_BASE 192 5#define PIUSB_IOCTL_BASE 192
6#define PIUSB_GETVNDCMD _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 1, struct ioctl_struct) 6
7#define PIUSB_SETVNDCMD _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 2, struct ioctl_struct) 7#define PIUSB_IOR(offset) \
8#define PIUSB_WRITEPIPE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 3, struct ioctl_struct) 8 _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
9#define PIUSB_READPIPE _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 4, struct ioctl_struct) 9#define PIUSB_IOW(offset) \
10#define PIUSB_SETFRAMESIZE _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 5, struct ioctl_struct) 10 _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
11#define PIUSB_WHATCAMERA _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 6) 11#define PIUSB_IO(offset) \
12#define PIUSB_USERBUFFER _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 7, struct ioctl_struct) 12 _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset)
13#define PIUSB_ISHIGHSPEED _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 8) 13
14#define PIUSB_UNMAP_USERBUFFER _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + 9, struct ioctl_struct) 14#define PIUSB_GETVNDCMD PIUSB_IOR(1)
15#define PIUSB_SETVNDCMD PIUSB_IOW(2)
16#define PIUSB_WRITEPIPE PIUSB_IOW(3)
17#define PIUSB_READPIPE PIUSB_IOR(4)
18#define PIUSB_SETFRAMESIZE PIUSB_IOW(5)
19#define PIUSB_WHATCAMERA PIUSB_IO(6)
20#define PIUSB_USERBUFFER PIUSB_IOW(7)
21#define PIUSB_ISHIGHSPEED PIUSB_IO(8)
22#define PIUSB_UNMAP_USERBUFFER PIUSB_IOW(9)
15 23
16struct ioctl_struct { 24struct ioctl_struct {
17 unsigned char cmd; 25 unsigned char cmd;
18 unsigned long numbytes; 26 unsigned long numbytes;
19 unsigned char dir; //1=out;0=in 27 unsigned char dir; /* 1=out; 0=in */
20 int endpoint; 28 int endpoint;
21 int numFrames; 29 int numFrames;
22 unsigned char *pData; 30 unsigned char *pData;