Implement support for ATAPI command set devices. It's used by some USB CD drives
and easy to implement since ATAPI basically is SCSI anyway and we don't use many problematic commands. Only tested for the 0x05 subclass, but 0x02 should work the same. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36162 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -273,7 +273,8 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
|
|||||||
command.data_transfer_length = (dataLength != NULL ? *dataLength : 0);
|
command.data_transfer_length = (dataLength != NULL ? *dataLength : 0);
|
||||||
command.flags = (directionIn ? CBW_DATA_INPUT : CBW_DATA_OUTPUT);
|
command.flags = (directionIn ? CBW_DATA_INPUT : CBW_DATA_OUTPUT);
|
||||||
command.lun = lun->logical_unit_number;
|
command.lun = lun->logical_unit_number;
|
||||||
command.command_block_length = opLength;
|
command.command_block_length
|
||||||
|
= device->is_atapi ? ATAPI_COMMAND_LENGTH : opLength;
|
||||||
memset(command.command_block, 0, sizeof(command.command_block));
|
memset(command.command_block, 0, sizeof(command.command_block));
|
||||||
|
|
||||||
switch (opLength) {
|
switch (opLength) {
|
||||||
@@ -504,8 +505,14 @@ usb_disk_test_unit_ready(device_lun *lun)
|
|||||||
if (!lun->device->tur_supported)
|
if (!lun->device->tur_supported)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
status_t result = usb_disk_operation(lun, SCSI_TEST_UNIT_READY_6, 6, 0, 0,
|
status_t result;
|
||||||
NULL, NULL, true);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if (result == B_DEV_INVALID_IOCTL) {
|
if (result == B_DEV_INVALID_IOCTL) {
|
||||||
lun->device->tur_supported = false;
|
lun->device->tur_supported = false;
|
||||||
@@ -652,6 +659,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
|||||||
device->current_tag = 0;
|
device->current_tag = 0;
|
||||||
device->sync_support = SYNC_SUPPORT_RELOAD;
|
device->sync_support = SYNC_SUPPORT_RELOAD;
|
||||||
device->tur_supported = true;
|
device->tur_supported = true;
|
||||||
|
device->is_atapi = false;
|
||||||
device->luns = NULL;
|
device->luns = NULL;
|
||||||
|
|
||||||
// scan through the interfaces to find our bulk-only data interface
|
// scan through the interfaces to find our bulk-only data interface
|
||||||
@@ -667,7 +675,9 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (interface->descr->interface_class == 0x08 /* mass storage */
|
if (interface->descr->interface_class == 0x08 /* mass storage */
|
||||||
&& interface->descr->interface_subclass == 0x06 /* SCSI */
|
&& (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_protocol == 0x50 /* bulk-only */) {
|
||||||
|
|
||||||
bool hasIn = false;
|
bool hasIn = false;
|
||||||
@@ -696,6 +706,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
device->interface = interface->descr->interface_number;
|
device->interface = interface->descr->interface_number;
|
||||||
|
device->is_atapi = interface->descr->interface_subclass != 0x06;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -746,8 +757,11 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
|||||||
status_t ready = usb_disk_test_unit_ready(lun);
|
status_t ready = usb_disk_test_unit_ready(lun);
|
||||||
if (ready == B_OK || ready == B_DEV_NO_MEDIA) {
|
if (ready == B_OK || ready == B_DEV_NO_MEDIA) {
|
||||||
if (ready == B_OK) {
|
if (ready == B_OK) {
|
||||||
// TODO: check for write protection
|
if (lun->device_type == B_CD)
|
||||||
//if (usb_disk_mode_sense(lun) != B_OK)
|
lun->write_protected = true;
|
||||||
|
// TODO: check for write protection; disabled since
|
||||||
|
// some devices lock up when getting the mode sense
|
||||||
|
else if (/*usb_disk_mode_sense(lun) != B_OK*/true)
|
||||||
lun->write_protected = false;
|
lun->write_protected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1210,8 +1224,10 @@ init_driver()
|
|||||||
&usb_disk_device_removed
|
&usb_disk_device_removed
|
||||||
};
|
};
|
||||||
|
|
||||||
static usb_support_descriptor supportedDevices = {
|
static usb_support_descriptor supportedDevices[] = {
|
||||||
0x08 /* mass storage */, 0x06 /* SCSI */, 0x50 /* bulk only */, 0, 0
|
{ 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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
gDeviceList = NULL;
|
gDeviceList = NULL;
|
||||||
@@ -1228,7 +1244,7 @@ init_driver()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gUSBModule->register_driver(DRIVER_NAME, &supportedDevices, 1, NULL);
|
gUSBModule->register_driver(DRIVER_NAME, supportedDevices, 3, NULL);
|
||||||
gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks);
|
gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#define REQUEST_MASS_STORAGE_RESET 0xff
|
#define REQUEST_MASS_STORAGE_RESET 0xff
|
||||||
#define REQUEST_GET_MAX_LUN 0xfe
|
#define REQUEST_GET_MAX_LUN 0xfe
|
||||||
#define MAX_LOGICAL_UNIT_NUMBER 15
|
#define MAX_LOGICAL_UNIT_NUMBER 15
|
||||||
|
#define ATAPI_COMMAND_LENGTH 12
|
||||||
|
|
||||||
#define CBW_SIGNATURE 0x43425355
|
#define CBW_SIGNATURE 0x43425355
|
||||||
#define CBW_DATA_OUTPUT 0x00
|
#define CBW_DATA_OUTPUT 0x00
|
||||||
@@ -45,6 +46,7 @@ typedef struct disk_device_s {
|
|||||||
uint32 current_tag;
|
uint32 current_tag;
|
||||||
uint8 sync_support;
|
uint8 sync_support;
|
||||||
bool tur_supported;
|
bool tur_supported;
|
||||||
|
bool is_atapi;
|
||||||
|
|
||||||
// used to store callback information
|
// used to store callback information
|
||||||
sem_id notify;
|
sem_id notify;
|
||||||
|
|||||||
Reference in New Issue
Block a user