xref: /haiku/src/add-ons/kernel/busses/scsi/usb/datafab/datafab.c (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
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
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
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 */
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
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
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
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
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
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
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
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
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
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
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
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
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