From 49df4099d1da0432db60774252d0c0413210d30a Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 6 Apr 2008 15:57:26 +0000 Subject: [PATCH] Implement a binary compatible way of setting an alternate interface through usb_raw. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24835 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/bus/usb/usb_raw.cpp | 53 ++++++++++++++++++- src/add-ons/kernel/drivers/bus/usb/usb_raw.h | 10 ++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp index b30acfbc61..e3ee5287b3 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp @@ -258,7 +258,7 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) } const usb_interface_info *interfaceInfo = - configurationInfo->interface[command->endpoint.interface_index].active; + configurationInfo->interface[command->interface.interface_index].active; if (!interfaceInfo) { command->interface.status = RAW_STATUS_ABORTED; return B_OK; @@ -270,6 +270,26 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) return B_OK; } + case RAW_COMMAND_GET_ALT_INTERFACE_COUNT: { + const usb_configuration_info *configurationInfo = + gUSBModule->get_nth_configuration(device->device, + command->alternate.config_index); + if (!configurationInfo) { + command->alternate.status = RAW_STATUS_INVALID_CONFIGURATION; + return B_OK; + } + + if (command->alternate.interface_index >= configurationInfo->interface_count) { + command->alternate.status = RAW_STATUS_INVALID_INTERFACE; + return B_OK; + } + + *command->alternate.alternate_count + = configurationInfo->interface[command->alternate.interface_index].alt_count; + command->alternate.status = RAW_STATUS_SUCCESS; + return B_OK; + } + case RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR: { const usb_configuration_info *configurationInfo = gUSBModule->get_nth_configuration(device->device, @@ -446,6 +466,37 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) return B_OK; } + case RAW_COMMAND_SET_ALT_INTERFACE: { + const usb_configuration_info *configurationInfo = + gUSBModule->get_nth_configuration(device->device, + command->alternate.config_index); + if (!configurationInfo) { + command->alternate.status = RAW_STATUS_INVALID_CONFIGURATION; + return B_OK; + } + + if (command->alternate.interface_index >= configurationInfo->interface_count) { + command->alternate.status = RAW_STATUS_INVALID_INTERFACE; + return B_OK; + } + + const usb_interface_list *interfaceList = + &configurationInfo->interface[command->alternate.interface_index]; + if (command->alternate.alternate_index >= interfaceList->alt_count) { + command->alternate.status = RAW_STATUS_INVALID_INTERFACE; + return B_OK; + } + + if (gUSBModule->set_alt_interface(device->device, + &interfaceList->alt[command->alternate.alternate_index]) < B_OK) { + command->alternate.status = RAW_STATUS_FAILED; + return B_OK; + } + + command->alternate.status = RAW_STATUS_SUCCESS; + return B_OK; + } + case RAW_COMMAND_CONTROL_TRANSFER: { benaphore_lock(&device->lock); if (gUSBModule->queue_request(device->device, diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h index 4d281e99f6..b4824ada4c 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h @@ -23,12 +23,14 @@ typedef enum { RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, RAW_COMMAND_GET_STRING_DESCRIPTOR, RAW_COMMAND_GET_GENERIC_DESCRIPTOR, + RAW_COMMAND_GET_ALT_INTERFACE_COUNT, RAW_COMMAND_SET_CONFIGURATION = 0x3000, RAW_COMMAND_SET_FEATURE, RAW_COMMAND_CLEAR_FEATURE, RAW_COMMAND_GET_STATUS, RAW_COMMAND_GET_DESCRIPTOR, + RAW_COMMAND_SET_ALT_INTERFACE, RAW_COMMAND_CONTROL_TRANSFER = 0x4000, RAW_COMMAND_INTERRUPT_TRANSFER, @@ -78,6 +80,14 @@ typedef union { uint32 interface_index; } interface; + struct { + status_t status; + uint32 *alternate_count; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + } alternate; + struct { status_t status; usb_endpoint_descriptor *descriptor;