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);
 | 
			
		||||
    dev->info = info;
 | 
			
		||||
    dev->auto_attach = 1;
 | 
			
		||||
    QLIST_INIT(&dev->strings);
 | 
			
		||||
    rc = dev->info->init(dev);
 | 
			
		||||
    if (rc == 0 && dev->auto_attach)
 | 
			
		||||
        usb_device_attach(dev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,9 +151,42 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
 | 
			
		|||
    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;
 | 
			
		||||
    const char *str;
 | 
			
		||||
 | 
			
		||||
    if (len < 4) {
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,22 +201,25 @@ int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len
 | 
			
		|||
        return 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (str[index] == NULL) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    str = usb_desc_get_string(dev, index);
 | 
			
		||||
    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[1] = USB_DT_STRING;
 | 
			
		||||
    i = 0; pos = 2;
 | 
			
		||||
    while (pos+1 < bLength && pos+1 < len) {
 | 
			
		||||
        dest[pos++] = str[index][i++];
 | 
			
		||||
        dest[pos++] = str[i++];
 | 
			
		||||
        dest[pos++] = 0;
 | 
			
		||||
    }
 | 
			
		||||
    return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
        break;
 | 
			
		||||
    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);
 | 
			
		||||
        break;
 | 
			
		||||
    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_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_string(const char* const *str, int index, uint8_t *dest, size_t len);
 | 
			
		||||
 | 
			
		||||
/* 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_handle_control(USBDevice *dev, int request, int value,
 | 
			
		||||
                            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 USBDescEndpoint USBDescEndpoint;
 | 
			
		||||
typedef struct USBDescOther USBDescOther;
 | 
			
		||||
typedef struct USBDescString USBDescString;
 | 
			
		||||
 | 
			
		||||
struct USBDescString {
 | 
			
		||||
    uint8_t index;
 | 
			
		||||
    char *str;
 | 
			
		||||
    QLIST_ENTRY(USBDescString) next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* definition of a USB device */
 | 
			
		||||
struct USBDevice {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,6 +162,8 @@ struct USBDevice {
 | 
			
		|||
    int setup_state;
 | 
			
		||||
    int setup_len;
 | 
			
		||||
    int setup_index;
 | 
			
		||||
 | 
			
		||||
    QLIST_HEAD(, USBDescString) strings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct USBDeviceInfo {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue