1 /*
2 * \file: datafab.c
3 * \brief: USB SCSI module extention for Datafab USB readers
4 *
5 * This file is a part of BeOS USB SCSI interface module project.
6 * Copyright (c) 2005 by Siarzhuk Zharski <imker@gmx.li>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * This protocol extension module was developed using information from
23 * "Driver for Datafab USB Compact Flash reader" in Linux usb storage driver.
24 *
25 * $Source: /cvsroot/sis4be/usb_scsi/datafab/datafab.c,v $
26 * $Author: zharik $
27 * $Revision: 1.3 $
28 * $Date: 2005/03/12 21:18:48 $
29 *
30 */
31 #include "usb_scsi.h"
32
33 #include <string.h>
34 #include "device_info.h"
35 #include "proto_module.h"
36
37 #define DATAFAB_MODULE_NAME "datafab"
38 #define DATAFAB_PROTOCOL_MODULE_NAME \
39 MODULE_PREFIX DATAFAB_MODULE_NAME PROTOCOL_SUFFIX
40
41 typedef struct {
42 usb_device_info *udi;
43 uint8 *cmd;
44 uint8 cmdlen;
45 iovec*sg_data;
46 int32 sg_count;
47 int32 transfer_len;
48 EDirection dir;
49 CCB_SCSIIO *ccbio;
50 int32 residue;
51 } usb_scsi_transport_info;
52
53 typedef struct{
54 /*
55 0 M General configuration bit-significant information:
56 F 15 0 = ATA device
57 X 14-8 Retired
58 F 7 1 = removable media device
59 X 6 Obsolete
60 X 5-3 Retired
61 V 2 Response incomplete
62 X 1 Retired
63 F 0 Reserved
64 */
65 uint16 info;
66 #define NON_ATA_DEVICE 0x
67 #define REMOVABLE_DEVICE 0x
68 /*
69 1 X Obsolete
70 2 O V Specific configuration
71 3 X Obsolete
72 4-5 X Retired
73 6 X Obsolete
74 7-8 O V Reserved for assignment by the CompactFlash™ Association
75 9 X Retired
76 */
77 uint16 pad1[9];
78 /*
79 10-19 M F Serial number (20 ASCII characters)
80 */
81 uint16 serial[10];
82 /*
83 20-21 X Retired
84 22 X Obsolete
85 */
86 uint16 pad2[3];
87 /*
88 23-26 M F Firmware revision (8 ASCII characters)
89 */
90 uint16 firmware_rev[4];
91 /*
92 27-46 M F Model number (40 ASCII characters)
93 */
94 uint16 model_num[20];
95 /*
96 47 M F 15-8 80h
97 F 7-0 00h = Reserved
98 F 01h-FFh = Maximum number of sectors that shall be transferred per interrupt on
99 READ/WRITE MULTIPLE commands
100 *//*
101 48 F Reserved
102 *//*
103 49 M Capabilities
104 F 15-14 Reserved for the IDENTIFY PACKET DEVICE command.
105 F 13 1 = Standby timer values as specified in this standard are supported
106 0 = Standby timer values shall be managed by the device
107 F 12 Reserved for the IDENTIFY PACKET DEVICE command.
108 F 11 1 = IORDY supported
109 0 = IORDY may be supported
110 F 10 1 = IORDY may be disabled
111 F 9 1 = LBA supported
112 F 8 1 = DMA supported.
113 X 7-0 Retired
114 *//*
115 50 M Capabilities
116 F 15 Shall be cleared to zero.
117 F 14 Shall be set to one.
118 F 13-2 Reserved.
119 X 1 Obsolete
120 F 0 Shall be set to one to indicate a device specific Standby timer value minimum.
121 *//*
122 51-52 X Obsolete
123 *//*
124 53 M F 15-3 Reserved
125 F 2 1 = the fields reported in word 88 are valid
126 0 = the fields reported in word 88 are not valid
127 F 1 1 = the fields reported in words (70:64) are valid
128 0 = the fields reported in words (70:64) are not valid
129 X 0 Obsolete
130 *//*
131 54-58 X Obsolete
132 *//*
133 59 M F 15-9 Reserved
134 V 8 1 = Multiple sector setting is valid
135 V 7-0 xxh = Current setting for number of sectors that shall be transferred per interrupt on
136 R/W Multiple command
137 */
138 uint16 pad3[13];
139 /*
140 60-61 M F Total number of user addressable sectors
141 */
142 uint32 total_secs;
143 /*
144 62 X Obsolete
145 *//*
146 63 M F 15-11 Reserved
147 V 10 1 = Multiword DMA mode 2 is selected
148 0 = Multiword DMA mode 2 is not selected
149 V 9 1 = Multiword DMA mode 1 is selected
150 0 = Multiword DMA mode 1 is not selected
151 V 8 1 = Multiword DMA mode 0 is selected
152 0 = Multiword DMA mode 0 is not selected
153 F 7-3 Reserved
154 F 2 1 = Multiword DMA mode 2 and below are supported
155 F 1 1 = Multiword DMA mode 1 and below are supported
156 F 0 1 = Multiword DMA mode 0 is supported
157 64 M F 15-8 Reserved
158 F 7-0 PIO modes supported
159 65 M Minimum Multiword DMA transfer cycle time per word
160 F 15-0 Cycle time in nanoseconds
161 66 M Manufacturer’s recommended Multiword DMA transfer cycle time
162 F 15-0 Cycle time in nanoseconds
163 67 M Minimum PIO transfer cycle time without flow control
164 F 15-0 Cycle time in nanoseconds
165 68 M Minimum PIO transfer cycle time with IORDY flow control
166 F 15-0 Cycle time in nanoseconds
167 69-70 F Reserved (for future command overlap and queuing)
168 71-74 F Reserved for IDENTIFY PACKET DEVICE command.
169 75 O Queue depth
170 F 15-5 Reserved
171 F 4-0 Maximum queue depth – 1
172 76-79 F Reserved
173 80 M Major version number
174 0000h or FFFFh = device does not report version
175 F 15 Reserved
176 F 14 Reserved for ATA/ATAPI-14
177 F 13 Reserved for ATA/ATAPI-13
178 F 12 Reserved for ATA/ATAPI-12
179 F 11 Reserved for ATA/ATAPI-11
180 F 10 Reserved for ATA/ATAPI-10
181 F 9 Reserved for ATA/ATAPI-9
182 F 8 Reserved for ATA/ATAPI-8
183 F 7 Reserved for ATA/ATAPI-7
184 F 6 1 = supports ATA/ATAPI-6
185 F 5 1 = supports ATA/ATAPI-5
186 F 4 1 = supports ATA/ATAPI-4
187 F 3 1 = supports ATA-3
188 X 2 Obsolete
189 X 1 Obsolete
190 F 0 Reserved
191 81 M F Minor version number
192 0000h or FFFFh = device does not report version
193 0001h-FFFEh = see 8.15.41
194 82 M Command set supported.
195 X 15 Obsolete
196 F 14 1 = NOP command supported
197 F 13 1 = READ BUFFER command supported
198 F 12 1 = WRITE BUFFER command supported
199 X 11 Obsolete
200 F 10 1 = Host Protected Area feature set supported
201 F 9 1 = DEVICE RESET command supported
202 F 8 1 = SERVICE interrupt supported
203 F 7 1 = release interrupt supported
204 F 6 1 = look-ahead supported
205 F 5 1 = write cache supported
206 F 4 Shall be cleared to zero to indicate that the PACKET Command feature set is not
207 supported.
208 F 3 1 = mandatory Power Management feature set supported
209 F 2 1 = Removable Media feature set supported
210 F 1 1 = Security Mode feature set supported
211 F 0 1 = SMART feature set supported
212 83 M Command sets supported.
213 F 15 Shall be cleared to zero
214 F 14 Shall be set to one
215 F 13 1 = FLUSH CACHE EXT command supported
216 F 12 1 = mandatory FLUSH CACHE command supported
217 F 11 1 = Device Configuration Overlay feature set supported
218 F 10 1 = 48-bit Address feature set supported
219 F 9 1 = Automatic Acoustic Management feature set supported
220 F 8 1 = SET MAX security extension supported
221 F 7 See Address Offset Reserved Area Boot, NCITS TR27:2001
222 F 6 1 = SET FEATURES subcommand required to spinup after power-up
223 F 5 1 = Power-Up In Standby feature set supported
224 F 4 1 = Removable Media Status Notification feature set supported
225 F 3 1 = Advanced Power Management feature set supported
226 F 2 1 = CFA feature set supported
227 F 1 1 = READ/WRITE DMA QUEUED supported
228 F 0 1 = DOWNLOAD MICROCODE command supported
229 84 M Command set/feature supported extension.
230 F 15 Shall be cleared to zero
231 F 14 Shall be set to one
232 F 13-6 Reserved
233 F 5 1 = General Purpose Logging feature set supported
234 F 4 Reserved
235 F 3 1 = Media Card Pass Through Command feature set supported
236 F 2 1 = Media serial number supported
237 F 1 1 = SMART self-test supported
238 F 0 1 = SMART error logging supported
239 85 M Command set/feature enabled.
240 X 15 Obsolete
241 F 14 1 = NOP command enabled
242 F 13 1 = READ BUFFER command enabled
243 F 12 1 = WRITE BUFFER command enabled
244 X 11 Obsolete
245 V 10 1 = Host Protected Area feature set enabled
246 F 9 1 = DEVICE RESET command enabled
247 V 8 1 = SERVICE interrupt enabled
248 V 7 1 = release interrupt enabled
249 V 6 1 = look-ahead enabled
250 V 5 1 = write cache enabled
251 F 4 Shall be cleared to zero to indicate that the PACKET Command feature set is not
252 supported.
253 F 3 1 = Power Management feature set enabled
254 F 2 1 = Removable Media feature set enabled
255 V 1 1 = Security Mode feature set enabled
256 V 0 1 = SMART feature set enabled
257 86 M Command set/feature enabled.
258 F 15-14 Reserved
259 F 13 1 = FLUSH CACHE EXT command supported
260 F 12 1 = FLUSH CACHE command supported
261 F 11 1 = Device Configuration Overlay supported
262 F 10 1 = 48-bit Address features set supported
263 V 9 1 = Automatic Acoustic Management feature set enabled
264 F 8 1 = SET MAX security extension enabled by SET MAX SET PASSWORD
265 F 7 See Address Offset Reserved Area Boot, NCITS TR27:2001
266 F 6 1 = SET FEATURES subcommand required to spin-up after power-up
267 V 5 1 = Power-Up In Standby feature set enabled
268 V 4 1 = Removable Media Status Notification feature set enabled
269 V 3 1 = Advanced Power Management feature set enabled
270 F 2 1 = CFA feature set enabled
271 F 1 1 = READ/WRITE DMA QUEUED command supported
272 F 0 1 = DOWNLOAD MICROCODE command supported
273 87 M Command set/feature default.
274 F 15 Shall be cleared to zero
275 F 14 Shall be set to one
276 F 13-6 Reserved
277 F 5 General Purpose Logging feature set supported
278 V 4 Reserved
279 V 3 1 = Media Card Pass Through Command feature set enabled
280 V 2 1 = Media serial number is valid
281 F 1 1 = SMART self-test supported
282 F 0 1 = SMART error logging supported
283 88 O F 15-14 Reserved
284 V 13 1 = Ultra DMA mode 5 is selected
285 0 = Ultra DMA mode 5 is not selected
286 V 12 1 = Ultra DMA mode 4 is selected
287 0 = Ultra DMA mode 4 is not selected
288 V 11 1 = Ultra DMA mode 3 is selected
289 0 = Ultra DMA mode 3 is not selected
290 V 10 1 = Ultra DMA mode 2 is selected
291 0 = Ultra DMA mode 2 is not selected
292 V 9 1 = Ultra DMA mode 1 is selected
293 0 = Ultra DMA mode 1 is not selected
294 V 8 1 = Ultra DMA mode 0 is selected
295 0 = Ultra DMA mode 0 is not selected
296 F 7-6 Reserved
297 F 5 1 = Ultra DMA mode 5 and below are supported
298 F 4 1 = Ultra DMA mode 4 and below are supported
299 F 3 1 = Ultra DMA mode 3 and below are supported
300 F 2 1 = Ultra DMA mode 2 and below are supported
301 F 1 1 = Ultra DMA mode 1 and below are supported
302 F 0 1 = Ultra DMA mode 0 is supported
303 89 O F Time required for security erase unit completion
304 90 O F Time required for Enhanced security erase completion
305 91 O V Current advanced power management value
306 92 O V Master Password Revision Code
307 93 * Hardware reset result. The contents of bits (12:0) of this word shall change only during the
308 execution of a hardware reset.
309 F 15 Shall be cleared to zero.
310 F 14 Shall be set to one.
311 V 13 1 = device detected CBLID- above ViH
312 0 = device detected CBLID- below ViL
313 12-8 Device 1 hardware reset result. Device 0 shall clear these bits to zero. Device 1
314 shall set these bits as follows:
315 F 12 Reserved.
316 V 11 0 = Device 1 did not assert PDIAG-.
317 1 = Device 1 asserted PDIAG-.
318 V 10-9 These bits indicate how Device 1 determined the device number:
319 00 = Reserved.
320 01 = a jumper was used.
321 10 = the CSEL signal was used.
322 11 = some other method was used or the method is unknown.
323 8 Shall be set to one.
324 7-0 Device 0 hardware reset result. Device 1 shall clear these bits to zero. Device 0
325 shall set these bits as follows:
326 F 7 Reserved.
327 F 6 0 = Device 0 does not respond when Device 1 is selected.
328 1 = Device 0 responds when Device 1 is selected.
329 V 5 0 = Device 0 did not detect the assertion of DASP-.
330 1 = Device 0 detected the assertion of DASP-.
331 V 4 0 = Device 0 did not detect the assertion of PDIAG-.
332 1 = Device 0 detected the assertion of PDIAG-.
333 V 3 0 = Device 0 failed diagnostics.
334 1 = Device 0 passed diagnostics.
335 V 2-1 These bits indicate how Device 0 determined the device number:
336 00 = Reserved.
337 01 = a jumper was used.
338 10 = the CSEL signal was used.
339 11 = some other method was used or the method is unknown.
340 F 0 Shall be set to one.
341 94 O V 15-8 Vendor’s recommended acoustic management value.
342 V 7-0 Current automatic acoustic management value.
343 95-99 F Reserved
344 100-103 O V Maximum user LBA for 48-bit Address feature set.
345 104-126 F Reserved
346 127 O Removable Media Status Notification feature set support
347 F 15-2 Reserved
348 F 1-0 00 = Removable Media Status Notification feature set not supported
349 01 = Removable Media Status Notification feature supported
350 10 = Reserved
351 11 = Reserved
352 128 O Security status
353 F 15-9 Reserved
354 V 8 Security level 0 = High, 1 = Maximum
355 F 7-6 Reserved
356 F 5 1 = Enhanced security erase supported
357 V 4 1 = Security count expired
358 V 3 1 = Security frozen
359 V 2 1 = Security locked
360 V 1 1 = Security enabled
361 F 0 1 = Security supported
362 129-159 X Vendor specific
363 160 O CFA power mode 1
364 F 15 Word 160 supported
365 F 14 Reserved
366 F 13 CFA power mode 1 is required for one or more commands implemented by the
367 device
368 V 12 CFA power mode 1 disabled
369 F 11-0 Maximum current in ma
370 161-175 X Reserved for assignment by the CompactFlash™ Association
371 176-205 O V Current media serial number
372 206-254 F Reserved
373 255 M X Integrity word
374 15-8 Checksum
375 7-0 Signature
376 */
377 uint16 pad4[24];
378 uint16 pad5[25];
379 uint16 pad6[25];
380 uint16 pad7[20];
381 uint16 pad8[25];
382 uint16 pad9[25];
383 uint16 padA[25];
384 uint16 padB[25];
385 }ATA_DEVICE_INFO;
386
387 #define DEVICE_INFO_SIZE 512
388
389 typedef struct {
390 uint8 feature; /* R: error, W:feature */
391 uint8 sector_count; /* R: IReason W: Sectors Count*/
392 uint8 address[3]; /* part of address */
393 uint8 addr_dev; /* part of address and device info*/
394 #define ADDR_MASK 0x0F
395 #define DEV_MASK 0xF0
396 #define DEV_ON 0xA0
397 #define DEV_LBA 0x40
398 #define DEV_MASTER 0x00
399 #define DEV_SLAVE 0x10
400 uint8 command; /* R: status W:command */
401 uint8 intr_reset; /* interrupt/reset register */
402 #define IR_IRQ_ENABLE 0x01
403 #define IR_RESET 0x02
404 }command_registers;
405
406 typedef struct {
407 uint8 reg1;
408 uint8 reg2;
409 }status_registers;
410
411 #define IDE_CMD_IDENTIFY_DEVICE 0xEC
412 #define IDE_CMD_READ 0x20
413 #define IDE_CMD_WRITE 0x30
414
415 /* duplication! */
416 #define INQ_VENDOR_LEN 0x08
417 #define INQ_PRODUCT_LEN 0x10
418 #define INQ_REVISION_LEN 0x04
419
420
421 /*
422 B_DEV_INVALID_IOCTL = B_DEVICE_ERROR_BASE,
423 B_DEV_NO_MEMORY,
424 B_DEV_BAD_DRIVE_NUM,
425 B_DEV_NO_MEDIA,
426 B_DEV_UNREADABLE,
427 B_DEV_FORMAT_ERROR,
428 B_DEV_TIMEOUT,
429 B_DEV_RECALIBRATE_ERROR,
430 B_DEV_SEEK_ERROR,
431 B_DEV_ID_ERROR,
432 B_DEV_READ_ERROR, a
433 B_DEV_WRITE_ERROR,
434 B_DEV_NOT_READY,
435 B_DEV_MEDIA_CHANGED,
436 B_DEV_MEDIA_CHANGE_REQUESTED,
437 B_DEV_RESOURCE_CONFLICT,
438 B_DEV_CONFIGURATION_ERROR, 10
439 B_DEV_DISABLED_BY_USER,
440 B_DEV_DOOR_OPEN,
441
442 B_DEV_INVALID_PIPE, 13
443 B_DEV_CRC_ERROR,
444 B_DEV_STALLED, 15
445 B_DEV_BAD_PID,
446 B_DEV_UNEXPECTED_PID,
447 B_DEV_DATA_OVERRUN, 18
448 B_DEV_DATA_UNDERRUN,
449 B_DEV_FIFO_OVERRUN, 1a
450 B_DEV_FIFO_UNDERRUN,
451 B_DEV_PENDING,
452 B_DEV_MULTIPLE_ERRORS, 1d
453 B_DEV_TOO_LATE
454 */
455
456 /**
457 \fn:datafab_initialize
458 \param udi: device on wich we should perform initialization
459 \return:error code if initialization failed or B_OK if it passed
460
461 initialize procedure for bulk only protocol devices.
462 */
463 status_t
datafab_initialize(usb_device_info * udi)464 datafab_initialize(usb_device_info *udi)
465 {
466 status_t status = B_OK;
467 /*TODO*/
468 return status;
469 }
470 /**
471 \fn:datafab_reset
472 \param udi: device on wich we should perform reset
473 \return:error code if reset failed or B_OK if it passed
474
475 reset procedure for bulk only protocol devices. Tries to send
476 BulkOnlyReset USB request and clear USB_FEATURE_ENDPOINT_HALT features on
477 input and output pipes. ([2] 3.1)
478 */
479 status_t
datafab_reset(usb_device_info * udi)480 datafab_reset(usb_device_info *udi)
481 {
482 status_t status = B_OK;
483 /* not required ? */
484 return status;
485 }
486
487 /**
488 \fn:usb_callback
489 \param cookie:???
490 \param status:???
491 \param data:???
492 \param actual_len:???
493 \return:???
494
495 ???
496 */
usb_callback(void * cookie,uint32 status,void * data,uint32 actual_len)497 static void usb_callback(void *cookie,
498 uint32 status,
499 void *data,
500 uint32 actual_len)
501 {
502 if(cookie){
503 usb_device_info *udi = (usb_device_info *)cookie;
504 udi->status = status;
505 udi->data = data;
506 udi->actual_len = actual_len;
507 if(udi->status != B_CANCELED)
508 release_sem(udi->trans_sem);
509 }
510 }
511
512 /**
513 \fn:queue_bulk
514 \param udi: device for which que_bulk request is performed
515 \param buffer: data buffer, used in bulk i/o operation
516 \param len: length of data buffer
517 \param b_in: is "true" if input (device->host) data transfer, "false" otherwise
518 \return: status of operation.
519
520 performs queue_bulk USB request for corresponding pipe and handle timeout of this
521 operation.
522 */
523 static status_t
queue_bulk(usb_device_info * udi,void * buffer,size_t len,bool b_in)524 queue_bulk(usb_device_info *udi,
525 void *buffer,
526 size_t len,
527 bool b_in)
528 {
529 status_t status = B_OK;
530 usb_pipe pipe = b_in ? udi->pipe_in : udi->pipe_out;
531 status = (*udi->usb_m->queue_bulk)(pipe, buffer, len, usb_callback, udi);
532 if(status != B_OK){
533 PTRACE_ALWAYS(udi, "datafab_queue_bulk:failed:%08x\n", status);
534 } else {
535 status = acquire_sem_etc(udi->trans_sem, 1, B_RELATIVE_TIMEOUT,
536 /*DATAFAB_USB_TIMEOUT*/ udi->trans_timeout);
537 if(status != B_OK){
538 PTRACE_ALWAYS(udi, "datafab_queue_bulk:acquire_sem_etc failed:%08x\n", status);
539 (*udi->usb_m->cancel_queued_transfers)(pipe);
540 }
541 }
542 return status;
543 }
544
545 /**
546 \fn:handle_INQUIRY
547 \param usti: pointer to usb_scsi_transport_info sutruct containing request
548 information
549 \return: command execution status
550
551 handles INQUIRY SCSI command
552 */
553 static status_t
handle_INQUIRY(usb_scsi_transport_info * usti)554 handle_INQUIRY(usb_scsi_transport_info *usti)
555 {
556 status_t status = B_CMD_FAILED;
557 uint8 *data = usti->ccbio->cam_data_ptr;
558 if(usti->ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID){
559 PTRACE(usti->udi,"handle_INQUIRY: problems!!! scatter gatter ....=-(\n");
560 } else {
561 command_registers cr = {
562 .feature = 0,
563 .sector_count = 1,
564 .address = {0},
565 .addr_dev = 0xa0,
566 .command = 0xec,
567 .intr_reset = 0x01
568 };
569
570 ATA_DEVICE_INFO adi = {0};
571
572 PTRACE(usti->udi, "ATA_DEVICE_INFO sizeof:%d pipe_in:%x, pipe_out:%x\n", sizeof(adi),
573 usti->udi->pipe_in, usti->udi->pipe_out);
574
575 PTRACE(usti->udi, "command_registers sizeof:%d\n", sizeof(cr));
576
577 memset(data, 0, usti->ccbio->cam_dxfer_len);
578 //TODO!!!
579 /* data[0] = 0x1F;*/ /* we can play here with type of device */
580 /* data[1] = 0x80;
581 data[2] = 0x02;
582 data[3] = 0x02;
583 data[4] = (0 != usti->udi) ? 5 : 31; / * udi != 0 - mean FIX_NO_INQUIRY * /
584 if(usti->ccbio->cam_dxfer_len >= 0x24){
585 strncpy(&data[8], "USB SCSI", INQ_VENDOR_LEN);
586 strncpy(&data[16], "Reserved", INQ_PRODUCT_LEN);
587 strncpy(&data[32], "N/A", INQ_REVISION_LEN);
588 } */
589 status = queue_bulk(usti->udi, &cr, sizeof(cr), false);
590 if(B_OK != status){
591 PTRACE(usti->udi, "write command 1 status:%08x\n", status);
592 //goto finalize;
593 }
594
595 status = queue_bulk(usti->udi, &adi, sizeof(adi), true);
596 if(B_OK != status){
597 PTRACE(usti->udi, "write command 2 status:%08x\n", status);
598 goto finalize;
599 }
600
601 PTRACE(usti->udi, "ADI::info:%08x\n", adi.info);
602 usti->udi->trace_bytes("ADI::pad1:", (char*)adi.pad1, sizeof(adi.pad1));
603 usti->udi->trace_bytes("ADI::serial:", (char*)adi.serial, sizeof(adi.serial));
604 usti->udi->trace_bytes("ADI::pad2:", (char*)adi.pad2, sizeof(adi.pad2));
605 usti->udi->trace_bytes("ADI::firmware_rev:", (char*)adi.firmware_rev, sizeof(adi.firmware_rev));
606 usti->udi->trace_bytes("ADI::model_num:", (char*)adi.model_num, sizeof(adi.model_num));
607 usti->udi->trace_bytes("ADI::pad3:", (char*)adi.pad3, sizeof(adi.pad3));
608 usti->udi->trace_bytes("ADI::total_secs:", (char*)&adi.total_secs, sizeof(adi.total_secs));
609 usti->udi->trace_bytes("ADI::pad4:", (char*)adi.pad4, sizeof(adi.pad4));
610 usti->udi->trace_bytes("ADI::pad5:", (char*)adi.pad5, sizeof(adi.pad5));
611 usti->udi->trace_bytes("ADI::pad6:", (char*)adi.pad6, sizeof(adi.pad6));
612 usti->udi->trace_bytes("ADI::pad7:", (char*)adi.pad7, sizeof(adi.pad7));
613 usti->udi->trace_bytes("ADI::pad8:", (char*)adi.pad8, sizeof(adi.pad8));
614 usti->udi->trace_bytes("ADI::pad9:", (char*)adi.pad9, sizeof(adi.pad9));
615 usti->udi->trace_bytes("ADI::padA:", (char*)adi.padA, sizeof(adi.padA));
616 usti->udi->trace_bytes("ADI::padB:", (char*)adi.padB, sizeof(adi.padB));
617
618 finalize:
619 status = B_CMD_WIRE_FAILED;
620 }
621 return status;
622 }
623
624 /**
625 \fn:handle_TEST_UNIT_READY
626 \param usti: pointer to usb_scsi_transport_info sutruct containing request
627 information
628 \return: command execution status
629
630 handles TEST_UNIT_READY SCSI command
631 */
632 static status_t
handle_TEST_UNIT_READY(usb_scsi_transport_info * usti)633 handle_TEST_UNIT_READY(usb_scsi_transport_info *usti)
634 {
635 status_t status = B_CMD_FAILED;
636 return status;
637 }
638
639 /**
640 \fn:handle_READ_CAPACITY
641 \param usti: pointer to usb_scsi_transport_info sutruct containing request
642 information
643 \return: command execution status
644
645 handles READ_CAPACITY SCSI command
646 */
647 static status_t
handle_READ_CAPACITY(usb_scsi_transport_info * usti)648 handle_READ_CAPACITY(usb_scsi_transport_info *usti)
649 {
650 status_t status = B_CMD_FAILED;
651 return status;
652 }
653
654 /**
655 \fn:handle_REQUEST_SENSE
656 \param usti: pointer to usb_scsi_transport_info sutruct containing request
657 information
658 \return: command execution status
659
660 handles REQUEST_SENSE SCSI command
661 */
662 static status_t
handle_REQUEST_SENSE(usb_scsi_transport_info * usti)663 handle_REQUEST_SENSE(usb_scsi_transport_info *usti)
664 {
665 status_t status = B_CMD_FAILED;
666 return status;
667 }
668
669 /**
670 \fn:handle_MODE_SENSE
671 \param usti: pointer to usb_scsi_transport_info sutruct containing request
672 information
673 \return: command execution status
674
675 handles MODE_SENSE SCSI command
676 */
677 static status_t
handle_MODE_SENSE(usb_scsi_transport_info * usti)678 handle_MODE_SENSE(usb_scsi_transport_info *usti)
679 {
680 status_t status = B_CMD_FAILED;
681 return status;
682 }
683
684 /**
685 \fn:handle_MODE_SELECT
686 \param usti: pointer to usb_scsi_transport_info sutruct containing request
687 information
688 \return: command execution status
689
690 handles MODE_SELECT SCSI command
691 */
692 static status_t
handle_MODE_SELECT(usb_scsi_transport_info * usti)693 handle_MODE_SELECT(usb_scsi_transport_info *usti)
694 {
695 status_t status = B_CMD_FAILED;
696 return status;
697 }
698
699 /**
700 \fn:handle_READ
701 \param usti: pointer to usb_scsi_transport_info sutruct containing request
702 information
703 \return: command execution status
704
705 handles READ SCSI command
706 */
707 static status_t
handle_READ(usb_scsi_transport_info * usti)708 handle_READ(usb_scsi_transport_info *usti)
709 {
710 status_t status = B_CMD_FAILED;
711 return status;
712 }
713
714 /**
715 \fn:handle_WRITE
716 \param usti: pointer to usb_scsi_transport_info sutruct containing request
717 information
718 \return: command execution status
719
720 handles WRITE SCSI command
721 */
722 static status_t
handle_WRITE(usb_scsi_transport_info * usti)723 handle_WRITE(usb_scsi_transport_info *usti)
724 {
725 status_t status = B_CMD_FAILED;
726 return status;
727 }
728
729 /**
730 \fn:handle_UnknownCommand
731 \param usti: pointer to usb_scsi_transport_info sutruct containing request
732 information
733 \return: command execution status
734
735 handles "Unknown" SCSI command that were not handled
736 */
737 static status_t
handle_UnknownCommand(usb_scsi_transport_info * usti)738 handle_UnknownCommand(usb_scsi_transport_info *usti)
739 {
740 status_t status = B_CMD_FAILED;
741 return status;
742 }
743
744 /**
745 \fn:datafab_transfer
746 \param udi: corresponding device
747 \param cmd: SCSI command to be performed on USB device
748 \param cmdlen: length of SCSI command
749 \param data_sg: io vectors array with data to transfer
750 \param sglist_count: count of entries in io vector array
751 \param transfer_len: overall length of data to be transferred
752 \param dir: direction of data transfer
753 \param ccbio: CCB_SCSIIO struct for original SCSI command
754 \param cb: callback to handle of final stage of command performing (autosense \
755 request etc.)
756
757 transfer procedure for bulk-only protocol. Performs SCSI command on USB device
758 [2]
759 */
760 void
datafab_transfer(usb_device_info * udi,uint8 * cmd,uint8 cmdlen,iovec * sg_data,int32 sg_count,int32 transfer_len,EDirection dir,CCB_SCSIIO * ccbio,ud_transfer_callback cb)761 datafab_transfer(usb_device_info *udi,
762 uint8 *cmd,
763 uint8 cmdlen,
764 iovec*sg_data,
765 int32 sg_count,
766 int32 transfer_len,
767 EDirection dir,
768 CCB_SCSIIO *ccbio,
769 ud_transfer_callback cb)
770 {
771 status_t command_status = B_CMD_WIRE_FAILED;//B_OK;
772 int32 residue = transfer_len;
773 usb_scsi_transport_info usti = {
774 .udi = udi,
775 .cmd = cmd,
776 .cmdlen = cmdlen,
777 .sg_data = sg_data,
778 .sg_count = sg_count,
779 .transfer_len = transfer_len,
780 .dir = dir,
781 .ccbio = ccbio,
782 .residue = transfer_len
783 };
784
785 switch(cmd[0]){
786 case TEST_UNIT_READY:
787 command_status = handle_TEST_UNIT_READY(&usti);
788 break;
789 case INQUIRY:
790 command_status = handle_INQUIRY(&usti);
791 break;
792 case READ_CAPACITY:
793 command_status = handle_READ_CAPACITY(&usti);
794 break;
795 case REQUEST_SENSE:
796 command_status = handle_REQUEST_SENSE(&usti);
797 break;
798 case MODE_SENSE_6:
799 case MODE_SENSE_10:
800 command_status = handle_MODE_SENSE(&usti);
801 break;
802 case MODE_SELECT_6:
803 case MODE_SELECT_10:
804 command_status = handle_MODE_SELECT(&usti);
805 break;
806 /* case ALLOW_MEDIUM_REMOVAL:
807 command_status = handle_ALLOW_MEDIUM_REMOVAL();
808 break;*/
809 case READ_6:
810 case READ_10:
811 case READ_12:
812 command_status = handle_READ(&usti);
813 break;
814 case WRITE_6:
815 case WRITE_10:
816 case WRITE_12:
817 command_status = handle_WRITE(&usti);
818 break;
819 default:
820 command_status = handle_UnknownCommand(&usti);
821 break;
822 }
823 /* finalize transfer */
824 cb(udi, ccbio, residue, command_status);
825 }
826
827 static status_t
std_ops(int32 op,...)828 std_ops(int32 op, ...)
829 {
830 switch(op) {
831 case B_MODULE_INIT:
832 return B_OK;
833 case B_MODULE_UNINIT:
834 return B_OK;
835 default:
836 return B_ERROR;
837 }
838 }
839
840 static protocol_module_info datafab_protocol_module = {
841 { DATAFAB_PROTOCOL_MODULE_NAME, 0, std_ops },
842 datafab_initialize,
843 datafab_reset,
844 datafab_transfer,
845 };
846
847 _EXPORT protocol_module_info *modules[] = {
848 &datafab_protocol_module,
849 NULL
850 };
851