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