[haiku-commits] r38379 - in haiku/trunk/src/add-ons/kernel/drivers/disk/usb: . usb_floppy

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 26 Aug 2010 22:28:54 +0200 (CEST)

Author: pulkomandy
Date: 2010-08-26 22:28:54 +0200 (Thu, 26 Aug 2010)
New Revision: 38379
Changeset: http://dev.haiku-os.org/changeset/38379

Added:
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/
Modified:
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/Jamfile
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/Jamfile
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.cpp
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.h
   haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk_scsi.h
Log:
Work In Progress (do not try yet!) driver for usb floppy drive.
This is loosely based on usb_disk, but uses a different protocol for sending 
the commands.
Refactoring is unfinished, so don't look at the style too muh, it will e fixed 
and cleaned up later.

Basic communication with the drive works (sending commands). Command themselves 
still mostly untested.
Command Blocks sent to the drive are most likely wrong and may erase your 
floppies or do any other weird things!


Modified: haiku/trunk/src/add-ons/kernel/drivers/disk/usb/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/disk/usb/Jamfile     2010-08-26 
14:35:03 UTC (rev 38378)
+++ haiku/trunk/src/add-ons/kernel/drivers/disk/usb/Jamfile     2010-08-26 
20:28:54 UTC (rev 38379)
@@ -1,3 +1,4 @@
 SubDir HAIKU_TOP src add-ons kernel drivers disk usb ;
 
 SubInclude HAIKU_TOP src add-ons kernel drivers disk usb usb_disk ;
+SubInclude HAIKU_TOP src add-ons kernel drivers disk usb usb_floppy ;

Modified: haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_disk/Jamfile    
2010-08-26 11:52:11 UTC (rev 38366)
+++ haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/Jamfile  
2010-08-26 20:28:54 UTC (rev 38379)
@@ -1,8 +1,8 @@
-SubDir HAIKU_TOP src add-ons kernel drivers disk usb usb_disk ;
+SubDir HAIKU_TOP src add-ons kernel drivers disk usb usb_floppy ;
 
 SubDirSysHdrs $(HAIKU_TOP) src add-ons kernel bus_managers usb ;
 UsePrivateHeaders kernel ;
 
-KernelAddon usb_disk :
+KernelAddon usb_floppy :
        usb_disk.cpp
        ;

Modified: 
haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp       
2010-08-26 11:52:11 UTC (rev 38366)
+++ haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.cpp     
2010-08-26 20:28:54 UTC (rev 38379)
@@ -16,12 +16,12 @@
 #include "usb_disk_scsi.h"
 
 
-#define DRIVER_NAME                    "usb_disk"
-#define DEVICE_NAME_BASE       "disk/usb/"
+#define DRIVER_NAME                    "usb_floppy"
+#define DEVICE_NAME_BASE       "disk/ufi/"
 #define DEVICE_NAME                    DEVICE_NAME_BASE"%ld/%d/raw"
 
 
-//#define TRACE_USB_DISK
+#define TRACE_USB_DISK
 #ifdef TRACE_USB_DISK
 #define TRACE(x...)                    dprintf(DRIVER_NAME": "x)
 #define TRACE_ALWAYS(x...)     dprintf(DRIVER_NAME": "x)
@@ -128,8 +128,8 @@
                                void *data, size_t dataLength);
 status_t       usb_disk_receive_csw(disk_device *device,
                                command_status_wrapper *status);
-status_t       usb_disk_operation(device_lun *lun, uint8 operation,
-                               uint8 opLength, uint32 logicalBlockAddress,
+status_t       usb_disk_operation(device_lun *lun, uint8* operation,
+                               uint32 logicalBlockAddress,
                                uint16 transferLength, void *data, uint32 
*dataLength,
                                bool directionIn);
 
@@ -147,12 +147,18 @@
 //
 
 
+// FIXME: should be part of the device struct.
+static unsigned char interruptBuffer[2];
+sem_id interruptLock;
+
+
 void
 usb_disk_free_device_and_luns(disk_device *device)
 {
        mutex_lock(&device->lock);
        mutex_destroy(&device->lock);
        delete_sem(device->notify);
+       delete_sem(interruptLock);
        for (uint8 i = 0; i < device->lun_count; i++)
                free(device->luns[i]);
        free(device->luns);
@@ -165,40 +171,9 @@
 //
 
 
-status_t
-usb_disk_mass_storage_reset(disk_device *device)
-{
-       return gUSBModule->send_request(device->device, 
USB_REQTYPE_INTERFACE_OUT
-               | USB_REQTYPE_CLASS, REQUEST_MASS_STORAGE_RESET, 0x0000,
-               device->interface, 0, NULL, NULL);
-}
-
-
-uint8
-usb_disk_get_max_lun(disk_device *device)
-{
-       uint8 result = 0;
-       size_t actualLength = 0;
-
-       // devices that do not support multiple LUNs may stall this request
-       if (gUSBModule->send_request(device->device, USB_REQTYPE_INTERFACE_IN
-               | USB_REQTYPE_CLASS, REQUEST_GET_MAX_LUN, 0x0000, 
device->interface,
-               1, &result, &actualLength) != B_OK || actualLength != 1)
-               return 0;
-
-       if (result > MAX_LOGICAL_UNIT_NUMBER) {
-               // invalid max lun
-               return 0;
-       }
-
-       return result;
-}
-
-
 void
 usb_disk_reset_recovery(disk_device *device)
 {
-       usb_disk_mass_storage_reset(device);
        gUSBModule->clear_feature(device->bulk_in, USB_FEATURE_ENDPOINT_HALT);
        gUSBModule->clear_feature(device->bulk_out, USB_FEATURE_ENDPOINT_HALT);
 }
@@ -238,85 +213,60 @@
 }
 
 
+void
+usb_disk_interrupt(void* cookie, int32 status, void* data, uint32 length)
+{
+       char* stRep = (char*)data;
+       TRACE("interrupt of length %ld! status: %d misc: %d\n", length,
+               stRep[0], stRep[1]);
+       release_sem(interruptLock);
+
+       gUSBModule->queue_interrupt(((disk_device*)cookie)->interrupt,
+               interruptBuffer, 2, usb_disk_interrupt, cookie);
+}
+
+
 status_t
 usb_disk_receive_csw(disk_device *device, command_status_wrapper *status)
 {
-       status_t result = usb_disk_transfer_data(device, true, status,
-               sizeof(command_status_wrapper));
-       if (result != B_OK)
-               return result;
+       TRACE("Waiting for result...\n");
+       gUSBModule->queue_interrupt(device->interrupt,
+               interruptBuffer, 2, usb_disk_interrupt, device);
 
-       if (device->status != B_OK
-               || device->actual_length != sizeof(command_status_wrapper)) {
-               // receiving the command status wrapper failed
-               return B_ERROR;
-       }
+       acquire_sem(interruptLock);
 
+       status->status = interruptBuffer[0];
+       status->misc = interruptBuffer[1];
+
        return B_OK;
 }
 
 
 status_t
-usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
+usb_disk_operation(device_lun *lun, uint8* operation,
        uint32 logicalBlockAddress, uint16 transferLength, void *data,
        uint32 *dataLength, bool directionIn)
 {
-       TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: 
%p; dlen: %p (%lu); in: %c\n",
-               lun->logical_unit_number, operation, opLength, 
logicalBlockAddress,
+       TRACE("operation: lun: %u; op: %u; lba: %lu; tlen: %u; data: %p; dlen: 
%p (%lu); in: %c\n",
+               lun->logical_unit_number, operation[0], logicalBlockAddress,
                transferLength, data, dataLength, dataLength ? *dataLength : 0,
                directionIn ? 'y' : 'n');
 
-       disk_device *device = lun->device;
-       command_block_wrapper command;
-       command.signature = CBW_SIGNATURE;
-       command.tag = device->current_tag++;
-       command.data_transfer_length = (dataLength != NULL ? *dataLength : 0);
-       command.flags = (directionIn ? CBW_DATA_INPUT : CBW_DATA_OUTPUT);
-       command.lun = lun->logical_unit_number;
-       command.command_block_length
-               = device->is_atapi ? ATAPI_COMMAND_LENGTH : opLength;
-       memset(command.command_block, 0, sizeof(command.command_block));
+       disk_device* device = lun->device;
 
-       switch (opLength) {
-               case 6: {
-                       scsi_command_6 *commandBlock = (scsi_command_6 
*)command.command_block;
-                       commandBlock->operation = operation;
-                       commandBlock->lun = lun->logical_unit_number << 5;
-                       commandBlock->allocation_length = (uint8)transferLength;
-                       if (operation == SCSI_MODE_SENSE_6) {
-                               // we hijack the lba argument to transport the 
desired page
-                               commandBlock->reserved[1] = 
(uint8)logicalBlockAddress;
-                       }
-                       break;
-               }
+       // Step 1 : send the SCSI operation as a class specific request
+       size_t actualLength = 0;
+       status_t result = gUSBModule->send_request(device->device,
+               USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, 0, 0,
+               device->interface, 12, operation, &actualLength);
 
-               case 10: {
-                       scsi_command_10 *commandBlock = (scsi_command_10 
*)command.command_block;
-                       commandBlock->operation = operation;
-                       commandBlock->lun_flags = lun->logical_unit_number << 5;
-                       commandBlock->logical_block_address = 
htonl(logicalBlockAddress);
-                       commandBlock->transfer_length = htons(transferLength);
-                       break;
-               }
-
-               default:
-                       TRACE_ALWAYS("unsupported operation length %d\n", 
opLength);
-                       return B_BAD_VALUE;
-       }
-
-       status_t result = usb_disk_transfer_data(device, false, &command,
-               sizeof(command_block_wrapper));
-       if (result != B_OK)
-               return result;
-
-       if (device->status != B_OK ||
-               device->actual_length != sizeof(command_block_wrapper)) {
-               // sending the command block wrapper failed
-               TRACE_ALWAYS("sending the command block wrapper failed\n");
-               usb_disk_reset_recovery(device);
+       if (result != B_OK || actualLength != 12) {
+               TRACE("Command stage: wrote %ld bytes (%s) (interface = %d)\n", 
actualLength, strerror(result),
+                       device->interface);
                return B_ERROR;
        }
 
+       // Step 2 : data phase : send or receive data
        size_t transferedData = 0;
        if (data != NULL && dataLength != NULL && *dataLength > 0) {
                // we have data to transfer in a data stage
@@ -339,6 +289,7 @@
                }
        }
 
+       // step 3 : wait for the device to send the interrupt ACK
        command_status_wrapper status;
        result =  usb_disk_receive_csw(device, &status);
        if (result != B_OK) {
@@ -348,58 +299,14 @@
        }
 
        if (result != B_OK) {
-               TRACE_ALWAYS("receiving the command status wrapper failed\n");
+               TRACE_ALWAYS("receiving the command status interrupt failed\n");
                usb_disk_reset_recovery(device);
                return result;
        }
 
-       if (status.signature != CSW_SIGNATURE || status.tag != command.tag) {
-               // the command status wrapper is not valid
-               TRACE_ALWAYS("command status wrapper is not valid\n");
-               usb_disk_reset_recovery(device);
-               return B_ERROR;
-       }
-
        switch (status.status) {
-               case CSW_STATUS_COMMAND_PASSED:
-               case CSW_STATUS_COMMAND_FAILED: {
-                       if (status.data_residue > command.data_transfer_length) 
{
-                               // command status wrapper is not meaningful
-                               TRACE_ALWAYS("command status wrapper has 
invalid residue\n");
-                               usb_disk_reset_recovery(device);
-                               return B_ERROR;
-                       }
-
-                       if (dataLength != NULL) {
-                               *dataLength -= status.data_residue;
-                               if (transferedData < *dataLength) {
-                                       TRACE_ALWAYS("less data transfered than 
indicated\n");
-                                       *dataLength = transferedData;
-                               }
-                       }
-
-                       if (status.status == CSW_STATUS_COMMAND_PASSED) {
-                               // the operation is complete and has succeeded
-                               return B_OK;
-                       } else {
-                               // the operation is complete but has failed at 
the SCSI level
-                               if (operation != SCSI_TEST_UNIT_READY_6) {
-                                       TRACE_ALWAYS("operation 0x%02x failed 
at the SCSI level\n",
-                                               operation);
-                               }
-
-                               result = usb_disk_request_sense(lun);
-                               return result == B_OK ? B_ERROR : result;
-                       }
-               }
-
-               case CSW_STATUS_PHASE_ERROR: {
-                       // a protocol or device error occured
-                       TRACE_ALWAYS("phase error in operation 0x%02x\n", 
operation);
-                       usb_disk_reset_recovery(device);
-                       return B_ERROR;
-               }
-
+               case 0:
+                       return B_OK;
                default: {
                        // command status wrapper is not meaningful
                        TRACE_ALWAYS("command status wrapper has invalid 
status\n");
@@ -419,8 +326,16 @@
 usb_disk_request_sense(device_lun *lun)
 {
        uint32 dataLength = sizeof(scsi_request_sense_6_parameter);
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_REQUEST_SENSE_6;
+       commandBlock[1] = lun->logical_unit_number << 5;
+       commandBlock[2] = 0; // page code
+       commandBlock[4] = dataLength;
+
        scsi_request_sense_6_parameter parameter;
-       status_t result = usb_disk_operation(lun, SCSI_REQUEST_SENSE_6, 6, 0,
+       status_t result = usb_disk_operation(lun, commandBlock, 0,
                dataLength, &parameter, &dataLength, true);
        if (result != B_OK) {
                TRACE_ALWAYS("getting request sense data failed\n");
@@ -482,8 +397,18 @@
 usb_disk_mode_sense(device_lun *lun)
 {
        uint32 dataLength = sizeof(scsi_mode_sense_6_parameter);
+
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_MODE_SENSE_6;
+       commandBlock[1] = lun->logical_unit_number << 5;
+       commandBlock[2] = 0; // Current values
+       commandBlock[7] = dataLength >> 8;
+       commandBlock[8] = dataLength;
+
        scsi_mode_sense_6_parameter parameter;
-       status_t result = usb_disk_operation(lun, SCSI_MODE_SENSE_6, 6,
+       status_t result = usb_disk_operation(lun, commandBlock,
                SCSI_MODE_PAGE_DEVICE_CONFIGURATION, dataLength, &parameter,
                &dataLength, true);
        if (result != B_OK) {
@@ -505,14 +430,15 @@
        if (!lun->device->tur_supported)
                return B_OK;
 
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_INQUIRY_6;
+       commandBlock[1] = lun->logical_unit_number << 5;
+
        status_t result;
-       if (lun->device->is_atapi) {
-               result = usb_disk_operation(lun, SCSI_START_STOP_UNIT_6, 6, 0, 
1,
-                       NULL, NULL, false);
-       } else {
-               result = usb_disk_operation(lun, SCSI_TEST_UNIT_READY_6, 6, 0, 
0,
-                       NULL, NULL, true);
-       }
+       result = usb_disk_operation(lun, commandBlock, 0, 0,
+               NULL, NULL, true);
 
        if (result == B_DEV_INVALID_IOCTL) {
                lun->device->tur_supported = false;
@@ -527,10 +453,19 @@
 usb_disk_inquiry(device_lun *lun)
 {
        uint32 dataLength = sizeof(scsi_inquiry_6_parameter);
+
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_INQUIRY_6;
+       commandBlock[1] = lun->logical_unit_number << 5;
+       commandBlock[2] = 0; // page code
+       commandBlock[4] = dataLength;
+
        scsi_inquiry_6_parameter parameter;
        status_t result = B_ERROR;
        for (uint32 tries = 0; tries < 3; tries++) {
-               result = usb_disk_operation(lun, SCSI_INQUIRY_6, 6, 0, 
dataLength,
+               result = usb_disk_operation(lun, commandBlock, 0, dataLength,
                        &parameter, &dataLength, true);
                if (result == B_OK)
                        break;
@@ -572,13 +507,19 @@
        scsi_read_capacity_10_parameter parameter;
        status_t result = B_ERROR;
 
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_READ_CAPACITY_10;
+       commandBlock[1] = lun->logical_unit_number << 5;
+
        // Retry reading the capacity up to three times. The first try might 
only
        // yield a unit attention telling us that the device or media status
        // changed, which is more or less expected if it is the first operation
        // on the device or the device only clears the unit atention for 
capacity
        // reads.
        for (int32 i = 0; i < 3; i++) {
-               result = usb_disk_operation(lun, SCSI_READ_CAPACITY_10, 10, 0, 
0,
+               result = usb_disk_operation(lun, commandBlock, 0, 0,
                        &parameter, &dataLength, true);
                if (result == B_OK)
                        break;
@@ -603,30 +544,7 @@
 status_t
 usb_disk_synchronize(device_lun *lun, bool force)
 {
-       if (lun->device->sync_support == 0) {
-               // this device reported an illegal request when syncing or 
repeatedly
-               // returned an other error, it apparently does not support 
syncing...
-               return B_UNSUPPORTED;
-       }
-
-       if (!lun->should_sync && !force)
-               return B_OK;
-
-       status_t result = usb_disk_operation(lun, SCSI_SYNCHRONIZE_CACHE_10, 10,
-               0, 0, NULL, NULL, false);
-
-       if (result == B_OK) {
-               lun->device->sync_support = SYNC_SUPPORT_RELOAD;
-               lun->should_sync = false;
-               return B_OK;
-       }
-
-       if (result == B_DEV_INVALID_IOCTL)
-               lun->device->sync_support = 0;
-       else
-               lun->device->sync_support--;
-
-       return result;
+       return B_UNSUPPORTED;
 }
 
 
@@ -662,8 +580,9 @@
        device->is_atapi = false;
        device->luns = NULL;
 
-       // scan through the interfaces to find our bulk-only data interface
-       const usb_configuration_info *configuration = 
gUSBModule->get_configuration(newDevice);
+       // scan through the interfaces to find our data interface
+       const usb_configuration_info *configuration
+               = gUSBModule->get_configuration(newDevice);
        if (configuration == NULL) {
                free(device);
                return B_ERROR;
@@ -675,35 +594,45 @@
                        continue;
 
                if (interface->descr->interface_class == 0x08 /* mass storage */
-                       && (interface->descr->interface_subclass == 0x06 /* 
SCSI */
-                               || interface->descr->interface_subclass == 0x02 
/* ATAPI */
-                               || interface->descr->interface_subclass == 0x05 
/* ATAPI */)
-                       && interface->descr->interface_protocol == 0x50 /* 
bulk-only */) {
+                       || interface->descr->interface_subclass == 0x04 /* UFI 
(floppy) */
+                       && interface->descr->interface_protocol == 0x00) {
 
                        bool hasIn = false;
                        bool hasOut = false;
+                       bool hasInt = false;
                        for (size_t j = 0; j < interface->endpoint_count; j++) {
                                usb_endpoint_info *endpoint = 
&interface->endpoint[j];
-                               if (endpoint == NULL
-                                       || endpoint->descr->attributes != 
USB_ENDPOINT_ATTR_BULK)
+                               if (endpoint == NULL)
                                        continue;
 
                                if (!hasIn && (endpoint->descr->endpoint_address
-                                       & USB_ENDPOINT_ADDR_DIR_IN)) {
+                                       & USB_ENDPOINT_ADDR_DIR_IN)
+                                       && endpoint->descr->attributes == 
USB_ENDPOINT_ATTR_BULK) {
                                        device->bulk_in = endpoint->handle;
                                        hasIn = true;
                                } else if (!hasOut && 
(endpoint->descr->endpoint_address
-                                       & USB_ENDPOINT_ADDR_DIR_IN) == 0) {
+                                       & USB_ENDPOINT_ADDR_DIR_IN) == 0
+                                       && endpoint->descr->attributes == 
USB_ENDPOINT_ATTR_BULK) {
                                        device->bulk_out = endpoint->handle;
                                        hasOut = true;
+                               } else if (!hasInt && 
(endpoint->descr->endpoint_address
+                                       & USB_ENDPOINT_ADDR_DIR_IN)
+                                       && endpoint->descr->attributes
+                                       == USB_ENDPOINT_ATTR_INTERRUPT) {
+                                       // TODO:ensure there is only one 
interrupt endpoint and
+                                       // stop enumerating
+                                       device->interrupt = endpoint->handle;
+                                       hasInt = true;
                                }
 
-                               if (hasIn && hasOut)
+                               if (hasIn && hasOut && hasInt)
                                        break;
                        }
 
-                       if (!(hasIn && hasOut))
+                       if (!(hasIn && hasOut && hasInt)) {
+                               TRACE("in: %d, out: %d, int: %d\n", hasIn, 
hasOut, hasInt);
                                continue;
+                       }
 
                        device->interface = interface->descr->interface_number;
                        device->is_atapi = interface->descr->interface_subclass 
!= 0x06;
@@ -712,7 +641,7 @@
        }
 
        if (device->interface == 0xff) {
-               TRACE_ALWAYS("no valid bulk-only interface found\n");
+               TRACE_ALWAYS("no valid CBI interface found\n");
                free(device);
                return B_ERROR;
        }
@@ -726,7 +655,15 @@
                return device->notify;
        }
 
-       device->lun_count = usb_disk_get_max_lun(device) + 1;
+       interruptLock = create_sem(0, "usb_disk interrupt lock");
+       if (interruptLock < B_OK) {
+               mutex_destroy(&device->lock);
+               free(device);
+               return interruptLock;
+       }
+
+       // TODO: handle more than 1 unit
+       device->lun_count = 1;
        device->luns = (device_lun **)malloc(device->lun_count
                * sizeof(device_lun *));
        for (uint8 i = 0; i < device->lun_count; i++)
@@ -863,7 +800,19 @@
 usb_disk_block_read(device_lun *lun, uint32 blockPosition, uint16 blockCount,
        void *buffer, size_t *length)
 {
-       status_t result = usb_disk_operation(lun, SCSI_READ_10, 10, 
blockPosition,
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_READ_10;
+       commandBlock[1] = lun->logical_unit_number << 5;
+       commandBlock[2] = blockPosition >> 24;
+       commandBlock[3] = blockPosition >> 16;
+       commandBlock[4] = blockPosition >> 8;
+       commandBlock[5] = blockPosition;
+       commandBlock[7] = *length >> 8;
+       commandBlock[8] = *length;
+
+       status_t result = usb_disk_operation(lun, commandBlock, blockPosition,
                blockCount, buffer, length, true);
        return result;
 }
@@ -873,7 +822,19 @@
 usb_disk_block_write(device_lun *lun, uint32 blockPosition, uint16 blockCount,
        void *buffer, size_t *length)
 {
-       status_t result = usb_disk_operation(lun, SCSI_WRITE_10, 10, 
blockPosition,
+       uint8 commandBlock[12];
+       memset(commandBlock, 0, sizeof(commandBlock));
+
+       commandBlock[0] = SCSI_WRITE_10;
+       commandBlock[1] = lun->logical_unit_number << 5;
+       commandBlock[2] = blockPosition >> 24;
+       commandBlock[3] = blockPosition >> 16;
+       commandBlock[4] = blockPosition >> 8;
+       commandBlock[5] = blockPosition;
+       commandBlock[7] = *length >> 8;
+       commandBlock[8] = *length;
+
+       status_t result = usb_disk_operation(lun, commandBlock, blockPosition,
                blockCount, buffer, length, false);
        if (result == B_OK)
                lun->should_sync = true;
@@ -1047,14 +1008,32 @@
                        break;
 
                case B_EJECT_DEVICE:
-                       result = usb_disk_operation(lun, 
SCSI_START_STOP_UNIT_6, 6, 0, 2,
+               {
+                       uint8 commandBlock[12];
+                       memset(commandBlock, 0, sizeof(commandBlock));
+
+                       commandBlock[0] = SCSI_START_STOP_UNIT_6;
+                       commandBlock[1] = lun->logical_unit_number << 5;
+                       commandBlock[4] = 2;
+
+                       result = usb_disk_operation(lun, commandBlock, 0, 2,
                                NULL, NULL, false);
                        break;
+               }
 
                case B_LOAD_MEDIA:
-                       result = usb_disk_operation(lun, 
SCSI_START_STOP_UNIT_6, 6, 0, 3,
+               {
+                       uint8 commandBlock[12];
+                       memset(commandBlock, 0, sizeof(commandBlock));
+
+                       commandBlock[0] = SCSI_START_STOP_UNIT_6;
+                       commandBlock[1] = lun->logical_unit_number << 5;
+                       commandBlock[4] = 3;
+
+                       result = usb_disk_operation(lun, commandBlock, 0, 3,
                                NULL, NULL, false);
                        break;
+               }
 
 #if HAIKU_TARGET_PLATFORM_HAIKU
                case B_GET_ICON:
@@ -1225,9 +1204,7 @@
        };
 
        static usb_support_descriptor supportedDevices[] = {
-               { 0x08 /* mass storage */, 0x06 /* SCSI */, 0x50 /* bulk */, 0, 
0 },
-               { 0x08 /* mass storage */, 0x02 /* ATAPI */, 0x50 /* bulk */, 
0, 0 },
-               { 0x08 /* mass storage */, 0x05 /* ATAPI */, 0x50 /* bulk */, 
0, 0 }
+               { 0x08 /* mass storage */, 0x04 /* UFI */, 0x00, 0, 0 }
        };
 
        gDeviceList = NULL;

Modified: haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.h 
2010-08-26 11:52:11 UTC (rev 38366)
+++ haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk.h       
2010-08-26 20:28:54 UTC (rev 38379)
@@ -42,6 +42,7 @@
        // device state
        usb_pipe        bulk_in;
        usb_pipe        bulk_out;
+       usb_pipe        interrupt;
        uint8           interface;
        uint32          current_tag;
        uint8           sync_support;
@@ -89,10 +90,8 @@
 
 
 typedef struct command_status_wrapper_s {
-       uint32          signature;
-       uint32          tag;
-       uint32          data_residue;
        uint8           status;
+       uint8           misc;
 } _PACKED command_status_wrapper;
 
 #endif // _USB_DISK_H_

Modified: 
haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk_scsi.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk_scsi.h    
2010-08-26 11:52:11 UTC (rev 38366)
+++ haiku/trunk/src/add-ons/kernel/drivers/disk/usb/usb_floppy/usb_disk_scsi.h  
2010-08-26 20:28:54 UTC (rev 38379)
@@ -21,24 +21,6 @@
        SCSI_SYNCHRONIZE_CACHE_10 = 0x35,
 } scsi_operations;
 
-// common command structures
-typedef struct scsi_command_6_s {
-       uint8   operation;
-       uint8   lun;
-       uint8   reserved[2];
-       uint8   allocation_length;
-       uint8   control;
-} _PACKED scsi_command_6;
-
-typedef struct scsi_command_10_s {
-       uint8   operation;
-       uint8   lun_flags;
-       uint32  logical_block_address;
-       uint8   additional_data;
-       uint16  transfer_length;
-       uint8   control;
-} _PACKED scsi_command_10;
-
 // parameters = returned data
 typedef struct scsi_request_sense_6_parameter_s {
        uint8   error_code : 7;


Other related posts: