revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / ahci / bus_pci.c
blob23a939725ccc8e870c8c2c8c80303bb505698840
1 /*
2 Copyright © 2004-2018, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PCI bus driver for ahci.device
6 Lang: English
7 */
9 #include <aros/debug.h>
11 #include <proto/exec.h>
13 /* We want all other bases obtained from our base */
14 #define __NOLIBBASE__
16 #include <proto/oop.h>
18 #include <aros/asmcall.h>
19 #include <aros/symbolsets.h>
20 #include <asm/io.h>
21 #include <exec/lists.h>
22 #include <hardware/ahci.h>
23 #include <hidd/pci.h>
24 #include <oop/oop.h>
26 #include <string.h>
28 #include "ahci.h"
29 #include "pci.h"
31 typedef struct
33 struct AHCIBase *AHCIBase;
34 struct List devices;
35 OOP_AttrBase HiddPCIDeviceAttrBase;
36 OOP_MethodID HiddPCIDriverMethodBase;
37 } EnumeratorArgs;
39 CONST_STRPTR ahciDeviceName = "ahci.device";
40 CONST_STRPTR ahciControllerName = "PCI AHCI Controller";
42 int ahci_attach(device_t dev)
44 struct ahci_softc *sc = device_get_softc(dev);
46 if (sc->sc_ad == NULL)
48 sc->sc_ad = ahci_lookup_device(dev);
49 if (sc->sc_ad == NULL)
50 return ENXIO; /* WTF? This matched during the probe... */
52 return sc->sc_ad->ad_attach(dev);
55 void ahci_release(device_t dev)
57 struct AHCIBase *AHCIBase = dev->dev_AHCIBase;
58 OOP_MethodID HiddPCIDeviceBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
60 HIDD_PCIDevice_Release(dev->dev_Object);
61 FreePooled(AHCIBase->ahci_MemPool, dev, sizeof(*dev) + sizeof(*(dev->dev_softc)));
65 * PCI BUS ENUMERATOR
66 * collect all SATA devices and spawn concurrent tasks.
68 * ahci.device unit numbers are as follows:
69 * First AHCI device: unit 0..31
70 * Second device: units 32..63
71 * etc..
74 static
75 AROS_UFH3(void, ahci_PCIEnumerator_h,
76 AROS_UFHA(struct Hook *, hook, A0),
77 AROS_UFHA(OOP_Object *, Device, A2),
78 AROS_UFHA(APTR, message,A1))
80 AROS_USERFUNC_INIT
82 device_t dev;
84 EnumeratorArgs *a = hook->h_Data;
85 struct AHCIBase *AHCIBase = a->AHCIBase;
86 OOP_MethodID HiddPCIDeviceBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
87 CONST_STRPTR owner;
89 dev = AllocPooled(AHCIBase->ahci_MemPool, sizeof(*dev) + sizeof(*(dev->dev_softc)));
90 if (dev == NULL)
91 return;
93 dev->dev_AHCIBase = AHCIBase;
94 dev->dev_Object = Device;
95 dev->dev_softc = (void *)&dev[1];
96 dev->dev_HostID = AHCIBase->ahci_HostCount;
98 D(bug("[AHCI:PCI] %s: Checking PCI device @ 0x%p\n", __PRETTY_FUNCTION__, Device));
100 dev->dev_softc->sc_ad = ahci_lookup_device(dev);
101 if (!dev->dev_softc->sc_ad) {
102 D(bug("[AHCI:PCI] %s: Device not supported\n", __PRETTY_FUNCTION__));
103 FreePooled(AHCIBase->ahci_MemPool, dev, sizeof(*dev) + sizeof(*(dev->dev_softc)));
104 return;
107 D(bug("[AHCI:PCI] %s: Found '%s'\n", __PRETTY_FUNCTION__, dev->dev_softc->sc_ad->name));
109 owner = HIDD_PCIDevice_Obtain(Device, AHCIBase->ahci_Device.dd_Library.lib_Node.ln_Name);
110 if (owner)
112 D(bug("[AHCI:PCI] Device is already in use by %s\n", __PRETTY_FUNCTION__, owner));
113 FreePooled(AHCIBase->ahci_MemPool, dev, sizeof(*dev) + sizeof(*(dev->dev_softc)));
114 return;
117 AHCIBase->ahci_HostCount++;
119 AddTail(&a->devices, (struct Node *)dev);
121 return;
122 AROS_USERFUNC_EXIT
125 static const struct TagItem Requirements[] =
127 {tHidd_PCI_Class, PCI_CLASS_MASSSTORAGE},
128 {tHidd_PCI_SubClass, PCI_SUBCLASS_SATA},
129 {tHidd_PCI_Interface, 1},
130 {TAG_DONE }
133 static int ahci_bus_Detect(struct AHCIBase *AHCIBase)
135 OOP_Object *pci;
136 EnumeratorArgs Args;
137 device_t dev;
138 struct TagItem ahci_tags[] =
140 {aHidd_Name , (IPTR)ahciDeviceName },
141 {aHidd_HardwareName , (IPTR)ahciControllerName },
142 {aHidd_Producer , 0 },
143 #define AHCI_TAG_VEND 2
144 {aHidd_Product , 0 },
145 #define AHCI_TAG_PROD 3
146 {aHidd_DriverData , 0 },
147 #define AHCI_TAG_DATA 4
148 {TAG_DONE , 0 }
151 D(bug("[AHCI:PCI] %s: Enumerating PCI Devices\n", __PRETTY_FUNCTION__));
153 Args.AHCIBase = AHCIBase;
154 NEWLIST(&Args.devices);
156 pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
158 if (pci)
160 struct Hook FindHook =
162 h_Entry: (IPTR (*)())ahci_PCIEnumerator_h,
163 h_Data: &Args
166 struct pHidd_PCI_EnumDevices enummsg =
168 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
169 callback: &FindHook,
170 requirements: Requirements,
173 OOP_DoMethod(pci, &enummsg.mID);
174 OOP_DisposeObject(pci);
177 D(bug("[AHCI:PCI] %s: Registering Detected Hosts..\n", __PRETTY_FUNCTION__));
179 while ((dev = (device_t)RemHead(&Args.devices)) != NULL) {
180 if ((ahci_tags[AHCI_TAG_VEND].ti_Data = dev->dev_softc->sc_ad->ad_vendor) == 0)
181 ahci_tags[AHCI_TAG_VEND].ti_Data = pci_get_vendor(dev);
182 if ((ahci_tags[AHCI_TAG_PROD].ti_Data = dev->dev_softc->sc_ad->ad_product) == 0)
183 ahci_tags[AHCI_TAG_PROD].ti_Data = pci_get_device(dev);
184 ahci_tags[AHCI_TAG_DATA].ti_Data = (IPTR)dev;
185 HW_AddDriver(AHCIBase->storageRoot, AHCIBase->ahciClass, ahci_tags);
186 D(bug("[AHCI:PCI] %s: AHCI Controller Object @ 0x%p\n", __PRETTY_FUNCTION__, dev->dev_Controller));
187 if (dev->dev_Controller)
189 if (ahci_attach(dev) != 0) {
190 ahci_release(dev);
191 return FALSE;
196 return TRUE;
200 * ahci.device main code has two init routines with 0 and 127 priorities.
201 * All bus scanners must run between them.
203 ADD2INITLIB(ahci_bus_Detect, 30)