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