xref: /haiku/src/add-ons/kernel/busses/usb/ohci.cpp (revision 03187b607b2b5eec7ee059f1ead09bdba14991fb)
1 /*
2  * Copyright 2005-2008, 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  */
10 
11 #include <module.h>
12 #include <PCI.h>
13 #include <USB3.h>
14 #include <KernelExport.h>
15 #include <util/AutoLock.h>
16 
17 #include "ohci.h"
18 
19 #define USB_MODULE_NAME "ohci"
20 
21 pci_module_info *OHCI::sPCIModule = NULL;
22 
23 
24 static int32
25 ohci_std_ops(int32 op, ...)
26 {
27 	switch (op)	{
28 		case B_MODULE_INIT:
29 			TRACE_MODULE("init module\n");
30 			return B_OK;
31 		case B_MODULE_UNINIT:
32 			TRACE_MODULE("uninit module\n");
33 			return B_OK;
34 	}
35 
36 	return EINVAL;
37 }
38 
39 
40 usb_host_controller_info ohci_module = {
41 	{
42 		"busses/usb/ohci",
43 		0,
44 		ohci_std_ops
45 	},
46 	NULL,
47 	OHCI::AddTo
48 };
49 
50 
51 module_info *modules[] = {
52 	(module_info *)&ohci_module,
53 	NULL
54 };
55 
56 
57 OHCI::OHCI(pci_info *info, Stack *stack)
58 	:	BusManager(stack),
59 		fPCIInfo(info),
60 		fStack(stack),
61 		fOperationalRegisters(NULL),
62 		fRegisterArea(-1),
63 		fHccaArea(-1),
64 		fHcca(NULL),
65 		fInterruptEndpoints(NULL),
66 		fDummyControl(NULL),
67 		fDummyBulk(NULL),
68 		fDummyIsochronous(NULL),
69 		fFirstTransfer(NULL),
70 		fLastTransfer(NULL),
71 		fFinishTransfersSem(-1),
72 		fFinishThread(-1),
73 		fStopFinishThread(false),
74 		fRootHub(NULL),
75 		fRootHubAddress(0),
76 		fPortCount(0)
77 {
78 	if (!fInitOK) {
79 		TRACE_ERROR("bus manager failed to init\n");
80 		return;
81 	}
82 
83 	TRACE("constructing new OHCI host controller driver\n");
84 	fInitOK = false;
85 
86 	mutex_init(&fEndpointLock, "ohci endpoint lock");
87 
88 	// enable busmaster and memory mapped access
89 	uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus,
90 		fPCIInfo->device, fPCIInfo->function, PCI_command, 2);
91 	command &= ~PCI_command_io;
92 	command |= PCI_command_master | PCI_command_memory;
93 
94 	sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
95 		fPCIInfo->function, PCI_command, 2, command);
96 
97 	// map the registers
98 	uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus,
99 		fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4);
100 	offset &= PCI_address_memory_32_mask;
101 	TRACE_ALWAYS("iospace offset: 0x%lx\n", offset);
102 	fRegisterArea = map_physical_memory("OHCI memory mapped registers",
103 		(void *)offset,	B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS,
104 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA,
105 		(void **)&fOperationalRegisters);
106 	if (fRegisterArea < B_OK) {
107 		TRACE_ERROR("failed to map register memory\n");
108 		return;
109 	}
110 
111 	TRACE("mapped operational registers: %p\n", fOperationalRegisters);
112 
113 	// Check the revision of the controller, which should be 10h
114 	uint32 revision = _ReadReg(OHCI_REVISION) & 0xff;
115 	TRACE("version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision),
116 		OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision)
117 		? ", legacy support" : "");
118 	if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) {
119 		TRACE_ERROR("unsupported OHCI revision\n");
120 		return;
121 	}
122 
123 	void *hccaPhysicalAddress;
124 	fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress,
125 		sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area");
126 
127 	if (fHccaArea < B_OK) {
128 		TRACE_ERROR("unable to create the HCCA block area\n");
129 		return;
130 	}
131 
132 	memset(fHcca, 0, sizeof(ohci_hcca));
133 
134 	// Set Up Host controller
135 	// Dummy endpoints
136 	fDummyControl = _AllocateEndpoint();
137 	if (!fDummyControl)
138 		return;
139 
140 	fDummyBulk = _AllocateEndpoint();
141 	if (!fDummyBulk) {
142 		_FreeEndpoint(fDummyControl);
143 		return;
144 	}
145 
146 	fDummyIsochronous = _AllocateEndpoint();
147 	if (!fDummyIsochronous) {
148 		_FreeEndpoint(fDummyControl);
149 		_FreeEndpoint(fDummyBulk);
150 		return;
151 	}
152 
153 	// Static endpoints that get linked in the HCCA
154 	fInterruptEndpoints = new(std::nothrow)
155 		ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT];
156 	if (!fInterruptEndpoints) {
157 		TRACE_ERROR("failed to allocate memory for interrupt endpoints\n");
158 		_FreeEndpoint(fDummyControl);
159 		_FreeEndpoint(fDummyBulk);
160 		_FreeEndpoint(fDummyIsochronous);
161 		return;
162 	}
163 
164 	for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) {
165 		fInterruptEndpoints[i] = _AllocateEndpoint();
166 		if (!fInterruptEndpoints[i]) {
167 			TRACE_ERROR("failed to allocate interrupt endpoint %ld", i);
168 			while (--i >= 0)
169 				_FreeEndpoint(fInterruptEndpoints[i]);
170 			_FreeEndpoint(fDummyBulk);
171 			_FreeEndpoint(fDummyControl);
172 			_FreeEndpoint(fDummyIsochronous);
173 			return;
174 		}
175 	}
176 
177 	// build flat tree so that at each of the static interrupt endpoints
178 	// fInterruptEndpoints[i] == interrupt endpoint for interval 2^i
179 	uint32 interval = OHCI_BIGGEST_INTERVAL;
180 	uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1;
181 	while (interval > 1) {
182 		uint32 insertIndex = interval / 2;
183 		while (insertIndex < OHCI_BIGGEST_INTERVAL) {
184 			fHcca->interrupt_table[insertIndex]
185 				= fInterruptEndpoints[intervalIndex]->physical_address;
186 			insertIndex += interval;
187 		}
188 
189 		intervalIndex--;
190 		interval /= 2;
191 	}
192 
193 	// setup the empty slot in the list and linking of all -> first
194 	fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address;
195 	for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) {
196 		fInterruptEndpoints[i]->next_physical_endpoint
197 			= fInterruptEndpoints[0]->physical_address;
198 		fInterruptEndpoints[i]->next_logical_endpoint
199 			= fInterruptEndpoints[0];
200 	}
201 
202 	// Now link the first endpoint to the isochronous endpoint
203 	fInterruptEndpoints[0]->next_physical_endpoint
204 		= fDummyIsochronous->physical_address;
205 
206 	// Determine in what context we are running (Kindly copied from FreeBSD)
207 	uint32 control = _ReadReg(OHCI_CONTROL);
208 	if (control & OHCI_INTERRUPT_ROUTING) {
209 		TRACE_ALWAYS("smm is in control of the host controller\n");
210 		uint32 status = _ReadReg(OHCI_COMMAND_STATUS);
211 		_WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST);
212 		for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) {
213 			snooze(1000);
214 			control = _ReadReg(OHCI_CONTROL);
215 		}
216 
217 		if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
218 			TRACE_ERROR("smm does not respond. resetting...\n");
219 			_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
220 			snooze(USB_DELAY_BUS_RESET);
221 		} else
222 			TRACE_ALWAYS("ownership change successful\n");
223 	} else {
224 		TRACE("cold started\n");
225 		snooze(USB_DELAY_BUS_RESET);
226 	}
227 
228 	// This reset should not be necessary according to the OHCI spec, but
229 	// without it some controllers do not start.
230 	_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
231 	snooze(USB_DELAY_BUS_RESET);
232 
233 	// We now own the host controller and the bus has been reset
234 	uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);
235 	uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval);
236 
237 	// Disable interrupts right before we reset
238 	_WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET);
239 	// Nominal time for a reset is 10 us
240 	uint32 reset = 0;
241 	for (uint32 i = 0; i < 10; i++) {
242 		spin(10);
243 		reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET;
244 		if (reset == 0)
245 			break;
246 	}
247 
248 	if (reset) {
249 		TRACE_ERROR("error resetting the host controller (timeout)\n");
250 		return;
251 	}
252 
253 	// The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL.
254 	// Interrupts are disabled.
255 
256 	// Set up host controller register
257 	_WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress);
258 	_WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address);
259 	_WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address);
260 	// Disable all interrupts
261 	_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
262 	// Switch on desired functional features
263 	control = _ReadReg(OHCI_CONTROL);
264 	control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST
265 		| OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING);
266 	control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4
267 		| OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL;
268 	// And finally start the controller
269 	_WriteReg(OHCI_CONTROL, control);
270 
271 	// The controller is now OPERATIONAL.
272 	frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
273 		^ OHCI_FRAME_INTERVAL_TOGGLE;
274 	frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue;
275 	_WriteReg(OHCI_FRAME_INTERVAL, frameInterval);
276 	// 90% periodic
277 	uint32 periodic = OHCI_PERIODIC(intervalValue);
278 	_WriteReg(OHCI_PERIODIC_START, periodic);
279 
280 	// Fiddle the No Over Current Protection bit to avoid chip bug
281 	uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A);
282 	_WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
283 	_WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
284 	snooze(OHCI_ENABLE_POWER_DELAY);
285 	_WriteReg(OHCI_RH_DESCRIPTOR_A, desca);
286 
287 	// The AMD756 requires a delay before re-reading the register,
288 	// otherwise it will occasionally report 0 ports.
289 	uint32 numberOfPorts = 0;
290 	for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) {
291 		snooze(OHCI_READ_DESC_DELAY);
292 		uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A);
293 		numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor);
294 	}
295 	if (numberOfPorts > OHCI_MAX_PORT_COUNT)
296 		numberOfPorts = OHCI_MAX_PORT_COUNT;
297 	fPortCount = numberOfPorts;
298 	TRACE("port count is %d\n", fPortCount);
299 
300 	// Create semaphore the finisher thread will wait for
301 	fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers");
302 	if (fFinishTransfersSem < B_OK) {
303 		TRACE_ERROR("failed to create semaphore\n");
304 		return;
305 	}
306 
307 	// Create the finisher service thread
308 	fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread",
309 		B_URGENT_DISPLAY_PRIORITY, (void *)this);
310 	resume_thread(fFinishThread);
311 
312 	// Install the interrupt handler
313 	TRACE("installing interrupt handler\n");
314 	install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
315 		_InterruptHandler, (void *)this, 0);
316 
317 	// Enable interesting interrupts now that the handler is in place
318 	_WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
319 		| OHCI_MASTER_INTERRUPT_ENABLE);
320 
321 	TRACE("OHCI host controller driver constructed\n");
322 	fInitOK = true;
323 }
324 
325 
326 OHCI::~OHCI()
327 {
328 	int32 result = 0;
329 	fStopFinishThread = true;
330 	delete_sem(fFinishTransfersSem);
331 	wait_for_thread(fFinishThread, &result);
332 
333 	_LockEndpoints();
334 	mutex_destroy(&fEndpointLock);
335 
336 	if (fHccaArea >= B_OK)
337 		delete_area(fHccaArea);
338 	if (fRegisterArea >= B_OK)
339 		delete_area(fRegisterArea);
340 
341 	_FreeEndpoint(fDummyControl);
342 	_FreeEndpoint(fDummyBulk);
343 	_FreeEndpoint(fDummyIsochronous);
344 
345 	if (fInterruptEndpoints != NULL) {
346 		for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++)
347 			_FreeEndpoint(fInterruptEndpoints[i]);
348 	}
349 
350 	delete [] fInterruptEndpoints;
351 	delete fRootHub;
352 
353 	put_module(B_PCI_MODULE_NAME);
354 }
355 
356 
357 status_t
358 OHCI::Start()
359 {
360 	TRACE("starting OHCI host controller\n");
361 
362 	uint32 control = _ReadReg(OHCI_CONTROL);
363 	if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
364 		!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
365 		TRACE_ERROR("controller not started (0x%08lx)!\n", control);
366 		return B_ERROR;
367 	} else
368 		TRACE("controller is operational!\n");
369 
370 	fRootHubAddress = AllocateAddress();
371 	fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
372 	if (!fRootHub) {
373 		TRACE_ERROR("no memory to allocate root hub\n");
374 		return B_NO_MEMORY;
375 	}
376 
377 	if (fRootHub->InitCheck() < B_OK) {
378 		TRACE_ERROR("root hub failed init check\n");
379 		return B_ERROR;
380 	}
381 
382 	SetRootHub(fRootHub);
383 	TRACE_ALWAYS("successfully started the controller\n");
384 	return BusManager::Start();
385 }
386 
387 
388 status_t
389 OHCI::SubmitTransfer(Transfer *transfer)
390 {
391 	// short circuit the root hub
392 	if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
393 		return fRootHub->ProcessTransfer(this, transfer);
394 
395 	uint32 type = transfer->TransferPipe()->Type();
396 	if (type & USB_OBJECT_CONTROL_PIPE) {
397 		TRACE("submitting request\n");
398 		return _SubmitRequest(transfer);
399 	}
400 
401 	if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) {
402 		TRACE("submitting %s transfer\n",
403 			(type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt");
404 		return _SubmitTransfer(transfer);
405 	}
406 
407 	if (type & USB_OBJECT_ISO_PIPE) {
408 		TRACE("submitting isochronous transfer\n");
409 		return _SubmitIsochronousTransfer(transfer);
410 	}
411 
412 	TRACE_ERROR("tried to submit transfer for unknown pipe type %lu\n", type);
413 	return B_ERROR;
414 }
415 
416 
417 status_t
418 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
419 {
420 	if (pipe->Type() & USB_OBJECT_ISO_PIPE)
421 		return _CancelQueuedIsochronousTransfers(pipe, force);
422 
423 	if (!Lock())
424 		return B_ERROR;
425 
426 	struct transfer_entry {
427 		Transfer *			transfer;
428 		transfer_entry *	next;
429 	};
430 
431 	transfer_entry *list = NULL;
432 	transfer_data *current = fFirstTransfer;
433 	while (current) {
434 		if (current->transfer && current->transfer->TransferPipe() == pipe) {
435 			// Check if the skip bit is already set
436 			if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) {
437 				current->endpoint->flags |= OHCI_ENDPOINT_SKIP;
438 				// In case the controller is processing
439 				// this endpoint, wait for it to finish
440 				snooze(1000);
441 			}
442 
443 			// Clear the endpoint
444 			current->endpoint->head_physical_descriptor
445 				= current->endpoint->tail_physical_descriptor;
446 
447 			if (!force) {
448 				// If the transfer is canceled by force, the one causing the
449 				// cancel is probably not the one who initiated the transfer
450 				// and the callback is likely not safe anymore
451 				transfer_entry *entry
452 					= (transfer_entry *)malloc(sizeof(transfer_entry));
453 				if (entry != NULL) {
454 					entry->transfer = current->transfer;
455 					current->transfer = NULL;
456 					entry->next = list;
457 					list = entry;
458 				}
459 			}
460 			current->canceled = true;
461 		}
462 		current = current->link;
463 	}
464 
465 	Unlock();
466 
467 	while (list != NULL) {
468 		transfer_entry *next = list->next;
469 		list->transfer->Finished(B_CANCELED, 0);
470 		delete list->transfer;
471 		free(list);
472 		list = next;
473 	}
474 
475 	// notify the finisher so it can clean up the canceled transfers
476 	release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
477 	return B_OK;
478 }
479 
480 
481 status_t
482 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
483 {
484 	TRACE("pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe);
485 	if (pipe->DeviceAddress() == fRootHubAddress) {
486 		// no need to insert/remove endpoint descriptors for the root hub
487 		return B_OK;
488 	}
489 
490 	switch (change) {
491 		case USB_CHANGE_CREATED:
492 			return _InsertEndpointForPipe(pipe);
493 
494 		case USB_CHANGE_DESTROYED:
495 			return _RemoveEndpointForPipe(pipe);
496 
497 		case USB_CHANGE_PIPE_POLICY_CHANGED:
498 			TRACE("pipe policy changing unhandled!\n");
499 			break;
500 
501 		default:
502 			TRACE_ERROR("unknown pipe change!\n");
503 			return B_ERROR;
504 	}
505 
506 	return B_OK;
507 }
508 
509 
510 status_t
511 OHCI::AddTo(Stack *stack)
512 {
513 #ifdef TRACE_USB
514 	set_dprintf_enabled(true);
515 #ifndef HAIKU_TARGET_PLATFORM_HAIKU
516 	load_driver_symbols("ohci");
517 #endif
518 #endif
519 
520 	if (!sPCIModule) {
521 		status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
522 		if (status < B_OK) {
523 			TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status);
524 			return status;
525 		}
526 	}
527 
528 	TRACE_MODULE("searching devices\n");
529 	bool found = false;
530 	pci_info *item = new(std::nothrow) pci_info;
531 	if (!item) {
532 		sPCIModule = NULL;
533 		put_module(B_PCI_MODULE_NAME);
534 		return B_NO_MEMORY;
535 	}
536 
537 	for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) {
538 		if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb
539 			&& item->class_api == PCI_usb_ohci) {
540 			if (item->u.h0.interrupt_line == 0
541 				|| item->u.h0.interrupt_line == 0xFF) {
542 				TRACE_MODULE_ERROR("found device with invalid IRQ -"
543 					" check IRQ assignement\n");
544 				continue;
545 			}
546 
547 			TRACE_MODULE("found device at IRQ %u\n",
548 				item->u.h0.interrupt_line);
549 			OHCI *bus = new(std::nothrow) OHCI(item, stack);
550 			if (!bus) {
551 				delete item;
552 				sPCIModule = NULL;
553 				put_module(B_PCI_MODULE_NAME);
554 				return B_NO_MEMORY;
555 			}
556 
557 			if (bus->InitCheck() < B_OK) {
558 				TRACE_MODULE_ERROR("bus failed init check\n");
559 				delete bus;
560 				continue;
561 			}
562 
563 			// the bus took it away
564 			item = new(std::nothrow) pci_info;
565 
566 			bus->Start();
567 			stack->AddBusManager(bus);
568 			found = true;
569 		}
570 	}
571 
572 	if (!found) {
573 		TRACE_MODULE_ERROR("no devices found\n");
574 		delete item;
575 		sPCIModule = NULL;
576 		put_module(B_PCI_MODULE_NAME);
577 		return ENODEV;
578 	}
579 
580 	delete item;
581 	return B_OK;
582 }
583 
584 
585 status_t
586 OHCI::GetPortStatus(uint8 index, usb_port_status *status)
587 {
588 	if (index >= fPortCount) {
589 		TRACE_ERROR("get port status for invalid port %u\n", index);
590 		return B_BAD_INDEX;
591 	}
592 
593 	status->status = status->change = 0;
594 	uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index));
595 
596 	// status
597 	if (portStatus & OHCI_RH_PORTSTATUS_CCS)
598 		status->status |= PORT_STATUS_CONNECTION;
599 	if (portStatus & OHCI_RH_PORTSTATUS_PES)
600 		status->status |= PORT_STATUS_ENABLE;
601 	if (portStatus & OHCI_RH_PORTSTATUS_PSS)
602 		status->status |= PORT_STATUS_SUSPEND;
603 	if (portStatus & OHCI_RH_PORTSTATUS_POCI)
604 		status->status |= PORT_STATUS_OVER_CURRENT;
605 	if (portStatus & OHCI_RH_PORTSTATUS_PRS)
606 		status->status |= PORT_STATUS_RESET;
607 	if (portStatus & OHCI_RH_PORTSTATUS_PPS)
608 		status->status |= PORT_STATUS_POWER;
609 	if (portStatus & OHCI_RH_PORTSTATUS_LSDA)
610 		status->status |= PORT_STATUS_LOW_SPEED;
611 
612 	// change
613 	if (portStatus & OHCI_RH_PORTSTATUS_CSC)
614 		status->change |= PORT_STATUS_CONNECTION;
615 	if (portStatus & OHCI_RH_PORTSTATUS_PESC)
616 		status->change |= PORT_STATUS_ENABLE;
617 	if (portStatus & OHCI_RH_PORTSTATUS_PSSC)
618 		status->change |= PORT_STATUS_SUSPEND;
619 	if (portStatus & OHCI_RH_PORTSTATUS_OCIC)
620 		status->change |= PORT_STATUS_OVER_CURRENT;
621 	if (portStatus & OHCI_RH_PORTSTATUS_PRSC)
622 		status->change |= PORT_STATUS_RESET;
623 
624 	TRACE("port %u status 0x%04x change 0x%04x\n", index,
625 		status->status, status->change);
626 	return B_OK;
627 }
628 
629 
630 status_t
631 OHCI::SetPortFeature(uint8 index, uint16 feature)
632 {
633 	TRACE("set port feature index %u feature %u\n", index, feature);
634 	if (index > fPortCount)
635 		return B_BAD_INDEX;
636 
637 	switch (feature) {
638 		case PORT_ENABLE:
639 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES);
640 			return B_OK;
641 
642 		case PORT_SUSPEND:
643 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS);
644 			return B_OK;
645 
646 		case PORT_RESET:
647 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
648 			return B_OK;
649 
650 		case PORT_POWER:
651 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
652 			return B_OK;
653 	}
654 
655 	return B_BAD_VALUE;
656 }
657 
658 
659 status_t
660 OHCI::ClearPortFeature(uint8 index, uint16 feature)
661 {
662 	TRACE("clear port feature index %u feature %u\n", index, feature);
663 	if (index > fPortCount)
664 		return B_BAD_INDEX;
665 
666 	switch (feature) {
667 		case PORT_ENABLE:
668 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS);
669 			return B_OK;
670 
671 		case PORT_SUSPEND:
672 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI);
673 			return B_OK;
674 
675 		case PORT_POWER:
676 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA);
677 			return B_OK;
678 
679 		case C_PORT_CONNECTION:
680 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
681 			return B_OK;
682 
683 		case C_PORT_ENABLE:
684 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC);
685 			return B_OK;
686 
687 		case C_PORT_SUSPEND:
688 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC);
689 			return B_OK;
690 
691 		case C_PORT_OVER_CURRENT:
692 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC);
693 			return B_OK;
694 
695 		case C_PORT_RESET:
696 			_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC);
697 			return B_OK;
698 	}
699 
700 	return B_BAD_VALUE;
701 }
702 
703 
704 int32
705 OHCI::_InterruptHandler(void *data)
706 {
707 	return ((OHCI *)data)->_Interrupt();
708 }
709 
710 
711 int32
712 OHCI::_Interrupt()
713 {
714 	static spinlock lock = B_SPINLOCK_INITIALIZER;
715 	acquire_spinlock(&lock);
716 
717 	uint32 status = 0;
718 	uint32 acknowledge = 0;
719 	bool finishTransfers = false;
720 	int32 result = B_HANDLED_INTERRUPT;
721 
722 	// The LSb of done_head is used to inform the HCD that an interrupt
723 	// condition exists for both the done list and for another event recorded in
724 	// the HcInterruptStatus register. If done_head is 0, then the interrupt
725 	// was caused by other than the HccaDoneHead update and the
726 	// HcInterruptStatus register needs to be accessed to determine that exact
727 	// interrupt cause. If HccDoneHead is nonzero, then a done list update
728 	// interrupt is indicated and if the LSb of the Dword is nonzero, then an
729 	// additional interrupt event is indicated and HcInterruptStatus should be
730 	// checked to determine its cause.
731 	uint32 doneHead = fHcca->done_head;
732 	if (doneHead != 0) {
733 		status = OHCI_WRITEBACK_DONE_HEAD;
734 		if (doneHead & OHCI_DONE_INTERRUPTS)
735 			status |= _ReadReg(OHCI_INTERRUPT_STATUS)
736 				& _ReadReg(OHCI_INTERRUPT_ENABLE);
737 	} else {
738 		status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE)
739 			& ~OHCI_WRITEBACK_DONE_HEAD;
740 		if (status == 0) {
741 			// Nothing to be done (PCI shared interrupt)
742 			release_spinlock(&lock);
743 			return B_UNHANDLED_INTERRUPT;
744 		}
745 	}
746 
747 	if (status & OHCI_SCHEDULING_OVERRUN) {
748 		TRACE_MODULE("scheduling overrun occured\n");
749 		acknowledge |= OHCI_SCHEDULING_OVERRUN;
750 	}
751 
752 	if (status & OHCI_WRITEBACK_DONE_HEAD) {
753 		TRACE_MODULE("transfer descriptors processed\n");
754 		fHcca->done_head = 0;
755 		acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
756 		result = B_INVOKE_SCHEDULER;
757 		finishTransfers = true;
758 	}
759 
760 	if (status & OHCI_RESUME_DETECTED) {
761 		TRACE_MODULE("resume detected\n");
762 		acknowledge |= OHCI_RESUME_DETECTED;
763 	}
764 
765 	if (status & OHCI_UNRECOVERABLE_ERROR) {
766 		TRACE_MODULE_ERROR("unrecoverable error - controller halted\n");
767 		_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
768 		// TODO: clear all pending transfers, reset and resetup the controller
769 	}
770 
771 	if (status & OHCI_ROOT_HUB_STATUS_CHANGE) {
772 		TRACE_MODULE("root hub status change\n");
773 		// Disable the interrupt as it will otherwise be retriggered until the
774 		// port has been reset and the change is cleared explicitly.
775 		// TODO: renable it once we use status changes instead of polling
776 		_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE);
777 		acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
778 	}
779 
780 	if (acknowledge != 0)
781 		_WriteReg(OHCI_INTERRUPT_STATUS, acknowledge);
782 
783 	release_spinlock(&lock);
784 
785 	if (finishTransfers)
786 		release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
787 
788 	return result;
789 }
790 
791 
792 status_t
793 OHCI::_AddPendingTransfer(Transfer *transfer,
794 	ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor,
795 	ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor,
796 	bool directionIn)
797 {
798 	if (!transfer || !endpoint || !lastDescriptor)
799 		return B_BAD_VALUE;
800 
801 	transfer_data *data = new(std::nothrow) transfer_data;
802 	if (!data)
803 		return B_NO_MEMORY;
804 
805 	status_t result = transfer->InitKernelAccess();
806 	if (result < B_OK) {
807 		delete data;
808 		return result;
809 	}
810 
811 	data->transfer = transfer;
812 	data->endpoint = endpoint;
813 	data->incoming = directionIn;
814 	data->canceled = false;
815 	data->link = NULL;
816 
817 	// the current tail will become the first descriptor
818 	data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor;
819 
820 	// the data and first descriptors might be the same
821 	if (dataDescriptor == firstDescriptor)
822 		data->data_descriptor = data->first_descriptor;
823 	else
824 		data->data_descriptor = dataDescriptor;
825 
826 	// even the last and the first descriptor might be the same
827 	if (lastDescriptor == firstDescriptor)
828 		data->last_descriptor = data->first_descriptor;
829 	else
830 		data->last_descriptor = lastDescriptor;
831 
832 	if (!Lock()) {
833 		delete data;
834 		return B_ERROR;
835 	}
836 
837 	if (fLastTransfer)
838 		fLastTransfer->link = data;
839 	else
840 		fFirstTransfer = data;
841 
842 	fLastTransfer = data;
843 	Unlock();
844 
845 	return B_OK;
846 }
847 
848 
849 status_t
850 OHCI::_CancelQueuedIsochronousTransfers(Pipe *pipe, bool force)
851 {
852 	// TODO
853 	return B_ERROR;
854 }
855 
856 
857 int32
858 OHCI::_FinishThread(void *data)
859 {
860 	((OHCI *)data)->_FinishTransfers();
861 	return B_OK;
862 }
863 
864 
865 void
866 OHCI::_FinishTransfers()
867 {
868 	while (!fStopFinishThread) {
869 		if (acquire_sem(fFinishTransfersSem) < B_OK)
870 			continue;
871 
872 		// eat up sems that have been released by multiple interrupts
873 		int32 semCount = 0;
874 		get_sem_count(fFinishTransfersSem, &semCount);
875 		if (semCount > 0)
876 			acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);
877 
878 		if (!Lock())
879 			continue;
880 
881 		TRACE("finishing transfers (first transfer: %p; last"
882 			" transfer: %p)\n", fFirstTransfer, fLastTransfer);
883 		transfer_data *lastTransfer = NULL;
884 		transfer_data *transfer = fFirstTransfer;
885 		Unlock();
886 
887 		while (transfer) {
888 			bool transferDone = false;
889 			ohci_general_td *descriptor = transfer->first_descriptor;
890 			ohci_endpoint_descriptor *endpoint = transfer->endpoint;
891 			status_t callbackStatus = B_OK;
892 
893 			MutexLocker endpointLocker(endpoint->lock);
894 
895 			if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
896 				!= endpoint->tail_physical_descriptor) {
897 				// there are still active transfers on this endpoint, we need
898 				// to wait for all of them to complete, otherwise we'd read
899 				// a potentially bogus data toggle value below
900 				TRACE("endpoint %p still has active tds\n", endpoint);
901 				lastTransfer = transfer;
902 				transfer = transfer->link;
903 				continue;
904 			}
905 
906 			endpointLocker.Unlock();
907 
908 			while (descriptor && !transfer->canceled) {
909 				uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
910 				if (status == OHCI_TD_CONDITION_NOT_ACCESSED) {
911 					// td is still active
912 					TRACE("td %p still active\n", descriptor);
913 					break;
914 				}
915 
916 				if (status != OHCI_TD_CONDITION_NO_ERROR) {
917 					// an error occured, but we must ensure that the td
918 					// was actually done
919 					if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) {
920 						// the endpoint is halted, this guaratees us that this
921 						// descriptor has passed (we don't know if the endpoint
922 						// was halted because of this td, but we do not need
923 						// to know, as when it was halted by another td this
924 						// still ensures that this td was handled before).
925 						TRACE_ERROR("td error: 0x%08lx\n", status);
926 
927 						switch (status) {
928 							case OHCI_TD_CONDITION_CRC_ERROR:
929 							case OHCI_TD_CONDITION_BIT_STUFFING:
930 							case OHCI_TD_CONDITION_TOGGLE_MISMATCH:
931 								callbackStatus = B_DEV_CRC_ERROR;
932 								break;
933 
934 							case OHCI_TD_CONDITION_STALL:
935 								callbackStatus = B_DEV_STALLED;
936 								break;
937 
938 							case OHCI_TD_CONDITION_NO_RESPONSE:
939 								callbackStatus = B_TIMED_OUT;
940 								break;
941 
942 							case OHCI_TD_CONDITION_PID_CHECK_FAILURE:
943 								callbackStatus = B_DEV_BAD_PID;
944 								break;
945 
946 							case OHCI_TD_CONDITION_UNEXPECTED_PID:
947 								callbackStatus = B_DEV_UNEXPECTED_PID;
948 								break;
949 
950 							case OHCI_TD_CONDITION_DATA_OVERRUN:
951 								callbackStatus = B_DEV_DATA_OVERRUN;
952 								break;
953 
954 							case OHCI_TD_CONDITION_DATA_UNDERRUN:
955 								callbackStatus = B_DEV_DATA_UNDERRUN;
956 								break;
957 
958 							case OHCI_TD_CONDITION_BUFFER_OVERRUN:
959 								callbackStatus = B_DEV_FIFO_OVERRUN;
960 								break;
961 
962 							case OHCI_TD_CONDITION_BUFFER_UNDERRUN:
963 								callbackStatus = B_DEV_FIFO_UNDERRUN;
964 								break;
965 
966 							default:
967 								callbackStatus = B_ERROR;
968 								break;
969 						}
970 
971 						transferDone = true;
972 						break;
973 					} else {
974 						// an error occured but the endpoint is not halted so
975 						// the td is in fact still active
976 						TRACE("td %p active with error\n", descriptor);
977 						break;
978 					}
979 				}
980 
981 				// the td has completed without an error
982 				TRACE("td %p done\n", descriptor);
983 
984 				if (descriptor == transfer->last_descriptor
985 					|| descriptor->buffer_physical != 0) {
986 					// this is the last td of the transfer or a short packet
987 					callbackStatus = B_OK;
988 					transferDone = true;
989 					break;
990 				}
991 
992 				descriptor
993 					= (ohci_general_td *)descriptor->next_logical_descriptor;
994 			}
995 
996 			if (transfer->canceled) {
997 				// when a transfer is canceled, all transfers to that endpoint
998 				// are canceled by setting the head pointer to the tail pointer
999 				// which causes all of the tds to become "free" (as they are
1000 				// inaccessible and not accessed anymore (as setting the head
1001 				// pointer required disabling the endpoint))
1002 				callbackStatus = B_OK;
1003 				transferDone = true;
1004 			}
1005 
1006 			if (!transferDone) {
1007 				lastTransfer = transfer;
1008 				transfer = transfer->link;
1009 				continue;
1010 			}
1011 
1012 			// remove the transfer from the list first so we are sure
1013 			// it doesn't get canceled while we still process it
1014 			transfer_data *next = transfer->link;
1015 			if (Lock()) {
1016 				if (lastTransfer)
1017 					lastTransfer->link = transfer->link;
1018 
1019 				if (transfer == fFirstTransfer)
1020 					fFirstTransfer = transfer->link;
1021 				if (transfer == fLastTransfer)
1022 					fLastTransfer = lastTransfer;
1023 
1024 				transfer->link = NULL;
1025 				Unlock();
1026 			}
1027 
1028 			// break the descriptor chain on the last descriptor
1029 			transfer->last_descriptor->next_logical_descriptor = NULL;
1030 			TRACE("transfer %p done with status 0x%08lx\n",
1031 				transfer, callbackStatus);
1032 
1033 			// if canceled the callback has already been called
1034 			if (!transfer->canceled) {
1035 				size_t actualLength = 0;
1036 				if (callbackStatus == B_OK) {
1037 					if (transfer->data_descriptor && transfer->incoming) {
1038 						// data to read out
1039 						iovec *vector = transfer->transfer->Vector();
1040 						size_t vectorCount = transfer->transfer->VectorCount();
1041 
1042 						transfer->transfer->PrepareKernelAccess();
1043 						actualLength = _ReadDescriptorChain(
1044 							transfer->data_descriptor,
1045 							vector, vectorCount);
1046 					} else if (transfer->data_descriptor) {
1047 						// read the actual length that was sent
1048 						actualLength = _ReadActualLength(
1049 							transfer->data_descriptor);
1050 					}
1051 
1052 					// get the last data toggle and store it for next time
1053 					transfer->transfer->TransferPipe()->SetDataToggle(
1054 						(endpoint->head_physical_descriptor
1055 							& OHCI_ENDPOINT_TOGGLE_CARRY) != 0);
1056 
1057 					if (transfer->transfer->IsFragmented()) {
1058 						// this transfer may still have data left
1059 						TRACE("advancing fragmented transfer\n");
1060 						transfer->transfer->AdvanceByFragment(actualLength);
1061 						if (transfer->transfer->VectorLength() > 0) {
1062 							TRACE("still %ld bytes left on transfer\n",
1063 								transfer->transfer->VectorLength());
1064 							// TODO actually resubmit the transfer
1065 						}
1066 
1067 						// the transfer is done, but we already set the
1068 						// actualLength with AdvanceByFragment()
1069 						actualLength = 0;
1070 					}
1071 				}
1072 
1073 				transfer->transfer->Finished(callbackStatus, actualLength);
1074 			}
1075 
1076 			if (callbackStatus != B_OK) {
1077 				// remove the transfer and make the head pointer valid again
1078 				// (including clearing the halt state)
1079 				_RemoveTransferFromEndpoint(transfer);
1080 			}
1081 
1082 			// free the descriptors
1083 			_FreeDescriptorChain(transfer->first_descriptor);
1084 
1085 			delete transfer->transfer;
1086 			delete transfer;
1087 			transfer = next;
1088 		}
1089 	}
1090 }
1091 
1092 
1093 status_t
1094 OHCI::_SubmitRequest(Transfer *transfer)
1095 {
1096 	usb_request_data *requestData = transfer->RequestData();
1097 	bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0;
1098 
1099 	ohci_general_td *setupDescriptor
1100 		= _CreateGeneralDescriptor(sizeof(usb_request_data));
1101 	if (!setupDescriptor) {
1102 		TRACE_ERROR("failed to allocate setup descriptor\n");
1103 		return B_NO_MEMORY;
1104 	}
1105 
1106 	setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP
1107 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1108 		| OHCI_TD_TOGGLE_0
1109 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
1110 
1111 	ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0);
1112 	if (!statusDescriptor) {
1113 		TRACE_ERROR("failed to allocate status descriptor\n");
1114 		_FreeGeneralDescriptor(setupDescriptor);
1115 		return B_NO_MEMORY;
1116 	}
1117 
1118 	statusDescriptor->flags
1119 		= (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN)
1120 		| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1121 		| OHCI_TD_TOGGLE_1
1122 		| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1123 
1124 	iovec vector;
1125 	vector.iov_base = requestData;
1126 	vector.iov_len = sizeof(usb_request_data);
1127 	_WriteDescriptorChain(setupDescriptor, &vector, 1);
1128 
1129 	status_t result;
1130 	ohci_general_td *dataDescriptor = NULL;
1131 	if (transfer->VectorCount() > 0) {
1132 		ohci_general_td *lastDescriptor = NULL;
1133 		result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor,
1134 			directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1135 			transfer->VectorLength());
1136 		if (result < B_OK) {
1137 			_FreeGeneralDescriptor(setupDescriptor);
1138 			_FreeGeneralDescriptor(statusDescriptor);
1139 			return result;
1140 		}
1141 
1142 		if (!directionIn) {
1143 			_WriteDescriptorChain(dataDescriptor, transfer->Vector(),
1144 				transfer->VectorCount());
1145 		}
1146 
1147 		_LinkDescriptors(setupDescriptor, dataDescriptor);
1148 		_LinkDescriptors(lastDescriptor, statusDescriptor);
1149 	} else {
1150 		_LinkDescriptors(setupDescriptor, statusDescriptor);
1151 	}
1152 
1153 	// Add to the transfer list
1154 	ohci_endpoint_descriptor *endpoint
1155 		= (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie();
1156 
1157 	MutexLocker endpointLocker(endpoint->lock);
1158 	result = _AddPendingTransfer(transfer, endpoint, setupDescriptor,
1159 		dataDescriptor, statusDescriptor, directionIn);
1160 	if (result < B_OK) {
1161 		TRACE_ERROR("failed to add pending transfer\n");
1162 		_FreeDescriptorChain(setupDescriptor);
1163 		return result;
1164 	}
1165 
1166 	// Add the descriptor chain to the endpoint
1167 	_SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor);
1168 	endpointLocker.Unlock();
1169 
1170 	// Tell the controller to process the control list
1171 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1172 	_WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED);
1173 	return B_OK;
1174 }
1175 
1176 
1177 status_t
1178 OHCI::_SubmitTransfer(Transfer *transfer)
1179 {
1180 	Pipe *pipe = transfer->TransferPipe();
1181 	bool directionIn = (pipe->Direction() == Pipe::In);
1182 
1183 	ohci_general_td *firstDescriptor = NULL;
1184 	ohci_general_td *lastDescriptor = NULL;
1185 	status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor,
1186 		directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1187 		transfer->VectorLength());
1188 
1189 	if (result < B_OK)
1190 		return result;
1191 
1192 	// Apply data toggle to the first descriptor (the others will use the carry)
1193 	firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY;
1194 	firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1
1195 		: OHCI_TD_TOGGLE_0;
1196 
1197 	// Set the last descriptor to generate an interrupt
1198 	lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK;
1199 	lastDescriptor->flags |=
1200 		OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1201 
1202 	if (!directionIn) {
1203 		_WriteDescriptorChain(firstDescriptor, transfer->Vector(),
1204 			transfer->VectorCount());
1205 	}
1206 
1207 	// Add to the transfer list
1208 	ohci_endpoint_descriptor *endpoint
1209 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1210 
1211 	MutexLocker endpointLocker(endpoint->lock);
1212 	result = _AddPendingTransfer(transfer, endpoint, firstDescriptor,
1213 		firstDescriptor, lastDescriptor, directionIn);
1214 	if (result < B_OK) {
1215 		TRACE_ERROR("failed to add pending transfer\n");
1216 		_FreeDescriptorChain(firstDescriptor);
1217 		return result;
1218 	}
1219 
1220 	// Add the descriptor chain to the endpoint
1221 	_SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1222 	endpointLocker.Unlock();
1223 
1224 	endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1225 	if (pipe->Type() & USB_OBJECT_BULK_PIPE) {
1226 		// Tell the controller to process the bulk list
1227 		_WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED);
1228 	}
1229 
1230 	return B_OK;
1231 }
1232 
1233 
1234 status_t
1235 OHCI::_SubmitIsochronousTransfer(Transfer *transfer)
1236 {
1237 	return B_ERROR;
1238 }
1239 
1240 
1241 void
1242 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint,
1243 	ohci_general_td *first, ohci_general_td *last)
1244 {
1245 	// fill in the information of the first descriptor into the current tail
1246 	ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor;
1247 	tail->flags = first->flags;
1248 	tail->buffer_physical = first->buffer_physical;
1249 	tail->next_physical_descriptor = first->next_physical_descriptor;
1250 	tail->last_physical_byte_address = first->last_physical_byte_address;
1251 	tail->buffer_size = first->buffer_size;
1252 	tail->buffer_logical = first->buffer_logical;
1253 	tail->next_logical_descriptor = first->next_logical_descriptor;
1254 
1255 	// the first descriptor becomes the new tail
1256 	first->flags = 0;
1257 	first->buffer_physical = 0;
1258 	first->next_physical_descriptor = 0;
1259 	first->last_physical_byte_address = 0;
1260 	first->buffer_size = 0;
1261 	first->buffer_logical = NULL;
1262 	first->next_logical_descriptor = NULL;
1263 
1264 	if (first == last)
1265 		_LinkDescriptors(tail, first);
1266 	else
1267 		_LinkDescriptors(last, first);
1268 
1269 	// update the endpoint tail pointer to reflect the change
1270 	endpoint->tail_logical_descriptor = first;
1271 	endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1272 	TRACE("switched tail from %p to %p\n", tail, first);
1273 
1274 #if 0
1275 	_PrintEndpoint(endpoint);
1276 	_PrintDescriptorChain(tail);
1277 #endif
1278 }
1279 
1280 
1281 void
1282 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer)
1283 {
1284 	// The transfer failed and the endpoint was halted. This means that the
1285 	// endpoint head pointer might point somewhere into the descriptor chain
1286 	// of this transfer. As we do not know if this transfer actually caused
1287 	// the halt on the endpoint we have to make sure this is the case. If we
1288 	// find the head to point to somewhere into the descriptor chain then
1289 	// simply advancing the head pointer to the link of the last transfer
1290 	// will bring the endpoint into a valid state again. This operation is
1291 	// safe as the endpoint is currently halted and we therefore can change
1292 	// the head pointer.
1293 	ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1294 	ohci_general_td *descriptor = transfer->first_descriptor;
1295 	while (descriptor) {
1296 		if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1297 			== descriptor->physical_address) {
1298 			// This descriptor caused the halt. Advance the head pointer. This
1299 			// will either move the head to the next valid transfer that can
1300 			// then be restarted, or it will move the head to the tail when
1301 			// there are no more transfer descriptors. Setting the head will
1302 			// also clear the halt state as it is stored in the first bit of
1303 			// the head pointer.
1304 			endpoint->head_physical_descriptor
1305 				= transfer->last_descriptor->next_physical_descriptor;
1306 			return;
1307 		}
1308 
1309 		descriptor = (ohci_general_td *)descriptor->next_logical_descriptor;
1310 	}
1311 }
1312 
1313 
1314 ohci_endpoint_descriptor *
1315 OHCI::_AllocateEndpoint()
1316 {
1317 	ohci_endpoint_descriptor *endpoint;
1318 	void *physicalAddress;
1319 
1320 	mutex *lock = (mutex *)malloc(sizeof(mutex));
1321 	if (lock == NULL) {
1322 		TRACE_ERROR("no memory to allocate endpoint lock\n");
1323 		return NULL;
1324 	}
1325 
1326 	// Allocate memory chunk
1327 	if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress,
1328 		sizeof(ohci_endpoint_descriptor)) < B_OK) {
1329 		TRACE_ERROR("failed to allocate endpoint descriptor\n");
1330 		free(lock);
1331 		return NULL;
1332 	}
1333 
1334 	mutex_init(lock, "ohci endpoint lock");
1335 
1336 	endpoint->flags = OHCI_ENDPOINT_SKIP;
1337 	endpoint->physical_address = (addr_t)physicalAddress;
1338 	endpoint->head_physical_descriptor = 0;
1339 	endpoint->tail_logical_descriptor = NULL;
1340 	endpoint->tail_physical_descriptor = 0;
1341 	endpoint->next_logical_endpoint = NULL;
1342 	endpoint->next_physical_endpoint = 0;
1343 	endpoint->lock = lock;
1344 	return endpoint;
1345 }
1346 
1347 
1348 void
1349 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
1350 {
1351 	if (!endpoint)
1352 		return;
1353 
1354 	mutex_destroy(endpoint->lock);
1355 	free(endpoint->lock);
1356 
1357 	fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address,
1358 		sizeof(ohci_endpoint_descriptor));
1359 }
1360 
1361 
1362 status_t
1363 OHCI::_InsertEndpointForPipe(Pipe *pipe)
1364 {
1365 	TRACE("inserting endpoint for device %u endpoint %u\n",
1366 		pipe->DeviceAddress(), pipe->EndpointAddress());
1367 
1368 	ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
1369 	if (!endpoint) {
1370 		TRACE_ERROR("cannot allocate memory for endpoint\n");
1371 		return B_NO_MEMORY;
1372 	}
1373 
1374 	uint32 flags = OHCI_ENDPOINT_SKIP;
1375 
1376 	// Set up device and endpoint address
1377 	flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress())
1378 		| OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress());
1379 
1380 	// Set the direction
1381 	switch (pipe->Direction()) {
1382 		case Pipe::In:
1383 			flags |= OHCI_ENDPOINT_DIRECTION_IN;
1384 			break;
1385 
1386 		case Pipe::Out:
1387 			flags |= OHCI_ENDPOINT_DIRECTION_OUT;
1388 			break;
1389 
1390 		case Pipe::Default:
1391 			flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR;
1392 			break;
1393 
1394 		default:
1395 			TRACE_ERROR("direction unknown\n");
1396 			_FreeEndpoint(endpoint);
1397 			return B_ERROR;
1398 	}
1399 
1400 	// Set up the speed
1401 	switch (pipe->Speed()) {
1402 		case USB_SPEED_LOWSPEED:
1403 			flags |= OHCI_ENDPOINT_LOW_SPEED;
1404 			break;
1405 
1406 		case USB_SPEED_FULLSPEED:
1407 			flags |= OHCI_ENDPOINT_FULL_SPEED;
1408 			break;
1409 
1410 		default:
1411 			TRACE_ERROR("unacceptable speed\n");
1412 			_FreeEndpoint(endpoint);
1413 			return B_ERROR;
1414 	}
1415 
1416 	// Set the maximum packet size
1417 	flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize());
1418 	endpoint->flags = flags;
1419 
1420 	// Add the endpoint to the appropriate list
1421 	uint32 type = pipe->Type();
1422 	ohci_endpoint_descriptor *head = NULL;
1423 	if (type & USB_OBJECT_CONTROL_PIPE)
1424 		head = fDummyControl;
1425 	else if (type & USB_OBJECT_BULK_PIPE)
1426 		head = fDummyBulk;
1427 	else if (type & USB_OBJECT_INTERRUPT_PIPE)
1428 		head = _FindInterruptEndpoint(pipe->Interval());
1429 	else if (type & USB_OBJECT_ISO_PIPE)
1430 		head = fDummyIsochronous;
1431 	else
1432 		TRACE_ERROR("unknown pipe type\n");
1433 
1434 	if (head == NULL) {
1435 		TRACE_ERROR("no list found for endpoint\n");
1436 		_FreeEndpoint(endpoint);
1437 		return B_ERROR;
1438 	}
1439 
1440 	// Create (necessary) tail descriptor
1441 	if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
1442 		// Set the isochronous bit format
1443 		endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
1444 		// TODO
1445 		_FreeEndpoint(endpoint);
1446 		return B_ERROR;
1447 	} else {
1448 		ohci_general_td *tail = _CreateGeneralDescriptor(0);
1449 		tail->flags = 0;
1450 		endpoint->tail_logical_descriptor = tail;
1451 		endpoint->head_physical_descriptor = tail->physical_address;
1452 		endpoint->tail_physical_descriptor = tail->physical_address;
1453 	}
1454 
1455 	if (!_LockEndpoints()) {
1456 		if (endpoint->tail_logical_descriptor) {
1457 			_FreeGeneralDescriptor(
1458 				(ohci_general_td *)endpoint->tail_logical_descriptor);
1459 		}
1460 
1461 		_FreeEndpoint(endpoint);
1462 		return B_ERROR;
1463 	}
1464 
1465 	pipe->SetControllerCookie((void *)endpoint);
1466 	endpoint->next_logical_endpoint = head->next_logical_endpoint;
1467 	endpoint->next_physical_endpoint = head->next_physical_endpoint;
1468 	head->next_logical_endpoint = (void *)endpoint;
1469 	head->next_physical_endpoint = (uint32)endpoint->physical_address;
1470 
1471 	_UnlockEndpoints();
1472 	return B_OK;
1473 }
1474 
1475 
1476 status_t
1477 OHCI::_RemoveEndpointForPipe(Pipe *pipe)
1478 {
1479 	TRACE("removing endpoint for device %u endpoint %u\n",
1480 		pipe->DeviceAddress(), pipe->EndpointAddress());
1481 
1482 	ohci_endpoint_descriptor *endpoint
1483 		= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1484 	if (endpoint == NULL)
1485 		return B_OK;
1486 
1487 	// TODO implement properly, but at least disable it for now
1488 	endpoint->flags |= OHCI_ENDPOINT_SKIP;
1489 	return B_OK;
1490 }
1491 
1492 
1493 ohci_endpoint_descriptor *
1494 OHCI::_FindInterruptEndpoint(uint8 interval)
1495 {
1496 	uint32 index = 0;
1497 	uint32 power = 1;
1498 	while (power <= OHCI_BIGGEST_INTERVAL / 2) {
1499 		if (power * 2 > interval)
1500 			break;
1501 
1502 		power *= 2;
1503 		index++;
1504 	}
1505 
1506 	return fInterruptEndpoints[index];
1507 }
1508 
1509 
1510 ohci_general_td *
1511 OHCI::_CreateGeneralDescriptor(size_t bufferSize)
1512 {
1513 	ohci_general_td *descriptor;
1514 	void *physicalAddress;
1515 
1516 	if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
1517 		sizeof(ohci_general_td)) != B_OK) {
1518 		TRACE_ERROR("failed to allocate general descriptor\n");
1519 		return NULL;
1520 	}
1521 
1522 	descriptor->physical_address = (addr_t)physicalAddress;
1523 	descriptor->next_physical_descriptor = 0;
1524 	descriptor->next_logical_descriptor = NULL;
1525 	descriptor->buffer_size = bufferSize;
1526 	if (bufferSize == 0) {
1527 		descriptor->buffer_physical = 0;
1528 		descriptor->buffer_logical = NULL;
1529 		descriptor->last_physical_byte_address = 0;
1530 		return descriptor;
1531 	}
1532 
1533 	if (fStack->AllocateChunk(&descriptor->buffer_logical,
1534 		(void **)&descriptor->buffer_physical, bufferSize) != B_OK) {
1535 		TRACE_ERROR("failed to allocate space for buffer\n");
1536 		fStack->FreeChunk(descriptor, (void *)descriptor->physical_address,
1537 			sizeof(ohci_general_td));
1538 		return NULL;
1539 	}
1540 
1541 	descriptor->last_physical_byte_address
1542 		= descriptor->buffer_physical + bufferSize - 1;
1543 	return descriptor;
1544 }
1545 
1546 
1547 void
1548 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor)
1549 {
1550 	if (!descriptor)
1551 		return;
1552 
1553 	if (descriptor->buffer_logical) {
1554 		fStack->FreeChunk(descriptor->buffer_logical,
1555 			(void *)descriptor->buffer_physical, descriptor->buffer_size);
1556 	}
1557 
1558 	fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address,
1559 		sizeof(ohci_general_td));
1560 }
1561 
1562 
1563 status_t
1564 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
1565 	ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize)
1566 {
1567 	size_t blockSize = 8192;
1568 	int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize;
1569 	if (descriptorCount == 0)
1570 		descriptorCount = 1;
1571 
1572 	ohci_general_td *firstDescriptor = NULL;
1573 	ohci_general_td *lastDescriptor = *_firstDescriptor;
1574 	for (int32 i = 0; i < descriptorCount; i++) {
1575 		ohci_general_td *descriptor = _CreateGeneralDescriptor(
1576 			min_c(blockSize, bufferSize));
1577 
1578 		if (!descriptor) {
1579 			_FreeDescriptorChain(firstDescriptor);
1580 			return B_NO_MEMORY;
1581 		}
1582 
1583 		descriptor->flags = direction
1584 			| OHCI_TD_BUFFER_ROUNDING
1585 			| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1586 			| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE)
1587 			| OHCI_TD_TOGGLE_CARRY;
1588 
1589 		// link to previous
1590 		if (lastDescriptor)
1591 			_LinkDescriptors(lastDescriptor, descriptor);
1592 
1593 		bufferSize -= blockSize;
1594 		lastDescriptor = descriptor;
1595 		if (!firstDescriptor)
1596 			firstDescriptor = descriptor;
1597 	}
1598 
1599 	*_firstDescriptor = firstDescriptor;
1600 	*_lastDescriptor = lastDescriptor;
1601 	return B_OK;
1602 }
1603 
1604 
1605 void
1606 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor)
1607 {
1608 	ohci_general_td *current = topDescriptor;
1609 	ohci_general_td *next = NULL;
1610 
1611 	while (current) {
1612 		next = (ohci_general_td *)current->next_logical_descriptor;
1613 		_FreeGeneralDescriptor(current);
1614 		current = next;
1615 	}
1616 }
1617 
1618 
1619 size_t
1620 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, iovec *vector,
1621 	size_t vectorCount)
1622 {
1623 	ohci_general_td *current = topDescriptor;
1624 	size_t actualLength = 0;
1625 	size_t vectorIndex = 0;
1626 	size_t vectorOffset = 0;
1627 	size_t bufferOffset = 0;
1628 
1629 	while (current) {
1630 		if (!current->buffer_logical)
1631 			break;
1632 
1633 		while (true) {
1634 			size_t length = min_c(current->buffer_size - bufferOffset,
1635 				vector[vectorIndex].iov_len - vectorOffset);
1636 
1637 			TRACE("copying %ld bytes to bufferOffset %ld from"
1638 				" vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
1639 				vectorOffset, vectorIndex, vectorCount);
1640 			memcpy((uint8 *)current->buffer_logical + bufferOffset,
1641 				(uint8 *)vector[vectorIndex].iov_base + vectorOffset, length);
1642 
1643 			actualLength += length;
1644 			vectorOffset += length;
1645 			bufferOffset += length;
1646 
1647 			if (vectorOffset >= vector[vectorIndex].iov_len) {
1648 				if (++vectorIndex >= vectorCount) {
1649 					TRACE("wrote descriptor chain (%ld bytes, no"
1650 						" more vectors)\n", actualLength);
1651 					return actualLength;
1652 				}
1653 
1654 				vectorOffset = 0;
1655 			}
1656 
1657 			if (bufferOffset >= current->buffer_size) {
1658 				bufferOffset = 0;
1659 				break;
1660 			}
1661 		}
1662 
1663 		if (!current->next_logical_descriptor)
1664 			break;
1665 
1666 		current = (ohci_general_td *)current->next_logical_descriptor;
1667 	}
1668 
1669 	TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
1670 	return actualLength;
1671 }
1672 
1673 
1674 size_t
1675 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, iovec *vector,
1676 	size_t vectorCount)
1677 {
1678 	ohci_general_td *current = topDescriptor;
1679 	size_t actualLength = 0;
1680 	size_t vectorIndex = 0;
1681 	size_t vectorOffset = 0;
1682 	size_t bufferOffset = 0;
1683 
1684 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
1685 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
1686 		if (!current->buffer_logical)
1687 			break;
1688 
1689 		size_t bufferSize = current->buffer_size;
1690 		if (current->buffer_physical != 0) {
1691 			bufferSize -= current->last_physical_byte_address
1692 				- current->buffer_physical + 1;
1693 		}
1694 
1695 		while (true) {
1696 			size_t length = min_c(bufferSize - bufferOffset,
1697 				vector[vectorIndex].iov_len - vectorOffset);
1698 
1699 			TRACE("copying %ld bytes to vectorOffset %ld from"
1700 				" bufferOffset %ld at index %ld of %ld\n", length, vectorOffset,
1701 				bufferOffset, vectorIndex, vectorCount);
1702 			memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset,
1703 				(uint8 *)current->buffer_logical + bufferOffset, length);
1704 
1705 			actualLength += length;
1706 			vectorOffset += length;
1707 			bufferOffset += length;
1708 
1709 			if (vectorOffset >= vector[vectorIndex].iov_len) {
1710 				if (++vectorIndex >= vectorCount) {
1711 					TRACE("read descriptor chain (%ld bytes, no more vectors)\n",
1712 						actualLength);
1713 					return actualLength;
1714 				}
1715 
1716 				vectorOffset = 0;
1717 			}
1718 
1719 			if (bufferOffset >= bufferSize) {
1720 				bufferOffset = 0;
1721 				break;
1722 			}
1723 		}
1724 
1725 		current = (ohci_general_td *)current->next_logical_descriptor;
1726 	}
1727 
1728 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
1729 	return actualLength;
1730 }
1731 
1732 
1733 size_t
1734 OHCI::_ReadActualLength(ohci_general_td *topDescriptor)
1735 {
1736 	ohci_general_td *current = topDescriptor;
1737 	size_t actualLength = 0;
1738 
1739 	while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
1740 		!= OHCI_TD_CONDITION_NOT_ACCESSED) {
1741 		size_t length = current->buffer_size;
1742 		if (current->buffer_physical != 0) {
1743 			length -= current->last_physical_byte_address
1744 				- current->buffer_physical + 1;
1745 		}
1746 
1747 		actualLength += length;
1748 		current = (ohci_general_td *)current->next_logical_descriptor;
1749 	}
1750 
1751 	TRACE("read actual length (%ld bytes)\n", actualLength);
1752 	return actualLength;
1753 }
1754 
1755 
1756 void
1757 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second)
1758 {
1759 	first->next_physical_descriptor = second->physical_address;
1760 	first->next_logical_descriptor = second;
1761 }
1762 
1763 
1764 ohci_isochronous_td *
1765 OHCI::_CreateIsochronousDescriptor()
1766 {
1767 	// TODO
1768 	return NULL;
1769 }
1770 
1771 
1772 void
1773 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor)
1774 {
1775 	// TODO
1776 }
1777 
1778 
1779 bool
1780 OHCI::_LockEndpoints()
1781 {
1782 	return (mutex_lock(&fEndpointLock) == B_OK);
1783 }
1784 
1785 
1786 void
1787 OHCI::_UnlockEndpoints()
1788 {
1789 	mutex_unlock(&fEndpointLock);
1790 }
1791 
1792 
1793 inline void
1794 OHCI::_WriteReg(uint32 reg, uint32 value)
1795 {
1796 	*(volatile uint32 *)(fOperationalRegisters + reg) = value;
1797 }
1798 
1799 
1800 inline uint32
1801 OHCI::_ReadReg(uint32 reg)
1802 {
1803 	return *(volatile uint32 *)(fOperationalRegisters + reg);
1804 }
1805 
1806 
1807 void
1808 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint)
1809 {
1810 	TRACE_ALWAYS("endpoint %p\n", endpoint);
1811 	dprintf("\tflags........... 0x%08lx\n", endpoint->flags);
1812 	dprintf("\ttail_physical... 0x%08lx\n", endpoint->tail_physical_descriptor);
1813 	dprintf("\thead_physical... 0x%08lx\n", endpoint->head_physical_descriptor);
1814 	dprintf("\tnext_physical... 0x%08lx\n", endpoint->next_physical_endpoint);
1815 	dprintf("\tphysical........ 0x%08lx\n", endpoint->physical_address);
1816 	dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor);
1817 	dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint);
1818 }
1819 
1820 
1821 void
1822 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor)
1823 {
1824 	while (topDescriptor) {
1825 		TRACE_ALWAYS("descriptor %p\n", topDescriptor);
1826 		dprintf("\tflags........... 0x%08lx\n", topDescriptor->flags);
1827 		dprintf("\tbuffer_physical. 0x%08lx\n", topDescriptor->buffer_physical);
1828 		dprintf("\tnext_physical... 0x%08lx\n", topDescriptor->next_physical_descriptor);
1829 		dprintf("\tlast_byte....... 0x%08lx\n", topDescriptor->last_physical_byte_address);
1830 		dprintf("\tphysical........ 0x%08lx\n", topDescriptor->physical_address);
1831 		dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
1832 		dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
1833 		dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
1834 
1835 		topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor;
1836 	}
1837 }
1838