2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: BeginIO - Start up a timer.device request.
9 #include "timer_intern.h"
10 #include <devices/newstyle.h>
11 #include <exec/errors.h>
12 #include <exec/initializers.h>
13 #include <proto/exec.h>
14 #include <aros/debug.h>
16 /****************************************************************************************/
18 #define NEWSTYLE_DEVICE 1
20 #define ioStd(x) ((struct IOStdReq *)x)
22 /****************************************************************************************/
26 static const UWORD SupportedCommands
[] =
37 /****************************************************************************************/
39 static void addToWaitList(struct TimerBase
*, struct MinList
*, struct timerequest
*);
41 /*****i***********************************************************************
44 #include <devices/timer.h>
45 #include <proto/timer.h>
46 AROS_LH1(void, BeginIO
,
49 AROS_LHA(struct timerequest
*, timereq
, A1
),
52 struct TimerBase
*, TimerBase
, 5, Timer
)
55 BeginIO() will perform a timer.device command. It is normally
56 called from within DoIO() and SendIO().
59 timereq - The request to process.
62 The requested message will be processed.
65 This function is safe to call from interrupts.
72 exec/Abort(), exec/SendIO(), exec/DoIO()
77 23-01-1998 iaint Implemented again.
79 ******************************************************************************/
82 AROS_LIBBASE_EXT_DECL(struct TimerBase
*, TimerBase
)
87 timereq
->tr_node
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
88 timereq
->tr_node
.io_Error
= 0;
90 unitNum
= (ULONG
)timereq
->tr_node
.io_Unit
;
92 switch(timereq
->tr_node
.io_Command
)
95 case NSCMD_DEVICEQUERY
:
96 #warning In timer.device this is maybe a bit problematic, as the timerequest structure does not have io_Data and io_Length members
98 if (timereq
->tr_node
.io_Message
.mn_Length
< sizeof(struct IOStdReq
))
100 timereq
->tr_node
.io_Error
= IOERR_BADLENGTH
;
102 else if(ioStd(timereq
)->io_Length
< ((LONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
104 timereq
->tr_node
.io_Error
= IOERR_BADLENGTH
;
108 struct NSDeviceQueryResult
*d
;
110 d
= (struct NSDeviceQueryResult
*)ioStd(timereq
)->io_Data
;
112 d
->DevQueryFormat
= 0;
113 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
114 d
->DeviceType
= NSDEVTYPE_TIMER
;
115 d
->DeviceSubType
= 0;
116 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
118 ioStd(timereq
)->io_Actual
= sizeof(struct NSDeviceQueryResult
);
124 GetSysTime(&timereq
->tr_time
);
126 if(!(timereq
->tr_node
.io_Flags
& IOF_QUICK
))
128 ReplyMsg((struct Message
*)timereq
);
130 replyit
= FALSE
; /* Because replyit will clear the timeval */
135 TimerBase
->tb_CurrentTime
.tv_secs
= timereq
->tr_time
.tv_secs
;
136 TimerBase
->tb_CurrentTime
.tv_micro
= timereq
->tr_time
.tv_micro
;
145 /* Firstly, check to see if request is for past */
147 if(CmpTime(&TimerBase
->tb_CurrentTime
, &timereq
->tr_time
) <= 0)
150 timereq
->tr_time
.tv_secs
= timereq
->tr_time
.tv_micro
= 0;
151 timereq
->tr_node
.io_Error
= 0;
156 /* Ok, we add this to the list */
157 addToWaitList(TimerBase
, &TimerBase
->tb_Lists
[TL_WAITVBL
], timereq
);
160 timereq
->tr_node
.io_Flags
&= ~IOF_QUICK
;
166 Adjust the time request to be relative to the
167 the elapsed time counter that we keep.
170 AddTime(&timereq
->tr_time
, &TimerBase
->tb_Elapsed
);
172 /* Slot it into the list */
173 addToWaitList(TimerBase
, &TimerBase
->tb_Lists
[TL_VBLANK
], timereq
);
175 timereq
->tr_node
.io_Flags
&= ~IOF_QUICK
;
181 case UNIT_WAITECLOCK
:
184 timereq
->tr_node
.io_Error
= IOERR_NOCMD
;
186 } /* switch(unitNum) */
200 timereq
->tr_node
.io_Error
= IOERR_NOCMD
;
203 } /* switch(command) */
207 timereq
->tr_time
.tv_secs
= 0;
208 timereq
->tr_time
.tv_micro
= 0;
209 if(!(timereq
->tr_node
.io_Flags
& IOF_QUICK
))
211 ReplyMsg((struct Message
*)timereq
);
219 addToWaitList( struct TimerBase
*TimerBase
,
220 struct MinList
*list
,
221 struct timerequest
*iotr
)
223 /* We are disabled, so we should take as little time as possible. */
224 struct timerequest
*tr
;
227 tr
= (struct timerequest
*)list
->mlh_Head
;
229 while(tr
->tr_node
.io_Message
.mn_Node
.ln_Succ
!= NULL
)
231 /* If the time in the new request is less than the next request */
232 if(CmpTime(&tr
->tr_time
, &iotr
->tr_time
) < 0)
234 /* Add the node before the next request */
238 tr
->tr_node
.io_Message
.mn_Node
.ln_Pred
243 tr
= (struct timerequest
*)tr
->tr_node
.io_Message
.mn_Node
.ln_Succ
;
247 This will catch the case of either an empty list, or request is
248 for after all other requests
252 AddTail((struct List
*)list
, (struct Node
*)iotr
);
257 bug("Current list contents:\n");
258 ForeachNode(list
, tr
)
260 bug("%ld: %ld.%ld\n", i
,
261 tr
->tr_time
.tv_secs
, tr
->tr_time
.tv_micro
);