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