mirror of https://github.com/xqemu/xqemu.git
usb: track configuration and interface count in USBDevice.
Move fields from USBHostDevice to USBDevice. Add bits to usb-desc.c to fill them for emulated devices too. Also allow to set configuration 0 (== None) for emulated devices. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
097db43848
commit
65360511a2
|
@ -223,6 +223,29 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
static int usb_desc_set_config(USBDevice *dev, int value)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
dev->configuration = 0;
|
||||||
|
dev->ninterfaces = 0;
|
||||||
|
dev->config = NULL;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < dev->device->bNumConfigurations; i++) {
|
||||||
|
if (dev->device->confs[i].bConfigurationValue == value) {
|
||||||
|
dev->configuration = value;
|
||||||
|
dev->ninterfaces = dev->device->confs[i].bNumInterfaces;
|
||||||
|
dev->config = dev->device->confs + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < dev->device->bNumConfigurations) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_desc_setdefaults(USBDevice *dev)
|
static void usb_desc_setdefaults(USBDevice *dev)
|
||||||
{
|
{
|
||||||
const USBDesc *desc = dev->info->usb_desc;
|
const USBDesc *desc = dev->info->usb_desc;
|
||||||
|
@ -237,7 +260,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
|
||||||
dev->device = desc->high;
|
dev->device = desc->high;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev->config = dev->device->confs;
|
usb_desc_set_config(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_desc_init(USBDevice *dev)
|
void usb_desc_init(USBDevice *dev)
|
||||||
|
@ -408,7 +431,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||||
int request, int value, int index, int length, uint8_t *data)
|
int request, int value, int index, int length, uint8_t *data)
|
||||||
{
|
{
|
||||||
const USBDesc *desc = dev->info->usb_desc;
|
const USBDesc *desc = dev->info->usb_desc;
|
||||||
int i, ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
assert(desc != NULL);
|
assert(desc != NULL);
|
||||||
switch(request) {
|
switch(request) {
|
||||||
|
@ -427,12 +450,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
|
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
|
||||||
for (i = 0; i < dev->device->bNumConfigurations; i++) {
|
ret = usb_desc_set_config(dev, value);
|
||||||
if (dev->device->confs[i].bConfigurationValue == value) {
|
|
||||||
dev->config = dev->device->confs + i;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace_usb_set_config(dev->addr, value, ret);
|
trace_usb_set_config(dev->addr, value, ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
3
hw/usb.h
3
hw/usb.h
|
@ -188,6 +188,9 @@ struct USBDevice {
|
||||||
|
|
||||||
QLIST_HEAD(, USBDescString) strings;
|
QLIST_HEAD(, USBDescString) strings;
|
||||||
const USBDescDevice *device;
|
const USBDescDevice *device;
|
||||||
|
|
||||||
|
int configuration;
|
||||||
|
int ninterfaces;
|
||||||
const USBDescConfig *config;
|
const USBDescConfig *config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
21
usb-linux.c
21
usb-linux.c
|
@ -106,8 +106,6 @@ typedef struct USBHostDevice {
|
||||||
|
|
||||||
uint8_t descr[8192];
|
uint8_t descr[8192];
|
||||||
int descr_len;
|
int descr_len;
|
||||||
int configuration;
|
|
||||||
int ninterfaces;
|
|
||||||
int closing;
|
int closing;
|
||||||
uint32_t iso_urb_count;
|
uint32_t iso_urb_count;
|
||||||
Notifier exit;
|
Notifier exit;
|
||||||
|
@ -547,8 +545,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
if (configuration == 0) { /* address state - ignore */
|
if (configuration == 0) { /* address state - ignore */
|
||||||
dev->ninterfaces = 0;
|
dev->dev.ninterfaces = 0;
|
||||||
dev->configuration = 0;
|
dev->dev.configuration = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,8 +604,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
trace_usb_host_claim_interfaces(dev->bus_num, dev->addr,
|
trace_usb_host_claim_interfaces(dev->bus_num, dev->addr,
|
||||||
nb_interfaces, configuration);
|
nb_interfaces, configuration);
|
||||||
|
|
||||||
dev->ninterfaces = nb_interfaces;
|
dev->dev.ninterfaces = nb_interfaces;
|
||||||
dev->configuration = configuration;
|
dev->dev.configuration = configuration;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -624,7 +622,7 @@ static int usb_host_release_interfaces(USBHostDevice *s)
|
||||||
|
|
||||||
trace_usb_host_release_interfaces(s->bus_num, s->addr);
|
trace_usb_host_release_interfaces(s->bus_num, s->addr);
|
||||||
|
|
||||||
for (i = 0; i < s->ninterfaces; i++) {
|
for (i = 0; i < s->dev.ninterfaces; i++) {
|
||||||
ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
|
ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("USBDEVFS_RELEASEINTERFACE");
|
perror("USBDEVFS_RELEASEINTERFACE");
|
||||||
|
@ -1123,7 +1121,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
s->ep_out[i].type = INVALID_EP_TYPE;
|
s->ep_out[i].type = INVALID_EP_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->configuration == 0) {
|
if (s->dev.configuration == 0) {
|
||||||
/* not configured yet -- leave all endpoints disabled */
|
/* not configured yet -- leave all endpoints disabled */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1138,12 +1136,11 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
if (descriptors[i + 1] != USB_DT_CONFIG) {
|
if (descriptors[i + 1] != USB_DT_CONFIG) {
|
||||||
fprintf(stderr, "invalid descriptor data\n");
|
fprintf(stderr, "invalid descriptor data\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else if (descriptors[i + 5] != s->configuration) {
|
} else if (descriptors[i + 5] != s->dev.configuration) {
|
||||||
DPRINTF("not requested configuration %d\n", s->configuration);
|
DPRINTF("not requested configuration %d\n", s->dev.configuration);
|
||||||
i += (descriptors[i + 3] << 8) + descriptors[i + 2];
|
i += (descriptors[i + 3] << 8) + descriptors[i + 2];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += descriptors[i];
|
i += descriptors[i];
|
||||||
|
|
||||||
if (descriptors[i + 1] != USB_DT_INTERFACE ||
|
if (descriptors[i + 1] != USB_DT_INTERFACE ||
|
||||||
|
@ -1154,7 +1151,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface = descriptors[i + 2];
|
interface = descriptors[i + 2];
|
||||||
alt_interface = usb_linux_get_alt_setting(s, s->configuration,
|
alt_interface = usb_linux_get_alt_setting(s, s->dev.configuration,
|
||||||
interface);
|
interface);
|
||||||
|
|
||||||
/* the current interface descriptor is the active interface
|
/* the current interface descriptor is the active interface
|
||||||
|
|
Loading…
Reference in New Issue