2 Copyright © 2004-2018, The AROS Development Team. All rights reserved.
5 Desc: PCI bus driver for ahci.device
9 #include <aros/debug.h>
11 #include <proto/exec.h>
13 /* We want all other bases obtained from our base */
16 #include <proto/oop.h>
18 #include <aros/asmcall.h>
19 #include <aros/symbolsets.h>
21 #include <exec/lists.h>
22 #include <hardware/ahci.h>
33 struct AHCIBase
*AHCIBase
;
35 OOP_AttrBase HiddPCIDeviceAttrBase
;
36 OOP_MethodID HiddPCIDriverMethodBase
;
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
)));
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
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
))
84 EnumeratorArgs
*a
= hook
->h_Data
;
85 struct AHCIBase
*AHCIBase
= a
->AHCIBase
;
86 OOP_MethodID HiddPCIDeviceBase
= AHCIBase
->ahci_HiddPCIDeviceMethodBase
;
89 dev
= AllocPooled(AHCIBase
->ahci_MemPool
, sizeof(*dev
) + sizeof(*(dev
->dev_softc
)));
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
)));
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
);
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
)));
117 AHCIBase
->ahci_HostCount
++;
119 AddTail(&a
->devices
, (struct Node
*)dev
);
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},
133 static int ahci_bus_Detect(struct AHCIBase
*AHCIBase
)
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
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
);
160 struct Hook FindHook
=
162 h_Entry
: (IPTR (*)())ahci_PCIEnumerator_h
,
166 struct pHidd_PCI_EnumDevices enummsg
=
168 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
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) {
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)