Import 2.3.18pre1
[davej-history.git] / drivers / usb / ezusb.c
blob4c00ef143cfd8448496d28f0a2f06d9c9f647010
1 /*****************************************************************************/
3 /*
4 * ezusb.c -- Firmware download miscdevice for Anchorchips EZUSB microcontrollers.
6 * Copyright (C) 1999
7 * Thomas Sailer (sailer@ife.ee.ethz.ch)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * History:
24 * 0.1 26.05.99 Created
25 * 0.2 23.07.99 Removed EZUSB_INTERRUPT. Interrupt pipes may be polled with
26 * bulk reads.
27 * Implemented EZUSB_SETINTERFACE, more sanity checks for EZUSB_BULK.
28 * Preliminary ISO support
29 * 0.3 01.09.99 Async Bulk and ISO support
30 * 0.4 01.09.99
34 /*****************************************************************************/
36 #include <linux/config.h>
37 #include <linux/module.h>
38 #include <linux/socket.h>
39 #include <linux/miscdevice.h>
40 #include <linux/list.h>
41 #include <linux/vmalloc.h>
42 #include <linux/slab.h>
43 #include <linux/spinlock.h>
44 #include <asm/uaccess.h>
46 #include "usb.h"
47 #include "ezusb.h"
49 /* --------------------------------------------------------------------- */
51 #define NREZUSB 1
53 static struct ezusb {
54 struct semaphore mutex;
55 struct usb_device *usbdev;
56 struct list_head async_pending;
57 struct list_head async_completed;
58 wait_queue_head_t wait;
59 spinlock_t lock;
60 } ezusb[NREZUSB];
62 struct async {
63 struct list_head asynclist;
64 struct ezusb *ez;
65 void *data;
66 unsigned dataorder;
67 void *userdata;
68 unsigned datalen;
69 union {
70 struct usb_isoc_desc *iso;
71 void *bulk;
72 } desc;
73 unsigned numframes; /* 0 means bulk, > 0 means iso */
74 struct ezusb_asynccompleted completed;
77 /* --------------------------------------------------------------------- */
79 extern inline unsigned ld2(unsigned int x)
81 unsigned r = 0;
83 if (x >= 0x10000) {
84 x >>= 16;
85 r += 16;
87 if (x >= 0x100) {
88 x >>= 8;
89 r += 8;
91 if (x >= 0x10) {
92 x >>= 4;
93 r += 4;
95 if (x >= 4) {
96 x >>= 2;
97 r += 2;
99 if (x >= 2)
100 r++;
101 return r;
104 /* --------------------------------------------------------------------- */
106 extern __inline__ void async_removelist(struct async *as)
108 struct ezusb *ez = as->ez;
109 unsigned long flags;
111 spin_lock_irqsave(&ez->lock, flags);
112 list_del(&as->asynclist);
113 INIT_LIST_HEAD(&as->asynclist);
114 spin_unlock_irqrestore(&ez->lock, flags);
117 extern __inline__ void async_newpending(struct async *as)
119 struct ezusb *ez = as->ez;
120 unsigned long flags;
122 spin_lock_irqsave(&ez->lock, flags);
123 list_add_tail(&as->asynclist, &ez->async_pending);
124 spin_unlock_irqrestore(&ez->lock, flags);
127 extern __inline__ void async_movetocompleted(struct async *as)
129 struct ezusb *ez = as->ez;
130 unsigned long flags;
132 spin_lock_irqsave(&ez->lock, flags);
133 list_del(&as->asynclist);
134 list_add_tail(&as->asynclist, &ez->async_completed);
135 spin_unlock_irqrestore(&ez->lock, flags);
138 extern __inline__ struct async *async_getcompleted(struct ezusb *ez)
140 unsigned long flags;
141 struct async *as = NULL;
143 spin_lock_irqsave(&ez->lock, flags);
144 if (!list_empty(&ez->async_completed)) {
145 as = list_entry(ez->async_completed.next, struct async, asynclist);
146 list_del(&as->asynclist);
147 INIT_LIST_HEAD(&as->asynclist);
149 spin_unlock_irqrestore(&ez->lock, flags);
150 return as;
153 extern __inline__ struct async *async_getpending(struct ezusb *ez, void *context)
155 unsigned long flags;
156 struct async *as;
157 struct list_head *p;
159 spin_lock_irqsave(&ez->lock, flags);
160 for (p = ez->async_pending.next; p != &ez->async_pending; ) {
161 as = list_entry(p, struct async, asynclist);
162 p = p->next;
163 if (as->completed.context != context)
164 continue;
165 list_del(&as->asynclist);
166 INIT_LIST_HEAD(&as->asynclist);
167 spin_unlock_irqrestore(&ez->lock, flags);
168 return as;
170 spin_unlock_irqrestore(&ez->lock, flags);
171 return NULL;
174 /* --------------------------------------------------------------------- */
176 static int async_completed(int status, void *__buffer, int rval, void *dev_id)
178 struct async *as = (struct async *)dev_id;
179 struct ezusb *ez = as->ez;
180 unsigned cnt;
182 printk(KERN_DEBUG "ezusb: async_completed: status %d rval %d\n", status, rval);
183 as->completed.length = rval;
184 if (as->numframes > 0) {
185 as->completed.status = USB_ST_NOERROR;
186 for (cnt = 0; cnt < as->numframes; cnt++) {
187 as->completed.isostat[cnt].status = as->desc.iso->frames[cnt].frame_status;
188 as->completed.isostat[cnt].length = as->desc.iso->frames[cnt].frame_length;
190 } else
191 as->completed.status = status;
192 spin_lock(&ez->lock);
193 list_del(&as->asynclist);
194 list_add_tail(&as->asynclist, &ez->async_completed);
195 spin_unlock(&ez->lock);
196 wake_up(&ez->wait);
197 return 0;
200 static void remove_async(struct async *as)
202 if (as->data && as->dataorder)
203 free_pages((unsigned long)as->data, as->dataorder);
204 if (as->numframes)
205 usb_free_isoc(as->desc.iso);
206 kfree(as);
209 static void kill_async(struct async *as)
211 struct ezusb *ez = as->ez;
213 if (as->numframes)
214 /* ISO case */
215 usb_kill_isoc(as->desc.iso);
216 else
217 usb_terminate_bulk(ez->usbdev, as->desc.bulk);
218 as->completed.status = USB_ST_REMOVED;
219 async_movetocompleted(as);
222 static void destroy_all_async(struct ezusb *ez)
224 struct async *as;
225 unsigned long flags;
227 spin_lock_irqsave(&ez->lock, flags);
228 if (!list_empty(&ez->async_pending)) {
229 as = list_entry(ez->async_pending.next, struct async, asynclist);
230 list_del(&as->asynclist);
231 INIT_LIST_HEAD(&as->asynclist);
232 spin_unlock_irqrestore(&ez->lock, flags);
233 kill_async(as);
234 spin_lock_irqsave(&ez->lock, flags);
236 spin_unlock_irqrestore(&ez->lock, flags);
237 while ((as = async_getcompleted(ez)))
238 remove_async(as);
241 /* --------------------------------------------------------------------- */
243 static loff_t ezusb_llseek(struct file *file, loff_t offset, int origin)
245 struct ezusb *ez = (struct ezusb *)file->private_data;
247 switch(origin) {
248 case 1:
249 offset += file->f_pos;
250 break;
251 case 2:
252 offset += 0x10000;
253 break;
255 if (offset < 0 || offset >= 0x10000)
256 return -EINVAL;
257 return (file->f_pos = offset);
260 static ssize_t ezusb_read(struct file *file, char *buf, size_t sz, loff_t *ppos)
262 struct ezusb *ez = (struct ezusb *)file->private_data;
263 unsigned pos = *ppos;
264 unsigned ret = 0;
265 unsigned len;
266 unsigned char b[64];
267 devrequest dr;
268 int i;
270 if (*ppos < 0 || *ppos >= 0x10000)
271 return -EINVAL;
272 down(&ez->mutex);
273 if (!ez->usbdev) {
274 up(&ez->mutex);
275 return -EIO;
277 while (sz > 0 && pos < 0x10000) {
278 len = sz;
279 if (len > sizeof(b))
280 len = sizeof(b);
281 if (pos + len > 0x10000)
282 len = 0x10000 - pos;
283 dr.requesttype = 0xc0;
284 dr.request = 0xa0;
285 dr.value = pos;
286 dr.index = 0;
287 dr.length = len;
288 i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0), &dr, b, len);
289 if (i) {
290 up(&ez->mutex);
291 printk(KERN_WARNING "ezusb: upload failed pos %u len %u ret %d\n", dr.value, dr.length, i);
292 *ppos = pos;
293 if (ret)
294 return ret;
295 return -ENXIO;
297 if (copy_to_user(buf, b, len)) {
298 up(&ez->mutex);
299 *ppos = pos;
300 if (ret)
301 return ret;
302 return -EFAULT;
304 pos += len;
305 buf += len;
306 sz -= len;
307 ret += len;
309 up(&ez->mutex);
310 *ppos = pos;
311 return ret;
314 static ssize_t ezusb_write(struct file *file, const char *buf, size_t sz, loff_t *ppos)
316 struct ezusb *ez = (struct ezusb *)file->private_data;
317 unsigned pos = *ppos;
318 unsigned ret = 0;
319 unsigned len;
320 unsigned char b[64];
321 devrequest dr;
322 int i;
324 if (*ppos < 0 || *ppos >= 0x10000)
325 return -EINVAL;
326 down(&ez->mutex);
327 if (!ez->usbdev) {
328 up(&ez->mutex);
329 return -EIO;
331 while (sz > 0 && pos < 0x10000) {
332 len = sz;
333 if (len > sizeof(b))
334 len = sizeof(b);
335 if (pos + len > 0x10000)
336 len = 0x10000 - pos;
337 if (copy_from_user(b, buf, len)) {
338 up(&ez->mutex);
339 *ppos = pos;
340 if (ret)
341 return ret;
342 return -EFAULT;
344 dr.requesttype = 0x40;
345 dr.request = 0xa0;
346 dr.value = pos;
347 dr.index = 0;
348 dr.length = len;
349 i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0), &dr, b, len);
350 if (i) {
351 up(&ez->mutex);
352 printk(KERN_WARNING "ezusb: download failed pos %u len %u ret %d\n", dr.value, dr.length, i);
353 *ppos = pos;
354 if (ret)
355 return ret;
356 return -ENXIO;
358 pos += len;
359 buf += len;
360 sz -= len;
361 ret += len;
363 up(&ez->mutex);
364 *ppos = pos;
365 return ret;
368 static int ezusb_open(struct inode *inode, struct file *file)
370 struct ezusb *ez = &ezusb[0];
372 down(&ez->mutex);
373 while (!ez->usbdev) {
374 up(&ez->mutex);
375 if (!(file->f_flags & O_NONBLOCK)) {
376 return -EIO;
378 schedule_timeout(HZ/2);
379 if (signal_pending(current))
380 return -EAGAIN;
381 down(&ez->mutex);
383 up(&ez->mutex);
384 file->f_pos = 0;
385 file->private_data = ez;
386 MOD_INC_USE_COUNT;
387 return 0;
390 static int ezusb_release(struct inode *inode, struct file *file)
392 struct ezusb *ez = (struct ezusb *)file->private_data;
394 down(&ez->mutex);
395 destroy_all_async(ez);
396 up(&ez->mutex);
397 MOD_DEC_USE_COUNT;
398 return 0;
401 static int ezusb_control(struct usb_device *usbdev, unsigned char requesttype,
402 unsigned char request, unsigned short value,
403 unsigned short index, unsigned short length,
404 void *data)
406 unsigned char *tbuf = NULL;
407 unsigned int pipe;
408 int i;
410 if (length > PAGE_SIZE)
411 return -EINVAL;
412 /* __range_ok is broken;
413 with unsigned short size, it gave
414 addl %si,%edx ; sbbl %ecx,%ecx; cmpl %edx,12(%eax); sbbl $0,%ecx
416 if (requesttype & 0x80) {
417 pipe = usb_rcvctrlpipe(usbdev, 0);
418 if (length > 0 && !access_ok(VERIFY_WRITE, data, (unsigned int)length))
419 return -EFAULT;
420 } else
421 pipe = usb_sndctrlpipe(usbdev, 0);
422 if (length > 0) {
423 if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))
424 return -ENOMEM;
425 if (!(requesttype & 0x80)) {
426 if (copy_from_user(tbuf, data, length)) {
427 free_page((unsigned long)tbuf);
428 return -EFAULT;
432 i = usb_control_msg(usbdev, pipe, request, requesttype, value, index, tbuf, length);
433 if (i < 0) {
434 if (length > 0)
435 free_page((unsigned long)tbuf);
436 printk(KERN_WARNING "ezusb: EZUSB_CONTROL failed rqt %u rq %u len %u ret %d\n",
437 requesttype, request, length, i);
438 return -ENXIO;
440 if (requesttype & 0x80 && length > 0 && copy_to_user(data, tbuf, length))
441 i = -EFAULT;
442 if (length > 0)
443 free_page((unsigned long)tbuf);
444 return i;
447 static int ezusb_bulk(struct usb_device *usbdev, unsigned int ep, unsigned int length, void *data)
449 unsigned char *tbuf = NULL;
450 unsigned int pipe;
451 unsigned long len2 = 0;
452 int ret = 0;
454 if (length > PAGE_SIZE)
455 return -EINVAL;
456 if ((ep & ~0x80) >= 16)
457 return -EINVAL;
458 if (ep & 0x80) {
459 pipe = usb_rcvbulkpipe(usbdev, ep & 0x7f);
460 if (length > 0 && !access_ok(VERIFY_WRITE, data, length))
461 return -EFAULT;
462 } else
463 pipe = usb_sndbulkpipe(usbdev, ep & 0x7f);
464 if (!usb_maxpacket(usbdev, pipe, !(ep & 0x80)))
465 return -EINVAL;
466 if (length > 0) {
467 if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))
468 return -ENOMEM;
469 if (!(ep & 0x80)) {
470 if (copy_from_user(tbuf, data, length)) {
471 free_page((unsigned long)tbuf);
472 return -EFAULT;
476 ret = usbdev->bus->op->bulk_msg(usbdev, pipe, tbuf, length, &len2);
477 if (ret < 0) {
478 if (length > 0)
479 free_page((unsigned long)tbuf);
480 printk(KERN_WARNING "ezusb: EZUSB_BULK failed ep 0x%x len %u ret %d\n",
481 ep, length, ret);
482 return -ENXIO;
484 if (len2 > length)
485 len2 = length;
486 ret = len2;
487 if (ep & 0x80 && len2 > 0 && copy_to_user(data, tbuf, len2))
488 ret = -EFAULT;
489 if (length > 0)
490 free_page((unsigned long)tbuf);
491 return ret;
494 static int ezusb_resetep(struct usb_device *usbdev, unsigned int ep)
496 if ((ep & ~0x80) >= 16)
497 return -EINVAL;
498 usb_settoggle(usbdev, ep & 0xf, !(ep & 0x80), 0);
499 return 0;
502 static int ezusb_setinterface(struct usb_device *usbdev, unsigned int interface, unsigned int altsetting)
504 if (usb_set_interface(usbdev, interface, altsetting) < 0)
505 return -EINVAL;
506 return 0;
509 static int ezusb_setconfiguration(struct usb_device *usbdev, unsigned int config)
511 if (usb_set_configuration(usbdev, config) < 0)
512 return -EINVAL;
513 return 0;
516 static int ezusb_requestbulk(struct ezusb *ez, struct ezusb_asyncbulk *ab)
518 struct async *as = NULL;
519 unsigned int pipe;
521 if (ab->len > PAGE_SIZE)
522 return -EINVAL;
523 if ((ab->ep & ~0x80) >= 16)
524 return -EINVAL;
525 if (ab->ep & 0x80) {
526 pipe = usb_rcvbulkpipe(ez->usbdev, ab->ep & 0x7f);
527 if (ab->len > 0 && !access_ok(VERIFY_WRITE, ab->data, ab->len))
528 return -EFAULT;
529 } else
530 pipe = usb_sndbulkpipe(ez->usbdev, ab->ep & 0x7f);
531 if (!usb_maxpacket(ez->usbdev, pipe, !(ab->ep & 0x80)))
532 return -EINVAL;
533 if (!(as = kmalloc(sizeof(struct async), GFP_KERNEL)))
534 return -ENOMEM;
535 INIT_LIST_HEAD(&as->asynclist);
536 as->ez = ez;
537 as->userdata = ab->data;
538 as->numframes = 0;
539 as->data = 0;
540 as->dataorder = 0;
541 as->datalen = ab->len;
542 as->completed.context = ab->context;
543 if (ab->len > 0) {
544 as->dataorder = 1;
545 if (!(as->data = (unsigned char *)__get_free_page(GFP_KERNEL))) {
546 kfree(as);
547 return -ENOMEM;
549 if (!(ab->ep & 0x80)) {
550 if (copy_from_user(as->data, ab->data, ab->len))
551 goto err_fault;
552 as->datalen = 0; /* no need to copy back at completion */
555 async_newpending(as);
556 if (!(as->desc.bulk = usb_request_bulk(ez->usbdev, pipe, async_completed, as->data, ab->len, as))) {
557 async_removelist(as);
558 goto err_inval;
560 return 0;
562 err_fault:
563 if (as) {
564 if (as->data)
565 free_page((unsigned long)as->data);
566 kfree(as);
568 return -EFAULT;
570 err_inval:
571 if (as) {
572 if (as->data)
573 free_page((unsigned long)as->data);
574 kfree(as);
576 return -EINVAL;
579 static int ezusb_requestiso(struct ezusb *ez, struct ezusb_asynciso *ai, unsigned char *cmd)
581 struct async *as;
582 unsigned int maxpkt, pipe;
583 unsigned int dsize, order, assize, j;
584 int i;
586 if ((ai->ep & ~0x80) >= 16 || ai->framecnt < 1 || ai->framecnt > 128)
587 return -EINVAL;
588 if (ai->ep & 0x80)
589 pipe = usb_rcvisocpipe(ez->usbdev, ai->ep & 0x7f);
590 else
591 pipe = usb_sndisocpipe(ez->usbdev, ai->ep & 0x7f);
592 if (!(maxpkt = usb_maxpacket(ez->usbdev, pipe, !(ai->ep & 0x80))))
593 return -EINVAL;
594 dsize = maxpkt * ai->framecnt;
595 if (dsize > 65536)
596 return -EINVAL;
597 order = ld2(dsize >> PAGE_SHIFT);
598 if (dsize > (PAGE_SIZE << order))
599 order++;
600 if (ai->ep & 0x80)
601 if (dsize > 0 && !access_ok(VERIFY_WRITE, ai->data, dsize))
602 return -EFAULT;
603 assize = sizeof(struct async) + ai->framecnt * sizeof(struct ezusb_isoframestat);
604 if (!(as = kmalloc(assize, GFP_KERNEL)))
605 return -ENOMEM;
606 memset(as, 0, assize);
607 INIT_LIST_HEAD(&as->asynclist);
608 as->ez = ez;
609 as->userdata = ai->data;
610 as->numframes = ai->framecnt;
611 as->data = 0;
612 as->dataorder = order;
613 as->datalen = dsize;
614 as->completed.context = ai->context;
615 as->desc.iso = NULL;
616 if (dsize > 0) {
617 if (!(as->data = (unsigned char *)__get_free_pages(GFP_KERNEL, order))) {
618 kfree(as);
619 return -ENOMEM;
621 if (!(ai->ep & 0x80)) {
622 if (copy_from_user(as->data, ai->data, dsize))
623 goto err_fault;
624 as->datalen = 0; /* no need to copy back at completion */
627 if ((i = usb_init_isoc(ez->usbdev, pipe, ai->framecnt, as, &as->desc.iso))) {
628 printk(KERN_DEBUG "ezusb: usb_init_isoc error %d\n", i);
629 goto err_inval;
631 as->desc.iso->start_type = START_ABSOLUTE;
632 as->desc.iso->start_frame = ai->startframe;
633 as->desc.iso->callback_frames = 0;
634 as->desc.iso->callback_fn = async_completed;
635 as->desc.iso->data = as->data;
636 as->desc.iso->buf_size = dsize;
637 for (j = 0; j < ai->framecnt; j++) {
638 if (get_user(i, (int *)(cmd + j * sizeof(struct ezusb_isoframestat)))) {
639 usb_free_isoc(as->desc.iso);
640 kfree(as);
641 return -EFAULT;
643 if (i < 0)
644 i = 0;
645 as->desc.iso->frames[j].frame_length = i;
647 async_newpending(as);
648 if ((i = usb_run_isoc(as->desc.iso, NULL))) {
649 printk(KERN_DEBUG "ezusb: usb_run_isoc error %d\n", i);
650 async_removelist(as);
651 goto err_inval;
653 return 0;
655 err_fault:
656 if (as) {
657 if (as->desc.iso)
658 usb_free_isoc(as->desc.iso);
659 if (as->data)
660 free_page((unsigned long)as->data);
661 kfree(as);
663 return -EFAULT;
665 err_inval:
666 if (as) {
667 if (as->desc.iso)
668 usb_free_isoc(as->desc.iso);
669 if (as->data)
670 free_page((unsigned long)as->data);
671 kfree(as);
673 return -EINVAL;
676 static int ezusb_terminateasync(struct ezusb *ez, void *context)
678 struct async *as;
679 int ret = 0;
681 while ((as = async_getpending(ez, context))) {
682 kill_async(as);
683 ret++;
685 return ret;
688 static int ezusb_asynccompl(struct async *as, void *arg)
690 if (as->datalen > 0) {
691 if (copy_to_user(as->userdata, as->data, as->datalen)) {
692 remove_async(as);
693 return -EFAULT;
696 if (copy_to_user(arg, &as->completed,
697 sizeof(struct ezusb_asynccompleted) +
698 as->numframes * sizeof(struct ezusb_isoframestat))) {
699 remove_async(as);
700 return -EFAULT;
702 remove_async(as);
703 return 0;
706 static int ezusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
708 struct ezusb *ez = (struct ezusb *)file->private_data;
709 DECLARE_WAITQUEUE(wait, current);
710 struct usb_proc_ctrltransfer pctrl;
711 struct usb_proc_bulktransfer pbulk;
712 struct usb_proc_setinterface psetintf;
713 struct ezusb_ctrltransfer ctrl;
714 struct ezusb_bulktransfer bulk;
715 struct ezusb_setinterface setintf;
716 struct ezusb_asyncbulk abulk;
717 struct ezusb_asynciso aiso;
718 struct async *as;
719 void *context;
720 unsigned int ep, cfg;
721 int i, ret = 0;
723 down(&ez->mutex);
724 if (!ez->usbdev) {
725 up(&ez->mutex);
726 return -EIO;
728 switch (cmd) {
729 case USB_PROC_CONTROL:
730 if (copy_from_user(&pctrl, (void *)arg, sizeof(pctrl))) {
731 ret = -EFAULT;
732 break;
734 ret = ezusb_control(ez->usbdev, pctrl.requesttype, pctrl.request,
735 pctrl.value, pctrl.index, pctrl.length, pctrl.data);
736 break;
738 case USB_PROC_BULK:
739 if (copy_from_user(&pbulk, (void *)arg, sizeof(pbulk))) {
740 ret = -EFAULT;
741 break;
743 ret = ezusb_bulk(ez->usbdev, pbulk.ep, pbulk.len, pbulk.data);
744 break;
746 case USB_PROC_RESETEP:
747 if (get_user(ep, (unsigned int *)arg)) {
748 ret = -EFAULT;
749 break;
751 ret = ezusb_resetep(ez->usbdev, ep);
752 break;
754 case USB_PROC_SETINTERFACE:
755 if (copy_from_user(&psetintf, (void *)arg, sizeof(psetintf))) {
756 ret = -EFAULT;
757 break;
759 ret = ezusb_setinterface(ez->usbdev, psetintf.interface, psetintf.altsetting);
760 break;
762 case USB_PROC_SETCONFIGURATION:
763 if (get_user(cfg, (unsigned int *)arg)) {
764 ret = -EFAULT;
765 break;
767 ret = ezusb_setconfiguration(ez->usbdev, cfg);
768 break;
770 case EZUSB_CONTROL:
771 if (copy_from_user(&ctrl, (void *)arg, sizeof(ctrl))) {
772 ret = -EFAULT;
773 break;
775 if (ctrl.dlen != ctrl.length) {
776 ret = -EINVAL;
777 break;
779 ret = ezusb_control(ez->usbdev, ctrl.requesttype, ctrl.request,
780 ctrl.value, ctrl.index, ctrl.length, ctrl.data);
781 break;
783 case EZUSB_BULK:
784 if (copy_from_user(&bulk, (void *)arg, sizeof(bulk))) {
785 ret = -EFAULT;
786 break;
788 ret = ezusb_bulk(ez->usbdev, bulk.ep, bulk.len, bulk.data);
789 break;
791 case EZUSB_RESETEP:
792 if (get_user(ep, (unsigned int *)arg)) {
793 ret = -EFAULT;
794 break;
796 ret = ezusb_resetep(ez->usbdev, ep);
797 break;
799 case EZUSB_SETINTERFACE:
800 if (copy_from_user(&setintf, (void *)arg, sizeof(setintf))) {
801 ret = -EFAULT;
802 break;
804 ret = ezusb_setinterface(ez->usbdev, setintf.interface, setintf.altsetting);
805 break;
807 case EZUSB_SETCONFIGURATION:
808 if (get_user(cfg, (unsigned int *)arg)) {
809 ret = -EFAULT;
810 break;
812 ret = ezusb_setconfiguration(ez->usbdev, cfg);
813 break;
815 case EZUSB_ASYNCCOMPLETED:
816 current->state = TASK_INTERRUPTIBLE;
817 add_wait_queue(&ez->wait, &wait);
818 for (;;) {
819 if (!ez->usbdev)
820 break;
821 if ((as = async_getcompleted(ez)))
822 break;
823 if (signal_pending(current))
824 break;
825 up(&ez->mutex);
826 schedule();
827 down(&ez->mutex);
829 remove_wait_queue(&ez->wait, &wait);
830 current->state = TASK_RUNNING;
831 if (as) {
832 ret = ezusb_asynccompl(as, (void *)arg);
833 break;
835 if (signal_pending(current)) {
836 ret = -EINTR;
837 break;
839 ret = -EIO;
840 break;
842 case EZUSB_ASYNCCOMPLETEDNB:
843 if ((as = async_getcompleted(ez))) {
844 ret = ezusb_asynccompl(as, (void *)arg);
845 break;
847 ret = -EAGAIN;
848 break;
850 case EZUSB_REQUESTBULK:
851 if (copy_from_user(&abulk, (void *)arg, sizeof(abulk))) {
852 ret = -EFAULT;
853 break;
855 ret = ezusb_requestbulk(ez, &abulk);
856 break;
858 case EZUSB_REQUESTISO:
859 if (copy_from_user(&aiso, (void *)arg, sizeof(aiso))) {
860 ret = -EFAULT;
861 break;
863 ret = ezusb_requestiso(ez, &aiso, ((unsigned char *)arg)+sizeof(aiso));
864 break;
866 case EZUSB_TERMINATEASYNC:
867 if (get_user(context, (void **)arg)) {
868 ret = -EFAULT;
869 break;
871 ret = ezusb_terminateasync(ez, context);
872 break;
874 case EZUSB_GETFRAMENUMBER:
875 i = usb_get_current_frame_number(ez->usbdev);
876 ret = put_user(i, (int *)arg);
877 break;
879 default:
880 ret = -ENOIOCTLCMD;
881 break;
883 up(&ez->mutex);
884 return ret;
887 static struct file_operations ezusb_fops = {
888 ezusb_llseek,
889 ezusb_read,
890 ezusb_write,
891 NULL, /* readdir */
892 NULL, /* poll */
893 ezusb_ioctl,
894 NULL, /* mmap */
895 ezusb_open,
896 NULL, /* flush */
897 ezusb_release,
898 NULL, /* fsync */
899 NULL, /* fasync */
900 NULL, /* check_media_change */
901 NULL, /* revalidate */
902 NULL /* lock */
905 static struct miscdevice ezusb_misc = {
906 192, "ezusb", &ezusb_fops
909 /* --------------------------------------------------------------------- */
911 static int ezusb_probe(struct usb_device *usbdev)
913 struct ezusb *ez = &ezusb[0];
914 struct usb_interface_descriptor *interface;
915 struct usb_endpoint_descriptor *endpoint;
917 #undef KERN_DEBUG
918 #define KERN_DEBUG ""
919 printk(KERN_DEBUG "ezusb: probe: vendor id 0x%x, device id 0x%x\n",
920 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
922 /* the 1234:5678 is just a self assigned test ID */
923 if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) &&
924 (usbdev->descriptor.idVendor != 0x1234 || usbdev->descriptor.idProduct != 0x5678))
925 return -1;
927 /* We don't handle multiple configurations */
928 if (usbdev->descriptor.bNumConfigurations != 1)
929 return -1;
931 /* We don't handle multiple interfaces */
932 if (usbdev->config[0].bNumInterfaces != 1)
933 return -1;
935 down(&ez->mutex);
936 if (ez->usbdev) {
937 up(&ez->mutex);
938 printk(KERN_INFO "ezusb: device already used\n");
939 return -1;
941 ez->usbdev = usbdev;
942 usbdev->private = ez;
943 if (usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue) < 0) {
944 printk(KERN_ERR "ezusb: set_configuration failed\n");
945 goto err;
947 interface = &usbdev->config[0].interface[0].altsetting[1];
948 if (usb_set_interface(usbdev, 0, 1) < 0) {
949 printk(KERN_ERR "ezusb: set_interface failed\n");
950 goto err;
952 up(&ez->mutex);
953 MOD_INC_USE_COUNT;
954 return 0;
956 err:
957 up(&ez->mutex);
958 ez->usbdev = NULL;
959 usbdev->private = NULL;
960 return -1;
963 static void ezusb_disconnect(struct usb_device *usbdev)
965 struct ezusb *ez = (struct ezusb *)usbdev->private;
967 down(&ez->mutex);
968 destroy_all_async(ez);
969 ez->usbdev = NULL;
970 up(&ez->mutex);
971 wake_up(&ez->wait);
972 usbdev->private = NULL;
973 MOD_DEC_USE_COUNT;
976 static struct usb_driver ezusb_driver = {
977 "ezusb",
978 ezusb_probe,
979 ezusb_disconnect,
980 { NULL, NULL }
983 /* --------------------------------------------------------------------- */
985 int ezusb_init(void)
987 unsigned u;
989 /* initialize struct */
990 for (u = 0; u < NREZUSB; u++) {
991 init_MUTEX(&ezusb[u].mutex);
992 ezusb[u].usbdev = NULL;
993 INIT_LIST_HEAD(&ezusb[u].async_pending);
994 INIT_LIST_HEAD(&ezusb[u].async_completed);
995 init_waitqueue_head(&ezusb[u].wait);
996 spin_lock_init(&ezusb[u].lock);
998 /* register misc device */
999 if (misc_register(&ezusb_misc)) {
1000 printk(KERN_WARNING "ezusb: cannot register minor %d\n", ezusb_misc.minor);
1001 return -1;
1003 usb_register(&ezusb_driver);
1004 printk(KERN_INFO "ezusb: Anchorchip firmware download driver registered\n");
1005 return 0;
1008 void ezusb_cleanup(void)
1010 usb_deregister(&ezusb_driver);
1011 misc_deregister(&ezusb_misc);
1014 /* --------------------------------------------------------------------- */
1016 #ifdef MODULE
1018 int minor = 192;
1020 int init_module(void)
1022 ezusb_misc.minor = minor;
1023 return ezusb_init();
1026 void cleanup_module(void)
1028 ezusb_cleanup();
1031 #endif
1033 /* --------------------------------------------------------------------- */