• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <usb.h>
10 #include <dm/device-internal.h>
11 
copy_to_unicode(char * buff,int length,const char * str)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 
usb_emul_get_string(struct usb_string * strings,int index,char * buff,int length)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 
usb_emul_find_descriptor(struct usb_generic_descriptor ** ptr,int type,int index)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 
usb_emul_get_descriptor(struct usb_dev_platdata * plat,int value,void * buffer,int length)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 
usb_emul_find_devnum(int devnum,int port1,struct udevice ** emulp)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 
usb_emul_find(struct udevice * bus,ulong pipe,int port1,struct udevice ** emulp)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 
usb_emul_find_for_dev(struct udevice * dev,struct udevice ** emulp)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 
usb_emul_control(struct udevice * emul,struct usb_device * udev,unsigned long pipe,void * buffer,int length,struct devrequest * setup)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 
usb_emul_bulk(struct udevice * emul,struct usb_device * udev,unsigned long pipe,void * buffer,int length)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 
usb_emul_int(struct udevice * emul,struct usb_device * udev,unsigned long pipe,void * buffer,int length,int interval)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 
usb_emul_setup_device(struct udevice * dev,struct usb_string * strings,void ** desc_list)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