1 /*
2  * Minix3 USB mass storage driver implementation
3  * using DDEkit, and libblockdriver
4  */
5 
6 #include <sys/cdefs.h>			/* __CTASSERT() */
7 #include <sys/ioc_disk.h>		/* cases for mass_storage_ioctl */
8 #ifdef USB_STORAGE_SIGNAL
9 #include <sys/signal.h>			/* signal handling */
10 #endif
11 
12 #include <ddekit/minix/msg_queue.h>
13 #include <ddekit/thread.h>
14 #include <ddekit/usb.h>
15 
16 #include <minix/blockdriver.h>
17 #include <minix/com.h>			/* for msg_queue ranges */
18 #include <minix/drvlib.h>		/* DEV_PER_DRIVE, partition */
19 #include <minix/ipc.h>			/* message */
20 #include <minix/safecopies.h>		/* GRANT_VALID */
21 #include <minix/sef.h>
22 #include <minix/sysutil.h>		/* panic */
23 #include <minix/usb.h>			/* structures like usb_ctrlrequest */
24 #include <minix/usb_ch9.h>		/* descriptor structures */
25 
26 #include <assert.h>
27 #include <limits.h>			/* ULONG_MAX */
28 #include <time.h>			/* nanosleep */
29 
30 #include "common.h"
31 #include "bulk.h"
32 #include "usb_storage.h"
33 #include "urb_helper.h"
34 #include "scsi.h"
35 
36 
37 /*---------------------------*
38  *    declared functions     *
39  *---------------------------*/
40 /* TODO: these are missing from DDE header files */
41 extern void ddekit_minix_wait_exit(void);
42 extern void ddekit_shutdown(void);
43 
44 /* SCSI URB related prototypes */
45 static int mass_storage_send_scsi_cbw_out(int, scsi_transfer *);
46 static int mass_storage_send_scsi_data_in(void *, unsigned int);
47 static int mass_storage_send_scsi_data_out(void *, unsigned int);
48 static int mass_storage_send_scsi_csw_in(void);
49 
50 #ifdef MASS_RESET_RECOVERY
51 /* Bulk only URB related prototypes */
52 static int mass_storage_reset_recovery(void);
53 static int mass_storage_send_bulk_reset(void);
54 static int mass_storage_send_clear_feature(int, int);
55 #endif
56 
57 /* SEF related functions */
58 static int mass_storage_sef_hdlr(int, sef_init_info_t *);
59 static void mass_storage_signal_handler(int);
60 
61 /* DDEKit IPC related */
62 static void ddekit_usb_task(void *);
63 
64 /* Mass storage related prototypes */
65 static void mass_storage_task(void *);
66 static int mass_storage_test(void);
67 static int mass_storage_check_error(void);
68 static int mass_storage_try_first_open(void);
69 static int mass_storage_transfer_restrictions(u64_t, unsigned long);
70 static ssize_t mass_storage_write(unsigned long, endpoint_t, iovec_t *,
71 				unsigned int, unsigned long);
72 static ssize_t mass_storage_read(unsigned long, endpoint_t, iovec_t *,
73 				unsigned int, unsigned long);
74 
75 /* Minix's libblockdriver callbacks */
76 static int mass_storage_open(devminor_t, int);
77 static int mass_storage_close(devminor_t);
78 static ssize_t mass_storage_transfer(devminor_t, int, u64_t, endpoint_t,
79 					iovec_t *, unsigned int, int);
80 static int mass_storage_ioctl(devminor_t, unsigned long, endpoint_t,
81 				cp_grant_id_t, endpoint_t);
82 static void mass_storage_cleanup(void);
83 static struct device * mass_storage_part(devminor_t);
84 static void mass_storage_geometry(devminor_t, struct part_geom *);
85 
86 /* DDEKit's USB driver callbacks */
87 static void usb_driver_completion(void *);
88 static void usb_driver_connect(struct ddekit_usb_dev *, unsigned int);
89 static void usb_driver_disconnect(struct ddekit_usb_dev *);
90 
91 /* Simplified enumeration method for endpoint resolution */
92 static int mass_storage_get_endpoints(urb_ep_config *, urb_ep_config *);
93 static int mass_storage_parse_endpoint(usb_descriptor_t *, urb_ep_config *,
94 					urb_ep_config *);
95 static int mass_storage_parse_descriptors(char *, unsigned int, urb_ep_config *,
96 					urb_ep_config *);
97 
98 
99 /*---------------------------*
100  *    defined variables      *
101  *---------------------------*/
102 #define MASS_PACKED __attribute__((__packed__))
103 
104 /* Mass Storage callback structure */
105 static struct blockdriver mass_storage = {
106 	.bdr_type	= BLOCKDRIVER_TYPE_DISK,
107 	.bdr_open	= mass_storage_open,
108 	.bdr_close	= mass_storage_close,
109 	.bdr_transfer	= mass_storage_transfer,
110 	.bdr_ioctl	= mass_storage_ioctl,
111 	.bdr_cleanup	= mass_storage_cleanup,
112 	.bdr_part	= mass_storage_part,
113 	.bdr_geometry	= mass_storage_geometry,
114 	.bdr_intr	= NULL,
115 	.bdr_alarm	= NULL,
116 	.bdr_other	= NULL,
117 	.bdr_device	= NULL
118 };
119 
120 /* USB callback structure */
121 static struct ddekit_usb_driver mass_storage_driver = {
122 	.completion	= usb_driver_completion,
123 	.connect	= usb_driver_connect,
124 	.disconnect	= usb_driver_disconnect
125 };
126 
127 /* Instance of global driver information */
128 mass_storage_state driver_state;
129 
130 /* Tags used to pair CBW and CSW for bulk communication
131  * With this we can check if SCSI reply was meant for SCSI request */
132 static unsigned int current_cbw_tag = 0;	/* What shall be send next */
133 static unsigned int last_cbw_tag = 0;		/* What was sent recently */
134 
135 /* Semaphore used to block mass storage thread to
136  * allow DDE dispatcher operation */
137 static ddekit_sem_t * mass_storage_sem = NULL;
138 
139 /* Mass storage (using libblockdriver) thread */
140 ddekit_thread_t * mass_storage_thread = NULL;
141 
142 /* DDEKit USB message handling thread */
143 ddekit_thread_t * ddekit_usb_thread = NULL;
144 
145 /* Static URB buffer size (must be multiple of SECTOR_SIZE) */
146 #define BUFFER_SIZE (64*SECTOR_SIZE)
147 
148 /* Large buffer for URB read/write operations */
149 static unsigned char buffer[BUFFER_SIZE];
150 
151 /* Length of local buffer where descriptors are temporarily stored */
152 #define MAX_DESCRIPTORS_LEN 128
153 
154 /* Maximum 'Test Unit Ready' command retries */
155 #define MAX_TEST_RETRIES 3
156 
157 /* 'Test Unit Ready' failure delay time (in nanoseconds) */
158 #define NEXT_TEST_DELAY 50000000 /* 50ms */
159 
160 
161 /*---------------------------*
162  *    defined functions      *
163  *---------------------------*/
164 /*===========================================================================*
165  *    main                                                                   *
166  *===========================================================================*/
167 int
168 main(int argc, char * argv[])
169 {
170 	MASS_DEBUG_MSG("Starting...");
171 
172 	/* Store arguments for future parsing */
173 	env_setargs(argc, argv);
174 
175 	/* Clear current state */
176 	memset(&driver_state, 0, sizeof(driver_state));
177 
178 	/* Initialize SEF related callbacks */
179 	sef_setcb_init_fresh(mass_storage_sef_hdlr);
180 	sef_setcb_init_lu(mass_storage_sef_hdlr);
181 	sef_setcb_init_restart(mass_storage_sef_hdlr);
182 	sef_setcb_signal_handler(mass_storage_signal_handler);
183 
184 	/* Initialize DDEkit (involves sef_startup()) */
185 	ddekit_init();
186 	MASS_DEBUG_MSG("DDEkit ready...");
187 
188 	/* Semaphore initialization */
189 	mass_storage_sem = ddekit_sem_init(0);
190 	if (NULL == mass_storage_sem)
191 		panic("Initializing mass_storage_sem failed!");
192 
193 	/* Starting mass storage thread */
194 	mass_storage_thread = ddekit_thread_create(mass_storage_task, NULL,
195 						"mass_storage_task");
196 	if (NULL == mass_storage_thread)
197 		panic("Initializing mass_storage_thread failed!");
198 
199 	MASS_DEBUG_MSG("Storage task (libblockdriver) ready...");
200 
201 	/* Run USB IPC task to collect messages */
202 	ddekit_usb_thread = ddekit_thread_create(ddekit_usb_task, NULL,
203 						"ddekit_task" );
204 	if (NULL == ddekit_usb_thread)
205 		panic("Initializing ddekit_usb_thread failed!");
206 
207 	MASS_DEBUG_MSG("USB IPC task ready...");
208 
209 	/* Block and wait until exit signal is received */
210 	ddekit_minix_wait_exit();
211 	MASS_DEBUG_MSG("Exiting...");
212 
213 	/* Release objects that were explicitly allocated above */
214 	ddekit_thread_terminate(ddekit_usb_thread);
215 	ddekit_thread_terminate(mass_storage_thread);
216 	ddekit_sem_deinit(mass_storage_sem);
217 
218 	/* TODO: no ddekit_deinit for proper cleanup? */
219 
220 	MASS_DEBUG_MSG("Cleanup completed...");
221 
222 	return EXIT_SUCCESS;
223 }
224 
225 
226 /*===========================================================================*
227  *    mass_storage_send_scsi_cbw_out                                         *
228  *===========================================================================*/
229 static int
230 mass_storage_send_scsi_cbw_out(int scsi_cmd, scsi_transfer * info)
231 {
232 	/* URB to be send */
233 	struct ddekit_usb_urb urb;
234 
235 	/* CBW data buffer */
236 	mass_storage_cbw cbw;
237 
238 	MASS_DEBUG_DUMP;
239 
240 	/* Reset URB and assign given values */
241 	init_urb(&urb, driver_state.cur_periph->dev,
242 		&(driver_state.cur_periph->ep_out));
243 
244 	/* Reset CBW and assign default values */
245 	init_cbw(&cbw, last_cbw_tag = current_cbw_tag++);
246 
247 	/* Fill CBW with SCSI command */
248 	if (create_scsi_cmd(&cbw, scsi_cmd, info))
249 		return EXIT_FAILURE;
250 
251 	/* Attach CBW to URB */
252 	attach_urb_data(&urb, URB_BUF_TYPE_DATA, &cbw, sizeof(cbw));
253 
254 	/* Send and wait for response */
255 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
256 		return EXIT_FAILURE;
257 
258 	return EXIT_SUCCESS;
259 }
260 
261 
262 /*===========================================================================*
263  *    mass_storage_send_scsi_data_in                                         *
264  *===========================================================================*/
265 static int
266 mass_storage_send_scsi_data_in(void * buf, unsigned int in_len)
267 {
268 	/* URB to be send */
269 	struct ddekit_usb_urb urb;
270 
271 	MASS_DEBUG_DUMP;
272 
273 	/* Reset URB and assign given values */
274 	init_urb(&urb, driver_state.cur_periph->dev,
275 		&(driver_state.cur_periph->ep_in));
276 
277 	/* Attach buffer to URB */
278 	attach_urb_data(&urb, URB_BUF_TYPE_DATA, buf, in_len);
279 
280 	/* Send and wait for response */
281 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
282 		return EXIT_FAILURE;
283 
284 	return EXIT_SUCCESS;
285 }
286 
287 
288 /*===========================================================================*
289  *    mass_storage_send_scsi_data_out                                        *
290  *===========================================================================*/
291 static int
292 mass_storage_send_scsi_data_out(void * buf, unsigned int out_len)
293 {
294 	/* URB to be send */
295 	struct ddekit_usb_urb urb;
296 
297 	MASS_DEBUG_DUMP;
298 
299 	/* Reset URB and assign given values */
300 	init_urb(&urb, driver_state.cur_periph->dev,
301 		&(driver_state.cur_periph->ep_out));
302 
303 	/* Attach buffer to URB */
304 	attach_urb_data(&urb, URB_BUF_TYPE_DATA, buf, out_len);
305 
306 	/* Send and wait for response */
307 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
308 		return EXIT_FAILURE;
309 
310 	return EXIT_SUCCESS;
311 }
312 
313 
314 /*===========================================================================*
315  *    mass_storage_send_scsi_csw_in                                          *
316  *===========================================================================*/
317 static int
318 mass_storage_send_scsi_csw_in(void)
319 {
320 	/* URB to be send */
321 	struct ddekit_usb_urb urb;
322 
323 	/* CBW data buffer */
324 	mass_storage_csw csw;
325 
326 	MASS_DEBUG_DUMP;
327 
328 	/* Reset URB and assign given values */
329 	init_urb(&urb, driver_state.cur_periph->dev,
330 		&(driver_state.cur_periph->ep_in));
331 
332 	/* Clear CSW for receiving */
333 	init_csw(&csw);
334 
335 	/* Attach CSW to URB */
336 	attach_urb_data(&urb, URB_BUF_TYPE_DATA, &csw, sizeof(csw));
337 
338 	/* Send and wait for response */
339 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
340 		return EXIT_FAILURE;
341 
342 	/* Check for proper reply */
343 	if (check_csw(&csw, last_cbw_tag))
344 		return EXIT_FAILURE;
345 
346 	return EXIT_SUCCESS;
347 }
348 
349 
350 #ifdef MASS_RESET_RECOVERY
351 /*===========================================================================*
352  *    mass_storage_reset_recovery                                            *
353  *===========================================================================*/
354 static int
355 mass_storage_reset_recovery(void)
356 {
357 	MASS_DEBUG_DUMP;
358 
359 	/* Bulk-Only Mass Storage Reset */
360 	if (mass_storage_send_bulk_reset()) {
361 		MASS_MSG("Bulk-only mass storage reset failed");
362 		return EIO;
363 	}
364 
365 	/* Clear Feature HALT to the Bulk-In endpoint */
366 	if (URB_INVALID_EP != driver_state.cur_periph->ep_in.ep_num)
367 		if (mass_storage_send_clear_feature(
368 					driver_state.cur_periph->ep_in.ep_num,
369 					DDEKIT_USB_IN)) {
370 			MASS_MSG("Resetting IN EP failed");
371 			return EIO;
372 		}
373 
374 	/* Clear Feature HALT to the Bulk-Out endpoint */
375 	if (URB_INVALID_EP != driver_state.cur_periph->ep_out.ep_num)
376 		if (mass_storage_send_clear_feature(
377 					driver_state.cur_periph->ep_out.ep_num,
378 					DDEKIT_USB_OUT)) {
379 			MASS_MSG("Resetting OUT EP failed");
380 			return EIO;
381 		}
382 
383 	return EXIT_SUCCESS;
384 }
385 
386 
387 /*===========================================================================*
388  *    mass_storage_send_bulk_reset                                           *
389  *===========================================================================*/
390 static int
391 mass_storage_send_bulk_reset(void)
392 {
393 	/* URB to be send */
394 	struct ddekit_usb_urb urb;
395 
396 	/* Setup buffer to be send */
397 	struct usb_ctrlrequest bulk_setup;
398 
399 	/* Control EP configuration */
400 	urb_ep_config ep_conf;
401 
402 	MASS_DEBUG_DUMP;
403 
404 	/* Initialize EP configuration */
405 	ep_conf.ep_num = 0;
406 	ep_conf.direction = DDEKIT_USB_OUT;
407 	ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
408 	ep_conf.max_packet_size = 0;
409 	ep_conf.interval = 0;
410 
411 	/* Reset URB and assign given values */
412 	init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);
413 
414 	/* Clear setup data */
415 	memset(&bulk_setup, 0, sizeof(bulk_setup));
416 
417 	/* For explanation of these values see usbmassbulk_10.pdf */
418 	/* 3.1 Bulk-Only Mass Storage Reset */
419 	bulk_setup.bRequestType = 0x21; /* Class, Interface, host to device */
420 	bulk_setup.bRequest = 0xff;
421 	bulk_setup.wValue = 0x00;
422 	bulk_setup.wIndex = 0x00; /* TODO: hard-coded interface 0 */
423 	bulk_setup.wLength = 0x00;
424 
425 	/* Attach request to URB */
426 	attach_urb_data(&urb, URB_BUF_TYPE_SETUP,
427 			&bulk_setup, sizeof(bulk_setup));
428 
429 	/* Send and wait for response */
430 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
431 		return EXIT_FAILURE;
432 
433 	return EXIT_SUCCESS;
434 }
435 
436 
437 /*===========================================================================*
438  *    mass_storage_send_clear_feature                                        *
439  *===========================================================================*/
440 static int
441 mass_storage_send_clear_feature(int ep_num, int direction)
442 {
443 	/* URB to be send */
444 	struct ddekit_usb_urb urb;
445 
446 	/* Setup buffer to be send */
447 	struct usb_ctrlrequest bulk_setup;
448 
449 	/* Control EP configuration */
450 	urb_ep_config ep_conf;
451 
452 	MASS_DEBUG_DUMP;
453 
454 	assert((ep_num >= 0) && (ep_num < 16));
455 	assert((DDEKIT_USB_OUT == direction) || (DDEKIT_USB_IN == direction));
456 
457 	/* Initialize EP configuration */
458 	ep_conf.ep_num = 0;
459 	ep_conf.direction = DDEKIT_USB_OUT;
460 	ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
461 	ep_conf.max_packet_size = 0;
462 	ep_conf.interval = 0;
463 
464 	/* Reset URB and assign given values */
465 	init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);
466 
467 	/* Clear setup data */
468 	memset(&bulk_setup, 0, sizeof(bulk_setup));
469 
470 	/* For explanation of these values see usbmassbulk_10.pdf */
471 	/* 3.1 Bulk-Only Mass Storage Reset */
472 	bulk_setup.bRequestType = 0x02; /* Standard, Endpoint, host to device */
473 	bulk_setup.bRequest = 0x01; /* CLEAR_FEATURE */
474 	bulk_setup.wValue = 0x00; /* Endpoint */
475 	bulk_setup.wIndex = ep_num; /* Endpoint number... */
476 	if (DDEKIT_USB_IN == direction)
477 		bulk_setup.wIndex |= UE_DIR_IN; /* ...and direction bit */
478 	bulk_setup.wLength = 0x00;
479 
480 	/* Attach request to URB */
481 	attach_urb_data(&urb, URB_BUF_TYPE_SETUP,
482 			&bulk_setup, sizeof(bulk_setup));
483 
484 	/* Send and wait for response */
485 	if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
486 		return EXIT_FAILURE;
487 
488 	return EXIT_SUCCESS;
489 }
490 #endif
491 
492 
493 /*===========================================================================*
494  *    mass_storage_sef_hdlr                                                  *
495  *===========================================================================*/
496 static int
497 mass_storage_sef_hdlr(int type, sef_init_info_t * UNUSED(info))
498 {
499 	int env_res;
500 
501 	MASS_DEBUG_DUMP;
502 
503 	/* Parse given environment */
504 	env_res = env_parse("instance", "d", 0,
505 			&(driver_state.instance),0, 255);
506 
507 	/* Get instance number */
508 	if (EP_UNSET == env_res) {
509 		MASS_DEBUG_MSG("Instance number was not supplied");
510 		driver_state.instance = 0;
511 	} else {
512 		/* Only SET and UNSET are allowed */
513 		if (EP_SET != env_res)
514 			return EXIT_FAILURE;
515 	}
516 
517 	switch (type) {
518 		case SEF_INIT_FRESH:
519 			/* Announce we are up! */
520 			blockdriver_announce(type);
521 			return EXIT_SUCCESS;
522 		case SEF_INIT_LU:
523 		case SEF_INIT_RESTART:
524 			MASS_MSG("Only 'fresh' SEF initialization supported\n");
525 			break;
526 		default:
527 			MASS_MSG("illegal SEF type\n");
528 			break;
529 	}
530 
531 	return EXIT_FAILURE;
532 }
533 
534 
535 /*===========================================================================*
536  *    mass_storage_signal_handler                                            *
537  *===========================================================================*/
538 static void
539 mass_storage_signal_handler(int this_signal)
540 {
541 	MASS_DEBUG_DUMP;
542 
543 #ifdef USB_STORAGE_SIGNAL
544 	/* Only check for termination signal, ignore anything else. */
545 	if (this_signal != SIGTERM)
546 		return;
547 #else
548 	MASS_MSG("Handling signal 0x%X", this_signal);
549 #endif
550 
551 	/* Try graceful DDEKit exit */
552 	ddekit_shutdown();
553 
554 	/* Unreachable, when ddekit_shutdown works correctly */
555 	panic("Calling ddekit_shutdown failed!");
556 }
557 
558 
559 /*===========================================================================*
560  *    ddekit_usb_task                                                        *
561  *===========================================================================*/
562 static void
563 ddekit_usb_task(void * UNUSED(arg))
564 {
565 	MASS_DEBUG_DUMP;
566 
567 	/* TODO: This call was meant to return 'int' but loops forever instead,
568 	 * so no return value is checked */
569 	ddekit_usb_init(&mass_storage_driver, NULL, NULL);
570 }
571 
572 
573 /*===========================================================================*
574  *    mass_storage_task                                                      *
575  *===========================================================================*/
576 static void
577 mass_storage_task(void * UNUSED(unused))
578 {
579 	message m;
580 	int ipc_status;
581 	struct ddekit_minix_msg_q * mq;
582 
583 	MASS_DEBUG_DUMP;
584 
585 	mq = ddekit_minix_create_msg_q(BDEV_RQ_BASE, BDEV_RQ_BASE + 0xff);
586 
587 	for (;;) {
588 		ddekit_minix_rcv(mq, &m, &ipc_status);
589 		blockdriver_process(&mass_storage, &m, ipc_status);
590 	}
591 }
592 
593 
594 /*===========================================================================*
595  *    mass_storage_test                                                      *
596  *===========================================================================*/
597 static int
598 mass_storage_test(void)
599 {
600 	int repeat;
601 	int error;
602 
603 	struct timespec test_wait;
604 
605 	MASS_DEBUG_DUMP;
606 
607 	/* Delay between consecutive test commands, in case of their failure */
608 	test_wait.tv_nsec = NEXT_TEST_DELAY;
609 	test_wait.tv_sec = 0;
610 
611 	for (repeat = 0; repeat < MAX_TEST_RETRIES; repeat++) {
612 
613 		/* SCSI TEST UNIT READY OUT stage */
614 		if (mass_storage_send_scsi_cbw_out(SCSI_TEST_UNIT_READY, NULL))
615 			return EIO;
616 
617 		/* TODO: Only CSW failure should normally contribute to retry */
618 
619 		/* SCSI TEST UNIT READY IN stage */
620 		if (EXIT_SUCCESS == mass_storage_send_scsi_csw_in())
621 			return EXIT_SUCCESS;
622 
623 		/* Check for errors */
624 		if (EXIT_SUCCESS != (error = mass_storage_check_error())) {
625 			MASS_MSG("SCSI sense error checking failed");
626 			return error;
627 		}
628 
629 		/* Ignore potential signal interruption (no return value check),
630 		 * since it causes driver termination anyway */
631 		if (nanosleep(&test_wait, NULL))
632 			MASS_MSG("Calling nanosleep() failed");
633 	}
634 
635 	return EIO;
636 }
637 
638 
639 /*===========================================================================*
640  *    mass_storage_check_error                                               *
641  *===========================================================================*/
642 static int
643 mass_storage_check_error(void)
644 {
645 	/* SCSI sense structure for local use */
646 	typedef struct MASS_PACKED scsi_sense {
647 
648 		uint8_t code : 7;
649 		uint8_t valid : 1;
650 		uint8_t obsolete : 8;
651 		uint8_t sense : 4;
652 		uint8_t reserved : 1;
653 		uint8_t ili : 1;
654 		uint8_t eom : 1;
655 		uint8_t filemark : 1;
656 		uint32_t information : 32;
657 		uint8_t additional_len : 8;
658 		uint32_t command_specific : 32;
659 		uint8_t additional_code : 8;
660 		uint8_t additional_qual : 8;
661 		uint8_t unit_code : 8;
662 		uint8_t key_specific1 : 7;
663 		uint8_t sksv : 1;
664 		uint16_t key_specific2 : 16;
665 	}
666 	scsi_sense;
667 
668 	/* Sense variable to hold received data */
669 	scsi_sense sense;
670 
671 	MASS_DEBUG_DUMP;
672 
673 	/* Check if bit-fields are packed correctly */
674 	__CTASSERT(sizeof(sense) == SCSI_REQUEST_SENSE_DATA_LEN);
675 
676 	/* SCSI REQUEST SENSE OUT stage */
677 	if (mass_storage_send_scsi_cbw_out(SCSI_REQUEST_SENSE, NULL))
678 		return EIO;
679 
680 	/* SCSI REQUEST SENSE first IN stage */
681 	if (mass_storage_send_scsi_data_in(&sense, sizeof(sense)))
682 		return EIO;
683 
684 	/* SCSI REQUEST SENSE second IN stage */
685 	if (mass_storage_send_scsi_csw_in())
686 		return EIO;
687 
688 	/* When any sense code is present something may have failed */
689 	if (sense.sense) {
690 #ifdef MASS_DEBUG
691 		MASS_MSG("SCSI sense:                ");
692 		MASS_MSG("code             : %8X", sense.code            );
693 		MASS_MSG("valid            : %8X", sense.valid           );
694 		MASS_MSG("obsolete         : %8X", sense.obsolete        );
695 		MASS_MSG("sense            : %8X", sense.sense           );
696 		MASS_MSG("reserved         : %8X", sense.reserved        );
697 		MASS_MSG("ili              : %8X", sense.ili             );
698 		MASS_MSG("eom              : %8X", sense.eom             );
699 		MASS_MSG("filemark         : %8X", sense.filemark        );
700 		MASS_MSG("information      : %8X", sense.information     );
701 		MASS_MSG("additional_len   : %8X", sense.additional_len  );
702 		MASS_MSG("command_specific : %8X", sense.command_specific);
703 		MASS_MSG("additional_code  : %8X", sense.additional_code );
704 		MASS_MSG("additional_qual  : %8X", sense.additional_qual );
705 		MASS_MSG("unit_code        : %8X", sense.unit_code       );
706 		MASS_MSG("key_specific1    : %8X", sense.key_specific1   );
707 		MASS_MSG("sksv             : %8X", sense.sksv            );
708 		MASS_MSG("key_specific2    : %8X", sense.key_specific2   );
709 #else
710 		MASS_MSG("SCSI sense: 0x%02X 0x%02X 0x%02X", sense.sense,
711 			sense.additional_code, sense.additional_qual);
712 #endif
713 	}
714 
715 	return EXIT_SUCCESS;
716 }
717 
718 
719 /*===========================================================================*
720  *    mass_storage_try_first_open                                            *
721  *===========================================================================*/
722 static int
723 mass_storage_try_first_open()
724 {
725 	unsigned int llba;
726 	unsigned int blen;
727 	unsigned char inquiry[SCSI_INQUIRY_DATA_LEN];
728 	unsigned char capacity[SCSI_READ_CAPACITY_DATA_LEN];
729 
730 	MASS_DEBUG_DUMP;
731 
732 	assert(NULL != driver_state.cur_drive);
733 
734 	llba = 0; /* Last logical block address */
735 	blen = 0; /* Block length (usually 512B) */
736 
737 	/* Run TEST UNIT READY before other SCSI command
738 	 * Some devices refuse to work without this */
739 	if (mass_storage_test())
740 		return EIO;
741 
742 	/* SCSI INQUIRY OUT stage */
743 	if (mass_storage_send_scsi_cbw_out(SCSI_INQUIRY, NULL))
744 		return EIO;
745 
746 	/* SCSI INQUIRY first IN stage */
747 	if (mass_storage_send_scsi_data_in(inquiry, sizeof(inquiry)))
748 		return EIO;
749 
750 	/* SCSI INQUIRY second IN stage */
751 	if (mass_storage_send_scsi_csw_in())
752 		return EIO;
753 
754 	/* Check for proper reply */
755 	if (check_inquiry_reply(inquiry))
756 		return EIO;
757 
758 	/* Run TEST UNIT READY before other SCSI command
759 	 * Some devices refuse to work without this */
760 	if (mass_storage_test())
761 		return EIO;
762 
763 	/* SCSI READ CAPACITY OUT stage */
764 	if (mass_storage_send_scsi_cbw_out(SCSI_READ_CAPACITY, NULL))
765 		return EIO;
766 
767 	/* SCSI READ CAPACITY first IN stage */
768 	if (mass_storage_send_scsi_data_in(capacity, sizeof(capacity)))
769 		return EIO;
770 
771 	/* SCSI READ CAPACITY second IN stage */
772 	if (mass_storage_send_scsi_csw_in())
773 		return EIO;
774 
775 	/* Check for proper reply */
776 	if (check_read_capacity_reply(capacity, &llba, &blen))
777 		return EIO;
778 
779 	/* For now only Minix's default SECTOR_SIZE is supported */
780 	if (SECTOR_SIZE != blen)
781 		panic("Invalid block size used by USB device!");
782 
783 	/* Get information about capacity from reply */
784 	driver_state.cur_drive->disk.dv_base = 0;
785 	driver_state.cur_drive->disk.dv_size = llba * blen;
786 
787 	return EXIT_SUCCESS;
788 }
789 
790 
791 /*===========================================================================*
792  *    mass_storage_transfer_restrictions                                     *
793  *===========================================================================*/
794 static int
795 mass_storage_transfer_restrictions(u64_t pos, unsigned long bytes)
796 {
797 	MASS_DEBUG_DUMP;
798 
799 	assert(NULL != driver_state.cur_device);
800 
801 	/* Zero-length request must not be issued */
802 	if (0 == bytes) {
803 		MASS_MSG("Transfer request length equals 0");
804 		return EINVAL;
805 	}
806 
807 	/* Starting position must be aligned to sector */
808 	if (0 != (pos % SECTOR_SIZE)) {
809 		MASS_MSG("Transfer position not divisible by %u", SECTOR_SIZE);
810 		return EINVAL;
811 	}
812 
813 	/* Length must be integer multiple of sector sizes */
814 	if (0 != (bytes % SECTOR_SIZE)) {
815 		MASS_MSG("Data length not divisible by %u", SECTOR_SIZE);
816 		return EINVAL;
817 	}
818 
819 	/* Guard against ridiculous 64B overflow */
820 	if ((pos + bytes) <= pos) {
821 		MASS_MSG("Request outside available address space");
822 		return EINVAL;
823 	}
824 
825 	return EXIT_SUCCESS;
826 }
827 
828 
829 /*===========================================================================*
830  *    mass_storage_write                                                     *
831  *===========================================================================*/
832 static ssize_t
833 mass_storage_write(unsigned long sector_number,
834 		endpoint_t endpt,
835 		iovec_t * iov,
836 		unsigned int iov_count,
837 		unsigned long bytes_left)
838 {
839 	/*
840 	 * This function writes whatever was put in 'iov' array
841 	 * (iov[0] : iov[iov_count]), into continuous region of mass storage,
842 	 * starting from sector 'sector_number'. Total amount of 'iov'
843 	 * data should be greater or equal to initial value of 'bytes_left'.
844 	 *
845 	 * Endpoint value 'endpt', determines if vectors 'iov' contain memory
846 	 * addresses for copying or grant IDs.
847 	 */
848 
849 	iov_state cur_iov;		/* Current state of vector copying */
850 	unsigned long bytes_to_write;	/* To be written in this iteration */
851 	ssize_t bytes_already_written;	/* Total amount written (retval) */
852 
853 	MASS_DEBUG_DUMP;
854 
855 	/* Initialize locals */
856 	cur_iov.remaining_bytes = 0;	/* No IO vector initially */
857 	cur_iov.iov_idx = 0;		/* Starting from first vector */
858 	bytes_already_written = 0;	/* Nothing copied yet */
859 
860 	/* Mass storage operations are sector based */
861 	assert(0 == (sizeof(buffer) % SECTOR_SIZE));
862 	assert(0 == (bytes_left % SECTOR_SIZE));
863 
864 	while (bytes_left > 0) {
865 
866 		/* Fill write buffer with data from IO Vectors */
867 		{
868 			unsigned long buf_offset;
869 			unsigned long copy_len;
870 
871 			/* Start copying to the beginning of the buffer */
872 			buf_offset = 0;
873 
874 			/* Copy as long as not copied vectors exist or
875 			 * buffer is not fully filled */
876 			for (;;) {
877 
878 				/* If entire previous vector
879 				 * was used get new one */
880 				if (0 == cur_iov.remaining_bytes) {
881 					/* Check if there are
882 					 * vectors to copied */
883 					if (cur_iov.iov_idx < iov_count) {
884 
885 						cur_iov.base_addr =
886 						  iov[cur_iov.iov_idx].iov_addr;
887 						cur_iov.remaining_bytes =
888 						  iov[cur_iov.iov_idx].iov_size;
889 						cur_iov.offset = 0;
890 						cur_iov.iov_idx++;
891 
892 					} else {
893 						/* All vectors copied */
894 						break;
895 					}
896 				}
897 
898 				/* Copy as much as it is possible from vector
899 				 * and at most the amount that can be
900 				 * put in buffer */
901 				copy_len = MIN(sizeof(buffer) - buf_offset,
902 						cur_iov.remaining_bytes);
903 
904 				/* This distinction is required as transfer can
905 				 * be used from within this process and meaning
906 				 * of IO vector'a address is different than
907 				 * grant ID */
908 				if (endpt == SELF) {
909 					memcpy(&buffer[buf_offset],
910 						(void*)(cur_iov.base_addr +
911 						cur_iov.offset), copy_len);
912 				} else {
913 					ssize_t copy_res;
914 					if ((copy_res = sys_safecopyfrom(endpt,
915 						cur_iov.base_addr,
916 						cur_iov.offset,
917 						(vir_bytes)
918 						(&buffer[buf_offset]),
919 						copy_len))) {
920 						MASS_MSG("sys_safecopyfrom "
921 							"failed");
922 						return copy_res;
923 					}
924 				}
925 
926 				/* Alter current state of copying */
927 				buf_offset += copy_len;
928 				cur_iov.offset += copy_len;
929 				cur_iov.remaining_bytes -= copy_len;
930 
931 				/* Buffer was filled */
932 				if (sizeof(buffer) == buf_offset)
933 					break;
934 			}
935 
936 			/* Determine how many bytes from copied buffer we wish
937 			 * to write, buf_offset represents total amount of
938 			 * bytes copied above */
939 			if (bytes_left >= buf_offset) {
940 				bytes_to_write = buf_offset;
941 				bytes_left -= buf_offset;
942 			} else {
943 				bytes_to_write = bytes_left;
944 				bytes_left = 0;
945 			}
946 		}
947 
948 		/* Send URB and alter sector number */
949 		if (bytes_to_write > 0) {
950 
951 			scsi_transfer info;
952 
953 			info.length = bytes_to_write;
954 			info.lba = sector_number;
955 
956 			/* SCSI WRITE first OUT stage */
957 			if (mass_storage_send_scsi_cbw_out(SCSI_WRITE, &info))
958 				return EIO;
959 
960 			/* SCSI WRITE second OUT stage */
961 			if (mass_storage_send_scsi_data_out(buffer,
962 							bytes_to_write))
963 				return EIO;
964 
965 			/* SCSI WRITE IN stage */
966 			if (mass_storage_send_scsi_csw_in())
967 				return EIO;
968 
969 			/* Writing completed so shift starting
970 			 * sector for next iteration */
971 			sector_number += bytes_to_write / SECTOR_SIZE;
972 
973 			/* Update amount of data already copied */
974 			bytes_already_written += bytes_to_write;
975 		}
976 	}
977 
978 	return bytes_already_written;
979 }
980 
981 
982 /*===========================================================================*
983  *    mass_storage_read                                                      *
984  *===========================================================================*/
985 static ssize_t
986 mass_storage_read(unsigned long sector_number,
987 		endpoint_t endpt,
988 		iovec_t * iov,
989 		unsigned int iov_count,
990 		unsigned long bytes_left)
991 {
992 	/*
993 	 * This function reads 'bytes_left' bytes of mass storage data into
994 	 * 'iov' array (iov[0] : iov[iov_count]) starting from sector
995 	 * 'sector_number'. Total amount of 'iov' data should be greater or
996 	 * equal to initial value of 'bytes_left'.
997 	 *
998 	 * Endpoint value 'endpt', determines if vectors 'iov' contain memory
999 	 * addresses for copying or grant IDs.
1000 	 */
1001 
1002 	iov_state cur_iov;		/* Current state of vector copying */
1003 	unsigned long bytes_to_read;	/* To be read in this iteration */
1004 	ssize_t bytes_already_read;	/* Total amount read (retval) */
1005 
1006 	MASS_DEBUG_DUMP;
1007 
1008 	/* Initialize locals */
1009 	cur_iov.remaining_bytes = 0;	/* No IO vector initially */
1010 	cur_iov.iov_idx = 0;		/* Starting from first vector */
1011 	bytes_already_read = 0;		/* Nothing copied yet */
1012 
1013 	/* Mass storage operations are sector based */
1014 	assert(0 == (sizeof(buffer) % SECTOR_SIZE));
1015 	assert(0 == (bytes_left % SECTOR_SIZE));
1016 
1017 	while (bytes_left > 0) {
1018 
1019 		/* Decide read length and alter remaining bytes */
1020 		{
1021 			/* Number of bytes to be read in next URB */
1022 			if (bytes_left > sizeof(buffer)) {
1023 				bytes_to_read = sizeof(buffer);
1024 			} else {
1025 				bytes_to_read = bytes_left;
1026 			}
1027 
1028 			bytes_left -= bytes_to_read;
1029 		}
1030 
1031 		/* Send URB and alter sector number */
1032 		{
1033 			scsi_transfer info;
1034 
1035 			info.length = bytes_to_read;
1036 			info.lba = sector_number;
1037 
1038 			/* SCSI READ OUT stage */
1039 			if (mass_storage_send_scsi_cbw_out(SCSI_READ, &info))
1040 				return EIO;
1041 
1042 			/* SCSI READ first IN stage */
1043 			if (mass_storage_send_scsi_data_in(buffer,
1044 							bytes_to_read))
1045 				return EIO;
1046 
1047 			/* SCSI READ second IN stage */
1048 			if (mass_storage_send_scsi_csw_in())
1049 				return EIO;
1050 
1051 			/* Reading completed so shift starting
1052 			 * sector for next iteration */
1053 			sector_number += bytes_to_read / SECTOR_SIZE;
1054 		}
1055 
1056 		/* Fill IO Vectors with data from buffer */
1057 		{
1058 			unsigned long buf_offset;
1059 			unsigned long copy_len;
1060 
1061 			/* Start copying from the beginning of the buffer */
1062 			buf_offset = 0;
1063 
1064 			/* Copy as long as there are unfilled vectors
1065 			 * or data in buffer remains */
1066 			for (;;) {
1067 
1068 				/* If previous vector was filled get new one */
1069 				if (0 == cur_iov.remaining_bytes) {
1070 					/* Check if there are vectors
1071 					 * to be filled */
1072 					if (cur_iov.iov_idx < iov_count) {
1073 
1074 						cur_iov.base_addr =
1075 						  iov[cur_iov.iov_idx].iov_addr;
1076 						cur_iov.remaining_bytes =
1077 						  iov[cur_iov.iov_idx].iov_size;
1078 						cur_iov.offset = 0;
1079 						cur_iov.iov_idx++;
1080 
1081 					} else {
1082 						/* Total length of vectors
1083 						 * should be greater or equal
1084 						 * to initial value of
1085 						 * bytes_left. Being here means
1086 						 * that everything should
1087 						 * have been copied already */
1088 						assert(0 == bytes_left);
1089 						break;
1090 					}
1091 				}
1092 
1093 				/* Copy as much as it is possible from buffer
1094 				 * and at most the amount that can be
1095 				 * put in vector */
1096 				copy_len = MIN(bytes_to_read - buf_offset,
1097 						cur_iov.remaining_bytes);
1098 
1099 				/* This distinction is required as transfer can
1100 				 * be used from within this process and meaning
1101 				 * of IO vector'a address is different than
1102 				 * grant ID */
1103 				if (endpt == SELF) {
1104 					memcpy((void*)(cur_iov.base_addr +
1105 							cur_iov.offset),
1106 							&buffer[buf_offset],
1107 							copy_len);
1108 				} else {
1109 					ssize_t copy_res;
1110 					if ((copy_res = sys_safecopyto(endpt,
1111 						cur_iov.base_addr,
1112 						cur_iov.offset,
1113 						(vir_bytes)
1114 						(&buffer[buf_offset]),
1115 						copy_len))) {
1116 						MASS_MSG("sys_safecopyto "
1117 							"failed");
1118 						return copy_res;
1119 					}
1120 				}
1121 
1122 				/* Alter current state of copying */
1123 				buf_offset += copy_len;
1124 				cur_iov.offset += copy_len;
1125 				cur_iov.remaining_bytes -= copy_len;
1126 
1127 				/* Everything was copied */
1128 				if (bytes_to_read == buf_offset)
1129 					break;
1130 			}
1131 
1132 			/* Update amount of data already copied */
1133 			bytes_already_read += buf_offset;
1134 		}
1135 	}
1136 
1137 	return bytes_already_read;
1138 }
1139 
1140 
1141 /*===========================================================================*
1142  *    mass_storage_open                                                      *
1143  *===========================================================================*/
1144 static int
1145 mass_storage_open(devminor_t minor, int UNUSED(access))
1146 {
1147 	mass_storage_drive * d;
1148 	int r;
1149 
1150 	MASS_DEBUG_DUMP;
1151 
1152 	/* Decode minor into drive device information */
1153 	if (NULL == (mass_storage_part(minor)))
1154 		return ENXIO;
1155 
1156 	/* Copy evaluated current drive for simplified dereference */
1157 	d = driver_state.cur_drive;
1158 
1159 #ifdef MASS_RESET_RECOVERY
1160 	/* In case of previous CBW mismatch */
1161 	if (mass_storage_reset_recovery()) {
1162 		MASS_MSG("Resetting mass storage device failed");
1163 		return EIO;
1164 	}
1165 #endif
1166 
1167 	/* In case of missing endpoint information, do simple
1168 	 * enumeration and hold it for future use */
1169 	if ((URB_INVALID_EP == driver_state.cur_periph->ep_in.ep_num) ||
1170 		(URB_INVALID_EP == driver_state.cur_periph->ep_out.ep_num)) {
1171 
1172 		if (mass_storage_get_endpoints(&driver_state.cur_periph->ep_in,
1173 					&driver_state.cur_periph->ep_out))
1174 			return EIO;
1175 	}
1176 
1177 	/* If drive hasn't been opened yet, try to open it */
1178 	if (d->open_ct == 0) {
1179 		if ((r = mass_storage_try_first_open())) {
1180 			MASS_MSG("Opening mass storage device"
1181 				" for the first time failed");
1182 
1183 			/* Do one more test before failing, to output
1184 			 * sense errors in case they weren't dumped already */
1185 			if (mass_storage_test())
1186 				MASS_MSG("Final TEST UNIT READY failed");
1187 
1188 			return r;
1189 		}
1190 
1191 		/* Clear remembered device state for current
1192 		 * drive before calling partition */
1193 		memset(&d->part[0],	0, sizeof(d->part));
1194 		memset(&d->subpart[0],	0, sizeof(d->subpart));
1195 
1196 		/* Try parsing partition table (for entire drive) */
1197 		/* Warning!! This call uses mass_storage_part with own minors
1198 		 * and alters global driver_state.cur_device! */
1199 		partition(&mass_storage, (d->drive_idx * DEV_PER_DRIVE),
1200 			P_PRIMARY, 0);
1201 
1202 		/* Decode minor into UPDATED drive device information */
1203 		if (NULL == (mass_storage_part(minor)))
1204 			return ENXIO;
1205 
1206 		/* Decoded size must be positive or else
1207 		 * we assume device (partition) is unavailable */
1208 		if (0 == driver_state.cur_device->dv_size)
1209 			return ENXIO;
1210 	}
1211 
1212 	/* Run TEST UNIT READY before further commands
1213 	 * Some devices refuse to work without this */
1214 	if (mass_storage_test())
1215 		return EIO;
1216 
1217 	/* Opening completed */
1218 	d->open_ct++;
1219 
1220 	return EXIT_SUCCESS;
1221 }
1222 
1223 
1224 /*===========================================================================*
1225  *    mass_storage_close                                                     *
1226  *===========================================================================*/
1227 static int mass_storage_close(devminor_t minor)
1228 {
1229 	MASS_DEBUG_DUMP;
1230 
1231 	/* Decode minor into drive device information */
1232 	if (NULL == (mass_storage_part(minor)))
1233 		return ENXIO;
1234 
1235 	/* If drive hasn't been opened yet */
1236 	if (driver_state.cur_drive->open_ct == 0) {
1237 		MASS_MSG("Device was not opened yet");
1238 		return ERESTART;
1239 	}
1240 
1241 	/* Act accordingly */
1242 	driver_state.cur_drive->open_ct--;
1243 
1244 	return EXIT_SUCCESS;
1245 }
1246 
1247 
1248 /*===========================================================================*
1249  *    mass_storage_transfer                                                  *
1250  *===========================================================================*/
1251 static ssize_t
1252 mass_storage_transfer(devminor_t minor,		/* device minor number */
1253 		int do_write,			/* 1 write, 0 read */
1254 		u64_t pos,			/* position of starting point */
1255 		endpoint_t endpt,		/* endpoint */
1256 		iovec_t * iov,			/* vector */
1257 		unsigned int iov_count,		/* how many vectors */
1258 		int UNUSED(flags))		/* transfer flags */
1259 {
1260 	u64_t temp_sector_number;
1261 	unsigned long bytes;
1262 	unsigned long sector_number;
1263 	unsigned int cur_iov_idx;
1264 	int r;
1265 
1266 	MASS_DEBUG_DUMP;
1267 
1268 	/* Decode minor into drive device information */
1269 	if (NULL == (mass_storage_part(minor)))
1270 		return ENXIO;
1271 
1272 	bytes = 0;
1273 
1274 	/* How much data is going to be transferred? */
1275 	for (cur_iov_idx = 0; cur_iov_idx < iov_count; ++cur_iov_idx) {
1276 
1277 		/* Check if grant ID was supplied
1278 		 * instead of address and if it is valid */
1279 		if (endpt != SELF)
1280 			if (!GRANT_VALID((cp_grant_id_t)
1281 				(iov[cur_iov_idx].iov_addr)))
1282 				return EINVAL;
1283 
1284 		/* All supplied vectors must have positive length */
1285 		if ((signed long)(iov[cur_iov_idx].iov_size) <= 0) {
1286 			MASS_MSG("Transfer request length is not positive");
1287 			return EINVAL;
1288 		}
1289 
1290 		/* Requirements were met, more bytes can be transferred */
1291 		bytes += iov[cur_iov_idx].iov_size;
1292 
1293 		/* Request size must never overflow */
1294 		if ((signed long)bytes <= 0) {
1295 			MASS_MSG("Transfer request length overflowed");
1296 			return EINVAL;
1297 		}
1298 	}
1299 
1300 	/* Check if reading beyond device/partition */
1301 	if (pos >= driver_state.cur_device->dv_size) {
1302 		MASS_MSG("Request out of bounds for given device");
1303 		return 0; /* No error and no bytes read */
1304 	}
1305 
1306 	/* Check if arguments agree with accepted restriction
1307 	 * for parameters of transfer */
1308 	if ((r = mass_storage_transfer_restrictions(pos, bytes)))
1309 		return r;
1310 
1311 	/* If 'hard' requirements above were met, do additional
1312 	 * limiting to device/partition boundary */
1313 	if ((pos + bytes) > driver_state.cur_device->dv_size)
1314 		bytes = (driver_state.cur_device->dv_size - pos) &
1315 			~SECTOR_MASK;
1316 
1317 	/* We have to obtain sector number of given position
1318 	 * and limit it to what URB can handle */
1319 	temp_sector_number = (driver_state.cur_device->dv_base + pos) /
1320 				SECTOR_SIZE;
1321 	assert(temp_sector_number < ULONG_MAX); /* LBA is limited to 32B */
1322 	sector_number = (unsigned long)temp_sector_number;
1323 
1324 	if (do_write)
1325 		return mass_storage_write(sector_number, endpt, iov,
1326 					iov_count, bytes);
1327 	else
1328 		return mass_storage_read(sector_number, endpt, iov,
1329 					iov_count, bytes);
1330 }
1331 
1332 
1333 /*===========================================================================*
1334  *    mass_storage_ioctl                                                     *
1335  *===========================================================================*/
1336 static int
1337 mass_storage_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
1338 			cp_grant_id_t grant, endpoint_t UNUSED(user_endpt))
1339 {
1340 	MASS_DEBUG_DUMP;
1341 
1342 	/* Decode minor into drive device information */
1343 	if (NULL == (mass_storage_part(minor)))
1344 		return ENXIO;
1345 
1346 	switch (request) {
1347 		case DIOCOPENCT:
1348 			if (sys_safecopyto(endpt, grant, 0,
1349 				(vir_bytes) &(driver_state.cur_drive->open_ct),
1350 				sizeof(driver_state.cur_drive->open_ct)))
1351 				panic("sys_safecopyto failed!");
1352 
1353 			return EXIT_SUCCESS;
1354 
1355 		default:
1356 			MASS_MSG("Unimplemented IOCTL request: 0x%X",
1357 				(int)request);
1358 			break;
1359 	}
1360 
1361 	return ENOTTY;
1362 }
1363 
1364 
1365 /*===========================================================================*
1366  *    mass_storage_cleanup                                                   *
1367  *===========================================================================*/
1368 static void mass_storage_cleanup(void)
1369 {
1370 	MASS_DEBUG_DUMP;
1371 	return;
1372 }
1373 
1374 
1375 /*===========================================================================*
1376  *    mass_storage_part                                                      *
1377  *===========================================================================*/
1378 static struct device *
1379 mass_storage_part(devminor_t minor)
1380 {
1381 	unsigned long sel_drive;
1382 	unsigned long sel_device;
1383 
1384 	MASS_DEBUG_DUMP;
1385 
1386 	/* Override every time before further decision */
1387 	driver_state.cur_drive = NULL;
1388 	driver_state.cur_device = NULL;
1389 	driver_state.cur_periph = NULL;
1390 
1391 	/* Decode 'minor' code to find which device file was used */
1392 	if (minor < MINOR_d0p0s0) {
1393 
1394 		/* No sub-partitions used */
1395 		sel_drive = minor / DEV_PER_DRIVE;
1396 		sel_device = minor % DEV_PER_DRIVE;
1397 
1398 		/* Only valid minors */
1399 		if (sel_drive < MAX_DRIVES) {
1400 			/* Associate minor (device/partition)
1401 			 * with peripheral number */
1402 			/* TODO:PERIPH
1403 			 * Proper peripheral selection based
1404 			 * on minor should be here: */
1405 			driver_state.cur_periph = &driver_state.periph[0];
1406 
1407 			/* Select drive entry for opening count etc. */
1408 			driver_state.cur_drive =
1409 				&(driver_state.cur_periph->drives[sel_drive]);
1410 
1411 			/* Select device entry for given device file */
1412 			/* Device 0 means entire drive.
1413 			 * Devices 1,2,3,4 mean partitions 0,1,2,3 */
1414 			if (0 == sel_device)
1415 				driver_state.cur_device =
1416 					&(driver_state.cur_drive->disk);
1417 			else
1418 				driver_state.cur_device =
1419 					&(driver_state.cur_drive->part
1420 								[sel_device-1]);
1421 		}
1422 
1423 	} else {
1424 
1425 		/* Shift values accordingly */
1426 		minor -= MINOR_d0p0s0;
1427 
1428 		/* Sub-partitions used */
1429 		sel_drive = minor / SUBPART_PER_DISK;
1430 		sel_device = minor % SUBPART_PER_DISK;
1431 
1432 		/* Only valid minors */
1433 		if (sel_drive < MAX_DRIVES) {
1434 			/* Leave in case of ridiculously high number */
1435 			if (minor < SUBPART_PER_DISK) {
1436 				/* Associate minor (device/partition)
1437 				 * with peripheral number */
1438 				/* TODO:PERIPH
1439 				 * Proper peripheral selection based
1440 				 * on minor should be here: */
1441 				driver_state.cur_periph =
1442 						&driver_state.periph[0];
1443 
1444 				/* Select drive entry for opening count etc. */
1445 				driver_state.cur_drive =
1446 					&(driver_state.cur_periph->drives
1447 								[sel_drive]);
1448 				/* Select device entry for given
1449 				 * sub-partition device file */
1450 				driver_state.cur_device =
1451 					&(driver_state.cur_drive->subpart
1452 								[sel_device]);
1453 			}
1454 		}
1455 	}
1456 
1457 	/* Check for success */
1458 	if (NULL == driver_state.cur_device) {
1459 		MASS_MSG("Device for minor: %u not found", minor);
1460 	} else {
1461 		/* Assign index as well */
1462 		driver_state.cur_drive->drive_idx = sel_drive;
1463 	}
1464 
1465 	return driver_state.cur_device;
1466 }
1467 
1468 
1469 /*===========================================================================*
1470  *    mass_storage_geometry                                                  *
1471  *===========================================================================*/
1472 /* This command is optional for most mass storage devices
1473  * It should rather be used with USB floppy disk reader */
1474 #ifdef MASS_USE_GEOMETRY
1475 static void
1476 mass_storage_geometry(devminor_t minor, struct part_geom * part)
1477 {
1478 	char flexible_disk_page[SCSI_MODE_SENSE_FLEX_DATA_LEN];
1479 
1480 	MASS_DEBUG_DUMP;
1481 
1482 	/* Decode minor into drive device information */
1483 	if (NULL == (mass_storage_part(minor)))
1484 		return;
1485 
1486 	/* SCSI MODE SENSE OUT stage */
1487 	if (mass_storage_send_scsi_cbw_out(SCSI_MODE_SENSE, NULL))
1488 		return;
1489 
1490 	/* SCSI MODE SENSE first IN stage */
1491 	if (mass_storage_send_scsi_data_in(flexible_disk_page,
1492 					sizeof(flexible_disk_page)))
1493 		return;
1494 
1495 	/* SCSI MODE SENSE second IN stage */
1496 	if (mass_storage_send_scsi_csw_in())
1497 		return;
1498 
1499 	/* Get geometry from reply */
1500 	if (check_mode_sense_reply(flexible_disk_page, &(part->cylinders),
1501 				&(part->heads), &(part->sectors)))
1502 		return;
1503 #else
1504 static void
1505 mass_storage_geometry(devminor_t UNUSED(minor), struct part_geom * part)
1506 {
1507 	MASS_DEBUG_DUMP;
1508 
1509 	part->cylinders = part->size / SECTOR_SIZE;
1510 	part->heads = 64;
1511 	part->sectors = 32;
1512 #endif
1513 }
1514 
1515 
1516 /*===========================================================================*
1517  *    usb_driver_completion                                                  *
1518  *===========================================================================*/
1519 static void
1520 usb_driver_completion(void * UNUSED(priv))
1521 {
1522 	/* Last request was completed so allow continuing
1523 	 * execution from place where semaphore was downed */
1524 	ddekit_sem_up(mass_storage_sem);
1525 }
1526 
1527 
1528 /*===========================================================================*
1529  *    usb_driver_connect                                                     *
1530  *===========================================================================*/
1531 static void
1532 usb_driver_connect(struct ddekit_usb_dev * dev,
1533 		unsigned int interfaces)
1534 {
1535 	MASS_DEBUG_DUMP;
1536 
1537 	/* TODO:PERIPH
1538 	 * Some sort of more complex peripheral assignment should be here */
1539 	driver_state.cur_periph = &driver_state.periph[0];
1540 
1541 	if (NULL != driver_state.cur_periph->dev)
1542 		panic("Only one peripheral can be connected!");
1543 
1544 	/* Hold host information for future use */
1545 	driver_state.cur_periph->dev = dev;
1546 	driver_state.cur_periph->interfaces = interfaces;
1547 	driver_state.cur_periph->ep_in.ep_num = URB_INVALID_EP;
1548 	driver_state.cur_periph->ep_out.ep_num = URB_INVALID_EP;
1549 }
1550 
1551 
1552 /*===========================================================================*
1553  *    usb_driver_disconnect                                                  *
1554  *===========================================================================*/
1555 static void
1556 usb_driver_disconnect(struct ddekit_usb_dev * UNUSED(dev))
1557 {
1558 	MASS_DEBUG_DUMP;
1559 
1560 	/* TODO:PERIPH
1561 	 * Some sort of peripheral discard should be here */
1562 	driver_state.cur_periph = &driver_state.periph[0];
1563 
1564 	assert(NULL != driver_state.cur_periph->dev);
1565 
1566 	/* Clear */
1567 	driver_state.cur_periph->dev = NULL;
1568 	driver_state.cur_periph->interfaces = 0;
1569 	driver_state.cur_periph->ep_in.ep_num = URB_INVALID_EP;
1570 	driver_state.cur_periph->ep_out.ep_num = URB_INVALID_EP;
1571 }
1572 
1573 
1574 /*===========================================================================*
1575  *    mass_storage_get_endpoints                                             *
1576  *===========================================================================*/
1577 static int
1578 mass_storage_get_endpoints(urb_ep_config * ep_in, urb_ep_config * ep_out)
1579 {
1580 	/* URB to be send */
1581 	struct ddekit_usb_urb urb;
1582 
1583 	/* Setup buffer to be attached */
1584 	struct usb_ctrlrequest setup_buf;
1585 
1586 	/* Control EP configuration */
1587 	urb_ep_config ep_conf;
1588 
1589 	/* Descriptors' buffer */
1590 	unsigned char descriptors[MAX_DESCRIPTORS_LEN];
1591 
1592 	MASS_DEBUG_DUMP;
1593 
1594 	/* Initialize EP configuration */
1595 	ep_conf.ep_num = 0;
1596 	ep_conf.direction = DDEKIT_USB_IN;
1597 	ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
1598 	ep_conf.max_packet_size = 0;
1599 	ep_conf.interval = 0;
1600 
1601 	/* Reset URB and assign given values */
1602 	init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);
1603 
1604 	/* Clear setup data */
1605 	memset(&setup_buf, 0, sizeof(setup_buf));
1606 
1607 	/* Standard get endpoint request */
1608 	setup_buf.bRequestType = 0x80; /* Device to host */
1609 	setup_buf.bRequest = UR_GET_DESCRIPTOR;
1610 	setup_buf.wValue = UDESC_CONFIG << 8; /* TODO: configuration 0 */
1611 	setup_buf.wIndex = 0x00;
1612 	setup_buf.wLength = MAX_DESCRIPTORS_LEN;
1613 
1614 	/* Attach buffers to URB */
1615 	attach_urb_data(&urb, URB_BUF_TYPE_SETUP,
1616 			&setup_buf, sizeof(setup_buf));
1617 	attach_urb_data(&urb, URB_BUF_TYPE_DATA,
1618 			descriptors, sizeof(descriptors));
1619 
1620 	/* Send and wait for response */
1621 	if (blocking_urb_submit(&urb, mass_storage_sem,
1622 				URB_SUBMIT_ALLOW_MISMATCH))
1623 		return EXIT_FAILURE;
1624 
1625 	/* Check if buffer was supposed to hold more data */
1626 	if (urb.size < urb.actual_length) {
1627 		MASS_MSG("Too much descriptor data received");
1628 		return EXIT_FAILURE;
1629 	}
1630 
1631 	return mass_storage_parse_descriptors(urb.data, urb.actual_length,
1632 						ep_in, ep_out);
1633 }
1634 
1635 
1636 /*===========================================================================*
1637  *    mass_storage_parse_endpoint                                            *
1638  *===========================================================================*/
1639 static int
1640 mass_storage_parse_endpoint(usb_descriptor_t * cur_desc,
1641 			urb_ep_config * ep_in, urb_ep_config * ep_out)
1642 {
1643 	usb_endpoint_descriptor_t * ep_desc;
1644 
1645 	urb_ep_config * this_ep;
1646 
1647 	MASS_DEBUG_DUMP;
1648 
1649 	ep_desc = (usb_endpoint_descriptor_t *)cur_desc;
1650 
1651 	/* Only bulk with no other attributes are important */
1652 	if (UE_BULK == ep_desc->bmAttributes) {
1653 
1654 		/* Check for direction */
1655 		if (UE_DIR_IN == UE_GET_DIR(ep_desc->bEndpointAddress)) {
1656 
1657 			this_ep = ep_in;
1658 			this_ep->direction = DDEKIT_USB_IN;
1659 
1660 		} else {
1661 
1662 			this_ep = ep_out;
1663 			this_ep->direction = DDEKIT_USB_OUT;
1664 		}
1665 
1666 		/* Check if it was set before */
1667 		if (URB_INVALID_EP != this_ep->ep_num) {
1668 			MASS_MSG("BULK EP already set");
1669 			return EXIT_FAILURE;
1670 		}
1671 
1672 		/* Assign rest */
1673 		this_ep->ep_num = UE_GET_ADDR(ep_desc->bEndpointAddress);
1674 		this_ep->type = DDEKIT_USB_TRANSFER_BLK;
1675 		this_ep->max_packet_size = UGETW(ep_desc->wMaxPacketSize);
1676 		this_ep->interval = ep_desc->bInterval;
1677 	}
1678 
1679 	/* EP type other than bulk, is also correct,
1680 	 * just no parsing is performed */
1681 	return EXIT_SUCCESS;
1682 }
1683 
1684 /*===========================================================================*
1685  *    mass_storage_parse_descriptors                                         *
1686  *===========================================================================*/
1687 static int
1688 mass_storage_parse_descriptors(char * desc_buf, unsigned int buf_len,
1689 				urb_ep_config * ep_in, urb_ep_config * ep_out)
1690 {
1691 	/* Currently parsed, descriptors */
1692 	usb_descriptor_t * cur_desc;
1693 	usb_interface_descriptor_t * ifc_desc;
1694 
1695 	/* Byte counter for descriptor parsing */
1696 	unsigned int cur_byte;
1697 
1698 	/* Non zero if recently parsed interface is valid for this device */
1699 	int valid_interface;
1700 
1701 	MASS_DEBUG_DUMP;
1702 
1703 	/* Parse descriptors to get endpoints */
1704 	ep_in->ep_num = URB_INVALID_EP;
1705 	ep_out->ep_num = URB_INVALID_EP;
1706 	valid_interface = 0;
1707 	cur_byte = 0;
1708 
1709 	while (cur_byte < buf_len) {
1710 
1711 		/* Map descriptor to buffer */
1712 		/* Structure is packed so alignment should not matter */
1713 		cur_desc = (usb_descriptor_t *)&(desc_buf[cur_byte]);
1714 
1715 		/* Check this so we won't be reading
1716 		 * memory outside the buffer */
1717 		if ((cur_desc->bLength > 3) &&
1718 			(cur_byte + cur_desc->bLength <= buf_len)) {
1719 
1720 			/* Parse based on descriptor type */
1721 			switch (cur_desc->bDescriptorType) {
1722 
1723 				case UDESC_CONFIG: {
1724 					if (USB_CONFIG_DESCRIPTOR_SIZE !=
1725 						cur_desc->bLength) {
1726 						MASS_MSG("Wrong configuration"
1727 							" descriptor length");
1728 						return EXIT_FAILURE;
1729 					}
1730 					break;
1731 				}
1732 
1733 				case UDESC_STRING:
1734 					break;
1735 
1736 				case UDESC_INTERFACE: {
1737 					ifc_desc =
1738 					 (usb_interface_descriptor_t *)cur_desc;
1739 
1740 					if (USB_INTERFACE_DESCRIPTOR_SIZE !=
1741 						cur_desc->bLength) {
1742 						MASS_MSG("Wrong interface"
1743 							" descriptor length");
1744 						return EXIT_FAILURE;
1745 					}
1746 
1747 					/* Check if following data is meant
1748 					 * for our interfaces */
1749 					if ((1 << ifc_desc->bInterfaceNumber) &
1750 					    driver_state.cur_periph->interfaces)
1751 						valid_interface = 1;
1752 					else
1753 						valid_interface = 0;
1754 
1755 					break;
1756 				}
1757 
1758 				case UDESC_ENDPOINT: {
1759 					if (USB_ENDPOINT_DESCRIPTOR_SIZE !=
1760 						cur_desc->bLength) {
1761 						MASS_MSG("Wrong endpoint"
1762 							" descriptor length");
1763 						return EXIT_FAILURE;
1764 					}
1765 
1766 					/* Previous interface was,
1767 					 * what we were looking for */
1768 					if (valid_interface) {
1769 						if (EXIT_SUCCESS !=
1770 						    mass_storage_parse_endpoint(
1771 						    cur_desc, ep_in, ep_out))
1772 							return EXIT_FAILURE;
1773 
1774 					}
1775 
1776 					break;
1777 				}
1778 
1779 				default: {
1780 					MASS_MSG("Wrong descriptor type");
1781 					return EXIT_FAILURE;
1782 				}
1783 			}
1784 
1785 		} else {
1786 			MASS_MSG("Invalid descriptor length");
1787 			return EXIT_FAILURE;
1788 		}
1789 
1790 		/* Get next descriptor */
1791 		cur_byte += cur_desc->bLength;
1792 	}
1793 
1794 	/* Total length should match sum of all descriptors' lengths... */
1795 	if (cur_byte > buf_len)
1796 		return EXIT_FAILURE;
1797 
1798 	/* ...and descriptors should be valid */
1799 	if ((URB_INVALID_EP == ep_in->ep_num) ||
1800 		(URB_INVALID_EP == ep_out->ep_num)) {
1801 		MASS_MSG("Valid bulk endpoints not found");
1802 		return EXIT_FAILURE;
1803 	}
1804 
1805 	return EXIT_SUCCESS;
1806 }
1807