- Made pciuhci.device and pciehci.device compile again: completed
[AROS.git] / rom / usb / pciusb / pci_aros.c
blob2f0d990c1a1e0ed972dd8e5467bf919176db2ef5
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 <resources/acpi.h>
13 #include <proto/acpi.h>
14 #include <proto/bootloader.h>
15 #include <proto/oop.h>
16 #include <proto/utility.h>
17 #include <proto/exec.h>
19 #include <inttypes.h>
20 #include <string.h>
22 #include "uhwcmd.h"
23 #include "ohciproto.h"
25 #ifdef __i386__
26 #define HAVE_ACPI
27 #endif
28 #ifdef __x86_64__
29 #define HAVE_ACPI
30 #endif
32 #define NewList NEWLIST
34 #undef HiddPCIDeviceAttrBase
35 //#undef HiddUSBDeviceAttrBase
36 //#undef HiddUSBHubAttrBase
37 //#undef HiddUSBDrvAttrBase
38 #undef HiddAttrBase
40 #define HiddPCIDeviceAttrBase (hd->hd_HiddPCIDeviceAB)
41 //#define HiddUSBDeviceAttrBase (hd->hd_HiddUSBDeviceAB)
42 //#define HiddUSBHubAttrBase (hd->hd_HiddUSBHubAB)
43 //#define HiddUSBDrvAttrBase (hd->hd_HiddUSBDrvAB)
44 #define HiddAttrBase (hd->hd_HiddAB)
46 AROS_UFH3(void, pciEnumerator,
47 AROS_UFHA(struct Hook *, hook, A0),
48 AROS_UFHA(OOP_Object *, pciDevice, A2),
49 AROS_UFHA(APTR, message, A1))
51 AROS_USERFUNC_INIT
53 struct PCIDevice *hd = (struct PCIDevice *) hook->h_Data;
54 struct PCIController *hc;
55 IPTR hcitype;
56 IPTR bus;
57 IPTR dev;
58 IPTR sub;
59 IPTR intline;
60 ULONG devid;
62 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Interface, &hcitype);
63 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Bus, &bus);
64 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Dev, &dev);
65 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Sub, &sub);
66 OOP_GetAttr(pciDevice, aHidd_PCIDevice_INTLine, &intline);
68 devid = (bus<<16)|dev;
70 KPRINTF(10, ("Found PCI device 0x%lx of type %ld, Intline=%ld\n", devid, hcitype, intline));
72 if(intline == 255)
74 // we can't work without the correct interrupt line
75 // BIOS needs plug & play os option disabled. Alternatively AROS must support APIC reconfiguration
76 KPRINTF(200, ("ERROR: PCI card has no interrupt line assigned by BIOS, disable Plug & Play OS!\n"));
78 else
80 switch (hcitype)
82 case HCITYPE_OHCI:
83 case HCITYPE_EHCI:
84 case HCITYPE_UHCI:
85 #ifdef AROS_USB30_CODE
86 case HCITYPE_XHCI:
87 #endif
88 KPRINTF(10, ("Setting up device...\n"));
90 hc = AllocPooled(hd->hd_MemPool, sizeof(struct PCIController));
91 if (hc)
93 hc->hc_Device = hd;
94 hc->hc_DevID = devid;
95 hc->hc_FunctionNum = sub;
96 hc->hc_HCIType = hcitype;
97 hc->hc_PCIDeviceObject = pciDevice;
98 hc->hc_PCIIntLine = intline;
100 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (IPTR *) &hc->hc_PCIDriverObject);
102 NewList(&hc->hc_CtrlXFerQueue);
103 NewList(&hc->hc_IntXFerQueue);
104 NewList(&hc->hc_IsoXFerQueue);
105 NewList(&hc->hc_BulkXFerQueue);
106 NewList(&hc->hc_TDQueue);
107 NewList(&hc->hc_AbortQueue);
108 NewList(&hc->hc_PeriodicTDQueue);
109 NewList(&hc->hc_OhciRetireQueue);
110 AddTail(&hd->hd_TempHCIList, &hc->hc_Node);
112 break;
114 default:
115 KPRINTF(10, ("Unsupported HCI type %ld\n", hcitype));
119 AROS_USERFUNC_EXIT
122 /* /// "pciInit()" */
123 BOOL pciInit(struct PCIDevice *hd)
125 struct PCIController *hc;
126 struct PCIController *nexthc;
127 struct PCIUnit *hu;
128 ULONG unitno = 0;
130 KPRINTF(10, ("*** pciInit(%p) ***\n", hd));
131 /* if(sizeof(IPTR) > 4)
133 KPRINTF(200, ("I said the pciusb.device is not 64bit compatible right now. Go away!\n"));
134 return FALSE;
137 NewList(&hd->hd_TempHCIList);
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 return FALSE;
171 // Create units with a list of host controllers having the same bus and device number.
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);
187 hc = (struct PCIController *) hd->hd_TempHCIList.lh_Head;
188 while((nexthc = (struct PCIController *) hc->hc_Node.ln_Succ))
190 if(hc->hc_DevID == hu->hu_DevID)
192 Remove(&hc->hc_Node);
193 hc->hc_Unit = hu;
194 AddTail(&hu->hu_Controllers, &hc->hc_Node);
196 hc = nexthc;
198 AddTail(&hd->hd_Units, (struct Node *) hu);
199 unitno++;
201 return TRUE;
203 /* \\\ */
205 /* /// "PCIXReadConfigByte()" */
206 UBYTE PCIXReadConfigByte(struct PCIController *hc, UBYTE offset)
208 struct pHidd_PCIDevice_ReadConfigByte msg;
210 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
211 msg.reg = offset;
213 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
215 /* \\\ */
217 /* /// "PCIXReadConfigWord()" */
218 UWORD PCIXReadConfigWord(struct PCIController *hc, UBYTE offset)
220 struct pHidd_PCIDevice_ReadConfigWord msg;
222 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
223 msg.reg = offset;
225 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
227 /* \\\ */
229 /* /// "PCIXReadConfigLong()" */
230 ULONG PCIXReadConfigLong(struct PCIController *hc, UBYTE offset)
232 struct pHidd_PCIDevice_ReadConfigLong msg;
234 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong);
235 msg.reg = offset;
237 return OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
239 /* \\\ */
241 /* /// "PCIXWriteConfigByte()" */
242 void PCIXWriteConfigByte(struct PCIController *hc, ULONG offset, UBYTE value)
244 struct pHidd_PCIDevice_WriteConfigByte msg;
246 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
247 msg.reg = offset;
248 msg.val = value;
250 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
252 /* \\\ */
254 /* /// "PCIXWriteConfigWord()" */
255 void PCIXWriteConfigWord(struct PCIController *hc, ULONG offset, UWORD value)
257 struct pHidd_PCIDevice_WriteConfigWord msg;
259 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigWord);
260 msg.reg = offset;
261 msg.val = value;
263 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
265 /* \\\ */
267 /* /// "PCIXWriteConfigLong()" */
268 void PCIXWriteConfigLong(struct PCIController *hc, ULONG offset, ULONG value)
270 struct pHidd_PCIDevice_WriteConfigLong msg;
272 msg.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigLong);
273 msg.reg = offset;
274 msg.val = value;
276 OOP_DoMethod(hc->hc_PCIDeviceObject, (OOP_Msg) &msg);
278 /* \\\ */
280 /* /// "pciStrcat()" */
281 void pciStrcat(STRPTR d, STRPTR s)
283 while(*d) d++;
284 while((*d++ = *s++));
286 /* \\\ */
288 /* /// "pciAllocUnit()" */
289 BOOL pciAllocUnit(struct PCIUnit *hu)
291 #if 0
292 struct PCIDevice *hd = hu->hu_Device;
293 #endif
294 struct PCIController *hc;
296 BOOL allocgood = TRUE;
297 ULONG usb11ports = 0;
298 ULONG usb20ports = 0;
299 #ifdef AROS_USB30_CODE
300 ULONG usb30ports = 0;
301 #endif
302 ULONG cnt;
304 ULONG ohcicnt = 0;
305 ULONG uhcicnt = 0;
306 ULONG ehcicnt = 0;
307 #ifdef AROS_USB30_CODE
308 ULONG xhcicnt = 0;
309 #endif
311 STRPTR prodname;
313 KPRINTF(10, ("*** pciAllocUnit(%p) ***\n", hu));
315 #if 0 // FIXME this needs to be replaced by something AROS supports
316 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
317 while(hc->hc_Node.ln_Succ)
319 PCIXObtainBoard(hc->hc_BoardObject);
320 if (PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, (ULONG) hd->hd_Library.lib_Node.ln_Name))
321 hc->hc_Flags |= HCF_BOARD_ALLOCATED;
322 else
324 KPRINTF(20, ("Couldn't allocate board, already allocated by %s\n", PCIXGetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER)));
325 allocgood = FALSE;
327 PCIXReleaseBoard(hc->hc_BoardObject);
329 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
332 if(allocgood)
334 #endif
335 // allocate necessary memory
336 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
337 while(hc->hc_Node.ln_Succ)
339 switch(hc->hc_HCIType)
341 case HCITYPE_UHCI:
343 allocgood = uhciInit(hc,hu);
344 if(allocgood) {
345 uhcicnt++;
347 break;
350 case HCITYPE_OHCI:
352 allocgood = ohciInit(hc,hu);
353 if(allocgood) {
354 ohcicnt++;
356 break;
359 case HCITYPE_EHCI:
361 allocgood = ehciInit(hc,hu);
362 if(allocgood) {
363 ehcicnt++;
364 if(usb20ports) {
365 KPRINTF(200, ("WARNING: More than one EHCI controller per board?!?\n"));
367 usb20ports = hc->hc_NumPorts;
369 for(cnt = 0; cnt < usb20ports; cnt++) {
370 hu->hu_PortMap20[cnt] = hc;
371 hc->hc_PortNum20[cnt] = cnt;
374 break;
376 #ifdef AROS_USB30_CODE
377 case HCITYPE_XHCI:
379 allocgood = xhciInit(hc,hu);
380 if(allocgood) {
381 xhcicnt++;
382 if(usb30ports) {
383 KPRINTF(200, ("WARNING: More than one XHCI controller per board?!?\n"));
385 usb20ports = hc->xhc_NumPorts20;
386 usb30ports = hc->xhc_NumPorts30;
388 break;
390 #endif
392 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
394 #if 0 // FIXME this needs to be replaced by something AROS supports
397 if(!allocgood)
399 // free previously allocated boards
400 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
401 while(hc->hc_Node.ln_Succ)
403 PCIXObtainBoard(hc->hc_BoardObject);
404 if (hc->hc_Flags & HCF_ALLOCATED)
406 hc->hc_Flags &= ~HCF_ALLOCATED;
407 PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, 0);
409 PCIXReleaseBoard(hc->hc_BoardObject);
411 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
413 #else
414 if(!allocgood)
416 #endif
417 return FALSE;
420 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
421 while(hc->hc_Node.ln_Succ)
423 if((hc->hc_HCIType == HCITYPE_UHCI) || (hc->hc_HCIType == HCITYPE_OHCI))
425 if(hc->hc_complexrouting)
427 ULONG locport = 0;
428 for(cnt = 0; cnt < usb20ports; cnt++)
430 if(((hc->hc_portroute >> (cnt<<2)) & 0xf) == hc->hc_FunctionNum)
432 KPRINTF(10, ("CHC %ld Port %ld assigned to global Port %ld\n", hc->hc_FunctionNum, locport, cnt));
433 hu->hu_PortMap11[cnt] = hc;
434 hu->hu_PortNum11[cnt] = locport;
435 hc->hc_PortNum20[locport] = cnt;
436 locport++;
439 } else {
440 for(cnt = usb11ports; cnt < usb11ports + hc->hc_NumPorts; cnt++)
442 hu->hu_PortMap11[cnt] = hc;
443 hu->hu_PortNum11[cnt] = cnt - usb11ports;
444 hc->hc_PortNum20[cnt - usb11ports] = cnt;
447 usb11ports += hc->hc_NumPorts;
449 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
451 if((usb11ports != usb20ports) && usb20ports)
453 KPRINTF(20, ("Warning! #EHCI Ports (%ld) does not match USB 1.1 Ports (%ld)!\n", usb20ports, usb11ports));
456 hu->hu_RootHub11Ports = usb11ports;
457 hu->hu_RootHub20Ports = usb20ports;
458 #ifdef AROS_USB30_CODE
459 // FIXME: This is probably wrong as well...
460 hu->hu_RootHub30Ports = usb30ports;
461 hu->hu_RootHubPorts = (usb11ports > usb20ports) ? ((usb11ports > usb30ports) ? usb11ports : usb30ports) : ((usb30ports > usb20ports) ? usb30ports : usb20ports);
462 #else
463 hu->hu_RootHubPorts = (usb11ports > usb20ports) ? usb11ports : usb20ports;
464 #endif
465 for(cnt = 0; cnt < hu->hu_RootHubPorts; cnt++)
467 hu->hu_EhciOwned[cnt] = hu->hu_PortMap20[cnt] ? TRUE : FALSE;
470 #ifdef AROS_USB30_CODE
471 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));
472 #else
473 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));
474 #endif
476 hu->hu_FrameCounter = 1;
477 hu->hu_RootHubAddr = 0;
479 // put em online
480 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
481 while(hc->hc_Node.ln_Succ)
483 hc->hc_Flags |= HCF_ONLINE;
484 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
487 // create product name of device
488 prodname = hu->hu_ProductName;
489 *prodname = 0;
490 pciStrcat(prodname, "PCI ");
491 if(ohcicnt + uhcicnt)
493 if(ohcicnt + uhcicnt >1)
495 prodname[4] = ohcicnt + uhcicnt + '0';
496 prodname[5] = 'x';
497 prodname[6] = 0;
499 pciStrcat(prodname, ohcicnt ? "OHCI" : "UHCI");
500 if(ehcicnt)
502 pciStrcat(prodname, " +");
503 } else{
504 pciStrcat(prodname, " USB 1.1");
507 if(ehcicnt)
509 pciStrcat(prodname, " EHCI USB 2.0");
511 #ifdef AROS_USB30_CODE
512 if(xhcicnt)
514 if(xhcicnt >1)
516 prodname[4] = xhcicnt + '0';
517 prodname[5] = 'x';
518 prodname[6] = 0;
520 pciStrcat(prodname, " XHCI USB 3.0");
522 #endif
523 #if 0 // user can use pcitool to check what the chipset is and not guess it from this
524 pciStrcat(prodname, " Host Controller (");
525 if(ohcicnt + uhcicnt)
527 pciStrcat(prodname, ohcicnt ? "NEC)" : "VIA, Intel, ALI, etc.)");
528 } else {
529 pciStrcat(prodname, "Emulated?)");
531 #else
532 pciStrcat(prodname, " Host Controller");
533 #endif
534 KPRINTF(10, ("Unit allocated!\n"));
536 return TRUE;
538 /* \\\ */
540 /* /// "pciFreeUnit()" */
541 void pciFreeUnit(struct PCIUnit *hu)
543 struct PCIDevice *hd = hu->hu_Device;
544 struct PCIController *hc;
546 struct TagItem pciDeactivate[] =
548 { aHidd_PCIDevice_isIO, FALSE },
549 { aHidd_PCIDevice_isMEM, FALSE },
550 { aHidd_PCIDevice_isMaster, FALSE },
551 { TAG_DONE, 0UL },
554 KPRINTF(10, ("*** pciFreeUnit(%p) ***\n", hu));
556 // put em offline
557 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
558 while(hc->hc_Node.ln_Succ)
560 hc->hc_Flags &= ~HCF_ONLINE;
561 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
564 #ifdef AROS_USB30_CODE
565 xhciFree(hc, hu);
566 #endif
567 // doing this in three steps to avoid these damn host errors
568 ehciFree(hc, hu);
569 ohciFree(hc, hu);
570 uhciFree(hc, hu);
572 //FIXME: (x/e/o/u)hciFree routines actually ONLY stops the chip NOT free anything as below...
573 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
574 while(hc->hc_Node.ln_Succ) {
575 if(hc->hc_PCIMem) {
576 HIDD_PCIDriver_FreePCIMem(hc->hc_PCIDriverObject, hc->hc_PCIMem);
577 hc->hc_PCIMem = NULL;
579 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
582 // disable and free board
583 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
584 while(hc->hc_Node.ln_Succ)
586 OOP_SetAttrs(hc->hc_PCIDeviceObject, (struct TagItem *) pciDeactivate); // deactivate busmaster and IO/Mem
587 if(hc->hc_PCIIntHandler.is_Node.ln_Name)
589 RemIntServer(INTB_KERNEL + hc->hc_PCIIntLine, &hc->hc_PCIIntHandler);
590 hc->hc_PCIIntHandler.is_Node.ln_Name = NULL;
592 #if 0
594 PCIXObtainBoard(hc->hc_BoardObject);
595 hc->hc_Flags &= ~HCF_ALLOCATED;
596 PCIXSetBoardAttr(hc->hc_BoardObject, PCIXTAG_OWNER, 0);
597 PCIXReleaseBoard(hc->hc_BoardObject);
598 #endif
599 hc = (struct PCIController *) hc->hc_Node.ln_Succ;
602 /* \\\ */
604 /* /// "pciExpunge()" */
605 void pciExpunge(struct PCIDevice *hd)
607 struct PCIController *hc;
608 struct PCIUnit *hu;
610 KPRINTF(10, ("*** pciExpunge(%p) ***\n", hd));
612 hu = (struct PCIUnit *) hd->hd_Units.lh_Head;
613 while(((struct Node *) hu)->ln_Succ)
615 Remove((struct Node *) hu);
616 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
617 while(hc->hc_Node.ln_Succ)
619 Remove(&hc->hc_Node);
620 FreePooled(hd->hd_MemPool, hc, sizeof(struct PCIController));
621 hc = (struct PCIController *) hu->hu_Controllers.lh_Head;
623 FreePooled(hd->hd_MemPool, hu, sizeof(struct PCIUnit));
624 hu = (struct PCIUnit *) hd->hd_Units.lh_Head;
626 if(hd->hd_PCIHidd)
628 struct OOP_ABDescr attrbases[] =
630 { (STRPTR) IID_Hidd, &hd->hd_HiddAB },
631 { (STRPTR) IID_Hidd_PCIDevice, &hd->hd_HiddPCIDeviceAB },
632 { NULL, NULL }
635 OOP_ReleaseAttrBases(attrbases);
637 OOP_DisposeObject(hd->hd_PCIHidd);
640 /* \\\ */
642 /* /// "pciGetPhysical()" */
643 APTR pciGetPhysical(struct PCIController *hc, APTR virtaddr)
645 //struct PCIDevice *hd = hc->hc_Device;
646 return(HIDD_PCIDriver_CPUtoPCI(hc->hc_PCIDriverObject, virtaddr));
648 /* \\\ */
651 * Process some AROS-specific arguments.
652 * 'usbpoweron' helps to bring up USB ports on IntelMac,
653 * whose firmware sets them up incorrectly.
655 static int getArguments(struct PCIDevice *base)
657 APTR BootLoaderBase;
658 #ifdef HAVE_ACPI
659 struct ACPIBase *ACPIBase;
661 ACPIBase = OpenResource("acpi.resource");
662 if (ACPIBase)
665 * Use ACPI IDs to identify known machines which need HDF_FORCEPOWER to work.
666 * Currently we know only MacMini.
668 struct ACPI_TABLE_DEF_HEADER *dsdt = ACPI_FindSDT(ACPI_MAKE_ID('D','S','D','T'));
670 if (dsdt)
672 /* Yes, the last byte in ID is zero */
673 if (strcmp(dsdt->oem_table_id, "Macmini") == 0)
675 base->hd_Flags = HDF_FORCEPOWER;
676 return TRUE;
680 #endif
682 BootLoaderBase = OpenResource("bootloader.resource");
683 if (BootLoaderBase)
685 struct List *args = GetBootInfo(BL_Args);
687 if (args)
689 struct Node *node;
691 for (node = args->lh_Head; node->ln_Succ; node = node->ln_Succ)
693 if (stricmp(node->ln_Name, "forceusbpower") == 0)
695 base->hd_Flags = HDF_FORCEPOWER;
696 break;
702 return TRUE;
705 ADD2INITLIB(getArguments, 10)