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) | ||||
| { | ||||
|     const USBDesc *desc = dev->info->usb_desc; | ||||
| @ -237,7 +260,7 @@ static void usb_desc_setdefaults(USBDevice *dev) | ||||
|         dev->device = desc->high; | ||||
|         break; | ||||
|     } | ||||
|     dev->config = dev->device->confs; | ||||
|     usb_desc_set_config(dev, 0); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
|     const USBDesc *desc = dev->info->usb_desc; | ||||
|     int i, ret = -1; | ||||
|     int ret = -1; | ||||
| 
 | ||||
|     assert(desc != NULL); | ||||
|     switch(request) { | ||||
| @ -427,12 +450,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p, | ||||
|         ret = 1; | ||||
|         break; | ||||
|     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: | ||||
|         for (i = 0; i < dev->device->bNumConfigurations; i++) { | ||||
|             if (dev->device->confs[i].bConfigurationValue == value) { | ||||
|                 dev->config = dev->device->confs + i; | ||||
|                 ret = 0; | ||||
|             } | ||||
|         } | ||||
|         ret = usb_desc_set_config(dev, value); | ||||
|         trace_usb_set_config(dev->addr, value, ret); | ||||
|         break; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										3
									
								
								hw/usb.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								hw/usb.h
									
									
									
									
									
								
							| @ -188,6 +188,9 @@ struct USBDevice { | ||||
| 
 | ||||
|     QLIST_HEAD(, USBDescString) strings; | ||||
|     const USBDescDevice *device; | ||||
| 
 | ||||
|     int configuration; | ||||
|     int ninterfaces; | ||||
|     const USBDescConfig *config; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										21
									
								
								usb-linux.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								usb-linux.c
									
									
									
									
									
								
							| @ -106,8 +106,6 @@ typedef struct USBHostDevice { | ||||
| 
 | ||||
|     uint8_t   descr[8192]; | ||||
|     int       descr_len; | ||||
|     int       configuration; | ||||
|     int       ninterfaces; | ||||
|     int       closing; | ||||
|     uint32_t  iso_urb_count; | ||||
|     Notifier  exit; | ||||
| @ -547,8 +545,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration) | ||||
|     int ret, i; | ||||
| 
 | ||||
|     if (configuration == 0) { /* address state - ignore */ | ||||
|         dev->ninterfaces   = 0; | ||||
|         dev->configuration = 0; | ||||
|         dev->dev.ninterfaces   = 0; | ||||
|         dev->dev.configuration = 0; | ||||
|         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, | ||||
|                                     nb_interfaces, configuration); | ||||
| 
 | ||||
|     dev->ninterfaces   = nb_interfaces; | ||||
|     dev->configuration = configuration; | ||||
|     dev->dev.ninterfaces   = nb_interfaces; | ||||
|     dev->dev.configuration = configuration; | ||||
|     return 1; | ||||
| 
 | ||||
| fail: | ||||
| @ -624,7 +622,7 @@ static int usb_host_release_interfaces(USBHostDevice *s) | ||||
| 
 | ||||
|     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); | ||||
|         if (ret < 0) { | ||||
|             perror("USBDEVFS_RELEASEINTERFACE"); | ||||
| @ -1123,7 +1121,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) | ||||
|         s->ep_out[i].type = INVALID_EP_TYPE; | ||||
|     } | ||||
| 
 | ||||
|     if (s->configuration == 0) { | ||||
|     if (s->dev.configuration == 0) { | ||||
|         /* not configured yet -- leave all endpoints disabled */ | ||||
|         return 0; | ||||
|     } | ||||
| @ -1138,12 +1136,11 @@ static int usb_linux_update_endp_table(USBHostDevice *s) | ||||
|         if (descriptors[i + 1] != USB_DT_CONFIG) { | ||||
|             fprintf(stderr, "invalid descriptor data\n"); | ||||
|             return 1; | ||||
|         } else if (descriptors[i + 5] != s->configuration) { | ||||
|             DPRINTF("not requested configuration %d\n", s->configuration); | ||||
|         } else if (descriptors[i + 5] != s->dev.configuration) { | ||||
|             DPRINTF("not requested configuration %d\n", s->dev.configuration); | ||||
|             i += (descriptors[i + 3] << 8) + descriptors[i + 2]; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         i += descriptors[i]; | ||||
| 
 | ||||
|         if (descriptors[i + 1] != USB_DT_INTERFACE || | ||||
| @ -1154,7 +1151,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) | ||||
|         } | ||||
| 
 | ||||
|         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); | ||||
| 
 | ||||
|         /* the current interface descriptor is the active interface
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Gerd Hoffmann
						Gerd Hoffmann