revert between 56095 -> 55830 in arch
[AROS.git] / rom / expansion / addbootnode.c
blob332c24cbe5ac7e14d2e0322f03be382cb356a517
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Add a bootable device into the system.
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <exec/memory.h>
13 #include <exec/execbase.h>
14 #include <dos/filehandler.h>
16 #include <proto/exec.h>
17 #include <proto/dos.h>
19 #include "expansion_intern.h"
21 /*****************************************************************************
23 NAME */
24 #include <libraries/configvars.h>
25 #include <proto/expansion.h>
27 AROS_LH4(BOOL, AddBootNode,
29 /* SYNOPSIS */
30 AROS_LHA(LONG , bootPri, D0),
31 AROS_LHA(ULONG , flags, D1),
32 AROS_LHA(struct DeviceNode *, deviceNode, A0),
33 AROS_LHA(struct ConfigDev *, configDev, A1),
35 /* LOCATION */
36 struct ExpansionBase *, ExpansionBase, 6, Expansion)
38 /* FUNCTION
39 AddBootNode() will add a device into the system. It does this in
40 one of two ways:
42 1. If DOS is running, add the device to DOS's list of devices
43 immediately.
44 2. Otherwise, save the information for later use by DOS, possibly
45 as a boot device.
47 This allows device drivers to add devices into the system's disk
48 device list at any time, without having to worry about whether DOS
49 is available.
51 If a device is added before DOS is running, then it is possible for
52 the device to be used as a boot device. This allows for the user
53 to choose which device he/she wishes to boot from, and even which
54 OS they may wish to boot from.
56 The bootstrap will attempt to boot from the highest priority device
57 on the Expansion BootNode list, and if that fails continue
58 through the list until it can succeed.
60 Floppy disk devices should always be given the highest priority, to
61 allow a user to prevent a hard disk or network boot by inserting a
62 floppy disk.
64 AddBootNode() will also perform a second bit of magic, that if there
65 is no filesystem specified for this device, (i.e. dn_SegList, dn_Task
66 and dn_Handler are all NULL), then the standard DOS filesystem
67 will be used for this device.
69 INPUTS
70 bootPri - a BYTE describing the boot priority for this disk.
71 Recommended priorities are:
73 +5 - unit 0 on the floppy disk. The floppy
74 should be the highest priority.
75 0 - standard hard disk priority
76 -5 - recommended for a network disk
77 -128 - don't bother trying
79 flags - Additional information:
81 ADNF_STARTPROC (bit 0)-
82 if set this will cause AddBootNode() to start
83 a filesystem handler for the device node from
84 the information contained in the deviceNode
85 packet. This bit is only useful when there is
86 no running handler for this task (ie dn_Task
87 is NULL).
89 deviceNode - DOS device node for this device. Typically created
90 by MakeDosNode().
92 configDev - A valid expansion board ConfigDev structure, this
93 is required for an autoboot before DOS is running.
94 If left NULL, the node cannot be BootPoint booted.
96 RESULT
97 TRUE if everything was ok,
98 FALSE if for some reason we failed (lack of memory etc).
100 NOTES
101 The address of the ConfigDev structure is stored in the ln_Name
102 field of the BootNode structure.
104 EXAMPLE
106 BUGS
108 SEE ALSO
109 AddDosNode()
111 INTERNALS
113 HISTORY
115 *****************************************************************************/
117 AROS_LIBFUNC_INIT
119 struct BootNode *bn;
120 APTR DOSBase;
121 BOOL ok = FALSE;
123 if (deviceNode == NULL)
124 return ok;
126 D(bug("[AddBootNode] Adding %b from Task %s\n", deviceNode->dn_Name, FindTask(NULL)->tc_Node.ln_Name));
128 ObtainSemaphore(&IntExpBase(ExpansionBase)->BootSemaphore);
130 /* See if DOS is up and running... */
131 DOSBase = OpenLibrary("dos.library", 0);
133 /* See if DOS has chosen a boot device yet */
134 if (!(ExpansionBase->Flags & EBF_DOSFLAG))
136 /* If DOS isn't up yet, that's fine */
137 ok = TRUE;
139 /* Don't add the same node twice */
140 ForeachNode(&ExpansionBase->MountList, bn)
142 if (stricmp(AROS_BSTR_ADDR(
143 ((struct DeviceNode *) bn->bn_DeviceNode)->dn_Name),
144 AROS_BSTR_ADDR(deviceNode->dn_Name)) == 0)
146 /* so there was already an entry with that DOS name */
147 D(bug("[AddBootNode] Rejecting attempt to add duplicate device\n"));
148 ok = FALSE;
152 if (ok)
154 bn = AllocMem(sizeof(struct BootNode), MEMF_CLEAR | MEMF_PUBLIC);
155 if (bn == NULL)
156 ok = FALSE;
159 if (ok)
161 bn->bn_Node.ln_Name = (STRPTR)configDev;
162 bn->bn_Node.ln_Type = NT_BOOTNODE;
163 bn->bn_Node.ln_Pri = bootPri;
164 bn->bn_Flags = flags;
165 bn->bn_DeviceNode = deviceNode;
166 D(bug("[AddBootNode] Add BootNode %p to the MountList\n", bn));
167 Forbid();
168 Enqueue(&ExpansionBase->MountList, (struct Node *)bn);
169 Permit();
171 else
172 ok = FALSE;
174 else if (DOSBase != NULL)
176 /* We should add the filesystem to the DOS device list. It will
177 * be usable from this point onwards.
179 * The DeviceNode structure that was passed to us can be added
180 * to the DOS list as it is, and we will let DOS start the
181 * filesystem task if it is necessary to do so.
183 if (AddDosEntry((struct DosList *)deviceNode))
185 if (!(flags & ADNF_STARTPROC))
187 ok = TRUE;
189 else
191 STRPTR dosname;
192 BYTE len = AROS_BSTR_strlen(deviceNode->dn_Name);
194 /* append a colon to the name, DeviceProc() needs a full path */
195 dosname = AllocVec(len + 1 + 1, MEMF_ANY);
196 if (dosname)
198 CopyMem(AROS_BSTR_ADDR(deviceNode->dn_Name), dosname, len);
199 dosname[len++] = ':';
200 dosname[len++] = 0;
202 /* DeviceProc() will see that dn_Device for this node is NULL
203 * and start up the handler.
205 D(bug("[AddBootNode] Starting up \"%s\"\n", dosname));
206 DeviceProc(dosname);
207 FreeVec(dosname);
208 ok = TRUE;
214 else
215 Alert(AT_DeadEnd | AG_OpenLib | AO_DOSLib);
217 ReleaseSemaphore(&IntExpBase(ExpansionBase)->BootSemaphore);
218 if (DOSBase != NULL)
219 CloseLibrary((struct Library *)DOSBase);
221 return ok;
223 AROS_LIBFUNC_EXIT
224 } /* AddBootNode */