diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/imm.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/imm.c')
-rw-r--r-- | drivers/scsi/imm.c | 1300 |
1 files changed, 1300 insertions, 0 deletions
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c new file mode 100644 index 000000000000..be7f2ca0183f --- /dev/null +++ b/drivers/scsi/imm.c | |||
@@ -0,0 +1,1300 @@ | |||
1 | /* imm.c -- low level driver for the IOMEGA MatchMaker | ||
2 | * parallel port SCSI host adapter. | ||
3 | * | ||
4 | * (The IMM is the embedded controller in the ZIP Plus drive.) | ||
5 | * | ||
6 | * Current Maintainer: David Campbell (Perth, Western Australia) | ||
7 | * campbell@torque.net | ||
8 | * | ||
9 | * My unoffical company acronym list is 21 pages long: | ||
10 | * FLA: Four letter acronym with built in facility for | ||
11 | * future expansion to five letters. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/blkdev.h> | ||
19 | #include <linux/parport.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | #include <asm/io.h> | ||
22 | |||
23 | #include <scsi/scsi.h> | ||
24 | #include <scsi/scsi_cmnd.h> | ||
25 | #include <scsi/scsi_device.h> | ||
26 | #include <scsi/scsi_host.h> | ||
27 | |||
28 | /* The following #define is to avoid a clash with hosts.c */ | ||
29 | #define IMM_PROBE_SPP 0x0001 | ||
30 | #define IMM_PROBE_PS2 0x0002 | ||
31 | #define IMM_PROBE_ECR 0x0010 | ||
32 | #define IMM_PROBE_EPP17 0x0100 | ||
33 | #define IMM_PROBE_EPP19 0x0200 | ||
34 | |||
35 | |||
36 | typedef struct { | ||
37 | struct pardevice *dev; /* Parport device entry */ | ||
38 | int base; /* Actual port address */ | ||
39 | int base_hi; /* Hi Base address for ECP-ISA chipset */ | ||
40 | int mode; /* Transfer mode */ | ||
41 | struct scsi_cmnd *cur_cmd; /* Current queued command */ | ||
42 | struct work_struct imm_tq; /* Polling interrupt stuff */ | ||
43 | unsigned long jstart; /* Jiffies at start */ | ||
44 | unsigned failed:1; /* Failure flag */ | ||
45 | unsigned dp:1; /* Data phase present */ | ||
46 | unsigned rd:1; /* Read data in data phase */ | ||
47 | unsigned wanted:1; /* Parport sharing busy flag */ | ||
48 | wait_queue_head_t *waiting; | ||
49 | struct Scsi_Host *host; | ||
50 | struct list_head list; | ||
51 | } imm_struct; | ||
52 | |||
53 | static void imm_reset_pulse(unsigned int base); | ||
54 | static int device_check(imm_struct *dev); | ||
55 | |||
56 | #include "imm.h" | ||
57 | |||
58 | static inline imm_struct *imm_dev(struct Scsi_Host *host) | ||
59 | { | ||
60 | return *(imm_struct **)&host->hostdata; | ||
61 | } | ||
62 | |||
63 | static DEFINE_SPINLOCK(arbitration_lock); | ||
64 | |||
65 | static void got_it(imm_struct *dev) | ||
66 | { | ||
67 | dev->base = dev->dev->port->base; | ||
68 | if (dev->cur_cmd) | ||
69 | dev->cur_cmd->SCp.phase = 1; | ||
70 | else | ||
71 | wake_up(dev->waiting); | ||
72 | } | ||
73 | |||
74 | static void imm_wakeup(void *ref) | ||
75 | { | ||
76 | imm_struct *dev = (imm_struct *) ref; | ||
77 | unsigned long flags; | ||
78 | |||
79 | spin_lock_irqsave(&arbitration_lock, flags); | ||
80 | if (dev->wanted) { | ||
81 | parport_claim(dev->dev); | ||
82 | got_it(dev); | ||
83 | dev->wanted = 0; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&arbitration_lock, flags); | ||
86 | } | ||
87 | |||
88 | static int imm_pb_claim(imm_struct *dev) | ||
89 | { | ||
90 | unsigned long flags; | ||
91 | int res = 1; | ||
92 | spin_lock_irqsave(&arbitration_lock, flags); | ||
93 | if (parport_claim(dev->dev) == 0) { | ||
94 | got_it(dev); | ||
95 | res = 0; | ||
96 | } | ||
97 | dev->wanted = res; | ||
98 | spin_unlock_irqrestore(&arbitration_lock, flags); | ||
99 | return res; | ||
100 | } | ||
101 | |||
102 | static void imm_pb_dismiss(imm_struct *dev) | ||
103 | { | ||
104 | unsigned long flags; | ||
105 | int wanted; | ||
106 | spin_lock_irqsave(&arbitration_lock, flags); | ||
107 | wanted = dev->wanted; | ||
108 | dev->wanted = 0; | ||
109 | spin_unlock_irqrestore(&arbitration_lock, flags); | ||
110 | if (!wanted) | ||
111 | parport_release(dev->dev); | ||
112 | } | ||
113 | |||
114 | static inline void imm_pb_release(imm_struct *dev) | ||
115 | { | ||
116 | parport_release(dev->dev); | ||
117 | } | ||
118 | |||
119 | /* This is to give the imm driver a way to modify the timings (and other | ||
120 | * parameters) by writing to the /proc/scsi/imm/0 file. | ||
121 | * Very simple method really... (Too simple, no error checking :( ) | ||
122 | * Reason: Kernel hackers HATE having to unload and reload modules for | ||
123 | * testing... | ||
124 | * Also gives a method to use a script to obtain optimum timings (TODO) | ||
125 | */ | ||
126 | static inline int imm_proc_write(imm_struct *dev, char *buffer, int length) | ||
127 | { | ||
128 | unsigned long x; | ||
129 | |||
130 | if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) { | ||
131 | x = simple_strtoul(buffer + 5, NULL, 0); | ||
132 | dev->mode = x; | ||
133 | return length; | ||
134 | } | ||
135 | printk("imm /proc: invalid variable\n"); | ||
136 | return (-EINVAL); | ||
137 | } | ||
138 | |||
139 | static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, | ||
140 | off_t offset, int length, int inout) | ||
141 | { | ||
142 | imm_struct *dev = imm_dev(host); | ||
143 | int len = 0; | ||
144 | |||
145 | if (inout) | ||
146 | return imm_proc_write(dev, buffer, length); | ||
147 | |||
148 | len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION); | ||
149 | len += | ||
150 | sprintf(buffer + len, "Parport : %s\n", | ||
151 | dev->dev->port->name); | ||
152 | len += | ||
153 | sprintf(buffer + len, "Mode : %s\n", | ||
154 | IMM_MODE_STRING[dev->mode]); | ||
155 | |||
156 | /* Request for beyond end of buffer */ | ||
157 | if (offset > len) | ||
158 | return 0; | ||
159 | |||
160 | *start = buffer + offset; | ||
161 | len -= offset; | ||
162 | if (len > length) | ||
163 | len = length; | ||
164 | return len; | ||
165 | } | ||
166 | |||
167 | #if IMM_DEBUG > 0 | ||
168 | #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\ | ||
169 | y, __FUNCTION__, __LINE__); imm_fail_func(x,y); | ||
170 | static inline void | ||
171 | imm_fail_func(imm_struct *dev, int error_code) | ||
172 | #else | ||
173 | static inline void | ||
174 | imm_fail(imm_struct *dev, int error_code) | ||
175 | #endif | ||
176 | { | ||
177 | /* If we fail a device then we trash status / message bytes */ | ||
178 | if (dev->cur_cmd) { | ||
179 | dev->cur_cmd->result = error_code << 16; | ||
180 | dev->failed = 1; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Wait for the high bit to be set. | ||
186 | * | ||
187 | * In principle, this could be tied to an interrupt, but the adapter | ||
188 | * doesn't appear to be designed to support interrupts. We spin on | ||
189 | * the 0x80 ready bit. | ||
190 | */ | ||
191 | static unsigned char imm_wait(imm_struct *dev) | ||
192 | { | ||
193 | int k; | ||
194 | unsigned short ppb = dev->base; | ||
195 | unsigned char r; | ||
196 | |||
197 | w_ctr(ppb, 0x0c); | ||
198 | |||
199 | k = IMM_SPIN_TMO; | ||
200 | do { | ||
201 | r = r_str(ppb); | ||
202 | k--; | ||
203 | udelay(1); | ||
204 | } | ||
205 | while (!(r & 0x80) && (k)); | ||
206 | |||
207 | /* | ||
208 | * STR register (LPT base+1) to SCSI mapping: | ||
209 | * | ||
210 | * STR imm imm | ||
211 | * =================================== | ||
212 | * 0x80 S_REQ S_REQ | ||
213 | * 0x40 !S_BSY (????) | ||
214 | * 0x20 !S_CD !S_CD | ||
215 | * 0x10 !S_IO !S_IO | ||
216 | * 0x08 (????) !S_BSY | ||
217 | * | ||
218 | * imm imm meaning | ||
219 | * ================================== | ||
220 | * 0xf0 0xb8 Bit mask | ||
221 | * 0xc0 0x88 ZIP wants more data | ||
222 | * 0xd0 0x98 ZIP wants to send more data | ||
223 | * 0xe0 0xa8 ZIP is expecting SCSI command data | ||
224 | * 0xf0 0xb8 end of transfer, ZIP is sending status | ||
225 | */ | ||
226 | w_ctr(ppb, 0x04); | ||
227 | if (k) | ||
228 | return (r & 0xb8); | ||
229 | |||
230 | /* Counter expired - Time out occurred */ | ||
231 | imm_fail(dev, DID_TIME_OUT); | ||
232 | printk("imm timeout in imm_wait\n"); | ||
233 | return 0; /* command timed out */ | ||
234 | } | ||
235 | |||
236 | static int imm_negotiate(imm_struct * tmp) | ||
237 | { | ||
238 | /* | ||
239 | * The following is supposedly the IEEE 1284-1994 negotiate | ||
240 | * sequence. I have yet to obtain a copy of the above standard | ||
241 | * so this is a bit of a guess... | ||
242 | * | ||
243 | * A fair chunk of this is based on the Linux parport implementation | ||
244 | * of IEEE 1284. | ||
245 | * | ||
246 | * Return 0 if data available | ||
247 | * 1 if no data available | ||
248 | */ | ||
249 | |||
250 | unsigned short base = tmp->base; | ||
251 | unsigned char a, mode; | ||
252 | |||
253 | switch (tmp->mode) { | ||
254 | case IMM_NIBBLE: | ||
255 | mode = 0x00; | ||
256 | break; | ||
257 | case IMM_PS2: | ||
258 | mode = 0x01; | ||
259 | break; | ||
260 | default: | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | w_ctr(base, 0x04); | ||
265 | udelay(5); | ||
266 | w_dtr(base, mode); | ||
267 | udelay(100); | ||
268 | w_ctr(base, 0x06); | ||
269 | udelay(5); | ||
270 | a = (r_str(base) & 0x20) ? 0 : 1; | ||
271 | udelay(5); | ||
272 | w_ctr(base, 0x07); | ||
273 | udelay(5); | ||
274 | w_ctr(base, 0x06); | ||
275 | |||
276 | if (a) { | ||
277 | printk | ||
278 | ("IMM: IEEE1284 negotiate indicates no data available.\n"); | ||
279 | imm_fail(tmp, DID_ERROR); | ||
280 | } | ||
281 | return a; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Clear EPP timeout bit. | ||
286 | */ | ||
287 | static inline void epp_reset(unsigned short ppb) | ||
288 | { | ||
289 | int i; | ||
290 | |||
291 | i = r_str(ppb); | ||
292 | w_str(ppb, i); | ||
293 | w_str(ppb, i & 0xfe); | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Wait for empty ECP fifo (if we are in ECP fifo mode only) | ||
298 | */ | ||
299 | static inline void ecp_sync(imm_struct *dev) | ||
300 | { | ||
301 | int i, ppb_hi = dev->base_hi; | ||
302 | |||
303 | if (ppb_hi == 0) | ||
304 | return; | ||
305 | |||
306 | if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */ | ||
307 | for (i = 0; i < 100; i++) { | ||
308 | if (r_ecr(ppb_hi) & 0x01) | ||
309 | return; | ||
310 | udelay(5); | ||
311 | } | ||
312 | printk("imm: ECP sync failed as data still present in FIFO.\n"); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static int imm_byte_out(unsigned short base, const char *buffer, int len) | ||
317 | { | ||
318 | int i; | ||
319 | |||
320 | w_ctr(base, 0x4); /* apparently a sane mode */ | ||
321 | for (i = len >> 1; i; i--) { | ||
322 | w_dtr(base, *buffer++); | ||
323 | w_ctr(base, 0x5); /* Drop STROBE low */ | ||
324 | w_dtr(base, *buffer++); | ||
325 | w_ctr(base, 0x0); /* STROBE high + INIT low */ | ||
326 | } | ||
327 | w_ctr(base, 0x4); /* apparently a sane mode */ | ||
328 | return 1; /* All went well - we hope! */ | ||
329 | } | ||
330 | |||
331 | static int imm_nibble_in(unsigned short base, char *buffer, int len) | ||
332 | { | ||
333 | unsigned char l; | ||
334 | int i; | ||
335 | |||
336 | /* | ||
337 | * The following is based on documented timing signals | ||
338 | */ | ||
339 | w_ctr(base, 0x4); | ||
340 | for (i = len; i; i--) { | ||
341 | w_ctr(base, 0x6); | ||
342 | l = (r_str(base) & 0xf0) >> 4; | ||
343 | w_ctr(base, 0x5); | ||
344 | *buffer++ = (r_str(base) & 0xf0) | l; | ||
345 | w_ctr(base, 0x4); | ||
346 | } | ||
347 | return 1; /* All went well - we hope! */ | ||
348 | } | ||
349 | |||
350 | static int imm_byte_in(unsigned short base, char *buffer, int len) | ||
351 | { | ||
352 | int i; | ||
353 | |||
354 | /* | ||
355 | * The following is based on documented timing signals | ||
356 | */ | ||
357 | w_ctr(base, 0x4); | ||
358 | for (i = len; i; i--) { | ||
359 | w_ctr(base, 0x26); | ||
360 | *buffer++ = r_dtr(base); | ||
361 | w_ctr(base, 0x25); | ||
362 | } | ||
363 | return 1; /* All went well - we hope! */ | ||
364 | } | ||
365 | |||
366 | static int imm_out(imm_struct *dev, char *buffer, int len) | ||
367 | { | ||
368 | unsigned short ppb = dev->base; | ||
369 | int r = imm_wait(dev); | ||
370 | |||
371 | /* | ||
372 | * Make sure that: | ||
373 | * a) the SCSI bus is BUSY (device still listening) | ||
374 | * b) the device is listening | ||
375 | */ | ||
376 | if ((r & 0x18) != 0x08) { | ||
377 | imm_fail(dev, DID_ERROR); | ||
378 | printk("IMM: returned SCSI status %2x\n", r); | ||
379 | return 0; | ||
380 | } | ||
381 | switch (dev->mode) { | ||
382 | case IMM_EPP_32: | ||
383 | case IMM_EPP_16: | ||
384 | case IMM_EPP_8: | ||
385 | epp_reset(ppb); | ||
386 | w_ctr(ppb, 0x4); | ||
387 | #ifdef CONFIG_SCSI_IZIP_EPP16 | ||
388 | if (!(((long) buffer | len) & 0x01)) | ||
389 | outsw(ppb + 4, buffer, len >> 1); | ||
390 | #else | ||
391 | if (!(((long) buffer | len) & 0x03)) | ||
392 | outsl(ppb + 4, buffer, len >> 2); | ||
393 | #endif | ||
394 | else | ||
395 | outsb(ppb + 4, buffer, len); | ||
396 | w_ctr(ppb, 0xc); | ||
397 | r = !(r_str(ppb) & 0x01); | ||
398 | w_ctr(ppb, 0xc); | ||
399 | ecp_sync(dev); | ||
400 | break; | ||
401 | |||
402 | case IMM_NIBBLE: | ||
403 | case IMM_PS2: | ||
404 | /* 8 bit output, with a loop */ | ||
405 | r = imm_byte_out(ppb, buffer, len); | ||
406 | break; | ||
407 | |||
408 | default: | ||
409 | printk("IMM: bug in imm_out()\n"); | ||
410 | r = 0; | ||
411 | } | ||
412 | return r; | ||
413 | } | ||
414 | |||
415 | static int imm_in(imm_struct *dev, char *buffer, int len) | ||
416 | { | ||
417 | unsigned short ppb = dev->base; | ||
418 | int r = imm_wait(dev); | ||
419 | |||
420 | /* | ||
421 | * Make sure that: | ||
422 | * a) the SCSI bus is BUSY (device still listening) | ||
423 | * b) the device is sending data | ||
424 | */ | ||
425 | if ((r & 0x18) != 0x18) { | ||
426 | imm_fail(dev, DID_ERROR); | ||
427 | return 0; | ||
428 | } | ||
429 | switch (dev->mode) { | ||
430 | case IMM_NIBBLE: | ||
431 | /* 4 bit input, with a loop */ | ||
432 | r = imm_nibble_in(ppb, buffer, len); | ||
433 | w_ctr(ppb, 0xc); | ||
434 | break; | ||
435 | |||
436 | case IMM_PS2: | ||
437 | /* 8 bit input, with a loop */ | ||
438 | r = imm_byte_in(ppb, buffer, len); | ||
439 | w_ctr(ppb, 0xc); | ||
440 | break; | ||
441 | |||
442 | case IMM_EPP_32: | ||
443 | case IMM_EPP_16: | ||
444 | case IMM_EPP_8: | ||
445 | epp_reset(ppb); | ||
446 | w_ctr(ppb, 0x24); | ||
447 | #ifdef CONFIG_SCSI_IZIP_EPP16 | ||
448 | if (!(((long) buffer | len) & 0x01)) | ||
449 | insw(ppb + 4, buffer, len >> 1); | ||
450 | #else | ||
451 | if (!(((long) buffer | len) & 0x03)) | ||
452 | insl(ppb + 4, buffer, len >> 2); | ||
453 | #endif | ||
454 | else | ||
455 | insb(ppb + 4, buffer, len); | ||
456 | w_ctr(ppb, 0x2c); | ||
457 | r = !(r_str(ppb) & 0x01); | ||
458 | w_ctr(ppb, 0x2c); | ||
459 | ecp_sync(dev); | ||
460 | break; | ||
461 | |||
462 | default: | ||
463 | printk("IMM: bug in imm_ins()\n"); | ||
464 | r = 0; | ||
465 | break; | ||
466 | } | ||
467 | return r; | ||
468 | } | ||
469 | |||
470 | static int imm_cpp(unsigned short ppb, unsigned char b) | ||
471 | { | ||
472 | /* | ||
473 | * Comments on udelay values refer to the | ||
474 | * Command Packet Protocol (CPP) timing diagram. | ||
475 | */ | ||
476 | |||
477 | unsigned char s1, s2, s3; | ||
478 | w_ctr(ppb, 0x0c); | ||
479 | udelay(2); /* 1 usec - infinite */ | ||
480 | w_dtr(ppb, 0xaa); | ||
481 | udelay(10); /* 7 usec - infinite */ | ||
482 | w_dtr(ppb, 0x55); | ||
483 | udelay(10); /* 7 usec - infinite */ | ||
484 | w_dtr(ppb, 0x00); | ||
485 | udelay(10); /* 7 usec - infinite */ | ||
486 | w_dtr(ppb, 0xff); | ||
487 | udelay(10); /* 7 usec - infinite */ | ||
488 | s1 = r_str(ppb) & 0xb8; | ||
489 | w_dtr(ppb, 0x87); | ||
490 | udelay(10); /* 7 usec - infinite */ | ||
491 | s2 = r_str(ppb) & 0xb8; | ||
492 | w_dtr(ppb, 0x78); | ||
493 | udelay(10); /* 7 usec - infinite */ | ||
494 | s3 = r_str(ppb) & 0x38; | ||
495 | /* | ||
496 | * Values for b are: | ||
497 | * 0000 00aa Assign address aa to current device | ||
498 | * 0010 00aa Select device aa in EPP Winbond mode | ||
499 | * 0010 10aa Select device aa in EPP mode | ||
500 | * 0011 xxxx Deselect all devices | ||
501 | * 0110 00aa Test device aa | ||
502 | * 1101 00aa Select device aa in ECP mode | ||
503 | * 1110 00aa Select device aa in Compatible mode | ||
504 | */ | ||
505 | w_dtr(ppb, b); | ||
506 | udelay(2); /* 1 usec - infinite */ | ||
507 | w_ctr(ppb, 0x0c); | ||
508 | udelay(10); /* 7 usec - infinite */ | ||
509 | w_ctr(ppb, 0x0d); | ||
510 | udelay(2); /* 1 usec - infinite */ | ||
511 | w_ctr(ppb, 0x0c); | ||
512 | udelay(10); /* 7 usec - infinite */ | ||
513 | w_dtr(ppb, 0xff); | ||
514 | udelay(10); /* 7 usec - infinite */ | ||
515 | |||
516 | /* | ||
517 | * The following table is electrical pin values. | ||
518 | * (BSY is inverted at the CTR register) | ||
519 | * | ||
520 | * BSY ACK POut SEL Fault | ||
521 | * S1 0 X 1 1 1 | ||
522 | * S2 1 X 0 1 1 | ||
523 | * S3 L X 1 1 S | ||
524 | * | ||
525 | * L => Last device in chain | ||
526 | * S => Selected | ||
527 | * | ||
528 | * Observered values for S1,S2,S3 are: | ||
529 | * Disconnect => f8/58/78 | ||
530 | * Connect => f8/58/70 | ||
531 | */ | ||
532 | if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30)) | ||
533 | return 1; /* Connected */ | ||
534 | if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38)) | ||
535 | return 0; /* Disconnected */ | ||
536 | |||
537 | return -1; /* No device present */ | ||
538 | } | ||
539 | |||
540 | static inline int imm_connect(imm_struct *dev, int flag) | ||
541 | { | ||
542 | unsigned short ppb = dev->base; | ||
543 | |||
544 | imm_cpp(ppb, 0xe0); /* Select device 0 in compatible mode */ | ||
545 | imm_cpp(ppb, 0x30); /* Disconnect all devices */ | ||
546 | |||
547 | if ((dev->mode == IMM_EPP_8) || | ||
548 | (dev->mode == IMM_EPP_16) || | ||
549 | (dev->mode == IMM_EPP_32)) | ||
550 | return imm_cpp(ppb, 0x28); /* Select device 0 in EPP mode */ | ||
551 | return imm_cpp(ppb, 0xe0); /* Select device 0 in compatible mode */ | ||
552 | } | ||
553 | |||
554 | static void imm_disconnect(imm_struct *dev) | ||
555 | { | ||
556 | imm_cpp(dev->base, 0x30); /* Disconnect all devices */ | ||
557 | } | ||
558 | |||
559 | static int imm_select(imm_struct *dev, int target) | ||
560 | { | ||
561 | int k; | ||
562 | unsigned short ppb = dev->base; | ||
563 | |||
564 | /* | ||
565 | * Firstly we want to make sure there is nothing | ||
566 | * holding onto the SCSI bus. | ||
567 | */ | ||
568 | w_ctr(ppb, 0xc); | ||
569 | |||
570 | k = IMM_SELECT_TMO; | ||
571 | do { | ||
572 | k--; | ||
573 | } while ((r_str(ppb) & 0x08) && (k)); | ||
574 | |||
575 | if (!k) | ||
576 | return 0; | ||
577 | |||
578 | /* | ||
579 | * Now assert the SCSI ID (HOST and TARGET) on the data bus | ||
580 | */ | ||
581 | w_ctr(ppb, 0x4); | ||
582 | w_dtr(ppb, 0x80 | (1 << target)); | ||
583 | udelay(1); | ||
584 | |||
585 | /* | ||
586 | * Deassert SELIN first followed by STROBE | ||
587 | */ | ||
588 | w_ctr(ppb, 0xc); | ||
589 | w_ctr(ppb, 0xd); | ||
590 | |||
591 | /* | ||
592 | * ACK should drop low while SELIN is deasserted. | ||
593 | * FAULT should drop low when the SCSI device latches the bus. | ||
594 | */ | ||
595 | k = IMM_SELECT_TMO; | ||
596 | do { | ||
597 | k--; | ||
598 | } | ||
599 | while (!(r_str(ppb) & 0x08) && (k)); | ||
600 | |||
601 | /* | ||
602 | * Place the interface back into a sane state (status mode) | ||
603 | */ | ||
604 | w_ctr(ppb, 0xc); | ||
605 | return (k) ? 1 : 0; | ||
606 | } | ||
607 | |||
608 | static int imm_init(imm_struct *dev) | ||
609 | { | ||
610 | if (imm_connect(dev, 0) != 1) | ||
611 | return -EIO; | ||
612 | imm_reset_pulse(dev->base); | ||
613 | udelay(1000); /* Delay to allow devices to settle */ | ||
614 | imm_disconnect(dev); | ||
615 | udelay(1000); /* Another delay to allow devices to settle */ | ||
616 | return device_check(dev); | ||
617 | } | ||
618 | |||
619 | static inline int imm_send_command(struct scsi_cmnd *cmd) | ||
620 | { | ||
621 | imm_struct *dev = imm_dev(cmd->device->host); | ||
622 | int k; | ||
623 | |||
624 | /* NOTE: IMM uses byte pairs */ | ||
625 | for (k = 0; k < cmd->cmd_len; k += 2) | ||
626 | if (!imm_out(dev, &cmd->cmnd[k], 2)) | ||
627 | return 0; | ||
628 | return 1; | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * The bulk flag enables some optimisations in the data transfer loops, | ||
633 | * it should be true for any command that transfers data in integral | ||
634 | * numbers of sectors. | ||
635 | * | ||
636 | * The driver appears to remain stable if we speed up the parallel port | ||
637 | * i/o in this function, but not elsewhere. | ||
638 | */ | ||
639 | static int imm_completion(struct scsi_cmnd *cmd) | ||
640 | { | ||
641 | /* Return codes: | ||
642 | * -1 Error | ||
643 | * 0 Told to schedule | ||
644 | * 1 Finished data transfer | ||
645 | */ | ||
646 | imm_struct *dev = imm_dev(cmd->device->host); | ||
647 | unsigned short ppb = dev->base; | ||
648 | unsigned long start_jiffies = jiffies; | ||
649 | |||
650 | unsigned char r, v; | ||
651 | int fast, bulk, status; | ||
652 | |||
653 | v = cmd->cmnd[0]; | ||
654 | bulk = ((v == READ_6) || | ||
655 | (v == READ_10) || (v == WRITE_6) || (v == WRITE_10)); | ||
656 | |||
657 | /* | ||
658 | * We only get here if the drive is ready to comunicate, | ||
659 | * hence no need for a full imm_wait. | ||
660 | */ | ||
661 | w_ctr(ppb, 0x0c); | ||
662 | r = (r_str(ppb) & 0xb8); | ||
663 | |||
664 | /* | ||
665 | * while (device is not ready to send status byte) | ||
666 | * loop; | ||
667 | */ | ||
668 | while (r != (unsigned char) 0xb8) { | ||
669 | /* | ||
670 | * If we have been running for more than a full timer tick | ||
671 | * then take a rest. | ||
672 | */ | ||
673 | if (time_after(jiffies, start_jiffies + 1)) | ||
674 | return 0; | ||
675 | |||
676 | /* | ||
677 | * FAIL if: | ||
678 | * a) Drive status is screwy (!ready && !present) | ||
679 | * b) Drive is requesting/sending more data than expected | ||
680 | */ | ||
681 | if (((r & 0x88) != 0x88) || (cmd->SCp.this_residual <= 0)) { | ||
682 | imm_fail(dev, DID_ERROR); | ||
683 | return -1; /* ERROR_RETURN */ | ||
684 | } | ||
685 | /* determine if we should use burst I/O */ | ||
686 | if (dev->rd == 0) { | ||
687 | fast = (bulk | ||
688 | && (cmd->SCp.this_residual >= | ||
689 | IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 2; | ||
690 | status = imm_out(dev, cmd->SCp.ptr, fast); | ||
691 | } else { | ||
692 | fast = (bulk | ||
693 | && (cmd->SCp.this_residual >= | ||
694 | IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 1; | ||
695 | status = imm_in(dev, cmd->SCp.ptr, fast); | ||
696 | } | ||
697 | |||
698 | cmd->SCp.ptr += fast; | ||
699 | cmd->SCp.this_residual -= fast; | ||
700 | |||
701 | if (!status) { | ||
702 | imm_fail(dev, DID_BUS_BUSY); | ||
703 | return -1; /* ERROR_RETURN */ | ||
704 | } | ||
705 | if (cmd->SCp.buffer && !cmd->SCp.this_residual) { | ||
706 | /* if scatter/gather, advance to the next segment */ | ||
707 | if (cmd->SCp.buffers_residual--) { | ||
708 | cmd->SCp.buffer++; | ||
709 | cmd->SCp.this_residual = | ||
710 | cmd->SCp.buffer->length; | ||
711 | cmd->SCp.ptr = | ||
712 | page_address(cmd->SCp.buffer->page) + | ||
713 | cmd->SCp.buffer->offset; | ||
714 | |||
715 | /* | ||
716 | * Make sure that we transfer even number of bytes | ||
717 | * otherwise it makes imm_byte_out() messy. | ||
718 | */ | ||
719 | if (cmd->SCp.this_residual & 0x01) | ||
720 | cmd->SCp.this_residual++; | ||
721 | } | ||
722 | } | ||
723 | /* Now check to see if the drive is ready to comunicate */ | ||
724 | w_ctr(ppb, 0x0c); | ||
725 | r = (r_str(ppb) & 0xb8); | ||
726 | |||
727 | /* If not, drop back down to the scheduler and wait a timer tick */ | ||
728 | if (!(r & 0x80)) | ||
729 | return 0; | ||
730 | } | ||
731 | return 1; /* FINISH_RETURN */ | ||
732 | } | ||
733 | |||
734 | /* | ||
735 | * Since the IMM itself doesn't generate interrupts, we use | ||
736 | * the scheduler's task queue to generate a stream of call-backs and | ||
737 | * complete the request when the drive is ready. | ||
738 | */ | ||
739 | static void imm_interrupt(void *data) | ||
740 | { | ||
741 | imm_struct *dev = (imm_struct *) data; | ||
742 | struct scsi_cmnd *cmd = dev->cur_cmd; | ||
743 | struct Scsi_Host *host = cmd->device->host; | ||
744 | unsigned long flags; | ||
745 | |||
746 | if (!cmd) { | ||
747 | printk("IMM: bug in imm_interrupt\n"); | ||
748 | return; | ||
749 | } | ||
750 | if (imm_engine(dev, cmd)) { | ||
751 | INIT_WORK(&dev->imm_tq, imm_interrupt, (void *) dev); | ||
752 | schedule_delayed_work(&dev->imm_tq, 1); | ||
753 | return; | ||
754 | } | ||
755 | /* Command must of completed hence it is safe to let go... */ | ||
756 | #if IMM_DEBUG > 0 | ||
757 | switch ((cmd->result >> 16) & 0xff) { | ||
758 | case DID_OK: | ||
759 | break; | ||
760 | case DID_NO_CONNECT: | ||
761 | printk("imm: no device at SCSI ID %i\n", cmd->device->id); | ||
762 | break; | ||
763 | case DID_BUS_BUSY: | ||
764 | printk("imm: BUS BUSY - EPP timeout detected\n"); | ||
765 | break; | ||
766 | case DID_TIME_OUT: | ||
767 | printk("imm: unknown timeout\n"); | ||
768 | break; | ||
769 | case DID_ABORT: | ||
770 | printk("imm: told to abort\n"); | ||
771 | break; | ||
772 | case DID_PARITY: | ||
773 | printk("imm: parity error (???)\n"); | ||
774 | break; | ||
775 | case DID_ERROR: | ||
776 | printk("imm: internal driver error\n"); | ||
777 | break; | ||
778 | case DID_RESET: | ||
779 | printk("imm: told to reset device\n"); | ||
780 | break; | ||
781 | case DID_BAD_INTR: | ||
782 | printk("imm: bad interrupt (???)\n"); | ||
783 | break; | ||
784 | default: | ||
785 | printk("imm: bad return code (%02x)\n", | ||
786 | (cmd->result >> 16) & 0xff); | ||
787 | } | ||
788 | #endif | ||
789 | |||
790 | if (cmd->SCp.phase > 1) | ||
791 | imm_disconnect(dev); | ||
792 | |||
793 | imm_pb_dismiss(dev); | ||
794 | |||
795 | spin_lock_irqsave(host->host_lock, flags); | ||
796 | dev->cur_cmd = NULL; | ||
797 | cmd->scsi_done(cmd); | ||
798 | spin_unlock_irqrestore(host->host_lock, flags); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd) | ||
803 | { | ||
804 | unsigned short ppb = dev->base; | ||
805 | unsigned char l = 0, h = 0; | ||
806 | int retv, x; | ||
807 | |||
808 | /* First check for any errors that may have occurred | ||
809 | * Here we check for internal errors | ||
810 | */ | ||
811 | if (dev->failed) | ||
812 | return 0; | ||
813 | |||
814 | switch (cmd->SCp.phase) { | ||
815 | case 0: /* Phase 0 - Waiting for parport */ | ||
816 | if (time_after(jiffies, dev->jstart + HZ)) { | ||
817 | /* | ||
818 | * We waited more than a second | ||
819 | * for parport to call us | ||
820 | */ | ||
821 | imm_fail(dev, DID_BUS_BUSY); | ||
822 | return 0; | ||
823 | } | ||
824 | return 1; /* wait until imm_wakeup claims parport */ | ||
825 | /* Phase 1 - Connected */ | ||
826 | case 1: | ||
827 | imm_connect(dev, CONNECT_EPP_MAYBE); | ||
828 | cmd->SCp.phase++; | ||
829 | |||
830 | /* Phase 2 - We are now talking to the scsi bus */ | ||
831 | case 2: | ||
832 | if (!imm_select(dev, cmd->device->id)) { | ||
833 | imm_fail(dev, DID_NO_CONNECT); | ||
834 | return 0; | ||
835 | } | ||
836 | cmd->SCp.phase++; | ||
837 | |||
838 | /* Phase 3 - Ready to accept a command */ | ||
839 | case 3: | ||
840 | w_ctr(ppb, 0x0c); | ||
841 | if (!(r_str(ppb) & 0x80)) | ||
842 | return 1; | ||
843 | |||
844 | if (!imm_send_command(cmd)) | ||
845 | return 0; | ||
846 | cmd->SCp.phase++; | ||
847 | |||
848 | /* Phase 4 - Setup scatter/gather buffers */ | ||
849 | case 4: | ||
850 | if (cmd->use_sg) { | ||
851 | /* if many buffers are available, start filling the first */ | ||
852 | cmd->SCp.buffer = | ||
853 | (struct scatterlist *) cmd->request_buffer; | ||
854 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | ||
855 | cmd->SCp.ptr = | ||
856 | page_address(cmd->SCp.buffer->page) + | ||
857 | cmd->SCp.buffer->offset; | ||
858 | } else { | ||
859 | /* else fill the only available buffer */ | ||
860 | cmd->SCp.buffer = NULL; | ||
861 | cmd->SCp.this_residual = cmd->request_bufflen; | ||
862 | cmd->SCp.ptr = cmd->request_buffer; | ||
863 | } | ||
864 | cmd->SCp.buffers_residual = cmd->use_sg - 1; | ||
865 | cmd->SCp.phase++; | ||
866 | if (cmd->SCp.this_residual & 0x01) | ||
867 | cmd->SCp.this_residual++; | ||
868 | /* Phase 5 - Pre-Data transfer stage */ | ||
869 | case 5: | ||
870 | /* Spin lock for BUSY */ | ||
871 | w_ctr(ppb, 0x0c); | ||
872 | if (!(r_str(ppb) & 0x80)) | ||
873 | return 1; | ||
874 | |||
875 | /* Require negotiation for read requests */ | ||
876 | x = (r_str(ppb) & 0xb8); | ||
877 | dev->rd = (x & 0x10) ? 1 : 0; | ||
878 | dev->dp = (x & 0x20) ? 0 : 1; | ||
879 | |||
880 | if ((dev->dp) && (dev->rd)) | ||
881 | if (imm_negotiate(dev)) | ||
882 | return 0; | ||
883 | cmd->SCp.phase++; | ||
884 | |||
885 | /* Phase 6 - Data transfer stage */ | ||
886 | case 6: | ||
887 | /* Spin lock for BUSY */ | ||
888 | w_ctr(ppb, 0x0c); | ||
889 | if (!(r_str(ppb) & 0x80)) | ||
890 | return 1; | ||
891 | |||
892 | if (dev->dp) { | ||
893 | retv = imm_completion(cmd); | ||
894 | if (retv == -1) | ||
895 | return 0; | ||
896 | if (retv == 0) | ||
897 | return 1; | ||
898 | } | ||
899 | cmd->SCp.phase++; | ||
900 | |||
901 | /* Phase 7 - Post data transfer stage */ | ||
902 | case 7: | ||
903 | if ((dev->dp) && (dev->rd)) { | ||
904 | if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { | ||
905 | w_ctr(ppb, 0x4); | ||
906 | w_ctr(ppb, 0xc); | ||
907 | w_ctr(ppb, 0xe); | ||
908 | w_ctr(ppb, 0x4); | ||
909 | } | ||
910 | } | ||
911 | cmd->SCp.phase++; | ||
912 | |||
913 | /* Phase 8 - Read status/message */ | ||
914 | case 8: | ||
915 | /* Check for data overrun */ | ||
916 | if (imm_wait(dev) != (unsigned char) 0xb8) { | ||
917 | imm_fail(dev, DID_ERROR); | ||
918 | return 0; | ||
919 | } | ||
920 | if (imm_negotiate(dev)) | ||
921 | return 0; | ||
922 | if (imm_in(dev, &l, 1)) { /* read status byte */ | ||
923 | /* Check for optional message byte */ | ||
924 | if (imm_wait(dev) == (unsigned char) 0xb8) | ||
925 | imm_in(dev, &h, 1); | ||
926 | cmd->result = (DID_OK << 16) + (l & STATUS_MASK); | ||
927 | } | ||
928 | if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { | ||
929 | w_ctr(ppb, 0x4); | ||
930 | w_ctr(ppb, 0xc); | ||
931 | w_ctr(ppb, 0xe); | ||
932 | w_ctr(ppb, 0x4); | ||
933 | } | ||
934 | return 0; /* Finished */ | ||
935 | break; | ||
936 | |||
937 | default: | ||
938 | printk("imm: Invalid scsi phase\n"); | ||
939 | } | ||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static int imm_queuecommand(struct scsi_cmnd *cmd, | ||
944 | void (*done)(struct scsi_cmnd *)) | ||
945 | { | ||
946 | imm_struct *dev = imm_dev(cmd->device->host); | ||
947 | |||
948 | if (dev->cur_cmd) { | ||
949 | printk("IMM: bug in imm_queuecommand\n"); | ||
950 | return 0; | ||
951 | } | ||
952 | dev->failed = 0; | ||
953 | dev->jstart = jiffies; | ||
954 | dev->cur_cmd = cmd; | ||
955 | cmd->scsi_done = done; | ||
956 | cmd->result = DID_ERROR << 16; /* default return code */ | ||
957 | cmd->SCp.phase = 0; /* bus free */ | ||
958 | |||
959 | INIT_WORK(&dev->imm_tq, imm_interrupt, dev); | ||
960 | schedule_work(&dev->imm_tq); | ||
961 | |||
962 | imm_pb_claim(dev); | ||
963 | |||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | /* | ||
968 | * Apparently the disk->capacity attribute is off by 1 sector | ||
969 | * for all disk drives. We add the one here, but it should really | ||
970 | * be done in sd.c. Even if it gets fixed there, this will still | ||
971 | * work. | ||
972 | */ | ||
973 | static int imm_biosparam(struct scsi_device *sdev, struct block_device *dev, | ||
974 | sector_t capacity, int ip[]) | ||
975 | { | ||
976 | ip[0] = 0x40; | ||
977 | ip[1] = 0x20; | ||
978 | ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]); | ||
979 | if (ip[2] > 1024) { | ||
980 | ip[0] = 0xff; | ||
981 | ip[1] = 0x3f; | ||
982 | ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]); | ||
983 | } | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int imm_abort(struct scsi_cmnd *cmd) | ||
988 | { | ||
989 | imm_struct *dev = imm_dev(cmd->device->host); | ||
990 | /* | ||
991 | * There is no method for aborting commands since Iomega | ||
992 | * have tied the SCSI_MESSAGE line high in the interface | ||
993 | */ | ||
994 | |||
995 | switch (cmd->SCp.phase) { | ||
996 | case 0: /* Do not have access to parport */ | ||
997 | case 1: /* Have not connected to interface */ | ||
998 | dev->cur_cmd = NULL; /* Forget the problem */ | ||
999 | return SUCCESS; | ||
1000 | break; | ||
1001 | default: /* SCSI command sent, can not abort */ | ||
1002 | return FAILED; | ||
1003 | break; | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | static void imm_reset_pulse(unsigned int base) | ||
1008 | { | ||
1009 | w_ctr(base, 0x04); | ||
1010 | w_dtr(base, 0x40); | ||
1011 | udelay(1); | ||
1012 | w_ctr(base, 0x0c); | ||
1013 | w_ctr(base, 0x0d); | ||
1014 | udelay(50); | ||
1015 | w_ctr(base, 0x0c); | ||
1016 | w_ctr(base, 0x04); | ||
1017 | } | ||
1018 | |||
1019 | static int imm_reset(struct scsi_cmnd *cmd) | ||
1020 | { | ||
1021 | imm_struct *dev = imm_dev(cmd->device->host); | ||
1022 | |||
1023 | if (cmd->SCp.phase) | ||
1024 | imm_disconnect(dev); | ||
1025 | dev->cur_cmd = NULL; /* Forget the problem */ | ||
1026 | |||
1027 | imm_connect(dev, CONNECT_NORMAL); | ||
1028 | imm_reset_pulse(dev->base); | ||
1029 | udelay(1000); /* device settle delay */ | ||
1030 | imm_disconnect(dev); | ||
1031 | udelay(1000); /* device settle delay */ | ||
1032 | return SUCCESS; | ||
1033 | } | ||
1034 | |||
1035 | static int device_check(imm_struct *dev) | ||
1036 | { | ||
1037 | /* This routine looks for a device and then attempts to use EPP | ||
1038 | to send a command. If all goes as planned then EPP is available. */ | ||
1039 | |||
1040 | static char cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1041 | int loop, old_mode, status, k, ppb = dev->base; | ||
1042 | unsigned char l; | ||
1043 | |||
1044 | old_mode = dev->mode; | ||
1045 | for (loop = 0; loop < 8; loop++) { | ||
1046 | /* Attempt to use EPP for Test Unit Ready */ | ||
1047 | if ((ppb & 0x0007) == 0x0000) | ||
1048 | dev->mode = IMM_EPP_32; | ||
1049 | |||
1050 | second_pass: | ||
1051 | imm_connect(dev, CONNECT_EPP_MAYBE); | ||
1052 | /* Select SCSI device */ | ||
1053 | if (!imm_select(dev, loop)) { | ||
1054 | imm_disconnect(dev); | ||
1055 | continue; | ||
1056 | } | ||
1057 | printk("imm: Found device at ID %i, Attempting to use %s\n", | ||
1058 | loop, IMM_MODE_STRING[dev->mode]); | ||
1059 | |||
1060 | /* Send SCSI command */ | ||
1061 | status = 1; | ||
1062 | w_ctr(ppb, 0x0c); | ||
1063 | for (l = 0; (l < 3) && (status); l++) | ||
1064 | status = imm_out(dev, &cmd[l << 1], 2); | ||
1065 | |||
1066 | if (!status) { | ||
1067 | imm_disconnect(dev); | ||
1068 | imm_connect(dev, CONNECT_EPP_MAYBE); | ||
1069 | imm_reset_pulse(dev->base); | ||
1070 | udelay(1000); | ||
1071 | imm_disconnect(dev); | ||
1072 | udelay(1000); | ||
1073 | if (dev->mode == IMM_EPP_32) { | ||
1074 | dev->mode = old_mode; | ||
1075 | goto second_pass; | ||
1076 | } | ||
1077 | printk("imm: Unable to establish communication\n"); | ||
1078 | return -EIO; | ||
1079 | } | ||
1080 | w_ctr(ppb, 0x0c); | ||
1081 | |||
1082 | k = 1000000; /* 1 Second */ | ||
1083 | do { | ||
1084 | l = r_str(ppb); | ||
1085 | k--; | ||
1086 | udelay(1); | ||
1087 | } while (!(l & 0x80) && (k)); | ||
1088 | |||
1089 | l &= 0xb8; | ||
1090 | |||
1091 | if (l != 0xb8) { | ||
1092 | imm_disconnect(dev); | ||
1093 | imm_connect(dev, CONNECT_EPP_MAYBE); | ||
1094 | imm_reset_pulse(dev->base); | ||
1095 | udelay(1000); | ||
1096 | imm_disconnect(dev); | ||
1097 | udelay(1000); | ||
1098 | if (dev->mode == IMM_EPP_32) { | ||
1099 | dev->mode = old_mode; | ||
1100 | goto second_pass; | ||
1101 | } | ||
1102 | printk | ||
1103 | ("imm: Unable to establish communication\n"); | ||
1104 | return -EIO; | ||
1105 | } | ||
1106 | imm_disconnect(dev); | ||
1107 | printk | ||
1108 | ("imm: Communication established at 0x%x with ID %i using %s\n", | ||
1109 | ppb, loop, IMM_MODE_STRING[dev->mode]); | ||
1110 | imm_connect(dev, CONNECT_EPP_MAYBE); | ||
1111 | imm_reset_pulse(dev->base); | ||
1112 | udelay(1000); | ||
1113 | imm_disconnect(dev); | ||
1114 | udelay(1000); | ||
1115 | return 0; | ||
1116 | } | ||
1117 | printk("imm: No devices found\n"); | ||
1118 | return -ENODEV; | ||
1119 | } | ||
1120 | |||
1121 | static int imm_adjust_queue(struct scsi_device *device) | ||
1122 | { | ||
1123 | blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); | ||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
1127 | static struct scsi_host_template imm_template = { | ||
1128 | .module = THIS_MODULE, | ||
1129 | .proc_name = "imm", | ||
1130 | .proc_info = imm_proc_info, | ||
1131 | .name = "Iomega VPI2 (imm) interface", | ||
1132 | .queuecommand = imm_queuecommand, | ||
1133 | .eh_abort_handler = imm_abort, | ||
1134 | .eh_bus_reset_handler = imm_reset, | ||
1135 | .eh_host_reset_handler = imm_reset, | ||
1136 | .bios_param = imm_biosparam, | ||
1137 | .this_id = 7, | ||
1138 | .sg_tablesize = SG_ALL, | ||
1139 | .cmd_per_lun = 1, | ||
1140 | .use_clustering = ENABLE_CLUSTERING, | ||
1141 | .can_queue = 1, | ||
1142 | .slave_alloc = imm_adjust_queue, | ||
1143 | .unchecked_isa_dma = 1, /* imm cannot deal with highmem, so | ||
1144 | * this is an easy trick to ensure | ||
1145 | * all io pages for this host reside | ||
1146 | * in low memory */ | ||
1147 | }; | ||
1148 | |||
1149 | /*************************************************************************** | ||
1150 | * Parallel port probing routines * | ||
1151 | ***************************************************************************/ | ||
1152 | |||
1153 | static LIST_HEAD(imm_hosts); | ||
1154 | |||
1155 | static int __imm_attach(struct parport *pb) | ||
1156 | { | ||
1157 | struct Scsi_Host *host; | ||
1158 | imm_struct *dev; | ||
1159 | DECLARE_WAIT_QUEUE_HEAD(waiting); | ||
1160 | DEFINE_WAIT(wait); | ||
1161 | int ports; | ||
1162 | int modes, ppb; | ||
1163 | int err = -ENOMEM; | ||
1164 | |||
1165 | init_waitqueue_head(&waiting); | ||
1166 | |||
1167 | dev = kmalloc(sizeof(imm_struct), GFP_KERNEL); | ||
1168 | if (!dev) | ||
1169 | return -ENOMEM; | ||
1170 | |||
1171 | memset(dev, 0, sizeof(imm_struct)); | ||
1172 | |||
1173 | dev->base = -1; | ||
1174 | dev->mode = IMM_AUTODETECT; | ||
1175 | INIT_LIST_HEAD(&dev->list); | ||
1176 | |||
1177 | dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup, | ||
1178 | NULL, 0, dev); | ||
1179 | |||
1180 | if (!dev->dev) | ||
1181 | goto out; | ||
1182 | |||
1183 | |||
1184 | /* Claim the bus so it remembers what we do to the control | ||
1185 | * registers. [ CTR and ECP ] | ||
1186 | */ | ||
1187 | err = -EBUSY; | ||
1188 | dev->waiting = &waiting; | ||
1189 | prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE); | ||
1190 | if (imm_pb_claim(dev)) | ||
1191 | schedule_timeout(3 * HZ); | ||
1192 | if (dev->wanted) { | ||
1193 | printk(KERN_ERR "imm%d: failed to claim parport because " | ||
1194 | "a pardevice is owning the port for too long " | ||
1195 | "time!\n", pb->number); | ||
1196 | imm_pb_dismiss(dev); | ||
1197 | dev->waiting = NULL; | ||
1198 | finish_wait(&waiting, &wait); | ||
1199 | goto out1; | ||
1200 | } | ||
1201 | dev->waiting = NULL; | ||
1202 | finish_wait(&waiting, &wait); | ||
1203 | ppb = dev->base = dev->dev->port->base; | ||
1204 | dev->base_hi = dev->dev->port->base_hi; | ||
1205 | w_ctr(ppb, 0x0c); | ||
1206 | modes = dev->dev->port->modes; | ||
1207 | |||
1208 | /* Mode detection works up the chain of speed | ||
1209 | * This avoids a nasty if-then-else-if-... tree | ||
1210 | */ | ||
1211 | dev->mode = IMM_NIBBLE; | ||
1212 | |||
1213 | if (modes & PARPORT_MODE_TRISTATE) | ||
1214 | dev->mode = IMM_PS2; | ||
1215 | |||
1216 | /* Done configuration */ | ||
1217 | |||
1218 | err = imm_init(dev); | ||
1219 | |||
1220 | imm_pb_release(dev); | ||
1221 | |||
1222 | if (err) | ||
1223 | goto out1; | ||
1224 | |||
1225 | /* now the glue ... */ | ||
1226 | if (dev->mode == IMM_NIBBLE || dev->mode == IMM_PS2) | ||
1227 | ports = 3; | ||
1228 | else | ||
1229 | ports = 8; | ||
1230 | |||
1231 | INIT_WORK(&dev->imm_tq, imm_interrupt, dev); | ||
1232 | |||
1233 | err = -ENOMEM; | ||
1234 | host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); | ||
1235 | if (!host) | ||
1236 | goto out1; | ||
1237 | host->io_port = pb->base; | ||
1238 | host->n_io_port = ports; | ||
1239 | host->dma_channel = -1; | ||
1240 | host->unique_id = pb->number; | ||
1241 | *(imm_struct **)&host->hostdata = dev; | ||
1242 | dev->host = host; | ||
1243 | list_add_tail(&dev->list, &imm_hosts); | ||
1244 | err = scsi_add_host(host, NULL); | ||
1245 | if (err) | ||
1246 | goto out2; | ||
1247 | scsi_scan_host(host); | ||
1248 | return 0; | ||
1249 | |||
1250 | out2: | ||
1251 | list_del_init(&dev->list); | ||
1252 | scsi_host_put(host); | ||
1253 | out1: | ||
1254 | parport_unregister_device(dev->dev); | ||
1255 | out: | ||
1256 | kfree(dev); | ||
1257 | return err; | ||
1258 | } | ||
1259 | |||
1260 | static void imm_attach(struct parport *pb) | ||
1261 | { | ||
1262 | __imm_attach(pb); | ||
1263 | } | ||
1264 | |||
1265 | static void imm_detach(struct parport *pb) | ||
1266 | { | ||
1267 | imm_struct *dev; | ||
1268 | list_for_each_entry(dev, &imm_hosts, list) { | ||
1269 | if (dev->dev->port == pb) { | ||
1270 | list_del_init(&dev->list); | ||
1271 | scsi_remove_host(dev->host); | ||
1272 | scsi_host_put(dev->host); | ||
1273 | parport_unregister_device(dev->dev); | ||
1274 | kfree(dev); | ||
1275 | break; | ||
1276 | } | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | static struct parport_driver imm_driver = { | ||
1281 | .name = "imm", | ||
1282 | .attach = imm_attach, | ||
1283 | .detach = imm_detach, | ||
1284 | }; | ||
1285 | |||
1286 | static int __init imm_driver_init(void) | ||
1287 | { | ||
1288 | printk("imm: Version %s\n", IMM_VERSION); | ||
1289 | return parport_register_driver(&imm_driver); | ||
1290 | } | ||
1291 | |||
1292 | static void __exit imm_driver_exit(void) | ||
1293 | { | ||
1294 | parport_unregister_driver(&imm_driver); | ||
1295 | } | ||
1296 | |||
1297 | module_init(imm_driver_init); | ||
1298 | module_exit(imm_driver_exit); | ||
1299 | |||
1300 | MODULE_LICENSE("GPL"); | ||