2 * Copyright 2005-2013, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 * Salvatore Benedetto <salvatore.benedetto@gmail.com>
8 * Michael Lotz <mmlr@mlotz.ch>
9 * Siarzhuk Zharski <imker@gmx.li>
16 #include <KernelExport.h>
17 #include <util/AutoLock.h>
21 #define USB_MODULE_NAME "ohci"
23 pci_module_info
*OHCI::sPCIModule
= NULL
;
24 pci_x86_module_info
*OHCI::sPCIx86Module
= NULL
;
28 ohci_std_ops(int32 op
, ...)
32 TRACE_MODULE("init module\n");
35 TRACE_MODULE("uninit module\n");
43 usb_host_controller_info ohci_module
= {
54 module_info
*modules
[] = {
55 (module_info
*)&ohci_module
,
60 OHCI::OHCI(pci_info
*info
, Stack
*stack
)
64 fOperationalRegisters(NULL
),
68 fInterruptEndpoints(NULL
),
71 fDummyIsochronous(NULL
),
74 fFinishTransfersSem(-1),
76 fStopFinishThread(false),
77 fProcessingPipe(NULL
),
78 fFrameBandwidth(NULL
),
86 TRACE_ERROR("bus manager failed to init\n");
90 TRACE("constructing new OHCI host controller driver\n");
93 mutex_init(&fEndpointLock
, "ohci endpoint lock");
95 // enable busmaster and memory mapped access
96 uint16 command
= sPCIModule
->read_pci_config(fPCIInfo
->bus
,
97 fPCIInfo
->device
, fPCIInfo
->function
, PCI_command
, 2);
98 command
&= ~PCI_command_io
;
99 command
|= PCI_command_master
| PCI_command_memory
;
101 sPCIModule
->write_pci_config(fPCIInfo
->bus
, fPCIInfo
->device
,
102 fPCIInfo
->function
, PCI_command
, 2, command
);
105 uint32 offset
= sPCIModule
->read_pci_config(fPCIInfo
->bus
,
106 fPCIInfo
->device
, fPCIInfo
->function
, PCI_base_registers
, 4);
107 offset
&= PCI_address_memory_32_mask
;
108 TRACE_ALWAYS("iospace offset: 0x%" B_PRIx32
"\n", offset
);
109 fRegisterArea
= map_physical_memory("OHCI memory mapped registers",
110 offset
, B_PAGE_SIZE
, B_ANY_KERNEL_BLOCK_ADDRESS
,
111 B_KERNEL_READ_AREA
| B_KERNEL_WRITE_AREA
| B_READ_AREA
| B_WRITE_AREA
,
112 (void **)&fOperationalRegisters
);
113 if (fRegisterArea
< B_OK
) {
114 TRACE_ERROR("failed to map register memory\n");
118 TRACE("mapped operational registers: %p\n", fOperationalRegisters
);
120 // Check the revision of the controller, which should be 10h
121 uint32 revision
= _ReadReg(OHCI_REVISION
) & 0xff;
122 TRACE("version %" B_PRId32
".%" B_PRId32
"%s\n",
123 OHCI_REVISION_HIGH(revision
), OHCI_REVISION_LOW(revision
),
124 OHCI_REVISION_LEGACY(revision
) ? ", legacy support" : "");
126 if (OHCI_REVISION_HIGH(revision
) != 1 || OHCI_REVISION_LOW(revision
) != 0) {
127 TRACE_ERROR("unsupported OHCI revision\n");
131 phys_addr_t hccaPhysicalAddress
;
132 fHccaArea
= fStack
->AllocateArea((void **)&fHcca
, &hccaPhysicalAddress
,
133 sizeof(ohci_hcca
), "USB OHCI Host Controller Communication Area");
135 if (fHccaArea
< B_OK
) {
136 TRACE_ERROR("unable to create the HCCA block area\n");
140 memset(fHcca
, 0, sizeof(ohci_hcca
));
142 // Set Up Host controller
144 fDummyControl
= _AllocateEndpoint();
148 fDummyBulk
= _AllocateEndpoint();
150 _FreeEndpoint(fDummyControl
);
154 fDummyIsochronous
= _AllocateEndpoint();
155 if (!fDummyIsochronous
) {
156 _FreeEndpoint(fDummyControl
);
157 _FreeEndpoint(fDummyBulk
);
161 // Static endpoints that get linked in the HCCA
162 fInterruptEndpoints
= new(std::nothrow
)
163 ohci_endpoint_descriptor
*[OHCI_STATIC_ENDPOINT_COUNT
];
164 if (!fInterruptEndpoints
) {
165 TRACE_ERROR("failed to allocate memory for interrupt endpoints\n");
166 _FreeEndpoint(fDummyControl
);
167 _FreeEndpoint(fDummyBulk
);
168 _FreeEndpoint(fDummyIsochronous
);
172 for (int32 i
= 0; i
< OHCI_STATIC_ENDPOINT_COUNT
; i
++) {
173 fInterruptEndpoints
[i
] = _AllocateEndpoint();
174 if (!fInterruptEndpoints
[i
]) {
175 TRACE_ERROR("failed to allocate interrupt endpoint %" B_PRId32
"\n",
178 _FreeEndpoint(fInterruptEndpoints
[i
]);
179 _FreeEndpoint(fDummyBulk
);
180 _FreeEndpoint(fDummyControl
);
181 _FreeEndpoint(fDummyIsochronous
);
186 // build flat tree so that at each of the static interrupt endpoints
187 // fInterruptEndpoints[i] == interrupt endpoint for interval 2^i
188 uint32 interval
= OHCI_BIGGEST_INTERVAL
;
189 uint32 intervalIndex
= OHCI_STATIC_ENDPOINT_COUNT
- 1;
190 while (interval
> 1) {
191 uint32 insertIndex
= interval
/ 2;
192 while (insertIndex
< OHCI_BIGGEST_INTERVAL
) {
193 fHcca
->interrupt_table
[insertIndex
]
194 = fInterruptEndpoints
[intervalIndex
]->physical_address
;
195 insertIndex
+= interval
;
202 // setup the empty slot in the list and linking of all -> first
203 fHcca
->interrupt_table
[0] = fInterruptEndpoints
[0]->physical_address
;
204 for (int32 i
= 1; i
< OHCI_STATIC_ENDPOINT_COUNT
; i
++) {
205 fInterruptEndpoints
[i
]->next_physical_endpoint
206 = fInterruptEndpoints
[0]->physical_address
;
207 fInterruptEndpoints
[i
]->next_logical_endpoint
208 = fInterruptEndpoints
[0];
211 // Now link the first endpoint to the isochronous endpoint
212 fInterruptEndpoints
[0]->next_physical_endpoint
213 = fDummyIsochronous
->physical_address
;
215 // When the handover from SMM takes place, all interrupts are routed to the
216 // OS. As we don't yet have an interrupt handler installed at this point,
217 // this may cause interrupt storms if the firmware does not disable the
218 // interrupts during handover. Therefore we disable interrupts before
219 // requesting ownership. We have to keep the ownership change interrupt
220 // enabled though, as otherwise the SMM will not be notified of the
221 // ownership change request we trigger below.
222 _WriteReg(OHCI_INTERRUPT_DISABLE
, OHCI_ALL_INTERRUPTS
&
223 ~OHCI_OWNERSHIP_CHANGE
) ;
225 // Determine in what context we are running (Kindly copied from FreeBSD)
226 uint32 control
= _ReadReg(OHCI_CONTROL
);
227 if (control
& OHCI_INTERRUPT_ROUTING
) {
228 TRACE_ALWAYS("smm is in control of the host controller\n");
229 uint32 status
= _ReadReg(OHCI_COMMAND_STATUS
);
230 _WriteReg(OHCI_COMMAND_STATUS
, status
| OHCI_OWNERSHIP_CHANGE_REQUEST
);
231 for (uint32 i
= 0; i
< 100 && (control
& OHCI_INTERRUPT_ROUTING
); i
++) {
233 control
= _ReadReg(OHCI_CONTROL
);
236 if ((control
& OHCI_INTERRUPT_ROUTING
) != 0) {
237 TRACE_ERROR("smm does not respond.\n");
239 // TODO: Enable this reset as soon as the non-specified
240 // reset a few lines later is replaced by a better solution.
241 //_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
242 //snooze(USB_DELAY_BUS_RESET);
244 TRACE_ALWAYS("ownership change successful\n");
246 TRACE("cold started\n");
247 snooze(USB_DELAY_BUS_RESET
);
250 // TODO: This reset delays system boot time. It should not be necessary
251 // according to the OHCI spec, but without it some controllers don't start.
252 _WriteReg(OHCI_CONTROL
, OHCI_HC_FUNCTIONAL_STATE_RESET
);
253 snooze(USB_DELAY_BUS_RESET
);
255 // We now own the host controller and the bus has been reset
256 uint32 frameInterval
= _ReadReg(OHCI_FRAME_INTERVAL
);
257 uint32 intervalValue
= OHCI_GET_INTERVAL_VALUE(frameInterval
);
259 _WriteReg(OHCI_COMMAND_STATUS
, OHCI_HOST_CONTROLLER_RESET
);
260 // Nominal time for a reset is 10 us
262 for (uint32 i
= 0; i
< 10; i
++) {
264 reset
= _ReadReg(OHCI_COMMAND_STATUS
) & OHCI_HOST_CONTROLLER_RESET
;
270 TRACE_ERROR("error resetting the host controller (timeout)\n");
274 // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL.
276 // Set up host controller register
277 _WriteReg(OHCI_HCCA
, (uint32
)hccaPhysicalAddress
);
278 _WriteReg(OHCI_CONTROL_HEAD_ED
, (uint32
)fDummyControl
->physical_address
);
279 _WriteReg(OHCI_BULK_HEAD_ED
, (uint32
)fDummyBulk
->physical_address
);
280 // Switch on desired functional features
281 control
= _ReadReg(OHCI_CONTROL
);
282 control
&= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK
| OHCI_ENABLE_LIST
283 | OHCI_HC_FUNCTIONAL_STATE_MASK
| OHCI_INTERRUPT_ROUTING
);
284 control
|= OHCI_ENABLE_LIST
| OHCI_CONTROL_BULK_RATIO_1_4
285 | OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL
;
286 // And finally start the controller
287 _WriteReg(OHCI_CONTROL
, control
);
289 // The controller is now OPERATIONAL.
290 frameInterval
= (_ReadReg(OHCI_FRAME_INTERVAL
) & OHCI_FRAME_INTERVAL_TOGGLE
)
291 ^ OHCI_FRAME_INTERVAL_TOGGLE
;
292 frameInterval
|= OHCI_FSMPS(intervalValue
) | intervalValue
;
293 _WriteReg(OHCI_FRAME_INTERVAL
, frameInterval
);
295 uint32 periodic
= OHCI_PERIODIC(intervalValue
);
296 _WriteReg(OHCI_PERIODIC_START
, periodic
);
298 // Fiddle the No Over Current Protection bit to avoid chip bug
299 uint32 desca
= _ReadReg(OHCI_RH_DESCRIPTOR_A
);
300 _WriteReg(OHCI_RH_DESCRIPTOR_A
, desca
| OHCI_RH_NO_OVER_CURRENT_PROTECTION
);
301 _WriteReg(OHCI_RH_STATUS
, OHCI_RH_LOCAL_POWER_STATUS_CHANGE
);
302 snooze(OHCI_ENABLE_POWER_DELAY
);
303 _WriteReg(OHCI_RH_DESCRIPTOR_A
, desca
);
305 // The AMD756 requires a delay before re-reading the register,
306 // otherwise it will occasionally report 0 ports.
307 uint32 numberOfPorts
= 0;
308 for (uint32 i
= 0; i
< 10 && numberOfPorts
== 0; i
++) {
309 snooze(OHCI_READ_DESC_DELAY
);
310 uint32 descriptor
= _ReadReg(OHCI_RH_DESCRIPTOR_A
);
311 numberOfPorts
= OHCI_RH_GET_PORT_COUNT(descriptor
);
313 if (numberOfPorts
> OHCI_MAX_PORT_COUNT
)
314 numberOfPorts
= OHCI_MAX_PORT_COUNT
;
315 fPortCount
= numberOfPorts
;
316 TRACE("port count is %d\n", fPortCount
);
318 // Create the array that will keep bandwidth information
319 fFrameBandwidth
= new(std::nothrow
) uint16
[NUMBER_OF_FRAMES
];
321 for (int32 i
= 0; i
< NUMBER_OF_FRAMES
; i
++)
322 fFrameBandwidth
[i
] = MAX_AVAILABLE_BANDWIDTH
;
324 // Create semaphore the finisher thread will wait for
325 fFinishTransfersSem
= create_sem(0, "OHCI Finish Transfers");
326 if (fFinishTransfersSem
< B_OK
) {
327 TRACE_ERROR("failed to create semaphore\n");
331 // Create the finisher service thread
332 fFinishThread
= spawn_kernel_thread(_FinishThread
, "ohci finish thread",
333 B_URGENT_DISPLAY_PRIORITY
, (void *)this);
334 resume_thread(fFinishThread
);
336 // Find the right interrupt vector, using MSIs if available.
337 fIRQ
= fPCIInfo
->u
.h0
.interrupt_line
;
338 if (sPCIx86Module
!= NULL
&& sPCIx86Module
->get_msi_count(fPCIInfo
->bus
,
339 fPCIInfo
->device
, fPCIInfo
->function
) >= 1) {
341 if (sPCIx86Module
->configure_msi(fPCIInfo
->bus
, fPCIInfo
->device
,
342 fPCIInfo
->function
, 1, &msiVector
) == B_OK
343 && sPCIx86Module
->enable_msi(fPCIInfo
->bus
, fPCIInfo
->device
,
344 fPCIInfo
->function
) == B_OK
) {
345 TRACE_ALWAYS("using message signaled interrupts\n");
351 // Install the interrupt handler
352 TRACE("installing interrupt handler\n");
353 install_io_interrupt_handler(fIRQ
, _InterruptHandler
, (void *)this, 0);
355 // Enable interesting interrupts now that the handler is in place
356 _WriteReg(OHCI_INTERRUPT_ENABLE
, OHCI_NORMAL_INTERRUPTS
357 | OHCI_MASTER_INTERRUPT_ENABLE
);
359 TRACE("OHCI host controller driver constructed\n");
367 fStopFinishThread
= true;
368 delete_sem(fFinishTransfersSem
);
369 wait_for_thread(fFinishThread
, &result
);
371 remove_io_interrupt_handler(fIRQ
, _InterruptHandler
, (void *)this);
374 mutex_destroy(&fEndpointLock
);
376 if (fHccaArea
>= B_OK
)
377 delete_area(fHccaArea
);
378 if (fRegisterArea
>= B_OK
)
379 delete_area(fRegisterArea
);
381 _FreeEndpoint(fDummyControl
);
382 _FreeEndpoint(fDummyBulk
);
383 _FreeEndpoint(fDummyIsochronous
);
385 if (fInterruptEndpoints
!= NULL
) {
386 for (int i
= 0; i
< OHCI_STATIC_ENDPOINT_COUNT
; i
++)
387 _FreeEndpoint(fInterruptEndpoints
[i
]);
390 delete [] fFrameBandwidth
;
391 delete [] fInterruptEndpoints
;
394 if (fUseMSI
&& sPCIx86Module
!= NULL
) {
395 sPCIx86Module
->disable_msi(fPCIInfo
->bus
,
396 fPCIInfo
->device
, fPCIInfo
->function
);
397 sPCIx86Module
->unconfigure_msi(fPCIInfo
->bus
,
398 fPCIInfo
->device
, fPCIInfo
->function
);
400 put_module(B_PCI_MODULE_NAME
);
401 if (sPCIx86Module
!= NULL
) {
402 sPCIx86Module
= NULL
;
403 put_module(B_PCI_X86_MODULE_NAME
);
411 TRACE("starting OHCI host controller\n");
413 uint32 control
= _ReadReg(OHCI_CONTROL
);
414 if ((control
& OHCI_HC_FUNCTIONAL_STATE_MASK
)
415 != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL
) {
416 TRACE_ERROR("controller not started (0x%08" B_PRIx32
")!\n", control
);
419 TRACE("controller is operational!\n");
421 fRootHubAddress
= AllocateAddress();
422 fRootHub
= new(std::nothrow
) OHCIRootHub(RootObject(), fRootHubAddress
);
424 TRACE_ERROR("no memory to allocate root hub\n");
428 if (fRootHub
->InitCheck() < B_OK
) {
429 TRACE_ERROR("root hub failed init check\n");
433 SetRootHub(fRootHub
);
434 TRACE_ALWAYS("successfully started the controller\n");
435 return BusManager::Start();
440 OHCI::SubmitTransfer(Transfer
*transfer
)
442 // short circuit the root hub
443 if (transfer
->TransferPipe()->DeviceAddress() == fRootHubAddress
)
444 return fRootHub
->ProcessTransfer(this, transfer
);
446 uint32 type
= transfer
->TransferPipe()->Type();
447 if (type
& USB_OBJECT_CONTROL_PIPE
) {
448 TRACE("submitting request\n");
449 return _SubmitRequest(transfer
);
452 if ((type
& USB_OBJECT_BULK_PIPE
) || (type
& USB_OBJECT_INTERRUPT_PIPE
)) {
453 TRACE("submitting %s transfer\n",
454 (type
& USB_OBJECT_BULK_PIPE
) ? "bulk" : "interrupt");
455 return _SubmitTransfer(transfer
);
458 if (type
& USB_OBJECT_ISO_PIPE
) {
459 TRACE("submitting isochronous transfer\n");
460 return _SubmitIsochronousTransfer(transfer
);
463 TRACE_ERROR("tried to submit transfer for unknown pipe type %" B_PRIu32
"\n",
470 OHCI::CancelQueuedTransfers(Pipe
*pipe
, bool force
)
475 struct transfer_entry
{
477 transfer_entry
* next
;
480 transfer_entry
*list
= NULL
;
481 transfer_data
*current
= fFirstTransfer
;
483 if (current
->transfer
&& current
->transfer
->TransferPipe() == pipe
) {
484 // Check if the skip bit is already set
485 if (!(current
->endpoint
->flags
& OHCI_ENDPOINT_SKIP
)) {
486 current
->endpoint
->flags
|= OHCI_ENDPOINT_SKIP
;
487 // In case the controller is processing
488 // this endpoint, wait for it to finish
492 // Clear the endpoint
493 current
->endpoint
->head_physical_descriptor
494 = current
->endpoint
->tail_physical_descriptor
;
497 if (pipe
->Type() & USB_OBJECT_ISO_PIPE
) {
498 ohci_isochronous_td
*descriptor
499 = (ohci_isochronous_td
*)current
->first_descriptor
;
501 uint16 frame
= OHCI_ITD_GET_STARTING_FRAME(
503 _ReleaseIsochronousBandwidth(frame
,
504 OHCI_ITD_GET_FRAME_COUNT(descriptor
->flags
));
506 == (ohci_isochronous_td
*)current
->last_descriptor
)
507 // this is the last ITD of the transfer
511 = (ohci_isochronous_td
*)
512 descriptor
->next_done_descriptor
;
516 // If the transfer is canceled by force, the one causing the
517 // cancel is probably not the one who initiated the transfer
518 // and the callback is likely not safe anymore
519 transfer_entry
*entry
520 = (transfer_entry
*)malloc(sizeof(transfer_entry
));
522 entry
->transfer
= current
->transfer
;
523 current
->transfer
= NULL
;
528 current
->canceled
= true;
530 current
= current
->link
;
535 while (list
!= NULL
) {
536 transfer_entry
*next
= list
->next
;
537 list
->transfer
->Finished(B_CANCELED
, 0);
538 delete list
->transfer
;
543 // wait for any transfers that might have made it before canceling
544 while (fProcessingPipe
== pipe
)
547 // notify the finisher so it can clean up the canceled transfers
548 release_sem_etc(fFinishTransfersSem
, 1, B_DO_NOT_RESCHEDULE
);
554 OHCI::NotifyPipeChange(Pipe
*pipe
, usb_change change
)
556 TRACE("pipe change %d for pipe %p\n", change
, pipe
);
557 if (pipe
->DeviceAddress() == fRootHubAddress
) {
558 // no need to insert/remove endpoint descriptors for the root hub
563 case USB_CHANGE_CREATED
:
564 return _InsertEndpointForPipe(pipe
);
566 case USB_CHANGE_DESTROYED
:
567 return _RemoveEndpointForPipe(pipe
);
569 case USB_CHANGE_PIPE_POLICY_CHANGED
:
570 TRACE("pipe policy changing unhandled!\n");
574 TRACE_ERROR("unknown pipe change!\n");
583 OHCI::AddTo(Stack
*stack
)
586 set_dprintf_enabled(true);
587 #ifndef HAIKU_TARGET_PLATFORM_HAIKU
588 load_driver_symbols("ohci");
593 status_t status
= get_module(B_PCI_MODULE_NAME
, (module_info
**)&sPCIModule
);
595 TRACE_MODULE_ERROR("getting pci module failed! 0x%08" B_PRIx32
"\n",
601 TRACE_MODULE("searching devices\n");
603 pci_info
*item
= new(std::nothrow
) pci_info
;
606 put_module(B_PCI_MODULE_NAME
);
610 // Try to get the PCI x86 module as well so we can enable possible MSIs.
611 if (sPCIx86Module
== NULL
&& get_module(B_PCI_X86_MODULE_NAME
,
612 (module_info
**)&sPCIx86Module
) != B_OK
) {
613 // If it isn't there, that's not critical though.
614 TRACE_MODULE_ERROR("failed to get pci x86 module\n");
615 sPCIx86Module
= NULL
;
618 for (uint32 i
= 0 ; sPCIModule
->get_nth_pci_info(i
, item
) >= B_OK
; i
++) {
619 if (item
->class_base
== PCI_serial_bus
&& item
->class_sub
== PCI_usb
620 && item
->class_api
== PCI_usb_ohci
) {
621 if (item
->u
.h0
.interrupt_line
== 0
622 || item
->u
.h0
.interrupt_line
== 0xFF) {
623 TRACE_MODULE_ERROR("found device with invalid IRQ -"
624 " check IRQ assignement\n");
628 TRACE_MODULE("found device at IRQ %u\n",
629 item
->u
.h0
.interrupt_line
);
630 OHCI
*bus
= new(std::nothrow
) OHCI(item
, stack
);
634 put_module(B_PCI_MODULE_NAME
);
636 if (sPCIx86Module
!= NULL
) {
637 sPCIx86Module
= NULL
;
638 put_module(B_PCI_X86_MODULE_NAME
);
644 if (bus
->InitCheck() < B_OK
) {
645 TRACE_MODULE_ERROR("bus failed init check\n");
650 // the bus took it away
651 item
= new(std::nothrow
) pci_info
;
654 stack
->AddBusManager(bus
);
660 TRACE_MODULE_ERROR("no devices found\n");
663 put_module(B_PCI_MODULE_NAME
);
665 if (sPCIx86Module
!= NULL
) {
666 sPCIx86Module
= NULL
;
667 put_module(B_PCI_X86_MODULE_NAME
);
679 OHCI::GetPortStatus(uint8 index
, usb_port_status
*status
)
681 if (index
>= fPortCount
) {
682 TRACE_ERROR("get port status for invalid port %u\n", index
);
686 status
->status
= status
->change
= 0;
687 uint32 portStatus
= _ReadReg(OHCI_RH_PORT_STATUS(index
));
690 if (portStatus
& OHCI_RH_PORTSTATUS_CCS
)
691 status
->status
|= PORT_STATUS_CONNECTION
;
692 if (portStatus
& OHCI_RH_PORTSTATUS_PES
)
693 status
->status
|= PORT_STATUS_ENABLE
;
694 if (portStatus
& OHCI_RH_PORTSTATUS_PSS
)
695 status
->status
|= PORT_STATUS_SUSPEND
;
696 if (portStatus
& OHCI_RH_PORTSTATUS_POCI
)
697 status
->status
|= PORT_STATUS_OVER_CURRENT
;
698 if (portStatus
& OHCI_RH_PORTSTATUS_PRS
)
699 status
->status
|= PORT_STATUS_RESET
;
700 if (portStatus
& OHCI_RH_PORTSTATUS_PPS
)
701 status
->status
|= PORT_STATUS_POWER
;
702 if (portStatus
& OHCI_RH_PORTSTATUS_LSDA
)
703 status
->status
|= PORT_STATUS_LOW_SPEED
;
706 if (portStatus
& OHCI_RH_PORTSTATUS_CSC
)
707 status
->change
|= PORT_STATUS_CONNECTION
;
708 if (portStatus
& OHCI_RH_PORTSTATUS_PESC
)
709 status
->change
|= PORT_STATUS_ENABLE
;
710 if (portStatus
& OHCI_RH_PORTSTATUS_PSSC
)
711 status
->change
|= PORT_STATUS_SUSPEND
;
712 if (portStatus
& OHCI_RH_PORTSTATUS_OCIC
)
713 status
->change
|= PORT_STATUS_OVER_CURRENT
;
714 if (portStatus
& OHCI_RH_PORTSTATUS_PRSC
)
715 status
->change
|= PORT_STATUS_RESET
;
717 TRACE("port %u status 0x%04x change 0x%04x\n", index
,
718 status
->status
, status
->change
);
724 OHCI::SetPortFeature(uint8 index
, uint16 feature
)
726 TRACE("set port feature index %u feature %u\n", index
, feature
);
727 if (index
> fPortCount
)
732 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PES
);
736 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PSS
);
740 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PRS
);
744 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PPS
);
753 OHCI::ClearPortFeature(uint8 index
, uint16 feature
)
755 TRACE("clear port feature index %u feature %u\n", index
, feature
);
756 if (index
> fPortCount
)
761 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_CCS
);
765 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_POCI
);
769 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_LSDA
);
772 case C_PORT_CONNECTION
:
773 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_CSC
);
777 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PESC
);
781 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PSSC
);
784 case C_PORT_OVER_CURRENT
:
785 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_OCIC
);
789 _WriteReg(OHCI_RH_PORT_STATUS(index
), OHCI_RH_PORTSTATUS_PRSC
);
798 OHCI::_InterruptHandler(void *data
)
800 return ((OHCI
*)data
)->_Interrupt();
807 static spinlock lock
= B_SPINLOCK_INITIALIZER
;
808 acquire_spinlock(&lock
);
811 uint32 acknowledge
= 0;
812 bool finishTransfers
= false;
813 int32 result
= B_HANDLED_INTERRUPT
;
815 // The LSb of done_head is used to inform the HCD that an interrupt
816 // condition exists for both the done list and for another event recorded in
817 // the HcInterruptStatus register. If done_head is 0, then the interrupt
818 // was caused by other than the HccaDoneHead update and the
819 // HcInterruptStatus register needs to be accessed to determine that exact
820 // interrupt cause. If HccDoneHead is nonzero, then a done list update
821 // interrupt is indicated and if the LSb of the Dword is nonzero, then an
822 // additional interrupt event is indicated and HcInterruptStatus should be
823 // checked to determine its cause.
824 uint32 doneHead
= fHcca
->done_head
;
826 status
= OHCI_WRITEBACK_DONE_HEAD
;
827 if (doneHead
& OHCI_DONE_INTERRUPTS
)
828 status
|= _ReadReg(OHCI_INTERRUPT_STATUS
)
829 & _ReadReg(OHCI_INTERRUPT_ENABLE
);
831 status
= _ReadReg(OHCI_INTERRUPT_STATUS
) & _ReadReg(OHCI_INTERRUPT_ENABLE
)
832 & ~OHCI_WRITEBACK_DONE_HEAD
;
834 // Nothing to be done (PCI shared interrupt)
835 release_spinlock(&lock
);
836 return B_UNHANDLED_INTERRUPT
;
840 if (status
& OHCI_SCHEDULING_OVERRUN
) {
841 TRACE_MODULE("scheduling overrun occured\n");
842 acknowledge
|= OHCI_SCHEDULING_OVERRUN
;
845 if (status
& OHCI_WRITEBACK_DONE_HEAD
) {
846 TRACE_MODULE("transfer descriptors processed\n");
847 fHcca
->done_head
= 0;
848 acknowledge
|= OHCI_WRITEBACK_DONE_HEAD
;
849 result
= B_INVOKE_SCHEDULER
;
850 finishTransfers
= true;
853 if (status
& OHCI_RESUME_DETECTED
) {
854 TRACE_MODULE("resume detected\n");
855 acknowledge
|= OHCI_RESUME_DETECTED
;
858 if (status
& OHCI_UNRECOVERABLE_ERROR
) {
859 TRACE_MODULE_ERROR("unrecoverable error - controller halted\n");
860 _WriteReg(OHCI_CONTROL
, OHCI_HC_FUNCTIONAL_STATE_RESET
);
861 // TODO: clear all pending transfers, reset and resetup the controller
864 if (status
& OHCI_ROOT_HUB_STATUS_CHANGE
) {
865 TRACE_MODULE("root hub status change\n");
866 // Disable the interrupt as it will otherwise be retriggered until the
867 // port has been reset and the change is cleared explicitly.
868 // TODO: renable it once we use status changes instead of polling
869 _WriteReg(OHCI_INTERRUPT_DISABLE
, OHCI_ROOT_HUB_STATUS_CHANGE
);
870 acknowledge
|= OHCI_ROOT_HUB_STATUS_CHANGE
;
873 if (acknowledge
!= 0)
874 _WriteReg(OHCI_INTERRUPT_STATUS
, acknowledge
);
876 release_spinlock(&lock
);
879 release_sem_etc(fFinishTransfersSem
, 1, B_DO_NOT_RESCHEDULE
);
886 OHCI::_AddPendingTransfer(Transfer
*transfer
,
887 ohci_endpoint_descriptor
*endpoint
, ohci_general_td
*firstDescriptor
,
888 ohci_general_td
*dataDescriptor
, ohci_general_td
*lastDescriptor
,
891 if (!transfer
|| !endpoint
|| !lastDescriptor
)
894 transfer_data
*data
= new(std::nothrow
) transfer_data
;
898 status_t result
= transfer
->InitKernelAccess();
904 data
->transfer
= transfer
;
905 data
->endpoint
= endpoint
;
906 data
->incoming
= directionIn
;
907 data
->canceled
= false;
910 // the current tail will become the first descriptor
911 data
->first_descriptor
= (ohci_general_td
*)endpoint
->tail_logical_descriptor
;
913 // the data and first descriptors might be the same
914 if (dataDescriptor
== firstDescriptor
)
915 data
->data_descriptor
= data
->first_descriptor
;
917 data
->data_descriptor
= dataDescriptor
;
919 // even the last and the first descriptor might be the same
920 if (lastDescriptor
== firstDescriptor
)
921 data
->last_descriptor
= data
->first_descriptor
;
923 data
->last_descriptor
= lastDescriptor
;
931 fLastTransfer
->link
= data
;
933 fFirstTransfer
= data
;
935 fLastTransfer
= data
;
943 OHCI::_AddPendingIsochronousTransfer(Transfer
*transfer
,
944 ohci_endpoint_descriptor
*endpoint
, ohci_isochronous_td
*firstDescriptor
,
945 ohci_isochronous_td
*lastDescriptor
, bool directionIn
)
947 if (!transfer
|| !endpoint
|| !lastDescriptor
)
950 transfer_data
*data
= new(std::nothrow
) transfer_data
;
954 status_t result
= transfer
->InitKernelAccess();
960 data
->transfer
= transfer
;
961 data
->endpoint
= endpoint
;
962 data
->incoming
= directionIn
;
963 data
->canceled
= false;
966 // the current tail will become the first descriptor
967 data
->first_descriptor
= (ohci_general_td
*)endpoint
->tail_logical_descriptor
;
969 // the data and first descriptors are the same
970 data
->data_descriptor
= data
->first_descriptor
;
972 // the last and the first descriptor might be the same
973 if (lastDescriptor
== firstDescriptor
)
974 data
->last_descriptor
= data
->first_descriptor
;
976 data
->last_descriptor
= (ohci_general_td
*)lastDescriptor
;
984 fLastTransfer
->link
= data
;
986 fFirstTransfer
= data
;
988 fLastTransfer
= data
;
996 OHCI::_FinishThread(void *data
)
998 ((OHCI
*)data
)->_FinishTransfers();
1004 OHCI::_FinishTransfers()
1006 while (!fStopFinishThread
) {
1007 if (acquire_sem(fFinishTransfersSem
) < B_OK
)
1010 // eat up sems that have been released by multiple interrupts
1012 get_sem_count(fFinishTransfersSem
, &semCount
);
1014 acquire_sem_etc(fFinishTransfersSem
, semCount
, B_RELATIVE_TIMEOUT
, 0);
1019 TRACE("finishing transfers (first transfer: %p; last"
1020 " transfer: %p)\n", fFirstTransfer
, fLastTransfer
);
1021 transfer_data
*lastTransfer
= NULL
;
1022 transfer_data
*transfer
= fFirstTransfer
;
1026 bool transferDone
= false;
1027 ohci_general_td
*descriptor
= transfer
->first_descriptor
;
1028 ohci_endpoint_descriptor
*endpoint
= transfer
->endpoint
;
1029 status_t callbackStatus
= B_OK
;
1031 if (endpoint
->flags
& OHCI_ENDPOINT_ISOCHRONOUS_FORMAT
) {
1032 transfer_data
*next
= transfer
->link
;
1033 if (_FinishIsochronousTransfer(transfer
, &lastTransfer
)) {
1034 delete transfer
->transfer
;
1041 MutexLocker
endpointLocker(endpoint
->lock
);
1043 if ((endpoint
->head_physical_descriptor
& OHCI_ENDPOINT_HEAD_MASK
)
1044 != endpoint
->tail_physical_descriptor
1045 && (endpoint
->head_physical_descriptor
1046 & OHCI_ENDPOINT_HALTED
) == 0) {
1047 // there are still active transfers on this endpoint, we need
1048 // to wait for all of them to complete, otherwise we'd read
1049 // a potentially bogus data toggle value below
1050 TRACE("endpoint %p still has active tds\n", endpoint
);
1051 lastTransfer
= transfer
;
1052 transfer
= transfer
->link
;
1056 endpointLocker
.Unlock();
1058 while (descriptor
&& !transfer
->canceled
) {
1059 uint32 status
= OHCI_TD_GET_CONDITION_CODE(descriptor
->flags
);
1060 if (status
== OHCI_TD_CONDITION_NOT_ACCESSED
) {
1061 // td is still active
1062 TRACE("td %p still active\n", descriptor
);
1066 if (status
!= OHCI_TD_CONDITION_NO_ERROR
) {
1067 // an error occured, but we must ensure that the td
1068 // was actually done
1069 if (endpoint
->head_physical_descriptor
& OHCI_ENDPOINT_HALTED
) {
1070 // the endpoint is halted, this guaratees us that this
1071 // descriptor has passed (we don't know if the endpoint
1072 // was halted because of this td, but we do not need
1073 // to know, as when it was halted by another td this
1074 // still ensures that this td was handled before).
1075 TRACE_ERROR("td error: 0x%08" B_PRIx32
"\n", status
);
1077 callbackStatus
= _GetStatusOfConditionCode(status
);
1079 transferDone
= true;
1082 // an error occured but the endpoint is not halted so
1083 // the td is in fact still active
1084 TRACE("td %p active with error\n", descriptor
);
1089 // the td has completed without an error
1090 TRACE("td %p done\n", descriptor
);
1092 if (descriptor
== transfer
->last_descriptor
1093 || descriptor
->buffer_physical
!= 0) {
1094 // this is the last td of the transfer or a short packet
1095 callbackStatus
= B_OK
;
1096 transferDone
= true;
1101 = (ohci_general_td
*)descriptor
->next_logical_descriptor
;
1104 if (transfer
->canceled
) {
1105 // when a transfer is canceled, all transfers to that endpoint
1106 // are canceled by setting the head pointer to the tail pointer
1107 // which causes all of the tds to become "free" (as they are
1108 // inaccessible and not accessed anymore (as setting the head
1109 // pointer required disabling the endpoint))
1110 callbackStatus
= B_OK
;
1111 transferDone
= true;
1114 if (!transferDone
) {
1115 lastTransfer
= transfer
;
1116 transfer
= transfer
->link
;
1120 // remove the transfer from the list first so we are sure
1121 // it doesn't get canceled while we still process it
1122 transfer_data
*next
= transfer
->link
;
1125 lastTransfer
->link
= transfer
->link
;
1127 if (transfer
== fFirstTransfer
)
1128 fFirstTransfer
= transfer
->link
;
1129 if (transfer
== fLastTransfer
)
1130 fLastTransfer
= lastTransfer
;
1132 // store the currently processing pipe here so we can wait
1133 // in cancel if we are processing something on the target pipe
1134 if (!transfer
->canceled
)
1135 fProcessingPipe
= transfer
->transfer
->TransferPipe();
1137 transfer
->link
= NULL
;
1141 // break the descriptor chain on the last descriptor
1142 transfer
->last_descriptor
->next_logical_descriptor
= NULL
;
1143 TRACE("transfer %p done with status 0x%08" B_PRIx32
"\n",
1144 transfer
, callbackStatus
);
1146 // if canceled the callback has already been called
1147 if (!transfer
->canceled
) {
1148 size_t actualLength
= 0;
1149 if (callbackStatus
== B_OK
) {
1150 if (transfer
->data_descriptor
&& transfer
->incoming
) {
1152 iovec
*vector
= transfer
->transfer
->Vector();
1153 size_t vectorCount
= transfer
->transfer
->VectorCount();
1155 transfer
->transfer
->PrepareKernelAccess();
1156 actualLength
= _ReadDescriptorChain(
1157 transfer
->data_descriptor
,
1158 vector
, vectorCount
);
1159 } else if (transfer
->data_descriptor
) {
1160 // read the actual length that was sent
1161 actualLength
= _ReadActualLength(
1162 transfer
->data_descriptor
);
1165 // get the last data toggle and store it for next time
1166 transfer
->transfer
->TransferPipe()->SetDataToggle(
1167 (endpoint
->head_physical_descriptor
1168 & OHCI_ENDPOINT_TOGGLE_CARRY
) != 0);
1170 if (transfer
->transfer
->IsFragmented()) {
1171 // this transfer may still have data left
1172 TRACE("advancing fragmented transfer\n");
1173 transfer
->transfer
->AdvanceByFragment(actualLength
);
1174 if (transfer
->transfer
->VectorLength() > 0) {
1175 TRACE("still %ld bytes left on transfer\n",
1176 transfer
->transfer
->VectorLength());
1177 // TODO actually resubmit the transfer
1180 // the transfer is done, but we already set the
1181 // actualLength with AdvanceByFragment()
1186 transfer
->transfer
->Finished(callbackStatus
, actualLength
);
1187 fProcessingPipe
= NULL
;
1190 if (callbackStatus
!= B_OK
) {
1191 // remove the transfer and make the head pointer valid again
1192 // (including clearing the halt state)
1193 _RemoveTransferFromEndpoint(transfer
);
1196 // free the descriptors
1197 _FreeDescriptorChain(transfer
->first_descriptor
);
1199 delete transfer
->transfer
;
1208 OHCI::_FinishIsochronousTransfer(transfer_data
*transfer
,
1209 transfer_data
**_lastTransfer
)
1211 status_t callbackStatus
= B_OK
;
1212 size_t actualLength
= 0;
1215 if (transfer
->canceled
)
1216 callbackStatus
= B_CANCELED
;
1218 // at first check if ALL ITDs are retired by HC
1219 ohci_isochronous_td
*descriptor
1220 = (ohci_isochronous_td
*)transfer
->first_descriptor
;
1221 while (descriptor
) {
1222 if (OHCI_TD_GET_CONDITION_CODE(descriptor
->flags
)
1223 == OHCI_TD_CONDITION_NOT_ACCESSED
) {
1224 TRACE("ITD %p still active\n", descriptor
);
1225 *_lastTransfer
= transfer
;
1229 if (descriptor
== (ohci_isochronous_td
*)transfer
->last_descriptor
) {
1230 // this is the last ITD of the transfer
1231 descriptor
= (ohci_isochronous_td
*)transfer
->first_descriptor
;
1236 = (ohci_isochronous_td
*)descriptor
->next_done_descriptor
;
1239 while (descriptor
) {
1240 uint32 status
= OHCI_TD_GET_CONDITION_CODE(descriptor
->flags
);
1241 if (status
!= OHCI_TD_CONDITION_NO_ERROR
) {
1242 TRACE_ERROR("ITD error: 0x%08" B_PRIx32
"\n", status
);
1243 // spec says that in most cases condition code
1244 // of retired ITDs is set to NoError, but for the
1245 // time overrun it can be DataOverrun. We assume
1246 // the _first_ occurience of such error as status
1247 // reported to the callback
1248 if (callbackStatus
== B_OK
)
1249 callbackStatus
= _GetStatusOfConditionCode(status
);
1252 usb_isochronous_data
*isochronousData
1253 = transfer
->transfer
->IsochronousData();
1255 uint32 frameCount
= OHCI_ITD_GET_FRAME_COUNT(descriptor
->flags
);
1256 for (size_t i
= 0; i
< frameCount
; i
++, packet
++) {
1257 usb_iso_packet_descriptor
* packet_descriptor
1258 = &isochronousData
->packet_descriptors
[packet
];
1260 uint16 offset
= descriptor
->offset
[OHCI_ITD_OFFSET_IDX(i
)];
1261 uint8 code
= OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset
);
1262 packet_descriptor
->status
= _GetStatusOfConditionCode(code
);
1264 // not touched by HC - sheduled too late to be processed
1265 // in the requested frame - so we ignore it too
1266 if (packet_descriptor
->status
== B_DEV_TOO_LATE
)
1269 size_t len
= OHCI_ITD_GET_BUFFER_LENGTH(offset
);
1270 if (!transfer
->incoming
)
1271 len
= packet_descriptor
->request_length
- len
;
1273 packet_descriptor
->actual_length
= len
;
1274 actualLength
+= len
;
1277 uint16 frame
= OHCI_ITD_GET_STARTING_FRAME(descriptor
->flags
);
1278 _ReleaseIsochronousBandwidth(frame
,
1279 OHCI_ITD_GET_FRAME_COUNT(descriptor
->flags
));
1281 TRACE("ITD %p done\n", descriptor
);
1283 if (descriptor
== (ohci_isochronous_td
*)transfer
->last_descriptor
)
1287 = (ohci_isochronous_td
*)descriptor
->next_done_descriptor
;
1291 // remove the transfer from the list first so we are sure
1292 // it doesn't get canceled while we still process it
1295 (*_lastTransfer
)->link
= transfer
->link
;
1297 if (transfer
== fFirstTransfer
)
1298 fFirstTransfer
= transfer
->link
;
1299 if (transfer
== fLastTransfer
)
1300 fLastTransfer
= *_lastTransfer
;
1302 // store the currently processing pipe here so we can wait
1303 // in cancel if we are processing something on the target pipe
1304 if (!transfer
->canceled
)
1305 fProcessingPipe
= transfer
->transfer
->TransferPipe();
1307 transfer
->link
= NULL
;
1311 // break the descriptor chain on the last descriptor
1312 transfer
->last_descriptor
->next_logical_descriptor
= NULL
;
1313 TRACE("iso.transfer %p done with status 0x%08" B_PRIx32
" len:%ld\n",
1314 transfer
, callbackStatus
, actualLength
);
1316 // if canceled the callback has already been called
1317 if (!transfer
->canceled
) {
1318 if (callbackStatus
== B_OK
&& actualLength
> 0) {
1319 if (transfer
->data_descriptor
&& transfer
->incoming
) {
1321 iovec
*vector
= transfer
->transfer
->Vector();
1322 size_t vectorCount
= transfer
->transfer
->VectorCount();
1324 transfer
->transfer
->PrepareKernelAccess();
1325 _ReadIsochronousDescriptorChain(
1326 (ohci_isochronous_td
*)transfer
->data_descriptor
,
1327 vector
, vectorCount
);
1331 transfer
->transfer
->Finished(callbackStatus
, actualLength
);
1332 fProcessingPipe
= NULL
;
1335 _FreeIsochronousDescriptorChain(
1336 (ohci_isochronous_td
*)transfer
->first_descriptor
);
1343 OHCI::_SubmitRequest(Transfer
*transfer
)
1345 usb_request_data
*requestData
= transfer
->RequestData();
1346 bool directionIn
= (requestData
->RequestType
& USB_REQTYPE_DEVICE_IN
) != 0;
1348 ohci_general_td
*setupDescriptor
1349 = _CreateGeneralDescriptor(sizeof(usb_request_data
));
1350 if (!setupDescriptor
) {
1351 TRACE_ERROR("failed to allocate setup descriptor\n");
1355 setupDescriptor
->flags
= OHCI_TD_DIRECTION_PID_SETUP
1356 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED
)
1358 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE
);
1360 ohci_general_td
*statusDescriptor
= _CreateGeneralDescriptor(0);
1361 if (!statusDescriptor
) {
1362 TRACE_ERROR("failed to allocate status descriptor\n");
1363 _FreeGeneralDescriptor(setupDescriptor
);
1367 statusDescriptor
->flags
1368 = (directionIn
? OHCI_TD_DIRECTION_PID_OUT
: OHCI_TD_DIRECTION_PID_IN
)
1369 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED
)
1371 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE
);
1374 vector
.iov_base
= requestData
;
1375 vector
.iov_len
= sizeof(usb_request_data
);
1376 _WriteDescriptorChain(setupDescriptor
, &vector
, 1);
1379 ohci_general_td
*dataDescriptor
= NULL
;
1380 if (transfer
->VectorCount() > 0) {
1381 ohci_general_td
*lastDescriptor
= NULL
;
1382 result
= _CreateDescriptorChain(&dataDescriptor
, &lastDescriptor
,
1383 directionIn
? OHCI_TD_DIRECTION_PID_IN
: OHCI_TD_DIRECTION_PID_OUT
,
1384 transfer
->VectorLength());
1385 if (result
< B_OK
) {
1386 _FreeGeneralDescriptor(setupDescriptor
);
1387 _FreeGeneralDescriptor(statusDescriptor
);
1392 _WriteDescriptorChain(dataDescriptor
, transfer
->Vector(),
1393 transfer
->VectorCount());
1396 _LinkDescriptors(setupDescriptor
, dataDescriptor
);
1397 _LinkDescriptors(lastDescriptor
, statusDescriptor
);
1399 _LinkDescriptors(setupDescriptor
, statusDescriptor
);
1402 // Add to the transfer list
1403 ohci_endpoint_descriptor
*endpoint
1404 = (ohci_endpoint_descriptor
*)transfer
->TransferPipe()->ControllerCookie();
1406 MutexLocker
endpointLocker(endpoint
->lock
);
1407 result
= _AddPendingTransfer(transfer
, endpoint
, setupDescriptor
,
1408 dataDescriptor
, statusDescriptor
, directionIn
);
1409 if (result
< B_OK
) {
1410 TRACE_ERROR("failed to add pending transfer\n");
1411 _FreeDescriptorChain(setupDescriptor
);
1415 // Add the descriptor chain to the endpoint
1416 _SwitchEndpointTail(endpoint
, setupDescriptor
, statusDescriptor
);
1417 endpointLocker
.Unlock();
1419 // Tell the controller to process the control list
1420 endpoint
->flags
&= ~OHCI_ENDPOINT_SKIP
;
1421 _WriteReg(OHCI_COMMAND_STATUS
, OHCI_CONTROL_LIST_FILLED
);
1427 OHCI::_SubmitTransfer(Transfer
*transfer
)
1429 Pipe
*pipe
= transfer
->TransferPipe();
1430 bool directionIn
= (pipe
->Direction() == Pipe::In
);
1432 ohci_general_td
*firstDescriptor
= NULL
;
1433 ohci_general_td
*lastDescriptor
= NULL
;
1434 status_t result
= _CreateDescriptorChain(&firstDescriptor
, &lastDescriptor
,
1435 directionIn
? OHCI_TD_DIRECTION_PID_IN
: OHCI_TD_DIRECTION_PID_OUT
,
1436 transfer
->VectorLength());
1441 // Apply data toggle to the first descriptor (the others will use the carry)
1442 firstDescriptor
->flags
&= ~OHCI_TD_TOGGLE_CARRY
;
1443 firstDescriptor
->flags
|= pipe
->DataToggle() ? OHCI_TD_TOGGLE_1
1446 // Set the last descriptor to generate an interrupt
1447 lastDescriptor
->flags
&= ~OHCI_TD_INTERRUPT_MASK
;
1448 lastDescriptor
->flags
|=
1449 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE
);
1452 _WriteDescriptorChain(firstDescriptor
, transfer
->Vector(),
1453 transfer
->VectorCount());
1456 // Add to the transfer list
1457 ohci_endpoint_descriptor
*endpoint
1458 = (ohci_endpoint_descriptor
*)pipe
->ControllerCookie();
1460 MutexLocker
endpointLocker(endpoint
->lock
);
1461 result
= _AddPendingTransfer(transfer
, endpoint
, firstDescriptor
,
1462 firstDescriptor
, lastDescriptor
, directionIn
);
1463 if (result
< B_OK
) {
1464 TRACE_ERROR("failed to add pending transfer\n");
1465 _FreeDescriptorChain(firstDescriptor
);
1469 // Add the descriptor chain to the endpoint
1470 _SwitchEndpointTail(endpoint
, firstDescriptor
, lastDescriptor
);
1471 endpointLocker
.Unlock();
1473 endpoint
->flags
&= ~OHCI_ENDPOINT_SKIP
;
1474 if (pipe
->Type() & USB_OBJECT_BULK_PIPE
) {
1475 // Tell the controller to process the bulk list
1476 _WriteReg(OHCI_COMMAND_STATUS
, OHCI_BULK_LIST_FILLED
);
1484 OHCI::_SubmitIsochronousTransfer(Transfer
*transfer
)
1486 Pipe
*pipe
= transfer
->TransferPipe();
1487 bool directionIn
= (pipe
->Direction() == Pipe::In
);
1488 usb_isochronous_data
*isochronousData
= transfer
->IsochronousData();
1490 ohci_isochronous_td
*firstDescriptor
= NULL
;
1491 ohci_isochronous_td
*lastDescriptor
= NULL
;
1492 status_t result
= _CreateIsochronousDescriptorChain(&firstDescriptor
,
1493 &lastDescriptor
, transfer
);
1495 if (firstDescriptor
== 0 || lastDescriptor
== 0)
1501 // Set the last descriptor to generate an interrupt
1502 lastDescriptor
->flags
&= ~OHCI_ITD_INTERRUPT_MASK
;
1503 // let the controller retire last ITD
1504 lastDescriptor
->flags
|= OHCI_ITD_SET_DELAY_INTERRUPT(1);
1506 // If direction is out set every descriptor data
1507 if (pipe
->Direction() == Pipe::Out
)
1508 _WriteIsochronousDescriptorChain(firstDescriptor
,
1509 transfer
->Vector(), transfer
->VectorCount());
1511 // Initialize the packet descriptors
1512 for (uint32 i
= 0; i
< isochronousData
->packet_count
; i
++) {
1513 isochronousData
->packet_descriptors
[i
].actual_length
= 0;
1514 isochronousData
->packet_descriptors
[i
].status
= B_NO_INIT
;
1517 // Add to the transfer list
1518 ohci_endpoint_descriptor
*endpoint
1519 = (ohci_endpoint_descriptor
*)pipe
->ControllerCookie();
1521 MutexLocker
endpointLocker(endpoint
->lock
);
1522 result
= _AddPendingIsochronousTransfer(transfer
, endpoint
,
1523 firstDescriptor
, lastDescriptor
, directionIn
);
1524 if (result
< B_OK
) {
1525 TRACE_ERROR("failed to add pending iso.transfer:"
1526 "0x%08" B_PRIx32
"\n", result
);
1527 _FreeIsochronousDescriptorChain(firstDescriptor
);
1531 // Add the descriptor chain to the endpoint
1532 _SwitchIsochronousEndpointTail(endpoint
, firstDescriptor
, lastDescriptor
);
1533 endpointLocker
.Unlock();
1535 endpoint
->flags
&= ~OHCI_ENDPOINT_SKIP
;
1542 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor
*endpoint
,
1543 ohci_general_td
*first
, ohci_general_td
*last
)
1545 // fill in the information of the first descriptor into the current tail
1546 ohci_general_td
*tail
= (ohci_general_td
*)endpoint
->tail_logical_descriptor
;
1547 tail
->flags
= first
->flags
;
1548 tail
->buffer_physical
= first
->buffer_physical
;
1549 tail
->next_physical_descriptor
= first
->next_physical_descriptor
;
1550 tail
->last_physical_byte_address
= first
->last_physical_byte_address
;
1551 tail
->buffer_size
= first
->buffer_size
;
1552 tail
->buffer_logical
= first
->buffer_logical
;
1553 tail
->next_logical_descriptor
= first
->next_logical_descriptor
;
1555 // the first descriptor becomes the new tail
1557 first
->buffer_physical
= 0;
1558 first
->next_physical_descriptor
= 0;
1559 first
->last_physical_byte_address
= 0;
1560 first
->buffer_size
= 0;
1561 first
->buffer_logical
= NULL
;
1562 first
->next_logical_descriptor
= NULL
;
1565 _LinkDescriptors(tail
, first
);
1567 _LinkDescriptors(last
, first
);
1569 // update the endpoint tail pointer to reflect the change
1570 endpoint
->tail_logical_descriptor
= first
;
1571 endpoint
->tail_physical_descriptor
= (uint32
)first
->physical_address
;
1572 TRACE("switched tail from %p to %p\n", tail
, first
);
1575 _PrintEndpoint(endpoint
);
1576 _PrintDescriptorChain(tail
);
1582 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor
*endpoint
,
1583 ohci_isochronous_td
*first
, ohci_isochronous_td
*last
)
1585 // fill in the information of the first descriptor into the current tail
1586 ohci_isochronous_td
*tail
1587 = (ohci_isochronous_td
*)endpoint
->tail_logical_descriptor
;
1588 tail
->flags
= first
->flags
;
1589 tail
->buffer_page_byte_0
= first
->buffer_page_byte_0
;
1590 tail
->next_physical_descriptor
= first
->next_physical_descriptor
;
1591 tail
->last_byte_address
= first
->last_byte_address
;
1592 tail
->buffer_size
= first
->buffer_size
;
1593 tail
->buffer_logical
= first
->buffer_logical
;
1594 tail
->next_logical_descriptor
= first
->next_logical_descriptor
;
1595 tail
->next_done_descriptor
= first
->next_done_descriptor
;
1597 // the first descriptor becomes the new tail
1599 first
->buffer_page_byte_0
= 0;
1600 first
->next_physical_descriptor
= 0;
1601 first
->last_byte_address
= 0;
1602 first
->buffer_size
= 0;
1603 first
->buffer_logical
= NULL
;
1604 first
->next_logical_descriptor
= NULL
;
1605 first
->next_done_descriptor
= NULL
;
1607 for (int i
= 0; i
< OHCI_ITD_NOFFSET
; i
++) {
1608 tail
->offset
[i
] = first
->offset
[i
];
1609 first
->offset
[i
] = 0;
1613 _LinkIsochronousDescriptors(tail
, first
, NULL
);
1615 _LinkIsochronousDescriptors(last
, first
, NULL
);
1617 // update the endpoint tail pointer to reflect the change
1618 endpoint
->tail_logical_descriptor
= first
;
1619 endpoint
->tail_physical_descriptor
= (uint32
)first
->physical_address
;
1620 TRACE("switched tail from %p to %p\n", tail
, first
);
1623 _PrintEndpoint(endpoint
);
1624 _PrintDescriptorChain(tail
);
1630 OHCI::_RemoveTransferFromEndpoint(transfer_data
*transfer
)
1632 // The transfer failed and the endpoint was halted. This means that the
1633 // endpoint head pointer might point somewhere into the descriptor chain
1634 // of this transfer. As we do not know if this transfer actually caused
1635 // the halt on the endpoint we have to make sure this is the case. If we
1636 // find the head to point to somewhere into the descriptor chain then
1637 // simply advancing the head pointer to the link of the last transfer
1638 // will bring the endpoint into a valid state again. This operation is
1639 // safe as the endpoint is currently halted and we therefore can change
1640 // the head pointer.
1641 ohci_endpoint_descriptor
*endpoint
= transfer
->endpoint
;
1642 ohci_general_td
*descriptor
= transfer
->first_descriptor
;
1643 while (descriptor
) {
1644 if ((endpoint
->head_physical_descriptor
& OHCI_ENDPOINT_HEAD_MASK
)
1645 == descriptor
->physical_address
) {
1646 // This descriptor caused the halt. Advance the head pointer. This
1647 // will either move the head to the next valid transfer that can
1648 // then be restarted, or it will move the head to the tail when
1649 // there are no more transfer descriptors. Setting the head will
1650 // also clear the halt state as it is stored in the first bit of
1651 // the head pointer.
1652 endpoint
->head_physical_descriptor
1653 = transfer
->last_descriptor
->next_physical_descriptor
;
1657 descriptor
= (ohci_general_td
*)descriptor
->next_logical_descriptor
;
1662 ohci_endpoint_descriptor
*
1663 OHCI::_AllocateEndpoint()
1665 ohci_endpoint_descriptor
*endpoint
;
1666 phys_addr_t physicalAddress
;
1668 mutex
*lock
= (mutex
*)malloc(sizeof(mutex
));
1670 TRACE_ERROR("no memory to allocate endpoint lock\n");
1674 // Allocate memory chunk
1675 if (fStack
->AllocateChunk((void **)&endpoint
, &physicalAddress
,
1676 sizeof(ohci_endpoint_descriptor
)) < B_OK
) {
1677 TRACE_ERROR("failed to allocate endpoint descriptor\n");
1682 mutex_init(lock
, "ohci endpoint lock");
1684 endpoint
->flags
= OHCI_ENDPOINT_SKIP
;
1685 endpoint
->physical_address
= (uint32
)physicalAddress
;
1686 endpoint
->head_physical_descriptor
= 0;
1687 endpoint
->tail_logical_descriptor
= NULL
;
1688 endpoint
->tail_physical_descriptor
= 0;
1689 endpoint
->next_logical_endpoint
= NULL
;
1690 endpoint
->next_physical_endpoint
= 0;
1691 endpoint
->lock
= lock
;
1697 OHCI::_FreeEndpoint(ohci_endpoint_descriptor
*endpoint
)
1702 mutex_destroy(endpoint
->lock
);
1703 free(endpoint
->lock
);
1705 fStack
->FreeChunk((void *)endpoint
, endpoint
->physical_address
,
1706 sizeof(ohci_endpoint_descriptor
));
1711 OHCI::_InsertEndpointForPipe(Pipe
*pipe
)
1713 TRACE("inserting endpoint for device %u endpoint %u\n",
1714 pipe
->DeviceAddress(), pipe
->EndpointAddress());
1716 ohci_endpoint_descriptor
*endpoint
= _AllocateEndpoint();
1718 TRACE_ERROR("cannot allocate memory for endpoint\n");
1722 uint32 flags
= OHCI_ENDPOINT_SKIP
;
1724 // Set up device and endpoint address
1725 flags
|= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe
->DeviceAddress())
1726 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe
->EndpointAddress());
1728 // Set the direction
1729 switch (pipe
->Direction()) {
1731 flags
|= OHCI_ENDPOINT_DIRECTION_IN
;
1735 flags
|= OHCI_ENDPOINT_DIRECTION_OUT
;
1739 flags
|= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR
;
1743 TRACE_ERROR("direction unknown\n");
1744 _FreeEndpoint(endpoint
);
1749 switch (pipe
->Speed()) {
1750 case USB_SPEED_LOWSPEED
:
1751 flags
|= OHCI_ENDPOINT_LOW_SPEED
;
1754 case USB_SPEED_FULLSPEED
:
1755 flags
|= OHCI_ENDPOINT_FULL_SPEED
;
1759 TRACE_ERROR("unacceptable speed\n");
1760 _FreeEndpoint(endpoint
);
1764 // Set the maximum packet size
1765 flags
|= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe
->MaxPacketSize());
1766 endpoint
->flags
= flags
;
1768 // Add the endpoint to the appropriate list
1769 uint32 type
= pipe
->Type();
1770 ohci_endpoint_descriptor
*head
= NULL
;
1771 if (type
& USB_OBJECT_CONTROL_PIPE
)
1772 head
= fDummyControl
;
1773 else if (type
& USB_OBJECT_BULK_PIPE
)
1775 else if (type
& USB_OBJECT_INTERRUPT_PIPE
)
1776 head
= _FindInterruptEndpoint(pipe
->Interval());
1777 else if (type
& USB_OBJECT_ISO_PIPE
)
1778 head
= fDummyIsochronous
;
1780 TRACE_ERROR("unknown pipe type\n");
1783 TRACE_ERROR("no list found for endpoint\n");
1784 _FreeEndpoint(endpoint
);
1788 // Create (necessary) tail descriptor
1789 if (pipe
->Type() & USB_OBJECT_ISO_PIPE
) {
1790 // Set the isochronous bit format
1791 endpoint
->flags
|= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT
;
1792 ohci_isochronous_td
*tail
= _CreateIsochronousDescriptor(0);
1794 endpoint
->tail_logical_descriptor
= tail
;
1795 endpoint
->head_physical_descriptor
= tail
->physical_address
;
1796 endpoint
->tail_physical_descriptor
= tail
->physical_address
;
1798 ohci_general_td
*tail
= _CreateGeneralDescriptor(0);
1800 endpoint
->tail_logical_descriptor
= tail
;
1801 endpoint
->head_physical_descriptor
= tail
->physical_address
;
1802 endpoint
->tail_physical_descriptor
= tail
->physical_address
;
1805 if (!_LockEndpoints()) {
1806 if (endpoint
->tail_logical_descriptor
) {
1807 _FreeGeneralDescriptor(
1808 (ohci_general_td
*)endpoint
->tail_logical_descriptor
);
1811 _FreeEndpoint(endpoint
);
1815 pipe
->SetControllerCookie((void *)endpoint
);
1816 endpoint
->next_logical_endpoint
= head
->next_logical_endpoint
;
1817 endpoint
->next_physical_endpoint
= head
->next_physical_endpoint
;
1818 head
->next_logical_endpoint
= (void *)endpoint
;
1819 head
->next_physical_endpoint
= (uint32
)endpoint
->physical_address
;
1827 OHCI::_RemoveEndpointForPipe(Pipe
*pipe
)
1829 TRACE("removing endpoint for device %u endpoint %u\n",
1830 pipe
->DeviceAddress(), pipe
->EndpointAddress());
1832 ohci_endpoint_descriptor
*endpoint
1833 = (ohci_endpoint_descriptor
*)pipe
->ControllerCookie();
1834 if (endpoint
== NULL
)
1837 // TODO implement properly, but at least disable it for now
1838 endpoint
->flags
|= OHCI_ENDPOINT_SKIP
;
1843 ohci_endpoint_descriptor
*
1844 OHCI::_FindInterruptEndpoint(uint8 interval
)
1848 while (power
<= OHCI_BIGGEST_INTERVAL
/ 2) {
1849 if (power
* 2 > interval
)
1856 return fInterruptEndpoints
[index
];
1861 OHCI::_CreateGeneralDescriptor(size_t bufferSize
)
1863 ohci_general_td
*descriptor
;
1864 phys_addr_t physicalAddress
;
1866 if (fStack
->AllocateChunk((void **)&descriptor
, &physicalAddress
,
1867 sizeof(ohci_general_td
)) != B_OK
) {
1868 TRACE_ERROR("failed to allocate general descriptor\n");
1872 descriptor
->physical_address
= (uint32
)physicalAddress
;
1873 descriptor
->next_physical_descriptor
= 0;
1874 descriptor
->next_logical_descriptor
= NULL
;
1875 descriptor
->buffer_size
= bufferSize
;
1876 if (bufferSize
== 0) {
1877 descriptor
->buffer_physical
= 0;
1878 descriptor
->buffer_logical
= NULL
;
1879 descriptor
->last_physical_byte_address
= 0;
1883 if (fStack
->AllocateChunk(&descriptor
->buffer_logical
,
1884 &physicalAddress
, bufferSize
) != B_OK
) {
1885 TRACE_ERROR("failed to allocate space for buffer\n");
1886 fStack
->FreeChunk(descriptor
, descriptor
->physical_address
,
1887 sizeof(ohci_general_td
));
1890 descriptor
->buffer_physical
= physicalAddress
;
1892 descriptor
->last_physical_byte_address
1893 = descriptor
->buffer_physical
+ bufferSize
- 1;
1899 OHCI::_FreeGeneralDescriptor(ohci_general_td
*descriptor
)
1904 if (descriptor
->buffer_logical
) {
1905 fStack
->FreeChunk(descriptor
->buffer_logical
,
1906 descriptor
->buffer_physical
, descriptor
->buffer_size
);
1909 fStack
->FreeChunk((void *)descriptor
, descriptor
->physical_address
,
1910 sizeof(ohci_general_td
));
1915 OHCI::_CreateDescriptorChain(ohci_general_td
**_firstDescriptor
,
1916 ohci_general_td
**_lastDescriptor
, uint32 direction
, size_t bufferSize
)
1918 size_t blockSize
= 8192;
1919 int32 descriptorCount
= (bufferSize
+ blockSize
- 1) / blockSize
;
1920 if (descriptorCount
== 0)
1921 descriptorCount
= 1;
1923 ohci_general_td
*firstDescriptor
= NULL
;
1924 ohci_general_td
*lastDescriptor
= *_firstDescriptor
;
1925 for (int32 i
= 0; i
< descriptorCount
; i
++) {
1926 ohci_general_td
*descriptor
= _CreateGeneralDescriptor(
1927 min_c(blockSize
, bufferSize
));
1930 _FreeDescriptorChain(firstDescriptor
);
1934 descriptor
->flags
= direction
1935 | OHCI_TD_BUFFER_ROUNDING
1936 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED
)
1937 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE
)
1938 | OHCI_TD_TOGGLE_CARRY
;
1942 _LinkDescriptors(lastDescriptor
, descriptor
);
1944 bufferSize
-= blockSize
;
1945 lastDescriptor
= descriptor
;
1946 if (!firstDescriptor
)
1947 firstDescriptor
= descriptor
;
1950 *_firstDescriptor
= firstDescriptor
;
1951 *_lastDescriptor
= lastDescriptor
;
1957 OHCI::_FreeDescriptorChain(ohci_general_td
*topDescriptor
)
1959 ohci_general_td
*current
= topDescriptor
;
1960 ohci_general_td
*next
= NULL
;
1963 next
= (ohci_general_td
*)current
->next_logical_descriptor
;
1964 _FreeGeneralDescriptor(current
);
1970 ohci_isochronous_td
*
1971 OHCI::_CreateIsochronousDescriptor(size_t bufferSize
)
1973 ohci_isochronous_td
*descriptor
= NULL
;
1974 phys_addr_t physicalAddress
;
1976 if (fStack
->AllocateChunk((void **)&descriptor
, &physicalAddress
,
1977 sizeof(ohci_isochronous_td
)) != B_OK
) {
1978 TRACE_ERROR("failed to allocate isochronous descriptor\n");
1982 descriptor
->physical_address
= (uint32
)physicalAddress
;
1983 descriptor
->next_physical_descriptor
= 0;
1984 descriptor
->next_logical_descriptor
= NULL
;
1985 descriptor
->next_done_descriptor
= NULL
;
1986 descriptor
->buffer_size
= bufferSize
;
1987 if (bufferSize
== 0) {
1988 descriptor
->buffer_page_byte_0
= 0;
1989 descriptor
->buffer_logical
= NULL
;
1990 descriptor
->last_byte_address
= 0;
1994 if (fStack
->AllocateChunk(&descriptor
->buffer_logical
,
1995 &physicalAddress
, bufferSize
) != B_OK
) {
1996 TRACE_ERROR("failed to allocate space for iso.buffer\n");
1997 fStack
->FreeChunk(descriptor
, descriptor
->physical_address
,
1998 sizeof(ohci_isochronous_td
));
2001 descriptor
->buffer_page_byte_0
= (uint32
)physicalAddress
;
2002 descriptor
->last_byte_address
2003 = descriptor
->buffer_page_byte_0
+ bufferSize
- 1;
2010 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td
*descriptor
)
2015 if (descriptor
->buffer_logical
) {
2016 fStack
->FreeChunk(descriptor
->buffer_logical
,
2017 descriptor
->buffer_page_byte_0
, descriptor
->buffer_size
);
2020 fStack
->FreeChunk((void *)descriptor
, descriptor
->physical_address
,
2021 sizeof(ohci_general_td
));
2026 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td
**_firstDescriptor
,
2027 ohci_isochronous_td
**_lastDescriptor
, Transfer
*transfer
)
2029 Pipe
*pipe
= transfer
->TransferPipe();
2030 usb_isochronous_data
*isochronousData
= transfer
->IsochronousData();
2032 size_t dataLength
= transfer
->VectorLength();
2033 size_t packet_count
= isochronousData
->packet_count
;
2035 if (packet_count
== 0) {
2036 TRACE_ERROR("isochronous packet_count should not be equal to zero.");
2040 size_t packetSize
= dataLength
/ packet_count
;
2041 if (dataLength
% packet_count
!= 0)
2044 if (packetSize
> pipe
->MaxPacketSize()) {
2045 TRACE_ERROR("isochronous packetSize %ld is bigger"
2046 " than pipe MaxPacketSize %ld.", packetSize
, pipe
->MaxPacketSize());
2050 uint16 bandwidth
= transfer
->Bandwidth() / packet_count
;
2051 if (transfer
->Bandwidth() % packet_count
!= 0)
2054 ohci_isochronous_td
*firstDescriptor
= NULL
;
2055 ohci_isochronous_td
*lastDescriptor
= *_firstDescriptor
;
2057 // the frame number currently processed by the host controller
2058 uint16 currentFrame
= fHcca
->current_frame_number
& 0xFFFF;
2059 uint16 safeFrames
= 5;
2061 // The entry where to start inserting the first Isochronous descriptor
2062 // real frame number may differ in case provided one has not bandwidth
2063 if (isochronousData
->flags
& USB_ISO_ASAP
||
2064 isochronousData
->starting_frame_number
== NULL
)
2065 // We should stay about 5-10 ms ahead of the controller
2066 // USB1 frame is equal to 1 ms
2067 currentFrame
+= safeFrames
;
2069 currentFrame
= *isochronousData
->starting_frame_number
;
2071 uint16 packets
= packet_count
;
2072 uint16 frameOffset
= 0;
2073 while (packets
> 0) {
2074 // look for up to 8 continous frames with available bandwidth
2075 uint16 frameCount
= 0;
2076 while (frameCount
< min_c(OHCI_ITD_NOFFSET
, packets
)
2077 && _AllocateIsochronousBandwidth(frameOffset
+ currentFrame
2078 + frameCount
, bandwidth
))
2081 if (frameCount
== 0) {
2082 // starting frame has no bandwidth for our transaction - try next
2083 if (++frameOffset
>= 0xFFFF) {
2084 TRACE_ERROR("failed to allocate bandwidth\n");
2085 _FreeIsochronousDescriptorChain(firstDescriptor
);
2091 ohci_isochronous_td
*descriptor
= _CreateIsochronousDescriptor(
2092 packetSize
* frameCount
);
2095 TRACE_ERROR("failed to allocate ITD\n");
2096 _ReleaseIsochronousBandwidth(currentFrame
+ frameOffset
, frameCount
);
2097 _FreeIsochronousDescriptorChain(firstDescriptor
);
2101 uint16 pageOffset
= descriptor
->buffer_page_byte_0
& 0xfff;
2102 descriptor
->buffer_page_byte_0
&= ~0xfff;
2103 for (uint16 i
= 0; i
< frameCount
; i
++) {
2104 descriptor
->offset
[OHCI_ITD_OFFSET_IDX(i
)]
2105 = OHCI_ITD_MK_OFFS(pageOffset
+ packetSize
* i
);
2108 descriptor
->flags
= OHCI_ITD_SET_FRAME_COUNT(frameCount
)
2109 | OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED
)
2110 | OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE
)
2111 | OHCI_ITD_SET_STARTING_FRAME(currentFrame
+ frameOffset
);
2113 // the last packet may be shorter than other ones in this transfer
2114 if (packets
<= OHCI_ITD_NOFFSET
)
2115 descriptor
->last_byte_address
2116 += dataLength
- packetSize
* (packet_count
);
2120 _LinkIsochronousDescriptors(lastDescriptor
, descriptor
, descriptor
);
2122 lastDescriptor
= descriptor
;
2123 if (!firstDescriptor
)
2124 firstDescriptor
= descriptor
;
2126 packets
-= frameCount
;
2128 frameOffset
+= frameCount
;
2130 if (packets
== 0 && isochronousData
->starting_frame_number
)
2131 *isochronousData
->starting_frame_number
= currentFrame
+ frameOffset
;
2134 *_firstDescriptor
= firstDescriptor
;
2135 *_lastDescriptor
= lastDescriptor
;
2142 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td
*topDescriptor
)
2144 ohci_isochronous_td
*current
= topDescriptor
;
2145 ohci_isochronous_td
*next
= NULL
;
2148 next
= (ohci_isochronous_td
*)current
->next_done_descriptor
;
2149 _FreeIsochronousDescriptor(current
);
2156 OHCI::_WriteDescriptorChain(ohci_general_td
*topDescriptor
, iovec
*vector
,
2159 ohci_general_td
*current
= topDescriptor
;
2160 size_t actualLength
= 0;
2161 size_t vectorIndex
= 0;
2162 size_t vectorOffset
= 0;
2163 size_t bufferOffset
= 0;
2166 if (!current
->buffer_logical
)
2170 size_t length
= min_c(current
->buffer_size
- bufferOffset
,
2171 vector
[vectorIndex
].iov_len
- vectorOffset
);
2173 TRACE("copying %ld bytes to bufferOffset %ld from"
2174 " vectorOffset %ld at index %ld of %ld\n", length
, bufferOffset
,
2175 vectorOffset
, vectorIndex
, vectorCount
);
2176 memcpy((uint8
*)current
->buffer_logical
+ bufferOffset
,
2177 (uint8
*)vector
[vectorIndex
].iov_base
+ vectorOffset
, length
);
2179 actualLength
+= length
;
2180 vectorOffset
+= length
;
2181 bufferOffset
+= length
;
2183 if (vectorOffset
>= vector
[vectorIndex
].iov_len
) {
2184 if (++vectorIndex
>= vectorCount
) {
2185 TRACE("wrote descriptor chain (%ld bytes, no"
2186 " more vectors)\n", actualLength
);
2187 return actualLength
;
2193 if (bufferOffset
>= current
->buffer_size
) {
2199 if (!current
->next_logical_descriptor
)
2202 current
= (ohci_general_td
*)current
->next_logical_descriptor
;
2205 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength
);
2206 return actualLength
;
2211 OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td
*topDescriptor
,
2212 iovec
*vector
, size_t vectorCount
)
2214 ohci_isochronous_td
*current
= topDescriptor
;
2215 size_t actualLength
= 0;
2216 size_t vectorIndex
= 0;
2217 size_t vectorOffset
= 0;
2218 size_t bufferOffset
= 0;
2221 if (!current
->buffer_logical
)
2225 size_t length
= min_c(current
->buffer_size
- bufferOffset
,
2226 vector
[vectorIndex
].iov_len
- vectorOffset
);
2228 TRACE("copying %ld bytes to bufferOffset %ld from"
2229 " vectorOffset %ld at index %ld of %ld\n", length
, bufferOffset
,
2230 vectorOffset
, vectorIndex
, vectorCount
);
2231 memcpy((uint8
*)current
->buffer_logical
+ bufferOffset
,
2232 (uint8
*)vector
[vectorIndex
].iov_base
+ vectorOffset
, length
);
2234 actualLength
+= length
;
2235 vectorOffset
+= length
;
2236 bufferOffset
+= length
;
2238 if (vectorOffset
>= vector
[vectorIndex
].iov_len
) {
2239 if (++vectorIndex
>= vectorCount
) {
2240 TRACE("wrote descriptor chain (%ld bytes, no"
2241 " more vectors)\n", actualLength
);
2242 return actualLength
;
2248 if (bufferOffset
>= current
->buffer_size
) {
2254 if (!current
->next_logical_descriptor
)
2257 current
= (ohci_isochronous_td
*)current
->next_logical_descriptor
;
2260 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength
);
2261 return actualLength
;
2266 OHCI::_ReadDescriptorChain(ohci_general_td
*topDescriptor
, iovec
*vector
,
2269 ohci_general_td
*current
= topDescriptor
;
2270 size_t actualLength
= 0;
2271 size_t vectorIndex
= 0;
2272 size_t vectorOffset
= 0;
2273 size_t bufferOffset
= 0;
2275 while (current
&& OHCI_TD_GET_CONDITION_CODE(current
->flags
)
2276 != OHCI_TD_CONDITION_NOT_ACCESSED
) {
2277 if (!current
->buffer_logical
)
2280 size_t bufferSize
= current
->buffer_size
;
2281 if (current
->buffer_physical
!= 0) {
2282 bufferSize
-= current
->last_physical_byte_address
2283 - current
->buffer_physical
+ 1;
2287 size_t length
= min_c(bufferSize
- bufferOffset
,
2288 vector
[vectorIndex
].iov_len
- vectorOffset
);
2290 TRACE("copying %ld bytes to vectorOffset %ld from"
2291 " bufferOffset %ld at index %ld of %ld\n", length
, vectorOffset
,
2292 bufferOffset
, vectorIndex
, vectorCount
);
2293 memcpy((uint8
*)vector
[vectorIndex
].iov_base
+ vectorOffset
,
2294 (uint8
*)current
->buffer_logical
+ bufferOffset
, length
);
2296 actualLength
+= length
;
2297 vectorOffset
+= length
;
2298 bufferOffset
+= length
;
2300 if (vectorOffset
>= vector
[vectorIndex
].iov_len
) {
2301 if (++vectorIndex
>= vectorCount
) {
2302 TRACE("read descriptor chain (%ld bytes, no more vectors)\n",
2304 return actualLength
;
2310 if (bufferOffset
>= bufferSize
) {
2316 current
= (ohci_general_td
*)current
->next_logical_descriptor
;
2319 TRACE("read descriptor chain (%ld bytes)\n", actualLength
);
2320 return actualLength
;
2325 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td
*topDescriptor
,
2326 iovec
*vector
, size_t vectorCount
)
2328 ohci_isochronous_td
*current
= topDescriptor
;
2329 size_t actualLength
= 0;
2330 size_t vectorIndex
= 0;
2331 size_t vectorOffset
= 0;
2332 size_t bufferOffset
= 0;
2334 while (current
&& OHCI_ITD_GET_CONDITION_CODE(current
->flags
)
2335 != OHCI_ITD_CONDITION_NOT_ACCESSED
) {
2336 size_t bufferSize
= current
->buffer_size
;
2337 if (current
->buffer_logical
!= NULL
&& bufferSize
> 0) {
2339 size_t length
= min_c(bufferSize
- bufferOffset
,
2340 vector
[vectorIndex
].iov_len
- vectorOffset
);
2342 TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset"
2343 " %ld at index %ld of %ld\n", length
, vectorOffset
,
2344 bufferOffset
, vectorIndex
, vectorCount
);
2345 memcpy((uint8
*)vector
[vectorIndex
].iov_base
+ vectorOffset
,
2346 (uint8
*)current
->buffer_logical
+ bufferOffset
, length
);
2348 actualLength
+= length
;
2349 vectorOffset
+= length
;
2350 bufferOffset
+= length
;
2352 if (vectorOffset
>= vector
[vectorIndex
].iov_len
) {
2353 if (++vectorIndex
>= vectorCount
) {
2354 TRACE("read descriptor chain (%ld bytes, "
2355 "no more vectors)\n", actualLength
);
2362 if (bufferOffset
>= bufferSize
) {
2369 current
= (ohci_isochronous_td
*)current
->next_done_descriptor
;
2372 TRACE("read descriptor chain (%ld bytes)\n", actualLength
);
2378 OHCI::_ReadActualLength(ohci_general_td
*topDescriptor
)
2380 ohci_general_td
*current
= topDescriptor
;
2381 size_t actualLength
= 0;
2383 while (current
&& OHCI_TD_GET_CONDITION_CODE(current
->flags
)
2384 != OHCI_TD_CONDITION_NOT_ACCESSED
) {
2385 size_t length
= current
->buffer_size
;
2386 if (current
->buffer_physical
!= 0) {
2387 length
-= current
->last_physical_byte_address
2388 - current
->buffer_physical
+ 1;
2391 actualLength
+= length
;
2392 current
= (ohci_general_td
*)current
->next_logical_descriptor
;
2395 TRACE("read actual length (%ld bytes)\n", actualLength
);
2396 return actualLength
;
2401 OHCI::_LinkDescriptors(ohci_general_td
*first
, ohci_general_td
*second
)
2403 first
->next_physical_descriptor
= second
->physical_address
;
2404 first
->next_logical_descriptor
= second
;
2409 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td
*first
,
2410 ohci_isochronous_td
*second
, ohci_isochronous_td
*nextDone
)
2412 first
->next_physical_descriptor
= second
->physical_address
;
2413 first
->next_logical_descriptor
= second
;
2414 first
->next_done_descriptor
= nextDone
;
2419 OHCI::_AllocateIsochronousBandwidth(uint16 frame
, uint16 size
)
2421 frame
%= NUMBER_OF_FRAMES
;
2422 if (size
> fFrameBandwidth
[frame
])
2425 fFrameBandwidth
[frame
]-= size
;
2431 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame
, uint16 frameCount
)
2433 for (size_t index
= 0; index
< frameCount
; index
++) {
2434 uint16 frame
= (startFrame
+ index
) % NUMBER_OF_FRAMES
;
2435 fFrameBandwidth
[frame
] = MAX_AVAILABLE_BANDWIDTH
;
2441 OHCI::_GetStatusOfConditionCode(uint8 conditionCode
)
2443 switch (conditionCode
) {
2444 case OHCI_TD_CONDITION_NO_ERROR
:
2447 case OHCI_TD_CONDITION_CRC_ERROR
:
2448 case OHCI_TD_CONDITION_BIT_STUFFING
:
2449 case OHCI_TD_CONDITION_TOGGLE_MISMATCH
:
2450 return B_DEV_CRC_ERROR
;
2452 case OHCI_TD_CONDITION_STALL
:
2453 return B_DEV_STALLED
;
2455 case OHCI_TD_CONDITION_NO_RESPONSE
:
2458 case OHCI_TD_CONDITION_PID_CHECK_FAILURE
:
2459 return B_DEV_BAD_PID
;
2461 case OHCI_TD_CONDITION_UNEXPECTED_PID
:
2462 return B_DEV_UNEXPECTED_PID
;
2464 case OHCI_TD_CONDITION_DATA_OVERRUN
:
2465 return B_DEV_DATA_OVERRUN
;
2467 case OHCI_TD_CONDITION_DATA_UNDERRUN
:
2468 return B_DEV_DATA_UNDERRUN
;
2470 case OHCI_TD_CONDITION_BUFFER_OVERRUN
:
2471 return B_DEV_FIFO_OVERRUN
;
2473 case OHCI_TD_CONDITION_BUFFER_UNDERRUN
:
2474 return B_DEV_FIFO_UNDERRUN
;
2476 case OHCI_TD_CONDITION_NOT_ACCESSED
:
2477 return B_DEV_PENDING
;
2480 return B_DEV_TOO_LATE
; // PSW: _NOT_ACCESSED
2491 OHCI::_LockEndpoints()
2493 return (mutex_lock(&fEndpointLock
) == B_OK
);
2498 OHCI::_UnlockEndpoints()
2500 mutex_unlock(&fEndpointLock
);
2505 OHCI::_WriteReg(uint32 reg
, uint32 value
)
2507 *(volatile uint32
*)(fOperationalRegisters
+ reg
) = value
;
2512 OHCI::_ReadReg(uint32 reg
)
2514 return *(volatile uint32
*)(fOperationalRegisters
+ reg
);
2519 OHCI::_PrintEndpoint(ohci_endpoint_descriptor
*endpoint
)
2521 dprintf("endpoint %p\n", endpoint
);
2522 dprintf("\tflags........... 0x%08" B_PRIx32
"\n", endpoint
->flags
);
2523 dprintf("\ttail_physical... 0x%08" B_PRIx32
"\n", endpoint
->tail_physical_descriptor
);
2524 dprintf("\thead_physical... 0x%08" B_PRIx32
"\n", endpoint
->head_physical_descriptor
);
2525 dprintf("\tnext_physical... 0x%08" B_PRIx32
"\n", endpoint
->next_physical_endpoint
);
2526 dprintf("\tphysical........ 0x%08" B_PRIx32
"\n", endpoint
->physical_address
);
2527 dprintf("\ttail_logical.... %p\n", endpoint
->tail_logical_descriptor
);
2528 dprintf("\tnext_logical.... %p\n", endpoint
->next_logical_endpoint
);
2533 OHCI::_PrintDescriptorChain(ohci_general_td
*topDescriptor
)
2535 while (topDescriptor
) {
2536 dprintf("descriptor %p\n", topDescriptor
);
2537 dprintf("\tflags........... 0x%08" B_PRIx32
"\n", topDescriptor
->flags
);
2538 dprintf("\tbuffer_physical. 0x%08" B_PRIx32
"\n", topDescriptor
->buffer_physical
);
2539 dprintf("\tnext_physical... 0x%08" B_PRIx32
"\n", topDescriptor
->next_physical_descriptor
);
2540 dprintf("\tlast_byte....... 0x%08" B_PRIx32
"\n", topDescriptor
->last_physical_byte_address
);
2541 dprintf("\tphysical........ 0x%08" B_PRIx32
"\n", topDescriptor
->physical_address
);
2542 dprintf("\tbuffer_size..... %lu\n", topDescriptor
->buffer_size
);
2543 dprintf("\tbuffer_logical.. %p\n", topDescriptor
->buffer_logical
);
2544 dprintf("\tnext_logical.... %p\n", topDescriptor
->next_logical_descriptor
);
2546 topDescriptor
= (ohci_general_td
*)topDescriptor
->next_logical_descriptor
;
2552 OHCI::_PrintDescriptorChain(ohci_isochronous_td
*topDescriptor
)
2554 while (topDescriptor
) {
2555 dprintf("iso.descriptor %p\n", topDescriptor
);
2556 dprintf("\tflags........... 0x%08" B_PRIx32
"\n", topDescriptor
->flags
);
2557 dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32
"\n", topDescriptor
->buffer_page_byte_0
);
2558 dprintf("\tnext_physical... 0x%08" B_PRIx32
"\n", topDescriptor
->next_physical_descriptor
);
2559 dprintf("\tlast_byte....... 0x%08" B_PRIx32
"\n", topDescriptor
->last_byte_address
);
2560 dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n"
2561 "\t0x%04x 0x%04x 0x%04x 0x%04x\n",
2562 topDescriptor
->offset
[0], topDescriptor
->offset
[1],
2563 topDescriptor
->offset
[2], topDescriptor
->offset
[3],
2564 topDescriptor
->offset
[4], topDescriptor
->offset
[5],
2565 topDescriptor
->offset
[6], topDescriptor
->offset
[7]);
2566 dprintf("\tphysical........ 0x%08" B_PRIx32
"\n", topDescriptor
->physical_address
);
2567 dprintf("\tbuffer_size..... %lu\n", topDescriptor
->buffer_size
);
2568 dprintf("\tbuffer_logical.. %p\n", topDescriptor
->buffer_logical
);
2569 dprintf("\tnext_logical.... %p\n", topDescriptor
->next_logical_descriptor
);
2570 dprintf("\tnext_done....... %p\n", topDescriptor
->next_done_descriptor
);
2572 topDescriptor
= (ohci_isochronous_td
*)topDescriptor
->next_done_descriptor
;