1use core::mem::MaybeUninit;
22use kernel::capabilities;
23use kernel::component::Component;
24use kernel::create_capability;
25use kernel::hil::usb::UsbController;
26
27#[macro_export]
28macro_rules! usb_component_static {
29 ($U:ty $(,)?) => {{
30 let usb_client = kernel::static_buf!(capsules_extra::usb::usbc_client::Client<'static, $U>);
31 let usb_driver = kernel::static_buf!(
32 capsules_extra::usb::usb_user::UsbSyscallDriver<
33 'static,
34 capsules_extra::usb::usbc_client::Client<'static, $U>,
35 >
36 );
37 (usb_client, usb_driver)
38 }};
39}
40
41pub struct UsbComponent<U: UsbController<'static> + 'static> {
42 board_kernel: &'static kernel::Kernel,
43 driver_num: usize,
44 usbc: &'static U,
45}
46
47impl<U: UsbController<'static> + 'static> UsbComponent<U> {
48 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize, usbc: &'static U) -> Self {
49 Self {
50 board_kernel,
51 driver_num,
52 usbc,
53 }
54 }
55}
56
57impl<U: UsbController<'static> + 'static> Component for UsbComponent<U> {
58 type StaticInput = (
59 &'static mut MaybeUninit<capsules_extra::usb::usbc_client::Client<'static, U>>,
60 &'static mut MaybeUninit<
61 capsules_extra::usb::usb_user::UsbSyscallDriver<
62 'static,
63 capsules_extra::usb::usbc_client::Client<'static, U>,
64 >,
65 >,
66 );
67 type Output = &'static capsules_extra::usb::usb_user::UsbSyscallDriver<
68 'static,
69 capsules_extra::usb::usbc_client::Client<'static, U>,
70 >;
71
72 fn finalize(self, s: Self::StaticInput) -> Self::Output {
73 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
74
75 let usb_client = s.0.write(capsules_extra::usb::usbc_client::Client::new(
77 self.usbc,
78 capsules_extra::usb::usbc_client::MAX_CTRL_PACKET_SIZE_SAM4L,
79 ));
80 self.usbc.set_client(usb_client);
81
82 let usb_driver =
84 s.1.write(capsules_extra::usb::usb_user::UsbSyscallDriver::new(
85 usb_client,
86 self.board_kernel.create_grant(self.driver_num, &grant_cap),
87 ));
88
89 usb_driver
90 }
91}