xref: /haiku/src/add-ons/kernel/bus_managers/usb/Device.cpp (revision 3e216965baa8d58a67bf7372e2bfa13d999f5a9d)
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 Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
14 	usb_speed speed)
15 	:	Object(parent),
16 		fDeviceDescriptor(desc),
17 		fInitOK(false),
18 		fConfigurations(NULL),
19 		fCurrentConfiguration(NULL),
20 		fSpeed(speed),
21 		fDeviceAddress(deviceAddress)
22 {
23 	TRACE(("USB Device %d: creating device\n", fDeviceAddress));
24 
25 	fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0,
26 		fSpeed, fDeviceDescriptor.max_packet_size_0);
27 	if (!fDefaultPipe) {
28 		TRACE_ERROR(("USB Device %d: could not allocate default pipe\n", fDeviceAddress));
29 		return;
30 	}
31 
32 	// Get the device descriptor
33 	// We already have a part of it, but we want it all
34 	size_t actualLength;
35 	status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0, 0,
36 		(void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor), &actualLength);
37 
38 	if (status < B_OK || actualLength != sizeof(fDeviceDescriptor)) {
39 		TRACE_ERROR(("USB Device %d: error while getting the device descriptor\n", fDeviceAddress));
40 		return;
41 	}
42 
43 	TRACE(("full device descriptor for device %d:\n", fDeviceAddress));
44 	TRACE(("\tlength:..............%d\n", fDeviceDescriptor.length));
45 	TRACE(("\tdescriptor_type:.....0x%04x\n", fDeviceDescriptor.descriptor_type));
46 	TRACE(("\tusb_version:.........0x%04x\n", fDeviceDescriptor.usb_version));
47 	TRACE(("\tdevice_class:........0x%02x\n", fDeviceDescriptor.device_class));
48 	TRACE(("\tdevice_subclass:.....0x%02x\n", fDeviceDescriptor.device_subclass));
49 	TRACE(("\tdevice_protocol:.....0x%02x\n", fDeviceDescriptor.device_protocol));
50 	TRACE(("\tmax_packet_size_0:...%d\n", fDeviceDescriptor.max_packet_size_0));
51 	TRACE(("\tvendor_id:...........0x%04x\n", fDeviceDescriptor.vendor_id));
52 	TRACE(("\tproduct_id:..........0x%04x\n", fDeviceDescriptor.product_id));
53 	TRACE(("\tdevice_version:......0x%04x\n", fDeviceDescriptor.device_version));
54 	TRACE(("\tmanufacturer:........0x%02x\n", fDeviceDescriptor.manufacturer));
55 	TRACE(("\tproduct:.............0x%02x\n", fDeviceDescriptor.product));
56 	TRACE(("\tserial_number:.......0x%02x\n", fDeviceDescriptor.serial_number));
57 	TRACE(("\tnum_configurations:..%d\n", fDeviceDescriptor.num_configurations));
58 
59 	// Get the configurations
60 	fConfigurations = (usb_configuration_info *)malloc(
61 		fDeviceDescriptor.num_configurations * sizeof(usb_configuration_info));
62 	if (fConfigurations == NULL) {
63 		TRACE_ERROR(("USB Device %d: out of memory during config creations!\n", fDeviceAddress));
64 		return;
65 	}
66 
67 	for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
68 		usb_configuration_descriptor configDescriptor;
69 		status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0,
70 			(void *)&configDescriptor, sizeof(usb_configuration_descriptor),
71 			&actualLength);
72 
73 		if (status < B_OK || actualLength != sizeof(usb_configuration_descriptor)) {
74 			TRACE_ERROR(("USB Device %d: error fetching configuration %ld\n", fDeviceAddress, i));
75 			return;
76 		}
77 
78 		TRACE(("USB Device %d: configuration %ld\n", fDeviceAddress, i));
79 		TRACE(("\tlength:..............%d\n", configDescriptor.length));
80 		TRACE(("\tdescriptor_type:.....0x%02x\n", configDescriptor.descriptor_type));
81 		TRACE(("\ttotal_length:........%d\n", configDescriptor.total_length));
82 		TRACE(("\tnumber_interfaces:...%d\n", configDescriptor.number_interfaces));
83 		TRACE(("\tconfiguration_value:.0x%02x\n", configDescriptor.configuration_value));
84 		TRACE(("\tconfiguration:.......0x%02x\n", configDescriptor.configuration));
85 		TRACE(("\tattributes:..........0x%02x\n", configDescriptor.attributes));
86 		TRACE(("\tmax_power:...........%d\n", configDescriptor.max_power));
87 
88 		uint8 *configData = (uint8 *)malloc(configDescriptor.total_length);
89 		status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0,
90 			(void *)configData, configDescriptor.total_length, &actualLength);
91 
92 		if (status < B_OK || actualLength != configDescriptor.total_length) {
93 			TRACE_ERROR(("USB Device %d: error fetching full configuration descriptor %ld\n", fDeviceAddress, i));
94 			return;
95 		}
96 
97 		usb_configuration_descriptor *configuration = (usb_configuration_descriptor *)configData;
98 		fConfigurations[i].descr = configuration;
99 		fConfigurations[i].interface_count = configuration->number_interfaces;
100 		fConfigurations[i].interface = (usb_interface_list *)malloc(
101 			configuration->number_interfaces * sizeof(usb_interface_list));
102 		memset(fConfigurations[i].interface, 0,
103 			configuration->number_interfaces * sizeof(usb_interface_list));
104 
105 		usb_interface_info *currentInterface = NULL;
106 		uint32 descriptorStart = sizeof(usb_configuration_descriptor);
107 		while (descriptorStart < actualLength) {
108 			switch (configData[descriptorStart + 1]) {
109 				case USB_DESCRIPTOR_INTERFACE: {
110 					TRACE(("USB Device %d: got interface descriptor\n", fDeviceAddress));
111 					usb_interface_descriptor *interfaceDescriptor = (usb_interface_descriptor *)&configData[descriptorStart];
112 					TRACE(("\tlength:.............%d\n", interfaceDescriptor->length));
113 					TRACE(("\tdescriptor_type:....0x%02x\n", interfaceDescriptor->descriptor_type));
114 					TRACE(("\tinterface_number:...%d\n", interfaceDescriptor->interface_number));
115 					TRACE(("\talternate_setting:..%d\n", interfaceDescriptor->alternate_setting));
116 					TRACE(("\tnum_endpoints:......%d\n", interfaceDescriptor->num_endpoints));
117 					TRACE(("\tinterface_class:....0x%02x\n", interfaceDescriptor->interface_class));
118 					TRACE(("\tinterface_subclass:.0x%02x\n", interfaceDescriptor->interface_subclass));
119 					TRACE(("\tinterface_protocol:.0x%02x\n", interfaceDescriptor->interface_protocol));
120 					TRACE(("\tinterface:..........%d\n", interfaceDescriptor->interface));
121 
122 					usb_interface_list *interfaceList =
123 						&fConfigurations[i].interface[interfaceDescriptor->interface_number];
124 
125 					/* allocate this alternate */
126 					interfaceList->alt_count++;
127 					interfaceList->alt = (usb_interface_info *)realloc(
128 						interfaceList->alt, interfaceList->alt_count
129 						* sizeof(usb_interface_info));
130 					interfaceList->active = interfaceList->alt;
131 
132 					/* setup this alternate */
133 					usb_interface_info *interfaceInfo =
134 						&interfaceList->alt[interfaceList->alt_count - 1];
135 					interfaceInfo->descr = interfaceDescriptor;
136 					interfaceInfo->endpoint_count = 0;
137 					interfaceInfo->endpoint = NULL;
138 					interfaceInfo->generic_count = 0;
139 					interfaceInfo->generic = NULL;
140 
141 					Interface *interface = new(std::nothrow) Interface(this,
142 						interfaceDescriptor->interface_number);
143 					interfaceInfo->handle = interface->USBID();
144 
145 					currentInterface = interfaceInfo;
146 					break;
147 				}
148 
149 				case USB_DESCRIPTOR_ENDPOINT: {
150 					TRACE(("USB Device %d: got endpoint descriptor\n", fDeviceAddress));
151 					usb_endpoint_descriptor *endpointDescriptor = (usb_endpoint_descriptor *)&configData[descriptorStart];
152 					TRACE(("\tlength:.............%d\n", endpointDescriptor->length));
153 					TRACE(("\tdescriptor_type:....0x%02x\n", endpointDescriptor->descriptor_type));
154 					TRACE(("\tendpoint_address:...0x%02x\n", endpointDescriptor->endpoint_address));
155 					TRACE(("\tattributes:.........0x%02x\n", endpointDescriptor->attributes));
156 					TRACE(("\tmax_packet_size:....%d\n", endpointDescriptor->max_packet_size));
157 					TRACE(("\tinterval:...........%d\n", endpointDescriptor->interval));
158 
159 					if (!currentInterface)
160 						break;
161 
162 					/* allocate this endpoint */
163 					currentInterface->endpoint_count++;
164 					currentInterface->endpoint = (usb_endpoint_info *)realloc(
165 						currentInterface->endpoint,
166 						currentInterface->endpoint_count
167 						* sizeof(usb_endpoint_info));
168 
169 					/* setup this endpoint */
170 					usb_endpoint_info *endpointInfo =
171 						&currentInterface->endpoint[currentInterface->endpoint_count - 1];
172 					endpointInfo->descr = endpointDescriptor;
173 					endpointInfo->handle = 0;
174 					break;
175 				}
176 
177 				default:
178 					TRACE(("USB Device %d: got generic descriptor\n", fDeviceAddress));
179 					usb_generic_descriptor *genericDescriptor = (usb_generic_descriptor *)&configData[descriptorStart];
180 					TRACE(("\tlength:.............%d\n", genericDescriptor->length));
181 					TRACE(("\tdescriptor_type:....0x%02x\n", genericDescriptor->descriptor_type));
182 
183 					if (!currentInterface)
184 						break;
185 
186 					/* allocate this descriptor */
187 					currentInterface->generic_count++;
188 					currentInterface->generic = (usb_descriptor **)realloc(
189 						currentInterface->generic,
190 						currentInterface->generic_count
191 						* sizeof(usb_descriptor *));
192 
193 					/* add this descriptor */
194 					currentInterface->generic[currentInterface->generic_count - 1] =
195 						(usb_descriptor *)genericDescriptor;
196 					break;
197 			}
198 
199 			descriptorStart += configData[descriptorStart];
200 		}
201 	}
202 
203 	// Set default configuration
204 	TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress));
205 	if (SetConfigurationAt(0) < B_OK) {
206 		TRACE_ERROR(("USB Device %d: failed to set default configuration\n", fDeviceAddress));
207 		return;
208 	}
209 
210 	fInitOK = true;
211 }
212 
213 
214 Device::~Device()
215 {
216 	// Destroy open endpoints. Do not send a device request to unconfigure
217 	// though, since we may be deleted because the device was unplugged
218 	// already.
219 	Unconfigure(false);
220 
221 	// Free all allocated resources
222 	for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
223 		usb_configuration_info *configuration = &fConfigurations[i];
224 		for (size_t j = 0; j < configuration->interface_count; j++) {
225 			usb_interface_list *interfaceList = configuration->interface;
226 			for (size_t k = 0; k < interfaceList->alt_count; k++) {
227 				usb_interface_info *interface = &interfaceList->alt[k];
228 				delete (Interface *)GetStack()->GetObject(interface->handle);
229 				free(interface->endpoint);
230 				free(interface->generic);
231 			}
232 
233 			free(interfaceList->alt);
234 		}
235 
236 		free(configuration->interface);
237 		free(configuration->descr);
238 	}
239 
240 	free(fConfigurations);
241 	delete fDefaultPipe;
242 }
243 
244 
245 status_t
246 Device::InitCheck()
247 {
248 	if (fInitOK)
249 		return B_OK;
250 
251 	return B_ERROR;
252 }
253 
254 
255 status_t
256 Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
257 	void *data, size_t dataLength, size_t *actualLength)
258 {
259 	return fDefaultPipe->SendRequest(
260 		USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD,		// type
261 		USB_REQUEST_GET_DESCRIPTOR,							// request
262 		(descriptorType << 8) | index,						// value
263 		languageID,											// index
264 		dataLength,											// length
265 		data,												// buffer
266 		dataLength,											// buffer length
267 		actualLength);										// actual length
268 }
269 
270 
271 const usb_configuration_info *
272 Device::Configuration() const
273 {
274 	return fCurrentConfiguration;
275 }
276 
277 
278 const usb_configuration_info *
279 Device::ConfigurationAt(uint8 index) const
280 {
281 	if (index >= fDeviceDescriptor.num_configurations)
282 		return NULL;
283 
284 	return &fConfigurations[index];
285 }
286 
287 
288 status_t
289 Device::SetConfiguration(const usb_configuration_info *configuration)
290 {
291 	if (!configuration)
292 		return Unconfigure(true);
293 
294 	for (uint8 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
295 		if (configuration->descr->configuration_value
296 			== fConfigurations[i].descr->configuration_value)
297 			return SetConfigurationAt(i);
298 	}
299 
300 	return B_BAD_VALUE;
301 }
302 
303 
304 status_t
305 Device::SetConfigurationAt(uint8 index)
306 {
307 	if (index >= fDeviceDescriptor.num_configurations)
308 		return B_BAD_VALUE;
309 	if (&fConfigurations[index] == fCurrentConfiguration)
310 		return B_OK;
311 
312 	// Destroy our open endpoints
313 	Unconfigure(false);
314 
315 	// Tell the device to set the configuration
316 	status_t result = fDefaultPipe->SendRequest(
317 		USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD,		// type
318 		USB_REQUEST_SET_CONFIGURATION,						// request
319 		fConfigurations[index].descr->configuration_value,	// value
320 		0,													// index
321 		0,													// length
322 		NULL,												// buffer
323 		0,													// buffer length
324 		NULL);												// actual length
325 
326 	if (result < B_OK)
327 		return result;
328 
329 	// Set current configuration
330 	fCurrentConfiguration = &fConfigurations[index];
331 
332 	// Initialize all the endpoints that are now active
333 	usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[0].active;
334 	for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) {
335 		usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i];
336 		Pipe *pipe = NULL;
337 
338 		switch (endpoint->descr->attributes & 0x03) {
339 			case 0x00: /* Control Endpoint */
340 				pipe = new(std::nothrow) ControlPipe(this, fDeviceAddress,
341 					endpoint->descr->endpoint_address & 0x0f, fSpeed,
342 					endpoint->descr->max_packet_size);
343 				break;
344 
345 			case 0x01: /* Isochronous Endpoint */
346 				pipe = new(std::nothrow) IsochronousPipe(this, fDeviceAddress,
347 					endpoint->descr->endpoint_address & 0x0f,
348 					(endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
349 					fSpeed, endpoint->descr->max_packet_size);
350 				break;
351 
352 			case 0x02: /* Bulk Endpoint */
353 				pipe = new(std::nothrow) BulkPipe(this, fDeviceAddress,
354 					endpoint->descr->endpoint_address & 0x0f,
355 					(endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
356 					fSpeed, endpoint->descr->max_packet_size);
357 				break;
358 
359 			case 0x03: /* Interrupt Endpoint */
360 				pipe = new(std::nothrow) InterruptPipe(this, fDeviceAddress,
361 					endpoint->descr->endpoint_address & 0x0f,
362 					(endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
363 					fSpeed, endpoint->descr->max_packet_size);
364 				break;
365 		}
366 
367 		endpoint->handle = pipe->USBID();
368 	}
369 
370 	// Wait some for the configuration being finished
371 	snooze(USB_DELAY_SET_CONFIGURATION);
372 	return B_OK;
373 }
374 
375 
376 status_t
377 Device::Unconfigure(bool atDeviceLevel)
378 {
379 	// if we only want to destroy our open pipes before setting
380 	// another configuration unconfigure will be called with
381 	// atDevice = false. otherwise we explicitly want to unconfigure
382 	// the device and have to send it the corresponding request.
383 	if (atDeviceLevel) {
384 		status_t result = fDefaultPipe->SendRequest(
385 			USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD,	// type
386 			USB_REQUEST_SET_CONFIGURATION,					// request
387 			0,												// value
388 			0,												// index
389 			0,												// length
390 			NULL,											// buffer
391 			0,												// buffer length
392 			NULL);											// actual length
393 
394 		if (result < B_OK)
395 			return result;
396 
397 		snooze(USB_DELAY_SET_CONFIGURATION);
398 	}
399 
400 	if (!fCurrentConfiguration)
401 		return B_OK;
402 
403 	usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[0].active;
404 	for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) {
405 		usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i];
406 		delete (Pipe *)GetStack()->GetObject(endpoint->handle);
407 		endpoint->handle = 0;
408 	}
409 
410 	fCurrentConfiguration = NULL;
411 	return B_OK;
412 }
413 
414 
415 const usb_device_descriptor *
416 Device::DeviceDescriptor() const
417 {
418 	return &fDeviceDescriptor;
419 }
420 
421 
422 status_t
423 Device::ReportDevice(usb_support_descriptor *supportDescriptors,
424 	uint32 supportDescriptorCount, const usb_notify_hooks *hooks,
425 	usb_driver_cookie **cookies, bool added)
426 {
427 	TRACE(("USB Device %d: reporting device\n", fDeviceAddress));
428 	bool supported = false;
429 	if (supportDescriptorCount == 0 || supportDescriptors == NULL)
430 		supported = true;
431 
432 	for (uint32 i = 0; !supported && i < supportDescriptorCount; i++) {
433 		if ((supportDescriptors[i].vendor != 0
434 			&& fDeviceDescriptor.vendor_id != supportDescriptors[i].vendor)
435 			|| (supportDescriptors[i].product != 0
436 			&& fDeviceDescriptor.product_id != supportDescriptors[i].product))
437 			continue;
438 
439 		if ((supportDescriptors[i].dev_class == 0
440 			|| fDeviceDescriptor.device_class == supportDescriptors[i].dev_class)
441 			&& (supportDescriptors[i].dev_subclass == 0
442 			|| fDeviceDescriptor.device_subclass == supportDescriptors[i].dev_subclass)
443 			&& (supportDescriptors[i].dev_protocol == 0
444 			|| fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) {
445 			supported = true;
446 		}
447 
448 		// we have to check all interfaces for matching class/subclass/protocol
449 		for (uint32 j = 0; !supported && j < fDeviceDescriptor.num_configurations; j++) {
450 			for (uint32 k = 0; !supported && k < fConfigurations[j].interface_count; k++) {
451 				for (uint32 l = 0; !supported && l < fConfigurations[j].interface[k].alt_count; l++) {
452 					usb_interface_descriptor *descriptor = fConfigurations[j].interface[k].alt[l].descr;
453 					if ((supportDescriptors[i].dev_class == 0
454 						|| descriptor->interface_class == supportDescriptors[i].dev_class)
455 						&& (supportDescriptors[i].dev_subclass == 0
456 						|| descriptor->interface_subclass == supportDescriptors[i].dev_subclass)
457 						&& (supportDescriptors[i].dev_protocol == 0
458 						|| descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) {
459 						supported = true;
460 					}
461 				}
462 			}
463 		}
464 	}
465 
466 	if (!supported)
467 		return B_UNSUPPORTED;
468 
469 	if ((added && hooks->device_added == NULL)
470 		|| (!added && hooks->device_removed == NULL)) {
471 		// hooks are not installed, but report success to indicate that
472 		// the driver supports the device
473 		return B_OK;
474 	}
475 
476 	usb_id id = USBID();
477 	if (added) {
478 		usb_driver_cookie *cookie = new(std::nothrow) usb_driver_cookie;
479 		if (hooks->device_added(id, &cookie->cookie) >= B_OK) {
480 			cookie->device = id;
481 			cookie->link = *cookies;
482 			*cookies = cookie;
483 		} else
484 			delete cookie;
485 	} else {
486 		usb_driver_cookie **pointer = cookies;
487 		usb_driver_cookie *cookie = *cookies;
488 		while (cookie) {
489 			if (cookie->device == id)
490 				break;
491 			pointer = &cookie->link;
492 			cookie = cookie->link;
493 		}
494 
495 		if (!cookie) {
496 			// the device is supported, but there is no cookie. this most
497 			// probably means that the device_added hook above failed.
498 			return B_OK;
499 		}
500 
501 		hooks->device_removed(cookie->cookie);
502 		*pointer = cookie->link;
503 		delete cookie;
504 	}
505 
506 	return B_OK;
507 }
508 
509 
510 status_t
511 Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
512 	Device *device)
513 {
514 	if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0)
515 		return B_ERROR;
516 
517 	((Hub *)Parent())->BuildDeviceName(string, index, bufferSize, this);
518 	return B_OK;
519 }
520 
521 
522 status_t
523 Device::SetFeature(uint16 selector)
524 {
525 	return fDefaultPipe->SendRequest(
526 		USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
527 		USB_REQUEST_SET_FEATURE,
528 		selector,
529 		0,
530 		0,
531 		NULL,
532 		0,
533 		NULL);
534 }
535 
536 
537 status_t
538 Device::ClearFeature(uint16 selector)
539 {
540 	return fDefaultPipe->SendRequest(
541 		USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
542 		USB_REQUEST_CLEAR_FEATURE,
543 		selector,
544 		0,
545 		0,
546 		NULL,
547 		0,
548 		NULL);
549 }
550 
551 
552 status_t
553 Device::GetStatus(uint16 *status)
554 {
555 	return fDefaultPipe->SendRequest(
556 		USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN,
557 		USB_REQUEST_GET_STATUS,
558 		0,
559 		0,
560 		2,
561 		(void *)status,
562 		2,
563 		NULL);
564 }
565