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