1 /*
2  * The Mass Storage protocol state machine in this file is based on mbed's
3  * implementation. We augment it by adding Zephyr's USB transport and Storage
4  * APIs.
5  *
6  * Copyright (c) 2010-2011 mbed.org, MIT License
7  * Copyright (c) 2016 Intel Corporation.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 
29 /**
30  * @file
31  * @brief Mass Storage device class driver
32  *
33  * Driver for USB Mass Storage device class driver
34  */
35 
36 #include <zephyr/init.h>
37 #include <errno.h>
38 #include <string.h>
39 #include <zephyr/sys/byteorder.h>
40 #include <zephyr/sys/__assert.h>
41 #include <zephyr/storage/disk_access.h>
42 #include <zephyr/usb/usb_device.h>
43 #include <usb_descriptor.h>
44 
45 #include <zephyr/logging/log.h>
46 LOG_MODULE_REGISTER(usb_msc, CONFIG_USB_MASS_STORAGE_LOG_LEVEL);
47 
48 /* MSC Subclass and Protocol Codes */
49 #define SCSI_TRANSPARENT_SUBCLASS	0x06
50 #define BULK_ONLY_TRANSPORT_PROTOCOL	0x50
51 
52 /* MSC Request Codes for Bulk-Only Transport */
53 #define MSC_REQUEST_GET_MAX_LUN		0xFE
54 #define MSC_REQUEST_RESET		0xFF
55 
56 /* MSC Command Block Wrapper (CBW) Signature */
57 #define CBW_Signature			0x43425355
58 
59 /* MSC Command Block Wrapper Flags */
60 #define CBW_DIRECTION_DATA_IN		0x80
61 
62 /* MSC Bulk-Only Command Block Wrapper (CBW) */
63 struct CBW {
64 	uint32_t Signature;
65 	uint32_t Tag;
66 	uint32_t DataLength;
67 	uint8_t  Flags;
68 	uint8_t  LUN;
69 	uint8_t  CBLength;
70 	uint8_t  CB[16];
71 } __packed;
72 
73 /* MSC Command Status Wrapper (CBW) Signature */
74 #define CSW_Signature			0x53425355
75 
76 /* MSC Command Block Status Values */
77 #define CSW_STATUS_CMD_PASSED		0x00
78 #define CSW_STATUS_CMD_FAILED		0x01
79 #define CSW_STATUS_PHASE_ERROR		0x02
80 
81 /* MSC Bulk-Only Command Status Wrapper (CSW) */
82 struct CSW {
83 	uint32_t Signature;
84 	uint32_t Tag;
85 	uint32_t DataResidue;
86 	uint8_t  Status;
87 } __packed;
88 
89 /* SCSI transparent command set used by MSC */
90 #define TEST_UNIT_READY			0x00
91 #define REQUEST_SENSE			0x03
92 #define FORMAT_UNIT			0x04
93 #define INQUIRY				0x12
94 #define MODE_SELECT6			0x15
95 #define MODE_SENSE6			0x1A
96 #define START_STOP_UNIT			0x1B
97 #define MEDIA_REMOVAL			0x1E
98 #define READ_FORMAT_CAPACITIES		0x23
99 #define READ_CAPACITY			0x25
100 #define READ10				0x28
101 #define WRITE10				0x2A
102 #define VERIFY10			0x2F
103 #define READ12				0xA8
104 #define WRITE12				0xAA
105 #define MODE_SELECT10			0x55
106 #define MODE_SENSE10			0x5A
107 
108 /* max USB packet size */
109 #define MAX_PACKET	CONFIG_MASS_STORAGE_BULK_EP_MPS
110 
111 #define BLOCK_SIZE	512
112 #define DISK_THREAD_PRIO	-5
113 
114 BUILD_ASSERT(MAX_PACKET <= BLOCK_SIZE);
115 
116 #define THREAD_OP_READ_QUEUED		1
117 #define THREAD_OP_WRITE_QUEUED		3
118 #define THREAD_OP_WRITE_DONE		4
119 
120 #define MASS_STORAGE_IN_EP_ADDR		0x82
121 #define MASS_STORAGE_OUT_EP_ADDR	0x01
122 
123 struct usb_mass_config {
124 	struct usb_if_descriptor if0;
125 	struct usb_ep_descriptor if0_in_ep;
126 	struct usb_ep_descriptor if0_out_ep;
127 } __packed;
128 
129 USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_mass_config mass_cfg = {
130 	/* Interface descriptor */
131 	.if0 = {
132 		.bLength = sizeof(struct usb_if_descriptor),
133 		.bDescriptorType = USB_DESC_INTERFACE,
134 		.bInterfaceNumber = 0,
135 		.bAlternateSetting = 0,
136 		.bNumEndpoints = 2,
137 		.bInterfaceClass = USB_BCC_MASS_STORAGE,
138 		.bInterfaceSubClass = SCSI_TRANSPARENT_SUBCLASS,
139 		.bInterfaceProtocol = BULK_ONLY_TRANSPORT_PROTOCOL,
140 		.iInterface = 0,
141 	},
142 	/* First Endpoint IN */
143 	.if0_in_ep = {
144 		.bLength = sizeof(struct usb_ep_descriptor),
145 		.bDescriptorType = USB_DESC_ENDPOINT,
146 		.bEndpointAddress = MASS_STORAGE_IN_EP_ADDR,
147 		.bmAttributes = USB_DC_EP_BULK,
148 		.wMaxPacketSize =
149 			sys_cpu_to_le16(CONFIG_MASS_STORAGE_BULK_EP_MPS),
150 		.bInterval = 0x00,
151 	},
152 	/* Second Endpoint OUT */
153 	.if0_out_ep = {
154 		.bLength = sizeof(struct usb_ep_descriptor),
155 		.bDescriptorType = USB_DESC_ENDPOINT,
156 		.bEndpointAddress = MASS_STORAGE_OUT_EP_ADDR,
157 		.bmAttributes = USB_DC_EP_BULK,
158 		.wMaxPacketSize =
159 			sys_cpu_to_le16(CONFIG_MASS_STORAGE_BULK_EP_MPS),
160 		.bInterval = 0x00,
161 	},
162 };
163 
164 static volatile int thread_op;
165 static K_KERNEL_STACK_DEFINE(mass_thread_stack, CONFIG_MASS_STORAGE_STACK_SIZE);
166 static struct k_thread mass_thread_data;
167 static struct k_sem disk_wait_sem;
168 static volatile uint32_t defered_wr_sz;
169 
170 /*
171  * Keep block buffer larger than BLOCK_SIZE for the case
172  * the dCBWDataTransferLength is multiple of the BLOCK_SIZE and
173  * the length of the transferred data is not aligned to the BLOCK_SIZE.
174  *
175  * Align for cases where the underlying disk access requires word-aligned
176  * addresses.
177  */
178 static uint8_t __aligned(4) page[BLOCK_SIZE + CONFIG_MASS_STORAGE_BULK_EP_MPS];
179 
180 /* Initialized during mass_storage_init() */
181 static uint32_t block_count;
182 static const char *disk_pdrv = CONFIG_MASS_STORAGE_DISK_NAME;
183 
184 #define MSD_OUT_EP_IDX			0
185 #define MSD_IN_EP_IDX			1
186 
187 static void mass_storage_bulk_out(uint8_t ep,
188 				  enum usb_dc_ep_cb_status_code ep_status);
189 static void mass_storage_bulk_in(uint8_t ep,
190 				 enum usb_dc_ep_cb_status_code ep_status);
191 
192 /* Describe EndPoints configuration */
193 static struct usb_ep_cfg_data mass_ep_data[] = {
194 	{
195 		.ep_cb	= mass_storage_bulk_out,
196 		.ep_addr = MASS_STORAGE_OUT_EP_ADDR
197 	},
198 	{
199 		.ep_cb = mass_storage_bulk_in,
200 		.ep_addr = MASS_STORAGE_IN_EP_ADDR
201 	}
202 };
203 
204 /* CSW Status */
205 enum Status {
206 	CSW_PASSED,
207 	CSW_FAILED,
208 	CSW_ERROR,
209 };
210 
211 /* MSC Bulk-only Stage */
212 enum Stage {
213 	MSC_READ_CBW,     /* wait a CBW */
214 	MSC_ERROR,        /* error */
215 	MSC_PROCESS_CBW,  /* process a CBW request */
216 	MSC_SEND_CSW,     /* send a CSW */
217 	MSC_WAIT_CSW      /* wait that a CSW has been effectively sent */
218 };
219 
220 /* state of the bulk-only state machine */
221 static enum Stage stage;
222 
223 /*current CBW*/
224 static struct CBW cbw;
225 
226 /*CSW which will be sent*/
227 static struct CSW csw;
228 
229 /*addr where will be read or written data*/
230 static uint32_t curr_lba;
231 
232 /*length of a reading or writing*/
233 static uint32_t length;
234 
235 /*offset into curr_lba for read/write*/
236 static uint16_t curr_offset;
237 
238 static uint8_t max_lun_count;
239 
240 /*memory OK (after a memoryVerify)*/
241 static bool memOK;
242 
243 #define INQ_VENDOR_ID_LEN 8
244 #define INQ_PRODUCT_ID_LEN 16
245 #define INQ_REVISION_LEN 4
246 
247 struct dabc_inquiry_data {
248 	uint8_t head[8];
249 	uint8_t t10_vid[INQ_VENDOR_ID_LEN];
250 	uint8_t product_id[INQ_PRODUCT_ID_LEN];
251 	uint8_t product_rev[INQ_REVISION_LEN];
252 } __packed;
253 
254 static const struct dabc_inquiry_data inq_rsp = {
255 	.head = {0x00, 0x80, 0x00, 0x01, 36 - 4, 0x80, 0x00, 0x00},
256 	.t10_vid = CONFIG_MASS_STORAGE_INQ_VENDOR_ID,
257 	.product_id = CONFIG_MASS_STORAGE_INQ_PRODUCT_ID,
258 	.product_rev = CONFIG_MASS_STORAGE_INQ_REVISION,
259 };
260 
261 BUILD_ASSERT(sizeof(CONFIG_MASS_STORAGE_INQ_VENDOR_ID) == (INQ_VENDOR_ID_LEN + 1),
262 	"CONFIG_MASS_STORAGE_INQ_VENDOR_ID must be 8 characters (pad with spaces)");
263 
264 BUILD_ASSERT(sizeof(CONFIG_MASS_STORAGE_INQ_PRODUCT_ID) == (INQ_PRODUCT_ID_LEN + 1),
265 	"CONFIG_MASS_STORAGE_INQ_PRODUCT_ID must be 16 characters (pad with spaces)");
266 
267 BUILD_ASSERT(sizeof(CONFIG_MASS_STORAGE_INQ_REVISION) == (INQ_REVISION_LEN + 1),
268 	"CONFIG_MASS_STORAGE_INQ_REVISION must be 4 characters (pad with spaces)");
269 
msd_state_machine_reset(void)270 static void msd_state_machine_reset(void)
271 {
272 	stage = MSC_READ_CBW;
273 }
274 
msd_init(void)275 static void msd_init(void)
276 {
277 	(void)memset((void *)&cbw, 0, sizeof(struct CBW));
278 	(void)memset((void *)&csw, 0, sizeof(struct CSW));
279 	(void)memset(page, 0, sizeof(page));
280 	curr_lba = 0U;
281 	length = 0U;
282 	curr_offset = 0U;
283 }
284 
sendCSW(void)285 static void sendCSW(void)
286 {
287 	csw.Signature = CSW_Signature;
288 	if (usb_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&csw,
289 		      sizeof(struct CSW), NULL) != 0) {
290 		LOG_ERR("usb write failure");
291 	}
292 	stage = MSC_WAIT_CSW;
293 }
294 
fail(void)295 static void fail(void)
296 {
297 	if (cbw.DataLength) {
298 		/* Stall data stage */
299 		if ((cbw.Flags & 0x80) != 0U) {
300 			usb_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
301 		} else {
302 			usb_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
303 		}
304 	}
305 
306 	csw.Status = CSW_FAILED;
307 	sendCSW();
308 }
309 
write(uint8_t * buf,uint16_t size)310 static bool write(uint8_t *buf, uint16_t size)
311 {
312 	if (size >= cbw.DataLength) {
313 		size = cbw.DataLength;
314 	}
315 
316 	/* updating the State Machine , so that we send CSW when this
317 	 * transfer is complete, ie when we get a bulk in callback
318 	 */
319 	stage = MSC_SEND_CSW;
320 
321 	if (usb_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buf, size, NULL)) {
322 		LOG_ERR("USB write failed");
323 		return false;
324 	}
325 
326 	csw.DataResidue -= size;
327 	csw.Status = CSW_PASSED;
328 	return true;
329 }
330 
331 /**
332  * @brief Handler called for Class requests not handled by the USB stack.
333  *
334  * @param pSetup    Information about the request to execute.
335  * @param len       Size of the buffer.
336  * @param data      Buffer containing the request result.
337  *
338  * @return  0 on success, negative errno code on fail.
339  */
mass_storage_class_handle_req(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)340 static int mass_storage_class_handle_req(struct usb_setup_packet *setup,
341 					 int32_t *len, uint8_t **data)
342 {
343 	if (setup->wIndex != mass_cfg.if0.bInterfaceNumber ||
344 	    setup->wValue != 0) {
345 		LOG_ERR("Invalid setup parameters");
346 		return -EINVAL;
347 	}
348 
349 	if (usb_reqtype_is_to_device(setup)) {
350 		if (setup->bRequest == MSC_REQUEST_RESET &&
351 		    setup->wLength == 0) {
352 			LOG_DBG("MSC_REQUEST_RESET");
353 			msd_state_machine_reset();
354 			return 0;
355 		}
356 	} else {
357 		if (setup->bRequest == MSC_REQUEST_GET_MAX_LUN &&
358 		    setup->wLength == 1) {
359 			LOG_DBG("MSC_REQUEST_GET_MAX_LUN");
360 			max_lun_count = 0U;
361 			*data = (uint8_t *)(&max_lun_count);
362 			*len = 1;
363 			return 0;
364 		}
365 	}
366 
367 	LOG_WRN("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
368 		setup->bmRequestType, setup->bRequest);
369 	return -ENOTSUP;
370 }
371 
testUnitReady(void)372 static void testUnitReady(void)
373 {
374 	if (cbw.DataLength != 0U) {
375 		if ((cbw.Flags & 0x80) != 0U) {
376 			LOG_WRN("Stall IN endpoint");
377 			usb_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
378 		} else {
379 			LOG_WRN("Stall OUT endpoint");
380 			usb_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
381 		}
382 	}
383 
384 	csw.Status = CSW_PASSED;
385 	sendCSW();
386 }
387 
requestSense(void)388 static bool requestSense(void)
389 {
390 	uint8_t request_sense[] = {
391 		0x70,
392 		0x00,
393 		0x05,   /* Sense Key: illegal request */
394 		0x00,
395 		0x00,
396 		0x00,
397 		0x00,
398 		0x0A,
399 		0x00,
400 		0x00,
401 		0x00,
402 		0x00,
403 		0x30,
404 		0x01,
405 		0x00,
406 		0x00,
407 		0x00,
408 		0x00,
409 	};
410 
411 	return write(request_sense, sizeof(request_sense));
412 }
413 
inquiryRequest(void)414 static bool inquiryRequest(void)
415 {
416 	return write((uint8_t *)&inq_rsp, sizeof(inq_rsp));
417 }
418 
modeSense6(void)419 static bool modeSense6(void)
420 {
421 	uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
422 
423 	return write(sense6, sizeof(sense6));
424 }
425 
readFormatCapacity(void)426 static bool readFormatCapacity(void)
427 {
428 	uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
429 			(uint8_t)((block_count >> 24) & 0xff),
430 			(uint8_t)((block_count >> 16) & 0xff),
431 			(uint8_t)((block_count >> 8) & 0xff),
432 			(uint8_t)((block_count >> 0) & 0xff),
433 
434 			0x02,
435 			(uint8_t)((BLOCK_SIZE >> 16) & 0xff),
436 			(uint8_t)((BLOCK_SIZE >> 8) & 0xff),
437 			(uint8_t)((BLOCK_SIZE >> 0) & 0xff),
438 	};
439 
440 	return write(capacity, sizeof(capacity));
441 }
442 
readCapacity(void)443 static bool readCapacity(void)
444 {
445 	uint8_t capacity[8];
446 
447 	sys_put_be32(block_count - 1, &capacity[0]);
448 	sys_put_be32(BLOCK_SIZE, &capacity[4]);
449 
450 	return write(capacity, sizeof(capacity));
451 }
452 
thread_memory_read_done(void)453 static void thread_memory_read_done(void)
454 {
455 	uint32_t n = length;
456 
457 	if (n > MAX_PACKET) {
458 		n = MAX_PACKET;
459 	}
460 	if (n > BLOCK_SIZE - curr_offset) {
461 		n = BLOCK_SIZE - curr_offset;
462 	}
463 
464 	if (usb_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
465 		&page[curr_offset], n, NULL) != 0) {
466 		LOG_ERR("Failed to write EP 0x%x",
467 			mass_ep_data[MSD_IN_EP_IDX].ep_addr);
468 	}
469 	curr_offset += n;
470 	if (curr_offset >= BLOCK_SIZE) {
471 		curr_offset -= BLOCK_SIZE;
472 		curr_lba += 1;
473 	}
474 	length -= n;
475 	csw.DataResidue -= n;
476 
477 	if (!length || (stage != MSC_PROCESS_CBW)) {
478 		csw.Status = (stage == MSC_PROCESS_CBW) ?
479 			CSW_PASSED : CSW_FAILED;
480 		stage = (stage == MSC_PROCESS_CBW) ? MSC_SEND_CSW : stage;
481 	}
482 }
483 
484 
memoryRead(void)485 static void memoryRead(void)
486 {
487 	if (curr_lba >= block_count) {
488 		LOG_WRN("Attempt to read past end of device: lba=%u", curr_lba);
489 		fail();
490 		return;
491 	}
492 
493 	if (!curr_offset) {
494 		/* we need a new block */
495 		thread_op = THREAD_OP_READ_QUEUED;
496 		LOG_DBG("Signal thread for %u", curr_lba);
497 		k_sem_give(&disk_wait_sem);
498 	} else {
499 		thread_memory_read_done();
500 	}
501 }
502 
check_cbw_data_length(void)503 static bool check_cbw_data_length(void)
504 {
505 	if (!cbw.DataLength) {
506 		LOG_WRN("Zero length in CBW");
507 		csw.Status = CSW_FAILED;
508 		sendCSW();
509 		return false;
510 	}
511 
512 	return true;
513 }
514 
infoTransfer(void)515 static bool infoTransfer(void)
516 {
517 	uint32_t n;
518 
519 	if (!check_cbw_data_length()) {
520 		return false;
521 	}
522 
523 	/* Logical Block Address of First Block */
524 	n = sys_get_be32(&cbw.CB[2]);
525 
526 	LOG_DBG("LBA (block) : 0x%x ", n);
527 	if (n >= block_count) {
528 		LOG_ERR("LBA out of range");
529 		fail();
530 		return false;
531 	}
532 
533 	curr_lba = n;
534 	curr_offset = 0U;
535 
536 	/* Number of Blocks to transfer */
537 	switch (cbw.CB[0]) {
538 	case READ10:
539 	case WRITE10:
540 	case VERIFY10:
541 		n = sys_get_be16(&cbw.CB[7]);
542 		break;
543 
544 	case READ12:
545 	case WRITE12:
546 		n = sys_get_be32(&cbw.CB[6]);
547 		break;
548 	}
549 
550 	LOG_DBG("Size (block) : 0x%x ", n);
551 	length = n * BLOCK_SIZE;
552 
553 	if (cbw.DataLength != length) {
554 		LOG_ERR("DataLength mismatch");
555 		fail();
556 		return false;
557 	}
558 
559 	return true;
560 }
561 
CBWDecode(uint8_t * buf,uint16_t size)562 static void CBWDecode(uint8_t *buf, uint16_t size)
563 {
564 	if (size != sizeof(cbw)) {
565 		LOG_ERR("size != sizeof(cbw)");
566 		return;
567 	}
568 
569 	memcpy((uint8_t *)&cbw, buf, size);
570 	if (cbw.Signature != CBW_Signature) {
571 		LOG_ERR("CBW Signature Mismatch");
572 		return;
573 	}
574 
575 	csw.Tag = cbw.Tag;
576 	csw.DataResidue = cbw.DataLength;
577 
578 	if ((cbw.CBLength <  1) || (cbw.CBLength > 16) || (cbw.LUN != 0U)) {
579 		LOG_WRN("cbw.CBLength %d", cbw.CBLength);
580 		fail();
581 	} else {
582 		switch (cbw.CB[0]) {
583 		case TEST_UNIT_READY:
584 			LOG_DBG(">> TUR");
585 			testUnitReady();
586 			break;
587 		case REQUEST_SENSE:
588 			LOG_DBG(">> REQ_SENSE");
589 			if (check_cbw_data_length()) {
590 				requestSense();
591 			}
592 			break;
593 		case INQUIRY:
594 			LOG_DBG(">> INQ");
595 			if (check_cbw_data_length()) {
596 				inquiryRequest();
597 			}
598 			break;
599 		case MODE_SENSE6:
600 			LOG_DBG(">> MODE_SENSE6");
601 			if (check_cbw_data_length()) {
602 				modeSense6();
603 			}
604 			break;
605 		case READ_FORMAT_CAPACITIES:
606 			LOG_DBG(">> READ_FORMAT_CAPACITY");
607 			if (check_cbw_data_length()) {
608 				readFormatCapacity();
609 			}
610 			break;
611 		case READ_CAPACITY:
612 			LOG_DBG(">> READ_CAPACITY");
613 			if (check_cbw_data_length()) {
614 				readCapacity();
615 			}
616 			break;
617 		case READ10:
618 		case READ12:
619 			LOG_DBG(">> READ");
620 			if (infoTransfer()) {
621 				if ((cbw.Flags & 0x80)) {
622 					stage = MSC_PROCESS_CBW;
623 					memoryRead();
624 				} else {
625 					usb_ep_set_stall(
626 					  mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
627 					LOG_WRN("Stall OUT endpoint");
628 					csw.Status = CSW_ERROR;
629 					sendCSW();
630 				}
631 			}
632 			break;
633 		case WRITE10:
634 		case WRITE12:
635 			LOG_DBG(">> WRITE");
636 			if (infoTransfer()) {
637 				if (!(cbw.Flags & 0x80)) {
638 					stage = MSC_PROCESS_CBW;
639 				} else {
640 					usb_ep_set_stall(
641 					  mass_ep_data[MSD_IN_EP_IDX].ep_addr);
642 					LOG_WRN("Stall IN endpoint");
643 					csw.Status = CSW_ERROR;
644 					sendCSW();
645 				}
646 			}
647 			break;
648 		case VERIFY10:
649 			LOG_DBG(">> VERIFY10");
650 			if (!(cbw.CB[1] & 0x02)) {
651 				csw.Status = CSW_PASSED;
652 				sendCSW();
653 				break;
654 			}
655 			if (infoTransfer()) {
656 				if (!(cbw.Flags & 0x80)) {
657 					stage = MSC_PROCESS_CBW;
658 					memOK = true;
659 				} else {
660 					usb_ep_set_stall(
661 					  mass_ep_data[MSD_IN_EP_IDX].ep_addr);
662 					LOG_WRN("Stall IN endpoint");
663 					csw.Status = CSW_ERROR;
664 					sendCSW();
665 				}
666 			}
667 			break;
668 		case MEDIA_REMOVAL:
669 			LOG_DBG(">> MEDIA_REMOVAL");
670 			csw.Status = CSW_PASSED;
671 			sendCSW();
672 			break;
673 		default:
674 			LOG_WRN(">> default CB[0] %x", cbw.CB[0]);
675 			fail();
676 			break;
677 		}		/*switch(cbw.CB[0])*/
678 	}		/* else */
679 
680 }
681 
memoryVerify(uint8_t * buf,uint16_t size)682 static void memoryVerify(uint8_t *buf, uint16_t size)
683 {
684 	uint32_t n;
685 
686 	if (curr_lba >= block_count) {
687 		LOG_WRN("Attempt to read past end of device: lba=%u", curr_lba);
688 		fail();
689 		return;
690 	}
691 
692 	/* BUG: if a packet crosses block boundaries, we will probably fail. */
693 
694 	/* beginning of a new block -> load a whole block in RAM */
695 	if (!curr_offset) {
696 		LOG_DBG("Disk READ sector %u", curr_lba);
697 		if (disk_access_read(disk_pdrv, page, curr_lba, 1)) {
698 			LOG_ERR("---- Disk Read Error %u", curr_lba);
699 		}
700 	}
701 
702 	/* info are in RAM -> no need to re-read memory */
703 	for (n = 0U; n < size; n++) {
704 		if (page[curr_offset + n] != buf[n]) {
705 			LOG_DBG("Mismatch sector %u offset %u",
706 				curr_lba, curr_offset + n);
707 			memOK = false;
708 			break;
709 		}
710 	}
711 
712 	curr_offset += n;
713 	if (curr_offset >= BLOCK_SIZE) {
714 		curr_offset -= BLOCK_SIZE;
715 		curr_lba += 1;
716 	}
717 	length -= size;
718 	csw.DataResidue -= size;
719 
720 	if (!length || (stage != MSC_PROCESS_CBW)) {
721 		csw.Status = (memOK && (stage == MSC_PROCESS_CBW)) ?
722 						CSW_PASSED : CSW_FAILED;
723 		sendCSW();
724 	}
725 }
726 
memoryWrite(uint8_t * buf,uint16_t size)727 static void memoryWrite(uint8_t *buf, uint16_t size)
728 {
729 	if (curr_lba >= block_count) {
730 		LOG_WRN("Attempt to write past end of device: lba=%u", curr_lba);
731 		fail();
732 		return;
733 	}
734 
735 	/* we fill an array in RAM of 1 block before writing it in memory */
736 	for (int i = 0; i < size; i++) {
737 		page[curr_offset + i] = buf[i];
738 	}
739 
740 	/* if the array is filled, write it in memory */
741 	if (curr_offset + size >= BLOCK_SIZE) {
742 		if (!(disk_access_status(disk_pdrv) &
743 					DISK_STATUS_WR_PROTECT)) {
744 			LOG_DBG("Disk WRITE Qd %u", curr_lba);
745 			thread_op = THREAD_OP_WRITE_QUEUED;  /* write_queued */
746 			defered_wr_sz = size;
747 			k_sem_give(&disk_wait_sem);
748 			return;
749 		}
750 	}
751 
752 	curr_offset += size;
753 	length -= size;
754 	csw.DataResidue -= size;
755 
756 	if ((!length) || (stage != MSC_PROCESS_CBW)) {
757 		csw.Status = (stage == MSC_ERROR) ? CSW_FAILED : CSW_PASSED;
758 		sendCSW();
759 	}
760 }
761 
762 
mass_storage_bulk_out(uint8_t ep,enum usb_dc_ep_cb_status_code ep_status)763 static void mass_storage_bulk_out(uint8_t ep,
764 		enum usb_dc_ep_cb_status_code ep_status)
765 {
766 	uint32_t bytes_read = 0U;
767 	uint8_t bo_buf[CONFIG_MASS_STORAGE_BULK_EP_MPS];
768 
769 	ARG_UNUSED(ep_status);
770 
771 	usb_ep_read_wait(ep, bo_buf, CONFIG_MASS_STORAGE_BULK_EP_MPS,
772 			 &bytes_read);
773 
774 	switch (stage) {
775 	/*the device has to decode the CBW received*/
776 	case MSC_READ_CBW:
777 		LOG_DBG("> BO - MSC_READ_CBW");
778 		CBWDecode(bo_buf, bytes_read);
779 		break;
780 
781 	/*the device has to receive data from the host*/
782 	case MSC_PROCESS_CBW:
783 		switch (cbw.CB[0]) {
784 		case WRITE10:
785 		case WRITE12:
786 			/* LOG_DBG("> BO - PROC_CBW WR");*/
787 			memoryWrite(bo_buf, bytes_read);
788 			break;
789 		case VERIFY10:
790 			LOG_DBG("> BO - PROC_CBW VER");
791 			memoryVerify(bo_buf, bytes_read);
792 			break;
793 		default:
794 			LOG_ERR("> BO - PROC_CBW default <<ERROR!!!>>");
795 			break;
796 		}
797 		break;
798 
799 	/*an error has occurred: stall endpoint and send CSW*/
800 	default:
801 		LOG_WRN("Stall OUT endpoint, stage: %d", stage);
802 		usb_ep_set_stall(ep);
803 		csw.Status = CSW_ERROR;
804 		sendCSW();
805 		break;
806 	}
807 
808 	if (thread_op != THREAD_OP_WRITE_QUEUED) {
809 		usb_ep_read_continue(ep);
810 	} else {
811 		LOG_DBG("> BO not clearing NAKs yet");
812 	}
813 
814 }
815 
thread_memory_write_done(void)816 static void thread_memory_write_done(void)
817 {
818 	uint32_t size = defered_wr_sz;
819 	size_t overflowed_len = (curr_offset + size) - BLOCK_SIZE;
820 
821 	if (BLOCK_SIZE > (curr_offset + size)) {
822 		overflowed_len = 0;
823 	}
824 
825 	if (overflowed_len > 0) {
826 		memmove(page, &page[BLOCK_SIZE], overflowed_len);
827 	}
828 
829 	curr_offset = overflowed_len;
830 	curr_lba += 1;
831 	length -= size;
832 	csw.DataResidue -= size;
833 
834 	if (!length) {
835 		if (disk_access_ioctl(disk_pdrv, DISK_IOCTL_CTRL_SYNC, NULL)) {
836 			LOG_ERR("!! Disk cache sync error !!");
837 		}
838 	}
839 
840 	if ((!length) || (stage != MSC_PROCESS_CBW)) {
841 		csw.Status = (stage == MSC_ERROR) ? CSW_FAILED : CSW_PASSED;
842 		sendCSW();
843 	}
844 
845 	thread_op = THREAD_OP_WRITE_DONE;
846 
847 	usb_ep_read_continue(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
848 }
849 
850 /**
851  * @brief EP Bulk IN handler, used to send data to the Host
852  *
853  * @param ep        Endpoint address.
854  * @param ep_status Endpoint status code.
855  *
856  * @return  N/A.
857  */
mass_storage_bulk_in(uint8_t ep,enum usb_dc_ep_cb_status_code ep_status)858 static void mass_storage_bulk_in(uint8_t ep,
859 				 enum usb_dc_ep_cb_status_code ep_status)
860 {
861 	ARG_UNUSED(ep_status);
862 	ARG_UNUSED(ep);
863 
864 	switch (stage) {
865 	/*the device has to send data to the host*/
866 	case MSC_PROCESS_CBW:
867 		switch (cbw.CB[0]) {
868 		case READ10:
869 		case READ12:
870 			/* LOG_DBG("< BI - PROC_CBW  READ"); */
871 			memoryRead();
872 			break;
873 		default:
874 			LOG_ERR("< BI-PROC_CBW default <<ERROR!!>>");
875 			break;
876 		}
877 		break;
878 
879 	/*the device has to send a CSW*/
880 	case MSC_SEND_CSW:
881 		LOG_DBG("< BI - MSC_SEND_CSW");
882 		sendCSW();
883 		break;
884 
885 	/*the host has received the CSW -> we wait a CBW*/
886 	case MSC_WAIT_CSW:
887 		LOG_DBG("< BI - MSC_WAIT_CSW");
888 		stage = MSC_READ_CBW;
889 		break;
890 
891 	/*an error has occurred*/
892 	default:
893 		LOG_WRN("Stall IN endpoint, stage: %d", stage);
894 		usb_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
895 		sendCSW();
896 		break;
897 	}
898 }
899 
900 
901 
902 /**
903  * @brief Callback used to know the USB connection status
904  *
905  * @param status USB device status code.
906  *
907  * @return  N/A.
908  */
mass_storage_status_cb(struct usb_cfg_data * cfg,enum usb_dc_status_code status,const uint8_t * param)909 static void mass_storage_status_cb(struct usb_cfg_data *cfg,
910 				   enum usb_dc_status_code status,
911 				   const uint8_t *param)
912 {
913 	ARG_UNUSED(param);
914 	ARG_UNUSED(cfg);
915 
916 	/* Check the USB status and do needed action if required */
917 	switch (status) {
918 	case USB_DC_ERROR:
919 		LOG_DBG("USB device error");
920 		break;
921 	case USB_DC_RESET:
922 		LOG_DBG("USB device reset detected");
923 		msd_state_machine_reset();
924 		msd_init();
925 		break;
926 	case USB_DC_CONNECTED:
927 		LOG_DBG("USB device connected");
928 		break;
929 	case USB_DC_CONFIGURED:
930 		LOG_DBG("USB device configured");
931 		break;
932 	case USB_DC_DISCONNECTED:
933 		LOG_DBG("USB device disconnected");
934 		break;
935 	case USB_DC_SUSPEND:
936 		LOG_DBG("USB device suspended");
937 		break;
938 	case USB_DC_RESUME:
939 		LOG_DBG("USB device resumed");
940 		break;
941 	case USB_DC_INTERFACE:
942 		LOG_DBG("USB interface selected");
943 		break;
944 	case USB_DC_SOF:
945 		break;
946 	case USB_DC_UNKNOWN:
947 	default:
948 		LOG_DBG("USB unknown state");
949 		break;
950 	}
951 }
952 
mass_interface_config(struct usb_desc_header * head,uint8_t bInterfaceNumber)953 static void mass_interface_config(struct usb_desc_header *head,
954 				  uint8_t bInterfaceNumber)
955 {
956 	ARG_UNUSED(head);
957 
958 	mass_cfg.if0.bInterfaceNumber = bInterfaceNumber;
959 }
960 
961 /* Configuration of the Mass Storage Device send to the USB Driver */
962 USBD_DEFINE_CFG_DATA(mass_storage_config) = {
963 	.usb_device_description = NULL,
964 	.interface_config = mass_interface_config,
965 	.interface_descriptor = &mass_cfg.if0,
966 	.cb_usb_status = mass_storage_status_cb,
967 	.interface = {
968 		.class_handler = mass_storage_class_handle_req,
969 		.custom_handler = NULL,
970 	},
971 	.num_endpoints = ARRAY_SIZE(mass_ep_data),
972 	.endpoint = mass_ep_data
973 };
974 
mass_thread_main(void * p1,void * p2,void * p3)975 static void mass_thread_main(void *p1, void *p2, void *p3)
976 {
977 	ARG_UNUSED(p1);
978 	ARG_UNUSED(p2);
979 	ARG_UNUSED(p3);
980 
981 	while (1) {
982 		k_sem_take(&disk_wait_sem, K_FOREVER);
983 		LOG_DBG("sem %d", thread_op);
984 
985 		switch (thread_op) {
986 		case THREAD_OP_READ_QUEUED:
987 			if (disk_access_read(disk_pdrv,
988 						page, curr_lba, 1)) {
989 				LOG_ERR("!! Disk Read Error %u !",
990 					curr_lba);
991 			}
992 
993 			thread_memory_read_done();
994 			break;
995 		case THREAD_OP_WRITE_QUEUED:
996 			if (disk_access_write(disk_pdrv,
997 						page, curr_lba, 1)) {
998 				LOG_ERR("!!!!! Disk Write Error %u !!!!!",
999 					curr_lba);
1000 			}
1001 			thread_memory_write_done();
1002 			break;
1003 		default:
1004 			LOG_ERR("XXXXXX thread_op  %d ! XXXXX", thread_op);
1005 		}
1006 	}
1007 }
1008 
1009 /**
1010  * @brief Initialize USB mass storage setup
1011  *
1012  * This routine is called to reset the USB device controller chip to a
1013  * quiescent state. Also it initializes the backing storage and initializes
1014  * the mass storage protocol state.
1015  *
1016  * @param dev device struct.
1017  *
1018  * @return negative errno code on fatal failure, 0 otherwise
1019  */
mass_storage_init(void)1020 static int mass_storage_init(void)
1021 {
1022 	uint32_t block_size = 0U;
1023 
1024 
1025 	if (disk_access_init(disk_pdrv) != 0) {
1026 		LOG_ERR("Storage init ERROR !!!! - Aborting USB init");
1027 		return 0;
1028 	}
1029 
1030 	if (disk_access_ioctl(disk_pdrv,
1031 				DISK_IOCTL_GET_SECTOR_COUNT, &block_count)) {
1032 		LOG_ERR("Unable to get sector count - Aborting USB init");
1033 		return 0;
1034 	}
1035 
1036 	if (disk_access_ioctl(disk_pdrv,
1037 				DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) {
1038 		LOG_ERR("Unable to get sector size - Aborting USB init");
1039 		return 0;
1040 	}
1041 
1042 	if (block_size != BLOCK_SIZE) {
1043 		LOG_ERR("Block Size reported by the storage side is "
1044 			"different from Mass Storage Class page Buffer - "
1045 			"Aborting");
1046 		return 0;
1047 	}
1048 
1049 
1050 	LOG_INF("Sect Count %u", block_count);
1051 	LOG_INF("Memory Size %llu", (uint64_t) block_count * BLOCK_SIZE);
1052 
1053 	msd_state_machine_reset();
1054 	msd_init();
1055 
1056 	k_sem_init(&disk_wait_sem, 0, 1);
1057 
1058 	/* Start a thread to offload disk ops */
1059 	k_thread_create(&mass_thread_data, mass_thread_stack,
1060 			CONFIG_MASS_STORAGE_STACK_SIZE,
1061 			mass_thread_main, NULL, NULL, NULL,
1062 			DISK_THREAD_PRIO, 0, K_NO_WAIT);
1063 
1064 	k_thread_name_set(&mass_thread_data, "usb_mass");
1065 
1066 	return 0;
1067 }
1068 
1069 SYS_INIT(mass_storage_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
1070