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
28 device_manager_info* gDeviceManager;
29 static 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
36 typedef 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
51 static status_t
init_bus(device_node * node,void ** bus_cookie)52 init_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
88 static void
uninit_bus(void * bus_cookie)89 uninit_bus(void* bus_cookie)
90 {
91 CALLED();
92 OHCI* ohci = (OHCI*)bus_cookie;
93 delete ohci;
94 }
95
96
97 static status_t
register_child_devices(void * cookie)98 register_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
123 static status_t
init_device(device_node * node,void ** device_cookie)124 init_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
153 static void
uninit_device(void * device_cookie)154 uninit_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
162 static status_t
register_device(device_node * parent)163 register_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
176 static float
supports_device(device_node * parent)177 supports_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
216 module_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
223 static 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.
242 static 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
257 module_info* modules[] = {
258 (module_info* )&sOHCIDevice,
259 (module_info* )&gOHCIPCIDeviceModule,
260 NULL
261 };
262
263
264 //
265 // #pragma mark -
266 //
267
268
OHCI(pci_info * info,pci_device_module_info * pci,pci_device * device,Stack * stack,device_node * node)269 OHCI::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
~OHCI()579 OHCI::~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
616 status_t
Start()617 OHCI::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
650 status_t
SubmitTransfer(Transfer * transfer)651 OHCI::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
680 status_t
CancelQueuedTransfers(Pipe * pipe,bool force)681 OHCI::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 (pipe->Type() & USB_OBJECT_ISO_PIPE) {
708 ohci_isochronous_td *descriptor
709 = (ohci_isochronous_td *)current->first_descriptor;
710 while (descriptor) {
711 uint16 frame = OHCI_ITD_GET_STARTING_FRAME(
712 descriptor->flags);
713 _ReleaseIsochronousBandwidth(frame,
714 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
715 if (descriptor
716 == (ohci_isochronous_td*)current->last_descriptor)
717 // this is the last ITD of the transfer
718 break;
719
720 descriptor
721 = (ohci_isochronous_td *)
722 descriptor->next_done_descriptor;
723 }
724 }
725
726 transfer_entry *entry
727 = (transfer_entry *)malloc(sizeof(transfer_entry));
728 if (entry != NULL) {
729 entry->transfer = current->transfer;
730 current->transfer = NULL;
731 entry->next = list;
732 list = entry;
733 }
734
735 current->canceled = true;
736 }
737 current = current->link;
738 }
739
740 Unlock();
741
742 while (list != NULL) {
743 transfer_entry *next = list->next;
744
745 // If the transfer is canceled by force, the one causing the
746 // cancel is possibly not the one who initiated the transfer
747 // and the callback is likely not safe anymore
748 if (!force)
749 list->transfer->Finished(B_CANCELED, 0);
750
751 delete list->transfer;
752 free(list);
753 list = next;
754 }
755
756 // wait for any transfers that might have made it before canceling
757 while (fProcessingPipe == pipe)
758 snooze(1000);
759
760 // notify the finisher so it can clean up the canceled transfers
761 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
762 return B_OK;
763 }
764
765
766 status_t
NotifyPipeChange(Pipe * pipe,usb_change change)767 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
768 {
769 TRACE("pipe change %d for pipe %p\n", change, pipe);
770 if (pipe->DeviceAddress() == fRootHubAddress) {
771 // no need to insert/remove endpoint descriptors for the root hub
772 return B_OK;
773 }
774
775 switch (change) {
776 case USB_CHANGE_CREATED:
777 return _InsertEndpointForPipe(pipe);
778
779 case USB_CHANGE_DESTROYED:
780 return _RemoveEndpointForPipe(pipe);
781
782 case USB_CHANGE_PIPE_POLICY_CHANGED:
783 TRACE("pipe policy changing unhandled!\n");
784 break;
785
786 default:
787 TRACE_ERROR("unknown pipe change!\n");
788 return B_ERROR;
789 }
790
791 return B_OK;
792 }
793
794
795 status_t
GetPortStatus(uint8 index,usb_port_status * status)796 OHCI::GetPortStatus(uint8 index, usb_port_status *status)
797 {
798 if (index >= fPortCount) {
799 TRACE_ERROR("get port status for invalid port %u\n", index);
800 return B_BAD_INDEX;
801 }
802
803 status->status = status->change = 0;
804 uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index));
805
806 // status
807 if (portStatus & OHCI_RH_PORTSTATUS_CCS)
808 status->status |= PORT_STATUS_CONNECTION;
809 if (portStatus & OHCI_RH_PORTSTATUS_PES)
810 status->status |= PORT_STATUS_ENABLE;
811 if (portStatus & OHCI_RH_PORTSTATUS_PSS)
812 status->status |= PORT_STATUS_SUSPEND;
813 if (portStatus & OHCI_RH_PORTSTATUS_POCI)
814 status->status |= PORT_STATUS_OVER_CURRENT;
815 if (portStatus & OHCI_RH_PORTSTATUS_PRS)
816 status->status |= PORT_STATUS_RESET;
817 if (portStatus & OHCI_RH_PORTSTATUS_PPS)
818 status->status |= PORT_STATUS_POWER;
819 if (portStatus & OHCI_RH_PORTSTATUS_LSDA)
820 status->status |= PORT_STATUS_LOW_SPEED;
821
822 // change
823 if (portStatus & OHCI_RH_PORTSTATUS_CSC)
824 status->change |= PORT_STATUS_CONNECTION;
825 if (portStatus & OHCI_RH_PORTSTATUS_PESC)
826 status->change |= PORT_STATUS_ENABLE;
827 if (portStatus & OHCI_RH_PORTSTATUS_PSSC)
828 status->change |= PORT_STATUS_SUSPEND;
829 if (portStatus & OHCI_RH_PORTSTATUS_OCIC)
830 status->change |= PORT_STATUS_OVER_CURRENT;
831 if (portStatus & OHCI_RH_PORTSTATUS_PRSC)
832 status->change |= PORT_STATUS_RESET;
833
834 TRACE("port %u status 0x%04x change 0x%04x\n", index,
835 status->status, status->change);
836 return B_OK;
837 }
838
839
840 status_t
SetPortFeature(uint8 index,uint16 feature)841 OHCI::SetPortFeature(uint8 index, uint16 feature)
842 {
843 TRACE("set port feature index %u feature %u\n", index, feature);
844 if (index > fPortCount)
845 return B_BAD_INDEX;
846
847 switch (feature) {
848 case PORT_ENABLE:
849 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES);
850 return B_OK;
851
852 case PORT_SUSPEND:
853 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS);
854 return B_OK;
855
856 case PORT_RESET:
857 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
858 return B_OK;
859
860 case PORT_POWER:
861 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
862 return B_OK;
863 }
864
865 return B_BAD_VALUE;
866 }
867
868
869 status_t
ClearPortFeature(uint8 index,uint16 feature)870 OHCI::ClearPortFeature(uint8 index, uint16 feature)
871 {
872 TRACE("clear port feature index %u feature %u\n", index, feature);
873 if (index > fPortCount)
874 return B_BAD_INDEX;
875
876 switch (feature) {
877 case PORT_ENABLE:
878 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS);
879 return B_OK;
880
881 case PORT_SUSPEND:
882 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI);
883 return B_OK;
884
885 case PORT_POWER:
886 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA);
887 return B_OK;
888
889 case C_PORT_CONNECTION:
890 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
891 return B_OK;
892
893 case C_PORT_ENABLE:
894 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC);
895 return B_OK;
896
897 case C_PORT_SUSPEND:
898 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC);
899 return B_OK;
900
901 case C_PORT_OVER_CURRENT:
902 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC);
903 return B_OK;
904
905 case C_PORT_RESET:
906 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC);
907 return B_OK;
908 }
909
910 return B_BAD_VALUE;
911 }
912
913
914 int32
_InterruptHandler(void * data)915 OHCI::_InterruptHandler(void *data)
916 {
917 return ((OHCI *)data)->_Interrupt();
918 }
919
920
921 int32
_Interrupt()922 OHCI::_Interrupt()
923 {
924 static spinlock lock = B_SPINLOCK_INITIALIZER;
925 acquire_spinlock(&lock);
926
927 uint32 status = 0;
928 uint32 acknowledge = 0;
929 bool finishTransfers = false;
930 int32 result = B_HANDLED_INTERRUPT;
931
932 // The LSb of done_head is used to inform the HCD that an interrupt
933 // condition exists for both the done list and for another event recorded in
934 // the HcInterruptStatus register. If done_head is 0, then the interrupt
935 // was caused by other than the HccaDoneHead update and the
936 // HcInterruptStatus register needs to be accessed to determine that exact
937 // interrupt cause. If HccDoneHead is nonzero, then a done list update
938 // interrupt is indicated and if the LSb of the Dword is nonzero, then an
939 // additional interrupt event is indicated and HcInterruptStatus should be
940 // checked to determine its cause.
941 uint32 doneHead = fHcca->done_head;
942 if (doneHead != 0) {
943 status = OHCI_WRITEBACK_DONE_HEAD;
944 if (doneHead & OHCI_DONE_INTERRUPTS)
945 status |= _ReadReg(OHCI_INTERRUPT_STATUS)
946 & _ReadReg(OHCI_INTERRUPT_ENABLE);
947 } else {
948 status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE)
949 & ~OHCI_WRITEBACK_DONE_HEAD;
950 if (status == 0) {
951 // Nothing to be done (PCI shared interrupt)
952 release_spinlock(&lock);
953 return B_UNHANDLED_INTERRUPT;
954 }
955 }
956
957 if (status & OHCI_SCHEDULING_OVERRUN) {
958 TRACE_MODULE("scheduling overrun occured\n");
959 acknowledge |= OHCI_SCHEDULING_OVERRUN;
960 }
961
962 if (status & OHCI_WRITEBACK_DONE_HEAD) {
963 TRACE_MODULE("transfer descriptors processed\n");
964 fHcca->done_head = 0;
965 acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
966 result = B_INVOKE_SCHEDULER;
967 finishTransfers = true;
968 }
969
970 if (status & OHCI_RESUME_DETECTED) {
971 TRACE_MODULE("resume detected\n");
972 acknowledge |= OHCI_RESUME_DETECTED;
973 }
974
975 if (status & OHCI_UNRECOVERABLE_ERROR) {
976 TRACE_MODULE_ERROR("unrecoverable error - controller halted\n");
977 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
978 // TODO: clear all pending transfers, reset and resetup the controller
979 }
980
981 if (status & OHCI_ROOT_HUB_STATUS_CHANGE) {
982 TRACE_MODULE("root hub status change\n");
983 // Disable the interrupt as it will otherwise be retriggered until the
984 // port has been reset and the change is cleared explicitly.
985 // TODO: renable it once we use status changes instead of polling
986 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE);
987 acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
988 }
989
990 if (acknowledge != 0)
991 _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge);
992
993 release_spinlock(&lock);
994
995 if (finishTransfers)
996 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
997
998 return result;
999 }
1000
1001
1002 status_t
_AddPendingTransfer(Transfer * transfer,ohci_endpoint_descriptor * endpoint,ohci_general_td * firstDescriptor,ohci_general_td * dataDescriptor,ohci_general_td * lastDescriptor,bool directionIn)1003 OHCI::_AddPendingTransfer(Transfer *transfer,
1004 ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor,
1005 ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor,
1006 bool directionIn)
1007 {
1008 if (!transfer || !endpoint || !lastDescriptor)
1009 return B_BAD_VALUE;
1010
1011 transfer_data *data = new(std::nothrow) transfer_data;
1012 if (!data)
1013 return B_NO_MEMORY;
1014
1015 status_t result = transfer->InitKernelAccess();
1016 if (result < B_OK) {
1017 delete data;
1018 return result;
1019 }
1020
1021 data->transfer = transfer;
1022 data->endpoint = endpoint;
1023 data->incoming = directionIn;
1024 data->canceled = false;
1025 data->link = NULL;
1026
1027 // the current tail will become the first descriptor
1028 data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor;
1029
1030 // the data and first descriptors might be the same
1031 if (dataDescriptor == firstDescriptor)
1032 data->data_descriptor = data->first_descriptor;
1033 else
1034 data->data_descriptor = dataDescriptor;
1035
1036 // even the last and the first descriptor might be the same
1037 if (lastDescriptor == firstDescriptor)
1038 data->last_descriptor = data->first_descriptor;
1039 else
1040 data->last_descriptor = lastDescriptor;
1041
1042 if (!Lock()) {
1043 delete data;
1044 return B_ERROR;
1045 }
1046
1047 if (fLastTransfer)
1048 fLastTransfer->link = data;
1049 else
1050 fFirstTransfer = data;
1051
1052 fLastTransfer = data;
1053 Unlock();
1054
1055 return B_OK;
1056 }
1057
1058
1059 status_t
_AddPendingIsochronousTransfer(Transfer * transfer,ohci_endpoint_descriptor * endpoint,ohci_isochronous_td * firstDescriptor,ohci_isochronous_td * lastDescriptor,bool directionIn)1060 OHCI::_AddPendingIsochronousTransfer(Transfer *transfer,
1061 ohci_endpoint_descriptor *endpoint, ohci_isochronous_td *firstDescriptor,
1062 ohci_isochronous_td *lastDescriptor, bool directionIn)
1063 {
1064 if (!transfer || !endpoint || !lastDescriptor)
1065 return B_BAD_VALUE;
1066
1067 transfer_data *data = new(std::nothrow) transfer_data;
1068 if (!data)
1069 return B_NO_MEMORY;
1070
1071 status_t result = transfer->InitKernelAccess();
1072 if (result < B_OK) {
1073 delete data;
1074 return result;
1075 }
1076
1077 data->transfer = transfer;
1078 data->endpoint = endpoint;
1079 data->incoming = directionIn;
1080 data->canceled = false;
1081 data->link = NULL;
1082
1083 // the current tail will become the first descriptor
1084 data->first_descriptor = (ohci_general_td*)endpoint->tail_logical_descriptor;
1085
1086 // the data and first descriptors are the same
1087 data->data_descriptor = data->first_descriptor;
1088
1089 // the last and the first descriptor might be the same
1090 if (lastDescriptor == firstDescriptor)
1091 data->last_descriptor = data->first_descriptor;
1092 else
1093 data->last_descriptor = (ohci_general_td*)lastDescriptor;
1094
1095 if (!Lock()) {
1096 delete data;
1097 return B_ERROR;
1098 }
1099
1100 if (fLastTransfer)
1101 fLastTransfer->link = data;
1102 else
1103 fFirstTransfer = data;
1104
1105 fLastTransfer = data;
1106 Unlock();
1107
1108 return B_OK;
1109 }
1110
1111
1112 int32
_FinishThread(void * data)1113 OHCI::_FinishThread(void *data)
1114 {
1115 ((OHCI *)data)->_FinishTransfers();
1116 return B_OK;
1117 }
1118
1119
1120 void
_FinishTransfers()1121 OHCI::_FinishTransfers()
1122 {
1123 while (!fStopFinishThread) {
1124 if (acquire_sem(fFinishTransfersSem) < B_OK)
1125 continue;
1126
1127 // eat up sems that have been released by multiple interrupts
1128 int32 semCount = 0;
1129 get_sem_count(fFinishTransfersSem, &semCount);
1130 if (semCount > 0)
1131 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);
1132
1133 if (!Lock())
1134 continue;
1135
1136 TRACE("finishing transfers (first transfer: %p; last"
1137 " transfer: %p)\n", fFirstTransfer, fLastTransfer);
1138 transfer_data *lastTransfer = NULL;
1139 transfer_data *transfer = fFirstTransfer;
1140 Unlock();
1141
1142 while (transfer) {
1143 bool transferDone = false;
1144 ohci_general_td *descriptor = transfer->first_descriptor;
1145 ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1146 status_t callbackStatus = B_OK;
1147
1148 if (endpoint->flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT) {
1149 transfer_data *next = transfer->link;
1150 if (_FinishIsochronousTransfer(transfer, &lastTransfer)) {
1151 delete transfer->transfer;
1152 delete transfer;
1153 }
1154 transfer = next;
1155 continue;
1156 }
1157
1158 MutexLocker endpointLocker(endpoint->lock);
1159
1160 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1161 != endpoint->tail_physical_descriptor
1162 && (endpoint->head_physical_descriptor
1163 & OHCI_ENDPOINT_HALTED) == 0) {
1164 // there are still active transfers on this endpoint, we need
1165 // to wait for all of them to complete, otherwise we'd read
1166 // a potentially bogus data toggle value below
1167 TRACE("endpoint %p still has active tds\n", endpoint);
1168 lastTransfer = transfer;
1169 transfer = transfer->link;
1170 continue;
1171 }
1172
1173 endpointLocker.Unlock();
1174
1175 while (descriptor && !transfer->canceled) {
1176 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1177 if (status == OHCI_TD_CONDITION_NOT_ACCESSED) {
1178 // td is still active
1179 TRACE("td %p still active\n", descriptor);
1180 break;
1181 }
1182
1183 if (status != OHCI_TD_CONDITION_NO_ERROR) {
1184 // an error occured, but we must ensure that the td
1185 // was actually done
1186 if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) {
1187 // the endpoint is halted, this guaratees us that this
1188 // descriptor has passed (we don't know if the endpoint
1189 // was halted because of this td, but we do not need
1190 // to know, as when it was halted by another td this
1191 // still ensures that this td was handled before).
1192 TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status);
1193
1194 callbackStatus = _GetStatusOfConditionCode(status);
1195
1196 transferDone = true;
1197 break;
1198 } else {
1199 // an error occured but the endpoint is not halted so
1200 // the td is in fact still active
1201 TRACE("td %p active with error\n", descriptor);
1202 break;
1203 }
1204 }
1205
1206 // the td has completed without an error
1207 TRACE("td %p done\n", descriptor);
1208
1209 if (descriptor == transfer->last_descriptor
1210 || descriptor->buffer_physical != 0) {
1211 // this is the last td of the transfer or a short packet
1212 callbackStatus = B_OK;
1213 transferDone = true;
1214 break;
1215 }
1216
1217 descriptor
1218 = (ohci_general_td *)descriptor->next_logical_descriptor;
1219 }
1220
1221 if (transfer->canceled) {
1222 // when a transfer is canceled, all transfers to that endpoint
1223 // are canceled by setting the head pointer to the tail pointer
1224 // which causes all of the tds to become "free" (as they are
1225 // inaccessible and not accessed anymore (as setting the head
1226 // pointer required disabling the endpoint))
1227 callbackStatus = B_OK;
1228 transferDone = true;
1229 }
1230
1231 if (!transferDone) {
1232 lastTransfer = transfer;
1233 transfer = transfer->link;
1234 continue;
1235 }
1236
1237 // remove the transfer from the list first so we are sure
1238 // it doesn't get canceled while we still process it
1239 transfer_data *next = transfer->link;
1240 if (Lock()) {
1241 if (lastTransfer)
1242 lastTransfer->link = transfer->link;
1243
1244 if (transfer == fFirstTransfer)
1245 fFirstTransfer = transfer->link;
1246 if (transfer == fLastTransfer)
1247 fLastTransfer = lastTransfer;
1248
1249 // store the currently processing pipe here so we can wait
1250 // in cancel if we are processing something on the target pipe
1251 if (!transfer->canceled)
1252 fProcessingPipe = transfer->transfer->TransferPipe();
1253
1254 transfer->link = NULL;
1255 Unlock();
1256 }
1257
1258 // break the descriptor chain on the last descriptor
1259 transfer->last_descriptor->next_logical_descriptor = NULL;
1260 TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n",
1261 transfer, callbackStatus);
1262
1263 // if canceled the callback has already been called
1264 if (!transfer->canceled) {
1265 size_t actualLength = 0;
1266 if (callbackStatus == B_OK) {
1267 if (transfer->data_descriptor && transfer->incoming) {
1268 // data to read out
1269 generic_io_vec *vector = transfer->transfer->Vector();
1270 size_t vectorCount = transfer->transfer->VectorCount();
1271
1272 transfer->transfer->PrepareKernelAccess();
1273 actualLength = _ReadDescriptorChain(
1274 transfer->data_descriptor,
1275 vector, vectorCount, transfer->transfer->IsPhysical());
1276 } else if (transfer->data_descriptor) {
1277 // read the actual length that was sent
1278 actualLength = _ReadActualLength(
1279 transfer->data_descriptor);
1280 }
1281
1282 // get the last data toggle and store it for next time
1283 transfer->transfer->TransferPipe()->SetDataToggle(
1284 (endpoint->head_physical_descriptor
1285 & OHCI_ENDPOINT_TOGGLE_CARRY) != 0);
1286
1287 if (transfer->transfer->IsFragmented()) {
1288 // this transfer may still have data left
1289 TRACE("advancing fragmented transfer\n");
1290 transfer->transfer->AdvanceByFragment(actualLength);
1291 if (transfer->transfer->FragmentLength() > 0) {
1292 TRACE("still %ld bytes left on transfer\n",
1293 transfer->transfer->FragmentLength());
1294 // TODO actually resubmit the transfer
1295 }
1296
1297 // the transfer is done, but we already set the
1298 // actualLength with AdvanceByFragment()
1299 actualLength = 0;
1300 }
1301 }
1302
1303 transfer->transfer->Finished(callbackStatus, actualLength);
1304 fProcessingPipe = NULL;
1305 }
1306
1307 if (callbackStatus != B_OK) {
1308 // remove the transfer and make the head pointer valid again
1309 // (including clearing the halt state)
1310 _RemoveTransferFromEndpoint(transfer);
1311 }
1312
1313 // free the descriptors
1314 _FreeDescriptorChain(transfer->first_descriptor);
1315
1316 delete transfer->transfer;
1317 delete transfer;
1318 transfer = next;
1319 }
1320 }
1321 }
1322
1323
1324 bool
_FinishIsochronousTransfer(transfer_data * transfer,transfer_data ** _lastTransfer)1325 OHCI::_FinishIsochronousTransfer(transfer_data *transfer,
1326 transfer_data **_lastTransfer)
1327 {
1328 status_t callbackStatus = B_OK;
1329 size_t actualLength = 0;
1330 uint32 packet = 0;
1331
1332 if (transfer->canceled)
1333 callbackStatus = B_CANCELED;
1334 else {
1335 // at first check if ALL ITDs are retired by HC
1336 ohci_isochronous_td *descriptor
1337 = (ohci_isochronous_td *)transfer->first_descriptor;
1338 while (descriptor) {
1339 if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags)
1340 == OHCI_TD_CONDITION_NOT_ACCESSED) {
1341 TRACE("ITD %p still active\n", descriptor);
1342 *_lastTransfer = transfer;
1343 return false;
1344 }
1345
1346 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) {
1347 // this is the last ITD of the transfer
1348 descriptor = (ohci_isochronous_td *)transfer->first_descriptor;
1349 break;
1350 }
1351
1352 descriptor
1353 = (ohci_isochronous_td *)descriptor->next_done_descriptor;
1354 }
1355
1356 while (descriptor) {
1357 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
1358 if (status != OHCI_TD_CONDITION_NO_ERROR) {
1359 TRACE_ERROR("ITD error: 0x%08" B_PRIx32 "\n", status);
1360 // spec says that in most cases condition code
1361 // of retired ITDs is set to NoError, but for the
1362 // time overrun it can be DataOverrun. We assume
1363 // the _first_ occurience of such error as status
1364 // reported to the callback
1365 if (callbackStatus == B_OK)
1366 callbackStatus = _GetStatusOfConditionCode(status);
1367 }
1368
1369 usb_isochronous_data *isochronousData
1370 = transfer->transfer->IsochronousData();
1371
1372 uint32 frameCount = OHCI_ITD_GET_FRAME_COUNT(descriptor->flags);
1373 for (size_t i = 0; i < frameCount; i++, packet++) {
1374 usb_iso_packet_descriptor* packet_descriptor
1375 = &isochronousData->packet_descriptors[packet];
1376
1377 uint16 offset = descriptor->offset[OHCI_ITD_OFFSET_IDX(i)];
1378 uint8 code = OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset);
1379 packet_descriptor->status = _GetStatusOfConditionCode(code);
1380
1381 // not touched by HC - sheduled too late to be processed
1382 // in the requested frame - so we ignore it too
1383 if (packet_descriptor->status == B_DEV_TOO_LATE)
1384 continue;
1385
1386 size_t len = OHCI_ITD_GET_BUFFER_LENGTH(offset);
1387 if (!transfer->incoming)
1388 len = packet_descriptor->request_length - len;
1389
1390 packet_descriptor->actual_length = len;
1391 actualLength += len;
1392 }
1393
1394 uint16 frame = OHCI_ITD_GET_STARTING_FRAME(descriptor->flags);
1395 _ReleaseIsochronousBandwidth(frame,
1396 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags));
1397
1398 TRACE("ITD %p done\n", descriptor);
1399
1400 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor)
1401 break;
1402
1403 descriptor
1404 = (ohci_isochronous_td *)descriptor->next_done_descriptor;
1405 }
1406 }
1407
1408 // remove the transfer from the list first so we are sure
1409 // it doesn't get canceled while we still process it
1410 if (Lock()) {
1411 if (*_lastTransfer)
1412 (*_lastTransfer)->link = transfer->link;
1413
1414 if (transfer == fFirstTransfer)
1415 fFirstTransfer = transfer->link;
1416 if (transfer == fLastTransfer)
1417 fLastTransfer = *_lastTransfer;
1418
1419 // store the currently processing pipe here so we can wait
1420 // in cancel if we are processing something on the target pipe
1421 if (!transfer->canceled)
1422 fProcessingPipe = transfer->transfer->TransferPipe();
1423
1424 transfer->link = NULL;
1425 Unlock();
1426 }
1427
1428 // break the descriptor chain on the last descriptor
1429 transfer->last_descriptor->next_logical_descriptor = NULL;
1430 TRACE("iso.transfer %p done with status 0x%08" B_PRIx32 " len:%ld\n",
1431 transfer, callbackStatus, actualLength);
1432
1433 // if canceled the callback has already been called
1434 if (!transfer->canceled) {
1435 if (callbackStatus == B_OK && actualLength > 0) {
1436 if (transfer->data_descriptor && transfer->incoming) {
1437 // data to read out
1438 generic_io_vec *vector = transfer->transfer->Vector();
1439 size_t vectorCount = transfer->transfer->VectorCount();
1440
1441 transfer->transfer->PrepareKernelAccess();
1442 _ReadIsochronousDescriptorChain(
1443 (ohci_isochronous_td*)transfer->data_descriptor,
1444 vector, vectorCount, transfer->transfer->IsPhysical());
1445 }
1446 }
1447
1448 transfer->transfer->Finished(callbackStatus, actualLength);
1449 fProcessingPipe = NULL;
1450 }
1451
1452 _FreeIsochronousDescriptorChain(
1453 (ohci_isochronous_td*)transfer->first_descriptor);
1454
1455 return true;
1456 }
1457
1458
1459 status_t
_SubmitRequest(Transfer * transfer)1460 OHCI::_SubmitRequest(Transfer *transfer)
1461 {
1462 usb_request_data *requestData = transfer->RequestData();
1463 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0;
1464
1465 ohci_general_td *setupDescriptor
1466 = _CreateGeneralDescriptor(sizeof(usb_request_data));
1467 if (!setupDescriptor) {
1468 TRACE_ERROR("failed to allocate setup descriptor\n");
1469 return B_NO_MEMORY;
1470 }
1471
1472 setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP
1473 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1474 | OHCI_TD_TOGGLE_0
1475 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
1476
1477 ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0);
1478 if (!statusDescriptor) {
1479 TRACE_ERROR("failed to allocate status descriptor\n");
1480 _FreeGeneralDescriptor(setupDescriptor);
1481 return B_NO_MEMORY;
1482 }
1483
1484 statusDescriptor->flags
1485 = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN)
1486 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
1487 | OHCI_TD_TOGGLE_1
1488 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1489
1490 generic_io_vec vector;
1491 vector.base = (generic_addr_t)requestData;
1492 vector.length = sizeof(usb_request_data);
1493 _WriteDescriptorChain(setupDescriptor, &vector, 1, false);
1494
1495 status_t result;
1496 ohci_general_td *dataDescriptor = NULL;
1497 if (transfer->VectorCount() > 0) {
1498 ohci_general_td *lastDescriptor = NULL;
1499 result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor,
1500 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1501 transfer->FragmentLength());
1502 if (result < B_OK) {
1503 _FreeGeneralDescriptor(setupDescriptor);
1504 _FreeGeneralDescriptor(statusDescriptor);
1505 return result;
1506 }
1507
1508 if (!directionIn) {
1509 _WriteDescriptorChain(dataDescriptor, transfer->Vector(),
1510 transfer->VectorCount(), transfer->IsPhysical());
1511 }
1512
1513 _LinkDescriptors(setupDescriptor, dataDescriptor);
1514 _LinkDescriptors(lastDescriptor, statusDescriptor);
1515 } else {
1516 _LinkDescriptors(setupDescriptor, statusDescriptor);
1517 }
1518
1519 // Add to the transfer list
1520 ohci_endpoint_descriptor *endpoint
1521 = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie();
1522
1523 MutexLocker endpointLocker(endpoint->lock);
1524 result = _AddPendingTransfer(transfer, endpoint, setupDescriptor,
1525 dataDescriptor, statusDescriptor, directionIn);
1526 if (result < B_OK) {
1527 TRACE_ERROR("failed to add pending transfer\n");
1528 _FreeDescriptorChain(setupDescriptor);
1529 return result;
1530 }
1531
1532 // Add the descriptor chain to the endpoint
1533 _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor);
1534 endpointLocker.Unlock();
1535
1536 // Tell the controller to process the control list
1537 endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1538 _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED);
1539 return B_OK;
1540 }
1541
1542
1543 status_t
_SubmitTransfer(Transfer * transfer)1544 OHCI::_SubmitTransfer(Transfer *transfer)
1545 {
1546 Pipe *pipe = transfer->TransferPipe();
1547 bool directionIn = (pipe->Direction() == Pipe::In);
1548
1549 ohci_general_td *firstDescriptor = NULL;
1550 ohci_general_td *lastDescriptor = NULL;
1551 status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor,
1552 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
1553 transfer->FragmentLength());
1554
1555 if (result < B_OK)
1556 return result;
1557
1558 // Apply data toggle to the first descriptor (the others will use the carry)
1559 firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY;
1560 firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1
1561 : OHCI_TD_TOGGLE_0;
1562
1563 // Set the last descriptor to generate an interrupt
1564 lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK;
1565 lastDescriptor->flags |=
1566 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
1567
1568 if (!directionIn) {
1569 _WriteDescriptorChain(firstDescriptor, transfer->Vector(),
1570 transfer->VectorCount(), transfer->IsPhysical());
1571 }
1572
1573 // Add to the transfer list
1574 ohci_endpoint_descriptor *endpoint
1575 = (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1576
1577 MutexLocker endpointLocker(endpoint->lock);
1578
1579 // We do not support queuing other transfers in tandem with a fragmented one.
1580 transfer_data *it = fFirstTransfer;
1581 while (it) {
1582 if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) {
1583 TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
1584 _FreeDescriptorChain(firstDescriptor);
1585 return B_DEV_RESOURCE_CONFLICT;
1586 }
1587
1588 it = it->link;
1589 }
1590
1591 result = _AddPendingTransfer(transfer, endpoint, firstDescriptor,
1592 firstDescriptor, lastDescriptor, directionIn);
1593 if (result < B_OK) {
1594 TRACE_ERROR("failed to add pending transfer\n");
1595 _FreeDescriptorChain(firstDescriptor);
1596 return result;
1597 }
1598
1599 // Add the descriptor chain to the endpoint
1600 _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1601 endpointLocker.Unlock();
1602
1603 endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1604 if (pipe->Type() & USB_OBJECT_BULK_PIPE) {
1605 // Tell the controller to process the bulk list
1606 _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED);
1607 }
1608
1609 return B_OK;
1610 }
1611
1612
1613 status_t
_SubmitIsochronousTransfer(Transfer * transfer)1614 OHCI::_SubmitIsochronousTransfer(Transfer *transfer)
1615 {
1616 Pipe *pipe = transfer->TransferPipe();
1617 bool directionIn = (pipe->Direction() == Pipe::In);
1618
1619 ohci_isochronous_td *firstDescriptor = NULL;
1620 ohci_isochronous_td *lastDescriptor = NULL;
1621 status_t result = _CreateIsochronousDescriptorChain(&firstDescriptor,
1622 &lastDescriptor, transfer);
1623
1624 if (firstDescriptor == 0 || lastDescriptor == 0)
1625 return B_ERROR;
1626
1627 if (result < B_OK)
1628 return result;
1629
1630 // Set the last descriptor to generate an interrupt
1631 lastDescriptor->flags &= ~OHCI_ITD_INTERRUPT_MASK;
1632 // let the controller retire last ITD
1633 lastDescriptor->flags |= OHCI_ITD_SET_DELAY_INTERRUPT(1);
1634
1635 // If direction is out set every descriptor data
1636 if (pipe->Direction() == Pipe::Out)
1637 _WriteIsochronousDescriptorChain(firstDescriptor,
1638 transfer->Vector(), transfer->VectorCount(), transfer->IsPhysical());
1639
1640 // Add to the transfer list
1641 ohci_endpoint_descriptor *endpoint
1642 = (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1643
1644 MutexLocker endpointLocker(endpoint->lock);
1645 result = _AddPendingIsochronousTransfer(transfer, endpoint,
1646 firstDescriptor, lastDescriptor, directionIn);
1647 if (result < B_OK) {
1648 TRACE_ERROR("failed to add pending iso.transfer:"
1649 "0x%08" B_PRIx32 "\n", result);
1650 _FreeIsochronousDescriptorChain(firstDescriptor);
1651 return result;
1652 }
1653
1654 // Add the descriptor chain to the endpoint
1655 _SwitchIsochronousEndpointTail(endpoint, firstDescriptor, lastDescriptor);
1656 endpointLocker.Unlock();
1657
1658 endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
1659
1660 return B_OK;
1661 }
1662
1663
1664 void
_SwitchEndpointTail(ohci_endpoint_descriptor * endpoint,ohci_general_td * first,ohci_general_td * last)1665 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint,
1666 ohci_general_td *first, ohci_general_td *last)
1667 {
1668 // fill in the information of the first descriptor into the current tail
1669 ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor;
1670 tail->flags = first->flags;
1671 tail->buffer_physical = first->buffer_physical;
1672 tail->next_physical_descriptor = first->next_physical_descriptor;
1673 tail->last_physical_byte_address = first->last_physical_byte_address;
1674 tail->buffer_size = first->buffer_size;
1675 tail->buffer_logical = first->buffer_logical;
1676 tail->next_logical_descriptor = first->next_logical_descriptor;
1677
1678 // the first descriptor becomes the new tail
1679 first->flags = 0;
1680 first->buffer_physical = 0;
1681 first->next_physical_descriptor = 0;
1682 first->last_physical_byte_address = 0;
1683 first->buffer_size = 0;
1684 first->buffer_logical = NULL;
1685 first->next_logical_descriptor = NULL;
1686
1687 if (first == last)
1688 _LinkDescriptors(tail, first);
1689 else
1690 _LinkDescriptors(last, first);
1691
1692 // update the endpoint tail pointer to reflect the change
1693 endpoint->tail_logical_descriptor = first;
1694 endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1695 TRACE("switched tail from %p to %p\n", tail, first);
1696
1697 #if 0
1698 _PrintEndpoint(endpoint);
1699 _PrintDescriptorChain(tail);
1700 #endif
1701 }
1702
1703
1704 void
_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor * endpoint,ohci_isochronous_td * first,ohci_isochronous_td * last)1705 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor *endpoint,
1706 ohci_isochronous_td *first, ohci_isochronous_td *last)
1707 {
1708 // fill in the information of the first descriptor into the current tail
1709 ohci_isochronous_td *tail
1710 = (ohci_isochronous_td*)endpoint->tail_logical_descriptor;
1711 tail->flags = first->flags;
1712 tail->buffer_page_byte_0 = first->buffer_page_byte_0;
1713 tail->next_physical_descriptor = first->next_physical_descriptor;
1714 tail->last_byte_address = first->last_byte_address;
1715 tail->buffer_size = first->buffer_size;
1716 tail->buffer_logical = first->buffer_logical;
1717 tail->next_logical_descriptor = first->next_logical_descriptor;
1718 tail->next_done_descriptor = first->next_done_descriptor;
1719
1720 // the first descriptor becomes the new tail
1721 first->flags = 0;
1722 first->buffer_page_byte_0 = 0;
1723 first->next_physical_descriptor = 0;
1724 first->last_byte_address = 0;
1725 first->buffer_size = 0;
1726 first->buffer_logical = NULL;
1727 first->next_logical_descriptor = NULL;
1728 first->next_done_descriptor = NULL;
1729
1730 for (int i = 0; i < OHCI_ITD_NOFFSET; i++) {
1731 tail->offset[i] = first->offset[i];
1732 first->offset[i] = 0;
1733 }
1734
1735 if (first == last)
1736 _LinkIsochronousDescriptors(tail, first, NULL);
1737 else
1738 _LinkIsochronousDescriptors(last, first, NULL);
1739
1740 // update the endpoint tail pointer to reflect the change
1741 endpoint->tail_logical_descriptor = first;
1742 endpoint->tail_physical_descriptor = (uint32)first->physical_address;
1743 TRACE("switched tail from %p to %p\n", tail, first);
1744
1745 #if 0
1746 _PrintEndpoint(endpoint);
1747 _PrintDescriptorChain(tail);
1748 #endif
1749 }
1750
1751
1752 void
_RemoveTransferFromEndpoint(transfer_data * transfer)1753 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer)
1754 {
1755 // The transfer failed and the endpoint was halted. This means that the
1756 // endpoint head pointer might point somewhere into the descriptor chain
1757 // of this transfer. As we do not know if this transfer actually caused
1758 // the halt on the endpoint we have to make sure this is the case. If we
1759 // find the head to point to somewhere into the descriptor chain then
1760 // simply advancing the head pointer to the link of the last transfer
1761 // will bring the endpoint into a valid state again. This operation is
1762 // safe as the endpoint is currently halted and we therefore can change
1763 // the head pointer.
1764 ohci_endpoint_descriptor *endpoint = transfer->endpoint;
1765 ohci_general_td *descriptor = transfer->first_descriptor;
1766 while (descriptor) {
1767 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
1768 == descriptor->physical_address) {
1769 // This descriptor caused the halt. Advance the head pointer. This
1770 // will either move the head to the next valid transfer that can
1771 // then be restarted, or it will move the head to the tail when
1772 // there are no more transfer descriptors. Setting the head will
1773 // also clear the halt state as it is stored in the first bit of
1774 // the head pointer.
1775 endpoint->head_physical_descriptor
1776 = transfer->last_descriptor->next_physical_descriptor;
1777 return;
1778 }
1779
1780 descriptor = (ohci_general_td *)descriptor->next_logical_descriptor;
1781 }
1782 }
1783
1784
1785 ohci_endpoint_descriptor *
_AllocateEndpoint()1786 OHCI::_AllocateEndpoint()
1787 {
1788 ohci_endpoint_descriptor *endpoint;
1789 phys_addr_t physicalAddress;
1790
1791 mutex *lock = (mutex *)malloc(sizeof(mutex));
1792 if (lock == NULL) {
1793 TRACE_ERROR("no memory to allocate endpoint lock\n");
1794 return NULL;
1795 }
1796
1797 // Allocate memory chunk
1798 if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress,
1799 sizeof(ohci_endpoint_descriptor)) < B_OK) {
1800 TRACE_ERROR("failed to allocate endpoint descriptor\n");
1801 free(lock);
1802 return NULL;
1803 }
1804
1805 mutex_init(lock, "ohci endpoint lock");
1806
1807 endpoint->flags = OHCI_ENDPOINT_SKIP;
1808 endpoint->physical_address = (uint32)physicalAddress;
1809 endpoint->head_physical_descriptor = 0;
1810 endpoint->tail_logical_descriptor = NULL;
1811 endpoint->tail_physical_descriptor = 0;
1812 endpoint->next_logical_endpoint = NULL;
1813 endpoint->next_physical_endpoint = 0;
1814 endpoint->lock = lock;
1815 return endpoint;
1816 }
1817
1818
1819 void
_FreeEndpoint(ohci_endpoint_descriptor * endpoint)1820 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
1821 {
1822 if (!endpoint)
1823 return;
1824
1825 mutex_destroy(endpoint->lock);
1826 free(endpoint->lock);
1827
1828 fStack->FreeChunk((void *)endpoint, endpoint->physical_address,
1829 sizeof(ohci_endpoint_descriptor));
1830 }
1831
1832
1833 status_t
_InsertEndpointForPipe(Pipe * pipe)1834 OHCI::_InsertEndpointForPipe(Pipe *pipe)
1835 {
1836 TRACE("inserting endpoint for device %u endpoint %u\n",
1837 pipe->DeviceAddress(), pipe->EndpointAddress());
1838
1839 ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
1840 if (!endpoint) {
1841 TRACE_ERROR("cannot allocate memory for endpoint\n");
1842 return B_NO_MEMORY;
1843 }
1844
1845 uint32 flags = OHCI_ENDPOINT_SKIP;
1846
1847 // Set up device and endpoint address
1848 flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress())
1849 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress());
1850
1851 // Set the direction
1852 switch (pipe->Direction()) {
1853 case Pipe::In:
1854 flags |= OHCI_ENDPOINT_DIRECTION_IN;
1855 break;
1856
1857 case Pipe::Out:
1858 flags |= OHCI_ENDPOINT_DIRECTION_OUT;
1859 break;
1860
1861 case Pipe::Default:
1862 flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR;
1863 break;
1864
1865 default:
1866 TRACE_ERROR("direction unknown\n");
1867 _FreeEndpoint(endpoint);
1868 return B_ERROR;
1869 }
1870
1871 // Set up the speed
1872 switch (pipe->Speed()) {
1873 case USB_SPEED_LOWSPEED:
1874 flags |= OHCI_ENDPOINT_LOW_SPEED;
1875 break;
1876
1877 case USB_SPEED_FULLSPEED:
1878 flags |= OHCI_ENDPOINT_FULL_SPEED;
1879 break;
1880
1881 default:
1882 TRACE_ERROR("unacceptable speed\n");
1883 _FreeEndpoint(endpoint);
1884 return B_ERROR;
1885 }
1886
1887 // Set the maximum packet size
1888 flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize());
1889 endpoint->flags = flags;
1890
1891 // Add the endpoint to the appropriate list
1892 uint32 type = pipe->Type();
1893 ohci_endpoint_descriptor *head = NULL;
1894 if (type & USB_OBJECT_CONTROL_PIPE)
1895 head = fDummyControl;
1896 else if (type & USB_OBJECT_BULK_PIPE)
1897 head = fDummyBulk;
1898 else if (type & USB_OBJECT_INTERRUPT_PIPE)
1899 head = _FindInterruptEndpoint(pipe->Interval());
1900 else if (type & USB_OBJECT_ISO_PIPE)
1901 head = fDummyIsochronous;
1902 else
1903 TRACE_ERROR("unknown pipe type\n");
1904
1905 if (head == NULL) {
1906 TRACE_ERROR("no list found for endpoint\n");
1907 _FreeEndpoint(endpoint);
1908 return B_ERROR;
1909 }
1910
1911 // Create (necessary) tail descriptor
1912 if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
1913 // Set the isochronous bit format
1914 endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
1915 ohci_isochronous_td *tail = _CreateIsochronousDescriptor(0);
1916 tail->flags = 0;
1917 endpoint->tail_logical_descriptor = tail;
1918 endpoint->head_physical_descriptor = tail->physical_address;
1919 endpoint->tail_physical_descriptor = tail->physical_address;
1920 } else {
1921 ohci_general_td *tail = _CreateGeneralDescriptor(0);
1922 tail->flags = 0;
1923 endpoint->tail_logical_descriptor = tail;
1924 endpoint->head_physical_descriptor = tail->physical_address;
1925 endpoint->tail_physical_descriptor = tail->physical_address;
1926 }
1927
1928 if (!_LockEndpoints()) {
1929 if (endpoint->tail_logical_descriptor) {
1930 _FreeGeneralDescriptor(
1931 (ohci_general_td *)endpoint->tail_logical_descriptor);
1932 }
1933
1934 _FreeEndpoint(endpoint);
1935 return B_ERROR;
1936 }
1937
1938 pipe->SetControllerCookie((void *)endpoint);
1939 endpoint->next_logical_endpoint = head->next_logical_endpoint;
1940 endpoint->next_physical_endpoint = head->next_physical_endpoint;
1941 head->next_logical_endpoint = (void *)endpoint;
1942 head->next_physical_endpoint = (uint32)endpoint->physical_address;
1943
1944 _UnlockEndpoints();
1945 return B_OK;
1946 }
1947
1948
1949 status_t
_RemoveEndpointForPipe(Pipe * pipe)1950 OHCI::_RemoveEndpointForPipe(Pipe *pipe)
1951 {
1952 TRACE("removing endpoint for device %u endpoint %u\n",
1953 pipe->DeviceAddress(), pipe->EndpointAddress());
1954
1955 ohci_endpoint_descriptor *endpoint
1956 = (ohci_endpoint_descriptor *)pipe->ControllerCookie();
1957 if (endpoint == NULL)
1958 return B_OK;
1959
1960 // TODO implement properly, but at least disable it for now
1961 endpoint->flags |= OHCI_ENDPOINT_SKIP;
1962 return B_OK;
1963 }
1964
1965
1966 ohci_endpoint_descriptor *
_FindInterruptEndpoint(uint8 interval)1967 OHCI::_FindInterruptEndpoint(uint8 interval)
1968 {
1969 uint32 index = 0;
1970 uint32 power = 1;
1971 while (power <= OHCI_BIGGEST_INTERVAL / 2) {
1972 if (power * 2 > interval)
1973 break;
1974
1975 power *= 2;
1976 index++;
1977 }
1978
1979 return fInterruptEndpoints[index];
1980 }
1981
1982
1983 ohci_general_td *
_CreateGeneralDescriptor(size_t bufferSize)1984 OHCI::_CreateGeneralDescriptor(size_t bufferSize)
1985 {
1986 ohci_general_td *descriptor;
1987 phys_addr_t physicalAddress;
1988
1989 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
1990 sizeof(ohci_general_td)) != B_OK) {
1991 TRACE_ERROR("failed to allocate general descriptor\n");
1992 return NULL;
1993 }
1994
1995 descriptor->physical_address = (uint32)physicalAddress;
1996 descriptor->next_physical_descriptor = 0;
1997 descriptor->next_logical_descriptor = NULL;
1998 descriptor->buffer_size = bufferSize;
1999 if (bufferSize == 0) {
2000 descriptor->buffer_physical = 0;
2001 descriptor->buffer_logical = NULL;
2002 descriptor->last_physical_byte_address = 0;
2003 return descriptor;
2004 }
2005
2006 if (fStack->AllocateChunk(&descriptor->buffer_logical,
2007 &physicalAddress, bufferSize) != B_OK) {
2008 TRACE_ERROR("failed to allocate space for buffer\n");
2009 fStack->FreeChunk(descriptor, descriptor->physical_address,
2010 sizeof(ohci_general_td));
2011 return NULL;
2012 }
2013 descriptor->buffer_physical = physicalAddress;
2014
2015 descriptor->last_physical_byte_address
2016 = descriptor->buffer_physical + bufferSize - 1;
2017 return descriptor;
2018 }
2019
2020
2021 void
_FreeGeneralDescriptor(ohci_general_td * descriptor)2022 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor)
2023 {
2024 if (!descriptor)
2025 return;
2026
2027 if (descriptor->buffer_logical) {
2028 fStack->FreeChunk(descriptor->buffer_logical,
2029 descriptor->buffer_physical, descriptor->buffer_size);
2030 }
2031
2032 fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2033 sizeof(ohci_general_td));
2034 }
2035
2036
2037 status_t
_CreateDescriptorChain(ohci_general_td ** _firstDescriptor,ohci_general_td ** _lastDescriptor,uint32 direction,size_t bufferSize)2038 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
2039 ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize)
2040 {
2041 size_t blockSize = 8192;
2042 int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize;
2043 if (descriptorCount == 0)
2044 descriptorCount = 1;
2045
2046 ohci_general_td *firstDescriptor = NULL;
2047 ohci_general_td *lastDescriptor = *_firstDescriptor;
2048 for (int32 i = 0; i < descriptorCount; i++) {
2049 ohci_general_td *descriptor = _CreateGeneralDescriptor(
2050 min_c(blockSize, bufferSize));
2051
2052 if (!descriptor) {
2053 _FreeDescriptorChain(firstDescriptor);
2054 return B_NO_MEMORY;
2055 }
2056
2057 descriptor->flags = direction
2058 | OHCI_TD_BUFFER_ROUNDING
2059 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
2060 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE)
2061 | OHCI_TD_TOGGLE_CARRY;
2062
2063 // link to previous
2064 if (lastDescriptor)
2065 _LinkDescriptors(lastDescriptor, descriptor);
2066
2067 bufferSize -= blockSize;
2068 lastDescriptor = descriptor;
2069 if (!firstDescriptor)
2070 firstDescriptor = descriptor;
2071 }
2072
2073 *_firstDescriptor = firstDescriptor;
2074 *_lastDescriptor = lastDescriptor;
2075 return B_OK;
2076 }
2077
2078
2079 void
_FreeDescriptorChain(ohci_general_td * topDescriptor)2080 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor)
2081 {
2082 ohci_general_td *current = topDescriptor;
2083 ohci_general_td *next = NULL;
2084
2085 while (current) {
2086 next = (ohci_general_td *)current->next_logical_descriptor;
2087 _FreeGeneralDescriptor(current);
2088 current = next;
2089 }
2090 }
2091
2092
2093 ohci_isochronous_td *
_CreateIsochronousDescriptor(size_t bufferSize)2094 OHCI::_CreateIsochronousDescriptor(size_t bufferSize)
2095 {
2096 ohci_isochronous_td *descriptor = NULL;
2097 phys_addr_t physicalAddress;
2098
2099 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
2100 sizeof(ohci_isochronous_td)) != B_OK) {
2101 TRACE_ERROR("failed to allocate isochronous descriptor\n");
2102 return NULL;
2103 }
2104
2105 descriptor->physical_address = (uint32)physicalAddress;
2106 descriptor->next_physical_descriptor = 0;
2107 descriptor->next_logical_descriptor = NULL;
2108 descriptor->next_done_descriptor = NULL;
2109 descriptor->buffer_size = bufferSize;
2110 if (bufferSize == 0) {
2111 descriptor->buffer_page_byte_0 = 0;
2112 descriptor->buffer_logical = NULL;
2113 descriptor->last_byte_address = 0;
2114 return descriptor;
2115 }
2116
2117 if (fStack->AllocateChunk(&descriptor->buffer_logical,
2118 &physicalAddress, bufferSize) != B_OK) {
2119 TRACE_ERROR("failed to allocate space for iso.buffer\n");
2120 fStack->FreeChunk(descriptor, descriptor->physical_address,
2121 sizeof(ohci_isochronous_td));
2122 return NULL;
2123 }
2124 descriptor->buffer_page_byte_0 = (uint32)physicalAddress;
2125 descriptor->last_byte_address
2126 = descriptor->buffer_page_byte_0 + bufferSize - 1;
2127
2128 return descriptor;
2129 }
2130
2131
2132 void
_FreeIsochronousDescriptor(ohci_isochronous_td * descriptor)2133 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor)
2134 {
2135 if (!descriptor)
2136 return;
2137
2138 if (descriptor->buffer_logical) {
2139 fStack->FreeChunk(descriptor->buffer_logical,
2140 descriptor->buffer_page_byte_0, descriptor->buffer_size);
2141 }
2142
2143 fStack->FreeChunk((void *)descriptor, descriptor->physical_address,
2144 sizeof(ohci_general_td));
2145 }
2146
2147
2148 status_t
_CreateIsochronousDescriptorChain(ohci_isochronous_td ** _firstDescriptor,ohci_isochronous_td ** _lastDescriptor,Transfer * transfer)2149 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor,
2150 ohci_isochronous_td **_lastDescriptor, Transfer *transfer)
2151 {
2152 Pipe *pipe = transfer->TransferPipe();
2153 usb_isochronous_data *isochronousData = transfer->IsochronousData();
2154
2155 size_t dataLength = transfer->FragmentLength();
2156 size_t packet_count = isochronousData->packet_count;
2157
2158 if (packet_count == 0) {
2159 TRACE_ERROR("isochronous packet_count should not be equal to zero.");
2160 return B_BAD_VALUE;
2161 }
2162
2163 size_t packetSize = dataLength / packet_count;
2164 if (dataLength % packet_count != 0)
2165 packetSize++;
2166
2167 if (packetSize > pipe->MaxPacketSize()) {
2168 TRACE_ERROR("isochronous packetSize %ld is bigger"
2169 " than pipe MaxPacketSize %ld.", packetSize, pipe->MaxPacketSize());
2170 return B_BAD_VALUE;
2171 }
2172
2173 uint16 bandwidth = transfer->Bandwidth() / packet_count;
2174 if (transfer->Bandwidth() % packet_count != 0)
2175 bandwidth++;
2176
2177 ohci_isochronous_td *firstDescriptor = NULL;
2178 ohci_isochronous_td *lastDescriptor = *_firstDescriptor;
2179
2180 // the frame number currently processed by the host controller
2181 uint16 currentFrame = fHcca->current_frame_number & 0xFFFF;
2182 uint16 safeFrames = 5;
2183
2184 // The entry where to start inserting the first Isochronous descriptor
2185 // real frame number may differ in case provided one has not bandwidth
2186 if (isochronousData->flags & USB_ISO_ASAP ||
2187 isochronousData->starting_frame_number == NULL)
2188 // We should stay about 5-10 ms ahead of the controller
2189 // USB1 frame is equal to 1 ms
2190 currentFrame += safeFrames;
2191 else
2192 currentFrame = *isochronousData->starting_frame_number;
2193
2194 uint16 packets = packet_count;
2195 uint16 frameOffset = 0;
2196 while (packets > 0) {
2197 // look for up to 8 continous frames with available bandwidth
2198 uint16 frameCount = 0;
2199 while (frameCount < min_c(OHCI_ITD_NOFFSET, packets)
2200 && _AllocateIsochronousBandwidth(frameOffset + currentFrame
2201 + frameCount, bandwidth))
2202 frameCount++;
2203
2204 if (frameCount == 0) {
2205 // starting frame has no bandwidth for our transaction - try next
2206 if (++frameOffset >= 0xFFFF) {
2207 TRACE_ERROR("failed to allocate bandwidth\n");
2208 _FreeIsochronousDescriptorChain(firstDescriptor);
2209 return B_NO_MEMORY;
2210 }
2211 continue;
2212 }
2213
2214 ohci_isochronous_td *descriptor = _CreateIsochronousDescriptor(
2215 packetSize * frameCount);
2216
2217 if (!descriptor) {
2218 TRACE_ERROR("failed to allocate ITD\n");
2219 _ReleaseIsochronousBandwidth(currentFrame + frameOffset, frameCount);
2220 _FreeIsochronousDescriptorChain(firstDescriptor);
2221 return B_NO_MEMORY;
2222 }
2223
2224 uint16 pageOffset = descriptor->buffer_page_byte_0 & 0xfff;
2225 descriptor->buffer_page_byte_0 &= ~0xfff;
2226 for (uint16 i = 0; i < frameCount; i++) {
2227 descriptor->offset[OHCI_ITD_OFFSET_IDX(i)]
2228 = OHCI_ITD_MK_OFFS(pageOffset + packetSize * i);
2229 }
2230
2231 descriptor->flags = OHCI_ITD_SET_FRAME_COUNT(frameCount)
2232 | OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED)
2233 | OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE)
2234 | OHCI_ITD_SET_STARTING_FRAME(currentFrame + frameOffset);
2235
2236 // the last packet may be shorter than other ones in this transfer
2237 if (packets <= OHCI_ITD_NOFFSET)
2238 descriptor->last_byte_address
2239 += dataLength - packetSize * (packet_count);
2240
2241 // link to previous
2242 if (lastDescriptor)
2243 _LinkIsochronousDescriptors(lastDescriptor, descriptor, descriptor);
2244
2245 lastDescriptor = descriptor;
2246 if (!firstDescriptor)
2247 firstDescriptor = descriptor;
2248
2249 packets -= frameCount;
2250
2251 frameOffset += frameCount;
2252
2253 if (packets == 0 && isochronousData->starting_frame_number)
2254 *isochronousData->starting_frame_number = currentFrame + frameOffset;
2255 }
2256
2257 *_firstDescriptor = firstDescriptor;
2258 *_lastDescriptor = lastDescriptor;
2259
2260 return B_OK;
2261 }
2262
2263
2264 void
_FreeIsochronousDescriptorChain(ohci_isochronous_td * topDescriptor)2265 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor)
2266 {
2267 ohci_isochronous_td *current = topDescriptor;
2268 ohci_isochronous_td *next = NULL;
2269
2270 while (current) {
2271 next = (ohci_isochronous_td *)current->next_done_descriptor;
2272 _FreeIsochronousDescriptor(current);
2273 current = next;
2274 }
2275 }
2276
2277
2278 size_t
_WriteDescriptorChain(ohci_general_td * topDescriptor,generic_io_vec * vector,size_t vectorCount,bool physical)2279 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector,
2280 size_t vectorCount, bool physical)
2281 {
2282 ohci_general_td *current = topDescriptor;
2283 size_t actualLength = 0;
2284 size_t vectorIndex = 0;
2285 size_t vectorOffset = 0;
2286 size_t bufferOffset = 0;
2287
2288 while (current) {
2289 if (!current->buffer_logical)
2290 break;
2291
2292 while (true) {
2293 size_t length = min_c(current->buffer_size - bufferOffset,
2294 vector[vectorIndex].length - vectorOffset);
2295
2296 TRACE("copying %ld bytes to bufferOffset %ld from"
2297 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
2298 vectorOffset, vectorIndex, vectorCount);
2299 status_t status = generic_memcpy(
2300 (generic_addr_t)current->buffer_logical + bufferOffset, false,
2301 vector[vectorIndex].base + vectorOffset, physical, length);
2302 ASSERT_ALWAYS(status == B_OK);
2303
2304 actualLength += length;
2305 vectorOffset += length;
2306 bufferOffset += length;
2307
2308 if (vectorOffset >= vector[vectorIndex].length) {
2309 if (++vectorIndex >= vectorCount) {
2310 TRACE("wrote descriptor chain (%ld bytes, no"
2311 " more vectors)\n", actualLength);
2312 return actualLength;
2313 }
2314
2315 vectorOffset = 0;
2316 }
2317
2318 if (bufferOffset >= current->buffer_size) {
2319 bufferOffset = 0;
2320 break;
2321 }
2322 }
2323
2324 if (!current->next_logical_descriptor)
2325 break;
2326
2327 current = (ohci_general_td *)current->next_logical_descriptor;
2328 }
2329
2330 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
2331 return actualLength;
2332 }
2333
2334
2335 size_t
_WriteIsochronousDescriptorChain(ohci_isochronous_td * topDescriptor,generic_io_vec * vector,size_t vectorCount,bool physical)2336 OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor,
2337 generic_io_vec *vector, size_t vectorCount, bool physical)
2338 {
2339 ohci_isochronous_td *current = topDescriptor;
2340 size_t actualLength = 0;
2341 size_t vectorIndex = 0;
2342 size_t vectorOffset = 0;
2343 size_t bufferOffset = 0;
2344
2345 while (current) {
2346 if (!current->buffer_logical)
2347 break;
2348
2349 while (true) {
2350 size_t length = min_c(current->buffer_size - bufferOffset,
2351 vector[vectorIndex].length - vectorOffset);
2352
2353 TRACE("copying %ld bytes to bufferOffset %ld from"
2354 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset,
2355 vectorOffset, vectorIndex, vectorCount);
2356 status_t status = generic_memcpy(
2357 (generic_addr_t)current->buffer_logical + bufferOffset, false,
2358 vector[vectorIndex].base + vectorOffset, physical, length);
2359 ASSERT_ALWAYS(status == B_OK);
2360
2361 actualLength += length;
2362 vectorOffset += length;
2363 bufferOffset += length;
2364
2365 if (vectorOffset >= vector[vectorIndex].length) {
2366 if (++vectorIndex >= vectorCount) {
2367 TRACE("wrote descriptor chain (%ld bytes, no"
2368 " more vectors)\n", actualLength);
2369 return actualLength;
2370 }
2371
2372 vectorOffset = 0;
2373 }
2374
2375 if (bufferOffset >= current->buffer_size) {
2376 bufferOffset = 0;
2377 break;
2378 }
2379 }
2380
2381 if (!current->next_logical_descriptor)
2382 break;
2383
2384 current = (ohci_isochronous_td *)current->next_logical_descriptor;
2385 }
2386
2387 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength);
2388 return actualLength;
2389 }
2390
2391
2392 size_t
_ReadDescriptorChain(ohci_general_td * topDescriptor,generic_io_vec * vector,size_t vectorCount,bool physical)2393 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector,
2394 size_t vectorCount, bool physical)
2395 {
2396 ohci_general_td *current = topDescriptor;
2397 size_t actualLength = 0;
2398 size_t vectorIndex = 0;
2399 size_t vectorOffset = 0;
2400 size_t bufferOffset = 0;
2401
2402 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2403 != OHCI_TD_CONDITION_NOT_ACCESSED) {
2404 if (!current->buffer_logical)
2405 break;
2406
2407 size_t bufferSize = current->buffer_size;
2408 if (current->buffer_physical != 0) {
2409 bufferSize -= current->last_physical_byte_address
2410 - current->buffer_physical + 1;
2411 }
2412
2413 while (true) {
2414 size_t length = min_c(bufferSize - bufferOffset,
2415 vector[vectorIndex].length - vectorOffset);
2416
2417 TRACE("copying %ld bytes to vectorOffset %ld from"
2418 " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset,
2419 bufferOffset, vectorIndex, vectorCount);
2420 status_t status = generic_memcpy(
2421 vector[vectorIndex].base + vectorOffset, physical,
2422 (generic_addr_t)current->buffer_logical + bufferOffset, false, length);
2423 ASSERT_ALWAYS(status == B_OK);
2424
2425 actualLength += length;
2426 vectorOffset += length;
2427 bufferOffset += length;
2428
2429 if (vectorOffset >= vector[vectorIndex].length) {
2430 if (++vectorIndex >= vectorCount) {
2431 TRACE("read descriptor chain (%ld bytes, no more vectors)\n",
2432 actualLength);
2433 return actualLength;
2434 }
2435
2436 vectorOffset = 0;
2437 }
2438
2439 if (bufferOffset >= bufferSize) {
2440 bufferOffset = 0;
2441 break;
2442 }
2443 }
2444
2445 current = (ohci_general_td *)current->next_logical_descriptor;
2446 }
2447
2448 TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2449 return actualLength;
2450 }
2451
2452
2453 void
_ReadIsochronousDescriptorChain(ohci_isochronous_td * topDescriptor,generic_io_vec * vector,size_t vectorCount,bool physical)2454 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor,
2455 generic_io_vec *vector, size_t vectorCount, bool physical)
2456 {
2457 ohci_isochronous_td *current = topDescriptor;
2458 size_t actualLength = 0;
2459 size_t vectorIndex = 0;
2460 size_t vectorOffset = 0;
2461 size_t bufferOffset = 0;
2462
2463 while (current && OHCI_ITD_GET_CONDITION_CODE(current->flags)
2464 != OHCI_ITD_CONDITION_NOT_ACCESSED) {
2465 size_t bufferSize = current->buffer_size;
2466 if (current->buffer_logical != NULL && bufferSize > 0) {
2467 while (true) {
2468 size_t length = min_c(bufferSize - bufferOffset,
2469 vector[vectorIndex].length - vectorOffset);
2470
2471 TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset"
2472 " %ld at index %ld of %ld\n", length, vectorOffset,
2473 bufferOffset, vectorIndex, vectorCount);
2474 status_t status = generic_memcpy(
2475 vector[vectorIndex].base + vectorOffset, physical,
2476 (generic_addr_t)current->buffer_logical + bufferOffset, false, length);
2477 ASSERT_ALWAYS(status == B_OK);
2478
2479 actualLength += length;
2480 vectorOffset += length;
2481 bufferOffset += length;
2482
2483 if (vectorOffset >= vector[vectorIndex].length) {
2484 if (++vectorIndex >= vectorCount) {
2485 TRACE("read descriptor chain (%ld bytes, "
2486 "no more vectors)\n", actualLength);
2487 return;
2488 }
2489
2490 vectorOffset = 0;
2491 }
2492
2493 if (bufferOffset >= bufferSize) {
2494 bufferOffset = 0;
2495 break;
2496 }
2497 }
2498 }
2499
2500 current = (ohci_isochronous_td *)current->next_done_descriptor;
2501 }
2502
2503 TRACE("read descriptor chain (%ld bytes)\n", actualLength);
2504 return;
2505 }
2506
2507
2508 size_t
_ReadActualLength(ohci_general_td * topDescriptor)2509 OHCI::_ReadActualLength(ohci_general_td *topDescriptor)
2510 {
2511 ohci_general_td *current = topDescriptor;
2512 size_t actualLength = 0;
2513
2514 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags)
2515 != OHCI_TD_CONDITION_NOT_ACCESSED) {
2516 size_t length = current->buffer_size;
2517 if (current->buffer_physical != 0) {
2518 length -= current->last_physical_byte_address
2519 - current->buffer_physical + 1;
2520 }
2521
2522 actualLength += length;
2523 current = (ohci_general_td *)current->next_logical_descriptor;
2524 }
2525
2526 TRACE("read actual length (%ld bytes)\n", actualLength);
2527 return actualLength;
2528 }
2529
2530
2531 void
_LinkDescriptors(ohci_general_td * first,ohci_general_td * second)2532 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second)
2533 {
2534 first->next_physical_descriptor = second->physical_address;
2535 first->next_logical_descriptor = second;
2536 }
2537
2538
2539 void
_LinkIsochronousDescriptors(ohci_isochronous_td * first,ohci_isochronous_td * second,ohci_isochronous_td * nextDone)2540 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td *first,
2541 ohci_isochronous_td *second, ohci_isochronous_td *nextDone)
2542 {
2543 first->next_physical_descriptor = second->physical_address;
2544 first->next_logical_descriptor = second;
2545 first->next_done_descriptor = nextDone;
2546 }
2547
2548
2549 bool
_AllocateIsochronousBandwidth(uint16 frame,uint16 size)2550 OHCI::_AllocateIsochronousBandwidth(uint16 frame, uint16 size)
2551 {
2552 frame %= NUMBER_OF_FRAMES;
2553 if (size > fFrameBandwidth[frame])
2554 return false;
2555
2556 fFrameBandwidth[frame]-= size;
2557 return true;
2558 }
2559
2560
2561 void
_ReleaseIsochronousBandwidth(uint16 startFrame,uint16 frameCount)2562 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame, uint16 frameCount)
2563 {
2564 for (size_t index = 0; index < frameCount; index++) {
2565 uint16 frame = (startFrame + index) % NUMBER_OF_FRAMES;
2566 fFrameBandwidth[frame] = MAX_AVAILABLE_BANDWIDTH;
2567 }
2568 }
2569
2570
2571 status_t
_GetStatusOfConditionCode(uint8 conditionCode)2572 OHCI::_GetStatusOfConditionCode(uint8 conditionCode)
2573 {
2574 switch (conditionCode) {
2575 case OHCI_TD_CONDITION_NO_ERROR:
2576 return B_OK;
2577
2578 case OHCI_TD_CONDITION_CRC_ERROR:
2579 case OHCI_TD_CONDITION_BIT_STUFFING:
2580 case OHCI_TD_CONDITION_TOGGLE_MISMATCH:
2581 return B_DEV_CRC_ERROR;
2582
2583 case OHCI_TD_CONDITION_STALL:
2584 return B_DEV_STALLED;
2585
2586 case OHCI_TD_CONDITION_NO_RESPONSE:
2587 return B_TIMED_OUT;
2588
2589 case OHCI_TD_CONDITION_PID_CHECK_FAILURE:
2590 return B_DEV_BAD_PID;
2591
2592 case OHCI_TD_CONDITION_UNEXPECTED_PID:
2593 return B_DEV_UNEXPECTED_PID;
2594
2595 case OHCI_TD_CONDITION_DATA_OVERRUN:
2596 return B_DEV_DATA_OVERRUN;
2597
2598 case OHCI_TD_CONDITION_DATA_UNDERRUN:
2599 return B_DEV_DATA_UNDERRUN;
2600
2601 case OHCI_TD_CONDITION_BUFFER_OVERRUN:
2602 return B_DEV_WRITE_ERROR;
2603
2604 case OHCI_TD_CONDITION_BUFFER_UNDERRUN:
2605 return B_DEV_READ_ERROR;
2606
2607 case OHCI_TD_CONDITION_NOT_ACCESSED:
2608 return B_DEV_PENDING;
2609
2610 case 0x0E:
2611 return B_DEV_TOO_LATE; // PSW: _NOT_ACCESSED
2612
2613 default:
2614 break;
2615 }
2616
2617 return B_ERROR;
2618 }
2619
2620
2621 bool
_LockEndpoints()2622 OHCI::_LockEndpoints()
2623 {
2624 return (mutex_lock(&fEndpointLock) == B_OK);
2625 }
2626
2627
2628 void
_UnlockEndpoints()2629 OHCI::_UnlockEndpoints()
2630 {
2631 mutex_unlock(&fEndpointLock);
2632 }
2633
2634
2635 inline void
_WriteReg(uint32 reg,uint32 value)2636 OHCI::_WriteReg(uint32 reg, uint32 value)
2637 {
2638 *(volatile uint32 *)(fOperationalRegisters + reg) = value;
2639 }
2640
2641
2642 inline uint32
_ReadReg(uint32 reg)2643 OHCI::_ReadReg(uint32 reg)
2644 {
2645 return *(volatile uint32 *)(fOperationalRegisters + reg);
2646 }
2647
2648
2649 void
_PrintEndpoint(ohci_endpoint_descriptor * endpoint)2650 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint)
2651 {
2652 dprintf("endpoint %p\n", endpoint);
2653 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags);
2654 dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor);
2655 dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor);
2656 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint);
2657 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address);
2658 dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor);
2659 dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint);
2660 }
2661
2662
2663 void
_PrintDescriptorChain(ohci_general_td * topDescriptor)2664 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor)
2665 {
2666 while (topDescriptor) {
2667 dprintf("descriptor %p\n", topDescriptor);
2668 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2669 dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical);
2670 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2671 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address);
2672 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2673 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2674 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2675 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2676
2677 topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor;
2678 }
2679 }
2680
2681
2682 void
_PrintDescriptorChain(ohci_isochronous_td * topDescriptor)2683 OHCI::_PrintDescriptorChain(ohci_isochronous_td *topDescriptor)
2684 {
2685 while (topDescriptor) {
2686 dprintf("iso.descriptor %p\n", topDescriptor);
2687 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags);
2688 dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32 "\n", topDescriptor->buffer_page_byte_0);
2689 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor);
2690 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_byte_address);
2691 dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n"
2692 "\t0x%04x 0x%04x 0x%04x 0x%04x\n",
2693 topDescriptor->offset[0], topDescriptor->offset[1],
2694 topDescriptor->offset[2], topDescriptor->offset[3],
2695 topDescriptor->offset[4], topDescriptor->offset[5],
2696 topDescriptor->offset[6], topDescriptor->offset[7]);
2697 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address);
2698 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size);
2699 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical);
2700 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor);
2701 dprintf("\tnext_done....... %p\n", topDescriptor->next_done_descriptor);
2702
2703 topDescriptor = (ohci_isochronous_td *)topDescriptor->next_done_descriptor;
2704 }
2705 }
2706
2707