aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/hil_mlc.c505
-rw-r--r--drivers/input/serio/hp_sdc.c427
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c227
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h24
-rw-r--r--drivers/input/serio/i8042.c7
5 files changed, 664 insertions, 526 deletions
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 4fa93ff30919..93a1a6ba216a 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
86static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) { 86static 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
93static void hil_mlc_clear_di_scratch (hil_mlc *mlc) { 94static 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
97static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) { 99static 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
101static int hil_mlc_match_di_scratch (hil_mlc *mlc) { 104static 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
120static int hil_mlc_find_free_di(hil_mlc *mlc) { 126static 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
136static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) { 147static 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
148static void hil_mlc_send_polls(hil_mlc *mlc) { 163static 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
218static int hilse_match(hil_mlc *mlc, int unused) { 239static 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. */
247static int hilse_init_lcv(hil_mlc *mlc, int unused) { 274static 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
260static int hilse_inc_lcv(hil_mlc *mlc, int lim) { 289static 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
266static int hilse_set_lcv(hil_mlc *mlc, int val) { 295static 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) */
273static int hilse_set_ddi(hil_mlc *mlc, int val) { 304static 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
279static int hilse_dec_ddi(hil_mlc *mlc, int unused) { 312static 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
290static int hilse_inc_ddi(hil_mlc *mlc, int unused) { 325static 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
299static int hilse_take_idd(hil_mlc *mlc, int unused) { 333static 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
337static int hilse_take_rsc(hil_mlc *mlc, int unused) { 383static 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
350static int hilse_take_exd(hil_mlc *mlc, int unused) { 398static 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
363static int hilse_take_rnm(hil_mlc *mlc, int unused) { 413static 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
379static int hilse_operate(hil_mlc *mlc, int repoll) { 427static 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;
@@ -408,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll) {
408#define OUT_LAST(pack) \ 459#define OUT_LAST(pack) \
409{ HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, 460{ HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 },
410 461
411struct hilse_node hil_mlc_se[HILSEN_END] = { 462const struct hilse_node hil_mlc_se[HILSEN_END] = {
412 463
413 /* 0 HILSEN_START */ 464 /* 0 HILSEN_START */
414 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) 465 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
@@ -428,7 +479,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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
533static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { 584static 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,29 +607,27 @@ static inline void hilse_setup_input(hil_mlc *mlc, 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
564static int doze = 0; 614static int doze;
565static int seidx; /* For debug */ 615static int seidx; /* For debug */
566static int kick = 1;
567#endif 616#endif
568 617
569static int hilse_donode (hil_mlc *mlc) { 618static int hilse_donode(hil_mlc *mlc)
570 struct hilse_node *node; 619{
620 const struct hilse_node *node;
571 int nextidx = 0; 621 int nextidx = 0;
572 int sched_long = 0; 622 int sched_long = 0;
573 unsigned long flags; 623 unsigned long flags;
574 624
575#ifdef HIL_MLC_DEBUG 625#ifdef HIL_MLC_DEBUG
576 if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { 626 if (mlc->seidx && mlc->seidx != seidx &&
577 printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx); 627 mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) {
628 printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx);
578 doze = 0; 629 doze = 0;
579 } 630 }
580 kick = 0;
581 631
582 seidx = mlc->seidx; 632 seidx = mlc->seidx;
583#endif 633#endif
@@ -588,52 +638,61 @@ static int hilse_donode (hil_mlc *mlc) {
588 hil_packet pack; 638 hil_packet pack;
589 639
590 case HILSE_FUNC: 640 case HILSE_FUNC:
591 if (node->object.func == NULL) break; 641 BUG_ON(node->object.func == NULL);
592 rc = node->object.func(mlc, node->arg); 642 rc = node->object.func(mlc, node->arg);
593 nextidx = (rc > 0) ? node->ugly : 643 nextidx = (rc > 0) ? node->ugly :
594 ((rc < 0) ? node->bad : node->good); 644 ((rc < 0) ? node->bad : node->good);
595 if (nextidx == HILSEN_FOLLOW) nextidx = rc; 645 if (nextidx == HILSEN_FOLLOW)
646 nextidx = rc;
596 break; 647 break;
648
597 case HILSE_EXPECT_LAST: 649 case HILSE_EXPECT_LAST:
598 case HILSE_EXPECT_DISC: 650 case HILSE_EXPECT_DISC:
599 case HILSE_EXPECT: 651 case HILSE_EXPECT:
600 case HILSE_IN: 652 case HILSE_IN:
601 /* Already set up from previous HILSE_OUT_* */ 653 /* Already set up from previous HILSE_OUT_* */
602 write_lock_irqsave(&(mlc->lock), flags); 654 write_lock_irqsave(&mlc->lock, flags);
603 rc = mlc->in(mlc, node->arg); 655 rc = mlc->in(mlc, node->arg);
604 if (rc == 2) { 656 if (rc == 2) {
605 nextidx = HILSEN_DOZE; 657 nextidx = HILSEN_DOZE;
606 sched_long = 1; 658 sched_long = 1;
607 write_unlock_irqrestore(&(mlc->lock), flags); 659 write_unlock_irqrestore(&mlc->lock, flags);
608 break; 660 break;
609 } 661 }
610 if (rc == 1) nextidx = node->ugly; 662 if (rc == 1)
611 else if (rc == 0) nextidx = node->good; 663 nextidx = node->ugly;
612 else nextidx = node->bad; 664 else if (rc == 0)
665 nextidx = node->good;
666 else
667 nextidx = node->bad;
613 mlc->istarted = 0; 668 mlc->istarted = 0;
614 write_unlock_irqrestore(&(mlc->lock), flags); 669 write_unlock_irqrestore(&mlc->lock, flags);
615 break; 670 break;
671
616 case HILSE_OUT_LAST: 672 case HILSE_OUT_LAST:
617 write_lock_irqsave(&(mlc->lock), flags); 673 write_lock_irqsave(&mlc->lock, flags);
618 pack = node->object.packet; 674 pack = node->object.packet;
619 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); 675 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
620 goto out; 676 goto out;
677
621 case HILSE_OUT_DISC: 678 case HILSE_OUT_DISC:
622 write_lock_irqsave(&(mlc->lock), flags); 679 write_lock_irqsave(&mlc->lock, flags);
623 pack = node->object.packet; 680 pack = node->object.packet;
624 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); 681 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
625 goto out; 682 goto out;
683
626 case HILSE_OUT: 684 case HILSE_OUT:
627 write_lock_irqsave(&(mlc->lock), flags); 685 write_lock_irqsave(&mlc->lock, flags);
628 pack = node->object.packet; 686 pack = node->object.packet;
629 out: 687 out:
630 if (mlc->istarted) goto out2; 688 if (mlc->istarted)
689 goto out2;
631 /* Prepare to receive input */ 690 /* Prepare to receive input */
632 if ((node + 1)->act & HILSE_IN) 691 if ((node + 1)->act & HILSE_IN)
633 hilse_setup_input(mlc, node + 1); 692 hilse_setup_input(mlc, node + 1);
634 693
635 out2: 694 out2:
636 write_unlock_irqrestore(&(mlc->lock), flags); 695 write_unlock_irqrestore(&mlc->lock, flags);
637 696
638 if (down_trylock(&mlc->osem)) { 697 if (down_trylock(&mlc->osem)) {
639 nextidx = HILSEN_DOZE; 698 nextidx = HILSEN_DOZE;
@@ -641,60 +700,71 @@ static int hilse_donode (hil_mlc *mlc) {
641 } 700 }
642 up(&mlc->osem); 701 up(&mlc->osem);
643 702
644 write_lock_irqsave(&(mlc->lock), flags); 703 write_lock_irqsave(&mlc->lock, flags);
645 if (!(mlc->ostarted)) { 704 if (!mlc->ostarted) {
646 mlc->ostarted = 1; 705 mlc->ostarted = 1;
647 mlc->opacket = pack; 706 mlc->opacket = pack;
648 mlc->out(mlc); 707 mlc->out(mlc);
649 nextidx = HILSEN_DOZE; 708 nextidx = HILSEN_DOZE;
650 write_unlock_irqrestore(&(mlc->lock), flags); 709 write_unlock_irqrestore(&mlc->lock, flags);
651 break; 710 break;
652 } 711 }
653 mlc->ostarted = 0; 712 mlc->ostarted = 0;
654 do_gettimeofday(&(mlc->instart)); 713 do_gettimeofday(&(mlc->instart));
655 write_unlock_irqrestore(&(mlc->lock), flags); 714 write_unlock_irqrestore(&mlc->lock, flags);
656 nextidx = HILSEN_NEXT; 715 nextidx = HILSEN_NEXT;
657 break; 716 break;
717
658 case HILSE_CTS: 718 case HILSE_CTS:
719 write_lock_irqsave(&mlc->lock, flags);
659 nextidx = mlc->cts(mlc) ? node->bad : node->good; 720 nextidx = mlc->cts(mlc) ? node->bad : node->good;
721 write_unlock_irqrestore(&mlc->lock, flags);
660 break; 722 break;
723
661 default: 724 default:
662 BUG(); 725 BUG();
663 nextidx = 0;
664 break;
665 } 726 }
666 727
667#ifdef HIL_MLC_DEBUG 728#ifdef HIL_MLC_DEBUG
668 if (nextidx == HILSEN_DOZE) doze++; 729 if (nextidx == HILSEN_DOZE)
730 doze++;
669#endif 731#endif
670 732
671 while (nextidx & HILSEN_SCHED) { 733 while (nextidx & HILSEN_SCHED) {
672 struct timeval tv; 734 struct timeval tv;
673 735
674 if (!sched_long) goto sched; 736 if (!sched_long)
737 goto sched;
675 738
676 do_gettimeofday(&tv); 739 do_gettimeofday(&tv);
677 tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); 740 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec);
678 tv.tv_usec -= mlc->instart.tv_usec; 741 tv.tv_usec -= mlc->instart.tv_usec;
679 if (tv.tv_usec >= mlc->intimeout) goto sched; 742 if (tv.tv_usec >= mlc->intimeout) goto sched;
680 tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000; 743 tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC;
681 if (!tv.tv_usec) goto sched; 744 if (!tv.tv_usec) goto sched;
682 mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec); 745 mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec);
683 break; 746 break;
684 sched: 747 sched:
685 tasklet_schedule(&hil_mlcs_tasklet); 748 tasklet_schedule(&hil_mlcs_tasklet);
686 break; 749 break;
687 } 750 }
688 if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; 751
689 else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; 752 if (nextidx & HILSEN_DOWN)
690 else mlc->seidx = nextidx & HILSEN_MASK; 753 mlc->seidx += nextidx & HILSEN_MASK;
754 else if (nextidx & HILSEN_UP)
755 mlc->seidx -= nextidx & HILSEN_MASK;
756 else
757 mlc->seidx = nextidx & HILSEN_MASK;
758
759 if (nextidx & HILSEN_BREAK)
760 return 1;
691 761
692 if (nextidx & HILSEN_BREAK) return 1;
693 return 0; 762 return 0;
694} 763}
695 764
696/******************** tasklet context functions **************************/ 765/******************** tasklet context functions **************************/
697static void hil_mlcs_process(unsigned long unused) { 766static void hil_mlcs_process(unsigned long unused)
767{
698 struct list_head *tmp; 768 struct list_head *tmp;
699 769
700 read_lock(&hil_mlcs_lock); 770 read_lock(&hil_mlcs_lock);
@@ -702,19 +772,20 @@ static void hil_mlcs_process(unsigned long unused) {
702 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); 772 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list);
703 while (hilse_donode(mlc) == 0) { 773 while (hilse_donode(mlc) == 0) {
704#ifdef HIL_MLC_DEBUG 774#ifdef HIL_MLC_DEBUG
705 if (mlc->seidx != 41 && 775 if (mlc->seidx != 41 &&
706 mlc->seidx != 42 && 776 mlc->seidx != 42 &&
707 mlc->seidx != 43) 777 mlc->seidx != 43)
708 printk(KERN_DEBUG PREFIX " + "); 778 printk(KERN_DEBUG PREFIX " + ");
709#endif 779#endif
710 }; 780 }
711 } 781 }
712 read_unlock(&hil_mlcs_lock); 782 read_unlock(&hil_mlcs_lock);
713} 783}
714 784
715/************************* Keepalive timer task *********************/ 785/************************* Keepalive timer task *********************/
716 786
717void hil_mlcs_timer (unsigned long data) { 787void hil_mlcs_timer(unsigned long data)
788{
718 hil_mlcs_probe = 1; 789 hil_mlcs_probe = 1;
719 tasklet_schedule(&hil_mlcs_tasklet); 790 tasklet_schedule(&hil_mlcs_tasklet);
720 /* Re-insert the periodic task. */ 791 /* Re-insert the periodic task. */
@@ -724,28 +795,25 @@ void hil_mlcs_timer (unsigned long data) {
724 795
725/******************** user/kernel context functions **********************/ 796/******************** user/kernel context functions **********************/
726 797
727static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { 798static int hil_mlc_serio_write(struct serio *serio, unsigned char c)
799{
728 struct hil_mlc_serio_map *map; 800 struct hil_mlc_serio_map *map;
729 struct hil_mlc *mlc; 801 struct hil_mlc *mlc;
730 struct serio_driver *drv; 802 struct serio_driver *drv;
731 uint8_t *idx, *last; 803 uint8_t *idx, *last;
732 804
733 map = serio->port_data; 805 map = serio->port_data;
734 if (map == NULL) { 806 BUG_ON(map == NULL);
735 BUG(); 807
736 return -EIO;
737 }
738 mlc = map->mlc; 808 mlc = map->mlc;
739 if (mlc == NULL) { 809 BUG_ON(mlc == NULL);
740 BUG(); 810
741 return -EIO; 811 mlc->serio_opacket[map->didx] |=
742 }
743 mlc->serio_opacket[map->didx] |=
744 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); 812 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx]));
745 813
746 if (mlc->serio_oidx[map->didx] >= 3) { 814 if (mlc->serio_oidx[map->didx] >= 3) {
747 /* for now only commands */ 815 /* for now only commands */
748 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) 816 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD))
749 return -EIO; 817 return -EIO;
750 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { 818 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) {
751 case HIL_CMD_IDD: 819 case HIL_CMD_IDD:
@@ -771,12 +839,11 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
771 return -EIO; 839 return -EIO;
772 emu: 840 emu:
773 drv = serio->drv; 841 drv = serio->drv;
774 if (drv == NULL) { 842 BUG_ON(drv == NULL);
775 BUG(); 843
776 return -EIO;
777 }
778 last = idx + 15; 844 last = idx + 15;
779 while ((last != idx) && (*last == 0)) last--; 845 while ((last != idx) && (*last == 0))
846 last--;
780 847
781 while (idx != last) { 848 while (idx != last) {
782 drv->interrupt(serio, 0, 0); 849 drv->interrupt(serio, 0, 0);
@@ -789,14 +856,15 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
789 drv->interrupt(serio, HIL_ERR_INT >> 16, 0); 856 drv->interrupt(serio, HIL_ERR_INT >> 16, 0);
790 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); 857 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0);
791 drv->interrupt(serio, *idx, 0); 858 drv->interrupt(serio, *idx, 0);
792 859
793 mlc->serio_oidx[map->didx] = 0; 860 mlc->serio_oidx[map->didx] = 0;
794 mlc->serio_opacket[map->didx] = 0; 861 mlc->serio_opacket[map->didx] = 0;
795 862
796 return 0; 863 return 0;
797} 864}
798 865
799static int hil_mlc_serio_open(struct serio *serio) { 866static int hil_mlc_serio_open(struct serio *serio)
867{
800 struct hil_mlc_serio_map *map; 868 struct hil_mlc_serio_map *map;
801 struct hil_mlc *mlc; 869 struct hil_mlc *mlc;
802 870
@@ -804,67 +872,57 @@ static int hil_mlc_serio_open(struct serio *serio) {
804 return -EBUSY; 872 return -EBUSY;
805 873
806 map = serio->port_data; 874 map = serio->port_data;
807 if (map == NULL) { 875 BUG_ON(map == NULL);
808 BUG(); 876
809 return -ENODEV;
810 }
811 mlc = map->mlc; 877 mlc = map->mlc;
812 if (mlc == NULL) { 878 BUG_ON(mlc == NULL);
813 BUG();
814 return -ENODEV;
815 }
816 879
817 return 0; 880 return 0;
818} 881}
819 882
820static void hil_mlc_serio_close(struct serio *serio) { 883static void hil_mlc_serio_close(struct serio *serio)
884{
821 struct hil_mlc_serio_map *map; 885 struct hil_mlc_serio_map *map;
822 struct hil_mlc *mlc; 886 struct hil_mlc *mlc;
823 887
824 map = serio->port_data; 888 map = serio->port_data;
825 if (map == NULL) { 889 BUG_ON(map == NULL);
826 BUG(); 890
827 return;
828 }
829 mlc = map->mlc; 891 mlc = map->mlc;
830 if (mlc == NULL) { 892 BUG_ON(mlc == NULL);
831 BUG();
832 return;
833 }
834 893
835 serio_set_drvdata(serio, NULL); 894 serio_set_drvdata(serio, NULL);
836 serio->drv = NULL; 895 serio->drv = NULL;
837 /* TODO wake up interruptable */ 896 /* TODO wake up interruptable */
838} 897}
839 898
840static struct serio_device_id hil_mlc_serio_id = { 899static const struct serio_device_id hil_mlc_serio_id = {
841 .type = SERIO_HIL_MLC, 900 .type = SERIO_HIL_MLC,
842 .proto = SERIO_HIL, 901 .proto = SERIO_HIL,
843 .extra = SERIO_ANY, 902 .extra = SERIO_ANY,
844 .id = SERIO_ANY, 903 .id = SERIO_ANY,
845}; 904};
846 905
847int hil_mlc_register(hil_mlc *mlc) { 906int hil_mlc_register(hil_mlc *mlc)
907{
848 int i; 908 int i;
849 unsigned long flags; 909 unsigned long flags;
850 910
851 if (mlc == NULL) { 911 BUG_ON(mlc == NULL);
852 return -EINVAL;
853 }
854 912
855 mlc->istarted = 0; 913 mlc->istarted = 0;
856 mlc->ostarted = 0; 914 mlc->ostarted = 0;
857 915
858 rwlock_init(&mlc->lock); 916 rwlock_init(&mlc->lock);
859 init_MUTEX(&(mlc->osem)); 917 init_MUTEX(&mlc->osem);
860 918
861 init_MUTEX(&(mlc->isem)); 919 init_MUTEX(&mlc->isem);
862 mlc->icount = -1; 920 mlc->icount = -1;
863 mlc->imatch = 0; 921 mlc->imatch = 0;
864 922
865 mlc->opercnt = 0; 923 mlc->opercnt = 0;
866 924
867 init_MUTEX_LOCKED(&(mlc->csem)); 925 init_MUTEX_LOCKED(&(mlc->csem));
868 926
869 hil_mlc_clear_di_scratch(mlc); 927 hil_mlc_clear_di_scratch(mlc);
870 hil_mlc_clear_di_map(mlc, 0); 928 hil_mlc_clear_di_map(mlc, 0);
@@ -873,6 +931,8 @@ int hil_mlc_register(hil_mlc *mlc) {
873 hil_mlc_copy_di_scratch(mlc, i); 931 hil_mlc_copy_di_scratch(mlc, i);
874 mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); 932 mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL);
875 mlc->serio[i] = mlc_serio; 933 mlc->serio[i] = mlc_serio;
934 snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i);
935 snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i);
876 mlc_serio->id = hil_mlc_serio_id; 936 mlc_serio->id = hil_mlc_serio_id;
877 mlc_serio->write = hil_mlc_serio_write; 937 mlc_serio->write = hil_mlc_serio_write;
878 mlc_serio->open = hil_mlc_serio_open; 938 mlc_serio->open = hil_mlc_serio_open;
@@ -897,19 +957,18 @@ int hil_mlc_register(hil_mlc *mlc) {
897 return 0; 957 return 0;
898} 958}
899 959
900int hil_mlc_unregister(hil_mlc *mlc) { 960int hil_mlc_unregister(hil_mlc *mlc)
961{
901 struct list_head *tmp; 962 struct list_head *tmp;
902 unsigned long flags; 963 unsigned long flags;
903 int i; 964 int i;
904 965
905 if (mlc == NULL) 966 BUG_ON(mlc == NULL);
906 return -EINVAL;
907 967
908 write_lock_irqsave(&hil_mlcs_lock, flags); 968 write_lock_irqsave(&hil_mlcs_lock, flags);
909 list_for_each(tmp, &hil_mlcs) { 969 list_for_each(tmp, &hil_mlcs)
910 if (list_entry(tmp, hil_mlc, list) == mlc) 970 if (list_entry(tmp, hil_mlc, list) == mlc)
911 goto found; 971 goto found;
912 }
913 972
914 /* not found in list */ 973 /* not found in list */
915 write_unlock_irqrestore(&hil_mlcs_lock, flags); 974 write_unlock_irqrestore(&hil_mlcs_lock, flags);
@@ -918,7 +977,7 @@ int hil_mlc_unregister(hil_mlc *mlc) {
918 977
919 found: 978 found:
920 list_del(tmp); 979 list_del(tmp);
921 write_unlock_irqrestore(&hil_mlcs_lock, flags); 980 write_unlock_irqrestore(&hil_mlcs_lock, flags);
922 981
923 for (i = 0; i < HIL_MLC_DEVMEM; i++) { 982 for (i = 0; i < HIL_MLC_DEVMEM; i++) {
924 serio_unregister_port(mlc->serio[i]); 983 serio_unregister_port(mlc->serio[i]);
@@ -942,7 +1001,7 @@ static int __init hil_mlc_init(void)
942 1001
943 return 0; 1002 return 0;
944} 1003}
945 1004
946static void __exit hil_mlc_exit(void) 1005static void __exit hil_mlc_exit(void)
947{ 1006{
948 del_timer(&hil_mlcs_kicker); 1007 del_timer(&hil_mlcs_kicker);
@@ -950,6 +1009,6 @@ static void __exit hil_mlc_exit(void)
950 tasklet_disable(&hil_mlcs_tasklet); 1009 tasklet_disable(&hil_mlcs_tasklet);
951 tasklet_kill(&hil_mlcs_tasklet); 1010 tasklet_kill(&hil_mlcs_tasklet);
952} 1011}
953 1012
954module_init(hil_mlc_init); 1013module_init(hil_mlc_init);
955module_exit(hil_mlc_exit); 1014module_exit(hil_mlc_exit);
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index b57370dc4e3d..6af199805ffc 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -34,27 +34,27 @@
34 * 34 *
35 * Driver theory of operation: 35 * Driver theory of operation:
36 * 36 *
37 * hp_sdc_put does all writing to the SDC. ISR can run on a different 37 * hp_sdc_put does all writing to the SDC. ISR can run on a different
38 * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time 38 * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time
39 * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. 39 * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly.
40 * 40 *
41 * All data coming back from the SDC is sent via interrupt and can be read 41 * All data coming back from the SDC is sent via interrupt and can be read
42 * fully in the ISR, so there are no latency/throughput problems there. 42 * fully in the ISR, so there are no latency/throughput problems there.
43 * The problem is with output, due to the slow clock speed of the SDC 43 * The problem is with output, due to the slow clock speed of the SDC
44 * compared to the CPU. This should not be too horrible most of the time, 44 * compared to the CPU. This should not be too horrible most of the time,
45 * but if used with HIL devices that support the multibyte transfer command, 45 * but if used with HIL devices that support the multibyte transfer command,
46 * keeping outbound throughput flowing at the 6500KBps that the HIL is 46 * keeping outbound throughput flowing at the 6500KBps that the HIL is
47 * capable of is more than can be done at HZ=100. 47 * capable of is more than can be done at HZ=100.
48 * 48 *
49 * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf 49 * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf
50 * is set to 0 when the IBF flag in the status register has cleared. ISR 50 * is set to 0 when the IBF flag in the status register has cleared. ISR
51 * may do this, and may also access the parts of queued transactions related 51 * may do this, and may also access the parts of queued transactions related
52 * to reading data back from the SDC, but otherwise will not touch the 52 * to reading data back from the SDC, but otherwise will not touch the
53 * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. 53 * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1.
54 * 54 *
55 * The i8042 write index and the values in the 4-byte input buffer 55 * The i8042 write index and the values in the 4-byte input buffer
56 * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, 56 * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively,
57 * to minimize the amount of IO needed to the SDC. However these values 57 * to minimize the amount of IO needed to the SDC. However these values
58 * do not need to be locked since they are only ever accessed by hp_sdc_put. 58 * do not need to be locked since they are only ever accessed by hp_sdc_put.
59 * 59 *
60 * A timer task schedules the tasklet once per second just to make 60 * A timer task schedules the tasklet once per second just to make
@@ -100,39 +100,46 @@ EXPORT_SYMBOL(hp_sdc_release_timer_irq);
100EXPORT_SYMBOL(hp_sdc_release_hil_irq); 100EXPORT_SYMBOL(hp_sdc_release_hil_irq);
101EXPORT_SYMBOL(hp_sdc_release_cooked_irq); 101EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
102 102
103EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
103EXPORT_SYMBOL(hp_sdc_enqueue_transaction); 104EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
104EXPORT_SYMBOL(hp_sdc_dequeue_transaction); 105EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
105 106
106static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ 107static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
107 108
108/*************** primitives for use in any context *********************/ 109/*************** primitives for use in any context *********************/
109static inline uint8_t hp_sdc_status_in8 (void) { 110static inline uint8_t hp_sdc_status_in8(void)
111{
110 uint8_t status; 112 uint8_t status;
111 unsigned long flags; 113 unsigned long flags;
112 114
113 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 115 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
114 status = sdc_readb(hp_sdc.status_io); 116 status = sdc_readb(hp_sdc.status_io);
115 if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0; 117 if (!(status & HP_SDC_STATUS_IBF))
118 hp_sdc.ibf = 0;
116 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 119 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
117 120
118 return status; 121 return status;
119} 122}
120 123
121static inline uint8_t hp_sdc_data_in8 (void) { 124static inline uint8_t hp_sdc_data_in8(void)
122 return sdc_readb(hp_sdc.data_io); 125{
126 return sdc_readb(hp_sdc.data_io);
123} 127}
124 128
125static inline void hp_sdc_status_out8 (uint8_t val) { 129static inline void hp_sdc_status_out8(uint8_t val)
130{
126 unsigned long flags; 131 unsigned long flags;
127 132
128 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 133 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
129 hp_sdc.ibf = 1; 134 hp_sdc.ibf = 1;
130 if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff; 135 if ((val & 0xf0) == 0xe0)
136 hp_sdc.wi = 0xff;
131 sdc_writeb(val, hp_sdc.status_io); 137 sdc_writeb(val, hp_sdc.status_io);
132 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 138 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
133} 139}
134 140
135static inline void hp_sdc_data_out8 (uint8_t val) { 141static inline void hp_sdc_data_out8(uint8_t val)
142{
136 unsigned long flags; 143 unsigned long flags;
137 144
138 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 145 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
@@ -141,11 +148,12 @@ static inline void hp_sdc_data_out8 (uint8_t val) {
141 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 148 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
142} 149}
143 150
144/* Care must be taken to only invoke hp_sdc_spin_ibf when 151/* Care must be taken to only invoke hp_sdc_spin_ibf when
145 * absolutely needed, or in rarely invoked subroutines. 152 * absolutely needed, or in rarely invoked subroutines.
146 * Not only does it waste CPU cycles, it also wastes bus cycles. 153 * Not only does it waste CPU cycles, it also wastes bus cycles.
147 */ 154 */
148static inline void hp_sdc_spin_ibf(void) { 155static inline void hp_sdc_spin_ibf(void)
156{
149 unsigned long flags; 157 unsigned long flags;
150 rwlock_t *lock; 158 rwlock_t *lock;
151 159
@@ -158,19 +166,21 @@ static inline void hp_sdc_spin_ibf(void) {
158 } 166 }
159 read_unlock(lock); 167 read_unlock(lock);
160 write_lock(lock); 168 write_lock(lock);
161 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {}; 169 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF)
170 { }
162 hp_sdc.ibf = 0; 171 hp_sdc.ibf = 0;
163 write_unlock_irqrestore(lock, flags); 172 write_unlock_irqrestore(lock, flags);
164} 173}
165 174
166 175
167/************************ Interrupt context functions ************************/ 176/************************ Interrupt context functions ************************/
168static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { 177static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data)
178{
169 hp_sdc_transaction *curr; 179 hp_sdc_transaction *curr;
170 180
171 read_lock(&hp_sdc.rtq_lock); 181 read_lock(&hp_sdc.rtq_lock);
172 if (hp_sdc.rcurr < 0) { 182 if (hp_sdc.rcurr < 0) {
173 read_unlock(&hp_sdc.rtq_lock); 183 read_unlock(&hp_sdc.rtq_lock);
174 return; 184 return;
175 } 185 }
176 curr = hp_sdc.tq[hp_sdc.rcurr]; 186 curr = hp_sdc.tq[hp_sdc.rcurr];
@@ -183,25 +193,27 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
183 193
184 if (hp_sdc.rqty <= 0) { 194 if (hp_sdc.rqty <= 0) {
185 /* All data has been gathered. */ 195 /* All data has been gathered. */
186 if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) { 196 if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE)
187 if (curr->act.semaphore) up(curr->act.semaphore); 197 if (curr->act.semaphore)
188 } 198 up(curr->act.semaphore);
189 if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) { 199
200 if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK)
190 if (curr->act.irqhook) 201 if (curr->act.irqhook)
191 curr->act.irqhook(irq, dev_id, status, data); 202 curr->act.irqhook(irq, dev_id, status, data);
192 } 203
193 curr->actidx = curr->idx; 204 curr->actidx = curr->idx;
194 curr->idx++; 205 curr->idx++;
195 /* Return control of this transaction */ 206 /* Return control of this transaction */
196 write_lock(&hp_sdc.rtq_lock); 207 write_lock(&hp_sdc.rtq_lock);
197 hp_sdc.rcurr = -1; 208 hp_sdc.rcurr = -1;
198 hp_sdc.rqty = 0; 209 hp_sdc.rqty = 0;
199 write_unlock(&hp_sdc.rtq_lock); 210 write_unlock(&hp_sdc.rtq_lock);
200 tasklet_schedule(&hp_sdc.task); 211 tasklet_schedule(&hp_sdc.task);
201 } 212 }
202} 213}
203 214
204static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { 215static irqreturn_t hp_sdc_isr(int irq, void *dev_id)
216{
205 uint8_t status, data; 217 uint8_t status, data;
206 218
207 status = hp_sdc_status_in8(); 219 status = hp_sdc_status_in8();
@@ -209,67 +221,74 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
209 data = hp_sdc_data_in8(); 221 data = hp_sdc_data_in8();
210 222
211 /* For now we are ignoring these until we get the SDC to behave. */ 223 /* For now we are ignoring these until we get the SDC to behave. */
212 if (((status & 0xf1) == 0x51) && data == 0x82) { 224 if (((status & 0xf1) == 0x51) && data == 0x82)
213 return IRQ_HANDLED; 225 return IRQ_HANDLED;
214 }
215 226
216 switch(status & HP_SDC_STATUS_IRQMASK) { 227 switch (status & HP_SDC_STATUS_IRQMASK) {
217 case 0: /* This case is not documented. */ 228 case 0: /* This case is not documented. */
218 break; 229 break;
219 case HP_SDC_STATUS_USERTIMER: 230
220 case HP_SDC_STATUS_PERIODIC: 231 case HP_SDC_STATUS_USERTIMER:
221 case HP_SDC_STATUS_TIMER: 232 case HP_SDC_STATUS_PERIODIC:
233 case HP_SDC_STATUS_TIMER:
222 read_lock(&hp_sdc.hook_lock); 234 read_lock(&hp_sdc.hook_lock);
223 if (hp_sdc.timer != NULL) 235 if (hp_sdc.timer != NULL)
224 hp_sdc.timer(irq, dev_id, status, data); 236 hp_sdc.timer(irq, dev_id, status, data);
225 read_unlock(&hp_sdc.hook_lock); 237 read_unlock(&hp_sdc.hook_lock);
226 break; 238 break;
227 case HP_SDC_STATUS_REG: 239
240 case HP_SDC_STATUS_REG:
228 hp_sdc_take(irq, dev_id, status, data); 241 hp_sdc_take(irq, dev_id, status, data);
229 break; 242 break;
230 case HP_SDC_STATUS_HILCMD: 243
231 case HP_SDC_STATUS_HILDATA: 244 case HP_SDC_STATUS_HILCMD:
245 case HP_SDC_STATUS_HILDATA:
232 read_lock(&hp_sdc.hook_lock); 246 read_lock(&hp_sdc.hook_lock);
233 if (hp_sdc.hil != NULL) 247 if (hp_sdc.hil != NULL)
234 hp_sdc.hil(irq, dev_id, status, data); 248 hp_sdc.hil(irq, dev_id, status, data);
235 read_unlock(&hp_sdc.hook_lock); 249 read_unlock(&hp_sdc.hook_lock);
236 break; 250 break;
237 case HP_SDC_STATUS_PUP: 251
252 case HP_SDC_STATUS_PUP:
238 read_lock(&hp_sdc.hook_lock); 253 read_lock(&hp_sdc.hook_lock);
239 if (hp_sdc.pup != NULL) 254 if (hp_sdc.pup != NULL)
240 hp_sdc.pup(irq, dev_id, status, data); 255 hp_sdc.pup(irq, dev_id, status, data);
241 else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); 256 else
257 printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
242 read_unlock(&hp_sdc.hook_lock); 258 read_unlock(&hp_sdc.hook_lock);
243 break; 259 break;
244 default: 260
261 default:
245 read_lock(&hp_sdc.hook_lock); 262 read_lock(&hp_sdc.hook_lock);
246 if (hp_sdc.cooked != NULL) 263 if (hp_sdc.cooked != NULL)
247 hp_sdc.cooked(irq, dev_id, status, data); 264 hp_sdc.cooked(irq, dev_id, status, data);
248 read_unlock(&hp_sdc.hook_lock); 265 read_unlock(&hp_sdc.hook_lock);
249 break; 266 break;
250 } 267 }
268
251 return IRQ_HANDLED; 269 return IRQ_HANDLED;
252} 270}
253 271
254 272
255static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { 273static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id)
274{
256 int status; 275 int status;
257 276
258 status = hp_sdc_status_in8(); 277 status = hp_sdc_status_in8();
259 printk(KERN_WARNING PREFIX "NMI !\n"); 278 printk(KERN_WARNING PREFIX "NMI !\n");
260 279
261#if 0 280#if 0
262 if (status & HP_SDC_NMISTATUS_FHS) { 281 if (status & HP_SDC_NMISTATUS_FHS) {
263 read_lock(&hp_sdc.hook_lock); 282 read_lock(&hp_sdc.hook_lock);
264 if (hp_sdc.timer != NULL) 283 if (hp_sdc.timer != NULL)
265 hp_sdc.timer(irq, dev_id, status, 0); 284 hp_sdc.timer(irq, dev_id, status, 0);
266 read_unlock(&hp_sdc.hook_lock); 285 read_unlock(&hp_sdc.hook_lock);
267 } 286 } else {
268 else {
269 /* TODO: pass this on to the HIL handler, or do SAK here? */ 287 /* TODO: pass this on to the HIL handler, or do SAK here? */
270 printk(KERN_WARNING PREFIX "HIL NMI\n"); 288 printk(KERN_WARNING PREFIX "HIL NMI\n");
271 } 289 }
272#endif 290#endif
291
273 return IRQ_HANDLED; 292 return IRQ_HANDLED;
274} 293}
275 294
@@ -278,13 +297,17 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {
278 297
279unsigned long hp_sdc_put(void); 298unsigned long hp_sdc_put(void);
280 299
281static void hp_sdc_tasklet(unsigned long foo) { 300static void hp_sdc_tasklet(unsigned long foo)
282 301{
283 write_lock_irq(&hp_sdc.rtq_lock); 302 write_lock_irq(&hp_sdc.rtq_lock);
303
284 if (hp_sdc.rcurr >= 0) { 304 if (hp_sdc.rcurr >= 0) {
285 struct timeval tv; 305 struct timeval tv;
306
286 do_gettimeofday(&tv); 307 do_gettimeofday(&tv);
287 if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000; 308 if (tv.tv_sec > hp_sdc.rtv.tv_sec)
309 tv.tv_usec += USEC_PER_SEC;
310
288 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { 311 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
289 hp_sdc_transaction *curr; 312 hp_sdc_transaction *curr;
290 uint8_t tmp; 313 uint8_t tmp;
@@ -300,27 +323,29 @@ static void hp_sdc_tasklet(unsigned long foo) {
300 hp_sdc.rqty = 0; 323 hp_sdc.rqty = 0;
301 tmp = curr->seq[curr->actidx]; 324 tmp = curr->seq[curr->actidx];
302 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; 325 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
303 if(tmp & HP_SDC_ACT_SEMAPHORE) { 326 if (tmp & HP_SDC_ACT_SEMAPHORE)
304 if (curr->act.semaphore) 327 if (curr->act.semaphore)
305 up(curr->act.semaphore); 328 up(curr->act.semaphore);
306 } 329
307 if(tmp & HP_SDC_ACT_CALLBACK) { 330 if (tmp & HP_SDC_ACT_CALLBACK) {
308 /* Note this means that irqhooks may be called 331 /* Note this means that irqhooks may be called
309 * in tasklet/bh context. 332 * in tasklet/bh context.
310 */ 333 */
311 if (curr->act.irqhook) 334 if (curr->act.irqhook)
312 curr->act.irqhook(0, NULL, 0, 0); 335 curr->act.irqhook(0, NULL, 0, 0);
313 } 336 }
337
314 curr->actidx = curr->idx; 338 curr->actidx = curr->idx;
315 curr->idx++; 339 curr->idx++;
316 hp_sdc.rcurr = -1; 340 hp_sdc.rcurr = -1;
317 } 341 }
318 } 342 }
319 write_unlock_irq(&hp_sdc.rtq_lock); 343 write_unlock_irq(&hp_sdc.rtq_lock);
320 hp_sdc_put(); 344 hp_sdc_put();
321} 345}
322 346
323unsigned long hp_sdc_put(void) { 347unsigned long hp_sdc_put(void)
348{
324 hp_sdc_transaction *curr; 349 hp_sdc_transaction *curr;
325 uint8_t act; 350 uint8_t act;
326 int idx, curridx; 351 int idx, curridx;
@@ -333,19 +358,24 @@ unsigned long hp_sdc_put(void) {
333 requires output, so we skip to the administrativa. */ 358 requires output, so we skip to the administrativa. */
334 if (hp_sdc.ibf) { 359 if (hp_sdc.ibf) {
335 hp_sdc_status_in8(); 360 hp_sdc_status_in8();
336 if (hp_sdc.ibf) goto finish; 361 if (hp_sdc.ibf)
362 goto finish;
337 } 363 }
338 364
339 anew: 365 anew:
340 /* See if we are in the middle of a sequence. */ 366 /* See if we are in the middle of a sequence. */
341 if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0; 367 if (hp_sdc.wcurr < 0)
368 hp_sdc.wcurr = 0;
342 read_lock_irq(&hp_sdc.rtq_lock); 369 read_lock_irq(&hp_sdc.rtq_lock);
343 if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++; 370 if (hp_sdc.rcurr == hp_sdc.wcurr)
371 hp_sdc.wcurr++;
344 read_unlock_irq(&hp_sdc.rtq_lock); 372 read_unlock_irq(&hp_sdc.rtq_lock);
345 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 373 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
374 hp_sdc.wcurr = 0;
346 curridx = hp_sdc.wcurr; 375 curridx = hp_sdc.wcurr;
347 376
348 if (hp_sdc.tq[curridx] != NULL) goto start; 377 if (hp_sdc.tq[curridx] != NULL)
378 goto start;
349 379
350 while (++curridx != hp_sdc.wcurr) { 380 while (++curridx != hp_sdc.wcurr) {
351 if (curridx >= HP_SDC_QUEUE_LEN) { 381 if (curridx >= HP_SDC_QUEUE_LEN) {
@@ -358,7 +388,8 @@ unsigned long hp_sdc_put(void) {
358 continue; 388 continue;
359 } 389 }
360 read_unlock_irq(&hp_sdc.rtq_lock); 390 read_unlock_irq(&hp_sdc.rtq_lock);
361 if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */ 391 if (hp_sdc.tq[curridx] != NULL)
392 break; /* Found one. */
362 } 393 }
363 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ 394 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
364 curridx = -1; 395 curridx = -1;
@@ -374,7 +405,8 @@ unsigned long hp_sdc_put(void) {
374 goto finish; 405 goto finish;
375 } 406 }
376 407
377 if (hp_sdc.wcurr == -1) goto done; 408 if (hp_sdc.wcurr == -1)
409 goto done;
378 410
379 curr = hp_sdc.tq[curridx]; 411 curr = hp_sdc.tq[curridx];
380 idx = curr->actidx; 412 idx = curr->actidx;
@@ -383,20 +415,23 @@ unsigned long hp_sdc_put(void) {
383 hp_sdc.tq[curridx] = NULL; 415 hp_sdc.tq[curridx] = NULL;
384 /* Interleave outbound data between the transactions. */ 416 /* Interleave outbound data between the transactions. */
385 hp_sdc.wcurr++; 417 hp_sdc.wcurr++;
386 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 418 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
387 goto finish; 419 hp_sdc.wcurr = 0;
420 goto finish;
388 } 421 }
389 422
390 act = curr->seq[idx]; 423 act = curr->seq[idx];
391 idx++; 424 idx++;
392 425
393 if (curr->idx >= curr->endidx) { 426 if (curr->idx >= curr->endidx) {
394 if (act & HP_SDC_ACT_DEALLOC) kfree(curr); 427 if (act & HP_SDC_ACT_DEALLOC)
428 kfree(curr);
395 hp_sdc.tq[curridx] = NULL; 429 hp_sdc.tq[curridx] = NULL;
396 /* Interleave outbound data between the transactions. */ 430 /* Interleave outbound data between the transactions. */
397 hp_sdc.wcurr++; 431 hp_sdc.wcurr++;
398 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 432 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
399 goto finish; 433 hp_sdc.wcurr = 0;
434 goto finish;
400 } 435 }
401 436
402 while (act & HP_SDC_ACT_PRECMD) { 437 while (act & HP_SDC_ACT_PRECMD) {
@@ -409,9 +444,10 @@ unsigned long hp_sdc_put(void) {
409 curr->idx++; 444 curr->idx++;
410 /* act finished? */ 445 /* act finished? */
411 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) 446 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
412 goto actdone; 447 goto actdone;
413 /* skip quantity field if data-out sequence follows. */ 448 /* skip quantity field if data-out sequence follows. */
414 if (act & HP_SDC_ACT_DATAOUT) curr->idx++; 449 if (act & HP_SDC_ACT_DATAOUT)
450 curr->idx++;
415 goto finish; 451 goto finish;
416 } 452 }
417 if (act & HP_SDC_ACT_DATAOUT) { 453 if (act & HP_SDC_ACT_DATAOUT) {
@@ -423,15 +459,15 @@ unsigned long hp_sdc_put(void) {
423 hp_sdc_data_out8(curr->seq[curr->idx]); 459 hp_sdc_data_out8(curr->seq[curr->idx]);
424 curr->idx++; 460 curr->idx++;
425 /* act finished? */ 461 /* act finished? */
426 if ((curr->idx - idx >= qty) && 462 if (curr->idx - idx >= qty &&
427 ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)) 463 (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)
428 goto actdone; 464 goto actdone;
429 goto finish; 465 goto finish;
430 } 466 }
431 idx += qty; 467 idx += qty;
432 act &= ~HP_SDC_ACT_DATAOUT; 468 act &= ~HP_SDC_ACT_DATAOUT;
433 } 469 } else
434 else while (act & HP_SDC_ACT_DATAREG) { 470 while (act & HP_SDC_ACT_DATAREG) {
435 int mask; 471 int mask;
436 uint8_t w7[4]; 472 uint8_t w7[4];
437 473
@@ -445,26 +481,30 @@ unsigned long hp_sdc_put(void) {
445 act &= ~HP_SDC_ACT_DATAREG; 481 act &= ~HP_SDC_ACT_DATAREG;
446 break; 482 break;
447 } 483 }
448 484
449 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; 485 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
450 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; 486 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
451 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; 487 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
452 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; 488 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
453 489
454 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || 490 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
455 w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) { 491 w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) {
456 int i = 0; 492 int i = 0;
457 493
458 /* Need to point the write index register */ 494 /* Need to point the write index register */
459 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; 495 while (i < 4 && w7[i] == hp_sdc.r7[i])
496 i++;
497
460 if (i < 4) { 498 if (i < 4) {
461 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); 499 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
462 hp_sdc.wi = 0x70 + i; 500 hp_sdc.wi = 0x70 + i;
463 goto finish; 501 goto finish;
464 } 502 }
503
465 idx++; 504 idx++;
466 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) 505 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
467 goto actdone; 506 goto actdone;
507
468 curr->idx = idx; 508 curr->idx = idx;
469 act &= ~HP_SDC_ACT_DATAREG; 509 act &= ~HP_SDC_ACT_DATAREG;
470 break; 510 break;
@@ -476,12 +516,13 @@ unsigned long hp_sdc_put(void) {
476 { 516 {
477 int i = 0; 517 int i = 0;
478 518
479 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; 519 while ((i < 4) && w7[i] == hp_sdc.r7[i])
520 i++;
480 if (i >= 4) { 521 if (i >= 4) {
481 curr->idx = idx + 1; 522 curr->idx = idx + 1;
482 if ((act & HP_SDC_ACT_DURING) == 523 if ((act & HP_SDC_ACT_DURING) ==
483 HP_SDC_ACT_DATAREG) 524 HP_SDC_ACT_DATAREG)
484 goto actdone; 525 goto actdone;
485 } 526 }
486 } 527 }
487 goto finish; 528 goto finish;
@@ -497,7 +538,7 @@ unsigned long hp_sdc_put(void) {
497 538
498 539
499 if (act & HP_SDC_ACT_POSTCMD) { 540 if (act & HP_SDC_ACT_POSTCMD) {
500 uint8_t postcmd; 541 uint8_t postcmd;
501 542
502 /* curr->idx should == idx at this point. */ 543 /* curr->idx should == idx at this point. */
503 postcmd = curr->seq[idx]; 544 postcmd = curr->seq[idx];
@@ -505,12 +546,12 @@ unsigned long hp_sdc_put(void) {
505 if (act & HP_SDC_ACT_DATAIN) { 546 if (act & HP_SDC_ACT_DATAIN) {
506 547
507 /* Start a new read */ 548 /* Start a new read */
508 hp_sdc.rqty = curr->seq[curr->idx]; 549 hp_sdc.rqty = curr->seq[curr->idx];
509 do_gettimeofday(&hp_sdc.rtv); 550 do_gettimeofday(&hp_sdc.rtv);
510 curr->idx++; 551 curr->idx++;
511 /* Still need to lock here in case of spurious irq. */ 552 /* Still need to lock here in case of spurious irq. */
512 write_lock_irq(&hp_sdc.rtq_lock); 553 write_lock_irq(&hp_sdc.rtq_lock);
513 hp_sdc.rcurr = curridx; 554 hp_sdc.rcurr = curridx;
514 write_unlock_irq(&hp_sdc.rtq_lock); 555 write_unlock_irq(&hp_sdc.rtq_lock);
515 hp_sdc_status_out8(postcmd); 556 hp_sdc_status_out8(postcmd);
516 goto finish; 557 goto finish;
@@ -519,75 +560,86 @@ unsigned long hp_sdc_put(void) {
519 goto actdone; 560 goto actdone;
520 } 561 }
521 562
522actdone: 563 actdone:
523 if (act & HP_SDC_ACT_SEMAPHORE) { 564 if (act & HP_SDC_ACT_SEMAPHORE)
524 up(curr->act.semaphore); 565 up(curr->act.semaphore);
525 } 566 else if (act & HP_SDC_ACT_CALLBACK)
526 else if (act & HP_SDC_ACT_CALLBACK) {
527 curr->act.irqhook(0,NULL,0,0); 567 curr->act.irqhook(0,NULL,0,0);
528 } 568
529 if (curr->idx >= curr->endidx) { /* This transaction is over. */ 569 if (curr->idx >= curr->endidx) { /* This transaction is over. */
530 if (act & HP_SDC_ACT_DEALLOC) kfree(curr); 570 if (act & HP_SDC_ACT_DEALLOC)
571 kfree(curr);
531 hp_sdc.tq[curridx] = NULL; 572 hp_sdc.tq[curridx] = NULL;
532 } 573 } else {
533 else {
534 curr->actidx = idx + 1; 574 curr->actidx = idx + 1;
535 curr->idx = idx + 2; 575 curr->idx = idx + 2;
536 } 576 }
537 /* Interleave outbound data between the transactions. */ 577 /* Interleave outbound data between the transactions. */
538 hp_sdc.wcurr++; 578 hp_sdc.wcurr++;
539 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 579 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
580 hp_sdc.wcurr = 0;
540 581
541 finish: 582 finish:
542 /* If by some quirk IBF has cleared and our ISR has run to 583 /* If by some quirk IBF has cleared and our ISR has run to
543 see that that has happened, do it all again. */ 584 see that that has happened, do it all again. */
544 if (!hp_sdc.ibf && limit++ < 20) goto anew; 585 if (!hp_sdc.ibf && limit++ < 20)
586 goto anew;
545 587
546 done: 588 done:
547 if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task); 589 if (hp_sdc.wcurr >= 0)
590 tasklet_schedule(&hp_sdc.task);
548 write_unlock(&hp_sdc.lock); 591 write_unlock(&hp_sdc.lock);
592
549 return 0; 593 return 0;
550} 594}
551 595
552/******* Functions called in either user or kernel context ****/ 596/******* Functions called in either user or kernel context ****/
553int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { 597int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
554 unsigned long flags; 598{
555 int i; 599 int i;
556 600
557 if (this == NULL) { 601 if (this == NULL) {
558 tasklet_schedule(&hp_sdc.task); 602 BUG();
559 return -EINVAL; 603 return -EINVAL;
560 }; 604 }
561
562 write_lock_irqsave(&hp_sdc.lock, flags);
563 605
564 /* Can't have same transaction on queue twice */ 606 /* Can't have same transaction on queue twice */
565 for (i=0; i < HP_SDC_QUEUE_LEN; i++) 607 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
566 if (hp_sdc.tq[i] == this) goto fail; 608 if (hp_sdc.tq[i] == this)
609 goto fail;
567 610
568 this->actidx = 0; 611 this->actidx = 0;
569 this->idx = 1; 612 this->idx = 1;
570 613
571 /* Search for empty slot */ 614 /* Search for empty slot */
572 for (i=0; i < HP_SDC_QUEUE_LEN; i++) { 615 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
573 if (hp_sdc.tq[i] == NULL) { 616 if (hp_sdc.tq[i] == NULL) {
574 hp_sdc.tq[i] = this; 617 hp_sdc.tq[i] = this;
575 write_unlock_irqrestore(&hp_sdc.lock, flags);
576 tasklet_schedule(&hp_sdc.task); 618 tasklet_schedule(&hp_sdc.task);
577 return 0; 619 return 0;
578 } 620 }
579 } 621
580 write_unlock_irqrestore(&hp_sdc.lock, flags);
581 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); 622 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
582 return -EBUSY; 623 return -EBUSY;
583 624
584 fail: 625 fail:
585 write_unlock_irqrestore(&hp_sdc.lock,flags);
586 printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); 626 printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
587 return -EINVAL; 627 return -EINVAL;
588} 628}
589 629
590int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { 630int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
631 unsigned long flags;
632 int ret;
633
634 write_lock_irqsave(&hp_sdc.lock, flags);
635 ret = __hp_sdc_enqueue_transaction(this);
636 write_unlock_irqrestore(&hp_sdc.lock,flags);
637
638 return ret;
639}
640
641int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
642{
591 unsigned long flags; 643 unsigned long flags;
592 int i; 644 int i;
593 645
@@ -595,8 +647,9 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
595 647
596 /* TODO: don't remove it if it's not done. */ 648 /* TODO: don't remove it if it's not done. */
597 649
598 for (i=0; i < HP_SDC_QUEUE_LEN; i++) 650 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
599 if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL; 651 if (hp_sdc.tq[i] == this)
652 hp_sdc.tq[i] = NULL;
600 653
601 write_unlock_irqrestore(&hp_sdc.lock, flags); 654 write_unlock_irqrestore(&hp_sdc.lock, flags);
602 return 0; 655 return 0;
@@ -605,11 +658,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
605 658
606 659
607/********************** User context functions **************************/ 660/********************** User context functions **************************/
608int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { 661int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback)
609 662{
610 if (callback == NULL || hp_sdc.dev == NULL) { 663 if (callback == NULL || hp_sdc.dev == NULL)
611 return -EINVAL; 664 return -EINVAL;
612 } 665
613 write_lock_irq(&hp_sdc.hook_lock); 666 write_lock_irq(&hp_sdc.hook_lock);
614 if (hp_sdc.timer != NULL) { 667 if (hp_sdc.timer != NULL) {
615 write_unlock_irq(&hp_sdc.hook_lock); 668 write_unlock_irq(&hp_sdc.hook_lock);
@@ -629,11 +682,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {
629 return 0; 682 return 0;
630} 683}
631 684
632int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { 685int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback)
633 686{
634 if (callback == NULL || hp_sdc.dev == NULL) { 687 if (callback == NULL || hp_sdc.dev == NULL)
635 return -EINVAL; 688 return -EINVAL;
636 } 689
637 write_lock_irq(&hp_sdc.hook_lock); 690 write_lock_irq(&hp_sdc.hook_lock);
638 if (hp_sdc.hil != NULL) { 691 if (hp_sdc.hil != NULL) {
639 write_unlock_irq(&hp_sdc.hook_lock); 692 write_unlock_irq(&hp_sdc.hook_lock);
@@ -650,11 +703,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {
650 return 0; 703 return 0;
651} 704}
652 705
653int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { 706int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback)
654 707{
655 if (callback == NULL || hp_sdc.dev == NULL) { 708 if (callback == NULL || hp_sdc.dev == NULL)
656 return -EINVAL; 709 return -EINVAL;
657 } 710
658 write_lock_irq(&hp_sdc.hook_lock); 711 write_lock_irq(&hp_sdc.hook_lock);
659 if (hp_sdc.cooked != NULL) { 712 if (hp_sdc.cooked != NULL) {
660 write_unlock_irq(&hp_sdc.hook_lock); 713 write_unlock_irq(&hp_sdc.hook_lock);
@@ -672,9 +725,8 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {
672 return 0; 725 return 0;
673} 726}
674 727
675int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { 728int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback)
676 729{
677
678 write_lock_irq(&hp_sdc.hook_lock); 730 write_lock_irq(&hp_sdc.hook_lock);
679 if ((callback != hp_sdc.timer) || 731 if ((callback != hp_sdc.timer) ||
680 (hp_sdc.timer == NULL)) { 732 (hp_sdc.timer == NULL)) {
@@ -694,8 +746,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {
694 return 0; 746 return 0;
695} 747}
696 748
697int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { 749int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback)
698 750{
699 write_lock_irq(&hp_sdc.hook_lock); 751 write_lock_irq(&hp_sdc.hook_lock);
700 if ((callback != hp_sdc.hil) || 752 if ((callback != hp_sdc.hil) ||
701 (hp_sdc.hil == NULL)) { 753 (hp_sdc.hil == NULL)) {
@@ -715,8 +767,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {
715 return 0; 767 return 0;
716} 768}
717 769
718int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { 770int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback)
719 771{
720 write_lock_irq(&hp_sdc.hook_lock); 772 write_lock_irq(&hp_sdc.hook_lock);
721 if ((callback != hp_sdc.cooked) || 773 if ((callback != hp_sdc.cooked) ||
722 (hp_sdc.cooked == NULL)) { 774 (hp_sdc.cooked == NULL)) {
@@ -738,7 +790,8 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {
738 790
739/************************* Keepalive timer task *********************/ 791/************************* Keepalive timer task *********************/
740 792
741void hp_sdc_kicker (unsigned long data) { 793void hp_sdc_kicker (unsigned long data)
794{
742 tasklet_schedule(&hp_sdc.task); 795 tasklet_schedule(&hp_sdc.task);
743 /* Re-insert the periodic task. */ 796 /* Re-insert the periodic task. */
744 mod_timer(&hp_sdc.kicker, jiffies + HZ); 797 mod_timer(&hp_sdc.kicker, jiffies + HZ);
@@ -748,12 +801,12 @@ void hp_sdc_kicker (unsigned long data) {
748 801
749#if defined(__hppa__) 802#if defined(__hppa__)
750 803
751static struct parisc_device_id hp_sdc_tbl[] = { 804static const struct parisc_device_id hp_sdc_tbl[] = {
752 { 805 {
753 .hw_type = HPHW_FIO, 806 .hw_type = HPHW_FIO,
754 .hversion_rev = HVERSION_REV_ANY_ID, 807 .hversion_rev = HVERSION_REV_ANY_ID,
755 .hversion = HVERSION_ANY_ID, 808 .hversion = HVERSION_ANY_ID,
756 .sversion = 0x73, 809 .sversion = 0x73,
757 }, 810 },
758 { 0, } 811 { 0, }
759}; 812};
@@ -772,16 +825,15 @@ static struct parisc_driver hp_sdc_driver = {
772 825
773static int __init hp_sdc_init(void) 826static int __init hp_sdc_init(void)
774{ 827{
775 int i;
776 char *errstr; 828 char *errstr;
777 hp_sdc_transaction t_sync; 829 hp_sdc_transaction t_sync;
778 uint8_t ts_sync[6]; 830 uint8_t ts_sync[6];
779 struct semaphore s_sync; 831 struct semaphore s_sync;
780 832
781 rwlock_init(&hp_sdc.lock); 833 rwlock_init(&hp_sdc.lock);
782 rwlock_init(&hp_sdc.ibf_lock); 834 rwlock_init(&hp_sdc.ibf_lock);
783 rwlock_init(&hp_sdc.rtq_lock); 835 rwlock_init(&hp_sdc.rtq_lock);
784 rwlock_init(&hp_sdc.hook_lock); 836 rwlock_init(&hp_sdc.hook_lock);
785 837
786 hp_sdc.timer = NULL; 838 hp_sdc.timer = NULL;
787 hp_sdc.hil = NULL; 839 hp_sdc.hil = NULL;
@@ -796,7 +848,8 @@ static int __init hp_sdc_init(void)
796 hp_sdc.r7[3] = 0xff; 848 hp_sdc.r7[3] = 0xff;
797 hp_sdc.ibf = 1; 849 hp_sdc.ibf = 1;
798 850
799 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL; 851 memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq));
852
800 hp_sdc.wcurr = -1; 853 hp_sdc.wcurr = -1;
801 hp_sdc.rcurr = -1; 854 hp_sdc.rcurr = -1;
802 hp_sdc.rqty = 0; 855 hp_sdc.rqty = 0;
@@ -804,27 +857,32 @@ static int __init hp_sdc_init(void)
804 hp_sdc.dev_err = -ENODEV; 857 hp_sdc.dev_err = -ENODEV;
805 858
806 errstr = "IO not found for"; 859 errstr = "IO not found for";
807 if (!hp_sdc.base_io) goto err0; 860 if (!hp_sdc.base_io)
861 goto err0;
808 862
809 errstr = "IRQ not found for"; 863 errstr = "IRQ not found for";
810 if (!hp_sdc.irq) goto err0; 864 if (!hp_sdc.irq)
865 goto err0;
811 866
812 hp_sdc.dev_err = -EBUSY; 867 hp_sdc.dev_err = -EBUSY;
813 868
814#if defined(__hppa__) 869#if defined(__hppa__)
815 errstr = "IO not available for"; 870 errstr = "IO not available for";
816 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0; 871 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
817#endif 872 goto err0;
873#endif
818 874
819 errstr = "IRQ not available for"; 875 errstr = "IRQ not available for";
820 if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC", 876 if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
821 (void *) hp_sdc.base_io)) goto err1; 877 "HP SDC", &hp_sdc))
878 goto err1;
822 879
823 errstr = "NMI not available for"; 880 errstr = "NMI not available for";
824 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI", 881 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED,
825 (void *) hp_sdc.base_io)) goto err2; 882 "HP SDC NMI", &hp_sdc))
883 goto err2;
826 884
827 printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", 885 printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
828 (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 886 (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
829 887
830 hp_sdc_status_in8(); 888 hp_sdc_status_in8();
@@ -854,13 +912,14 @@ static int __init hp_sdc_init(void)
854 hp_sdc.dev_err = 0; 912 hp_sdc.dev_err = 0;
855 return 0; 913 return 0;
856 err2: 914 err2:
857 free_irq(hp_sdc.irq, NULL); 915 free_irq(hp_sdc.irq, &hp_sdc);
858 err1: 916 err1:
859 release_region(hp_sdc.data_io, 2); 917 release_region(hp_sdc.data_io, 2);
860 err0: 918 err0:
861 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", 919 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
862 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 920 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
863 hp_sdc.dev = NULL; 921 hp_sdc.dev = NULL;
922
864 return hp_sdc.dev_err; 923 return hp_sdc.dev_err;
865} 924}
866 925
@@ -868,8 +927,10 @@ static int __init hp_sdc_init(void)
868 927
869static int __init hp_sdc_init_hppa(struct parisc_device *d) 928static int __init hp_sdc_init_hppa(struct parisc_device *d)
870{ 929{
871 if (!d) return 1; 930 if (!d)
872 if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */ 931 return 1;
932 if (hp_sdc.dev != NULL)
933 return 1; /* We only expect one SDC */
873 934
874 hp_sdc.dev = d; 935 hp_sdc.dev = d;
875 hp_sdc.irq = d->irq; 936 hp_sdc.irq = d->irq;
@@ -898,18 +959,16 @@ static void hp_sdc_exit(void)
898 /* Wait until we know this has been processed by the i8042 */ 959 /* Wait until we know this has been processed by the i8042 */
899 hp_sdc_spin_ibf(); 960 hp_sdc_spin_ibf();
900 961
901 free_irq(hp_sdc.nmi, NULL); 962 free_irq(hp_sdc.nmi, &hp_sdc);
902 free_irq(hp_sdc.irq, NULL); 963 free_irq(hp_sdc.irq, &hp_sdc);
903 write_unlock_irq(&hp_sdc.lock); 964 write_unlock_irq(&hp_sdc.lock);
904 965
905 del_timer(&hp_sdc.kicker); 966 del_timer(&hp_sdc.kicker);
906 967
907 tasklet_kill(&hp_sdc.task); 968 tasklet_kill(&hp_sdc.task);
908 969
909/* release_region(hp_sdc.data_io, 2); */
910
911#if defined(__hppa__) 970#if defined(__hppa__)
912 if (unregister_parisc_driver(&hp_sdc_driver)) 971 if (unregister_parisc_driver(&hp_sdc_driver))
913 printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); 972 printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
914#endif 973#endif
915} 974}
@@ -923,7 +982,7 @@ static int __init hp_sdc_register(void)
923 mm_segment_t fs; 982 mm_segment_t fs;
924 unsigned char i; 983 unsigned char i;
925#endif 984#endif
926 985
927 hp_sdc.dev = NULL; 986 hp_sdc.dev = NULL;
928 hp_sdc.dev_err = 0; 987 hp_sdc.dev_err = 0;
929#if defined(__hppa__) 988#if defined(__hppa__)
@@ -960,8 +1019,8 @@ static int __init hp_sdc_register(void)
960 tq_init.seq = tq_init_seq; 1019 tq_init.seq = tq_init_seq;
961 tq_init.act.semaphore = &tq_init_sem; 1020 tq_init.act.semaphore = &tq_init_sem;
962 1021
963 tq_init_seq[0] = 1022 tq_init_seq[0] =
964 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 1023 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
965 tq_init_seq[1] = HP_SDC_CMD_READ_KCC; 1024 tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
966 tq_init_seq[2] = 1; 1025 tq_init_seq[2] = 1;
967 tq_init_seq[3] = 0; 1026 tq_init_seq[3] = 0;
@@ -979,13 +1038,13 @@ static int __init hp_sdc_register(void)
979 } 1038 }
980 hp_sdc.r11 = tq_init_seq[4]; 1039 hp_sdc.r11 = tq_init_seq[4];
981 if (hp_sdc.r11 & HP_SDC_CFG_NEW) { 1040 if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
982 char *str; 1041 const char *str;
983 printk(KERN_INFO PREFIX "New style SDC\n"); 1042 printk(KERN_INFO PREFIX "New style SDC\n");
984 tq_init_seq[1] = HP_SDC_CMD_READ_XTD; 1043 tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
985 tq_init.actidx = 0; 1044 tq_init.actidx = 0;
986 tq_init.idx = 1; 1045 tq_init.idx = 1;
987 down(&tq_init_sem); 1046 down(&tq_init_sem);
988 hp_sdc_enqueue_transaction(&tq_init); 1047 hp_sdc_enqueue_transaction(&tq_init);
989 down(&tq_init_sem); 1048 down(&tq_init_sem);
990 up(&tq_init_sem); 1049 up(&tq_init_sem);
991 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1050 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
@@ -995,15 +1054,13 @@ static int __init hp_sdc_register(void)
995 hp_sdc.r7e = tq_init_seq[4]; 1054 hp_sdc.r7e = tq_init_seq[4];
996 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) 1055 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
997 printk(KERN_INFO PREFIX "Revision: %s\n", str); 1056 printk(KERN_INFO PREFIX "Revision: %s\n", str);
998 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) { 1057 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER)
999 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); 1058 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
1000 } 1059 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC)
1001 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) {
1002 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); 1060 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
1003 }
1004 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " 1061 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
1005 "on next firmware reset.\n"); 1062 "on next firmware reset.\n");
1006 tq_init_seq[0] = HP_SDC_ACT_PRECMD | 1063 tq_init_seq[0] = HP_SDC_ACT_PRECMD |
1007 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 1064 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
1008 tq_init_seq[1] = HP_SDC_CMD_SET_STR; 1065 tq_init_seq[1] = HP_SDC_CMD_SET_STR;
1009 tq_init_seq[2] = 1; 1066 tq_init_seq[2] = 1;
@@ -1012,14 +1069,12 @@ static int __init hp_sdc_register(void)
1012 tq_init.idx = 1; 1069 tq_init.idx = 1;
1013 tq_init.endidx = 4; 1070 tq_init.endidx = 4;
1014 down(&tq_init_sem); 1071 down(&tq_init_sem);
1015 hp_sdc_enqueue_transaction(&tq_init); 1072 hp_sdc_enqueue_transaction(&tq_init);
1016 down(&tq_init_sem); 1073 down(&tq_init_sem);
1017 up(&tq_init_sem); 1074 up(&tq_init_sem);
1018 } 1075 } else
1019 else { 1076 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
1020 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
1021 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); 1077 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
1022 }
1023 1078
1024 return 0; 1079 return 0;
1025} 1080}
@@ -1027,13 +1082,13 @@ static int __init hp_sdc_register(void)
1027module_init(hp_sdc_register); 1082module_init(hp_sdc_register);
1028module_exit(hp_sdc_exit); 1083module_exit(hp_sdc_exit);
1029 1084
1030/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) 1085/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64)
1031 * cycles cycles-adj time 1086 * cycles cycles-adj time
1032 * between two consecutive mfctl(16)'s: 4 n/a 63ns 1087 * between two consecutive mfctl(16)'s: 4 n/a 63ns
1033 * hp_sdc_spin_ibf when idle: 119 115 1.7us 1088 * hp_sdc_spin_ibf when idle: 119 115 1.7us
1034 * gsc_writeb status register: 83 79 1.2us 1089 * gsc_writeb status register: 83 79 1.2us
1035 * IBF to clear after sending SET_IM: 6204 6006 93us 1090 * IBF to clear after sending SET_IM: 6204 6006 93us
1036 * IBF to clear after sending LOAD_RT: 4467 4352 68us 1091 * IBF to clear after sending LOAD_RT: 4467 4352 68us
1037 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us 1092 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us
1038 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us 1093 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us
1039 * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms 1094 * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index aa4a8a4ccfdb..c45ea74d53e4 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -58,12 +58,13 @@ struct hp_sdc_mlc_priv_s {
58} hp_sdc_mlc_priv; 58} hp_sdc_mlc_priv;
59 59
60/************************* Interrupt context ******************************/ 60/************************* Interrupt context ******************************/
61static void hp_sdc_mlc_isr (int irq, void *dev_id, 61static void hp_sdc_mlc_isr (int irq, void *dev_id,
62 uint8_t status, uint8_t data) { 62 uint8_t status, uint8_t data)
63 int idx; 63{
64 int idx;
64 hil_mlc *mlc = &hp_sdc_mlc; 65 hil_mlc *mlc = &hp_sdc_mlc;
65 66
66 write_lock(&(mlc->lock)); 67 write_lock(&mlc->lock);
67 if (mlc->icount < 0) { 68 if (mlc->icount < 0) {
68 printk(KERN_WARNING PREFIX "HIL Overflow!\n"); 69 printk(KERN_WARNING PREFIX "HIL Overflow!\n");
69 up(&mlc->isem); 70 up(&mlc->isem);
@@ -73,239 +74,232 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id,
73 if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) { 74 if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) {
74 mlc->ipacket[idx] |= data | HIL_ERR_INT; 75 mlc->ipacket[idx] |= data | HIL_ERR_INT;
75 mlc->icount--; 76 mlc->icount--;
76 if (hp_sdc_mlc_priv.got5x) goto check; 77 if (hp_sdc_mlc_priv.got5x || !idx)
77 if (!idx) goto check; 78 goto check;
78 if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) != 79 if ((mlc->ipacket[idx - 1] & HIL_PKT_ADDR_MASK) !=
79 (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) { 80 (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) {
80 mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK; 81 mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK;
81 mlc->ipacket[idx] |= (mlc->ipacket[idx-1] 82 mlc->ipacket[idx] |= (mlc->ipacket[idx - 1]
82 & HIL_PKT_ADDR_MASK); 83 & HIL_PKT_ADDR_MASK);
83 } 84 }
84 goto check; 85 goto check;
85 } 86 }
86 /* We know status is 5X */ 87 /* We know status is 5X */
87 if (data & HP_SDC_HIL_ISERR) goto err; 88 if (data & HP_SDC_HIL_ISERR)
88 mlc->ipacket[idx] = 89 goto err;
90 mlc->ipacket[idx] =
89 (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT; 91 (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT;
90 hp_sdc_mlc_priv.got5x = 1; 92 hp_sdc_mlc_priv.got5x = 1;
91 goto out; 93 goto out;
92 94
93 check: 95 check:
94 hp_sdc_mlc_priv.got5x = 0; 96 hp_sdc_mlc_priv.got5x = 0;
95 if (mlc->imatch == 0) goto done; 97 if (mlc->imatch == 0)
96 if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) 98 goto done;
97 && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done; 99 if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
98 if (mlc->ipacket[idx] == mlc->imatch) goto done; 100 && (mlc->ipacket[idx] == (mlc->imatch | idx)))
101 goto done;
102 if (mlc->ipacket[idx] == mlc->imatch)
103 goto done;
99 goto out; 104 goto out;
100 105
101 err: 106 err:
102 printk(KERN_DEBUG PREFIX "err code %x\n", data); 107 printk(KERN_DEBUG PREFIX "err code %x\n", data);
108
103 switch (data) { 109 switch (data) {
104 case HP_SDC_HIL_RC_DONE: 110 case HP_SDC_HIL_RC_DONE:
105 printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n"); 111 printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n");
106 break; 112 break;
113
107 case HP_SDC_HIL_ERR: 114 case HP_SDC_HIL_ERR:
108 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | 115 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR |
109 HIL_ERR_FERR | HIL_ERR_FOF; 116 HIL_ERR_FERR | HIL_ERR_FOF;
110 break; 117 break;
118
111 case HP_SDC_HIL_TO: 119 case HP_SDC_HIL_TO:
112 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR; 120 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR;
113 break; 121 break;
122
114 case HP_SDC_HIL_RC: 123 case HP_SDC_HIL_RC:
115 printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n"); 124 printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n");
116 break; 125 break;
126
117 default: 127 default:
118 printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); 128 printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data);
119 break; 129 break;
120 } 130 }
131
121 /* No more data will be coming due to an error. */ 132 /* No more data will be coming due to an error. */
122 done: 133 done:
123 tasklet_schedule(mlc->tasklet); 134 tasklet_schedule(mlc->tasklet);
124 up(&(mlc->isem)); 135 up(&mlc->isem);
125 out: 136 out:
126 write_unlock(&(mlc->lock)); 137 write_unlock(&mlc->lock);
127} 138}
128 139
129 140
130/******************** Tasklet or userspace context functions ****************/ 141/******************** Tasklet or userspace context functions ****************/
131 142
132static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) { 143static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout)
133 unsigned long flags; 144{
134 struct hp_sdc_mlc_priv_s *priv; 145 struct hp_sdc_mlc_priv_s *priv;
135 int rc = 2; 146 int rc = 2;
136 147
137 priv = mlc->priv; 148 priv = mlc->priv;
138 149
139 write_lock_irqsave(&(mlc->lock), flags);
140
141 /* Try to down the semaphore */ 150 /* Try to down the semaphore */
142 if (down_trylock(&(mlc->isem))) { 151 if (down_trylock(&mlc->isem)) {
143 struct timeval tv; 152 struct timeval tv;
144 if (priv->emtestmode) { 153 if (priv->emtestmode) {
145 mlc->ipacket[0] = 154 mlc->ipacket[0] =
146 HIL_ERR_INT | (mlc->opacket & 155 HIL_ERR_INT | (mlc->opacket &
147 (HIL_PKT_CMD | 156 (HIL_PKT_CMD |
148 HIL_PKT_ADDR_MASK | 157 HIL_PKT_ADDR_MASK |
149 HIL_PKT_DATA_MASK)); 158 HIL_PKT_DATA_MASK));
150 mlc->icount = 14; 159 mlc->icount = 14;
151 /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ 160 /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */
152 goto wasup; 161 goto wasup;
153 } 162 }
154 do_gettimeofday(&tv); 163 do_gettimeofday(&tv);
155 tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); 164 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec);
156 if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { 165 if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) {
157 /* printk("!%i %i", 166 /* printk("!%i %i",
158 tv.tv_usec - mlc->instart.tv_usec, 167 tv.tv_usec - mlc->instart.tv_usec,
159 mlc->intimeout); 168 mlc->intimeout);
160 */ 169 */
161 rc = 1; 170 rc = 1;
162 up(&(mlc->isem)); 171 up(&mlc->isem);
163 } 172 }
164 goto done; 173 goto done;
165 } 174 }
166 wasup: 175 wasup:
167 up(&(mlc->isem)); 176 up(&mlc->isem);
168 rc = 0; 177 rc = 0;
169 goto done;
170 done: 178 done:
171 write_unlock_irqrestore(&(mlc->lock), flags);
172 return rc; 179 return rc;
173} 180}
174 181
175static int hp_sdc_mlc_cts (hil_mlc *mlc) { 182static int hp_sdc_mlc_cts(hil_mlc *mlc)
183{
176 struct hp_sdc_mlc_priv_s *priv; 184 struct hp_sdc_mlc_priv_s *priv;
177 unsigned long flags;
178 185
179 priv = mlc->priv; 186 priv = mlc->priv;
180
181 write_lock_irqsave(&(mlc->lock), flags);
182 187
183 /* Try to down the semaphores -- they should be up. */ 188 /* Try to down the semaphores -- they should be up. */
184 if (down_trylock(&(mlc->isem))) { 189 BUG_ON(down_trylock(&mlc->isem));
185 BUG(); 190 BUG_ON(down_trylock(&mlc->osem));
186 goto busy; 191
187 } 192 up(&mlc->isem);
188 if (down_trylock(&(mlc->osem))) { 193 up(&mlc->osem);
189 BUG();
190 up(&(mlc->isem));
191 goto busy;
192 }
193 up(&(mlc->isem));
194 up(&(mlc->osem));
195 194
196 if (down_trylock(&(mlc->csem))) { 195 if (down_trylock(&mlc->csem)) {
197 if (priv->trans.act.semaphore != &(mlc->csem)) goto poll; 196 if (priv->trans.act.semaphore != &mlc->csem)
198 goto busy; 197 goto poll;
198 else
199 goto busy;
199 } 200 }
200 if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done; 201
202 if (!(priv->tseq[4] & HP_SDC_USE_LOOP))
203 goto done;
201 204
202 poll: 205 poll:
203 priv->trans.act.semaphore = &(mlc->csem); 206 priv->trans.act.semaphore = &mlc->csem;
204 priv->trans.actidx = 0; 207 priv->trans.actidx = 0;
205 priv->trans.idx = 1; 208 priv->trans.idx = 1;
206 priv->trans.endidx = 5; 209 priv->trans.endidx = 5;
207 priv->tseq[0] = 210 priv->tseq[0] =
208 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 211 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
209 priv->tseq[1] = HP_SDC_CMD_READ_USE; 212 priv->tseq[1] = HP_SDC_CMD_READ_USE;
210 priv->tseq[2] = 1; 213 priv->tseq[2] = 1;
211 priv->tseq[3] = 0; 214 priv->tseq[3] = 0;
212 priv->tseq[4] = 0; 215 priv->tseq[4] = 0;
213 hp_sdc_enqueue_transaction(&(priv->trans)); 216 __hp_sdc_enqueue_transaction(&priv->trans);
214 busy: 217 busy:
215 write_unlock_irqrestore(&(mlc->lock), flags);
216 return 1; 218 return 1;
217 done: 219 done:
218 priv->trans.act.semaphore = &(mlc->osem); 220 priv->trans.act.semaphore = &mlc->osem;
219 up(&(mlc->csem)); 221 up(&mlc->csem);
220 write_unlock_irqrestore(&(mlc->lock), flags);
221 return 0; 222 return 0;
222} 223}
223 224
224static void hp_sdc_mlc_out (hil_mlc *mlc) { 225static void hp_sdc_mlc_out(hil_mlc *mlc)
226{
225 struct hp_sdc_mlc_priv_s *priv; 227 struct hp_sdc_mlc_priv_s *priv;
226 unsigned long flags;
227 228
228 priv = mlc->priv; 229 priv = mlc->priv;
229 230
230 write_lock_irqsave(&(mlc->lock), flags);
231
232 /* Try to down the semaphore -- it should be up. */ 231 /* Try to down the semaphore -- it should be up. */
233 if (down_trylock(&(mlc->osem))) { 232 BUG_ON(down_trylock(&mlc->osem));
234 BUG();
235 goto done;
236 }
237 233
238 if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; 234 if (mlc->opacket & HIL_DO_ALTER_CTRL)
235 goto do_control;
239 236
240 do_data: 237 do_data:
241 if (priv->emtestmode) { 238 if (priv->emtestmode) {
242 up(&(mlc->osem)); 239 up(&mlc->osem);
243 goto done; 240 return;
244 } 241 }
245 /* Shouldn't be sending commands when loop may be busy */ 242 /* Shouldn't be sending commands when loop may be busy */
246 if (down_trylock(&(mlc->csem))) { 243 BUG_ON(down_trylock(&mlc->csem));
247 BUG(); 244 up(&mlc->csem);
248 goto done;
249 }
250 up(&(mlc->csem));
251 245
252 priv->trans.actidx = 0; 246 priv->trans.actidx = 0;
253 priv->trans.idx = 1; 247 priv->trans.idx = 1;
254 priv->trans.act.semaphore = &(mlc->osem); 248 priv->trans.act.semaphore = &mlc->osem;
255 priv->trans.endidx = 6; 249 priv->trans.endidx = 6;
256 priv->tseq[0] = 250 priv->tseq[0] =
257 HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; 251 HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE;
258 priv->tseq[1] = 0x7; 252 priv->tseq[1] = 0x7;
259 priv->tseq[2] = 253 priv->tseq[2] =
260 (mlc->opacket & 254 (mlc->opacket &
261 (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) 255 (HIL_PKT_ADDR_MASK | HIL_PKT_CMD))
262 >> HIL_PKT_ADDR_SHIFT; 256 >> HIL_PKT_ADDR_SHIFT;
263 priv->tseq[3] = 257 priv->tseq[3] =
264 (mlc->opacket & HIL_PKT_DATA_MASK) 258 (mlc->opacket & HIL_PKT_DATA_MASK)
265 >> HIL_PKT_DATA_SHIFT; 259 >> HIL_PKT_DATA_SHIFT;
266 priv->tseq[4] = 0; /* No timeout */ 260 priv->tseq[4] = 0; /* No timeout */
267 if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1; 261 if (priv->tseq[3] == HIL_CMD_DHR)
262 priv->tseq[4] = 1;
268 priv->tseq[5] = HP_SDC_CMD_DO_HIL; 263 priv->tseq[5] = HP_SDC_CMD_DO_HIL;
269 goto enqueue; 264 goto enqueue;
270 265
271 do_control: 266 do_control:
272 priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; 267 priv->emtestmode = mlc->opacket & HIL_CTRL_TEST;
273 268
274 /* we cannot emulate this, it should not be used. */ 269 /* we cannot emulate this, it should not be used. */
275 BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); 270 BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE);
276 271
277 if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only; 272 if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY)
278 if (mlc->opacket & HIL_CTRL_APE) { 273 goto control_only;
279 BUG(); /* Should not send command/data after engaging APE */ 274
280 goto done; 275 /* Should not send command/data after engaging APE */
281 } 276 BUG_ON(mlc->opacket & HIL_CTRL_APE);
282 /* Disengaging APE this way would not be valid either since 277
278 /* Disengaging APE this way would not be valid either since
283 * the loop must be allowed to idle. 279 * the loop must be allowed to idle.
284 * 280 *
285 * So, it works out that we really never actually send control 281 * So, it works out that we really never actually send control
286 * and data when using SDC, we just send the data. 282 * and data when using SDC, we just send the data.
287 */ 283 */
288 goto do_data; 284 goto do_data;
289 285
290 control_only: 286 control_only:
291 priv->trans.actidx = 0; 287 priv->trans.actidx = 0;
292 priv->trans.idx = 1; 288 priv->trans.idx = 1;
293 priv->trans.act.semaphore = &(mlc->osem); 289 priv->trans.act.semaphore = &mlc->osem;
294 priv->trans.endidx = 4; 290 priv->trans.endidx = 4;
295 priv->tseq[0] = 291 priv->tseq[0] =
296 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 292 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
297 priv->tseq[1] = HP_SDC_CMD_SET_LPC; 293 priv->tseq[1] = HP_SDC_CMD_SET_LPC;
298 priv->tseq[2] = 1; 294 priv->tseq[2] = 1;
299 // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; 295 /* priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; */
300 priv->tseq[3] = 0; 296 priv->tseq[3] = 0;
301 if (mlc->opacket & HIL_CTRL_APE) { 297 if (mlc->opacket & HIL_CTRL_APE) {
302 priv->tseq[3] |= HP_SDC_LPC_APE_IPF; 298 priv->tseq[3] |= HP_SDC_LPC_APE_IPF;
303 down_trylock(&(mlc->csem)); 299 down_trylock(&mlc->csem);
304 } 300 }
305 enqueue: 301 enqueue:
306 hp_sdc_enqueue_transaction(&(priv->trans)); 302 hp_sdc_enqueue_transaction(&priv->trans);
307 done:
308 write_unlock_irqrestore(&(mlc->lock), flags);
309} 303}
310 304
311static int __init hp_sdc_mlc_init(void) 305static int __init hp_sdc_mlc_init(void)
@@ -316,18 +310,18 @@ static int __init hp_sdc_mlc_init(void)
316 310
317 hp_sdc_mlc_priv.emtestmode = 0; 311 hp_sdc_mlc_priv.emtestmode = 0;
318 hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; 312 hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq;
319 hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem); 313 hp_sdc_mlc_priv.trans.act.semaphore = &mlc->osem;
320 hp_sdc_mlc_priv.got5x = 0; 314 hp_sdc_mlc_priv.got5x = 0;
321 315
322 mlc->cts = &hp_sdc_mlc_cts; 316 mlc->cts = &hp_sdc_mlc_cts;
323 mlc->in = &hp_sdc_mlc_in; 317 mlc->in = &hp_sdc_mlc_in;
324 mlc->out = &hp_sdc_mlc_out; 318 mlc->out = &hp_sdc_mlc_out;
319 mlc->priv = &hp_sdc_mlc_priv;
325 320
326 if (hil_mlc_register(mlc)) { 321 if (hil_mlc_register(mlc)) {
327 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); 322 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");
328 goto err0; 323 goto err0;
329 } 324 }
330 mlc->priv = &hp_sdc_mlc_priv;
331 325
332 if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { 326 if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) {
333 printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); 327 printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n");
@@ -335,10 +329,9 @@ static int __init hp_sdc_mlc_init(void)
335 } 329 }
336 return 0; 330 return 0;
337 err1: 331 err1:
338 if (hil_mlc_unregister(mlc)) { 332 if (hil_mlc_unregister(mlc))
339 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" 333 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
340 "This is bad. Could cause an oops.\n"); 334 "This is bad. Could cause an oops.\n");
341 }
342 err0: 335 err0:
343 return -EBUSY; 336 return -EBUSY;
344} 337}
@@ -346,14 +339,14 @@ static int __init hp_sdc_mlc_init(void)
346static void __exit hp_sdc_mlc_exit(void) 339static void __exit hp_sdc_mlc_exit(void)
347{ 340{
348 hil_mlc *mlc = &hp_sdc_mlc; 341 hil_mlc *mlc = &hp_sdc_mlc;
349 if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) { 342
343 if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr))
350 printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" 344 printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n"
351 "This is bad. Could cause an oops.\n"); 345 "This is bad. Could cause an oops.\n");
352 } 346
353 if (hil_mlc_unregister(mlc)) { 347 if (hil_mlc_unregister(mlc))
354 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" 348 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
355 "This is bad. Could cause an oops.\n"); 349 "This is bad. Could cause an oops.\n");
356 }
357} 350}
358 351
359module_init(hp_sdc_mlc_init); 352module_init(hp_sdc_mlc_init);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index d36bd5475b6d..6858bc58f0fd 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -160,6 +160,28 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
160 }, 160 },
161 }, 161 },
162 { 162 {
163 /*
164 * No data is coming from the touchscreen unless KBC
165 * is in legacy mode.
166 */
167 .ident = "Panasonic CF-29",
168 .matches = {
169 DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
170 DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
171 },
172 },
173 {
174 /*
175 * Errors on MUX ports are reported without raising AUXDATA
176 * causing "spurious NAK" messages.
177 */
178 .ident = "HP Pavilion DV4017EA",
179 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
181 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
182 },
183 },
184 {
163 .ident = "Toshiba P10", 185 .ident = "Toshiba P10",
164 .matches = { 186 .matches = {
165 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 187 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
@@ -280,6 +302,8 @@ static struct pnp_driver i8042_pnp_kbd_driver = {
280}; 302};
281 303
282static struct pnp_device_id pnp_aux_devids[] = { 304static struct pnp_device_id pnp_aux_devids[] = {
305 { .id = "FJC6000", .driver_data = 0 },
306 { .id = "FJC6001", .driver_data = 0 },
283 { .id = "PNP0f03", .driver_data = 0 }, 307 { .id = "PNP0f03", .driver_data = 0 },
284 { .id = "PNP0f0b", .driver_data = 0 }, 308 { .id = "PNP0f0b", .driver_data = 0 },
285 { .id = "PNP0f0e", .driver_data = 0 }, 309 { .id = "PNP0f0e", .driver_data = 0 },
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index db9cca3b65e0..7c17377a65b9 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -768,6 +768,13 @@ static void i8042_controller_reset(void)
768 i8042_flush(); 768 i8042_flush();
769 769
770/* 770/*
771 * Disable both KBD and AUX interfaces so they don't get in the way
772 */
773
774 i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS;
775 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
776
777/*
771 * Disable MUX mode if present. 778 * Disable MUX mode if present.
772 */ 779 */
773 780