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