2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: BeginIO - Start up a timer.device request.
10 #include <devices/newstyle.h>
11 #include <exec/errors.h>
12 #include <exec/initializers.h>
13 #include <proto/exec.h>
15 #include <asm/mpc5200b.h>
17 /****************************************************************************************/
19 #define NEWSTYLE_DEVICE 1
21 #define ioStd(x) ((struct IOStdReq *)x)
23 /****************************************************************************************/
27 static const UWORD SupportedCommands
[] =
38 /****************************************************************************************/
40 BOOL
timer_addToWaitList(struct TimerBase
*, struct MinList
*, struct timerequest
*);
42 /*****i***********************************************************************
45 #include <devices/timer.h>
46 #include <proto/timer.h>
47 AROS_LH1(void, BeginIO
,
50 AROS_LHA(struct timerequest
*, timereq
, A1
),
53 struct TimerBase
*, TimerBase
, 5, Timer
)
56 BeginIO() will perform a timer.device command. It is normally
57 called from within DoIO() and SendIO().
60 timereq - The request to process.
63 The requested message will be processed.
66 This function is safe to call from interrupts.
73 exec/Abort(), exec/SendIO(), exec/DoIO()
78 23-01-1998 iaint Implemented again.
80 ******************************************************************************/
87 uint32_t initial_time
= mftbl();
90 EClockUpdate(TimerBase
);
93 timereq
->tr_node
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
94 timereq
->tr_node
.io_Error
= 0;
96 unitNum
= (ULONG
)timereq
->tr_node
.io_Unit
;
98 switch(timereq
->tr_node
.io_Command
)
101 case NSCMD_DEVICEQUERY
:
102 #warning In timer.device this is maybe a bit problematic, as the timerequest structure does not have io_Data and io_Length members
104 if (timereq
->tr_node
.io_Message
.mn_Length
< sizeof(struct IOStdReq
))
106 timereq
->tr_node
.io_Error
= IOERR_BADLENGTH
;
108 else if(ioStd(timereq
)->io_Length
< ((LONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
110 timereq
->tr_node
.io_Error
= IOERR_BADLENGTH
;
114 struct NSDeviceQueryResult
*d
;
116 d
= (struct NSDeviceQueryResult
*)ioStd(timereq
)->io_Data
;
118 d
->DevQueryFormat
= 0;
119 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
120 d
->DeviceType
= NSDEVTYPE_TIMER
;
121 d
->DeviceSubType
= 0;
122 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
124 ioStd(timereq
)->io_Actual
= sizeof(struct NSDeviceQueryResult
);
131 EClockUpdate(TimerBase
);
133 GetSysTime(&timereq
->tr_time
);
135 if(!(timereq
->tr_node
.io_Flags
& IOF_QUICK
))
137 ReplyMsg((struct Message
*)timereq
);
139 replyit
= FALSE
; /* Because replyit will clear the timeval */
144 TimerBase
->tb_CurrentTime
.tv_secs
= timereq
->tr_time
.tv_secs
;
145 TimerBase
->tb_CurrentTime
.tv_micro
= timereq
->tr_time
.tv_micro
;
146 EClockSet(TimerBase
);
155 /* Firstly, check to see if request is for past */
157 if(CmpTime(&TimerBase
->tb_CurrentTime
, &timereq
->tr_time
) <= 0)
160 timereq
->tr_time
.tv_secs
= timereq
->tr_time
.tv_micro
= 0;
161 timereq
->tr_node
.io_Error
= 0;
166 /* Ok, we add this to the list */
167 if (timer_addToWaitList(TimerBase
, &TimerBase
->tb_Lists
[TL_WAITVBL
], timereq
))
169 TimerSetup(TimerBase
, initial_time
);
173 timereq
->tr_node
.io_Flags
&= ~IOF_QUICK
;
180 AddTime(&timereq
->tr_time
, &TimerBase
->tb_Elapsed
);
181 /* Slot it into the list */
182 if (timer_addToWaitList(TimerBase
, &TimerBase
->tb_Lists
[TL_VBLANK
], timereq
))
184 TimerSetup(TimerBase
, initial_time
);
187 timereq
->tr_node
.io_Flags
&= ~IOF_QUICK
;
192 case UNIT_WAITECLOCK
:
195 timereq
->tr_node
.io_Error
= IOERR_NOCMD
;
197 } /* switch(unitNum) */
211 timereq
->tr_node
.io_Error
= IOERR_NOCMD
;
213 } /* switch(command) */
217 timereq
->tr_time
.tv_secs
= 0;
218 timereq
->tr_time
.tv_micro
= 0;
219 if(!(timereq
->tr_node
.io_Flags
& IOF_QUICK
))
221 ReplyMsg((struct Message
*)timereq
);
229 timer_addToWaitList(struct TimerBase
*TimerBase
,
230 struct MinList
*list
,
231 struct timerequest
*iotr
)
233 /* We are disabled, so we should take as little time as possible. */
234 struct timerequest
*tr
;
237 ForeachNode(list
, tr
)
239 /* If the time in the new request is less than the next request */
240 if(CmpTime(&tr
->tr_time
, &iotr
->tr_time
) < 0)
242 /* Add the node before the next request */
246 tr
->tr_node
.io_Message
.mn_Node
.ln_Pred
254 This will catch the case of either an empty list, or request is
255 for after all other requests
259 AddTail((struct List
*)list
, (struct Node
*)iotr
);
261 /* Return TRUE if it ended up on head of list */
263 return ((struct timerequest
*)list
->mlh_Head
== iotr
) ? TRUE
: FALSE
;