xref: /haiku/src/add-ons/kernel/busses/usb/ohci.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
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 (fIRQ == 0xFF)
548 		fIRQ = 0;
549 
550 	if (fPci->get_msi_count(fDevice) >= 1) {
551 		uint32 msiVector = 0;
552 		if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
553 			&& fPci->enable_msi(fDevice) == B_OK) {
554 			TRACE_ALWAYS("using message signaled interrupts\n");
555 			fIRQ = msiVector;
556 			fUseMSI = true;
557 		}
558 	}
559 
560 	if (fIRQ == 0) {
561 		TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
562 			fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
563 		return;
564 	}
565 
566 	// Install the interrupt handler
567 	TRACE("installing interrupt handler\n");
568 	install_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this, 0);
569 
570 	// Enable interesting interrupts now that the handler is in place
571 	_WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
572 		| OHCI_MASTER_INTERRUPT_ENABLE);
573 
574 	TRACE("OHCI host controller driver constructed\n");
575 	fInitOK = true;
576 }
577 
578 
579 OHCI::~OHCI()
580 {
581 	int32 result = 0;
582 	fStopFinishThread = true;
583 	delete_sem(fFinishTransfersSem);
584 	wait_for_thread(fFinishThread, &result);
585 
586 	remove_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this);
587 
588 	_LockEndpoints();
589 	mutex_destroy(&fEndpointLock);
590 
591 	if (fHccaArea >= B_OK)
592 		delete_area(fHccaArea);
593 	if (fRegisterArea >= B_OK)
594 		delete_area(fRegisterArea);
595 
596 	_FreeEndpoint(fDummyControl);
597 	_FreeEndpoint(fDummyBulk);
598 	_FreeEndpoint(fDummyIsochronous);
599 
600 	if (fInterruptEndpoints != NULL) {
601 		for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++)
602 			_FreeEndpoint(fInterruptEndpoints[i]);
603 	}
604 
605 	delete [] fFrameBandwidth;
606 	delete [] fInterruptEndpoints;
607 	delete fRootHub;
608 
609 	if (fUseMSI) {
610 		fPci->disable_msi(fDevice);
611 		fPci->unconfigure_msi(fDevice);
612 	}
613 }
614 
615 
616 status_t
617 OHCI::Start()
618 {
619 	TRACE("starting OHCI host controller\n");
620 
621 	uint32 control = _ReadReg(OHCI_CONTROL);
622 	if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
623 		!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
624 		TRACE_ERROR("controller not started (0x%08" B_PRIx32 ")!\n", control);
625 		return B_ERROR;
626 	} else
627 		TRACE("controller is operational!\n");
628 
629 	fRootHubAddress = AllocateAddress();
630 	fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
631 	if (!fRootHub) {
632 		TRACE_ERROR("no memory to allocate root hub\n");
633 		return B_NO_MEMORY;
634 	}
635 
636 	if (fRootHub->InitCheck() < B_OK) {
637 		TRACE_ERROR("root hub failed init check\n");
638 		return B_ERROR;
639 	}
640 
641 	SetRootHub(fRootHub);
642 
643 	fRootHub->RegisterNode(Node());
644 
645 	TRACE_ALWAYS("successfully started the controller\n");
646 	return BusManager::Start();
647 }
648 
649 
650 status_t
651 OHCI::SubmitTransfer(Transfer *transfer)
652 {
653 	// short circuit the root hub
654 	if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
655 		return fRootHub->ProcessTransfer(this, transfer);
656 
657 	uint32 type = transfer->TransferPipe()->Type();
658 	if (type & USB_OBJECT_CONTROL_PIPE) {
659 		TRACE("submitting request\n");
660 		return _SubmitRequest(transfer);
661 	}
662 
663 	if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) {
664 		TRACE("submitting %s transfer\n",
665 			(type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt");
666 		return _SubmitTransfer(transfer);
667 	}
668 
669 	if (type & USB_OBJECT_ISO_PIPE) {
670 		TRACE("submitting isochronous transfer\n");
671 		return _SubmitIsochronousTransfer(transfer);
672 	}
673 
674 	TRACE_ERROR("tried to submit transfer for unknown pipe type %" B_PRIu32 "\n",
675 		type);
676 	return B_ERROR;
677 }
678 
679 
680 status_t
681 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
682 {
683 	if (!Lock())
684 		return B_ERROR;
685 
686 	struct transfer_entry {
687 		Transfer *			transfer;
688 		transfer_entry *	next;
689 	};
690 
691 	transfer_entry *list = NULL;
692 	transfer_data *current = fFirstTransfer;
693 	while (current) {
694 		if (current->transfer && current->transfer->TransferPipe() == pipe) {
695 			// Check if the skip bit is already set
696 			if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) {
697 				current->endpoint->flags |= OHCI_ENDPOINT_SKIP;
698 				// In case the controller is processing
699 				// this endpoint, wait for it to finish
700 				snooze(1000);
701 			}
702 
703 			// Clear the endpoint
704 			current->endpoint->head_physical_descriptor
705 				= current->endpoint->tail_physical_descriptor;
706 
707 			if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
708 				ohci_isochronous_td *descriptor
709 					= (ohci_isochronous_td *)current->first_descriptor;
710 				while (descriptor) {
711 					uint16 frame = OHCI_ITD_GET_STARTING_FRAME(
712 						descriptor->flags);
713 					_ReleaseIsochronousBandwidth(frame,
714 						OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
715 					if (descriptor
716 							== (ohci_isochronous_td*)current->last_descriptor)
717 						// this is the last ITD of the transfer
718 						break;
719 
720 					descriptor
721 						= (ohci_isochronous_td *)
722 						descriptor->next_done_descriptor;
723 				}
724 			}
725 
726 			transfer_entry *entry
727 				= (transfer_entry *)malloc(sizeof(transfer_entry));
728 			if (entry != NULL) {
729 				entry->transfer = current->transfer;
730 				current->transfer = NULL;
731 				entry->next = list;
732 				list = entry;
733 			}
734 
735 			current->canceled = true;
736 		}
737 		current = current->link;
738 	}
739 
740 	Unlock();
741 
742 	while (list != NULL) {
743 		transfer_entry *next = list->next;
744 
745 		// If the transfer is canceled by force, the one causing the
746 		// cancel is possibly not the one who initiated the transfer
747 		// and the callback is likely not safe anymore
748 		if (!force)
749 			list->transfer->Finished(B_CANCELED, 0);
750 
751 		delete list->transfer;
752 		free(list);
753 		list = next;
754 	}
755 
756 	// wait for any transfers that might have made it before canceling
757 	while (fProcessingPipe == pipe)
758 		snooze(1000);
759 
760 	// notify the finisher so it can clean up the canceled transfers
761 	release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
762 	return B_OK;
763 }
764 
765 
766 status_t
767 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
768 {
769 	TRACE("pipe change %d for pipe %p\n", change, pipe);
770 	if (pipe->DeviceAddress() == fRootHubAddress) {
771 		// no need to insert/remove endpoint descriptors for the root hub
772 		return B_OK;
773 	}
774 
775 	switch (change) {
776 		case USB_CHANGE_CREATED:
777 			return _InsertEndpointForPipe(pipe);
778 
779 		case USB_CHANGE_DESTROYED:
780 			return _RemoveEndpointForPipe(pipe);
781 
782 		case USB_CHANGE_PIPE_POLICY_CHANGED:
783 			TRACE("pipe policy changing unhandled!\n");
784 			break;
785 
786 		default:
787 			TRACE_ERROR("unknown pipe change!\n");
788 			return B_ERROR;
789 	}
790 
791 	return B_OK;
792 }
793 
794 
795 status_t
796 OHCI::GetPortStatus(uint8 index, usb_port_status *status)
797 {
798 	if (index >= fPortCount) {
799 		TRACE_ERROR("get port status for invalid port %u\n", index);
800 		return B_BAD_INDEX;
801 	}
802 
803 	status->status = status->change = 0;
804 	uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index));
805 
806 	// status
807 	if (portStatus & OHCI_RH_PORTSTATUS_CCS)
808 		status->status |= PORT_STATUS_CONNECTION;
809 	if (portStatus & OHCI_RH_PORTSTATUS_PES)
810 		status->status |= PORT_STATUS_ENABLE;
811 	if (portStatus & OHCI_RH_PORTSTATUS_PSS)
812 		status->status |= PORT_STATUS_SUSPEND;
813 	if (portStatus & OHCI_RH_PORTSTATUS_POCI)
814 		status->status |= PORT_STATUS_OVER_CURRENT;
815 	if (portStatus & OHCI_RH_PORTSTATUS_PRS)
816 		status->status |= PORT_STATUS_RESET;
817 	if (portStatus & OHCI_RH_PORTSTATUS_PPS)
818 		status->status |= PORT_STATUS_POWER;
819 	if (portStatus & OHCI_RH_PORTSTATUS_LSDA)
820 		status->status |= PORT_STATUS_LOW_SPEED;
821 
822 	// change
823 	if (portStatus & OHCI_RH_PORTSTATUS_CSC)
824 		status->change |= PORT_STATUS_CONNECTION;
825 	if (portStatus & OHCI_RH_PORTSTATUS_PESC)
826 		status->change |= PORT_STATUS_ENABLE;
827 	if (portStatus & OHCI_RH_PORTSTATUS_PSSC)
828 		status->change |= PORT_STATUS_SUSPEND;
829 	if (portStatus & OHCI_RH_PORTSTATUS_OCIC)
830 		status->change |= PORT_STATUS_OVER_CURRENT;
831 	if (portStatus & OHCI_RH_PORTSTATUS_PRSC)
832 		status->change |= PORT_STATUS_RESET;
833 
834 	TRACE("port %u status 0x%04x change 0x%04x\n", index,
835 		status->status, status->change);
836 	return B_OK;
837 }
838 
839 
840 status_t
841 OHCI::SetPortFeature(uint8 index, uint16 feature)
842 {
843 	TRACE("set port feature index %u feature %u\n", index, feature);
844 	if (index > fPortCount)
845 		return B_BAD_INDEX;
846 
847 	switch (feature) {
848 		case PORT_ENABLE:
849 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES);
850 			return B_OK;
851 
852 		case PORT_SUSPEND:
853 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS);
854 			return B_OK;
855 
856 		case PORT_RESET:
857 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
858 			return B_OK;
859 
860 		case PORT_POWER:
861 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
862 			return B_OK;
863 	}
864 
865 	return B_BAD_VALUE;
866 }
867 
868 
869 status_t
870 OHCI::ClearPortFeature(uint8 index, uint16 feature)
871 {
872 	TRACE("clear port feature index %u feature %u\n", index, feature);
873 	if (index > fPortCount)
874 		return B_BAD_INDEX;
875 
876 	switch (feature) {
877 		case PORT_ENABLE:
878 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS);
879 			return B_OK;
880 
881 		case PORT_SUSPEND:
882 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI);
883 			return B_OK;
884 
885 		case PORT_POWER:
886 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA);
887 			return B_OK;
888 
889 		case C_PORT_CONNECTION:
890 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
891 			return B_OK;
892 
893 		case C_PORT_ENABLE:
894 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC);
895 			return B_OK;
896 
897 		case C_PORT_SUSPEND:
898 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC);
899 			return B_OK;
900 
901 		case C_PORT_OVER_CURRENT:
902 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC);
903 			return B_OK;
904 
905 		case C_PORT_RESET:
906 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC);
907 			return B_OK;
908 	}
909 
910 	return B_BAD_VALUE;
911 }
912 
913 
914 int32
915 OHCI::_InterruptHandler(void *data)
916 {
917 	return ((OHCI *)data)->_Interrupt();
918 }
919 
920 
921 int32
922 OHCI::_Interrupt()
923 {
924 	static spinlock lock = B_SPINLOCK_INITIALIZER;
925 	acquire_spinlock(&lock);
926 
927 	uint32 status = 0;
928 	uint32 acknowledge = 0;
929 	bool finishTransfers = false;
930 	int32 result = B_HANDLED_INTERRUPT;
931 
932 	// The LSb of done_head is used to inform the HCD that an interrupt
933 	// condition exists for both the done list and for another event recorded in
934 	// the HcInterruptStatus register. If done_head is 0, then the interrupt
935 	// was caused by other than the HccaDoneHead update and the
936 	// HcInterruptStatus register needs to be accessed to determine that exact
937 	// interrupt cause. If HccDoneHead is nonzero, then a done list update
938 	// interrupt is indicated and if the LSb of the Dword is nonzero, then an
939 	// additional interrupt event is indicated and HcInterruptStatus should be
940 	// checked to determine its cause.
941 	uint32 doneHead = fHcca->done_head;
942 	if (doneHead != 0) {
943 		status = OHCI_WRITEBACK_DONE_HEAD;
944 		if (doneHead & OHCI_DONE_INTERRUPTS)
945 			status |= _ReadReg(OHCI_INTERRUPT_STATUS)
946 				& _ReadReg(OHCI_INTERRUPT_ENABLE);
947 	} else {
948 		status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE)
949 			& ~OHCI_WRITEBACK_DONE_HEAD;
950 		if (status == 0) {
951 			// Nothing to be done (PCI shared interrupt)
952 			release_spinlock(&lock);
953 			return B_UNHANDLED_INTERRUPT;
954 		}
955 	}
956 
957 	if (status & OHCI_SCHEDULING_OVERRUN) {
958 		TRACE_MODULE("scheduling overrun occured\n");
959 		acknowledge |= OHCI_SCHEDULING_OVERRUN;
960 	}
961 
962 	if (status & OHCI_WRITEBACK_DONE_HEAD) {
963 		TRACE_MODULE("transfer descriptors processed\n");
964 		fHcca->done_head = 0;
965 		acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
966 		result = B_INVOKE_SCHEDULER;
967 		finishTransfers = true;
968 	}
969 
970 	if (status & OHCI_RESUME_DETECTED) {
971 		TRACE_MODULE("resume detected\n");
972 		acknowledge |= OHCI_RESUME_DETECTED;
973 	}
974 
975 	if (status & OHCI_UNRECOVERABLE_ERROR) {
976 		TRACE_MODULE_ERROR("unrecoverable error - controller halted\n");
977 		_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
978 		// TODO: clear all pending transfers, reset and resetup the controller
979 	}
980 
981 	if (status & OHCI_ROOT_HUB_STATUS_CHANGE) {
982 		TRACE_MODULE("root hub status change\n");
983 		// Disable the interrupt as it will otherwise be retriggered until the
984 		// port has been reset and the change is cleared explicitly.
985 		// TODO: renable it once we use status changes instead of polling
986 		_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE);
987 		acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
988 	}
989 
990 	if (acknowledge != 0)
991 		_WriteReg(OHCI_INTERRUPT_STATUS, acknowledge);
992 
993 	release_spinlock(&lock);
994 
995 	if (finishTransfers)
996 		release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
997 
998 	return result;
999 }
1000 
1001 
1002 status_t
1003 OHCI::_AddPendingTransfer(Transfer *transfer,
1004 	ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor,
1005 	ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor,
1006 	bool directionIn)
1007 {
1008 	if (!transfer || !endpoint || !lastDescriptor)
1009 		return B_BAD_VALUE;
1010 
1011 	transfer_data *data = new(std::nothrow) transfer_data;
1012 	if (!data)
1013 		return B_NO_MEMORY;
1014 
1015 	status_t result = transfer->InitKernelAccess();
1016 	if (result < B_OK) {
1017 		delete data;
1018 		return result;
1019 	}
1020 
1021 	data->transfer = transfer;
1022 	data->endpoint = endpoint;
1023 	data->incoming = directionIn;
1024 	data->canceled = false;
1025 	data->link = NULL;
1026 
1027 	// the current tail will become the first descriptor
1028 	data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor;
1029 
1030 	// the data and first descriptors might be the same
1031 	if (dataDescriptor == firstDescriptor)
1032 		data->data_descriptor = data->first_descriptor;
1033 	else
1034 		data->data_descriptor = dataDescriptor;
1035 
1036 	// even the last and the first descriptor might be the same
1037 	if (lastDescriptor == firstDescriptor)
1038 		data->last_descriptor = data->first_descriptor;
1039 	else
1040 		data->last_descriptor = lastDescriptor;
1041 
1042 	if (!Lock()) {
1043 		delete data;
1044 		return B_ERROR;
1045 	}
1046 
1047 	if (fLastTransfer)
1048 		fLastTransfer->link = data;
1049 	else
1050 		fFirstTransfer = data;
1051 
1052 	fLastTransfer = data;
1053 	Unlock();
1054 
1055 	return B_OK;
1056 }
1057 
1058 
1059 status_t
1060 OHCI::_AddPendingIsochronousTransfer(Transfer *transfer,
1061 	ohci_endpoint_descriptor *endpoint, ohci_isochronous_td *firstDescriptor,
1062 	ohci_isochronous_td *lastDescriptor, bool directionIn)
1063 {
1064 	if (!transfer || !endpoint || !lastDescriptor)
1065 		return B_BAD_VALUE;
1066 
1067 	transfer_data *data = new(std::nothrow) transfer_data;
1068 	if (!data)
1069 		return B_NO_MEMORY;
1070 
1071 	status_t result = transfer->InitKernelAccess();
1072 	if (result < B_OK) {
1073 		delete data;
1074 		return result;
1075 	}
1076 
1077 	data->transfer = transfer;
1078 	data->endpoint = endpoint;
1079 	data->incoming = directionIn;
1080 	data->canceled = false;
1081 	data->link = NULL;
1082 
1083 	// the current tail will become the first descriptor
1084 	data->first_descriptor = (ohci_general_td*)endpoint->tail_logical_descriptor;
1085 
1086 	// the data and first descriptors are the same
1087 	data->data_descriptor = data->first_descriptor;
1088 
1089 	// the last and the first descriptor might be the same
1090 	if (lastDescriptor == firstDescriptor)
1091 		data->last_descriptor = data->first_descriptor;
1092 	else
1093 		data->last_descriptor = (ohci_general_td*)lastDescriptor;
1094 
1095 	if (!Lock()) {
1096 		delete data;
1097 		return B_ERROR;
1098 	}
1099 
1100 	if (fLastTransfer)
1101 		fLastTransfer->link = data;
1102 	else
1103 		fFirstTransfer = data;
1104 
1105 	fLastTransfer = data;
1106 	Unlock();
1107 
1108 	return B_OK;
1109 }
1110 
1111 
1112 int32
1113 OHCI::_FinishThread(void *data)
1114 {
1115 	((OHCI *)data)->_FinishTransfers();
1116 	return B_OK;
1117 }
1118 
1119 
1120 void
1121 OHCI::_FinishTransfers()
1122 {
1123 	while (!fStopFinishThread) {
1124 		if (acquire_sem(fFinishTransfersSem) < B_OK)
1125 			continue;
1126 
1127 		// eat up sems that have been released by multiple interrupts
1128 		int32 semCount = 0;
1129 		get_sem_count(fFinishTransfersSem, &semCount);
1130 		if (semCount > 0)
1131 			acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);
1132 
1133 		if (!Lock())
1134 			continue;
1135 
1136 		TRACE("finishing transfers (first transfer: %p; last"
1137 			" transfer: %p)\n", fFirstTransfer, fLastTransfer);
1138 		transfer_data *lastTransfer = NULL;
1139 		transfer_data *transfer = fFirstTransfer;
1140 		Unlock();
1141 
1142 		while (transfer) {
1143 			bool transferDone = false;
1144 			ohci_general_td *descriptor = transfer->first_descriptor;
1145 			ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1146 			status_t callbackStatus = B_OK;
1147 
1148 			if (endpoint->flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT) {
1149 				transfer_data *next = transfer->link;
1150 				if (_FinishIsochronousTransfer(transfer, &lastTransfer)) {
1151 					delete transfer->transfer;
1152 					delete transfer;
1153 				}
1154 				transfer = next;
1155 				continue;
1156 			}
1157 
1158 			MutexLocker endpointLocker(endpoint->lock);
1159 
1160 			if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1161 					!= endpoint->tail_physical_descriptor
1162 						&& (endpoint->head_physical_descriptor
1163 							& OHCI_ENDPOINT_HALTED) == 0) {
1164 				// there are still active transfers on this endpoint, we need
1165 				// to wait for all of them to complete, otherwise we'd read
1166 				// a potentially bogus data toggle value below
1167 				TRACE("endpoint %p still has active tds\n", endpoint);
1168 				lastTransfer = transfer;
1169 				transfer = transfer->link;
1170 				continue;
1171 			}
1172 
1173 			endpointLocker.Unlock();
1174 
1175 			while (descriptor && !transfer->canceled) {
1176 				uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1177 				if (status == OHCI_TD_CONDITION_NOT_ACCESSED) {
1178 					// td is still active
1179 					TRACE("td %p still active\n", descriptor);
1180 					break;
1181 				}
1182 
1183 				if (status != OHCI_TD_CONDITION_NO_ERROR) {
1184 					// an error occured, but we must ensure that the td
1185 					// was actually done
1186 					if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) {
1187 						// the endpoint is halted, this guaratees us that this
1188 						// descriptor has passed (we don't know if the endpoint
1189 						// was halted because of this td, but we do not need
1190 						// to know, as when it was halted by another td this
1191 						// still ensures that this td was handled before).
1192 						TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status);
1193 
1194 						callbackStatus = _GetStatusOfConditionCode(status);
1195 
1196 						transferDone = true;
1197 						break;
1198 					} else {
1199 						// an error occured but the endpoint is not halted so
1200 						// the td is in fact still active
1201 						TRACE("td %p active with error\n", descriptor);
1202 						break;
1203 					}
1204 				}
1205 
1206 				// the td has completed without an error
1207 				TRACE("td %p done\n", descriptor);
1208 
1209 				if (descriptor == transfer->last_descriptor
1210 					|| descriptor->buffer_physical != 0) {
1211 					// this is the last td of the transfer or a short packet
1212 					callbackStatus = B_OK;
1213 					transferDone = true;
1214 					break;
1215 				}
1216 
1217 				descriptor
1218 					= (ohci_general_td *)descriptor->next_logical_descriptor;
1219 			}
1220 
1221 			if (transfer->canceled) {
1222 				// when a transfer is canceled, all transfers to that endpoint
1223 				// are canceled by setting the head pointer to the tail pointer
1224 				// which causes all of the tds to become "free" (as they are
1225 				// inaccessible and not accessed anymore (as setting the head
1226 				// pointer required disabling the endpoint))
1227 				callbackStatus = B_OK;
1228 				transferDone = true;
1229 			}
1230 
1231 			if (!transferDone) {
1232 				lastTransfer = transfer;
1233 				transfer = transfer->link;
1234 				continue;
1235 			}
1236 
1237 			// remove the transfer from the list first so we are sure
1238 			// it doesn't get canceled while we still process it
1239 			transfer_data *next = transfer->link;
1240 			if (Lock()) {
1241 				if (lastTransfer)
1242 					lastTransfer->link = transfer->link;
1243 
1244 				if (transfer == fFirstTransfer)
1245 					fFirstTransfer = transfer->link;
1246 				if (transfer == fLastTransfer)
1247 					fLastTransfer = lastTransfer;
1248 
1249 				// store the currently processing pipe here so we can wait
1250 				// in cancel if we are processing something on the target pipe
1251 				if (!transfer->canceled)
1252 					fProcessingPipe = transfer->transfer->TransferPipe();
1253 
1254 				transfer->link = NULL;
1255 				Unlock();
1256 			}
1257 
1258 			// break the descriptor chain on the last descriptor
1259 			transfer->last_descriptor->next_logical_descriptor = NULL;
1260 			TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n",
1261 				transfer, callbackStatus);
1262 
1263 			// if canceled the callback has already been called
1264 			if (!transfer->canceled) {
1265 				size_t actualLength = 0;
1266 				if (callbackStatus == B_OK) {
1267 					if (transfer->data_descriptor && transfer->incoming) {
1268 						// data to read out
1269 						generic_io_vec *vector = transfer->transfer->Vector();
1270 						size_t vectorCount = transfer->transfer->VectorCount();
1271 
1272 						transfer->transfer->PrepareKernelAccess();
1273 						actualLength = _ReadDescriptorChain(
1274 							transfer->data_descriptor,
1275 							vector, vectorCount, transfer->transfer->IsPhysical());
1276 					} else if (transfer->data_descriptor) {
1277 						// read the actual length that was sent
1278 						actualLength = _ReadActualLength(
1279 							transfer->data_descriptor);
1280 					}
1281 
1282 					// get the last data toggle and store it for next time
1283 					transfer->transfer->TransferPipe()->SetDataToggle(
1284 						(endpoint->head_physical_descriptor
1285 							& OHCI_ENDPOINT_TOGGLE_CARRY) != 0);
1286 
1287 					if (transfer->transfer->IsFragmented()) {
1288 						// this transfer may still have data left
1289 						TRACE("advancing fragmented transfer\n");
1290 						transfer->transfer->AdvanceByFragment(actualLength);
1291 						if (transfer->transfer->FragmentLength() > 0) {
1292 							TRACE("still %ld bytes left on transfer\n",
1293 								transfer->transfer->FragmentLength());
1294 							// TODO actually resubmit the transfer
1295 						}
1296 
1297 						// the transfer is done, but we already set the
1298 						// actualLength with AdvanceByFragment()
1299 						actualLength = 0;
1300 					}
1301 				}
1302 
1303 				transfer->transfer->Finished(callbackStatus, actualLength);
1304 				fProcessingPipe = NULL;
1305 			}
1306 
1307 			if (callbackStatus != B_OK) {
1308 				// remove the transfer and make the head pointer valid again
1309 				// (including clearing the halt state)
1310 				_RemoveTransferFromEndpoint(transfer);
1311 			}
1312 
1313 			// free the descriptors
1314 			_FreeDescriptorChain(transfer->first_descriptor);
1315 
1316 			delete transfer->transfer;
1317 			delete transfer;
1318 			transfer = next;
1319 		}
1320 	}
1321 }
1322 
1323 
1324 bool
1325 OHCI::_FinishIsochronousTransfer(transfer_data *transfer,
1326 	transfer_data **_lastTransfer)
1327 {
1328 	status_t callbackStatus = B_OK;
1329 	size_t actualLength = 0;
1330 	uint32 packet = 0;
1331 
1332 	if (transfer->canceled)
1333 		callbackStatus = B_CANCELED;
1334 	else {
1335 		// at first check if ALL ITDs are retired by HC
1336 		ohci_isochronous_td *descriptor
1337 			= (ohci_isochronous_td *)transfer->first_descriptor;
1338 		while (descriptor) {
1339 			if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags)
1340 				== OHCI_TD_CONDITION_NOT_ACCESSED) {
1341 				TRACE("ITD %p still active\n", descriptor);
1342 				*_lastTransfer = transfer;
1343 				return false;
1344 			}
1345 
1346 			if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) {
1347 				// this is the last ITD of the transfer
1348 				descriptor = (ohci_isochronous_td *)transfer->first_descriptor;
1349 				break;
1350 			}
1351 
1352 			descriptor
1353 				= (ohci_isochronous_td *)descriptor->next_done_descriptor;
1354 		}
1355 
1356 		while (descriptor) {
1357 			uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1358 			if (status != OHCI_TD_CONDITION_NO_ERROR) {
1359 				TRACE_ERROR("ITD error: 0x%08" B_PRIx32 "\n", status);
1360 				// spec says that in most cases condition code
1361 				// of retired ITDs is set to NoError, but for the
1362 				// time overrun it can be DataOverrun. We assume
1363 				// the _first_ occurience of such error as status
1364 				// reported to the callback
1365 				if (callbackStatus == B_OK)
1366 					callbackStatus = _GetStatusOfConditionCode(status);
1367 			}
1368 
1369 			usb_isochronous_data *isochronousData
1370 				= transfer->transfer->IsochronousData();
1371 
1372 			uint32 frameCount = OHCI_ITD_GET_FRAME_COUNT(descriptor->flags);
1373 			for (size_t i = 0; i < frameCount; i++, packet++) {
1374 				usb_iso_packet_descriptor* packet_descriptor
1375 					= &isochronousData->packet_descriptors[packet];
1376 
1377 				uint16 offset = descriptor->offset[OHCI_ITD_OFFSET_IDX(i)];
1378 				uint8 code = OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset);
1379 				packet_descriptor->status = _GetStatusOfConditionCode(code);
1380 
1381 				// not touched by HC - sheduled too late to be processed
1382 				// in the requested frame - so we ignore it too
1383 				if (packet_descriptor->status == B_DEV_TOO_LATE)
1384 					continue;
1385 
1386 				size_t len = OHCI_ITD_GET_BUFFER_LENGTH(offset);
1387 				if (!transfer->incoming)
1388 					len = packet_descriptor->request_length - len;
1389 
1390 				packet_descriptor->actual_length = len;
1391 				actualLength += len;
1392 			}
1393 
1394 			uint16 frame = OHCI_ITD_GET_STARTING_FRAME(descriptor->flags);
1395 			_ReleaseIsochronousBandwidth(frame,
1396 				OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
1397 
1398 			TRACE("ITD %p done\n", descriptor);
1399 
1400 			if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor)
1401 				break;
1402 
1403 			descriptor
1404 				= (ohci_isochronous_td *)descriptor->next_done_descriptor;
1405 		}
1406 	}
1407 
1408 	// remove the transfer from the list first so we are sure
1409 	// it doesn't get canceled while we still process it
1410 	if (Lock()) {
1411 		if (*_lastTransfer)
1412 			(*_lastTransfer)->link = transfer->link;
1413 
1414 		if (transfer == fFirstTransfer)
1415 			fFirstTransfer = transfer->link;
1416 		if (transfer == fLastTransfer)
1417 			fLastTransfer = *_lastTransfer;
1418 
1419 		// store the currently processing pipe here so we can wait
1420 		// in cancel if we are processing something on the target pipe
1421 		if (!transfer->canceled)
1422 			fProcessingPipe = transfer->transfer->TransferPipe();
1423 
1424 		transfer->link = NULL;
1425 		Unlock();
1426 	}
1427 
1428 	// break the descriptor chain on the last descriptor
1429 	transfer->last_descriptor->next_logical_descriptor = NULL;
1430 	TRACE("iso.transfer %p done with status 0x%08" B_PRIx32 " len:%ld\n",
1431 		transfer, callbackStatus, actualLength);
1432 
1433 	// if canceled the callback has already been called
1434 	if (!transfer->canceled) {
1435 		if (callbackStatus == B_OK && actualLength > 0) {
1436 			if (transfer->data_descriptor && transfer->incoming) {
1437 				// data to read out
1438 				generic_io_vec *vector = transfer->transfer->Vector();
1439 				size_t vectorCount = transfer->transfer->VectorCount();
1440 
1441 				transfer->transfer->PrepareKernelAccess();
1442 				_ReadIsochronousDescriptorChain(
1443 					(ohci_isochronous_td*)transfer->data_descriptor,
1444 					vector, vectorCount, transfer->transfer->IsPhysical());
1445 			}
1446 		}
1447 
1448 		transfer->transfer->Finished(callbackStatus, actualLength);
1449 		fProcessingPipe = NULL;
1450 	}
1451 
1452 	_FreeIsochronousDescriptorChain(
1453 		(ohci_isochronous_td*)transfer->first_descriptor);
1454 
1455 	return true;
1456 }
1457 
1458 
1459 status_t
1460 OHCI::_SubmitRequest(Transfer *transfer)
1461 {
1462 	usb_request_data *requestData = transfer->RequestData();
1463 	bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0;
1464 
1465 	ohci_general_td *setupDescriptor
1466 		= _CreateGeneralDescriptor(sizeof(usb_request_data));
1467 	if (!setupDescriptor) {
1468 		TRACE_ERROR("failed to allocate setup descriptor\n");
1469 		return B_NO_MEMORY;
1470 	}
1471 
1472 	setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP
1473 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1474 		| OHCI_TD_TOGGLE_0
1475 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
1476 
1477 	ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0);
1478 	if (!statusDescriptor) {
1479 		TRACE_ERROR("failed to allocate status descriptor\n");
1480 		_FreeGeneralDescriptor(setupDescriptor);
1481 		return B_NO_MEMORY;
1482 	}
1483 
1484 	statusDescriptor->flags
1485 		= (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN)
1486 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1487 		| OHCI_TD_TOGGLE_1
1488 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1489 
1490 	generic_io_vec vector;
1491 	vector.base = (generic_addr_t)requestData;
1492 	vector.length = sizeof(usb_request_data);
1493 	_WriteDescriptorChain(setupDescriptor, &vector, 1, false);
1494 
1495 	status_t result;
1496 	ohci_general_td *dataDescriptor = NULL;
1497 	if (transfer->VectorCount() > 0) {
1498 		ohci_general_td *lastDescriptor = NULL;
1499 		result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor,
1500 			directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1501 			transfer->FragmentLength());
1502 		if (result < B_OK) {
1503 			_FreeGeneralDescriptor(setupDescriptor);
1504 			_FreeGeneralDescriptor(statusDescriptor);
1505 			return result;
1506 		}
1507 
1508 		if (!directionIn) {
1509 			_WriteDescriptorChain(dataDescriptor, transfer->Vector(),
1510 				transfer->VectorCount(), transfer->IsPhysical());
1511 		}
1512 
1513 		_LinkDescriptors(setupDescriptor, dataDescriptor);
1514 		_LinkDescriptors(lastDescriptor, statusDescriptor);
1515 	} else {
1516 		_LinkDescriptors(setupDescriptor, statusDescriptor);
1517 	}
1518 
1519 	// Add to the transfer list
1520 	ohci_endpoint_descriptor *endpoint
1521 		= (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie();
1522 
1523 	MutexLocker endpointLocker(endpoint->lock);
1524 	result = _AddPendingTransfer(transfer, endpoint, setupDescriptor,
1525 		dataDescriptor, statusDescriptor, directionIn);
1526 	if (result < B_OK) {
1527 		TRACE_ERROR("failed to add pending transfer\n");
1528 		_FreeDescriptorChain(setupDescriptor);
1529 		return result;
1530 	}
1531 
1532 	// Add the descriptor chain to the endpoint
1533 	_SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor);
1534 	endpointLocker.Unlock();
1535 
1536 	// Tell the controller to process the control list
1537 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1538 	_WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED);
1539 	return B_OK;
1540 }
1541 
1542 
1543 status_t
1544 OHCI::_SubmitTransfer(Transfer *transfer)
1545 {
1546 	Pipe *pipe = transfer->TransferPipe();
1547 	bool directionIn = (pipe->Direction() == Pipe::In);
1548 
1549 	ohci_general_td *firstDescriptor = NULL;
1550 	ohci_general_td *lastDescriptor = NULL;
1551 	status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor,
1552 		directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1553 		transfer->FragmentLength());
1554 
1555 	if (result < B_OK)
1556 		return result;
1557 
1558 	// Apply data toggle to the first descriptor (the others will use the carry)
1559 	firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY;
1560 	firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1
1561 		: OHCI_TD_TOGGLE_0;
1562 
1563 	// Set the last descriptor to generate an interrupt
1564 	lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK;
1565 	lastDescriptor->flags |=
1566 		OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1567 
1568 	if (!directionIn) {
1569 		_WriteDescriptorChain(firstDescriptor, transfer->Vector(),
1570 			transfer->VectorCount(), transfer->IsPhysical());
1571 	}
1572 
1573 	// Add to the transfer list
1574 	ohci_endpoint_descriptor *endpoint
1575 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1576 
1577 	MutexLocker endpointLocker(endpoint->lock);
1578 
1579 	// We do not support queuing other transfers in tandem with a fragmented one.
1580 	transfer_data *it = fFirstTransfer;
1581 	while (it) {
1582 		if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) {
1583 			TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
1584 			_FreeDescriptorChain(firstDescriptor);
1585 			return B_DEV_RESOURCE_CONFLICT;
1586 		}
1587 
1588 		it = it->link;
1589 	}
1590 
1591 	result = _AddPendingTransfer(transfer, endpoint, firstDescriptor,
1592 		firstDescriptor, lastDescriptor, directionIn);
1593 	if (result < B_OK) {
1594 		TRACE_ERROR("failed to add pending transfer\n");
1595 		_FreeDescriptorChain(firstDescriptor);
1596 		return result;
1597 	}
1598 
1599 	// Add the descriptor chain to the endpoint
1600 	_SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1601 	endpointLocker.Unlock();
1602 
1603 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1604 	if (pipe->Type() & USB_OBJECT_BULK_PIPE) {
1605 		// Tell the controller to process the bulk list
1606 		_WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED);
1607 	}
1608 
1609 	return B_OK;
1610 }
1611 
1612 
1613 status_t
1614 OHCI::_SubmitIsochronousTransfer(Transfer *transfer)
1615 {
1616 	Pipe *pipe = transfer->TransferPipe();
1617 	bool directionIn = (pipe->Direction() == Pipe::In);
1618 
1619 	ohci_isochronous_td *firstDescriptor = NULL;
1620 	ohci_isochronous_td *lastDescriptor = NULL;
1621 	status_t result = _CreateIsochronousDescriptorChain(&firstDescriptor,
1622 		&lastDescriptor, transfer);
1623 
1624 	if (firstDescriptor == 0 || lastDescriptor == 0)
1625 		return B_ERROR;
1626 
1627 	if (result < B_OK)
1628 		return result;
1629 
1630 	// Set the last descriptor to generate an interrupt
1631 	lastDescriptor->flags &= ~OHCI_ITD_INTERRUPT_MASK;
1632 	// let the controller retire last ITD
1633 	lastDescriptor->flags |= OHCI_ITD_SET_DELAY_INTERRUPT(1);
1634 
1635 	// If direction is out set every descriptor data
1636 	if (pipe->Direction() == Pipe::Out)
1637 		_WriteIsochronousDescriptorChain(firstDescriptor,
1638 			transfer->Vector(), transfer->VectorCount(), transfer->IsPhysical());
1639 
1640 	// Add to the transfer list
1641 	ohci_endpoint_descriptor *endpoint
1642 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1643 
1644 	MutexLocker endpointLocker(endpoint->lock);
1645 	result = _AddPendingIsochronousTransfer(transfer, endpoint,
1646 		firstDescriptor, lastDescriptor, directionIn);
1647 	if (result < B_OK) {
1648 		TRACE_ERROR("failed to add pending iso.transfer:"
1649 			"0x%08" B_PRIx32 "\n", result);
1650 		_FreeIsochronousDescriptorChain(firstDescriptor);
1651 		return result;
1652 	}
1653 
1654 	// Add the descriptor chain to the endpoint
1655 	_SwitchIsochronousEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1656 	endpointLocker.Unlock();
1657 
1658 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1659 
1660 	return B_OK;
1661 }
1662 
1663 
1664 void
1665 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint,
1666 	ohci_general_td *first, ohci_general_td *last)
1667 {
1668 	// fill in the information of the first descriptor into the current tail
1669 	ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor;
1670 	tail->flags = first->flags;
1671 	tail->buffer_physical = first->buffer_physical;
1672 	tail->next_physical_descriptor = first->next_physical_descriptor;
1673 	tail->last_physical_byte_address = first->last_physical_byte_address;
1674 	tail->buffer_size = first->buffer_size;
1675 	tail->buffer_logical = first->buffer_logical;
1676 	tail->next_logical_descriptor = first->next_logical_descriptor;
1677 
1678 	// the first descriptor becomes the new tail
1679 	first->flags = 0;
1680 	first->buffer_physical = 0;
1681 	first->next_physical_descriptor = 0;
1682 	first->last_physical_byte_address = 0;
1683 	first->buffer_size = 0;
1684 	first->buffer_logical = NULL;
1685 	first->next_logical_descriptor = NULL;
1686 
1687 	if (first == last)
1688 		_LinkDescriptors(tail, first);
1689 	else
1690 		_LinkDescriptors(last, first);
1691 
1692 	// update the endpoint tail pointer to reflect the change
1693 	endpoint->tail_logical_descriptor = first;
1694 	endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1695 	TRACE("switched tail from %p to %p\n", tail, first);
1696 
1697 #if 0
1698 	_PrintEndpoint(endpoint);
1699 	_PrintDescriptorChain(tail);
1700 #endif
1701 }
1702 
1703 
1704 void
1705 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor *endpoint,
1706 	ohci_isochronous_td *first, ohci_isochronous_td *last)
1707 {
1708 	// fill in the information of the first descriptor into the current tail
1709 	ohci_isochronous_td *tail
1710 		= (ohci_isochronous_td*)endpoint->tail_logical_descriptor;
1711 	tail->flags = first->flags;
1712 	tail->buffer_page_byte_0 = first->buffer_page_byte_0;
1713 	tail->next_physical_descriptor = first->next_physical_descriptor;
1714 	tail->last_byte_address = first->last_byte_address;
1715 	tail->buffer_size = first->buffer_size;
1716 	tail->buffer_logical = first->buffer_logical;
1717 	tail->next_logical_descriptor = first->next_logical_descriptor;
1718 	tail->next_done_descriptor = first->next_done_descriptor;
1719 
1720 	// the first descriptor becomes the new tail
1721 	first->flags = 0;
1722 	first->buffer_page_byte_0 = 0;
1723 	first->next_physical_descriptor = 0;
1724 	first->last_byte_address = 0;
1725 	first->buffer_size = 0;
1726 	first->buffer_logical = NULL;
1727 	first->next_logical_descriptor = NULL;
1728 	first->next_done_descriptor = NULL;
1729 
1730 	for (int i = 0; i < OHCI_ITD_NOFFSET; i++) {
1731 		tail->offset[i] = first->offset[i];
1732 		first->offset[i] = 0;
1733 	}
1734 
1735 	if (first == last)
1736 		_LinkIsochronousDescriptors(tail, first, NULL);
1737 	else
1738 		_LinkIsochronousDescriptors(last, first, NULL);
1739 
1740 	// update the endpoint tail pointer to reflect the change
1741 	endpoint->tail_logical_descriptor = first;
1742 	endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1743 	TRACE("switched tail from %p to %p\n", tail, first);
1744 
1745 #if 0
1746 	_PrintEndpoint(endpoint);
1747 	_PrintDescriptorChain(tail);
1748 #endif
1749 }
1750 
1751 
1752 void
1753 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer)
1754 {
1755 	// The transfer failed and the endpoint was halted. This means that the
1756 	// endpoint head pointer might point somewhere into the descriptor chain
1757 	// of this transfer. As we do not know if this transfer actually caused
1758 	// the halt on the endpoint we have to make sure this is the case. If we
1759 	// find the head to point to somewhere into the descriptor chain then
1760 	// simply advancing the head pointer to the link of the last transfer
1761 	// will bring the endpoint into a valid state again. This operation is
1762 	// safe as the endpoint is currently halted and we therefore can change
1763 	// the head pointer.
1764 	ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1765 	ohci_general_td *descriptor = transfer->first_descriptor;
1766 	while (descriptor) {
1767 		if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1768 			== descriptor->physical_address) {
1769 			// This descriptor caused the halt. Advance the head pointer. This
1770 			// will either move the head to the next valid transfer that can
1771 			// then be restarted, or it will move the head to the tail when
1772 			// there are no more transfer descriptors. Setting the head will
1773 			// also clear the halt state as it is stored in the first bit of
1774 			// the head pointer.
1775 			endpoint->head_physical_descriptor
1776 				= transfer->last_descriptor->next_physical_descriptor;
1777 			return;
1778 		}
1779 
1780 		descriptor = (ohci_general_td *)descriptor->next_logical_descriptor;
1781 	}
1782 }
1783 
1784 
1785 ohci_endpoint_descriptor *
1786 OHCI::_AllocateEndpoint()
1787 {
1788 	ohci_endpoint_descriptor *endpoint;
1789 	phys_addr_t physicalAddress;
1790 
1791 	mutex *lock = (mutex *)malloc(sizeof(mutex));
1792 	if (lock == NULL) {
1793 		TRACE_ERROR("no memory to allocate endpoint lock\n");
1794 		return NULL;
1795 	}
1796 
1797 	// Allocate memory chunk
1798 	if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress,
1799 		sizeof(ohci_endpoint_descriptor)) < B_OK) {
1800 		TRACE_ERROR("failed to allocate endpoint descriptor\n");
1801 		free(lock);
1802 		return NULL;
1803 	}
1804 
1805 	mutex_init(lock, "ohci endpoint lock");
1806 
1807 	endpoint->flags = OHCI_ENDPOINT_SKIP;
1808 	endpoint->physical_address = (uint32)physicalAddress;
1809 	endpoint->head_physical_descriptor = 0;
1810 	endpoint->tail_logical_descriptor = NULL;
1811 	endpoint->tail_physical_descriptor = 0;
1812 	endpoint->next_logical_endpoint = NULL;
1813 	endpoint->next_physical_endpoint = 0;
1814 	endpoint->lock = lock;
1815 	return endpoint;
1816 }
1817 
1818 
1819 void
1820 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
1821 {
1822 	if (!endpoint)
1823 		return;
1824 
1825 	mutex_destroy(endpoint->lock);
1826 	free(endpoint->lock);
1827 
1828 	fStack->FreeChunk((void *)endpoint, endpoint->physical_address,
1829 		sizeof(ohci_endpoint_descriptor));
1830 }
1831 
1832 
1833 status_t
1834 OHCI::_InsertEndpointForPipe(Pipe *pipe)
1835 {
1836 	TRACE("inserting endpoint for device %u endpoint %u\n",
1837 		pipe->DeviceAddress(), pipe->EndpointAddress());
1838 
1839 	ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
1840 	if (!endpoint) {
1841 		TRACE_ERROR("cannot allocate memory for endpoint\n");
1842 		return B_NO_MEMORY;
1843 	}
1844 
1845 	uint32 flags = OHCI_ENDPOINT_SKIP;
1846 
1847 	// Set up device and endpoint address
1848 	flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress())
1849 		| OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress());
1850 
1851 	// Set the direction
1852 	switch (pipe->Direction()) {
1853 		case Pipe::In:
1854 			flags |= OHCI_ENDPOINT_DIRECTION_IN;
1855 			break;
1856 
1857 		case Pipe::Out:
1858 			flags |= OHCI_ENDPOINT_DIRECTION_OUT;
1859 			break;
1860 
1861 		case Pipe::Default:
1862 			flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR;
1863 			break;
1864 
1865 		default:
1866 			TRACE_ERROR("direction unknown\n");
1867 			_FreeEndpoint(endpoint);
1868 			return B_ERROR;
1869 	}
1870 
1871 	// Set up the speed
1872 	switch (pipe->Speed()) {
1873 		case USB_SPEED_LOWSPEED:
1874 			flags |= OHCI_ENDPOINT_LOW_SPEED;
1875 			break;
1876 
1877 		case USB_SPEED_FULLSPEED:
1878 			flags |= OHCI_ENDPOINT_FULL_SPEED;
1879 			break;
1880 
1881 		default:
1882 			TRACE_ERROR("unacceptable speed\n");
1883 			_FreeEndpoint(endpoint);
1884 			return B_ERROR;
1885 	}
1886 
1887 	// Set the maximum packet size
1888 	flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize());
1889 	endpoint->flags = flags;
1890 
1891 	// Add the endpoint to the appropriate list
1892 	uint32 type = pipe->Type();
1893 	ohci_endpoint_descriptor *head = NULL;
1894 	if (type & USB_OBJECT_CONTROL_PIPE)
1895 		head = fDummyControl;
1896 	else if (type & USB_OBJECT_BULK_PIPE)
1897 		head = fDummyBulk;
1898 	else if (type & USB_OBJECT_INTERRUPT_PIPE)
1899 		head = _FindInterruptEndpoint(pipe->Interval());
1900 	else if (type & USB_OBJECT_ISO_PIPE)
1901 		head = fDummyIsochronous;
1902 	else
1903 		TRACE_ERROR("unknown pipe type\n");
1904 
1905 	if (head == NULL) {
1906 		TRACE_ERROR("no list found for endpoint\n");
1907 		_FreeEndpoint(endpoint);
1908 		return B_ERROR;
1909 	}
1910 
1911 	// Create (necessary) tail descriptor
1912 	if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
1913 		// Set the isochronous bit format
1914 		endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
1915 		ohci_isochronous_td *tail = _CreateIsochronousDescriptor(0);
1916 		tail->flags = 0;
1917 		endpoint->tail_logical_descriptor = tail;
1918 		endpoint->head_physical_descriptor = tail->physical_address;
1919 		endpoint->tail_physical_descriptor = tail->physical_address;
1920 	} else {
1921 		ohci_general_td *tail = _CreateGeneralDescriptor(0);
1922 		tail->flags = 0;
1923 		endpoint->tail_logical_descriptor = tail;
1924 		endpoint->head_physical_descriptor = tail->physical_address;
1925 		endpoint->tail_physical_descriptor = tail->physical_address;
1926 	}
1927 
1928 	if (!_LockEndpoints()) {
1929 		if (endpoint->tail_logical_descriptor) {
1930 			_FreeGeneralDescriptor(
1931 				(ohci_general_td *)endpoint->tail_logical_descriptor);
1932 		}
1933 
1934 		_FreeEndpoint(endpoint);
1935 		return B_ERROR;
1936 	}
1937 
1938 	pipe->SetControllerCookie((void *)endpoint);
1939 	endpoint->next_logical_endpoint = head->next_logical_endpoint;
1940 	endpoint->next_physical_endpoint = head->next_physical_endpoint;
1941 	head->next_logical_endpoint = (void *)endpoint;
1942 	head->next_physical_endpoint = (uint32)endpoint->physical_address;
1943 
1944 	_UnlockEndpoints();
1945 	return B_OK;
1946 }
1947 
1948 
1949 status_t
1950 OHCI::_RemoveEndpointForPipe(Pipe *pipe)
1951 {
1952 	TRACE("removing endpoint for device %u endpoint %u\n",
1953 		pipe->DeviceAddress(), pipe->EndpointAddress());
1954 
1955 	ohci_endpoint_descriptor *endpoint
1956 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1957 	if (endpoint == NULL)
1958 		return B_OK;
1959 
1960 	// TODO implement properly, but at least disable it for now
1961 	endpoint->flags |= OHCI_ENDPOINT_SKIP;
1962 	return B_OK;
1963 }
1964 
1965 
1966 ohci_endpoint_descriptor *
1967 OHCI::_FindInterruptEndpoint(uint8 interval)
1968 {
1969 	uint32 index = 0;
1970 	uint32 power = 1;
1971 	while (power <= OHCI_BIGGEST_INTERVAL / 2) {
1972 		if (power * 2 > interval)
1973 			break;
1974 
1975 		power *= 2;
1976 		index++;
1977 	}
1978 
1979 	return fInterruptEndpoints[index];
1980 }
1981 
1982 
1983 ohci_general_td *
1984 OHCI::_CreateGeneralDescriptor(size_t bufferSize)
1985 {
1986 	ohci_general_td *descriptor;
1987 	phys_addr_t physicalAddress;
1988 
1989 	if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
1990 		sizeof(ohci_general_td)) != B_OK) {
1991 		TRACE_ERROR("failed to allocate general descriptor\n");
1992 		return NULL;
1993 	}
1994 
1995 	descriptor->physical_address = (uint32)physicalAddress;
1996 	descriptor->next_physical_descriptor = 0;
1997 	descriptor->next_logical_descriptor = NULL;
1998 	descriptor->buffer_size = bufferSize;
1999 	if (bufferSize == 0) {
2000 		descriptor->buffer_physical = 0;
2001 		descriptor->buffer_logical = NULL;
2002 		descriptor->last_physical_byte_address = 0;
2003 		return descriptor;
2004 	}
2005 
2006 	if (fStack->AllocateChunk(&descriptor->buffer_logical,
2007 		&physicalAddress, bufferSize) != B_OK) {
2008 		TRACE_ERROR("failed to allocate space for buffer\n");
2009 		fStack->FreeChunk(descriptor, descriptor->physical_address,
2010 			sizeof(ohci_general_td));
2011 		return NULL;
2012 	}
2013 	descriptor->buffer_physical = physicalAddress;
2014 
2015 	descriptor->last_physical_byte_address
2016 		= descriptor->buffer_physical + bufferSize - 1;
2017 	return descriptor;
2018 }
2019 
2020 
2021 void
2022 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor)
2023 {
2024 	if (!descriptor)
2025 		return;
2026 
2027 	if (descriptor->buffer_logical) {
2028 		fStack->FreeChunk(descriptor->buffer_logical,
2029 			descriptor->buffer_physical, descriptor->buffer_size);
2030 	}
2031 
2032 	fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2033 		sizeof(ohci_general_td));
2034 }
2035 
2036 
2037 status_t
2038 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
2039 	ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize)
2040 {
2041 	size_t blockSize = 8192;
2042 	int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize;
2043 	if (descriptorCount == 0)
2044 		descriptorCount = 1;
2045 
2046 	ohci_general_td *firstDescriptor = NULL;
2047 	ohci_general_td *lastDescriptor = *_firstDescriptor;
2048 	for (int32 i = 0; i < descriptorCount; i++) {
2049 		ohci_general_td *descriptor = _CreateGeneralDescriptor(
2050 			min_c(blockSize, bufferSize));
2051 
2052 		if (!descriptor) {
2053 			_FreeDescriptorChain(firstDescriptor);
2054 			return B_NO_MEMORY;
2055 		}
2056 
2057 		descriptor->flags = direction
2058 			| OHCI_TD_BUFFER_ROUNDING
2059 			| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
2060 			| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE)
2061 			| OHCI_TD_TOGGLE_CARRY;
2062 
2063 		// link to previous
2064 		if (lastDescriptor)
2065 			_LinkDescriptors(lastDescriptor, descriptor);
2066 
2067 		bufferSize -= blockSize;
2068 		lastDescriptor = descriptor;
2069 		if (!firstDescriptor)
2070 			firstDescriptor = descriptor;
2071 	}
2072 
2073 	*_firstDescriptor = firstDescriptor;
2074 	*_lastDescriptor = lastDescriptor;
2075 	return B_OK;
2076 }
2077 
2078 
2079 void
2080 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor)
2081 {
2082 	ohci_general_td *current = topDescriptor;
2083 	ohci_general_td *next = NULL;
2084 
2085 	while (current) {
2086 		next = (ohci_general_td *)current->next_logical_descriptor;
2087 		_FreeGeneralDescriptor(current);
2088 		current = next;
2089 	}
2090 }
2091 
2092 
2093 ohci_isochronous_td *
2094 OHCI::_CreateIsochronousDescriptor(size_t bufferSize)
2095 {
2096 	ohci_isochronous_td *descriptor = NULL;
2097 	phys_addr_t physicalAddress;
2098 
2099 	if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
2100 		sizeof(ohci_isochronous_td)) != B_OK) {
2101 		TRACE_ERROR("failed to allocate isochronous descriptor\n");
2102 		return NULL;
2103 	}
2104 
2105 	descriptor->physical_address = (uint32)physicalAddress;
2106 	descriptor->next_physical_descriptor = 0;
2107 	descriptor->next_logical_descriptor = NULL;
2108 	descriptor->next_done_descriptor = NULL;
2109 	descriptor->buffer_size = bufferSize;
2110 	if (bufferSize == 0) {
2111 		descriptor->buffer_page_byte_0 = 0;
2112 		descriptor->buffer_logical = NULL;
2113 		descriptor->last_byte_address = 0;
2114 		return descriptor;
2115 	}
2116 
2117 	if (fStack->AllocateChunk(&descriptor->buffer_logical,
2118 		&physicalAddress, bufferSize) != B_OK) {
2119 		TRACE_ERROR("failed to allocate space for iso.buffer\n");
2120 		fStack->FreeChunk(descriptor, descriptor->physical_address,
2121 			sizeof(ohci_isochronous_td));
2122 		return NULL;
2123 	}
2124 	descriptor->buffer_page_byte_0 = (uint32)physicalAddress;
2125 	descriptor->last_byte_address
2126 		= descriptor->buffer_page_byte_0 + bufferSize - 1;
2127 
2128 	return descriptor;
2129 }
2130 
2131 
2132 void
2133 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor)
2134 {
2135 	if (!descriptor)
2136 		return;
2137 
2138 	if (descriptor->buffer_logical) {
2139 		fStack->FreeChunk(descriptor->buffer_logical,
2140 			descriptor->buffer_page_byte_0, descriptor->buffer_size);
2141 	}
2142 
2143 	fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2144 		sizeof(ohci_general_td));
2145 }
2146 
2147 
2148 status_t
2149 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor,
2150 	ohci_isochronous_td **_lastDescriptor, Transfer *transfer)
2151 {
2152 	Pipe *pipe = transfer->TransferPipe();
2153 	usb_isochronous_data *isochronousData = transfer->IsochronousData();
2154 
2155 	size_t dataLength = transfer->FragmentLength();
2156 	size_t packet_count = isochronousData->packet_count;
2157 
2158 	if (packet_count == 0) {
2159 		TRACE_ERROR("isochronous packet_count should not be equal to zero.");
2160 		return B_BAD_VALUE;
2161 	}
2162 
2163 	size_t packetSize = dataLength / packet_count;
2164 	if (dataLength % packet_count != 0)
2165 		packetSize++;
2166 
2167 	if (packetSize > pipe->MaxPacketSize()) {
2168 		TRACE_ERROR("isochronous packetSize %ld is bigger"
2169 			" than pipe MaxPacketSize %ld.", packetSize, pipe->MaxPacketSize());
2170 		return B_BAD_VALUE;
2171 	}
2172 
2173 	uint16 bandwidth = transfer->Bandwidth() / packet_count;
2174 	if (transfer->Bandwidth() % packet_count != 0)
2175 		bandwidth++;
2176 
2177 	ohci_isochronous_td *firstDescriptor = NULL;
2178 	ohci_isochronous_td *lastDescriptor = *_firstDescriptor;
2179 
2180 	// the frame number currently processed by the host controller
2181 	uint16 currentFrame = fHcca->current_frame_number & 0xFFFF;
2182 	uint16 safeFrames = 5;
2183 
2184 	// The entry where to start inserting the first Isochronous descriptor
2185 	// real frame number may differ in case provided one has not bandwidth
2186 	if (isochronousData->flags & USB_ISO_ASAP ||
2187 		isochronousData->starting_frame_number == NULL)
2188 		// We should stay about 5-10 ms ahead of the controller
2189 		// USB1 frame is equal to 1 ms
2190 		currentFrame += safeFrames;
2191 	else
2192 		currentFrame = *isochronousData->starting_frame_number;
2193 
2194 	uint16 packets = packet_count;
2195 	uint16 frameOffset = 0;
2196 	while (packets > 0) {
2197 		// look for up to 8 continous frames with available bandwidth
2198 		uint16 frameCount = 0;
2199 		while (frameCount < min_c(OHCI_ITD_NOFFSET, packets)
2200 				&& _AllocateIsochronousBandwidth(frameOffset + currentFrame
2201 					+ frameCount, bandwidth))
2202 			frameCount++;
2203 
2204 		if (frameCount == 0) {
2205 			// starting frame has no bandwidth for our transaction - try next
2206 			if (++frameOffset >= 0xFFFF) {
2207 				TRACE_ERROR("failed to allocate bandwidth\n");
2208 				_FreeIsochronousDescriptorChain(firstDescriptor);
2209 				return B_NO_MEMORY;
2210 			}
2211 			continue;
2212 		}
2213 
2214 		ohci_isochronous_td *descriptor = _CreateIsochronousDescriptor(
2215 				packetSize * frameCount);
2216 
2217 		if (!descriptor) {
2218 			TRACE_ERROR("failed to allocate ITD\n");
2219 			_ReleaseIsochronousBandwidth(currentFrame + frameOffset, frameCount);
2220 			_FreeIsochronousDescriptorChain(firstDescriptor);
2221 			return B_NO_MEMORY;
2222 		}
2223 
2224 		uint16 pageOffset = descriptor->buffer_page_byte_0 & 0xfff;
2225 		descriptor->buffer_page_byte_0 &= ~0xfff;
2226 		for (uint16 i = 0; i < frameCount; i++) {
2227 			descriptor->offset[OHCI_ITD_OFFSET_IDX(i)]
2228 				= OHCI_ITD_MK_OFFS(pageOffset + packetSize * i);
2229 		}
2230 
2231 		descriptor->flags = OHCI_ITD_SET_FRAME_COUNT(frameCount)
2232 				| OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED)
2233 				| OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE)
2234 				| OHCI_ITD_SET_STARTING_FRAME(currentFrame + frameOffset);
2235 
2236 		// the last packet may be shorter than other ones in this transfer
2237 		if (packets <= OHCI_ITD_NOFFSET)
2238 			descriptor->last_byte_address
2239 				+= dataLength - packetSize * (packet_count);
2240 
2241 		// link to previous
2242 		if (lastDescriptor)
2243 			_LinkIsochronousDescriptors(lastDescriptor, descriptor, descriptor);
2244 
2245 		lastDescriptor = descriptor;
2246 		if (!firstDescriptor)
2247 			firstDescriptor = descriptor;
2248 
2249 		packets -= frameCount;
2250 
2251 		frameOffset += frameCount;
2252 
2253 		if (packets == 0 && isochronousData->starting_frame_number)
2254 			*isochronousData->starting_frame_number = currentFrame + frameOffset;
2255 	}
2256 
2257 	*_firstDescriptor = firstDescriptor;
2258 	*_lastDescriptor = lastDescriptor;
2259 
2260 	return B_OK;
2261 }
2262 
2263 
2264 void
2265 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor)
2266 {
2267 	ohci_isochronous_td *current = topDescriptor;
2268 	ohci_isochronous_td *next = NULL;
2269 
2270 	while (current) {
2271 		next = (ohci_isochronous_td *)current->next_done_descriptor;
2272 		_FreeIsochronousDescriptor(current);
2273 		current = next;
2274 	}
2275 }
2276 
2277 
2278 size_t
2279 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector,
2280 	size_t vectorCount, bool physical)
2281 {
2282 	ohci_general_td *current = topDescriptor;
2283 	size_t actualLength = 0;
2284 	size_t vectorIndex = 0;
2285 	size_t vectorOffset = 0;
2286 	size_t bufferOffset = 0;
2287 
2288 	while (current) {
2289 		if (!current->buffer_logical)
2290 			break;
2291 
2292 		while (true) {
2293 			size_t length = min_c(current->buffer_size - bufferOffset,
2294 				vector[vectorIndex].length - vectorOffset);
2295 
2296 			TRACE("copying %ld bytes to bufferOffset %ld from"
2297 				" vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
2298 				vectorOffset, vectorIndex, vectorCount);
2299 			status_t status = generic_memcpy(
2300 				(generic_addr_t)current->buffer_logical + bufferOffset, false,
2301 				vector[vectorIndex].base + vectorOffset, physical, length);
2302 			ASSERT_ALWAYS(status == B_OK);
2303 
2304 			actualLength += length;
2305 			vectorOffset += length;
2306 			bufferOffset += length;
2307 
2308 			if (vectorOffset >= vector[vectorIndex].length) {
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 	generic_io_vec *vector, size_t vectorCount, bool physical)
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].length - 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 			status_t status = generic_memcpy(
2357 				(generic_addr_t)current->buffer_logical + bufferOffset, false,
2358 				vector[vectorIndex].base + vectorOffset, physical, length);
2359 			ASSERT_ALWAYS(status == B_OK);
2360 
2361 			actualLength += length;
2362 			vectorOffset += length;
2363 			bufferOffset += length;
2364 
2365 			if (vectorOffset >= vector[vectorIndex].length) {
2366 				if (++vectorIndex >= vectorCount) {
2367 					TRACE("wrote descriptor chain (%ld bytes, no"
2368 						" more vectors)\n", actualLength);
2369 					return actualLength;
2370 				}
2371 
2372 				vectorOffset = 0;
2373 			}
2374 
2375 			if (bufferOffset >= current->buffer_size) {
2376 				bufferOffset = 0;
2377 				break;
2378 			}
2379 		}
2380 
2381 		if (!current->next_logical_descriptor)
2382 			break;
2383 
2384 		current = (ohci_isochronous_td *)current->next_logical_descriptor;
2385 	}
2386 
2387 	TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
2388 	return actualLength;
2389 }
2390 
2391 
2392 size_t
2393 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector,
2394 	size_t vectorCount, bool physical)
2395 {
2396 	ohci_general_td *current = topDescriptor;
2397 	size_t actualLength = 0;
2398 	size_t vectorIndex = 0;
2399 	size_t vectorOffset = 0;
2400 	size_t bufferOffset = 0;
2401 
2402 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2403 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
2404 		if (!current->buffer_logical)
2405 			break;
2406 
2407 		size_t bufferSize = current->buffer_size;
2408 		if (current->buffer_physical != 0) {
2409 			bufferSize -= current->last_physical_byte_address
2410 				- current->buffer_physical + 1;
2411 		}
2412 
2413 		while (true) {
2414 			size_t length = min_c(bufferSize - bufferOffset,
2415 				vector[vectorIndex].length - vectorOffset);
2416 
2417 			TRACE("copying %ld bytes to vectorOffset %ld from"
2418 				" bufferOffset %ld at index %ld of %ld\n", length, vectorOffset,
2419 				bufferOffset, vectorIndex, vectorCount);
2420 			status_t status = generic_memcpy(
2421 				vector[vectorIndex].base + vectorOffset, physical,
2422 				(generic_addr_t)current->buffer_logical + bufferOffset, false, length);
2423 			ASSERT_ALWAYS(status == B_OK);
2424 
2425 			actualLength += length;
2426 			vectorOffset += length;
2427 			bufferOffset += length;
2428 
2429 			if (vectorOffset >= vector[vectorIndex].length) {
2430 				if (++vectorIndex >= vectorCount) {
2431 					TRACE("read descriptor chain (%ld bytes, no more vectors)\n",
2432 						actualLength);
2433 					return actualLength;
2434 				}
2435 
2436 				vectorOffset = 0;
2437 			}
2438 
2439 			if (bufferOffset >= bufferSize) {
2440 				bufferOffset = 0;
2441 				break;
2442 			}
2443 		}
2444 
2445 		current = (ohci_general_td *)current->next_logical_descriptor;
2446 	}
2447 
2448 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2449 	return actualLength;
2450 }
2451 
2452 
2453 void
2454 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor,
2455 	generic_io_vec *vector, size_t vectorCount, bool physical)
2456 {
2457 	ohci_isochronous_td *current = topDescriptor;
2458 	size_t actualLength = 0;
2459 	size_t vectorIndex = 0;
2460 	size_t vectorOffset = 0;
2461 	size_t bufferOffset = 0;
2462 
2463 	while (current && OHCI_ITD_GET_CONDITION_CODE(current->flags)
2464 			!= OHCI_ITD_CONDITION_NOT_ACCESSED) {
2465 		size_t bufferSize = current->buffer_size;
2466 		if (current->buffer_logical != NULL && bufferSize > 0) {
2467 			while (true) {
2468 				size_t length = min_c(bufferSize - bufferOffset,
2469 					vector[vectorIndex].length - vectorOffset);
2470 
2471 				TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset"
2472 					" %ld at index %ld of %ld\n", length, vectorOffset,
2473 					bufferOffset, vectorIndex, vectorCount);
2474 				status_t status = generic_memcpy(
2475 					vector[vectorIndex].base + vectorOffset, physical,
2476 					(generic_addr_t)current->buffer_logical + bufferOffset, false, length);
2477 				ASSERT_ALWAYS(status == B_OK);
2478 
2479 				actualLength += length;
2480 				vectorOffset += length;
2481 				bufferOffset += length;
2482 
2483 				if (vectorOffset >= vector[vectorIndex].length) {
2484 					if (++vectorIndex >= vectorCount) {
2485 						TRACE("read descriptor chain (%ld bytes, "
2486 							"no more vectors)\n", actualLength);
2487 						return;
2488 					}
2489 
2490 					vectorOffset = 0;
2491 				}
2492 
2493 				if (bufferOffset >= bufferSize) {
2494 					bufferOffset = 0;
2495 					break;
2496 				}
2497 			}
2498 		}
2499 
2500 		current = (ohci_isochronous_td *)current->next_done_descriptor;
2501 	}
2502 
2503 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2504 	return;
2505 }
2506 
2507 
2508 size_t
2509 OHCI::_ReadActualLength(ohci_general_td *topDescriptor)
2510 {
2511 	ohci_general_td *current = topDescriptor;
2512 	size_t actualLength = 0;
2513 
2514 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2515 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
2516 		size_t length = current->buffer_size;
2517 		if (current->buffer_physical != 0) {
2518 			length -= current->last_physical_byte_address
2519 				- current->buffer_physical + 1;
2520 		}
2521 
2522 		actualLength += length;
2523 		current = (ohci_general_td *)current->next_logical_descriptor;
2524 	}
2525 
2526 	TRACE("read actual length (%ld bytes)\n", actualLength);
2527 	return actualLength;
2528 }
2529 
2530 
2531 void
2532 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second)
2533 {
2534 	first->next_physical_descriptor = second->physical_address;
2535 	first->next_logical_descriptor = second;
2536 }
2537 
2538 
2539 void
2540 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td *first,
2541 	ohci_isochronous_td *second, ohci_isochronous_td *nextDone)
2542 {
2543 	first->next_physical_descriptor = second->physical_address;
2544 	first->next_logical_descriptor = second;
2545 	first->next_done_descriptor = nextDone;
2546 }
2547 
2548 
2549 bool
2550 OHCI::_AllocateIsochronousBandwidth(uint16 frame, uint16 size)
2551 {
2552 	frame %= NUMBER_OF_FRAMES;
2553 	if (size > fFrameBandwidth[frame])
2554 		return false;
2555 
2556 	fFrameBandwidth[frame]-= size;
2557 	return true;
2558 }
2559 
2560 
2561 void
2562 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame, uint16 frameCount)
2563 {
2564 	for (size_t index = 0; index < frameCount; index++) {
2565 		uint16 frame = (startFrame + index) % NUMBER_OF_FRAMES;
2566 		fFrameBandwidth[frame] = MAX_AVAILABLE_BANDWIDTH;
2567 	}
2568 }
2569 
2570 
2571 status_t
2572 OHCI::_GetStatusOfConditionCode(uint8 conditionCode)
2573 {
2574 	switch (conditionCode) {
2575 		case OHCI_TD_CONDITION_NO_ERROR:
2576 			return B_OK;
2577 
2578 		case OHCI_TD_CONDITION_CRC_ERROR:
2579 		case OHCI_TD_CONDITION_BIT_STUFFING:
2580 		case OHCI_TD_CONDITION_TOGGLE_MISMATCH:
2581 			return B_DEV_CRC_ERROR;
2582 
2583 		case OHCI_TD_CONDITION_STALL:
2584 			return B_DEV_STALLED;
2585 
2586 		case OHCI_TD_CONDITION_NO_RESPONSE:
2587 			return B_TIMED_OUT;
2588 
2589 		case OHCI_TD_CONDITION_PID_CHECK_FAILURE:
2590 			return B_DEV_BAD_PID;
2591 
2592 		case OHCI_TD_CONDITION_UNEXPECTED_PID:
2593 			return B_DEV_UNEXPECTED_PID;
2594 
2595 		case OHCI_TD_CONDITION_DATA_OVERRUN:
2596 			return B_DEV_DATA_OVERRUN;
2597 
2598 		case OHCI_TD_CONDITION_DATA_UNDERRUN:
2599 			return B_DEV_DATA_UNDERRUN;
2600 
2601 		case OHCI_TD_CONDITION_BUFFER_OVERRUN:
2602 			return B_DEV_WRITE_ERROR;
2603 
2604 		case OHCI_TD_CONDITION_BUFFER_UNDERRUN:
2605 			return B_DEV_READ_ERROR;
2606 
2607 		case OHCI_TD_CONDITION_NOT_ACCESSED:
2608 			return B_DEV_PENDING;
2609 
2610 		case 0x0E:
2611 			return B_DEV_TOO_LATE; // PSW: _NOT_ACCESSED
2612 
2613 		default:
2614 			break;
2615 	}
2616 
2617 	return B_ERROR;
2618 }
2619 
2620 
2621 bool
2622 OHCI::_LockEndpoints()
2623 {
2624 	return (mutex_lock(&fEndpointLock) == B_OK);
2625 }
2626 
2627 
2628 void
2629 OHCI::_UnlockEndpoints()
2630 {
2631 	mutex_unlock(&fEndpointLock);
2632 }
2633 
2634 
2635 inline void
2636 OHCI::_WriteReg(uint32 reg, uint32 value)
2637 {
2638 	*(volatile uint32 *)(fOperationalRegisters + reg) = value;
2639 }
2640 
2641 
2642 inline uint32
2643 OHCI::_ReadReg(uint32 reg)
2644 {
2645 	return *(volatile uint32 *)(fOperationalRegisters + reg);
2646 }
2647 
2648 
2649 void
2650 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint)
2651 {
2652 	dprintf("endpoint %p\n", endpoint);
2653 	dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags);
2654 	dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor);
2655 	dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor);
2656 	dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint);
2657 	dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address);
2658 	dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor);
2659 	dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint);
2660 }
2661 
2662 
2663 void
2664 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor)
2665 {
2666 	while (topDescriptor) {
2667 		dprintf("descriptor %p\n", topDescriptor);
2668 		dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2669 		dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical);
2670 		dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2671 		dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address);
2672 		dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2673 		dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2674 		dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2675 		dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2676 
2677 		topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor;
2678 	}
2679 }
2680 
2681 
2682 void
2683 OHCI::_PrintDescriptorChain(ohci_isochronous_td *topDescriptor)
2684 {
2685 	while (topDescriptor) {
2686 		dprintf("iso.descriptor %p\n", topDescriptor);
2687 		dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2688 		dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32 "\n", topDescriptor->buffer_page_byte_0);
2689 		dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2690 		dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_byte_address);
2691 		dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n"
2692 							"\t0x%04x 0x%04x 0x%04x 0x%04x\n",
2693 				topDescriptor->offset[0], topDescriptor->offset[1],
2694 				topDescriptor->offset[2], topDescriptor->offset[3],
2695 				topDescriptor->offset[4], topDescriptor->offset[5],
2696 				topDescriptor->offset[6], topDescriptor->offset[7]);
2697 		dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2698 		dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2699 		dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2700 		dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2701 		dprintf("\tnext_done....... %p\n", topDescriptor->next_done_descriptor);
2702 
2703 		topDescriptor = (ohci_isochronous_td *)topDescriptor->next_done_descriptor;
2704 	}
2705 }
2706 
2707