@@ -49,9 +49,31 @@ struct udc_mcux_config {
49
49
struct udc_mcux_data {
50
50
const struct device * dev ;
51
51
usb_device_struct_t mcux_device ;
52
+ struct k_work work ;
53
+ struct k_fifo fifo ;
52
54
uint8_t controller_id ; /* 0xFF is invalid value */
53
55
};
54
56
57
+ /* Structure for driver's events */
58
+ struct udc_mcux_event {
59
+ sys_snode_t node ;
60
+ const struct device * dev ;
61
+ usb_device_callback_message_struct_t mcux_msg ;
62
+ };
63
+
64
+ K_MEM_SLAB_DEFINE (udc_event_slab , sizeof (struct udc_mcux_event ),
65
+ CONFIG_UDC_NXP_EVENT_COUNT , sizeof (void * ));
66
+
67
+ static int udc_mcux_lock (const struct device * dev )
68
+ {
69
+ return udc_lock_internal (dev , K_FOREVER );
70
+ }
71
+
72
+ static int udc_mcux_unlock (const struct device * dev )
73
+ {
74
+ return udc_unlock_internal (dev );
75
+ }
76
+
55
77
static int udc_mcux_control (const struct device * dev , usb_device_control_type_t command ,
56
78
void * param )
57
79
{
@@ -81,7 +103,6 @@ static int udc_mcux_ep_feed(const struct device *dev,
81
103
usb_status_t status = kStatus_USB_Success ;
82
104
uint8_t * data ;
83
105
uint32_t len ;
84
- unsigned int key ;
85
106
usb_device_endpoint_status_struct_t ep_status ;
86
107
87
108
ep_status .endpointAddress = cfg -> addr ;
@@ -90,10 +111,10 @@ static int udc_mcux_ep_feed(const struct device *dev,
90
111
return - EACCES ; /* stalled */
91
112
}
92
113
93
- key = irq_lock ( );
114
+ udc_mcux_lock ( dev );
94
115
if (!udc_ep_is_busy (dev , cfg -> addr )) {
95
116
udc_ep_set_busy (dev , cfg -> addr , true);
96
- irq_unlock ( key );
117
+ udc_mcux_unlock ( dev );
97
118
98
119
if (USB_EP_DIR_IS_OUT (cfg -> addr )) {
99
120
len = net_buf_tailroom (buf );
@@ -107,13 +128,13 @@ static int udc_mcux_ep_feed(const struct device *dev,
107
128
cfg -> addr , data , len );
108
129
}
109
130
110
- key = irq_lock ( );
131
+ udc_mcux_lock ( dev );
111
132
if (status != kStatus_USB_Success ) {
112
133
udc_ep_set_busy (dev , cfg -> addr , false);
113
134
}
114
- irq_unlock ( key );
135
+ udc_mcux_unlock ( dev );
115
136
} else {
116
- irq_unlock ( key );
137
+ udc_mcux_unlock ( dev );
117
138
return - EBUSY ;
118
139
}
119
140
@@ -303,13 +324,12 @@ static int udc_mcux_handler_out(const struct device *dev, uint8_t ep,
303
324
{
304
325
int err ;
305
326
struct net_buf * buf ;
306
- unsigned int key ;
307
327
308
328
buf = udc_buf_get (dev , ep );
309
329
310
- key = irq_lock ( );
330
+ udc_mcux_lock ( dev );
311
331
udc_ep_set_busy (dev , ep , false);
312
- irq_unlock ( key );
332
+ udc_mcux_unlock ( dev );
313
333
314
334
if (buf == NULL ) {
315
335
udc_submit_event (dev , UDC_EVT_ERROR , - ENOBUFS );
@@ -357,7 +377,6 @@ static int udc_mcux_handler_in(const struct device *dev, uint8_t ep,
357
377
{
358
378
int err ;
359
379
struct net_buf * buf ;
360
- unsigned int key ;
361
380
362
381
buf = udc_buf_peek (dev , ep );
363
382
if (buf == NULL ) {
@@ -371,9 +390,9 @@ static int udc_mcux_handler_in(const struct device *dev, uint8_t ep,
371
390
372
391
buf = udc_buf_get (dev , ep );
373
392
374
- key = irq_lock ( );
393
+ udc_mcux_lock ( dev );
375
394
udc_ep_set_busy (dev , ep , false);
376
- irq_unlock ( key );
395
+ udc_mcux_unlock ( dev );
377
396
378
397
if (buf == NULL ) {
379
398
udc_submit_event (dev , UDC_EVT_ERROR , - ENOBUFS );
@@ -388,16 +407,95 @@ static int udc_mcux_handler_in(const struct device *dev, uint8_t ep,
388
407
return err ;
389
408
}
390
409
410
+ static void udc_mcux_event_submit (const struct device * dev ,
411
+ const usb_device_callback_message_struct_t * mcux_msg )
412
+ {
413
+ struct udc_mcux_data * priv = udc_get_private (dev );
414
+ struct udc_mcux_event * ev ;
415
+ int ret ;
416
+
417
+ ret = k_mem_slab_alloc (& udc_event_slab , (void * * )& ev , K_NO_WAIT );
418
+ if (ret ) {
419
+ udc_submit_event (dev , UDC_EVT_ERROR , ret );
420
+ LOG_ERR ("Failed to allocate slab" );
421
+ return ;
422
+ }
423
+
424
+ ev -> dev = dev ;
425
+ ev -> mcux_msg = * mcux_msg ;
426
+ k_fifo_put (& priv -> fifo , ev );
427
+ k_work_submit_to_queue (udc_get_work_q (), & priv -> work );
428
+ }
429
+
430
+ static void udc_mcux_work_handler (struct k_work * item )
431
+ {
432
+ struct udc_mcux_event * ev ;
433
+ struct udc_mcux_data * priv ;
434
+ usb_device_callback_message_struct_t * mcux_msg ;
435
+ int err ;
436
+ uint8_t ep ;
437
+
438
+ priv = CONTAINER_OF (item , struct udc_mcux_data , work );
439
+ while ((ev = k_fifo_get (& priv -> fifo , K_NO_WAIT )) != NULL ) {
440
+ mcux_msg = & ev -> mcux_msg ;
441
+
442
+ if (mcux_msg -> code == kUSB_DeviceNotifyBusReset ) {
443
+ struct udc_ep_config * cfg ;
444
+
445
+ udc_mcux_control (ev -> dev , kUSB_DeviceControlSetDefaultStatus , NULL );
446
+ cfg = udc_get_ep_cfg (ev -> dev , USB_CONTROL_EP_OUT );
447
+ if (cfg -> stat .enabled ) {
448
+ udc_ep_disable_internal (ev -> dev , USB_CONTROL_EP_OUT );
449
+ }
450
+ cfg = udc_get_ep_cfg (ev -> dev , USB_CONTROL_EP_IN );
451
+ if (cfg -> stat .enabled ) {
452
+ udc_ep_disable_internal (ev -> dev , USB_CONTROL_EP_IN );
453
+ }
454
+ if (udc_ep_enable_internal (ev -> dev , USB_CONTROL_EP_OUT ,
455
+ USB_EP_TYPE_CONTROL ,
456
+ USB_MCUX_EP0_SIZE , 0 )) {
457
+ LOG_ERR ("Failed to enable control endpoint" );
458
+ }
459
+
460
+ if (udc_ep_enable_internal (ev -> dev , USB_CONTROL_EP_IN ,
461
+ USB_EP_TYPE_CONTROL ,
462
+ USB_MCUX_EP0_SIZE , 0 )) {
463
+ LOG_ERR ("Failed to enable control endpoint" );
464
+ }
465
+ udc_submit_event (ev -> dev , UDC_EVT_RESET , 0 );
466
+ } else {
467
+ ep = mcux_msg -> code ;
468
+
469
+ if (mcux_msg -> isSetup ) {
470
+ struct usb_setup_packet * setup =
471
+ (struct usb_setup_packet * )mcux_msg -> buffer ;
472
+
473
+ err = udc_mcux_handler_setup (ev -> dev , setup );
474
+ } else if (USB_EP_DIR_IS_IN (ep )) {
475
+ err = udc_mcux_handler_in (ev -> dev , ep , mcux_msg -> buffer ,
476
+ mcux_msg -> length );
477
+ } else {
478
+ err = udc_mcux_handler_out (ev -> dev , ep , mcux_msg -> buffer ,
479
+ mcux_msg -> length );
480
+ }
481
+
482
+ if (unlikely (err )) {
483
+ udc_submit_event (ev -> dev , UDC_EVT_ERROR , err );
484
+ }
485
+ }
486
+
487
+ k_mem_slab_free (& udc_event_slab , (void * )ev );
488
+ }
489
+ }
490
+
391
491
/* NXP MCUX controller driver notify transfers/status through this interface */
392
492
usb_status_t USB_DeviceNotificationTrigger (void * handle , void * msg )
393
493
{
394
494
usb_device_callback_message_struct_t * mcux_msg = msg ;
395
- uint8_t ep ;
396
495
usb_device_notification_t mcux_notify ;
397
496
struct udc_mcux_data * priv ;
398
497
const struct device * dev ;
399
498
usb_status_t mcux_status = kStatus_USB_Success ;
400
- int err = 0 ;
401
499
402
500
if ((NULL == msg ) || (NULL == handle )) {
403
501
return kStatus_USB_InvalidHandle ;
@@ -409,31 +507,7 @@ usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
409
507
410
508
switch (mcux_notify ) {
411
509
case kUSB_DeviceNotifyBusReset :
412
- struct udc_ep_config * cfg ;
413
-
414
- udc_mcux_control (dev , kUSB_DeviceControlSetDefaultStatus , NULL );
415
- cfg = udc_get_ep_cfg (dev , USB_CONTROL_EP_OUT );
416
- if (cfg -> stat .enabled ) {
417
- udc_ep_disable_internal (dev , USB_CONTROL_EP_OUT );
418
- }
419
- cfg = udc_get_ep_cfg (dev , USB_CONTROL_EP_IN );
420
- if (cfg -> stat .enabled ) {
421
- udc_ep_disable_internal (dev , USB_CONTROL_EP_IN );
422
- }
423
- if (udc_ep_enable_internal (dev , USB_CONTROL_EP_OUT ,
424
- USB_EP_TYPE_CONTROL ,
425
- USB_MCUX_EP0_SIZE , 0 )) {
426
- LOG_ERR ("Failed to enable control endpoint" );
427
- return - EIO ;
428
- }
429
-
430
- if (udc_ep_enable_internal (dev , USB_CONTROL_EP_IN ,
431
- USB_EP_TYPE_CONTROL ,
432
- USB_MCUX_EP0_SIZE , 0 )) {
433
- LOG_ERR ("Failed to enable control endpoint" );
434
- return - EIO ;
435
- }
436
- udc_submit_event (dev , UDC_EVT_RESET , 0 );
510
+ udc_mcux_event_submit (dev , mcux_msg );
437
511
break ;
438
512
case kUSB_DeviceNotifyError :
439
513
udc_submit_event (dev , UDC_EVT_ERROR , - EIO );
@@ -458,25 +532,10 @@ usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
458
532
udc_submit_event (dev , UDC_EVT_SOF , 0 );
459
533
break ;
460
534
default :
461
- ep = mcux_msg -> code ;
462
- if (mcux_msg -> isSetup ) {
463
- struct usb_setup_packet * setup =
464
- (struct usb_setup_packet * )mcux_msg -> buffer ;
465
-
466
- err = udc_mcux_handler_setup (dev , setup );
467
- } else if (USB_EP_DIR_IS_IN (ep )) {
468
- err = udc_mcux_handler_in (dev , ep , mcux_msg -> buffer , mcux_msg -> length );
469
- } else {
470
- err = udc_mcux_handler_out (dev , ep , mcux_msg -> buffer , mcux_msg -> length );
471
- }
472
-
535
+ udc_mcux_event_submit (dev , mcux_msg );
473
536
break ;
474
537
}
475
538
476
- if (unlikely (err )) {
477
- udc_submit_event (dev , UDC_EVT_ERROR , err );
478
- mcux_status = kStatus_USB_Error ;
479
- }
480
539
return mcux_status ;
481
540
}
482
541
@@ -532,17 +591,16 @@ static int udc_mcux_ep_dequeue(const struct device *dev,
532
591
struct udc_ep_config * const cfg )
533
592
{
534
593
struct net_buf * buf ;
535
- unsigned int key ;
536
594
537
595
cfg -> stat .halted = false;
538
596
buf = udc_buf_get_all (dev , cfg -> addr );
539
597
if (buf ) {
540
598
udc_submit_ep_event (dev , buf , - ECONNABORTED );
541
599
}
542
600
543
- key = irq_lock ( );
601
+ udc_mcux_lock ( dev );
544
602
udc_ep_set_busy (dev , cfg -> addr , false);
545
- irq_unlock ( key );
603
+ udc_mcux_unlock ( dev );
546
604
547
605
return 0 ;
548
606
}
@@ -676,16 +734,6 @@ static int udc_mcux_shutdown(const struct device *dev)
676
734
return 0 ;
677
735
}
678
736
679
- static int udc_mcux_lock (const struct device * dev )
680
- {
681
- return udc_lock_internal (dev , K_FOREVER );
682
- }
683
-
684
- static int udc_mcux_unlock (const struct device * dev )
685
- {
686
- return udc_unlock_internal (dev );
687
- }
688
-
689
737
static inline void udc_mcux_get_hal_driver_id (struct udc_mcux_data * priv ,
690
738
const struct udc_mcux_config * config )
691
739
{
@@ -723,6 +771,8 @@ static int udc_mcux_driver_preinit(const struct device *dev)
723
771
}
724
772
725
773
k_mutex_init (& data -> mutex );
774
+ k_fifo_init (& priv -> fifo );
775
+ k_work_init (& priv -> work , udc_mcux_work_handler );
726
776
727
777
for (int i = 0 ; i < config -> num_of_eps ; i ++ ) {
728
778
config -> ep_cfg_out [i ].caps .out = 1 ;
0 commit comments