1 /*****************************************************************************
2  * Copyright (c) 2013 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 
13 #include <string.h>
14 #include "usb-core.h"
15 
16 #undef DEBUG
17 //#define DEBUG
18 #ifdef DEBUG
19 #define dprintf(_x ...) do { printf(_x); } while(0)
20 #else
21 #define dprintf(_x ...)
22 #endif
23 
24 #define __unused __attribute__((unused))
25 
26 struct usb_hcd_ops *head;
27 struct usb_dev *devpool;
28 #define USB_DEVPOOL_SIZE 4096
29 
usb_alloc_devpool(void)30 static struct usb_dev *usb_alloc_devpool(void)
31 {
32 	struct usb_dev *head, *curr, *prev;
33 	unsigned int dev_count = 0, i;
34 
35 	head = SLOF_alloc_mem(USB_DEVPOOL_SIZE);
36 	if (!head)
37 		return NULL;
38 
39 	dev_count = USB_DEVPOOL_SIZE/sizeof(struct usb_dev);
40 	dprintf("%s: %d number of devices\n", __func__, dev_count);
41 	/* Although an array, link them*/
42 	for (i = 0, curr = head, prev = NULL; i < dev_count; i++, curr++) {
43 		if (prev)
44 			prev->next = curr;
45 		curr->next = NULL;
46 		prev = curr;
47 	}
48 
49 #ifdef DEBUG
50 	for (i = 0, curr = head; curr; curr = curr->next)
51 		printf("%s: %d dev %p\n", __func__, i++, curr);
52 #endif
53 
54 	return head;
55 }
56 
usb_devpool_get(void)57 struct usb_dev *usb_devpool_get(void)
58 {
59 	struct usb_dev *new;
60 
61 	if (!devpool) {
62 		devpool = usb_alloc_devpool();
63 		if (!devpool)
64 			return NULL;
65 	}
66 
67 	new = devpool;
68 	devpool = devpool->next;
69 	memset(new, 0, sizeof(*new));
70 	new->next = NULL;
71 	return new;
72 }
73 
usb_devpool_put(struct usb_dev * dev)74 void usb_devpool_put(struct usb_dev *dev)
75 {
76 	struct usb_dev *curr;
77 	if (!dev && !devpool)
78 		return;
79 
80 	curr = devpool;
81 	while (curr->next)
82 		curr = curr->next;
83 	curr->next = dev;
84 	dev->next = NULL;
85 }
86 
87 #ifndef DEBUG
88 #define validate_hcd_ops(dev) (dev && dev->hcidev && dev->hcidev->ops)
89 #else
validate_hcd_ops(struct usb_dev * dev)90 int validate_hcd_ops(struct usb_dev *dev)
91 {
92 	int ret = true;
93 
94 	if (!dev) {
95 		printf("dev is NULL\n");
96 		ret = false;
97 	} else if (!dev->hcidev) {
98 		printf("hcidev is NULL\n");
99 		ret = false;
100 	} else if (!dev->hcidev->ops)  {
101 		printf("ops is NULL\n");
102 		ret = false;
103 	}
104 	return ret;
105 }
106 #endif
107 
usb_get_pipe(struct usb_dev * dev,struct usb_ep_descr * ep,char * buf,size_t len)108 struct usb_pipe *usb_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
109 			char *buf, size_t len)
110 {
111 	if (validate_hcd_ops(dev) && dev->hcidev->ops->get_pipe)
112 		return dev->hcidev->ops->get_pipe(dev, ep, buf, len);
113 	else {
114 		printf("%s: Failed\n", __func__);
115 		return NULL;
116 	}
117 }
118 
usb_put_pipe(struct usb_pipe * pipe)119 void usb_put_pipe(struct usb_pipe *pipe)
120 {
121 	struct usb_dev *dev = NULL;
122 	if (pipe && pipe->dev) {
123 		dev = pipe->dev;
124 		if (validate_hcd_ops(dev) && dev->hcidev->ops->put_pipe)
125 			dev->hcidev->ops->put_pipe(pipe);
126 	}
127 }
128 
usb_poll_intr(struct usb_pipe * pipe,uint8_t * buf)129 int usb_poll_intr(struct usb_pipe *pipe, uint8_t *buf)
130 {
131 	struct usb_dev *dev = NULL;
132 	if (pipe && pipe->dev) {
133 		dev = pipe->dev;
134 		if (validate_hcd_ops(dev) && dev->hcidev->ops->poll_intr)
135 			return dev->hcidev->ops->poll_intr(pipe, buf);
136 	}
137 	return 0;
138 }
139 
usb_hcd_register(struct usb_hcd_ops * ops)140 void usb_hcd_register(struct usb_hcd_ops *ops)
141 {
142 	struct usb_hcd_ops *list;
143 
144 	if (!ops)
145 		printf("Error");
146 	dprintf("Registering %s %d\n", ops->name, ops->usb_type);
147 
148 	if (head) {
149 		list = head;
150 		while (list->next)
151 			list = list->next;
152 		list->next = ops;
153 	} else
154 		head = ops;
155 }
156 
usb_hcd_init(void * hcidev)157 void usb_hcd_init(void *hcidev)
158 {
159 	struct usb_hcd_dev *dev = hcidev;
160 	struct usb_hcd_ops *list = head;
161 
162 	if (!dev) {
163 		printf("Device Error");
164 		return;
165 	}
166 
167 	while (list) {
168 		if (list->usb_type == dev->type) {
169 			dprintf("usb_ops(%p) for the controller found\n", list);
170 			dev->ops = list;
171 			dev->ops->init(dev);
172 			return;
173 		}
174 		list = list->next;
175 	}
176 
177 	dprintf("usb_ops for the controller not found\n");
178 }
179 
usb_hcd_exit(void * _hcidev)180 void usb_hcd_exit(void *_hcidev)
181 {
182 	struct usb_hcd_dev *hcidev = _hcidev;
183 
184 	dprintf("%s: enter \n", __func__);
185 	if (!hcidev) {
186 		printf("Device Error");
187 		return;
188 	}
189 
190 	if (hcidev->ops->exit)
191 		hcidev->ops->exit(hcidev);
192 }
193 
usb_send_ctrl(struct usb_pipe * pipe,struct usb_dev_req * req,void * data)194 int usb_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data)
195 {
196 	struct usb_dev *dev = NULL;
197 	if (!pipe)
198 		return false;
199 	dev = pipe->dev;
200 	if (validate_hcd_ops(dev) && dev->hcidev->ops->send_ctrl)
201 		return dev->hcidev->ops->send_ctrl(pipe, req, data);
202 	else {
203 		printf("%s: Failed\n", __func__);
204 		return false;
205 	}
206 }
207 
usb_transfer_ctrl(void * dev,void * req,void * data)208 int usb_transfer_ctrl(void *dev, void *req, void *data)
209 {
210 	struct usb_pipe *pipe = NULL;
211 	struct usb_dev *usbdev;
212 
213 	if (!dev)
214 		return false;
215 	usbdev = (struct usb_dev *)dev;
216 	pipe = usbdev->control;
217 	return usb_send_ctrl(pipe, req, data);
218 }
219 
usb_transfer_bulk(void * dev,int dir,void * td,void * td_phys,void * data,int size)220 int usb_transfer_bulk(void *dev, int dir, void *td, void *td_phys, void *data, int size)
221 {
222 	struct usb_pipe *pipe = NULL;
223 	struct usb_dev *usbdev;
224 
225 	if (!dev)
226 		return false;
227 	usbdev = (struct usb_dev *)dev;
228 	pipe = (dir == USB_PIPE_OUT) ? usbdev->bulk_out : usbdev->bulk_in;
229 	if (!pipe)
230 		return false;
231 	if (validate_hcd_ops(usbdev) && usbdev->hcidev->ops->transfer_bulk)
232 		return usbdev->hcidev->ops->transfer_bulk(pipe, td, td_phys, data, size);
233 	else {
234 		printf("%s: Failed\n", __func__);
235 		return false;
236 	}
237 }
238 
239 /*
240  * USB Specification 1.1
241  *     9.3 USB Device Requests
242  *     9.4 Standard Device Requests
243  */
usb_set_address(struct usb_dev * dev,uint32_t port)244 static int usb_set_address(struct usb_dev *dev, uint32_t port)
245 {
246 	struct usb_dev_req req;
247 	struct usb_hcd_dev *hcidev;
248 
249 	if (!dev)
250 		return false;
251 
252 	hcidev = dev->hcidev;
253 	req.bmRequestType = 0;
254 	req.bRequest = REQ_SET_ADDRESS;
255 	req.wIndex = 0;
256 	req.wLength = 0;
257 	req.wValue = cpu_to_le16((uint16_t)(hcidev->nextaddr));
258 	if (usb_send_ctrl(dev->control, &req, NULL)) {
259 		dev->addr = hcidev->nextaddr++;
260 		return true;
261 	} else
262 		return false;
263 }
264 
usb_get_device_descr(struct usb_dev * dev,void * data,size_t size)265 static int usb_get_device_descr(struct usb_dev *dev, void *data, size_t size)
266 {
267 	struct usb_dev_req req;
268 
269 	if (!dev)
270 		return false;
271 
272 	req.bmRequestType = 0x80;
273 	req.bRequest = REQ_GET_DESCRIPTOR;
274 	req.wIndex = 0;
275 	req.wLength = cpu_to_le16((uint16_t) size);
276 	req.wValue = cpu_to_le16(DESCR_TYPE_DEVICE << 8);
277 	return usb_send_ctrl(dev->control, &req, data);
278 }
279 
usb_get_config_descr(struct usb_dev * dev,void * data,size_t size)280 static int usb_get_config_descr(struct usb_dev *dev, void *data, size_t size)
281 {
282 	struct usb_dev_req req;
283 
284 	if (!dev)
285 		return false;
286 
287 	req.bmRequestType = 0x80;
288 	req.bRequest = REQ_GET_DESCRIPTOR;
289 	req.wIndex = 0;
290 	req.wLength = cpu_to_le16((uint16_t) size);
291 	req.wValue = cpu_to_le16(DESCR_TYPE_CONFIGURATION << 8);
292 	return usb_send_ctrl(dev->control, &req, data);
293 
294 }
295 
usb_set_config(struct usb_dev * dev,uint8_t cfg_value)296 static int usb_set_config(struct usb_dev *dev, uint8_t cfg_value)
297 {
298 	struct usb_dev_req req;
299 
300 	if (!dev)
301 		return false;
302 
303 	req.bmRequestType = 0x00;
304 	req.bRequest = REQ_SET_CONFIGURATION;
305 	req.wIndex = 0;
306 	req.wLength = 0;
307 	req.wValue = cpu_to_le16(0x00FF & cfg_value);
308 	return usb_send_ctrl(dev->control, &req, NULL);
309 }
310 
usb_clear_halt(struct usb_pipe * pipe)311 static int usb_clear_halt(struct usb_pipe *pipe)
312 {
313 	struct usb_dev_req req;
314 	struct usb_dev *dev;
315 
316 	if (pipe && pipe->dev) {
317 		dev = pipe->dev;
318 		dprintf("Clearing port %d dir %d type %d\n",
319 			pipe->epno, pipe->dir, pipe->type);
320 		req.bmRequestType = REQT_DIR_OUT | REQT_REC_EP;
321 		req.bRequest = REQ_CLEAR_FEATURE;
322 		req.wValue = FEATURE_ENDPOINT_HALT;
323 		req.wIndex = cpu_to_le16(pipe->epno | pipe->dir);
324 		req.wLength = 0;
325 		return usb_send_ctrl(dev->control, &req, NULL);
326 	}
327 	return false;
328 }
329 
usb_dev_populate_pipe(struct usb_dev * dev,struct usb_ep_descr * ep,void * buf,size_t len)330 int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
331 			void *buf, size_t len)
332 {
333 	uint8_t dir, type;
334 
335 	dir = (ep->bEndpointAddress & 0x80) >> 7;
336 	type = ep->bmAttributes & USB_EP_TYPE_MASK;
337 
338 	dprintf("EP: %s: %d size %d type %d\n", dir ? "IN " : "OUT",
339 		ep->bEndpointAddress & 0xF, le16_to_cpu(ep->wMaxPacketSize),
340 		type);
341 	if (type == USB_EP_TYPE_BULK) {
342 		if (dir)
343 			dev->bulk_in = usb_get_pipe(dev, ep, buf, len);
344 		else
345 			dev->bulk_out = usb_get_pipe(dev, ep, buf, len);
346 	} else if (type == USB_EP_TYPE_INTR)
347 		dev->intr = usb_get_pipe(dev, ep, buf, len);
348 
349 	return true;
350 }
351 
usb_dev_copy_epdesc(struct usb_dev * dev,struct usb_ep_descr * ep)352 static void usb_dev_copy_epdesc(struct usb_dev *dev, struct usb_ep_descr *ep)
353 {
354 	uint32_t ep_cnt;
355 
356 	ep_cnt = dev->ep_cnt;
357 	if (ep_cnt < USB_DEV_EP_MAX)
358 		memcpy((void *)&dev->ep[ep_cnt], ep, sizeof(*ep));
359 	else
360 		dprintf("usb-core: only %d EPs supported\n", USB_DEV_EP_MAX);
361 	dev->ep_cnt++;
362 }
363 
usb_hid_init(void * vdev)364 int usb_hid_init(void *vdev)
365 {
366 	struct usb_dev *dev;
367 	dev = (struct usb_dev *) vdev;
368 	if (!dev)
369 		return false;
370 	if (dev->class == DEV_HID_KEYB)
371 		usb_hid_kbd_init(dev);
372 	return true;
373 }
374 
usb_hid_exit(void * vdev)375 int usb_hid_exit(void *vdev)
376 {
377 	struct usb_dev *dev;
378 	dev = (struct usb_dev *) vdev;
379 	if (!dev)
380 		return false;
381 	if (dev->class == DEV_HID_KEYB)
382 		usb_hid_kbd_exit(dev);
383 	return true;
384 }
385 
usb_msc_init(void * vdev)386 int usb_msc_init(void *vdev)
387 {
388 	struct usb_dev *dev;
389 	int i;
390 
391 	dev = (struct usb_dev *) vdev;
392 	dprintf("%s: enter %x\n", __func__, dev->class);
393 	if (!dev)
394 		return false;
395 	if (usb_get_intf_class(dev->class) == 8) {
396 		for (i = 0; i < dev->ep_cnt; i++) {
397 			if ((dev->ep[i].bmAttributes & USB_EP_TYPE_MASK)
398 				== USB_EP_TYPE_BULK)
399 				usb_dev_populate_pipe(dev, &dev->ep[i], NULL, 0);
400 		}
401 	}
402 	return true;
403 }
404 
usb_msc_exit(void * vdev)405 int usb_msc_exit(void *vdev)
406 {
407 	struct  usb_dev *dev;
408 	dev = (struct usb_dev *) vdev;
409 	dprintf("%s: enter %x\n", __func__, dev->class);
410 	if (!dev)
411 		return false;
412 	if (usb_get_intf_class(dev->class) == 8) {
413 		if (dev->bulk_in)
414 			usb_put_pipe(dev->bulk_in);
415 		if (dev->bulk_out)
416 			usb_put_pipe(dev->bulk_out);
417 	}
418 	return true;
419 }
420 
usb_msc_reset(struct usb_dev * dev)421 int usb_msc_reset(struct usb_dev *dev)
422 {
423 	struct usb_dev_req req;
424 
425 	if (!dev)
426 		return false;
427 
428 	req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
429 	req.bRequest = 0xFF;
430 	req.wLength = 0;
431 	req.wValue = 0;
432 	req.wIndex = cpu_to_le16(dev->intf_num);
433 	return usb_send_ctrl(dev->control, &req, NULL);
434 }
435 
usb_msc_resetrecovery(struct usb_dev * dev)436 void usb_msc_resetrecovery(struct usb_dev *dev)
437 {
438 	// usb_msc_reset(dev);
439 	usb_clear_halt(dev->bulk_in);
440 	usb_clear_halt(dev->bulk_out);
441 	SLOF_msleep(2);
442 }
443 
usb_handle_device(struct usb_dev * dev,struct usb_dev_config_descr * cfg,uint8_t * ptr,uint16_t len)444 static int usb_handle_device(struct usb_dev *dev, struct usb_dev_config_descr *cfg,
445 		uint8_t *ptr, uint16_t len)
446 {
447 	struct usb_dev_intf_descr *intf = NULL;
448 	struct usb_ep_descr *ep = NULL;
449 	struct usb_dev_hid_descr *hid __unused = NULL;
450 	uint8_t desc_len, desc_type;
451 
452 	len -= sizeof(struct usb_dev_config_descr);
453 	ptr = (uint8_t *)(ptr + sizeof(struct usb_dev_config_descr));
454 
455 	while (len > 0) {
456 		desc_len = *ptr;
457 		desc_type = *(ptr + 1);
458 		switch (desc_type) {
459 		case DESCR_TYPE_INTERFACE:
460 			intf = (struct usb_dev_intf_descr *)ptr;
461 			dev->class = intf->bInterfaceClass << 16 |
462 				intf->bInterfaceSubClass << 8 |
463 				intf->bInterfaceProtocol;
464 			break;
465 		case DESCR_TYPE_ENDPOINT:
466 			ep = (struct usb_ep_descr *)ptr;
467 			dev->intf_num = intf->bInterfaceNumber;
468 			usb_dev_copy_epdesc(dev, ep);
469 			break;
470 		case DESCR_TYPE_HID:
471 			hid = (struct usb_dev_hid_descr *)ptr;
472 			dprintf("hid-report %d size %d\n",
473 				hid->bReportType, le16_to_cpu(hid->wReportLength));
474 			break;
475 		case DESCR_TYPE_HUB:
476 			break;
477 		default:
478 			dprintf("ptr %p desc_type %d\n", ptr, desc_type);
479 		}
480 		ptr += desc_len;
481 		len -= desc_len;
482 	}
483 	return true;
484 }
485 
usb_setup_new_device(struct usb_dev * dev,unsigned int port)486 int usb_setup_new_device(struct usb_dev *dev, unsigned int port)
487 {
488 	struct usb_dev_descr descr;
489 	struct usb_dev_config_descr cfg;
490 	struct usb_ep_descr ep;
491 	uint16_t len;
492 	void *data = NULL;
493 
494 	dprintf("usb: %s - port %d\n", __func__, port);
495 
496 	dev->addr = 0;
497 	dev->port = port;
498 	ep.bEndpointAddress = 0;
499 	ep.bmAttributes = USB_EP_TYPE_CONTROL;
500 	ep.wMaxPacketSize = cpu_to_le16(8);
501 	dev->control = usb_get_pipe(dev, &ep, NULL, 0);
502 
503 	if (!usb_get_device_descr(dev, &descr, 8))
504 		goto fail;
505 	dev->control->mps = descr.bMaxPacketSize0;
506 
507 	/*
508 	 * For USB3.0 ADDRESS-SLOT command takes care of setting
509 	 * address, skip this during generic device setup for USB3.0
510 	 * devices
511 	 */
512 	if (dev->speed != USB_SUPER_SPEED) {
513 		/*
514 		 * Qemu starts the port number from 1 which was
515 		 * revealed in bootindex and resulted in mismatch for
516 		 * storage devices names. Adjusting this here for
517 		 * compatibility.
518 		 */
519 		dev->port = port + 1;
520 		if(!usb_set_address(dev, dev->port))
521 			goto fail;
522 	}
523 	mb();
524 	SLOF_msleep(100);
525 
526 	if (!usb_get_device_descr(dev, &descr, sizeof(struct usb_dev_descr)))
527 		goto fail;
528 
529 	if (!usb_get_config_descr(dev, &cfg, sizeof(struct usb_dev_config_descr)))
530 		goto fail;
531 
532 	len = le16_to_cpu(cfg.wTotalLength);
533 	/* No device config descriptor present */
534 	if (len == sizeof(struct usb_dev_config_descr))
535 		goto fail;
536 
537 	data = SLOF_dma_alloc(len);
538 	if (!data) {
539 		printf("%s: alloc failed %d\n", __func__, port);
540 		goto fail;
541 	}
542 
543 	if (!usb_get_config_descr(dev, data, len))
544 		goto fail_mem_free;
545 	if (!usb_set_config(dev, cfg.bConfigurationValue))
546 		goto fail_mem_free;
547 	mb();
548 	SLOF_msleep(100);
549 
550 	if (!usb_handle_device(dev, &cfg, data, len))
551 		goto fail_mem_free;
552 
553 	SLOF_dma_free(data, len);
554 	return true;
555 fail_mem_free:
556 	SLOF_dma_free(data, len);
557 fail:
558 	return false;
559 }
560