aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/keyboard/hil_kbd.c77
-rw-r--r--drivers/input/mouse/hil_ptr.c93
-rw-r--r--drivers/input/serio/hil_mlc.c487
-rw-r--r--drivers/input/serio/hp_sdc.c395
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c227
5 files changed, 703 insertions, 576 deletions
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 7143f37927cd..18f4d417576f 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -94,10 +94,12 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
94 idx = kbd->idx4/4; 94 idx = kbd->idx4/4;
95 p = data[idx - 1]; 95 p = data[idx - 1];
96 96
97 if ((p & ~HIL_CMDCT_POL) == 97 if ((p & ~HIL_CMDCT_POL) ==
98 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; 98 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
99 if ((p & ~HIL_CMDCT_RPL) == 99 goto report;
100 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; 100 if ((p & ~HIL_CMDCT_RPL) ==
101 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
102 goto report;
101 103
102 /* Not a poll response. See if we are loading config records. */ 104 /* Not a poll response. See if we are loading config records. */
103 switch (p & HIL_PKT_DATA_MASK) { 105 switch (p & HIL_PKT_DATA_MASK) {
@@ -107,27 +109,32 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
107 for (; i < HIL_KBD_MAX_LENGTH; i++) 109 for (; i < HIL_KBD_MAX_LENGTH; i++)
108 kbd->idd[i] = 0; 110 kbd->idd[i] = 0;
109 break; 111 break;
112
110 case HIL_CMD_RSC: 113 case HIL_CMD_RSC:
111 for (i = 0; i < idx; i++) 114 for (i = 0; i < idx; i++)
112 kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; 115 kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
113 for (; i < HIL_KBD_MAX_LENGTH; i++) 116 for (; i < HIL_KBD_MAX_LENGTH; i++)
114 kbd->rsc[i] = 0; 117 kbd->rsc[i] = 0;
115 break; 118 break;
119
116 case HIL_CMD_EXD: 120 case HIL_CMD_EXD:
117 for (i = 0; i < idx; i++) 121 for (i = 0; i < idx; i++)
118 kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; 122 kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
119 for (; i < HIL_KBD_MAX_LENGTH; i++) 123 for (; i < HIL_KBD_MAX_LENGTH; i++)
120 kbd->exd[i] = 0; 124 kbd->exd[i] = 0;
121 break; 125 break;
126
122 case HIL_CMD_RNM: 127 case HIL_CMD_RNM:
123 for (i = 0; i < idx; i++) 128 for (i = 0; i < idx; i++)
124 kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; 129 kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
125 for (; i < HIL_KBD_MAX_LENGTH + 1; i++) 130 for (; i < HIL_KBD_MAX_LENGTH + 1; i++)
126 kbd->rnm[i] = '\0'; 131 kbd->rnm[i] = '\0';
127 break; 132 break;
133
128 default: 134 default:
129 /* These occur when device isn't present */ 135 /* These occur when device isn't present */
130 if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; 136 if (p == (HIL_ERR_INT | HIL_PKT_CMD))
137 break;
131 /* Anything else we'd like to know about. */ 138 /* Anything else we'd like to know about. */
132 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); 139 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
133 break; 140 break;
@@ -139,16 +146,19 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
139 switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { 146 switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
140 case HIL_POL_CHARTYPE_NONE: 147 case HIL_POL_CHARTYPE_NONE:
141 break; 148 break;
149
142 case HIL_POL_CHARTYPE_ASCII: 150 case HIL_POL_CHARTYPE_ASCII:
143 while (cnt < idx - 1) 151 while (cnt < idx - 1)
144 input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); 152 input_report_key(dev, kbd->data[cnt++] & 0x7f, 1);
145 break; 153 break;
154
146 case HIL_POL_CHARTYPE_RSVD1: 155 case HIL_POL_CHARTYPE_RSVD1:
147 case HIL_POL_CHARTYPE_RSVD2: 156 case HIL_POL_CHARTYPE_RSVD2:
148 case HIL_POL_CHARTYPE_BINARY: 157 case HIL_POL_CHARTYPE_BINARY:
149 while (cnt < idx - 1) 158 while (cnt < idx - 1)
150 input_report_key(dev, kbd->data[cnt++], 1); 159 input_report_key(dev, kbd->data[cnt++], 1);
151 break; 160 break;
161
152 case HIL_POL_CHARTYPE_SET1: 162 case HIL_POL_CHARTYPE_SET1:
153 while (cnt < idx - 1) { 163 while (cnt < idx - 1) {
154 unsigned int key; 164 unsigned int key;
@@ -161,6 +171,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
161 input_report_key(dev, key, !up); 171 input_report_key(dev, key, !up);
162 } 172 }
163 break; 173 break;
174
164 case HIL_POL_CHARTYPE_SET2: 175 case HIL_POL_CHARTYPE_SET2:
165 while (cnt < idx - 1) { 176 while (cnt < idx - 1) {
166 unsigned int key; 177 unsigned int key;
@@ -173,6 +184,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
173 input_report_key(dev, key, !up); 184 input_report_key(dev, key, !up);
174 } 185 }
175 break; 186 break;
187
176 case HIL_POL_CHARTYPE_SET3: 188 case HIL_POL_CHARTYPE_SET3:
177 while (cnt < idx - 1) { 189 while (cnt < idx - 1) {
178 unsigned int key; 190 unsigned int key;
@@ -191,42 +203,43 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
191 up(&kbd->sem); 203 up(&kbd->sem);
192} 204}
193 205
194static void hil_kbd_process_err(struct hil_kbd *kbd) { 206static void hil_kbd_process_err(struct hil_kbd *kbd)
207{
195 printk(KERN_WARNING PREFIX "errored HIL packet\n"); 208 printk(KERN_WARNING PREFIX "errored HIL packet\n");
196 kbd->idx4 = 0; 209 kbd->idx4 = 0;
197 up(&kbd->sem); 210 up(&kbd->sem);
198} 211}
199 212
200static irqreturn_t hil_kbd_interrupt(struct serio *serio, 213static irqreturn_t hil_kbd_interrupt(struct serio *serio,
201 unsigned char data, unsigned int flags) 214 unsigned char data, unsigned int flags)
202{ 215{
203 struct hil_kbd *kbd; 216 struct hil_kbd *kbd;
204 hil_packet packet; 217 hil_packet packet;
205 int idx; 218 int idx;
206 219
207 kbd = serio_get_drvdata(serio); 220 kbd = serio_get_drvdata(serio);
208 if (kbd == NULL) { 221 BUG_ON(kbd == NULL);
209 BUG();
210 return IRQ_HANDLED;
211 }
212 222
213 if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { 223 if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) {
214 hil_kbd_process_err(kbd); 224 hil_kbd_process_err(kbd);
215 return IRQ_HANDLED; 225 return IRQ_HANDLED;
216 } 226 }
217 idx = kbd->idx4/4; 227 idx = kbd->idx4/4;
218 if (!(kbd->idx4 % 4)) kbd->data[idx] = 0; 228 if (!(kbd->idx4 % 4))
229 kbd->data[idx] = 0;
219 packet = kbd->data[idx]; 230 packet = kbd->data[idx];
220 packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); 231 packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8);
221 kbd->data[idx] = packet; 232 kbd->data[idx] = packet;
222 233
223 /* Records of N 4-byte hil_packets must terminate with a command. */ 234 /* Records of N 4-byte hil_packets must terminate with a command. */
224 if ((++(kbd->idx4)) % 4) return IRQ_HANDLED; 235 if ((++(kbd->idx4)) % 4)
236 return IRQ_HANDLED;
225 if ((packet & 0xffff0000) != HIL_ERR_INT) { 237 if ((packet & 0xffff0000) != HIL_ERR_INT) {
226 hil_kbd_process_err(kbd); 238 hil_kbd_process_err(kbd);
227 return IRQ_HANDLED; 239 return IRQ_HANDLED;
228 } 240 }
229 if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd); 241 if (packet & HIL_PKT_CMD)
242 hil_kbd_process_record(kbd);
230 return IRQ_HANDLED; 243 return IRQ_HANDLED;
231} 244}
232 245
@@ -235,10 +248,7 @@ static void hil_kbd_disconnect(struct serio *serio)
235 struct hil_kbd *kbd; 248 struct hil_kbd *kbd;
236 249
237 kbd = serio_get_drvdata(serio); 250 kbd = serio_get_drvdata(serio);
238 if (kbd == NULL) { 251 BUG_ON(kbd == NULL);
239 BUG();
240 return;
241 }
242 252
243 serio_close(serio); 253 serio_close(serio);
244 input_unregister_device(kbd->dev); 254 input_unregister_device(kbd->dev);
@@ -267,34 +277,34 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
267 serio_set_drvdata(serio, kbd); 277 serio_set_drvdata(serio, kbd);
268 kbd->serio = serio; 278 kbd->serio = serio;
269 279
270 init_MUTEX_LOCKED(&(kbd->sem)); 280 init_MUTEX_LOCKED(&kbd->sem);
271 281
272 /* Get device info. MLC driver supplies devid/status/etc. */ 282 /* Get device info. MLC driver supplies devid/status/etc. */
273 serio->write(serio, 0); 283 serio->write(serio, 0);
274 serio->write(serio, 0); 284 serio->write(serio, 0);
275 serio->write(serio, HIL_PKT_CMD >> 8); 285 serio->write(serio, HIL_PKT_CMD >> 8);
276 serio->write(serio, HIL_CMD_IDD); 286 serio->write(serio, HIL_CMD_IDD);
277 down(&(kbd->sem)); 287 down(&kbd->sem);
278 288
279 serio->write(serio, 0); 289 serio->write(serio, 0);
280 serio->write(serio, 0); 290 serio->write(serio, 0);
281 serio->write(serio, HIL_PKT_CMD >> 8); 291 serio->write(serio, HIL_PKT_CMD >> 8);
282 serio->write(serio, HIL_CMD_RSC); 292 serio->write(serio, HIL_CMD_RSC);
283 down(&(kbd->sem)); 293 down(&kbd->sem);
284 294
285 serio->write(serio, 0); 295 serio->write(serio, 0);
286 serio->write(serio, 0); 296 serio->write(serio, 0);
287 serio->write(serio, HIL_PKT_CMD >> 8); 297 serio->write(serio, HIL_PKT_CMD >> 8);
288 serio->write(serio, HIL_CMD_RNM); 298 serio->write(serio, HIL_CMD_RNM);
289 down(&(kbd->sem)); 299 down(&kbd->sem);
290 300
291 serio->write(serio, 0); 301 serio->write(serio, 0);
292 serio->write(serio, 0); 302 serio->write(serio, 0);
293 serio->write(serio, HIL_PKT_CMD >> 8); 303 serio->write(serio, HIL_PKT_CMD >> 8);
294 serio->write(serio, HIL_CMD_EXD); 304 serio->write(serio, HIL_CMD_EXD);
295 down(&(kbd->sem)); 305 down(&kbd->sem);
296 306
297 up(&(kbd->sem)); 307 up(&kbd->sem);
298 308
299 did = kbd->idd[0]; 309 did = kbd->idd[0];
300 idd = kbd->idd + 1; 310 idd = kbd->idd + 1;
@@ -310,12 +320,11 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
310 goto bail2; 320 goto bail2;
311 } 321 }
312 322
313 if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { 323 if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
314 printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); 324 printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
315 goto bail2; 325 goto bail2;
316 } 326 }
317 327
318
319 kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); 328 kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
320 kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); 329 kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
321 kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; 330 kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
@@ -344,8 +353,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
344 serio->write(serio, 0); 353 serio->write(serio, 0);
345 serio->write(serio, HIL_PKT_CMD >> 8); 354 serio->write(serio, HIL_PKT_CMD >> 8);
346 serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ 355 serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
347 down(&(kbd->sem)); 356 down(&kbd->sem);
348 up(&(kbd->sem)); 357 up(&kbd->sem);
349 358
350 return 0; 359 return 0;
351 bail2: 360 bail2:
@@ -374,20 +383,20 @@ static struct serio_driver hil_kbd_serio_drv = {
374 }, 383 },
375 .description = "HP HIL keyboard driver", 384 .description = "HP HIL keyboard driver",
376 .id_table = hil_kbd_ids, 385 .id_table = hil_kbd_ids,
377 .connect = hil_kbd_connect, 386 .connect = hil_kbd_connect,
378 .disconnect = hil_kbd_disconnect, 387 .disconnect = hil_kbd_disconnect,
379 .interrupt = hil_kbd_interrupt 388 .interrupt = hil_kbd_interrupt
380}; 389};
381 390
382static int __init hil_kbd_init(void) 391static int __init hil_kbd_init(void)
383{ 392{
384 return serio_register_driver(&hil_kbd_serio_drv); 393 return serio_register_driver(&hil_kbd_serio_drv);
385} 394}
386 395
387static void __exit hil_kbd_exit(void) 396static void __exit hil_kbd_exit(void)
388{ 397{
389 serio_unregister_driver(&hil_kbd_serio_drv); 398 serio_unregister_driver(&hil_kbd_serio_drv);
390} 399}
391 400
392module_init(hil_kbd_init); 401module_init(hil_kbd_init);
393module_exit(hil_kbd_exit); 402module_exit(hil_kbd_exit);
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index bfb174fe3230..8e9421a643bc 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -88,10 +88,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
88 idx = ptr->idx4/4; 88 idx = ptr->idx4/4;
89 p = data[idx - 1]; 89 p = data[idx - 1];
90 90
91 if ((p & ~HIL_CMDCT_POL) == 91 if ((p & ~HIL_CMDCT_POL) ==
92 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; 92 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
93 if ((p & ~HIL_CMDCT_RPL) == 93 goto report;
94 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; 94 if ((p & ~HIL_CMDCT_RPL) ==
95 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
96 goto report;
95 97
96 /* Not a poll response. See if we are loading config records. */ 98 /* Not a poll response. See if we are loading config records. */
97 switch (p & HIL_PKT_DATA_MASK) { 99 switch (p & HIL_PKT_DATA_MASK) {
@@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
101 for (; i < HIL_PTR_MAX_LENGTH; i++) 103 for (; i < HIL_PTR_MAX_LENGTH; i++)
102 ptr->idd[i] = 0; 104 ptr->idd[i] = 0;
103 break; 105 break;
106
104 case HIL_CMD_RSC: 107 case HIL_CMD_RSC:
105 for (i = 0; i < idx; i++) 108 for (i = 0; i < idx; i++)
106 ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 109 ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
107 for (; i < HIL_PTR_MAX_LENGTH; i++) 110 for (; i < HIL_PTR_MAX_LENGTH; i++)
108 ptr->rsc[i] = 0; 111 ptr->rsc[i] = 0;
109 break; 112 break;
113
110 case HIL_CMD_EXD: 114 case HIL_CMD_EXD:
111 for (i = 0; i < idx; i++) 115 for (i = 0; i < idx; i++)
112 ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 116 ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
113 for (; i < HIL_PTR_MAX_LENGTH; i++) 117 for (; i < HIL_PTR_MAX_LENGTH; i++)
114 ptr->exd[i] = 0; 118 ptr->exd[i] = 0;
115 break; 119 break;
120
116 case HIL_CMD_RNM: 121 case HIL_CMD_RNM:
117 for (i = 0; i < idx; i++) 122 for (i = 0; i < idx; i++)
118 ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 123 ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
119 for (; i < HIL_PTR_MAX_LENGTH + 1; i++) 124 for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
120 ptr->rnm[i] = '\0'; 125 ptr->rnm[i] = 0;
121 break; 126 break;
127
122 default: 128 default:
123 /* These occur when device isn't present */ 129 /* These occur when device isn't present */
124 if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; 130 if (p == (HIL_ERR_INT | HIL_PKT_CMD))
131 break;
125 /* Anything else we'd like to know about. */ 132 /* Anything else we'd like to know about. */
126 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); 133 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
127 break; 134 break;
@@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
130 137
131 report: 138 report:
132 if ((p & HIL_CMDCT_POL) != idx - 1) { 139 if ((p & HIL_CMDCT_POL) != idx - 1) {
133 printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); 140 printk(KERN_WARNING PREFIX
141 "Malformed poll packet %x (idx = %i)\n", p, idx);
134 goto out; 142 goto out;
135 } 143 }
136 144
@@ -139,7 +147,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
139 laxis += i; 147 laxis += i;
140 148
141 ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ 149 ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
142 absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; 150 absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
143 151
144 for (cnt = 1; i < laxis; i++) { 152 for (cnt = 1; i < laxis; i++) {
145 unsigned int lo,hi,val; 153 unsigned int lo,hi,val;
@@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
157 input_report_abs(dev, ABS_X + i, val); 165 input_report_abs(dev, ABS_X + i, val);
158 } else { 166 } else {
159 val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); 167 val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
160 if (i%3) val *= -1; 168 if (i%3)
169 val *= -1;
161 input_report_rel(dev, REL_X + i, val); 170 input_report_rel(dev, REL_X + i, val);
162 } 171 }
163 } 172 }
@@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
168 btn = ptr->data[cnt++]; 177 btn = ptr->data[cnt++];
169 up = btn & 1; 178 up = btn & 1;
170 btn &= 0xfe; 179 btn &= 0xfe;
171 if (btn == 0x8e) { 180 if (btn == 0x8e)
172 continue; /* TODO: proximity == touch? */ 181 continue; /* TODO: proximity == touch? */
173 } 182 else
174 else if ((btn > 0x8c) || (btn < 0x80)) continue; 183 if ((btn > 0x8c) || (btn < 0x80))
184 continue;
175 btn = (btn - 0x80) >> 1; 185 btn = (btn - 0x80) >> 1;
176 btn = ptr->btnmap[btn]; 186 btn = ptr->btnmap[btn];
177 input_report_key(dev, btn, !up); 187 input_report_key(dev, btn, !up);
@@ -182,14 +192,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
182 up(&ptr->sem); 192 up(&ptr->sem);
183} 193}
184 194
185static void hil_ptr_process_err(struct hil_ptr *ptr) { 195static void hil_ptr_process_err(struct hil_ptr *ptr)
196{
186 printk(KERN_WARNING PREFIX "errored HIL packet\n"); 197 printk(KERN_WARNING PREFIX "errored HIL packet\n");
187 ptr->idx4 = 0; 198 ptr->idx4 = 0;
188 up(&ptr->sem); 199 up(&ptr->sem);
189 return;
190} 200}
191 201
192static irqreturn_t hil_ptr_interrupt(struct serio *serio, 202static irqreturn_t hil_ptr_interrupt(struct serio *serio,
193 unsigned char data, unsigned int flags) 203 unsigned char data, unsigned int flags)
194{ 204{
195 struct hil_ptr *ptr; 205 struct hil_ptr *ptr;
@@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio,
197 int idx; 207 int idx;
198 208
199 ptr = serio_get_drvdata(serio); 209 ptr = serio_get_drvdata(serio);
200 if (ptr == NULL) { 210 BUG_ON(ptr == NULL);
201 BUG();
202 return IRQ_HANDLED;
203 }
204 211
205 if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { 212 if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
206 hil_ptr_process_err(ptr); 213 hil_ptr_process_err(ptr);
207 return IRQ_HANDLED; 214 return IRQ_HANDLED;
208 } 215 }
209 idx = ptr->idx4/4; 216 idx = ptr->idx4/4;
210 if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; 217 if (!(ptr->idx4 % 4))
218 ptr->data[idx] = 0;
211 packet = ptr->data[idx]; 219 packet = ptr->data[idx];
212 packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); 220 packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
213 ptr->data[idx] = packet; 221 ptr->data[idx] = packet;
214 222
215 /* Records of N 4-byte hil_packets must terminate with a command. */ 223 /* Records of N 4-byte hil_packets must terminate with a command. */
216 if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; 224 if ((++(ptr->idx4)) % 4)
225 return IRQ_HANDLED;
217 if ((packet & 0xffff0000) != HIL_ERR_INT) { 226 if ((packet & 0xffff0000) != HIL_ERR_INT) {
218 hil_ptr_process_err(ptr); 227 hil_ptr_process_err(ptr);
219 return IRQ_HANDLED; 228 return IRQ_HANDLED;
220 } 229 }
221 if (packet & HIL_PKT_CMD) 230 if (packet & HIL_PKT_CMD)
222 hil_ptr_process_record(ptr); 231 hil_ptr_process_record(ptr);
232
223 return IRQ_HANDLED; 233 return IRQ_HANDLED;
224} 234}
225 235
@@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio)
228 struct hil_ptr *ptr; 238 struct hil_ptr *ptr;
229 239
230 ptr = serio_get_drvdata(serio); 240 ptr = serio_get_drvdata(serio);
231 if (ptr == NULL) { 241 BUG_ON(ptr == NULL);
232 BUG();
233 return;
234 }
235 242
236 serio_close(serio); 243 serio_close(serio);
237 input_unregister_device(ptr->dev); 244 input_unregister_device(ptr->dev);
@@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio)
241static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) 248static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
242{ 249{
243 struct hil_ptr *ptr; 250 struct hil_ptr *ptr;
244 char *txt; 251 const char *txt;
245 unsigned int i, naxsets, btntype; 252 unsigned int i, naxsets, btntype;
246 uint8_t did, *idd; 253 uint8_t did, *idd;
247 254
@@ -260,34 +267,34 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
260 serio_set_drvdata(serio, ptr); 267 serio_set_drvdata(serio, ptr);
261 ptr->serio = serio; 268 ptr->serio = serio;
262 269
263 init_MUTEX_LOCKED(&(ptr->sem)); 270 init_MUTEX_LOCKED(&ptr->sem);
264 271
265 /* Get device info. MLC driver supplies devid/status/etc. */ 272 /* Get device info. MLC driver supplies devid/status/etc. */
266 serio->write(serio, 0); 273 serio->write(serio, 0);
267 serio->write(serio, 0); 274 serio->write(serio, 0);
268 serio->write(serio, HIL_PKT_CMD >> 8); 275 serio->write(serio, HIL_PKT_CMD >> 8);
269 serio->write(serio, HIL_CMD_IDD); 276 serio->write(serio, HIL_CMD_IDD);
270 down(&(ptr->sem)); 277 down(&ptr->sem);
271 278
272 serio->write(serio, 0); 279 serio->write(serio, 0);
273 serio->write(serio, 0); 280 serio->write(serio, 0);
274 serio->write(serio, HIL_PKT_CMD >> 8); 281 serio->write(serio, HIL_PKT_CMD >> 8);
275 serio->write(serio, HIL_CMD_RSC); 282 serio->write(serio, HIL_CMD_RSC);
276 down(&(ptr->sem)); 283 down(&ptr->sem);
277 284
278 serio->write(serio, 0); 285 serio->write(serio, 0);
279 serio->write(serio, 0); 286 serio->write(serio, 0);
280 serio->write(serio, HIL_PKT_CMD >> 8); 287 serio->write(serio, HIL_PKT_CMD >> 8);
281 serio->write(serio, HIL_CMD_RNM); 288 serio->write(serio, HIL_CMD_RNM);
282 down(&(ptr->sem)); 289 down(&ptr->sem);
283 290
284 serio->write(serio, 0); 291 serio->write(serio, 0);
285 serio->write(serio, 0); 292 serio->write(serio, 0);
286 serio->write(serio, HIL_PKT_CMD >> 8); 293 serio->write(serio, HIL_PKT_CMD >> 8);
287 serio->write(serio, HIL_CMD_EXD); 294 serio->write(serio, HIL_CMD_EXD);
288 down(&(ptr->sem)); 295 down(&ptr->sem);
289 296
290 up(&(ptr->sem)); 297 up(&ptr->sem);
291 298
292 did = ptr->idd[0]; 299 did = ptr->idd[0];
293 idd = ptr->idd + 1; 300 idd = ptr->idd + 1;
@@ -301,12 +308,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
301 ptr->dev->evbit[0] = BIT(EV_ABS); 308 ptr->dev->evbit[0] = BIT(EV_ABS);
302 txt = "absolute"; 309 txt = "absolute";
303 } 310 }
304 if (!ptr->dev->evbit[0]) { 311 if (!ptr->dev->evbit[0])
305 goto bail2; 312 goto bail2;
306 }
307 313
308 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); 314 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
309 if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); 315 if (ptr->nbtn)
316 ptr->dev->evbit[0] |= BIT(EV_KEY);
310 317
311 naxsets = HIL_IDD_NUM_AXSETS(*idd); 318 naxsets = HIL_IDD_NUM_AXSETS(*idd);
312 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); 319 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
@@ -315,7 +322,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
315 did, txt); 322 did, txt);
316 printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", 323 printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
317 ptr->nbtn, naxsets, ptr->naxes); 324 ptr->nbtn, naxsets, ptr->naxes);
318 325
319 btntype = BTN_MISC; 326 btntype = BTN_MISC;
320 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) 327 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
321#ifdef TABLET_SIMULATES_MOUSE 328#ifdef TABLET_SIMULATES_MOUSE
@@ -325,7 +332,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
325#endif 332#endif
326 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) 333 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
327 btntype = BTN_TOUCH; 334 btntype = BTN_TOUCH;
328 335
329 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) 336 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
330 btntype = BTN_MOUSE; 337 btntype = BTN_MOUSE;
331 338
@@ -341,12 +348,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
341 } 348 }
342 349
343 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { 350 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
344 for (i = 0; i < ptr->naxes; i++) { 351 for (i = 0; i < ptr->naxes; i++)
345 set_bit(REL_X + i, ptr->dev->relbit); 352 set_bit(REL_X + i, ptr->dev->relbit);
346 } 353 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
347 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
348 set_bit(REL_X + i, ptr->dev->relbit); 354 set_bit(REL_X + i, ptr->dev->relbit);
349 }
350 } else { 355 } else {
351 for (i = 0; i < ptr->naxes; i++) { 356 for (i = 0; i < ptr->naxes; i++) {
352 set_bit(ABS_X + i, ptr->dev->absbit); 357 set_bit(ABS_X + i, ptr->dev->absbit);
@@ -419,11 +424,11 @@ static int __init hil_ptr_init(void)
419{ 424{
420 return serio_register_driver(&hil_ptr_serio_driver); 425 return serio_register_driver(&hil_ptr_serio_driver);
421} 426}
422 427
423static void __exit hil_ptr_exit(void) 428static void __exit hil_ptr_exit(void)
424{ 429{
425 serio_unregister_driver(&hil_ptr_serio_driver); 430 serio_unregister_driver(&hil_ptr_serio_driver);
426} 431}
427 432
428module_init(hil_ptr_init); 433module_init(hil_ptr_init);
429module_exit(hil_ptr_exit); 434module_exit(hil_ptr_exit);
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 0710704d2fd3..485b0742842b 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -32,11 +32,11 @@
32 * 32 *
33 * Driver theory of operation: 33 * Driver theory of operation:
34 * 34 *
35 * Some access methods and an ISR is defined by the sub-driver 35 * Some access methods and an ISR is defined by the sub-driver
36 * (e.g. hp_sdc_mlc.c). These methods are expected to provide a 36 * (e.g. hp_sdc_mlc.c). These methods are expected to provide a
37 * few bits of logic in addition to raw access to the HIL MLC, 37 * few bits of logic in addition to raw access to the HIL MLC,
38 * specifically, the ISR, which is entirely registered by the 38 * specifically, the ISR, which is entirely registered by the
39 * sub-driver and invoked directly, must check for record 39 * sub-driver and invoked directly, must check for record
40 * termination or packet match, at which point a semaphore must 40 * termination or packet match, at which point a semaphore must
41 * be cleared and then the hil_mlcs_tasklet must be scheduled. 41 * be cleared and then the hil_mlcs_tasklet must be scheduled.
42 * 42 *
@@ -47,7 +47,7 @@
47 * itself if output is pending. (This rescheduling should be replaced 47 * itself if output is pending. (This rescheduling should be replaced
48 * at some point with a sub-driver-specific mechanism.) 48 * at some point with a sub-driver-specific mechanism.)
49 * 49 *
50 * A timer task prods the tasklet once per second to prevent 50 * A timer task prods the tasklet once per second to prevent
51 * hangups when attached devices do not return expected data 51 * hangups when attached devices do not return expected data
52 * and to initiate probes of the loop for new devices. 52 * and to initiate probes of the loop for new devices.
53 */ 53 */
@@ -83,69 +83,85 @@ DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
83 83
84/********************** Device info/instance management **********************/ 84/********************** Device info/instance management **********************/
85 85
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;
@@ -428,7 +479,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
428 EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), 479 EXPECT(HIL_ERR_INT | TEST_PACKET(0xa),
429 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) 480 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART)
430 OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ 481 OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */
431 482
432 /* 9 HILSEN_DHR */ 483 /* 9 HILSEN_DHR */
433 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) 484 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
434 485
@@ -439,7 +490,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
439 IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) 490 IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT)
440 491
441 /* 14 HILSEN_IFC */ 492 /* 14 HILSEN_IFC */
442 OUT(HIL_PKT_CMD | HIL_CMD_IFC) 493 OUT(HIL_PKT_CMD | HIL_CMD_IFC)
443 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 494 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
444 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) 495 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT )
445 496
@@ -455,7 +506,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
455 506
456 /* 18 HILSEN_HEAL */ 507 /* 18 HILSEN_HEAL */
457 OUT_LAST(HIL_CMD_ELB) 508 OUT_LAST(HIL_CMD_ELB)
458 EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, 509 EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT,
459 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) 510 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT)
460 FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) 511 FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0)
461 512
@@ -503,7 +554,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
503 554
504 /* 44 HILSEN_PROBE */ 555 /* 44 HILSEN_PROBE */
505 OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) 556 OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT)
506 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) 557 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
507 OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) 558 OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB)
508 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) 559 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
509 OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) 560 OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1)
@@ -514,7 +565,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
514 /* 52 HILSEN_DSR */ 565 /* 52 HILSEN_DSR */
515 FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) 566 FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0)
516 OUT(HIL_PKT_CMD | HIL_CMD_DSR) 567 OUT(HIL_PKT_CMD | HIL_CMD_DSR)
517 IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) 568 IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC)
518 569
519 /* 55 HILSEN_REPOLL */ 570 /* 55 HILSEN_REPOLL */
520 OUT(HIL_PKT_CMD | HIL_CMD_RPL) 571 OUT(HIL_PKT_CMD | HIL_CMD_RPL)
@@ -523,14 +574,15 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = {
523 FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) 574 FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE)
524 575
525 /* 58 HILSEN_IFCACF */ 576 /* 58 HILSEN_IFCACF */
526 OUT(HIL_PKT_CMD | HIL_CMD_IFC) 577 OUT(HIL_PKT_CMD | HIL_CMD_IFC)
527 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 578 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
528 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) 579 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL)
529 580
530 /* 60 HILSEN_END */ 581 /* 60 HILSEN_END */
531}; 582};
532 583
533static inline void hilse_setup_input(hil_mlc *mlc, const 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,25 +607,25 @@ static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node
555 do_gettimeofday(&(mlc->instart)); 607 do_gettimeofday(&(mlc->instart));
556 mlc->icount = 15; 608 mlc->icount = 15;
557 memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); 609 memset(mlc->ipacket, 0, 16 * sizeof(hil_packet));
558 BUG_ON(down_trylock(&(mlc->isem))); 610 BUG_ON(down_trylock(&mlc->isem));
559
560 return;
561} 611}
562 612
563#ifdef HIL_MLC_DEBUG 613#ifdef HIL_MLC_DEBUG
564static int doze = 0; 614static int doze;
565static int seidx; /* For debug */ 615static int seidx; /* For debug */
566#endif 616#endif
567 617
568static int hilse_donode (hil_mlc *mlc) { 618static int hilse_donode(hil_mlc *mlc)
619{
569 const struct hilse_node *node; 620 const struct hilse_node *node;
570 int nextidx = 0; 621 int nextidx = 0;
571 int sched_long = 0; 622 int sched_long = 0;
572 unsigned long flags; 623 unsigned long flags;
573 624
574#ifdef HIL_MLC_DEBUG 625#ifdef HIL_MLC_DEBUG
575 if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { 626 if (mlc->seidx && mlc->seidx != seidx &&
576 printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); 627 mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) {
628 printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx);
577 doze = 0; 629 doze = 0;
578 } 630 }
579 631
@@ -588,50 +640,59 @@ static int hilse_donode (hil_mlc *mlc) {
588 case HILSE_FUNC: 640 case HILSE_FUNC:
589 BUG_ON(node->object.func == NULL); 641 BUG_ON(node->object.func == NULL);
590 rc = node->object.func(mlc, node->arg); 642 rc = node->object.func(mlc, node->arg);
591 nextidx = (rc > 0) ? node->ugly : 643 nextidx = (rc > 0) ? node->ugly :
592 ((rc < 0) ? node->bad : node->good); 644 ((rc < 0) ? node->bad : node->good);
593 if (nextidx == HILSEN_FOLLOW) nextidx = rc; 645 if (nextidx == HILSEN_FOLLOW)
646 nextidx = rc;
594 break; 647 break;
648
595 case HILSE_EXPECT_LAST: 649 case HILSE_EXPECT_LAST:
596 case HILSE_EXPECT_DISC: 650 case HILSE_EXPECT_DISC:
597 case HILSE_EXPECT: 651 case HILSE_EXPECT:
598 case HILSE_IN: 652 case HILSE_IN:
599 /* Already set up from previous HILSE_OUT_* */ 653 /* Already set up from previous HILSE_OUT_* */
600 write_lock_irqsave(&(mlc->lock), flags); 654 write_lock_irqsave(&mlc->lock, flags);
601 rc = mlc->in(mlc, node->arg); 655 rc = mlc->in(mlc, node->arg);
602 if (rc == 2) { 656 if (rc == 2) {
603 nextidx = HILSEN_DOZE; 657 nextidx = HILSEN_DOZE;
604 sched_long = 1; 658 sched_long = 1;
605 write_unlock_irqrestore(&(mlc->lock), flags); 659 write_unlock_irqrestore(&mlc->lock, flags);
606 break; 660 break;
607 } 661 }
608 if (rc == 1) nextidx = node->ugly; 662 if (rc == 1)
609 else if (rc == 0) nextidx = node->good; 663 nextidx = node->ugly;
610 else nextidx = node->bad; 664 else if (rc == 0)
665 nextidx = node->good;
666 else
667 nextidx = node->bad;
611 mlc->istarted = 0; 668 mlc->istarted = 0;
612 write_unlock_irqrestore(&(mlc->lock), flags); 669 write_unlock_irqrestore(&mlc->lock, flags);
613 break; 670 break;
671
614 case HILSE_OUT_LAST: 672 case HILSE_OUT_LAST:
615 write_lock_irqsave(&(mlc->lock), flags); 673 write_lock_irqsave(&mlc->lock, flags);
616 pack = node->object.packet; 674 pack = node->object.packet;
617 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); 675 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
618 goto out; 676 goto out;
677
619 case HILSE_OUT_DISC: 678 case HILSE_OUT_DISC:
620 write_lock_irqsave(&(mlc->lock), flags); 679 write_lock_irqsave(&mlc->lock, flags);
621 pack = node->object.packet; 680 pack = node->object.packet;
622 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); 681 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
623 goto out; 682 goto out;
683
624 case HILSE_OUT: 684 case HILSE_OUT:
625 write_lock_irqsave(&(mlc->lock), flags); 685 write_lock_irqsave(&mlc->lock, flags);
626 pack = node->object.packet; 686 pack = node->object.packet;
627 out: 687 out:
628 if (mlc->istarted) goto out2; 688 if (mlc->istarted)
689 goto out2;
629 /* Prepare to receive input */ 690 /* Prepare to receive input */
630 if ((node + 1)->act & HILSE_IN) 691 if ((node + 1)->act & HILSE_IN)
631 hilse_setup_input(mlc, node + 1); 692 hilse_setup_input(mlc, node + 1);
632 693
633 out2: 694 out2:
634 write_unlock_irqrestore(&(mlc->lock), flags); 695 write_unlock_irqrestore(&mlc->lock, flags);
635 696
636 if (down_trylock(&mlc->osem)) { 697 if (down_trylock(&mlc->osem)) {
637 nextidx = HILSEN_DOZE; 698 nextidx = HILSEN_DOZE;
@@ -639,37 +700,39 @@ static int hilse_donode (hil_mlc *mlc) {
639 } 700 }
640 up(&mlc->osem); 701 up(&mlc->osem);
641 702
642 write_lock_irqsave(&(mlc->lock), flags); 703 write_lock_irqsave(&mlc->lock, flags);
643 if (!(mlc->ostarted)) { 704 if (!mlc->ostarted) {
644 mlc->ostarted = 1; 705 mlc->ostarted = 1;
645 mlc->opacket = pack; 706 mlc->opacket = pack;
646 mlc->out(mlc); 707 mlc->out(mlc);
647 nextidx = HILSEN_DOZE; 708 nextidx = HILSEN_DOZE;
648 write_unlock_irqrestore(&(mlc->lock), flags); 709 write_unlock_irqrestore(&mlc->lock, flags);
649 break; 710 break;
650 } 711 }
651 mlc->ostarted = 0; 712 mlc->ostarted = 0;
652 do_gettimeofday(&(mlc->instart)); 713 do_gettimeofday(&(mlc->instart));
653 write_unlock_irqrestore(&(mlc->lock), flags); 714 write_unlock_irqrestore(&mlc->lock, flags);
654 nextidx = HILSEN_NEXT; 715 nextidx = HILSEN_NEXT;
655 break; 716 break;
717
656 case HILSE_CTS: 718 case HILSE_CTS:
657 nextidx = mlc->cts(mlc) ? node->bad : node->good; 719 nextidx = mlc->cts(mlc) ? node->bad : node->good;
658 break; 720 break;
721
659 default: 722 default:
660 BUG(); 723 BUG();
661 nextidx = 0;
662 break;
663 } 724 }
664 725
665#ifdef HIL_MLC_DEBUG 726#ifdef HIL_MLC_DEBUG
666 if (nextidx == HILSEN_DOZE) doze++; 727 if (nextidx == HILSEN_DOZE)
728 doze++;
667#endif 729#endif
668 730
669 while (nextidx & HILSEN_SCHED) { 731 while (nextidx & HILSEN_SCHED) {
670 struct timeval tv; 732 struct timeval tv;
671 733
672 if (!sched_long) goto sched; 734 if (!sched_long)
735 goto sched;
673 736
674 do_gettimeofday(&tv); 737 do_gettimeofday(&tv);
675 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); 738 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec);
@@ -682,17 +745,24 @@ static int hilse_donode (hil_mlc *mlc) {
682 sched: 745 sched:
683 tasklet_schedule(&hil_mlcs_tasklet); 746 tasklet_schedule(&hil_mlcs_tasklet);
684 break; 747 break;
685 } 748 }
686 if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; 749
687 else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; 750 if (nextidx & HILSEN_DOWN)
688 else mlc->seidx = nextidx & HILSEN_MASK; 751 mlc->seidx += nextidx & HILSEN_MASK;
752 else if (nextidx & HILSEN_UP)
753 mlc->seidx -= nextidx & HILSEN_MASK;
754 else
755 mlc->seidx = nextidx & HILSEN_MASK;
756
757 if (nextidx & HILSEN_BREAK)
758 return 1;
689 759
690 if (nextidx & HILSEN_BREAK) return 1;
691 return 0; 760 return 0;
692} 761}
693 762
694/******************** tasklet context functions **************************/ 763/******************** tasklet context functions **************************/
695static void hil_mlcs_process(unsigned long unused) { 764static void hil_mlcs_process(unsigned long unused)
765{
696 struct list_head *tmp; 766 struct list_head *tmp;
697 767
698 read_lock(&hil_mlcs_lock); 768 read_lock(&hil_mlcs_lock);
@@ -700,19 +770,20 @@ static void hil_mlcs_process(unsigned long unused) {
700 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); 770 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list);
701 while (hilse_donode(mlc) == 0) { 771 while (hilse_donode(mlc) == 0) {
702#ifdef HIL_MLC_DEBUG 772#ifdef HIL_MLC_DEBUG
703 if (mlc->seidx != 41 && 773 if (mlc->seidx != 41 &&
704 mlc->seidx != 42 && 774 mlc->seidx != 42 &&
705 mlc->seidx != 43) 775 mlc->seidx != 43)
706 printk(KERN_DEBUG PREFIX " + "); 776 printk(KERN_DEBUG PREFIX " + ");
707#endif 777#endif
708 }; 778 }
709 } 779 }
710 read_unlock(&hil_mlcs_lock); 780 read_unlock(&hil_mlcs_lock);
711} 781}
712 782
713/************************* Keepalive timer task *********************/ 783/************************* Keepalive timer task *********************/
714 784
715void hil_mlcs_timer (unsigned long data) { 785void hil_mlcs_timer(unsigned long data)
786{
716 hil_mlcs_probe = 1; 787 hil_mlcs_probe = 1;
717 tasklet_schedule(&hil_mlcs_tasklet); 788 tasklet_schedule(&hil_mlcs_tasklet);
718 /* Re-insert the periodic task. */ 789 /* Re-insert the periodic task. */
@@ -722,28 +793,25 @@ void hil_mlcs_timer (unsigned long data) {
722 793
723/******************** user/kernel context functions **********************/ 794/******************** user/kernel context functions **********************/
724 795
725static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { 796static int hil_mlc_serio_write(struct serio *serio, unsigned char c)
797{
726 struct hil_mlc_serio_map *map; 798 struct hil_mlc_serio_map *map;
727 struct hil_mlc *mlc; 799 struct hil_mlc *mlc;
728 struct serio_driver *drv; 800 struct serio_driver *drv;
729 uint8_t *idx, *last; 801 uint8_t *idx, *last;
730 802
731 map = serio->port_data; 803 map = serio->port_data;
732 if (map == NULL) { 804 BUG_ON(map == NULL);
733 BUG(); 805
734 return -EIO;
735 }
736 mlc = map->mlc; 806 mlc = map->mlc;
737 if (mlc == NULL) { 807 BUG_ON(mlc == NULL);
738 BUG(); 808
739 return -EIO; 809 mlc->serio_opacket[map->didx] |=
740 }
741 mlc->serio_opacket[map->didx] |=
742 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); 810 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx]));
743 811
744 if (mlc->serio_oidx[map->didx] >= 3) { 812 if (mlc->serio_oidx[map->didx] >= 3) {
745 /* for now only commands */ 813 /* for now only commands */
746 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) 814 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD))
747 return -EIO; 815 return -EIO;
748 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { 816 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) {
749 case HIL_CMD_IDD: 817 case HIL_CMD_IDD:
@@ -769,12 +837,11 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
769 return -EIO; 837 return -EIO;
770 emu: 838 emu:
771 drv = serio->drv; 839 drv = serio->drv;
772 if (drv == NULL) { 840 BUG_ON(drv == NULL);
773 BUG(); 841
774 return -EIO;
775 }
776 last = idx + 15; 842 last = idx + 15;
777 while ((last != idx) && (*last == 0)) last--; 843 while ((last != idx) && (*last == 0))
844 last--;
778 845
779 while (idx != last) { 846 while (idx != last) {
780 drv->interrupt(serio, 0, 0); 847 drv->interrupt(serio, 0, 0);
@@ -787,14 +854,15 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
787 drv->interrupt(serio, HIL_ERR_INT >> 16, 0); 854 drv->interrupt(serio, HIL_ERR_INT >> 16, 0);
788 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); 855 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0);
789 drv->interrupt(serio, *idx, 0); 856 drv->interrupt(serio, *idx, 0);
790 857
791 mlc->serio_oidx[map->didx] = 0; 858 mlc->serio_oidx[map->didx] = 0;
792 mlc->serio_opacket[map->didx] = 0; 859 mlc->serio_opacket[map->didx] = 0;
793 860
794 return 0; 861 return 0;
795} 862}
796 863
797static int hil_mlc_serio_open(struct serio *serio) { 864static int hil_mlc_serio_open(struct serio *serio)
865{
798 struct hil_mlc_serio_map *map; 866 struct hil_mlc_serio_map *map;
799 struct hil_mlc *mlc; 867 struct hil_mlc *mlc;
800 868
@@ -802,33 +870,24 @@ static int hil_mlc_serio_open(struct serio *serio) {
802 return -EBUSY; 870 return -EBUSY;
803 871
804 map = serio->port_data; 872 map = serio->port_data;
805 if (map == NULL) { 873 BUG_ON(map == NULL);
806 BUG(); 874
807 return -ENODEV;
808 }
809 mlc = map->mlc; 875 mlc = map->mlc;
810 if (mlc == NULL) { 876 BUG_ON(mlc == NULL);
811 BUG();
812 return -ENODEV;
813 }
814 877
815 return 0; 878 return 0;
816} 879}
817 880
818static void hil_mlc_serio_close(struct serio *serio) { 881static void hil_mlc_serio_close(struct serio *serio)
882{
819 struct hil_mlc_serio_map *map; 883 struct hil_mlc_serio_map *map;
820 struct hil_mlc *mlc; 884 struct hil_mlc *mlc;
821 885
822 map = serio->port_data; 886 map = serio->port_data;
823 if (map == NULL) { 887 BUG_ON(map == NULL);
824 BUG(); 888
825 return;
826 }
827 mlc = map->mlc; 889 mlc = map->mlc;
828 if (mlc == NULL) { 890 BUG_ON(mlc == NULL);
829 BUG();
830 return;
831 }
832 891
833 serio_set_drvdata(serio, NULL); 892 serio_set_drvdata(serio, NULL);
834 serio->drv = NULL; 893 serio->drv = NULL;
@@ -842,27 +901,26 @@ static const struct serio_device_id hil_mlc_serio_id = {
842 .id = SERIO_ANY, 901 .id = SERIO_ANY,
843}; 902};
844 903
845int hil_mlc_register(hil_mlc *mlc) { 904int hil_mlc_register(hil_mlc *mlc)
905{
846 int i; 906 int i;
847 unsigned long flags; 907 unsigned long flags;
848 908
849 if (mlc == NULL) { 909 BUG_ON(mlc == NULL);
850 return -EINVAL;
851 }
852 910
853 mlc->istarted = 0; 911 mlc->istarted = 0;
854 mlc->ostarted = 0; 912 mlc->ostarted = 0;
855 913
856 rwlock_init(&mlc->lock); 914 rwlock_init(&mlc->lock);
857 init_MUTEX(&(mlc->osem)); 915 init_MUTEX(&mlc->osem);
858 916
859 init_MUTEX(&(mlc->isem)); 917 init_MUTEX(&mlc->isem);
860 mlc->icount = -1; 918 mlc->icount = -1;
861 mlc->imatch = 0; 919 mlc->imatch = 0;
862 920
863 mlc->opercnt = 0; 921 mlc->opercnt = 0;
864 922
865 init_MUTEX_LOCKED(&(mlc->csem)); 923 init_MUTEX_LOCKED(&(mlc->csem));
866 924
867 hil_mlc_clear_di_scratch(mlc); 925 hil_mlc_clear_di_scratch(mlc);
868 hil_mlc_clear_di_map(mlc, 0); 926 hil_mlc_clear_di_map(mlc, 0);
@@ -897,19 +955,18 @@ int hil_mlc_register(hil_mlc *mlc) {
897 return 0; 955 return 0;
898} 956}
899 957
900int hil_mlc_unregister(hil_mlc *mlc) { 958int hil_mlc_unregister(hil_mlc *mlc)
959{
901 struct list_head *tmp; 960 struct list_head *tmp;
902 unsigned long flags; 961 unsigned long flags;
903 int i; 962 int i;
904 963
905 if (mlc == NULL) 964 BUG_ON(mlc == NULL);
906 return -EINVAL;
907 965
908 write_lock_irqsave(&hil_mlcs_lock, flags); 966 write_lock_irqsave(&hil_mlcs_lock, flags);
909 list_for_each(tmp, &hil_mlcs) { 967 list_for_each(tmp, &hil_mlcs)
910 if (list_entry(tmp, hil_mlc, list) == mlc) 968 if (list_entry(tmp, hil_mlc, list) == mlc)
911 goto found; 969 goto found;
912 }
913 970
914 /* not found in list */ 971 /* not found in list */
915 write_unlock_irqrestore(&hil_mlcs_lock, flags); 972 write_unlock_irqrestore(&hil_mlcs_lock, flags);
@@ -918,7 +975,7 @@ int hil_mlc_unregister(hil_mlc *mlc) {
918 975
919 found: 976 found:
920 list_del(tmp); 977 list_del(tmp);
921 write_unlock_irqrestore(&hil_mlcs_lock, flags); 978 write_unlock_irqrestore(&hil_mlcs_lock, flags);
922 979
923 for (i = 0; i < HIL_MLC_DEVMEM; i++) { 980 for (i = 0; i < HIL_MLC_DEVMEM; i++) {
924 serio_unregister_port(mlc->serio[i]); 981 serio_unregister_port(mlc->serio[i]);
@@ -942,7 +999,7 @@ static int __init hil_mlc_init(void)
942 999
943 return 0; 1000 return 0;
944} 1001}
945 1002
946static void __exit hil_mlc_exit(void) 1003static void __exit hil_mlc_exit(void)
947{ 1004{
948 del_timer(&hil_mlcs_kicker); 1005 del_timer(&hil_mlcs_kicker);
@@ -950,6 +1007,6 @@ static void __exit hil_mlc_exit(void)
950 tasklet_disable(&hil_mlcs_tasklet); 1007 tasklet_disable(&hil_mlcs_tasklet);
951 tasklet_kill(&hil_mlcs_tasklet); 1008 tasklet_kill(&hil_mlcs_tasklet);
952} 1009}
953 1010
954module_init(hil_mlc_init); 1011module_init(hil_mlc_init);
955module_exit(hil_mlc_exit); 1012module_exit(hil_mlc_exit);
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 353a8a18948b..31826e601fba 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
@@ -106,33 +106,39 @@ EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
106static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ 106static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
107 107
108/*************** primitives for use in any context *********************/ 108/*************** primitives for use in any context *********************/
109static inline uint8_t hp_sdc_status_in8 (void) { 109static inline uint8_t hp_sdc_status_in8(void)
110{
110 uint8_t status; 111 uint8_t status;
111 unsigned long flags; 112 unsigned long flags;
112 113
113 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 114 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
114 status = sdc_readb(hp_sdc.status_io); 115 status = sdc_readb(hp_sdc.status_io);
115 if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0; 116 if (!(status & HP_SDC_STATUS_IBF))
117 hp_sdc.ibf = 0;
116 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 118 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
117 119
118 return status; 120 return status;
119} 121}
120 122
121static inline uint8_t hp_sdc_data_in8 (void) { 123static inline uint8_t hp_sdc_data_in8(void)
122 return sdc_readb(hp_sdc.data_io); 124{
125 return sdc_readb(hp_sdc.data_io);
123} 126}
124 127
125static inline void hp_sdc_status_out8 (uint8_t val) { 128static inline void hp_sdc_status_out8(uint8_t val)
129{
126 unsigned long flags; 130 unsigned long flags;
127 131
128 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 132 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
129 hp_sdc.ibf = 1; 133 hp_sdc.ibf = 1;
130 if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff; 134 if ((val & 0xf0) == 0xe0)
135 hp_sdc.wi = 0xff;
131 sdc_writeb(val, hp_sdc.status_io); 136 sdc_writeb(val, hp_sdc.status_io);
132 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 137 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
133} 138}
134 139
135static inline void hp_sdc_data_out8 (uint8_t val) { 140static inline void hp_sdc_data_out8(uint8_t val)
141{
136 unsigned long flags; 142 unsigned long flags;
137 143
138 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 144 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
@@ -141,11 +147,12 @@ static inline void hp_sdc_data_out8 (uint8_t val) {
141 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 147 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
142} 148}
143 149
144/* Care must be taken to only invoke hp_sdc_spin_ibf when 150/* Care must be taken to only invoke hp_sdc_spin_ibf when
145 * absolutely needed, or in rarely invoked subroutines. 151 * absolutely needed, or in rarely invoked subroutines.
146 * Not only does it waste CPU cycles, it also wastes bus cycles. 152 * Not only does it waste CPU cycles, it also wastes bus cycles.
147 */ 153 */
148static inline void hp_sdc_spin_ibf(void) { 154static inline void hp_sdc_spin_ibf(void)
155{
149 unsigned long flags; 156 unsigned long flags;
150 rwlock_t *lock; 157 rwlock_t *lock;
151 158
@@ -158,19 +165,21 @@ static inline void hp_sdc_spin_ibf(void) {
158 } 165 }
159 read_unlock(lock); 166 read_unlock(lock);
160 write_lock(lock); 167 write_lock(lock);
161 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {}; 168 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF)
169 { }
162 hp_sdc.ibf = 0; 170 hp_sdc.ibf = 0;
163 write_unlock_irqrestore(lock, flags); 171 write_unlock_irqrestore(lock, flags);
164} 172}
165 173
166 174
167/************************ Interrupt context functions ************************/ 175/************************ Interrupt context functions ************************/
168static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { 176static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data)
177{
169 hp_sdc_transaction *curr; 178 hp_sdc_transaction *curr;
170 179
171 read_lock(&hp_sdc.rtq_lock); 180 read_lock(&hp_sdc.rtq_lock);
172 if (hp_sdc.rcurr < 0) { 181 if (hp_sdc.rcurr < 0) {
173 read_unlock(&hp_sdc.rtq_lock); 182 read_unlock(&hp_sdc.rtq_lock);
174 return; 183 return;
175 } 184 }
176 curr = hp_sdc.tq[hp_sdc.rcurr]; 185 curr = hp_sdc.tq[hp_sdc.rcurr];
@@ -183,25 +192,27 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
183 192
184 if (hp_sdc.rqty <= 0) { 193 if (hp_sdc.rqty <= 0) {
185 /* All data has been gathered. */ 194 /* All data has been gathered. */
186 if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) { 195 if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE)
187 if (curr->act.semaphore) up(curr->act.semaphore); 196 if (curr->act.semaphore)
188 } 197 up(curr->act.semaphore);
189 if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) { 198
199 if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK)
190 if (curr->act.irqhook) 200 if (curr->act.irqhook)
191 curr->act.irqhook(irq, dev_id, status, data); 201 curr->act.irqhook(irq, dev_id, status, data);
192 } 202
193 curr->actidx = curr->idx; 203 curr->actidx = curr->idx;
194 curr->idx++; 204 curr->idx++;
195 /* Return control of this transaction */ 205 /* Return control of this transaction */
196 write_lock(&hp_sdc.rtq_lock); 206 write_lock(&hp_sdc.rtq_lock);
197 hp_sdc.rcurr = -1; 207 hp_sdc.rcurr = -1;
198 hp_sdc.rqty = 0; 208 hp_sdc.rqty = 0;
199 write_unlock(&hp_sdc.rtq_lock); 209 write_unlock(&hp_sdc.rtq_lock);
200 tasklet_schedule(&hp_sdc.task); 210 tasklet_schedule(&hp_sdc.task);
201 } 211 }
202} 212}
203 213
204static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { 214static irqreturn_t hp_sdc_isr(int irq, void *dev_id)
215{
205 uint8_t status, data; 216 uint8_t status, data;
206 217
207 status = hp_sdc_status_in8(); 218 status = hp_sdc_status_in8();
@@ -209,67 +220,74 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
209 data = hp_sdc_data_in8(); 220 data = hp_sdc_data_in8();
210 221
211 /* For now we are ignoring these until we get the SDC to behave. */ 222 /* For now we are ignoring these until we get the SDC to behave. */
212 if (((status & 0xf1) == 0x51) && data == 0x82) { 223 if (((status & 0xf1) == 0x51) && data == 0x82)
213 return IRQ_HANDLED; 224 return IRQ_HANDLED;
214 }
215 225
216 switch(status & HP_SDC_STATUS_IRQMASK) { 226 switch (status & HP_SDC_STATUS_IRQMASK) {
217 case 0: /* This case is not documented. */ 227 case 0: /* This case is not documented. */
218 break; 228 break;
219 case HP_SDC_STATUS_USERTIMER: 229
220 case HP_SDC_STATUS_PERIODIC: 230 case HP_SDC_STATUS_USERTIMER:
221 case HP_SDC_STATUS_TIMER: 231 case HP_SDC_STATUS_PERIODIC:
232 case HP_SDC_STATUS_TIMER:
222 read_lock(&hp_sdc.hook_lock); 233 read_lock(&hp_sdc.hook_lock);
223 if (hp_sdc.timer != NULL) 234 if (hp_sdc.timer != NULL)
224 hp_sdc.timer(irq, dev_id, status, data); 235 hp_sdc.timer(irq, dev_id, status, data);
225 read_unlock(&hp_sdc.hook_lock); 236 read_unlock(&hp_sdc.hook_lock);
226 break; 237 break;
227 case HP_SDC_STATUS_REG: 238
239 case HP_SDC_STATUS_REG:
228 hp_sdc_take(irq, dev_id, status, data); 240 hp_sdc_take(irq, dev_id, status, data);
229 break; 241 break;
230 case HP_SDC_STATUS_HILCMD: 242
231 case HP_SDC_STATUS_HILDATA: 243 case HP_SDC_STATUS_HILCMD:
244 case HP_SDC_STATUS_HILDATA:
232 read_lock(&hp_sdc.hook_lock); 245 read_lock(&hp_sdc.hook_lock);
233 if (hp_sdc.hil != NULL) 246 if (hp_sdc.hil != NULL)
234 hp_sdc.hil(irq, dev_id, status, data); 247 hp_sdc.hil(irq, dev_id, status, data);
235 read_unlock(&hp_sdc.hook_lock); 248 read_unlock(&hp_sdc.hook_lock);
236 break; 249 break;
237 case HP_SDC_STATUS_PUP: 250
251 case HP_SDC_STATUS_PUP:
238 read_lock(&hp_sdc.hook_lock); 252 read_lock(&hp_sdc.hook_lock);
239 if (hp_sdc.pup != NULL) 253 if (hp_sdc.pup != NULL)
240 hp_sdc.pup(irq, dev_id, status, data); 254 hp_sdc.pup(irq, dev_id, status, data);
241 else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); 255 else
256 printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
242 read_unlock(&hp_sdc.hook_lock); 257 read_unlock(&hp_sdc.hook_lock);
243 break; 258 break;
244 default: 259
260 default:
245 read_lock(&hp_sdc.hook_lock); 261 read_lock(&hp_sdc.hook_lock);
246 if (hp_sdc.cooked != NULL) 262 if (hp_sdc.cooked != NULL)
247 hp_sdc.cooked(irq, dev_id, status, data); 263 hp_sdc.cooked(irq, dev_id, status, data);
248 read_unlock(&hp_sdc.hook_lock); 264 read_unlock(&hp_sdc.hook_lock);
249 break; 265 break;
250 } 266 }
267
251 return IRQ_HANDLED; 268 return IRQ_HANDLED;
252} 269}
253 270
254 271
255static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { 272static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id)
273{
256 int status; 274 int status;
257 275
258 status = hp_sdc_status_in8(); 276 status = hp_sdc_status_in8();
259 printk(KERN_WARNING PREFIX "NMI !\n"); 277 printk(KERN_WARNING PREFIX "NMI !\n");
260 278
261#if 0 279#if 0
262 if (status & HP_SDC_NMISTATUS_FHS) { 280 if (status & HP_SDC_NMISTATUS_FHS) {
263 read_lock(&hp_sdc.hook_lock); 281 read_lock(&hp_sdc.hook_lock);
264 if (hp_sdc.timer != NULL) 282 if (hp_sdc.timer != NULL)
265 hp_sdc.timer(irq, dev_id, status, 0); 283 hp_sdc.timer(irq, dev_id, status, 0);
266 read_unlock(&hp_sdc.hook_lock); 284 read_unlock(&hp_sdc.hook_lock);
267 } 285 } else {
268 else {
269 /* TODO: pass this on to the HIL handler, or do SAK here? */ 286 /* TODO: pass this on to the HIL handler, or do SAK here? */
270 printk(KERN_WARNING PREFIX "HIL NMI\n"); 287 printk(KERN_WARNING PREFIX "HIL NMI\n");
271 } 288 }
272#endif 289#endif
290
273 return IRQ_HANDLED; 291 return IRQ_HANDLED;
274} 292}
275 293
@@ -278,13 +296,17 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {
278 296
279unsigned long hp_sdc_put(void); 297unsigned long hp_sdc_put(void);
280 298
281static void hp_sdc_tasklet(unsigned long foo) { 299static void hp_sdc_tasklet(unsigned long foo)
282 300{
283 write_lock_irq(&hp_sdc.rtq_lock); 301 write_lock_irq(&hp_sdc.rtq_lock);
302
284 if (hp_sdc.rcurr >= 0) { 303 if (hp_sdc.rcurr >= 0) {
285 struct timeval tv; 304 struct timeval tv;
305
286 do_gettimeofday(&tv); 306 do_gettimeofday(&tv);
287 if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000; 307 if (tv.tv_sec > hp_sdc.rtv.tv_sec)
308 tv.tv_usec += USEC_PER_SEC;
309
288 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { 310 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
289 hp_sdc_transaction *curr; 311 hp_sdc_transaction *curr;
290 uint8_t tmp; 312 uint8_t tmp;
@@ -300,27 +322,29 @@ static void hp_sdc_tasklet(unsigned long foo) {
300 hp_sdc.rqty = 0; 322 hp_sdc.rqty = 0;
301 tmp = curr->seq[curr->actidx]; 323 tmp = curr->seq[curr->actidx];
302 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; 324 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
303 if(tmp & HP_SDC_ACT_SEMAPHORE) { 325 if (tmp & HP_SDC_ACT_SEMAPHORE)
304 if (curr->act.semaphore) 326 if (curr->act.semaphore)
305 up(curr->act.semaphore); 327 up(curr->act.semaphore);
306 } 328
307 if(tmp & HP_SDC_ACT_CALLBACK) { 329 if (tmp & HP_SDC_ACT_CALLBACK) {
308 /* Note this means that irqhooks may be called 330 /* Note this means that irqhooks may be called
309 * in tasklet/bh context. 331 * in tasklet/bh context.
310 */ 332 */
311 if (curr->act.irqhook) 333 if (curr->act.irqhook)
312 curr->act.irqhook(0, NULL, 0, 0); 334 curr->act.irqhook(0, NULL, 0, 0);
313 } 335 }
336
314 curr->actidx = curr->idx; 337 curr->actidx = curr->idx;
315 curr->idx++; 338 curr->idx++;
316 hp_sdc.rcurr = -1; 339 hp_sdc.rcurr = -1;
317 } 340 }
318 } 341 }
319 write_unlock_irq(&hp_sdc.rtq_lock); 342 write_unlock_irq(&hp_sdc.rtq_lock);
320 hp_sdc_put(); 343 hp_sdc_put();
321} 344}
322 345
323unsigned long hp_sdc_put(void) { 346unsigned long hp_sdc_put(void)
347{
324 hp_sdc_transaction *curr; 348 hp_sdc_transaction *curr;
325 uint8_t act; 349 uint8_t act;
326 int idx, curridx; 350 int idx, curridx;
@@ -333,19 +357,24 @@ unsigned long hp_sdc_put(void) {
333 requires output, so we skip to the administrativa. */ 357 requires output, so we skip to the administrativa. */
334 if (hp_sdc.ibf) { 358 if (hp_sdc.ibf) {
335 hp_sdc_status_in8(); 359 hp_sdc_status_in8();
336 if (hp_sdc.ibf) goto finish; 360 if (hp_sdc.ibf)
361 goto finish;
337 } 362 }
338 363
339 anew: 364 anew:
340 /* See if we are in the middle of a sequence. */ 365 /* See if we are in the middle of a sequence. */
341 if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0; 366 if (hp_sdc.wcurr < 0)
367 hp_sdc.wcurr = 0;
342 read_lock_irq(&hp_sdc.rtq_lock); 368 read_lock_irq(&hp_sdc.rtq_lock);
343 if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++; 369 if (hp_sdc.rcurr == hp_sdc.wcurr)
370 hp_sdc.wcurr++;
344 read_unlock_irq(&hp_sdc.rtq_lock); 371 read_unlock_irq(&hp_sdc.rtq_lock);
345 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 372 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
373 hp_sdc.wcurr = 0;
346 curridx = hp_sdc.wcurr; 374 curridx = hp_sdc.wcurr;
347 375
348 if (hp_sdc.tq[curridx] != NULL) goto start; 376 if (hp_sdc.tq[curridx] != NULL)
377 goto start;
349 378
350 while (++curridx != hp_sdc.wcurr) { 379 while (++curridx != hp_sdc.wcurr) {
351 if (curridx >= HP_SDC_QUEUE_LEN) { 380 if (curridx >= HP_SDC_QUEUE_LEN) {
@@ -358,7 +387,8 @@ unsigned long hp_sdc_put(void) {
358 continue; 387 continue;
359 } 388 }
360 read_unlock_irq(&hp_sdc.rtq_lock); 389 read_unlock_irq(&hp_sdc.rtq_lock);
361 if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */ 390 if (hp_sdc.tq[curridx] != NULL)
391 break; /* Found one. */
362 } 392 }
363 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ 393 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
364 curridx = -1; 394 curridx = -1;
@@ -374,7 +404,8 @@ unsigned long hp_sdc_put(void) {
374 goto finish; 404 goto finish;
375 } 405 }
376 406
377 if (hp_sdc.wcurr == -1) goto done; 407 if (hp_sdc.wcurr == -1)
408 goto done;
378 409
379 curr = hp_sdc.tq[curridx]; 410 curr = hp_sdc.tq[curridx];
380 idx = curr->actidx; 411 idx = curr->actidx;
@@ -383,20 +414,23 @@ unsigned long hp_sdc_put(void) {
383 hp_sdc.tq[curridx] = NULL; 414 hp_sdc.tq[curridx] = NULL;
384 /* Interleave outbound data between the transactions. */ 415 /* Interleave outbound data between the transactions. */
385 hp_sdc.wcurr++; 416 hp_sdc.wcurr++;
386 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 417 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
387 goto finish; 418 hp_sdc.wcurr = 0;
419 goto finish;
388 } 420 }
389 421
390 act = curr->seq[idx]; 422 act = curr->seq[idx];
391 idx++; 423 idx++;
392 424
393 if (curr->idx >= curr->endidx) { 425 if (curr->idx >= curr->endidx) {
394 if (act & HP_SDC_ACT_DEALLOC) kfree(curr); 426 if (act & HP_SDC_ACT_DEALLOC)
427 kfree(curr);
395 hp_sdc.tq[curridx] = NULL; 428 hp_sdc.tq[curridx] = NULL;
396 /* Interleave outbound data between the transactions. */ 429 /* Interleave outbound data between the transactions. */
397 hp_sdc.wcurr++; 430 hp_sdc.wcurr++;
398 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 431 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
399 goto finish; 432 hp_sdc.wcurr = 0;
433 goto finish;
400 } 434 }
401 435
402 while (act & HP_SDC_ACT_PRECMD) { 436 while (act & HP_SDC_ACT_PRECMD) {
@@ -409,9 +443,10 @@ unsigned long hp_sdc_put(void) {
409 curr->idx++; 443 curr->idx++;
410 /* act finished? */ 444 /* act finished? */
411 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) 445 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
412 goto actdone; 446 goto actdone;
413 /* skip quantity field if data-out sequence follows. */ 447 /* skip quantity field if data-out sequence follows. */
414 if (act & HP_SDC_ACT_DATAOUT) curr->idx++; 448 if (act & HP_SDC_ACT_DATAOUT)
449 curr->idx++;
415 goto finish; 450 goto finish;
416 } 451 }
417 if (act & HP_SDC_ACT_DATAOUT) { 452 if (act & HP_SDC_ACT_DATAOUT) {
@@ -423,15 +458,15 @@ unsigned long hp_sdc_put(void) {
423 hp_sdc_data_out8(curr->seq[curr->idx]); 458 hp_sdc_data_out8(curr->seq[curr->idx]);
424 curr->idx++; 459 curr->idx++;
425 /* act finished? */ 460 /* act finished? */
426 if ((curr->idx - idx >= qty) && 461 if (curr->idx - idx >= qty &&
427 ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)) 462 (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)
428 goto actdone; 463 goto actdone;
429 goto finish; 464 goto finish;
430 } 465 }
431 idx += qty; 466 idx += qty;
432 act &= ~HP_SDC_ACT_DATAOUT; 467 act &= ~HP_SDC_ACT_DATAOUT;
433 } 468 } else
434 else while (act & HP_SDC_ACT_DATAREG) { 469 while (act & HP_SDC_ACT_DATAREG) {
435 int mask; 470 int mask;
436 uint8_t w7[4]; 471 uint8_t w7[4];
437 472
@@ -445,26 +480,30 @@ unsigned long hp_sdc_put(void) {
445 act &= ~HP_SDC_ACT_DATAREG; 480 act &= ~HP_SDC_ACT_DATAREG;
446 break; 481 break;
447 } 482 }
448 483
449 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; 484 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
450 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; 485 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
451 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; 486 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
452 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; 487 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
453 488
454 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || 489 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
455 w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) { 490 w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) {
456 int i = 0; 491 int i = 0;
457 492
458 /* Need to point the write index register */ 493 /* Need to point the write index register */
459 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; 494 while (i < 4 && w7[i] == hp_sdc.r7[i])
495 i++;
496
460 if (i < 4) { 497 if (i < 4) {
461 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); 498 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
462 hp_sdc.wi = 0x70 + i; 499 hp_sdc.wi = 0x70 + i;
463 goto finish; 500 goto finish;
464 } 501 }
502
465 idx++; 503 idx++;
466 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) 504 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
467 goto actdone; 505 goto actdone;
506
468 curr->idx = idx; 507 curr->idx = idx;
469 act &= ~HP_SDC_ACT_DATAREG; 508 act &= ~HP_SDC_ACT_DATAREG;
470 break; 509 break;
@@ -476,12 +515,13 @@ unsigned long hp_sdc_put(void) {
476 { 515 {
477 int i = 0; 516 int i = 0;
478 517
479 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; 518 while ((i < 4) && w7[i] == hp_sdc.r7[i])
519 i++;
480 if (i >= 4) { 520 if (i >= 4) {
481 curr->idx = idx + 1; 521 curr->idx = idx + 1;
482 if ((act & HP_SDC_ACT_DURING) == 522 if ((act & HP_SDC_ACT_DURING) ==
483 HP_SDC_ACT_DATAREG) 523 HP_SDC_ACT_DATAREG)
484 goto actdone; 524 goto actdone;
485 } 525 }
486 } 526 }
487 goto finish; 527 goto finish;
@@ -497,7 +537,7 @@ unsigned long hp_sdc_put(void) {
497 537
498 538
499 if (act & HP_SDC_ACT_POSTCMD) { 539 if (act & HP_SDC_ACT_POSTCMD) {
500 uint8_t postcmd; 540 uint8_t postcmd;
501 541
502 /* curr->idx should == idx at this point. */ 542 /* curr->idx should == idx at this point. */
503 postcmd = curr->seq[idx]; 543 postcmd = curr->seq[idx];
@@ -505,12 +545,12 @@ unsigned long hp_sdc_put(void) {
505 if (act & HP_SDC_ACT_DATAIN) { 545 if (act & HP_SDC_ACT_DATAIN) {
506 546
507 /* Start a new read */ 547 /* Start a new read */
508 hp_sdc.rqty = curr->seq[curr->idx]; 548 hp_sdc.rqty = curr->seq[curr->idx];
509 do_gettimeofday(&hp_sdc.rtv); 549 do_gettimeofday(&hp_sdc.rtv);
510 curr->idx++; 550 curr->idx++;
511 /* Still need to lock here in case of spurious irq. */ 551 /* Still need to lock here in case of spurious irq. */
512 write_lock_irq(&hp_sdc.rtq_lock); 552 write_lock_irq(&hp_sdc.rtq_lock);
513 hp_sdc.rcurr = curridx; 553 hp_sdc.rcurr = curridx;
514 write_unlock_irq(&hp_sdc.rtq_lock); 554 write_unlock_irq(&hp_sdc.rtq_lock);
515 hp_sdc_status_out8(postcmd); 555 hp_sdc_status_out8(postcmd);
516 goto finish; 556 goto finish;
@@ -519,64 +559,69 @@ unsigned long hp_sdc_put(void) {
519 goto actdone; 559 goto actdone;
520 } 560 }
521 561
522actdone: 562 actdone:
523 if (act & HP_SDC_ACT_SEMAPHORE) { 563 if (act & HP_SDC_ACT_SEMAPHORE)
524 up(curr->act.semaphore); 564 up(curr->act.semaphore);
525 } 565 else if (act & HP_SDC_ACT_CALLBACK)
526 else if (act & HP_SDC_ACT_CALLBACK) {
527 curr->act.irqhook(0,NULL,0,0); 566 curr->act.irqhook(0,NULL,0,0);
528 } 567
529 if (curr->idx >= curr->endidx) { /* This transaction is over. */ 568 if (curr->idx >= curr->endidx) { /* This transaction is over. */
530 if (act & HP_SDC_ACT_DEALLOC) kfree(curr); 569 if (act & HP_SDC_ACT_DEALLOC)
570 kfree(curr);
531 hp_sdc.tq[curridx] = NULL; 571 hp_sdc.tq[curridx] = NULL;
532 } 572 } else {
533 else {
534 curr->actidx = idx + 1; 573 curr->actidx = idx + 1;
535 curr->idx = idx + 2; 574 curr->idx = idx + 2;
536 } 575 }
537 /* Interleave outbound data between the transactions. */ 576 /* Interleave outbound data between the transactions. */
538 hp_sdc.wcurr++; 577 hp_sdc.wcurr++;
539 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; 578 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
579 hp_sdc.wcurr = 0;
540 580
541 finish: 581 finish:
542 /* If by some quirk IBF has cleared and our ISR has run to 582 /* If by some quirk IBF has cleared and our ISR has run to
543 see that that has happened, do it all again. */ 583 see that that has happened, do it all again. */
544 if (!hp_sdc.ibf && limit++ < 20) goto anew; 584 if (!hp_sdc.ibf && limit++ < 20)
585 goto anew;
545 586
546 done: 587 done:
547 if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task); 588 if (hp_sdc.wcurr >= 0)
589 tasklet_schedule(&hp_sdc.task);
548 write_unlock(&hp_sdc.lock); 590 write_unlock(&hp_sdc.lock);
591
549 return 0; 592 return 0;
550} 593}
551 594
552/******* Functions called in either user or kernel context ****/ 595/******* Functions called in either user or kernel context ****/
553int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { 596int hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
597{
554 unsigned long flags; 598 unsigned long flags;
555 int i; 599 int i;
556 600
557 if (this == NULL) { 601 if (this == NULL) {
558 tasklet_schedule(&hp_sdc.task); 602 tasklet_schedule(&hp_sdc.task);
559 return -EINVAL; 603 return -EINVAL;
560 }; 604 }
561 605
562 write_lock_irqsave(&hp_sdc.lock, flags); 606 write_lock_irqsave(&hp_sdc.lock, flags);
563 607
564 /* Can't have same transaction on queue twice */ 608 /* Can't have same transaction on queue twice */
565 for (i=0; i < HP_SDC_QUEUE_LEN; i++) 609 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
566 if (hp_sdc.tq[i] == this) goto fail; 610 if (hp_sdc.tq[i] == this)
611 goto fail;
567 612
568 this->actidx = 0; 613 this->actidx = 0;
569 this->idx = 1; 614 this->idx = 1;
570 615
571 /* Search for empty slot */ 616 /* Search for empty slot */
572 for (i=0; i < HP_SDC_QUEUE_LEN; i++) { 617 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
573 if (hp_sdc.tq[i] == NULL) { 618 if (hp_sdc.tq[i] == NULL) {
574 hp_sdc.tq[i] = this; 619 hp_sdc.tq[i] = this;
575 write_unlock_irqrestore(&hp_sdc.lock, flags); 620 write_unlock_irqrestore(&hp_sdc.lock, flags);
576 tasklet_schedule(&hp_sdc.task); 621 tasklet_schedule(&hp_sdc.task);
577 return 0; 622 return 0;
578 } 623 }
579 } 624
580 write_unlock_irqrestore(&hp_sdc.lock, flags); 625 write_unlock_irqrestore(&hp_sdc.lock, flags);
581 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); 626 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
582 return -EBUSY; 627 return -EBUSY;
@@ -587,7 +632,8 @@ int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
587 return -EINVAL; 632 return -EINVAL;
588} 633}
589 634
590int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { 635int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
636{
591 unsigned long flags; 637 unsigned long flags;
592 int i; 638 int i;
593 639
@@ -595,8 +641,9 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
595 641
596 /* TODO: don't remove it if it's not done. */ 642 /* TODO: don't remove it if it's not done. */
597 643
598 for (i=0; i < HP_SDC_QUEUE_LEN; i++) 644 for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
599 if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL; 645 if (hp_sdc.tq[i] == this)
646 hp_sdc.tq[i] = NULL;
600 647
601 write_unlock_irqrestore(&hp_sdc.lock, flags); 648 write_unlock_irqrestore(&hp_sdc.lock, flags);
602 return 0; 649 return 0;
@@ -605,11 +652,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
605 652
606 653
607/********************** User context functions **************************/ 654/********************** User context functions **************************/
608int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { 655int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback)
609 656{
610 if (callback == NULL || hp_sdc.dev == NULL) { 657 if (callback == NULL || hp_sdc.dev == NULL)
611 return -EINVAL; 658 return -EINVAL;
612 } 659
613 write_lock_irq(&hp_sdc.hook_lock); 660 write_lock_irq(&hp_sdc.hook_lock);
614 if (hp_sdc.timer != NULL) { 661 if (hp_sdc.timer != NULL) {
615 write_unlock_irq(&hp_sdc.hook_lock); 662 write_unlock_irq(&hp_sdc.hook_lock);
@@ -629,11 +676,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {
629 return 0; 676 return 0;
630} 677}
631 678
632int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { 679int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback)
633 680{
634 if (callback == NULL || hp_sdc.dev == NULL) { 681 if (callback == NULL || hp_sdc.dev == NULL)
635 return -EINVAL; 682 return -EINVAL;
636 } 683
637 write_lock_irq(&hp_sdc.hook_lock); 684 write_lock_irq(&hp_sdc.hook_lock);
638 if (hp_sdc.hil != NULL) { 685 if (hp_sdc.hil != NULL) {
639 write_unlock_irq(&hp_sdc.hook_lock); 686 write_unlock_irq(&hp_sdc.hook_lock);
@@ -650,11 +697,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {
650 return 0; 697 return 0;
651} 698}
652 699
653int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { 700int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback)
654 701{
655 if (callback == NULL || hp_sdc.dev == NULL) { 702 if (callback == NULL || hp_sdc.dev == NULL)
656 return -EINVAL; 703 return -EINVAL;
657 } 704
658 write_lock_irq(&hp_sdc.hook_lock); 705 write_lock_irq(&hp_sdc.hook_lock);
659 if (hp_sdc.cooked != NULL) { 706 if (hp_sdc.cooked != NULL) {
660 write_unlock_irq(&hp_sdc.hook_lock); 707 write_unlock_irq(&hp_sdc.hook_lock);
@@ -672,9 +719,8 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {
672 return 0; 719 return 0;
673} 720}
674 721
675int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { 722int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback)
676 723{
677
678 write_lock_irq(&hp_sdc.hook_lock); 724 write_lock_irq(&hp_sdc.hook_lock);
679 if ((callback != hp_sdc.timer) || 725 if ((callback != hp_sdc.timer) ||
680 (hp_sdc.timer == NULL)) { 726 (hp_sdc.timer == NULL)) {
@@ -694,8 +740,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {
694 return 0; 740 return 0;
695} 741}
696 742
697int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { 743int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback)
698 744{
699 write_lock_irq(&hp_sdc.hook_lock); 745 write_lock_irq(&hp_sdc.hook_lock);
700 if ((callback != hp_sdc.hil) || 746 if ((callback != hp_sdc.hil) ||
701 (hp_sdc.hil == NULL)) { 747 (hp_sdc.hil == NULL)) {
@@ -715,8 +761,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {
715 return 0; 761 return 0;
716} 762}
717 763
718int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { 764int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback)
719 765{
720 write_lock_irq(&hp_sdc.hook_lock); 766 write_lock_irq(&hp_sdc.hook_lock);
721 if ((callback != hp_sdc.cooked) || 767 if ((callback != hp_sdc.cooked) ||
722 (hp_sdc.cooked == NULL)) { 768 (hp_sdc.cooked == NULL)) {
@@ -738,7 +784,8 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {
738 784
739/************************* Keepalive timer task *********************/ 785/************************* Keepalive timer task *********************/
740 786
741void hp_sdc_kicker (unsigned long data) { 787void hp_sdc_kicker (unsigned long data)
788{
742 tasklet_schedule(&hp_sdc.task); 789 tasklet_schedule(&hp_sdc.task);
743 /* Re-insert the periodic task. */ 790 /* Re-insert the periodic task. */
744 mod_timer(&hp_sdc.kicker, jiffies + HZ); 791 mod_timer(&hp_sdc.kicker, jiffies + HZ);
@@ -750,10 +797,10 @@ void hp_sdc_kicker (unsigned long data) {
750 797
751static const struct parisc_device_id hp_sdc_tbl[] = { 798static const struct parisc_device_id hp_sdc_tbl[] = {
752 { 799 {
753 .hw_type = HPHW_FIO, 800 .hw_type = HPHW_FIO,
754 .hversion_rev = HVERSION_REV_ANY_ID, 801 .hversion_rev = HVERSION_REV_ANY_ID,
755 .hversion = HVERSION_ANY_ID, 802 .hversion = HVERSION_ANY_ID,
756 .sversion = 0x73, 803 .sversion = 0x73,
757 }, 804 },
758 { 0, } 805 { 0, }
759}; 806};
@@ -772,16 +819,15 @@ static struct parisc_driver hp_sdc_driver = {
772 819
773static int __init hp_sdc_init(void) 820static int __init hp_sdc_init(void)
774{ 821{
775 int i;
776 char *errstr; 822 char *errstr;
777 hp_sdc_transaction t_sync; 823 hp_sdc_transaction t_sync;
778 uint8_t ts_sync[6]; 824 uint8_t ts_sync[6];
779 struct semaphore s_sync; 825 struct semaphore s_sync;
780 826
781 rwlock_init(&hp_sdc.lock); 827 rwlock_init(&hp_sdc.lock);
782 rwlock_init(&hp_sdc.ibf_lock); 828 rwlock_init(&hp_sdc.ibf_lock);
783 rwlock_init(&hp_sdc.rtq_lock); 829 rwlock_init(&hp_sdc.rtq_lock);
784 rwlock_init(&hp_sdc.hook_lock); 830 rwlock_init(&hp_sdc.hook_lock);
785 831
786 hp_sdc.timer = NULL; 832 hp_sdc.timer = NULL;
787 hp_sdc.hil = NULL; 833 hp_sdc.hil = NULL;
@@ -796,7 +842,8 @@ static int __init hp_sdc_init(void)
796 hp_sdc.r7[3] = 0xff; 842 hp_sdc.r7[3] = 0xff;
797 hp_sdc.ibf = 1; 843 hp_sdc.ibf = 1;
798 844
799 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL; 845 memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq));
846
800 hp_sdc.wcurr = -1; 847 hp_sdc.wcurr = -1;
801 hp_sdc.rcurr = -1; 848 hp_sdc.rcurr = -1;
802 hp_sdc.rqty = 0; 849 hp_sdc.rqty = 0;
@@ -804,27 +851,32 @@ static int __init hp_sdc_init(void)
804 hp_sdc.dev_err = -ENODEV; 851 hp_sdc.dev_err = -ENODEV;
805 852
806 errstr = "IO not found for"; 853 errstr = "IO not found for";
807 if (!hp_sdc.base_io) goto err0; 854 if (!hp_sdc.base_io)
855 goto err0;
808 856
809 errstr = "IRQ not found for"; 857 errstr = "IRQ not found for";
810 if (!hp_sdc.irq) goto err0; 858 if (!hp_sdc.irq)
859 goto err0;
811 860
812 hp_sdc.dev_err = -EBUSY; 861 hp_sdc.dev_err = -EBUSY;
813 862
814#if defined(__hppa__) 863#if defined(__hppa__)
815 errstr = "IO not available for"; 864 errstr = "IO not available for";
816 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0; 865 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
817#endif 866 goto err0;
867#endif
818 868
819 errstr = "IRQ not available for"; 869 errstr = "IRQ not available for";
820 if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, 870 if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
821 "HP SDC", &hp_sdc)) goto err1; 871 "HP SDC", &hp_sdc))
872 goto err1;
822 873
823 errstr = "NMI not available for"; 874 errstr = "NMI not available for";
824 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, 875 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED,
825 "HP SDC NMI", &hp_sdc)) goto err2; 876 "HP SDC NMI", &hp_sdc))
877 goto err2;
826 878
827 printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", 879 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); 880 (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
829 881
830 hp_sdc_status_in8(); 882 hp_sdc_status_in8();
@@ -858,9 +910,10 @@ static int __init hp_sdc_init(void)
858 err1: 910 err1:
859 release_region(hp_sdc.data_io, 2); 911 release_region(hp_sdc.data_io, 2);
860 err0: 912 err0:
861 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", 913 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); 914 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
863 hp_sdc.dev = NULL; 915 hp_sdc.dev = NULL;
916
864 return hp_sdc.dev_err; 917 return hp_sdc.dev_err;
865} 918}
866 919
@@ -868,8 +921,10 @@ static int __init hp_sdc_init(void)
868 921
869static int __init hp_sdc_init_hppa(struct parisc_device *d) 922static int __init hp_sdc_init_hppa(struct parisc_device *d)
870{ 923{
871 if (!d) return 1; 924 if (!d)
872 if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */ 925 return 1;
926 if (hp_sdc.dev != NULL)
927 return 1; /* We only expect one SDC */
873 928
874 hp_sdc.dev = d; 929 hp_sdc.dev = d;
875 hp_sdc.irq = d->irq; 930 hp_sdc.irq = d->irq;
@@ -906,10 +961,8 @@ static void hp_sdc_exit(void)
906 961
907 tasklet_kill(&hp_sdc.task); 962 tasklet_kill(&hp_sdc.task);
908 963
909/* release_region(hp_sdc.data_io, 2); */
910
911#if defined(__hppa__) 964#if defined(__hppa__)
912 if (unregister_parisc_driver(&hp_sdc_driver)) 965 if (unregister_parisc_driver(&hp_sdc_driver))
913 printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); 966 printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
914#endif 967#endif
915} 968}
@@ -923,7 +976,7 @@ static int __init hp_sdc_register(void)
923 mm_segment_t fs; 976 mm_segment_t fs;
924 unsigned char i; 977 unsigned char i;
925#endif 978#endif
926 979
927 hp_sdc.dev = NULL; 980 hp_sdc.dev = NULL;
928 hp_sdc.dev_err = 0; 981 hp_sdc.dev_err = 0;
929#if defined(__hppa__) 982#if defined(__hppa__)
@@ -960,8 +1013,8 @@ static int __init hp_sdc_register(void)
960 tq_init.seq = tq_init_seq; 1013 tq_init.seq = tq_init_seq;
961 tq_init.act.semaphore = &tq_init_sem; 1014 tq_init.act.semaphore = &tq_init_sem;
962 1015
963 tq_init_seq[0] = 1016 tq_init_seq[0] =
964 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 1017 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
965 tq_init_seq[1] = HP_SDC_CMD_READ_KCC; 1018 tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
966 tq_init_seq[2] = 1; 1019 tq_init_seq[2] = 1;
967 tq_init_seq[3] = 0; 1020 tq_init_seq[3] = 0;
@@ -979,13 +1032,13 @@ static int __init hp_sdc_register(void)
979 } 1032 }
980 hp_sdc.r11 = tq_init_seq[4]; 1033 hp_sdc.r11 = tq_init_seq[4];
981 if (hp_sdc.r11 & HP_SDC_CFG_NEW) { 1034 if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
982 char *str; 1035 const char *str;
983 printk(KERN_INFO PREFIX "New style SDC\n"); 1036 printk(KERN_INFO PREFIX "New style SDC\n");
984 tq_init_seq[1] = HP_SDC_CMD_READ_XTD; 1037 tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
985 tq_init.actidx = 0; 1038 tq_init.actidx = 0;
986 tq_init.idx = 1; 1039 tq_init.idx = 1;
987 down(&tq_init_sem); 1040 down(&tq_init_sem);
988 hp_sdc_enqueue_transaction(&tq_init); 1041 hp_sdc_enqueue_transaction(&tq_init);
989 down(&tq_init_sem); 1042 down(&tq_init_sem);
990 up(&tq_init_sem); 1043 up(&tq_init_sem);
991 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1044 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
@@ -995,15 +1048,13 @@ static int __init hp_sdc_register(void)
995 hp_sdc.r7e = tq_init_seq[4]; 1048 hp_sdc.r7e = tq_init_seq[4];
996 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) 1049 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
997 printk(KERN_INFO PREFIX "Revision: %s\n", str); 1050 printk(KERN_INFO PREFIX "Revision: %s\n", str);
998 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) { 1051 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER)
999 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); 1052 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
1000 } 1053 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"); 1054 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
1003 }
1004 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " 1055 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
1005 "on next firmware reset.\n"); 1056 "on next firmware reset.\n");
1006 tq_init_seq[0] = HP_SDC_ACT_PRECMD | 1057 tq_init_seq[0] = HP_SDC_ACT_PRECMD |
1007 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 1058 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
1008 tq_init_seq[1] = HP_SDC_CMD_SET_STR; 1059 tq_init_seq[1] = HP_SDC_CMD_SET_STR;
1009 tq_init_seq[2] = 1; 1060 tq_init_seq[2] = 1;
@@ -1012,14 +1063,12 @@ static int __init hp_sdc_register(void)
1012 tq_init.idx = 1; 1063 tq_init.idx = 1;
1013 tq_init.endidx = 4; 1064 tq_init.endidx = 4;
1014 down(&tq_init_sem); 1065 down(&tq_init_sem);
1015 hp_sdc_enqueue_transaction(&tq_init); 1066 hp_sdc_enqueue_transaction(&tq_init);
1016 down(&tq_init_sem); 1067 down(&tq_init_sem);
1017 up(&tq_init_sem); 1068 up(&tq_init_sem);
1018 } 1069 } else
1019 else { 1070 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"); 1071 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
1022 }
1023 1072
1024 return 0; 1073 return 0;
1025} 1074}
@@ -1027,13 +1076,13 @@ static int __init hp_sdc_register(void)
1027module_init(hp_sdc_register); 1076module_init(hp_sdc_register);
1028module_exit(hp_sdc_exit); 1077module_exit(hp_sdc_exit);
1029 1078
1030/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) 1079/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64)
1031 * cycles cycles-adj time 1080 * cycles cycles-adj time
1032 * between two consecutive mfctl(16)'s: 4 n/a 63ns 1081 * between two consecutive mfctl(16)'s: 4 n/a 63ns
1033 * hp_sdc_spin_ibf when idle: 119 115 1.7us 1082 * hp_sdc_spin_ibf when idle: 119 115 1.7us
1034 * gsc_writeb status register: 83 79 1.2us 1083 * gsc_writeb status register: 83 79 1.2us
1035 * IBF to clear after sending SET_IM: 6204 6006 93us 1084 * IBF to clear after sending SET_IM: 6204 6006 93us
1036 * IBF to clear after sending LOAD_RT: 4467 4352 68us 1085 * IBF to clear after sending LOAD_RT: 4467 4352 68us
1037 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us 1086 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us
1038 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us 1087 * 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 1088 * 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 1f131ff1f69e..cb0b28877e05 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,247 @@ 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)
144{
133 unsigned long flags; 145 unsigned long flags;
134 struct hp_sdc_mlc_priv_s *priv; 146 struct hp_sdc_mlc_priv_s *priv;
135 int rc = 2; 147 int rc = 2;
136 148
137 priv = mlc->priv; 149 priv = mlc->priv;
138 150
139 write_lock_irqsave(&(mlc->lock), flags); 151 write_lock_irqsave(&mlc->lock, flags);
140 152
141 /* Try to down the semaphore */ 153 /* Try to down the semaphore */
142 if (down_trylock(&(mlc->isem))) { 154 if (down_trylock(&mlc->isem)) {
143 struct timeval tv; 155 struct timeval tv;
144 if (priv->emtestmode) { 156 if (priv->emtestmode) {
145 mlc->ipacket[0] = 157 mlc->ipacket[0] =
146 HIL_ERR_INT | (mlc->opacket & 158 HIL_ERR_INT | (mlc->opacket &
147 (HIL_PKT_CMD | 159 (HIL_PKT_CMD |
148 HIL_PKT_ADDR_MASK | 160 HIL_PKT_ADDR_MASK |
149 HIL_PKT_DATA_MASK)); 161 HIL_PKT_DATA_MASK));
150 mlc->icount = 14; 162 mlc->icount = 14;
151 /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ 163 /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */
152 goto wasup; 164 goto wasup;
153 } 165 }
154 do_gettimeofday(&tv); 166 do_gettimeofday(&tv);
155 tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); 167 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec);
156 if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { 168 if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) {
157 /* printk("!%i %i", 169 /* printk("!%i %i",
158 tv.tv_usec - mlc->instart.tv_usec, 170 tv.tv_usec - mlc->instart.tv_usec,
159 mlc->intimeout); 171 mlc->intimeout);
160 */ 172 */
161 rc = 1; 173 rc = 1;
162 up(&(mlc->isem)); 174 up(&mlc->isem);
163 } 175 }
164 goto done; 176 goto done;
165 } 177 }
166 wasup: 178 wasup:
167 up(&(mlc->isem)); 179 up(&mlc->isem);
168 rc = 0; 180 rc = 0;
169 goto done; 181 goto done;
170 done: 182 done:
171 write_unlock_irqrestore(&(mlc->lock), flags); 183 write_unlock_irqrestore(&mlc->lock, flags);
172 return rc; 184 return rc;
173} 185}
174 186
175static int hp_sdc_mlc_cts (hil_mlc *mlc) { 187static int hp_sdc_mlc_cts(hil_mlc *mlc)
188{
176 struct hp_sdc_mlc_priv_s *priv; 189 struct hp_sdc_mlc_priv_s *priv;
177 unsigned long flags; 190 unsigned long flags;
178 191
179 priv = mlc->priv; 192 priv = mlc->priv;
180 193
181 write_lock_irqsave(&(mlc->lock), flags); 194 write_lock_irqsave(&mlc->lock, flags);
182 195
183 /* Try to down the semaphores -- they should be up. */ 196 /* Try to down the semaphores -- they should be up. */
184 if (down_trylock(&(mlc->isem))) { 197 BUG_ON(down_trylock(&mlc->isem));
185 BUG(); 198 BUG_ON(down_trylock(&mlc->osem));
186 goto busy;
187 }
188 if (down_trylock(&(mlc->osem))) {
189 BUG();
190 up(&(mlc->isem));
191 goto busy;
192 }
193 up(&(mlc->isem));
194 up(&(mlc->osem));
195 199
196 if (down_trylock(&(mlc->csem))) { 200 up(&mlc->isem);
197 if (priv->trans.act.semaphore != &(mlc->csem)) goto poll; 201 up(&mlc->osem);
198 goto busy; 202
203 if (down_trylock(&mlc->csem)) {
204 if (priv->trans.act.semaphore != &mlc->csem)
205 goto poll;
206 else
207 goto busy;
199 } 208 }
200 if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done; 209
210 if (!(priv->tseq[4] & HP_SDC_USE_LOOP))
211 goto done;
201 212
202 poll: 213 poll:
203 priv->trans.act.semaphore = &(mlc->csem); 214 priv->trans.act.semaphore = &mlc->csem;
204 priv->trans.actidx = 0; 215 priv->trans.actidx = 0;
205 priv->trans.idx = 1; 216 priv->trans.idx = 1;
206 priv->trans.endidx = 5; 217 priv->trans.endidx = 5;
207 priv->tseq[0] = 218 priv->tseq[0] =
208 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 219 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
209 priv->tseq[1] = HP_SDC_CMD_READ_USE; 220 priv->tseq[1] = HP_SDC_CMD_READ_USE;
210 priv->tseq[2] = 1; 221 priv->tseq[2] = 1;
211 priv->tseq[3] = 0; 222 priv->tseq[3] = 0;
212 priv->tseq[4] = 0; 223 priv->tseq[4] = 0;
213 hp_sdc_enqueue_transaction(&(priv->trans)); 224 hp_sdc_enqueue_transaction(&priv->trans);
214 busy: 225 busy:
215 write_unlock_irqrestore(&(mlc->lock), flags); 226 write_unlock_irqrestore(&mlc->lock, flags);
216 return 1; 227 return 1;
217 done: 228 done:
218 priv->trans.act.semaphore = &(mlc->osem); 229 priv->trans.act.semaphore = &mlc->osem;
219 up(&(mlc->csem)); 230 up(&mlc->csem);
220 write_unlock_irqrestore(&(mlc->lock), flags); 231 write_unlock_irqrestore(&mlc->lock, flags);
221 return 0; 232 return 0;
222} 233}
223 234
224static void hp_sdc_mlc_out (hil_mlc *mlc) { 235static void hp_sdc_mlc_out(hil_mlc *mlc)
236{
225 struct hp_sdc_mlc_priv_s *priv; 237 struct hp_sdc_mlc_priv_s *priv;
226 unsigned long flags; 238 unsigned long flags;
227 239
228 priv = mlc->priv; 240 priv = mlc->priv;
229 241
230 write_lock_irqsave(&(mlc->lock), flags); 242 write_lock_irqsave(&mlc->lock, flags);
231 243
232 /* Try to down the semaphore -- it should be up. */ 244 /* Try to down the semaphore -- it should be up. */
233 if (down_trylock(&(mlc->osem))) { 245 BUG_ON(down_trylock(&mlc->osem));
234 BUG();
235 goto done;
236 }
237 246
238 if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; 247 if (mlc->opacket & HIL_DO_ALTER_CTRL)
248 goto do_control;
239 249
240 do_data: 250 do_data:
241 if (priv->emtestmode) { 251 if (priv->emtestmode) {
242 up(&(mlc->osem)); 252 up(&mlc->osem);
243 goto done; 253 goto done;
244 } 254 }
245 /* Shouldn't be sending commands when loop may be busy */ 255 /* Shouldn't be sending commands when loop may be busy */
246 if (down_trylock(&(mlc->csem))) { 256 BUG_ON(down_trylock(&mlc->csem));
247 BUG(); 257 up(&mlc->csem);
248 goto done;
249 }
250 up(&(mlc->csem));
251 258
252 priv->trans.actidx = 0; 259 priv->trans.actidx = 0;
253 priv->trans.idx = 1; 260 priv->trans.idx = 1;
254 priv->trans.act.semaphore = &(mlc->osem); 261 priv->trans.act.semaphore = &mlc->osem;
255 priv->trans.endidx = 6; 262 priv->trans.endidx = 6;
256 priv->tseq[0] = 263 priv->tseq[0] =
257 HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; 264 HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE;
258 priv->tseq[1] = 0x7; 265 priv->tseq[1] = 0x7;
259 priv->tseq[2] = 266 priv->tseq[2] =
260 (mlc->opacket & 267 (mlc->opacket &
261 (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) 268 (HIL_PKT_ADDR_MASK | HIL_PKT_CMD))
262 >> HIL_PKT_ADDR_SHIFT; 269 >> HIL_PKT_ADDR_SHIFT;
263 priv->tseq[3] = 270 priv->tseq[3] =
264 (mlc->opacket & HIL_PKT_DATA_MASK) 271 (mlc->opacket & HIL_PKT_DATA_MASK)
265 >> HIL_PKT_DATA_SHIFT; 272 >> HIL_PKT_DATA_SHIFT;
266 priv->tseq[4] = 0; /* No timeout */ 273 priv->tseq[4] = 0; /* No timeout */
267 if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1; 274 if (priv->tseq[3] == HIL_CMD_DHR)
275 priv->tseq[4] = 1;
268 priv->tseq[5] = HP_SDC_CMD_DO_HIL; 276 priv->tseq[5] = HP_SDC_CMD_DO_HIL;
269 goto enqueue; 277 goto enqueue;
270 278
271 do_control: 279 do_control:
272 priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; 280 priv->emtestmode = mlc->opacket & HIL_CTRL_TEST;
273 281
274 /* we cannot emulate this, it should not be used. */ 282 /* we cannot emulate this, it should not be used. */
275 BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); 283 BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE);
276 284
277 if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only; 285 if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY)
278 if (mlc->opacket & HIL_CTRL_APE) { 286 goto control_only;
279 BUG(); /* Should not send command/data after engaging APE */ 287
280 goto done; 288 /* Should not send command/data after engaging APE */
281 } 289 BUG_ON(mlc->opacket & HIL_CTRL_APE);
282 /* Disengaging APE this way would not be valid either since 290
291 /* Disengaging APE this way would not be valid either since
283 * the loop must be allowed to idle. 292 * the loop must be allowed to idle.
284 * 293 *
285 * So, it works out that we really never actually send control 294 * So, it works out that we really never actually send control
286 * and data when using SDC, we just send the data. 295 * and data when using SDC, we just send the data.
287 */ 296 */
288 goto do_data; 297 goto do_data;
289 298
290 control_only: 299 control_only:
291 priv->trans.actidx = 0; 300 priv->trans.actidx = 0;
292 priv->trans.idx = 1; 301 priv->trans.idx = 1;
293 priv->trans.act.semaphore = &(mlc->osem); 302 priv->trans.act.semaphore = &mlc->osem;
294 priv->trans.endidx = 4; 303 priv->trans.endidx = 4;
295 priv->tseq[0] = 304 priv->tseq[0] =
296 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 305 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
297 priv->tseq[1] = HP_SDC_CMD_SET_LPC; 306 priv->tseq[1] = HP_SDC_CMD_SET_LPC;
298 priv->tseq[2] = 1; 307 priv->tseq[2] = 1;
299 // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; 308 /* priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; */
300 priv->tseq[3] = 0; 309 priv->tseq[3] = 0;
301 if (mlc->opacket & HIL_CTRL_APE) { 310 if (mlc->opacket & HIL_CTRL_APE) {
302 priv->tseq[3] |= HP_SDC_LPC_APE_IPF; 311 priv->tseq[3] |= HP_SDC_LPC_APE_IPF;
303 down_trylock(&(mlc->csem)); 312 down_trylock(&mlc->csem);
304 } 313 }
305 enqueue: 314 enqueue:
306 hp_sdc_enqueue_transaction(&(priv->trans)); 315 hp_sdc_enqueue_transaction(&priv->trans);
307 done: 316 done:
308 write_unlock_irqrestore(&(mlc->lock), flags); 317 write_unlock_irqrestore(&mlc->lock, flags);
309} 318}
310 319
311static int __init hp_sdc_mlc_init(void) 320static int __init hp_sdc_mlc_init(void)
@@ -316,14 +325,13 @@ static int __init hp_sdc_mlc_init(void)
316 325
317 hp_sdc_mlc_priv.emtestmode = 0; 326 hp_sdc_mlc_priv.emtestmode = 0;
318 hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; 327 hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq;
319 hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem); 328 hp_sdc_mlc_priv.trans.act.semaphore = &mlc->osem;
320 hp_sdc_mlc_priv.got5x = 0; 329 hp_sdc_mlc_priv.got5x = 0;
321 330
322 mlc->cts = &hp_sdc_mlc_cts; 331 mlc->cts = &hp_sdc_mlc_cts;
323 mlc->in = &hp_sdc_mlc_in; 332 mlc->in = &hp_sdc_mlc_in;
324 mlc->out = &hp_sdc_mlc_out; 333 mlc->out = &hp_sdc_mlc_out;
325 334 mlc->priv = &hp_sdc_mlc_priv;
326 mlc->priv = &hp_sdc_mlc_priv;
327 335
328 if (hil_mlc_register(mlc)) { 336 if (hil_mlc_register(mlc)) {
329 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); 337 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");
@@ -336,10 +344,9 @@ static int __init hp_sdc_mlc_init(void)
336 } 344 }
337 return 0; 345 return 0;
338 err1: 346 err1:
339 if (hil_mlc_unregister(mlc)) { 347 if (hil_mlc_unregister(mlc))
340 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"
341 "This is bad. Could cause an oops.\n"); 349 "This is bad. Could cause an oops.\n");
342 }
343 err0: 350 err0:
344 return -EBUSY; 351 return -EBUSY;
345} 352}
@@ -347,14 +354,14 @@ static int __init hp_sdc_mlc_init(void)
347static void __exit hp_sdc_mlc_exit(void) 354static void __exit hp_sdc_mlc_exit(void)
348{ 355{
349 hil_mlc *mlc = &hp_sdc_mlc; 356 hil_mlc *mlc = &hp_sdc_mlc;
350 if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) { 357
358 if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr))
351 printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" 359 printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n"
352 "This is bad. Could cause an oops.\n"); 360 "This is bad. Could cause an oops.\n");
353 } 361
354 if (hil_mlc_unregister(mlc)) { 362 if (hil_mlc_unregister(mlc))
355 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" 363 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
356 "This is bad. Could cause an oops.\n"); 364 "This is bad. Could cause an oops.\n");
357 }
358} 365}
359 366
360module_init(hp_sdc_mlc_init); 367module_init(hp_sdc_mlc_init);