haiku/src/kits/device/USBEndpoint.cpp
Michael Lotz bfbbfedc5f * Prepare usb_raw.h for eventually being made public. Prefixed enums values
with B_USB_* and the command union is now usb_raw_command.
* Changed usb_raw and the BUSB* classes accordingly.
* Moved the raw_device struct into usb_raw.cpp as suggested by Francois as it
  was the only thing usb_raw_private.h defined.
* Removed usb_raw_private.h again because of the above.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24861 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-08 07:53:43 +00:00

231 lines
4.9 KiB
C++

/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#include <USBKit.h>
#include <usb_raw.h>
#include <unistd.h>
#include <string.h>
BUSBEndpoint::BUSBEndpoint(BUSBInterface *interface, uint32 index, int rawFD)
: fInterface(interface),
fIndex(index),
fRawFD(rawFD)
{
usb_raw_command command;
command.endpoint.descriptor = &fDescriptor;
command.endpoint.config_index = fInterface->Configuration()->Index();
command.endpoint.interface_index = fInterface->Index();
command.endpoint.endpoint_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, &command,
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
memset(&fDescriptor, 0, sizeof(fDescriptor));
}
BUSBEndpoint::~BUSBEndpoint()
{
}
uint32
BUSBEndpoint::Index() const
{
return fIndex;
}
const BUSBInterface *
BUSBEndpoint::Interface() const
{
return fInterface;
}
const BUSBConfiguration *
BUSBEndpoint::Configuration() const
{
return fInterface->Configuration();
}
const BUSBDevice *
BUSBEndpoint::Device() const
{
return fInterface->Device();
}
bool
BUSBEndpoint::IsBulk() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_BULK;
}
bool
BUSBEndpoint::IsInterrupt() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_INTERRUPT;
}
bool
BUSBEndpoint::IsIsochronous() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_ISOCHRONOUS;
}
bool
BUSBEndpoint::IsControl() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_CONTROL;
}
bool
BUSBEndpoint::IsInput() const
{
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_IN;
}
bool
BUSBEndpoint::IsOutput() const
{
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_OUT;
}
uint16
BUSBEndpoint::MaxPacketSize() const
{
return fDescriptor.max_packet_size;
}
uint8
BUSBEndpoint::Interval() const
{
return fDescriptor.interval;
}
const usb_endpoint_descriptor *
BUSBEndpoint::Descriptor() const
{
return &fDescriptor;
}
ssize_t
BUSBEndpoint::ControlTransfer(uint8 requestType, uint8 request, uint16 value,
uint16 index, uint16 length, void *data) const
{
if (length > 0 && data == NULL)
return B_BAD_VALUE;
usb_raw_command command;
command.control.request_type = requestType;
command.control.request = request;
command.control.value = value;
command.control.index = index;
command.control.length = length;
command.control.data = data;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command,
sizeof(command)) || command.control.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
return command.control.length;
}
ssize_t
BUSBEndpoint::InterruptTransfer(void *data, size_t length) const
{
if (length > 0 && data == NULL)
return B_BAD_VALUE;
usb_raw_command command;
command.transfer.interface = fInterface->Index();
command.transfer.endpoint = fIndex;
command.transfer.data = data;
command.transfer.length = length;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command,
sizeof(command)) || command.transfer.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
return command.transfer.length;
}
ssize_t
BUSBEndpoint::BulkTransfer(void *data, size_t length) const
{
if (length > 0 && data == NULL)
return B_BAD_VALUE;
usb_raw_command command;
command.transfer.interface = fInterface->Index();
command.transfer.endpoint = fIndex;
command.transfer.data = data;
command.transfer.length = length;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command,
sizeof(command)) || command.transfer.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
return command.transfer.length;
}
ssize_t
BUSBEndpoint::IsochronousTransfer(void *data, size_t length,
usb_iso_packet_descriptor *packetDescriptors, uint32 packetCount) const
{
if (length > 0 && data == NULL)
return B_BAD_VALUE;
usb_raw_command command;
command.isochronous.interface = fInterface->Index();
command.isochronous.endpoint = fIndex;
command.isochronous.data = data;
command.isochronous.length = length;
command.isochronous.packet_descriptors = packetDescriptors;
command.isochronous.packet_count = packetCount;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command,
sizeof(command)) || command.isochronous.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
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);
}