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