2 #include "hw/usb/desc.h"
5 /* ------------------------------------------------------------------ */
7 static uint8_t usb_lo(uint16_t val
)
12 static uint8_t usb_hi(uint16_t val
)
14 return (val
>> 8) & 0xff;
17 int usb_desc_device(const USBDescID
*id
, const USBDescDevice
*dev
,
18 uint8_t *dest
, size_t len
)
20 uint8_t bLength
= 0x12;
21 USBDescriptor
*d
= (void *)dest
;
28 d
->bDescriptorType
= USB_DT_DEVICE
;
30 d
->u
.device
.bcdUSB_lo
= usb_lo(dev
->bcdUSB
);
31 d
->u
.device
.bcdUSB_hi
= usb_hi(dev
->bcdUSB
);
32 d
->u
.device
.bDeviceClass
= dev
->bDeviceClass
;
33 d
->u
.device
.bDeviceSubClass
= dev
->bDeviceSubClass
;
34 d
->u
.device
.bDeviceProtocol
= dev
->bDeviceProtocol
;
35 d
->u
.device
.bMaxPacketSize0
= dev
->bMaxPacketSize0
;
37 d
->u
.device
.idVendor_lo
= usb_lo(id
->idVendor
);
38 d
->u
.device
.idVendor_hi
= usb_hi(id
->idVendor
);
39 d
->u
.device
.idProduct_lo
= usb_lo(id
->idProduct
);
40 d
->u
.device
.idProduct_hi
= usb_hi(id
->idProduct
);
41 d
->u
.device
.bcdDevice_lo
= usb_lo(id
->bcdDevice
);
42 d
->u
.device
.bcdDevice_hi
= usb_hi(id
->bcdDevice
);
43 d
->u
.device
.iManufacturer
= id
->iManufacturer
;
44 d
->u
.device
.iProduct
= id
->iProduct
;
45 d
->u
.device
.iSerialNumber
= id
->iSerialNumber
;
47 d
->u
.device
.bNumConfigurations
= dev
->bNumConfigurations
;
52 int usb_desc_device_qualifier(const USBDescDevice
*dev
,
53 uint8_t *dest
, size_t len
)
55 uint8_t bLength
= 0x0a;
56 USBDescriptor
*d
= (void *)dest
;
63 d
->bDescriptorType
= USB_DT_DEVICE_QUALIFIER
;
65 d
->u
.device_qualifier
.bcdUSB_lo
= usb_lo(dev
->bcdUSB
);
66 d
->u
.device_qualifier
.bcdUSB_hi
= usb_hi(dev
->bcdUSB
);
67 d
->u
.device_qualifier
.bDeviceClass
= dev
->bDeviceClass
;
68 d
->u
.device_qualifier
.bDeviceSubClass
= dev
->bDeviceSubClass
;
69 d
->u
.device_qualifier
.bDeviceProtocol
= dev
->bDeviceProtocol
;
70 d
->u
.device_qualifier
.bMaxPacketSize0
= dev
->bMaxPacketSize0
;
71 d
->u
.device_qualifier
.bNumConfigurations
= dev
->bNumConfigurations
;
72 d
->u
.device_qualifier
.bReserved
= 0;
77 int usb_desc_config(const USBDescConfig
*conf
, uint8_t *dest
, size_t len
)
79 uint8_t bLength
= 0x09;
80 uint16_t wTotalLength
= 0;
81 USBDescriptor
*d
= (void *)dest
;
89 d
->bDescriptorType
= USB_DT_CONFIG
;
91 d
->u
.config
.bNumInterfaces
= conf
->bNumInterfaces
;
92 d
->u
.config
.bConfigurationValue
= conf
->bConfigurationValue
;
93 d
->u
.config
.iConfiguration
= conf
->iConfiguration
;
94 d
->u
.config
.bmAttributes
= conf
->bmAttributes
;
95 d
->u
.config
.bMaxPower
= conf
->bMaxPower
;
96 wTotalLength
+= bLength
;
98 /* handle grouped interfaces if any */
99 for (i
= 0; i
< conf
->nif_groups
; i
++) {
100 rc
= usb_desc_iface_group(&(conf
->if_groups
[i
]),
109 /* handle normal (ungrouped / no IAD) interfaces if any */
110 for (i
= 0; i
< conf
->nif
; i
++) {
111 rc
= usb_desc_iface(conf
->ifs
+ i
, dest
+ wTotalLength
, len
- wTotalLength
);
118 d
->u
.config
.wTotalLength_lo
= usb_lo(wTotalLength
);
119 d
->u
.config
.wTotalLength_hi
= usb_hi(wTotalLength
);
123 int usb_desc_iface_group(const USBDescIfaceAssoc
*iad
, uint8_t *dest
,
129 /* handle interface association descriptor */
130 uint8_t bLength
= 0x08;
136 dest
[0x00] = bLength
;
137 dest
[0x01] = USB_DT_INTERFACE_ASSOC
;
138 dest
[0x02] = iad
->bFirstInterface
;
139 dest
[0x03] = iad
->bInterfaceCount
;
140 dest
[0x04] = iad
->bFunctionClass
;
141 dest
[0x05] = iad
->bFunctionSubClass
;
142 dest
[0x06] = iad
->bFunctionProtocol
;
143 dest
[0x07] = iad
->iFunction
;
146 /* handle associated interfaces in this group */
147 for (i
= 0; i
< iad
->nif
; i
++) {
148 int rc
= usb_desc_iface(&(iad
->ifs
[i
]), dest
+ pos
, len
- pos
);
158 int usb_desc_iface(const USBDescIface
*iface
, uint8_t *dest
, size_t len
)
160 uint8_t bLength
= 0x09;
162 USBDescriptor
*d
= (void *)dest
;
168 d
->bLength
= bLength
;
169 d
->bDescriptorType
= USB_DT_INTERFACE
;
171 d
->u
.interface
.bInterfaceNumber
= iface
->bInterfaceNumber
;
172 d
->u
.interface
.bAlternateSetting
= iface
->bAlternateSetting
;
173 d
->u
.interface
.bNumEndpoints
= iface
->bNumEndpoints
;
174 d
->u
.interface
.bInterfaceClass
= iface
->bInterfaceClass
;
175 d
->u
.interface
.bInterfaceSubClass
= iface
->bInterfaceSubClass
;
176 d
->u
.interface
.bInterfaceProtocol
= iface
->bInterfaceProtocol
;
177 d
->u
.interface
.iInterface
= iface
->iInterface
;
180 for (i
= 0; i
< iface
->ndesc
; i
++) {
181 rc
= usb_desc_other(iface
->descs
+ i
, dest
+ pos
, len
- pos
);
188 for (i
= 0; i
< iface
->bNumEndpoints
; i
++) {
189 rc
= usb_desc_endpoint(iface
->eps
+ i
, dest
+ pos
, len
- pos
);
199 int usb_desc_endpoint(const USBDescEndpoint
*ep
, uint8_t *dest
, size_t len
)
201 uint8_t bLength
= ep
->is_audio
? 0x09 : 0x07;
202 uint8_t extralen
= ep
->extra
? ep
->extra
[0] : 0;
203 USBDescriptor
*d
= (void *)dest
;
205 if (len
< bLength
+ extralen
) {
209 d
->bLength
= bLength
;
210 d
->bDescriptorType
= USB_DT_ENDPOINT
;
212 d
->u
.endpoint
.bEndpointAddress
= ep
->bEndpointAddress
;
213 d
->u
.endpoint
.bmAttributes
= ep
->bmAttributes
;
214 d
->u
.endpoint
.wMaxPacketSize_lo
= usb_lo(ep
->wMaxPacketSize
);
215 d
->u
.endpoint
.wMaxPacketSize_hi
= usb_hi(ep
->wMaxPacketSize
);
216 d
->u
.endpoint
.bInterval
= ep
->bInterval
;
218 d
->u
.endpoint
.bRefresh
= ep
->bRefresh
;
219 d
->u
.endpoint
.bSynchAddress
= ep
->bSynchAddress
;
222 memcpy(dest
+ bLength
, ep
->extra
, extralen
);
225 return bLength
+ extralen
;
228 int usb_desc_other(const USBDescOther
*desc
, uint8_t *dest
, size_t len
)
230 int bLength
= desc
->length
? desc
->length
: desc
->data
[0];
236 memcpy(dest
, desc
->data
, bLength
);
240 /* ------------------------------------------------------------------ */
242 static void usb_desc_ep_init(USBDevice
*dev
)
244 const USBDescIface
*iface
;
248 for (i
= 0; i
< dev
->ninterfaces
; i
++) {
249 iface
= dev
->ifaces
[i
];
253 for (e
= 0; e
< iface
->bNumEndpoints
; e
++) {
254 pid
= (iface
->eps
[e
].bEndpointAddress
& USB_DIR_IN
) ?
255 USB_TOKEN_IN
: USB_TOKEN_OUT
;
256 ep
= iface
->eps
[e
].bEndpointAddress
& 0x0f;
257 usb_ep_set_type(dev
, pid
, ep
, iface
->eps
[e
].bmAttributes
& 0x03);
258 usb_ep_set_ifnum(dev
, pid
, ep
, iface
->bInterfaceNumber
);
259 usb_ep_set_max_packet_size(dev
, pid
, ep
,
260 iface
->eps
[e
].wMaxPacketSize
);
265 static const USBDescIface
*usb_desc_find_interface(USBDevice
*dev
,
268 const USBDescIface
*iface
;
274 for (g
= 0; g
< dev
->config
->nif_groups
; g
++) {
275 for (i
= 0; i
< dev
->config
->if_groups
[g
].nif
; i
++) {
276 iface
= &dev
->config
->if_groups
[g
].ifs
[i
];
277 if (iface
->bInterfaceNumber
== nif
&&
278 iface
->bAlternateSetting
== alt
) {
283 for (i
= 0; i
< dev
->config
->nif
; i
++) {
284 iface
= &dev
->config
->ifs
[i
];
285 if (iface
->bInterfaceNumber
== nif
&&
286 iface
->bAlternateSetting
== alt
) {
293 static int usb_desc_set_interface(USBDevice
*dev
, int index
, int value
)
295 const USBDescIface
*iface
;
298 iface
= usb_desc_find_interface(dev
, index
, value
);
303 old
= dev
->altsetting
[index
];
304 dev
->altsetting
[index
] = value
;
305 dev
->ifaces
[index
] = iface
;
306 usb_desc_ep_init(dev
);
309 usb_device_set_interface(dev
, index
, old
, value
);
314 static int usb_desc_set_config(USBDevice
*dev
, int value
)
319 dev
->configuration
= 0;
320 dev
->ninterfaces
= 0;
323 for (i
= 0; i
< dev
->device
->bNumConfigurations
; i
++) {
324 if (dev
->device
->confs
[i
].bConfigurationValue
== value
) {
325 dev
->configuration
= value
;
326 dev
->ninterfaces
= dev
->device
->confs
[i
].bNumInterfaces
;
327 dev
->config
= dev
->device
->confs
+ i
;
328 assert(dev
->ninterfaces
<= USB_MAX_INTERFACES
);
331 if (i
< dev
->device
->bNumConfigurations
) {
336 for (i
= 0; i
< dev
->ninterfaces
; i
++) {
337 usb_desc_set_interface(dev
, i
, 0);
339 for (; i
< USB_MAX_INTERFACES
; i
++) {
340 dev
->altsetting
[i
] = 0;
341 dev
->ifaces
[i
] = NULL
;
347 static void usb_desc_setdefaults(USBDevice
*dev
)
349 const USBDesc
*desc
= usb_device_get_usb_desc(dev
);
351 assert(desc
!= NULL
);
352 switch (dev
->speed
) {
355 dev
->device
= desc
->full
;
358 dev
->device
= desc
->high
;
361 usb_desc_set_config(dev
, 0);
364 void usb_desc_init(USBDevice
*dev
)
366 const USBDesc
*desc
= usb_device_get_usb_desc(dev
);
368 assert(desc
!= NULL
);
369 dev
->speed
= USB_SPEED_FULL
;
372 dev
->speedmask
|= USB_SPEED_MASK_FULL
;
375 dev
->speedmask
|= USB_SPEED_MASK_HIGH
;
377 usb_desc_setdefaults(dev
);
380 void usb_desc_attach(USBDevice
*dev
)
382 const USBDesc
*desc
= usb_device_get_usb_desc(dev
);
384 assert(desc
!= NULL
);
385 if (desc
->high
&& (dev
->port
->speedmask
& USB_SPEED_MASK_HIGH
)) {
386 dev
->speed
= USB_SPEED_HIGH
;
387 } else if (desc
->full
&& (dev
->port
->speedmask
& USB_SPEED_MASK_FULL
)) {
388 dev
->speed
= USB_SPEED_FULL
;
390 fprintf(stderr
, "usb: port/device speed mismatch for \"%s\"\n",
391 usb_device_get_product_desc(dev
));
394 usb_desc_setdefaults(dev
);
397 void usb_desc_set_string(USBDevice
*dev
, uint8_t index
, const char *str
)
401 QLIST_FOREACH(s
, &dev
->strings
, next
) {
402 if (s
->index
== index
) {
407 s
= g_malloc0(sizeof(*s
));
409 QLIST_INSERT_HEAD(&dev
->strings
, s
, next
);
412 s
->str
= g_strdup(str
);
415 const char *usb_desc_get_string(USBDevice
*dev
, uint8_t index
)
419 QLIST_FOREACH(s
, &dev
->strings
, next
) {
420 if (s
->index
== index
) {
427 int usb_desc_string(USBDevice
*dev
, int index
, uint8_t *dest
, size_t len
)
429 uint8_t bLength
, pos
, i
;
439 dest
[1] = USB_DT_STRING
;
445 str
= usb_desc_get_string(dev
, index
);
447 str
= usb_device_get_usb_desc(dev
)->str
[index
];
453 bLength
= strlen(str
) * 2 + 2;
455 dest
[1] = USB_DT_STRING
;
457 while (pos
+1 < bLength
&& pos
+1 < len
) {
458 dest
[pos
++] = str
[i
++];
464 int usb_desc_get_descriptor(USBDevice
*dev
, int value
, uint8_t *dest
, size_t len
)
466 const USBDesc
*desc
= usb_device_get_usb_desc(dev
);
467 const USBDescDevice
*other_dev
;
469 uint8_t type
= value
>> 8;
470 uint8_t index
= value
& 0xff;
473 if (dev
->speed
== USB_SPEED_HIGH
) {
474 other_dev
= usb_device_get_usb_desc(dev
)->full
;
476 other_dev
= usb_device_get_usb_desc(dev
)->high
;
481 ret
= usb_desc_device(&desc
->id
, dev
->device
, buf
, sizeof(buf
));
482 trace_usb_desc_device(dev
->addr
, len
, ret
);
485 if (index
< dev
->device
->bNumConfigurations
) {
486 ret
= usb_desc_config(dev
->device
->confs
+ index
, buf
, sizeof(buf
));
488 trace_usb_desc_config(dev
->addr
, index
, len
, ret
);
491 ret
= usb_desc_string(dev
, index
, buf
, sizeof(buf
));
492 trace_usb_desc_string(dev
->addr
, index
, len
, ret
);
495 case USB_DT_DEVICE_QUALIFIER
:
496 if (other_dev
!= NULL
) {
497 ret
= usb_desc_device_qualifier(other_dev
, buf
, sizeof(buf
));
499 trace_usb_desc_device_qualifier(dev
->addr
, len
, ret
);
501 case USB_DT_OTHER_SPEED_CONFIG
:
502 if (other_dev
!= NULL
&& index
< other_dev
->bNumConfigurations
) {
503 ret
= usb_desc_config(other_dev
->confs
+ index
, buf
, sizeof(buf
));
504 buf
[0x01] = USB_DT_OTHER_SPEED_CONFIG
;
506 trace_usb_desc_other_speed_config(dev
->addr
, index
, len
, ret
);
510 /* ignore silently */
514 fprintf(stderr
, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__
,
515 dev
->addr
, type
, len
);
523 memcpy(dest
, buf
, ret
);
528 int usb_desc_handle_control(USBDevice
*dev
, USBPacket
*p
,
529 int request
, int value
, int index
, int length
, uint8_t *data
)
531 const USBDesc
*desc
= usb_device_get_usb_desc(dev
);
534 assert(desc
!= NULL
);
536 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
538 trace_usb_set_addr(dev
->addr
);
542 case DeviceRequest
| USB_REQ_GET_DESCRIPTOR
:
543 ret
= usb_desc_get_descriptor(dev
, value
, data
, length
);
546 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
548 * 9.4.2: 0 should be returned if the device is unconfigured, otherwise
549 * the non zero value of bConfigurationValue.
551 data
[0] = dev
->config
? dev
->config
->bConfigurationValue
: 0;
554 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
555 ret
= usb_desc_set_config(dev
, value
);
556 trace_usb_set_config(dev
->addr
, value
, ret
);
559 case DeviceRequest
| USB_REQ_GET_STATUS
: {
560 const USBDescConfig
*config
= dev
->config
?
561 dev
->config
: &dev
->device
->confs
[0];
565 * Default state: Device behavior when this request is received while
566 * the device is in the Default state is not specified.
567 * We return the same value that a configured device would return if
568 * it used the first configuration.
570 if (config
->bmAttributes
& 0x40) {
571 data
[0] |= 1 << USB_DEVICE_SELF_POWERED
;
573 if (dev
->remote_wakeup
) {
574 data
[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP
;
580 case DeviceOutRequest
| USB_REQ_CLEAR_FEATURE
:
581 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
582 dev
->remote_wakeup
= 0;
585 trace_usb_clear_device_feature(dev
->addr
, value
, ret
);
587 case DeviceOutRequest
| USB_REQ_SET_FEATURE
:
588 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
589 dev
->remote_wakeup
= 1;
592 trace_usb_set_device_feature(dev
->addr
, value
, ret
);
595 case InterfaceRequest
| USB_REQ_GET_INTERFACE
:
596 if (index
< 0 || index
>= dev
->ninterfaces
) {
599 data
[0] = dev
->altsetting
[index
];
602 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
603 ret
= usb_desc_set_interface(dev
, index
, value
);
604 trace_usb_set_interface(dev
->addr
, index
, value
, ret
);