xref: /qemu/hw/usb/core.c (revision 92414fdca00c1746b950a45f4bc76796239d18aa)
1 /*
2  * QEMU USB emulation
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25 
26 void usb_attach(USBPort *port, USBDevice *dev)
27 {
28     port->attach(port, dev);
29 }
30 
31 /**********************/
32 /* generic USB device helpers (you are not forced to use them when
33    writing your USB device driver, but they help handling the
34    protocol)
35 */
36 
37 #define SETUP_STATE_IDLE 0
38 #define SETUP_STATE_DATA 1
39 #define SETUP_STATE_ACK  2
40 
41 int usb_generic_handle_packet(USBDevice *s, int pid,
42                               uint8_t devaddr, uint8_t devep,
43                               uint8_t *data, int len)
44 {
45     int l, ret = 0;
46 
47     switch(pid) {
48     case USB_MSG_ATTACH:
49         s->state = USB_STATE_ATTACHED;
50         break;
51     case USB_MSG_DETACH:
52         s->state = USB_STATE_NOTATTACHED;
53         break;
54     case USB_MSG_RESET:
55         s->remote_wakeup = 0;
56         s->addr = 0;
57         s->state = USB_STATE_DEFAULT;
58         s->handle_reset(s);
59         break;
60     case USB_TOKEN_SETUP:
61         if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
62             return USB_RET_NODEV;
63         if (len != 8)
64             goto fail;
65         memcpy(s->setup_buf, data, 8);
66         s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
67         s->setup_index = 0;
68         if (s->setup_buf[0] & USB_DIR_IN) {
69             ret = s->handle_control(s,
70                                     (s->setup_buf[0] << 8) | s->setup_buf[1],
71                                     (s->setup_buf[3] << 8) | s->setup_buf[2],
72                                     (s->setup_buf[5] << 8) | s->setup_buf[4],
73                                     s->setup_len,
74                                     s->data_buf);
75             if (ret < 0)
76                 return ret;
77             if (ret < s->setup_len)
78                 s->setup_len = ret;
79             s->setup_state = SETUP_STATE_DATA;
80         } else {
81             if (s->setup_len == 0)
82                 s->setup_state = SETUP_STATE_ACK;
83             else
84                 s->setup_state = SETUP_STATE_DATA;
85         }
86         break;
87     case USB_TOKEN_IN:
88         if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
89             return USB_RET_NODEV;
90         switch(devep) {
91         case 0:
92             switch(s->setup_state) {
93             case SETUP_STATE_ACK:
94                 s->setup_state = SETUP_STATE_IDLE;
95                 if (!(s->setup_buf[0] & USB_DIR_IN)) {
96                     ret = s->handle_control(s,
97                                       (s->setup_buf[0] << 8) | s->setup_buf[1],
98                                       (s->setup_buf[3] << 8) | s->setup_buf[2],
99                                       (s->setup_buf[5] << 8) | s->setup_buf[4],
100                                       s->setup_len,
101                                       s->data_buf);
102                     if (ret > 0)
103                         ret = 0;
104                 } else {
105                     goto fail;
106                 }
107                 break;
108             case SETUP_STATE_DATA:
109                 if (s->setup_buf[0] & USB_DIR_IN) {
110                     l = s->setup_len - s->setup_index;
111                     if (l > len)
112                         l = len;
113                     memcpy(data, s->data_buf + s->setup_index, l);
114                     s->setup_index += l;
115                     if (s->setup_index >= s->setup_len)
116                         s->setup_state = SETUP_STATE_ACK;
117                     ret = l;
118                 } else {
119                     s->setup_state = SETUP_STATE_IDLE;
120                     goto fail;
121                 }
122                 break;
123             default:
124                 goto fail;
125             }
126             break;
127         default:
128             ret = s->handle_data(s, pid, devep, data, len);
129             break;
130         }
131         break;
132     case USB_TOKEN_OUT:
133         if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
134             return USB_RET_NODEV;
135         switch(devep) {
136         case 0:
137             switch(s->setup_state) {
138             case SETUP_STATE_ACK:
139                 s->setup_state = SETUP_STATE_IDLE;
140                 if (s->setup_buf[0] & USB_DIR_IN) {
141                     /* transfer OK */
142                 } else {
143                     goto fail;
144                 }
145                 break;
146             case SETUP_STATE_DATA:
147                 if (!(s->setup_buf[0] & USB_DIR_IN)) {
148                     l = s->setup_len - s->setup_index;
149                     if (l > len)
150                         l = len;
151                     memcpy(s->data_buf + s->setup_index, data, l);
152                     s->setup_index += l;
153                     if (s->setup_index >= s->setup_len)
154                         s->setup_state = SETUP_STATE_ACK;
155                     ret = l;
156                 } else {
157                     s->setup_state = SETUP_STATE_IDLE;
158                     goto fail;
159                 }
160                 break;
161             default:
162                 goto fail;
163             }
164             break;
165         default:
166             ret = s->handle_data(s, pid, devep, data, len);
167             break;
168         }
169         break;
170     default:
171     fail:
172         ret = USB_RET_STALL;
173         break;
174     }
175     return ret;
176 }
177 
178 /* XXX: fix overflow */
179 int set_usb_string(uint8_t *buf, const char *str)
180 {
181     int len, i;
182     uint8_t *q;
183 
184     q = buf;
185     len = strlen(str);
186     *q++ = 2 * len + 1;
187     *q++ = 3;
188     for(i = 0; i < len; i++) {
189         *q++ = str[i];
190         *q++ = 0;
191     }
192     return q - buf;
193 }
194 
195 /**********************/
196 /* USB hub emulation */
197 
198 //#define DEBUG
199 
200 #define MAX_PORTS 8
201 
202 typedef struct USBHubPort {
203     USBPort port;
204     USBDevice *dev;
205     uint16_t wPortStatus;
206     uint16_t wPortChange;
207 } USBHubPort;
208 
209 typedef struct USBHubState {
210     USBDevice dev;
211     int nb_ports;
212     USBHubPort ports[MAX_PORTS];
213 } USBHubState;
214 
215 #define ClearHubFeature		(0x2000 | USB_REQ_CLEAR_FEATURE)
216 #define ClearPortFeature	(0x2300 | USB_REQ_CLEAR_FEATURE)
217 #define GetHubDescriptor	(0xa000 | USB_REQ_GET_DESCRIPTOR)
218 #define GetHubStatus		(0xa000 | USB_REQ_GET_STATUS)
219 #define GetPortStatus		(0xa300 | USB_REQ_GET_STATUS)
220 #define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
221 #define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)
222 
223 #define PORT_STAT_CONNECTION	0x0001
224 #define PORT_STAT_ENABLE	0x0002
225 #define PORT_STAT_SUSPEND	0x0004
226 #define PORT_STAT_OVERCURRENT	0x0008
227 #define PORT_STAT_RESET		0x0010
228 #define PORT_STAT_POWER		0x0100
229 #define PORT_STAT_LOW_SPEED	0x0200
230 #define PORT_STAT_HIGH_SPEED    0x0400
231 #define PORT_STAT_TEST          0x0800
232 #define PORT_STAT_INDICATOR     0x1000
233 
234 #define PORT_STAT_C_CONNECTION	0x0001
235 #define PORT_STAT_C_ENABLE	0x0002
236 #define PORT_STAT_C_SUSPEND	0x0004
237 #define PORT_STAT_C_OVERCURRENT	0x0008
238 #define PORT_STAT_C_RESET	0x0010
239 
240 #define PORT_CONNECTION	        0
241 #define PORT_ENABLE		1
242 #define PORT_SUSPEND		2
243 #define PORT_OVERCURRENT	3
244 #define PORT_RESET		4
245 #define PORT_POWER		8
246 #define PORT_LOWSPEED		9
247 #define PORT_HIGHSPEED		10
248 #define PORT_C_CONNECTION	16
249 #define PORT_C_ENABLE		17
250 #define PORT_C_SUSPEND		18
251 #define PORT_C_OVERCURRENT	19
252 #define PORT_C_RESET		20
253 #define PORT_TEST               21
254 #define PORT_INDICATOR          22
255 
256 /* same as Linux kernel root hubs */
257 
258 static const uint8_t qemu_hub_dev_descriptor[] = {
259 	0x12,       /*  u8 bLength; */
260 	0x01,       /*  u8 bDescriptorType; Device */
261 	0x10, 0x01, /*  u16 bcdUSB; v1.1 */
262 
263 	0x09,	    /*  u8  bDeviceClass; HUB_CLASSCODE */
264 	0x00,	    /*  u8  bDeviceSubClass; */
265 	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
266 	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
267 
268 	0x00, 0x00, /*  u16 idVendor; */
269  	0x00, 0x00, /*  u16 idProduct; */
270 	0x01, 0x01, /*  u16 bcdDevice */
271 
272 	0x03,       /*  u8  iManufacturer; */
273 	0x02,       /*  u8  iProduct; */
274 	0x01,       /*  u8  iSerialNumber; */
275 	0x01        /*  u8  bNumConfigurations; */
276 };
277 
278 /* XXX: patch interrupt size */
279 static const uint8_t qemu_hub_config_descriptor[] = {
280 
281 	/* one configuration */
282 	0x09,       /*  u8  bLength; */
283 	0x02,       /*  u8  bDescriptorType; Configuration */
284 	0x19, 0x00, /*  u16 wTotalLength; */
285 	0x01,       /*  u8  bNumInterfaces; (1) */
286 	0x01,       /*  u8  bConfigurationValue; */
287 	0x00,       /*  u8  iConfiguration; */
288 	0xc0,       /*  u8  bmAttributes;
289 				 Bit 7: must be set,
290 				     6: Self-powered,
291 				     5: Remote wakeup,
292 				     4..0: resvd */
293 	0x00,       /*  u8  MaxPower; */
294 
295 	/* USB 1.1:
296 	 * USB 2.0, single TT organization (mandatory):
297 	 *	one interface, protocol 0
298 	 *
299 	 * USB 2.0, multiple TT organization (optional):
300 	 *	two interfaces, protocols 1 (like single TT)
301 	 *	and 2 (multiple TT mode) ... config is
302 	 *	sometimes settable
303 	 *	NOT IMPLEMENTED
304 	 */
305 
306 	/* one interface */
307 	0x09,       /*  u8  if_bLength; */
308 	0x04,       /*  u8  if_bDescriptorType; Interface */
309 	0x00,       /*  u8  if_bInterfaceNumber; */
310 	0x00,       /*  u8  if_bAlternateSetting; */
311 	0x01,       /*  u8  if_bNumEndpoints; */
312 	0x09,       /*  u8  if_bInterfaceClass; HUB_CLASSCODE */
313 	0x00,       /*  u8  if_bInterfaceSubClass; */
314 	0x00,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
315 	0x00,       /*  u8  if_iInterface; */
316 
317 	/* one endpoint (status change endpoint) */
318 	0x07,       /*  u8  ep_bLength; */
319 	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
320 	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
321  	0x03,       /*  u8  ep_bmAttributes; Interrupt */
322  	0x02, 0x00, /*  u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
323 	0xff        /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
324 };
325 
326 static const uint8_t qemu_hub_hub_descriptor[] =
327 {
328 	0x09,			/*  u8  bLength; */
329 	0x29,			/*  u8  bDescriptorType; Hub-descriptor */
330 	0x00,			/*  u8  bNbrPorts; (patched later) */
331 	0x0a,			/* u16  wHubCharacteristics; */
332 	0x00,			/*   (per-port OC, no power switching) */
333 	0x01,			/*  u8  bPwrOn2pwrGood; 2ms */
334 	0x00,			/*  u8  bHubContrCurrent; 0 mA */
335 	0x00,			/*  u8  DeviceRemovable; *** 7 Ports max *** */
336 	0xff			/*  u8  PortPwrCtrlMask; *** 7 ports max *** */
337 };
338 
339 static void usb_hub_attach(USBPort *port1, USBDevice *dev)
340 {
341     USBHubState *s = port1->opaque;
342     USBHubPort *port = &s->ports[port1->index];
343 
344     if (dev) {
345         if (port->dev)
346             usb_attach(port1, NULL);
347 
348         port->wPortStatus |= PORT_STAT_CONNECTION;
349         port->wPortChange |= PORT_STAT_C_CONNECTION;
350         if (dev->speed == USB_SPEED_LOW)
351             port->wPortStatus |= PORT_STAT_LOW_SPEED;
352         else
353             port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
354         port->dev = dev;
355     } else {
356         dev = port->dev;
357         if (dev) {
358             port->wPortStatus &= ~PORT_STAT_CONNECTION;
359             port->wPortChange |= PORT_STAT_C_CONNECTION;
360             if (port->wPortStatus & PORT_STAT_ENABLE) {
361                 port->wPortStatus &= ~PORT_STAT_ENABLE;
362                 port->wPortChange |= PORT_STAT_C_ENABLE;
363             }
364             port->dev = NULL;
365         }
366     }
367 }
368 
369 static void usb_hub_handle_reset(USBDevice *dev)
370 {
371     /* XXX: do it */
372 }
373 
374 static int usb_hub_handle_control(USBDevice *dev, int request, int value,
375                                   int index, int length, uint8_t *data)
376 {
377     USBHubState *s = (USBHubState *)dev;
378     int ret;
379 
380     switch(request) {
381     case DeviceRequest | USB_REQ_GET_STATUS:
382         data[0] = (1 << USB_DEVICE_SELF_POWERED) |
383             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
384         data[1] = 0x00;
385         ret = 2;
386         break;
387     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
388         if (value == USB_DEVICE_REMOTE_WAKEUP) {
389             dev->remote_wakeup = 0;
390         } else {
391             goto fail;
392         }
393         ret = 0;
394         break;
395     case DeviceOutRequest | USB_REQ_SET_FEATURE:
396         if (value == USB_DEVICE_REMOTE_WAKEUP) {
397             dev->remote_wakeup = 1;
398         } else {
399             goto fail;
400         }
401         ret = 0;
402         break;
403     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
404         dev->addr = value;
405         ret = 0;
406         break;
407     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
408         switch(value >> 8) {
409         case USB_DT_DEVICE:
410             memcpy(data, qemu_hub_dev_descriptor,
411                    sizeof(qemu_hub_dev_descriptor));
412             ret = sizeof(qemu_hub_dev_descriptor);
413             break;
414         case USB_DT_CONFIG:
415             memcpy(data, qemu_hub_config_descriptor,
416                    sizeof(qemu_hub_config_descriptor));
417             ret = sizeof(qemu_hub_config_descriptor);
418             break;
419         case USB_DT_STRING:
420             switch(value & 0xff) {
421             case 0:
422                 /* language ids */
423                 data[0] = 4;
424                 data[1] = 3;
425                 data[2] = 0x09;
426                 data[3] = 0x04;
427                 ret = 4;
428                 break;
429             case 1:
430                 /* serial number */
431                 ret = set_usb_string(data, "314159");
432                 break;
433             case 2:
434                 /* product description */
435                 ret = set_usb_string(data, "QEMU USB Hub");
436                 break;
437             case 3:
438                 /* vendor description */
439                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
440                 break;
441             default:
442                 goto fail;
443             }
444             break;
445         default:
446             goto fail;
447         }
448         break;
449     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
450         data[0] = 1;
451         ret = 1;
452         break;
453     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
454         ret = 0;
455         break;
456     case DeviceRequest | USB_REQ_GET_INTERFACE:
457         data[0] = 0;
458         ret = 1;
459         break;
460     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
461         ret = 0;
462         break;
463         /* usb specific requests */
464     case GetHubStatus:
465         data[0] = 0;
466         data[1] = 0;
467         data[2] = 0;
468         data[3] = 0;
469         ret = 4;
470         break;
471     case GetPortStatus:
472         {
473             unsigned int n = index - 1;
474             USBHubPort *port;
475             if (n >= s->nb_ports)
476                 goto fail;
477             port = &s->ports[n];
478             data[0] = port->wPortStatus;
479             data[1] = port->wPortStatus >> 8;
480             data[2] = port->wPortChange;
481             data[3] = port->wPortChange >> 8;
482             ret = 4;
483         }
484         break;
485     case SetHubFeature:
486     case ClearHubFeature:
487         if (value == 0 || value == 1) {
488         } else {
489             goto fail;
490         }
491         ret = 0;
492         break;
493     case SetPortFeature:
494         {
495             unsigned int n = index - 1;
496             USBHubPort *port;
497             USBDevice *dev;
498             if (n >= s->nb_ports)
499                 goto fail;
500             port = &s->ports[n];
501             dev = port->dev;
502             switch(value) {
503             case PORT_SUSPEND:
504                 port->wPortStatus |= PORT_STAT_SUSPEND;
505                 break;
506             case PORT_RESET:
507                 if (dev) {
508                     dev->handle_packet(dev,
509                                        USB_MSG_RESET, 0, 0, NULL, 0);
510                     port->wPortChange |= PORT_STAT_C_RESET;
511                     /* set enable bit */
512                     port->wPortChange |= PORT_STAT_C_ENABLE;
513                     port->wPortStatus |= PORT_STAT_ENABLE;
514                 }
515                 break;
516             case PORT_POWER:
517                 break;
518             default:
519                 goto fail;
520             }
521             ret = 0;
522         }
523         break;
524     case ClearPortFeature:
525         {
526             unsigned int n = index - 1;
527             USBHubPort *port;
528             USBDevice *dev;
529             if (n >= s->nb_ports)
530                 goto fail;
531             port = &s->ports[n];
532             dev = port->dev;
533             switch(value) {
534             case PORT_ENABLE:
535                 port->wPortStatus &= ~PORT_STAT_ENABLE;
536                 break;
537             case PORT_C_ENABLE:
538                 port->wPortChange &= ~PORT_STAT_C_ENABLE;
539                 break;
540             case PORT_SUSPEND:
541                 port->wPortStatus &= ~PORT_STAT_SUSPEND;
542                 break;
543             case PORT_C_SUSPEND:
544                 port->wPortChange &= ~PORT_STAT_C_SUSPEND;
545                 break;
546             case PORT_C_CONNECTION:
547                 port->wPortChange &= ~PORT_STAT_C_CONNECTION;
548                 break;
549             case PORT_C_OVERCURRENT:
550                 port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
551                 break;
552             case PORT_C_RESET:
553                 port->wPortChange &= ~PORT_STAT_C_RESET;
554                 break;
555             default:
556                 goto fail;
557             }
558             ret = 0;
559         }
560         break;
561     case GetHubDescriptor:
562         memcpy(data, qemu_hub_hub_descriptor,
563                sizeof(qemu_hub_hub_descriptor));
564         data[2] = s->nb_ports;
565         ret = sizeof(qemu_hub_hub_descriptor);
566         break;
567     default:
568     fail:
569         ret = USB_RET_STALL;
570         break;
571     }
572     return ret;
573 }
574 
575 static int usb_hub_handle_data(USBDevice *dev, int pid,
576                                uint8_t devep, uint8_t *data, int len)
577 {
578     USBHubState *s = (USBHubState *)dev;
579     int ret;
580 
581     switch(pid) {
582     case USB_TOKEN_IN:
583         if (devep == 1) {
584             USBHubPort *port;
585             unsigned int status;
586             int i, n;
587             n = (s->nb_ports + 1 + 7) / 8;
588             if (n > len)
589                 return USB_RET_BABBLE;
590             status = 0;
591             for(i = 0; i < s->nb_ports; i++) {
592                 port = &s->ports[i];
593                 if (port->wPortChange)
594                     status |= (1 << (i + 1));
595             }
596             if (status != 0) {
597                 for(i = 0; i < n; i++) {
598                     data[i] = status >> (8 * i);
599                 }
600                 ret = n;
601             } else {
602                 ret = 0;
603             }
604         } else {
605             goto fail;
606         }
607         break;
608     case USB_TOKEN_OUT:
609     default:
610     fail:
611         ret = USB_RET_STALL;
612         break;
613     }
614     return ret;
615 }
616 
617 static int usb_hub_broadcast_packet(USBHubState *s, int pid,
618                                     uint8_t devaddr, uint8_t devep,
619                                     uint8_t *data, int len)
620 {
621     USBHubPort *port;
622     USBDevice *dev;
623     int i, ret;
624 
625     for(i = 0; i < s->nb_ports; i++) {
626         port = &s->ports[i];
627         dev = port->dev;
628         if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
629             ret = dev->handle_packet(dev, pid,
630                                      devaddr, devep,
631                                      data, len);
632             if (ret != USB_RET_NODEV) {
633                 return ret;
634             }
635         }
636     }
637     return USB_RET_NODEV;
638 }
639 
640 static int usb_hub_handle_packet(USBDevice *dev, int pid,
641                                  uint8_t devaddr, uint8_t devep,
642                                  uint8_t *data, int len)
643 {
644     USBHubState *s = (USBHubState *)dev;
645 
646 #if defined(DEBUG) && 0
647     printf("usb_hub: pid=0x%x\n", pid);
648 #endif
649     if (dev->state == USB_STATE_DEFAULT &&
650         dev->addr != 0 &&
651         devaddr != dev->addr &&
652         (pid == USB_TOKEN_SETUP ||
653          pid == USB_TOKEN_OUT ||
654          pid == USB_TOKEN_IN)) {
655         /* broadcast the packet to the devices */
656         return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
657     }
658     return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
659 }
660 
661 USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports)
662 {
663     USBHubState *s;
664     USBHubPort *port;
665     int i;
666 
667     if (nb_ports > MAX_PORTS)
668         return NULL;
669     s = qemu_mallocz(sizeof(USBHubState));
670     if (!s)
671         return NULL;
672     s->dev.speed = USB_SPEED_FULL;
673     s->dev.handle_packet = usb_hub_handle_packet;
674 
675     /* generic USB device init */
676     s->dev.handle_reset = usb_hub_handle_reset;
677     s->dev.handle_control = usb_hub_handle_control;
678     s->dev.handle_data = usb_hub_handle_data;
679 
680     s->nb_ports = nb_ports;
681     for(i = 0; i < s->nb_ports; i++) {
682         port = &s->ports[i];
683         port->wPortStatus = PORT_STAT_POWER;
684         port->wPortChange = 0;
685         port->port.attach = usb_hub_attach;
686         port->port.opaque = s;
687         port->port.index = i;
688         usb_ports[i] = &port->port;
689     }
690     return (USBDevice *)s;
691 }
692