2 Copyright © 2004-2013, The AROS Development Team. All rights reserved.
5 Desc: PCI bus driver for ahci.device
9 #define __OOP_NOMETHODBASES__
11 #include <aros/asmcall.h>
12 #include <aros/debug.h>
13 #include <aros/symbolsets.h>
15 #include <exec/lists.h>
16 #include <hardware/ahci.h>
19 #include <proto/exec.h>
20 #include <proto/oop.h>
24 #include "ahci_intern.h"
30 struct AHCIBase
*AHCIBase
;
32 OOP_AttrBase HiddPCIDeviceAttrBase
;
33 OOP_MethodID HiddPCIDriverMethodBase
;
36 int ahci_attach(device_t dev
)
38 struct ahci_softc
*sc
= device_get_softc(dev
);
40 sc
->sc_ad
= ahci_lookup_device(dev
);
41 if (sc
->sc_ad
== NULL
)
42 return ENXIO
; /* WTF? This matched during the probe... */
44 return sc
->sc_ad
->ad_attach(dev
);
47 void ahci_release(device_t dev
)
49 struct AHCIBase
*AHCIBase
= dev
->dev_AHCIBase
;
50 OOP_MethodID HiddPCIDeviceBase
= AHCIBase
->ahci_HiddPCIDeviceMethodBase
;
52 HIDD_PCIDevice_Release(dev
->dev_Object
);
53 FreePooled(AHCIBase
->ahci_MemPool
, dev
, sizeof(*dev
) + sizeof(*(dev
->dev_softc
)));
58 * collect all SATA devices and spawn concurrent tasks.
60 * ahci.device unit numbers are as follows:
61 * First AHCI device: unit 0..31
62 * Second device: units 32..63
67 AROS_UFH3(void, ahci_PCIEnumerator_h
,
68 AROS_UFHA(struct Hook
*, hook
, A0
),
69 AROS_UFHA(OOP_Object
*, Device
, A2
),
70 AROS_UFHA(APTR
, message
,A1
))
75 const struct ahci_device
*ad
;
76 EnumeratorArgs
*a
= hook
->h_Data
;
77 struct AHCIBase
*AHCIBase
= a
->AHCIBase
;
78 OOP_MethodID HiddPCIDeviceBase
= AHCIBase
->ahci_HiddPCIDeviceMethodBase
;
81 dev
= AllocPooled(AHCIBase
->ahci_MemPool
, sizeof(*dev
) + sizeof(*(dev
->dev_softc
)));
85 dev
->dev_AHCIBase
= AHCIBase
;
86 dev
->dev_Object
= Device
;
87 dev
->dev_softc
= (void *)&dev
[1];
88 dev
->dev_HostID
= AHCIBase
->ahci_HostCount
;
90 D(bug("[PCI-AHCI] ahci_PCIEnumerator_h: Scan device %04x:%04x\n", pci_get_vendor(dev
), pci_get_device(dev
)));
92 ad
= ahci_lookup_device(dev
);
94 FreePooled(AHCIBase
->ahci_MemPool
, dev
, sizeof(*dev
) + sizeof(*(dev
->dev_softc
)));
98 D(bug("[AHCI] Found PCI device %04x:%04x\n", pci_get_vendor(dev
), pci_get_device(dev
)));
100 owner
= HIDD_PCIDevice_Obtain(Device
, AHCIBase
->ahci_Device
.dd_Library
.lib_Node
.ln_Name
);
103 D(bug("[AHCI] Device is already in use by %s\n", owner
));
104 FreePooled(AHCIBase
->ahci_MemPool
, dev
, sizeof(*dev
) + sizeof(*(dev
->dev_softc
)));
108 AHCIBase
->ahci_HostCount
++;
109 AddTail(&a
->devices
, (struct Node
*)dev
);
115 static const struct TagItem Requirements
[] =
117 {tHidd_PCI_Class
, PCI_CLASS_MASSSTORAGE
},
118 {tHidd_PCI_SubClass
, PCI_SUBCLASS_SATA
},
119 {tHidd_PCI_Interface
, 1},
123 static int ahci_pci_scan(struct AHCIBase
*AHCIBase
)
129 D(bug("[PCI-AHCI] ahci_scan: Enumerating devices\n"));
131 Args
.AHCIBase
= AHCIBase
;
132 NEWLIST(&Args
.devices
);
134 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
138 struct Hook FindHook
=
140 h_Entry
: (IPTR (*)())ahci_PCIEnumerator_h
,
144 struct pHidd_PCI_EnumDevices enummsg
=
146 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
148 requirements
: Requirements
,
151 OOP_DoMethod(pci
, &enummsg
.mID
);
152 OOP_DisposeObject(pci
);
155 D(bug("[PCI-AHCI] ahci_scan: Registering Probed Hosts..\n"));
157 while ((dev
= (device_t
)RemHead(&Args
.devices
)) != NULL
) {
158 if (ahci_attach(dev
) != 0) {
167 * ahci.device main code has two init routines with 0 and 127 priorities.
168 * All bus scanners must run between them.
170 ADD2INITLIB(ahci_pci_scan
, 30)