* Copyright 2011-2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, kallisti5@unixzen.com
*/
#include "Option.h"
OptionDevice::OptionDevice(usb_device device, uint16 vendorID,
uint16 productID, const char *description)
:
ACMDevice(device, vendorID, productID, description)
{
TRACE_FUNCALLS("> OptionDevice found: %s\n", description);
}
status_t
OptionDevice::AddDevice(const usb_configuration_info *config)
{
TRACE_FUNCALLS("> OptionDevice::AddDevice(%08x, %08x)\n", this, config);
int portsFound = 0;
if (config->interface_count > 0) {
for (size_t index = 0; index < config->interface_count; index++) {
usb_interface_info *interface = config->interface[index].active;
int txEndpointID = -1;
int rxEndpointID = -1;
int irEndpointID = -1;
for (size_t i = 0; i < interface->endpoint_count; i++) {
usb_endpoint_info *endpoint = &interface->endpoint[i];
if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_INTERRUPT
&& (endpoint->descr->endpoint_address
& USB_ENDPOINT_ADDR_DIR_IN) != 0) {
irEndpointID = i;
continue;
}
if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_BULK) {
if ((endpoint->descr->endpoint_address
& USB_ENDPOINT_ADDR_DIR_IN) != 0) {
rxEndpointID = i;
} else {
txEndpointID = i;
}
continue;
}
}
TRACE("> OptionDevice::%s: endpoint %d, tx: %d, rx: %d, ir: %d\n",
__func__, index, txEndpointID, rxEndpointID, irEndpointID);
if (txEndpointID < 0 || rxEndpointID < 0 || irEndpointID < 0)
continue;
TRACE("> OptionDevice::%s: found port at interface %d\n", __func__,
index);
portsFound++;
usb_endpoint_info *irEndpoint = &interface->endpoint[irEndpointID];
usb_endpoint_info *txEndpoint = &interface->endpoint[txEndpointID];
usb_endpoint_info *rxEndpoint = &interface->endpoint[rxEndpointID];
SetControlPipe(irEndpoint->handle);
SetReadPipe(rxEndpoint->handle);
SetWritePipe(txEndpoint->handle);
}
if (portsFound > 0) {
if (portsFound > 1) {
TRACE_ALWAYS("> OptionDevice::%s: Warning: Found more than one "
"serial port on this device (%d). Only the last one is "
"is used.\n", __func__, portsFound);
}
return B_OK;
}
}
return ENODEV;
}
status_t
OptionDevice::ResetDevice()
{
TRACE_FUNCALLS("> OptionDevice::ResetDevice(%08x)\n", this);
return B_OK;
}