xref: /haiku/src/add-ons/kernel/bus_managers/usb/BusManager.cpp (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 /*
2  * Copyright 2003-2006, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz <mmlr@mlotz.ch>
7  *		Niels S. Reedijk
8  */
9 
10 #include "usb_p.h"
11 
12 
13 BusManager::BusManager(Stack *stack)
14 	:	fInitOK(false),
15 		fRootHub(NULL)
16 {
17 	if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
18 		TRACE_ERROR(("usb BusManager: failed to create busmanager lock\n"));
19 		return;
20 	}
21 
22 	fRootObject = new(std::nothrow) Object(stack, this);
23 	if (!fRootObject)
24 		return;
25 
26 	// Clear the device map
27 	for (int32 i = 0; i < 128; i++)
28 		fDeviceMap[i] = false;
29 
30 	// Set the default pipes to NULL (these will be created when needed)
31 	for (int32 i = 0; i <= USB_SPEED_MAX; i++)
32 		fDefaultPipes[i] = NULL;
33 
34 	fInitOK = true;
35 }
36 
37 
38 BusManager::~BusManager()
39 {
40 	Lock();
41 	benaphore_destroy(&fLock);
42 	for (int32 i = 0; i <= USB_SPEED_MAX; i++)
43 		delete fDefaultPipes[i];
44 }
45 
46 
47 status_t
48 BusManager::InitCheck()
49 {
50 	if (fInitOK)
51 		return B_OK;
52 
53 	return B_ERROR;
54 }
55 
56 
57 bool
58 BusManager::Lock()
59 {
60 	return (benaphore_lock(&fLock) == B_OK);
61 }
62 
63 
64 void
65 BusManager::Unlock()
66 {
67 	benaphore_unlock(&fLock);
68 }
69 
70 
71 int8
72 BusManager::AllocateAddress()
73 {
74 	if (!Lock())
75 		return -1;
76 
77 	int8 deviceAddress = -1;
78 	for (int32 i = 1; i < 128; i++) {
79 		if (fDeviceMap[i] == false) {
80 			deviceAddress = i;
81 			fDeviceMap[i] = true;
82 			break;
83 		}
84 	}
85 
86 	Unlock();
87 	return deviceAddress;
88 }
89 
90 
91 Device *
92 BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
93 {
94 	// Check if there is a free entry in the device map (for the device number)
95 	int8 deviceAddress = AllocateAddress();
96 	if (deviceAddress < 0) {
97 		TRACE_ERROR(("usb BusManager::AllocateNewDevice(): could not get a new address\n"));
98 		return NULL;
99 	}
100 
101 	TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress));
102 	ControlPipe *defaultPipe = _GetDefaultPipe(speed);
103 
104 	if (!defaultPipe) {
105 		TRACE(("usb BusManager::AllocateNewDevice(): Error getting the default pipe for speed %d\n", (int)speed));
106 		return NULL;
107 	}
108 
109 	status_t result = B_ERROR;
110 	for (int32 i = 0; i < 15; i++) {
111 		// Set the address of the device USB 1.1 spec p202
112 		result = defaultPipe->SendRequest(
113 			USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,	// type
114 			USB_REQUEST_SET_ADDRESS,						// request
115 			deviceAddress,									// value
116 			0,												// index
117 			0,												// length
118 			NULL,											// buffer
119 			0,												// buffer length
120 			NULL);											// actual length
121 
122 		if (result >= B_OK)
123 			break;
124 
125 		snooze(USB_DELAY_SET_ADDRESS_RETRY);
126 	}
127 
128 	if (result < B_OK) {
129 		TRACE_ERROR(("usb BusManager::AllocateNewDevice(): error while setting device address\n"));
130 		return NULL;
131 	}
132 
133 	// Wait a bit for the device to complete addressing
134 	snooze(USB_DELAY_SET_ADDRESS);
135 
136 	// Create a temporary pipe with the new address
137 	ControlPipe pipe(parent, deviceAddress, 0, speed, 8);
138 
139 	// Get the device descriptor
140 	// Just retrieve the first 8 bytes of the descriptor -> minimum supported
141 	// size of any device. It is enough because it includes the device type.
142 
143 	size_t actualLength = 0;
144 	usb_device_descriptor deviceDescriptor;
145 
146 	TRACE(("usb BusManager::AllocateNewDevice(): getting the device descriptor\n"));
147 	pipe.SendRequest(
148 		USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD,		// type
149 		USB_REQUEST_GET_DESCRIPTOR,							// request
150 		USB_DESCRIPTOR_DEVICE << 8,							// value
151 		0,													// index
152 		8,													// length
153 		(void *)&deviceDescriptor,							// buffer
154 		8,													// buffer length
155 		&actualLength);										// actual length
156 
157 	if (actualLength != 8) {
158 		TRACE_ERROR(("usb BusManager::AllocateNewDevice(): error while getting the device descriptor\n"));
159 		return NULL;
160 	}
161 
162 	TRACE(("short device descriptor for device %d:\n", deviceAddress));
163 	TRACE(("\tlength:..............%d\n", deviceDescriptor.length));
164 	TRACE(("\tdescriptor_type:.....0x%04x\n", deviceDescriptor.descriptor_type));
165 	TRACE(("\tusb_version:.........0x%04x\n", deviceDescriptor.usb_version));
166 	TRACE(("\tdevice_class:........0x%02x\n", deviceDescriptor.device_class));
167 	TRACE(("\tdevice_subclass:.....0x%02x\n", deviceDescriptor.device_subclass));
168 	TRACE(("\tdevice_protocol:.....0x%02x\n", deviceDescriptor.device_protocol));
169 	TRACE(("\tmax_packet_size_0:...%d\n", deviceDescriptor.max_packet_size_0));
170 
171 	// Create a new instance based on the type (Hub or Device)
172 	if (deviceDescriptor.device_class == 0x09) {
173 		TRACE(("usb BusManager::AllocateNewDevice(): creating new hub\n"));
174 		Hub *hub = new(std::nothrow) Hub(parent, deviceDescriptor,
175 			deviceAddress, speed);
176 		if (!hub) {
177 			TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n"));
178 			return NULL;
179 		}
180 
181 		if (hub->InitCheck() < B_OK) {
182 			TRACE_ERROR(("usb BusManager::AllocateNewDevice(): hub failed init check\n"));
183 			delete hub;
184 			return NULL;
185 		}
186 
187 		return (Device *)hub;
188 	}
189 
190 	TRACE(("usb BusManager::AllocateNewDevice(): creating new device\n"));
191 	Device *device = new(std::nothrow) Device(parent, deviceDescriptor,
192 		deviceAddress, speed);
193 	if (!device) {
194 		TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate device\n"));
195 		return NULL;
196 	}
197 
198 	if (device->InitCheck() < B_OK) {
199 		TRACE_ERROR(("usb BusManager::AllocateNewDevice(): device failed init check\n"));
200 		delete device;
201 		return NULL;
202 	}
203 
204 	return device;
205 }
206 
207 
208 status_t
209 BusManager::Start()
210 {
211 	return B_OK;
212 }
213 
214 
215 status_t
216 BusManager::Stop()
217 {
218 	return B_OK;
219 }
220 
221 
222 status_t
223 BusManager::SubmitTransfer(Transfer *transfer)
224 {
225 	// virtual function to be overridden
226 	return B_ERROR;
227 }
228 
229 
230 status_t
231 BusManager::NotifyPipeChange(Pipe *pipe, usb_change change)
232 {
233 	// virtual function to be overridden
234 	return B_ERROR;
235 }
236 
237 ControlPipe *
238 BusManager::_GetDefaultPipe(usb_speed speed)
239 {
240 	if (!Lock())
241 		return NULL;
242 
243 
244 	if (fDefaultPipes[speed] == NULL) {
245 		fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject,
246 					0, 0, speed, 8);
247 		if (!fDefaultPipes[speed]) {
248 			TRACE_ERROR(("usb BusManager: failed to allocate default pipe\n"));
249 			Unlock();
250 			return NULL;
251 		}
252 	}
253 
254 	Unlock();
255 
256 	return fDefaultPipes[speed];
257 }
258