xref: /haiku/src/add-ons/kernel/busses/usb/ohci.cpp (revision f967e2c0c73efb25581afdc95a838f7633e8c03b)
1 /*
2  * Copyright 2005-2013, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jan-Rixt Van Hoye
7  *		Salvatore Benedetto <salvatore.benedetto@gmail.com>
8  *		Michael Lotz <mmlr@mlotz.ch>
9  *		Siarzhuk Zharski <imker@gmx.li>
10  */
11 
12 
13 #include <stdio.h>
14 
15 #include <module.h>
16 #include <bus/PCI.h>
17 #include <USB3.h>
18 #include <KernelExport.h>
19 #include <util/AutoLock.h>
20 
21 #include "ohci.h"
22 
23 
24 #define CALLED(x...)	TRACE_MODULE("CALLED %s\n", __PRETTY_FUNCTION__)
25 
26 #define USB_MODULE_NAME "ohci"
27 
28 device_manager_info* gDeviceManager;
29 static usb_for_controller_interface* gUSB;
30 
31 
32 #define OHCI_PCI_DEVICE_MODULE_NAME "busses/usb/ohci/pci/driver_v1"
33 #define OHCI_PCI_USB_BUS_MODULE_NAME "busses/usb/ohci/device_v1"
34 
35 
36 typedef struct {
37 	OHCI* ohci;
38 	pci_device_module_info* pci;
39 	pci_device* device;
40 
41 	pci_info pciinfo;
42 
43 	device_node* node;
44 	device_node* driver_node;
45 } ohci_pci_sim_info;
46 
47 
48 //	#pragma mark -
49 
50 
51 static status_t
52 init_bus(device_node* node, void** bus_cookie)
53 {
54 	CALLED();
55 
56 	driver_module_info* driver;
57 	ohci_pci_sim_info* bus;
58 	device_node* parent = gDeviceManager->get_parent_node(node);
59 	gDeviceManager->get_driver(parent, &driver, (void**)&bus);
60 	gDeviceManager->put_node(parent);
61 
62 	Stack *stack;
63 	if (gUSB->get_stack((void**)&stack) != B_OK)
64 		return B_ERROR;
65 
66 	OHCI *ohci = new(std::nothrow) OHCI(&bus->pciinfo, bus->pci, bus->device, stack, node);
67 	if (ohci == NULL) {
68 		return B_NO_MEMORY;
69 	}
70 
71 	if (ohci->InitCheck() < B_OK) {
72 		TRACE_MODULE_ERROR("bus failed init check\n");
73 		delete ohci;
74 		return B_ERROR;
75 	}
76 
77 	if (ohci->Start() != B_OK) {
78 		delete ohci;
79 		return B_ERROR;
80 	}
81 
82 	*bus_cookie = ohci;
83 
84 	return B_OK;
85 }
86 
87 
88 static void
89 uninit_bus(void* bus_cookie)
90 {
91 	CALLED();
92 	OHCI* ohci = (OHCI*)bus_cookie;
93 	delete ohci;
94 }
95 
96 
97 static status_t
98 register_child_devices(void* cookie)
99 {
100 	CALLED();
101 	ohci_pci_sim_info* bus = (ohci_pci_sim_info*)cookie;
102 	device_node* node = bus->driver_node;
103 
104 	char prettyName[25];
105 	sprintf(prettyName, "OHCI Controller %" B_PRIu16, 0);
106 
107 	device_attr attrs[] = {
108 		// properties of this controller for the usb bus manager
109 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
110 			{ .string = prettyName }},
111 		{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
112 			{ .string = USB_FOR_CONTROLLER_MODULE_NAME }},
113 
114 		// private data to identify the device
115 		{ NULL }
116 	};
117 
118 	return gDeviceManager->register_node(node, OHCI_PCI_USB_BUS_MODULE_NAME,
119 		attrs, NULL, NULL);
120 }
121 
122 
123 static status_t
124 init_device(device_node* node, void** device_cookie)
125 {
126 	CALLED();
127 	ohci_pci_sim_info* bus = (ohci_pci_sim_info*)calloc(1,
128 		sizeof(ohci_pci_sim_info));
129 	if (bus == NULL)
130 		return B_NO_MEMORY;
131 
132 	pci_device_module_info* pci;
133 	pci_device* device;
134 	{
135 		device_node* pciParent = gDeviceManager->get_parent_node(node);
136 		gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci,
137 			(void**)&device);
138 		gDeviceManager->put_node(pciParent);
139 	}
140 
141 	bus->pci = pci;
142 	bus->device = device;
143 	bus->driver_node = node;
144 
145 	pci_info *pciInfo = &bus->pciinfo;
146 	pci->get_pci_info(device, pciInfo);
147 
148 	*device_cookie = bus;
149 	return B_OK;
150 }
151 
152 
153 static void
154 uninit_device(void* device_cookie)
155 {
156 	CALLED();
157 	ohci_pci_sim_info* bus = (ohci_pci_sim_info*)device_cookie;
158 	free(bus);
159 }
160 
161 
162 static status_t
163 register_device(device_node* parent)
164 {
165 	CALLED();
166 	device_attr attrs[] = {
167 		{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "OHCI PCI"}},
168 		{}
169 	};
170 
171 	return gDeviceManager->register_node(parent,
172 		OHCI_PCI_DEVICE_MODULE_NAME, attrs, NULL, NULL);
173 }
174 
175 
176 static float
177 supports_device(device_node* parent)
178 {
179 	CALLED();
180 	const char* bus;
181 	uint16 type, subType, api;
182 
183 	// make sure parent is a OHCI PCI device node
184 	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)
185 		< B_OK) {
186 		return -1;
187 	}
188 
189 	if (strcmp(bus, "pci") != 0)
190 		return 0.0f;
191 
192 	if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subType,
193 			false) < B_OK
194 		|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &type,
195 			false) < B_OK
196 		|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_INTERFACE, &api,
197 			false) < B_OK) {
198 		TRACE_MODULE("Could not find type/subtype/interface attributes\n");
199 		return -1;
200 	}
201 
202 	if (type == PCI_serial_bus && subType == PCI_usb && api == PCI_usb_ohci) {
203 		pci_device_module_info* pci;
204 		pci_device* device;
205 		gDeviceManager->get_driver(parent, (driver_module_info**)&pci,
206 			(void**)&device);
207 		TRACE_MODULE("OHCI Device found!\n");
208 
209 		return 0.8f;
210 	}
211 
212 	return 0.0f;
213 }
214 
215 
216 module_dependency module_dependencies[] = {
217 	{ USB_FOR_CONTROLLER_MODULE_NAME, (module_info**)&gUSB },
218 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager },
219 	{}
220 };
221 
222 
223 static usb_bus_interface gOHCIPCIDeviceModule = {
224 	{
225 		{
226 			OHCI_PCI_USB_BUS_MODULE_NAME,
227 			0,
228 			NULL
229 		},
230 		NULL,  // supports device
231 		NULL,  // register device
232 		init_bus,
233 		uninit_bus,
234 		NULL,  // register child devices
235 		NULL,  // rescan
236 		NULL,  // device removed
237 	},
238 };
239 
240 // Root device that binds to the PCI bus. It will register an usb_bus_interface
241 // node for each device.
242 static driver_module_info sOHCIDevice = {
243 	{
244 		OHCI_PCI_DEVICE_MODULE_NAME,
245 		0,
246 		NULL
247 	},
248 	supports_device,
249 	register_device,
250 	init_device,
251 	uninit_device,
252 	register_child_devices,
253 	NULL, // rescan
254 	NULL, // device removed
255 };
256 
257 module_info* modules[] = {
258 	(module_info* )&sOHCIDevice,
259 	(module_info* )&gOHCIPCIDeviceModule,
260 	NULL
261 };
262 
263 
264 //
265 // #pragma mark -
266 //
267 
268 
269 OHCI::OHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stack *stack,
270 	device_node* node)
271 	:	BusManager(stack, node),
272 		fPCIInfo(info),
273 		fPci(pci),
274 		fDevice(device),
275 		fStack(stack),
276 		fOperationalRegisters(NULL),
277 		fRegisterArea(-1),
278 		fHccaArea(-1),
279 		fHcca(NULL),
280 		fInterruptEndpoints(NULL),
281 		fDummyControl(NULL),
282 		fDummyBulk(NULL),
283 		fDummyIsochronous(NULL),
284 		fFirstTransfer(NULL),
285 		fLastTransfer(NULL),
286 		fFinishTransfersSem(-1),
287 		fFinishThread(-1),
288 		fStopFinishThread(false),
289 		fProcessingPipe(NULL),
290 		fFrameBandwidth(NULL),
291 		fRootHub(NULL),
292 		fRootHubAddress(0),
293 		fPortCount(0),
294 		fIRQ(0),
295 		fUseMSI(false)
296 {
297 	if (!fInitOK) {
298 		TRACE_ERROR("bus manager failed to init\n");
299 		return;
300 	}
301 
302 	TRACE("constructing new OHCI host controller driver\n");
303 	fInitOK = false;
304 
305 	mutex_init(&fEndpointLock, "ohci endpoint lock");
306 
307 	// enable busmaster and memory mapped access
308 	uint16 command = fPci->read_pci_config(fDevice, PCI_command, 2);
309 	command &= ~PCI_command_io;
310 	command |= PCI_command_master | PCI_command_memory;
311 
312 	fPci->write_pci_config(fDevice, PCI_command, 2, command);
313 
314 	// map the registers
315 	uint32 offset = fPci->read_pci_config(fDevice, PCI_base_registers, 4);
316 	offset &= PCI_address_memory_32_mask;
317 	TRACE_ALWAYS("iospace offset: 0x%" B_PRIx32 "\n", offset);
318 	fRegisterArea = map_physical_memory("OHCI memory mapped registers",
319 		offset,	B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS,
320 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
321 		(void **)&fOperationalRegisters);
322 	if (fRegisterArea < B_OK) {
323 		TRACE_ERROR("failed to map register memory\n");
324 		return;
325 	}
326 
327 	TRACE("mapped operational registers: %p\n", fOperationalRegisters);
328 
329 	// Check the revision of the controller, which should be 10h
330 	uint32 revision = _ReadReg(OHCI_REVISION) & 0xff;
331 	TRACE("version %" B_PRId32 ".%" B_PRId32 "%s\n",
332 		OHCI_REVISION_HIGH(revision), OHCI_REVISION_LOW(revision),
333 		OHCI_REVISION_LEGACY(revision) ? ", legacy support" : "");
334 
335 	if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) {
336 		TRACE_ERROR("unsupported OHCI revision\n");
337 		return;
338 	}
339 
340 	phys_addr_t hccaPhysicalAddress;
341 	fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress,
342 		sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area");
343 
344 	if (fHccaArea < B_OK) {
345 		TRACE_ERROR("unable to create the HCCA block area\n");
346 		return;
347 	}
348 
349 	memset(fHcca, 0, sizeof(ohci_hcca));
350 
351 	// Set Up Host controller
352 	// Dummy endpoints
353 	fDummyControl = _AllocateEndpoint();
354 	if (!fDummyControl)
355 		return;
356 
357 	fDummyBulk = _AllocateEndpoint();
358 	if (!fDummyBulk) {
359 		_FreeEndpoint(fDummyControl);
360 		return;
361 	}
362 
363 	fDummyIsochronous = _AllocateEndpoint();
364 	if (!fDummyIsochronous) {
365 		_FreeEndpoint(fDummyControl);
366 		_FreeEndpoint(fDummyBulk);
367 		return;
368 	}
369 
370 	// Static endpoints that get linked in the HCCA
371 	fInterruptEndpoints = new(std::nothrow)
372 		ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT];
373 	if (!fInterruptEndpoints) {
374 		TRACE_ERROR("failed to allocate memory for interrupt endpoints\n");
375 		_FreeEndpoint(fDummyControl);
376 		_FreeEndpoint(fDummyBulk);
377 		_FreeEndpoint(fDummyIsochronous);
378 		return;
379 	}
380 
381 	for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) {
382 		fInterruptEndpoints[i] = _AllocateEndpoint();
383 		if (!fInterruptEndpoints[i]) {
384 			TRACE_ERROR("failed to allocate interrupt endpoint %" B_PRId32 "\n",
385 				i);
386 			while (--i >= 0)
387 				_FreeEndpoint(fInterruptEndpoints[i]);
388 			_FreeEndpoint(fDummyBulk);
389 			_FreeEndpoint(fDummyControl);
390 			_FreeEndpoint(fDummyIsochronous);
391 			return;
392 		}
393 	}
394 
395 	// build flat tree so that at each of the static interrupt endpoints
396 	// fInterruptEndpoints[i] == interrupt endpoint for interval 2^i
397 	uint32 interval = OHCI_BIGGEST_INTERVAL;
398 	uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1;
399 	while (interval > 1) {
400 		uint32 insertIndex = interval / 2;
401 		while (insertIndex < OHCI_BIGGEST_INTERVAL) {
402 			fHcca->interrupt_table[insertIndex]
403 				= fInterruptEndpoints[intervalIndex]->physical_address;
404 			insertIndex += interval;
405 		}
406 
407 		intervalIndex--;
408 		interval /= 2;
409 	}
410 
411 	// setup the empty slot in the list and linking of all -> first
412 	fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address;
413 	for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) {
414 		fInterruptEndpoints[i]->next_physical_endpoint
415 			= fInterruptEndpoints[0]->physical_address;
416 		fInterruptEndpoints[i]->next_logical_endpoint
417 			= fInterruptEndpoints[0];
418 	}
419 
420 	// Now link the first endpoint to the isochronous endpoint
421 	fInterruptEndpoints[0]->next_physical_endpoint
422 		= fDummyIsochronous->physical_address;
423 
424 	// When the handover from SMM takes place, all interrupts are routed to the
425 	// OS. As we don't yet have an interrupt handler installed at this point,
426 	// this may cause interrupt storms if the firmware does not disable the
427 	// interrupts during handover. Therefore we disable interrupts before
428 	// requesting ownership. We have to keep the ownership change interrupt
429 	// enabled though, as otherwise the SMM will not be notified of the
430 	// ownership change request we trigger below.
431 	_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS &
432 		~OHCI_OWNERSHIP_CHANGE) ;
433 
434 	// Determine in what context we are running (Kindly copied from FreeBSD)
435 	uint32 control = _ReadReg(OHCI_CONTROL);
436 	if (control & OHCI_INTERRUPT_ROUTING) {
437 		TRACE_ALWAYS("smm is in control of the host controller\n");
438 		uint32 status = _ReadReg(OHCI_COMMAND_STATUS);
439 		_WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST);
440 		for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) {
441 			snooze(1000);
442 			control = _ReadReg(OHCI_CONTROL);
443 		}
444 
445 		if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
446 			TRACE_ERROR("smm does not respond.\n");
447 
448 			// TODO: Enable this reset as soon as the non-specified
449 			// reset a few lines later is replaced by a better solution.
450 			//_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
451 			//snooze(USB_DELAY_BUS_RESET);
452 		} else
453 			TRACE_ALWAYS("ownership change successful\n");
454 	} else {
455 		TRACE("cold started\n");
456 		snooze(USB_DELAY_BUS_RESET);
457 	}
458 
459 	// TODO: This reset delays system boot time. It should not be necessary
460 	// according to the OHCI spec, but without it some controllers don't start.
461 	_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
462 	snooze(USB_DELAY_BUS_RESET);
463 
464 	// We now own the host controller and the bus has been reset
465 	uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);
466 	uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval);
467 
468 	_WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET);
469 	// Nominal time for a reset is 10 us
470 	uint32 reset = 0;
471 	for (uint32 i = 0; i < 10; i++) {
472 		spin(10);
473 		reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET;
474 		if (reset == 0)
475 			break;
476 	}
477 
478 	if (reset) {
479 		TRACE_ERROR("error resetting the host controller (timeout)\n");
480 		return;
481 	}
482 
483 	// The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL.
484 
485 	// Set up host controller register
486 	_WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress);
487 	_WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address);
488 	_WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address);
489 	// Switch on desired functional features
490 	control = _ReadReg(OHCI_CONTROL);
491 	control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST
492 		| OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING);
493 	control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4
494 		| OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL;
495 	// And finally start the controller
496 	_WriteReg(OHCI_CONTROL, control);
497 
498 	// The controller is now OPERATIONAL.
499 	frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
500 		^ OHCI_FRAME_INTERVAL_TOGGLE;
501 	frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue;
502 	_WriteReg(OHCI_FRAME_INTERVAL, frameInterval);
503 	// 90% periodic
504 	uint32 periodic = OHCI_PERIODIC(intervalValue);
505 	_WriteReg(OHCI_PERIODIC_START, periodic);
506 
507 	// Fiddle the No Over Current Protection bit to avoid chip bug
508 	uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A);
509 	_WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
510 	_WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
511 	snooze(OHCI_ENABLE_POWER_DELAY);
512 	_WriteReg(OHCI_RH_DESCRIPTOR_A, desca);
513 
514 	// The AMD756 requires a delay before re-reading the register,
515 	// otherwise it will occasionally report 0 ports.
516 	uint32 numberOfPorts = 0;
517 	for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) {
518 		snooze(OHCI_READ_DESC_DELAY);
519 		uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A);
520 		numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor);
521 	}
522 	if (numberOfPorts > OHCI_MAX_PORT_COUNT)
523 		numberOfPorts = OHCI_MAX_PORT_COUNT;
524 	fPortCount = numberOfPorts;
525 	TRACE("port count is %d\n", fPortCount);
526 
527 	// Create the array that will keep bandwidth information
528 	fFrameBandwidth = new(std::nothrow) uint16[NUMBER_OF_FRAMES];
529 
530 	for (int32 i = 0; i < NUMBER_OF_FRAMES; i++)
531 		fFrameBandwidth[i] = MAX_AVAILABLE_BANDWIDTH;
532 
533 	// Create semaphore the finisher thread will wait for
534 	fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers");
535 	if (fFinishTransfersSem < B_OK) {
536 		TRACE_ERROR("failed to create semaphore\n");
537 		return;
538 	}
539 
540 	// Create the finisher service thread
541 	fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread",
542 		B_URGENT_DISPLAY_PRIORITY, (void *)this);
543 	resume_thread(fFinishThread);
544 
545 	// Find the right interrupt vector, using MSIs if available.
546 	fIRQ = fPCIInfo->u.h0.interrupt_line;
547 	if (fPci->get_msi_count(fDevice) >= 1) {
548 		uint8 msiVector = 0;
549 		if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
550 			&& fPci->enable_msi(fDevice) == B_OK) {
551 			TRACE_ALWAYS("using message signaled interrupts\n");
552 			fIRQ = msiVector;
553 			fUseMSI = true;
554 		}
555 	}
556 
557 	if (fIRQ == 0 || fIRQ == 0xFF) {
558 		TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
559 			fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
560 		return;
561 	}
562 
563 	// Install the interrupt handler
564 	TRACE("installing interrupt handler\n");
565 	install_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this, 0);
566 
567 	// Enable interesting interrupts now that the handler is in place
568 	_WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
569 		| OHCI_MASTER_INTERRUPT_ENABLE);
570 
571 	TRACE("OHCI host controller driver constructed\n");
572 	fInitOK = true;
573 }
574 
575 
576 OHCI::~OHCI()
577 {
578 	int32 result = 0;
579 	fStopFinishThread = true;
580 	delete_sem(fFinishTransfersSem);
581 	wait_for_thread(fFinishThread, &result);
582 
583 	remove_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this);
584 
585 	_LockEndpoints();
586 	mutex_destroy(&fEndpointLock);
587 
588 	if (fHccaArea >= B_OK)
589 		delete_area(fHccaArea);
590 	if (fRegisterArea >= B_OK)
591 		delete_area(fRegisterArea);
592 
593 	_FreeEndpoint(fDummyControl);
594 	_FreeEndpoint(fDummyBulk);
595 	_FreeEndpoint(fDummyIsochronous);
596 
597 	if (fInterruptEndpoints != NULL) {
598 		for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++)
599 			_FreeEndpoint(fInterruptEndpoints[i]);
600 	}
601 
602 	delete [] fFrameBandwidth;
603 	delete [] fInterruptEndpoints;
604 	delete fRootHub;
605 
606 	if (fUseMSI) {
607 		fPci->disable_msi(fDevice);
608 		fPci->unconfigure_msi(fDevice);
609 	}
610 }
611 
612 
613 status_t
614 OHCI::Start()
615 {
616 	TRACE("starting OHCI host controller\n");
617 
618 	uint32 control = _ReadReg(OHCI_CONTROL);
619 	if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
620 		!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
621 		TRACE_ERROR("controller not started (0x%08" B_PRIx32 ")!\n", control);
622 		return B_ERROR;
623 	} else
624 		TRACE("controller is operational!\n");
625 
626 	fRootHubAddress = AllocateAddress();
627 	fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
628 	if (!fRootHub) {
629 		TRACE_ERROR("no memory to allocate root hub\n");
630 		return B_NO_MEMORY;
631 	}
632 
633 	if (fRootHub->InitCheck() < B_OK) {
634 		TRACE_ERROR("root hub failed init check\n");
635 		return B_ERROR;
636 	}
637 
638 	SetRootHub(fRootHub);
639 
640 	fRootHub->RegisterNode(Node());
641 
642 	TRACE_ALWAYS("successfully started the controller\n");
643 	return BusManager::Start();
644 }
645 
646 
647 status_t
648 OHCI::SubmitTransfer(Transfer *transfer)
649 {
650 	// short circuit the root hub
651 	if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
652 		return fRootHub->ProcessTransfer(this, transfer);
653 
654 	uint32 type = transfer->TransferPipe()->Type();
655 	if (type & USB_OBJECT_CONTROL_PIPE) {
656 		TRACE("submitting request\n");
657 		return _SubmitRequest(transfer);
658 	}
659 
660 	if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) {
661 		TRACE("submitting %s transfer\n",
662 			(type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt");
663 		return _SubmitTransfer(transfer);
664 	}
665 
666 	if (type & USB_OBJECT_ISO_PIPE) {
667 		TRACE("submitting isochronous transfer\n");
668 		return _SubmitIsochronousTransfer(transfer);
669 	}
670 
671 	TRACE_ERROR("tried to submit transfer for unknown pipe type %" B_PRIu32 "\n",
672 		type);
673 	return B_ERROR;
674 }
675 
676 
677 status_t
678 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
679 {
680 	if (!Lock())
681 		return B_ERROR;
682 
683 	struct transfer_entry {
684 		Transfer *			transfer;
685 		transfer_entry *	next;
686 	};
687 
688 	transfer_entry *list = NULL;
689 	transfer_data *current = fFirstTransfer;
690 	while (current) {
691 		if (current->transfer && current->transfer->TransferPipe() == pipe) {
692 			// Check if the skip bit is already set
693 			if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) {
694 				current->endpoint->flags |= OHCI_ENDPOINT_SKIP;
695 				// In case the controller is processing
696 				// this endpoint, wait for it to finish
697 				snooze(1000);
698 			}
699 
700 			// Clear the endpoint
701 			current->endpoint->head_physical_descriptor
702 				= current->endpoint->tail_physical_descriptor;
703 
704 			if (!force) {
705 				if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
706 					ohci_isochronous_td *descriptor
707 						= (ohci_isochronous_td *)current->first_descriptor;
708 					while (descriptor) {
709 						uint16 frame = OHCI_ITD_GET_STARTING_FRAME(
710 							descriptor->flags);
711 						_ReleaseIsochronousBandwidth(frame,
712 							OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
713 						if (descriptor
714 								== (ohci_isochronous_td*)current->last_descriptor)
715 							// this is the last ITD of the transfer
716 							break;
717 
718 						descriptor
719 							= (ohci_isochronous_td *)
720 							descriptor->next_done_descriptor;
721 					}
722 				}
723 
724 				// If the transfer is canceled by force, the one causing the
725 				// cancel is probably not the one who initiated the transfer
726 				// and the callback is likely not safe anymore
727 				transfer_entry *entry
728 					= (transfer_entry *)malloc(sizeof(transfer_entry));
729 				if (entry != NULL) {
730 					entry->transfer = current->transfer;
731 					current->transfer = NULL;
732 					entry->next = list;
733 					list = entry;
734 				}
735 			}
736 			current->canceled = true;
737 		}
738 		current = current->link;
739 	}
740 
741 	Unlock();
742 
743 	while (list != NULL) {
744 		transfer_entry *next = list->next;
745 		list->transfer->Finished(B_CANCELED, 0);
746 		delete list->transfer;
747 		free(list);
748 		list = next;
749 	}
750 
751 	// wait for any transfers that might have made it before canceling
752 	while (fProcessingPipe == pipe)
753 		snooze(1000);
754 
755 	// notify the finisher so it can clean up the canceled transfers
756 	release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
757 	return B_OK;
758 }
759 
760 
761 status_t
762 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
763 {
764 	TRACE("pipe change %d for pipe %p\n", change, pipe);
765 	if (pipe->DeviceAddress() == fRootHubAddress) {
766 		// no need to insert/remove endpoint descriptors for the root hub
767 		return B_OK;
768 	}
769 
770 	switch (change) {
771 		case USB_CHANGE_CREATED:
772 			return _InsertEndpointForPipe(pipe);
773 
774 		case USB_CHANGE_DESTROYED:
775 			return _RemoveEndpointForPipe(pipe);
776 
777 		case USB_CHANGE_PIPE_POLICY_CHANGED:
778 			TRACE("pipe policy changing unhandled!\n");
779 			break;
780 
781 		default:
782 			TRACE_ERROR("unknown pipe change!\n");
783 			return B_ERROR;
784 	}
785 
786 	return B_OK;
787 }
788 
789 
790 status_t
791 OHCI::GetPortStatus(uint8 index, usb_port_status *status)
792 {
793 	if (index >= fPortCount) {
794 		TRACE_ERROR("get port status for invalid port %u\n", index);
795 		return B_BAD_INDEX;
796 	}
797 
798 	status->status = status->change = 0;
799 	uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index));
800 
801 	// status
802 	if (portStatus & OHCI_RH_PORTSTATUS_CCS)
803 		status->status |= PORT_STATUS_CONNECTION;
804 	if (portStatus & OHCI_RH_PORTSTATUS_PES)
805 		status->status |= PORT_STATUS_ENABLE;
806 	if (portStatus & OHCI_RH_PORTSTATUS_PSS)
807 		status->status |= PORT_STATUS_SUSPEND;
808 	if (portStatus & OHCI_RH_PORTSTATUS_POCI)
809 		status->status |= PORT_STATUS_OVER_CURRENT;
810 	if (portStatus & OHCI_RH_PORTSTATUS_PRS)
811 		status->status |= PORT_STATUS_RESET;
812 	if (portStatus & OHCI_RH_PORTSTATUS_PPS)
813 		status->status |= PORT_STATUS_POWER;
814 	if (portStatus & OHCI_RH_PORTSTATUS_LSDA)
815 		status->status |= PORT_STATUS_LOW_SPEED;
816 
817 	// change
818 	if (portStatus & OHCI_RH_PORTSTATUS_CSC)
819 		status->change |= PORT_STATUS_CONNECTION;
820 	if (portStatus & OHCI_RH_PORTSTATUS_PESC)
821 		status->change |= PORT_STATUS_ENABLE;
822 	if (portStatus & OHCI_RH_PORTSTATUS_PSSC)
823 		status->change |= PORT_STATUS_SUSPEND;
824 	if (portStatus & OHCI_RH_PORTSTATUS_OCIC)
825 		status->change |= PORT_STATUS_OVER_CURRENT;
826 	if (portStatus & OHCI_RH_PORTSTATUS_PRSC)
827 		status->change |= PORT_STATUS_RESET;
828 
829 	TRACE("port %u status 0x%04x change 0x%04x\n", index,
830 		status->status, status->change);
831 	return B_OK;
832 }
833 
834 
835 status_t
836 OHCI::SetPortFeature(uint8 index, uint16 feature)
837 {
838 	TRACE("set port feature index %u feature %u\n", index, feature);
839 	if (index > fPortCount)
840 		return B_BAD_INDEX;
841 
842 	switch (feature) {
843 		case PORT_ENABLE:
844 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES);
845 			return B_OK;
846 
847 		case PORT_SUSPEND:
848 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS);
849 			return B_OK;
850 
851 		case PORT_RESET:
852 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
853 			return B_OK;
854 
855 		case PORT_POWER:
856 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
857 			return B_OK;
858 	}
859 
860 	return B_BAD_VALUE;
861 }
862 
863 
864 status_t
865 OHCI::ClearPortFeature(uint8 index, uint16 feature)
866 {
867 	TRACE("clear port feature index %u feature %u\n", index, feature);
868 	if (index > fPortCount)
869 		return B_BAD_INDEX;
870 
871 	switch (feature) {
872 		case PORT_ENABLE:
873 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS);
874 			return B_OK;
875 
876 		case PORT_SUSPEND:
877 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI);
878 			return B_OK;
879 
880 		case PORT_POWER:
881 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA);
882 			return B_OK;
883 
884 		case C_PORT_CONNECTION:
885 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
886 			return B_OK;
887 
888 		case C_PORT_ENABLE:
889 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC);
890 			return B_OK;
891 
892 		case C_PORT_SUSPEND:
893 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC);
894 			return B_OK;
895 
896 		case C_PORT_OVER_CURRENT:
897 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC);
898 			return B_OK;
899 
900 		case C_PORT_RESET:
901 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC);
902 			return B_OK;
903 	}
904 
905 	return B_BAD_VALUE;
906 }
907 
908 
909 int32
910 OHCI::_InterruptHandler(void *data)
911 {
912 	return ((OHCI *)data)->_Interrupt();
913 }
914 
915 
916 int32
917 OHCI::_Interrupt()
918 {
919 	static spinlock lock = B_SPINLOCK_INITIALIZER;
920 	acquire_spinlock(&lock);
921 
922 	uint32 status = 0;
923 	uint32 acknowledge = 0;
924 	bool finishTransfers = false;
925 	int32 result = B_HANDLED_INTERRUPT;
926 
927 	// The LSb of done_head is used to inform the HCD that an interrupt
928 	// condition exists for both the done list and for another event recorded in
929 	// the HcInterruptStatus register. If done_head is 0, then the interrupt
930 	// was caused by other than the HccaDoneHead update and the
931 	// HcInterruptStatus register needs to be accessed to determine that exact
932 	// interrupt cause. If HccDoneHead is nonzero, then a done list update
933 	// interrupt is indicated and if the LSb of the Dword is nonzero, then an
934 	// additional interrupt event is indicated and HcInterruptStatus should be
935 	// checked to determine its cause.
936 	uint32 doneHead = fHcca->done_head;
937 	if (doneHead != 0) {
938 		status = OHCI_WRITEBACK_DONE_HEAD;
939 		if (doneHead & OHCI_DONE_INTERRUPTS)
940 			status |= _ReadReg(OHCI_INTERRUPT_STATUS)
941 				& _ReadReg(OHCI_INTERRUPT_ENABLE);
942 	} else {
943 		status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE)
944 			& ~OHCI_WRITEBACK_DONE_HEAD;
945 		if (status == 0) {
946 			// Nothing to be done (PCI shared interrupt)
947 			release_spinlock(&lock);
948 			return B_UNHANDLED_INTERRUPT;
949 		}
950 	}
951 
952 	if (status & OHCI_SCHEDULING_OVERRUN) {
953 		TRACE_MODULE("scheduling overrun occured\n");
954 		acknowledge |= OHCI_SCHEDULING_OVERRUN;
955 	}
956 
957 	if (status & OHCI_WRITEBACK_DONE_HEAD) {
958 		TRACE_MODULE("transfer descriptors processed\n");
959 		fHcca->done_head = 0;
960 		acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
961 		result = B_INVOKE_SCHEDULER;
962 		finishTransfers = true;
963 	}
964 
965 	if (status & OHCI_RESUME_DETECTED) {
966 		TRACE_MODULE("resume detected\n");
967 		acknowledge |= OHCI_RESUME_DETECTED;
968 	}
969 
970 	if (status & OHCI_UNRECOVERABLE_ERROR) {
971 		TRACE_MODULE_ERROR("unrecoverable error - controller halted\n");
972 		_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
973 		// TODO: clear all pending transfers, reset and resetup the controller
974 	}
975 
976 	if (status & OHCI_ROOT_HUB_STATUS_CHANGE) {
977 		TRACE_MODULE("root hub status change\n");
978 		// Disable the interrupt as it will otherwise be retriggered until the
979 		// port has been reset and the change is cleared explicitly.
980 		// TODO: renable it once we use status changes instead of polling
981 		_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE);
982 		acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
983 	}
984 
985 	if (acknowledge != 0)
986 		_WriteReg(OHCI_INTERRUPT_STATUS, acknowledge);
987 
988 	release_spinlock(&lock);
989 
990 	if (finishTransfers)
991 		release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
992 
993 	return result;
994 }
995 
996 
997 status_t
998 OHCI::_AddPendingTransfer(Transfer *transfer,
999 	ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor,
1000 	ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor,
1001 	bool directionIn)
1002 {
1003 	if (!transfer || !endpoint || !lastDescriptor)
1004 		return B_BAD_VALUE;
1005 
1006 	transfer_data *data = new(std::nothrow) transfer_data;
1007 	if (!data)
1008 		return B_NO_MEMORY;
1009 
1010 	status_t result = transfer->InitKernelAccess();
1011 	if (result < B_OK) {
1012 		delete data;
1013 		return result;
1014 	}
1015 
1016 	data->transfer = transfer;
1017 	data->endpoint = endpoint;
1018 	data->incoming = directionIn;
1019 	data->canceled = false;
1020 	data->link = NULL;
1021 
1022 	// the current tail will become the first descriptor
1023 	data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor;
1024 
1025 	// the data and first descriptors might be the same
1026 	if (dataDescriptor == firstDescriptor)
1027 		data->data_descriptor = data->first_descriptor;
1028 	else
1029 		data->data_descriptor = dataDescriptor;
1030 
1031 	// even the last and the first descriptor might be the same
1032 	if (lastDescriptor == firstDescriptor)
1033 		data->last_descriptor = data->first_descriptor;
1034 	else
1035 		data->last_descriptor = lastDescriptor;
1036 
1037 	if (!Lock()) {
1038 		delete data;
1039 		return B_ERROR;
1040 	}
1041 
1042 	if (fLastTransfer)
1043 		fLastTransfer->link = data;
1044 	else
1045 		fFirstTransfer = data;
1046 
1047 	fLastTransfer = data;
1048 	Unlock();
1049 
1050 	return B_OK;
1051 }
1052 
1053 
1054 status_t
1055 OHCI::_AddPendingIsochronousTransfer(Transfer *transfer,
1056 	ohci_endpoint_descriptor *endpoint, ohci_isochronous_td *firstDescriptor,
1057 	ohci_isochronous_td *lastDescriptor, bool directionIn)
1058 {
1059 	if (!transfer || !endpoint || !lastDescriptor)
1060 		return B_BAD_VALUE;
1061 
1062 	transfer_data *data = new(std::nothrow) transfer_data;
1063 	if (!data)
1064 		return B_NO_MEMORY;
1065 
1066 	status_t result = transfer->InitKernelAccess();
1067 	if (result < B_OK) {
1068 		delete data;
1069 		return result;
1070 	}
1071 
1072 	data->transfer = transfer;
1073 	data->endpoint = endpoint;
1074 	data->incoming = directionIn;
1075 	data->canceled = false;
1076 	data->link = NULL;
1077 
1078 	// the current tail will become the first descriptor
1079 	data->first_descriptor = (ohci_general_td*)endpoint->tail_logical_descriptor;
1080 
1081 	// the data and first descriptors are the same
1082 	data->data_descriptor = data->first_descriptor;
1083 
1084 	// the last and the first descriptor might be the same
1085 	if (lastDescriptor == firstDescriptor)
1086 		data->last_descriptor = data->first_descriptor;
1087 	else
1088 		data->last_descriptor = (ohci_general_td*)lastDescriptor;
1089 
1090 	if (!Lock()) {
1091 		delete data;
1092 		return B_ERROR;
1093 	}
1094 
1095 	if (fLastTransfer)
1096 		fLastTransfer->link = data;
1097 	else
1098 		fFirstTransfer = data;
1099 
1100 	fLastTransfer = data;
1101 	Unlock();
1102 
1103 	return B_OK;
1104 }
1105 
1106 
1107 int32
1108 OHCI::_FinishThread(void *data)
1109 {
1110 	((OHCI *)data)->_FinishTransfers();
1111 	return B_OK;
1112 }
1113 
1114 
1115 void
1116 OHCI::_FinishTransfers()
1117 {
1118 	while (!fStopFinishThread) {
1119 		if (acquire_sem(fFinishTransfersSem) < B_OK)
1120 			continue;
1121 
1122 		// eat up sems that have been released by multiple interrupts
1123 		int32 semCount = 0;
1124 		get_sem_count(fFinishTransfersSem, &semCount);
1125 		if (semCount > 0)
1126 			acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);
1127 
1128 		if (!Lock())
1129 			continue;
1130 
1131 		TRACE("finishing transfers (first transfer: %p; last"
1132 			" transfer: %p)\n", fFirstTransfer, fLastTransfer);
1133 		transfer_data *lastTransfer = NULL;
1134 		transfer_data *transfer = fFirstTransfer;
1135 		Unlock();
1136 
1137 		while (transfer) {
1138 			bool transferDone = false;
1139 			ohci_general_td *descriptor = transfer->first_descriptor;
1140 			ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1141 			status_t callbackStatus = B_OK;
1142 
1143 			if (endpoint->flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT) {
1144 				transfer_data *next = transfer->link;
1145 				if (_FinishIsochronousTransfer(transfer, &lastTransfer)) {
1146 					delete transfer->transfer;
1147 					delete transfer;
1148 				}
1149 				transfer = next;
1150 				continue;
1151 			}
1152 
1153 			MutexLocker endpointLocker(endpoint->lock);
1154 
1155 			if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1156 					!= endpoint->tail_physical_descriptor
1157 						&& (endpoint->head_physical_descriptor
1158 							& OHCI_ENDPOINT_HALTED) == 0) {
1159 				// there are still active transfers on this endpoint, we need
1160 				// to wait for all of them to complete, otherwise we'd read
1161 				// a potentially bogus data toggle value below
1162 				TRACE("endpoint %p still has active tds\n", endpoint);
1163 				lastTransfer = transfer;
1164 				transfer = transfer->link;
1165 				continue;
1166 			}
1167 
1168 			endpointLocker.Unlock();
1169 
1170 			while (descriptor && !transfer->canceled) {
1171 				uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1172 				if (status == OHCI_TD_CONDITION_NOT_ACCESSED) {
1173 					// td is still active
1174 					TRACE("td %p still active\n", descriptor);
1175 					break;
1176 				}
1177 
1178 				if (status != OHCI_TD_CONDITION_NO_ERROR) {
1179 					// an error occured, but we must ensure that the td
1180 					// was actually done
1181 					if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) {
1182 						// the endpoint is halted, this guaratees us that this
1183 						// descriptor has passed (we don't know if the endpoint
1184 						// was halted because of this td, but we do not need
1185 						// to know, as when it was halted by another td this
1186 						// still ensures that this td was handled before).
1187 						TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status);
1188 
1189 						callbackStatus = _GetStatusOfConditionCode(status);
1190 
1191 						transferDone = true;
1192 						break;
1193 					} else {
1194 						// an error occured but the endpoint is not halted so
1195 						// the td is in fact still active
1196 						TRACE("td %p active with error\n", descriptor);
1197 						break;
1198 					}
1199 				}
1200 
1201 				// the td has completed without an error
1202 				TRACE("td %p done\n", descriptor);
1203 
1204 				if (descriptor == transfer->last_descriptor
1205 					|| descriptor->buffer_physical != 0) {
1206 					// this is the last td of the transfer or a short packet
1207 					callbackStatus = B_OK;
1208 					transferDone = true;
1209 					break;
1210 				}
1211 
1212 				descriptor
1213 					= (ohci_general_td *)descriptor->next_logical_descriptor;
1214 			}
1215 
1216 			if (transfer->canceled) {
1217 				// when a transfer is canceled, all transfers to that endpoint
1218 				// are canceled by setting the head pointer to the tail pointer
1219 				// which causes all of the tds to become "free" (as they are
1220 				// inaccessible and not accessed anymore (as setting the head
1221 				// pointer required disabling the endpoint))
1222 				callbackStatus = B_OK;
1223 				transferDone = true;
1224 			}
1225 
1226 			if (!transferDone) {
1227 				lastTransfer = transfer;
1228 				transfer = transfer->link;
1229 				continue;
1230 			}
1231 
1232 			// remove the transfer from the list first so we are sure
1233 			// it doesn't get canceled while we still process it
1234 			transfer_data *next = transfer->link;
1235 			if (Lock()) {
1236 				if (lastTransfer)
1237 					lastTransfer->link = transfer->link;
1238 
1239 				if (transfer == fFirstTransfer)
1240 					fFirstTransfer = transfer->link;
1241 				if (transfer == fLastTransfer)
1242 					fLastTransfer = lastTransfer;
1243 
1244 				// store the currently processing pipe here so we can wait
1245 				// in cancel if we are processing something on the target pipe
1246 				if (!transfer->canceled)
1247 					fProcessingPipe = transfer->transfer->TransferPipe();
1248 
1249 				transfer->link = NULL;
1250 				Unlock();
1251 			}
1252 
1253 			// break the descriptor chain on the last descriptor
1254 			transfer->last_descriptor->next_logical_descriptor = NULL;
1255 			TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n",
1256 				transfer, callbackStatus);
1257 
1258 			// if canceled the callback has already been called
1259 			if (!transfer->canceled) {
1260 				size_t actualLength = 0;
1261 				if (callbackStatus == B_OK) {
1262 					if (transfer->data_descriptor && transfer->incoming) {
1263 						// data to read out
1264 						iovec *vector = transfer->transfer->Vector();
1265 						size_t vectorCount = transfer->transfer->VectorCount();
1266 
1267 						transfer->transfer->PrepareKernelAccess();
1268 						actualLength = _ReadDescriptorChain(
1269 							transfer->data_descriptor,
1270 							vector, vectorCount);
1271 					} else if (transfer->data_descriptor) {
1272 						// read the actual length that was sent
1273 						actualLength = _ReadActualLength(
1274 							transfer->data_descriptor);
1275 					}
1276 
1277 					// get the last data toggle and store it for next time
1278 					transfer->transfer->TransferPipe()->SetDataToggle(
1279 						(endpoint->head_physical_descriptor
1280 							& OHCI_ENDPOINT_TOGGLE_CARRY) != 0);
1281 
1282 					if (transfer->transfer->IsFragmented()) {
1283 						// this transfer may still have data left
1284 						TRACE("advancing fragmented transfer\n");
1285 						transfer->transfer->AdvanceByFragment(actualLength);
1286 						if (transfer->transfer->FragmentLength() > 0) {
1287 							TRACE("still %ld bytes left on transfer\n",
1288 								transfer->transfer->FragmentLength());
1289 							// TODO actually resubmit the transfer
1290 						}
1291 
1292 						// the transfer is done, but we already set the
1293 						// actualLength with AdvanceByFragment()
1294 						actualLength = 0;
1295 					}
1296 				}
1297 
1298 				transfer->transfer->Finished(callbackStatus, actualLength);
1299 				fProcessingPipe = NULL;
1300 			}
1301 
1302 			if (callbackStatus != B_OK) {
1303 				// remove the transfer and make the head pointer valid again
1304 				// (including clearing the halt state)
1305 				_RemoveTransferFromEndpoint(transfer);
1306 			}
1307 
1308 			// free the descriptors
1309 			_FreeDescriptorChain(transfer->first_descriptor);
1310 
1311 			delete transfer->transfer;
1312 			delete transfer;
1313 			transfer = next;
1314 		}
1315 	}
1316 }
1317 
1318 
1319 bool
1320 OHCI::_FinishIsochronousTransfer(transfer_data *transfer,
1321 	transfer_data **_lastTransfer)
1322 {
1323 	status_t callbackStatus = B_OK;
1324 	size_t actualLength = 0;
1325 	uint32 packet = 0;
1326 
1327 	if (transfer->canceled)
1328 		callbackStatus = B_CANCELED;
1329 	else {
1330 		// at first check if ALL ITDs are retired by HC
1331 		ohci_isochronous_td *descriptor
1332 			= (ohci_isochronous_td *)transfer->first_descriptor;
1333 		while (descriptor) {
1334 			if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags)
1335 				== OHCI_TD_CONDITION_NOT_ACCESSED) {
1336 				TRACE("ITD %p still active\n", descriptor);
1337 				*_lastTransfer = transfer;
1338 				return false;
1339 			}
1340 
1341 			if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) {
1342 				// this is the last ITD of the transfer
1343 				descriptor = (ohci_isochronous_td *)transfer->first_descriptor;
1344 				break;
1345 			}
1346 
1347 			descriptor
1348 				= (ohci_isochronous_td *)descriptor->next_done_descriptor;
1349 		}
1350 
1351 		while (descriptor) {
1352 			uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1353 			if (status != OHCI_TD_CONDITION_NO_ERROR) {
1354 				TRACE_ERROR("ITD error: 0x%08" B_PRIx32 "\n", status);
1355 				// spec says that in most cases condition code
1356 				// of retired ITDs is set to NoError, but for the
1357 				// time overrun it can be DataOverrun. We assume
1358 				// the _first_ occurience of such error as status
1359 				// reported to the callback
1360 				if (callbackStatus == B_OK)
1361 					callbackStatus = _GetStatusOfConditionCode(status);
1362 			}
1363 
1364 			usb_isochronous_data *isochronousData
1365 				= transfer->transfer->IsochronousData();
1366 
1367 			uint32 frameCount = OHCI_ITD_GET_FRAME_COUNT(descriptor->flags);
1368 			for (size_t i = 0; i < frameCount; i++, packet++) {
1369 				usb_iso_packet_descriptor* packet_descriptor
1370 					= &isochronousData->packet_descriptors[packet];
1371 
1372 				uint16 offset = descriptor->offset[OHCI_ITD_OFFSET_IDX(i)];
1373 				uint8 code = OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset);
1374 				packet_descriptor->status = _GetStatusOfConditionCode(code);
1375 
1376 				// not touched by HC - sheduled too late to be processed
1377 				// in the requested frame - so we ignore it too
1378 				if (packet_descriptor->status == B_DEV_TOO_LATE)
1379 					continue;
1380 
1381 				size_t len = OHCI_ITD_GET_BUFFER_LENGTH(offset);
1382 				if (!transfer->incoming)
1383 					len = packet_descriptor->request_length - len;
1384 
1385 				packet_descriptor->actual_length = len;
1386 				actualLength += len;
1387 			}
1388 
1389 			uint16 frame = OHCI_ITD_GET_STARTING_FRAME(descriptor->flags);
1390 			_ReleaseIsochronousBandwidth(frame,
1391 				OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
1392 
1393 			TRACE("ITD %p done\n", descriptor);
1394 
1395 			if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor)
1396 				break;
1397 
1398 			descriptor
1399 				= (ohci_isochronous_td *)descriptor->next_done_descriptor;
1400 		}
1401 	}
1402 
1403 	// remove the transfer from the list first so we are sure
1404 	// it doesn't get canceled while we still process it
1405 	if (Lock()) {
1406 		if (*_lastTransfer)
1407 			(*_lastTransfer)->link = transfer->link;
1408 
1409 		if (transfer == fFirstTransfer)
1410 			fFirstTransfer = transfer->link;
1411 		if (transfer == fLastTransfer)
1412 			fLastTransfer = *_lastTransfer;
1413 
1414 		// store the currently processing pipe here so we can wait
1415 		// in cancel if we are processing something on the target pipe
1416 		if (!transfer->canceled)
1417 			fProcessingPipe = transfer->transfer->TransferPipe();
1418 
1419 		transfer->link = NULL;
1420 		Unlock();
1421 	}
1422 
1423 	// break the descriptor chain on the last descriptor
1424 	transfer->last_descriptor->next_logical_descriptor = NULL;
1425 	TRACE("iso.transfer %p done with status 0x%08" B_PRIx32 " len:%ld\n",
1426 		transfer, callbackStatus, actualLength);
1427 
1428 	// if canceled the callback has already been called
1429 	if (!transfer->canceled) {
1430 		if (callbackStatus == B_OK && actualLength > 0) {
1431 			if (transfer->data_descriptor && transfer->incoming) {
1432 				// data to read out
1433 				iovec *vector = transfer->transfer->Vector();
1434 				size_t vectorCount = transfer->transfer->VectorCount();
1435 
1436 				transfer->transfer->PrepareKernelAccess();
1437 				_ReadIsochronousDescriptorChain(
1438 					(ohci_isochronous_td*)transfer->data_descriptor,
1439 					vector, vectorCount);
1440 			}
1441 		}
1442 
1443 		transfer->transfer->Finished(callbackStatus, actualLength);
1444 		fProcessingPipe = NULL;
1445 	}
1446 
1447 	_FreeIsochronousDescriptorChain(
1448 		(ohci_isochronous_td*)transfer->first_descriptor);
1449 
1450 	return true;
1451 }
1452 
1453 
1454 status_t
1455 OHCI::_SubmitRequest(Transfer *transfer)
1456 {
1457 	usb_request_data *requestData = transfer->RequestData();
1458 	bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0;
1459 
1460 	ohci_general_td *setupDescriptor
1461 		= _CreateGeneralDescriptor(sizeof(usb_request_data));
1462 	if (!setupDescriptor) {
1463 		TRACE_ERROR("failed to allocate setup descriptor\n");
1464 		return B_NO_MEMORY;
1465 	}
1466 
1467 	setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP
1468 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1469 		| OHCI_TD_TOGGLE_0
1470 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
1471 
1472 	ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0);
1473 	if (!statusDescriptor) {
1474 		TRACE_ERROR("failed to allocate status descriptor\n");
1475 		_FreeGeneralDescriptor(setupDescriptor);
1476 		return B_NO_MEMORY;
1477 	}
1478 
1479 	statusDescriptor->flags
1480 		= (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN)
1481 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1482 		| OHCI_TD_TOGGLE_1
1483 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1484 
1485 	iovec vector;
1486 	vector.iov_base = requestData;
1487 	vector.iov_len = sizeof(usb_request_data);
1488 	_WriteDescriptorChain(setupDescriptor, &vector, 1);
1489 
1490 	status_t result;
1491 	ohci_general_td *dataDescriptor = NULL;
1492 	if (transfer->VectorCount() > 0) {
1493 		ohci_general_td *lastDescriptor = NULL;
1494 		result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor,
1495 			directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1496 			transfer->FragmentLength());
1497 		if (result < B_OK) {
1498 			_FreeGeneralDescriptor(setupDescriptor);
1499 			_FreeGeneralDescriptor(statusDescriptor);
1500 			return result;
1501 		}
1502 
1503 		if (!directionIn) {
1504 			_WriteDescriptorChain(dataDescriptor, transfer->Vector(),
1505 				transfer->VectorCount());
1506 		}
1507 
1508 		_LinkDescriptors(setupDescriptor, dataDescriptor);
1509 		_LinkDescriptors(lastDescriptor, statusDescriptor);
1510 	} else {
1511 		_LinkDescriptors(setupDescriptor, statusDescriptor);
1512 	}
1513 
1514 	// Add to the transfer list
1515 	ohci_endpoint_descriptor *endpoint
1516 		= (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie();
1517 
1518 	MutexLocker endpointLocker(endpoint->lock);
1519 	result = _AddPendingTransfer(transfer, endpoint, setupDescriptor,
1520 		dataDescriptor, statusDescriptor, directionIn);
1521 	if (result < B_OK) {
1522 		TRACE_ERROR("failed to add pending transfer\n");
1523 		_FreeDescriptorChain(setupDescriptor);
1524 		return result;
1525 	}
1526 
1527 	// Add the descriptor chain to the endpoint
1528 	_SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor);
1529 	endpointLocker.Unlock();
1530 
1531 	// Tell the controller to process the control list
1532 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1533 	_WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED);
1534 	return B_OK;
1535 }
1536 
1537 
1538 status_t
1539 OHCI::_SubmitTransfer(Transfer *transfer)
1540 {
1541 	Pipe *pipe = transfer->TransferPipe();
1542 	bool directionIn = (pipe->Direction() == Pipe::In);
1543 
1544 	ohci_general_td *firstDescriptor = NULL;
1545 	ohci_general_td *lastDescriptor = NULL;
1546 	status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor,
1547 		directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1548 		transfer->FragmentLength());
1549 
1550 	if (result < B_OK)
1551 		return result;
1552 
1553 	// Apply data toggle to the first descriptor (the others will use the carry)
1554 	firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY;
1555 	firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1
1556 		: OHCI_TD_TOGGLE_0;
1557 
1558 	// Set the last descriptor to generate an interrupt
1559 	lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK;
1560 	lastDescriptor->flags |=
1561 		OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1562 
1563 	if (!directionIn) {
1564 		_WriteDescriptorChain(firstDescriptor, transfer->Vector(),
1565 			transfer->VectorCount());
1566 	}
1567 
1568 	// Add to the transfer list
1569 	ohci_endpoint_descriptor *endpoint
1570 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1571 
1572 	MutexLocker endpointLocker(endpoint->lock);
1573 
1574 	// We do not support queuing other transfers in tandem with a fragmented one.
1575 	transfer_data *it = fFirstTransfer;
1576 	while (it) {
1577 		if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) {
1578 			TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
1579 			_FreeDescriptorChain(firstDescriptor);
1580 			return B_DEV_RESOURCE_CONFLICT;
1581 		}
1582 
1583 		it = it->link;
1584 	}
1585 
1586 	result = _AddPendingTransfer(transfer, endpoint, firstDescriptor,
1587 		firstDescriptor, lastDescriptor, directionIn);
1588 	if (result < B_OK) {
1589 		TRACE_ERROR("failed to add pending transfer\n");
1590 		_FreeDescriptorChain(firstDescriptor);
1591 		return result;
1592 	}
1593 
1594 	// Add the descriptor chain to the endpoint
1595 	_SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1596 	endpointLocker.Unlock();
1597 
1598 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1599 	if (pipe->Type() & USB_OBJECT_BULK_PIPE) {
1600 		// Tell the controller to process the bulk list
1601 		_WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED);
1602 	}
1603 
1604 	return B_OK;
1605 }
1606 
1607 
1608 status_t
1609 OHCI::_SubmitIsochronousTransfer(Transfer *transfer)
1610 {
1611 	Pipe *pipe = transfer->TransferPipe();
1612 	bool directionIn = (pipe->Direction() == Pipe::In);
1613 	usb_isochronous_data *isochronousData = transfer->IsochronousData();
1614 
1615 	ohci_isochronous_td *firstDescriptor = NULL;
1616 	ohci_isochronous_td *lastDescriptor = NULL;
1617 	status_t result = _CreateIsochronousDescriptorChain(&firstDescriptor,
1618 		&lastDescriptor, transfer);
1619 
1620 	if (firstDescriptor == 0 || lastDescriptor == 0)
1621 		return B_ERROR;
1622 
1623 	if (result < B_OK)
1624 		return result;
1625 
1626 	// Set the last descriptor to generate an interrupt
1627 	lastDescriptor->flags &= ~OHCI_ITD_INTERRUPT_MASK;
1628 	// let the controller retire last ITD
1629 	lastDescriptor->flags |= OHCI_ITD_SET_DELAY_INTERRUPT(1);
1630 
1631 	// If direction is out set every descriptor data
1632 	if (pipe->Direction() == Pipe::Out)
1633 		_WriteIsochronousDescriptorChain(firstDescriptor,
1634 			transfer->Vector(), transfer->VectorCount());
1635 	else
1636 		// Initialize the packet descriptors
1637 		for (uint32 i = 0; i < isochronousData->packet_count; i++) {
1638 			isochronousData->packet_descriptors[i].actual_length = 0;
1639 			isochronousData->packet_descriptors[i].status = B_NO_INIT;
1640 		}
1641 
1642 	// Add to the transfer list
1643 	ohci_endpoint_descriptor *endpoint
1644 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1645 
1646 	MutexLocker endpointLocker(endpoint->lock);
1647 	result = _AddPendingIsochronousTransfer(transfer, endpoint,
1648 		firstDescriptor, lastDescriptor, directionIn);
1649 	if (result < B_OK) {
1650 		TRACE_ERROR("failed to add pending iso.transfer:"
1651 			"0x%08" B_PRIx32 "\n", result);
1652 		_FreeIsochronousDescriptorChain(firstDescriptor);
1653 		return result;
1654 	}
1655 
1656 	// Add the descriptor chain to the endpoint
1657 	_SwitchIsochronousEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1658 	endpointLocker.Unlock();
1659 
1660 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1661 
1662 	return B_OK;
1663 }
1664 
1665 
1666 void
1667 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint,
1668 	ohci_general_td *first, ohci_general_td *last)
1669 {
1670 	// fill in the information of the first descriptor into the current tail
1671 	ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor;
1672 	tail->flags = first->flags;
1673 	tail->buffer_physical = first->buffer_physical;
1674 	tail->next_physical_descriptor = first->next_physical_descriptor;
1675 	tail->last_physical_byte_address = first->last_physical_byte_address;
1676 	tail->buffer_size = first->buffer_size;
1677 	tail->buffer_logical = first->buffer_logical;
1678 	tail->next_logical_descriptor = first->next_logical_descriptor;
1679 
1680 	// the first descriptor becomes the new tail
1681 	first->flags = 0;
1682 	first->buffer_physical = 0;
1683 	first->next_physical_descriptor = 0;
1684 	first->last_physical_byte_address = 0;
1685 	first->buffer_size = 0;
1686 	first->buffer_logical = NULL;
1687 	first->next_logical_descriptor = NULL;
1688 
1689 	if (first == last)
1690 		_LinkDescriptors(tail, first);
1691 	else
1692 		_LinkDescriptors(last, first);
1693 
1694 	// update the endpoint tail pointer to reflect the change
1695 	endpoint->tail_logical_descriptor = first;
1696 	endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1697 	TRACE("switched tail from %p to %p\n", tail, first);
1698 
1699 #if 0
1700 	_PrintEndpoint(endpoint);
1701 	_PrintDescriptorChain(tail);
1702 #endif
1703 }
1704 
1705 
1706 void
1707 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor *endpoint,
1708 	ohci_isochronous_td *first, ohci_isochronous_td *last)
1709 {
1710 	// fill in the information of the first descriptor into the current tail
1711 	ohci_isochronous_td *tail
1712 		= (ohci_isochronous_td*)endpoint->tail_logical_descriptor;
1713 	tail->flags = first->flags;
1714 	tail->buffer_page_byte_0 = first->buffer_page_byte_0;
1715 	tail->next_physical_descriptor = first->next_physical_descriptor;
1716 	tail->last_byte_address = first->last_byte_address;
1717 	tail->buffer_size = first->buffer_size;
1718 	tail->buffer_logical = first->buffer_logical;
1719 	tail->next_logical_descriptor = first->next_logical_descriptor;
1720 	tail->next_done_descriptor = first->next_done_descriptor;
1721 
1722 	// the first descriptor becomes the new tail
1723 	first->flags = 0;
1724 	first->buffer_page_byte_0 = 0;
1725 	first->next_physical_descriptor = 0;
1726 	first->last_byte_address = 0;
1727 	first->buffer_size = 0;
1728 	first->buffer_logical = NULL;
1729 	first->next_logical_descriptor = NULL;
1730 	first->next_done_descriptor = NULL;
1731 
1732 	for (int i = 0; i < OHCI_ITD_NOFFSET; i++) {
1733 		tail->offset[i] = first->offset[i];
1734 		first->offset[i] = 0;
1735 	}
1736 
1737 	if (first == last)
1738 		_LinkIsochronousDescriptors(tail, first, NULL);
1739 	else
1740 		_LinkIsochronousDescriptors(last, first, NULL);
1741 
1742 	// update the endpoint tail pointer to reflect the change
1743 	endpoint->tail_logical_descriptor = first;
1744 	endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1745 	TRACE("switched tail from %p to %p\n", tail, first);
1746 
1747 #if 0
1748 	_PrintEndpoint(endpoint);
1749 	_PrintDescriptorChain(tail);
1750 #endif
1751 }
1752 
1753 
1754 void
1755 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer)
1756 {
1757 	// The transfer failed and the endpoint was halted. This means that the
1758 	// endpoint head pointer might point somewhere into the descriptor chain
1759 	// of this transfer. As we do not know if this transfer actually caused
1760 	// the halt on the endpoint we have to make sure this is the case. If we
1761 	// find the head to point to somewhere into the descriptor chain then
1762 	// simply advancing the head pointer to the link of the last transfer
1763 	// will bring the endpoint into a valid state again. This operation is
1764 	// safe as the endpoint is currently halted and we therefore can change
1765 	// the head pointer.
1766 	ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1767 	ohci_general_td *descriptor = transfer->first_descriptor;
1768 	while (descriptor) {
1769 		if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1770 			== descriptor->physical_address) {
1771 			// This descriptor caused the halt. Advance the head pointer. This
1772 			// will either move the head to the next valid transfer that can
1773 			// then be restarted, or it will move the head to the tail when
1774 			// there are no more transfer descriptors. Setting the head will
1775 			// also clear the halt state as it is stored in the first bit of
1776 			// the head pointer.
1777 			endpoint->head_physical_descriptor
1778 				= transfer->last_descriptor->next_physical_descriptor;
1779 			return;
1780 		}
1781 
1782 		descriptor = (ohci_general_td *)descriptor->next_logical_descriptor;
1783 	}
1784 }
1785 
1786 
1787 ohci_endpoint_descriptor *
1788 OHCI::_AllocateEndpoint()
1789 {
1790 	ohci_endpoint_descriptor *endpoint;
1791 	phys_addr_t physicalAddress;
1792 
1793 	mutex *lock = (mutex *)malloc(sizeof(mutex));
1794 	if (lock == NULL) {
1795 		TRACE_ERROR("no memory to allocate endpoint lock\n");
1796 		return NULL;
1797 	}
1798 
1799 	// Allocate memory chunk
1800 	if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress,
1801 		sizeof(ohci_endpoint_descriptor)) < B_OK) {
1802 		TRACE_ERROR("failed to allocate endpoint descriptor\n");
1803 		free(lock);
1804 		return NULL;
1805 	}
1806 
1807 	mutex_init(lock, "ohci endpoint lock");
1808 
1809 	endpoint->flags = OHCI_ENDPOINT_SKIP;
1810 	endpoint->physical_address = (uint32)physicalAddress;
1811 	endpoint->head_physical_descriptor = 0;
1812 	endpoint->tail_logical_descriptor = NULL;
1813 	endpoint->tail_physical_descriptor = 0;
1814 	endpoint->next_logical_endpoint = NULL;
1815 	endpoint->next_physical_endpoint = 0;
1816 	endpoint->lock = lock;
1817 	return endpoint;
1818 }
1819 
1820 
1821 void
1822 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
1823 {
1824 	if (!endpoint)
1825 		return;
1826 
1827 	mutex_destroy(endpoint->lock);
1828 	free(endpoint->lock);
1829 
1830 	fStack->FreeChunk((void *)endpoint, endpoint->physical_address,
1831 		sizeof(ohci_endpoint_descriptor));
1832 }
1833 
1834 
1835 status_t
1836 OHCI::_InsertEndpointForPipe(Pipe *pipe)
1837 {
1838 	TRACE("inserting endpoint for device %u endpoint %u\n",
1839 		pipe->DeviceAddress(), pipe->EndpointAddress());
1840 
1841 	ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
1842 	if (!endpoint) {
1843 		TRACE_ERROR("cannot allocate memory for endpoint\n");
1844 		return B_NO_MEMORY;
1845 	}
1846 
1847 	uint32 flags = OHCI_ENDPOINT_SKIP;
1848 
1849 	// Set up device and endpoint address
1850 	flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress())
1851 		| OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress());
1852 
1853 	// Set the direction
1854 	switch (pipe->Direction()) {
1855 		case Pipe::In:
1856 			flags |= OHCI_ENDPOINT_DIRECTION_IN;
1857 			break;
1858 
1859 		case Pipe::Out:
1860 			flags |= OHCI_ENDPOINT_DIRECTION_OUT;
1861 			break;
1862 
1863 		case Pipe::Default:
1864 			flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR;
1865 			break;
1866 
1867 		default:
1868 			TRACE_ERROR("direction unknown\n");
1869 			_FreeEndpoint(endpoint);
1870 			return B_ERROR;
1871 	}
1872 
1873 	// Set up the speed
1874 	switch (pipe->Speed()) {
1875 		case USB_SPEED_LOWSPEED:
1876 			flags |= OHCI_ENDPOINT_LOW_SPEED;
1877 			break;
1878 
1879 		case USB_SPEED_FULLSPEED:
1880 			flags |= OHCI_ENDPOINT_FULL_SPEED;
1881 			break;
1882 
1883 		default:
1884 			TRACE_ERROR("unacceptable speed\n");
1885 			_FreeEndpoint(endpoint);
1886 			return B_ERROR;
1887 	}
1888 
1889 	// Set the maximum packet size
1890 	flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize());
1891 	endpoint->flags = flags;
1892 
1893 	// Add the endpoint to the appropriate list
1894 	uint32 type = pipe->Type();
1895 	ohci_endpoint_descriptor *head = NULL;
1896 	if (type & USB_OBJECT_CONTROL_PIPE)
1897 		head = fDummyControl;
1898 	else if (type & USB_OBJECT_BULK_PIPE)
1899 		head = fDummyBulk;
1900 	else if (type & USB_OBJECT_INTERRUPT_PIPE)
1901 		head = _FindInterruptEndpoint(pipe->Interval());
1902 	else if (type & USB_OBJECT_ISO_PIPE)
1903 		head = fDummyIsochronous;
1904 	else
1905 		TRACE_ERROR("unknown pipe type\n");
1906 
1907 	if (head == NULL) {
1908 		TRACE_ERROR("no list found for endpoint\n");
1909 		_FreeEndpoint(endpoint);
1910 		return B_ERROR;
1911 	}
1912 
1913 	// Create (necessary) tail descriptor
1914 	if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
1915 		// Set the isochronous bit format
1916 		endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
1917 		ohci_isochronous_td *tail = _CreateIsochronousDescriptor(0);
1918 		tail->flags = 0;
1919 		endpoint->tail_logical_descriptor = tail;
1920 		endpoint->head_physical_descriptor = tail->physical_address;
1921 		endpoint->tail_physical_descriptor = tail->physical_address;
1922 	} else {
1923 		ohci_general_td *tail = _CreateGeneralDescriptor(0);
1924 		tail->flags = 0;
1925 		endpoint->tail_logical_descriptor = tail;
1926 		endpoint->head_physical_descriptor = tail->physical_address;
1927 		endpoint->tail_physical_descriptor = tail->physical_address;
1928 	}
1929 
1930 	if (!_LockEndpoints()) {
1931 		if (endpoint->tail_logical_descriptor) {
1932 			_FreeGeneralDescriptor(
1933 				(ohci_general_td *)endpoint->tail_logical_descriptor);
1934 		}
1935 
1936 		_FreeEndpoint(endpoint);
1937 		return B_ERROR;
1938 	}
1939 
1940 	pipe->SetControllerCookie((void *)endpoint);
1941 	endpoint->next_logical_endpoint = head->next_logical_endpoint;
1942 	endpoint->next_physical_endpoint = head->next_physical_endpoint;
1943 	head->next_logical_endpoint = (void *)endpoint;
1944 	head->next_physical_endpoint = (uint32)endpoint->physical_address;
1945 
1946 	_UnlockEndpoints();
1947 	return B_OK;
1948 }
1949 
1950 
1951 status_t
1952 OHCI::_RemoveEndpointForPipe(Pipe *pipe)
1953 {
1954 	TRACE("removing endpoint for device %u endpoint %u\n",
1955 		pipe->DeviceAddress(), pipe->EndpointAddress());
1956 
1957 	ohci_endpoint_descriptor *endpoint
1958 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1959 	if (endpoint == NULL)
1960 		return B_OK;
1961 
1962 	// TODO implement properly, but at least disable it for now
1963 	endpoint->flags |= OHCI_ENDPOINT_SKIP;
1964 	return B_OK;
1965 }
1966 
1967 
1968 ohci_endpoint_descriptor *
1969 OHCI::_FindInterruptEndpoint(uint8 interval)
1970 {
1971 	uint32 index = 0;
1972 	uint32 power = 1;
1973 	while (power <= OHCI_BIGGEST_INTERVAL / 2) {
1974 		if (power * 2 > interval)
1975 			break;
1976 
1977 		power *= 2;
1978 		index++;
1979 	}
1980 
1981 	return fInterruptEndpoints[index];
1982 }
1983 
1984 
1985 ohci_general_td *
1986 OHCI::_CreateGeneralDescriptor(size_t bufferSize)
1987 {
1988 	ohci_general_td *descriptor;
1989 	phys_addr_t physicalAddress;
1990 
1991 	if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
1992 		sizeof(ohci_general_td)) != B_OK) {
1993 		TRACE_ERROR("failed to allocate general descriptor\n");
1994 		return NULL;
1995 	}
1996 
1997 	descriptor->physical_address = (uint32)physicalAddress;
1998 	descriptor->next_physical_descriptor = 0;
1999 	descriptor->next_logical_descriptor = NULL;
2000 	descriptor->buffer_size = bufferSize;
2001 	if (bufferSize == 0) {
2002 		descriptor->buffer_physical = 0;
2003 		descriptor->buffer_logical = NULL;
2004 		descriptor->last_physical_byte_address = 0;
2005 		return descriptor;
2006 	}
2007 
2008 	if (fStack->AllocateChunk(&descriptor->buffer_logical,
2009 		&physicalAddress, bufferSize) != B_OK) {
2010 		TRACE_ERROR("failed to allocate space for buffer\n");
2011 		fStack->FreeChunk(descriptor, descriptor->physical_address,
2012 			sizeof(ohci_general_td));
2013 		return NULL;
2014 	}
2015 	descriptor->buffer_physical = physicalAddress;
2016 
2017 	descriptor->last_physical_byte_address
2018 		= descriptor->buffer_physical + bufferSize - 1;
2019 	return descriptor;
2020 }
2021 
2022 
2023 void
2024 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor)
2025 {
2026 	if (!descriptor)
2027 		return;
2028 
2029 	if (descriptor->buffer_logical) {
2030 		fStack->FreeChunk(descriptor->buffer_logical,
2031 			descriptor->buffer_physical, descriptor->buffer_size);
2032 	}
2033 
2034 	fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2035 		sizeof(ohci_general_td));
2036 }
2037 
2038 
2039 status_t
2040 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
2041 	ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize)
2042 {
2043 	size_t blockSize = 8192;
2044 	int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize;
2045 	if (descriptorCount == 0)
2046 		descriptorCount = 1;
2047 
2048 	ohci_general_td *firstDescriptor = NULL;
2049 	ohci_general_td *lastDescriptor = *_firstDescriptor;
2050 	for (int32 i = 0; i < descriptorCount; i++) {
2051 		ohci_general_td *descriptor = _CreateGeneralDescriptor(
2052 			min_c(blockSize, bufferSize));
2053 
2054 		if (!descriptor) {
2055 			_FreeDescriptorChain(firstDescriptor);
2056 			return B_NO_MEMORY;
2057 		}
2058 
2059 		descriptor->flags = direction
2060 			| OHCI_TD_BUFFER_ROUNDING
2061 			| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
2062 			| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE)
2063 			| OHCI_TD_TOGGLE_CARRY;
2064 
2065 		// link to previous
2066 		if (lastDescriptor)
2067 			_LinkDescriptors(lastDescriptor, descriptor);
2068 
2069 		bufferSize -= blockSize;
2070 		lastDescriptor = descriptor;
2071 		if (!firstDescriptor)
2072 			firstDescriptor = descriptor;
2073 	}
2074 
2075 	*_firstDescriptor = firstDescriptor;
2076 	*_lastDescriptor = lastDescriptor;
2077 	return B_OK;
2078 }
2079 
2080 
2081 void
2082 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor)
2083 {
2084 	ohci_general_td *current = topDescriptor;
2085 	ohci_general_td *next = NULL;
2086 
2087 	while (current) {
2088 		next = (ohci_general_td *)current->next_logical_descriptor;
2089 		_FreeGeneralDescriptor(current);
2090 		current = next;
2091 	}
2092 }
2093 
2094 
2095 ohci_isochronous_td *
2096 OHCI::_CreateIsochronousDescriptor(size_t bufferSize)
2097 {
2098 	ohci_isochronous_td *descriptor = NULL;
2099 	phys_addr_t physicalAddress;
2100 
2101 	if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
2102 		sizeof(ohci_isochronous_td)) != B_OK) {
2103 		TRACE_ERROR("failed to allocate isochronous descriptor\n");
2104 		return NULL;
2105 	}
2106 
2107 	descriptor->physical_address = (uint32)physicalAddress;
2108 	descriptor->next_physical_descriptor = 0;
2109 	descriptor->next_logical_descriptor = NULL;
2110 	descriptor->next_done_descriptor = NULL;
2111 	descriptor->buffer_size = bufferSize;
2112 	if (bufferSize == 0) {
2113 		descriptor->buffer_page_byte_0 = 0;
2114 		descriptor->buffer_logical = NULL;
2115 		descriptor->last_byte_address = 0;
2116 		return descriptor;
2117 	}
2118 
2119 	if (fStack->AllocateChunk(&descriptor->buffer_logical,
2120 		&physicalAddress, bufferSize) != B_OK) {
2121 		TRACE_ERROR("failed to allocate space for iso.buffer\n");
2122 		fStack->FreeChunk(descriptor, descriptor->physical_address,
2123 			sizeof(ohci_isochronous_td));
2124 		return NULL;
2125 	}
2126 	descriptor->buffer_page_byte_0 = (uint32)physicalAddress;
2127 	descriptor->last_byte_address
2128 		= descriptor->buffer_page_byte_0 + bufferSize - 1;
2129 
2130 	return descriptor;
2131 }
2132 
2133 
2134 void
2135 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor)
2136 {
2137 	if (!descriptor)
2138 		return;
2139 
2140 	if (descriptor->buffer_logical) {
2141 		fStack->FreeChunk(descriptor->buffer_logical,
2142 			descriptor->buffer_page_byte_0, descriptor->buffer_size);
2143 	}
2144 
2145 	fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2146 		sizeof(ohci_general_td));
2147 }
2148 
2149 
2150 status_t
2151 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor,
2152 	ohci_isochronous_td **_lastDescriptor, Transfer *transfer)
2153 {
2154 	Pipe *pipe = transfer->TransferPipe();
2155 	usb_isochronous_data *isochronousData = transfer->IsochronousData();
2156 
2157 	size_t dataLength = transfer->FragmentLength();
2158 	size_t packet_count = isochronousData->packet_count;
2159 
2160 	if (packet_count == 0) {
2161 		TRACE_ERROR("isochronous packet_count should not be equal to zero.");
2162 		return B_BAD_VALUE;
2163 	}
2164 
2165 	size_t packetSize = dataLength / packet_count;
2166 	if (dataLength % packet_count != 0)
2167 		packetSize++;
2168 
2169 	if (packetSize > pipe->MaxPacketSize()) {
2170 		TRACE_ERROR("isochronous packetSize %ld is bigger"
2171 			" than pipe MaxPacketSize %ld.", packetSize, pipe->MaxPacketSize());
2172 		return B_BAD_VALUE;
2173 	}
2174 
2175 	uint16 bandwidth = transfer->Bandwidth() / packet_count;
2176 	if (transfer->Bandwidth() % packet_count != 0)
2177 		bandwidth++;
2178 
2179 	ohci_isochronous_td *firstDescriptor = NULL;
2180 	ohci_isochronous_td *lastDescriptor = *_firstDescriptor;
2181 
2182 	// the frame number currently processed by the host controller
2183 	uint16 currentFrame = fHcca->current_frame_number & 0xFFFF;
2184 	uint16 safeFrames = 5;
2185 
2186 	// The entry where to start inserting the first Isochronous descriptor
2187 	// real frame number may differ in case provided one has not bandwidth
2188 	if (isochronousData->flags & USB_ISO_ASAP ||
2189 		isochronousData->starting_frame_number == NULL)
2190 		// We should stay about 5-10 ms ahead of the controller
2191 		// USB1 frame is equal to 1 ms
2192 		currentFrame += safeFrames;
2193 	else
2194 		currentFrame = *isochronousData->starting_frame_number;
2195 
2196 	uint16 packets = packet_count;
2197 	uint16 frameOffset = 0;
2198 	while (packets > 0) {
2199 		// look for up to 8 continous frames with available bandwidth
2200 		uint16 frameCount = 0;
2201 		while (frameCount < min_c(OHCI_ITD_NOFFSET, packets)
2202 				&& _AllocateIsochronousBandwidth(frameOffset + currentFrame
2203 					+ frameCount, bandwidth))
2204 			frameCount++;
2205 
2206 		if (frameCount == 0) {
2207 			// starting frame has no bandwidth for our transaction - try next
2208 			if (++frameOffset >= 0xFFFF) {
2209 				TRACE_ERROR("failed to allocate bandwidth\n");
2210 				_FreeIsochronousDescriptorChain(firstDescriptor);
2211 				return B_NO_MEMORY;
2212 			}
2213 			continue;
2214 		}
2215 
2216 		ohci_isochronous_td *descriptor = _CreateIsochronousDescriptor(
2217 				packetSize * frameCount);
2218 
2219 		if (!descriptor) {
2220 			TRACE_ERROR("failed to allocate ITD\n");
2221 			_ReleaseIsochronousBandwidth(currentFrame + frameOffset, frameCount);
2222 			_FreeIsochronousDescriptorChain(firstDescriptor);
2223 			return B_NO_MEMORY;
2224 		}
2225 
2226 		uint16 pageOffset = descriptor->buffer_page_byte_0 & 0xfff;
2227 		descriptor->buffer_page_byte_0 &= ~0xfff;
2228 		for (uint16 i = 0; i < frameCount; i++) {
2229 			descriptor->offset[OHCI_ITD_OFFSET_IDX(i)]
2230 				= OHCI_ITD_MK_OFFS(pageOffset + packetSize * i);
2231 		}
2232 
2233 		descriptor->flags = OHCI_ITD_SET_FRAME_COUNT(frameCount)
2234 				| OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED)
2235 				| OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE)
2236 				| OHCI_ITD_SET_STARTING_FRAME(currentFrame + frameOffset);
2237 
2238 		// the last packet may be shorter than other ones in this transfer
2239 		if (packets <= OHCI_ITD_NOFFSET)
2240 			descriptor->last_byte_address
2241 				+= dataLength - packetSize * (packet_count);
2242 
2243 		// link to previous
2244 		if (lastDescriptor)
2245 			_LinkIsochronousDescriptors(lastDescriptor, descriptor, descriptor);
2246 
2247 		lastDescriptor = descriptor;
2248 		if (!firstDescriptor)
2249 			firstDescriptor = descriptor;
2250 
2251 		packets -= frameCount;
2252 
2253 		frameOffset += frameCount;
2254 
2255 		if (packets == 0 && isochronousData->starting_frame_number)
2256 			*isochronousData->starting_frame_number = currentFrame + frameOffset;
2257 	}
2258 
2259 	*_firstDescriptor = firstDescriptor;
2260 	*_lastDescriptor = lastDescriptor;
2261 
2262 	return B_OK;
2263 }
2264 
2265 
2266 void
2267 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor)
2268 {
2269 	ohci_isochronous_td *current = topDescriptor;
2270 	ohci_isochronous_td *next = NULL;
2271 
2272 	while (current) {
2273 		next = (ohci_isochronous_td *)current->next_done_descriptor;
2274 		_FreeIsochronousDescriptor(current);
2275 		current = next;
2276 	}
2277 }
2278 
2279 
2280 size_t
2281 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, iovec *vector,
2282 	size_t vectorCount)
2283 {
2284 	ohci_general_td *current = topDescriptor;
2285 	size_t actualLength = 0;
2286 	size_t vectorIndex = 0;
2287 	size_t vectorOffset = 0;
2288 	size_t bufferOffset = 0;
2289 
2290 	while (current) {
2291 		if (!current->buffer_logical)
2292 			break;
2293 
2294 		while (true) {
2295 			size_t length = min_c(current->buffer_size - bufferOffset,
2296 				vector[vectorIndex].iov_len - vectorOffset);
2297 
2298 			TRACE("copying %ld bytes to bufferOffset %ld from"
2299 				" vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
2300 				vectorOffset, vectorIndex, vectorCount);
2301 			memcpy((uint8 *)current->buffer_logical + bufferOffset,
2302 				(uint8 *)vector[vectorIndex].iov_base + vectorOffset, length);
2303 
2304 			actualLength += length;
2305 			vectorOffset += length;
2306 			bufferOffset += length;
2307 
2308 			if (vectorOffset >= vector[vectorIndex].iov_len) {
2309 				if (++vectorIndex >= vectorCount) {
2310 					TRACE("wrote descriptor chain (%ld bytes, no"
2311 						" more vectors)\n", actualLength);
2312 					return actualLength;
2313 				}
2314 
2315 				vectorOffset = 0;
2316 			}
2317 
2318 			if (bufferOffset >= current->buffer_size) {
2319 				bufferOffset = 0;
2320 				break;
2321 			}
2322 		}
2323 
2324 		if (!current->next_logical_descriptor)
2325 			break;
2326 
2327 		current = (ohci_general_td *)current->next_logical_descriptor;
2328 	}
2329 
2330 	TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
2331 	return actualLength;
2332 }
2333 
2334 
2335 size_t
2336 OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor,
2337 	iovec *vector, size_t vectorCount)
2338 {
2339 	ohci_isochronous_td *current = topDescriptor;
2340 	size_t actualLength = 0;
2341 	size_t vectorIndex = 0;
2342 	size_t vectorOffset = 0;
2343 	size_t bufferOffset = 0;
2344 
2345 	while (current) {
2346 		if (!current->buffer_logical)
2347 			break;
2348 
2349 		while (true) {
2350 			size_t length = min_c(current->buffer_size - bufferOffset,
2351 				vector[vectorIndex].iov_len - vectorOffset);
2352 
2353 			TRACE("copying %ld bytes to bufferOffset %ld from"
2354 				" vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
2355 				vectorOffset, vectorIndex, vectorCount);
2356 			memcpy((uint8 *)current->buffer_logical + bufferOffset,
2357 				(uint8 *)vector[vectorIndex].iov_base + vectorOffset, length);
2358 
2359 			actualLength += length;
2360 			vectorOffset += length;
2361 			bufferOffset += length;
2362 
2363 			if (vectorOffset >= vector[vectorIndex].iov_len) {
2364 				if (++vectorIndex >= vectorCount) {
2365 					TRACE("wrote descriptor chain (%ld bytes, no"
2366 						" more vectors)\n", actualLength);
2367 					return actualLength;
2368 				}
2369 
2370 				vectorOffset = 0;
2371 			}
2372 
2373 			if (bufferOffset >= current->buffer_size) {
2374 				bufferOffset = 0;
2375 				break;
2376 			}
2377 		}
2378 
2379 		if (!current->next_logical_descriptor)
2380 			break;
2381 
2382 		current = (ohci_isochronous_td *)current->next_logical_descriptor;
2383 	}
2384 
2385 	TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
2386 	return actualLength;
2387 }
2388 
2389 
2390 size_t
2391 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, iovec *vector,
2392 	size_t vectorCount)
2393 {
2394 	ohci_general_td *current = topDescriptor;
2395 	size_t actualLength = 0;
2396 	size_t vectorIndex = 0;
2397 	size_t vectorOffset = 0;
2398 	size_t bufferOffset = 0;
2399 
2400 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2401 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
2402 		if (!current->buffer_logical)
2403 			break;
2404 
2405 		size_t bufferSize = current->buffer_size;
2406 		if (current->buffer_physical != 0) {
2407 			bufferSize -= current->last_physical_byte_address
2408 				- current->buffer_physical + 1;
2409 		}
2410 
2411 		while (true) {
2412 			size_t length = min_c(bufferSize - bufferOffset,
2413 				vector[vectorIndex].iov_len - vectorOffset);
2414 
2415 			TRACE("copying %ld bytes to vectorOffset %ld from"
2416 				" bufferOffset %ld at index %ld of %ld\n", length, vectorOffset,
2417 				bufferOffset, vectorIndex, vectorCount);
2418 			memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset,
2419 				(uint8 *)current->buffer_logical + bufferOffset, length);
2420 
2421 			actualLength += length;
2422 			vectorOffset += length;
2423 			bufferOffset += length;
2424 
2425 			if (vectorOffset >= vector[vectorIndex].iov_len) {
2426 				if (++vectorIndex >= vectorCount) {
2427 					TRACE("read descriptor chain (%ld bytes, no more vectors)\n",
2428 						actualLength);
2429 					return actualLength;
2430 				}
2431 
2432 				vectorOffset = 0;
2433 			}
2434 
2435 			if (bufferOffset >= bufferSize) {
2436 				bufferOffset = 0;
2437 				break;
2438 			}
2439 		}
2440 
2441 		current = (ohci_general_td *)current->next_logical_descriptor;
2442 	}
2443 
2444 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2445 	return actualLength;
2446 }
2447 
2448 
2449 void
2450 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor,
2451 	iovec *vector, size_t vectorCount)
2452 {
2453 	ohci_isochronous_td *current = topDescriptor;
2454 	size_t actualLength = 0;
2455 	size_t vectorIndex = 0;
2456 	size_t vectorOffset = 0;
2457 	size_t bufferOffset = 0;
2458 
2459 	while (current && OHCI_ITD_GET_CONDITION_CODE(current->flags)
2460 			!= OHCI_ITD_CONDITION_NOT_ACCESSED) {
2461 		size_t bufferSize = current->buffer_size;
2462 		if (current->buffer_logical != NULL && bufferSize > 0) {
2463 			while (true) {
2464 				size_t length = min_c(bufferSize - bufferOffset,
2465 					vector[vectorIndex].iov_len - vectorOffset);
2466 
2467 				TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset"
2468 					" %ld at index %ld of %ld\n", length, vectorOffset,
2469 					bufferOffset, vectorIndex, vectorCount);
2470 				memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset,
2471 					(uint8 *)current->buffer_logical + bufferOffset, length);
2472 
2473 				actualLength += length;
2474 				vectorOffset += length;
2475 				bufferOffset += length;
2476 
2477 				if (vectorOffset >= vector[vectorIndex].iov_len) {
2478 					if (++vectorIndex >= vectorCount) {
2479 						TRACE("read descriptor chain (%ld bytes, "
2480 							"no more vectors)\n", actualLength);
2481 						return;
2482 					}
2483 
2484 					vectorOffset = 0;
2485 				}
2486 
2487 				if (bufferOffset >= bufferSize) {
2488 					bufferOffset = 0;
2489 					break;
2490 				}
2491 			}
2492 		}
2493 
2494 		current = (ohci_isochronous_td *)current->next_done_descriptor;
2495 	}
2496 
2497 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2498 	return;
2499 }
2500 
2501 
2502 size_t
2503 OHCI::_ReadActualLength(ohci_general_td *topDescriptor)
2504 {
2505 	ohci_general_td *current = topDescriptor;
2506 	size_t actualLength = 0;
2507 
2508 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2509 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
2510 		size_t length = current->buffer_size;
2511 		if (current->buffer_physical != 0) {
2512 			length -= current->last_physical_byte_address
2513 				- current->buffer_physical + 1;
2514 		}
2515 
2516 		actualLength += length;
2517 		current = (ohci_general_td *)current->next_logical_descriptor;
2518 	}
2519 
2520 	TRACE("read actual length (%ld bytes)\n", actualLength);
2521 	return actualLength;
2522 }
2523 
2524 
2525 void
2526 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second)
2527 {
2528 	first->next_physical_descriptor = second->physical_address;
2529 	first->next_logical_descriptor = second;
2530 }
2531 
2532 
2533 void
2534 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td *first,
2535 	ohci_isochronous_td *second, ohci_isochronous_td *nextDone)
2536 {
2537 	first->next_physical_descriptor = second->physical_address;
2538 	first->next_logical_descriptor = second;
2539 	first->next_done_descriptor = nextDone;
2540 }
2541 
2542 
2543 bool
2544 OHCI::_AllocateIsochronousBandwidth(uint16 frame, uint16 size)
2545 {
2546 	frame %= NUMBER_OF_FRAMES;
2547 	if (size > fFrameBandwidth[frame])
2548 		return false;
2549 
2550 	fFrameBandwidth[frame]-= size;
2551 	return true;
2552 }
2553 
2554 
2555 void
2556 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame, uint16 frameCount)
2557 {
2558 	for (size_t index = 0; index < frameCount; index++) {
2559 		uint16 frame = (startFrame + index) % NUMBER_OF_FRAMES;
2560 		fFrameBandwidth[frame] = MAX_AVAILABLE_BANDWIDTH;
2561 	}
2562 }
2563 
2564 
2565 status_t
2566 OHCI::_GetStatusOfConditionCode(uint8 conditionCode)
2567 {
2568 	switch (conditionCode) {
2569 		case OHCI_TD_CONDITION_NO_ERROR:
2570 			return B_OK;
2571 
2572 		case OHCI_TD_CONDITION_CRC_ERROR:
2573 		case OHCI_TD_CONDITION_BIT_STUFFING:
2574 		case OHCI_TD_CONDITION_TOGGLE_MISMATCH:
2575 			return B_DEV_CRC_ERROR;
2576 
2577 		case OHCI_TD_CONDITION_STALL:
2578 			return B_DEV_STALLED;
2579 
2580 		case OHCI_TD_CONDITION_NO_RESPONSE:
2581 			return B_TIMED_OUT;
2582 
2583 		case OHCI_TD_CONDITION_PID_CHECK_FAILURE:
2584 			return B_DEV_BAD_PID;
2585 
2586 		case OHCI_TD_CONDITION_UNEXPECTED_PID:
2587 			return B_DEV_UNEXPECTED_PID;
2588 
2589 		case OHCI_TD_CONDITION_DATA_OVERRUN:
2590 			return B_DEV_DATA_OVERRUN;
2591 
2592 		case OHCI_TD_CONDITION_DATA_UNDERRUN:
2593 			return B_DEV_DATA_UNDERRUN;
2594 
2595 		case OHCI_TD_CONDITION_BUFFER_OVERRUN:
2596 			return B_DEV_FIFO_OVERRUN;
2597 
2598 		case OHCI_TD_CONDITION_BUFFER_UNDERRUN:
2599 			return B_DEV_FIFO_UNDERRUN;
2600 
2601 		case OHCI_TD_CONDITION_NOT_ACCESSED:
2602 			return B_DEV_PENDING;
2603 
2604 		case 0x0E:
2605 			return B_DEV_TOO_LATE; // PSW: _NOT_ACCESSED
2606 
2607 		default:
2608 			break;
2609 	}
2610 
2611 	return B_ERROR;
2612 }
2613 
2614 
2615 bool
2616 OHCI::_LockEndpoints()
2617 {
2618 	return (mutex_lock(&fEndpointLock) == B_OK);
2619 }
2620 
2621 
2622 void
2623 OHCI::_UnlockEndpoints()
2624 {
2625 	mutex_unlock(&fEndpointLock);
2626 }
2627 
2628 
2629 inline void
2630 OHCI::_WriteReg(uint32 reg, uint32 value)
2631 {
2632 	*(volatile uint32 *)(fOperationalRegisters + reg) = value;
2633 }
2634 
2635 
2636 inline uint32
2637 OHCI::_ReadReg(uint32 reg)
2638 {
2639 	return *(volatile uint32 *)(fOperationalRegisters + reg);
2640 }
2641 
2642 
2643 void
2644 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint)
2645 {
2646 	dprintf("endpoint %p\n", endpoint);
2647 	dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags);
2648 	dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor);
2649 	dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor);
2650 	dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint);
2651 	dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address);
2652 	dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor);
2653 	dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint);
2654 }
2655 
2656 
2657 void
2658 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor)
2659 {
2660 	while (topDescriptor) {
2661 		dprintf("descriptor %p\n", topDescriptor);
2662 		dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2663 		dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical);
2664 		dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2665 		dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address);
2666 		dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2667 		dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2668 		dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2669 		dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2670 
2671 		topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor;
2672 	}
2673 }
2674 
2675 
2676 void
2677 OHCI::_PrintDescriptorChain(ohci_isochronous_td *topDescriptor)
2678 {
2679 	while (topDescriptor) {
2680 		dprintf("iso.descriptor %p\n", topDescriptor);
2681 		dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2682 		dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32 "\n", topDescriptor->buffer_page_byte_0);
2683 		dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2684 		dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_byte_address);
2685 		dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n"
2686 							"\t0x%04x 0x%04x 0x%04x 0x%04x\n",
2687 				topDescriptor->offset[0], topDescriptor->offset[1],
2688 				topDescriptor->offset[2], topDescriptor->offset[3],
2689 				topDescriptor->offset[4], topDescriptor->offset[5],
2690 				topDescriptor->offset[6], topDescriptor->offset[7]);
2691 		dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2692 		dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2693 		dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2694 		dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2695 		dprintf("\tnext_done....... %p\n", topDescriptor->next_done_descriptor);
2696 
2697 		topDescriptor = (ohci_isochronous_td *)topDescriptor->next_done_descriptor;
2698 	}
2699 }
2700 
2701