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