grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / expansion / makedosnode.c
blob77fa2444d5b73bd7722ec7db601558dd32026e4e
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: MakeDosNode() - Create a DOS DeviceNode structure.
6 Lang: English
7 */
9 #include "expansion_intern.h"
10 #include <exec/memory.h>
11 #include <dos/dos.h>
12 #include <dos/dosextens.h>
13 #include <proto/exec.h>
14 #include <string.h>
16 # define DEBUG 0
17 # include <aros/debug.h>
19 /*****************************************************************************
21 NAME */
22 #include <dos/filehandler.h>
23 #include <proto/expansion.h>
25 AROS_LH1(struct DeviceNode *, MakeDosNode,
27 /* SYNOPSIS */
28 AROS_LHA(APTR, parmPacket, A0),
30 /* LOCATION */
31 struct ExpansionBase *, ExpansionBase, 24, Expansion)
33 /* FUNCTION
34 MakeDosNode() will create a DeviceNode structure suitable for
35 passing to dos.library which contains all the information about
36 a device stored in the parmPacket array. This will allow you to
37 enter a DOS device into the system from the information contained
38 in a DosEnvec structure (such as in a RigidDiskBlock PartitionBlock
39 structure).
41 MakeDosNode() will allocate the memory that it needs to construct
42 the DeviceNode, the strings and a FileSysStartupMsg that is passed
43 to the filesystem handler on startup.
45 You can use AddBootNode() to add a node to the system.
47 INPUTS
48 parmPacket - an IPTR array containing the device parameters
49 required to initialize the structures. This is a
50 variable length structure. See also the DosEnvec
51 structure in dos/filehandler.h
53 Index Description
54 -------- -----------
55 0 Exec string with dos device name (eg. DH0)
56 1 Exec string with exec device name (eg. fdsk.device)
57 2 unit number of device to open
58 3 flags (for OpenDevice())
59 4 length of the remaining data
60 5-n environment data - consists of:
62 5 Size of standard device block in 32 bit longwords
63 6 not used; 0
64 7 # of heads - drive specific
65 8 # of sectors per block - not used; 0
66 9 # of blocks per track - drive specific
67 10 # of reserved blocks at the start of the partition
68 11 # of reserved blocks at the end of the partition
69 12 device interleave
70 13 starting cylinder of partition
71 14 end cylinder of partition
72 15 initial number of buffers
73 16 type of memory for buffers (CHIP, FAST,...)
74 17 max number of bytes to transfer at one time
75 18 address mask allowable for DMA transfers
76 19 boot priority for autobootable devices
77 20 standard DOS filesystem ID (eg 'DOS\1')
78 21 baud rate for serial handler
79 22 control word for handler/filesystem
80 23 number of boot blocks on this partition
82 RESULT
83 deviceNode - An initialized DeviceNode structure, or NULL if
84 the required memory could not be allocated. The
85 caller will have to modify this structure before
86 passing it to AddBootNode().
88 NOTES
89 There are a number of fields of the DeviceNode structure that this
90 function cannot initialize due to a lack of information. You
91 should fill these in yourself.
93 EXAMPLE
95 BUGS
97 SEE ALSO
98 AddBootNode(), AddDosNode(), dos.library/MakeDosEntry()
100 INTERNALS
102 *****************************************************************************/
104 AROS_LIBFUNC_INIT
106 struct DeviceNode *dn;
107 struct FileSysStartupMsg *fssm;
108 struct DosEnvec *de;
109 const struct DosEnvec *de_pp;
110 ULONG desize;
111 STRPTR s1, s2 = 0;
112 BSTR bs1, bs2;
113 int strLen1, strLen2, sz1, sz2;
114 int i; /* Loop variable */
116 if (parmPacket == NULL)
118 return NULL;
121 /* This is the environment structure */
122 de_pp = (struct DosEnvec *)((IPTR *)parmPacket + 4);
123 desize = sizeof(IPTR) * (de_pp->de_TableSize + 1);
125 /* Get the length of the strings we'll be packing */
126 strLen1 = strlen((STRPTR)((IPTR *)parmPacket)[0]);
127 /* Round size to alloc to nearest mutiple of 4 */
128 sz1 = (AROS_BSTR_MEMSIZE4LEN(strLen1) + 3) & ~3;
130 /* There doesn't have to exist an underlying block device */
131 if ((STRPTR)((IPTR *)parmPacket)[1] != NULL)
133 strLen2 = strlen((STRPTR)((IPTR *)parmPacket)[1]);
135 else
137 strLen2 = 0;
139 sz2 = AROS_BSTR_MEMSIZE4LEN(strLen2 + 1);
141 /* Allocate it all as one big chunk. Helps with disposal later. */
142 dn = AllocVec(sizeof(*dn)+sizeof(*fssm)+desize+sz1+sz2, MEMF_CLEAR | MEMF_PUBLIC);
143 if (dn == NULL)
145 return NULL;
148 /* fssm is the (IPTR aligned) memory after the DeviceNode */
149 fssm = (struct FileSysStartupMsg *)(&dn[1]);
150 /* de is the (IPTR aligned) memory after the fssm */
151 de = (struct DosEnvec *)(&fssm[1]);
152 /* s1 is the memory after the de */
153 s1 = ((APTR)de) + desize;
154 /* And s2 is then memory after that */
155 s2 = s1 + sz1;
157 /* Now that we have the pointers, fill it all */
158 CopyMem(de_pp, de, desize);
160 bs1 = MKBADDR(s1);
161 bs2 = MKBADDR(s2);
163 for (i = 0; i < strLen1; i++)
165 AROS_BSTR_putchar(bs1, i, ((STRPTR)((IPTR *)parmPacket)[0])[i]);
168 for (i = 0; i < strLen2; i++)
170 AROS_BSTR_putchar(bs2, i, ((STRPTR)((IPTR *)parmPacket)[1])[i]);
173 AROS_BSTR_setstrlen(bs1, strLen1 > 255 ? 255 : strLen1);
174 /* fssm_Device is a BSTR that includes terminating NULL in BSTR length byte! */
175 AROS_BSTR_setstrlen(bs2, strLen2 + 1 > 255 ? 255 : strLen2 + 1);
177 /* Strings are done, now the FileSysStartupMsg */
178 fssm->fssm_Unit = ((IPTR *)parmPacket)[2];
179 fssm->fssm_Device = bs2;
180 fssm->fssm_Environ = MKBADDR(de);
181 fssm->fssm_Flags = ((IPTR *)parmPacket)[3];
183 /* FSSM is done, now the DeviceNode */
184 dn->dn_Startup = MKBADDR(fssm);
185 dn->dn_Type = DLT_DEVICE;
186 dn->dn_Name = bs1;
187 dn->dn_Priority = 10;
188 dn->dn_StackSize = 4000;
190 #if __WORDSIZE > 32
192 * EXPERIMENTAL: Fix up BufMemType on 64 bits.
193 * Many software set Mask to 0x7FFFFFFF, assuming 31-bit memory, with BufMemType = PUBLIC.
194 * This is perfectly true on 32-bit architectures, where addresses from 0x80000000 and up
195 * belong to MMIO, however on 64 bits we might have memory beyond this address.
196 * And AllocMem(MEMF_PUBLIC) would prefer to return that memory. This might screw up
197 * filesystems expecting AllocMem() to return memory fully corresponding to the mask.
199 if ((de->de_TableSize >= DE_MASK) && (!(de->de_Mask & 0x7FFFFFFF)))
200 de->de_BufMemType |= MEMF_31BIT;
201 #endif
203 return dn;
205 AROS_LIBFUNC_EXIT
206 } /* MakeDosNode */