diff options
author | Helge Deller <deller@gmx.de> | 2007-02-28 23:51:29 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-02-28 23:51:29 -0500 |
commit | ffd51f46cdf856c0b453d2828a74d552cc15f881 (patch) | |
tree | 2322b5c7dbbbf876e549e40ff340240b6a59af20 /drivers/input/serio/hil_mlc.c | |
parent | 3acaf540a33199141695f2e2fcfa8829053159bf (diff) |
Input: HIL - cleanup coding style
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/serio/hil_mlc.c')
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 487 |
1 files changed, 272 insertions, 215 deletions
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 0710704d2fd3..485b0742842b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -32,11 +32,11 @@ | |||
32 | * | 32 | * |
33 | * Driver theory of operation: | 33 | * Driver theory of operation: |
34 | * | 34 | * |
35 | * Some access methods and an ISR is defined by the sub-driver | 35 | * Some access methods and an ISR is defined by the sub-driver |
36 | * (e.g. hp_sdc_mlc.c). These methods are expected to provide a | 36 | * (e.g. hp_sdc_mlc.c). These methods are expected to provide a |
37 | * few bits of logic in addition to raw access to the HIL MLC, | 37 | * few bits of logic in addition to raw access to the HIL MLC, |
38 | * specifically, the ISR, which is entirely registered by the | 38 | * specifically, the ISR, which is entirely registered by the |
39 | * sub-driver and invoked directly, must check for record | 39 | * sub-driver and invoked directly, must check for record |
40 | * termination or packet match, at which point a semaphore must | 40 | * termination or packet match, at which point a semaphore must |
41 | * be cleared and then the hil_mlcs_tasklet must be scheduled. | 41 | * be cleared and then the hil_mlcs_tasklet must be scheduled. |
42 | * | 42 | * |
@@ -47,7 +47,7 @@ | |||
47 | * itself if output is pending. (This rescheduling should be replaced | 47 | * itself if output is pending. (This rescheduling should be replaced |
48 | * at some point with a sub-driver-specific mechanism.) | 48 | * at some point with a sub-driver-specific mechanism.) |
49 | * | 49 | * |
50 | * A timer task prods the tasklet once per second to prevent | 50 | * A timer task prods the tasklet once per second to prevent |
51 | * hangups when attached devices do not return expected data | 51 | * hangups when attached devices do not return expected data |
52 | * and to initiate probes of the loop for new devices. | 52 | * and to initiate probes of the loop for new devices. |
53 | */ | 53 | */ |
@@ -83,69 +83,85 @@ DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); | |||
83 | 83 | ||
84 | /********************** Device info/instance management **********************/ | 84 | /********************** Device info/instance management **********************/ |
85 | 85 | ||
86 | static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) { | 86 | static void hil_mlc_clear_di_map(hil_mlc *mlc, int val) |
87 | { | ||
87 | int j; | 88 | int j; |
88 | for (j = val; j < 7 ; j++) { | 89 | |
90 | for (j = val; j < 7 ; j++) | ||
89 | mlc->di_map[j] = -1; | 91 | mlc->di_map[j] = -1; |
90 | } | ||
91 | } | 92 | } |
92 | 93 | ||
93 | static void hil_mlc_clear_di_scratch (hil_mlc *mlc) { | 94 | static void hil_mlc_clear_di_scratch(hil_mlc *mlc) |
94 | memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch)); | 95 | { |
96 | memset(&mlc->di_scratch, 0, sizeof(mlc->di_scratch)); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) { | 99 | static void hil_mlc_copy_di_scratch(hil_mlc *mlc, int idx) |
98 | memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch)); | 100 | { |
101 | memcpy(&mlc->di[idx], &mlc->di_scratch, sizeof(mlc->di_scratch)); | ||
99 | } | 102 | } |
100 | 103 | ||
101 | static int hil_mlc_match_di_scratch (hil_mlc *mlc) { | 104 | static int hil_mlc_match_di_scratch(hil_mlc *mlc) |
105 | { | ||
102 | int idx; | 106 | int idx; |
103 | 107 | ||
104 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 108 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
105 | int j, found; | 109 | int j, found = 0; |
106 | 110 | ||
107 | /* In-use slots are not eligible. */ | 111 | /* In-use slots are not eligible. */ |
108 | found = 0; | 112 | for (j = 0; j < 7 ; j++) |
109 | for (j = 0; j < 7 ; j++) { | 113 | if (mlc->di_map[j] == idx) |
110 | if (mlc->di_map[j] == idx) found++; | 114 | found++; |
111 | } | 115 | |
112 | if (found) continue; | 116 | if (found) |
113 | if (!memcmp(mlc->di + idx, | 117 | continue; |
114 | &(mlc->di_scratch), | 118 | |
115 | sizeof(mlc->di_scratch))) break; | 119 | if (!memcmp(mlc->di + idx, &mlc->di_scratch, |
120 | sizeof(mlc->di_scratch))) | ||
121 | break; | ||
116 | } | 122 | } |
117 | return((idx >= HIL_MLC_DEVMEM) ? -1 : idx); | 123 | return idx >= HIL_MLC_DEVMEM ? -1 : idx; |
118 | } | 124 | } |
119 | 125 | ||
120 | static int hil_mlc_find_free_di(hil_mlc *mlc) { | 126 | static int hil_mlc_find_free_di(hil_mlc *mlc) |
127 | { | ||
121 | int idx; | 128 | int idx; |
122 | /* TODO: Pick all-zero slots first, failing that, | 129 | |
123 | * randomize the slot picked among those eligible. | 130 | /* TODO: Pick all-zero slots first, failing that, |
131 | * randomize the slot picked among those eligible. | ||
124 | */ | 132 | */ |
125 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 133 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
126 | int j, found; | 134 | int j, found = 0; |
127 | found = 0; | 135 | |
128 | for (j = 0; j < 7 ; j++) { | 136 | for (j = 0; j < 7 ; j++) |
129 | if (mlc->di_map[j] == idx) found++; | 137 | if (mlc->di_map[j] == idx) |
130 | } | 138 | found++; |
131 | if (!found) break; | 139 | |
140 | if (!found) | ||
141 | break; | ||
132 | } | 142 | } |
133 | return(idx); /* Note: It is guaranteed at least one above will match */ | 143 | |
144 | return idx; /* Note: It is guaranteed at least one above will match */ | ||
134 | } | 145 | } |
135 | 146 | ||
136 | static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) { | 147 | static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) |
148 | { | ||
137 | int idx; | 149 | int idx; |
150 | |||
138 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 151 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
139 | int j, found; | 152 | int j, found = 0; |
140 | found = 0; | 153 | |
141 | for (j = 0; j < 7 ; j++) { | 154 | for (j = 0; j < 7 ; j++) |
142 | if (mlc->di_map[j] == idx) found++; | 155 | if (mlc->di_map[j] == idx) |
143 | } | 156 | found++; |
144 | if (!found) mlc->serio_map[idx].di_revmap = -1; | 157 | |
158 | if (!found) | ||
159 | mlc->serio_map[idx].di_revmap = -1; | ||
145 | } | 160 | } |
146 | } | 161 | } |
147 | 162 | ||
148 | static void hil_mlc_send_polls(hil_mlc *mlc) { | 163 | static void hil_mlc_send_polls(hil_mlc *mlc) |
164 | { | ||
149 | int did, i, cnt; | 165 | int did, i, cnt; |
150 | struct serio *serio; | 166 | struct serio *serio; |
151 | struct serio_driver *drv; | 167 | struct serio_driver *drv; |
@@ -157,26 +173,31 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { | |||
157 | 173 | ||
158 | while (mlc->icount < 15 - i) { | 174 | while (mlc->icount < 15 - i) { |
159 | hil_packet p; | 175 | hil_packet p; |
176 | |||
160 | p = mlc->ipacket[i]; | 177 | p = mlc->ipacket[i]; |
161 | if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { | 178 | if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { |
162 | if (drv == NULL || drv->interrupt == NULL) goto skip; | 179 | if (drv && drv->interrupt) { |
180 | drv->interrupt(serio, 0, 0); | ||
181 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | ||
182 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | ||
183 | drv->interrupt(serio, HIL_CMD_POL + cnt, 0); | ||
184 | } | ||
163 | 185 | ||
164 | drv->interrupt(serio, 0, 0); | ||
165 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | ||
166 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | ||
167 | drv->interrupt(serio, HIL_CMD_POL + cnt, 0); | ||
168 | skip: | ||
169 | did = (p & HIL_PKT_ADDR_MASK) >> 8; | 186 | did = (p & HIL_PKT_ADDR_MASK) >> 8; |
170 | serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; | 187 | serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; |
171 | drv = (serio != NULL) ? serio->drv : NULL; | 188 | drv = (serio != NULL) ? serio->drv : NULL; |
172 | cnt = 0; | 189 | cnt = 0; |
173 | } | 190 | } |
174 | cnt++; i++; | 191 | |
175 | if (drv == NULL || drv->interrupt == NULL) continue; | 192 | cnt++; |
176 | drv->interrupt(serio, (p >> 24), 0); | 193 | i++; |
177 | drv->interrupt(serio, (p >> 16) & 0xff, 0); | 194 | |
178 | drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); | 195 | if (drv && drv->interrupt) { |
179 | drv->interrupt(serio, p & 0xff, 0); | 196 | drv->interrupt(serio, (p >> 24), 0); |
197 | drv->interrupt(serio, (p >> 16) & 0xff, 0); | ||
198 | drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); | ||
199 | drv->interrupt(serio, p & 0xff, 0); | ||
200 | } | ||
180 | } | 201 | } |
181 | } | 202 | } |
182 | 203 | ||
@@ -215,12 +236,16 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { | |||
215 | #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) | 236 | #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) |
216 | #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) | 237 | #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) |
217 | 238 | ||
218 | static int hilse_match(hil_mlc *mlc, int unused) { | 239 | static int hilse_match(hil_mlc *mlc, int unused) |
240 | { | ||
219 | int rc; | 241 | int rc; |
242 | |||
220 | rc = hil_mlc_match_di_scratch(mlc); | 243 | rc = hil_mlc_match_di_scratch(mlc); |
221 | if (rc == -1) { | 244 | if (rc == -1) { |
222 | rc = hil_mlc_find_free_di(mlc); | 245 | rc = hil_mlc_find_free_di(mlc); |
223 | if (rc == -1) goto err; | 246 | if (rc == -1) |
247 | goto err; | ||
248 | |||
224 | #ifdef HIL_MLC_DEBUG | 249 | #ifdef HIL_MLC_DEBUG |
225 | printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); | 250 | printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); |
226 | #endif | 251 | #endif |
@@ -231,6 +256,7 @@ static int hilse_match(hil_mlc *mlc, int unused) { | |||
231 | serio_rescan(mlc->serio[rc]); | 256 | serio_rescan(mlc->serio[rc]); |
232 | return -1; | 257 | return -1; |
233 | } | 258 | } |
259 | |||
234 | mlc->di_map[mlc->ddi] = rc; | 260 | mlc->di_map[mlc->ddi] = rc; |
235 | #ifdef HIL_MLC_DEBUG | 261 | #ifdef HIL_MLC_DEBUG |
236 | printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); | 262 | printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); |
@@ -238,152 +264,177 @@ static int hilse_match(hil_mlc *mlc, int unused) { | |||
238 | mlc->serio_map[rc].di_revmap = mlc->ddi; | 264 | mlc->serio_map[rc].di_revmap = mlc->ddi; |
239 | hil_mlc_clean_serio_map(mlc); | 265 | hil_mlc_clean_serio_map(mlc); |
240 | return 0; | 266 | return 0; |
267 | |||
241 | err: | 268 | err: |
242 | printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); | 269 | printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); |
243 | return 1; | 270 | return 1; |
244 | } | 271 | } |
245 | 272 | ||
246 | /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ | 273 | /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ |
247 | static int hilse_init_lcv(hil_mlc *mlc, int unused) { | 274 | static int hilse_init_lcv(hil_mlc *mlc, int unused) |
275 | { | ||
248 | struct timeval tv; | 276 | struct timeval tv; |
249 | 277 | ||
250 | do_gettimeofday(&tv); | 278 | do_gettimeofday(&tv); |
251 | 279 | ||
252 | if(mlc->lcv == 0) goto restart; /* First init, no need to dally */ | 280 | if (mlc->lcv && (tv.tv_sec - mlc->lcv_tv.tv_sec) < 5) |
253 | if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1; | 281 | return -1; |
254 | restart: | 282 | |
255 | mlc->lcv_tv = tv; | 283 | mlc->lcv_tv = tv; |
256 | mlc->lcv = 0; | 284 | mlc->lcv = 0; |
285 | |||
257 | return 0; | 286 | return 0; |
258 | } | 287 | } |
259 | 288 | ||
260 | static int hilse_inc_lcv(hil_mlc *mlc, int lim) { | 289 | static int hilse_inc_lcv(hil_mlc *mlc, int lim) |
261 | if (mlc->lcv++ >= lim) return -1; | 290 | { |
262 | return 0; | 291 | return mlc->lcv++ >= lim ? -1 : 0; |
263 | } | 292 | } |
264 | 293 | ||
265 | #if 0 | 294 | #if 0 |
266 | static int hilse_set_lcv(hil_mlc *mlc, int val) { | 295 | static int hilse_set_lcv(hil_mlc *mlc, int val) |
296 | { | ||
267 | mlc->lcv = val; | 297 | mlc->lcv = val; |
298 | |||
268 | return 0; | 299 | return 0; |
269 | } | 300 | } |
270 | #endif | 301 | #endif |
271 | 302 | ||
272 | /* Management of the discovered device index (zero based, -1 means no devs) */ | 303 | /* Management of the discovered device index (zero based, -1 means no devs) */ |
273 | static int hilse_set_ddi(hil_mlc *mlc, int val) { | 304 | static int hilse_set_ddi(hil_mlc *mlc, int val) |
305 | { | ||
274 | mlc->ddi = val; | 306 | mlc->ddi = val; |
275 | hil_mlc_clear_di_map(mlc, val + 1); | 307 | hil_mlc_clear_di_map(mlc, val + 1); |
308 | |||
276 | return 0; | 309 | return 0; |
277 | } | 310 | } |
278 | 311 | ||
279 | static int hilse_dec_ddi(hil_mlc *mlc, int unused) { | 312 | static int hilse_dec_ddi(hil_mlc *mlc, int unused) |
313 | { | ||
280 | mlc->ddi--; | 314 | mlc->ddi--; |
281 | if (mlc->ddi <= -1) { | 315 | if (mlc->ddi <= -1) { |
282 | mlc->ddi = -1; | 316 | mlc->ddi = -1; |
283 | hil_mlc_clear_di_map(mlc, 0); | 317 | hil_mlc_clear_di_map(mlc, 0); |
284 | return -1; | 318 | return -1; |
285 | } | 319 | } |
286 | hil_mlc_clear_di_map(mlc, mlc->ddi + 1); | 320 | hil_mlc_clear_di_map(mlc, mlc->ddi + 1); |
321 | |||
287 | return 0; | 322 | return 0; |
288 | } | 323 | } |
289 | 324 | ||
290 | static int hilse_inc_ddi(hil_mlc *mlc, int unused) { | 325 | static int hilse_inc_ddi(hil_mlc *mlc, int unused) |
291 | if (mlc->ddi >= 6) { | 326 | { |
292 | BUG(); | 327 | BUG_ON(mlc->ddi >= 6); |
293 | return -1; | ||
294 | } | ||
295 | mlc->ddi++; | 328 | mlc->ddi++; |
329 | |||
296 | return 0; | 330 | return 0; |
297 | } | 331 | } |
298 | 332 | ||
299 | static int hilse_take_idd(hil_mlc *mlc, int unused) { | 333 | static int hilse_take_idd(hil_mlc *mlc, int unused) |
334 | { | ||
300 | int i; | 335 | int i; |
301 | 336 | ||
302 | /* Help the state engine: | 337 | /* Help the state engine: |
303 | * Is this a real IDD response or just an echo? | 338 | * Is this a real IDD response or just an echo? |
304 | * | 339 | * |
305 | * Real IDD response does not start with a command. | 340 | * Real IDD response does not start with a command. |
306 | */ | 341 | */ |
307 | if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail; | 342 | if (mlc->ipacket[0] & HIL_PKT_CMD) |
343 | goto bail; | ||
344 | |||
308 | /* Should have the command echoed further down. */ | 345 | /* Should have the command echoed further down. */ |
309 | for (i = 1; i < 16; i++) { | 346 | for (i = 1; i < 16; i++) { |
310 | if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == | 347 | if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == |
311 | (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && | 348 | (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && |
312 | (mlc->ipacket[i] & HIL_PKT_CMD) && | 349 | (mlc->ipacket[i] & HIL_PKT_CMD) && |
313 | ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) | 350 | ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) |
314 | break; | 351 | break; |
315 | } | 352 | } |
316 | if (i > 15) goto bail; | 353 | if (i > 15) |
354 | goto bail; | ||
355 | |||
317 | /* And the rest of the packets should still be clear. */ | 356 | /* And the rest of the packets should still be clear. */ |
318 | while (++i < 16) { | 357 | while (++i < 16) |
319 | if (mlc->ipacket[i]) break; | 358 | if (mlc->ipacket[i]) |
320 | } | 359 | break; |
321 | if (i < 16) goto bail; | 360 | |
322 | for (i = 0; i < 16; i++) { | 361 | if (i < 16) |
323 | mlc->di_scratch.idd[i] = | 362 | goto bail; |
363 | |||
364 | for (i = 0; i < 16; i++) | ||
365 | mlc->di_scratch.idd[i] = | ||
324 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 366 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
325 | } | 367 | |
326 | /* Next step is to see if RSC supported */ | 368 | /* Next step is to see if RSC supported */ |
327 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) | 369 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) |
328 | return HILSEN_NEXT; | 370 | return HILSEN_NEXT; |
329 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | 371 | |
372 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | ||
330 | return HILSEN_DOWN | 4; | 373 | return HILSEN_DOWN | 4; |
374 | |||
331 | return 0; | 375 | return 0; |
376 | |||
332 | bail: | 377 | bail: |
333 | mlc->ddi--; | 378 | mlc->ddi--; |
379 | |||
334 | return -1; /* This should send us off to ACF */ | 380 | return -1; /* This should send us off to ACF */ |
335 | } | 381 | } |
336 | 382 | ||
337 | static int hilse_take_rsc(hil_mlc *mlc, int unused) { | 383 | static int hilse_take_rsc(hil_mlc *mlc, int unused) |
384 | { | ||
338 | int i; | 385 | int i; |
339 | 386 | ||
340 | for (i = 0; i < 16; i++) { | 387 | for (i = 0; i < 16; i++) |
341 | mlc->di_scratch.rsc[i] = | 388 | mlc->di_scratch.rsc[i] = |
342 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 389 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
343 | } | 390 | |
344 | /* Next step is to see if EXD supported (IDD has already been read) */ | 391 | /* Next step is to see if EXD supported (IDD has already been read) */ |
345 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | 392 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) |
346 | return HILSEN_NEXT; | 393 | return HILSEN_NEXT; |
394 | |||
347 | return 0; | 395 | return 0; |
348 | } | 396 | } |
349 | 397 | ||
350 | static int hilse_take_exd(hil_mlc *mlc, int unused) { | 398 | static int hilse_take_exd(hil_mlc *mlc, int unused) |
399 | { | ||
351 | int i; | 400 | int i; |
352 | 401 | ||
353 | for (i = 0; i < 16; i++) { | 402 | for (i = 0; i < 16; i++) |
354 | mlc->di_scratch.exd[i] = | 403 | mlc->di_scratch.exd[i] = |
355 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 404 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
356 | } | 405 | |
357 | /* Next step is to see if RNM supported. */ | 406 | /* Next step is to see if RNM supported. */ |
358 | if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) | 407 | if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) |
359 | return HILSEN_NEXT; | 408 | return HILSEN_NEXT; |
409 | |||
360 | return 0; | 410 | return 0; |
361 | } | 411 | } |
362 | 412 | ||
363 | static int hilse_take_rnm(hil_mlc *mlc, int unused) { | 413 | static int hilse_take_rnm(hil_mlc *mlc, int unused) |
414 | { | ||
364 | int i; | 415 | int i; |
365 | 416 | ||
366 | for (i = 0; i < 16; i++) { | 417 | for (i = 0; i < 16; i++) |
367 | mlc->di_scratch.rnm[i] = | 418 | mlc->di_scratch.rnm[i] = |
368 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 419 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
369 | } | 420 | |
370 | do { | 421 | printk(KERN_INFO PREFIX "Device name gotten: %16s\n", |
371 | char nam[17]; | 422 | mlc->di_scratch.rnm); |
372 | snprintf(nam, 16, "%s", mlc->di_scratch.rnm); | 423 | |
373 | nam[16] = '\0'; | ||
374 | printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam); | ||
375 | } while (0); | ||
376 | return 0; | 424 | return 0; |
377 | } | 425 | } |
378 | 426 | ||
379 | static int hilse_operate(hil_mlc *mlc, int repoll) { | 427 | static int hilse_operate(hil_mlc *mlc, int repoll) |
428 | { | ||
380 | 429 | ||
381 | if (mlc->opercnt == 0) hil_mlcs_probe = 0; | 430 | if (mlc->opercnt == 0) |
431 | hil_mlcs_probe = 0; | ||
382 | mlc->opercnt = 1; | 432 | mlc->opercnt = 1; |
383 | 433 | ||
384 | hil_mlc_send_polls(mlc); | 434 | hil_mlc_send_polls(mlc); |
385 | 435 | ||
386 | if (!hil_mlcs_probe) return 0; | 436 | if (!hil_mlcs_probe) |
437 | return 0; | ||
387 | hil_mlcs_probe = 0; | 438 | hil_mlcs_probe = 0; |
388 | mlc->opercnt = 0; | 439 | mlc->opercnt = 0; |
389 | return 1; | 440 | return 1; |
@@ -428,7 +479,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
428 | EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), | 479 | EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), |
429 | 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) | 480 | 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) |
430 | OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ | 481 | OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ |
431 | 482 | ||
432 | /* 9 HILSEN_DHR */ | 483 | /* 9 HILSEN_DHR */ |
433 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) | 484 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) |
434 | 485 | ||
@@ -439,7 +490,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
439 | IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) | 490 | IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) |
440 | 491 | ||
441 | /* 14 HILSEN_IFC */ | 492 | /* 14 HILSEN_IFC */ |
442 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) | 493 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) |
443 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, | 494 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, |
444 | 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) | 495 | 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) |
445 | 496 | ||
@@ -455,7 +506,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
455 | 506 | ||
456 | /* 18 HILSEN_HEAL */ | 507 | /* 18 HILSEN_HEAL */ |
457 | OUT_LAST(HIL_CMD_ELB) | 508 | OUT_LAST(HIL_CMD_ELB) |
458 | EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, | 509 | EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, |
459 | 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) | 510 | 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) |
460 | FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) | 511 | FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) |
461 | 512 | ||
@@ -503,7 +554,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
503 | 554 | ||
504 | /* 44 HILSEN_PROBE */ | 555 | /* 44 HILSEN_PROBE */ |
505 | OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) | 556 | OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) |
506 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) | 557 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) |
507 | OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) | 558 | OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) |
508 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) | 559 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) |
509 | OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) | 560 | OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) |
@@ -514,7 +565,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
514 | /* 52 HILSEN_DSR */ | 565 | /* 52 HILSEN_DSR */ |
515 | FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) | 566 | FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) |
516 | OUT(HIL_PKT_CMD | HIL_CMD_DSR) | 567 | OUT(HIL_PKT_CMD | HIL_CMD_DSR) |
517 | IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) | 568 | IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) |
518 | 569 | ||
519 | /* 55 HILSEN_REPOLL */ | 570 | /* 55 HILSEN_REPOLL */ |
520 | OUT(HIL_PKT_CMD | HIL_CMD_RPL) | 571 | OUT(HIL_PKT_CMD | HIL_CMD_RPL) |
@@ -523,14 +574,15 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
523 | FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) | 574 | FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) |
524 | 575 | ||
525 | /* 58 HILSEN_IFCACF */ | 576 | /* 58 HILSEN_IFCACF */ |
526 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) | 577 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) |
527 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, | 578 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, |
528 | 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) | 579 | 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) |
529 | 580 | ||
530 | /* 60 HILSEN_END */ | 581 | /* 60 HILSEN_END */ |
531 | }; | 582 | }; |
532 | 583 | ||
533 | static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) { | 584 | static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) |
585 | { | ||
534 | 586 | ||
535 | switch (node->act) { | 587 | switch (node->act) { |
536 | case HILSE_EXPECT_DISC: | 588 | case HILSE_EXPECT_DISC: |
@@ -555,25 +607,25 @@ static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node | |||
555 | do_gettimeofday(&(mlc->instart)); | 607 | do_gettimeofday(&(mlc->instart)); |
556 | mlc->icount = 15; | 608 | mlc->icount = 15; |
557 | memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); | 609 | memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); |
558 | BUG_ON(down_trylock(&(mlc->isem))); | 610 | BUG_ON(down_trylock(&mlc->isem)); |
559 | |||
560 | return; | ||
561 | } | 611 | } |
562 | 612 | ||
563 | #ifdef HIL_MLC_DEBUG | 613 | #ifdef HIL_MLC_DEBUG |
564 | static int doze = 0; | 614 | static int doze; |
565 | static int seidx; /* For debug */ | 615 | static int seidx; /* For debug */ |
566 | #endif | 616 | #endif |
567 | 617 | ||
568 | static int hilse_donode (hil_mlc *mlc) { | 618 | static int hilse_donode(hil_mlc *mlc) |
619 | { | ||
569 | const struct hilse_node *node; | 620 | const struct hilse_node *node; |
570 | int nextidx = 0; | 621 | int nextidx = 0; |
571 | int sched_long = 0; | 622 | int sched_long = 0; |
572 | unsigned long flags; | 623 | unsigned long flags; |
573 | 624 | ||
574 | #ifdef HIL_MLC_DEBUG | 625 | #ifdef HIL_MLC_DEBUG |
575 | if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { | 626 | if (mlc->seidx && mlc->seidx != seidx && |
576 | printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); | 627 | mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { |
628 | printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); | ||
577 | doze = 0; | 629 | doze = 0; |
578 | } | 630 | } |
579 | 631 | ||
@@ -588,50 +640,59 @@ static int hilse_donode (hil_mlc *mlc) { | |||
588 | case HILSE_FUNC: | 640 | case HILSE_FUNC: |
589 | BUG_ON(node->object.func == NULL); | 641 | BUG_ON(node->object.func == NULL); |
590 | rc = node->object.func(mlc, node->arg); | 642 | rc = node->object.func(mlc, node->arg); |
591 | nextidx = (rc > 0) ? node->ugly : | 643 | nextidx = (rc > 0) ? node->ugly : |
592 | ((rc < 0) ? node->bad : node->good); | 644 | ((rc < 0) ? node->bad : node->good); |
593 | if (nextidx == HILSEN_FOLLOW) nextidx = rc; | 645 | if (nextidx == HILSEN_FOLLOW) |
646 | nextidx = rc; | ||
594 | break; | 647 | break; |
648 | |||
595 | case HILSE_EXPECT_LAST: | 649 | case HILSE_EXPECT_LAST: |
596 | case HILSE_EXPECT_DISC: | 650 | case HILSE_EXPECT_DISC: |
597 | case HILSE_EXPECT: | 651 | case HILSE_EXPECT: |
598 | case HILSE_IN: | 652 | case HILSE_IN: |
599 | /* Already set up from previous HILSE_OUT_* */ | 653 | /* Already set up from previous HILSE_OUT_* */ |
600 | write_lock_irqsave(&(mlc->lock), flags); | 654 | write_lock_irqsave(&mlc->lock, flags); |
601 | rc = mlc->in(mlc, node->arg); | 655 | rc = mlc->in(mlc, node->arg); |
602 | if (rc == 2) { | 656 | if (rc == 2) { |
603 | nextidx = HILSEN_DOZE; | 657 | nextidx = HILSEN_DOZE; |
604 | sched_long = 1; | 658 | sched_long = 1; |
605 | write_unlock_irqrestore(&(mlc->lock), flags); | 659 | write_unlock_irqrestore(&mlc->lock, flags); |
606 | break; | 660 | break; |
607 | } | 661 | } |
608 | if (rc == 1) nextidx = node->ugly; | 662 | if (rc == 1) |
609 | else if (rc == 0) nextidx = node->good; | 663 | nextidx = node->ugly; |
610 | else nextidx = node->bad; | 664 | else if (rc == 0) |
665 | nextidx = node->good; | ||
666 | else | ||
667 | nextidx = node->bad; | ||
611 | mlc->istarted = 0; | 668 | mlc->istarted = 0; |
612 | write_unlock_irqrestore(&(mlc->lock), flags); | 669 | write_unlock_irqrestore(&mlc->lock, flags); |
613 | break; | 670 | break; |
671 | |||
614 | case HILSE_OUT_LAST: | 672 | case HILSE_OUT_LAST: |
615 | write_lock_irqsave(&(mlc->lock), flags); | 673 | write_lock_irqsave(&mlc->lock, flags); |
616 | pack = node->object.packet; | 674 | pack = node->object.packet; |
617 | pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); | 675 | pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); |
618 | goto out; | 676 | goto out; |
677 | |||
619 | case HILSE_OUT_DISC: | 678 | case HILSE_OUT_DISC: |
620 | write_lock_irqsave(&(mlc->lock), flags); | 679 | write_lock_irqsave(&mlc->lock, flags); |
621 | pack = node->object.packet; | 680 | pack = node->object.packet; |
622 | pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); | 681 | pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); |
623 | goto out; | 682 | goto out; |
683 | |||
624 | case HILSE_OUT: | 684 | case HILSE_OUT: |
625 | write_lock_irqsave(&(mlc->lock), flags); | 685 | write_lock_irqsave(&mlc->lock, flags); |
626 | pack = node->object.packet; | 686 | pack = node->object.packet; |
627 | out: | 687 | out: |
628 | if (mlc->istarted) goto out2; | 688 | if (mlc->istarted) |
689 | goto out2; | ||
629 | /* Prepare to receive input */ | 690 | /* Prepare to receive input */ |
630 | if ((node + 1)->act & HILSE_IN) | 691 | if ((node + 1)->act & HILSE_IN) |
631 | hilse_setup_input(mlc, node + 1); | 692 | hilse_setup_input(mlc, node + 1); |
632 | 693 | ||
633 | out2: | 694 | out2: |
634 | write_unlock_irqrestore(&(mlc->lock), flags); | 695 | write_unlock_irqrestore(&mlc->lock, flags); |
635 | 696 | ||
636 | if (down_trylock(&mlc->osem)) { | 697 | if (down_trylock(&mlc->osem)) { |
637 | nextidx = HILSEN_DOZE; | 698 | nextidx = HILSEN_DOZE; |
@@ -639,37 +700,39 @@ static int hilse_donode (hil_mlc *mlc) { | |||
639 | } | 700 | } |
640 | up(&mlc->osem); | 701 | up(&mlc->osem); |
641 | 702 | ||
642 | write_lock_irqsave(&(mlc->lock), flags); | 703 | write_lock_irqsave(&mlc->lock, flags); |
643 | if (!(mlc->ostarted)) { | 704 | if (!mlc->ostarted) { |
644 | mlc->ostarted = 1; | 705 | mlc->ostarted = 1; |
645 | mlc->opacket = pack; | 706 | mlc->opacket = pack; |
646 | mlc->out(mlc); | 707 | mlc->out(mlc); |
647 | nextidx = HILSEN_DOZE; | 708 | nextidx = HILSEN_DOZE; |
648 | write_unlock_irqrestore(&(mlc->lock), flags); | 709 | write_unlock_irqrestore(&mlc->lock, flags); |
649 | break; | 710 | break; |
650 | } | 711 | } |
651 | mlc->ostarted = 0; | 712 | mlc->ostarted = 0; |
652 | do_gettimeofday(&(mlc->instart)); | 713 | do_gettimeofday(&(mlc->instart)); |
653 | write_unlock_irqrestore(&(mlc->lock), flags); | 714 | write_unlock_irqrestore(&mlc->lock, flags); |
654 | nextidx = HILSEN_NEXT; | 715 | nextidx = HILSEN_NEXT; |
655 | break; | 716 | break; |
717 | |||
656 | case HILSE_CTS: | 718 | case HILSE_CTS: |
657 | nextidx = mlc->cts(mlc) ? node->bad : node->good; | 719 | nextidx = mlc->cts(mlc) ? node->bad : node->good; |
658 | break; | 720 | break; |
721 | |||
659 | default: | 722 | default: |
660 | BUG(); | 723 | BUG(); |
661 | nextidx = 0; | ||
662 | break; | ||
663 | } | 724 | } |
664 | 725 | ||
665 | #ifdef HIL_MLC_DEBUG | 726 | #ifdef HIL_MLC_DEBUG |
666 | if (nextidx == HILSEN_DOZE) doze++; | 727 | if (nextidx == HILSEN_DOZE) |
728 | doze++; | ||
667 | #endif | 729 | #endif |
668 | 730 | ||
669 | while (nextidx & HILSEN_SCHED) { | 731 | while (nextidx & HILSEN_SCHED) { |
670 | struct timeval tv; | 732 | struct timeval tv; |
671 | 733 | ||
672 | if (!sched_long) goto sched; | 734 | if (!sched_long) |
735 | goto sched; | ||
673 | 736 | ||
674 | do_gettimeofday(&tv); | 737 | do_gettimeofday(&tv); |
675 | tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); | 738 | tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); |
@@ -682,17 +745,24 @@ static int hilse_donode (hil_mlc *mlc) { | |||
682 | sched: | 745 | sched: |
683 | tasklet_schedule(&hil_mlcs_tasklet); | 746 | tasklet_schedule(&hil_mlcs_tasklet); |
684 | break; | 747 | break; |
685 | } | 748 | } |
686 | if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; | 749 | |
687 | else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; | 750 | if (nextidx & HILSEN_DOWN) |
688 | else mlc->seidx = nextidx & HILSEN_MASK; | 751 | mlc->seidx += nextidx & HILSEN_MASK; |
752 | else if (nextidx & HILSEN_UP) | ||
753 | mlc->seidx -= nextidx & HILSEN_MASK; | ||
754 | else | ||
755 | mlc->seidx = nextidx & HILSEN_MASK; | ||
756 | |||
757 | if (nextidx & HILSEN_BREAK) | ||
758 | return 1; | ||
689 | 759 | ||
690 | if (nextidx & HILSEN_BREAK) return 1; | ||
691 | return 0; | 760 | return 0; |
692 | } | 761 | } |
693 | 762 | ||
694 | /******************** tasklet context functions **************************/ | 763 | /******************** tasklet context functions **************************/ |
695 | static void hil_mlcs_process(unsigned long unused) { | 764 | static void hil_mlcs_process(unsigned long unused) |
765 | { | ||
696 | struct list_head *tmp; | 766 | struct list_head *tmp; |
697 | 767 | ||
698 | read_lock(&hil_mlcs_lock); | 768 | read_lock(&hil_mlcs_lock); |
@@ -700,19 +770,20 @@ static void hil_mlcs_process(unsigned long unused) { | |||
700 | struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); | 770 | struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); |
701 | while (hilse_donode(mlc) == 0) { | 771 | while (hilse_donode(mlc) == 0) { |
702 | #ifdef HIL_MLC_DEBUG | 772 | #ifdef HIL_MLC_DEBUG |
703 | if (mlc->seidx != 41 && | 773 | if (mlc->seidx != 41 && |
704 | mlc->seidx != 42 && | 774 | mlc->seidx != 42 && |
705 | mlc->seidx != 43) | 775 | mlc->seidx != 43) |
706 | printk(KERN_DEBUG PREFIX " + "); | 776 | printk(KERN_DEBUG PREFIX " + "); |
707 | #endif | 777 | #endif |
708 | }; | 778 | } |
709 | } | 779 | } |
710 | read_unlock(&hil_mlcs_lock); | 780 | read_unlock(&hil_mlcs_lock); |
711 | } | 781 | } |
712 | 782 | ||
713 | /************************* Keepalive timer task *********************/ | 783 | /************************* Keepalive timer task *********************/ |
714 | 784 | ||
715 | void hil_mlcs_timer (unsigned long data) { | 785 | void hil_mlcs_timer(unsigned long data) |
786 | { | ||
716 | hil_mlcs_probe = 1; | 787 | hil_mlcs_probe = 1; |
717 | tasklet_schedule(&hil_mlcs_tasklet); | 788 | tasklet_schedule(&hil_mlcs_tasklet); |
718 | /* Re-insert the periodic task. */ | 789 | /* Re-insert the periodic task. */ |
@@ -722,28 +793,25 @@ void hil_mlcs_timer (unsigned long data) { | |||
722 | 793 | ||
723 | /******************** user/kernel context functions **********************/ | 794 | /******************** user/kernel context functions **********************/ |
724 | 795 | ||
725 | static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | 796 | static int hil_mlc_serio_write(struct serio *serio, unsigned char c) |
797 | { | ||
726 | struct hil_mlc_serio_map *map; | 798 | struct hil_mlc_serio_map *map; |
727 | struct hil_mlc *mlc; | 799 | struct hil_mlc *mlc; |
728 | struct serio_driver *drv; | 800 | struct serio_driver *drv; |
729 | uint8_t *idx, *last; | 801 | uint8_t *idx, *last; |
730 | 802 | ||
731 | map = serio->port_data; | 803 | map = serio->port_data; |
732 | if (map == NULL) { | 804 | BUG_ON(map == NULL); |
733 | BUG(); | 805 | |
734 | return -EIO; | ||
735 | } | ||
736 | mlc = map->mlc; | 806 | mlc = map->mlc; |
737 | if (mlc == NULL) { | 807 | BUG_ON(mlc == NULL); |
738 | BUG(); | 808 | |
739 | return -EIO; | 809 | mlc->serio_opacket[map->didx] |= |
740 | } | ||
741 | mlc->serio_opacket[map->didx] |= | ||
742 | ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); | 810 | ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); |
743 | 811 | ||
744 | if (mlc->serio_oidx[map->didx] >= 3) { | 812 | if (mlc->serio_oidx[map->didx] >= 3) { |
745 | /* for now only commands */ | 813 | /* for now only commands */ |
746 | if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) | 814 | if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) |
747 | return -EIO; | 815 | return -EIO; |
748 | switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { | 816 | switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { |
749 | case HIL_CMD_IDD: | 817 | case HIL_CMD_IDD: |
@@ -769,12 +837,11 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | |||
769 | return -EIO; | 837 | return -EIO; |
770 | emu: | 838 | emu: |
771 | drv = serio->drv; | 839 | drv = serio->drv; |
772 | if (drv == NULL) { | 840 | BUG_ON(drv == NULL); |
773 | BUG(); | 841 | |
774 | return -EIO; | ||
775 | } | ||
776 | last = idx + 15; | 842 | last = idx + 15; |
777 | while ((last != idx) && (*last == 0)) last--; | 843 | while ((last != idx) && (*last == 0)) |
844 | last--; | ||
778 | 845 | ||
779 | while (idx != last) { | 846 | while (idx != last) { |
780 | drv->interrupt(serio, 0, 0); | 847 | drv->interrupt(serio, 0, 0); |
@@ -787,14 +854,15 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | |||
787 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | 854 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); |
788 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | 855 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); |
789 | drv->interrupt(serio, *idx, 0); | 856 | drv->interrupt(serio, *idx, 0); |
790 | 857 | ||
791 | mlc->serio_oidx[map->didx] = 0; | 858 | mlc->serio_oidx[map->didx] = 0; |
792 | mlc->serio_opacket[map->didx] = 0; | 859 | mlc->serio_opacket[map->didx] = 0; |
793 | 860 | ||
794 | return 0; | 861 | return 0; |
795 | } | 862 | } |
796 | 863 | ||
797 | static int hil_mlc_serio_open(struct serio *serio) { | 864 | static int hil_mlc_serio_open(struct serio *serio) |
865 | { | ||
798 | struct hil_mlc_serio_map *map; | 866 | struct hil_mlc_serio_map *map; |
799 | struct hil_mlc *mlc; | 867 | struct hil_mlc *mlc; |
800 | 868 | ||
@@ -802,33 +870,24 @@ static int hil_mlc_serio_open(struct serio *serio) { | |||
802 | return -EBUSY; | 870 | return -EBUSY; |
803 | 871 | ||
804 | map = serio->port_data; | 872 | map = serio->port_data; |
805 | if (map == NULL) { | 873 | BUG_ON(map == NULL); |
806 | BUG(); | 874 | |
807 | return -ENODEV; | ||
808 | } | ||
809 | mlc = map->mlc; | 875 | mlc = map->mlc; |
810 | if (mlc == NULL) { | 876 | BUG_ON(mlc == NULL); |
811 | BUG(); | ||
812 | return -ENODEV; | ||
813 | } | ||
814 | 877 | ||
815 | return 0; | 878 | return 0; |
816 | } | 879 | } |
817 | 880 | ||
818 | static void hil_mlc_serio_close(struct serio *serio) { | 881 | static void hil_mlc_serio_close(struct serio *serio) |
882 | { | ||
819 | struct hil_mlc_serio_map *map; | 883 | struct hil_mlc_serio_map *map; |
820 | struct hil_mlc *mlc; | 884 | struct hil_mlc *mlc; |
821 | 885 | ||
822 | map = serio->port_data; | 886 | map = serio->port_data; |
823 | if (map == NULL) { | 887 | BUG_ON(map == NULL); |
824 | BUG(); | 888 | |
825 | return; | ||
826 | } | ||
827 | mlc = map->mlc; | 889 | mlc = map->mlc; |
828 | if (mlc == NULL) { | 890 | BUG_ON(mlc == NULL); |
829 | BUG(); | ||
830 | return; | ||
831 | } | ||
832 | 891 | ||
833 | serio_set_drvdata(serio, NULL); | 892 | serio_set_drvdata(serio, NULL); |
834 | serio->drv = NULL; | 893 | serio->drv = NULL; |
@@ -842,27 +901,26 @@ static const struct serio_device_id hil_mlc_serio_id = { | |||
842 | .id = SERIO_ANY, | 901 | .id = SERIO_ANY, |
843 | }; | 902 | }; |
844 | 903 | ||
845 | int hil_mlc_register(hil_mlc *mlc) { | 904 | int hil_mlc_register(hil_mlc *mlc) |
905 | { | ||
846 | int i; | 906 | int i; |
847 | unsigned long flags; | 907 | unsigned long flags; |
848 | 908 | ||
849 | if (mlc == NULL) { | 909 | BUG_ON(mlc == NULL); |
850 | return -EINVAL; | ||
851 | } | ||
852 | 910 | ||
853 | mlc->istarted = 0; | 911 | mlc->istarted = 0; |
854 | mlc->ostarted = 0; | 912 | mlc->ostarted = 0; |
855 | 913 | ||
856 | rwlock_init(&mlc->lock); | 914 | rwlock_init(&mlc->lock); |
857 | init_MUTEX(&(mlc->osem)); | 915 | init_MUTEX(&mlc->osem); |
858 | 916 | ||
859 | init_MUTEX(&(mlc->isem)); | 917 | init_MUTEX(&mlc->isem); |
860 | mlc->icount = -1; | 918 | mlc->icount = -1; |
861 | mlc->imatch = 0; | 919 | mlc->imatch = 0; |
862 | 920 | ||
863 | mlc->opercnt = 0; | 921 | mlc->opercnt = 0; |
864 | 922 | ||
865 | init_MUTEX_LOCKED(&(mlc->csem)); | 923 | init_MUTEX_LOCKED(&(mlc->csem)); |
866 | 924 | ||
867 | hil_mlc_clear_di_scratch(mlc); | 925 | hil_mlc_clear_di_scratch(mlc); |
868 | hil_mlc_clear_di_map(mlc, 0); | 926 | hil_mlc_clear_di_map(mlc, 0); |
@@ -897,19 +955,18 @@ int hil_mlc_register(hil_mlc *mlc) { | |||
897 | return 0; | 955 | return 0; |
898 | } | 956 | } |
899 | 957 | ||
900 | int hil_mlc_unregister(hil_mlc *mlc) { | 958 | int hil_mlc_unregister(hil_mlc *mlc) |
959 | { | ||
901 | struct list_head *tmp; | 960 | struct list_head *tmp; |
902 | unsigned long flags; | 961 | unsigned long flags; |
903 | int i; | 962 | int i; |
904 | 963 | ||
905 | if (mlc == NULL) | 964 | BUG_ON(mlc == NULL); |
906 | return -EINVAL; | ||
907 | 965 | ||
908 | write_lock_irqsave(&hil_mlcs_lock, flags); | 966 | write_lock_irqsave(&hil_mlcs_lock, flags); |
909 | list_for_each(tmp, &hil_mlcs) { | 967 | list_for_each(tmp, &hil_mlcs) |
910 | if (list_entry(tmp, hil_mlc, list) == mlc) | 968 | if (list_entry(tmp, hil_mlc, list) == mlc) |
911 | goto found; | 969 | goto found; |
912 | } | ||
913 | 970 | ||
914 | /* not found in list */ | 971 | /* not found in list */ |
915 | write_unlock_irqrestore(&hil_mlcs_lock, flags); | 972 | write_unlock_irqrestore(&hil_mlcs_lock, flags); |
@@ -918,7 +975,7 @@ int hil_mlc_unregister(hil_mlc *mlc) { | |||
918 | 975 | ||
919 | found: | 976 | found: |
920 | list_del(tmp); | 977 | list_del(tmp); |
921 | write_unlock_irqrestore(&hil_mlcs_lock, flags); | 978 | write_unlock_irqrestore(&hil_mlcs_lock, flags); |
922 | 979 | ||
923 | for (i = 0; i < HIL_MLC_DEVMEM; i++) { | 980 | for (i = 0; i < HIL_MLC_DEVMEM; i++) { |
924 | serio_unregister_port(mlc->serio[i]); | 981 | serio_unregister_port(mlc->serio[i]); |
@@ -942,7 +999,7 @@ static int __init hil_mlc_init(void) | |||
942 | 999 | ||
943 | return 0; | 1000 | return 0; |
944 | } | 1001 | } |
945 | 1002 | ||
946 | static void __exit hil_mlc_exit(void) | 1003 | static void __exit hil_mlc_exit(void) |
947 | { | 1004 | { |
948 | del_timer(&hil_mlcs_kicker); | 1005 | del_timer(&hil_mlcs_kicker); |
@@ -950,6 +1007,6 @@ static void __exit hil_mlc_exit(void) | |||
950 | tasklet_disable(&hil_mlcs_tasklet); | 1007 | tasklet_disable(&hil_mlcs_tasklet); |
951 | tasklet_kill(&hil_mlcs_tasklet); | 1008 | tasklet_kill(&hil_mlcs_tasklet); |
952 | } | 1009 | } |
953 | 1010 | ||
954 | module_init(hil_mlc_init); | 1011 | module_init(hil_mlc_init); |
955 | module_exit(hil_mlc_exit); | 1012 | module_exit(hil_mlc_exit); |