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