1use kernel::grant::{AllowRoCount, AllowRwCount, Grant, UpcallCount};
9use kernel::hil::usb_hid;
10use kernel::processbuffer::{ReadableProcessBuffer, WriteableProcessBuffer};
11use kernel::syscall::{CommandReturn, SyscallDriver};
12use kernel::utilities::cells::{OptionalCell, TakeCell};
13use kernel::{ErrorCode, ProcessId};
14
15mod rw_allow {
17 pub const RECV: usize = 0;
18 pub const SEND: usize = 1;
19 pub const COUNT: u8 = 2;
21}
22
23#[derive(Default)]
24pub struct App {}
25
26pub struct UsbHidDriver<'a, U: usb_hid::UsbHid<'a, [u8; 64]>> {
27 usb: &'a U,
28
29 app: Grant<App, UpcallCount<1>, AllowRoCount<0>, AllowRwCount<{ rw_allow::COUNT }>>,
30 processid: OptionalCell<ProcessId>,
31
32 send_buffer: TakeCell<'static, [u8; 64]>,
33 recv_buffer: TakeCell<'static, [u8; 64]>,
34}
35
36impl<'a, U: usb_hid::UsbHid<'a, [u8; 64]>> UsbHidDriver<'a, U> {
37 pub fn new(
38 usb: &'a U,
39 send_buffer: &'static mut [u8; 64],
40 recv_buffer: &'static mut [u8; 64],
41 grant: Grant<App, UpcallCount<1>, AllowRoCount<0>, AllowRwCount<{ rw_allow::COUNT }>>,
42 ) -> UsbHidDriver<'a, U> {
43 UsbHidDriver {
44 usb,
45 app: grant,
46 processid: OptionalCell::empty(),
47 send_buffer: TakeCell::new(send_buffer),
48 recv_buffer: TakeCell::new(recv_buffer),
49 }
50 }
51}
52
53impl<'a, U: usb_hid::UsbHid<'a, [u8; 64]>> usb_hid::UsbHid<'a, [u8; 64]> for UsbHidDriver<'a, U> {
54 fn send_buffer(
55 &'a self,
56 send: &'static mut [u8; 64],
57 ) -> Result<usize, (ErrorCode, &'static mut [u8; 64])> {
58 self.usb.send_buffer(send)
59 }
60
61 fn send_cancel(&'a self) -> Result<&'static mut [u8; 64], ErrorCode> {
62 self.usb.send_cancel()
63 }
64
65 fn receive_buffer(
66 &'a self,
67 recv: &'static mut [u8; 64],
68 ) -> Result<(), (ErrorCode, &'static mut [u8; 64])> {
69 self.usb.receive_buffer(recv)
70 }
71
72 fn receive_cancel(&'a self) -> Result<&'static mut [u8; 64], ErrorCode> {
73 self.usb.receive_cancel()
74 }
75}
76
77impl<'a, U: usb_hid::UsbHid<'a, [u8; 64]>> usb_hid::Client<'a, [u8; 64]> for UsbHidDriver<'a, U> {
78 fn packet_received(
79 &'a self,
80 _result: Result<(), ErrorCode>,
81 buffer: &'static mut [u8; 64],
82 _endpoint: usize,
83 ) {
84 self.processid.map(|id| {
85 let _ = self.app.enter(id, |_app, kernel_data| {
86 let _ = kernel_data
87 .get_readwrite_processbuffer(rw_allow::RECV)
88 .and_then(|recv| {
89 recv.mut_enter(|dest| {
90 dest.copy_from_slice(buffer);
91 })
92 });
93
94 kernel_data.schedule_upcall(0, (0, 0, 0)).ok();
95 });
96 });
97
98 self.recv_buffer.replace(buffer);
99 }
100
101 fn packet_transmitted(
102 &'a self,
103 _result: Result<(), ErrorCode>,
104 buffer: &'static mut [u8; 64],
105 _endpoint: usize,
106 ) {
107 self.processid.map(|id| {
108 let _ = self.app.enter(id, |_app, kernel_data| {
109 kernel_data.schedule_upcall(0, (1, 0, 0)).ok();
110 });
111 });
112
113 self.send_buffer.replace(buffer);
115 }
116}
117
118impl<'a, U: usb_hid::UsbHid<'a, [u8; 64]>> SyscallDriver for UsbHidDriver<'a, U> {
119 fn command(
129 &self,
130 command_num: usize,
131 _data1: usize,
132 _data2: usize,
133 processid: ProcessId,
134 ) -> CommandReturn {
135 let can_access = self.processid.map_or_else(
136 || {
137 self.processid.set(processid);
138 true
139 },
140 |owning_app| {
141 owning_app == processid
143 },
144 );
145
146 if !can_access {
147 return CommandReturn::failure(ErrorCode::BUSY);
148 }
149
150 match command_num {
151 0 => CommandReturn::success(),
152
153 1 => self
155 .app
156 .enter(processid, |_, kernel_data| {
157 self.processid.set(processid);
158 kernel_data
159 .get_readwrite_processbuffer(rw_allow::SEND)
160 .and_then(|send| {
161 send.enter(|data| {
162 self.send_buffer.take().map_or(
163 CommandReturn::failure(ErrorCode::BUSY),
164 |buf| {
165 data.copy_to_slice(buf);
167
168 let _ = self.usb.send_buffer(buf);
169 CommandReturn::success()
170 },
171 )
172 })
173 })
174 .unwrap_or(CommandReturn::failure(ErrorCode::RESERVE))
175 })
176 .unwrap_or_else(|err| err.into()),
177
178 2 => self
180 .app
181 .enter(processid, |_app, _| {
182 self.processid.set(processid);
183 if let Some(buf) = self.recv_buffer.take() {
184 match self.usb.receive_buffer(buf) {
185 Ok(()) => CommandReturn::success(),
186 Err((err, buffer)) => {
187 self.recv_buffer.replace(buffer);
188 CommandReturn::failure(err)
189 }
190 }
191 } else {
192 CommandReturn::failure(ErrorCode::BUSY)
193 }
194 })
195 .unwrap_or_else(|err| err.into()),
196
197 3 => self
199 .app
200 .enter(processid, |_app, _| {
201 self.processid.set(processid);
202 match self.usb.receive_cancel() {
203 Ok(buf) => {
204 self.recv_buffer.replace(buf);
205 CommandReturn::success()
206 }
207 Err(err) => CommandReturn::failure(err),
208 }
209 })
210 .unwrap_or_else(|err| err.into()),
211
212 4 => self
214 .app
215 .enter(processid, |_app, _| {
216 self.processid.set(processid);
217 match self.usb.receive_cancel() {
218 Ok(buf) => {
219 self.recv_buffer.replace(buf);
220 CommandReturn::success()
221 }
222 Err(err) => CommandReturn::failure(err),
223 }
224 })
225 .unwrap_or_else(|err| err.into()),
226
227 5 => self
242 .app
243 .enter(processid, |_app, kernel_data| {
244 if let Some(buf) = self.recv_buffer.take() {
248 if let Err((err, buffer)) = self.usb.receive_buffer(buf) {
249 self.recv_buffer.replace(buffer);
250 return CommandReturn::failure(err);
251 }
252 } else {
253 return CommandReturn::failure(ErrorCode::ALREADY);
254 }
255
256 kernel_data
259 .get_readwrite_processbuffer(rw_allow::SEND)
260 .and_then(|send| {
261 send.enter(|data| {
262 self.send_buffer.take().map_or(
263 CommandReturn::failure(ErrorCode::BUSY),
264 |buf| {
265 data.copy_to_slice(buf);
267
268 let _ = self.usb.send_buffer(buf);
269 CommandReturn::success()
270 },
271 )
272 })
273 })
274 .unwrap_or(CommandReturn::failure(ErrorCode::FAIL))
275 })
276 .unwrap_or_else(|err| err.into()),
277
278 _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
280 }
281 }
282
283 fn allocate_grant(&self, processid: ProcessId) -> Result<(), kernel::process::Error> {
284 self.app.enter(processid, |_, _| {})
285 }
286}