usb_disk: Transition to "new" driver API.
Change-Id: Ia46cb6ddc9f83917a8f797149508d35b770e44f1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6473 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
7c18d58f2b
commit
b256fa4adf
@ -59,7 +59,7 @@ if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
|
|||||||
|
|
||||||
# drivers
|
# drivers
|
||||||
AddNewDriversToPackage : wmi@x86,x86_64 ;
|
AddNewDriversToPackage : wmi@x86,x86_64 ;
|
||||||
AddNewDriversToPackage disk : nvme_disk ;
|
AddNewDriversToPackage disk : nvme_disk usb_disk ;
|
||||||
AddNewDriversToPackage disk mmc : mmc_disk ;
|
AddNewDriversToPackage disk mmc : mmc_disk ;
|
||||||
AddNewDriversToPackage disk scsi : scsi_cd scsi_disk ;
|
AddNewDriversToPackage disk scsi : scsi_cd scsi_disk ;
|
||||||
AddNewDriversToPackage disk virtual : virtio_block ram_disk ;
|
AddNewDriversToPackage disk virtual : virtio_block ram_disk ;
|
||||||
@ -76,7 +76,6 @@ AddDriversToPackage audio old : $(SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD) ;
|
|||||||
AddDriversToPackage bluetooth h2 : $(SYSTEM_ADD_ONS_DRIVERS_BT_H2) ;
|
AddDriversToPackage bluetooth h2 : $(SYSTEM_ADD_ONS_DRIVERS_BT_H2) ;
|
||||||
AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
|
AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
|
||||||
AddDriversToPackage bus : usb_raw ;
|
AddDriversToPackage bus : usb_raw ;
|
||||||
AddDriversToPackage disk usb : usb_disk ;
|
|
||||||
AddDriversToPackage disk virtual : nbd ;
|
AddDriversToPackage disk virtual : nbd ;
|
||||||
AddDriversToPackage dvb : cx23882 ;
|
AddDriversToPackage dvb : cx23882 ;
|
||||||
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
|
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
|
||||||
|
@ -48,7 +48,6 @@ AddDriversToPackage audio hmulti : $(SYSTEM_ADD_ONS_DRIVERS_AUDIO) ;
|
|||||||
AddDriversToPackage audio old : $(SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD) ;
|
AddDriversToPackage audio old : $(SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD) ;
|
||||||
AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
|
AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
|
||||||
AddDriversToPackage bus : usb_raw ;
|
AddDriversToPackage bus : usb_raw ;
|
||||||
AddDriversToPackage disk usb : usb_disk ;
|
|
||||||
AddDriversToPackage disk virtual : nbd ;
|
AddDriversToPackage disk virtual : nbd ;
|
||||||
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
|
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
|
||||||
AddDriversToPackage input : ps2_hid usb_hid wacom ;
|
AddDriversToPackage input : ps2_hid usb_hid wacom ;
|
||||||
@ -151,7 +150,7 @@ AddBootModuleSymlinksToPackage
|
|||||||
highpoint_ide_pci
|
highpoint_ide_pci
|
||||||
ide_isa@x86
|
ide_isa@x86
|
||||||
<usb>uhci <usb>ohci <usb>ehci
|
<usb>uhci <usb>ohci <usb>ehci
|
||||||
scsi_cd scsi_disk usb_disk
|
scsi_cd scsi_disk
|
||||||
virtio virtio_pci virtio_block virtio_scsi
|
virtio virtio_pci virtio_block virtio_scsi
|
||||||
efi_gpt
|
efi_gpt
|
||||||
intel
|
intel
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
|
#include <bus/USB.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -25,6 +26,10 @@
|
|||||||
#include "usb_disk_scsi.h"
|
#include "usb_disk_scsi.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define USB_DISK_DEVICE_MODULE_NAME "drivers/disk/usb_disk/device_v1"
|
||||||
|
#define USB_DISK_DRIVER_MODULE_NAME "drivers/disk/usb_disk/driver_v1"
|
||||||
|
#define USB_DISK_DEVICE_ID_GENERATOR "usb_disk/device_id"
|
||||||
|
|
||||||
#define DRIVER_NAME "usb_disk"
|
#define DRIVER_NAME "usb_disk"
|
||||||
#define DEVICE_NAME_BASE "disk/usb/"
|
#define DEVICE_NAME_BASE "disk/usb/"
|
||||||
#define DEVICE_NAME DEVICE_NAME_BASE "%" B_PRIu32 "/%d/raw"
|
#define DEVICE_NAME DEVICE_NAME_BASE "%" B_PRIu32 "/%d/raw"
|
||||||
@ -34,19 +39,16 @@
|
|||||||
#ifdef TRACE_USB_DISK
|
#ifdef TRACE_USB_DISK
|
||||||
#define TRACE(x...) dprintf(DRIVER_NAME ": " x)
|
#define TRACE(x...) dprintf(DRIVER_NAME ": " x)
|
||||||
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
|
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
|
||||||
|
#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
|
||||||
#else
|
#else
|
||||||
#define TRACE(x...) /* nothing */
|
#define TRACE(x...) /* nothing */
|
||||||
|
#define CALLED()
|
||||||
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
|
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
device_manager_info *gDeviceManager;
|
||||||
static usb_module_info *gUSBModule = NULL;
|
static usb_module_info *gUSBModule = NULL;
|
||||||
static disk_device *gDeviceList = NULL;
|
|
||||||
static uint32 gDeviceCount = 0;
|
|
||||||
static uint32 gLunCount = 0;
|
|
||||||
static mutex gDeviceListLock;
|
|
||||||
static char **gDeviceNames = NULL;
|
|
||||||
|
|
||||||
static const uint8 kDeviceIcon[] = {
|
static const uint8 kDeviceIcon[] = {
|
||||||
0x6e, 0x63, 0x69, 0x66, 0x0a, 0x04, 0x01, 0x73, 0x05, 0x01, 0x02, 0x01,
|
0x6e, 0x63, 0x69, 0x66, 0x0a, 0x04, 0x01, 0x73, 0x05, 0x01, 0x02, 0x01,
|
||||||
@ -1331,10 +1333,11 @@ usb_disk_callback(void *cookie, status_t status, void *data,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
usb_disk_device_added(usb_device newDevice, void **cookie)
|
usb_disk_attach(device_node *node, usb_device newDevice, void **cookie)
|
||||||
{
|
{
|
||||||
TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice);
|
TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice);
|
||||||
disk_device *device = (disk_device *)malloc(sizeof(disk_device));
|
disk_device *device = (disk_device *)malloc(sizeof(disk_device));
|
||||||
|
device->node = node;
|
||||||
device->device = newDevice;
|
device->device = newDevice;
|
||||||
device->removed = false;
|
device->removed = false;
|
||||||
device->open_count = 0;
|
device->open_count = 0;
|
||||||
@ -1523,60 +1526,26 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&gDeviceListLock);
|
|
||||||
device->device_number = 0;
|
|
||||||
disk_device *other = gDeviceList;
|
|
||||||
while (other != NULL) {
|
|
||||||
if (other->device_number >= device->device_number)
|
|
||||||
device->device_number = other->device_number + 1;
|
|
||||||
|
|
||||||
other = (disk_device *)other->link;
|
|
||||||
}
|
|
||||||
|
|
||||||
device->link = (void *)gDeviceList;
|
|
||||||
gDeviceList = device;
|
|
||||||
gLunCount += device->lun_count;
|
|
||||||
for (uint8 i = 0; i < device->lun_count; i++)
|
|
||||||
sprintf(device->luns[i]->name, DEVICE_NAME, device->device_number, i);
|
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
|
|
||||||
TRACE("new device: 0x%p\n", device);
|
TRACE("new device: 0x%p\n", device);
|
||||||
*cookie = (void *)device;
|
*cookie = (void *)device;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static void
|
||||||
usb_disk_device_removed(void *cookie)
|
usb_disk_device_removed(void *cookie)
|
||||||
{
|
{
|
||||||
TRACE("device_removed(0x%p)\n", cookie);
|
TRACE("device_removed(0x%p)\n", cookie);
|
||||||
disk_device *device = (disk_device *)cookie;
|
disk_device *device = (disk_device *)cookie;
|
||||||
|
|
||||||
mutex_lock(&gDeviceListLock);
|
for (uint8 i = 0; i < device->lun_count; i++)
|
||||||
if (gDeviceList == device) {
|
gDeviceManager->unpublish_device(device->node, device->luns[i]->name);
|
||||||
gDeviceList = (disk_device *)device->link;
|
|
||||||
} else {
|
|
||||||
disk_device *element = gDeviceList;
|
|
||||||
while (element) {
|
|
||||||
if (element->link == device) {
|
|
||||||
element->link = device->link;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
element = (disk_device *)element->link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gLunCount -= device->lun_count;
|
|
||||||
gDeviceCount--;
|
|
||||||
|
|
||||||
device->removed = true;
|
device->removed = true;
|
||||||
gUSBModule->cancel_queued_transfers(device->bulk_in);
|
gUSBModule->cancel_queued_transfers(device->bulk_in);
|
||||||
gUSBModule->cancel_queued_transfers(device->bulk_out);
|
gUSBModule->cancel_queued_transfers(device->bulk_out);
|
||||||
if (device->open_count == 0)
|
if (device->open_count == 0)
|
||||||
usb_disk_free_device_and_luns(device);
|
usb_disk_free_device_and_luns(device);
|
||||||
|
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1770,50 +1739,57 @@ usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
usb_disk_open(const char *name, uint32 flags, void **cookie)
|
usb_disk_init_device(void* _info, void** _cookie)
|
||||||
{
|
{
|
||||||
TRACE("open(%s)\n", name);
|
CALLED();
|
||||||
if (strncmp(name, DEVICE_NAME_BASE, strlen(DEVICE_NAME_BASE)) != 0)
|
*_cookie = _info;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
usb_disk_uninit_device(void* _cookie)
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
usb_disk_open(void *deviceCookie, const char *path, int flags, void **_cookie)
|
||||||
|
{
|
||||||
|
TRACE("open(%s)\n", path);
|
||||||
|
if (strncmp(path, DEVICE_NAME_BASE, strlen(DEVICE_NAME_BASE)) != 0)
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
int32 lastPart = 0;
|
int32 lastPart = 0;
|
||||||
size_t nameLength = strlen(name);
|
size_t nameLength = strlen(path);
|
||||||
for (int32 i = nameLength - 1; i >= 0; i--) {
|
for (int32 i = nameLength - 1; i >= 0; i--) {
|
||||||
if (name[i] == '/') {
|
if (path[i] == '/') {
|
||||||
lastPart = i;
|
lastPart = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char rawName[nameLength + 4];
|
char rawName[nameLength + 4];
|
||||||
strncpy(rawName, name, lastPart + 1);
|
strncpy(rawName, path, lastPart + 1);
|
||||||
rawName[lastPart + 1] = 0;
|
rawName[lastPart + 1] = 0;
|
||||||
strcat(rawName, "raw");
|
strcat(rawName, "raw");
|
||||||
TRACE("opening raw device %s for %s\n", rawName, name);
|
|
||||||
|
|
||||||
mutex_lock(&gDeviceListLock);
|
disk_device *device = (disk_device *)deviceCookie;
|
||||||
disk_device *device = gDeviceList;
|
MutexLocker locker(device->lock);
|
||||||
while (device) {
|
|
||||||
for (uint8 i = 0; i < device->lun_count; i++) {
|
for (uint8 i = 0; i < device->lun_count; i++) {
|
||||||
device_lun *lun = device->luns[i];
|
device_lun *lun = device->luns[i];
|
||||||
if (strncmp(rawName, lun->name, 32) == 0) {
|
if (strncmp(rawName, lun->name, 32) == 0) {
|
||||||
// found the matching device/lun
|
// found the matching device/lun
|
||||||
if (device->removed) {
|
if (device->removed)
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
device->open_count++;
|
device->open_count++;
|
||||||
*cookie = lun;
|
*_cookie = lun;
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device = (disk_device *)device->link;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1838,10 +1814,11 @@ static status_t
|
|||||||
usb_disk_free(void *cookie)
|
usb_disk_free(void *cookie)
|
||||||
{
|
{
|
||||||
TRACE("free()\n");
|
TRACE("free()\n");
|
||||||
mutex_lock(&gDeviceListLock);
|
|
||||||
|
|
||||||
device_lun *lun = (device_lun *)cookie;
|
device_lun *lun = (device_lun *)cookie;
|
||||||
disk_device *device = lun->device;
|
disk_device *device = lun->device;
|
||||||
|
MutexLocker locker(device->lock);
|
||||||
|
|
||||||
device->open_count--;
|
device->open_count--;
|
||||||
if (device->open_count == 0 && device->removed) {
|
if (device->open_count == 0 && device->removed) {
|
||||||
// we can simply free the device here as it has been removed from
|
// we can simply free the device here as it has been removed from
|
||||||
@ -1849,7 +1826,6 @@ usb_disk_free(void *cookie)
|
|||||||
usb_disk_free_device_and_luns(device);
|
usb_disk_free_device_and_luns(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2201,121 +2177,168 @@ usb_disk_write(void *cookie, off_t position, const void *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
// #pragma mark - driver module API
|
||||||
//#pragma mark - Driver Entry Points
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static float
|
||||||
init_hardware()
|
usb_disk_supports_device(device_node *parent)
|
||||||
{
|
{
|
||||||
TRACE("init_hardware()\n");
|
CALLED();
|
||||||
return B_OK;
|
const char *bus;
|
||||||
|
|
||||||
|
// make sure parent is really the usb bus manager
|
||||||
|
if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (strcmp(bus, "usb"))
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
device_attr *attr = NULL;
|
||||||
|
uint8 baseClass = 0, subclass = 0, protocol = 0;
|
||||||
|
while (gDeviceManager->get_next_attr(parent, &attr) == B_OK) {
|
||||||
|
if (attr->type != B_UINT8_TYPE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(attr->name, USB_DEVICE_CLASS))
|
||||||
|
baseClass = attr->value.ui8;
|
||||||
|
if (!strcmp(attr->name, USB_DEVICE_SUBCLASS))
|
||||||
|
subclass = attr->value.ui8;
|
||||||
|
if (!strcmp(attr->name, USB_DEVICE_PROTOCOL))
|
||||||
|
protocol = attr->value.ui8;
|
||||||
|
|
||||||
|
if (baseClass != 0 && subclass != 0 && protocol != 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
init_driver()
|
|
||||||
{
|
|
||||||
TRACE("init_driver()\n");
|
|
||||||
static usb_notify_hooks notifyHooks = {
|
|
||||||
&usb_disk_device_added,
|
|
||||||
&usb_disk_device_removed
|
|
||||||
};
|
|
||||||
|
|
||||||
static usb_support_descriptor supportedDevices[] = {
|
static usb_support_descriptor supportedDevices[] = {
|
||||||
{ 0x08 /* mass storage */, 0x06 /* SCSI */, 0x50 /* bulk */, 0, 0 },
|
{ 0x08 /* mass storage */, 0x06 /* SCSI */, 0x50 /* bulk */, 0, 0 },
|
||||||
{ 0x08 /* mass storage */, 0x02 /* ATAPI */, 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 */, 0x05 /* ATAPI */, 0x50 /* bulk */, 0, 0 },
|
||||||
{ 0x08 /* mass storage */, 0x04 /* UFI */, 0x00, 0, 0 }
|
{ 0x08 /* mass storage */, 0x04 /* UFI */, 0x00, 0, 0 }
|
||||||
};
|
};
|
||||||
|
for (size_t i = 0; i < B_COUNT_OF(supportedDevices); i++) {
|
||||||
|
if (baseClass != supportedDevices[i].dev_class)
|
||||||
|
continue;
|
||||||
|
if (subclass != supportedDevices[i].dev_subclass)
|
||||||
|
continue;
|
||||||
|
if (supportedDevices[i].dev_protocol != 0 && protocol != supportedDevices[i].dev_protocol)
|
||||||
|
continue;
|
||||||
|
|
||||||
gDeviceList = NULL;
|
TRACE("USB disk device found!\n");
|
||||||
gDeviceCount = 0;
|
return 0.6;
|
||||||
gLunCount = 0;
|
|
||||||
mutex_init(&gDeviceListLock, "usb_disk device list lock");
|
|
||||||
|
|
||||||
TRACE("trying module %s\n", B_USB_MODULE_NAME);
|
|
||||||
status_t result = get_module(B_USB_MODULE_NAME,
|
|
||||||
(module_info **)&gUSBModule);
|
|
||||||
if (result < B_OK) {
|
|
||||||
TRACE_ALWAYS("getting module failed: %s\n", strerror(result));
|
|
||||||
mutex_destroy(&gDeviceListLock);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gUSBModule->register_driver(DRIVER_NAME, supportedDevices, 4, NULL);
|
return 0.0;
|
||||||
gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks);
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static status_t
|
||||||
uninit_driver()
|
usb_disk_register_device(device_node *node)
|
||||||
{
|
{
|
||||||
TRACE("uninit_driver()\n");
|
CALLED();
|
||||||
gUSBModule->uninstall_notify(DRIVER_NAME);
|
|
||||||
mutex_lock(&gDeviceListLock);
|
|
||||||
|
|
||||||
if (gDeviceNames) {
|
device_attr attrs[] = {
|
||||||
for (int32 i = 0; gDeviceNames[i]; i++)
|
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "USB Disk"} },
|
||||||
free(gDeviceNames[i]);
|
{ NULL }
|
||||||
free(gDeviceNames);
|
|
||||||
gDeviceNames = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_destroy(&gDeviceListLock);
|
|
||||||
put_module(B_USB_MODULE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char **
|
|
||||||
publish_devices()
|
|
||||||
{
|
|
||||||
TRACE("publish_devices()\n");
|
|
||||||
if (gDeviceNames) {
|
|
||||||
for (int32 i = 0; gDeviceNames[i]; i++)
|
|
||||||
free(gDeviceNames[i]);
|
|
||||||
free(gDeviceNames);
|
|
||||||
gDeviceNames = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gDeviceNames = (char **)malloc(sizeof(char *) * (gLunCount + 1));
|
|
||||||
if (gDeviceNames == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int32 index = 0;
|
|
||||||
mutex_lock(&gDeviceListLock);
|
|
||||||
disk_device *device = gDeviceList;
|
|
||||||
while (device) {
|
|
||||||
for (uint8 i = 0; i < device->lun_count; i++)
|
|
||||||
gDeviceNames[index++] = strdup(device->luns[i]->name);
|
|
||||||
|
|
||||||
device = (disk_device *)device->link;
|
|
||||||
}
|
|
||||||
|
|
||||||
gDeviceNames[index++] = NULL;
|
|
||||||
mutex_unlock(&gDeviceListLock);
|
|
||||||
return (const char **)gDeviceNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
device_hooks *
|
|
||||||
find_device(const char *name)
|
|
||||||
{
|
|
||||||
TRACE("find_device()\n");
|
|
||||||
static device_hooks hooks = {
|
|
||||||
&usb_disk_open,
|
|
||||||
&usb_disk_close,
|
|
||||||
&usb_disk_free,
|
|
||||||
&usb_disk_ioctl,
|
|
||||||
&usb_disk_read,
|
|
||||||
&usb_disk_write,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return &hooks;
|
return gDeviceManager->register_node(node, USB_DISK_DRIVER_MODULE_NAME,
|
||||||
|
attrs, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
usb_disk_init_driver(device_node *node, void **cookie)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
usb_device usb_device;
|
||||||
|
if (gDeviceManager->get_attr_uint32(node, USB_DEVICE_ID_ITEM, &usb_device, true) != B_OK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return usb_disk_attach(node, usb_device, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
usb_disk_uninit_driver(void *_cookie)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
usb_disk_register_child_devices(void* _cookie)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
disk_device *device = (disk_device *)_cookie;
|
||||||
|
|
||||||
|
device->number = gDeviceManager->create_id(USB_DISK_DEVICE_ID_GENERATOR);
|
||||||
|
if (device->number < 0)
|
||||||
|
return device->number;
|
||||||
|
|
||||||
|
status_t status = B_OK;
|
||||||
|
for (uint8 i = 0; i < device->lun_count; i++) {
|
||||||
|
sprintf(device->luns[i]->name, DEVICE_NAME, device->number, i);
|
||||||
|
status = gDeviceManager->publish_device(device->node, device->luns[i]->name,
|
||||||
|
USB_DISK_DEVICE_MODULE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
module_dependency module_dependencies[] = {
|
||||||
|
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager },
|
||||||
|
{ B_USB_MODULE_NAME, (module_info**)&gUSBModule},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct device_module_info sUsbDiskDevice = {
|
||||||
|
{
|
||||||
|
USB_DISK_DEVICE_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
|
||||||
|
usb_disk_init_device,
|
||||||
|
usb_disk_uninit_device,
|
||||||
|
usb_disk_device_removed,
|
||||||
|
|
||||||
|
usb_disk_open,
|
||||||
|
usb_disk_close,
|
||||||
|
usb_disk_free,
|
||||||
|
usb_disk_read,
|
||||||
|
usb_disk_write,
|
||||||
|
NULL, // io
|
||||||
|
usb_disk_ioctl,
|
||||||
|
|
||||||
|
NULL, // select
|
||||||
|
NULL, // deselect
|
||||||
|
};
|
||||||
|
|
||||||
|
struct driver_module_info sUsbDiskDriver = {
|
||||||
|
{
|
||||||
|
USB_DISK_DRIVER_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
|
||||||
|
usb_disk_supports_device,
|
||||||
|
usb_disk_register_device,
|
||||||
|
usb_disk_init_driver,
|
||||||
|
usb_disk_uninit_driver,
|
||||||
|
usb_disk_register_child_devices,
|
||||||
|
NULL, // rescan
|
||||||
|
NULL, // removed
|
||||||
|
};
|
||||||
|
|
||||||
|
module_info* modules[] = {
|
||||||
|
(module_info*)&sUsbDiskDriver,
|
||||||
|
(module_info*)&sUsbDiskDevice,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
#include <USB3.h>
|
#include <USB3.h>
|
||||||
|
#include <device_manager.h>
|
||||||
#include <usb/USB_massbulk.h>
|
#include <usb/USB_massbulk.h>
|
||||||
|
|
||||||
|
|
||||||
@ -25,12 +26,13 @@ typedef struct device_lun_s device_lun;
|
|||||||
|
|
||||||
// holds common information about an attached device (pointed to by luns)
|
// holds common information about an attached device (pointed to by luns)
|
||||||
typedef struct disk_device_s {
|
typedef struct disk_device_s {
|
||||||
|
int32 number;
|
||||||
|
device_node *node;
|
||||||
|
|
||||||
usb_device device;
|
usb_device device;
|
||||||
uint32 device_number;
|
|
||||||
bool removed;
|
bool removed;
|
||||||
uint32 open_count;
|
uint32 open_count;
|
||||||
mutex lock;
|
mutex lock;
|
||||||
void * link;
|
|
||||||
|
|
||||||
// device state
|
// device state
|
||||||
usb_pipe bulk_in;
|
usb_pipe bulk_in;
|
||||||
|
Loading…
Reference in New Issue
Block a user