1/*
2 * Copyright 2011-2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Alexander von Gluck IV, kallisti5@unixzen.com
7 */
8
9
10#include "Option.h"
11
12
13OptionDevice::OptionDevice(usb_device device, uint16 vendorID,
14	uint16 productID, const char *description)
15	:
16	ACMDevice(device, vendorID, productID, description)
17{
18	TRACE_FUNCALLS("> OptionDevice found: %s\n", description);
19}
20
21
22status_t
23OptionDevice::AddDevice(const usb_configuration_info *config)
24{
25	TRACE_FUNCALLS("> OptionDevice::AddDevice(%08x, %08x)\n", this, config);
26
27	int portsFound = 0;
28	if (config->interface_count > 0) {
29		for (size_t index = 0; index < config->interface_count; index++) {
30			usb_interface_info *interface = config->interface[index].active;
31
32			int txEndpointID = -1;
33			int rxEndpointID = -1;
34			int irEndpointID = -1;
35
36			for (size_t i = 0; i < interface->endpoint_count; i++) {
37				usb_endpoint_info *endpoint = &interface->endpoint[i];
38
39				// Find our Interrupt endpoint
40				if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_INTERRUPT
41					&& (endpoint->descr->endpoint_address
42						& USB_ENDPOINT_ADDR_DIR_IN) != 0) {
43					irEndpointID = i;
44					continue;
45				}
46
47				// Find our Transmit / Receive endpoints
48				if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_BULK) {
49					if ((endpoint->descr->endpoint_address
50						& USB_ENDPOINT_ADDR_DIR_IN) != 0) {
51						rxEndpointID = i;
52					} else {
53						txEndpointID = i;
54					}
55					continue;
56				}
57			}
58
59			TRACE("> OptionDevice::%s: endpoint %d, tx: %d, rx: %d, ir: %d\n",
60				__func__, index, txEndpointID, rxEndpointID, irEndpointID);
61
62			if (txEndpointID < 0 || rxEndpointID < 0 || irEndpointID < 0)
63				continue;
64
65			TRACE("> OptionDevice::%s: found port at interface %d\n", __func__,
66				index);
67			portsFound++;
68
69			usb_endpoint_info *irEndpoint = &interface->endpoint[irEndpointID];
70			usb_endpoint_info *txEndpoint = &interface->endpoint[txEndpointID];
71			usb_endpoint_info *rxEndpoint = &interface->endpoint[rxEndpointID];
72			SetControlPipe(irEndpoint->handle);
73			SetReadPipe(rxEndpoint->handle);
74			SetWritePipe(txEndpoint->handle);
75		}
76
77		// TODO: We need to handle multiple ports
78		// We use the last found serial port for now
79		if (portsFound > 0) {
80			if (portsFound > 1) {
81				TRACE_ALWAYS("> OptionDevice::%s: Warning: Found more than one "
82					"serial port on this device (%d). Only the last one is "
83					"is used.\n", __func__, portsFound);
84			}
85			return B_OK;
86		}
87	}
88	return ENODEV;
89}
90
91
92status_t
93OptionDevice::ResetDevice()
94{
95	TRACE_FUNCALLS("> OptionDevice::ResetDevice(%08x)\n", this);
96	return B_OK;
97}
98