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
41typedef 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
53typedef struct{
54/*
550 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/*
691 X Obsolete
702 O V Specific configuration
713 X Obsolete
724-5 X Retired
736 X Obsolete
747-8 O V Reserved for assignment by the CompactFlash� Association
759 X Retired
76*/
77  uint16 pad1[9];
78  /*
7910-19 M F Serial number (20 ASCII characters)
80*/
81  uint16 serial[10];
82/*
8320-21 X Retired
8422 X Obsolete
85*/
86  uint16 pad2[3];
87  /*
8823-26 M F Firmware revision (8 ASCII characters)
89*/
90  uint16 firmware_rev[4];
91  /*
9227-46 M F Model number (40 ASCII characters)
93*/
94  uint16 model_num[20];
95/*
9647 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*//*
10148 F Reserved
102*//*
10349 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*//*
11550 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*//*
12251-52 X Obsolete
123*//*
12453 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*//*
13154-58 X Obsolete
132*//*
13359 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/*
14060-61 M F Total number of user addressable sectors
141*/
142  uint32 total_secs;
143/*
14462 X Obsolete
145*//*
14663 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
15764 M F 15-8 Reserved
158  F 7-0 PIO modes supported
15965 M Minimum Multiword DMA transfer cycle time per word
160  F 15-0 Cycle time in nanoseconds
16166 M Manufacturer�s recommended Multiword DMA transfer cycle time
162  F 15-0 Cycle time in nanoseconds
16367 M Minimum PIO transfer cycle time without flow control
164  F 15-0 Cycle time in nanoseconds
16568 M Minimum PIO transfer cycle time with IORDY flow control
166  F 15-0 Cycle time in nanoseconds
16769-70 F Reserved (for future command overlap and queuing)
16871-74 F Reserved for IDENTIFY PACKET DEVICE command.
16975 O Queue depth
170  F 15-5 Reserved
171  F 4-0 Maximum queue depth � 1
17276-79 F Reserved
17380 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
19181 M F Minor version number
192  0000h or FFFFh = device does not report version
193  0001h-FFFEh = see 8.15.41
19482 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
21283 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
22984 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
23985 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
25786 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
27387 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
28388 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
30389 O F Time required for security erase unit completion
30490 O F Time required for Enhanced security erase completion
30591 O V Current advanced power management value
30692 O V Master Password Revision Code
30793 * 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.
34194 O V 15-8 Vendor�s recommended acoustic management value.
342  V 7-0 Current automatic acoustic management value.
34395-99 F Reserved
344100-103 O V Maximum user LBA for 48-bit Address feature set.
345104-126 F Reserved
346127 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
352128 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
362129-159 X Vendor specific
363160 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
370161-175 X Reserved for assignment by the CompactFlash� Association
371176-205 O V Current media serial number
372206-254 F Reserved
373255 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
389typedef 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
406typedef 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*/
463status_t
464datafab_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*/
479status_t
480datafab_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*/
497static 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*/
523static status_t
524queue_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*/
553static status_t
554handle_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
618finalize:
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*/
632static status_t
633handle_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*/
647static status_t
648handle_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*/
662static status_t
663handle_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*/
677static status_t
678handle_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*/
692static status_t
693handle_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*/
707static status_t
708handle_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*/
722static status_t
723handle_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*/
737static status_t
738handle_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*/
760void
761datafab_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
827static status_t
828std_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
840static 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