* Implemented setting an alternate interface through the USBKit library based
on a patch by Salvatore Benedetto, adapted to the usb_raw interface by me * Added two convenience functions IsStalled() and ClearStall() to USBEndpoint Both changes are actually untested, so if you have a use for them and encounter problems please shout. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24837 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,9 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Michael Lotz <[email protected]>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USBKIT_H
|
#ifndef _USBKIT_H
|
||||||
@@ -240,12 +237,25 @@ public:
|
|||||||
uint32 CountEndpoints() const;
|
uint32 CountEndpoints() const;
|
||||||
const BUSBEndpoint *EndpointAt(uint32 index) const;
|
const BUSBEndpoint *EndpointAt(uint32 index) const;
|
||||||
|
|
||||||
|
// Using CountAlternates() you can retrieve the number of alternate
|
||||||
|
// interfaces at this interface index. Note that this interface itself
|
||||||
|
// counts as an alternate so an alternate count of one really means
|
||||||
|
// that you are currently using the sole interface present.
|
||||||
|
// With SetAlternate() you can switch this BUSBInterface object to the
|
||||||
|
// alternate at the specified index. Note that all endpoints retrieved
|
||||||
|
// through EndpointAt() will become invalid and be deleted as soon as
|
||||||
|
// you set an alternate.
|
||||||
|
uint32 CountAlternates() const;
|
||||||
|
status_t SetAlternate(uint32 alternateIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BUSBConfiguration;
|
friend class BUSBConfiguration;
|
||||||
BUSBInterface(BUSBConfiguration *config,
|
BUSBInterface(BUSBConfiguration *config,
|
||||||
uint32 index, int rawFD);
|
uint32 index, int rawFD);
|
||||||
~BUSBInterface();
|
~BUSBInterface();
|
||||||
|
|
||||||
|
void _UpdateDescriptorAndEndpoints();
|
||||||
|
|
||||||
BUSBConfiguration *fConfiguration;
|
BUSBConfiguration *fConfiguration;
|
||||||
uint32 fIndex;
|
uint32 fIndex;
|
||||||
int fRawFD;
|
int fRawFD;
|
||||||
@@ -305,6 +315,11 @@ public:
|
|||||||
usb_iso_packet_descriptor *packetDescriptors,
|
usb_iso_packet_descriptor *packetDescriptors,
|
||||||
uint32 packetCount) const;
|
uint32 packetCount) const;
|
||||||
|
|
||||||
|
// These are convenience methods for getting and clearing the halt
|
||||||
|
// state of an endpoint. They use the control pipe of the device to
|
||||||
|
// send the corresponding requests.
|
||||||
|
bool IsStalled() const;
|
||||||
|
status_t ClearStall() const;
|
||||||
private:
|
private:
|
||||||
friend class BUSBInterface;
|
friend class BUSBInterface;
|
||||||
BUSBEndpoint(BUSBInterface *interface,
|
BUSBEndpoint(BUSBInterface *interface,
|
||||||
|
|||||||
@@ -213,3 +213,23 @@ BUSBEndpoint::IsochronousTransfer(void *data, size_t length,
|
|||||||
|
|
||||||
return command.isochronous.length;
|
return command.isochronous.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BUSBEndpoint::IsStalled() const
|
||||||
|
{
|
||||||
|
uint16 status = 0;
|
||||||
|
Device()->ControlTransfer(USB_REQTYPE_ENDPOINT_IN,
|
||||||
|
USB_REQUEST_GET_STATUS, USB_FEATURE_ENDPOINT_HALT,
|
||||||
|
fDescriptor.endpoint_address & 0x0f, sizeof(status), &status);
|
||||||
|
return status != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BUSBEndpoint::ClearStall() const
|
||||||
|
{
|
||||||
|
return Device()->ControlTransfer(USB_REQTYPE_ENDPOINT_OUT,
|
||||||
|
USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT,
|
||||||
|
fDescriptor.endpoint_address & 0x0f, 0, NULL);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Michael Lotz <[email protected]>
|
* Michael Lotz <[email protected]>
|
||||||
|
* Salvatore Benedetto <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <USBKit.h>
|
#include <USBKit.h>
|
||||||
@@ -19,18 +20,7 @@ BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index, int rawFD)
|
|||||||
fEndpoints(NULL),
|
fEndpoints(NULL),
|
||||||
fInterfaceString(NULL)
|
fInterfaceString(NULL)
|
||||||
{
|
{
|
||||||
raw_command command;
|
_UpdateDescriptorAndEndpoints();
|
||||||
command.interface.descriptor = &fDescriptor;
|
|
||||||
command.interface.config_index = fConfiguration->Index();
|
|
||||||
command.interface.interface_index = fIndex;
|
|
||||||
if (ioctl(fRawFD, RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, &command, sizeof(command))
|
|
||||||
|| command.interface.status != RAW_STATUS_SUCCESS) {
|
|
||||||
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
fEndpoints = new BUSBEndpoint *[fDescriptor.num_endpoints];
|
|
||||||
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
|
||||||
fEndpoints[i] = new BUSBEndpoint(this, i, fRawFD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,3 +138,62 @@ BUSBInterface::EndpointAt(uint32 index) const
|
|||||||
|
|
||||||
return fEndpoints[index];
|
return fEndpoints[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
BUSBInterface::CountAlternates() const
|
||||||
|
{
|
||||||
|
uint32 alternateCount;
|
||||||
|
raw_command command;
|
||||||
|
command.alternate.alternate_count = &alternateCount;
|
||||||
|
command.alternate.config_index = fConfiguration->Index();
|
||||||
|
command.alternate.interface_index = fIndex;
|
||||||
|
if (ioctl(fRawFD, RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command))
|
||||||
|
|| command.alternate.status != RAW_STATUS_SUCCESS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return alternateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BUSBInterface::SetAlternate(uint32 alternateIndex)
|
||||||
|
{
|
||||||
|
raw_command command;
|
||||||
|
command.alternate.config_index = fConfiguration->Index();
|
||||||
|
command.alternate.interface_index = fIndex;
|
||||||
|
command.alternate.alternate_index = alternateIndex;
|
||||||
|
if (ioctl(fRawFD, RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command))
|
||||||
|
|| command.alternate.status != RAW_STATUS_SUCCESS) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
_UpdateDescriptorAndEndpoints();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUSBInterface::_UpdateDescriptorAndEndpoints()
|
||||||
|
{
|
||||||
|
raw_command command;
|
||||||
|
command.interface.descriptor = &fDescriptor;
|
||||||
|
command.interface.config_index = fConfiguration->Index();
|
||||||
|
command.interface.interface_index = fIndex;
|
||||||
|
if (ioctl(fRawFD, RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, &command, sizeof(command))
|
||||||
|
|| command.interface.status != RAW_STATUS_SUCCESS) {
|
||||||
|
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fEndpoints) {
|
||||||
|
// Delete old endpoints
|
||||||
|
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
||||||
|
delete fEndpoints[i];
|
||||||
|
delete fEndpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
fEndpoints = new BUSBEndpoint *[fDescriptor.num_endpoints];
|
||||||
|
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
||||||
|
fEndpoints[i] = new BUSBEndpoint(this, i, fRawFD);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user