⛏️ index : haiku.git

/*
 * 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];

				// Find our Interrupt endpoint
				if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_INTERRUPT
					&& (endpoint->descr->endpoint_address
						& USB_ENDPOINT_ADDR_DIR_IN) != 0) {
					irEndpointID = i;
					continue;
				}

				// Find our Transmit / Receive endpoints
				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);
		}

		// TODO: We need to handle multiple ports
		// We use the last found serial port for now
		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;
}