* 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
This commit is contained in:
Michael Lotz
2006-08-19 23:09:05 +00:00
parent c3157a2749
commit 5b0ec61f97
18 changed files with 1062 additions and 419 deletions
+6 -187
View File
@@ -1,189 +1,8 @@
/* /*
** USB.h - Version 2 USB Device Driver API * This file is here for compatibility reasons.
** *
** Copyright 1999, Be Incorporated. All Rights Reserved. * You should include USB2.h or USB3.h depending on which API version you
** * intend to use.
*/ */
#ifndef _USB_H #include <USB2.h>
#define _USB_H
#include <KernelExport.h>
#include <bus_manager.h>
#include <USB_spec.h>
#include <USB_rle.h>
#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
+231
View File
@@ -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 <KernelExport.h>
#include <bus_manager.h>
#include <USB_spec.h>
#include <USB_rle.h>
#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_ */
+235
View File
@@ -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 <KernelExport.h>
#include <bus_manager.h>
#include <iovec.h>
#include <USB_spec.h>
#include <USB_rle.h>
#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_ */
@@ -18,38 +18,40 @@
#endif #endif
BusManager::BusManager() BusManager::BusManager(Stack *stack)
: fInitOK(false),
fDefaultPipe(NULL),
fDefaultPipeLowSpeed(NULL),
fRootHub(NULL),
fStack(stack),
fExploreThread(-1)
{ {
fInitOK = false; if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
fRootHub = NULL; TRACE(("usb BusManager: failed to create busmanager lock\n"));
// Set up the semaphore
fLock = create_sem(1, "bus manager lock");
if (fLock < B_OK)
return; return;
}
set_sem_owner(B_SYSTEM_TEAM, fLock);
// Clear the device map // Clear the device map
for (int32 i = 0; i < 128; i++) for (int32 i = 0; i < 128; i++)
fDeviceMap[i] = false; fDeviceMap[i] = false;
// Set up the default pipes // 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) if (!fDefaultPipe)
return; return;
fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 0, 8); fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 8);
if (!fDefaultPipeLowSpeed) if (!fDefaultPipeLowSpeed)
return; return;
fExploreThread = -1;
fInitOK = true; fInitOK = true;
} }
BusManager::~BusManager() 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 This is the 'main' function of the explore thread, which keeps track of
the hub states. the hub states.
@@ -127,7 +143,7 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
// Create a temporary pipe with the new address // Create a temporary pipe with the new address
ControlPipe pipe(this, deviceAddress, ControlPipe pipe(this, deviceAddress,
lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, 8); lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 8);
// Get the device descriptor // Get the device descriptor
// Just retrieve the first 8 bytes of the descriptor -> minimum supported // Just retrieve the first 8 bytes of the descriptor -> minimum supported
@@ -206,7 +222,8 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
int8 int8
BusManager::AllocateAddress() BusManager::AllocateAddress()
{ {
acquire_sem_etc(fLock, 1, B_CAN_INTERRUPT, 0); if (!Lock())
return -1;
int8 deviceAddress = -1; int8 deviceAddress = -1;
for (int32 i = 1; i < 128; i++) { for (int32 i = 1; i < 128; i++) {
@@ -217,7 +234,7 @@ BusManager::AllocateAddress()
} }
} }
release_sem(fLock); Unlock();
return deviceAddress; return deviceAddress;
} }
+10 -10
View File
@@ -20,7 +20,7 @@
Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed) int8 deviceAddress, bool lowSpeed)
: ControlPipe(bus, deviceAddress, : ControlPipe(bus, deviceAddress,
lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed,
desc.max_packet_size_0), desc.max_packet_size_0),
fDeviceDescriptor(desc), fDeviceDescriptor(desc),
fConfigurations(NULL), fConfigurations(NULL),
@@ -155,7 +155,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
interfaceInfo->generic = NULL; interfaceInfo->generic = NULL;
Interface *interface = new(std::nothrow) Interface(this); Interface *interface = new(std::nothrow) Interface(this);
interfaceInfo->handle = (usb_interface *)interface; interfaceInfo->handle = interface->USBID();
currentInterface = interfaceInfo; currentInterface = interfaceInfo;
break; break;
@@ -190,7 +190,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
switch (endpointDescriptor->attributes & 0x03) { switch (endpointDescriptor->attributes & 0x03) {
case 0x00: /* Control Endpoint */ case 0x00: /* Control Endpoint */
endpoint = new(std::nothrow) ControlPipe(this, endpoint = new(std::nothrow) ControlPipe(this,
LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, Speed(),
endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->endpoint_address & 0x0f,
endpointDescriptor->max_packet_size); endpointDescriptor->max_packet_size);
break; break;
@@ -198,7 +198,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
case 0x01: /* Isochronous Endpoint */ case 0x01: /* Isochronous Endpoint */
endpoint = new(std::nothrow) IsochronousPipe(this, endpoint = new(std::nothrow) IsochronousPipe(this,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, Speed(),
endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->endpoint_address & 0x0f,
endpointDescriptor->max_packet_size); endpointDescriptor->max_packet_size);
break; break;
@@ -206,7 +206,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
case 0x02: /* Bulk Endpoint */ case 0x02: /* Bulk Endpoint */
endpoint = new(std::nothrow) BulkPipe(this, endpoint = new(std::nothrow) BulkPipe(this,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, Speed(),
endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->endpoint_address & 0x0f,
endpointDescriptor->max_packet_size); endpointDescriptor->max_packet_size);
break; break;
@@ -214,13 +214,13 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
case 0x03: /* Interrupt Endpoint */ case 0x03: /* Interrupt Endpoint */
endpoint = new(std::nothrow) InterruptPipe(this, endpoint = new(std::nothrow) InterruptPipe(this,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, Speed(),
endpointDescriptor->endpoint_address & 0x0f, endpointDescriptor->endpoint_address & 0x0f,
endpointDescriptor->max_packet_size); endpointDescriptor->max_packet_size);
break; break;
} }
endpointInfo->handle = (usb_pipe *)endpoint; endpointInfo->handle = endpoint->USBID();
break; break;
} }
@@ -358,7 +358,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
TRACE(("USB Device ReportDevice\n")); TRACE(("USB Device ReportDevice\n"));
if (supportDescriptorCount == 0 || supportDescriptors == NULL) { if (supportDescriptorCount == 0 || supportDescriptors == NULL) {
if (added && hooks->device_added != 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) else if (!added && hooks->device_removed != NULL)
hooks->device_removed(fNotifyCookie); hooks->device_removed(fNotifyCookie);
return; return;
@@ -379,7 +379,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
|| fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) { || fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) {
if (added && hooks->device_added != 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) else if (!added && hooks->device_removed != NULL)
hooks->device_removed(fNotifyCookie); hooks->device_removed(fNotifyCookie);
return; return;
@@ -398,7 +398,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
|| descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) { || descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) {
if (added && hooks->device_added != 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) else if (!added && hooks->device_removed != NULL)
hooks->device_removed(fNotifyCookie); hooks->device_removed(fNotifyCookie);
return; return;
+7 -7
View File
@@ -61,13 +61,13 @@ Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
TRACE(("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable)); TRACE(("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable));
TRACE(("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask)); TRACE(("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask));
Pipe *pipe = (Pipe *)Configuration()->interface->active->endpoint[0].handle; Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
if (!pipe || pipe->Type() != Pipe::Interrupt) { if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
TRACE(("USB Hub: no interrupt pipe found\n")); TRACE(("USB Hub: no interrupt pipe found\n"));
return; return;
} }
fInterruptPipe = (InterruptPipe *)pipe; fInterruptPipe = (InterruptPipe *)object;
fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus), fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus),
InterruptCallback, this); InterruptCallback, this);
@@ -193,7 +193,7 @@ Hub::Explore()
if (newDevice) { if (newDevice) {
fChildren[i] = newDevice; fChildren[i] = newDevice;
Manager()->GetStack()->NotifyDeviceChange(fChildren[i], true); GetStack()->NotifyDeviceChange(fChildren[i], true);
} else { } else {
// the device failed to setup correctly, disable the port // the device failed to setup correctly, disable the port
// so that the device doesn't get in the way of future // so that the device doesn't get in the way of future
@@ -206,7 +206,7 @@ Hub::Explore()
// Device removed... // Device removed...
TRACE(("USB Hub Explore(): Device removed\n")); TRACE(("USB Hub Explore(): Device removed\n"));
if (fChildren[i]) { if (fChildren[i]) {
Manager()->GetStack()->NotifyDeviceChange(fChildren[i], false); GetStack()->NotifyDeviceChange(fChildren[i], false);
delete fChildren[i]; delete fChildren[i];
fChildren[i] = NULL; fChildren[i] = NULL;
} }
@@ -221,7 +221,7 @@ Hub::Explore()
// explore down the tree if we have hubs connected // explore down the tree if we have hubs connected
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { 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; continue;
((Hub *)fChildren[i])->Explore(); ((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); status_t result = Device::BuildDeviceName(string, index, bufferSize, device);
if (result < B_OK) { if (result < B_OK) {
// recursion to parent failed, we're at the root(hub) // 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); *index += snprintf(string + *index, bufferSize - *index, "%d", managerIndex);
} }
@@ -10,8 +10,7 @@
Interface::Interface(Device *device) Interface::Interface(Device *device)
: ControlPipe(device, : ControlPipe(device, device->Speed(), 0, 8)
device->LowSpeed() ? Pipe::LowSpeed : Pipe::NormalSpeed, 0, 8)
{ {
} }
@@ -15,6 +15,7 @@ KernelStaticLibrary libusb.a :
Transfer.cpp Transfer.cpp
Pipe.cpp Pipe.cpp
Interface.cpp Interface.cpp
Object.cpp
: -fno-pic : -fno-pic
; ;
@@ -0,0 +1,8 @@
#include "usb_p.h"
Object::Object(BusManager *bus)
{
fStack = bus->GetStack();
fUSBID = fStack->GetUSBID(this);
}
+22 -19
View File
@@ -12,16 +12,31 @@
Pipe::Pipe(Device *device, pipeDirection direction, pipeSpeed speed, Pipe::Pipe(Device *device, pipeDirection direction, pipeSpeed speed,
uint8 endpointAddress, uint32 maxPacketSize) uint8 endpointAddress, uint32 maxPacketSize)
: fDevice(device), : Object(device->Manager()),
fBus(NULL), fDevice(device),
fDeviceAddress(device->Address()),
fBus(device->Manager()),
fDirection(direction), fDirection(direction),
fSpeed(speed), fSpeed(speed),
fEndpoint(endpointAddress), fEndpoint(endpointAddress),
fMaxPacketSize(maxPacketSize), fMaxPacketSize(maxPacketSize),
fDataToggle(false) 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() Pipe::DeviceAddress()
{ {
if (!fDevice) if (!fDevice)
return -1; return fDeviceAddress;
return fDevice->Address(); return fDevice->Address();
} }
@@ -210,21 +225,9 @@ ControlPipe::ControlPipe(Device *device, pipeSpeed speed,
ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed, ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed,
uint8 endpointAddress, uint32 maxPacketSize) uint32 maxPacketSize)
: Pipe(NULL, Pipe::Default, speed, endpointAddress, maxPacketSize), : Pipe(bus, deviceAddress, speed, maxPacketSize)
fDeviceAddress(deviceAddress)
{ {
fBus = bus;
}
int8
ControlPipe::DeviceAddress()
{
if (!fDevice)
return fDeviceAddress;
return fDevice->Address();
} }
+63 -1
View File
@@ -20,7 +20,10 @@
Stack::Stack() Stack::Stack()
: fDriverList(NULL) : fObjectIndex(1),
fObjectMaxCount(1024),
fObjectArray(NULL),
fDriverList(NULL)
{ {
TRACE(("usb stack: stack init\n")); TRACE(("usb stack: stack init\n"));
@@ -29,6 +32,10 @@ Stack::Stack()
return; 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 // Initialise the memory chunks: create 8, 16 and 32 byte-heaps
// NOTE: This is probably the most ugly code you will see in the // NOTE: This is probably the most ugly code you will see in the
// whole stack. Unfortunately this is needed because of the fact // 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 void
Stack::AddBusManager(BusManager *busManager) Stack::AddBusManager(BusManager *busManager)
{ {
+320 -71
View File
@@ -3,10 +3,10 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk * Niels S. Reedijk
*/ */
#include <USB.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "usb_p.h" #include "usb_p.h"
@@ -27,6 +27,9 @@ bus_std_ops(int32 op, ...)
{ {
switch (op) { switch (op) {
case B_MODULE_INIT: { case B_MODULE_INIT: {
if (gUSBStack)
return B_OK;
#ifdef TRACE_USB #ifdef TRACE_USB
set_dprintf_enabled(true); set_dprintf_enabled(true);
load_driver_symbols("usb"); load_driver_symbols("usb");
@@ -85,65 +88,72 @@ uninstall_notify(const char *driverName)
const usb_device_descriptor * 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)); 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 NULL;
return ((const Device *)device)->DeviceDescriptor(); return ((Device *)object)->DeviceDescriptor();
} }
const usb_configuration_info * 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)); 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 NULL;
return ((const Device *)device)->ConfigurationAt((int32)index); return ((Device *)object)->ConfigurationAt((int32)index);
} }
const usb_configuration_info * const usb_configuration_info *
get_configuration(const usb_device *device) get_configuration(usb_device device)
{ {
TRACE(("usb_module: get_configuration(0x%08x)\n", 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 NULL;
return ((const Device *)device)->Configuration(); return ((Device *)object)->Configuration();
} }
status_t status_t
set_configuration(const usb_device *device, set_configuration(usb_device device,
const usb_configuration_info *configuration) const usb_configuration_info *configuration)
{ {
TRACE(("usb_module: set_configuration(0x%08x, 0x%08x)\n", device, 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 B_BAD_VALUE;
return ((Device *)device)->SetConfiguration(configuration); return ((Device *)object)->SetConfiguration(configuration);
} }
status_t status_t
set_alt_interface(const usb_device *device, set_alt_interface(usb_device device, const usb_interface_info *interface)
const usb_interface_info *interface)
{ {
TRACE(("usb_module: set_alt_interface(0x%08x, 0x%08x)\n", device, 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; return B_ERROR;
} }
status_t 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)); TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector));
if (!object) Object *object = gUSBStack->GetObject(handle);
if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
return B_BAD_VALUE; return B_BAD_VALUE;
return ((Pipe *)object)->SetFeature(selector); return ((Pipe *)object)->SetFeature(selector);
@@ -151,10 +161,11 @@ set_feature(const void *object, uint16 selector)
status_t 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)); TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector));
if (!object) Object *object = gUSBStack->GetObject(handle);
if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
return B_BAD_VALUE; return B_BAD_VALUE;
return ((Pipe *)object)->ClearFeature(selector); return ((Pipe *)object)->ClearFeature(selector);
@@ -162,10 +173,14 @@ clear_feature(const void *object, uint16 selector)
status_t 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)); TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", handle, status));
if (!object || !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 B_BAD_VALUE;
return ((Pipe *)object)->GetStatus(status); return ((Pipe *)object)->GetStatus(status);
@@ -173,100 +188,126 @@ get_status(const void *object, uint16 *status)
status_t status_t
get_descriptor(const usb_device *device, uint8 type, uint8 index, get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID,
uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 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)); 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 B_BAD_VALUE;
return ((Device *)device)->GetDescriptor(type, index, languageID, return ((Device *)object)->GetDescriptor(type, index, languageID,
data, dataLength, actualLength); data, dataLength, actualLength);
} }
status_t status_t
send_request(const usb_device *device, uint8 requestType, uint8 request, send_request(usb_device device, uint8 requestType, uint8 request,
uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength)
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)); 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));
if (!device) Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_BAD_VALUE; return B_BAD_VALUE;
return ((Device *)device)->SendRequest(requestType, request, value, index, return ((Device *)object)->SendRequest(requestType, request, value, index,
length, data, dataLength, actualLength); length, data, length, actualLength);
} }
status_t status_t
queue_request(const usb_device *device, uint8 requestType, uint8 request, queue_request(usb_device device, uint8 requestType, uint8 request,
uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, uint16 value, uint16 index, uint16 length, void *data,
usb_callback_func callback, void *callbackCookie) 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)); 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));
if (!device) Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_BAD_VALUE; return B_BAD_VALUE;
return ((Device *)device)->QueueRequest(requestType, request, value, index, return ((Device *)object)->QueueRequest(requestType, request, value, index,
length, data, dataLength, callback, callbackCookie); length, data, length, callback, callbackCookie);
} }
status_t 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) 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)); 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 B_BAD_VALUE;
return ((InterruptPipe *)pipe)->QueueInterrupt(data, dataLength, callback, return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback,
callbackCookie); callbackCookie);
} }
status_t 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) 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)); 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 B_BAD_VALUE;
return ((BulkPipe *)pipe)->QueueBulk(data, dataLength, callback, return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback,
callbackCookie); callbackCookie);
} }
status_t status_t
queue_isochronous(const usb_pipe *pipe, void *data, size_t dataLength, queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount,
rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, usb_callback_func callback, void *callbackCookie)
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)); TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, vector, vectorCount, callback, callbackCookie));
if (((Pipe *)pipe)->Type() != Pipe::Isochronous) Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
return B_BAD_VALUE; 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; return B_ERROR;
} }
status_t 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)); 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) { switch (opcode) {
case 'DNAM': { case 'DNAM': {
Object *object = gUSBStack->GetObject(*(usb_id *)buffer);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_BAD_VALUE;
uint32 index = 0; uint32 index = 0;
Device *device = *(Device **)buffer; return ((Device *)object)->BuildDeviceName((char *)buffer, &index,
return device->BuildDeviceName((char *)buffer, &index, bufferSize, NULL); 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: // First the bus_manager_info:
{ {
{ {
B_USB_MODULE_NAME, "bus_managers/usb/v3",
B_KEEP_LOADED, // Keep loaded, even if no driver requires it B_KEEP_LOADED, // Keep loaded, even if no driver requires it
bus_std_ops bus_std_ops
}, },
@@ -316,6 +361,7 @@ struct usb_module_info gModuleInfo = {
send_request, // send_request send_request, // send_request
queue_interrupt, // queue_interrupt queue_interrupt, // queue_interrupt
queue_bulk, // queue_bulk queue_bulk, // queue_bulk
queue_bulk_v, // queue_bulk_v
queue_isochronous, // queue_isochronous queue_isochronous, // queue_isochronous
queue_request, // queue_request queue_request, // queue_request
set_pipe_policy, // set_pipe_policy 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 *modules[] = {
(module_info *)&gModuleInfo, (module_info *)&gModuleInfoV2,
(module_info *)&gModuleInfoV3,
NULL NULL
}; };
+112 -75
View File
@@ -16,12 +16,12 @@
class Hub; class Hub;
class Device;
class Stack; class Stack;
class Device; class Device;
class Transfer; class Transfer;
class BusManager; class BusManager;
class ControlPipe; class ControlPipe;
class Object;
struct host_controller_info { 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 { class Stack {
public: public:
Stack(); Stack();
@@ -51,6 +62,10 @@ public:
bool Lock(); bool Lock();
void Unlock(); void Unlock();
usb_id GetUSBID(Object *object);
void PutUSBID(usb_id id);
Object *GetObject(usb_id id);
void AddBusManager(BusManager *bus); void AddBusManager(BusManager *bus);
int32 IndexOfBusManager(BusManager *bus); int32 IndexOfBusManager(BusManager *bus);
@@ -90,6 +105,10 @@ private:
addr_t fListhead32; addr_t fListhead32;
addr_t fListhead64; addr_t fListhead64;
uint32 fObjectIndex;
uint32 fObjectMaxCount;
Object **fObjectArray;
usb_driver_info *fDriverList; usb_driver_info *fDriverList;
}; };
@@ -101,11 +120,14 @@ private:
*/ */
class BusManager { class BusManager {
public: public:
BusManager(); BusManager(Stack *stack);
virtual ~BusManager(); virtual ~BusManager();
virtual status_t InitCheck(); virtual status_t InitCheck();
bool Lock();
void Unlock();
Device *AllocateNewDevice(Device *parent, Device *AllocateNewDevice(Device *parent,
bool lowSpeed); bool lowSpeed);
@@ -129,7 +151,7 @@ protected:
private: private:
static int32 ExploreThread(void *data); static int32 ExploreThread(void *data);
sem_id fLock; benaphore fLock;
bool fDeviceMap[128]; bool fDeviceMap[128];
ControlPipe *fDefaultPipe; ControlPipe *fDefaultPipe;
ControlPipe *fDefaultPipeLowSpeed; 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 Pipe class is the communication management between the hardware and
* the stack. It creates packets, manages these and performs callbacks. * the stack. It creates packets, manages these and performs callbacks.
*/ */
class Pipe { class Pipe : public Object {
public: public:
enum pipeDirection { In, Out, Default }; enum pipeDirection { In, Out, Default };
enum pipeSpeed { LowSpeed, NormalSpeed }; enum pipeSpeed { LowSpeed, NormalSpeed };
enum pipeType { Control, Bulk, Isochronous, Interrupt, Invalid };
Pipe(Device *device, Pipe(Device *device,
pipeDirection direction, pipeDirection direction,
pipeSpeed speed, pipeSpeed speed,
uint8 endpointAddress, uint8 endpointAddress,
uint32 maxPacketSize); uint32 maxPacketSize);
Pipe(BusManager *bus,
int8 deviceAddress,
pipeSpeed speed,
uint32 maxPacketSize);
virtual ~Pipe(); virtual ~Pipe();
virtual int8 DeviceAddress(); virtual uint32 Type() { return USB_OBJECT_PIPE; };
virtual pipeType Type() { return Invalid; };
virtual pipeSpeed Speed() { return fSpeed; }; int8 DeviceAddress();
virtual pipeDirection Direction() { return fDirection; }; pipeSpeed Speed() { return fSpeed; };
virtual int8 EndpointAddress() { return fEndpoint; }; pipeDirection Direction() { return fDirection; };
virtual uint32 MaxPacketSize() { return fMaxPacketSize; }; int8 EndpointAddress() { return fEndpoint; };
uint32 MaxPacketSize() { return fMaxPacketSize; };
virtual bool DataToggle() { return fDataToggle; }; virtual bool DataToggle() { return fDataToggle; };
virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; }; virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; };
@@ -176,7 +217,9 @@ virtual status_t GetStatus(uint16 *status);
protected: protected:
Device *fDevice; Device *fDevice;
int8 fDeviceAddress;
BusManager *fBus; BusManager *fBus;
usb_id fUSBID;
pipeDirection fDirection; pipeDirection fDirection;
pipeSpeed fSpeed; pipeSpeed fSpeed;
uint8 fEndpoint; 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 { class ControlPipe : public Pipe {
public: public:
ControlPipe(Device *device, ControlPipe(Device *device,
@@ -249,11 +239,9 @@ public:
ControlPipe(BusManager *bus, ControlPipe(BusManager *bus,
int8 deviceAddress, int8 deviceAddress,
pipeSpeed speed, pipeSpeed speed,
uint8 endpointAddress,
uint32 maxPacketSize); uint32 maxPacketSize);
virtual int8 DeviceAddress(); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; };
virtual pipeType Type() { return Control; };
// The data toggle is not relevant // The data toggle is not relevant
// for control transfers, as they are // for control transfers, as they are
@@ -278,9 +266,59 @@ static void SendRequestCallback(void *cookie,
void *data, size_t dataLength, void *data, size_t dataLength,
usb_callback_func callback, usb_callback_func callback,
void *callbackCookie); 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: public:
Interface(Device *device); Interface(Device *device);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_INTERFACE; };
// Convenience functions for standard requests // Convenience functions for standard requests
virtual status_t SetFeature(uint16 selector); virtual status_t SetFeature(uint16 selector);
virtual status_t ClearFeature(uint16 selector); virtual status_t ClearFeature(uint16 selector);
virtual status_t GetStatus(uint16 *status); virtual status_t GetStatus(uint16 *status);
private:
Device *fDevice;
}; };
@@ -306,10 +343,10 @@ public:
status_t InitCheck(); 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; }; int8 Address() { return fDeviceAddress; };
BusManager *Manager() { return fBus; }; BusManager *Manager() { return fBus; };
bool LowSpeed() { return fLowSpeed; };
virtual status_t GetDescriptor(uint8 descriptorType, virtual status_t GetDescriptor(uint8 descriptorType,
uint8 index, uint16 languageID, uint8 index, uint16 languageID,
@@ -359,7 +396,7 @@ public:
usb_device_descriptor &desc, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed); 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, virtual status_t GetDescriptor(uint8 descriptorType,
uint8 index, uint16 languageID, uint8 index, uint16 languageID,
@@ -11,7 +11,7 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <util/Vector.h> #include <util/Vector.h>
#include <USB.h> #include <USB3.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#define USB_MAX_AREAS 8 #define USB_MAX_AREAS 8
+2 -1
View File
@@ -33,7 +33,7 @@
// --------------------------- // ---------------------------
#include <module.h> #include <module.h>
#include <PCI.h> #include <PCI.h>
#include <USB.h> #include <USB3.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <stdlib.h> #include <stdlib.h>
@@ -187,6 +187,7 @@ module_info *modules[] =
//------------------------------------------------------------------------ //------------------------------------------------------------------------
OHCI::OHCI( pci_info *info , Stack *stack ) OHCI::OHCI( pci_info *info , Stack *stack )
: BusManager(stack)
{ {
m_pcii = info; m_pcii = info;
m_stack = stack; m_stack = stack;
+10 -25
View File
@@ -9,7 +9,7 @@
#include <module.h> #include <module.h>
#include <PCI.h> #include <PCI.h>
#include <USB.h> #include <USB3.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <stdlib.h> #include <stdlib.h>
@@ -323,7 +323,7 @@ Queue::PrintToStream()
UHCI::UHCI(pci_info *info, Stack *stack) UHCI::UHCI(pci_info *info, Stack *stack)
: BusManager(), : BusManager(stack),
fPCIInfo(info), fPCIInfo(info),
fStack(stack), fStack(stack),
fFrameArea(-1), fFrameArea(-1),
@@ -338,14 +338,14 @@ UHCI::UHCI(pci_info *info, Stack *stack)
fRootHub(NULL), fRootHub(NULL),
fRootHubAddress(0) fRootHubAddress(0)
{ {
TRACE(("usb_uhci: constructing new UHCI Host Controller Driver\n")); if (!fInitOK) {
fInitOK = false; TRACE(("usb_uhci: bus manager failed to init\n"));
if (benaphore_init(&fUHCILock, "usb uhci lock") < B_OK) {
TRACE_ERROR(("usb_uhci: failed to create busmanager lock\n"));
return; return;
} }
TRACE(("usb_uhci: constructing new UHCI Host Controller Driver\n"));
fInitOK = false;
fRegisterBase = sPCIModule->read_pci_config(fPCIInfo->bus, fRegisterBase = sPCIModule->read_pci_config(fPCIInfo->bus,
fPCIInfo->device, fPCIInfo->function, PCI_memory_base, 4); fPCIInfo->device, fPCIInfo->function, PCI_memory_base, 4);
fRegisterBase &= PCI_address_io_mask; fRegisterBase &= PCI_address_io_mask;
@@ -454,23 +454,9 @@ UHCI::~UHCI()
delete [] fQueues; delete [] fQueues;
delete fRootHub; delete fRootHub;
delete_area(fFrameArea); delete_area(fFrameArea);
benaphore_destroy(&fUHCILock);
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
} Unlock();
bool
UHCI::Lock()
{
return (benaphore_lock(&fUHCILock) == B_OK);
}
void
UHCI::Unlock()
{
benaphore_unlock(&fUHCILock);
} }
@@ -518,7 +504,6 @@ UHCI::Start()
} }
SetRootHub(fRootHub); SetRootHub(fRootHub);
SetStack(fStack);
TRACE(("usb_uhci: controller is started. status: %u curframe: %u\n", TRACE(("usb_uhci: controller is started. status: %u curframe: %u\n",
ReadReg16(UHCI_USBSTS), ReadReg16(UHCI_FRNUM))); ReadReg16(UHCI_USBSTS), ReadReg16(UHCI_FRNUM)));
@@ -535,7 +520,7 @@ UHCI::SubmitTransfer(Transfer *transfer)
if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
return fRootHub->SubmitTransfer(transfer); return fRootHub->SubmitTransfer(transfer);
if (transfer->TransferPipe()->Type() == Pipe::Control) if (transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE)
return SubmitRequest(transfer); return SubmitRequest(transfer);
if (!transfer->Data() || transfer->DataLength() == 0) if (!transfer->Data() || transfer->DataLength() == 0)
@@ -565,7 +550,7 @@ UHCI::SubmitTransfer(Transfer *transfer)
} }
Queue *queue = fQueues[3]; Queue *queue = fQueues[3];
if (pipe->Type() == Pipe::Interrupt) if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE)
queue = fQueues[2]; queue = fQueues[2];
result = AddPendingTransfer(transfer, queue, firstDescriptor, result = AddPendingTransfer(transfer, queue, firstDescriptor,
-4
View File
@@ -67,9 +67,6 @@ public:
UHCI(pci_info *info, Stack *stack); UHCI(pci_info *info, Stack *stack);
~UHCI(); ~UHCI();
bool Lock();
void Unlock();
status_t Start(); status_t Start();
virtual status_t SubmitTransfer(Transfer *transfer); virtual status_t SubmitTransfer(Transfer *transfer);
virtual status_t SubmitRequest(Transfer *transfer); virtual status_t SubmitRequest(Transfer *transfer);
@@ -139,7 +136,6 @@ static pci_module_info *sPCIModule;
uint32 fRegisterBase; uint32 fRegisterBase;
pci_info *fPCIInfo; pci_info *fPCIInfo;
Stack *fStack; Stack *fStack;
benaphore fUHCILock;
// Frame list memory // Frame list memory
area_id fFrameArea; area_id fFrameArea;
+1 -1
View File
@@ -135,7 +135,7 @@ UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 devicenum)
status_t status_t
UHCIRootHub::SubmitTransfer(Transfer *transfer) UHCIRootHub::SubmitTransfer(Transfer *transfer)
{ {
if (transfer->TransferPipe()->Type() != Pipe::Control) if ((transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
return B_ERROR; return B_ERROR;
usb_request_data *request = transfer->RequestData(); usb_request_data *request = transfer->RequestData();