Introduce some extensions to the USB v3 module API that allow for device
enumeration (getting roothubs, enumerating child devices and detecting device topology) and hub port management (resetting and disabling ports). These were laying around for quite some time. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27768 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
abe717da05
commit
7e1490e0ad
@ -129,7 +129,7 @@ struct usb_module_info {
|
||||
|
||||
/* Get the nth supported configuration of a device*/
|
||||
const usb_configuration_info *(*get_nth_configuration)(usb_device device,
|
||||
uint index);
|
||||
uint32 index);
|
||||
|
||||
/* Get the current configuration */
|
||||
const usb_configuration_info *(*get_configuration)(usb_device device);
|
||||
@ -211,9 +211,47 @@ struct usb_module_info {
|
||||
/* Cancel all pending async requests in a pipe */
|
||||
status_t (*cancel_queued_transfers)(usb_pipe pipe);
|
||||
|
||||
/* tuning, timeouts, etc */
|
||||
/* Tuning, configuration of timeouts, etc */
|
||||
status_t (*usb_ioctl)(uint32 opcode, void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
/*
|
||||
* Enumeration of device topology - With these commands you can enumerate
|
||||
* the roothubs and enumerate child devices of hubs. Note that the index
|
||||
* provided to get_nth_child does not map to the port where the child
|
||||
* device is attached to. To get this information you would call
|
||||
* get_device_parent which provides you with the parent hub and the port
|
||||
* index of a device. To test whether an enumerated child is a hub you
|
||||
* can either examine the device descriptor or you can call get_nth_child
|
||||
* and check the returned status. A value of B_OK indicates that the call
|
||||
* succeeded and the returned info is valid, B_ENTRY_NOT_FOUND indicates
|
||||
* that you have reached the last index. Any other error indicates that
|
||||
* the provided arguments are invalid (i.e. not a hub or invalid pointers)
|
||||
* or an internal error occured. Note that there are no guarantees that
|
||||
* the device handle you get stays valid while you are using it. If it gets
|
||||
* invalid any further use will simply return an error. You should install
|
||||
* notify hooks to avoid such situations.
|
||||
*/
|
||||
status_t (*get_nth_roothub)(uint32 index,
|
||||
usb_device *rootHub);
|
||||
status_t (*get_nth_child)(usb_device hub,
|
||||
uint8 index, usb_device *childDevice);
|
||||
status_t (*get_device_parent)(usb_device device,
|
||||
usb_device *parentHub,
|
||||
uint8 *portIndex);
|
||||
|
||||
/*
|
||||
* Hub interaction - These commands are only valid when used with a hub
|
||||
* device handle. Use reset_port to trigger a reset of the port with index
|
||||
* portIndex. This will cause a disconnect event for the attached device.
|
||||
* With disable_port you can specify that the port at portIndex shall be
|
||||
* disabled. This will also cause a disconnect event for the attached
|
||||
* device. Use reset_port to reenable a previously disabled port.
|
||||
*/
|
||||
status_t (*reset_port)(usb_device hub,
|
||||
uint8 portIndex);
|
||||
status_t (*disable_port)(usb_device hub,
|
||||
uint8 portIndex);
|
||||
};
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ get_device_descriptor(usb_device device)
|
||||
|
||||
|
||||
const usb_configuration_info *
|
||||
get_nth_configuration(usb_device device, uint index)
|
||||
get_nth_configuration(usb_device device, uint32 index)
|
||||
{
|
||||
TRACE(("usb_module: get_nth_configuration(%ld, %d)\n", device, index));
|
||||
Object *object = gUSBStack->GetObject(device);
|
||||
@ -355,6 +355,102 @@ usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
get_nth_roothub(uint32 index, usb_device *rootHub)
|
||||
{
|
||||
if (!rootHub)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BusManager *busManager = gUSBStack->BusManagerAt(index);
|
||||
if (!busManager)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
Hub *hub = busManager->GetRootHub();
|
||||
if (!hub)
|
||||
return B_NO_INIT;
|
||||
|
||||
*rootHub = hub->USBID();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice)
|
||||
{
|
||||
if (!childDevice)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Object *object = gUSBStack->GetObject(_hub);
|
||||
if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
Hub *hub = (Hub *)object;
|
||||
for (uint8 i = 0; i < 8; i++) {
|
||||
if (hub->ChildAt(i) == NULL)
|
||||
continue;
|
||||
|
||||
if (index-- > 0)
|
||||
continue;
|
||||
|
||||
*childDevice = hub->ChildAt(i)->USBID();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex)
|
||||
{
|
||||
if (!parentHub || !portIndex)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Object *object = gUSBStack->GetObject(_device);
|
||||
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
Object *parent = object->Parent();
|
||||
if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
Hub *hub = (Hub *)parent;
|
||||
for (uint8 i = 0; i < 8; i++) {
|
||||
if (hub->ChildAt(i) == object) {
|
||||
*portIndex = i;
|
||||
*parentHub = hub->USBID();
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
reset_port(usb_device _hub, uint8 portIndex)
|
||||
{
|
||||
Object *object = gUSBStack->GetObject(_hub);
|
||||
if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
Hub *hub = (Hub *)object;
|
||||
return hub->ResetPort(portIndex);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
disable_port(usb_device _hub, uint8 portIndex)
|
||||
{
|
||||
Object *object = gUSBStack->GetObject(_hub);
|
||||
if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
Hub *hub = (Hub *)object;
|
||||
return hub->DisablePort(portIndex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This module exports the USB API v3
|
||||
*/
|
||||
@ -389,7 +485,12 @@ struct usb_module_info gModuleInfoV3 = {
|
||||
queue_request, // queue_request
|
||||
set_pipe_policy, // set_pipe_policy
|
||||
cancel_queued_transfers, // cancel_queued_transfers
|
||||
usb_ioctl // usb_ioctl
|
||||
usb_ioctl, // usb_ioctl
|
||||
get_nth_roothub, // get_nth_roothub
|
||||
get_nth_child, // get_nth_child
|
||||
get_device_parent, // get_device_parent
|
||||
reset_port, // reset_port
|
||||
disable_port // disable_port
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user