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