2 Copyright © 2010-2013, The AROS Development Team. All rights reserved
6 /* Enable debug level 1000, keeps an eye on TD DoneQueue consistency */
10 #include <proto/exec.h>
11 #include <proto/oop.h>
13 #include <devices/usb_hub.h>
18 #include "ohciproto.h"
20 #undef HiddPCIDeviceAttrBase
21 #define HiddPCIDeviceAttrBase (hd->hd_HiddPCIDeviceAB)
23 #define HiddAttrBase (hd->hd_HiddAB)
27 static void PrintTD(const char *txt
, ULONG ptd
, struct PCIController
*hc
)
29 KPrintF("HC 0x%p %s TD list:", hc
, txt
);
33 struct OhciTD
*otd
= (struct OhciTD
*)((IPTR
)ptd
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
35 KPrintF(" 0x%p", otd
);
36 ptd
= READMEM32_LE(&otd
->otd_NextTD
);
42 #define PrintTD(txt, ptd, hc)
47 static void PrintED(const char *txt
, struct OhciED
*oed
, struct PCIController
*hc
)
51 KPrintF("%s ED 0x%p: EPCaps=%08lx, HeadPtr=%08lx, TailPtr=%08lx, NextED=%08lx\n", txt
, oed
,
52 READMEM32_LE(&oed
->oed_EPCaps
),
53 READMEM32_LE(&oed
->oed_HeadPtr
),
54 READMEM32_LE(&oed
->oed_TailPtr
),
55 READMEM32_LE(&oed
->oed_NextED
));
57 KPrintF("...TD list:", hc
, txt
, oed
);
58 for (otd
= oed
->oed_FirstTD
; otd
; otd
= otd
->otd_Succ
)
59 KPrintF(" 0x%p", otd
);
64 #define PrintED(txt, oed, hc)
67 static AROS_INTH1(OhciResetHandler
, struct PCIController
*, hc
)
72 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, OCSF_HCRESET
);
79 static void ohciFreeTDChain(struct PCIController
*hc
, struct OhciTD
*nextotd
)
85 KPRINTF(1, ("FreeTD %p\n", nextotd
));
87 nextotd
= (struct OhciTD
*) otd
->otd_Succ
;
92 static void ohciFreeEDContext(struct PCIController
*hc
, struct IOUsbHWReq
*ioreq
)
94 struct PCIUnit
*unit
= hc
->hc_Unit
;
95 struct OhciED
*oed
= ioreq
->iouh_DriverPrivate1
;
99 KPRINTF(5, ("Freeing EDContext 0x%p IOReq 0x%p\n", oed
, ioreq
));
101 if (ioreq
->iouh_Req
.io_Command
== UHCMD_CONTROLXFER
)
102 dir
= (ioreq
->iouh_SetupData
.bmRequestType
& URTF_IN
) ? UHDIR_IN
: UHDIR_OUT
;
104 dir
= ioreq
->iouh_Dir
;
106 usbReleaseBuffer(oed
->oed_Buffer
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
, dir
);
107 usbReleaseBuffer(oed
->oed_SetupData
, &ioreq
->iouh_SetupData
, 8, UHDIR_IN
);
109 devadrep
= (ioreq
->iouh_DevAddr
<<5) + ioreq
->iouh_Endpoint
+ ((ioreq
->iouh_Dir
== UHDIR_IN
) ? 0x10 : 0);
110 unit
->hu_DevBusyReq
[devadrep
] = NULL
;
111 unit
->hu_DevDataToggle
[devadrep
] = (READMEM32_LE(&oed
->oed_HeadPtr
) & OEHF_DATA1
) ? TRUE
: FALSE
;
114 ohciFreeTDChain(hc
, oed
->oed_FirstTD
);
119 static void ohciUpdateIntTree(struct PCIController
*hc
)
122 struct OhciED
*predoed
;
123 struct OhciED
*lastusedoed
;
126 // optimize linkage between queue heads
127 predoed
= lastusedoed
= hc
->hc_OhciTermED
;
128 for(cnt
= 0; cnt
< 5; cnt
++)
130 oed
= hc
->hc_OhciIntED
[cnt
];
131 if(oed
->oed_Succ
!= predoed
)
133 lastusedoed
= oed
->oed_Succ
;
135 oed
->oed_NextED
= lastusedoed
->oed_Self
;
136 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_ClearD
);
141 static void ohciHandleFinishedTDs(struct PCIController
*hc
)
143 struct IOUsbHWReq
*ioreq
;
144 struct IOUsbHWReq
*nextioreq
;
145 struct OhciED
*oed
= NULL
;
151 BOOL updatetree
= FALSE
;
152 ULONG donehead
, nexttd
;
155 KPRINTF(1, ("Checking for work done...\n"));
157 donehead
= hc
->hc_OhciDoneQueue
;
158 hc
->hc_OhciDoneQueue
= 0UL;
162 KPRINTF(1, ("Nothing to do!\n"));
165 otd
= (struct OhciTD
*) ((IPTR
)donehead
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
166 KPRINTF(10, ("DoneHead=%08lx, OTD=%p, Frame=%ld\n", donehead
, otd
, READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
)));
167 PrintTD("Done", donehead
, hc
); /* CHECKME: This can give inconsistent printout on cache-incoherent hardware */
170 CacheClearE(&otd
->otd_Ctrl
, 16, CACRF_InvalidateD
);
175 * WATCH OUT!!! Rogue TD is a very bad thing!!!
176 * If you see this, there's definitely a bug in DoneQueue processing flow.
177 * See below for the complete description.
179 KPRINTF(1000, ("Came across a rogue TD 0x%p that already has been freed!\n", otd
));
180 nexttd
= READMEM32_LE(&otd
->otd_NextTD
) & OHCI_PTRMASK
;
185 otd
= (struct OhciTD
*) ((IPTR
)nexttd
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
188 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_InvalidateD
);
189 ctrlstatus
= READMEM32_LE(&otd
->otd_Ctrl
);
190 KPRINTF(1, ("TD: %08lx - %08lx\n", READMEM32_LE(&otd
->otd_BufferPtr
),
191 READMEM32_LE(&otd
->otd_BufferEnd
)));
192 if(otd
->otd_BufferPtr
)
194 // FIXME this will blow up if physical memory is ever going to be discontinuous
195 len
= READMEM32_LE(&otd
->otd_BufferPtr
) - (READMEM32_LE(&otd
->otd_BufferEnd
) + 1 - otd
->otd_Length
);
197 len
= otd
->otd_Length
;
200 ioreq
= oed
->oed_IOReq
;
202 KPRINTF(1, ("Examining TD %p for ED %p (IOReq=%p), Status %08lx, len=%ld\n", otd
, oed
, ioreq
, ctrlstatus
, len
));
205 /* You should never see this (very weird inconsistency), but who knows... */
206 KPRINTF(1000, ("Came across a rogue ED 0x%p that already has been replied! TD 0x%p,\n", oed
, otd
));
207 nexttd
= READMEM32_LE(&otd
->otd_NextTD
) & OHCI_PTRMASK
;
212 otd
= (struct OhciTD
*) ((IPTR
)nexttd
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
218 epcaps
= READMEM32_LE(&oed
->oed_EPCaps
);
219 direction_in
= ((epcaps
& OECM_DIRECTION
) == OECF_DIRECTION_TD
)
220 ? (ioreq
->iouh_SetupData
.bmRequestType
& URTF_IN
)
221 : (epcaps
& OECF_DIRECTION_IN
);
222 CachePostDMA((APTR
)(IPTR
)READMEM32_LE(&otd
->otd_BufferEnd
) - len
+ 1, &len
, direction_in
? 0 : DMA_ReadFromRAM
);
225 ioreq
->iouh_Actual
+= len
;
227 * CHECKME: This condition may get triggered on control transfers even if terminating TD is not processed yet.
228 * (got triggered by MacMini's keyboard, when someone sends control ED with no data payload,
229 * and some other ED is being done meanwhile (its final packet generated an interrupt).
230 * In this case the given control ED can be partially done (setup TD is done, term TD is not).
231 * iouh_Length is 0, and the whole ED is retired, while still being processed by the HC. Next time
232 * its terminator TD arrives into done queue.
233 * This can cause weird things like looping TD list on itself. My modification of ohciFreeTD()
234 * explicitly clears NextTD to avoid keeping dangling value there, however the problem still can
235 * appear if this TD is quickly reused by another request.
236 * Final TDs have OTCM_DELAYINT fields set to zero. HC processes TDs in order, so if we receive
237 * the final TD, we assume the whole ED's list has been processed.
238 * This means it should be safe to simply disable this check.
239 * If this doesn't work for some reason, we need a more complex check which makes sure that all TDs
240 * are really done (or ED is halted). This can be done by checking OTCM_COMPLETIONCODE field against
241 * OTCF_CC_INVALID value.
242 * Pavel Fedin <pavel.fedin@mail.ru>
243 retire = (ioreq->iouh_Actual == ioreq->iouh_Length);
246 KPRINTF(10, ("TD 0x%p Data transfer done (%lu bytes)\n", otd, ioreq->iouh_Length));
249 if((ctrlstatus
& OTCM_DELAYINT
) != OTCF_NOINT
)
251 KPRINTF(10, ("TD 0x%p Terminator detected\n", otd
));
254 switch((ctrlstatus
& OTCM_COMPLETIONCODE
)>>OTCS_COMPLETIONCODE
)
256 case (OTCF_CC_NOERROR
>>OTCS_COMPLETIONCODE
):
259 case (OTCF_CC_CRCERROR
>>OTCS_COMPLETIONCODE
):
260 KPRINTF(200, ("CRC Error!\n"));
261 ioreq
->iouh_Req
.io_Error
= UHIOERR_CRCERROR
;
263 * CHECKME: Do we really need to set retire flag here?
264 * Critical errors are always accompanied by OEHF_HALTED bit.
265 * But what if HC thinks it's recoverable error and continues
266 * working on this ED? In this case early retirement happens,
267 * causing bad things. See long explanation above.
272 case (OTCF_CC_BABBLE
>>OTCS_COMPLETIONCODE
):
273 KPRINTF(200, ("Babble/Bitstuffing Error!\n"));
274 ioreq
->iouh_Req
.io_Error
= UHIOERR_CRCERROR
;
278 case (OTCF_CC_WRONGTOGGLE
>>OTCS_COMPLETIONCODE
):
279 KPRINTF(200, ("Data toggle mismatch length = %ld\n", len
));
282 case (OTCF_CC_STALL
>>OTCS_COMPLETIONCODE
):
283 KPRINTF(200, ("STALLED!\n"));
284 ioreq
->iouh_Req
.io_Error
= UHIOERR_STALL
;
288 case (OTCF_CC_TIMEOUT
>>OTCS_COMPLETIONCODE
):
289 KPRINTF(200, ("TIMEOUT!\n"));
290 ioreq
->iouh_Req
.io_Error
= UHIOERR_TIMEOUT
;
294 case (OTCF_CC_PIDCORRUPT
>>OTCS_COMPLETIONCODE
):
295 KPRINTF(200, ("PID Error!\n"));
296 ioreq
->iouh_Req
.io_Error
= UHIOERR_CRCERROR
;
300 case (OTCF_CC_WRONGPID
>>OTCS_COMPLETIONCODE
):
301 KPRINTF(200, ("Illegal PID!\n"));
302 ioreq
->iouh_Req
.io_Error
= UHIOERR_CRCERROR
;
306 case (OTCF_CC_OVERFLOW
>>OTCS_COMPLETIONCODE
):
307 KPRINTF(200, ("Overflow Error!\n"));
308 ioreq
->iouh_Req
.io_Error
= UHIOERR_OVERFLOW
;
312 case (OTCF_CC_SHORTPKT
>>OTCS_COMPLETIONCODE
):
313 KPRINTF(10, ("Short packet %ld < %ld\n", len
, otd
->otd_Length
));
314 if((!ioreq
->iouh_Req
.io_Error
) && (!(ioreq
->iouh_Flags
& UHFF_ALLOWRUNTPKTS
)))
316 ioreq
->iouh_Req
.io_Error
= UHIOERR_RUNTPACKET
;
321 case (OTCF_CC_OVERRUN
>>OTCS_COMPLETIONCODE
):
322 KPRINTF(200, ("Data Overrun Error!\n"));
323 ioreq
->iouh_Req
.io_Error
= UHIOERR_HOSTERROR
;
327 case (OTCF_CC_UNDERRUN
>>OTCS_COMPLETIONCODE
):
328 KPRINTF(200, ("Data Underrun Error!\n"));
329 ioreq
->iouh_Req
.io_Error
= UHIOERR_HOSTERROR
;
333 case (OTCF_CC_INVALID
>>OTCS_COMPLETIONCODE
):
334 KPRINTF(200, ("Not touched?!?\n"));
337 if(READMEM32_LE(&oed
->oed_HeadPtr
) & OEHF_HALTED
)
339 KPRINTF(100, ("OED halted!\n"));
345 KPRINTF(50, ("ED 0x%p stopped at TD 0x%p\n", oed
, otd
));
346 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
347 AddHead(&hc
->hc_OhciRetireQueue
, &ioreq
->iouh_Req
.io_Message
.mn_Node
);
350 nexttd
= READMEM32_LE(&otd
->otd_NextTD
) & OHCI_PTRMASK
;
351 KPRINTF(1, ("NextTD=0x%08lx\n", nexttd
));
356 otd
= (struct OhciTD
*) ((IPTR
)nexttd
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
357 KPRINTF(1, ("NextOTD = %p\n", otd
));
360 ioreq
= (struct IOUsbHWReq
*) hc
->hc_OhciRetireQueue
.lh_Head
;
361 while((nextioreq
= (struct IOUsbHWReq
*) ((struct Node
*) ioreq
)->ln_Succ
))
363 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
364 oed
= (struct OhciED
*) ioreq
->iouh_DriverPrivate1
;
367 KPRINTF(50, ("HC 0x%p Retiring IOReq=0x%p Command=%ld ED=0x%p, Frame=%ld\n", hc
, ioreq
, ioreq
->iouh_Req
.io_Command
, oed
, READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
)));
369 if(oed
->oed_Continue
)
371 ULONG actual
= ioreq
->iouh_Actual
;
374 struct OhciTD
*predotd
= NULL
;
376 KPRINTF(10, ("Reloading Bulk transfer at %ld of %ld\n", ioreq
->iouh_Actual
, ioreq
->iouh_Length
));
377 otd
= oed
->oed_FirstTD
;
379 phyaddr
= (IPTR
)pciGetPhysical(hc
, oed
->oed_Buffer
+ actual
);
382 len
= ioreq
->iouh_Length
- actual
;
383 if(len
> OHCI_PAGE_SIZE
)
385 len
= OHCI_PAGE_SIZE
;
387 if((!otd
->otd_Succ
) && (actual
+ len
== ioreq
->iouh_Length
) && (!(ioreq
->iouh_Flags
& UHFF_NOSHORTPKT
)) && ((actual
% ioreq
->iouh_MaxPktSize
) == 0))
389 // special case -- zero padding would not fit in this run,
390 // and next time, we would forget about it. So rather abort
391 // reload now, so the zero padding goes with the next reload
395 otd
->otd_Length
= len
;
396 KPRINTF(1, ("TD with %ld bytes: %08x-%08x\n", len
, phyaddr
, phyaddr
+len
-1));
397 CONSTWRITEMEM32_LE(&otd
->otd_Ctrl
, OTCF_CC_INVALID
|OTCF_NOINT
);
400 otd
->otd_NextTD
= otd
->otd_Succ
->otd_Self
;
404 WRITEMEM32_LE(&otd
->otd_BufferPtr
, (IPTR
)CachePreDMA((APTR
)(IPTR
)phyaddr
, &len
, (ioreq
->iouh_Dir
== UHDIR_IN
) ? 0 : DMA_ReadFromRAM
));
406 WRITEMEM32_LE(&otd
->otd_BufferEnd
, phyaddr
);
409 CONSTWRITEMEM32_LE(&otd
->otd_BufferPtr
, 0);
410 CONSTWRITEMEM32_LE(&otd
->otd_BufferEnd
, 0);
412 CacheClearE(&otd
->otd_Ctrl
, 16, CACRF_ClearD
);
415 } while(otd
&& ((actual
< ioreq
->iouh_Length
) || (len
&& (ioreq
->iouh_Dir
== UHDIR_OUT
) && (actual
== ioreq
->iouh_Length
) && (!(ioreq
->iouh_Flags
& UHFF_NOSHORTPKT
)) && ((actual
% ioreq
->iouh_MaxPktSize
) == 0))));
416 oed
->oed_Continue
= (actual
< ioreq
->iouh_Length
);
417 predotd
->otd_NextTD
= hc
->hc_OhciTermTD
->otd_Self
;
419 CONSTWRITEMEM32_LE(&predotd
->otd_Ctrl
, OTCF_CC_INVALID
);
420 CacheClearE(&predotd
->otd_Ctrl
, 16, CACRF_ClearD
);
423 AddTail(&hc
->hc_TDQueue
, &ioreq
->iouh_Req
.io_Message
.mn_Node
);
426 ctrlstatus
= READMEM32_LE(&oed
->oed_HeadPtr
) & OEHF_DATA1
;
427 ctrlstatus
|= READMEM32_LE(&oed
->oed_FirstTD
->otd_Self
);
428 WRITEMEM32_LE(&oed
->oed_HeadPtr
, ctrlstatus
);
429 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_ClearD
);
431 PrintED("Continued bulk", oed
, hc
);
433 oldenables
= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
434 oldenables
|= OCSF_BULKENABLE
;
435 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, oldenables
);
441 PrintED("Completed", oed
, hc
);
443 ohciFreeEDContext(hc
, ioreq
);
444 if(ioreq
->iouh_Req
.io_Command
== UHCMD_INTXFER
)
448 // check for successful clear feature and set address ctrl transfers
449 if((!ioreq
->iouh_Req
.io_Error
) && (ioreq
->iouh_Req
.io_Command
== UHCMD_CONTROLXFER
))
451 uhwCheckSpecialCtrlTransfers(hc
, ioreq
);
453 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
456 KPRINTF(20, ("IOReq=%p has no OED!\n", ioreq
));
462 ohciUpdateIntTree(hc
);
466 static ULONG
ohciHandleAbortedEDs(struct PCIController
*hc
)
468 struct IOUsbHWReq
*ioreq
;
469 ULONG restartmask
= 0;
471 KPRINTF(50, ("Processing abort queue...\n"));
473 // We don't need this any more
474 ohciDisableInt(hc
, OISF_SOF
);
477 * If the aborted IORequest was replied in ohciHandleFinishedTDs(),
478 * it was already Remove()d from this queue. It's safe to do no checks.
479 * io_Error was set earlier.
481 while ((ioreq
= (struct IOUsbHWReq
*)RemHead(&hc
->hc_AbortQueue
)))
483 KPRINTF(70, ("HC 0x%p Aborted IOReq 0x%p\n", hc
, ioreq
));
484 PrintED("Aborted", ioreq
->iouh_DriverPrivate1
, hc
);
486 ohciFreeEDContext(hc
, ioreq
);
487 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
490 /* Restart stopped queues */
491 if (hc
->hc_Flags
& HCF_STOP_CTRL
)
493 KPRINTF(50, ("Restarting control transfers\n"));
494 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CTRL_ED
, 0);
495 restartmask
|= OCSF_CTRLENABLE
;
498 if (hc
->hc_Flags
& HCF_STOP_BULK
)
500 KPRINTF(50, ("Restarting bulk transfers\n"));
501 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_BULK_ED
, 0);
502 restartmask
|= OCSF_BULKENABLE
;
505 /* Everything is enabled again, aborting done */
506 hc
->hc_Flags
&= ~(HCF_STOP_CTRL
| HCF_STOP_BULK
| HCF_ABORT
);
508 /* We will accumulate flags and start queues only once, when everything is set up */
512 static ULONG
ohciScheduleCtrlTDs(struct PCIController
*hc
)
514 struct PCIUnit
*unit
= hc
->hc_Unit
;
515 struct IOUsbHWReq
*ioreq
;
518 struct OhciTD
*setupotd
;
519 struct OhciTD
*dataotd
;
520 struct OhciTD
*termotd
;
521 struct OhciTD
*predotd
;
530 /* *** CTRL Transfers *** */
531 KPRINTF(1, ("Scheduling new CTRL transfers...\n"));
532 ioreq
= (struct IOUsbHWReq
*) hc
->hc_CtrlXFerQueue
.lh_Head
;
533 while(((struct Node
*) ioreq
)->ln_Succ
)
535 devadrep
= (ioreq
->iouh_DevAddr
<<5) + ioreq
->iouh_Endpoint
;
536 KPRINTF(10, ("New CTRL transfer to %ld.%ld: %ld bytes\n", ioreq
->iouh_DevAddr
, ioreq
->iouh_Endpoint
, ioreq
->iouh_Length
));
537 /* is endpoint already in use or do we have to wait for next transaction */
538 if(unit
->hu_DevBusyReq
[devadrep
])
540 KPRINTF(5, ("Endpoint %02lx in use!\n", devadrep
));
541 ioreq
= (struct IOUsbHWReq
*) ((struct Node
*) ioreq
)->ln_Succ
;
545 oed
= ohciAllocED(hc
);
551 setupotd
= ohciAllocTD(hc
);
557 termotd
= ohciAllocTD(hc
);
560 ohciFreeTD(hc
, setupotd
);
564 oed
->oed_IOReq
= ioreq
;
566 KPRINTF(1, ("SetupTD=%p, TermTD=%p\n", setupotd
, termotd
));
569 epcaps
= (ioreq
->iouh_DevAddr
<<OECS_DEVADDR
)|(ioreq
->iouh_Endpoint
<<OECS_ENDPOINT
)|(ioreq
->iouh_MaxPktSize
<<OECS_MAXPKTLEN
)|OECF_DIRECTION_TD
;
571 if(ioreq
->iouh_Flags
& UHFF_LOWSPEED
)
573 KPRINTF(5, ("*** LOW SPEED ***\n"));
574 epcaps
|= OECF_LOWSPEED
;
577 WRITEMEM32_LE(&oed
->oed_EPCaps
, epcaps
);
579 oed
->oed_TailPtr
= hc
->hc_OhciTermTD
->otd_Self
;
580 oed
->oed_HeadPtr
= setupotd
->otd_Self
;
581 oed
->oed_FirstTD
= setupotd
;
583 setupotd
->otd_ED
= oed
;
584 setupotd
->otd_Length
= 0; // don't increase io_Actual for that transfer
585 CONSTWRITEMEM32_LE(&setupotd
->otd_Ctrl
, OTCF_PIDCODE_SETUP
|OTCF_CC_INVALID
|OTCF_NOINT
);
588 /* CHECKME: As i can understand, setup packet is always sent TO the device. Is this true? */
589 oed
->oed_SetupData
= usbGetBuffer(&ioreq
->iouh_SetupData
, len
, UHDIR_OUT
);
590 WRITEMEM32_LE(&setupotd
->otd_BufferPtr
, (IPTR
) CachePreDMA(pciGetPhysical(hc
, oed
->oed_SetupData
), &len
, DMA_ReadFromRAM
));
591 WRITEMEM32_LE(&setupotd
->otd_BufferEnd
, (IPTR
) pciGetPhysical(hc
, ((UBYTE
*)oed
->oed_SetupData
) + 7));
593 KPRINTF(1, ("TD send: %08lx - %08lx\n", READMEM32_LE(&setupotd
->otd_BufferPtr
),
594 READMEM32_LE(&setupotd
->otd_BufferEnd
)));
596 ctrl
= (ioreq
->iouh_SetupData
.bmRequestType
& URTF_IN
) ? (OTCF_PIDCODE_IN
|OTCF_CC_INVALID
|OTCF_NOINT
) : (OTCF_PIDCODE_OUT
|OTCF_CC_INVALID
|OTCF_NOINT
);
599 if (ioreq
->iouh_Length
)
601 oed
->oed_Buffer
= usbGetBuffer(ioreq
->iouh_Data
, ioreq
->iouh_Length
, (ioreq
->iouh_SetupData
.bmRequestType
& URTF_IN
) ? UHDIR_IN
: UHDIR_OUT
);
602 phyaddr
= (IPTR
)pciGetPhysical(hc
, oed
->oed_Buffer
);
606 dataotd
= ohciAllocTD(hc
);
609 predotd
->otd_Succ
= NULL
;
612 dataotd
->otd_ED
= oed
;
613 predotd
->otd_Succ
= dataotd
;
614 predotd
->otd_NextTD
= dataotd
->otd_Self
;
615 len
= ioreq
->iouh_Length
- actual
;
616 if(len
> OHCI_PAGE_SIZE
)
618 len
= OHCI_PAGE_SIZE
;
620 dataotd
->otd_Length
= len
;
621 KPRINTF(1, ("TD with %ld bytes\n", len
));
622 WRITEMEM32_LE(&dataotd
->otd_Ctrl
, ctrl
);
624 * CHECKME: Here and there we feed phyaddr to CachePreDMA(), however it expects a logical address.
625 * Perhaps the whole thing works only because HIDD_PCIDriver_CPUtoPCI() actually doesn't do any
628 WRITEMEM32_LE(&dataotd
->otd_BufferPtr
, (IPTR
)CachePreDMA((APTR
)(IPTR
)phyaddr
, &len
, (ioreq
->iouh_SetupData
.bmRequestType
& URTF_IN
) ? 0 : DMA_ReadFromRAM
));
630 WRITEMEM32_LE(&dataotd
->otd_BufferEnd
, phyaddr
);
632 KPRINTF(1, ("TD send: %08lx - %08lx\n", READMEM32_LE(&dataotd
->otd_BufferPtr
),
633 READMEM32_LE(&dataotd
->otd_BufferEnd
)));
635 CacheClearE(&dataotd
->otd_Ctrl
, 16, CACRF_ClearD
);
639 } while(actual
< ioreq
->iouh_Length
);
641 if(actual
!= ioreq
->iouh_Length
)
644 KPRINTF(200, ("Out of TDs for Ctrl Transfer!\n"));
645 dataotd
= setupotd
->otd_Succ
;
646 ohciFreeTD(hc
, setupotd
);
647 ohciFreeTDChain(hc
, dataotd
);
648 ohciFreeTD(hc
, termotd
);
649 usbReleaseBuffer(oed
->oed_Buffer
, ioreq
->iouh_Data
, 0, 0);
650 usbReleaseBuffer(oed
->oed_SetupData
, &oed
->oed_IOReq
->iouh_SetupData
, 0, 0);
654 predotd
->otd_Succ
= termotd
;
655 predotd
->otd_NextTD
= termotd
->otd_Self
;
657 setupotd
->otd_Succ
= termotd
;
658 setupotd
->otd_NextTD
= termotd
->otd_Self
;
660 CacheClearE(&setupotd
->otd_Ctrl
, 16, CACRF_ClearD
);
661 CacheClearE(&predotd
->otd_Ctrl
, 16, CACRF_ClearD
);
663 ctrl
^= (OTCF_PIDCODE_IN
^OTCF_PIDCODE_OUT
)|OTCF_NOINT
|OTCF_DATA1
|OTCF_TOGGLEFROMTD
;
665 termotd
->otd_Length
= 0;
666 termotd
->otd_ED
= oed
;
667 termotd
->otd_Succ
= NULL
;
668 termotd
->otd_NextTD
= hc
->hc_OhciTermTD
->otd_Self
;
669 CONSTWRITEMEM32_LE(&termotd
->otd_Ctrl
, ctrl
);
670 CONSTWRITEMEM32_LE(&termotd
->otd_BufferPtr
, 0);
671 CONSTWRITEMEM32_LE(&termotd
->otd_BufferEnd
, 0);
672 CacheClearE(&termotd
->otd_Ctrl
, 16, CACRF_ClearD
);
674 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
675 ioreq
->iouh_DriverPrivate1
= oed
;
677 // manage endpoint going busy
678 unit
->hu_DevBusyReq
[devadrep
] = ioreq
;
679 unit
->hu_NakTimeoutFrame
[devadrep
] = (ioreq
->iouh_Flags
& UHFF_NAKTIMEOUT
) ? hc
->hc_FrameCounter
+ ioreq
->iouh_NakTimeout
: 0;
682 AddTail(&hc
->hc_TDQueue
, (struct Node
*) ioreq
);
684 // looks good to me, now enqueue this entry
685 oed
->oed_Succ
= hc
->hc_OhciCtrlTailED
;
686 oed
->oed_NextED
= oed
->oed_Succ
->oed_Self
;
687 oed
->oed_Pred
= hc
->hc_OhciCtrlTailED
->oed_Pred
;
688 CacheClearE(&oed
->oed_Pred
->oed_EPCaps
, 16, CACRF_InvalidateD
);
689 oed
->oed_Pred
->oed_Succ
= oed
;
690 oed
->oed_Pred
->oed_NextED
= oed
->oed_Self
;
691 oed
->oed_Succ
->oed_Pred
= oed
;
692 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_ClearD
);
693 CacheClearE(&oed
->oed_Pred
->oed_EPCaps
, 16, CACRF_ClearD
);
696 PrintED("Control", oed
, hc
);
698 /* Control request is queued, we will start the queue */
699 startmask
= OCSF_CTRLENABLE
;
702 ioreq
= (struct IOUsbHWReq
*) hc
->hc_CtrlXFerQueue
.lh_Head
;
708 * If we are going to start the queue but it's not running yet,
709 * reset current ED pointer to zero. This will cause the HC to
710 * start over from the head.
712 oldenables
= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
713 if(!(oldenables
& OCSF_BULKENABLE
))
715 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_BULK_ED
, 0);
722 static void ohciScheduleIntTDs(struct PCIController
*hc
)
724 struct PCIUnit
*unit
= hc
->hc_Unit
;
725 struct IOUsbHWReq
*ioreq
;
727 struct OhciED
*intoed
;
730 struct OhciTD
*predotd
;
736 /* *** INT Transfers *** */
737 KPRINTF(1, ("Scheduling new INT transfers...\n"));
738 ioreq
= (struct IOUsbHWReq
*) hc
->hc_IntXFerQueue
.lh_Head
;
739 while(((struct Node
*) ioreq
)->ln_Succ
)
741 devadrep
= (ioreq
->iouh_DevAddr
<<5) + ioreq
->iouh_Endpoint
+ ((ioreq
->iouh_Dir
== UHDIR_IN
) ? 0x10 : 0);
742 KPRINTF(10, ("New INT transfer to %ld.%ld: %ld bytes\n", ioreq
->iouh_DevAddr
, ioreq
->iouh_Endpoint
, ioreq
->iouh_Length
));
743 /* is endpoint already in use or do we have to wait for next transaction */
744 if(unit
->hu_DevBusyReq
[devadrep
])
746 KPRINTF(5, ("Endpoint %02lx in use!\n", devadrep
));
747 ioreq
= (struct IOUsbHWReq
*) ((struct Node
*) ioreq
)->ln_Succ
;
751 oed
= ohciAllocED(hc
);
757 oed
->oed_IOReq
= ioreq
;
759 epcaps
= (ioreq
->iouh_DevAddr
<<OECS_DEVADDR
)|(ioreq
->iouh_Endpoint
<<OECS_ENDPOINT
)|(ioreq
->iouh_MaxPktSize
<<OECS_MAXPKTLEN
);
760 epcaps
|= (ioreq
->iouh_Dir
== UHDIR_IN
) ? OECF_DIRECTION_IN
: OECF_DIRECTION_OUT
;
762 if(ioreq
->iouh_Flags
& UHFF_LOWSPEED
)
764 KPRINTF(5, ("*** LOW SPEED ***\n"));
765 epcaps
|= OECF_LOWSPEED
;
768 WRITEMEM32_LE(&oed
->oed_EPCaps
, epcaps
);
769 oed
->oed_TailPtr
= hc
->hc_OhciTermTD
->otd_Self
;
772 oed
->oed_Buffer
= usbGetBuffer(ioreq
->iouh_Data
, ioreq
->iouh_Length
, ioreq
->iouh_Dir
);
773 phyaddr
= (IPTR
)pciGetPhysical(hc
, oed
->oed_Buffer
);
777 otd
= ohciAllocTD(hc
);
779 predotd
->otd_Succ
= otd
;
787 predotd
->otd_NextTD
= otd
->otd_Self
;
791 WRITEMEM32_LE(&oed
->oed_HeadPtr
, READMEM32_LE(&otd
->otd_Self
)|(unit
->hu_DevDataToggle
[devadrep
] ? OEHF_DATA1
: 0));
792 oed
->oed_FirstTD
= otd
;
794 len
= ioreq
->iouh_Length
- actual
;
795 if(len
> OHCI_PAGE_SIZE
)
797 len
= OHCI_PAGE_SIZE
;
799 otd
->otd_Length
= len
;
800 KPRINTF(1, ("Control TD 0x%p with %ld bytes\n", otd
, len
));
801 CONSTWRITEMEM32_LE(&otd
->otd_Ctrl
, OTCF_CC_INVALID
|OTCF_NOINT
);
804 WRITEMEM32_LE(&otd
->otd_BufferPtr
, (IPTR
)CachePreDMA((APTR
)(IPTR
)phyaddr
, &len
, (ioreq
->iouh_Dir
== UHDIR_IN
) ? 0 : DMA_ReadFromRAM
));
806 WRITEMEM32_LE(&otd
->otd_BufferEnd
, phyaddr
);
809 CONSTWRITEMEM32_LE(&otd
->otd_BufferPtr
, 0);
810 CONSTWRITEMEM32_LE(&otd
->otd_BufferEnd
, 0);
813 CacheClearE(&otd
->otd_Ctrl
, 16, CACRF_ClearD
);
815 } while(actual
< ioreq
->iouh_Length
);
817 if(actual
!= ioreq
->iouh_Length
)
820 KPRINTF(200, ("Out of TDs for Int Transfer!\n"));
821 ohciFreeTDChain(hc
, oed
->oed_FirstTD
);
822 usbReleaseBuffer(oed
->oed_Buffer
, ioreq
->iouh_Data
, 0, 0);
826 predotd
->otd_Succ
= NULL
;
827 predotd
->otd_NextTD
= hc
->hc_OhciTermTD
->otd_Self
;
829 CONSTWRITEMEM32_LE(&predotd
->otd_Ctrl
, OTCF_CC_INVALID
);
830 CacheClearE(&predotd
->otd_Ctrl
, 16, CACRF_ClearD
);
832 if(ioreq
->iouh_Interval
>= 31)
834 intoed
= hc
->hc_OhciIntED
[4]; // 32ms interval
839 intoed
= hc
->hc_OhciIntED
[cnt
++];
840 } while(ioreq
->iouh_Interval
>= (1<<cnt
));
843 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
844 ioreq
->iouh_DriverPrivate1
= oed
;
846 // manage endpoint going busy
847 unit
->hu_DevBusyReq
[devadrep
] = ioreq
;
848 unit
->hu_NakTimeoutFrame
[devadrep
] = (ioreq
->iouh_Flags
& UHFF_NAKTIMEOUT
) ? hc
->hc_FrameCounter
+ ioreq
->iouh_NakTimeout
: 0;
851 AddTail(&hc
->hc_TDQueue
, (struct Node
*) ioreq
);
853 // looks good to me, now enqueue this entry (behind Int head)
854 oed
->oed_Succ
= intoed
->oed_Succ
;
855 oed
->oed_NextED
= intoed
->oed_Succ
->oed_Self
;
856 oed
->oed_Pred
= intoed
;
857 intoed
->oed_Succ
= oed
;
858 intoed
->oed_NextED
= oed
->oed_Self
;
859 oed
->oed_Succ
->oed_Pred
= oed
;
860 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_ClearD
);
861 CacheClearE(&intoed
->oed_EPCaps
, 16, CACRF_ClearD
);
864 PrintED("Int", oed
, hc
);
867 ioreq
= (struct IOUsbHWReq
*) hc
->hc_IntXFerQueue
.lh_Head
;
871 static ULONG
ohciScheduleBulkTDs(struct PCIController
*hc
)
873 struct PCIUnit
*unit
= hc
->hc_Unit
;
874 struct IOUsbHWReq
*ioreq
;
878 struct OhciTD
*predotd
;
886 /* *** BULK Transfers *** */
887 KPRINTF(1, ("Scheduling new BULK transfers...\n"));
888 ioreq
= (struct IOUsbHWReq
*) hc
->hc_BulkXFerQueue
.lh_Head
;
889 while(((struct Node
*) ioreq
)->ln_Succ
)
891 devadrep
= (ioreq
->iouh_DevAddr
<<5) + ioreq
->iouh_Endpoint
+ ((ioreq
->iouh_Dir
== UHDIR_IN
) ? 0x10 : 0);
892 KPRINTF(10, ("New BULK transfer to %ld.%ld: %ld bytes\n", ioreq
->iouh_DevAddr
, ioreq
->iouh_Endpoint
, ioreq
->iouh_Length
));
893 /* is endpoint already in use or do we have to wait for next transaction */
894 if(unit
->hu_DevBusyReq
[devadrep
])
896 KPRINTF(5, ("Endpoint %02lx in use!\n", devadrep
));
897 ioreq
= (struct IOUsbHWReq
*) ((struct Node
*) ioreq
)->ln_Succ
;
901 oed
= ohciAllocED(hc
);
907 oed
->oed_IOReq
= ioreq
;
909 epcaps
= (ioreq
->iouh_DevAddr
<<OECS_DEVADDR
)|(ioreq
->iouh_Endpoint
<<OECS_ENDPOINT
)|(ioreq
->iouh_MaxPktSize
<<OECS_MAXPKTLEN
);
910 epcaps
|= (ioreq
->iouh_Dir
== UHDIR_IN
) ? OECF_DIRECTION_IN
: OECF_DIRECTION_OUT
;
912 if(ioreq
->iouh_Flags
& UHFF_LOWSPEED
)
914 KPRINTF(5, ("*** LOW SPEED ***\n"));
915 epcaps
|= OECF_LOWSPEED
;
918 WRITEMEM32_LE(&oed
->oed_EPCaps
, epcaps
);
919 oed
->oed_TailPtr
= hc
->hc_OhciTermTD
->otd_Self
;
922 oed
->oed_Buffer
= usbGetBuffer(ioreq
->iouh_Data
, ioreq
->iouh_Length
, ioreq
->iouh_Dir
);
923 phyaddr
= (IPTR
)pciGetPhysical(hc
, oed
->oed_Buffer
);
927 if((actual
>= OHCI_TD_BULK_LIMIT
) && (actual
< ioreq
->iouh_Length
))
929 KPRINTF(10, ("Bulk too large, splitting...\n"));
932 otd
= ohciAllocTD(hc
);
937 predotd
->otd_Succ
= NULL
;
944 predotd
->otd_Succ
= otd
;
945 predotd
->otd_NextTD
= otd
->otd_Self
;
947 WRITEMEM32_LE(&oed
->oed_HeadPtr
, READMEM32_LE(&otd
->otd_Self
)|(unit
->hu_DevDataToggle
[devadrep
] ? OEHF_DATA1
: 0));
948 oed
->oed_FirstTD
= otd
;
950 len
= ioreq
->iouh_Length
- actual
;
951 if(len
> OHCI_PAGE_SIZE
)
953 len
= OHCI_PAGE_SIZE
;
955 otd
->otd_Length
= len
;
956 KPRINTF(1, ("TD with %ld bytes: %08x-%08x\n", len
, phyaddr
, phyaddr
+len
-1));
957 CONSTWRITEMEM32_LE(&otd
->otd_Ctrl
, OTCF_CC_INVALID
|OTCF_NOINT
);
960 WRITEMEM32_LE(&otd
->otd_BufferPtr
, (IPTR
)CachePreDMA((APTR
)(IPTR
)phyaddr
, &len
, (ioreq
->iouh_Dir
== UHDIR_IN
) ? 0 : DMA_ReadFromRAM
));
962 WRITEMEM32_LE(&otd
->otd_BufferEnd
, phyaddr
);
965 CONSTWRITEMEM32_LE(&otd
->otd_BufferPtr
, 0);
966 CONSTWRITEMEM32_LE(&otd
->otd_BufferEnd
, 0);
969 CacheClearE(&otd
->otd_Ctrl
, 16, CACRF_ClearD
);
972 } while((actual
< ioreq
->iouh_Length
) || (len
&& (ioreq
->iouh_Dir
== UHDIR_OUT
) && (actual
== ioreq
->iouh_Length
) && (!(ioreq
->iouh_Flags
& UHFF_NOSHORTPKT
)) && ((actual
% ioreq
->iouh_MaxPktSize
) == 0)));
977 KPRINTF(200, ("Out of TDs for Bulk Transfer!\n"));
978 ohciFreeTDChain(hc
, oed
->oed_FirstTD
);
979 usbReleaseBuffer(oed
->oed_Buffer
, ioreq
->iouh_Data
, 0, 0);
983 oed
->oed_Continue
= (actual
< ioreq
->iouh_Length
);
984 predotd
->otd_Succ
= NULL
;
985 predotd
->otd_NextTD
= hc
->hc_OhciTermTD
->otd_Self
;
987 CONSTWRITEMEM32_LE(&predotd
->otd_Ctrl
, OTCF_CC_INVALID
);
988 CacheClearE(&predotd
->otd_Ctrl
, 16, CACRF_ClearD
);
990 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
991 ioreq
->iouh_DriverPrivate1
= oed
;
993 // manage endpoint going busy
994 unit
->hu_DevBusyReq
[devadrep
] = ioreq
;
995 unit
->hu_NakTimeoutFrame
[devadrep
] = (ioreq
->iouh_Flags
& UHFF_NAKTIMEOUT
) ? hc
->hc_FrameCounter
+ ioreq
->iouh_NakTimeout
: 0;
998 AddTail(&hc
->hc_TDQueue
, (struct Node
*) ioreq
);
1000 // looks good to me, now enqueue this entry
1001 oed
->oed_Succ
= hc
->hc_OhciBulkTailED
;
1002 oed
->oed_NextED
= oed
->oed_Succ
->oed_Self
;
1003 oed
->oed_Pred
= hc
->hc_OhciBulkTailED
->oed_Pred
;
1004 oed
->oed_Pred
->oed_Succ
= oed
;
1005 oed
->oed_Pred
->oed_NextED
= oed
->oed_Self
;
1006 oed
->oed_Succ
->oed_Pred
= oed
;
1007 CacheClearE(&oed
->oed_EPCaps
, 16, CACRF_ClearD
);
1008 CacheClearE(&oed
->oed_Pred
->oed_EPCaps
, 16, CACRF_ClearD
);
1011 KPRINTF(10, ("Activating BULK at %ld\n", READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
)));
1012 PrintED("Bulk", oed
, hc
);
1014 /* Similar to ohciScheduleCtrlTDs(), but use bulk queue */
1015 startmask
= OCSF_BULKENABLE
;
1017 ioreq
= (struct IOUsbHWReq
*) hc
->hc_BulkXFerQueue
.lh_Head
;
1022 oldenables
= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
1023 if(!(oldenables
& OCSF_BULKENABLE
))
1025 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_BULK_ED
, 0);
1031 void ohciUpdateFrameCounter(struct PCIController
*hc
)
1035 hc
->hc_FrameCounter
= (hc
->hc_FrameCounter
& 0xffff0000)|(READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
) & 0xffff);
1039 static AROS_INTH1(ohciCompleteInt
, struct PCIController
*,hc
)
1043 ULONG restartmask
= 0;
1045 KPRINTF(1, ("CompleteInt!\n"));
1047 ohciUpdateFrameCounter(hc
);
1049 /* **************** PROCESS DONE TRANSFERS **************** */
1051 if (hc
->hc_OhciDoneQueue
)
1052 ohciHandleFinishedTDs(hc
);
1054 if (hc
->hc_Flags
& HCF_ABORT
)
1055 restartmask
= ohciHandleAbortedEDs(hc
);
1057 if ((!(hc
->hc_Flags
& HCF_STOP_CTRL
)) && hc
->hc_CtrlXFerQueue
.lh_Head
->ln_Succ
)
1058 restartmask
|= ohciScheduleCtrlTDs(hc
);
1060 if (hc
->hc_IntXFerQueue
.lh_Head
->ln_Succ
)
1061 ohciScheduleIntTDs(hc
);
1063 if ((!(hc
->hc_Flags
& HCF_STOP_BULK
)) && hc
->hc_BulkXFerQueue
.lh_Head
->ln_Succ
)
1064 restartmask
|= ohciScheduleBulkTDs(hc
);
1067 * Restart queues. In restartmask we have accumulated which queues need to be started.
1069 * We do it here only once, after everything is set up, because otherwise HC goes nuts
1070 * in some cases. For example, the following situation caused TD queue loop: we are
1071 * simultaneously scheduling two control EDs and one of them completes with error. If
1072 * we attempt to start the queue right after a ED is scheduled (this is how the code
1073 * originally worked), it looks like the HC manages to deal with the first ED right
1074 * before the second one is scheduled. At this moment the first TD is HALTed with
1075 * oed_HeadPtr pointing to the failed TD, which went to the DoneQueue (which will be
1076 * picked up only on next ISR round, we are still in ohciSchedileCtrlEDs()). The
1077 * second ED is scheduled (first one is not removed yet!) and we re-trigger control
1078 * queue to start. It causes errorneous TD to reappear on the DoneQueue, effectively
1079 * looping it. DoneQueue loop causes ohciHandleFinishedTDs() to never exit.
1080 * Restarting queues here in this manner actually fixed the problem.
1084 restartmask
|= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
1085 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, restartmask
);
1089 KPRINTF(1, ("CompleteDone\n"));
1096 static AROS_INTH1(ohciIntCode
, struct PCIController
*, hc
)
1100 struct PCIDevice
*base
= hc
->hc_Device
;
1101 struct PCIUnit
*unit
= hc
->hc_Unit
;
1105 CacheClearE(&hc
->hc_OhciHCCA
->oha_DoneHead
, sizeof(hc
->hc_OhciHCCA
->oha_DoneHead
), CACRF_InvalidateD
);
1107 donehead
= READMEM32_LE(&hc
->hc_OhciHCCA
->oha_DoneHead
);
1112 intr
= OISF_DONEHEAD
;
1115 intr
|= READREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
);
1117 donehead
&= OHCI_PTRMASK
;
1119 CONSTWRITEMEM32_LE(&hc
->hc_OhciHCCA
->oha_DoneHead
, 0);
1121 KPRINTF(5, ("New Donehead %08lx for old %08lx\n", donehead
, hc
->hc_OhciDoneQueue
));
1123 intr
= READREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
);
1125 if (intr
& OISF_DONEHEAD
)
1127 KPRINTF(1, ("!!!!!!!!!!!!!!!!!!!!!!!DoneHead was empty!!!!!!!!!!!!!!!!!!!\n"));
1128 CacheClearE(hc
->hc_OhciHCCA
, sizeof(struct OhciHCCA
), CACRF_InvalidateD
);
1129 donehead
= READMEM32_LE(&hc
->hc_OhciHCCA
->oha_DoneHead
) & OHCI_PTRMASK
;
1130 CONSTWRITEMEM32_LE(&hc
->hc_OhciHCCA
->oha_DoneHead
, 0);
1132 KPRINTF(5, ("New Donehead %08lx for old %08lx\n", donehead
, hc
->hc_OhciDoneQueue
));
1135 CacheClearE(hc
->hc_OhciHCCA
, sizeof(struct OhciHCCA
), CACRF_ClearD
);
1137 intr
&= ~OISF_MASTERENABLE
;
1139 if(intr
& hc
->hc_PCIIntEnMask
)
1141 KPRINTF(1, ("ohciIntCode(0x%p) interrupts 0x%08lx, mask 0x%08lx\n", hc
, intr
, hc
->hc_PCIIntEnMask
));
1143 // Acknowledge all interrupts, but process only those we want
1144 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
, intr
);
1145 //KPRINTF(1, ("INT=%02lx\n", intr));
1146 intr
&= hc
->hc_PCIIntEnMask
;
1148 if(intr
& OISF_HOSTERROR
)
1150 KPRINTF(200, ("Host ERROR!\n"));
1152 if(intr
& OISF_SCHEDOVERRUN
)
1154 KPRINTF(200, ("Schedule overrun!\n"));
1156 if (!(hc
->hc_Flags
& HCF_ONLINE
))
1158 if(READREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
) & OISF_HUBCHANGE
)
1160 // if the driver is not online and the controller has a broken
1161 // hub change interrupt, make sure we don't run into infinite
1162 // interrupt by disabling the interrupt bit
1163 ohciDisableInt(hc
, OISF_HUBCHANGE
);
1167 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTEN
, OISF_HUBCHANGE
);
1168 if(intr
& OISF_FRAMECOUNTOVER
)
1170 hc
->hc_FrameCounter
|= 0x7fff;
1171 hc
->hc_FrameCounter
++;
1172 hc
->hc_FrameCounter
|= READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
) & 0xffff;
1173 KPRINTF(10, ("HCI 0x%p: Frame Counter Rollover %ld\n", hc
, hc
->hc_FrameCounter
));
1175 if(intr
& OISF_HUBCHANGE
)
1179 UWORD portreg
= OHCI_PORTSTATUS
;
1180 BOOL clearbits
= FALSE
;
1182 if(READREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
) & OISF_HUBCHANGE
)
1184 // some OHCI implementations will keep the interrupt bit stuck until
1185 // all port changes have been cleared, which is wrong according to the
1186 // OHCI spec. As a workaround we will clear all change bits, which should
1187 // be no problem as the port changes are reflected in the PortChangeMap
1191 for(hciport
= 0; hciport
< hc
->hc_NumPorts
; hciport
++, portreg
+= 4)
1193 oldval
= READREG32_LE(hc
->hc_RegBase
, portreg
);
1194 if(oldval
& OHPF_OVERCURRENTCHG
)
1196 hc
->hc_PortChangeMap
[hciport
] |= UPSF_PORT_OVER_CURRENT
;
1198 if(oldval
& OHPF_RESETCHANGE
)
1200 hc
->hc_PortChangeMap
[hciport
] |= UPSF_PORT_RESET
;
1202 if(oldval
& OHPF_ENABLECHANGE
)
1204 hc
->hc_PortChangeMap
[hciport
] |= UPSF_PORT_ENABLE
;
1206 if(oldval
& OHPF_CONNECTCHANGE
)
1208 hc
->hc_PortChangeMap
[hciport
] |= UPSF_PORT_CONNECTION
;
1210 if(oldval
& OHPF_RESUMEDTX
)
1212 hc
->hc_PortChangeMap
[hciport
] |= UPSF_PORT_SUSPEND
;
1216 WRITEREG32_LE(hc
->hc_RegBase
, portreg
, OHPF_CONNECTCHANGE
|OHPF_ENABLECHANGE
|OHPF_RESUMEDTX
|OHPF_OVERCURRENTCHG
|OHPF_RESETCHANGE
);
1219 KPRINTF(20, ("PCI Int Port %ld (glob %ld) Change %08lx\n", hciport
, hc
->hc_PortNum20
[hciport
] + 1, oldval
));
1220 if(hc
->hc_PortChangeMap
[hciport
])
1222 unit
->hu_RootPortChanges
|= 1UL<<(hc
->hc_PortNum20
[hciport
] + 1);
1225 uhwCheckRootHubChanges(unit
);
1228 // again try to get rid of any bits that may be causing the interrupt
1229 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBSTATUS
, OHSF_OVERCURRENTCHG
);
1230 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
, OISF_HUBCHANGE
);
1233 if(intr
& OISF_DONEHEAD
)
1235 KPRINTF(10, ("DoneHead Frame=%ld\n", READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
)));
1237 if(hc
->hc_OhciDoneQueue
)
1239 struct OhciTD
*donetd
= (struct OhciTD
*) ((IPTR
)donehead
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
1241 CacheClearE(&donetd
->otd_Ctrl
, 16, CACRF_InvalidateD
);
1242 while(donetd
->otd_NextTD
)
1244 donetd
= (struct OhciTD
*) ((IPTR
)donetd
->otd_NextTD
- hc
->hc_PCIVirtualAdjust
- offsetof(struct OhciTD
, otd_Ctrl
));
1245 CacheClearE(&donetd
->otd_Ctrl
, 16, CACRF_InvalidateD
);
1247 WRITEMEM32_LE(&donetd
->otd_NextTD
, hc
->hc_OhciDoneQueue
);
1248 CacheClearE(&donetd
->otd_Ctrl
, 16, CACRF_ClearD
);
1250 KPRINTF(10, ("Attached old DoneHead 0x%08lx to TD 0x%08lx\n", hc
->hc_OhciDoneQueue
, donetd
->otd_Self
));
1252 hc
->hc_OhciDoneQueue
= donehead
;
1254 if (intr
& OISF_SOF
)
1256 /* Aborted EDs are available for freeing */
1257 hc
->hc_Flags
|= HCF_ABORT
;
1260 if (intr
& (OISF_SOF
| OISF_DONEHEAD
))
1263 * These two are leveraged down to SoftInt.
1264 * This is done in order to keep queues rotation synchronized.
1266 SureCause(base
, &hc
->hc_CompleteInt
);
1269 KPRINTF(1, ("Exiting ohciIntCode(0x%p)\n", unit
));
1272 /* Unlock interrupts */
1273 WRITEREG32_LE(&hc
->hc_RegBase
, OHCI_INTEN
, OISF_MASTERENABLE
);
1281 * CHECKME: This routine is implemented according to the OHCI specification, however poorly tested.
1282 * Additionally, disabling and re-enabling the queue seems to create a significant delay. Perhaps
1283 * this can be optimized. In fact the only thing we really need to is to make sure that the ED to
1284 * be removed is neither on list nor being processed at the moment. Perhaps it's enough to simply
1285 * unlink it, set SKIP flag and wait for the next SOF.
1286 * But be careful, improper TD/ED removal can easily cause DoneQueue loops which are extremely hard
1287 * to isolate and fix (debug output adds delays which hide the problem). One of danger signs are
1288 * "Came accross a rogue TD" messages on the debug log. They mean that one of freed TDs reappeared
1289 * on the DoneQueue. If you run intensive I/O, you can be unlucky enough to reallocate and reuse this
1290 * TD before is passes DoneQueue, so it will appear there for the second time and create loop.
1292 void ohciAbortRequest(struct PCIController
*hc
, struct IOUsbHWReq
*ioreq
)
1294 struct PCIUnit
*unit
= hc
->hc_Unit
;
1295 struct OhciED
*oed
= ioreq
->iouh_DriverPrivate1
;
1296 UWORD devadrep
= (ioreq
->iouh_DevAddr
<<5) + ioreq
->iouh_Endpoint
+ ((ioreq
->iouh_Dir
== UHDIR_IN
) ? 0x10 : 0);
1297 ULONG disablemask
= 0;
1300 KPRINTF(70, ("HC 0x%p Aborting request 0x%p, command %ld, endpoint 0x%04lx, Frame=%ld\n", hc
, ioreq
, ioreq
->iouh_Req
.io_Command
, devadrep
, READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
)));
1301 PrintED("Aborting", oed
, hc
);
1303 /* Removing control and bulk EDs requires to stop the appropriate HC queue first (according to specification) */
1304 switch (ioreq
->iouh_Req
.io_Command
)
1306 case UHCMD_CONTROLXFER
:
1307 KPRINTF(50, ("Stopping control queue\n"));
1308 hc
->hc_Flags
|= HCF_STOP_CTRL
;
1309 disablemask
= OCSF_CTRLENABLE
;
1312 case UHCMD_BULKXFER
:
1313 KPRINTF(50, ("Stopping bulk queue\n"));
1314 hc
->hc_Flags
|= HCF_STOP_BULK
;
1315 disablemask
= OCSF_BULKENABLE
;
1319 /* Stop selected queue(s) */
1322 ctrlstatus
= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
1323 ctrlstatus
&= ~disablemask
;
1324 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, ctrlstatus
);
1332 * ...and move to abort queue.
1333 * We can't reply the request right now because some of its TDs
1334 * can be used by the HC right now. This means it does something
1335 * to the data buffer referred to by the request.
1336 * We reply the request only when the HC stops doing this. Otherwise
1337 * we may end up in trashed memory.
1339 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
1340 AddTail(&hc
->hc_AbortQueue
, &ioreq
->iouh_Req
.io_Message
.mn_Node
);
1342 if (ioreq
->iouh_Req
.io_Command
== UHCMD_INTXFER
)
1343 ohciUpdateIntTree(hc
);
1345 unit
->hu_DevDataToggle
[devadrep
] = (READMEM32_LE(&oed
->oed_HeadPtr
) & OEHF_DATA1
) ? TRUE
: FALSE
;
1348 * Request StartOfFrame interrupt. Upon next frame this ED
1349 * is guaranteed to be out of use and can be freed.
1351 ohciEnableInt(hc
, OISF_SOF
);
1354 BOOL
ohciInit(struct PCIController
*hc
, struct PCIUnit
*hu
) {
1356 struct PCIDevice
*hd
= hu
->hu_Device
;
1359 struct OhciED
*predoed
;
1373 struct TagItem pciActivateMem
[] =
1375 { aHidd_PCIDevice_isMEM
, TRUE
},
1379 struct TagItem pciActivateBusmaster
[] =
1381 { aHidd_PCIDevice_isMaster
, TRUE
},
1385 struct TagItem pciDeactivateBusmaster
[] =
1387 { aHidd_PCIDevice_isMaster
, FALSE
},
1391 hc
->hc_CompleteInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
1392 hc
->hc_CompleteInt
.is_Node
.ln_Name
= "OHCI CompleteInt";
1393 hc
->hc_CompleteInt
.is_Node
.ln_Pri
= 0;
1394 hc
->hc_CompleteInt
.is_Data
= hc
;
1395 hc
->hc_CompleteInt
.is_Code
= (VOID_FUNC
)ohciCompleteInt
;
1397 hc
->hc_PCIMemSize
= OHCI_HCCA_SIZE
+ OHCI_HCCA_ALIGNMENT
+ 1;
1398 hc
->hc_PCIMemSize
+= sizeof(struct OhciED
) * OHCI_ED_POOLSIZE
;
1399 hc
->hc_PCIMemSize
+= sizeof(struct OhciTD
) * OHCI_TD_POOLSIZE
;
1401 memptr
= HIDD_PCIDriver_AllocPCIMem(hc
->hc_PCIDriverObject
, hc
->hc_PCIMemSize
);
1402 hc
->hc_PCIMem
= (APTR
) memptr
;
1405 // PhysicalAddress - VirtualAdjust = VirtualAddress
1406 // VirtualAddress + VirtualAdjust = PhysicalAddress
1407 hc
->hc_PCIVirtualAdjust
= pciGetPhysical(hc
, memptr
) - (APTR
)memptr
;
1408 KPRINTF(10, ("VirtualAdjust 0x%08lx\n", hc
->hc_PCIVirtualAdjust
));
1411 memptr
= (UBYTE
*) (((IPTR
)hc
->hc_PCIMem
+ OHCI_HCCA_ALIGNMENT
) & (~OHCI_HCCA_ALIGNMENT
));
1412 hc
->hc_OhciHCCA
= (struct OhciHCCA
*) memptr
;
1413 KPRINTF(10, ("HCCA 0x%p\n", hc
->hc_OhciHCCA
));
1414 memptr
+= OHCI_HCCA_SIZE
;
1417 oed
= (struct OhciED
*) memptr
;
1418 hc
->hc_OhciEDPool
= oed
;
1419 cnt
= OHCI_ED_POOLSIZE
- 1;
1421 // minimal initalization
1422 oed
->oed_Succ
= (oed
+ 1);
1423 WRITEMEM32_LE(&oed
->oed_Self
, (IPTR
)(&oed
->oed_EPCaps
) + hc
->hc_PCIVirtualAdjust
);
1426 oed
->oed_Succ
= NULL
;
1427 WRITEMEM32_LE(&oed
->oed_Self
, (IPTR
)(&oed
->oed_EPCaps
) + hc
->hc_PCIVirtualAdjust
);
1428 memptr
+= sizeof(struct OhciED
) * OHCI_ED_POOLSIZE
;
1431 otd
= (struct OhciTD
*) memptr
;
1432 hc
->hc_OhciTDPool
= otd
;
1433 cnt
= OHCI_TD_POOLSIZE
- 1;
1435 otd
->otd_Succ
= (otd
+ 1);
1436 WRITEMEM32_LE(&otd
->otd_Self
, (IPTR
)(&otd
->otd_Ctrl
) + hc
->hc_PCIVirtualAdjust
);
1439 otd
->otd_Succ
= NULL
;
1440 WRITEMEM32_LE(&otd
->otd_Self
, (IPTR
)(&otd
->otd_Ctrl
) + hc
->hc_PCIVirtualAdjust
);
1441 memptr
+= sizeof(struct OhciTD
) * OHCI_TD_POOLSIZE
;
1444 hc
->hc_OhciTermED
= oed
= ohciAllocED(hc
);
1445 oed
->oed_Succ
= NULL
;
1446 oed
->oed_Pred
= NULL
;
1447 CONSTWRITEMEM32_LE(&oed
->oed_EPCaps
, OECF_SKIP
);
1448 oed
->oed_NextED
= 0;
1451 hc
->hc_OhciTermTD
= otd
= ohciAllocTD(hc
);
1452 otd
->otd_Succ
= NULL
;
1453 otd
->otd_NextTD
= 0;
1455 // dummy head & tail Ctrl ED
1456 hc
->hc_OhciCtrlHeadED
= predoed
= ohciAllocED(hc
);
1457 hc
->hc_OhciCtrlTailED
= oed
= ohciAllocED(hc
);
1458 CONSTWRITEMEM32_LE(&predoed
->oed_EPCaps
, OECF_SKIP
);
1459 CONSTWRITEMEM32_LE(&oed
->oed_EPCaps
, OECF_SKIP
);
1460 predoed
->oed_Succ
= oed
;
1461 predoed
->oed_Pred
= NULL
;
1462 predoed
->oed_NextED
= oed
->oed_Self
;
1463 oed
->oed_Succ
= NULL
;
1464 oed
->oed_Pred
= predoed
;
1465 oed
->oed_NextED
= 0;
1467 // dummy head & tail Bulk ED
1468 hc
->hc_OhciBulkHeadED
= predoed
= ohciAllocED(hc
);
1469 hc
->hc_OhciBulkTailED
= oed
= ohciAllocED(hc
);
1470 CONSTWRITEMEM32_LE(&predoed
->oed_EPCaps
, OECF_SKIP
);
1471 CONSTWRITEMEM32_LE(&oed
->oed_EPCaps
, OECF_SKIP
);
1472 predoed
->oed_Succ
= oed
;
1473 predoed
->oed_Pred
= NULL
;
1474 predoed
->oed_NextED
= oed
->oed_Self
;
1475 oed
->oed_Succ
= NULL
;
1476 oed
->oed_Pred
= predoed
;
1477 oed
->oed_NextED
= 0;
1479 hc
->hc_OhciIntED
[0] = oed
= ohciAllocED(hc
);
1480 oed
->oed_Succ
= hc
->hc_OhciTermED
;
1481 oed
->oed_Pred
= NULL
; // who knows...
1482 CONSTWRITEMEM32_LE(&oed
->oed_EPCaps
, OECF_SKIP
);
1483 oed
->oed_NextED
= hc
->hc_OhciTermED
->oed_Self
;
1485 // make 5 levels of QH interrupts
1486 for(cnt
= 1; cnt
< 5; cnt
++) {
1487 hc
->hc_OhciIntED
[cnt
] = oed
= ohciAllocED(hc
);
1488 oed
->oed_Succ
= predoed
;
1489 oed
->oed_Pred
= NULL
; // who knows...
1490 CONSTWRITEMEM32_LE(&oed
->oed_EPCaps
, OECF_SKIP
);
1491 oed
->oed_NextED
= hc
->hc_OhciTermED
->oed_Self
;
1495 ohciUpdateIntTree(hc
);
1497 // fill in framelist with IntED entry points based on interval
1498 tabptr
= hc
->hc_OhciHCCA
->oha_IntEDs
;
1499 for(cnt
= 0; cnt
< 32; cnt
++) {
1500 oed
= hc
->hc_OhciIntED
[4];
1503 if(cnt
& (1UL<<bitcnt
)) {
1504 oed
= hc
->hc_OhciIntED
[bitcnt
];
1507 } while(++bitcnt
< 5);
1508 *tabptr
++ = oed
->oed_Self
;
1511 // time to initialize hardware...
1512 OOP_GetAttr(hc
->hc_PCIDeviceObject
, aHidd_PCIDevice_Base0
, (IPTR
*) &hc
->hc_RegBase
);
1513 hc
->hc_RegBase
= (APTR
) (((IPTR
) hc
->hc_RegBase
) & (~0xf));
1514 KPRINTF(10, ("RegBase = 0x%p\n", hc
->hc_RegBase
));
1515 OOP_SetAttrs(hc
->hc_PCIDeviceObject
, (struct TagItem
*) pciActivateMem
); // enable memory
1517 hubdesca
= READREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCA
);
1518 revision
= READREG32_LE(hc
->hc_RegBase
, OHCI_REVISION
);
1519 hc
->hc_NumPorts
= (hubdesca
& OHAM_NUMPORTS
)>>OHAS_NUMPORTS
;
1520 KPRINTF(20, ("Found OHCI Controller %p FuncNum = %ld, Rev %02lx, with %ld ports\n",
1521 hc
->hc_PCIDeviceObject
, hc
->hc_FunctionNum
,
1525 KPRINTF(20, ("Powerswitching: %s %s\n",
1526 hubdesca
& OHAF_NOPOWERSWITCH
? "Always on" : "Available",
1527 hubdesca
& OHAF_INDIVIDUALPS
? "per port" : "global"));
1529 control
= READREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
);
1530 KPRINTF(10, ("OHCI control state: 0x%08lx\n", control
));
1532 // disable BIOS legacy support
1533 if (control
& OCLF_SMIINT
)
1535 KPRINTF(10, ("BIOS still has hands on OHCI, trying to get rid of it\n"));
1537 cmdstatus
= READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
);
1538 cmdstatus
|= OCSF_OWNERCHANGEREQ
;
1539 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, cmdstatus
);
1542 control
= READREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
);
1543 if(!(control
& OCLF_SMIINT
)) {
1544 KPRINTF(10, ("BIOS gave up on OHCI. Pwned!\n"));
1550 KPRINTF(10, ("BIOS didn't release OHCI. Forcing and praying...\n"));
1551 control
&= ~OCLF_SMIINT
;
1552 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
, control
);
1556 OOP_SetAttrs(hc
->hc_PCIDeviceObject
, (struct TagItem
*) pciDeactivateBusmaster
); // no busmaster yet
1558 KPRINTF(10, ("Resetting OHCI HC\n"));
1559 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, OCSF_HCRESET
);
1562 if(!(READREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
) & OCSF_HCRESET
)) {
1570 KPRINTF(20, ("Reset Timeout!\n"));
1572 KPRINTF(20, ("Reset finished after %ld ticks\n", 100-cnt
));
1576 OOP_SetAttrs(hc
->hc_PCIDeviceObject
, (struct TagItem
*) pciActivateBusmaster
); // enable busmaster
1578 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_FRAMECOUNT
, 0);
1579 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_PERIODICSTART
, 10800); // 10% of 12000
1580 frameival
= READREG32_LE(hc
->hc_RegBase
, OHCI_FRAMEINTERVAL
);
1581 KPRINTF(10, ("FrameInterval=%08lx\n", frameival
));
1582 frameival
&= ~OIVM_BITSPERFRAME
;
1583 frameival
|= OHCI_DEF_BITSPERFRAME
<<OIVS_BITSPERFRAME
;
1584 frameival
^= OIVF_TOGGLE
;
1585 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_FRAMEINTERVAL
, frameival
);
1587 // make sure nothing is running
1588 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_PERIODIC_ED
, 0);
1589 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CTRL_HEAD_ED
, AROS_LONG2LE(hc
->hc_OhciCtrlHeadED
->oed_Self
));
1590 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CTRL_ED
, 0);
1591 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_BULK_HEAD_ED
, AROS_LONG2LE(hc
->hc_OhciBulkHeadED
->oed_Self
));
1592 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_BULK_ED
, 0);
1593 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_DONEHEAD
, 0);
1595 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HCCA
, (IPTR
)pciGetPhysical(hc
, hc
->hc_OhciHCCA
));
1597 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
, OISF_ALL_INTS
);
1598 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTDIS
, OISF_ALL_INTS
);
1601 // install reset handler
1602 hc
->hc_ResetInt
.is_Code
= (VOID_FUNC
)OhciResetHandler
;
1603 hc
->hc_ResetInt
.is_Data
= hc
;
1604 AddResetCallback(&hc
->hc_ResetInt
);
1607 hc
->hc_PCIIntHandler
.is_Node
.ln_Name
= "OHCI PCI (pciusb.device)";
1608 hc
->hc_PCIIntHandler
.is_Node
.ln_Pri
= 5;
1609 hc
->hc_PCIIntHandler
.is_Node
.ln_Type
= NT_INTERRUPT
;
1610 hc
->hc_PCIIntHandler
.is_Code
= (VOID_FUNC
)ohciIntCode
;
1611 hc
->hc_PCIIntHandler
.is_Data
= hc
;
1612 PCIXAddInterrupt(hc
, &hc
->hc_PCIIntHandler
);
1614 hc
->hc_PCIIntEnMask
= OISF_DONEHEAD
|OISF_RESUMEDTX
|OISF_HOSTERROR
|OISF_FRAMECOUNTOVER
|OISF_HUBCHANGE
;
1616 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTEN
, hc
->hc_PCIIntEnMask
|OISF_MASTERENABLE
);
1618 /* Don't try to enter RESET state via OHCI_CONTROL - this flakes out
1619 * some chips, particularly the Sam460ex
1621 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
, OCLF_PERIODICENABLE
|OCLF_CTRLENABLE
|OCLF_BULKENABLE
|OCLF_ISOENABLE
|OCLF_USBOPER
);
1624 // make sure the ports are on with chipset quirk workaround
1625 hubdesca
= READREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCA
);
1626 if (hd
->hd_Flags
& HDF_FORCEPOWER
)
1627 hubdesca
|= OHAF_NOPOWERSWITCH
; /* Required for some IntelMacs */
1629 hubdesca
|= OHAF_NOOVERCURRENT
;
1630 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCA
, hubdesca
);
1632 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBSTATUS
, OHSF_POWERHUB
);
1633 if((hubdesca
& OHAF_NOPOWERSWITCH
) || (!(hubdesca
& OHAF_INDIVIDUALPS
))) {
1634 KPRINTF(20, ("Individual power switching not available, turning on all ports!\n"));
1635 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCB
, 0);
1637 KPRINTF(20, ("Enabling individual power switching\n"));
1638 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCB
, ((2<<hc
->hc_NumPorts
)-2)<<OHBS_PORTPOWERCTRL
);
1642 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCA
, hubdesca
);
1644 CacheClearE(hc
->hc_OhciHCCA
, sizeof(struct OhciHCCA
), CACRF_ClearD
);
1645 CacheClearE(hc
->hc_OhciEDPool
, sizeof(struct OhciED
) * OHCI_ED_POOLSIZE
, CACRF_ClearD
);
1646 CacheClearE(hc
->hc_OhciTDPool
, sizeof(struct OhciTD
) * OHCI_TD_POOLSIZE
, CACRF_ClearD
);
1648 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
, OCLF_PERIODICENABLE
|OCLF_CTRLENABLE
|OCLF_BULKENABLE
|OCLF_ISOENABLE
|OCLF_USBOPER
);
1651 KPRINTF(20, ("ohciInit returns TRUE...\n"));
1656 FIXME: What would the appropriate debug level be?
1658 KPRINTF(1000, ("ohciInit returns FALSE...\n"));
1662 void ohciFree(struct PCIController
*hc
, struct PCIUnit
*hu
) {
1664 hc
= (struct PCIController
*) hu
->hu_Controllers
.lh_Head
;
1665 while(hc
->hc_Node
.ln_Succ
)
1667 switch(hc
->hc_HCIType
)
1671 KPRINTF(20, ("Shutting down OHCI %p\n", hc
));
1672 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTDIS
, OISF_ALL_INTS
);
1673 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_INTSTATUS
, OISF_ALL_INTS
);
1675 // disable all ports
1676 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBDESCB
, 0);
1677 WRITEREG32_LE(hc
->hc_RegBase
, OHCI_HUBSTATUS
, OHSF_UNPOWERHUB
);
1680 KPRINTF(20, ("Stopping OHCI %p\n", hc
));
1681 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CONTROL
, 0);
1682 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, 0);
1685 //KPRINTF(20, ("Reset done UHCI %08lx\n", hc));
1687 KPRINTF(20, ("Resetting OHCI %p\n", hc
));
1688 CONSTWRITEREG32_LE(hc
->hc_RegBase
, OHCI_CMDSTATUS
, OCSF_HCRESET
);
1692 KPRINTF(20, ("Shutting down OHCI done.\n"));
1697 hc
= (struct PCIController
*) hc
->hc_Node
.ln_Succ
;