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