1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#include "transport.h"
54#include "protocol.h"
55#include "usb.h"
56#include "debug.h"
57#include "datafab.h"
58
59#include <linux/sched.h>
60#include <linux/errno.h>
61#include <linux/slab.h>
62
63extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
64 unsigned int len, unsigned int *act_len);
65
66static int datafab_determine_lun(struct us_data *us, struct datafab_info *info);
67
68
69static void datafab_dump_data(unsigned char *data, int len)
70{
71 unsigned char buf[80];
72 int sofar = 0;
73
74 if (!data)
75 return;
76
77 memset(buf, 0, sizeof(buf));
78
79 for (sofar = 0; sofar < len; sofar++) {
80 sprintf(buf + strlen(buf), "%02x ",
81 ((unsigned int) data[sofar]) & 0xFF);
82
83 if (sofar % 16 == 15) {
84 US_DEBUGP("datafab: %s\n", buf);
85 memset(buf, 0, sizeof(buf));
86 }
87 }
88
89 if (strlen(buf) != 0)
90 US_DEBUGP("datafab: %s\n", buf);
91}
92
93
94static int datafab_raw_bulk(int direction,
95 struct us_data *us,
96 unsigned char *data,
97 unsigned int len)
98{
99 int result;
100 int act_len;
101 int pipe;
102
103 if (direction == SCSI_DATA_READ)
104 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
105 else
106 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
107
108 result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
109
110
111 if (result == -EPIPE) {
112 US_DEBUGP("datafab_raw_bulk: EPIPE. clearing endpoint halt for"
113 " pipe 0x%x, stalled at %d bytes\n", pipe, act_len);
114 usb_stor_clear_halt(us, pipe);
115 }
116
117 if (result) {
118
119 if (result == -ETIMEDOUT) {
120 US_DEBUGP("datafab_raw_bulk: device NAKed\n");
121 return US_BULK_TRANSFER_FAILED;
122 }
123
124
125 if (result == -ECONNRESET) {
126 US_DEBUGP("datafab_raw_bulk: transfer aborted\n");
127 return US_BULK_TRANSFER_ABORTED;
128 }
129
130 if (result == -EPIPE) {
131 US_DEBUGP("datafab_raw_bulk: output pipe stalled\n");
132 return USB_STOR_TRANSPORT_FAILED;
133 }
134
135
136 US_DEBUGP("datafab_raw_bulk: unknown error\n");
137 return US_BULK_TRANSFER_FAILED;
138 }
139
140 if (act_len != len) {
141 US_DEBUGP("datafab_raw_bulk: Warning. Transferred only %d bytes\n", act_len);
142 return US_BULK_TRANSFER_SHORT;
143 }
144
145 US_DEBUGP("datafab_raw_bulk: Transfered %d of %d bytes\n", act_len, len);
146 return US_BULK_TRANSFER_GOOD;
147}
148
149static inline int datafab_bulk_read(struct us_data *us,
150 unsigned char *data,
151 unsigned int len)
152{
153 if (len == 0)
154 return USB_STOR_TRANSPORT_GOOD;
155
156 US_DEBUGP("datafab_bulk_read: len = %d\n", len);
157 return datafab_raw_bulk(SCSI_DATA_READ, us, data, len);
158}
159
160
161static inline int datafab_bulk_write(struct us_data *us,
162 unsigned char *data,
163 unsigned int len)
164{
165 if (len == 0)
166 return USB_STOR_TRANSPORT_GOOD;
167
168 US_DEBUGP("datafab_bulk_write: len = %d\n", len);
169 return datafab_raw_bulk(SCSI_DATA_WRITE, us, data, len);
170}
171
172
173static int datafab_read_data(struct us_data *us,
174 struct datafab_info *info,
175 u32 sector,
176 u32 sectors,
177 unsigned char *dest,
178 int use_sg)
179{
180 unsigned char command[8] = { 0, 0, 0, 0, 0, 0xE0, 0x20, 0x01 };
181 unsigned char *buffer = NULL;
182 unsigned char *ptr;
183 unsigned char thistime;
184 struct scatterlist *sg = NULL;
185 int totallen, len, result;
186 int sg_idx = 0, current_sg_offset = 0;
187 int transferred, rc;
188
189
190
191
192
193
194 if (sectors > 0x0FFFFFFF)
195 return USB_STOR_TRANSPORT_ERROR;
196
197 if (info->lun == -1) {
198 rc = datafab_determine_lun(us, info);
199 if (rc != USB_STOR_TRANSPORT_GOOD)
200 return rc;
201 }
202
203 command[5] += (info->lun << 4);
204
205
206
207
208
209
210
211
212 totallen = sectors * info->ssize;
213
214 do {
215
216 len = min_t(int, totallen, 65536);
217
218 if (use_sg) {
219 sg = (struct scatterlist *) dest;
220 buffer = kmalloc(len, GFP_NOIO);
221 if (buffer == NULL)
222 return USB_STOR_TRANSPORT_ERROR;
223 ptr = buffer;
224 } else {
225 ptr = dest;
226 }
227
228 thistime = (len / info->ssize) & 0xff;
229
230 command[0] = 0;
231 command[1] = thistime;
232 command[2] = sector & 0xFF;
233 command[3] = (sector >> 8) & 0xFF;
234 command[4] = (sector >> 16) & 0xFF;
235
236 command[5] |= (sector >> 24) & 0x0F;
237
238
239 US_DEBUGP("datafab_read_data: sending following command\n");
240 datafab_dump_data(command, sizeof(command));
241
242 result = datafab_bulk_write(us, command, sizeof(command));
243 if (result != USB_STOR_TRANSPORT_GOOD) {
244 if (use_sg)
245 kfree(buffer);
246 return result;
247 }
248
249
250 result = datafab_bulk_read(us, ptr, len);
251 if (result != USB_STOR_TRANSPORT_GOOD) {
252 if (use_sg)
253 kfree(buffer);
254 return result;
255 }
256
257 US_DEBUGP("datafab_read_data results: %d bytes\n", len);
258
259
260 sectors -= thistime;
261 sector += thistime;
262
263 if (use_sg) {
264 transferred = 0;
265 while (sg_idx < use_sg && transferred < len) {
266 if (len - transferred >= sg[sg_idx].length - current_sg_offset) {
267 US_DEBUGP("datafab_read_data: adding %d bytes to %d byte sg buffer\n", sg[sg_idx].length - current_sg_offset, sg[sg_idx].length);
268 memcpy(sg[sg_idx].address + current_sg_offset,
269 buffer + transferred,
270 sg[sg_idx].length - current_sg_offset);
271 transferred += sg[sg_idx].length - current_sg_offset;
272 current_sg_offset = 0;
273
274 ++sg_idx;
275 } else {
276 US_DEBUGP("datafab_read_data: adding %d bytes to %d byte sg buffer\n", len - transferred, sg[sg_idx].length);
277 memcpy(sg[sg_idx].address + current_sg_offset,
278 buffer + transferred,
279 len - transferred);
280 current_sg_offset += len - transferred;
281
282 break;
283 }
284 }
285 kfree(buffer);
286 } else {
287 dest += len;
288 }
289
290 totallen -= len;
291 } while (totallen > 0);
292
293 return USB_STOR_TRANSPORT_GOOD;
294}
295
296
297static int datafab_write_data(struct us_data *us,
298 struct datafab_info *info,
299 u32 sector,
300 u32 sectors,
301 unsigned char *src,
302 int use_sg)
303{
304 unsigned char command[8] = { 0, 0, 0, 0, 0, 0xE0, 0x30, 0x02 };
305 unsigned char reply[2] = { 0, 0 };
306 unsigned char *buffer = NULL;
307 unsigned char *ptr;
308 unsigned char thistime;
309 struct scatterlist *sg = NULL;
310 int totallen, len, result;
311 int sg_idx = 0, current_sg_offset = 0;
312 int transferred, rc;
313
314
315
316
317
318
319 if (sectors > 0x0FFFFFFF)
320 return USB_STOR_TRANSPORT_ERROR;
321
322 if (info->lun == -1) {
323 rc = datafab_determine_lun(us, info);
324 if (rc != USB_STOR_TRANSPORT_GOOD)
325 return rc;
326 }
327
328 command[5] += (info->lun << 4);
329
330
331
332
333
334
335
336
337 totallen = sectors * info->ssize;
338
339 do {
340
341 len = min_t(int, totallen, 65536);
342
343 if (use_sg) {
344 sg = (struct scatterlist *) src;
345 buffer = kmalloc(len, GFP_NOIO);
346 if (buffer == NULL)
347 return USB_STOR_TRANSPORT_ERROR;
348 ptr = buffer;
349
350 memset(buffer, 0, len);
351
352
353
354 transferred = 0;
355 while (transferred < len) {
356 if (len - transferred >= sg[sg_idx].length - current_sg_offset) {
357 US_DEBUGP("datafab_write_data: getting %d bytes from %d byte sg buffer\n", sg[sg_idx].length - current_sg_offset, sg[sg_idx].length);
358 memcpy(ptr + transferred,
359 sg[sg_idx].address + current_sg_offset,
360 sg[sg_idx].length - current_sg_offset);
361 transferred += sg[sg_idx].length - current_sg_offset;
362 current_sg_offset = 0;
363
364 ++sg_idx;
365 } else {
366 US_DEBUGP("datafab_write_data: getting %d bytes from %d byte sg buffer\n", len - transferred, sg[sg_idx].length);
367 memcpy(ptr + transferred,
368 sg[sg_idx].address + current_sg_offset,
369 len - transferred);
370 current_sg_offset += len - transferred;
371
372 break;
373 }
374 }
375 } else {
376 ptr = src;
377 }
378
379 thistime = (len / info->ssize) & 0xff;
380
381 command[0] = 0;
382 command[1] = thistime;
383 command[2] = sector & 0xFF;
384 command[3] = (sector >> 8) & 0xFF;
385 command[4] = (sector >> 16) & 0xFF;
386
387 command[5] |= (sector >> 24) & 0x0F;
388
389
390 US_DEBUGP("datafab_write_data: sending following command\n");
391 datafab_dump_data(command, sizeof(command));
392
393 result = datafab_bulk_write(us, command, sizeof(command));
394 if (result != USB_STOR_TRANSPORT_GOOD) {
395 if (use_sg)
396 kfree(buffer);
397 return result;
398 }
399
400
401 result = datafab_bulk_write(us, ptr, len);
402 if (result != USB_STOR_TRANSPORT_GOOD) {
403 if (use_sg)
404 kfree(buffer);
405 return result;
406 }
407
408
409 result = datafab_bulk_read(us, reply, sizeof(reply));
410 if (result != USB_STOR_TRANSPORT_GOOD) {
411 if (use_sg)
412 kfree(buffer);
413 return result;
414 }
415
416 if (reply[0] != 0x50 && reply[1] != 0) {
417 US_DEBUGP("datafab_write_data: Gah! write return code: %02x %02x\n", reply[0], reply[1]);
418 if (use_sg)
419 kfree(buffer);
420 return USB_STOR_TRANSPORT_ERROR;
421 }
422
423 sectors -= thistime;
424 sector += thistime;
425
426 if (use_sg) {
427 kfree(buffer);
428 } else {
429 src += len;
430 }
431
432 totallen -= len;
433 } while (totallen > 0);
434
435 return USB_STOR_TRANSPORT_GOOD;
436}
437
438
439static int datafab_determine_lun(struct us_data *us,
440 struct datafab_info *info)
441{
442
443
444
445
446
447
448 unsigned char command[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
449 unsigned char buf[512];
450 int count = 0, rc;
451
452 if (!us || !info)
453 return USB_STOR_TRANSPORT_ERROR;
454
455 US_DEBUGP("datafab_determine_lun: locating...\n");
456
457
458
459 while (count++ < 10) {
460 command[5] = 0xa0;
461
462 rc = datafab_bulk_write(us, command, 8);
463 if (rc != USB_STOR_TRANSPORT_GOOD)
464 return rc;
465
466 rc = datafab_bulk_read(us, buf, sizeof(buf));
467 if (rc == USB_STOR_TRANSPORT_GOOD) {
468 info->lun = 0;
469 return USB_STOR_TRANSPORT_GOOD;
470 }
471
472 command[5] = 0xb0;
473
474 rc = datafab_bulk_write(us, command, 8);
475 if (rc != USB_STOR_TRANSPORT_GOOD)
476 return rc;
477
478 rc = datafab_bulk_read(us, buf, sizeof(buf));
479 if (rc == USB_STOR_TRANSPORT_GOOD) {
480 info->lun = 1;
481 return USB_STOR_TRANSPORT_GOOD;
482 }
483
484 wait_ms(20);
485 }
486
487 return USB_STOR_TRANSPORT_FAILED;
488}
489
490static int datafab_id_device(struct us_data *us,
491 struct datafab_info *info)
492{
493
494
495
496
497 unsigned char command[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
498 unsigned char reply[512];
499 int rc;
500
501 if (!us || !info)
502 return USB_STOR_TRANSPORT_ERROR;
503
504 if (info->lun == -1) {
505 rc = datafab_determine_lun(us, info);
506 if (rc != USB_STOR_TRANSPORT_GOOD)
507 return rc;
508 }
509
510 command[5] += (info->lun << 4);
511
512 rc = datafab_bulk_write(us, command, 8);
513 if (rc != USB_STOR_TRANSPORT_GOOD)
514 return rc;
515
516
517
518 rc = datafab_bulk_read(us, reply, sizeof(reply));
519 if (rc == USB_STOR_TRANSPORT_GOOD) {
520
521
522 info->sectors = ((u32)(reply[117]) << 24) |
523 ((u32)(reply[116]) << 16) |
524 ((u32)(reply[115]) << 8) |
525 ((u32)(reply[114]) );
526 }
527
528 return rc;
529}
530
531
532static int datafab_handle_mode_sense(struct us_data *us,
533 Scsi_Cmnd * srb,
534 unsigned char *ptr,
535 int sense_6)
536{
537 unsigned char mode_param_header[8] = {
538 0, 0, 0, 0, 0, 0, 0, 0
539 };
540 unsigned char rw_err_page[12] = {
541 0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
542 };
543 unsigned char cache_page[12] = {
544 0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
545 };
546 unsigned char rbac_page[12] = {
547 0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
548 };
549 unsigned char timer_page[8] = {
550 0x1C, 0x6, 0, 0, 0, 0
551 };
552 unsigned char pc, page_code;
553 unsigned short total_len = 0;
554 unsigned short param_len, i = 0;
555
556
557
558
559
560
561 if (sense_6)
562 param_len = srb->cmnd[4];
563 else
564 param_len = ((u16) (srb->cmnd[7]) >> 8) | ((u16) (srb->cmnd[8]));
565
566 pc = srb->cmnd[2] >> 6;
567 page_code = srb->cmnd[2] & 0x3F;
568
569 switch (pc) {
570 case 0x0:
571 US_DEBUGP("datafab_handle_mode_sense: Current values\n");
572 break;
573 case 0x1:
574 US_DEBUGP("datafab_handle_mode_sense: Changeable values\n");
575 break;
576 case 0x2:
577 US_DEBUGP("datafab_handle_mode_sense: Default values\n");
578 break;
579 case 0x3:
580 US_DEBUGP("datafab_handle_mode_sense: Saves values\n");
581 break;
582 }
583
584 mode_param_header[3] = 0x80;
585
586 switch (page_code) {
587 case 0x0:
588
589 return USB_STOR_TRANSPORT_ERROR;
590
591 case 0x1:
592 total_len = sizeof(rw_err_page);
593 mode_param_header[0] = total_len >> 8;
594 mode_param_header[1] = total_len & 0xFF;
595 mode_param_header[3] = 0x00;
596
597 memcpy(ptr, mode_param_header, sizeof(mode_param_header));
598 i += sizeof(mode_param_header);
599 memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
600 break;
601
602 case 0x8:
603 total_len = sizeof(cache_page);
604 mode_param_header[0] = total_len >> 8;
605 mode_param_header[1] = total_len & 0xFF;
606 mode_param_header[3] = 0x00;
607
608 memcpy(ptr, mode_param_header, sizeof(mode_param_header));
609 i += sizeof(mode_param_header);
610 memcpy(ptr + i, cache_page, sizeof(cache_page));
611 break;
612
613 case 0x1B:
614 total_len = sizeof(rbac_page);
615 mode_param_header[0] = total_len >> 8;
616 mode_param_header[1] = total_len & 0xFF;
617 mode_param_header[3] = 0x00;
618
619 memcpy(ptr, mode_param_header, sizeof(mode_param_header));
620 i += sizeof(mode_param_header);
621 memcpy(ptr + i, rbac_page, sizeof(rbac_page));
622 break;
623
624 case 0x1C:
625 total_len = sizeof(timer_page);
626 mode_param_header[0] = total_len >> 8;
627 mode_param_header[1] = total_len & 0xFF;
628 mode_param_header[3] = 0x00;
629
630 memcpy(ptr, mode_param_header, sizeof(mode_param_header));
631 i += sizeof(mode_param_header);
632 memcpy(ptr + i, timer_page, sizeof(timer_page));
633 break;
634
635 case 0x3F:
636 total_len = sizeof(timer_page) + sizeof(rbac_page) +
637 sizeof(cache_page) + sizeof(rw_err_page);
638 mode_param_header[0] = total_len >> 8;
639 mode_param_header[1] = total_len & 0xFF;
640 mode_param_header[3] = 0x00;
641
642 memcpy(ptr, mode_param_header, sizeof(mode_param_header));
643 i += sizeof(mode_param_header);
644 memcpy(ptr + i, timer_page, sizeof(timer_page));
645 i += sizeof(timer_page);
646 memcpy(ptr + i, rbac_page, sizeof(rbac_page));
647 i += sizeof(rbac_page);
648 memcpy(ptr + i, cache_page, sizeof(cache_page));
649 i += sizeof(cache_page);
650 memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
651 break;
652 }
653
654 return USB_STOR_TRANSPORT_GOOD;
655}
656
657void datafab_info_destructor(void *extra)
658{
659
660
661}
662
663
664
665
666int datafab_transport(Scsi_Cmnd * srb, struct us_data *us)
667{
668 struct datafab_info *info;
669 int rc;
670 unsigned long block, blocks;
671 unsigned char *ptr = NULL;
672 unsigned char inquiry_reply[36] = {
673 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
674 };
675
676 if (!us->extra) {
677 us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO);
678 if (!us->extra) {
679 US_DEBUGP("datafab_transport: Gah! Can't allocate storage for Datafab info struct!\n");
680 return USB_STOR_TRANSPORT_ERROR;
681 }
682 memset(us->extra, 0, sizeof(struct datafab_info));
683 us->extra_destructor = datafab_info_destructor;
684 ((struct datafab_info *)us->extra)->lun = -1;
685 }
686
687 info = (struct datafab_info *) (us->extra);
688 ptr = (unsigned char *) srb->request_buffer;
689
690 if (srb->cmnd[0] == INQUIRY) {
691 US_DEBUGP("datafab_transport: INQUIRY. Returning bogus response");
692 memset( inquiry_reply + 8, 0, 28 );
693 fill_inquiry_response(us, inquiry_reply, 36);
694 return USB_STOR_TRANSPORT_GOOD;
695 }
696
697 if (srb->cmnd[0] == READ_CAPACITY) {
698 info->ssize = 0x200;
699 rc = datafab_id_device(us, info);
700 if (rc != USB_STOR_TRANSPORT_GOOD)
701 return rc;
702
703 US_DEBUGP("datafab_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n",
704 info->sectors, info->ssize);
705
706
707
708 ptr[0] = (info->sectors >> 24) & 0xFF;
709 ptr[1] = (info->sectors >> 16) & 0xFF;
710 ptr[2] = (info->sectors >> 8) & 0xFF;
711 ptr[3] = (info->sectors) & 0xFF;
712
713 ptr[4] = (info->ssize >> 24) & 0xFF;
714 ptr[5] = (info->ssize >> 16) & 0xFF;
715 ptr[6] = (info->ssize >> 8) & 0xFF;
716 ptr[7] = (info->ssize) & 0xFF;
717
718 return USB_STOR_TRANSPORT_GOOD;
719 }
720
721 if (srb->cmnd[0] == MODE_SELECT_10) {
722 US_DEBUGP("datafab_transport: Gah! MODE_SELECT_10.\n");
723 return USB_STOR_TRANSPORT_ERROR;
724 }
725
726
727
728
729 if (srb->cmnd[0] == READ_10) {
730 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
731 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
732
733 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
734
735 US_DEBUGP("datafab_transport: READ_10: read block 0x%04lx count %ld\n", block, blocks);
736 return datafab_read_data(us, info, block, blocks, ptr, srb->use_sg);
737 }
738
739 if (srb->cmnd[0] == READ_12) {
740
741
742 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
743 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
744
745 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
746 ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9]));
747
748 US_DEBUGP("datafab_transport: READ_12: read block 0x%04lx count %ld\n", block, blocks);
749 return datafab_read_data(us, info, block, blocks, ptr, srb->use_sg);
750 }
751
752 if (srb->cmnd[0] == WRITE_10) {
753 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
754 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
755
756 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
757
758 US_DEBUGP("datafab_transport: WRITE_10: write block 0x%04lx count %ld\n", block, blocks);
759 return datafab_write_data(us, info, block, blocks, ptr, srb->use_sg);
760 }
761
762 if (srb->cmnd[0] == WRITE_12) {
763
764
765 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
766 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
767
768 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
769 ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9]));
770
771 US_DEBUGP("datafab_transport: WRITE_12: write block 0x%04lx count %ld\n", block, blocks);
772 return datafab_write_data(us, info, block, blocks, ptr, srb->use_sg);
773 }
774
775 if (srb->cmnd[0] == TEST_UNIT_READY) {
776 US_DEBUGP("datafab_transport: TEST_UNIT_READY.\n");
777 return datafab_id_device(us, info);
778 }
779
780 if (srb->cmnd[0] == REQUEST_SENSE) {
781 US_DEBUGP("datafab_transport: REQUEST_SENSE. Returning faked response\n");
782
783
784
785
786
787 ptr[0] = 0xF0;
788 ptr[2] = info->sense_key;
789 ptr[7] = 11;
790 ptr[12] = info->sense_asc;
791 ptr[13] = info->sense_ascq;
792
793 return USB_STOR_TRANSPORT_GOOD;
794 }
795
796 if (srb->cmnd[0] == MODE_SENSE) {
797 US_DEBUGP("datafab_transport: MODE_SENSE_6 detected\n");
798 return datafab_handle_mode_sense(us, srb, ptr, TRUE);
799 }
800
801 if (srb->cmnd[0] == MODE_SENSE_10) {
802 US_DEBUGP("datafab_transport: MODE_SENSE_10 detected\n");
803 return datafab_handle_mode_sense(us, srb, ptr, FALSE);
804 }
805
806 if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
807
808
809
810 return USB_STOR_TRANSPORT_GOOD;
811 }
812
813 if (srb->cmnd[0] == START_STOP) {
814
815
816 US_DEBUGP("datafab_transport: START_STOP.\n");
817
818
819 rc = datafab_id_device(us, info);
820 if (rc == USB_STOR_TRANSPORT_GOOD) {
821 info->sense_key = NO_SENSE;
822 srb->result = SUCCESS;
823 } else {
824 info->sense_key = UNIT_ATTENTION;
825 srb->result = CHECK_CONDITION;
826 }
827 return rc;
828 }
829
830 US_DEBUGP("datafab_transport: Gah! Unknown command: %d (0x%x)\n", srb->cmnd[0], srb->cmnd[0]);
831 return USB_STOR_TRANSPORT_ERROR;
832}
833