| 199 |
|
|
| 200 |
#define MAX_PORTS 8 |
#define MAX_PORTS 8 |
| 201 |
|
|
|
#define DS_IDLE 0 |
|
|
#define DS_CONTROL_IN 1 |
|
|
#define DS_CONTROL_OUT 2 |
|
|
|
|
| 202 |
typedef struct USBHubPort { |
typedef struct USBHubPort { |
| 203 |
USBPort port; |
USBPort port; |
| 204 |
USBDevice *dev; |
USBDevice *dev; |
| 256 |
/* same as Linux kernel root hubs */ |
/* same as Linux kernel root hubs */ |
| 257 |
|
|
| 258 |
static const uint8_t qemu_hub_dev_descriptor[] = { |
static const uint8_t qemu_hub_dev_descriptor[] = { |
| 259 |
0x12, /* __u8 bLength; */ |
0x12, /* u8 bLength; */ |
| 260 |
0x01, /* __u8 bDescriptorType; Device */ |
0x01, /* u8 bDescriptorType; Device */ |
| 261 |
0x10, 0x01, /* __u16 bcdUSB; v1.1 */ |
0x10, 0x01, /* u16 bcdUSB; v1.1 */ |
| 262 |
|
|
| 263 |
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ |
0x09, /* u8 bDeviceClass; HUB_CLASSCODE */ |
| 264 |
0x00, /* __u8 bDeviceSubClass; */ |
0x00, /* u8 bDeviceSubClass; */ |
| 265 |
0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ |
0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ |
| 266 |
0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ |
0x08, /* u8 bMaxPacketSize0; 8 Bytes */ |
| 267 |
|
|
| 268 |
0x00, 0x00, /* __u16 idVendor; */ |
0x00, 0x00, /* u16 idVendor; */ |
| 269 |
0x00, 0x00, /* __u16 idProduct; */ |
0x00, 0x00, /* u16 idProduct; */ |
| 270 |
0x01, 0x01, /* __u16 bcdDevice */ |
0x01, 0x01, /* u16 bcdDevice */ |
| 271 |
|
|
| 272 |
0x03, /* __u8 iManufacturer; */ |
0x03, /* u8 iManufacturer; */ |
| 273 |
0x02, /* __u8 iProduct; */ |
0x02, /* u8 iProduct; */ |
| 274 |
0x01, /* __u8 iSerialNumber; */ |
0x01, /* u8 iSerialNumber; */ |
| 275 |
0x01 /* __u8 bNumConfigurations; */ |
0x01 /* u8 bNumConfigurations; */ |
| 276 |
}; |
}; |
| 277 |
|
|
| 278 |
/* XXX: patch interrupt size */ |
/* XXX: patch interrupt size */ |
| 279 |
static const uint8_t qemu_hub_config_descriptor[] = { |
static const uint8_t qemu_hub_config_descriptor[] = { |
| 280 |
|
|
| 281 |
/* one configuration */ |
/* one configuration */ |
| 282 |
0x09, /* __u8 bLength; */ |
0x09, /* u8 bLength; */ |
| 283 |
0x02, /* __u8 bDescriptorType; Configuration */ |
0x02, /* u8 bDescriptorType; Configuration */ |
| 284 |
0x19, 0x00, /* __u16 wTotalLength; */ |
0x19, 0x00, /* u16 wTotalLength; */ |
| 285 |
0x01, /* __u8 bNumInterfaces; (1) */ |
0x01, /* u8 bNumInterfaces; (1) */ |
| 286 |
0x01, /* __u8 bConfigurationValue; */ |
0x01, /* u8 bConfigurationValue; */ |
| 287 |
0x00, /* __u8 iConfiguration; */ |
0x00, /* u8 iConfiguration; */ |
| 288 |
0xc0, /* __u8 bmAttributes; |
0xc0, /* u8 bmAttributes; |
| 289 |
Bit 7: must be set, |
Bit 7: must be set, |
| 290 |
6: Self-powered, |
6: Self-powered, |
| 291 |
5: Remote wakeup, |
5: Remote wakeup, |
| 292 |
4..0: resvd */ |
4..0: resvd */ |
| 293 |
0x00, /* __u8 MaxPower; */ |
0x00, /* u8 MaxPower; */ |
| 294 |
|
|
| 295 |
/* USB 1.1: |
/* USB 1.1: |
| 296 |
* USB 2.0, single TT organization (mandatory): |
* USB 2.0, single TT organization (mandatory): |
| 304 |
*/ |
*/ |
| 305 |
|
|
| 306 |
/* one interface */ |
/* one interface */ |
| 307 |
0x09, /* __u8 if_bLength; */ |
0x09, /* u8 if_bLength; */ |
| 308 |
0x04, /* __u8 if_bDescriptorType; Interface */ |
0x04, /* u8 if_bDescriptorType; Interface */ |
| 309 |
0x00, /* __u8 if_bInterfaceNumber; */ |
0x00, /* u8 if_bInterfaceNumber; */ |
| 310 |
0x00, /* __u8 if_bAlternateSetting; */ |
0x00, /* u8 if_bAlternateSetting; */ |
| 311 |
0x01, /* __u8 if_bNumEndpoints; */ |
0x01, /* u8 if_bNumEndpoints; */ |
| 312 |
0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ |
0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */ |
| 313 |
0x00, /* __u8 if_bInterfaceSubClass; */ |
0x00, /* u8 if_bInterfaceSubClass; */ |
| 314 |
0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ |
0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ |
| 315 |
0x00, /* __u8 if_iInterface; */ |
0x00, /* u8 if_iInterface; */ |
| 316 |
|
|
| 317 |
/* one endpoint (status change endpoint) */ |
/* one endpoint (status change endpoint) */ |
| 318 |
0x07, /* __u8 ep_bLength; */ |
0x07, /* u8 ep_bLength; */ |
| 319 |
0x05, /* __u8 ep_bDescriptorType; Endpoint */ |
0x05, /* u8 ep_bDescriptorType; Endpoint */ |
| 320 |
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ |
0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ |
| 321 |
0x03, /* __u8 ep_bmAttributes; Interrupt */ |
0x03, /* u8 ep_bmAttributes; Interrupt */ |
| 322 |
0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ |
0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ |
| 323 |
0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */ |
0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ |
| 324 |
}; |
}; |
| 325 |
|
|
| 326 |
static const uint8_t qemu_hub_hub_descriptor[] = |
static const uint8_t qemu_hub_hub_descriptor[] = |
| 327 |
{ |
{ |
| 328 |
0x09, /* __u8 bLength; */ |
0x09, /* u8 bLength; */ |
| 329 |
0x29, /* __u8 bDescriptorType; Hub-descriptor */ |
0x29, /* u8 bDescriptorType; Hub-descriptor */ |
| 330 |
0x00, /* __u8 bNbrPorts; (patched later) */ |
0x00, /* u8 bNbrPorts; (patched later) */ |
| 331 |
0x0a, /* __u16 wHubCharacteristics; */ |
0x0a, /* u16 wHubCharacteristics; */ |
| 332 |
0x00, /* (per-port OC, no power switching) */ |
0x00, /* (per-port OC, no power switching) */ |
| 333 |
0x01, /* __u8 bPwrOn2pwrGood; 2ms */ |
0x01, /* u8 bPwrOn2pwrGood; 2ms */ |
| 334 |
0x00, /* __u8 bHubContrCurrent; 0 mA */ |
0x00, /* u8 bHubContrCurrent; 0 mA */ |
| 335 |
0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ |
0x00, /* u8 DeviceRemovable; *** 7 Ports max *** */ |
| 336 |
0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ |
0xff /* u8 PortPwrCtrlMask; *** 7 ports max *** */ |
| 337 |
}; |
}; |
| 338 |
|
|
| 339 |
static void usb_hub_attach(USBPort *port1, USBDevice *dev) |
static void usb_hub_attach(USBPort *port1, USBDevice *dev) |
| 567 |
default: |
default: |
| 568 |
fail: |
fail: |
| 569 |
ret = USB_RET_STALL; |
ret = USB_RET_STALL; |
| 570 |
|
break; |
| 571 |
} |
} |
| 572 |
return ret; |
return ret; |
| 573 |
} |
} |