1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2016-2019. All rights reserved.
3 * Description: LiteOS USB Driver Generic Function
4 * Author: Yannik Li
5 * Create: 2021-02-04
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29 * Notice of Export Control Law
30 * ===============================================
31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34 * applicable export control laws and regulations.
35 * --------------------------------------------------------------------------- */
36
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <los_event.h>
41 #include <fs/fs.h>
42 #include <los_magickey.h>
43 #include <los_hwi.h>
44 #include <linux/spinlock.h>
45 #include "osal_atomic.h"
46 #include "gadget/usbdev.h"
47 #include "f_common.h"
48
49 #ifdef __cplusplus
50 #if __cplusplus
51 //extern "C" {
52 #endif /* __cplusplus */
53 #endif /* __cplusplus */
54
55 #ifndef sizeof_field
56 #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
57 #endif
58
59 static int usbclass_generic_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
60 static int usbclass_generic_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
61 static int usbclass_generic_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev,
62 const struct usb_device_request *ctrl, uint8_t *dataout,
63 size_t outlen);
64 static void usbclass_generic_disconnect(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
65
66 /* USB driver operations */
67
68 struct usbdevclass_driverops_s g_generic_driverops =
69 {
70 usbclass_generic_bind,
71 usbclass_generic_unbind,
72 usbclass_generic_setup,
73 usbclass_generic_disconnect,
74 NULL,
75 NULL
76 };
77
78 struct usb_config_descriptor g_generic_config_desc =
79 {
80 .bLength = USB_CONFIG_DESC_SIZE,
81 .bDescriptorType = UDESC_CONFIG,
82 .wTotalLength = {0, 0}, /* dynamic */
83 .bNumInterface = 1,
84 .bConfigurationValue = 1,
85 .iConfiguration = 0,
86 .bmAttributes = UC_SELF_POWERED | UC_BUS_POWERED,
87 .bMaxPower = 1, /* max power */
88 };
89
90 static uint64_t g_generic_minor = 0;
91 static struct usb_obj g_generic_obj;
92 EVENT_CB_S eps_event_all;
93 uint32_t eps_event_mask = 0;
94
95 LINUX_LIST_HEAD(g_generic_devices);
96 DEFINE_SPINLOCK(g_generic_spinlock);
generic_dev_lock(void)97 static inline void generic_dev_lock(void)
98 {
99 spin_lock(&g_generic_spinlock);
100 }
101
generic_dev_unlock(void)102 static inline void generic_dev_unlock(void)
103 {
104 spin_unlock(&g_generic_spinlock);
105 }
106
generic_ffz64(uint64_t x)107 static inline uint32_t generic_ffz64(uint64_t x)
108 {
109 uint32_t num = 0;
110
111 if ((x & 0xffffffff) == 0xffffffff)
112 {
113 num += 32;
114 x >>= 32;
115 }
116 if ((x & 0xffff) == 0xffff)
117 {
118 num += 16;
119 x >>= 16;
120 }
121 if ((x & 0xff) == 0xff)
122 {
123 num += 8;
124 x >>= 8;
125 }
126 if ((x & 0xf) == 0xf)
127 {
128 num += 4;
129 x >>= 4;
130 }
131 if ((x & 0x3) == 0x3)
132 {
133 num += 2;
134 x >>= 2;
135 }
136 if ((x & 0x1) == 0x1)
137 {
138 num += 1;
139 }
140 return num;
141 }
142
generic_discard_events(struct generic_dev_s * dev,enum usb_generic_event_type type1,enum usb_generic_event_type type2,int keep)143 static void generic_discard_events(struct generic_dev_s *dev,
144 enum usb_generic_event_type type1,
145 enum usb_generic_event_type type2,
146 int keep)
147 {
148 uint32_t ev = dev->efifo.out, out = ev;
149 uint32_t mask = USB_GENERIC_EVENTS_NUM - 1;
150
151 for (; ev < dev->efifo.in; ++ev)
152 {
153 if ((dev->efifo.data[ev & mask] == type1 ||
154 dev->efifo.data[ev & mask] == type2) == keep)
155 {
156 dev->efifo.data[out++ & mask] = dev->efifo.data[ev & mask];
157 }
158 else
159 {
160 usb_debug("remove event %d\n", dev->efifo.data[ev & mask]);
161 }
162 }
163 dev->efifo.in = out;
164 }
165
__generic_event_add(struct generic_dev_s * dev,enum usb_generic_event_type type)166 static void __generic_event_add(struct generic_dev_s *dev,
167 enum usb_generic_event_type type)
168 {
169 enum usb_generic_event_type ev_type1, ev_type2 = type;
170 int keep = 0;
171
172 if (dev->setup_state == GENERIC_SETUP_PENDING)
173 {
174 dev->setup_state = GENERIC_SETUP_CANCELLED;
175 }
176
177 switch (type)
178 {
179 case GENERIC_RESUME:
180 /* remove previous GENERIC_SUSPEND */
181 ev_type2 = GENERIC_SUSPEND;
182 case GENERIC_SUSPEND:
183 case GENERIC_SETUP:
184 /* remove repeated event */
185 ev_type1 = type;
186 break;
187 case GENERIC_BIND:
188 case GENERIC_UNBIND:
189 case GENERIC_DISABLE:
190 case GENERIC_ENABLE:
191 /* just keep GENERIC_SUSPEND and GENERIC_RESUME */
192 ev_type1 = GENERIC_SUSPEND;
193 ev_type2 = GENERIC_RESUME;
194 keep = 1;
195 break;
196
197 default:
198 usb_err("%d: unknown event\n", type);
199 return;
200 }
201
202 generic_discard_events(dev, ev_type1, ev_type2, keep);
203 usb_debug("adding event %d\n", type);
204 event_fifo_put(&dev->efifo, type);
205 int bits = dev->minor_offset * EVENT_FOR_FUNCTION;
206 (void)LOS_EventWrite(&eps_event_all, (1 << bits));
207 }
208
generic_event_add(struct generic_dev_s * dev,enum usb_generic_event_type type)209 static void generic_event_add(struct generic_dev_s *dev,
210 enum usb_generic_event_type type)
211 {
212 unsigned long flags;
213 spin_lock_irqsave(&dev->event_lock, flags);
214 __generic_event_add(dev, type);
215 spin_unlock_irqrestore(&dev->event_lock, flags);
216 }
217
generic_dev_get(struct generic_dev_s * dev)218 static inline void generic_dev_get(struct generic_dev_s *dev)
219 {
220 usbobj_get(&dev->obj);
221 }
222
generic_dev_put(struct generic_dev_s * dev)223 static inline void generic_dev_put(struct generic_dev_s *dev)
224 {
225 usbobj_put(&dev->obj);
226 }
227
generic_dev_find_by_name(const char * name)228 static struct generic_dev_s *generic_dev_find_by_name(const char *name)
229 {
230 struct usb_obj *obj = NULL;
231 if (name == NULL)
232 {
233 usb_err("%s: name is NULL\n", __FUNCTION__);
234 return NULL;
235 }
236
237 obj = usbobj_find(&g_generic_obj, usbobj_default_match, (void *)name);
238 if (obj == NULL)
239 {
240 usb_err("%s is not exists!\n", name);
241 return NULL;
242 }
243
244 return container_of(obj, struct generic_dev_s, obj);
245 }
246
usbobj_minor_match(struct usb_obj * obj,void * match_data)247 static int usbobj_minor_match(struct usb_obj *obj, void *match_data)
248 {
249 struct generic_dev_s *dev = container_of(obj, struct generic_dev_s, obj);
250
251 return (dev->minor == *(int *)match_data);
252 }
253
__generic_dev_find_by_minor(int minor)254 static struct generic_dev_s *__generic_dev_find_by_minor(int minor)
255 {
256 struct usb_obj *obj = NULL;
257
258 obj = usbobj_find(&g_generic_obj, usbobj_minor_match, &minor);
259 if (obj == NULL)
260 {
261 usb_err("%d not found!\n", minor);
262 return NULL;
263 }
264
265 return container_of(obj, struct generic_dev_s, obj);
266 }
267
generic_dev_find_by_minor(int minor)268 static struct generic_dev_s *generic_dev_find_by_minor(int minor)
269 {
270 struct generic_dev_s *dev;
271
272 generic_dev_lock();
273 dev = __generic_dev_find_by_minor(minor);
274 generic_dev_unlock();
275 return dev;
276 }
277
generic_acquire_dev(int minor)278 static void *generic_acquire_dev(int minor)
279 {
280 struct generic_dev_s *dev = NULL;
281
282 generic_dev_lock();
283 dev = __generic_dev_find_by_minor(minor);
284 if (!dev || dev->inuse)
285 {
286 generic_dev_unlock();
287 return NULL;
288 }
289 else
290 {
291 dev->inuse = false;
292 }
293 generic_dev_unlock();
294
295 return dev;
296 }
297
generic_dev_new(const char * name)298 static struct generic_dev_s *generic_dev_new(const char *name)
299 {
300 struct generic_dev_s *dev = NULL;
301 static bool is_eevnt_initialized = false;
302 int ret;
303
304 if (g_generic_minor == (uint64_t)-1)
305 {
306 usb_err("%s: generic device is more than 64\n", __FUNCTION__);
307 return NULL;
308 }
309
310 dev = (struct generic_dev_s *)usbm_malloc(&g_generic_obj, sizeof(*dev));
311 if (!dev)
312 {
313 usb_err("%s malloc failed\n", __FUNCTION__);
314 return NULL;
315 }
316 (void)memset_s(dev, sizeof(*dev), 0, sizeof(*dev));
317 (void)usbobj_init(&dev->obj, name, usbobj_default_release);
318 (void)usbobj_init(&dev->memory_obj, name, NULL);
319 (void)usbobj_init(&dev->epfiles_obj, name, NULL);
320 spin_lock_init(&dev->event_lock);
321 spin_lock_init(&dev->eps_lock);
322 spin_lock_init(&dev->ep0_lock);
323
324 /* initialize the generic device */
325 ret = generic_ffz64(g_generic_minor);
326 g_generic_minor |= (1 << ret);
327 dev->minor = DEV_GENERIC + ret;
328 dev->minor_offset = ret;
329 dev->name = usbm_strdup(&dev->obj, name);
330 dev->event_mask = 0x0;
331 (VOID)LOS_EventInit(&dev->ep_event_all);
332 if (!is_eevnt_initialized)
333 {
334 (VOID)LOS_EventInit(&eps_event_all);
335 is_eevnt_initialized = true;
336 }
337 eps_event_mask |= (1 << (dev->minor_offset * EVENT_FOR_FUNCTION));
338 atomic_set(&dev->opened, 0);
339 dev->eps_enbale = false;
340 dev->state = GENERIC_READ_DESCRIPTORS;
341 usbobj_add(&dev->obj, &g_generic_obj);
342 generic_dev_opened(dev);
343 return dev;
344 }
345
generic_dev_clear(struct generic_dev_s * dev)346 static void generic_dev_clear(struct generic_dev_s *dev)
347 {
348 usbobj_put(&dev->epfiles_obj);
349 objres_release_all(&dev->obj);
350 }
351
generic_dev_reset(struct generic_dev_s * dev)352 static void generic_dev_reset(struct generic_dev_s *dev)
353 {
354
355 generic_dev_clear(dev);
356 /* initialize descriptors related variables */
357 dev->raw_descs_data = NULL;
358 dev->raw_descs = NULL;
359 dev->raw_strings = NULL;
360 dev->raw_descs_length = 0;
361 dev->fs_descs_count = 0;
362 dev->hs_descs_count = 0;
363 dev->ss_descs_count = 0;
364 dev->strings_count = 0;
365 dev->interfaces_count = 0;
366 dev->eps_count = 0;
367 dev->alt_setting = 0;
368 /* initialize the state of device */
369 dev->state = GENERIC_READ_DESCRIPTORS;
370 dev->setup_state = GENERIC_NO_SETUP;
371 dev->flags = 0;
372 }
373
generic_dev_opened(struct generic_dev_s * dev)374 void generic_dev_opened(struct generic_dev_s *dev)
375 {
376 generic_dev_get(dev);
377 if ((atomic_add_return(1, &dev->opened) == 1) &&
378 (dev->state == GENERIC_DEACTIVATED))
379 {
380 dev->state = GENERIC_CLOSING;
381 generic_dev_reset(dev);
382 }
383 }
384
generic_dev_closed(struct generic_dev_s * dev)385 void generic_dev_closed(struct generic_dev_s *dev)
386 {
387 /* set state to closing when opened flag is 0 */
388 if (atomic_dec_and_test(&dev->opened))
389 {
390 dev->state = GENERIC_CLOSING;
391 generic_dev_reset(dev);
392 }
393
394 /* set state to closing when opened flag is negative */
395 if (atomic_read(&dev->opened) < 0)
396 {
397 dev->state = GENERIC_CLOSING;
398 generic_dev_reset(dev);
399 }
400
401 /* decrees the reference value and release the device
402 * if there is no reference.
403 */
404 generic_dev_put(dev);
405 }
406
generic_eps_free(struct generic_dev_s * priv)407 static void generic_eps_free(struct generic_dev_s *priv)
408 {
409 struct generic_ep *ep = priv->eps;
410 uint16_t count = priv->eps_count;
411 unsigned long flags;
412
413 spin_lock_irqsave(&priv->eps_lock, flags);
414 while (count--)
415 {
416 /* free usb request of the endpoint */
417 if (ep->ep && ep->req)
418 {
419 EP_FREEREQ(ep->ep, ep->req);
420 }
421 ep->req = NULL;
422 /* free endpoint */
423 if (ep->ep && priv->usbdev)
424 {
425 DEV_FREEEP(priv->usbdev, ep->ep);
426 ep->ep = NULL;
427 }
428 ++ep;
429 }
430 spin_unlock_irqrestore(&priv->eps_lock, flags);
431 usbm_free(&priv->obj, priv->eps);
432 priv->eps = NULL;
433 }
434
generic_eps_alloc(struct generic_dev_s * priv)435 static int generic_eps_alloc(struct generic_dev_s *priv)
436 {
437 struct usbdev_req_s *req = NULL;
438 uint16_t eps_count = priv->eps_count;
439 size_t size = sizeof(struct generic_ep) * eps_count;
440 uint16_t i, j;
441
442 priv->eps = (struct generic_ep *)usbm_zalloc(&priv->obj, size);
443 if (priv->eps == NULL)
444 {
445 usb_err("%s: allocate eps failed", __FUNCTION__);
446 return -1;
447 }
448
449 for (i = 0; i < eps_count; i++)
450 {
451 usb_endpoint_descriptor_t *desc;
452 struct usbdev_ep_s *ep;
453 for (j = 0; j < 3; j++)
454 {
455 priv->eps[i].descs[j] = priv->eps_descs[i][j];
456 }
457 switch (priv->speed)
458 {
459 case USB_SPEED_SUPER:
460 desc = priv->eps[i].descs[2];
461 break;
462 case USB_SPEED_HIGH:
463 desc = priv->eps[i].descs[1];
464 break;
465 default:
466 desc = priv->eps[i].descs[1];
467 break;
468 }
469
470 ep = DEV_ALLOCEP(priv->usbdev, desc->bEndpointAddress, desc);
471 if (ep == NULL)
472 {
473 usb_err("%s: alloc ep %u failed", __FUNCTION__, desc->bEndpointAddress);
474 goto err;
475 }
476 priv->eps[i].ep = ep;
477 priv->eps[i].num = ep->eplog;
478 priv->devinfo->epno[i] = ep->eplog;
479
480 req = EP_ALLOCREQ(ep);
481 if (req == NULL)
482 {
483 usb_err("%s: alloc request for ep %u failed",
484 __FUNCTION__, desc->bEndpointAddress);
485 goto err;
486 }
487
488 priv->eps[i].req = req;
489 (VOID)LOS_EventInit(&priv->eps[i].event);
490 priv->eps_revmap[ep->eplog & USB_ENDPOINT_NUMBER_MASK] = i + 1;
491 }
492 return 0;
493
494 err:
495 generic_eps_free(priv);
496 return -1;
497 }
498
usbclass_generic_bind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)499 static int usbclass_generic_bind(struct usbdevclass_driver_s *driver,
500 struct usbdev_s *dev)
501 {
502 struct generic_driver_s *drvr = (struct generic_driver_s *)driver;
503 struct composite_dev_s *cdev = NULL;
504 struct generic_dev_s *priv = NULL;
505 struct composite_devobj_s *devobj = NULL;
506 int ret;
507
508 if (drvr == NULL || dev == NULL)
509 {
510 usb_err("%s: invalid paramter\n", __FUNCTION__);
511 return -1;
512 }
513
514 cdev = dev->ep0->priv;
515 priv = drvr->dev;
516 if (priv == NULL || priv->state != GENERIC_ACTIVE)
517 {
518 usb_err("%s: priv is NULL or state is error\n", __FUNCTION__);
519 return -1;
520 }
521 if (OsalTestSetBit(GENERIC_FL_BOUND, &priv->flags))
522 {
523 usb_err("%s: the generic device is bound\n", __FUNCTION__);
524 return -1;
525 }
526 priv->usbdev = dev;
527 devobj = usbclass_devobj_get(cdev, priv->minor);
528 if (devobj == NULL)
529 {
530 usb_err("%s: devobj is NULL\n", __FUNCTION__);
531 return -1;
532 }
533 priv->devinfo = &devobj->compdesc.devinfo;
534
535 /* initialize control request */
536 priv->ctrlreq = cdev->ctrlreq;
537 if (priv->ctrlreq == NULL)
538 {
539 usb_err("Ctrlreq is NULL!\r\n");
540 return -ENOMEM;
541 }
542 (VOID)LOS_EventInit(&priv->ctrlreq_event);
543 (VOID)LOS_EventInit(&priv->ep0_event);
544 /* allocate endpoints and conresponding requests */
545 priv->speed = USB_SPEED_HIGH;
546 ret = generic_eps_alloc(priv);
547 if (ret != 0)
548 {
549 usb_err("%s: eps allocated error\n", __FUNCTION__);
550 return -1;
551 }
552 /* send bind event to user */
553 generic_event_add(priv, GENERIC_BIND);
554
555 return 0;
556 }
557
usbclass_generic_unbind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)558 static int usbclass_generic_unbind(struct usbdevclass_driver_s *driver,
559 struct usbdev_s *dev)
560 {
561 struct generic_driver_s *drvr = NULL;
562 struct generic_dev_s *priv = NULL;
563
564 if (driver == NULL || dev == NULL)
565 {
566 usb_err("%s: invalid parameter\n", __FUNCTION__);
567 return -1;
568 }
569
570 drvr = (struct generic_driver_s *)driver;
571 priv = drvr->dev;
572 if (priv == NULL)
573 {
574 usb_err("%s: priv is NULL\n", __FUNCTION__);
575 return -1;
576 }
577 if (!OsalTestClearBit(GENERIC_FL_BOUND, &priv->flags))
578 {
579 usb_err("%s: the generic device is unbound\n", __FUNCTION__);
580 return -1;
581 }
582
583 generic_eps_disable(priv);
584 generic_eps_free(priv);
585 generic_event_add(priv, GENERIC_UNBIND);
586 return 0;
587 }
588
generic_revmap_ep(struct generic_dev_s * dev,uint8_t num)589 static int generic_revmap_ep(struct generic_dev_s *dev, uint8_t num)
590 {
591 num = dev->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
592 return num ? num : -1;
593 }
594
generic_revmap_intf(struct generic_dev_s * dev,uint8_t intf)595 static int generic_revmap_intf(struct generic_dev_s *dev, uint8_t intf)
596 {
597 return intf - dev->devinfo->ifnobase;
598 }
599
generic_set_alt(struct generic_dev_s * dev,uint32_t interface,uint32_t alt)600 static int generic_set_alt(struct generic_dev_s *dev,
601 uint32_t interface, uint32_t alt)
602 {
603 int ret = 0, intf;
604
605 if (alt != (uint32_t)-1)
606 {
607 intf = generic_revmap_intf(dev, interface);
608 if (intf < 0)
609 {
610 return intf;
611 }
612 }
613
614 if (dev->alt_setting != alt)
615 {
616 generic_eps_disable(dev);
617 }
618
619 if (alt == (uint32_t)-1)
620 {
621 generic_event_add(dev, GENERIC_DISABLE);
622 return 0;
623 }
624 if (dev->eps_enbale)
625 {
626 generic_eps_disable(dev);
627 }
628 ret = generic_eps_enable(dev);
629 if (ret >= 0)
630 {
631 generic_event_add(dev, GENERIC_ENABLE);
632 dev->alt_setting = alt;
633 }
634 return ret;
635 }
636
generic_set_config(struct generic_dev_s * dev)637 static int generic_set_config(struct generic_dev_s *dev)
638 {
639 int i, ret;
640
641 for (i = 0; i < 1; i++)
642 {
643 ret = generic_set_alt(dev, dev->devinfo->ifnobase + i, 0);
644 if (ret < 0)
645 {
646 usb_err("%s: interface %d set alt failed\n", __FUNCTION__, i);
647 return -1;
648 }
649 }
650 return 0;
651 }
652
use_tw(uWord w,int v)653 static void use_tw(uWord w, int v)
654 {
655 w[0] = (uint8_t)(v);
656 w[1] = (uint8_t)((v) >> 8);
657 }
658
usbclass_generic_setup(struct usbdevclass_driver_s * driver,struct usbdev_s * dev,const struct usb_device_request * ctrl,uint8_t * dataout,size_t outlen)659 static int usbclass_generic_setup(struct usbdevclass_driver_s *driver,
660 struct usbdev_s *dev,
661 const struct usb_device_request *ctrl,
662 uint8_t *dataout, size_t outlen)
663 {
664 uint16_t w_value;
665 uint16_t w_index;
666 struct generic_dev_s *priv = NULL;
667 struct generic_driver_s *drvr = NULL;
668 unsigned long flags;
669 int ret = -1;
670
671 if (dev == NULL || driver == NULL || ctrl == NULL)
672 {
673 usb_err("%s: invalid parameter\n", __FUNCTION__);
674 return -1;
675 }
676
677 drvr = (struct generic_driver_s *)driver;
678 priv = drvr->dev;
679 if (priv == NULL || priv->state != GENERIC_ACTIVE)
680 {
681 usb_err("%s: priv is NULL or state is incorrect\n", __FUNCTION__);
682 return -1;
683 }
684
685 w_index = UGETW(ctrl->wIndex);
686 w_value = UGETW(ctrl->wValue);
687
688 if (UT_GET_TYPE(ctrl->bmRequestType) == UT_STANDARD)
689 {
690 /**********************************************************************
691 * Standard Requests
692 **********************************************************************/
693 switch (ctrl->bRequest)
694 {
695 case USB_REQ_SET_CONFIGURATION:
696 if (ctrl->bmRequestType == 0)
697 {
698 ret = generic_set_config(priv);
699 }
700 return ret;
701
702 case USB_REQ_SET_INTERFACE:
703 if (ctrl->bmRequestType == 0)
704 {
705 ret = generic_set_alt(priv, w_index, w_value);
706 }
707 return ret;
708
709 default:
710 break;
711 }
712 }
713
714 /* process class or vendor specific requests */
715 switch (UT_GET_RECIPIENT(ctrl->bmRequestType))
716 {
717 case USB_RECIP_INTERFACE:
718 ret = generic_revmap_intf(priv, w_index);
719 if (ret < 0)
720 {
721 return ret;
722 }
723 break;
724
725 case USB_RECIP_ENDPOINT:
726 ret = generic_revmap_ep(priv, w_index);
727 if (ret < 0)
728 {
729 return ret;
730 }
731 break;
732
733 default:
734 if (priv->flags & GENERIC_ALL_CTRL_RECIP)
735 {
736 ret = w_index;
737 }
738 else
739 {
740 return -1;
741 }
742 }
743
744 spin_lock_irqsave(&priv->event_lock, flags);
745 priv->setup = *ctrl;
746 use_tw(priv->setup.wIndex, ret);
747 __generic_event_add(priv, GENERIC_SETUP);
748 spin_unlock_irqrestore(&priv->event_lock, flags);
749
750 return 0;
751 }
752
usbclass_generic_disconnect(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)753 static void usbclass_generic_disconnect(struct usbdevclass_driver_s *driver,
754 struct usbdev_s *dev)
755 {
756 struct generic_dev_s *priv = NULL;
757
758 (void)dev;
759 if (driver == NULL)
760 {
761 usb_err("driver pointer is NULL!\n");
762 return;
763 }
764
765 priv = ((struct generic_driver_s *)driver)->dev;
766 if (priv == NULL)
767 {
768 usb_err("No device!\n");
769 return;
770 }
771
772 (void)generic_set_alt(priv, 0, (uint32_t)-1);
773 }
774
generic_mkdevdesc(uint8_t * buf)775 static void generic_mkdevdesc(uint8_t *buf)
776 {
777 (void)buf;
778
779 /* f_generic does not provide device descriptor */
780 return;
781 }
782
generic_mkcfgdesc(uint8_t * buf,struct usbdev_devinfo_s * devinfo)783 static int16_t generic_mkcfgdesc(uint8_t *buf,
784 struct usbdev_devinfo_s *devinfo)
785 {
786 struct composite_devobj_s *device = container_of(devinfo,
787 struct composite_devobj_s,
788 compdesc.devinfo);
789 struct generic_driver_s *drvr = (struct generic_driver_s *)device->dev;
790 struct generic_dev_s *dev = drvr->dev;
791 int16_t total_len = 0;
792 int16_t len = USB_CONFIG_DESC_SIZE;
793 errno_t ret;
794
795 g_generic_config_desc.bNumInterface = devinfo->ninterfaces;
796
797 /* Copy device configure descriptor. */
798
799 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ,
800 (const void *)&g_generic_config_desc,
801 (uint32_t)len);
802 if (ret != EOK)
803 {
804 usb_err("memcpy_s fail, ret:%d\n", ret);
805 return -1;
806 }
807 total_len += len;
808
809 /* Copy device function descriptor. */
810
811 len = dev->raw_descs_length;
812 ret = memcpy_s(buf, (USB_COMP_EP0_BUFSIZ - total_len),
813 (const void *)dev->raw_descs, (uint32_t)len);
814 if (ret != EOK)
815 {
816 usb_err("memcpy_s fail, ret:%d\n", ret);
817 return -1;
818 }
819 total_len += len;
820
821 return (int16_t)total_len;
822 }
823
generic_mkstrdesc(uint8_t id,uint8_t * buf)824 static int generic_mkstrdesc(uint8_t id, uint8_t *buf)
825 {
826 struct generic_dev_s *dev = NULL;
827 int minor = (int)*buf;
828 struct usb_string_descriptor *s = ( struct usb_string_descriptor *)buf;
829 errno_t ret;
830 int i;
831
832 dev = generic_dev_find_by_minor(minor);
833 if (!dev)
834 {
835 return -1;
836 }
837
838 for (i = 0; dev->dev_strings->strings[i].s != NULL; i++)
839 {
840 const char *str = dev->dev_strings->strings[i].s;
841 uint32_t len = strlen(str);
842 if (dev->dev_strings->strings[i].id == id)
843 {
844 ret = utf8_to_utf16le(str, (uint8_t *)(buf + 2), len);
845 if (ret <= 0)
846 {
847 usb_err("memcpy_s failed, ret = %d\n", ret);
848 return -1;
849 }
850 s->bLength = 2 + (ret * 2);
851 s->bDescriptorType = UDESC_STRING;
852 return s->bLength;
853 }
854 }
855
856 usb_err("Can not find the id = %u of string\n", id);
857 return -1;
858 }
859
860 #define GENERIC_NCONFIGS 1
861 #define GENERIC_CONFIGID 0
generic_get_composite_devdesc(struct composite_devdesc_s * dev,int minor)862 static void generic_get_composite_devdesc(struct composite_devdesc_s *dev,
863 int minor)
864 {
865 struct generic_dev_s *priv = NULL;
866
867 (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0,
868 sizeof(struct composite_devdesc_s));
869
870 dev->mkdevdesc = generic_mkdevdesc;
871 dev->mkconfdesc = generic_mkcfgdesc;
872 dev->mkstrdesc = generic_mkstrdesc;
873
874 dev->nconfigs = GENERIC_NCONFIGS; /* Number of configurations supported */
875 dev->configid = GENERIC_CONFIGID; /* The only supported configuration ID */
876
877 /* get generic device by minor */
878 priv = generic_dev_find_by_minor(minor);
879 if (priv == NULL)
880 {
881 usb_err("%s: can't find generic dev %d", __FUNCTION__, minor);
882 return;
883 }
884
885 /* Interfaces.
886 *
887 * ifnobase must be provided by board-specific logic
888 */
889 dev->devinfo.ninterfaces = priv->interfaces_count;
890
891 /* Strings.
892 *
893 * strbase must be provided by board-specific logic
894 */
895
896 dev->devinfo.nstrings = priv->strings_count;
897
898 /* Endpoints.
899 *
900 * Endpoint numbers must be provided by board-specific logic.
901 */
902
903 dev->devinfo.nendpoints = priv->eps_count;
904 }
905
generic_classobject(int minor,struct usbdev_devinfo_s * devinfo,struct usbdevclass_driver_s ** classdev)906 static int generic_classobject(int minor, struct usbdev_devinfo_s *devinfo,
907 struct usbdevclass_driver_s **classdev)
908 {
909 struct generic_dev_s *dev = NULL;
910 struct generic_driver_s *drvr = NULL;
911
912 (void)devinfo;
913
914 /* Acquire the USB generic driver object */
915
916 dev = generic_acquire_dev(minor);
917 if (dev == NULL)
918 {
919 usb_err("%s: acquire the generic driver failed\n", __FUNCTION__);
920 return -1;
921 }
922
923 /* Allocate the structures needed */
924
925 drvr = (struct generic_driver_s *)usbm_malloc(&dev->obj, sizeof(*drvr));
926 if (drvr == NULL)
927 {
928 dev->inuse = false;
929 return -1;
930 }
931 memset_s(drvr, sizeof(*drvr), 0, sizeof(*drvr));
932
933 /* Initialize the USB class driver structure */
934
935 drvr->drvr.speed = USB_SPEED_HIGH;
936 drvr->drvr.ops = &g_generic_driverops;
937 drvr->dev = dev;
938
939 *classdev = &drvr->drvr;
940 return 0;
941 }
942
generic_uninitialize(struct usbdevclass_driver_s * classdev)943 static void generic_uninitialize(struct usbdevclass_driver_s *classdev)
944 {
945 struct generic_driver_s *generic_drvr = (struct generic_driver_s *)classdev;
946 struct generic_dev_s *priv = NULL;
947
948 if (generic_drvr == NULL || generic_drvr->dev == NULL)
949 {
950 usb_err("%s: invalid parameter\n", __FUNCTION__);
951 return;
952 }
953
954 priv = generic_drvr->dev;
955 generic_dev_put(priv);
956 }
957
generic_obj_release_dev(struct generic_dev_s * dev)958 static void generic_obj_release_dev(struct generic_dev_s *dev)
959 {
960 if (dev)
961 {
962 usbobj_remove(&dev->obj);
963 g_generic_minor &= ~(1 << dev->minor_offset);
964 }
965 }
966
usbdev_generic_alloc_instance(const char * name)967 int usbdev_generic_alloc_instance(const char *name)
968 {
969 static bool is_initialized = false;
970 struct generic_dev_s *dev = NULL;
971 struct usb_obj *obj = NULL;
972 int ret;
973
974 if (!name || (strlen(name) == 0) ||
975 (strlen(name) > GENERIC_NAME_LEN))
976 {
977 return -1;
978 }
979
980 if (!is_initialized)
981 {
982 (void)usbobj_init(&g_generic_obj, "generic", NULL);
983 is_initialized = true;
984 }
985
986 /* check the device is exist or not */
987 obj = usbobj_find(&g_generic_obj, usbobj_default_match, (void *)name);
988 if (obj != NULL)
989 {
990 usb_err("%s already exists!\n", name);
991 return -1;
992 }
993
994 dev = generic_dev_new(name);
995 if (dev == NULL)
996 {
997 return -1;
998 }
999
1000 ret = generic_create_ep0(dev);
1001 if (ret)
1002 {
1003 generic_dev_put(dev);
1004 return -1;
1005 }
1006
1007 return dev->minor;
1008 }
1009
usbdev_generic_free_instance(const char * name)1010 int usbdev_generic_free_instance(const char *name)
1011 {
1012 struct generic_dev_s *dev = NULL;
1013 int ret;
1014
1015 if (!name || (strlen(name) == 0))
1016 {
1017 usb_err("%s: invalid parameter\n", __FUNCTION__);
1018 return -1;
1019 }
1020
1021 dev = generic_dev_find_by_name(name);
1022 if (!dev)
1023 {
1024 usb_err("%s does not exist!\n", name);
1025 return -1;
1026 }
1027
1028 /* remove ep0 device node */
1029 ret = generic_remove_ep0(dev);
1030 if (ret)
1031 {
1032 return -1;
1033 }
1034 ret = generic_remove_epfiles(dev);
1035 if (ret)
1036 {
1037 return -1;
1038 }
1039
1040 generic_obj_release_dev(dev);
1041 generic_dev_closed(dev);
1042
1043 return 0;
1044 }
1045
usbdev_generic_initialize_sub(struct composite_devdesc_s * dev,int ifnobase,int minor)1046 void usbdev_generic_initialize_sub(struct composite_devdesc_s *dev,
1047 int ifnobase, int minor)
1048 {
1049 //int ret;
1050 generic_get_composite_devdesc(dev, minor);
1051
1052 /* Overwrite and correct some values... */
1053
1054 dev->classobject = generic_classobject;
1055 dev->uninitialize = generic_uninitialize;
1056
1057 /* Interfaces */
1058
1059 dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */
1060 dev->minor = minor; /* The minor interface number */
1061
1062 /* Strings */
1063
1064 dev->devinfo.strbase = 0; /* Offset to String Numbers */
1065 }
1066
1067 #ifdef __cplusplus
1068 #if __cplusplus
1069 //}
1070 #endif /* __cplusplus */
1071 #endif /* __cplusplus */
1072