mirror of https://github.com/xqemu/xqemu.git
usb descriptors: add settable strings.
This patch allows to set usb descriptor strings per device instance. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
062651c7e7
commit
132a3f55f0
|
@ -48,6 +48,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||||
pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
|
pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
|
||||||
dev->info = info;
|
dev->info = info;
|
||||||
dev->auto_attach = 1;
|
dev->auto_attach = 1;
|
||||||
|
QLIST_INIT(&dev->strings);
|
||||||
rc = dev->info->init(dev);
|
rc = dev->info->init(dev);
|
||||||
if (rc == 0 && dev->auto_attach)
|
if (rc == 0 && dev->auto_attach)
|
||||||
usb_device_attach(dev);
|
usb_device_attach(dev);
|
||||||
|
|
|
@ -151,9 +151,42 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
|
||||||
return bLength;
|
return bLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len)
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str)
|
||||||
|
{
|
||||||
|
USBDescString *s;
|
||||||
|
|
||||||
|
QLIST_FOREACH(s, &dev->strings, next) {
|
||||||
|
if (s->index == index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s == NULL) {
|
||||||
|
s = qemu_mallocz(sizeof(*s));
|
||||||
|
s->index = index;
|
||||||
|
QLIST_INSERT_HEAD(&dev->strings, s, next);
|
||||||
|
}
|
||||||
|
qemu_free(s->str);
|
||||||
|
s->str = qemu_strdup(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
|
||||||
|
{
|
||||||
|
USBDescString *s;
|
||||||
|
|
||||||
|
QLIST_FOREACH(s, &dev->strings, next) {
|
||||||
|
if (s->index == index) {
|
||||||
|
return s->str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t bLength, pos, i;
|
uint8_t bLength, pos, i;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
if (len < 4) {
|
if (len < 4) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -168,22 +201,25 @@ int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str[index] == NULL) {
|
str = usb_desc_get_string(dev, index);
|
||||||
return 0;
|
if (str == NULL) {
|
||||||
|
str = dev->info->usb_desc->str[index];
|
||||||
|
if (str == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bLength = strlen(str[index]) * 2 + 2;
|
|
||||||
|
bLength = strlen(str) * 2 + 2;
|
||||||
dest[0] = bLength;
|
dest[0] = bLength;
|
||||||
dest[1] = USB_DT_STRING;
|
dest[1] = USB_DT_STRING;
|
||||||
i = 0; pos = 2;
|
i = 0; pos = 2;
|
||||||
while (pos+1 < bLength && pos+1 < len) {
|
while (pos+1 < bLength && pos+1 < len) {
|
||||||
dest[pos++] = str[index][i++];
|
dest[pos++] = str[i++];
|
||||||
dest[pos++] = 0;
|
dest[pos++] = 0;
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len)
|
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len)
|
||||||
{
|
{
|
||||||
const USBDesc *desc = dev->info->usb_desc;
|
const USBDesc *desc = dev->info->usb_desc;
|
||||||
|
@ -204,7 +240,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
|
||||||
trace_usb_desc_config(dev->addr, index, len, ret);
|
trace_usb_desc_config(dev->addr, index, len, ret);
|
||||||
break;
|
break;
|
||||||
case USB_DT_STRING:
|
case USB_DT_STRING:
|
||||||
ret = usb_desc_string(desc->str, index, buf, sizeof(buf));
|
ret = usb_desc_string(dev, index, buf, sizeof(buf));
|
||||||
trace_usb_desc_string(dev->addr, index, len, ret);
|
trace_usb_desc_string(dev->addr, index, len, ret);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -76,9 +76,11 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len);
|
||||||
int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
|
int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
|
||||||
int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
|
int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
|
||||||
int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
|
int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
|
||||||
int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len);
|
|
||||||
|
|
||||||
/* control message emulation helpers */
|
/* control message emulation helpers */
|
||||||
|
void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
|
||||||
|
const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
|
||||||
|
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
|
||||||
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
|
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
|
||||||
int usb_desc_handle_control(USBDevice *dev, int request, int value,
|
int usb_desc_handle_control(USBDevice *dev, int request, int value,
|
||||||
int index, int length, uint8_t *data);
|
int index, int length, uint8_t *data);
|
||||||
|
|
9
hw/usb.h
9
hw/usb.h
|
@ -135,6 +135,13 @@ typedef struct USBDescConfig USBDescConfig;
|
||||||
typedef struct USBDescIface USBDescIface;
|
typedef struct USBDescIface USBDescIface;
|
||||||
typedef struct USBDescEndpoint USBDescEndpoint;
|
typedef struct USBDescEndpoint USBDescEndpoint;
|
||||||
typedef struct USBDescOther USBDescOther;
|
typedef struct USBDescOther USBDescOther;
|
||||||
|
typedef struct USBDescString USBDescString;
|
||||||
|
|
||||||
|
struct USBDescString {
|
||||||
|
uint8_t index;
|
||||||
|
char *str;
|
||||||
|
QLIST_ENTRY(USBDescString) next;
|
||||||
|
};
|
||||||
|
|
||||||
/* definition of a USB device */
|
/* definition of a USB device */
|
||||||
struct USBDevice {
|
struct USBDevice {
|
||||||
|
@ -155,6 +162,8 @@ struct USBDevice {
|
||||||
int setup_state;
|
int setup_state;
|
||||||
int setup_len;
|
int setup_len;
|
||||||
int setup_index;
|
int setup_index;
|
||||||
|
|
||||||
|
QLIST_HEAD(, USBDescString) strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct USBDeviceInfo {
|
struct USBDeviceInfo {
|
||||||
|
|
Loading…
Reference in New Issue