Home | History | Annotate | Download | only in emul
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2015 Google, Inc
      4  * Written by Simon Glass <sjg (at) chromium.org>
      5  */
      6 
      7 #include <common.h>
      8 #include <dm.h>
      9 #include <usb.h>
     10 #include <dm/device-internal.h>
     11 
     12 static int copy_to_unicode(char *buff, int length, const char *str)
     13 {
     14 	int ptr;
     15 	int i;
     16 
     17 	if (length < 2)
     18 		return 0;
     19 	buff[1] = USB_DT_STRING;
     20 	for (ptr = 2, i = 0; ptr + 1 < length && *str; i++, ptr += 2) {
     21 		buff[ptr] = str[i];
     22 		buff[ptr + 1] = 0;
     23 	}
     24 	buff[0] = ptr;
     25 
     26 	return ptr;
     27 }
     28 
     29 static int usb_emul_get_string(struct usb_string *strings, int index,
     30 			       char *buff, int length)
     31 {
     32 	if (index == 0) {
     33 		char *desc = buff;
     34 
     35 		desc[0] = 4;
     36 		desc[1] = USB_DT_STRING;
     37 		desc[2] = 0x09;
     38 		desc[3] = 0x14;
     39 		return 4;
     40 	} else if (strings) {
     41 		struct usb_string *ptr;
     42 
     43 		for (ptr = strings; ptr->s; ptr++) {
     44 			if (ptr->id == index)
     45 				return copy_to_unicode(buff, length, ptr->s);
     46 		}
     47 	}
     48 
     49 	return -EINVAL;
     50 }
     51 
     52 struct usb_generic_descriptor **usb_emul_find_descriptor(
     53 		struct usb_generic_descriptor **ptr, int type, int index)
     54 {
     55 	debug("%s: type=%x, index=%d\n", __func__, type, index);
     56 	for (; *ptr; ptr++) {
     57 		if ((*ptr)->bDescriptorType != type)
     58 			continue;
     59 		switch (type) {
     60 		case USB_DT_CONFIG: {
     61 			struct usb_config_descriptor *cdesc;
     62 
     63 			cdesc = (struct usb_config_descriptor *)*ptr;
     64 			if (cdesc && cdesc->bConfigurationValue == index)
     65 				return ptr;
     66 			break;
     67 		}
     68 		default:
     69 			return ptr;
     70 		}
     71 	}
     72 	debug("%s: config ptr=%p\n", __func__, *ptr);
     73 
     74 	return ptr;
     75 }
     76 
     77 static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
     78 				   void *buffer, int length)
     79 {
     80 	struct usb_generic_descriptor **ptr;
     81 	int type = value >> 8;
     82 	int index = value & 0xff;
     83 	int upto, todo;
     84 
     85 	debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat);
     86 	if (type == USB_DT_STRING) {
     87 		return usb_emul_get_string(plat->strings, index, buffer,
     88 					   length);
     89 	}
     90 
     91 	ptr = usb_emul_find_descriptor(plat->desc_list, type, index);
     92 	if (!ptr) {
     93 		debug("%s: Could not find descriptor type %d, index %d\n",
     94 		      __func__, type, index);
     95 		return -ENOENT;
     96 	}
     97 	for (upto = 0; *ptr && upto < length; ptr++, upto += todo) {
     98 		todo = min(length - upto, (int)(*ptr)->bLength);
     99 
    100 		memcpy(buffer + upto, *ptr, todo);
    101 	}
    102 
    103 	return upto ? upto : length ? -EIO : 0;
    104 }
    105 
    106 static int usb_emul_find_devnum(int devnum, int port1, struct udevice **emulp)
    107 {
    108 	struct udevice *dev;
    109 	struct uclass *uc;
    110 	int ret;
    111 
    112 	*emulp = NULL;
    113 	ret = uclass_get(UCLASS_USB_EMUL, &uc);
    114 	if (ret)
    115 		return ret;
    116 	uclass_foreach_dev(dev, uc) {
    117 		struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
    118 
    119 		/*
    120 		 * devnum is initialzied to zero at the beginning of the
    121 		 * enumeration process in usb_setup_device(). At this
    122 		 * point, udev->devnum has not been assigned to any valid
    123 		 * USB address either, so we can't rely on the comparison
    124 		 * result between udev->devnum and devnum to select an
    125 		 * emulator device.
    126 		 */
    127 		if (!devnum) {
    128 			struct usb_emul_platdata *plat;
    129 
    130 			/*
    131 			 * If the parent is sandbox USB controller, we are
    132 			 * the root hub. And there is only one root hub
    133 			 * in the system.
    134 			 */
    135 			if (device_get_uclass_id(dev->parent) == UCLASS_USB) {
    136 				debug("%s: Found emulator '%s'\n",
    137 				      __func__, dev->name);
    138 				*emulp = dev;
    139 				return 0;
    140 			}
    141 
    142 			plat = dev_get_uclass_platdata(dev);
    143 			if (plat->port1 == port1) {
    144 				debug("%s: Found emulator '%s', port %d\n",
    145 				      __func__, dev->name, port1);
    146 				*emulp = dev;
    147 				return 0;
    148 			}
    149 		} else if (udev->devnum == devnum) {
    150 			debug("%s: Found emulator '%s', addr %d\n", __func__,
    151 			      dev->name, udev->devnum);
    152 			*emulp = dev;
    153 			return 0;
    154 		}
    155 	}
    156 
    157 	debug("%s: No emulator found, addr %d\n", __func__, devnum);
    158 	return -ENOENT;
    159 }
    160 
    161 int usb_emul_find(struct udevice *bus, ulong pipe, int port1,
    162 		  struct udevice **emulp)
    163 {
    164 	int devnum = usb_pipedevice(pipe);
    165 
    166 	return usb_emul_find_devnum(devnum, port1, emulp);
    167 }
    168 
    169 int usb_emul_find_for_dev(struct udevice *dev, struct udevice **emulp)
    170 {
    171 	struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
    172 
    173 	return usb_emul_find_devnum(udev->devnum, 0, emulp);
    174 }
    175 
    176 int usb_emul_control(struct udevice *emul, struct usb_device *udev,
    177 		     unsigned long pipe, void *buffer, int length,
    178 		     struct devrequest *setup)
    179 {
    180 	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
    181 	struct usb_dev_platdata *plat;
    182 	int ret;
    183 
    184 	/* We permit getting the descriptor before we are probed */
    185 	plat = dev_get_parent_platdata(emul);
    186 	if (!ops->control)
    187 		return -ENOSYS;
    188 	debug("%s: dev=%s\n", __func__, emul->name);
    189 	if (pipe == usb_rcvctrlpipe(udev, 0)) {
    190 		switch (setup->request) {
    191 		case USB_REQ_GET_DESCRIPTOR: {
    192 			return usb_emul_get_descriptor(plat, setup->value,
    193 						       buffer, length);
    194 		}
    195 		default:
    196 			ret = device_probe(emul);
    197 			if (ret)
    198 				return ret;
    199 			return ops->control(emul, udev, pipe, buffer, length,
    200 					    setup);
    201 		}
    202 	} else if (pipe == usb_snddefctrl(udev)) {
    203 		switch (setup->request) {
    204 		case USB_REQ_SET_ADDRESS:
    205 			debug("   ** set address %s %d\n", emul->name,
    206 			      setup->value);
    207 			plat->devnum = setup->value;
    208 			return 0;
    209 		default:
    210 			debug("requestsend =%x\n", setup->request);
    211 			break;
    212 		}
    213 	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
    214 		switch (setup->request) {
    215 		case USB_REQ_SET_CONFIGURATION:
    216 			plat->configno = setup->value;
    217 			return 0;
    218 		default:
    219 			ret = device_probe(emul);
    220 			if (ret)
    221 				return ret;
    222 			return ops->control(emul, udev, pipe, buffer, length,
    223 					    setup);
    224 		}
    225 	}
    226 	debug("pipe=%lx\n", pipe);
    227 
    228 	return -EIO;
    229 }
    230 
    231 int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
    232 		  unsigned long pipe, void *buffer, int length)
    233 {
    234 	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
    235 	int ret;
    236 
    237 	/* We permit getting the descriptor before we are probed */
    238 	if (!ops->bulk)
    239 		return -ENOSYS;
    240 	debug("%s: dev=%s\n", __func__, emul->name);
    241 	ret = device_probe(emul);
    242 	if (ret)
    243 		return ret;
    244 	return ops->bulk(emul, udev, pipe, buffer, length);
    245 }
    246 
    247 int usb_emul_int(struct udevice *emul, struct usb_device *udev,
    248 		  unsigned long pipe, void *buffer, int length, int interval)
    249 {
    250 	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
    251 
    252 	if (!ops->interrupt)
    253 		return -ENOSYS;
    254 	debug("%s: dev=%s\n", __func__, emul->name);
    255 
    256 	return ops->interrupt(emul, udev, pipe, buffer, length, interval);
    257 }
    258 
    259 int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings,
    260 			  void **desc_list)
    261 {
    262 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
    263 	struct usb_generic_descriptor **ptr;
    264 	struct usb_config_descriptor *cdesc;
    265 	int upto;
    266 
    267 	plat->strings = strings;
    268 	plat->desc_list = (struct usb_generic_descriptor **)desc_list;
    269 
    270 	/* Fill in wTotalLength for each configuration descriptor */
    271 	ptr = plat->desc_list;
    272 	for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) {
    273 		debug("   - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType);
    274 		if ((*ptr)->bDescriptorType == USB_DT_CONFIG) {
    275 			if (cdesc) {
    276 				cdesc->wTotalLength = upto;
    277 				debug("%s: config %d length %d\n", __func__,
    278 				      cdesc->bConfigurationValue,
    279 				      cdesc->bLength);
    280 			}
    281 			cdesc = (struct usb_config_descriptor *)*ptr;
    282 			upto = 0;
    283 		}
    284 	}
    285 	if (cdesc) {
    286 		cdesc->wTotalLength = upto;
    287 		debug("%s: config %d length %d\n", __func__,
    288 		      cdesc->bConfigurationValue, cdesc->wTotalLength);
    289 	}
    290 
    291 	return 0;
    292 }
    293 
    294 UCLASS_DRIVER(usb_emul) = {
    295 	.id		= UCLASS_USB_EMUL,
    296 	.name		= "usb_emul",
    297 	.post_bind	= dm_scan_fdt_dev,
    298 	.per_device_platdata_auto_alloc_size = sizeof(struct usb_emul_platdata),
    299 	.per_child_auto_alloc_size = sizeof(struct usb_device),
    300 	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
    301 };
    302