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