Bugfix to avoid an endless loop.
[cake.git] / test / dummydev.c
blob4a0c8e6445e2396505197a564957f0f4d108e96a
1 /*
2 Copyright © 1995-2002, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/errors.h>
7 #include <exec/types.h>
8 #include <exec/resident.h>
9 #include <clib/exec_protos.h>
10 #include <aros/libcall.h>
11 #ifdef __GNUC__
12 # include "dummydev_gcc.h"
13 #endif
14 #include "initstruct.h"
16 struct inittable;
17 extern const char name[];
18 extern const char version[];
19 extern const APTR inittabl[4];
20 extern void *const functable[];
21 extern const struct inittable datatable;
22 extern struct dummybase *dummy_init();
23 extern void dummy_open();
24 extern BPTR dummy_close();
25 extern BPTR dummy_expunge();
26 extern int dummy_null();
27 extern void dummy_beginio();
28 extern LONG dummy_abortio();
29 extern const char end;
31 int entry(void)
33 /* If the device was executed by accident return error code. */
34 return -1;
37 const struct Resident resident=
39 RTC_MATCHWORD,
40 (struct Resident *)&resident,
41 (APTR)&end,
42 RTF_AUTOINIT,
44 NT_LIBRARY,
46 (char *)name,
47 (char *)&version[6],
48 (ULONG *)inittabl
51 const char name[]="dummy.device";
53 const char version[]="$VER: dummy 1.0 (28.3.96)\n\015";
55 const APTR inittabl[4]=
57 (APTR)sizeof(struct dummybase),
58 (APTR)functable,
59 (APTR)&datatable,
60 &dummy_init
63 void *const functable[]=
65 &dummy_open,
66 &dummy_close,
67 &dummy_expunge,
68 &dummy_null,
69 &dummy_beginio,
70 &dummy_abortio,
71 (void *)-1
74 struct inittable
76 S_CPYO(1,1,B);
77 S_CPYO(2,1,L);
78 S_CPYO(3,1,B);
79 S_CPYO(4,1,W);
80 S_CPYO(5,1,W);
81 S_CPYO(6,1,L);
82 S_END (end);
85 #define O(n) offsetof(struct dummybase,n)
87 const struct inittable datatable=
89 { { I_CPYO(1,B,O(device.dd_Library.lib_Node.ln_Type)), { NT_LIBRARY } } },
90 { { I_CPYO(1,L,O(device.dd_Library.lib_Node.ln_Name)), { (IPTR)name } } },
91 { { I_CPYO(1,B,O(device.dd_Library.lib_Flags )), { LIBF_SUMUSED|LIBF_CHANGED } } },
92 { { I_CPYO(1,W,O(device.dd_Library.lib_Version )), { 1 } } },
93 { { I_CPYO(1,W,O(device.dd_Library.lib_Revision )), { 0 } } },
94 { { I_CPYO(1,L,O(device.dd_Library.lib_IdString )), { (IPTR)&version[6] } } },
95 I_END ()
98 #undef O
100 AROS_LH2(struct dummybase *, init,
101 AROS_LA(struct dummybase *, dummybase, D0),
102 AROS_LA(BPTR, segList, A0),
103 struct ExecBase *, SysBase, 0, dummy)
105 AROS_LIBFUNC_INIT
106 /* This function is single-threaded by exec by calling Forbid. */
108 /* Store arguments */
109 dummybase->sysbase=SysBase;
110 dummybase->seglist=segList;
112 /* You would return NULL here if the init failed. */
113 return dummybase;
114 AROS_LIBFUNC_EXIT
117 /* Use This from now on */
118 #ifdef SysBase
119 #undef SysBase
120 #endif
121 #define SysBase dummybase->sysbase
123 AROS_LH3(void, open,
124 AROS_LA(struct dummyrequest *, iob, A1),
125 AROS_LA(ULONG, unitnum, D0),
126 AROS_LA(ULONG, flags, D0),
127 struct dummybase *, dummybase, 1, dummy)
129 AROS_LIBFUNC_INIT
131 This function is single-threaded by exec by calling Forbid.
132 If you break the Forbid() another task may enter this function
133 at the same time. Take care.
136 /* Keep compiler happy */
137 unitnum=0;
138 flags=0;
141 Normally you'd init the unit and set the unit field here -
142 but this is only a dummy without child tasks.
145 /* I have one more opener. */
146 dummybase->device.dd_Library.lib_OpenCnt++;
147 dummybase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
149 /* Set returncode */
150 iob->iorequest.io_Error=0;
152 /* Mark Message as recently used. */
153 iob->iorequest.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
154 AROS_LIBFUNC_EXIT
157 AROS_LH1(BPTR, close,
158 AROS_LA(struct dummyrequest *, iob, A1),
159 struct dummybase *, dummybase, 2, dummy)
161 AROS_LIBFUNC_INIT
163 This function is single-threaded by exec by calling Forbid.
164 If you break the Forbid() another task may enter this function
165 at the same time. Take care.
168 /* Let any following attemps to use the device crash hard. */
169 iob->iorequest.io_Device=(struct Device *)-1;
171 /* I have one fewer opener. */
172 if(!--dummybase->device.dd_Library.lib_OpenCnt)
174 /* Delayed expunge pending? */
175 if(dummybase->device.dd_Library.lib_Flags&LIBF_DELEXP)
176 /* Then expunge the device */
177 return expunge();
179 return 0;
180 AROS_LIBFUNC_EXIT
183 AROS_LH0(BPTR, expunge, struct dummybase *, dummybase, 3, dummy)
185 AROS_LIBFUNC_INIT
187 BPTR ret;
189 This function is single-threaded by exec by calling Forbid.
190 Never break the Forbid() or strange things might happen.
193 /* Test for openers. */
194 if(dummybase->device.dd_Library.lib_OpenCnt)
196 /* Set the delayed expunge flag and return. */
197 dummybase->device.dd_Library.lib_Flags|=LIBF_DELEXP;
198 return 0;
201 /* Get rid of the device. Remove it from the list. */
202 Remove(&dummybase->device.dd_Library.lib_Node);
204 /* Get returncode here - FreeMem() will destroy the field. */
205 ret=dummybase->seglist;
207 /* Free the memory. */
208 FreeMem((char *)dummybase-dummybase->device.dd_Library.lib_NegSize,
209 dummybase->device.dd_Library.lib_NegSize+dummybase->device.dd_Library.lib_PosSize);
211 return ret;
212 AROS_LIBFUNC_EXIT
214 AROS_LH0I(int, null, struct dummybase *, dummybase, 4, dummy)
216 AROS_LIBFUNC_INIT
217 return 0;
218 AROS_LIBFUNC_EXIT
221 AROS_LH1(void, beginio,
222 AROS_LA(struct dummyrequest *, iob, A1),
223 struct dummybase *, dummybase, 5, dummy)
225 AROS_LIBFUNC_INIT
227 /* WaitIO will look into this */
228 iob->iorequest.io_Message.mn_Node.ln_Type=NT_MESSAGE;
231 Dispatch command (the quick bit tells me that it is allowed to
232 wait on the user's context. I'll ignore it here and do everything quick.)
234 switch(iob->iorequest.io_Command)
236 case 0x1:
237 iob->iorequest.io_Error=0;
238 iob->id=++(dummybase->count);
239 break;
240 default:
241 iob->iorequest.io_Error=IOERR_NOCMD;
242 break;
244 Commands dispatched to a cild task and processed asynchronbously
245 clear the quick bit before the end of beginio.
250 The request is finished now - so send it back.
251 Note that something that was done quick and had the quick bit set
252 doesn't need a ReplyMsg().
254 if(!(iob->iorequest.io_Flags&IOF_QUICK))
255 ReplyMsg(&iob->iorequest.io_Message);
256 AROS_LIBFUNC_EXIT
259 AROS_LH1I(LONG, abortio,
260 AROS_LA(struct dummyrequest *, iob, A1),
261 struct dummybase *, dummybase, 6, dummy)
263 AROS_LIBFUNC_INIT
264 /* Get compiler happy */
265 iob=0;
267 /* Since everything is finished quick nothing needs an abort. */
268 return IOERR_NOCMD;
269 AROS_LIBFUNC_EXIT
272 const char end=0;