2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
5 Desc: BindDrivers CLI command
9 /******************************************************************************
18 DEVICES/S,DRIVERS/S,DIR/K/A
26 For all device drivers with a .info file in SYS:Expansion, load
27 the device driver via Exec/InitResident() if its PRODUCT=
28 tooltype matches a device that is in the system, and not yet
33 DEVICES -- List all devices, and their bindings
35 DRIVERS -- List all drivers, and their supported products
37 DIR <directory> -- Directory to search, instead of SYS:Expansion/
56 06.01.2012 Jason S. McMullan - Implemented
58 ******************************************************************************/
62 #include <aros/debug.h>
68 #include <exec/resident.h>
70 #include <proto/exec.h>
71 #include <proto/icon.h>
72 #include <proto/dos.h>
73 #include <proto/expansion.h>
76 #define SH_GLOBAL_SYSBASE 1 /* for kprintf() */
78 #include <aros/shcommands.h>
82 struct BindDriverNode
{
84 UBYTE
*bd_ProductString
;
85 struct DiskObject
*bd_Icon
;
87 /* Must be at the end of this extendable structure.. */
95 static LONG
BindDriverAdd(struct List
*drivers
, CONST_STRPTR name
, APTR IconBase
, APTR SysBase
)
97 struct BindDriverNode
*bd
;
98 struct DiskObject
*icon
;
102 icon
= GetDiskObject(name
);
106 if ((product
= FindToolType(icon
->do_ToolTypes
, "PRODUCT"))) {
108 for (cp
= product
; *cp
; cp
++) {
109 if (!(isdigit(*cp
) || *cp
== '|' || *cp
== '/'))
115 /* String had only valid characters */
116 if ((bd
= AllocVec(sizeof(*bd
) + sizeof(bd
->bd_Product
[0])*products
+ strlen(name
) + 1, MEMF_ANY
| MEMF_CLEAR
))) {
119 bd
->bd_ProductString
= product
;
120 bd
->bd_Node
.ln_Name
= (APTR
)&bd
->bd_Product
[products
];
122 D(bug("%s: bd=%lx, icon=%lx\n", __func__
, bd
, icon
));
123 strcpy(bd
->bd_Node
.ln_Name
, name
);
124 for (i
= 0, cp
= product
; *cp
; i
++) {
128 val
= strtoul(cp
, &next
, 10);
129 if (next
== (char *)cp
)
132 bd
->bd_Product
[i
].mfg
= val
;
135 val
= strtoul(cp
, &next
, 10);
136 if (next
== (char *)cp
)
138 bd
->bd_Product
[i
].prod
= val
;
140 bd
->bd_Product
[i
].prod
= PROD_ANY
;
143 if (*next
&& *next
!= '|')
154 if (bd
->bd_Products
) {
155 AddTail(drivers
, &bd
->bd_Node
);
158 FreeDiskObject(bd
->bd_Icon
);
165 D(bug("%s: \tNo PRODUCT= tooltype\n", __func__
));
171 static struct Resident
*SearchResident(BPTR seglist
)
173 const int ressize
= offsetof(struct Resident
, rt_Init
) + sizeof(APTR
);
175 D(bug("%lx: Search for resident...\n", BADDR(seglist
)));
177 APTR addr
= (APTR
)((IPTR
)BADDR(seglist
) - sizeof(ULONG
));
178 ULONG size
= *(ULONG
*)addr
;
180 for (addr
+= sizeof(BPTR
) + sizeof(ULONG
),
181 size
-= sizeof(BPTR
) + sizeof(ULONG
);
183 size
-= 2, addr
+= 2) {
184 struct Resident
*res
= (struct Resident
*)addr
;
186 if (res
->rt_MatchWord
== RTC_MATCHWORD
&&
187 res
->rt_MatchTag
== res
) {
188 D(bug("%lx: Resident found at %lx\n", BADDR(seglist
), res
));
193 seglist
= *(BPTR
*)BADDR(seglist
);
196 D(bug("%lx: No resident\n", BADDR(seglist
)));
200 static LONG
BindDriver(STRPTR name
, UWORD mfg
, UBYTE prod
, UBYTE
*prodstr
, UBYTE
**tooltypes
, APTR ExpansionBase
, APTR DOSBase
, APTR SysBase
)
203 LONG err
= RETURN_OK
;
205 struct CurrentBinding cb
;
206 cb
.cb_ConfigDev
= NULL
;
207 cb
.cb_FileName
= name
;
208 cb
.cb_ProductString
= prodstr
;
209 cb
.cb_ToolTypes
= tooltypes
;
211 while ((cb
.cb_ConfigDev
= FindConfigDev(cb
.cb_ConfigDev
, mfg
, prod
))) {
213 if (cb
.cb_ConfigDev
->cd_Flags
& CDF_SHUTUP
)
216 if (!(cb
.cb_ConfigDev
->cd_Flags
& CDF_CONFIGME
))
219 if ((seglist
= LoadSeg(name
)) != BNULL
) {
220 struct Resident
*res
;
222 if ((res
= SearchResident(seglist
))) {
223 D(bug("Binding=%lx, name=%s, res=%lx\n", &cb
, name
, res
));
224 ObtainConfigBinding();
225 SetCurrentBinding(&cb
, sizeof(cb
));
226 D(bug("Calling InitResident via %lx\n", (IPTR
)SysBase
- 6 * 17));
227 if (InitResident(res
, seglist
) == NULL
) {
228 D(bug("\tfailed\n"));
233 ReleaseConfigBinding();
235 /* No resident? Then never loadable */
237 D(bug("No resident for %s\n", name
));
241 /* Can't load the file? Then don't try again */
245 if (err
!= RETURN_OK
) {
254 AROS_SH3(BindDrivers
, 41.1,
255 AROS_SHA(BOOL
, ,DRIVERS
,/S
, FALSE
),
256 AROS_SHA(BOOL
, ,DEVICES
,/S
, FALSE
),
257 AROS_SHA(STRPTR
, ,DIR,/K
, "SYS:Expansion"))
262 struct ExAllControl
*eac
;
265 struct BindDriverNode
*node
, *tmp
;
266 struct Library
*ExpansionBase
;
267 struct Library
*IconBase
;
270 if (!(ExpansionBase
= OpenLibrary("expansion.library", 33)))
273 if (!(IconBase
= OpenLibrary("icon.library", 36))) {
274 CloseLibrary(ExpansionBase
);
278 /* Just dump what devices we have */
279 if (SHArg(DEVICES
)) {
280 struct ConfigDev
*cdev
= NULL
;
282 ObtainConfigBinding();
283 while ((cdev
= FindConfigDev(cdev
, -1, -1))) {
284 struct Node
*node
= cdev
->cd_Driver
;
285 Printf("%5ld/%-3ld %08lx-%08lx %s\n",
286 cdev
->cd_Rom
.er_Manufacturer
,
287 cdev
->cd_Rom
.er_Product
,
288 (ULONG
)(IPTR
)cdev
->cd_BoardAddr
,
289 (ULONG
)(IPTR
)cdev
->cd_BoardAddr
+cdev
->cd_BoardSize
-1,
290 (cdev
->cd_Flags
& CDF_CONFIGME
) ?
291 "(unbound)" : (const char *)node
->ln_Name
);
293 ReleaseConfigBinding();
294 CloseLibrary(IconBase
);
295 CloseLibrary(ExpansionBase
);
301 lock
= Lock(SHArg(DIR), SHARED_LOCK
);
304 Printf("BindDrivers: Can't open %s\n", SHArg(DIR));
305 CloseLibrary(IconBase
);
306 CloseLibrary(ExpansionBase
);
311 olddir
= CurrentDir(lock
);
313 if ((eac
= AllocDosObject(DOS_EXALLCONTROL
,NULL
))) {
318 more
= ExAll(lock
, (struct ExAllData
*)&eadarr
[0], sizeof(eadarr
), ED_NAME
, eac
);
319 if (!more
&& (IoErr() != ERROR_NO_MORE_ENTRIES
))
322 if (eac
->eac_Entries
) {
323 struct ExAllData
*ead
;
325 for (ead
= (APTR
)&eadarr
[0]; ead
; ead
=ead
->ed_Next
)
326 BindDriverAdd(&drivers
, ead
->ed_Name
, IconBase
, SysBase
);
331 ForeachNodeSafe(&drivers
, node
, tmp
) {
333 for (i
= 0; i
< node
->bd_Products
; i
++) {
334 /* If SHArg(DRIVERS) is true, just list the drivers
336 if (SHArg(DRIVERS
)) {
337 Printf("%5ld/%-3ld %s\n", (ULONG
)node
->bd_Product
[i
].mfg
, (ULONG
)node
->bd_Product
[i
].prod
, node
->bd_Node
.ln_Name
);
340 err
= BindDriver(node
->bd_Node
.ln_Name
, node
->bd_Product
[i
].mfg
, node
->bd_Product
[i
].prod
, node
->bd_ProductString
, node
->bd_Icon
->do_ToolTypes
, ExpansionBase
, DOSBase
, SysBase
);
341 if (err
!= RETURN_OK
)
345 Remove(&node
->bd_Node
);
346 FreeDiskObject(node
->bd_Icon
);
353 CloseLibrary(IconBase
);
354 CloseLibrary(ExpansionBase
);