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