From 5b0ec61f972bca106675a66c37354e38efb8016d Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 19 Aug 2006 23:09:05 +0000 Subject: [PATCH] * Added USB API Version 3. It's put into USB3.h while the v2 API resides in USB2.h. USB.h just includes USB2.h for now. * Rewrote both headers on the way. * The usb module now exports both, the v2 and v3 module_info. * Changed the internals of the USB Stack to give out usb_ids instead of opaque handles to internal classes. * Cleaned up some more of the Stack by moving members into other classes and removing unused stuff. * Updated the usb_raw driver from v2 to v3 API. Since both usb_hid (which still uses the v2 API) and usb_raw (which now uses the v3 API) work, I'd call it a success ;-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18539 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/USB.h | 193 +-------- headers/os/drivers/USB2.h | 231 +++++++++++ headers/os/drivers/USB3.h | 235 +++++++++++ .../kernel/bus_managers/usb/BusManager.cpp | 47 ++- .../kernel/bus_managers/usb/Device.cpp | 20 +- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 14 +- .../kernel/bus_managers/usb/Interface.cpp | 3 +- src/add-ons/kernel/bus_managers/usb/Jamfile | 1 + .../kernel/bus_managers/usb/Object.cpp | 8 + src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 41 +- src/add-ons/kernel/bus_managers/usb/Stack.cpp | 64 ++- src/add-ons/kernel/bus_managers/usb/usb.cpp | 391 ++++++++++++++---- src/add-ons/kernel/bus_managers/usb/usb_p.h | 187 +++++---- .../kernel/bus_managers/usb/usbspec_p.h | 2 +- src/add-ons/kernel/busses/usb/ohci.cpp | 3 +- src/add-ons/kernel/busses/usb/uhci.cpp | 35 +- src/add-ons/kernel/busses/usb/uhci.h | 4 - src/add-ons/kernel/busses/usb/uhci_rh.cpp | 2 +- 18 files changed, 1062 insertions(+), 419 deletions(-) create mode 100644 headers/os/drivers/USB2.h create mode 100644 headers/os/drivers/USB3.h create mode 100644 src/add-ons/kernel/bus_managers/usb/Object.cpp diff --git a/headers/os/drivers/USB.h b/headers/os/drivers/USB.h index b06d386728..4c45701c10 100644 --- a/headers/os/drivers/USB.h +++ b/headers/os/drivers/USB.h @@ -1,189 +1,8 @@ /* -** USB.h - Version 2 USB Device Driver API -** -** Copyright 1999, Be Incorporated. All Rights Reserved. -** -*/ + * This file is here for compatibility reasons. + * + * You should include USB2.h or USB3.h depending on which API version you + * intend to use. + */ -#ifndef _USB_H -#define _USB_H - -#include -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct usb_module_info usb_module_info; - -/* these are opaque handles to internal stack objects */ -typedef struct usb_device usb_device; -typedef struct usb_interface usb_interface; -typedef struct usb_pipe usb_pipe; - -typedef struct usb_endpoint_info usb_endpoint_info; -typedef struct usb_interface_info usb_interface_info; -typedef struct usb_interface_list usb_interface_list; -typedef struct usb_configuration_info usb_configuration_info; - -typedef struct usb_notify_hooks { - status_t (*device_added)(const usb_device *device, void **cookie); - status_t (*device_removed)(void *cookie); -} usb_notify_hooks; - -typedef struct usb_support_descriptor { - uint8 dev_class; - uint8 dev_subclass; - uint8 dev_protocol; - uint16 vendor; - uint16 product; -} usb_support_descriptor; - -/* ie, I support any hub device: -** usb_support_descriptor hub_devs = { 9, 0, 0, 0, 0 }; -*/ - -struct usb_endpoint_info { - usb_endpoint_descriptor *descr; /* descriptor and handle */ - usb_pipe *handle; /* of this endpoint/pipe */ -}; - -struct usb_interface_info { - usb_interface_descriptor *descr; /* descriptor and handle */ - usb_interface *handle; /* of this interface */ - - size_t endpoint_count; /* count and list of endpoints */ - usb_endpoint_info *endpoint; /* in this interface */ - - size_t generic_count; /* unparsed descriptors in this */ - usb_descriptor **generic; /* interface */ -}; - -struct usb_interface_list { - size_t alt_count; /* count and list of alternate */ - usb_interface_info *alt; /* interfaces available */ - - usb_interface_info *active; /* currently active alternate */ -}; - -struct usb_configuration_info { - usb_configuration_descriptor *descr; /* descriptor of this config */ - - size_t interface_count; /* interfaces in this config */ - usb_interface_list *interface; -}; - - -typedef void (*usb_callback_func)(void *cookie, uint32 status, - void *data, uint32 actual_len); - -struct usb_module_info { - bus_manager_info binfo; - - /* inform the bus manager of our intent to support a set of devices */ - status_t (*register_driver)(const char *driver_name, - const usb_support_descriptor *descriptors, - size_t count, - const char *optional_republish_driver_name); - - /* request notification from the bus manager for add/remove of devices we - support */ - status_t (*install_notify)(const char *driver_name, - const usb_notify_hooks *hooks); - status_t (*uninstall_notify)(const char *driver_name); - - /* get the device descriptor */ - const usb_device_descriptor *(*get_device_descriptor)(const usb_device *dev); - - /* get the nth supported configuration */ - const usb_configuration_info *(*get_nth_configuration)(const usb_device *dev, uint index); - - /* get the active configuration */ - const usb_configuration_info *(*get_configuration)(const usb_device *dev); - - /* set the active configuration */ - status_t (*set_configuration)(const usb_device *dev, - const usb_configuration_info *configuration); - - status_t (*set_alt_interface)(const usb_device *dev, - const usb_interface_info *ifc); - - /* standard device requests -- convenience functions */ - /* obj may be a usb_device*, usb_pipe*, or usb_interface* */ - status_t (*set_feature)(const void *object, uint16 selector); - status_t (*clear_feature)(const void *object, uint16 selector); - status_t (*get_status)(const void *object, uint16 *status); - - status_t (*get_descriptor)(const usb_device *d, - uint8 type, uint8 index, uint16 lang, - void *data, size_t len, size_t *actual_len); - - /* generic device request function */ - status_t (*send_request)(const usb_device *d, - uint8 request_type, uint8 request, - uint16 value, uint16 index, uint16 length, - void *data, size_t data_len, size_t *actual_len); - - /* async request queueing */ - status_t (*queue_interrupt)(const usb_pipe *handle, - void *data, size_t len, - usb_callback_func notify, void *cookie); - - status_t (*queue_bulk)(const usb_pipe *handle, - void *data, size_t len, - usb_callback_func notify, void *cookie); - - status_t (*queue_isochronous)(const usb_pipe *handle, - void *data, size_t len, - rlea* rle_array, uint16 buffer_duration_ms, - usb_callback_func notify, void *cookie); - - status_t (*queue_request)(const usb_device *d, - uint8 request_type, uint8 request, - uint16 value, uint16 index, uint16 length, - void *data, size_t data_len, - usb_callback_func notify, void *cookie); - - status_t (*set_pipe_policy)(const usb_pipe *handle, uint8 max_num_queued_packets, - uint16 max_buffer_duration_ms, uint16 sample_size); - - /* cancel pending async requests to an endpoint */ - status_t (*cancel_queued_transfers)(const usb_pipe *handle); - - /* tuning, timeouts, etc */ - status_t (*usb_ioctl)(uint32 opcode, void* buf, size_t buf_size); -}; - -/* status code for usb callback functions */ -#define B_USB_STATUS_SUCCESS 0x0000 -#define B_USB_STATUS_DEVICE_CRC_ERROR 0x0002 -#define B_USB_STATUS_DEVICE_TIMEOUT 0x0004 -#define B_USB_STATUS_DEVICE_STALLED 0x0008 -#define B_USB_STATUS_IRP_CANCELLED_BY_REQUEST 0x0010 -#define B_USB_STATUS_DRIVER_INTERNAL_ERROR 0x0020 -#define B_USB_STATUS_ADAPTER_HARDWARE_ERROR 0x0040 -#define B_USB_STATUS_ISOCH_IRP_ABORTED 0x0080 - -/* result codes for usb bus manager functions */ -#define B_USBD_SUCCESS 0 -#define B_USBD_BAD_HANDLE 1 -#define B_USBD_BAD_ARGS 2 -#define B_USBD_NO_DATA 3 -#define B_USBD_DEVICE_FAILURE 4 -#define B_USBD_COMMAND_FAILED 5 -#define B_USBD_PIPE_NOT_CONFIGURED 6 -#define B_USBD_DEVICE_ERROR 7 -#define B_USBD_PIPE_ERROR 8 -#define B_USBD_NO_MEMORY 9 - -#define B_USB_MODULE_NAME "bus_managers/usb/v2" - -#ifdef __cplusplus -} -#endif - -#endif +#include diff --git a/headers/os/drivers/USB2.h b/headers/os/drivers/USB2.h new file mode 100644 index 0000000000..864c9270fb --- /dev/null +++ b/headers/os/drivers/USB2.h @@ -0,0 +1,231 @@ +/* + * Version 2 USB Device Driver API + * + * Copyright 2006, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + +#ifndef _USB_V2_H_ +#define _USB_V2_H_ + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct usb_module_info usb_module_info; + +/* these are opaque handles to internal stack objects */ +typedef struct usb_device usb_device; +typedef struct usb_interface usb_interface; +typedef struct usb_pipe usb_pipe; + +typedef struct usb_endpoint_info usb_endpoint_info; +typedef struct usb_interface_info usb_interface_info; +typedef struct usb_interface_list usb_interface_list; +typedef struct usb_configuration_info usb_configuration_info; + +typedef struct usb_notify_hooks { + status_t (*device_added)(const usb_device *device, void **cookie); + status_t (*device_removed)(void *cookie); +} usb_notify_hooks; + +typedef struct usb_support_descriptor { + uint8 dev_class; + uint8 dev_subclass; + uint8 dev_protocol; + uint16 vendor; + uint16 product; +} usb_support_descriptor; + +struct usb_endpoint_info { + usb_endpoint_descriptor *descr; /* descriptor and handle */ + usb_pipe *handle; /* of this endpoint/pipe */ +}; + +struct usb_interface_info { + usb_interface_descriptor *descr; /* descriptor and handle */ + usb_interface *handle; /* of this interface */ + + size_t endpoint_count; /* count and list of endpoints */ + usb_endpoint_info *endpoint; /* in this interface */ + + size_t generic_count; /* unparsed descriptors in */ + usb_descriptor **generic; /* this interface */ +}; + +struct usb_interface_list { + size_t alt_count; /* count and list of alternate */ + usb_interface_info *alt; /* interfaces available */ + + usb_interface_info *active; /* currently active alternate */ +}; + +struct usb_configuration_info { + usb_configuration_descriptor *descr; /* descriptor of this config */ + + size_t interface_count;/* interfaces in this config */ + usb_interface_list *interface; +}; + +typedef void (*usb_callback_func)(void *cookie, uint32 status, void *data, + uint32 actualLength); + + +/* The usb_module_info represents the public API of the USB Stack. */ +struct usb_module_info { + bus_manager_info binfo; + + /* + * Use register_driver() to inform the Stack of your interest to support + * USB devices. Support descriptors are used to indicate support for a + * specific device class/subclass/protocol or vendor/product. + * A value of 0 can be used as a wildcard for all fields. + * + * Would you like to be notified about all added hubs (class 0x09) you + * would a support descriptor like this to register_driver: + * usb_support_descriptor hub_devs = { 9, 0, 0, 0, 0 }; + * + * If you intend to support just any device, or you at least want to be + * notified about any device, just pass NULL as the supportDescriptor and + * 0 as the supportDescriptorCount to register_driver. + */ + status_t (*register_driver)(const char *driverName, + const usb_support_descriptor *supportDescriptors, + size_t supportDescriptorCount, + const char *optionalRepublishDriverName); + + /* + * Install notification hooks using your registered driverName. The + * device_added hook will be called for every device that matches the + * support descriptors you provided in register_driver. + * When first installing the hooks you will receive a notification about + * any already present matching device. If you return B_OK in this hook, + * you can use the id that is provided. If the hook indicates an error, + * the resources will be deallocated and you may not use the usb_device + * that is provided. In this case you will not receive a device_removed + * notification for the device either. + */ + status_t (*install_notify)(const char *driverName, + const usb_notify_hooks *hooks); + status_t (*uninstall_notify)(const char *driverName); + + /* Get the device descriptor of a device. */ + const usb_device_descriptor *(*get_device_descriptor)(const usb_device *device); + + /* Get the nth supported configuration of a device*/ + const usb_configuration_info *(*get_nth_configuration)(const usb_device *device, + uint index); + + /* Get the current configuration */ + const usb_configuration_info *(*get_configuration)(const usb_device *device); + + /* Set the current configuration */ + status_t (*set_configuration)(const usb_device *device, + const usb_configuration_info *configuration); + + status_t (*set_alt_interface)(const usb_device *device, + const usb_interface_info *interface); + + /* + * Standard device requests - convenience functions + * The provided object may be a usb_device, usb_pipe or usb_interface + */ + status_t (*set_feature)(const void *object, uint16 selector); + status_t (*clear_feature)(const void *object, uint16 selector); + status_t (*get_status)(const void *object, uint16 *status); + + status_t (*get_descriptor)(const usb_device *device, + uint8 descriptorType, uint8 index, + uint16 languageID, void *data, + size_t dataLength, + size_t *actualLength); + + /* Generic device request function - synchronous */ + status_t (*send_request)(const usb_device *device, + uint8 requestType, uint8 request, + uint16 value, uint16 index, + uint16 length, void *data, + size_t dataLength, + size_t *actualLength); + + /* + * Asynchronous request queueing. These functions return immediately + * and the return code only tells whether the _queuing_ of the request + * was successful or not. It doesn't indicate transfer success or error. + * + * When the transfer is finished, the provided callback function is + * called with the transfer status, a pointer to the data buffer and + * the actually transfered length as well as with the callbackCookie + * that was used when queuing the request. + */ + status_t (*queue_interrupt)(const usb_pipe *pipe, + void *data, size_t dataLength, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_bulk)(const usb_pipe *pipe, + void *data, size_t dataLength, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_isochronous)(const usb_pipe *pipe, + void *data, size_t dataLength, + rlea *rleArray, + uint16 bufferDurationMS, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_request)(const usb_device *device, + uint8 requestType, uint8 request, + uint16 value, uint16 index, + uint16 length, void *data, + size_t dataLength, + usb_callback_func callback, + void *callbackCookie); + + status_t (*set_pipe_policy)(const usb_pipe *pipe, + uint8 maxNumQueuedPackets, + uint16 maxBufferDurationMS, + uint16 sampleSize); + + /* Cancel all pending async requests in a pipe */ + status_t (*cancel_queued_transfers)(const usb_pipe *pipe); + + /* tuning, timeouts, etc */ + status_t (*usb_ioctl)(uint32 opcode, void *buffer, + size_t bufferSize); +}; + + +/* + * These status are passed to the usb_callback_func callbacks. They indicate + * the status of a completed queued transfer. Multiple of these status codes + * may be combined. For example it is possible to have: + * B_USB_STATUS_DEVICE_TIMEOUT | B_USB_STATUS_DEVICE_STALLED + * This indicates that a timeout happened and that the used pipe is now + * stalled. + */ +#define B_USB_STATUS_SUCCESS 0x0000 +#define B_USB_STATUS_DEVICE_CRC_ERROR 0x0002 +#define B_USB_STATUS_DEVICE_TIMEOUT 0x0004 +#define B_USB_STATUS_DEVICE_STALLED 0x0008 +#define B_USB_STATUS_IRP_CANCELLED_BY_REQUEST 0x0010 +#define B_USB_STATUS_DRIVER_INTERNAL_ERROR 0x0020 +#define B_USB_STATUS_ADAPTER_HARDWARE_ERROR 0x0040 +#define B_USB_STATUS_ISOCH_IRP_ABORTED 0x0080 + + +#define B_USB_MODULE_NAME "bus_managers/usb/v2" + + +#ifdef __cplusplus +} +#endif + +#endif /* !_USB_V2_H_ */ diff --git a/headers/os/drivers/USB3.h b/headers/os/drivers/USB3.h new file mode 100644 index 0000000000..9b7db95720 --- /dev/null +++ b/headers/os/drivers/USB3.h @@ -0,0 +1,235 @@ +/* + * Version 3 USB Device Driver API + * + * Copyright 2006, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + +#ifndef _USB_V3_H_ +#define _USB_V3_H_ + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct usb_module_info usb_module_info; + +typedef uint32 usb_id; +typedef usb_id usb_device; +typedef usb_id usb_interface; +typedef usb_id usb_pipe; + +typedef struct usb_endpoint_info usb_endpoint_info; +typedef struct usb_interface_info usb_interface_info; +typedef struct usb_interface_list usb_interface_list; +typedef struct usb_configuration_info usb_configuration_info; + +typedef struct usb_notify_hooks { + status_t (*device_added)(usb_device device, void **cookie); + status_t (*device_removed)(void *cookie); +} usb_notify_hooks; + +typedef struct usb_support_descriptor { + uint8 dev_class; + uint8 dev_subclass; + uint8 dev_protocol; + uint16 vendor; + uint16 product; +} usb_support_descriptor; + +struct usb_endpoint_info { + usb_endpoint_descriptor *descr; /* descriptor and handle */ + usb_pipe handle; /* of this endpoint/pipe */ +}; + +struct usb_interface_info { + usb_interface_descriptor *descr; /* descriptor and handle */ + usb_interface handle; /* of this interface */ + + size_t endpoint_count; /* count and list of endpoints */ + usb_endpoint_info *endpoint; /* in this interface */ + + size_t generic_count; /* unparsed descriptors in */ + usb_descriptor **generic; /* this interface */ +}; + +struct usb_interface_list { + size_t alt_count; /* count and list of alternate */ + usb_interface_info *alt; /* interfaces available */ + + usb_interface_info *active; /* currently active alternate */ +}; + +struct usb_configuration_info { + usb_configuration_descriptor *descr; /* descriptor of this config */ + + size_t interface_count;/* interfaces in this config */ + usb_interface_list *interface; +}; + +typedef void (*usb_callback_func)(void *cookie, uint32 status, void *data, + uint32 actualLength); + + +/* The usb_module_info represents the public API of the USB Stack. */ +struct usb_module_info { + bus_manager_info binfo; + + /* + * Use register_driver() to inform the Stack of your interest to support + * USB devices. Support descriptors are used to indicate support for a + * specific device class/subclass/protocol or vendor/product. + * A value of 0 can be used as a wildcard for all fields. + * + * Would you like to be notified about all added hubs (class 0x09) you + * would a support descriptor like this to register_driver: + * usb_support_descriptor hub_devs = { 9, 0, 0, 0, 0 }; + * + * If you intend to support just any device, or you at least want to be + * notified about any device, just pass NULL as the supportDescriptor and + * 0 as the supportDescriptorCount to register_driver. + */ + status_t (*register_driver)(const char *driverName, + const usb_support_descriptor *supportDescriptors, + size_t supportDescriptorCount, + const char *optionalRepublishDriverName); + + /* + * Install notification hooks using your registered driverName. The + * device_added hook will be called for every device that matches the + * support descriptors you provided in register_driver. + * When first installing the hooks you will receive a notification about + * any already present matching device. If you return B_OK in this hook, + * you can use the id that is provided. If the hook indicates an error, + * the resources will be deallocated and you may not use the usb_device + * that is provided. In this case you will not receive a device_removed + * notification for the device either. + */ + status_t (*install_notify)(const char *driverName, + const usb_notify_hooks *hooks); + status_t (*uninstall_notify)(const char *driverName); + + /* Get the device descriptor of a device. */ + const usb_device_descriptor *(*get_device_descriptor)(usb_device device); + + /* Get the nth supported configuration of a device*/ + const usb_configuration_info *(*get_nth_configuration)(usb_device device, + uint index); + + /* Get the current configuration */ + const usb_configuration_info *(*get_configuration)(usb_device device); + + /* Set the current configuration */ + status_t (*set_configuration)(usb_device device, + const usb_configuration_info *configuration); + + status_t (*set_alt_interface)(usb_device device, + const usb_interface_info *interface); + + /* + * Standard device requests - convenience functions + * The provided handle may be a usb_device, usb_pipe or usb_interface + */ + status_t (*set_feature)(usb_id handle, uint16 selector); + status_t (*clear_feature)(usb_id handle, uint16 selector); + status_t (*get_status)(usb_id handle, uint16 *status); + + status_t (*get_descriptor)(usb_device device, + uint8 descriptorType, uint8 index, + uint16 languageID, void *data, + size_t dataLength, + size_t *actualLength); + + /* Generic device request function - synchronous */ + status_t (*send_request)(usb_device device, + uint8 requestType, uint8 request, + uint16 value, uint16 index, + uint16 length, void *data, + size_t *actualLength); + + /* + * Asynchronous request queueing. These functions return immediately + * and the return code only tells whether the _queuing_ of the request + * was successful or not. It doesn't indicate transfer success or error. + * + * When the transfer is finished, the provided callback function is + * called with the transfer status, a pointer to the data buffer and + * the actually transfered length as well as with the callbackCookie + * that was used when queuing the request. + */ + status_t (*queue_interrupt)(usb_pipe pipe, + void *data, size_t dataLength, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_bulk)(usb_pipe pipe, + void *data, size_t dataLength, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_bulk_v)(usb_pipe pipe, + iovec *vector, size_t vectorCount, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_isochronous)(usb_pipe pipe, + void *data, size_t dataLength, + rlea *rleArray, + uint16 bufferDurationMS, + usb_callback_func callback, + void *callbackCookie); + + status_t (*queue_request)(usb_device device, + uint8 requestType, uint8 request, + uint16 value, uint16 index, + uint16 length, void *data, + usb_callback_func callback, + void *callbackCookie); + + status_t (*set_pipe_policy)(usb_pipe pipe, + uint8 maxNumQueuedPackets, + uint16 maxBufferDurationMS, + uint16 sampleSize); + + /* Cancel all pending async requests in a pipe */ + status_t (*cancel_queued_transfers)(usb_pipe pipe); + + /* tuning, timeouts, etc */ + status_t (*usb_ioctl)(uint32 opcode, void *buffer, + size_t bufferSize); +}; + + +/* + * These status are passed to the usb_callback_func callbacks. They indicate + * the status of a completed queued transfer. Multiple of these status codes + * may be combined. For example it is possible to have: + * B_USB_STATUS_DEVICE_TIMEOUT | B_USB_STATUS_DEVICE_STALLED + * This indicates that a timeout happened and that the used pipe is now + * stalled. + */ +#define B_USB_STATUS_SUCCESS 0x0000 +#define B_USB_STATUS_DEVICE_CRC_ERROR 0x0002 +#define B_USB_STATUS_DEVICE_TIMEOUT 0x0004 +#define B_USB_STATUS_DEVICE_STALLED 0x0008 +#define B_USB_STATUS_IRP_CANCELLED_BY_REQUEST 0x0010 +#define B_USB_STATUS_DRIVER_INTERNAL_ERROR 0x0020 +#define B_USB_STATUS_ADAPTER_HARDWARE_ERROR 0x0040 +#define B_USB_STATUS_ISOCH_IRP_ABORTED 0x0080 + + +#define B_USB_MODULE_NAME "bus_managers/usb/v3" + + +#ifdef __cplusplus +} +#endif + +#endif /* !_USB_V3_H_ */ diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 159afb7b18..6b6f78db0a 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -18,38 +18,40 @@ #endif -BusManager::BusManager() +BusManager::BusManager(Stack *stack) + : fInitOK(false), + fDefaultPipe(NULL), + fDefaultPipeLowSpeed(NULL), + fRootHub(NULL), + fStack(stack), + fExploreThread(-1) { - fInitOK = false; - fRootHub = NULL; - - // Set up the semaphore - fLock = create_sem(1, "bus manager lock"); - if (fLock < B_OK) + if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) { + TRACE(("usb BusManager: failed to create busmanager lock\n")); return; - - set_sem_owner(B_SYSTEM_TEAM, fLock); + } // Clear the device map for (int32 i = 0; i < 128; i++) fDeviceMap[i] = false; // Set up the default pipes - fDefaultPipe = new(std::nothrow) ControlPipe(this, 0, Pipe::NormalSpeed, 0, 8); + fDefaultPipe = new(std::nothrow) ControlPipe(this, 0, Pipe::NormalSpeed, 8); if (!fDefaultPipe) return; - fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 0, 8); + fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 8); if (!fDefaultPipeLowSpeed) return; - fExploreThread = -1; fInitOK = true; } BusManager::~BusManager() { + Lock(); + benaphore_destroy(&fLock); } @@ -63,6 +65,20 @@ BusManager::InitCheck() } +bool +BusManager::Lock() +{ + return (benaphore_lock(&fLock) == B_OK); +} + + +void +BusManager::Unlock() +{ + benaphore_unlock(&fLock); +} + + /* This is the 'main' function of the explore thread, which keeps track of the hub states. @@ -127,7 +143,7 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) // Create a temporary pipe with the new address ControlPipe pipe(this, deviceAddress, - lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, 8); + lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 8); // Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported @@ -206,7 +222,8 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) int8 BusManager::AllocateAddress() { - acquire_sem_etc(fLock, 1, B_CAN_INTERRUPT, 0); + if (!Lock()) + return -1; int8 deviceAddress = -1; for (int32 i = 1; i < 128; i++) { @@ -217,7 +234,7 @@ BusManager::AllocateAddress() } } - release_sem(fLock); + Unlock(); return deviceAddress; } diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 5cb7f432d1..1f013650e9 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -20,7 +20,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, int8 deviceAddress, bool lowSpeed) : ControlPipe(bus, deviceAddress, - lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, + lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, desc.max_packet_size_0), fDeviceDescriptor(desc), fConfigurations(NULL), @@ -155,7 +155,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, interfaceInfo->generic = NULL; Interface *interface = new(std::nothrow) Interface(this); - interfaceInfo->handle = (usb_interface *)interface; + interfaceInfo->handle = interface->USBID(); currentInterface = interfaceInfo; break; @@ -190,7 +190,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, switch (endpointDescriptor->attributes & 0x03) { case 0x00: /* Control Endpoint */ endpoint = new(std::nothrow) ControlPipe(this, - LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, + Speed(), endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->max_packet_size); break; @@ -198,7 +198,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, case 0x01: /* Isochronous Endpoint */ endpoint = new(std::nothrow) IsochronousPipe(this, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, + Speed(), endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->max_packet_size); break; @@ -206,7 +206,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, case 0x02: /* Bulk Endpoint */ endpoint = new(std::nothrow) BulkPipe(this, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, + Speed(), endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->max_packet_size); break; @@ -214,13 +214,13 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, case 0x03: /* Interrupt Endpoint */ endpoint = new(std::nothrow) InterruptPipe(this, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, + Speed(), endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->max_packet_size); break; } - endpointInfo->handle = (usb_pipe *)endpoint; + endpointInfo->handle = endpoint->USBID(); break; } @@ -358,7 +358,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors, TRACE(("USB Device ReportDevice\n")); if (supportDescriptorCount == 0 || supportDescriptors == NULL) { if (added && hooks->device_added != NULL) - hooks->device_added((const usb_device *)this, &fNotifyCookie); + hooks->device_added(USBID(), &fNotifyCookie); else if (!added && hooks->device_removed != NULL) hooks->device_removed(fNotifyCookie); return; @@ -379,7 +379,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors, || fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) { if (added && hooks->device_added != NULL) - hooks->device_added((const usb_device *)this, &fNotifyCookie); + hooks->device_added(USBID(), &fNotifyCookie); else if (!added && hooks->device_removed != NULL) hooks->device_removed(fNotifyCookie); return; @@ -398,7 +398,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors, || descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) { if (added && hooks->device_added != NULL) - hooks->device_added((const usb_device *)this, &fNotifyCookie); + hooks->device_added(USBID(), &fNotifyCookie); else if (!added && hooks->device_removed != NULL) hooks->device_removed(fNotifyCookie); return; diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 75451842c8..ceafcf4087 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -61,13 +61,13 @@ Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc, TRACE(("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable)); TRACE(("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask)); - Pipe *pipe = (Pipe *)Configuration()->interface->active->endpoint[0].handle; - if (!pipe || pipe->Type() != Pipe::Interrupt) { + Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle); + if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) { TRACE(("USB Hub: no interrupt pipe found\n")); return; } - fInterruptPipe = (InterruptPipe *)pipe; + fInterruptPipe = (InterruptPipe *)object; fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus), InterruptCallback, this); @@ -193,7 +193,7 @@ Hub::Explore() if (newDevice) { fChildren[i] = newDevice; - Manager()->GetStack()->NotifyDeviceChange(fChildren[i], true); + GetStack()->NotifyDeviceChange(fChildren[i], true); } else { // the device failed to setup correctly, disable the port // so that the device doesn't get in the way of future @@ -206,7 +206,7 @@ Hub::Explore() // Device removed... TRACE(("USB Hub Explore(): Device removed\n")); if (fChildren[i]) { - Manager()->GetStack()->NotifyDeviceChange(fChildren[i], false); + GetStack()->NotifyDeviceChange(fChildren[i], false); delete fChildren[i]; fChildren[i] = NULL; } @@ -221,7 +221,7 @@ Hub::Explore() // explore down the tree if we have hubs connected for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { - if (!fChildren[i] || !fChildren[i]->IsHub()) + if (!fChildren[i] || (fChildren[i]->Type() & USB_OBJECT_HUB) == 0) continue; ((Hub *)fChildren[i])->Explore(); @@ -280,7 +280,7 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, status_t result = Device::BuildDeviceName(string, index, bufferSize, device); if (result < B_OK) { // recursion to parent failed, we're at the root(hub) - int32 managerIndex = Manager()->GetStack()->IndexOfBusManager(Manager()); + int32 managerIndex = GetStack()->IndexOfBusManager(Manager()); *index += snprintf(string + *index, bufferSize - *index, "%d", managerIndex); } diff --git a/src/add-ons/kernel/bus_managers/usb/Interface.cpp b/src/add-ons/kernel/bus_managers/usb/Interface.cpp index 0c6571bce4..080188232c 100644 --- a/src/add-ons/kernel/bus_managers/usb/Interface.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Interface.cpp @@ -10,8 +10,7 @@ Interface::Interface(Device *device) - : ControlPipe(device, - device->LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, 8) + : ControlPipe(device, device->Speed(), 0, 8) { } diff --git a/src/add-ons/kernel/bus_managers/usb/Jamfile b/src/add-ons/kernel/bus_managers/usb/Jamfile index a47bd2f5ff..3626dc7200 100644 --- a/src/add-ons/kernel/bus_managers/usb/Jamfile +++ b/src/add-ons/kernel/bus_managers/usb/Jamfile @@ -15,6 +15,7 @@ KernelStaticLibrary libusb.a : Transfer.cpp Pipe.cpp Interface.cpp + Object.cpp : -fno-pic ; diff --git a/src/add-ons/kernel/bus_managers/usb/Object.cpp b/src/add-ons/kernel/bus_managers/usb/Object.cpp new file mode 100644 index 0000000000..7a5d57651f --- /dev/null +++ b/src/add-ons/kernel/bus_managers/usb/Object.cpp @@ -0,0 +1,8 @@ +#include "usb_p.h" + + +Object::Object(BusManager *bus) +{ + fStack = bus->GetStack(); + fUSBID = fStack->GetUSBID(this); +} diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 4c5de13b7f..a3e75c47d2 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -12,16 +12,31 @@ Pipe::Pipe(Device *device, pipeDirection direction, pipeSpeed speed, uint8 endpointAddress, uint32 maxPacketSize) - : fDevice(device), - fBus(NULL), + : Object(device->Manager()), + fDevice(device), + fDeviceAddress(device->Address()), + fBus(device->Manager()), fDirection(direction), fSpeed(speed), fEndpoint(endpointAddress), fMaxPacketSize(maxPacketSize), fDataToggle(false) { - if (fDevice) - fBus = fDevice->Manager(); +} + + +Pipe::Pipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed, + uint32 maxPacketSize) + : Object(bus), + fDevice(NULL), + fDeviceAddress(deviceAddress), + fBus(bus), + fDirection(Default), + fSpeed(speed), + fEndpoint(0), + fMaxPacketSize(maxPacketSize), + fDataToggle(true) +{ } @@ -34,7 +49,7 @@ int8 Pipe::DeviceAddress() { if (!fDevice) - return -1; + return fDeviceAddress; return fDevice->Address(); } @@ -210,21 +225,9 @@ ControlPipe::ControlPipe(Device *device, pipeSpeed speed, ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed, - uint8 endpointAddress, uint32 maxPacketSize) - : Pipe(NULL, Pipe::Default, speed, endpointAddress, maxPacketSize), - fDeviceAddress(deviceAddress) + uint32 maxPacketSize) + : Pipe(bus, deviceAddress, speed, maxPacketSize) { - fBus = bus; -} - - -int8 -ControlPipe::DeviceAddress() -{ - if (!fDevice) - return fDeviceAddress; - - return fDevice->Address(); } diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 9718ecf671..68b792d00a 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -20,7 +20,10 @@ Stack::Stack() - : fDriverList(NULL) + : fObjectIndex(1), + fObjectMaxCount(1024), + fObjectArray(NULL), + fDriverList(NULL) { TRACE(("usb stack: stack init\n")); @@ -29,6 +32,10 @@ Stack::Stack() return; } + size_t objectArraySize = fObjectMaxCount * sizeof(Object *); + fObjectArray = (Object **)malloc(objectArraySize); + memset(fObjectArray, 0, objectArraySize); + // Initialise the memory chunks: create 8, 16 and 32 byte-heaps // NOTE: This is probably the most ugly code you will see in the // whole stack. Unfortunately this is needed because of the fact @@ -185,6 +192,61 @@ Stack::Unlock() } +usb_id +Stack::GetUSBID(Object *object) +{ + if (!Lock()) + return 0; + + if (fObjectIndex >= fObjectMaxCount) { + Unlock(); + return 0; + } + + uint32 id = fObjectIndex++; + fObjectArray[id] = object; + Unlock(); + + return (usb_id)id; +} + + +void +Stack::PutUSBID(usb_id id) +{ + if (!Lock()) + return; + + if (id >= fObjectMaxCount) { + TRACE(("usb stack: tried to put invalid usb_id!\n")); + Unlock(); + return; + } + + fObjectArray[id] = NULL; + Unlock(); +} + + +Object * +Stack::GetObject(usb_id id) +{ + if (!Lock()) + return NULL; + + if (id >= fObjectMaxCount) { + TRACE(("usb stack: tried to get object with invalid id\n")); + Unlock(); + return NULL; + } + + Object *result = fObjectArray[id]; + Unlock(); + + return result; +} + + void Stack::AddBusManager(BusManager *busManager) { diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index ef2f12b471..171a684f3b 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -3,10 +3,10 @@ * Distributed under the terms of the MIT License. * * Authors: + * Michael Lotz * Niels S. Reedijk */ -#include #include #include "usb_p.h" @@ -27,6 +27,9 @@ bus_std_ops(int32 op, ...) { switch (op) { case B_MODULE_INIT: { + if (gUSBStack) + return B_OK; + #ifdef TRACE_USB set_dprintf_enabled(true); load_driver_symbols("usb"); @@ -85,65 +88,72 @@ uninstall_notify(const char *driverName) const usb_device_descriptor * -get_device_descriptor(const usb_device *device) +get_device_descriptor(usb_device device) { TRACE(("usb_module: get_device_descriptor(0x%08x)\n", device)); - if (!device) + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; - return ((const Device *)device)->DeviceDescriptor(); + return ((Device *)object)->DeviceDescriptor(); } const usb_configuration_info * -get_nth_configuration(const usb_device *device, uint index) +get_nth_configuration(usb_device device, uint index) { TRACE(("usb_module: get_nth_configuration(0x%08x, %d)\n", device, index)); - if (!device) + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; - return ((const Device *)device)->ConfigurationAt((int32)index); + return ((Device *)object)->ConfigurationAt((int32)index); } - const usb_configuration_info * -get_configuration(const usb_device *device) +get_configuration(usb_device device) { TRACE(("usb_module: get_configuration(0x%08x)\n", device)); - if (!device) + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; - return ((const Device *)device)->Configuration(); + return ((Device *)object)->Configuration(); } status_t -set_configuration(const usb_device *device, +set_configuration(usb_device device, const usb_configuration_info *configuration) { TRACE(("usb_module: set_configuration(0x%08x, 0x%08x)\n", device, configuration)); - if (!device) + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)device)->SetConfiguration(configuration); + return ((Device *)object)->SetConfiguration(configuration); } status_t -set_alt_interface(const usb_device *device, - const usb_interface_info *interface) +set_alt_interface(usb_device device, const usb_interface_info *interface) { TRACE(("usb_module: set_alt_interface(0x%08x, 0x%08x)\n", device, interface)); + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) + return B_BAD_VALUE; + return B_ERROR; } status_t -set_feature(const void *object, uint16 selector) +set_feature(usb_id handle, uint16 selector) { - TRACE(("usb_module: set_feature(0x%08x, %d)\n", object, selector)); - if (!object) + TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector)); + Object *object = gUSBStack->GetObject(handle); + if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return B_BAD_VALUE; return ((Pipe *)object)->SetFeature(selector); @@ -151,10 +161,11 @@ set_feature(const void *object, uint16 selector) status_t -clear_feature(const void *object, uint16 selector) +clear_feature(usb_id handle, uint16 selector) { - TRACE(("usb_module: clear_feature(0x%08x, %d)\n", object, selector)); - if (!object) + TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector)); + Object *object = gUSBStack->GetObject(handle); + if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return B_BAD_VALUE; return ((Pipe *)object)->ClearFeature(selector); @@ -162,10 +173,14 @@ clear_feature(const void *object, uint16 selector) status_t -get_status(const void *object, uint16 *status) +get_status(usb_id handle, uint16 *status) { - TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", object, status)); - if (!object || !status) + TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", handle, status)); + if (!status) + return B_BAD_VALUE; + + Object *object = gUSBStack->GetObject(handle); + if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return B_BAD_VALUE; return ((Pipe *)object)->GetStatus(status); @@ -173,100 +188,126 @@ get_status(const void *object, uint16 *status) status_t -get_descriptor(const usb_device *device, uint8 type, uint8 index, - uint16 languageID, void *data, size_t dataLength, size_t *actualLength) +get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, + void *data, size_t dataLength, size_t *actualLength) { TRACE(("usb_module: get_descriptor(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%08x, %d, 0x%08x)\n", device, type, index, languageID, data, dataLength, actualLength)); - if (!device || !data) + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)device)->GetDescriptor(type, index, languageID, + return ((Device *)object)->GetDescriptor(type, index, languageID, data, dataLength, actualLength); } status_t -send_request(const usb_device *device, uint8 requestType, uint8 request, - uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, - size_t *actualLength) +send_request(usb_device device, uint8 requestType, uint8 request, + uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) { - TRACE(("usb_module: send_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, %d, 0x%08x)\n", device, requestType, request, value, index, length, data, dataLength, actualLength)); - if (!device) + TRACE(("usb_module: send_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, actualLength)); + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)device)->SendRequest(requestType, request, value, index, - length, data, dataLength, actualLength); + return ((Device *)object)->SendRequest(requestType, request, value, index, + length, data, length, actualLength); } status_t -queue_request(const usb_device *device, uint8 requestType, uint8 request, - uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, +queue_request(usb_device device, uint8 requestType, uint8 request, + uint16 value, uint16 index, uint16 length, void *data, usb_callback_func callback, void *callbackCookie) { - TRACE(("usb_module: queue_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, %d, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, dataLength, callback, callbackCookie)); - if (!device) + TRACE(("usb_module: queue_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, callback, callbackCookie)); + Object *object = gUSBStack->GetObject(device); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)device)->QueueRequest(requestType, request, value, index, - length, data, dataLength, callback, callbackCookie); + return ((Device *)object)->QueueRequest(requestType, request, value, index, + length, data, length, callback, callbackCookie); } status_t -queue_interrupt(const usb_pipe *pipe, void *data, size_t dataLength, +queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { TRACE(("usb_module: queue_interrupt(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie)); - if (((Pipe *)pipe)->Type() != Pipe::Interrupt) + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) return B_BAD_VALUE; - return ((InterruptPipe *)pipe)->QueueInterrupt(data, dataLength, callback, + return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, callbackCookie); } status_t -queue_bulk(const usb_pipe *pipe, void *data, size_t dataLength, +queue_bulk(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie)); - if (((Pipe *)pipe)->Type() != Pipe::Bulk) + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) return B_BAD_VALUE; - return ((BulkPipe *)pipe)->QueueBulk(data, dataLength, callback, + return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, callbackCookie); } status_t -queue_isochronous(const usb_pipe *pipe, void *data, size_t dataLength, - rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, - void *callbackCookie) +queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, + usb_callback_func callback, void *callbackCookie) { - TRACE(("usb_module: queue_isochronous(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, rleArray, bufferDurationMS, callback, callbackCookie)); - if (((Pipe *)pipe)->Type() != Pipe::Isochronous) + TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, vector, vectorCount, callback, callbackCookie)); + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) return B_BAD_VALUE; - return ((IsochronousPipe *)pipe)->QueueIsochronous(data, dataLength, - rleArray, bufferDurationMS, callback, callbackCookie); -} - - -status_t -set_pipe_policy(const usb_pipe *pipe, uint8 maxQueuedPackets, - uint16 maxBufferDurationMS, uint16 sampleSize) -{ - TRACE(("usb_module: set_pipe_policy(0x%08x, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize)); return B_ERROR; } status_t -cancel_queued_transfers(const usb_pipe *pipe) +queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, + rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, + void *callbackCookie) +{ + TRACE(("usb_module: queue_isochronous(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, rleArray, bufferDurationMS, callback, callbackCookie)); + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) + return B_BAD_VALUE; + + return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, + rleArray, bufferDurationMS, callback, callbackCookie); +} + + +status_t +set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, + uint16 maxBufferDurationMS, uint16 sampleSize) +{ + TRACE(("usb_module: set_pipe_policy(0x%08x, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize)); + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) + return B_BAD_VALUE; + + return B_ERROR; +} + + +status_t +cancel_queued_transfers(usb_pipe pipe) { TRACE(("usb_module: cancel_queued_transfers(0x%08x)\n", pipe)); - return ((Pipe *)pipe)->CancelQueuedTransfers(); + Object *object = gUSBStack->GetObject(pipe); + if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) + return B_BAD_VALUE; + + return ((Pipe *)object)->CancelQueuedTransfers(); } @@ -277,9 +318,13 @@ usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) switch (opcode) { case 'DNAM': { + Object *object = gUSBStack->GetObject(*(usb_id *)buffer); + if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) + return B_BAD_VALUE; + uint32 index = 0; - Device *device = *(Device **)buffer; - return device->BuildDeviceName((char *)buffer, &index, bufferSize, NULL); + return ((Device *)object)->BuildDeviceName((char *)buffer, &index, + bufferSize, NULL); } } @@ -288,13 +333,13 @@ usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) /* - This module exports the USB API + This module exports the USB API v3 */ -struct usb_module_info gModuleInfo = { +struct usb_module_info gModuleInfoV3 = { // First the bus_manager_info: { { - B_USB_MODULE_NAME, + "bus_managers/usb/v3", B_KEEP_LOADED, // Keep loaded, even if no driver requires it bus_std_ops }, @@ -316,6 +361,7 @@ struct usb_module_info gModuleInfo = { send_request, // send_request queue_interrupt, // queue_interrupt queue_bulk, // queue_bulk + queue_bulk_v, // queue_bulk_v queue_isochronous, // queue_isochronous queue_request, // queue_request set_pipe_policy, // set_pipe_policy @@ -324,7 +370,210 @@ struct usb_module_info gModuleInfo = { }; +// +// #pragma mark - +// + + +const usb_device_descriptor * +get_device_descriptor_v2(const void *device) +{ + return get_device_descriptor((usb_id)device); +} + + +const usb_configuration_info * +get_nth_configuration_v2(const void *device, uint index) +{ + return get_nth_configuration((usb_id)device, index); +} + + +const usb_configuration_info * +get_configuration_v2(const void *device) +{ + return get_configuration((usb_id)device); +} + + +status_t +set_configuration_v2(const void *device, + const usb_configuration_info *configuration) +{ + return set_configuration((usb_id)device, configuration); +} + + +status_t +set_alt_interface_v2(const void *device, const usb_interface_info *interface) +{ + return set_alt_interface((usb_id)device, interface); +} + + +status_t +set_feature_v2(const void *object, uint16 selector) +{ + return set_feature((usb_id)object, selector); +} + + +status_t +clear_feature_v2(const void *object, uint16 selector) +{ + return clear_feature((usb_id)object, selector); +} + + +status_t +get_status_v2(const void *object, uint16 *status) +{ + return get_status((usb_id)object, status); +} + + +status_t +get_descriptor_v2(const void *device, uint8 type, uint8 index, + uint16 languageID, void *data, size_t dataLength, size_t *actualLength) +{ + return get_descriptor((usb_id)device, type, index, languageID, data, + dataLength, actualLength); +} + + +status_t +send_request_v2(const void *device, uint8 requestType, uint8 request, + uint16 value, uint16 index, uint16 length, void *data, + size_t /*dataLength*/, size_t *actualLength) +{ + return send_request((usb_id)device, requestType, request, value, index, + length, data, actualLength); +} + + +status_t +queue_request_v2(const void *device, uint8 requestType, uint8 request, + uint16 value, uint16 index, uint16 length, void *data, + size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) +{ + return queue_request((usb_id)device, requestType, request, value, index, + length, data, callback, callbackCookie); +} + + +status_t +queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, + usb_callback_func callback, void *callbackCookie) +{ + return queue_interrupt((usb_id)pipe, data, dataLength, callback, + callbackCookie); +} + + +status_t +queue_bulk_v2(const void *pipe, void *data, size_t dataLength, + usb_callback_func callback, void *callbackCookie) +{ + return queue_bulk((usb_id)pipe, data, dataLength, callback, + callbackCookie); +} + + +status_t +queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, + rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, + void *callbackCookie) +{ + return queue_isochronous((usb_id)pipe, data, dataLength, rleArray, + bufferDurationMS, callback, callbackCookie); +} + + +status_t +set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, + uint16 maxBufferDurationMS, uint16 sampleSize) +{ + return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS, + sampleSize); +} + + +status_t +cancel_queued_transfers_v2(const void *pipe) +{ + return cancel_queued_transfers((usb_id)pipe); +} + + +struct usb_module_info_v2 { + bus_manager_info binfo; + status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); + status_t (*install_notify)(const char *, const usb_notify_hooks *); + status_t (*uninstall_notify)(const char *); + const usb_device_descriptor *(*get_device_descriptor)(const void *); + const usb_configuration_info *(*get_nth_configuration)(const void *, uint); + const usb_configuration_info *(*get_configuration)(const void *); + status_t (*set_configuration)(const void *, const usb_configuration_info *); + status_t (*set_alt_interface)(const void *, const usb_interface_info *); + status_t (*set_feature)(const void *, uint16); + status_t (*clear_feature)(const void *, uint16); + status_t (*get_status)(const void *, uint16 *); + status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); + status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); + status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); + status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); + status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); + status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); + status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); + status_t (*cancel_queued_transfers)(const void *); + status_t (*usb_ioctl)(uint32 opcode, void *,size_t); +}; + + +/* + This module exports the USB API v2 +*/ +struct usb_module_info_v2 gModuleInfoV2 = { + // First the bus_manager_info: + { + { + "bus_managers/usb/v2", + B_KEEP_LOADED, // Keep loaded, even if no driver requires it + bus_std_ops + }, + NULL // the rescan function + }, + + register_driver, // register_driver + install_notify, // install_notify + uninstall_notify, // uninstall_notify + get_device_descriptor_v2, // get_device_descriptor + get_nth_configuration_v2, // get_nth_configuration + get_configuration_v2, // get_configuration + set_configuration_v2, // set_configuration + set_alt_interface_v2, // set_alt_interface + set_feature_v2, // set_feature + clear_feature_v2, // clear_feature + get_status_v2, // get_status + get_descriptor_v2, // get_descriptor + send_request_v2, // send_request + queue_interrupt_v2, // queue_interrupt + queue_bulk_v2, // queue_bulk + queue_isochronous_v2, // queue_isochronous + queue_request_v2, // queue_request + set_pipe_policy_v2, // set_pipe_policy + cancel_queued_transfers_v2, // cancel_queued_transfers + usb_ioctl // usb_ioctl +}; + + +// +// #pragma mark - +// + + module_info *modules[] = { - (module_info *)&gModuleInfo, + (module_info *)&gModuleInfoV2, + (module_info *)&gModuleInfoV3, NULL }; diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index dab9d71f2d..d8343c5b38 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -16,12 +16,12 @@ class Hub; -class Device; class Stack; class Device; class Transfer; class BusManager; class ControlPipe; +class Object; struct host_controller_info { @@ -41,6 +41,17 @@ struct usb_driver_info { }; +#define USB_OBJECT_NONE 0x00000000 +#define USB_OBJECT_PIPE 0x00000001 +#define USB_OBJECT_CONTROL_PIPE 0x00000002 +#define USB_OBJECT_INTERRUPT_PIPE 0x00000004 +#define USB_OBJECT_BULK_PIPE 0x00000008 +#define USB_OBJECT_ISO_PIPE 0x00000010 +#define USB_OBJECT_INTERFACE 0x00000020 +#define USB_OBJECT_DEVICE 0x00000040 +#define USB_OBJECT_HUB 0x00000080 + + class Stack { public: Stack(); @@ -51,6 +62,10 @@ public: bool Lock(); void Unlock(); + usb_id GetUSBID(Object *object); + void PutUSBID(usb_id id); + Object *GetObject(usb_id id); + void AddBusManager(BusManager *bus); int32 IndexOfBusManager(BusManager *bus); @@ -90,6 +105,10 @@ private: addr_t fListhead32; addr_t fListhead64; + uint32 fObjectIndex; + uint32 fObjectMaxCount; + Object **fObjectArray; + usb_driver_info *fDriverList; }; @@ -101,11 +120,14 @@ private: */ class BusManager { public: - BusManager(); + BusManager(Stack *stack); virtual ~BusManager(); virtual status_t InitCheck(); + bool Lock(); + void Unlock(); + Device *AllocateNewDevice(Device *parent, bool lowSpeed); @@ -129,7 +151,7 @@ protected: private: static int32 ExploreThread(void *data); - sem_id fLock; + benaphore fLock; bool fDeviceMap[128]; ControlPipe *fDefaultPipe; ControlPipe *fDefaultPipeLowSpeed; @@ -139,29 +161,48 @@ static int32 ExploreThread(void *data); }; +class Object { +public: + Object(BusManager *bus); + + Stack *GetStack() { return fStack; }; + + usb_id USBID() { return fUSBID; }; +virtual uint32 Type() { return USB_OBJECT_NONE; }; + +private: + Stack *fStack; + usb_id fUSBID; +}; + + /* * The Pipe class is the communication management between the hardware and * the stack. It creates packets, manages these and performs callbacks. */ -class Pipe { +class Pipe : public Object { public: enum pipeDirection { In, Out, Default }; enum pipeSpeed { LowSpeed, NormalSpeed }; -enum pipeType { Control, Bulk, Isochronous, Interrupt, Invalid }; Pipe(Device *device, pipeDirection direction, pipeSpeed speed, uint8 endpointAddress, uint32 maxPacketSize); + Pipe(BusManager *bus, + int8 deviceAddress, + pipeSpeed speed, + uint32 maxPacketSize); virtual ~Pipe(); -virtual int8 DeviceAddress(); -virtual pipeType Type() { return Invalid; }; -virtual pipeSpeed Speed() { return fSpeed; }; -virtual pipeDirection Direction() { return fDirection; }; -virtual int8 EndpointAddress() { return fEndpoint; }; -virtual uint32 MaxPacketSize() { return fMaxPacketSize; }; +virtual uint32 Type() { return USB_OBJECT_PIPE; }; + + int8 DeviceAddress(); + pipeSpeed Speed() { return fSpeed; }; + pipeDirection Direction() { return fDirection; }; + int8 EndpointAddress() { return fEndpoint; }; + uint32 MaxPacketSize() { return fMaxPacketSize; }; virtual bool DataToggle() { return fDataToggle; }; virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; }; @@ -176,7 +217,9 @@ virtual status_t GetStatus(uint16 *status); protected: Device *fDevice; + int8 fDeviceAddress; BusManager *fBus; + usb_id fUSBID; pipeDirection fDirection; pipeSpeed fSpeed; uint8 fEndpoint; @@ -185,59 +228,6 @@ protected: }; -class InterruptPipe : public Pipe { -public: - InterruptPipe(Device *device, - pipeDirection direction, - pipeSpeed speed, - uint8 endpointAddress, - uint32 maxPacketSize); - -virtual pipeType Type() { return Interrupt; }; - - status_t QueueInterrupt(void *data, - size_t dataLength, - usb_callback_func callback, - void *callbackCookie); -}; - - -class BulkPipe : public Pipe { -public: - BulkPipe(Device *device, - pipeDirection direction, - pipeSpeed speed, - uint8 endpointAddress, - uint32 maxPacketSize); - -virtual pipeType Type() { return Bulk; }; - - status_t QueueBulk(void *data, - size_t dataLength, - usb_callback_func callback, - void *callbackCookie); -}; - - -class IsochronousPipe : public Pipe { -public: - IsochronousPipe(Device *device, - pipeDirection direction, - pipeSpeed speed, - uint8 endpointAddress, - uint32 maxPacketSize); - -virtual pipeType Type() { return Isochronous; }; - - status_t QueueIsochronous(void *data, - size_t dataLength, - rlea *rleArray, - uint16 bufferDurationMS, - usb_callback_func callback, - void *callbackCookie); -}; - - class ControlPipe : public Pipe { public: ControlPipe(Device *device, @@ -249,11 +239,9 @@ public: ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed, - uint8 endpointAddress, uint32 maxPacketSize); -virtual int8 DeviceAddress(); -virtual pipeType Type() { return Control; }; +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; }; // The data toggle is not relevant // for control transfers, as they are @@ -278,9 +266,59 @@ static void SendRequestCallback(void *cookie, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie); +}; -private: - int8 fDeviceAddress; + +class InterruptPipe : public Pipe { +public: + InterruptPipe(Device *device, + pipeDirection direction, + pipeSpeed speed, + uint8 endpointAddress, + uint32 maxPacketSize); + +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE; }; + + status_t QueueInterrupt(void *data, + size_t dataLength, + usb_callback_func callback, + void *callbackCookie); +}; + + +class BulkPipe : public Pipe { +public: + BulkPipe(Device *device, + pipeDirection direction, + pipeSpeed speed, + uint8 endpointAddress, + uint32 maxPacketSize); + +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; }; + + status_t QueueBulk(void *data, + size_t dataLength, + usb_callback_func callback, + void *callbackCookie); +}; + + +class IsochronousPipe : public Pipe { +public: + IsochronousPipe(Device *device, + pipeDirection direction, + pipeSpeed speed, + uint8 endpointAddress, + uint32 maxPacketSize); + +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; }; + + status_t QueueIsochronous(void *data, + size_t dataLength, + rlea *rleArray, + uint16 bufferDurationMS, + usb_callback_func callback, + void *callbackCookie); }; @@ -288,13 +326,12 @@ class Interface : public ControlPipe { public: Interface(Device *device); +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_INTERFACE; }; + // Convenience functions for standard requests virtual status_t SetFeature(uint16 selector); virtual status_t ClearFeature(uint16 selector); virtual status_t GetStatus(uint16 *status); - -private: - Device *fDevice; }; @@ -306,10 +343,10 @@ public: status_t InitCheck(); -virtual bool IsHub() { return false; }; +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE; }; + int8 Address() { return fDeviceAddress; }; BusManager *Manager() { return fBus; }; - bool LowSpeed() { return fLowSpeed; }; virtual status_t GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, @@ -359,7 +396,7 @@ public: usb_device_descriptor &desc, int8 deviceAddress, bool lowSpeed); -virtual bool IsHub() { return true; }; +virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE | USB_OBJECT_HUB; }; virtual status_t GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_p.h b/src/add-ons/kernel/bus_managers/usb/usbspec_p.h index 3213d8ac96..84273b64f8 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_p.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #define USB_MAX_AREAS 8 diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index 1a1833c435..a388bb4ce4 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -33,7 +33,7 @@ // --------------------------- #include #include -#include +#include #include #include @@ -187,6 +187,7 @@ module_info *modules[] = //------------------------------------------------------------------------ OHCI::OHCI( pci_info *info , Stack *stack ) + : BusManager(stack) { m_pcii = info; m_stack = stack; diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index d72a997c71..6a7749f144 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -323,7 +323,7 @@ Queue::PrintToStream() UHCI::UHCI(pci_info *info, Stack *stack) - : BusManager(), + : BusManager(stack), fPCIInfo(info), fStack(stack), fFrameArea(-1), @@ -338,14 +338,14 @@ UHCI::UHCI(pci_info *info, Stack *stack) fRootHub(NULL), fRootHubAddress(0) { - TRACE(("usb_uhci: constructing new UHCI Host Controller Driver\n")); - fInitOK = false; - - if (benaphore_init(&fUHCILock, "usb uhci lock") < B_OK) { - TRACE_ERROR(("usb_uhci: failed to create busmanager lock\n")); + if (!fInitOK) { + TRACE(("usb_uhci: bus manager failed to init\n")); return; } + TRACE(("usb_uhci: constructing new UHCI Host Controller Driver\n")); + fInitOK = false; + fRegisterBase = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_memory_base, 4); fRegisterBase &= PCI_address_io_mask; @@ -454,23 +454,9 @@ UHCI::~UHCI() delete [] fQueues; delete fRootHub; delete_area(fFrameArea); - benaphore_destroy(&fUHCILock); put_module(B_PCI_MODULE_NAME); -} - - -bool -UHCI::Lock() -{ - return (benaphore_lock(&fUHCILock) == B_OK); -} - - -void -UHCI::Unlock() -{ - benaphore_unlock(&fUHCILock); + Unlock(); } @@ -518,7 +504,6 @@ UHCI::Start() } SetRootHub(fRootHub); - SetStack(fStack); TRACE(("usb_uhci: controller is started. status: %u curframe: %u\n", ReadReg16(UHCI_USBSTS), ReadReg16(UHCI_FRNUM))); @@ -535,7 +520,7 @@ UHCI::SubmitTransfer(Transfer *transfer) if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) return fRootHub->SubmitTransfer(transfer); - if (transfer->TransferPipe()->Type() == Pipe::Control) + if (transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE) return SubmitRequest(transfer); if (!transfer->Data() || transfer->DataLength() == 0) @@ -565,7 +550,7 @@ UHCI::SubmitTransfer(Transfer *transfer) } Queue *queue = fQueues[3]; - if (pipe->Type() == Pipe::Interrupt) + if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) queue = fQueues[2]; result = AddPendingTransfer(transfer, queue, firstDescriptor, diff --git a/src/add-ons/kernel/busses/usb/uhci.h b/src/add-ons/kernel/busses/usb/uhci.h index 5925d4895f..f627c4e6ca 100644 --- a/src/add-ons/kernel/busses/usb/uhci.h +++ b/src/add-ons/kernel/busses/usb/uhci.h @@ -67,9 +67,6 @@ public: UHCI(pci_info *info, Stack *stack); ~UHCI(); - bool Lock(); - void Unlock(); - status_t Start(); virtual status_t SubmitTransfer(Transfer *transfer); virtual status_t SubmitRequest(Transfer *transfer); @@ -139,7 +136,6 @@ static pci_module_info *sPCIModule; uint32 fRegisterBase; pci_info *fPCIInfo; Stack *fStack; - benaphore fUHCILock; // Frame list memory area_id fFrameArea; diff --git a/src/add-ons/kernel/busses/usb/uhci_rh.cpp b/src/add-ons/kernel/busses/usb/uhci_rh.cpp index a1964ba2d3..5c16333212 100644 --- a/src/add-ons/kernel/busses/usb/uhci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/uhci_rh.cpp @@ -135,7 +135,7 @@ UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 devicenum) status_t UHCIRootHub::SubmitTransfer(Transfer *transfer) { - if (transfer->TransferPipe()->Type() != Pipe::Control) + if ((transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE) == 0) return B_ERROR; usb_request_data *request = transfer->RequestData();