- Add "--enable-usb30-code" in configure, defaults to no
[AROS.git] / rom / usb / pciusb / pci_aros.c
bloba57bce188bf055ff88febf6271457234b9017ea6
1 /* pci_aros.c - pci access abstraction for AROS by Chris Hodges
2 */
4 #include <aros/bootloader.h>
5 #include <aros/symbolsets.h>
6 #include <exec/types.h>
7 #include <oop/oop.h>
8 #include <devices/timer.h>
9 #include <hidd/hidd.h>
10 #include <hidd/pci.h>
11 #include <hidd/irq.h>
12 #include <proto/bootloader.h>
13 #include <proto/oop.h>
14 #include <proto/utility.h>
15 #include <proto/exec.h>
17 #include <inttypes.h>
18 #include <string.h>
20 #include "uhwcmd.h"
21 #include "ohciproto.h"
23 #define NewList NEWLIST
25 #undef HiddPCIDeviceAttrBase
26 //#undef HiddUSBDeviceAttrBase
27 //#undef HiddUSBHubAttrBase
28 //#undef HiddUSBDrvAttrBase
29 #undef HiddAttrBase
31 #define HiddPCIDeviceAttrBase (hd->hd_HiddPCIDeviceAB)
32 //#define HiddUSBDeviceAttrBase (hd->hd_HiddUSBDeviceAB)
33 //#define HiddUSBHubAttrBase (hd->hd_HiddUSBHubAB)
34 //#define HiddUSBDrvAttrBase (hd->hd_HiddUSBDrvAB)
35 #define HiddAttrBase (hd->hd_HiddAB)
37 AROS_UFH3(void, pciEnumerator,
38 AROS_UFHA(struct Hook *, hook, A0),
39 AROS_UFHA(OOP_Object *, pciDevice, A2),
40 AROS_UFHA(APTR, message, A1))
42 AROS_USERFUNC_INIT
44 struct PCIDevice *hd = (struct PCIDevice *) hook->h_Data;
45 struct PCIController *hc;
46 IPTR hcitype;
47 IPTR dev;
48 IPTR bus;
49 IPTR intline;
50 ULONG devid;
52 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Interface, &hcitype);
53 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Bus, &bus);
54 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Dev, &dev);
55 OOP_GetAttr(pciDevice, aHidd_PCIDevice_INTLine, &intline);
57 devid = (bus<<16)|dev;
59 KPRINTF(10, ("Found PCI device 0x%lx of type %ld, Intline=%ld\n", devid, hcitype, intline));
61 if(intline == 255)
63 // we can't work without the correct interrupt line
64 // BIOS needs plug & play os option disabled. Alternatively AROS must support APIC reconfiguration
65 KPRINTF(200, ("ERROR: PCI card has no interrupt line assigned by BIOS, disable Plug & Play OS!\n"));
67 else
69 switch (hcitype)
71 case HCITYPE_OHCI:
72 #ifndef __powerpc__ /* It was not from me. Perhaps on PPC these drivers suffer from CPU cache problems? (sonic) */
73 #ifndef __x86_64__ /* Not 64-bit-ready yet - sonic */
74 case HCITYPE_EHCI:
75 case HCITYPE_UHCI:
76 #endif
77 #endif
78 #if defined(AROS_USB30_CODE)
79 case HCITYPE_XHCI:
80 #endif
81 KPRINTF(10, ("Setting up device...\n"));
83 hc = AllocPooled(hd->hd_MemPool, sizeof(struct PCIController));
84 if (hc)
86 hc->hc_Device = hd;
87 hc->hc_DevID = devid;
88 hc->hc_HCIType = hcitype;
89 hc->hc_PCIDeviceObject = pciDevice;
90 hc->hc_PCIIntLine = intline;
92 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (IPTR *) &hc->hc_PCIDriverObject);
94 NewList(&hc->hc_CtrlXFerQueue);
95 NewList(&hc->hc_IntXFerQueue);
96 NewList(&hc->hc_IsoXFerQueue);
97 NewList(&hc->hc_BulkXFerQueue);
98 NewList(&hc->hc_TDQueue);
99 NewList(&hc->hc_AbortQueue);
100 NewList(&hc->hc_PeriodicTDQueue);
101 NewList(&hc->hc_OhciRetireQueue);
102 AddTail(&hd->hd_TempHCIList, &hc->hc_Node);
104 break;
106 default:
107 KPRINTF(10, ("Unsupported HCI type %ld\n", hcitype));
111 AROS_USERFUNC_EXIT
114 /* /// "pciInit()" */
115 BOOL pciInit(struct PCIDevice *hd)
117 struct PCIController *hc;
118 struct PCIController *nexthc;
119 struct PCIUnit *hu;
120 ULONG unitno = 0;
121 UWORD ohcicnt;
122 UWORD uhcicnt;
124 KPRINTF(10, ("*** pciInit(%p) ***\n", hd));
125 /* if(sizeof(IPTR) > 4)
127 KPRINTF(200, ("I said the pciusb.device is not 64bit compatible right now. Go away!\n"));
128 return FALSE;
131 NewList(&hd->hd_TempHCIList);
133 if(!(hd->hd_IRQHidd = OOP_NewObject(NULL, (STRPTR) CLID_Hidd_IRQ, NULL)))
135 KPRINTF(20, ("Unable to create IRQHidd object!\n"));
136 return FALSE;
139 if((hd->hd_PCIHidd = OOP_NewObject(NULL, (STRPTR) CLID_Hidd_PCI, NULL)))
141 struct TagItem tags[] =
143 { tHidd_PCI_Class, (PCI_CLASS_SERIAL_USB>>8) & 0xff },
144 { tHidd_PCI_SubClass, (PCI_CLASS_SERIAL_USB & 0xff) },
145 { TAG_DONE, 0UL }
148 struct OOP_ABDescr attrbases[] =
150 { (STRPTR) IID_Hidd, &hd->hd_HiddAB },
151 { (STRPTR) IID_Hidd_PCIDevice, &hd->hd_HiddPCIDeviceAB },
152 { NULL, NULL }
155 struct Hook findHook =
157 h_Entry: (IPTR (*)()) pciEnumerator,
158 h_Data: hd,
161 OOP_ObtainAttrBases(attrbases);
163 KPRINTF(20, ("Searching for devices...\n"));
165 HIDD_PCI_EnumDevices(hd->hd_PCIHidd, &findHook, (struct TagItem *) &tags);
166 } else {
167 KPRINTF(20, ("Unable to create PCIHidd object!\n"));
168 OOP_DisposeObject(hd->hd_IRQHidd);
169 return FALSE;
172 while(hd->hd_TempHCIList.lh_Head->ln_Succ)
174 hu = AllocPooled(hd->hd_MemPool, sizeof(struct PCIUnit));
175 if(!hu)
177 // actually, we should get rid of the allocated memory first, but I don't care as DeletePool() will take care of this eventually
178 return FALSE;
180 hu->hu_Device = hd;
181 hu->hu_UnitNo = unitno;
182 hu->hu_DevID = ((struct PCIController *) hd->hd_TempHCIList.lh_Head)->hc_DevID;
184 NewList(&hu->hu_Controllers);
185 NewList(&hu->hu_RHIOQueue);
186 ohcicnt = 0;
187 uhcicnt = 0;
188 // find all belonging host controllers
189 hc = (struct PCIController *) hd->hd_TempHCIList.lh_Head;
190 while((nexthc = (struct PCIController *) hc->hc_Node.ln_Succ))
192 if(hc->hc_DevID == hu->hu_DevID)
194 Remove(&hc->hc_Node);
195 hc->hc_Unit = hu;
196 if(hc->hc_HCIType == HCITYPE_UHCI)
198 hc->hc_FunctionNum = uhcicnt++;
200 else if(hc->hc_HCIType == HCITYPE_OHCI)
202 hc->hc_FunctionNum = ohcicnt++;
203 } else {
204 hc->hc_FunctionNum = 0;
206 AddTail(&hu->hu_Controllers, &hc->hc_Node);
208 hc = nexthc;
210 AddTail(&hd->hd_Units, (struct Node *) hu);
211 unitno++;
213 return TRUE;
215 /* \\\ */
217 /* /// "PCIXReadConfigByte()" */
218 UBYTE PCIXReadConfigByte(struct PCIController *hc, UBYTE offset)
220 struct pHidd_PCIDevice_ReadConfigByte msg;
222 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
223 msg.reg = offset;
225 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
227 /* \\\ */
229 /* /// "PCIXReadConfigWord()" */
230 UWORD PCIXReadConfigWord(struct PCIController *hc, UBYTE offset)
232 struct pHidd_PCIDevice_ReadConfigWord msg;
234 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
235 msg.reg = offset;
237 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
239 /* \\\ */
241 /* /// "PCIXReadConfigLong()" */
242 ULONG PCIXReadConfigLong(struct PCIController *hc, UBYTE offset)
244 struct pHidd_PCIDevice_ReadConfigLong msg;
246 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong);
247 msg.reg = offset;
249 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
251 /* \\\ */
253 /* /// "PCIXWriteConfigByte()" */
254 void PCIXWriteConfigByte(struct PCIController *hc, ULONG offset, UBYTE value)
256 struct pHidd_PCIDevice_WriteConfigByte msg;
258 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
259 msg.reg = offset;
260 msg.val = value;
262 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
264 /* \\\ */
266 /* /// "PCIXWriteConfigWord()" */
267 void PCIXWriteConfigWord(struct PCIController *hc, ULONG offset, UWORD value)
269 struct pHidd_PCIDevice_WriteConfigWord msg;
271 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigWord);
272 msg.reg = offset;
273 msg.val = value;
275 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
277 /* \\\ */
279 /* /// "PCIXWriteConfigLong()" */
280 void PCIXWriteConfigLong(struct PCIController *hc, ULONG offset, ULONG value)
282 struct pHidd_PCIDevice_WriteConfigLong msg;
284 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigLong);
285 msg.reg = offset;
286 msg.val = value;
288 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
290 /* \\\ */
292 /* /// "pciStrcat()" */
293 void pciStrcat(STRPTR d, STRPTR s)
295 while(*d) d++;
296 while((*d++ = *s++));
298 /* \\\ */
300 /* /// "pciAllocUnit()" */
301 BOOL pciAllocUnit(struct PCIUnit *hu)
303 #if 0
304 struct PCIDevice *hd = hu->hu_Device;
305 #endif
306 struct PCIController *hc;
308 BOOL allocgood = TRUE;
309 ULONG usb11ports;
310 ULONG usb20ports;
311 #if defined(AROS_USB30_CODE)
312 ULONG usb30ports;
313 #endif
314 ULONG cnt;
316 ULONG ohcicnt = 0;
317 ULONG uhcicnt = 0;
318 ULONG ehcicnt = 0;
319 #if defined(AROS_USB30_CODE)
320 ULONG xhcicnt = 0;
321 #endif
322 STRPTR prodname;
324 KPRINTF(10, ("*** pciAllocUnit(%p) ***\n", hu));
325 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
326 while(hc->hc_Node.ln_Succ)
328 #if 0 // FIXME this needs to be replaced by something AROS supports
329 PCIXObtainBoard(hc->hc_BoardObject);
330 if (PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, (ULONG) hd->hd_Library.lib_Node.ln_Name))
331 hc->hc_Flags |= HCF_BOARD_ALLOCATED;
332 else
334 KPRINTF(20, ("Couldn't allocate board, already allocated by %s\n", PCIXGetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER)));
335 allocgood = FALSE;
337 PCIXReleaseBoard(hc->hc_BoardObject);
338 #endif
340 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
343 if(allocgood)
345 // allocate necessary memory
346 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
347 while(hc->hc_Node.ln_Succ)
349 switch(hc->hc_HCIType)
351 case HCITYPE_UHCI:
353 allocgood = uhciInit(hc,hu);
354 break;
357 case HCITYPE_OHCI:
359 allocgood = ohciInit(hc,hu);
360 break;
363 case HCITYPE_EHCI:
365 allocgood = ehciInit(hc,hu);
366 break;
368 #if defined(AROS_USB30_CODE)
369 case HCITYPE_XHCI:
371 allocgood = xhciInit(hc,hu);
372 break;
374 #endif
376 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
380 if(!allocgood)
382 // free previously allocated boards
383 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
384 while(hc->hc_Node.ln_Succ)
386 #if 0
387 PCIXObtainBoard(hc->hc_BoardObject);
388 if (hc->hc_Flags & HCF_ALLOCATED)
390 hc->hc_Flags &= ~HCF_ALLOCATED;
391 PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, 0);
393 PCIXReleaseBoard(hc->hc_BoardObject);
394 #endif
395 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
397 return FALSE;
400 // find all belonging host controllers
401 usb11ports = 0;
402 usb20ports = 0;
403 #if defined(AROS_USB30_CODE)
404 usb30ports = 0;
405 #endif
407 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
408 while(hc->hc_Node.ln_Succ)
410 #if defined(AROS_USB30_CODE)
411 if(hc->hc_HCIType == HCITYPE_XHCI)
413 xhcicnt++;
414 if(usb30ports)
416 KPRINTF(200, ("WARNING: Two XHCI controllers per Board?!?\n"));
418 usb30ports = hc->hc_NumPorts;
420 else
421 #endif
422 if(hc->hc_HCIType == HCITYPE_EHCI)
424 ehcicnt++;
425 if(usb20ports)
427 KPRINTF(200, ("WARNING: Two EHCI controllers per Board?!?\n"));
429 usb20ports = hc->hc_NumPorts;
430 for(cnt = 0; cnt < usb20ports; cnt++)
432 hu->hu_PortMap20[cnt] = hc;
433 hc->hc_PortNum20[cnt] = cnt;
436 else if(hc->hc_HCIType == HCITYPE_UHCI)
438 uhcicnt++;
440 else if(hc->hc_HCIType == HCITYPE_OHCI)
442 ohcicnt++;
444 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
447 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
448 while(hc->hc_Node.ln_Succ)
450 if((hc->hc_HCIType == HCITYPE_UHCI) || (hc->hc_HCIType == HCITYPE_OHCI))
452 if(hc->hc_complexrouting)
454 ULONG locport = 0;
455 for(cnt = 0; cnt < usb20ports; cnt++)
457 if(((hc->hc_portroute >> (cnt<<2)) & 0xf) == hc->hc_FunctionNum)
459 KPRINTF(10, ("CHC %ld Port %ld assigned to global Port %ld\n", hc->hc_FunctionNum, locport, cnt));
460 hu->hu_PortMap11[cnt] = hc;
461 hu->hu_PortNum11[cnt] = locport;
462 hc->hc_PortNum20[locport] = cnt;
463 locport++;
466 } else {
467 for(cnt = usb11ports; cnt < usb11ports + hc->hc_NumPorts; cnt++)
469 hu->hu_PortMap11[cnt] = hc;
470 hu->hu_PortNum11[cnt] = cnt - usb11ports;
471 hc->hc_PortNum20[cnt - usb11ports] = cnt;
474 usb11ports += hc->hc_NumPorts;
476 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
478 if((usb11ports != usb20ports) && usb20ports)
480 KPRINTF(20, ("Warning! #EHCI Ports (%ld) does not match USB 1.1 Ports (%ld)!\n", usb20ports, usb11ports));
483 hu->hu_RootHub11Ports = usb11ports;
484 hu->hu_RootHub20Ports = usb20ports;
485 #if defined(AROS_USB30_CODE)
486 // FIXME: This is probably wrong as well...
487 hu->hu_RootHub30Ports = usb30ports;
488 hu->hu_RootHubPorts = (usb11ports > usb20ports) ? ((usb11ports > usb30ports) ? usb11ports : usb30ports) : ((usb30ports > usb20ports) ? usb30ports : usb20ports);
489 #else
490 hu->hu_RootHubPorts = (usb11ports > usb20ports) ? usb11ports : usb20ports;
491 #endif
492 for(cnt = 0; cnt < hu->hu_RootHubPorts; cnt++)
494 hu->hu_EhciOwned[cnt] = hu->hu_PortMap20[cnt] ? TRUE : FALSE;
497 #if defined(AROS_USB30_CODE)
498 KPRINTF(1000, ("Unit %ld: USB Board %08lx has %ld USB1.1, %ld USB2.0 and %ld USB3.0 ports!\n", hu->hu_UnitNo, hu->hu_DevID, hu->hu_RootHub11Ports, hu->hu_RootHub20Ports, hu->hu_RootHub30Ports));
499 #else
500 KPRINTF(10, ("Unit %ld: USB Board %08lx has %ld USB1.1 and %ld USB2.0 ports!\n", hu->hu_UnitNo, hu->hu_DevID, hu->hu_RootHub11Ports, hu->hu_RootHub20Ports));
501 #endif
503 hu->hu_FrameCounter = 1;
504 hu->hu_RootHubAddr = 0;
506 // put em online
507 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
508 while(hc->hc_Node.ln_Succ)
510 hc->hc_Flags |= HCF_ONLINE;
511 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
514 // create product name of device
515 prodname = hu->hu_ProductName;
516 *prodname = 0;
517 pciStrcat(prodname, "PCI ");
518 if(ohcicnt + uhcicnt)
520 if(ohcicnt + uhcicnt >1)
522 prodname[4] = ohcicnt + uhcicnt + '0';
523 prodname[5] = 'x';
524 prodname[6] = 0;
526 pciStrcat(prodname, ohcicnt ? "OHCI" : "UHCI");
527 if(ehcicnt)
529 pciStrcat(prodname, " +");
530 } else{
531 pciStrcat(prodname, " USB 1.1");
534 if(ehcicnt)
536 pciStrcat(prodname, " EHCI USB 2.0");
538 #if defined(AROS_USB30_CODE)
539 if(xhcicnt)
541 if(xhcicnt >1)
543 prodname[4] = xhcicnt + '0';
544 prodname[5] = 'x';
545 prodname[6] = 0;
547 pciStrcat(prodname, " XHCI USB 3.0");
549 #endif
550 #if 0 // user can use pcitool to check what the chipset is and not guess it from this
551 pciStrcat(prodname, " Host Controller (");
552 if(ohcicnt + uhcicnt)
554 pciStrcat(prodname, ohcicnt ? "NEC)" : "VIA, Intel, ALI, etc.)");
555 } else {
556 pciStrcat(prodname, "Emulated?)");
558 #else
559 pciStrcat(prodname, " Host Controller");
560 #endif
561 KPRINTF(10, ("Unit allocated!\n"));
563 return TRUE;
565 /* \\\ */
567 /* /// "pciFreeUnit()" */
568 void pciFreeUnit(struct PCIUnit *hu)
570 struct PCIDevice *hd = hu->hu_Device;
571 struct PCIController *hc;
573 struct TagItem pciDeactivate[] =
575 { aHidd_PCIDevice_isIO, FALSE },
576 { aHidd_PCIDevice_isMEM, FALSE },
577 { aHidd_PCIDevice_isMaster, FALSE },
578 { TAG_DONE, 0UL },
581 KPRINTF(10, ("*** pciFreeUnit(%p) ***\n", hu));
583 // put em offline
584 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
585 while(hc->hc_Node.ln_Succ)
587 hc->hc_Flags &= ~HCF_ONLINE;
588 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
591 #if defined(AROS_USB30_CODE)
592 xhciFree(hc, hu);
593 #endif
594 // doing this in three steps to avoid these damn host errors
595 ehciFree(hc, hu);
596 ohciFree(hc, hu);
597 uhciFree(hc, hu);
599 //FIXME: (x/e/o/u)hciFree routines actually ONLY stops the chip NOT free anything as below...
600 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
601 while(hc->hc_Node.ln_Succ) {
602 if(hc->hc_PCIMem) {
603 HIDD_PCIDriver_FreePCIMem(hc->hc_PCIDriverObject, hc->hc_PCIMem);
604 hc->hc_PCIMem = NULL;
606 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
609 // disable and free board
610 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
611 while(hc->hc_Node.ln_Succ)
613 OOP_SetAttrs(hc->hc_PCIDeviceObject, (struct TagItem *) pciDeactivate); // deactivate busmaster and IO/Mem
614 if(hc->hc_PCIIntHandler.h_Node.ln_Name)
616 HIDD_IRQ_RemHandler(hd->hd_IRQHidd, &hc->hc_PCIIntHandler);
617 hc->hc_PCIIntHandler.h_Node.ln_Name = NULL;
619 #if 0
621 PCIXObtainBoard(hc->hc_BoardObject);
622 hc->hc_Flags &= ~HCF_ALLOCATED;
623 PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, 0);
624 PCIXReleaseBoard(hc->hc_BoardObject);
625 #endif
626 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
629 /* \\\ */
631 /* /// "pciExpunge()" */
632 void pciExpunge(struct PCIDevice *hd)
634 struct PCIController *hc;
635 struct PCIUnit *hu;
637 KPRINTF(10, ("*** pciExpunge(%p) ***\n", hd));
639 hu = (struct PCIUnit *) hd->hd_Units.lh_Head;
640 while(((struct Node *) hu)->ln_Succ)
642 Remove((struct Node *) hu);
643 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
644 while(hc->hc_Node.ln_Succ)
646 Remove(&hc->hc_Node);
647 FreePooled(hd->hd_MemPool, hc, sizeof(struct PCIController));
648 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
650 FreePooled(hd->hd_MemPool, hu, sizeof(struct PCIUnit));
651 hu = (struct PCIUnit *) hd->hd_Units.lh_Head;
653 if(hd->hd_PCIHidd)
655 struct OOP_ABDescr attrbases[] =
657 { (STRPTR) IID_Hidd, &hd->hd_HiddAB },
658 { (STRPTR) IID_Hidd_PCIDevice, &hd->hd_HiddPCIDeviceAB },
659 { NULL, NULL }
662 OOP_ReleaseAttrBases(attrbases);
664 OOP_DisposeObject(hd->hd_PCIHidd);
666 if(hd->hd_IRQHidd)
668 OOP_DisposeObject(hd->hd_IRQHidd);
671 /* \\\ */
673 /* /// "pciGetPhysical()" */
674 APTR pciGetPhysical(struct PCIController *hc, APTR virtaddr)
676 //struct PCIDevice *hd = hc->hc_Device;
677 return(HIDD_PCIDriver_CPUtoPCI(hc->hc_PCIDriverObject, virtaddr));
679 /* \\\ */
682 * Process some AROS-specific arguments.
683 * 'usbpoweron' helps to bring up USB ports on IntelMac,
684 * whose firmware sets them up incorrectly.
686 static int getArguments(struct PCIDevice *base)
688 APTR BootLoaderBase = OpenResource("bootloader.resource");
690 if (BootLoaderBase)
692 struct List *args = GetBootInfo(BL_Args);
694 if (args)
696 struct Node *node;
698 for (node = args->lh_Head; node->ln_Succ; node = node->ln_Succ)
700 if (stricmp(node->ln_Name, "forceusbpower") == 0)
702 base->hd_Flags = HDF_FORCEPOWER;
703 break;
709 return TRUE;
712 ADD2INITLIB(getArguments, 10)