xref: /haiku/src/add-ons/kernel/busses/usb/ehci.cpp (revision 1345706a9ff6ad0dc041339a02d4259998b0765d)
1 /*
2  * Copyright 2006-2008, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz <mmlr@mlotz.ch>
7  */
8 
9 #include <module.h>
10 #include <PCI.h>
11 #include <USB3.h>
12 #include <KernelExport.h>
13 
14 #include "ehci.h"
15 
16 #define USB_MODULE_NAME	"ehci"
17 
18 pci_module_info *EHCI::sPCIModule = NULL;
19 
20 
21 static int32
22 ehci_std_ops(int32 op, ...)
23 {
24 	switch (op) {
25 		case B_MODULE_INIT:
26 			TRACE_MODULE("ehci init module\n");
27 			return B_OK;
28 		case B_MODULE_UNINIT:
29 			TRACE_MODULE("ehci uninit module\n");
30 			return B_OK;
31 	}
32 
33 	return EINVAL;
34 }
35 
36 
37 usb_host_controller_info ehci_module = {
38 	{
39 		"busses/usb/ehci",
40 		0,
41 		ehci_std_ops
42 	},
43 	NULL,
44 	EHCI::AddTo
45 };
46 
47 
48 module_info *modules[] = {
49 	(module_info *)&ehci_module,
50 	NULL
51 };
52 
53 
54 //
55 // #pragma mark -
56 //
57 
58 
59 #ifdef TRACE_USB
60 
61 void
62 print_descriptor_chain(ehci_qtd *descriptor)
63 {
64 	while (descriptor) {
65 		dprintf(" %08lx n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx s%ld\n",
66 			descriptor->this_phy, descriptor->next_phy,
67 			descriptor->alt_next_phy, descriptor->token,
68 			descriptor->buffer_phy[0], descriptor->buffer_phy[1],
69 			descriptor->buffer_phy[2], descriptor->buffer_phy[3],
70 			descriptor->buffer_phy[4], descriptor->buffer_size);
71 
72 		if (descriptor->next_phy & EHCI_QTD_TERMINATE)
73 			break;
74 
75 		descriptor = (ehci_qtd *)descriptor->next_log;
76 	}
77 }
78 
79 void
80 print_queue(ehci_qh *queueHead)
81 {
82 	dprintf("queue:    t%08lx n%08lx ch%08lx ca%08lx cu%08lx\n",
83 		queueHead->this_phy, queueHead->next_phy, queueHead->endpoint_chars,
84 		queueHead->endpoint_caps, queueHead->current_qtd_phy);
85 	dprintf("overlay:  n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx\n",
86 		queueHead->overlay.next_phy, queueHead->overlay.alt_next_phy,
87 		queueHead->overlay.token, queueHead->overlay.buffer_phy[0],
88 		queueHead->overlay.buffer_phy[1], queueHead->overlay.buffer_phy[2],
89 		queueHead->overlay.buffer_phy[3], queueHead->overlay.buffer_phy[4]);
90 	print_descriptor_chain((ehci_qtd *)queueHead->element_log);
91 }
92 
93 #endif // TRACE_USB
94 
95 
96 //
97 // #pragma mark -
98 //
99 
100 
101 EHCI::EHCI(pci_info *info, Stack *stack)
102 	:	BusManager(stack),
103 		fCapabilityRegisters(NULL),
104 		fOperationalRegisters(NULL),
105 		fRegisterArea(-1),
106 		fPCIInfo(info),
107 		fStack(stack),
108 		fEnabledInterrupts(0),
109 		fPeriodicFrameListArea(-1),
110 		fPeriodicFrameList(NULL),
111 		fInterruptEntries(NULL),
112 		fAsyncQueueHead(NULL),
113 		fAsyncAdvanceSem(-1),
114 		fFirstTransfer(NULL),
115 		fLastTransfer(NULL),
116 		fFinishTransfersSem(-1),
117 		fFinishThread(-1),
118 		fCleanupSem(-1),
119 		fCleanupThread(-1),
120 		fStopThreads(false),
121 		fFreeListHead(NULL),
122 		fProcessingPipe(NULL),
123 		fRootHub(NULL),
124 		fRootHubAddress(0),
125 		fPortCount(0),
126 		fPortResetChange(0),
127 		fPortSuspendChange(0)
128 {
129 	if (BusManager::InitCheck() < B_OK) {
130 		TRACE_ERROR("bus manager failed to init\n");
131 		return;
132 	}
133 
134 	TRACE("constructing new EHCI host controller driver\n");
135 	fInitOK = false;
136 
137 	// enable busmaster and memory mapped access
138 	uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus,
139 		fPCIInfo->device, fPCIInfo->function, PCI_command, 2);
140 	command &= ~PCI_command_io;
141 	command |= PCI_command_master | PCI_command_memory;
142 
143 	sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
144 		fPCIInfo->function, PCI_command, 2, command);
145 
146 	// map the registers
147 	uint32 offset = fPCIInfo->u.h0.base_registers[0] & (B_PAGE_SIZE - 1);
148 	addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0] - offset;
149 	size_t mapSize = (fPCIInfo->u.h0.base_register_sizes[0] + offset
150 		+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
151 
152 	TRACE("map physical memory 0x%08lx (base: 0x%08lx; offset: %lx); size: %ld\n",
153 		fPCIInfo->u.h0.base_registers[0], physicalAddress, offset,
154 		fPCIInfo->u.h0.base_register_sizes[0]);
155 
156 	fRegisterArea = map_physical_memory("EHCI memory mapped registers",
157 		physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS,
158 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA,
159 		(void **)&fCapabilityRegisters);
160 	if (fRegisterArea < B_OK) {
161 		TRACE("failed to map register memory\n");
162 		return;
163 	}
164 
165 	fCapabilityRegisters += offset;
166 	fOperationalRegisters = fCapabilityRegisters + ReadCapReg8(EHCI_CAPLENGTH);
167 	TRACE("mapped capability registers: 0x%08lx\n", (uint32)fCapabilityRegisters);
168 	TRACE("mapped operational registers: 0x%08lx\n", (uint32)fOperationalRegisters);
169 
170 	TRACE("structural parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCSPARAMS));
171 	TRACE("capability parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCCPARAMS));
172 
173 	// read port count from capability register
174 	fPortCount = ReadCapReg32(EHCI_HCSPARAMS) & 0x0f;
175 
176 	uint32 extendedCapPointer = ReadCapReg32(EHCI_HCCPARAMS) >> EHCI_ECP_SHIFT;
177 	extendedCapPointer &= EHCI_ECP_MASK;
178 	if (extendedCapPointer > 0) {
179 		TRACE("extended capabilities register at %ld\n", extendedCapPointer);
180 
181 		uint32 legacySupport = sPCIModule->read_pci_config(fPCIInfo->bus,
182 			fPCIInfo->device, fPCIInfo->function, extendedCapPointer, 4);
183 		if ((legacySupport & EHCI_LEGSUP_CAPID_MASK) == EHCI_LEGSUP_CAPID) {
184 			if ((legacySupport & EHCI_LEGSUP_BIOSOWNED) != 0) {
185 				TRACE_ALWAYS("the host controller is bios owned, claiming"
186 					" ownership\n");
187 
188 				sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
189 					fPCIInfo->function, extendedCapPointer + 3, 1, 1);
190 
191 				for (int32 i = 0; i < 20; i++) {
192 					legacySupport = sPCIModule->read_pci_config(fPCIInfo->bus,
193 						fPCIInfo->device, fPCIInfo->function,
194 						extendedCapPointer, 4);
195 
196 					if ((legacySupport & EHCI_LEGSUP_BIOSOWNED) == 0)
197 						break;
198 
199 					TRACE_ALWAYS("controller is still bios owned, waiting\n");
200 					snooze(50000);
201 				}
202 			}
203 
204 			if (legacySupport & EHCI_LEGSUP_BIOSOWNED) {
205 				TRACE_ERROR("bios won't give up control over the host controller (ignoring)\n");
206 			} else if (legacySupport & EHCI_LEGSUP_OSOWNED) {
207 				TRACE_ALWAYS("successfully took ownership of the host controller\n");
208 			}
209 
210 			// Force off the BIOS owned flag, and clear all SMIs. Some BIOSes
211 			// do indicate a successful handover but do not remove their SMIs
212 			// and then freeze the system when interrupts are generated.
213 			sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
214 				fPCIInfo->function, extendedCapPointer + 2, 1, 0);
215 			sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
216 				fPCIInfo->function, extendedCapPointer + 4, 4, 0);
217 		} else {
218 			TRACE("extended capability is not a legacy support register\n");
219 		}
220 	} else {
221 		TRACE("no extended capabilities register\n");
222 	}
223 
224 	// disable interrupts
225 	WriteOpReg(EHCI_USBINTR, 0);
226 
227 	// reset the host controller
228 	if (ControllerReset() < B_OK) {
229 		TRACE_ERROR("host controller failed to reset\n");
230 		return;
231 	}
232 
233 	// reset the segment register
234 	WriteOpReg(EHCI_CTRDSSEGMENT, 0);
235 
236 	// create semaphores the finisher thread will wait for
237 	fAsyncAdvanceSem = create_sem(0, "EHCI Async Advance");
238 	fFinishTransfersSem = create_sem(0, "EHCI Finish Transfers");
239 	fCleanupSem = create_sem(0, "EHCI Cleanup");
240 	if (fFinishTransfersSem < B_OK || fAsyncAdvanceSem < B_OK
241 		|| fCleanupSem < B_OK) {
242 		TRACE_ERROR("failed to create semaphores\n");
243 		return;
244 	}
245 
246 	// create finisher service thread
247 	fFinishThread = spawn_kernel_thread(FinishThread, "ehci finish thread",
248 		B_NORMAL_PRIORITY, (void *)this);
249 	resume_thread(fFinishThread);
250 
251 	// create cleanup service thread
252 	fCleanupThread = spawn_kernel_thread(CleanupThread, "ehci cleanup thread",
253 		B_NORMAL_PRIORITY, (void *)this);
254 	resume_thread(fCleanupThread);
255 
256 	// install the interrupt handler and enable interrupts
257 	install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
258 		InterruptHandler, (void *)this, 0);
259 	fEnabledInterrupts = EHCI_USBINTR_HOSTSYSERR | EHCI_USBINTR_USBERRINT
260 		| EHCI_USBINTR_USBINT | EHCI_USBINTR_INTONAA;
261 	WriteOpReg(EHCI_USBINTR, fEnabledInterrupts);
262 
263 	// allocate the periodic frame list
264 	fPeriodicFrameListArea = fStack->AllocateArea((void **)&fPeriodicFrameList,
265 		(void **)&physicalAddress, B_PAGE_SIZE * 2, "USB EHCI Periodic Framelist");
266 	if (fPeriodicFrameListArea < B_OK) {
267 		TRACE_ERROR("unable to allocate periodic framelist\n");
268 		return;
269 	}
270 
271 	// set the periodic frame list base on the controller
272 	WriteOpReg(EHCI_PERIODICLISTBASE, (uint32)physicalAddress);
273 
274 	// create the interrupt entries to support different polling intervals
275 	TRACE("creating interrupt entries\n");
276 	addr_t physicalBase = physicalAddress + B_PAGE_SIZE;
277 	uint8 *logicalBase = (uint8 *)fPeriodicFrameList + B_PAGE_SIZE;
278 	memset(logicalBase, 0, B_PAGE_SIZE);
279 
280 	fInterruptEntries = (interrupt_entry *)logicalBase;
281 	for (int32 i = 0; i < 11; i++) {
282 		ehci_qh *queueHead = &fInterruptEntries[i].queue_head;
283 		queueHead->this_phy = physicalBase;
284 		queueHead->current_qtd_phy = EHCI_QTD_TERMINATE;
285 		queueHead->overlay.next_phy = EHCI_QTD_TERMINATE;
286 		queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE;
287 		queueHead->overlay.token = EHCI_QTD_STATUS_HALTED;
288 
289 		// set dummy endpoint information
290 		queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH
291 			| (3 << EHCI_QH_CHARS_RL_SHIFT) | (64 << EHCI_QH_CHARS_MPL_SHIFT)
292 			| EHCI_QH_CHARS_TOGGLE;
293 		queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT)
294 			| (0xff << EHCI_QH_CAPS_ISM_SHIFT);
295 
296 		physicalBase += sizeof(interrupt_entry);
297 	}
298 
299 	// build flat interrupt tree
300 	TRACE("build up interrupt links\n");
301 	uint32 interval = 1024;
302 	uint32 intervalIndex = 10;
303 	while (interval > 1) {
304 		uint32 insertIndex = interval / 2;
305 		while (insertIndex < 1024) {
306 			uint32 entry = fInterruptEntries[intervalIndex].queue_head.this_phy;
307 			fPeriodicFrameList[insertIndex] = entry | EHCI_PFRAMELIST_QH;
308 			insertIndex += interval;
309 		}
310 
311 		intervalIndex--;
312 		interval /= 2;
313 	}
314 
315 	// setup the empty slot in the list and linking of all -> first
316 	ehci_qh *firstLogical = &fInterruptEntries[0].queue_head;
317 	uint32 firstPhysical = firstLogical->this_phy | EHCI_QH_TYPE_QH;
318 	fPeriodicFrameList[0] = firstPhysical;
319 	for (int32 i = 1; i < 11; i++) {
320 		fInterruptEntries[i].queue_head.next_phy = firstPhysical;
321 		fInterruptEntries[i].queue_head.next_log = firstLogical;
322 		fInterruptEntries[i].queue_head.prev_log = NULL;
323 	}
324 
325 	// terminate the first entry
326 	firstLogical->next_phy = EHCI_QH_TERMINATE;
327 	firstLogical->next_log = NULL;
328 	firstLogical->prev_log = NULL;
329 
330 	// allocate a queue head that will always stay in the async frame list
331 	fAsyncQueueHead = CreateQueueHead();
332 	if (!fAsyncQueueHead) {
333 		TRACE_ERROR("unable to allocate stray async queue head\n");
334 		return;
335 	}
336 
337 	fAsyncQueueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH;
338 	fAsyncQueueHead->next_log = fAsyncQueueHead;
339 	fAsyncQueueHead->prev_log = fAsyncQueueHead;
340 	fAsyncQueueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH | EHCI_QH_CHARS_RECHEAD;
341 	fAsyncQueueHead->endpoint_caps = 1 << EHCI_QH_CAPS_MULT_SHIFT;
342 	fAsyncQueueHead->current_qtd_phy = EHCI_QTD_TERMINATE;
343 	fAsyncQueueHead->overlay.next_phy = EHCI_QTD_TERMINATE;
344 
345 	WriteOpReg(EHCI_ASYNCLISTADDR, (uint32)fAsyncQueueHead->this_phy
346 		| EHCI_QH_TYPE_QH);
347 	TRACE("set the async list addr to 0x%08lx\n", ReadOpReg(EHCI_ASYNCLISTADDR));
348 
349 	fInitOK = true;
350 	TRACE("EHCI host controller driver constructed\n");
351 }
352 
353 
354 EHCI::~EHCI()
355 {
356 	TRACE("tear down EHCI host controller driver\n");
357 
358 	WriteOpReg(EHCI_USBCMD, 0);
359 	WriteOpReg(EHCI_CONFIGFLAG, 0);
360 	CancelAllPendingTransfers();
361 
362 	int32 result = 0;
363 	fStopThreads = true;
364 	delete_sem(fAsyncAdvanceSem);
365 	delete_sem(fFinishTransfersSem);
366 	wait_for_thread(fFinishThread, &result);
367 	wait_for_thread(fCleanupThread, &result);
368 
369 	delete fRootHub;
370 	delete_area(fPeriodicFrameListArea);
371 	delete_area(fRegisterArea);
372 	put_module(B_PCI_MODULE_NAME);
373 }
374 
375 
376 status_t
377 EHCI::Start()
378 {
379 	TRACE("starting EHCI host controller\n");
380 	TRACE("usbcmd: 0x%08lx; usbsts: 0x%08lx\n", ReadOpReg(EHCI_USBCMD), ReadOpReg(EHCI_USBSTS));
381 
382 	uint32 frameListSize = (ReadOpReg(EHCI_USBCMD) >> EHCI_USBCMD_FLS_SHIFT)
383 		& EHCI_USBCMD_FLS_MASK;
384 	WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) | EHCI_USBCMD_RUNSTOP
385 		| EHCI_USBCMD_ASENABLE | EHCI_USBCMD_PSENABLE
386 		| (frameListSize << EHCI_USBCMD_FLS_SHIFT)
387 		| (1 << EHCI_USBCMD_ITC_SHIFT));
388 
389 	bool running = false;
390 	for (int32 i = 0; i < 10; i++) {
391 		uint32 status = ReadOpReg(EHCI_USBSTS);
392 		TRACE("try %ld: status 0x%08lx\n", i, status);
393 
394 		if (status & EHCI_USBSTS_HCHALTED) {
395 			snooze(10000);
396 		} else {
397 			running = true;
398 			break;
399 		}
400 	}
401 
402 	if (!running) {
403 		TRACE("host controller didn't start\n");
404 		return B_ERROR;
405 	}
406 
407 	// route all ports to us
408 	WriteOpReg(EHCI_CONFIGFLAG, EHCI_CONFIGFLAG_FLAG);
409 	snooze(10000);
410 
411 	fRootHubAddress = AllocateAddress();
412 	fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress);
413 	if (!fRootHub) {
414 		TRACE_ERROR("no memory to allocate root hub\n");
415 		return B_NO_MEMORY;
416 	}
417 
418 	if (fRootHub->InitCheck() < B_OK) {
419 		TRACE_ERROR("root hub failed init check\n");
420 		return fRootHub->InitCheck();
421 	}
422 
423 	SetRootHub(fRootHub);
424 	TRACE_ALWAYS("successfully started the controller\n");
425 	return BusManager::Start();
426 }
427 
428 
429 status_t
430 EHCI::SubmitTransfer(Transfer *transfer)
431 {
432 	// short circuit the root hub
433 	if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
434 		return fRootHub->ProcessTransfer(this, transfer);
435 
436 	Pipe *pipe = transfer->TransferPipe();
437 	if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
438 		// ToDo: implement isochronous transfers...
439 		return B_ERROR;
440 	}
441 
442 	ehci_qh *queueHead = CreateQueueHead();
443 	if (!queueHead) {
444 		TRACE_ERROR("failed to allocate queue head\n");
445 		return B_NO_MEMORY;
446 	}
447 
448 	status_t result = InitQueueHead(queueHead, pipe);
449 	if (result < B_OK) {
450 		TRACE_ERROR("failed to init queue head\n");
451 		FreeQueueHead(queueHead);
452 		return result;
453 	}
454 
455 	bool directionIn;
456 	ehci_qtd *dataDescriptor;
457 	if (pipe->Type() & USB_OBJECT_CONTROL_PIPE) {
458 		result = FillQueueWithRequest(transfer, queueHead, &dataDescriptor,
459 			&directionIn);
460 	} else {
461 		result = FillQueueWithData(transfer, queueHead, &dataDescriptor,
462 			&directionIn);
463 	}
464 
465 	if (result < B_OK) {
466 		TRACE_ERROR("failed to fill transfer queue with data\n");
467 		FreeQueueHead(queueHead);
468 		return result;
469 	}
470 
471 	result = AddPendingTransfer(transfer, queueHead, dataDescriptor, directionIn);
472 	if (result < B_OK) {
473 		TRACE_ERROR("failed to add pending transfer\n");
474 		FreeQueueHead(queueHead);
475 		return result;
476 	}
477 
478 #ifdef TRACE_USB
479 	TRACE("linking queue\n");
480 	print_queue(queueHead);
481 #endif
482 
483 	if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE)
484 		result = LinkInterruptQueueHead(queueHead, pipe);
485 	else
486 		result = LinkQueueHead(queueHead);
487 
488 	if (result < B_OK) {
489 		TRACE_ERROR("failed to link queue head\n");
490 		FreeQueueHead(queueHead);
491 		return result;
492 	}
493 
494 	return B_OK;
495 }
496 
497 
498 status_t
499 EHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
500 {
501 	TRACE("pipe change %d for pipe %p\n", change, pipe);
502 	switch (change) {
503 		case USB_CHANGE_CREATED:
504 		case USB_CHANGE_DESTROYED: {
505 			// ToDo: we should create and keep a single queue head
506 			// for all transfers to/from this pipe
507 			break;
508 		}
509 
510 		case USB_CHANGE_PIPE_POLICY_CHANGED: {
511 			// ToDo: for isochronous pipes we might need to adapt to new
512 			// pipe policy settings here
513 			break;
514 		}
515 	}
516 
517 	return B_OK;
518 }
519 
520 
521 status_t
522 EHCI::AddTo(Stack *stack)
523 {
524 #ifdef TRACE_USB
525 	set_dprintf_enabled(true);
526 #ifndef HAIKU_TARGET_PLATFORM_HAIKU
527 	load_driver_symbols("ehci");
528 #endif
529 #endif
530 
531 	if (!sPCIModule) {
532 		status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
533 		if (status < B_OK) {
534 			TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status);
535 			return status;
536 		}
537 	}
538 
539 	TRACE_MODULE("searching devices\n");
540 	bool found = false;
541 	pci_info *item = new(std::nothrow) pci_info;
542 	if (!item) {
543 		sPCIModule = NULL;
544 		put_module(B_PCI_MODULE_NAME);
545 		return B_NO_MEMORY;
546 	}
547 
548 	for (int32 i = 0; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) {
549 		if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb
550 			&& item->class_api == PCI_usb_ehci) {
551 			if (item->u.h0.interrupt_line == 0
552 				|| item->u.h0.interrupt_line == 0xFF) {
553 				TRACE_MODULE_ERROR("found device with invalid IRQ - check IRQ assignement\n");
554 				continue;
555 			}
556 
557 			TRACE_MODULE("found device at IRQ %u\n", item->u.h0.interrupt_line);
558 			EHCI *bus = new(std::nothrow) EHCI(item, stack);
559 			if (!bus) {
560 				delete item;
561 				sPCIModule = NULL;
562 				put_module(B_PCI_MODULE_NAME);
563 				return B_NO_MEMORY;
564 			}
565 
566 			if (bus->InitCheck() < B_OK) {
567 				TRACE_MODULE_ERROR("bus failed init check\n");
568 				delete bus;
569 				continue;
570 			}
571 
572 			// the bus took it away
573 			item = new(std::nothrow) pci_info;
574 
575 			bus->Start();
576 			stack->AddBusManager(bus);
577 			found = true;
578 		}
579 	}
580 
581 	if (!found) {
582 		TRACE_MODULE_ERROR("no devices found\n");
583 		delete item;
584 		sPCIModule = NULL;
585 		put_module(B_PCI_MODULE_NAME);
586 		return ENODEV;
587 	}
588 
589 	delete item;
590 	return B_OK;
591 }
592 
593 
594 status_t
595 EHCI::GetPortStatus(uint8 index, usb_port_status *status)
596 {
597 	if (index >= fPortCount)
598 		return B_BAD_INDEX;
599 
600 	status->status = status->change = 0;
601 	uint32 portStatus = ReadOpReg(EHCI_PORTSC + index * sizeof(uint32));
602 
603 	// build the status
604 	if (portStatus & EHCI_PORTSC_CONNSTATUS)
605 		status->status |= PORT_STATUS_CONNECTION;
606 	if (portStatus & EHCI_PORTSC_ENABLE)
607 		status->status |= PORT_STATUS_ENABLE;
608 	if (portStatus & EHCI_PORTSC_ENABLE)
609 		status->status |= PORT_STATUS_HIGH_SPEED;
610 	if (portStatus & EHCI_PORTSC_OCACTIVE)
611 		status->status |= PORT_STATUS_OVER_CURRENT;
612 	if (portStatus & EHCI_PORTSC_PORTRESET)
613 		status->status |= PORT_STATUS_RESET;
614 	if (portStatus & EHCI_PORTSC_PORTPOWER)
615 		status->status |= PORT_STATUS_POWER;
616 	if (portStatus & EHCI_PORTSC_SUSPEND)
617 		status->status |= PORT_STATUS_SUSPEND;
618 	if (portStatus & EHCI_PORTSC_DMINUS)
619 		status->status |= PORT_STATUS_LOW_SPEED;
620 
621 	// build the change
622 	if (portStatus & EHCI_PORTSC_CONNCHANGE)
623 		status->change |= PORT_STATUS_CONNECTION;
624 	if (portStatus & EHCI_PORTSC_ENABLECHANGE)
625 		status->change |= PORT_STATUS_ENABLE;
626 	if (portStatus & EHCI_PORTSC_OCCHANGE)
627 		status->change |= PORT_STATUS_OVER_CURRENT;
628 
629 	// there are no bits to indicate suspend and reset change
630 	if (fPortResetChange & (1 << index))
631 		status->change |= PORT_STATUS_RESET;
632 	if (fPortSuspendChange & (1 << index))
633 		status->change |= PORT_STATUS_SUSPEND;
634 
635 	return B_OK;
636 }
637 
638 
639 status_t
640 EHCI::SetPortFeature(uint8 index, uint16 feature)
641 {
642 	if (index >= fPortCount)
643 		return B_BAD_INDEX;
644 
645 	uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32);
646 	uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
647 
648 	switch (feature) {
649 		case PORT_SUSPEND:
650 			return SuspendPort(index);
651 
652 		case PORT_RESET:
653 			return ResetPort(index);
654 
655 		case PORT_POWER:
656 			WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTPOWER);
657 			return B_OK;
658 	}
659 
660 	return B_BAD_VALUE;
661 }
662 
663 
664 status_t
665 EHCI::ClearPortFeature(uint8 index, uint16 feature)
666 {
667 	if (index >= fPortCount)
668 		return B_BAD_INDEX;
669 
670 	uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32);
671 	uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
672 
673 	switch (feature) {
674 		case PORT_ENABLE:
675 			WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_ENABLE);
676 			return B_OK;
677 
678 		case PORT_POWER:
679 			WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTPOWER);
680 			return B_OK;
681 
682 		case C_PORT_CONNECTION:
683 			WriteOpReg(portRegister, portStatus | EHCI_PORTSC_CONNCHANGE);
684 			return B_OK;
685 
686 		case C_PORT_ENABLE:
687 			WriteOpReg(portRegister, portStatus | EHCI_PORTSC_ENABLECHANGE);
688 			return B_OK;
689 
690 		case C_PORT_OVER_CURRENT:
691 			WriteOpReg(portRegister, portStatus | EHCI_PORTSC_OCCHANGE);
692 			return B_OK;
693 
694 		case C_PORT_RESET:
695 			fPortResetChange &= ~(1 << index);
696 			return B_OK;
697 
698 		case C_PORT_SUSPEND:
699 			fPortSuspendChange &= ~(1 << index);
700 			return B_OK;
701 	}
702 
703 	return B_BAD_VALUE;
704 }
705 
706 
707 status_t
708 EHCI::ResetPort(uint8 index)
709 {
710 	TRACE("reset port %d\n", index);
711 	uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32);
712 	uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
713 
714 	if (portStatus & EHCI_PORTSC_DMINUS) {
715 		TRACE_ALWAYS("lowspeed device connected, giving up port ownership\n");
716 		// there is a lowspeed device connected.
717 		// we give the ownership to a companion controller.
718 		WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER);
719 		fPortResetChange |= (1 << index);
720 		return B_OK;
721 	}
722 
723 	// enable reset signaling
724 	WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTRESET);
725 	snooze(250000);
726 
727 	// disable reset signaling
728 	portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
729 	WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTRESET);
730 	snooze(2000);
731 
732 	portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
733 	if (portStatus & EHCI_PORTSC_PORTRESET) {
734 		TRACE_ERROR("port reset won't complete\n");
735 		return B_ERROR;
736 	}
737 
738 	if ((portStatus & EHCI_PORTSC_ENABLE) == 0) {
739 		TRACE_ALWAYS("fullspeed device connected, giving up port ownership\n");
740 		// the port was not enabled, this means that no high speed device is
741 		// attached to this port. we give up ownership to a companion controler
742 		WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER);
743 	}
744 
745 	fPortResetChange |= (1 << index);
746 	return B_OK;
747 }
748 
749 
750 status_t
751 EHCI::SuspendPort(uint8 index)
752 {
753 	uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32);
754 	uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK;
755 	WriteOpReg(portRegister, portStatus | EHCI_PORTSC_SUSPEND);
756 	fPortSuspendChange |= (1 << index);
757 	return B_OK;
758 }
759 
760 
761 status_t
762 EHCI::ControllerReset()
763 {
764 	// halt the controller first
765 	WriteOpReg(EHCI_USBCMD, 0);
766 	snooze(10000);
767 
768 	// then reset it
769 	WriteOpReg(EHCI_USBCMD, EHCI_USBCMD_HCRESET);
770 
771 	int32 tries = 5;
772 	while (ReadOpReg(EHCI_USBCMD) & EHCI_USBCMD_HCRESET) {
773 		snooze(10000);
774 		if (tries-- < 0)
775 			return B_ERROR;
776 	}
777 
778 	return B_OK;
779 }
780 
781 
782 status_t
783 EHCI::LightReset()
784 {
785 	return B_ERROR;
786 }
787 
788 
789 int32
790 EHCI::InterruptHandler(void *data)
791 {
792 	return ((EHCI *)data)->Interrupt();
793 }
794 
795 
796 int32
797 EHCI::Interrupt()
798 {
799 	static spinlock lock = B_SPINLOCK_INITIALIZER;
800 	acquire_spinlock(&lock);
801 
802 	// check if any interrupt was generated
803 	uint32 status = ReadOpReg(EHCI_USBSTS) & EHCI_USBSTS_INTMASK;
804 	if ((status & fEnabledInterrupts) == 0) {
805 		if (status != 0) {
806 			TRACE("discarding not enabled interrupts 0x%08lx\n", status);
807 			WriteOpReg(EHCI_USBSTS, status);
808 		}
809 
810 		release_spinlock(&lock);
811 		return B_UNHANDLED_INTERRUPT;
812 	}
813 
814 	bool asyncAdvance = false;
815 	bool finishTransfers = false;
816 	int32 result = B_HANDLED_INTERRUPT;
817 
818 	if (status & EHCI_USBSTS_USBINT) {
819 		TRACE("transfer finished\n");
820 		result = B_INVOKE_SCHEDULER;
821 		finishTransfers = true;
822 	}
823 
824 	if (status & EHCI_USBSTS_USBERRINT) {
825 		TRACE("transfer error\n");
826 		result = B_INVOKE_SCHEDULER;
827 		finishTransfers = true;
828 	}
829 
830 	if (status & EHCI_USBSTS_FLROLLOVER)
831 		TRACE("frame list rollover\n");
832 
833 	if (status & EHCI_USBSTS_PORTCHANGE)
834 		TRACE("port change detected\n");
835 
836 	if (status & EHCI_USBSTS_INTONAA) {
837 		TRACE("interrupt on async advance\n");
838 		asyncAdvance = true;
839 		result = B_INVOKE_SCHEDULER;
840 	}
841 
842 	if (status & EHCI_USBSTS_HOSTSYSERR)
843 		TRACE_ERROR("host system error!\n");
844 
845 	WriteOpReg(EHCI_USBSTS, status);
846 	release_spinlock(&lock);
847 
848 	if (asyncAdvance)
849 		release_sem_etc(fAsyncAdvanceSem, 1, B_DO_NOT_RESCHEDULE);
850 	if (finishTransfers)
851 		release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
852 
853 	return result;
854 }
855 
856 
857 status_t
858 EHCI::AddPendingTransfer(Transfer *transfer, ehci_qh *queueHead,
859 	ehci_qtd *dataDescriptor, bool directionIn)
860 {
861 	transfer_data *data = new(std::nothrow) transfer_data;
862 	if (!data)
863 		return B_NO_MEMORY;
864 
865 	status_t result = transfer->InitKernelAccess();
866 	if (result < B_OK) {
867 		delete data;
868 		return result;
869 	}
870 
871 	data->transfer = transfer;
872 	data->queue_head = queueHead;
873 	data->data_descriptor = dataDescriptor;
874 	data->incoming = directionIn;
875 	data->canceled = false;
876 	data->link = NULL;
877 
878 	if (!Lock()) {
879 		delete data;
880 		return B_ERROR;
881 	}
882 
883 	if (fLastTransfer)
884 		fLastTransfer->link = data;
885 	else
886 		fFirstTransfer = data;
887 
888 	fLastTransfer = data;
889 	Unlock();
890 
891 	return B_OK;
892 }
893 
894 
895 status_t
896 EHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
897 {
898 	if (!Lock())
899 		return B_ERROR;
900 
901 	struct transfer_entry {
902 		Transfer *			transfer;
903 		transfer_entry *	next;
904 	};
905 
906 	transfer_entry *list = NULL;
907 	transfer_data *current = fFirstTransfer;
908 	while (current) {
909 		if (current->transfer && current->transfer->TransferPipe() == pipe) {
910 			// clear the active bit so the descriptors are canceled
911 			ehci_qtd *descriptor = (ehci_qtd *)current->queue_head->element_log;
912 			while (descriptor) {
913 				descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE;
914 				descriptor = (ehci_qtd *)descriptor->next_log;
915 			}
916 
917 			if (!force) {
918 				// if the transfer is canceled by force, the one causing the
919 				// cancel is probably not the one who initiated the transfer
920 				// and the callback is likely not safe anymore
921 				transfer_entry *entry
922 					= (transfer_entry *)malloc(sizeof(transfer_entry));
923 				if (entry != NULL) {
924 					entry->transfer = current->transfer;
925 					current->transfer = NULL;
926 					entry->next = list;
927 					list = entry;
928 				}
929 			}
930 
931 			current->canceled = true;
932 		}
933 
934 		current = current->link;
935 	}
936 
937 	Unlock();
938 
939 	while (list != NULL) {
940 		transfer_entry *next = list->next;
941 		list->transfer->Finished(B_CANCELED, 0);
942 		delete list->transfer;
943 		free(list);
944 		list = next;
945 	}
946 
947 	// wait for any transfers that might have made it before canceling
948 	while (fProcessingPipe == pipe)
949 		snooze(1000);
950 
951 	// notify the finisher so it can clean up the canceled transfers
952 	release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
953 	return B_OK;
954 }
955 
956 
957 status_t
958 EHCI::CancelAllPendingTransfers()
959 {
960 	if (!Lock())
961 		return B_ERROR;
962 
963 	transfer_data *transfer = fFirstTransfer;
964 	while (transfer) {
965 		transfer->transfer->Finished(B_CANCELED, 0);
966 		delete transfer->transfer;
967 
968 		transfer_data *next = transfer->link;
969 		delete transfer;
970 		transfer = next;
971 	}
972 
973 	fFirstTransfer = NULL;
974 	fLastTransfer = NULL;
975 	Unlock();
976 	return B_OK;
977 }
978 
979 
980 int32
981 EHCI::FinishThread(void *data)
982 {
983 	((EHCI *)data)->FinishTransfers();
984 	return B_OK;
985 }
986 
987 
988 void
989 EHCI::FinishTransfers()
990 {
991 	while (!fStopThreads) {
992 		if (acquire_sem(fFinishTransfersSem) < B_OK)
993 			continue;
994 
995 		// eat up sems that have been released by multiple interrupts
996 		int32 semCount = 0;
997 		get_sem_count(fFinishTransfersSem, &semCount);
998 		if (semCount > 0)
999 			acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);
1000 
1001 		if (!Lock())
1002 			continue;
1003 
1004 		TRACE("finishing transfers\n");
1005 		transfer_data *lastTransfer = NULL;
1006 		transfer_data *transfer = fFirstTransfer;
1007 		Unlock();
1008 
1009 		while (transfer) {
1010 			bool transferDone = false;
1011 			ehci_qtd *descriptor = (ehci_qtd *)transfer->queue_head->element_log;
1012 			status_t callbackStatus = B_OK;
1013 
1014 			while (descriptor) {
1015 				uint32 status = descriptor->token;
1016 				if (status & EHCI_QTD_STATUS_ACTIVE) {
1017 					// still in progress
1018 					TRACE("qtd (0x%08lx) still active\n", descriptor->this_phy);
1019 					break;
1020 				}
1021 
1022 				if (status & EHCI_QTD_STATUS_ERRMASK) {
1023 					// a transfer error occured
1024 					TRACE_ERROR("qtd (0x%08lx) error: 0x%08lx\n", descriptor->this_phy, status);
1025 
1026 					uint8 errorCount = status >> EHCI_QTD_ERRCOUNT_SHIFT;
1027 					errorCount &= EHCI_QTD_ERRCOUNT_MASK;
1028 					if (errorCount == 0) {
1029 						// the error counter counted down to zero, report why
1030 						int32 reasons = 0;
1031 						if (status & EHCI_QTD_STATUS_BUFFER) {
1032 							callbackStatus = transfer->incoming ? B_DEV_DATA_OVERRUN : B_DEV_DATA_UNDERRUN;
1033 							reasons++;
1034 						}
1035 						if (status & EHCI_QTD_STATUS_TERROR) {
1036 							callbackStatus = B_DEV_CRC_ERROR;
1037 							reasons++;
1038 						}
1039 
1040 						if (reasons > 1)
1041 							callbackStatus = B_DEV_MULTIPLE_ERRORS;
1042 					} else if (status & EHCI_QTD_STATUS_BABBLE) {
1043 						// there is a babble condition
1044 						callbackStatus = transfer->incoming ? B_DEV_FIFO_OVERRUN : B_DEV_FIFO_UNDERRUN;
1045 					} else {
1046 						// if the error counter didn't count down to zero
1047 						// and there was no babble, then this halt was caused
1048 						// by a stall handshake
1049 						callbackStatus = B_DEV_STALLED;
1050 					}
1051 
1052 					transferDone = true;
1053 					break;
1054 				}
1055 
1056 				if (descriptor->next_phy & EHCI_QTD_TERMINATE) {
1057 					// we arrived at the last (stray) descriptor, we're done
1058 					TRACE("qtd (0x%08lx) done\n", descriptor->this_phy);
1059 					callbackStatus = B_OK;
1060 					transferDone = true;
1061 					break;
1062 				}
1063 
1064 				descriptor = (ehci_qtd *)descriptor->next_log;
1065 			}
1066 
1067 			if (!transferDone) {
1068 				lastTransfer = transfer;
1069 				transfer = transfer->link;
1070 				continue;
1071 			}
1072 
1073 			// remove the transfer from the list first so we are sure
1074 			// it doesn't get canceled while we still process it
1075 			transfer_data *next = transfer->link;
1076 			if (Lock()) {
1077 				if (lastTransfer)
1078 					lastTransfer->link = transfer->link;
1079 
1080 				if (transfer == fFirstTransfer)
1081 					fFirstTransfer = transfer->link;
1082 				if (transfer == fLastTransfer)
1083 					fLastTransfer = lastTransfer;
1084 
1085 				// store the currently processing pipe here so we can wait
1086 				// in cancel if we are processing something on the target pipe
1087 				if (!transfer->canceled)
1088 					fProcessingPipe = transfer->transfer->TransferPipe();
1089 
1090 				transfer->link = NULL;
1091 				Unlock();
1092 			}
1093 
1094 			// if canceled the callback has already been called
1095 			if (!transfer->canceled) {
1096 				size_t actualLength = 0;
1097 
1098 				if (callbackStatus == B_OK) {
1099 					bool nextDataToggle = false;
1100 					if (transfer->data_descriptor && transfer->incoming) {
1101 						// data to read out
1102 						iovec *vector = transfer->transfer->Vector();
1103 						size_t vectorCount = transfer->transfer->VectorCount();
1104 						transfer->transfer->PrepareKernelAccess();
1105 						actualLength = ReadDescriptorChain(
1106 							transfer->data_descriptor,
1107 							vector, vectorCount,
1108 							&nextDataToggle);
1109 					} else if (transfer->data_descriptor) {
1110 						// calculate transfered length
1111 						actualLength = ReadActualLength(
1112 							transfer->data_descriptor, &nextDataToggle);
1113 					}
1114 
1115 					transfer->transfer->TransferPipe()->SetDataToggle(nextDataToggle);
1116 
1117 					if (transfer->transfer->IsFragmented()) {
1118 						// this transfer may still have data left
1119 						transfer->transfer->AdvanceByFragment(actualLength);
1120 						if (transfer->transfer->VectorLength() > 0) {
1121 							FreeDescriptorChain(transfer->data_descriptor);
1122 							transfer->transfer->PrepareKernelAccess();
1123 							status_t result = FillQueueWithData(
1124 								transfer->transfer,
1125 								transfer->queue_head,
1126 								&transfer->data_descriptor, NULL);
1127 
1128 							if (result == B_OK && Lock()) {
1129 								// reappend the transfer
1130 								if (fLastTransfer)
1131 									fLastTransfer->link = transfer;
1132 								if (!fFirstTransfer)
1133 									fFirstTransfer = transfer;
1134 
1135 								fLastTransfer = transfer;
1136 								Unlock();
1137 
1138 								transfer = next;
1139 								continue;
1140 							}
1141 						}
1142 
1143 						// the transfer is done, but we already set the
1144 						// actualLength with AdvanceByFragment()
1145 						actualLength = 0;
1146 					}
1147 				}
1148 
1149 				transfer->transfer->Finished(callbackStatus, actualLength);
1150 				fProcessingPipe = NULL;
1151 			}
1152 
1153 			// unlink hardware queue and delete the transfer
1154 			UnlinkQueueHead(transfer->queue_head, &fFreeListHead);
1155 			delete transfer->transfer;
1156 			delete transfer;
1157 			transfer = next;
1158 			release_sem(fCleanupSem);
1159 		}
1160 	}
1161 }
1162 
1163 
1164 int32
1165 EHCI::CleanupThread(void *data)
1166 {
1167 	((EHCI *)data)->Cleanup();
1168 	return B_OK;
1169 }
1170 
1171 
1172 void
1173 EHCI::Cleanup()
1174 {
1175 	ehci_qh *lastFreeListHead = NULL;
1176 
1177 	while (!fStopThreads) {
1178 		if (acquire_sem(fCleanupSem) < B_OK)
1179 			continue;
1180 
1181 		ehci_qh *freeListHead = fFreeListHead;
1182 		if (freeListHead == lastFreeListHead)
1183 			continue;
1184 
1185 		// set the doorbell and wait for the host controller to notify us
1186 		WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) | EHCI_USBCMD_INTONAAD);
1187 		if (acquire_sem(fAsyncAdvanceSem) < B_OK)
1188 			continue;
1189 
1190 		ehci_qh *current = freeListHead;
1191 		while (current != lastFreeListHead) {
1192 			ehci_qh *next = (ehci_qh *)current->next_log;
1193 			FreeQueueHead(current);
1194 			current = next;
1195 		}
1196 
1197 		lastFreeListHead = freeListHead;
1198 	}
1199 }
1200 
1201 
1202 ehci_qh *
1203 EHCI::CreateQueueHead()
1204 {
1205 	ehci_qh *result;
1206 	void *physicalAddress;
1207 	if (fStack->AllocateChunk((void **)&result, &physicalAddress,
1208 		sizeof(ehci_qh)) < B_OK) {
1209 		TRACE_ERROR("failed to allocate queue head\n");
1210 		return NULL;
1211 	}
1212 
1213 	result->this_phy = (addr_t)physicalAddress;
1214 	result->next_phy = EHCI_QH_TERMINATE;
1215 	result->next_log = NULL;
1216 	result->prev_log = NULL;
1217 
1218 	ehci_qtd *descriptor = CreateDescriptor(0, 0);
1219 	if (!descriptor) {
1220 		TRACE_ERROR("failed to allocate initial qtd for queue head\n");
1221 		fStack->FreeChunk(result, (void *)result->this_phy, sizeof(ehci_qh));
1222 		return NULL;
1223 	}
1224 
1225 	descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE;
1226 	result->stray_log = descriptor;
1227 	result->element_log = descriptor;
1228 	result->current_qtd_phy = EHCI_QTD_TERMINATE;
1229 	result->overlay.next_phy = descriptor->this_phy;
1230 	result->overlay.alt_next_phy = EHCI_QTD_TERMINATE;
1231 	result->overlay.token = 0;
1232 	for (int32 i = 0; i < 5; i++) {
1233 		result->overlay.buffer_phy[i] = 0;
1234 		result->overlay.ext_buffer_phy[i] = 0;
1235 	}
1236 
1237 	return result;
1238 }
1239 
1240 
1241 status_t
1242 EHCI::InitQueueHead(ehci_qh *queueHead, Pipe *pipe)
1243 {
1244 	switch (pipe->Speed()) {
1245 		case USB_SPEED_LOWSPEED:
1246 			queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_LOW;
1247 			break;
1248 		case USB_SPEED_FULLSPEED:
1249 			queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_FULL;
1250 			break;
1251 		case USB_SPEED_HIGHSPEED:
1252 			queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH;
1253 			break;
1254 		default:
1255 			TRACE_ERROR("unknown pipe speed\n");
1256 			return B_ERROR;
1257 	}
1258 
1259 	queueHead->endpoint_chars |= (3 << EHCI_QH_CHARS_RL_SHIFT)
1260 		| (pipe->MaxPacketSize() << EHCI_QH_CHARS_MPL_SHIFT)
1261 		| (pipe->EndpointAddress() << EHCI_QH_CHARS_EPT_SHIFT)
1262 		| (pipe->DeviceAddress() << EHCI_QH_CHARS_DEV_SHIFT)
1263 		| EHCI_QH_CHARS_TOGGLE;
1264 
1265 	queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT);
1266 	if (pipe->Speed() != USB_SPEED_HIGHSPEED) {
1267 		if (pipe->Type() & USB_OBJECT_CONTROL_PIPE)
1268 			queueHead->endpoint_chars |= EHCI_QH_CHARS_CONTROL;
1269 
1270 		queueHead->endpoint_caps |= (pipe->HubPort() << EHCI_QH_CAPS_PORT_SHIFT)
1271 			| (pipe->HubAddress() << EHCI_QH_CAPS_HUB_SHIFT);
1272 	}
1273 
1274 	return B_OK;
1275 }
1276 
1277 
1278 void
1279 EHCI::FreeQueueHead(ehci_qh *queueHead)
1280 {
1281 	if (!queueHead)
1282 		return;
1283 
1284 	FreeDescriptorChain((ehci_qtd *)queueHead->element_log);
1285 	FreeDescriptor((ehci_qtd *)queueHead->stray_log);
1286 	fStack->FreeChunk(queueHead, (void *)queueHead->this_phy, sizeof(ehci_qh));
1287 }
1288 
1289 
1290 status_t
1291 EHCI::LinkQueueHead(ehci_qh *queueHead)
1292 {
1293 	if (!Lock())
1294 		return B_ERROR;
1295 
1296 	ehci_qh *prevHead = (ehci_qh *)fAsyncQueueHead->prev_log;
1297 	queueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH;
1298 	queueHead->next_log = fAsyncQueueHead;
1299 	queueHead->prev_log = prevHead;
1300 	fAsyncQueueHead->prev_log = queueHead;
1301 	prevHead->next_log = queueHead;
1302 	prevHead->next_phy = queueHead->this_phy | EHCI_QH_TYPE_QH;
1303 
1304 	Unlock();
1305 	return B_OK;
1306 }
1307 
1308 
1309 status_t
1310 EHCI::LinkInterruptQueueHead(ehci_qh *queueHead, Pipe *pipe)
1311 {
1312 	if (!Lock())
1313 		return B_ERROR;
1314 
1315 	uint8 interval = pipe->Interval();
1316 	if (pipe->Speed() == USB_SPEED_HIGHSPEED) {
1317 		// Allow interrupts to be scheduled on each possible micro frame.
1318 		queueHead->endpoint_caps |= (0xff << EHCI_QH_CAPS_ISM_SHIFT);
1319 	} else {
1320 		// As we do not yet support FSTNs to correctly reference low/full
1321 		// speed interrupt transfers, we simply put them into the 1 interval
1322 		// queue. This way we ensure that we reach them on every micro frame
1323 		// and can do the corresponding start/complete split transactions.
1324 		// ToDo: use FSTNs to correctly link non high speed interrupt transfers
1325 		interval = 1;
1326 
1327 		// For now we also force start splits to be in micro frame 0 and
1328 		// complete splits to be in micro frame 2, 3 and 4.
1329 		queueHead->endpoint_caps |= (0x01 << EHCI_QH_CAPS_ISM_SHIFT);
1330 		queueHead->endpoint_caps |= (0x1c << EHCI_QH_CAPS_SCM_SHIFT);
1331 	}
1332 
1333 	// this should not happen
1334 	if (interval < 1)
1335 		interval = 1;
1336 
1337 	// this may happen as intervals can go up to 16; we limit the value to
1338 	// 11 as you cannot support intervals above that with a frame list of
1339 	// just 1024 entries...
1340 	if (interval > 11)
1341 		interval = 11;
1342 
1343 	ehci_qh *interruptQueue = &fInterruptEntries[interval - 1].queue_head;
1344 	queueHead->next_phy = interruptQueue->next_phy;
1345 	queueHead->next_log = interruptQueue->next_log;
1346 	queueHead->prev_log = interruptQueue;
1347 	if (interruptQueue->next_log)
1348 		((ehci_qh *)interruptQueue->next_log)->prev_log = queueHead;
1349 	interruptQueue->next_log = queueHead;
1350 	interruptQueue->next_phy = queueHead->this_phy | EHCI_QH_TYPE_QH;
1351 
1352 	Unlock();
1353 	return B_OK;
1354 }
1355 
1356 
1357 status_t
1358 EHCI::UnlinkQueueHead(ehci_qh *queueHead, ehci_qh **freeListHead)
1359 {
1360 	if (!Lock())
1361 		return B_ERROR;
1362 
1363 	ehci_qh *prevHead = (ehci_qh *)queueHead->prev_log;
1364 	ehci_qh *nextHead = (ehci_qh *)queueHead->next_log;
1365 	if (prevHead) {
1366 		prevHead->next_phy = queueHead->next_phy | EHCI_QH_TYPE_QH;
1367 		prevHead->next_log = queueHead->next_log;
1368 	}
1369 
1370 	if (nextHead)
1371 		nextHead->prev_log = queueHead->prev_log;
1372 
1373 	queueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH;
1374 	queueHead->prev_log = NULL;
1375 
1376 	queueHead->next_log = *freeListHead;
1377 	*freeListHead = queueHead;
1378 
1379 	Unlock();
1380 	return B_OK;
1381 }
1382 
1383 
1384 status_t
1385 EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead,
1386 	ehci_qtd **_dataDescriptor, bool *_directionIn)
1387 {
1388 	Pipe *pipe = transfer->TransferPipe();
1389 	usb_request_data *requestData = transfer->RequestData();
1390 	bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0;
1391 
1392 	ehci_qtd *setupDescriptor = CreateDescriptor(sizeof(usb_request_data),
1393 		EHCI_QTD_PID_SETUP);
1394 	ehci_qtd *statusDescriptor = CreateDescriptor(0,
1395 		directionIn ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN);
1396 
1397 	if (!setupDescriptor || !statusDescriptor) {
1398 		TRACE_ERROR("failed to allocate descriptors\n");
1399 		FreeDescriptor(setupDescriptor);
1400 		FreeDescriptor(statusDescriptor);
1401 		return B_NO_MEMORY;
1402 	}
1403 
1404 	iovec vector;
1405 	vector.iov_base = requestData;
1406 	vector.iov_len = sizeof(usb_request_data);
1407 	WriteDescriptorChain(setupDescriptor, &vector, 1);
1408 
1409 	ehci_qtd *strayDescriptor = (ehci_qtd *)queueHead->stray_log;
1410 	statusDescriptor->token |= EHCI_QTD_IOC | EHCI_QTD_DATA_TOGGLE;
1411 
1412 	ehci_qtd *dataDescriptor = NULL;
1413 	if (transfer->VectorCount() > 0) {
1414 		ehci_qtd *lastDescriptor = NULL;
1415 		status_t result = CreateDescriptorChain(pipe, &dataDescriptor,
1416 			&lastDescriptor, strayDescriptor, transfer->VectorLength(),
1417 			directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT);
1418 
1419 		if (result < B_OK) {
1420 			FreeDescriptor(setupDescriptor);
1421 			FreeDescriptor(statusDescriptor);
1422 			return result;
1423 		}
1424 
1425 		if (!directionIn) {
1426 			WriteDescriptorChain(dataDescriptor, transfer->Vector(),
1427 				transfer->VectorCount());
1428 		}
1429 
1430 		LinkDescriptors(setupDescriptor, dataDescriptor, strayDescriptor);
1431 		LinkDescriptors(lastDescriptor, statusDescriptor, strayDescriptor);
1432 	} else {
1433 		// no data: link setup and status descriptors directly
1434 		LinkDescriptors(setupDescriptor, statusDescriptor, strayDescriptor);
1435 	}
1436 
1437 	queueHead->element_log = setupDescriptor;
1438 	queueHead->overlay.next_phy = setupDescriptor->this_phy;
1439 	queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE;
1440 
1441 	*_dataDescriptor = dataDescriptor;
1442 	*_directionIn = directionIn;
1443 	return B_OK;
1444 }
1445 
1446 
1447 status_t
1448 EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead,
1449 	ehci_qtd **_dataDescriptor, bool *_directionIn)
1450 {
1451 	Pipe *pipe = transfer->TransferPipe();
1452 	bool directionIn = (pipe->Direction() == Pipe::In);
1453 
1454 	ehci_qtd *firstDescriptor = NULL;
1455 	ehci_qtd *lastDescriptor = NULL;
1456 	ehci_qtd *strayDescriptor = (ehci_qtd *)queueHead->stray_log;
1457 	status_t result = CreateDescriptorChain(pipe, &firstDescriptor,
1458 		&lastDescriptor, strayDescriptor, transfer->VectorLength(),
1459 		directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT);
1460 
1461 	if (result < B_OK)
1462 		return result;
1463 
1464 	lastDescriptor->token |= EHCI_QTD_IOC;
1465 	if (!directionIn) {
1466 		WriteDescriptorChain(firstDescriptor, transfer->Vector(),
1467 			transfer->VectorCount());
1468 	}
1469 
1470 	queueHead->element_log = firstDescriptor;
1471 	queueHead->overlay.next_phy = firstDescriptor->this_phy;
1472 	queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE;
1473 
1474 	*_dataDescriptor = firstDescriptor;
1475 	if (_directionIn)
1476 		*_directionIn = directionIn;
1477 	return B_OK;
1478 }
1479 
1480 
1481 ehci_qtd *
1482 EHCI::CreateDescriptor(size_t bufferSize, uint8 pid)
1483 {
1484 	ehci_qtd *result;
1485 	void *physicalAddress;
1486 	if (fStack->AllocateChunk((void **)&result, &physicalAddress,
1487 		sizeof(ehci_qtd)) < B_OK) {
1488 		TRACE_ERROR("failed to allocate a qtd\n");
1489 		return NULL;
1490 	}
1491 
1492 	result->this_phy = (addr_t)physicalAddress;
1493 	result->next_phy = EHCI_QTD_TERMINATE;
1494 	result->next_log = NULL;
1495 	result->alt_next_phy = EHCI_QTD_TERMINATE;
1496 	result->alt_next_log = NULL;
1497 	result->buffer_size = bufferSize;
1498 	result->token = bufferSize << EHCI_QTD_BYTES_SHIFT;
1499 	result->token |= 3 << EHCI_QTD_ERRCOUNT_SHIFT;
1500 	result->token |= pid << EHCI_QTD_PID_SHIFT;
1501 	result->token |= EHCI_QTD_STATUS_ACTIVE;
1502 	if (bufferSize == 0) {
1503 		result->buffer_log = NULL;
1504 		for (int32 i = 0; i < 5; i++) {
1505 			result->buffer_phy[i] = 0;
1506 			result->ext_buffer_phy[i] = 0;
1507 		}
1508 
1509 		return result;
1510 	}
1511 
1512 	if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress,
1513 		bufferSize) < B_OK) {
1514 		TRACE_ERROR("unable to allocate qtd buffer\n");
1515 		fStack->FreeChunk(result, (void *)result->this_phy, sizeof(ehci_qtd));
1516 		return NULL;
1517 	}
1518 
1519 	addr_t physicalBase = (addr_t)physicalAddress;
1520 	result->buffer_phy[0] = physicalBase;
1521 	result->ext_buffer_phy[0] = 0;
1522 	for (int32 i = 1; i < 5; i++) {
1523 		physicalBase += B_PAGE_SIZE;
1524 		result->buffer_phy[i] = physicalBase & EHCI_QTD_PAGE_MASK;
1525 		result->ext_buffer_phy[i] = 0;
1526 	}
1527 
1528 	return result;
1529 }
1530 
1531 
1532 status_t
1533 EHCI::CreateDescriptorChain(Pipe *pipe, ehci_qtd **_firstDescriptor,
1534 	ehci_qtd **_lastDescriptor, ehci_qtd *strayDescriptor, size_t bufferSize,
1535 	uint8 pid)
1536 {
1537 	size_t packetSize = B_PAGE_SIZE * 4;
1538 	int32 descriptorCount = (bufferSize + packetSize - 1) / packetSize;
1539 
1540 	bool dataToggle = pipe->DataToggle();
1541 	ehci_qtd *firstDescriptor = NULL;
1542 	ehci_qtd *lastDescriptor = *_firstDescriptor;
1543 	for (int32 i = 0; i < descriptorCount; i++) {
1544 		ehci_qtd *descriptor = CreateDescriptor(min_c(packetSize, bufferSize),
1545 			pid);
1546 
1547 		if (!descriptor) {
1548 			FreeDescriptorChain(firstDescriptor);
1549 			return B_NO_MEMORY;
1550 		}
1551 
1552 		if (dataToggle)
1553 			descriptor->token |= EHCI_QTD_DATA_TOGGLE;
1554 
1555 		if (lastDescriptor)
1556 			LinkDescriptors(lastDescriptor, descriptor, strayDescriptor);
1557 
1558 		bufferSize -= packetSize;
1559 		lastDescriptor = descriptor;
1560 		if (!firstDescriptor)
1561 			firstDescriptor = descriptor;
1562 	}
1563 
1564 	*_firstDescriptor = firstDescriptor;
1565 	*_lastDescriptor = lastDescriptor;
1566 	return B_OK;
1567 }
1568 
1569 
1570 void
1571 EHCI::FreeDescriptor(ehci_qtd *descriptor)
1572 {
1573 	if (!descriptor)
1574 		return;
1575 
1576 	if (descriptor->buffer_log) {
1577 		fStack->FreeChunk(descriptor->buffer_log,
1578 			(void *)descriptor->buffer_phy[0], descriptor->buffer_size);
1579 	}
1580 
1581 	fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, sizeof(ehci_qtd));
1582 }
1583 
1584 
1585 void
1586 EHCI::FreeDescriptorChain(ehci_qtd *topDescriptor)
1587 {
1588 	ehci_qtd *current = topDescriptor;
1589 	ehci_qtd *next = NULL;
1590 
1591 	while (current) {
1592 		next = (ehci_qtd *)current->next_log;
1593 		FreeDescriptor(current);
1594 		current = next;
1595 	}
1596 }
1597 
1598 
1599 void
1600 EHCI::LinkDescriptors(ehci_qtd *first, ehci_qtd *last, ehci_qtd *alt)
1601 {
1602 	first->next_phy = last->this_phy;
1603 	first->next_log = last;
1604 
1605 	if (alt) {
1606 		first->alt_next_phy = alt->this_phy;
1607 		first->alt_next_log = alt;
1608 	} else {
1609 		first->alt_next_phy = EHCI_QTD_TERMINATE;
1610 		first->alt_next_log = NULL;
1611 	}
1612 }
1613 
1614 
1615 size_t
1616 EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, iovec *vector,
1617 	size_t vectorCount)
1618 {
1619 	ehci_qtd *current = topDescriptor;
1620 	size_t actualLength = 0;
1621 	size_t vectorIndex = 0;
1622 	size_t vectorOffset = 0;
1623 	size_t bufferOffset = 0;
1624 
1625 	while (current) {
1626 		if (!current->buffer_log)
1627 			break;
1628 
1629 		while (true) {
1630 			size_t length = min_c(current->buffer_size - bufferOffset,
1631 				vector[vectorIndex].iov_len - vectorOffset);
1632 
1633 			memcpy((uint8 *)current->buffer_log + bufferOffset,
1634 				(uint8 *)vector[vectorIndex].iov_base + vectorOffset, length);
1635 
1636 			actualLength += length;
1637 			vectorOffset += length;
1638 			bufferOffset += length;
1639 
1640 			if (vectorOffset >= vector[vectorIndex].iov_len) {
1641 				if (++vectorIndex >= vectorCount) {
1642 					TRACE("wrote descriptor chain (%ld bytes, no more vectors)\n", actualLength);
1643 					return actualLength;
1644 				}
1645 
1646 				vectorOffset = 0;
1647 			}
1648 
1649 			if (bufferOffset >= current->buffer_size) {
1650 				bufferOffset = 0;
1651 				break;
1652 			}
1653 		}
1654 
1655 		if (current->next_phy & EHCI_QTD_TERMINATE)
1656 			break;
1657 
1658 		current = (ehci_qtd *)current->next_log;
1659 	}
1660 
1661 	TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
1662 	return actualLength;
1663 }
1664 
1665 
1666 size_t
1667 EHCI::ReadDescriptorChain(ehci_qtd *topDescriptor, iovec *vector,
1668 	size_t vectorCount, bool *nextDataToggle)
1669 {
1670 	uint32 dataToggle = 0;
1671 	ehci_qtd *current = topDescriptor;
1672 	size_t actualLength = 0;
1673 	size_t vectorIndex = 0;
1674 	size_t vectorOffset = 0;
1675 	size_t bufferOffset = 0;
1676 
1677 	while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) {
1678 		if (!current->buffer_log)
1679 			break;
1680 
1681 		dataToggle = current->token & EHCI_QTD_DATA_TOGGLE;
1682 		size_t bufferSize = current->buffer_size;
1683 		bufferSize -= (current->token >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK;
1684 
1685 		while (true) {
1686 			size_t length = min_c(bufferSize - bufferOffset,
1687 				vector[vectorIndex].iov_len - vectorOffset);
1688 
1689 			memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset,
1690 				(uint8 *)current->buffer_log + bufferOffset, length);
1691 
1692 			actualLength += length;
1693 			vectorOffset += length;
1694 			bufferOffset += length;
1695 
1696 			if (vectorOffset >= vector[vectorIndex].iov_len) {
1697 				if (++vectorIndex >= vectorCount) {
1698 					TRACE("read descriptor chain (%ld bytes, no more vectors)\n", actualLength);
1699 					*nextDataToggle = dataToggle > 0 ? true : false;
1700 					return actualLength;
1701 				}
1702 
1703 				vectorOffset = 0;
1704 			}
1705 
1706 			if (bufferOffset >= bufferSize) {
1707 				bufferOffset = 0;
1708 				break;
1709 			}
1710 		}
1711 
1712 		if (current->next_phy & EHCI_QTD_TERMINATE)
1713 			break;
1714 
1715 		current = (ehci_qtd *)current->next_log;
1716 	}
1717 
1718 	TRACE("read descriptor chain (%ld bytes)\n", actualLength);
1719 	*nextDataToggle = dataToggle > 0 ? true : false;
1720 	return actualLength;
1721 }
1722 
1723 
1724 size_t
1725 EHCI::ReadActualLength(ehci_qtd *topDescriptor, bool *nextDataToggle)
1726 {
1727 	size_t actualLength = 0;
1728 	ehci_qtd *current = topDescriptor;
1729 	uint32 dataToggle = 0;
1730 
1731 	while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) {
1732 		dataToggle = current->token & EHCI_QTD_DATA_TOGGLE;
1733 		size_t length = current->buffer_size;
1734 		length -= (current->token >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK;
1735 		actualLength += length;
1736 
1737 		if (current->next_phy & EHCI_QTD_TERMINATE)
1738 			break;
1739 
1740 		current = (ehci_qtd *)current->next_log;
1741 	}
1742 
1743 	TRACE("read actual length (%ld bytes)\n", actualLength);
1744 	*nextDataToggle = dataToggle > 0 ? true : false;
1745 	return actualLength;
1746 }
1747 
1748 
1749 inline void
1750 EHCI::WriteOpReg(uint32 reg, uint32 value)
1751 {
1752 	*(volatile uint32 *)(fOperationalRegisters + reg) = value;
1753 }
1754 
1755 
1756 inline uint32
1757 EHCI::ReadOpReg(uint32 reg)
1758 {
1759 	return *(volatile uint32 *)(fOperationalRegisters + reg);
1760 }
1761 
1762 
1763 inline uint8
1764 EHCI::ReadCapReg8(uint32 reg)
1765 {
1766 	return *(volatile uint8 *)(fCapabilityRegisters + reg);
1767 }
1768 
1769 
1770 inline uint16
1771 EHCI::ReadCapReg16(uint32 reg)
1772 {
1773 	return *(volatile uint16 *)(fCapabilityRegisters + reg);
1774 }
1775 
1776 
1777 inline uint32
1778 EHCI::ReadCapReg32(uint32 reg)
1779 {
1780 	return *(volatile uint32 *)(fCapabilityRegisters + reg);
1781 }
1782