1 #include "usb-msc-bulk.h"
11 #define PRINTF(...) printf(__VA_ARGS__)
16 static const uint8_t max_lun = 0;
18 static USBBuffer data_usb_buffer[USB_MSC_BUFFERS];
19 static unsigned int buffer_lengths[USB_MSC_BUFFERS];
21 static unsigned int buf_first = 0;
22 static unsigned int buf_free = 0;
23 static unsigned int buf_submitted = 0;
25 #define USB_BUFFER_ID_UNUSED 0
26 #define USB_BUFFER_ID_CBW 1
27 #define USB_BUFFER_ID_CSW 2
28 #define USB_BUFFER_ID_DATA 3
29 #define USB_BUFFER_ID_DISCARD 4
30 #define USB_BUFFER_ID_HALT 5
31 #define USB_BUFFER_ID_MASK 0x07
33 static struct usb_msc_bulk_cbw cbw_buffer;
34 static struct usb_msc_bulk_csw csw_buffer;
39 PROCESS(usb_mass_bulk_process,
"USB mass storage bulk only process");
41 static process_event_t reset_event;
43 static struct usb_msc_command_state state;
46 #define PREV_BUF(x) (((x) == 0) ? USB_MSC_BUFFERS - 1 : (x) - 1)
47 #define NEXT_BUF(x) (((x) < (USB_MSC_BUFFERS-1)) ? (x) + 1 : 0)
49 usb_msc_send_data_buf_flags(
const uint8_t *data,
unsigned int len,
50 unsigned int flags, uint16_t buf_flags)
52 USBBuffer *buffer = &data_usb_buffer[buf_free];
53 if (buffer->id != USB_BUFFER_ID_UNUSED) {
54 printf(
"Data IN buffer busy\n");
57 buffer->flags = USB_BUFFER_NOTIFY | buf_flags;
59 buffer->data = (uint8_t*)data;
61 buffer_lengths[buf_free] = len;
62 buffer->id = USB_BUFFER_ID_DATA |
flags;
63 if (buf_free != buf_first) {
64 data_usb_buffer[PREV_BUF(buf_free)].next = buffer;
66 state.cmd_data_submitted += len;
67 buf_free = NEXT_BUF(buf_free);
69 if (flags & USB_MSC_DATA_SEND) {
70 usb_submit_xmit_buffer(BULK_IN, &data_usb_buffer[buf_first]);
73 }
else if (flags & USB_MSC_DATA_LAST) {
75 PRINTF(
"Send last\n");
82 usb_msc_send_data(
const uint8_t *data,
unsigned int len,
unsigned int flags)
84 usb_msc_send_data_buf_flags(data, len, flags,0);
88 usb_msc_receive_data_buf_flags(uint8_t *data,
unsigned int len,
89 unsigned int flags, uint16_t buf_flags)
91 USBBuffer *buffer = &data_usb_buffer[buf_free];
92 if (buffer->id != USB_BUFFER_ID_UNUSED) {
93 printf(
"Data OUT buffer busy\n");
96 buffer->flags = USB_BUFFER_NOTIFY | buf_flags;
100 buffer_lengths[buf_free] = len;
101 buffer->id = USB_BUFFER_ID_DATA |
flags;
102 if (buf_free != buf_first) {
103 data_usb_buffer[PREV_BUF(buf_free)].next = buffer;
105 state.cmd_data_submitted += len;
106 buf_free = NEXT_BUF(buf_free);
107 if (flags & USB_MSC_DATA_RECEIVE) {
108 usb_submit_recv_buffer(BULK_OUT, &data_usb_buffer[buf_first]);
109 buf_first = buf_free;
110 }
else if (flags & USB_MSC_DATA_LAST) {
111 usb_discard_all_buffers(BULK_OUT);
113 while(buf_submitted != PREV_BUF(buf_free)) {
114 data_usb_buffer[buf_submitted].id = USB_BUFFER_ID_UNUSED;
115 buf_submitted = NEXT_BUF(buf_submitted);
117 buf_first = buf_free;
123 usb_msc_receive_data(uint8_t *data,
unsigned int len,
unsigned int flags)
125 usb_msc_receive_data_buf_flags(data,len,flags, 0);
129 handle_mass_bulk_requests()
131 switch(usb_setup_buffer.bmRequestType) {
133 switch(usb_setup_buffer.bRequest) {
134 case MASS_BULK_RESET:
135 PRINTF(
"Mass storage reset\n");
141 switch(usb_setup_buffer.bRequest) {
142 case MASS_BULK_GET_MAX_LUN:
144 usb_send_ctrl_response(&max_lun,
sizeof(max_lun));
152 static const struct USBRequestHandler mass_bulk_request_handler =
156 handle_mass_bulk_requests
159 static struct USBRequestHandlerHook mass_bulk_request_hook =
162 &mass_bulk_request_handler
168 USBBuffer *buffer = &data_usb_buffer[buf_free];
169 if (buffer->id != USB_BUFFER_ID_UNUSED) {
170 printf(
"CSW buffer busy\n");
174 csw_buffer.dCSWSignature = MASS_BULK_CSW_SIGNATURE;
175 csw_buffer.dCSWTag = cbw_buffer.dCBWTag;
176 csw_buffer.dCSWDataResidue =
177 cbw_buffer.dCBWDataTransferLength - state.cmd_data_submitted;
178 csw_buffer.bCSWStatus = state.status;
180 buffer->flags = USB_BUFFER_NOTIFY;
182 buffer->data =(uint8_t*)&csw_buffer ;
183 buffer->left =
sizeof(csw_buffer);
184 buffer->id = USB_BUFFER_ID_CSW;
185 if (buf_free != buf_first) {
186 data_usb_buffer[PREV_BUF(buf_free)].next = buffer;
188 buf_free = NEXT_BUF(buf_free);
189 usb_submit_xmit_buffer(BULK_IN, &data_usb_buffer[buf_first]);
190 buf_first = buf_free;
192 PRINTF(
"CSW sent: %ld\n",
sizeof(csw_buffer));
196 submit_cbw_buffer(
void)
198 USBBuffer *buffer = &data_usb_buffer[buf_free];
199 if (buffer->id != USB_BUFFER_ID_UNUSED) {
200 printf(
"CBW buffer busy\n");
203 buffer->flags = USB_BUFFER_NOTIFY;
205 buffer->data = (uint8_t*)&cbw_buffer;
206 buffer->left =
sizeof(cbw_buffer);
207 buffer->id = USB_BUFFER_ID_CBW;
208 if (buf_free != buf_first) {
209 data_usb_buffer[PREV_BUF(buf_free)].next = buffer;
211 buf_free = NEXT_BUF(buf_free);
212 usb_submit_recv_buffer(BULK_OUT, &data_usb_buffer[buf_first]);
213 PRINTF(
"CBW submitted: %d\n", buf_first);
214 buf_first = buf_free;
218 submit_halt(uint8_t addr)
220 USBBuffer *buffer = &data_usb_buffer[buf_free];
221 if (buffer->id != USB_BUFFER_ID_UNUSED) {
222 printf(
"CBW buffer busy\n");
225 buffer->flags = USB_BUFFER_NOTIFY | USB_BUFFER_HALT;
229 buffer->id = USB_BUFFER_ID_HALT;
230 if (buf_free != buf_first) {
231 data_usb_buffer[PREV_BUF(buf_free)].next = buffer;
233 buf_free = NEXT_BUF(buf_free);
235 usb_submit_xmit_buffer(addr, &data_usb_buffer[buf_first]);
237 usb_submit_recv_buffer(addr, &data_usb_buffer[buf_first]);
239 PRINTF(
"HALT submitted %p\n",buffer);
240 buf_first = buf_free;
244 get_next_buffer(uint8_t addr, uint32_t
id)
247 events = usb_get_ep_events(addr);
248 if (events & USB_EP_EVENT_NOTIFICATION) {
249 USBBuffer *buffer = &data_usb_buffer[buf_submitted];
250 if (!(buffer->flags & USB_BUFFER_SUBMITTED)) {
252 if (
id != (buffer->id & USB_BUFFER_ID_MASK)) {
253 printf(
"Wrong buffer ID expected %d, got %d\n",
254 (
int)
id, (
int)buffer->id);
257 if ((buffer->id & USB_BUFFER_ID_MASK) == USB_BUFFER_ID_DATA) {
258 state.cmd_data_transfered +=
259 buffer_lengths[buf_submitted] - buffer->left;
261 buffer->id = USB_BUFFER_ID_UNUSED;
262 buf_submitted =NEXT_BUF(buf_submitted);
269 PROCESS(usb_mass_bulk_request_process,
"USB mass storage request process");
275 usb_discard_all_buffers(BULK_OUT);
276 usb_discard_all_buffers(BULK_IN);
277 memset(data_usb_buffer, 0,
sizeof(data_usb_buffer));
283 PRINTF(
"receive_cbw_state\n");
286 if (ev == reset_event)
goto reset_state;
287 if (ev == PROCESS_EVENT_POLL) {
289 if ((buffer = get_next_buffer(BULK_OUT, USB_BUFFER_ID_CBW))) {
292 if (cbw_buffer.dCBWSignature == MASS_BULK_CBW_SIGNATURE) {
293 usb_msc_handler_status ret;
294 PRINTF(
"Got CBW seq %d\n",(
int)cbw_buffer.dCBWTag);
295 state.command = cbw_buffer.CBWCB;
296 state.command_length = cbw_buffer.bCBWCBLength;
297 state.status = MASS_BULK_CSW_STATUS_FAILED;
298 state.data_cb =
NULL;
299 state.cmd_data_submitted = 0;
300 state.cmd_data_transfered = 0;
301 ret = usb_msc_handle_command(&state);
302 if (ret == USB_MSC_HANDLER_OK) {
303 state.status = MASS_BULK_CSW_STATUS_PASSED;
304 }
else if (ret == USB_MSC_HANDLER_FAILED) {
305 state.status = MASS_BULK_CSW_STATUS_FAILED;
307 if (ret != USB_MSC_HANDLER_DELAYED
308 && buf_submitted == buf_free) {
309 if (cbw_buffer.dCBWDataTransferLength > 0) {
311 if (cbw_buffer.bmCBWFlags & MASS_BULK_CBW_FLAG_IN) {
312 submit_halt(BULK_IN);
314 submit_halt(BULK_OUT);
319 if (ev == reset_event)
goto reset_state;
320 if (ev == PROCESS_EVENT_POLL) {
322 get_next_buffer(BULK_IN, USB_BUFFER_ID_HALT);
323 if (buffer && (buffer->flags & USB_BUFFER_HALT))
break;
329 if (cbw_buffer.bmCBWFlags & MASS_BULK_CBW_FLAG_IN) {
330 goto send_data_state;
332 goto receive_data_state;
335 printf(
"Invalid CBW\n");
336 submit_halt(BULK_IN);
337 submit_halt(BULK_OUT);
340 if (ev == reset_event)
goto reset_state;
341 if (ev == PROCESS_EVENT_POLL) {
342 USBBuffer *buffer = get_next_buffer(BULK_IN, USB_BUFFER_ID_HALT);
343 if (buffer && (buffer->flags & USB_BUFFER_HALT))
break;
348 if (ev == reset_event)
goto reset_state;
349 if (ev == PROCESS_EVENT_POLL) {
350 USBBuffer *buffer = get_next_buffer(BULK_OUT, USB_BUFFER_ID_HALT);
351 if (buffer && (buffer->flags & USB_BUFFER_HALT))
break;
355 goto receive_cbw_state;
362 PRINTF(
"send_data_state\n");
366 while (buf_submitted == buf_free) {
367 PRINTF(
"Wait data\n");
373 if ((data_usb_buffer[PREV_BUF(buf_free)].
id & USB_MSC_DATA_LAST)
374 && state.cmd_data_submitted == cbw_buffer.dCBWDataTransferLength) {
379 while (data_usb_buffer[buf_submitted].flags & USB_BUFFER_SUBMITTED) {
382 while (!(data_usb_buffer[buf_submitted].flags & USB_BUFFER_SUBMITTED)) {
383 id = data_usb_buffer[buf_submitted].id;
385 if (
id == USB_BUFFER_ID_UNUSED)
break;
386 state.cmd_data_transfered += buffer_lengths[buf_submitted];
387 data_usb_buffer[buf_submitted].id = USB_BUFFER_ID_UNUSED;
388 buf_submitted =NEXT_BUF(buf_submitted);
389 if (
id & USB_MSC_DATA_DO_CALLBACK) {
391 state.data_cb(&state);
396 if (
id & USB_MSC_DATA_LAST) {
400 if (
id & USB_MSC_DATA_LAST) {
404 if (state.cmd_data_submitted < cbw_buffer.dCBWDataTransferLength) {
405 submit_halt(BULK_IN);
408 if (ev == reset_event)
goto reset_state;
409 if (ev == PROCESS_EVENT_POLL) {
410 USBBuffer *buffer = get_next_buffer(BULK_IN , USB_BUFFER_ID_HALT);
412 if (buffer->flags & USB_BUFFER_HALT)
break;
420 PRINTF(
"receive_data_state\n");
424 while (buf_submitted == buf_free) {
428 while (data_usb_buffer[buf_submitted].flags & USB_BUFFER_SUBMITTED) {
431 while (!(data_usb_buffer[buf_submitted].flags & USB_BUFFER_SUBMITTED)) {
432 id = data_usb_buffer[buf_submitted].id;
434 state.cmd_data_transfered += buffer_lengths[buf_submitted];
435 if (
id == USB_BUFFER_ID_UNUSED)
break;
436 data_usb_buffer[buf_submitted].id = USB_BUFFER_ID_UNUSED;
437 buf_submitted =NEXT_BUF(buf_submitted);
438 if (
id & USB_MSC_DATA_DO_CALLBACK) {
440 state.data_cb(&state);
444 if (
id & USB_MSC_DATA_LAST) {
448 if (
id & USB_MSC_DATA_LAST) {
454 if (state.cmd_data_submitted < cbw_buffer.dCBWDataTransferLength) {
455 submit_halt(BULK_OUT);
458 if (ev == reset_event)
goto reset_state;
459 if (ev == PROCESS_EVENT_POLL) {
460 USBBuffer *buffer = get_next_buffer(BULK_OUT, USB_BUFFER_ID_HALT);
461 if (buffer && (buffer->flags & USB_BUFFER_HALT))
break;
469 PRINTF(
"send_csw_state\n");
470 if (data_usb_buffer[PREV_BUF(buf_free)].
id != USB_BUFFER_ID_CSW) {
475 if (ev == reset_event)
goto reset_state;
477 if (ev == PROCESS_EVENT_POLL) {
479 if ((buffer = get_next_buffer(BULK_IN, USB_BUFFER_ID_CSW))) {
480 goto receive_cbw_state;
484 goto receive_cbw_state;
492 usb_msc_command_handler_init();
494 usb_set_ep_event_process(BULK_IN, &usb_mass_bulk_request_process);
495 usb_set_ep_event_process(BULK_OUT, &usb_mass_bulk_request_process);
496 usb_set_global_event_process(process_current);
497 usb_register_request_handler(&mass_bulk_request_hook);
500 if (ev == PROCESS_EVENT_EXIT)
break;
501 if (ev == PROCESS_EVENT_POLL) {
502 unsigned int events = usb_get_global_events();
504 if (events & USB_EVENT_CONFIG) {
505 if (usb_get_current_configuration() != 0) {
506 PRINTF(
"Configured\n");
507 memset(data_usb_buffer, 0,
sizeof(data_usb_buffer));
508 usb_setup_bulk_endpoint(BULK_IN);
509 usb_setup_bulk_endpoint(BULK_OUT);
513 usb_disable_endpoint(BULK_IN);
514 usb_disable_endpoint(BULK_OUT);
517 if (events & USB_EVENT_RESET) {