ahci: Removable media support
[AROS.git] / rom / devs / ahci / bus_pci.c
blob8b54834dda648275dd7322d43278e7f21e340cc8
1 /*
2 Copyright © 2004-2011, The AROS Development Team. All rights reserved.
3 $Id: lowlevel.c 34191 2010-08-17 16:19:51Z neil $
5 Desc: PCI bus driver for ata.device
6 Lang: English
7 */
9 #include <aros/asmcall.h>
10 #include <aros/debug.h>
11 #include <aros/symbolsets.h>
12 #include <asm/io.h>
13 #include <exec/lists.h>
14 #include <hardware/ahci.h>
15 #include <hidd/irq.h>
16 #include <hidd/pci.h>
17 #include <oop/oop.h>
18 #include <proto/exec.h>
19 #include <proto/oop.h>
21 #include <string.h>
23 #include "ahci_intern.h"
24 #include "ahci.h"
25 #include "pci.h"
27 typedef struct
29 struct AHCIBase *AHCIBase;
30 struct List devices;
31 OOP_AttrBase HiddPCIDeviceAttrBase;
32 OOP_MethodID HiddPCIDriverMethodBase;
33 } EnumeratorArgs;
35 int ahci_attach(device_t dev)
37 struct ahci_softc *sc = device_get_softc(dev);
39 sc->sc_ad = ahci_lookup_device(dev);
40 if (sc->sc_ad == NULL)
41 return ENXIO; /* WTF? This matched during the probe... */
43 return sc->sc_ad->ad_attach(dev);
47 * PCI BUS ENUMERATOR
48 * collect all SATA devices and spawn concurrent tasks.
51 static
52 AROS_UFH3(void, ahci_PCIEnumerator_h,
53 AROS_UFHA(struct Hook *, hook, A0),
54 AROS_UFHA(OOP_Object *, Device, A2),
55 AROS_UFHA(APTR, message,A1))
57 AROS_USERFUNC_INIT
59 device_t dev;
60 const struct ahci_device *ad;
61 EnumeratorArgs *a = hook->h_Data;
62 struct AHCIBase *AHCIBase = a->AHCIBase;
64 dev = AllocPooled(AHCIBase->ahci_MemPool, sizeof(*dev) + sizeof(*(dev->dev_softc)));
65 if (dev == NULL)
66 return;
68 dev->dev_AHCIBase = AHCIBase;
69 dev->dev_Object = Device;
70 dev->dev_softc = (void *)&dev[1];
72 D(bug("[PCI-AHCI] ahci_PCIEnumerator_h: Scan device %04x:%04x\n", pci_get_vendor(dev), pci_get_device(dev)));
74 ad = ahci_lookup_device(dev);
75 if (!ad) {
76 FreePooled(AHCIBase->ahci_MemPool, dev, sizeof(*dev) + sizeof(*(dev->dev_softc)));
77 return;
80 D(bug("[PCI-AHCI] ahci_PCIEnumerator_h: Found device %04x:%04x\n", pci_get_vendor(dev), pci_get_device(dev)));
82 AddTail(&a->devices, (struct Node *)dev);
84 return;
85 AROS_USERFUNC_EXIT
88 static const struct TagItem Requirements[] =
90 {tHidd_PCI_Class, PCI_CLASS_MASSSTORAGE},
91 {tHidd_PCI_SubClass, PCI_SUBCLASS_SATA},
92 {tHidd_PCI_Interface, 1},
93 {TAG_DONE }
96 static int ahci_pci_scan(struct AHCIBase *AHCIBase)
98 OOP_Object *pci;
99 EnumeratorArgs Args;
100 device_t dev;
102 D(bug("[PCI-AHCI] ahci_scan: Enumerating devices\n"));
104 Args.AHCIBase = AHCIBase;
105 NEWLIST(&Args.devices);
107 pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
109 if (pci)
111 struct Hook FindHook =
113 h_Entry: (IPTR (*)())ahci_PCIEnumerator_h,
114 h_Data: &Args
117 struct pHidd_PCI_EnumDevices enummsg =
119 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
120 callback: &FindHook,
121 requirements: Requirements,
124 OOP_DoMethod(pci, &enummsg.mID);
125 OOP_DisposeObject(pci);
128 D(bug("[PCI-AHCI] ahci_scan: Registering Probed Hosts..\n"));
130 while ((dev = (device_t)RemHead(&Args.devices)) != NULL) {
131 if (ahci_attach(dev) != 0) {
132 FreePooled(AHCIBase->ahci_MemPool, dev, sizeof(*dev) + sizeof(*(dev->dev_softc)));
136 return TRUE;
140 * ahci.device main code has two init routines with 0 and 127 priorities.
141 * All bus scanners must run between them.
143 ADD2INITLIB(ahci_pci_scan, 30)
144 ADD2LIBS("irq.hidd", 0, static struct Library *, __irqhidd)