revert between 56095 -> 55830 in arch
[AROS.git] / workbench / tools / SysExplorer / Modules / Storage / storage_enum.c
blobf87ca7e37990c315dc56d09b5e68023a4c9fced8
1 /*
2 Copyright (C) 2015-2019, The AROS Development Team.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #define __STORAGE_NOLIBBASE__
10 #include <proto/sysexp.h>
11 #include <proto/storage.h>
13 #include <proto/alib.h>
14 #include <proto/dos.h>
15 #include <proto/exec.h>
16 #include <proto/muimaster.h>
17 #include <proto/oop.h>
18 #include <proto/utility.h>
19 #include <proto/intuition.h>
21 #include <mui/NListtree_mcc.h>
22 #include <utility/tagitem.h>
23 #include <utility/hooks.h>
25 #include <devices/newstyle.h>
26 #include <devices/ata.h>
28 #include "locale.h"
29 #include "enums.h"
31 #include "storage_classes.h"
32 #include "storage_intern.h"
34 #if (1) // TODO : Move into libbase
35 extern OOP_AttrBase HiddAttrBase;
36 extern OOP_AttrBase HWAttrBase;
37 extern OOP_AttrBase HiddStorageUnitAB;
39 extern OOP_MethodID HWBase;
40 extern OOP_MethodID HiddStorageControllerBase;
41 extern OOP_MethodID HiddStorageBusBase;
42 extern OOP_MethodID HiddStorageUnitBase;
43 #endif
45 CONST_STRPTR storagebuswindowclass_name = "StorageBusWindow.Class";
46 CONST_STRPTR storageunitwindowclass_name = "StorageUnitWindow.Class";
48 AROS_UFH3S(BOOL, storageenumFunc,
49 AROS_UFHA(struct Hook *, h, A0),
50 AROS_UFHA(OOP_Object*, obj, A2),
51 AROS_UFHA(void *, parent, A1))
53 AROS_USERFUNC_INIT
55 BOOL objValid = TRUE;
56 CONST_STRPTR name = NULL;
57 struct MUI_NListtree_TreeNode *tn;
58 ULONG flags = 0;
59 struct SysexpEnum_data *edata = (struct SysexpEnum_data *)h->h_Data;
60 struct InsertObjectMsg msg =
62 .obj = obj,
63 .winClass = NULL
65 struct ClassHandlerNode *clHandlers;
66 struct SysexpBase *SysexpBase;
68 D(bug("[storage.sysexp] %s()\n", __func__));
70 if (!edata)
71 return TRUE;
73 SysexpBase = edata->ed_sysexpbase;
74 clHandlers = FindObjectHandler(obj, edata->ed_list);
76 D(bug("[storage.sysexp] %s: list @ 0x%p\n", __func__, edata->ed_list));
77 D(bug("[storage.sysexp] %s: handler @ 0x%p\n", __func__, clHandlers));
79 if (clHandlers)
81 if (clHandlers->muiClass)
82 msg.winClass = clHandlers->muiClass;
83 if (clHandlers->enumFunc)
84 flags = TNF_LIST|TNF_OPEN;
85 if (clHandlers->validFunc)
86 objValid = clHandlers->validFunc(obj, &flags);
89 if (objValid)
91 int objnum;
93 /* This is either HW or HIDD subclass */
94 OOP_GetAttr(obj, aHW_ClassName, (IPTR *)&name);
95 if (!name)
96 OOP_GetAttr(obj, aHidd_HardwareName, (IPTR *)&name);
98 D(bug("[storage.sysexp] %s: name = '%s'\n", __func__, name));
100 objnum = ++SysexpBase->GlobalCount;
102 tn = (APTR)DoMethod(SysexpBase->sesb_Tree, MUIM_NListtree_Insert, name, &msg,
103 parent, MUIV_NListtree_Insert_PrevNode_Tail, flags);
104 D(bug("[storage.sysexp] %s: Inserted TreeNode 0x%p <%s> UserData 0x%p\n", __func__, tn, tn->tn_Name, tn->tn_User));
106 /* If we have enumerator for this class, call it now */
107 if (clHandlers && clHandlers->enumFunc && (flags & TNF_LIST))
108 clHandlers->enumFunc(obj, tn);
110 if (objnum == SysexpBase->GlobalCount)
112 tn->tn_Flags &= ~flags;
115 return FALSE; /* Continue enumeration */
117 AROS_USERFUNC_EXIT
121 AROS_UFH3S(BOOL, storageunitenumFunc,
122 AROS_UFHA(struct Hook *, h, A0),
123 AROS_UFHA(OOP_Object*, unit, A2),
124 AROS_UFHA(void *, parent, A1))
126 AROS_USERFUNC_INIT
128 struct SysexpEnum_data *edata = (struct SysexpEnum_data *)h->h_Data;
129 struct InsertObjectMsg msg =
131 .obj = unit,
132 .winClass = StorageUnitWindow_CLASS
134 CONST_STRPTR name;
135 struct SysexpBase *SysexpBase;
137 D(bug("[storage.sysexp] %s()\n", __func__));
139 if (!edata)
140 return TRUE;
142 SysexpBase = edata->ed_sysexpbase;
144 D(bug("[storage.sysexp] %s: StorageUnit @ %p\n", __func__, unit));
145 if (!unit)
146 return TRUE;
148 SysexpBase->GlobalCount++;
150 OOP_GetAttr(unit, aHidd_StorageUnit_Model, (IPTR *)&name);
151 DoMethod(SysexpBase->sesb_Tree, MUIM_NListtree_Insert, name, &msg,
152 parent, MUIV_NListtree_Insert_PrevNode_Tail, 0);
154 return FALSE; /* Continue enumeration */
156 AROS_USERFUNC_EXIT
160 static struct SysexpEnum_data privatehookdata =
162 NULL,
163 NULL
166 struct Hook storageenum_hook =
168 .h_Entry = storageenumFunc,
169 .h_Data = &privatehookdata
172 struct Hook storageunitenum_hook =
174 .h_Entry = storageunitenumFunc,
175 .h_Data = &privatehookdata
178 static void storageHWEnum(OOP_Object *obj, struct MUI_NListtree_TreeNode *tn)
180 D(bug("[storage.sysexp] HWEnum: enumerating..\n"));
181 D(bug("[storage.sysexp] HWEnum: storage class list @ 0x%p\n", storageenum_hook.h_Data));
182 HW_EnumDrivers(obj, &storageenum_hook, tn);
185 static void storageControllerEnum(OOP_Object *obj, struct MUI_NListtree_TreeNode *tn)
187 D(bug("[storage.sysexp] ControllerEnum: enumerating..\n"));
188 D(bug("[storage.sysexp] ControllerEnum: storage class list @ 0x%p\n", storageenum_hook.h_Data));
189 HIDD_StorageController_EnumBuses(obj, &storageenum_hook, tn);
192 void storageBusEnum(OOP_Object *obj, struct MUI_NListtree_TreeNode *parent)
194 D(bug("[storage.sysexp] BusEnum: enumerating..\n"));
195 D(bug("[storage.sysexp] BusEnum: storage class list @ 0x%p\n", storageenum_hook.h_Data));
196 HIDD_StorageBus_EnumUnits(obj, &storageunitenum_hook, parent);
199 AROS_LH4(void, EnumBusUnits,
200 AROS_LHA(OOP_Object *, obj, A0),
201 AROS_LHA(struct MUI_NListtree_TreeNode *, parent, A1),
202 AROS_LHA(APTR, hookFunc, A2),
203 AROS_LHA(APTR, hookData, A3),
204 struct SysexpStorageBase *, StorageBase, 15, Storage)
206 AROS_LIBFUNC_INIT
208 struct Hook busunitenum_hook;
209 D(bug("[storage.sysexp] %s: StorageBus @ %p\n", __func__, obj));
211 busunitenum_hook.h_Entry = hookFunc;
212 busunitenum_hook.h_Data = hookData;
214 HIDD_StorageBus_EnumUnits(obj, &busunitenum_hook, parent);
216 AROS_LIBFUNC_EXIT
220 Query a units device to see if it supports ATA device features, and if they are enebaled
221 for the unit.
222 Add objects to the passed in colgroup(2) if supported features are found.
224 AROS_LH3(void, QueryATAStorageFeatures,
225 AROS_LHA(Object *, obj, A0),
226 AROS_LHA(char *, devName, A1),
227 AROS_LHA(int, devUnit, D0),
228 struct SysexpStorageBase *, StorageBase, 16, Storage)
230 AROS_LIBFUNC_INIT
231 #if (0)
232 struct IOStdReq *io;
233 struct MsgPort * ioReplyPort;
234 struct NSDeviceQueryResult nsdqr;
235 LONG error;
237 ioReplyPort = CreateMsgPort();
238 if (!ioReplyPort)
239 return;
241 io = CreateIORequest(ioReplyPort, sizeof(struct IOStdReq));
242 if (!io)
244 DeleteMsgPort(ioReplyPort);
245 return;
248 if (!OpenDevice(devName, devUnit,(struct IORequest *)io,0))
250 io->io_Command = NSCMD_DEVICEQUERY;
251 io->io_Length = sizeof(nsdqr);
252 io->io_Data = (APTR)&nsdqr;
254 error = DoIO((struct IORequest *)io);
256 if((!error) &&
257 (io->io_Actual >= 16) &&
258 (io->io_Actual <= sizeof(nsdqr)) &&
259 (nsdqr.SizeAvailable == io->io_Actual))
261 UWORD *cmdcheck;
262 for(cmdcheck = nsdqr.SupportedCommands;
263 *cmdcheck;
264 cmdcheck++)
266 ULONG queryres = 0;
268 // Does the device understand the SMART Cmd?
269 if(*cmdcheck == HD_SMARTCMD)
271 // Check if the unit Supports SMART
272 io->io_Command = HD_SMARTCMD;
273 io->io_Reserved1 = io->io_Reserved2 = ATAFEATURE_TEST_AVAIL;
274 io->io_Length = sizeof(queryres);
275 io->io_Data = (APTR)&queryres;
276 error = DoIO((struct IORequest *)io);
277 if ((!error) && (io->io_Actual >= 4) && (queryres == SMART_MAGIC_ID))
279 IPTR smartSpacer = (IPTR)HVSpace;
280 IPTR smartLabel = (IPTR)Label("SMART Supported");
281 if (DoMethod(obj, MUIM_Group_InitChange))
283 DoMethod(obj, OM_ADDMEMBER, smartSpacer);
284 DoMethod(obj, OM_ADDMEMBER, smartLabel);
285 DoMethod(obj, MUIM_Group_ExitChange);
290 // Does the device understand the TRIM Cmd?
291 if(*cmdcheck == HD_TRIMCMD)
293 // Check if the unit Supports TRIM
294 io->io_Command = HD_TRIMCMD;
295 io->io_Reserved1 = io->io_Reserved2 = ATAFEATURE_TEST_AVAIL;
296 io->io_Length = sizeof(queryres);
297 io->io_Data = (APTR)&queryres;
298 error = DoIO((struct IORequest *)io);
299 if ((!error) && (io->io_Actual >= 4) && (queryres == TRIM_MAGIC_ID))
301 IPTR trimSpacer = (IPTR)HVSpace;
302 IPTR trimLabel = (IPTR)Label("TRIM Supported");
303 if (DoMethod(obj, MUIM_Group_InitChange))
305 DoMethod(obj, OM_ADDMEMBER, trimSpacer);
306 DoMethod(obj, OM_ADDMEMBER, trimLabel);
307 DoMethod(obj, MUIM_Group_ExitChange);
313 CloseDevice((struct IORequest *)io);
315 DeleteIORequest((struct IORequest *)io);
316 DeleteMsgPort(ioReplyPort);
317 #endif
318 AROS_LIBFUNC_EXIT
321 AROS_LH5(BOOL, RegisterStorageClassHandler,
322 AROS_LHA(CONST_STRPTR, classid, A0),
323 AROS_LHA(BYTE, pri, D0),
324 AROS_LHA(struct MUI_CustomClass *, customwinclass, A1),
325 AROS_LHA(CLASS_ENUMFUNC, enumfunc, A2),
326 AROS_LHA(CLASS_VALIDFUNC, validfunc, A3),
327 struct SysexpStorageBase *, StorageBase, 9, Storage)
329 AROS_LIBFUNC_INIT
331 struct SysexpBase *SysexpBase = StorageBase->sesb_SysexpBase;
332 struct ClassHandlerNode *newClass;
333 BOOL add = TRUE;
335 if ((newClass = FindClassHandler(classid, &StorageBase->sesb_HandlerList)))
337 if (newClass->enumFunc != GetBase("HWEnum.Func"))
338 return FALSE;
340 D(bug("[storage.sysexp] %s: Updating '%s'..\n", __func__, classid));
341 add = FALSE;
344 if (add)
346 D(bug("[storage.sysexp] %s: Registering '%s'..\n", __func__, classid));
347 newClass = AllocMem(sizeof(struct ClassHandlerNode), MEMF_CLEAR);
350 if (newClass)
352 newClass->ch_Node.ln_Name = (char *)classid;
353 newClass->ch_Node.ln_Pri = pri;
354 newClass->muiClass = customwinclass;
355 newClass->enumFunc = enumfunc;
356 newClass->validFunc = validfunc;
358 if (add)
360 RegisterClassHandler(classid, pri, NULL, newClass->enumFunc, newClass->validFunc);
361 Enqueue(&StorageBase->sesb_HandlerList, &newClass->ch_Node);
364 return TRUE;
366 return FALSE;
368 AROS_LIBFUNC_EXIT
372 AROS_LH5(BOOL, RegisterStorageControllerHandler,
373 AROS_LHA(CONST_STRPTR, classid, A0),
374 AROS_LHA(BYTE, pri, D0),
375 AROS_LHA(struct MUI_CustomClass *, customwinclass, A1),
376 AROS_LHA(CLASS_ENUMFUNC, enumfunc, A2),
377 AROS_LHA(CLASS_VALIDFUNC, validfunc, A3),
378 struct SysexpStorageBase *, StorageBase, 10, Storage)
380 AROS_LIBFUNC_INIT
382 CLASS_ENUMFUNC enumFunc;
384 if (enumfunc)
385 enumFunc = enumfunc;
386 else
387 enumFunc = storageControllerEnum;
389 return RegisterStorageClassHandler(classid, pri, customwinclass, enumFunc, validfunc);
391 AROS_LIBFUNC_EXIT
394 AROS_LH5(BOOL, RegisterStorageBusHandler,
395 AROS_LHA(CONST_STRPTR, classid, A0),
396 AROS_LHA(BYTE, pri, D0),
397 AROS_LHA(struct MUI_CustomClass *, customwinclass, A1),
398 AROS_LHA(CLASS_ENUMFUNC, enumfunc, A2),
399 AROS_LHA(CLASS_VALIDFUNC, validfunc, A3),
400 struct SysexpStorageBase *, StorageBase, 11, Storage)
402 AROS_LIBFUNC_INIT
404 CLASS_ENUMFUNC enumFunc;
406 if (enumfunc)
407 enumFunc = enumfunc;
408 else
409 enumFunc = storageBusEnum;
411 return RegisterStorageClassHandler(classid, pri, customwinclass, enumFunc, validfunc);
413 AROS_LIBFUNC_EXIT
416 void StorageStartup(struct SysexpBase *SysexpBase)
418 struct SysexpStorageBase *StorageBase;
420 D(bug("[storage.sysexp] %s(%p)\n", __func__, SysexpBase));
422 StorageBase = GetBase("Storage.Module");
424 D(bug("[storage.sysexp] %s: StorageBase @ %p\n", __func__, StorageBase));
426 privatehookdata.ed_sysexpbase = SysexpBase;
427 privatehookdata.ed_list = &StorageBase->sesb_HandlerList;
429 StorageBase->sesb_DevicePageCLASS = GetBase("DevicePage.Class");
430 StorageBusWindow_CLASS->mcc_Class->cl_UserData = (IPTR)StorageBase;
432 RegisterBase(storagebuswindowclass_name, StorageBusWindow_CLASS);
433 RegisterBase(storageunitwindowclass_name, StorageUnitWindow_CLASS);
435 RegisterClassHandler(CLID_Hidd_Storage, 90, NULL, storageHWEnum, NULL);
436 RegisterStorageBusHandler(CLID_Hidd_StorageBus, 0, StorageBusWindow_CLASS, NULL, NULL);