7cdb2f07f8b5e77363bc940ee682f13dc01fe9e9
[pintos-anon] / src / devices / usb.c
1 #include "devices/usb.h"
2 #include "devices/usb_hub.h"
3 #include "threads/synch.h"
4 #include "threads/malloc.h"
5 #include "devices/timer.h"
6 #include <kernel/bitmap.h>
7 #include <string.h>
8 #include <stdio.h>
9
10 #define ADDRS_PER_HOST          127     /* number of configurable addresses */
11 #define ADDR_DEFAULT            0       /* default configuration address */
12 #define ADDR_FIRST              1       /* first configurable address */
13
14 /** sometimes used for ''value' */
15 /* used in desc_header */
16 #define SETUP_DESC_DEVICE       1
17 #define SETUP_DESC_CONFIG       2
18 #define SETUP_DESC_STRING       3
19 #define SETUP_DESC_IFACE        4
20 #define SETUP_DESC_ENDPOINT     5
21 #define SETUP_DESC_DEVQUAL      6
22 #define SETUP_DESC_SPDCONFIG    7
23 #define SETUP_DESC_IFACEPWR     8
24
25 #pragma pack(1)
26 struct desc_header
27 {
28   uint8_t length;
29   uint8_t type;
30 };
31
32 /**
33  * More details can be found in chapter 9 of the usb1.1 spec
34  */
35
36 struct device_descriptor
37 {
38   struct desc_header hdr;
39   uint16_t usb_spec;
40   uint8_t dev_class;
41   uint8_t dev_subclass;
42   uint8_t dev_proto;
43   uint8_t max_pktsz;
44   uint16_t vendor_id;
45   uint16_t product_id;
46   uint16_t device_id;
47   uint8_t manufacturer;
48   uint8_t product;
49   uint8_t serial;
50   uint8_t num_configs;
51 };
52
53 struct device_qualifier
54 {
55   uint16_t usb_spec;
56   uint8_t dev_class;
57   uint8_t dev_subclass;
58   uint8_t dev_proto;
59   uint8_t max_pktsz;
60   uint8_t num_configs;
61   uint8_t resv;
62 };
63
64 struct config_descriptor
65 {
66   struct desc_header hdr;
67   uint16_t total_length;
68   uint8_t num_ifaces;
69   uint8_t config_val;
70   uint8_t config_desc;
71   uint8_t attributes;
72   uint8_t max_power;
73 };
74
75 struct interface_descriptor
76 {
77   struct desc_header hdr;
78   uint8_t iface_num;
79   uint8_t alt_setting;
80   uint8_t num_endpoints;
81   uint8_t iface_class;
82   uint8_t iface_subclass;
83   uint8_t iface_proto;
84   uint8_t iface_desc;
85 };
86
87 struct endpoint_descriptor
88 {
89   struct desc_header hdr;
90   /* end point address */
91   uint8_t endpoint_num:4;
92   uint8_t resv1:3;
93   uint8_t direction:1;
94
95   /* attributes */
96   uint8_t transfer:2;
97   uint8_t synch:2;
98   uint8_t usage:2;
99   uint8_t resv2:2;
100
101   uint16_t max_pktsz;
102   uint8_t interval;
103
104 };
105
106 #pragma pack()
107
108 #define USB_CLASS_HUB           0x09
109 struct host
110 {
111   struct usb_host *dev;         /* host driver */
112   host_info info;               /* private to host */
113   struct bitmap *usb_dev_addrs; /* addrs used on device */
114   struct list host_usb_devs;    /* usb devices on host */
115   struct list_elem peers;       /* other hosts on system */
116 };
117
118 struct class
119 {
120   struct usb_class *dev;        /* class driver */
121   struct list usb_ifaces;       /* usb devices on class */
122   struct list_elem peers;
123 };
124
125 static struct list usb_dev_list;        /* list of all usb devices */
126 static struct list class_list;  /* list of all classes */
127 static struct list host_list;   /* list of all hosts on system */
128 static struct lock usb_sys_lock;        /* big usb lock */
129
130 #define usb_lock()              lock_acquire(&usb_sys_lock)
131 #define usb_unlock()            lock_release(&usb_sys_lock)
132
133 static void usb_scan_devices (struct host *h);
134 static struct usb_dev *usb_configure_default (struct host *h);
135 static char *usb_get_string (struct usb_dev *d, int ndx);
136 static struct class *usb_get_class_by_id (int id);
137 static void usb_setup_dev_addr (struct usb_dev *dev);
138 static void usb_config_dev (struct usb_dev *dev, int config_val);
139 static int usb_load_config (struct usb_dev *dev, int idx, void *data,
140                             int dsz);
141 static int usb_tx_all (struct usb_endpoint *eop, void *buf,
142                        int max_bytes, int bailout, bool in);
143 static void usb_attach_interfaces (struct usb_dev *dev);
144 static void usb_apply_class_to_interfaces (struct class *c);
145 static size_t wchar_to_ascii (char *dst, const char *src);
146
147 extern void uhci_init (void);
148 extern void ehci_init (void);
149
150 void
151 usb_init (void)
152 {
153   list_init (&host_list);
154   list_init (&class_list);
155   list_init (&usb_dev_list);
156   lock_init (&usb_sys_lock);
157
158   usb_hub_init ();
159
160   /* add usb hosts */
161   printf ("Initializing EHCI\n");
162   ehci_init ();
163   printf ("Initializing UHCI\n");
164   uhci_init ();
165 }
166
167 /* add host controller device to usb layer */
168 void
169 usb_register_host (struct usb_host *uh, host_info info)
170 {
171   struct host *h;
172
173   h = malloc (sizeof (struct host));
174   h->dev = uh;
175   h->info = info;
176   h->usb_dev_addrs = bitmap_create (ADDRS_PER_HOST);
177   list_init (&h->host_usb_devs);
178
179   usb_lock ();
180   list_push_back (&host_list, &h->peers);
181   usb_unlock ();
182
183   usb_scan_devices (h);
184 }
185
186 int
187 usb_register_class (struct usb_class *uc)
188 {
189   struct class *c;
190
191   usb_lock ();
192
193   /* check to make sure class is not in list */
194   if (usb_get_class_by_id (uc->class_id) != NULL)
195     {
196       usb_unlock ();
197       return -1;
198     }
199
200
201   /* add class to class list */
202   c = malloc (sizeof (struct class));
203   c->dev = uc;
204   list_init (&c->usb_ifaces);
205   list_push_back (&class_list, &c->peers);
206
207   usb_apply_class_to_interfaces (c);
208
209   usb_unlock ();
210
211   return 0;
212 }
213
214 static void
215 usb_scan_devices (struct host *h)
216 {
217   /* scan until there all devices using default pipe are configured */
218
219   printf ("USB: scanning devices...\n");
220   while (1)
221     {
222       struct usb_dev *dev;
223
224       dev = usb_configure_default (h);
225       if (dev == NULL)
226         break;
227
228       if (dev->ignore_device == false)
229         printf ("USB Device %d: %s (%s)\n",
230                 dev->addr, dev->product, dev->manufacturer);
231
232       list_push_back (&h->host_usb_devs, &dev->host_peers);
233       list_push_back (&usb_dev_list, &dev->sys_peers);
234       usb_attach_interfaces (dev);
235     }
236 }
237
238
239 static struct usb_dev *
240 usb_configure_default (struct host *h)
241 {
242   struct usb_dev *dev;
243   struct usb_setup_pkt sp;
244   char data[256];
245   struct device_descriptor *dd;
246   host_dev_info hi;
247   host_eop_info cfg_eop;
248   bool ignore_device = false;
249   int err, sz, txed;
250   int config_val;
251
252   hi = h->dev->create_dev_channel (h->info, ADDR_DEFAULT, USB_VERSION_1_1);
253   cfg_eop = h->dev->create_eop (hi, 0, 64);
254
255   /* determine device descriptor */
256   sp.recipient = USB_SETUP_RECIP_DEV;
257   sp.type = USB_SETUP_TYPE_STD;
258   sp.direction = 1;
259   sp.request = REQ_STD_GET_DESC;
260   sp.value = SETUP_DESC_DEVICE << 8;
261   sp.index = 0;
262   sp.length = sizeof (struct device_descriptor);
263
264   err =
265     h->dev->tx_pkt (cfg_eop, USB_TOKEN_SETUP, &sp, 0, sizeof (sp), NULL,
266                     true);
267   /* did it timeout? - no device */
268   if (err != USB_HOST_ERR_NONE)
269     {
270       h->dev->remove_eop (cfg_eop);
271       h->dev->remove_dev_channel (hi);
272       return NULL;
273     }
274
275   dd = (void *) &data;
276   memset (dd, 0, sizeof (data));
277   txed = 0;
278   h->dev->tx_pkt (cfg_eop, USB_TOKEN_IN, data, 0, sizeof (data) - txed, &sz,
279                   true);
280
281   /* some devices only send 16 bytes for the device descriptor - 
282    * they wind up with a NAK, waiting for another command to be issued
283    *
284   * if it's a 16 byte max packet device, we just take the first 16 bytes */
285
286   if (dd->usb_spec == USB_VERSION_1_0)
287     {
288       /* USB 1.0 devices have strict schedule requirements not yet supported */
289       printf ("USB 1.0 device detected - skipping\n");
290     }
291   else if (sz == 8)
292     {
293       /* read in the full descriptor */
294       txed = sz;
295       while (txed <= 16)
296         {
297           if (h->dev->
298               tx_pkt (cfg_eop, USB_TOKEN_IN, data + txed, 0,
299                       sizeof (data) - txed, &sz, true) != USB_HOST_ERR_NONE)
300             break;
301           txed += sz;
302         }
303     }
304   if (dd->num_configs == 0)
305     ignore_device = true;
306
307   h->dev->remove_eop (cfg_eop);
308   cfg_eop = h->dev->create_eop (hi, 0, dd->max_pktsz);
309
310   /* device exists - create device structure */
311   dev = malloc (sizeof (struct usb_dev));
312   memset (dev, 0, sizeof (struct usb_dev));
313   list_init (&dev->interfaces);
314
315   dev->ignore_device = ignore_device;
316   dev->h_dev = hi;
317   dev->h_cfg_eop = cfg_eop;
318
319   dev->cfg_eop.h_eop = cfg_eop;
320
321   dev->usb_version = dd->usb_spec;
322   dev->default_iface.class_id = dd->dev_class;
323   dev->default_iface.subclass_id = dd->dev_subclass;
324   dev->default_iface.iface_num = 0;
325   dev->default_iface.proto = dd->dev_proto;
326   dev->default_iface.class = NULL;
327   dev->default_iface.c_info = NULL;
328   dev->default_iface.dev = dev;
329
330   dev->cfg_eop.iface = &dev->default_iface;
331   dev->cfg_eop.max_pkt = dd->max_pktsz;
332   dev->cfg_eop.eop = 0;
333
334   dev->host = h;
335
336   dev->vendor_id = dd->vendor_id;
337   dev->product_id = dd->product_id;
338   dev->device_id = dd->device_id;
339
340   if (ignore_device == false)
341     {
342       dev->product = usb_get_string (dev, dd->product);
343       dev->manufacturer = usb_get_string (dev, dd->manufacturer);
344     }
345
346   config_val = -123;
347   /* read in configuration data if there are configurations available */
348   /* (which there should be...) */
349   if (dd->num_configs > 0 && ignore_device == false)
350     {
351       config_val = usb_load_config (dev, 0, data, sizeof (data));
352       if (config_val < 0)
353         {
354           printf
355             ("USB: Invalid configuration value %d on '%s (%s)' (%x,%x,%x)\n",
356              config_val, dev->product, dev->manufacturer, dev->vendor_id,
357              dev->product_id, dev->device_id);
358         }
359     }
360
361   usb_setup_dev_addr (dev);
362
363   usb_config_dev (dev, (config_val < 0) ? 1 : config_val);
364
365   return dev;
366 }
367
368 /**
369  * Load in data for 'idx' configuration into device structure
370  * XXX support multiple configurations
371  */
372 static int
373 usb_load_config (struct usb_dev *dev, int idx, void *data, int dsz)
374 {
375   struct usb_setup_pkt sp;
376   struct config_descriptor *cd;
377   struct host *h;
378   host_eop_info cfg;
379   void *ptr;
380   int config_val, err, sz;
381   int i;
382
383   h = dev->host;
384   cfg = dev->h_cfg_eop;
385
386   sp.recipient = USB_SETUP_RECIP_DEV;
387   sp.type = USB_SETUP_TYPE_STD;
388   sp.direction = 1;
389   sp.request = REQ_STD_GET_DESC;
390   sp.value = SETUP_DESC_CONFIG << 8 | idx;
391   sp.index = 0;
392   sp.length = dsz;
393   cd = data;
394
395   err = h->dev->tx_pkt (cfg, USB_TOKEN_SETUP, &sp, 0, sizeof (sp), &sz, true);
396   if (err != USB_HOST_ERR_NONE)
397     {
398       printf ("USB: Could not setup GET descriptor\n");
399       return -err;
400     }
401
402   sz = usb_tx_all (&dev->cfg_eop, cd, dsz,
403                    sizeof (struct config_descriptor), true);
404   if (sz < sizeof (struct config_descriptor))
405     {
406       printf ("USB: Did not rx GET descriptor (%d bytes, expected %d)\n", sz,
407               sizeof (struct config_descriptor));
408       return -err;
409     }
410
411   if (sz == 0 || cd->hdr.type != SETUP_DESC_CONFIG)
412     {
413       printf ("USB: Invalid descriptor\n");
414       return -1;
415     }
416
417   if (sz < cd->total_length)
418     sz += usb_tx_all (&dev->cfg_eop, data+sz, dsz, cd->total_length - sz, true);
419
420   dev->pwr = cd->max_power;
421
422   /* interface information comes right after config data */
423   /* scan interfaces */
424   ptr = data + sizeof (struct config_descriptor);
425
426   for (i = 0; i < cd->num_ifaces; i++)
427     {
428       struct interface_descriptor *iface;
429       struct usb_iface *ui;
430       int j;
431
432       iface = ptr;
433       if (iface->hdr.type != SETUP_DESC_IFACE)
434         {
435           hex_dump (0, iface, 64, false);
436           PANIC ("Expected %d, found %d\n", SETUP_DESC_IFACE,
437                  iface->hdr.type);
438         }
439
440       ui = malloc (sizeof (struct usb_iface));
441       ui->class_id = iface->iface_class;
442       ui->subclass_id = iface->iface_subclass;
443       ui->iface_num = iface->iface_num;
444       ui->proto = iface->iface_proto;
445       ui->class = NULL;
446       ui->c_info = NULL;
447       ui->dev = dev;
448       list_init (&ui->endpoints);
449
450       /* endpoint data comes after interfaces */
451       /* scan endpoints */
452       ptr += sizeof (struct interface_descriptor);
453       for (j = 0; j < iface->num_endpoints;
454            j++, ptr += sizeof (struct endpoint_descriptor))
455         {
456           struct usb_endpoint *ue;
457           struct endpoint_descriptor *ed;
458
459           ed = ptr;
460
461           ue = malloc (sizeof (struct usb_endpoint));
462           ue->eop = ed->endpoint_num;
463           ue->direction = ed->direction;
464           ue->attr = ed->transfer;
465           ue->max_pkt = ed->max_pktsz;
466           ue->interval = ed->interval;
467           ue->iface = ui;
468           ue->h_eop = h->dev->create_eop (dev->h_dev, ue->eop, ue->max_pkt);
469
470           list_push_back (&ui->endpoints, &ue->peers);
471         }
472
473       list_push_back (&dev->interfaces, &ui->peers);
474     }
475
476   config_val = cd->config_val;
477
478   return config_val;
479 }
480
481 /**
482  * Set USB device configuration to desired configuration value
483  */
484 static void
485 usb_config_dev (struct usb_dev *dev, int config_val)
486 {
487   struct usb_setup_pkt sp;
488   struct host *h;
489   host_eop_info cfg;
490   int err;
491
492   h = dev->host;
493   cfg = dev->h_cfg_eop;
494
495   sp.recipient = USB_SETUP_RECIP_DEV;
496   sp.type = USB_SETUP_TYPE_STD;
497   sp.direction = 0;
498   sp.request = REQ_STD_SET_CONFIG;
499   sp.value = config_val;
500   sp.index = 0;
501   sp.length = 0;
502   err = h->dev->tx_pkt (cfg, USB_TOKEN_SETUP, &sp, 0, sizeof (sp), NULL, true);
503   if (err != USB_HOST_ERR_NONE)
504     PANIC ("USB: Config setup packet did not tx\n");
505
506   err = h->dev->tx_pkt (cfg, USB_TOKEN_IN, NULL, 0, 0, NULL, true);
507   if (err != USB_HOST_ERR_NONE)
508     PANIC ("USB: Could not configure device!\n");
509 }
510
511 /**
512  * Set a device address to something other than the default pipe 
513  */
514 static void
515 usb_setup_dev_addr (struct usb_dev *dev)
516 {
517   struct usb_setup_pkt sp;
518   struct host *h;
519   host_eop_info cfg;
520   int err;
521
522   ASSERT (dev->addr == 0);
523
524   h = dev->host;
525   cfg = dev->h_cfg_eop;
526
527   dev->addr = bitmap_scan_and_flip (h->usb_dev_addrs, 1, 1, false);
528
529   sp.recipient = USB_SETUP_RECIP_DEV;
530   sp.type = USB_SETUP_TYPE_STD;
531   sp.direction = 0;
532   sp.request = REQ_STD_SET_ADDRESS;
533   sp.value = dev->addr;
534   sp.index = 0;
535   sp.length = 0;
536   err =
537     h->dev->tx_pkt (cfg, USB_TOKEN_SETUP, &sp, 0, sizeof (sp), NULL, true);
538   if (err != USB_HOST_ERR_NONE)
539     {
540       PANIC ("USB: WHOOPS!!!!!!!\n");
541     }
542   err = h->dev->tx_pkt (cfg, USB_TOKEN_IN, NULL, 0, 0, NULL, true);
543   if (err != USB_HOST_ERR_NONE)
544     {
545       PANIC ("USB: Error on setting device address (err = %d)\n", err);
546     }
547
548   h->dev->modify_dev_channel (dev->h_dev, dev->addr, dev->usb_version);
549 }
550
551 #define MAX_USB_STR     128
552 /* read string by string descriptor index from usb device */
553 static char *
554 usb_get_string (struct usb_dev *udev, int ndx)
555 {
556   struct usb_setup_pkt sp;
557   char str[MAX_USB_STR];
558   char *ret;
559   int sz;
560
561   sp.recipient = USB_SETUP_RECIP_DEV;
562   sp.type = USB_SETUP_TYPE_STD;
563   sp.direction = 1;
564   sp.request = REQ_STD_GET_DESC;
565   sp.value = (SETUP_DESC_STRING << 8) | ndx;
566   sp.index = 0;
567   sp.length = MAX_USB_STR;
568   udev->host->dev->tx_pkt (udev->h_cfg_eop, USB_TOKEN_SETUP,
569                            &sp, 0, sizeof (sp), NULL, false);
570   sz = usb_tx_all (&udev->cfg_eop, &str, MAX_USB_STR, 2, true);
571   sz +=
572     usb_tx_all (&udev->cfg_eop, str + sz, (uint8_t) (str[0]) - sz, 0, true);
573
574   /* string failed to tx? */
575   if (sz == 0)
576     return NULL;
577
578   /* some devices don't respect the string descriptor length value (str[0]) 
579    * and just send any old value they want, so we can't use it */
580
581   str[(sz < (MAX_USB_STR - 1)) ? (sz) : (MAX_USB_STR - 1)] = '\0';
582
583   /* usb uses wchars for strings, convert to ASCII */
584   wchar_to_ascii (str, str + 2);
585   ret = malloc (strlen (str) + 1);
586   strlcpy (ret, str, MAX_USB_STR);
587   return ret;
588 }
589
590 static struct class *
591 usb_get_class_by_id (int id)
592 {
593   struct list_elem *li;
594
595   li = list_begin (&class_list);
596   while (li != list_end (&class_list))
597     {
598       struct class *c;
599       c = list_entry (li, struct class, peers);
600       if (c->dev->class_id == id)
601         return c;
602       li = list_next (li);
603     }
604
605   return NULL;
606 }
607
608 /**
609  * Asssociate interfaces on a device with their respective device classes
610  */
611 static void
612 usb_attach_interfaces (struct usb_dev *dev)
613 {
614
615   struct list_elem *li;
616   li = list_begin (&dev->interfaces);
617   while (li != list_end (&dev->interfaces))
618     {
619       struct class *cl;
620       struct usb_iface *ui;
621
622       ui = list_entry (li, struct usb_iface, peers);
623       li = list_next (li);
624       cl = usb_get_class_by_id (ui->class_id);
625
626       /* no matching class? try next interface */
627       if (cl == NULL)
628         continue;
629
630       ui->c_info = cl->dev->attached (ui);
631       /* did class driver initialize it OK? */
632       if (ui->c_info != NULL)
633         {
634           /* yes, add to list of usable interfaces */
635           list_push_back (&cl->usb_ifaces, &ui->class_peers);
636           ui->class = cl;
637         }
638     }
639 }
640
641 /**
642  * Scan all interfaces for interfaces that match class's class id
643  * Attach interfaces that match
644  */
645 static void
646 usb_apply_class_to_interfaces (struct class *c)
647 {
648   struct list_elem *li;
649
650   li = list_begin (&usb_dev_list);
651   while (li != list_end (&usb_dev_list))
652     {
653       struct usb_dev *ud;
654       struct list_elem *lii;
655
656       ud = list_entry (li, struct usb_dev, sys_peers);
657
658       lii = list_begin (&ud->interfaces);
659       while (lii != list_end (&ud->interfaces))
660         {
661           struct usb_iface *ui;
662
663           ui = list_entry (lii, struct usb_iface, peers);
664
665           lii = list_next (lii);
666           if (ui->class_id != c->dev->class_id)
667             continue;
668
669           ui->c_info = c->dev->attached (ui);
670           if (ui->c_info == NULL)
671             continue;
672
673           list_push_back (&c->usb_ifaces, &ui->class_peers);
674           ui->class = c;
675         }
676
677       li = list_next (li);
678     }
679 }
680
681 int
682 usb_dev_bulk (struct usb_endpoint *eop, void *buf, int sz, int *tx)
683 {
684   struct host *h;
685   int err;
686   int token;
687
688   ASSERT (eop != NULL);
689   h = eop->iface->dev->host;
690
691   if (eop->direction == 0)
692     token = USB_TOKEN_OUT;
693   else
694     token = USB_TOKEN_IN;
695
696   err = h->dev->tx_pkt (eop->h_eop, token, buf, sz, sz, tx, true);
697
698   return err;
699 }
700
701 int
702 usb_dev_setup (struct usb_endpoint *eop, bool in,
703                struct usb_setup_pkt *s, void *buf, int sz)
704 {
705   struct host *h;
706   int err;
707
708   ASSERT (eop != NULL);
709   h = eop->iface->dev->host;
710
711   err = h->dev->tx_pkt (eop->h_eop, USB_TOKEN_SETUP, s,
712                         0, sizeof (struct usb_setup_pkt), NULL, true);
713   if (err != USB_HOST_ERR_NONE)
714     {
715       printf ("usb_dev_setup: failed\n");
716       return 0;
717     }
718
719   err = h->dev->tx_pkt (eop->h_eop, (in) ? USB_TOKEN_IN : USB_TOKEN_OUT,
720                         buf, 0, sz, &sz, true);
721
722   return sz;
723 }
724
725 /** convert a wchar string to ascii in place */
726 static size_t
727 wchar_to_ascii (char *dst, const char *src)
728 {
729   size_t sz = 0;
730   for (sz = 0; src[sz * 2] != '\0'; sz++)
731     {
732       dst[sz] = src[sz * 2];
733     }
734   dst[sz] = '\0';
735   return sz;
736 }
737
738 /* this is used for variable sized transfers where a normal bulk transfer would 
739    probably fail, since it expects some minimum size - we just want to 
740    read/write as much to the pipe as we can
741  */
742 static int
743 usb_tx_all (struct usb_endpoint *eop, void *buf,
744             int max_bytes, int bailout, bool in)
745 {
746   int txed;
747   int token;
748   int prev_sz = 0;
749   struct host *h;
750
751   if (max_bytes <= 0)
752     return 0;
753
754   if (bailout == 0)
755     bailout = 512;
756
757   txed = 0;
758   token = (in) ? USB_TOKEN_IN : USB_TOKEN_OUT;
759   h = eop->iface->dev->host;
760   while (txed < max_bytes && txed < bailout)
761     {
762       int sz, err;
763       sz = 0;
764       err = h->dev->tx_pkt (eop->h_eop, token,
765                             buf + txed, 0, max_bytes - txed, &sz, true);
766       if (prev_sz == 0)
767         prev_sz = sz;
768       txed += sz;
769       /* this should probably be using short packet detection */
770       if (err != USB_HOST_ERR_NONE || sz != prev_sz || sz == 0)
771         {
772           return txed;
773         }
774     }
775   return txed;
776 }