xref: /haiku/src/add-ons/kernel/drivers/ports/usb_serial/Option.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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 
13 OptionDevice::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 
22 status_t
23 OptionDevice::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 
92 status_t
93 OptionDevice::ResetDevice()
94 {
95 	TRACE_FUNCALLS("> OptionDevice::ResetDevice(%08x)\n", this);
96 	return B_OK;
97 }
98