Mercurial > vordog
comparison vordog.c @ 7:5a281ce7453c
Add comments
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 08 Jul 2008 16:06:24 +0800 |
parents | 76ce6e6624b8 |
children | a28764b2a28e |
comparison
equal
deleted
inserted
replaced
6:76ce6e6624b8 | 7:5a281ce7453c |
---|---|
153 .d_close = vordog_close, | 153 .d_close = vordog_close, |
154 .d_ioctl = vordog_ioctl, | 154 .d_ioctl = vordog_ioctl, |
155 .d_name = "vordog", | 155 .d_name = "vordog", |
156 }; | 156 }; |
157 | 157 |
158 /* Implements watchdog(9) compatible driver. */ | 158 /* |
159 static int | 159 * Implements watchdog(9) compatible driver. |
160 vordog_wd9_init(int timeout) { | 160 */ |
161 /*! \brief Initialize timer for an interval in specified seconds. | |
162 */ | |
163 static int | |
164 vordog_wd9_init(u_int timeout) { | |
161 int val; | 165 int val; |
162 | 166 |
163 if(timeout < 0 || timeout > 255) | 167 if(timeout < 0 || timeout > 255) |
164 return EINVAL; | 168 return EINVAL; |
165 | 169 |
167 val = 0x80 | (VDT_1S << 4) | VD_TIMER_RST; | 171 val = 0x80 | (VDT_1S << 4) | VD_TIMER_RST; |
168 outb(VD_CTR, val); | 172 outb(VD_CTR, val); |
169 return 0; | 173 return 0; |
170 } | 174 } |
171 | 175 |
176 /*! \brief Reset timer before it is timeout. | |
177 * | |
178 * It make the timer reload it's value from initial value register. | |
179 */ | |
172 static void | 180 static void |
173 vordog_wd9_reset(void) { | 181 vordog_wd9_reset(void) { |
174 outb(VD_STATUS, 0xc0); | 182 outb(VD_STATUS, 0xc0); |
175 } | 183 } |
176 | 184 |
185 /*! \brief Stop counting of watchdog timer. | |
186 */ | |
177 static void | 187 static void |
178 vordog_wd9_disable(void) { | 188 vordog_wd9_disable(void) { |
179 outb(VD_CTR, 0); | 189 outb(VD_CTR, 0); |
180 outb(VD_STATUS, 0xc0); | 190 outb(VD_STATUS, 0xc0); |
181 } | 191 } |
182 | 192 |
183 static void | 193 /*! \brief event handler for watchdog(9). |
184 vordog_wd9_evh(void *private, u_int cmd, int *error) { | 194 * |
195 * Timeout interval of watchdog(9) is defined by power of 2 nanoseconds. | |
196 * Watchdog timer of Vortex86 provides only small range of intervals. | |
197 * We use only the timer in seconds to simplize the code. It provides | |
198 * interval 1~255 seconds. | |
199 * | |
200 * Since, only SFTMR1_STS is work, in my experience, and it is triggered | |
201 * after 4 times of initial value. So, it only (i * 4) seconds in range | |
202 * of 4 ~ (255 * 4), where i is one of positive integer, are supported. | |
203 * | |
204 * The supported time intervals of watchdog(9) are 2^31~2^39 nanoseconds. | |
205 * vordog used a (i * 4) seconds for 2^n seconds while i * 4 seconds is | |
206 * smallest one of intervals that bigger than 2^n seconds. | |
207 */ | |
208 static void | |
209 vordog_wd9_evh(void *priv_data, u_int cmd, int *error) { | |
185 vd_softc_t sc; | 210 vd_softc_t sc; |
186 u_int timeout, u; | 211 u_int timeout, u; |
212 /* 2^31, 2^32, ..., 2^39 nanoseconds */ | |
187 static const int timeouts[] = { 1, 2, 3, 5, 9, 18, 35, 69, 138}; | 213 static const int timeouts[] = { 1, 2, 3, 5, 9, 18, 35, 69, 138}; |
188 | 214 |
189 sc = (vd_softc_t)private; | 215 sc = (vd_softc_t)priv_data; |
190 | 216 |
191 u = cmd & WD_INTERVAL; | 217 u = cmd & WD_INTERVAL; |
192 if(u < 31 || u > 39) { | 218 if(u < 31 || u > 39) { |
219 /* Out of range! Can not be configured. */ | |
193 vordog_wd9_disable(); | 220 vordog_wd9_disable(); |
194 sc->init_val = 0; | 221 sc->init_val = 0; |
195 return; | 222 return; |
196 } | 223 } |
197 | 224 |