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
main(int argc,char * argv[])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
mass_storage_send_scsi_cbw_out(int scsi_cmd,scsi_transfer * info)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
mass_storage_send_scsi_data_in(void * buf,unsigned int in_len)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
mass_storage_send_scsi_data_out(void * buf,unsigned int out_len)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
mass_storage_send_scsi_csw_in(void)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
mass_storage_reset_recovery(void)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
mass_storage_send_bulk_reset(void)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
mass_storage_send_clear_feature(int ep_num,int direction)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
mass_storage_sef_hdlr(int type,sef_init_info_t * UNUSED (info))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
mass_storage_signal_handler(int this_signal)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
ddekit_usb_task(void * UNUSED (arg))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
mass_storage_task(void * UNUSED (unused))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
mass_storage_test(void)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
mass_storage_check_error(void)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
mass_storage_try_first_open()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
mass_storage_transfer_restrictions(u64_t pos,unsigned long bytes)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
mass_storage_write(unsigned long sector_number,endpoint_t endpt,iovec_t * iov,unsigned int iov_count,unsigned long bytes_left)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
mass_storage_read(unsigned long sector_number,endpoint_t endpt,iovec_t * iov,unsigned int iov_count,unsigned long bytes_left)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
mass_storage_open(devminor_t minor,int UNUSED (access))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 *===========================================================================*/
mass_storage_close(devminor_t minor)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
mass_storage_transfer(devminor_t minor,int do_write,u64_t pos,endpoint_t endpt,iovec_t * iov,unsigned int iov_count,int UNUSED (flags))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
mass_storage_ioctl(devminor_t minor,unsigned long request,endpoint_t endpt,cp_grant_id_t grant,endpoint_t UNUSED (user_endpt))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 *===========================================================================*/
mass_storage_cleanup(void)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 *
mass_storage_part(devminor_t minor)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
mass_storage_geometry(devminor_t minor,struct part_geom * part)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