2 Copyright © 2018, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/exec.h>
10 /* We want all other bases obtained from our base */
13 #include <proto/oop.h>
14 #include <proto/utility.h>
16 #include <hidd/storage.h>
17 #include <hidd/ahci.h>
18 #include <hidd/hidd.h>
20 #include <utility/tagitem.h>
27 static AROS_INTH1(ahciBus_Reset
, struct ahci_Bus
*, bus
)
31 struct AHCIBase
*AHCIBase
= bus
->ab_Base
;
32 OOP_Object
*obj
= (void *)bus
- AHCIBase
->busClass
->InstOffset
;
34 D(bug ("[AHCI:Bus] ahciBus_Reset(%p)\n", bus
);)
36 HIDD_AHCIBus_Shutdown(obj
);
44 /*****************************************************************************************
47 --background_busclass--
53 This class serves as a base class for implementing AHCI SATA bus drivers.
55 *****************************************************************************************/
56 /*****************************************************************************************
68 Returns a pointer to OOP object of private unit class, representing
69 a drive on the bus, or NULL if there's no device.
81 *****************************************************************************************/
83 OOP_Object
*AHCIBus__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
85 struct AHCIBase
*AHCIBase
= cl
->UserData
;
86 struct ahci_port
*ap
= (struct ahci_port
*)GetTagData(aHidd_DriverData
, 0, msg
->attrList
);
88 D(bug ("[AHCI:Bus] Root__New()\n");)
93 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
96 struct ahci_Bus
*data
= OOP_INST_DATA(cl
, o
);
98 struct TagItem
*tstate
= msg
->attrList
;
101 while ((tag
= NextTagItem(&tstate
)))
105 Hidd_AHCIBus_Switch(tag
->ti_Tag
, idx
)
110 /* Cache device base pointer. Useful. */
111 data
->ab_Base
= AHCIBase
;
112 if ((data
->ab_Port
= ap
) != NULL
)
117 bug ("[AHCI:Bus] Root__New: AHCIBase @ %p\n", data
->ab_Base
);
118 bug ("[AHCI:Bus] Root__New: ahci_port @ %p\n", data
->ab_Port
);
124 void AHCIBus__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
127 struct ahci_Bus
*data
= OOP_INST_DATA(cl
, o
);
129 D(bug ("[AHCI:Bus] Root__Dispose(%p)\n", o
);)
131 OOP_DoSuperMethod(cl
, o
, msg
);
135 * Here we take into account that the table can be either
136 * terminated early, or have NULL entries.
138 void AHCIBus__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
140 struct AHCIBase
*AHCIBase
= cl
->UserData
;
142 struct ahci_Bus
*data
= OOP_INST_DATA(cl
, o
);
146 Hidd_Bus_Switch (msg
->attrID
, idx
)
148 case aoHidd_Bus_MaxUnits
:
153 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
156 void AHCIBus__Hidd_StorageBus__EnumUnits(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_StorageBus_EnumUnits
*msg
)
158 struct ahci_Bus
*data
= OOP_INST_DATA(cl
, o
);
160 D(bug ("[AHCI:Bus] Hidd_StorageBus__EnumUnits()\n");)
164 CALLHOOKPKT(msg
->callback
, data
->ab_Unit
, msg
->hookMsg
);
168 /*****************************************************************************************
171 moHidd_AHCIBus_Shutdown
174 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_AHCIBus_Shutdown *Msg);
176 APTR HIDD_AHCIBus_Shutdown(void);
182 Instantly shutdown all activity on the bus.
191 This method is called by ahci.device during system reset handler execution.
200 Default implementation disables interrupt using AltControl register.
202 *****************************************************************************************/
204 void AHCIBus__Hidd_AHCIBus__Shutdown(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg
*msg
)
207 struct ahci_Bus
*data
= OOP_INST_DATA(cl
, o
);
209 D(bug ("[AHCI:Bus] AHCIBus__Shutdown(%p)\n", o
);)
212 /***************** Private nonvirtual methods follow *****************/
214 BOOL
Hidd_AHCIBus_Start(OOP_Object
*o
, struct AHCIBase
*AHCIBase
)
216 D(bug ("[AHCI:Bus] AHCIBus_Start(%p)\n", o
);)
218 struct ahci_Bus
*ab
= OOP_INST_DATA(AHCIBase
->busClass
, o
);
219 struct ahci_port
*ap
= ab
->ab_Port
;
221 while (ap
->ap_signal
& AP_SIGF_INIT
)
223 ahci_os_lock_port(ap
);
224 if (ahci_cam_attach(ap
) == 0) {
225 ahci_cam_changed(ap
, NULL
, -1);
226 ahci_os_unlock_port(ap
);
227 while ((ap
->ap_flags
& AP_F_SCAN_COMPLETED
) == 0) {
231 ahci_os_unlock_port(ap
);
239 AROS_UFH3(BOOL
, Hidd_AHCIBus_Open
,
240 AROS_UFHA(struct Hook
*, h
, A0
),
241 AROS_UFHA(OOP_Object
*, obj
, A2
),
242 AROS_UFHA(IPTR
, reqUnit
, A1
))
246 D(bug ("[AHCI:Bus] Hidd_AHCIBus_Open(%p)\n", obj
);)
248 struct IORequest
*req
= h
->h_Data
;
249 struct AHCIBase
*AHCIBase
= (struct AHCIBase
*)req
->io_Device
;
250 struct ahci_Bus
*b
= (struct ahci_Bus
*)OOP_INST_DATA(AHCIBase
->busClass
, obj
);
251 ULONG bus
= reqUnit
>> 1;
252 UBYTE dev
= reqUnit
& 1;
254 D(bug("[ATA%02ld] Checking bus %u dev %u\n", reqUnit
, bus
, dev
));
256 if ((b
->ab_BusNum
== bus
) && b
->ab_Units
[dev
])
259 req
->io_Unit
= &b
->ab_Units
[dev
]->au_Unit
;
262 b
->ab_Units
[dev
]->au_Unit
.unit_OpenCnt
++;