File: | obj-scan-build/../linux/src/drivers/scsi/seagate.c |
Location: | line 1012, column 2 |
Description: | Value stored to 'underflow' is never read |
1 | /* |
2 | * seagate.c Copyright (C) 1992, 1993 Drew Eckhardt |
3 | * low level scsi driver for ST01/ST02, Future Domain TMC-885, |
4 | * TMC-950 by |
5 | * |
6 | * Drew Eckhardt |
7 | * |
8 | * <drew@colorado.edu> |
9 | * |
10 | * Note : TMC-880 boards don't work because they have two bits in |
11 | * the status register flipped, I'll fix this "RSN" |
12 | * |
13 | * This card does all the I/O via memory mapped I/O, so there is no need |
14 | * to check or allocate a region of the I/O address space. |
15 | */ |
16 | |
17 | /* |
18 | * Configuration : |
19 | * To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE |
20 | * -DIRQ will override the default of 5. |
21 | * Note: You can now set these options from the kernel's "command line". |
22 | * The syntax is: |
23 | * |
24 | * st0x=ADDRESS,IRQ (for a Seagate controller) |
25 | * or: |
26 | * tmc8xx=ADDRESS,IRQ (for a TMC-8xx or TMC-950 controller) |
27 | * eg: |
28 | * tmc8xx=0xC8000,15 |
29 | * |
30 | * will configure the driver for a TMC-8xx style controller using IRQ 15 |
31 | * with a base address of 0xC8000. |
32 | * |
33 | * -DFAST or -DFAST32 will use blind transfers where possible |
34 | * |
35 | * -DARBITRATE will cause the host adapter to arbitrate for the |
36 | * bus for better SCSI-II compatibility, rather than just |
37 | * waiting for BUS FREE and then doing its thing. Should |
38 | * let us do one command per Lun when I integrate my |
39 | * reorganization changes into the distribution sources. |
40 | * |
41 | * -DSLOW_HANDSHAKE will allow compatibility with broken devices that don't |
42 | * handshake fast enough (ie, some CD ROM's) for the Seagate |
43 | * code. |
44 | * |
45 | * -DSLOW_RATE=x, x some number will let you specify a default |
46 | * transfer rate if handshaking isn't working correctly. |
47 | */ |
48 | |
49 | #ifdef MACH1 |
50 | #define ARBITRATE |
51 | #define SLOW_HANDSHAKE |
52 | #define FAST32 |
53 | #endif |
54 | |
55 | #include <linux/module.h> |
56 | |
57 | #include <asm/io.h> |
58 | #include <asm/system.h> |
59 | #include <linux/signal.h> |
60 | #include <linux/sched.h> |
61 | #include <linux/string.h> |
62 | #include <linux/config.h> |
63 | #include <linux/proc_fs.h> |
64 | |
65 | #include <linux/blk.h> |
66 | #include "scsi.h" |
67 | #include "hosts.h" |
68 | #include "seagate.h" |
69 | #include "constants.h" |
70 | #include<linux/stat.h> |
71 | |
72 | struct proc_dir_entry proc_scsi_seagate = { |
73 | PROC_SCSI_SEAGATE, 7, "seagate", |
74 | S_IFDIR0040000 | S_IRUGO(00400|00040|00004) | S_IXUGO(00100|00010|00001), 2 |
75 | }; |
76 | |
77 | |
78 | #ifndef IRQ5 |
79 | #define IRQ5 5 |
80 | #endif |
81 | |
82 | #if (defined(FAST32) && !defined(FAST)) |
83 | #define FAST |
84 | #endif |
85 | |
86 | #if defined(SLOW_RATE50) && !defined(SLOW_HANDSHAKE) |
87 | #define SLOW_HANDSHAKE |
88 | #endif |
89 | |
90 | #if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE50) |
91 | #define SLOW_RATE50 50 |
92 | #endif |
93 | |
94 | |
95 | #if defined(LINKED) |
96 | #undef LINKED /* Linked commands are currently broken ! */ |
97 | #endif |
98 | |
99 | static int internal_command(unsigned char target, unsigned char lun, |
100 | const void *cmnd, |
101 | void *buff, int bufflen, int reselect); |
102 | |
103 | static int incommand; /* |
104 | set if arbitration has finished and we are |
105 | in some command phase. |
106 | */ |
107 | |
108 | static const void *base_address = NULL((void *) 0); /* |
109 | Where the card ROM starts, |
110 | used to calculate memory mapped |
111 | register location. |
112 | */ |
113 | #ifdef notyet |
114 | static volatile int abort_confirm = 0; |
115 | #endif |
116 | |
117 | static volatile void *st0x_cr_sr; /* |
118 | control register write, |
119 | status register read. |
120 | 256 bytes in length. |
121 | |
122 | Read is status of SCSI BUS, |
123 | as per STAT masks. |
124 | |
125 | */ |
126 | |
127 | |
128 | static volatile void *st0x_dr; /* |
129 | data register, read write |
130 | 256 bytes in length. |
131 | */ |
132 | |
133 | |
134 | static volatile int st0x_aborted=0; /* |
135 | set when we are aborted, ie by a time out, etc. |
136 | */ |
137 | |
138 | static unsigned char controller_type = 0; /* set to SEAGATE for ST0x boards or FD for TMC-8xx boards */ |
139 | static unsigned char irq = IRQ5; |
140 | |
141 | #define retcode(result)(((result) << 16) | (message << 8) | status) (((result) << 16) | (message << 8) | status) |
142 | #define STATUS(*(volatile unsigned char *) st0x_cr_sr) (*(volatile unsigned char *) st0x_cr_sr) |
143 | #define CONTROL(*(volatile unsigned char *) st0x_cr_sr) STATUS(*(volatile unsigned char *) st0x_cr_sr) |
144 | #define DATA(*(volatile unsigned char *) st0x_dr) (*(volatile unsigned char *) st0x_dr) |
145 | #define WRITE_CONTROL(d){ ((*(volatile unsigned char *) (st0x_cr_sr)) = ((d))); } { writeb((d), st0x_cr_sr)((*(volatile unsigned char *) (st0x_cr_sr)) = ((d))); } |
146 | #define WRITE_DATA(d){ ((*(volatile unsigned char *) (st0x_dr)) = ((d))); } { writeb((d), st0x_dr)((*(volatile unsigned char *) (st0x_dr)) = ((d))); } |
147 | |
148 | void st0x_setup (char *str, int *ints) { |
149 | controller_type = SEAGATE1; |
150 | base_address = (void *) ints[1]; |
151 | irq = ints[2]; |
152 | } |
153 | |
154 | void tmc8xx_setup (char *str, int *ints) { |
155 | controller_type = FD2; |
156 | base_address = (void *) ints[1]; |
157 | irq = ints[2]; |
158 | } |
159 | |
160 | |
161 | #ifndef OVERRIDE |
162 | static const char * seagate_bases[] = { |
163 | (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, |
164 | (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000 |
165 | }; |
166 | |
167 | typedef struct { |
168 | const char *signature ; |
169 | unsigned offset; |
170 | unsigned length; |
171 | unsigned char type; |
172 | } Signature; |
173 | |
174 | static const Signature signatures[] = { |
175 | #ifdef CONFIG_SCSI_SEAGATE1 |
176 | {"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE1}, |
177 | {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE1}, |
178 | |
179 | /* |
180 | * The following two lines are NOT mistakes. One detects ROM revision |
181 | * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter, |
182 | * and this is not going to change, the "SEAGATE" and "SCSI" together |
183 | * are probably "good enough" |
184 | */ |
185 | |
186 | {"SEAGATE SCSI BIOS ",16, 17, SEAGATE1}, |
187 | {"SEAGATE SCSI BIOS ",17, 17, SEAGATE1}, |
188 | |
189 | /* |
190 | * However, future domain makes several incompatible SCSI boards, so specific |
191 | * signatures must be used. |
192 | */ |
193 | |
194 | {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD2}, |
195 | {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD2}, |
196 | {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD2}, |
197 | {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD2}, |
198 | {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD2}, |
199 | {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD2}, |
200 | {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD2}, |
201 | {"FUTURE DOMAIN TMC-950", 5, 21, FD2}, |
202 | #endif /* CONFIG_SCSI_SEAGATE */ |
203 | } |
204 | ; |
205 | |
206 | #define NUM_SIGNATURES(sizeof(signatures) / sizeof(Signature)) (sizeof(signatures) / sizeof(Signature)) |
207 | #endif /* n OVERRIDE */ |
208 | |
209 | /* |
210 | * hostno stores the hostnumber, as told to us by the init routine. |
211 | */ |
212 | |
213 | static int hostno = -1; |
214 | static void seagate_reconnect_intr(int, void *, struct pt_regs *); |
215 | |
216 | #ifdef FAST |
217 | static int fast = 1; |
218 | #endif |
219 | |
220 | #ifdef SLOW_HANDSHAKE |
221 | /* |
222 | * Support for broken devices : |
223 | * The Seagate board has a handshaking problem. Namely, a lack |
224 | * thereof for slow devices. You can blast 600K/second through |
225 | * it if you are polling for each byte, more if you do a blind |
226 | * transfer. In the first case, with a fast device, REQ will |
227 | * transition high-low or high-low-high before your loop restarts |
228 | * and you'll have no problems. In the second case, the board |
229 | * will insert wait states for up to 13.2 usecs for REQ to |
230 | * transition low->high, and everything will work. |
231 | * |
232 | * However, there's nothing in the state machine that says |
233 | * you *HAVE* to see a high-low-high set of transitions before |
234 | * sending the next byte, and slow things like the Trantor CD ROMS |
235 | * will break because of this. |
236 | * |
237 | * So, we need to slow things down, which isn't as simple as it |
238 | * seems. We can't slow things down period, because then people |
239 | * who don't recompile their kernels will shoot me for ruining |
240 | * their performance. We need to do it on a case per case basis. |
241 | * |
242 | * The best for performance will be to, only for borken devices |
243 | * (this is stored on a per-target basis in the scsi_devices array) |
244 | * |
245 | * Wait for a low->high transition before continuing with that |
246 | * transfer. If we timeout, continue anyways. We don't need |
247 | * a long timeout, because REQ should only be asserted until the |
248 | * corresponding ACK is received and processed. |
249 | * |
250 | * Note that we can't use the system timer for this, because of |
251 | * resolution, and we *really* can't use the timer chip since |
252 | * gettimeofday() and the beeper routines use that. So, |
253 | * the best thing for us to do will be to calibrate a timing |
254 | * loop in the initialization code using the timer chip before |
255 | * gettimeofday() can screw with it. |
256 | */ |
257 | |
258 | static int borken_calibration = 0; |
259 | static void borken_init (void) { |
260 | register int count = 0, start = jiffies + 1, stop = start + 25; |
261 | |
262 | while (jiffies < start); |
263 | for (;jiffies < stop; ++count); |
264 | |
265 | /* |
266 | * Ok, we now have a count for .25 seconds. Convert to a |
267 | * count per second and divide by transfer rate in K. |
268 | */ |
269 | |
270 | borken_calibration = (count * 4) / (SLOW_RATE50*1024); |
271 | |
272 | if (borken_calibration < 1) |
273 | borken_calibration = 1; |
274 | #if (DEBUG & DEBUG_BORKEN0x8000) |
275 | printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n", |
276 | hostno, BORKEN_RATE, borken_calibration); |
277 | #endif |
278 | } |
279 | |
280 | static inlineinline __attribute__((always_inline)) void borken_wait(void) { |
281 | register int count; |
282 | for (count = borken_calibration; count && (STATUS(*(volatile unsigned char *) st0x_cr_sr) & STAT_REQ0x10); |
283 | --count); |
284 | #if (DEBUG & DEBUG_BORKEN0x8000) |
285 | if (count) |
286 | printk("scsi%d : borken timeout\n", hostno); |
287 | #endif |
288 | } |
289 | |
290 | #endif /* def SLOW_HANDSHAKE */ |
291 | |
292 | int seagate_st0x_detect (Scsi_Host_Template * tpnt) |
293 | { |
294 | struct Scsi_Host *instance; |
295 | #ifndef OVERRIDE |
296 | int i,j; |
297 | #endif |
298 | |
299 | tpnt->proc_dir = &proc_scsi_seagate; |
300 | /* |
301 | * First, we try for the manual override. |
302 | */ |
303 | #ifdef DEBUG |
304 | printk("Autodetecting ST0x / TMC-8xx\n"); |
305 | #endif |
306 | |
307 | if (hostno != -1) |
308 | { |
309 | printk ("ERROR : seagate_st0x_detect() called twice.\n"); |
310 | return 0; |
311 | } |
312 | |
313 | /* If the user specified the controller type from the command line, |
314 | controller_type will be non-zero, so don't try to detect one */ |
315 | |
316 | if (!controller_type) { |
317 | #ifdef OVERRIDE |
318 | base_address = (void *) OVERRIDE; |
319 | |
320 | /* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */ |
321 | #ifdef CONTROLLER |
322 | controller_type = CONTROLLER; |
323 | #else |
324 | #error Please use -DCONTROLLER=SEAGATE1 or -DCONTROLLER=FD2 to override controller type |
325 | #endif /* CONTROLLER */ |
326 | #ifdef DEBUG |
327 | printk("Base address overridden to %x, controller type is %s\n", |
328 | base_address,controller_type == SEAGATE1 ? "SEAGATE" : "FD"); |
329 | #endif |
330 | #else /* OVERRIDE */ |
331 | /* |
332 | * To detect this card, we simply look for the signature |
333 | * from the BIOS version notice in all the possible locations |
334 | * of the ROM's. This has a nice side effect of not trashing |
335 | * any register locations that might be used by something else. |
336 | * |
337 | * XXX - note that we probably should be probing the address |
338 | * space for the on-board RAM instead. |
339 | */ |
340 | |
341 | for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i) |
342 | for (j = 0; !base_address && j < NUM_SIGNATURES(sizeof(signatures) / sizeof(Signature)); ++j) |
343 | if (!memcmp__builtin_memcmp ((const void *) (seagate_bases[i] + |
344 | signatures[j].offset), (const void *) signatures[j].signature, |
345 | signatures[j].length)) { |
346 | base_address = (const void *) seagate_bases[i]; |
347 | controller_type = signatures[j].type; |
348 | } |
349 | #endif /* OVERRIDE */ |
350 | } /* (! controller_type) */ |
351 | |
352 | tpnt->this_id = (controller_type == SEAGATE1) ? 7 : 6; |
353 | tpnt->name = (controller_type == SEAGATE1) ? ST0X_ID_STR"Seagate ST-01/ST-02" : FD_ID_STR"TMC-8XX/TMC-950"; |
354 | |
355 | if (base_address) |
356 | { |
357 | st0x_cr_sr =(void *) (((const unsigned char *) base_address) + (controller_type == SEAGATE1 ? 0x1a00 : 0x1c00)); |
358 | st0x_dr = (void *) (((const unsigned char *) base_address ) + (controller_type == SEAGATE1 ? 0x1c00 : 0x1e00)); |
359 | #ifdef DEBUG |
360 | printk("%s detected. Base address = %x, cr = %x, dr = %x\n", tpnt->name, base_address, st0x_cr_sr, st0x_dr); |
361 | #endif |
362 | /* |
363 | * At all times, we will use IRQ 5. Should also check for IRQ3 if we |
364 | * loose our first interrupt. |
365 | */ |
366 | instance = scsi_register(tpnt, 0); |
367 | hostno = instance->host_no; |
368 | if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT0x20000000, |
369 | (controller_type == SEAGATE1) ? "seagate" : "tmc-8xx", NULL((void *) 0))) { |
370 | printk("scsi%d : unable to allocate IRQ%d\n", |
371 | hostno, (int) irq); |
372 | return 0; |
373 | } |
374 | instance->irq = irq; |
375 | instance->io_port = (unsigned int) base_address; |
376 | #ifdef SLOW_HANDSHAKE |
377 | borken_init(); |
378 | #endif |
379 | |
380 | printk("%s options:" |
381 | #ifdef ARBITRATE |
382 | " ARBITRATE" |
383 | #endif |
384 | #ifdef SLOW_HANDSHAKE |
385 | " SLOW_HANDSHAKE" |
386 | #endif |
387 | #ifdef FAST |
388 | #ifdef FAST32 |
389 | " FAST32" |
390 | #else |
391 | " FAST" |
392 | #endif |
393 | #endif |
394 | #ifdef LINKED |
395 | " LINKED" |
396 | #endif |
397 | "\n", tpnt->name); |
398 | return 1; |
399 | } |
400 | else |
401 | { |
402 | #ifdef DEBUG |
403 | printk("ST0x / TMC-8xx not detected.\n"); |
404 | #endif |
405 | return 0; |
406 | } |
407 | } |
408 | |
409 | const char *seagate_st0x_info(struct Scsi_Host * shpnt) { |
410 | static char buffer[64]; |
411 | sprintflinux_sprintf(buffer, "%s at irq %d, address 0x%05X", |
412 | (controller_type == SEAGATE1) ? ST0X_ID_STR"Seagate ST-01/ST-02" : FD_ID_STR"TMC-8XX/TMC-950", |
413 | irq, (unsigned int)base_address); |
414 | return buffer; |
415 | } |
416 | |
417 | int seagate_st0x_proc_info(char *buffer, char **start, off_t offset, |
418 | int length, int hostno, int inout) |
419 | { |
420 | const char *info = seagate_st0x_info(NULL((void *) 0)); |
421 | int len; |
422 | int pos; |
423 | int begin; |
424 | |
425 | if (inout) return(-ENOSYS38); |
426 | |
427 | begin = 0; |
428 | strcpy(buffer,info); |
429 | strcat(buffer,"\n"); |
430 | |
431 | pos = len = strlen(buffer); |
432 | |
433 | if (pos<offset) { |
434 | len = 0; |
435 | begin = pos; |
436 | } |
437 | |
438 | *start = buffer + (offset - begin); |
439 | len -= (offset - begin); |
440 | if ( len > length ) len = length; |
441 | return(len); |
442 | } |
443 | |
444 | /* |
445 | * These are our saved pointers for the outstanding command that is |
446 | * waiting for a reconnect |
447 | */ |
448 | |
449 | static unsigned char current_target, current_lun; |
450 | static unsigned char *current_cmnd, *current_data; |
451 | static int current_nobuffs; |
452 | static struct scatterlist *current_buffer; |
453 | static int current_bufflen; |
454 | |
455 | #ifdef LINKED |
456 | |
457 | /* |
458 | * linked_connected indicates whether or not we are currently connected to |
459 | * linked_target, linked_lun and in an INFORMATION TRANSFER phase, |
460 | * using linked commands. |
461 | */ |
462 | |
463 | static int linked_connected = 0; |
464 | static unsigned char linked_target, linked_lun; |
465 | #endif |
466 | |
467 | |
468 | static void (*done_fn)(Scsi_Cmnd *) = NULL((void *) 0); |
469 | static Scsi_Cmnd * SCint = NULL((void *) 0); |
470 | |
471 | /* |
472 | * These control whether or not disconnect / reconnect will be attempted, |
473 | * or are being attempted. |
474 | */ |
475 | |
476 | #define NO_RECONNECT0 0 |
477 | #define RECONNECT_NOW1 1 |
478 | #define CAN_RECONNECT2 2 |
479 | |
480 | #ifdef LINKED |
481 | |
482 | /* |
483 | * LINKED_RIGHT indicates that we are currently connected to the correct target |
484 | * for this command, LINKED_WRONG indicates that we are connected to the wrong |
485 | * target. Note that these imply CAN_RECONNECT. |
486 | */ |
487 | |
488 | #define LINKED_RIGHT 3 |
489 | #define LINKED_WRONG 4 |
490 | #endif |
491 | |
492 | /* |
493 | * This determines if we are expecting to reconnect or not. |
494 | */ |
495 | |
496 | static int should_reconnect = 0; |
497 | |
498 | /* |
499 | * The seagate_reconnect_intr routine is called when a target reselects the |
500 | * host adapter. This occurs on the interrupt triggered by the target |
501 | * asserting SEL. |
502 | */ |
503 | |
504 | static void seagate_reconnect_intr(int irq, void *dev_id, struct pt_regs *regs) |
505 | { |
506 | int temp; |
507 | Scsi_Cmnd * SCtmp; |
508 | |
509 | /* enable all other interrupts. */ |
510 | sti()__asm__ __volatile__ ("sti": : :"memory"); |
511 | #if (DEBUG & PHASE_RESELECT0x800) |
512 | printk("scsi%d : seagate_reconnect_intr() called\n", hostno); |
513 | #endif |
514 | |
515 | if (!should_reconnect) |
516 | printk("scsi%d: unexpected interrupt.\n", hostno); |
517 | else { |
518 | should_reconnect = 0; |
519 | |
520 | #if (DEBUG & PHASE_RESELECT0x800) |
521 | printk("scsi%d : internal_command(" |
522 | "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno, |
523 | current_target, current_data, current_bufflen); |
524 | #endif |
525 | |
526 | temp = internal_command (current_target, current_lun, |
527 | current_cmnd, current_data, current_bufflen, |
528 | RECONNECT_NOW1); |
529 | |
530 | if (msg_byte(temp)(((temp) >> 8) & 0xff) != DISCONNECT0x04) { |
531 | if (done_fn) { |
532 | #if (DEBUG & PHASE_RESELECT0x800) |
533 | printk("scsi%d : done_fn(%d,%08x)", hostno, |
534 | hostno, temp); |
535 | #endif |
536 | if(!SCint) panic("SCint == NULL in seagate"); |
537 | SCtmp = SCint; |
538 | SCint = NULL((void *) 0); |
539 | SCtmp->result = temp; |
540 | done_fn (SCtmp); |
541 | } else |
542 | printk("done_fn() not defined.\n"); |
543 | } |
544 | } |
545 | } |
546 | |
547 | /* |
548 | * The seagate_st0x_queue_command() function provides a queued interface |
549 | * to the seagate SCSI driver. Basically, it just passes control onto the |
550 | * seagate_command() function, after fixing it so that the done_fn() |
551 | * is set to the one passed to the function. We have to be very careful, |
552 | * because there are some commands on some devices that do not disconnect, |
553 | * and if we simply call the done_fn when the command is done then another |
554 | * command is started and queue_command is called again... We end up |
555 | * overflowing the kernel stack, and this tends not to be such a good idea. |
556 | */ |
557 | |
558 | static int recursion_depth = 0; |
559 | |
560 | int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) |
561 | { |
562 | int result, reconnect; |
563 | Scsi_Cmnd * SCtmp; |
564 | |
565 | done_fn = done; |
566 | current_target = SCpnt->target; |
567 | current_lun = SCpnt->lun; |
568 | current_cmnd = SCpnt->cmnd; |
569 | current_data = (unsigned char *) SCpnt->request_buffer; |
570 | current_bufflen = SCpnt->request_bufflen; |
571 | SCint = SCpnt; |
572 | if(recursion_depth) { |
573 | return 0; |
574 | }; |
575 | recursion_depth++; |
576 | do{ |
577 | #ifdef LINKED |
578 | /* |
579 | * Set linked command bit in control field of SCSI command. |
580 | */ |
581 | |
582 | current_cmnd[SCpnt->cmd_len] |= 0x01; |
583 | if (linked_connected) { |
584 | #if (DEBUG & DEBUG_LINKED0x4000) |
585 | printk("scsi%d : using linked commands, current I_T_L nexus is ", |
586 | hostno); |
587 | #endif |
588 | if ((linked_target == current_target) && |
589 | (linked_lun == current_lun)) { |
590 | #if (DEBUG & DEBUG_LINKED0x4000) |
591 | printk("correct\n"); |
592 | #endif |
593 | reconnect = LINKED_RIGHT; |
594 | } else { |
595 | #if (DEBUG & DEBUG_LINKED0x4000) |
596 | printk("incorrect\n"); |
597 | #endif |
598 | reconnect = LINKED_WRONG; |
599 | } |
600 | } else |
601 | #endif /* LINKED */ |
602 | reconnect = CAN_RECONNECT2; |
603 | |
604 | |
605 | |
606 | |
607 | |
608 | result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer, |
609 | SCint->request_bufflen, |
610 | reconnect); |
611 | if (msg_byte(result)(((result) >> 8) & 0xff) == DISCONNECT0x04) break; |
612 | SCtmp = SCint; |
613 | SCint = NULL((void *) 0); |
614 | SCtmp->result = result; |
615 | done_fn (SCtmp); |
616 | } while(SCint); |
617 | recursion_depth--; |
618 | return 0; |
619 | } |
620 | |
621 | int seagate_st0x_command (Scsi_Cmnd * SCpnt) { |
622 | return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer, |
623 | SCpnt->request_bufflen, |
624 | (int) NO_RECONNECT0); |
625 | } |
626 | |
627 | static int internal_command(unsigned char target, unsigned char lun, const void *cmnd, |
628 | void *buff, int bufflen, int reselect) { |
629 | int len = 0; |
630 | unsigned char *data = NULL((void *) 0); |
631 | struct scatterlist *buffer = NULL((void *) 0); |
632 | int nobuffs = 0; |
633 | int clock; |
634 | int temp; |
635 | #ifdef SLOW_HANDSHAKE |
636 | int borken; /* Does the current target require Very Slow I/O ? */ |
637 | #endif |
638 | |
639 | |
640 | #if (DEBUG & PHASE_DATAIN8) || (DEBUG & PHASE_DATOUT) |
641 | int transfered = 0; |
642 | #endif |
643 | |
644 | #if (((DEBUG & PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) == PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) || (DEBUG & PRINT_COMMAND0x200) || \ |
645 | (DEBUG & PHASE_EXIT0x400)) |
646 | int i; |
647 | #endif |
648 | |
649 | #if ((DEBUG & PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) == PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) |
650 | int phase=0, newphase; |
651 | #endif |
652 | |
653 | int done = 0; |
654 | unsigned char status = 0; |
655 | unsigned char message = 0; |
656 | register unsigned char status_read; |
657 | |
658 | unsigned transfersize = 0, underflow = 0; |
659 | |
660 | incommand = 0; |
661 | st0x_aborted = 0; |
662 | |
663 | #ifdef SLOW_HANDSHAKE |
664 | borken = (int) SCint->device->borken; |
665 | #endif |
666 | |
667 | #if (DEBUG & PRINT_COMMAND0x200) |
668 | printk ("scsi%d : target = %d, command = ", hostno, target); |
669 | print_command((unsigned char *) cmnd); |
670 | printk("\n"); |
671 | #endif |
672 | |
673 | #if (DEBUG & PHASE_RESELECT0x800) |
674 | switch (reselect) { |
675 | case RECONNECT_NOW1 : |
676 | printk("scsi%d : reconnecting\n", hostno); |
677 | break; |
678 | #ifdef LINKED |
679 | case LINKED_RIGHT : |
680 | printk("scsi%d : connected, can reconnect\n", hostno); |
681 | break; |
682 | case LINKED_WRONG : |
683 | printk("scsi%d : connected to wrong target, can reconnect\n", |
684 | hostno); |
685 | break; |
686 | #endif |
687 | case CAN_RECONNECT2 : |
688 | printk("scsi%d : allowed to reconnect\n", hostno); |
689 | break; |
690 | default : |
691 | printk("scsi%d : not allowed to reconnect\n", hostno); |
692 | } |
693 | #endif |
694 | |
695 | |
696 | if (target == (controller_type == SEAGATE1 ? 7 : 6)) |
697 | return DID_BAD_TARGET0x04; |
698 | |
699 | /* |
700 | * We work it differently depending on if this is "the first time," |
701 | * or a reconnect. If this is a reselect phase, then SEL will |
702 | * be asserted, and we must skip selection / arbitration phases. |
703 | */ |
704 | |
705 | switch (reselect) { |
706 | case RECONNECT_NOW1: |
707 | #if (DEBUG & PHASE_RESELECT0x800) |
708 | printk("scsi%d : phase RESELECT \n", hostno); |
709 | #endif |
710 | |
711 | /* |
712 | * At this point, we should find the logical or of our ID and the original |
713 | * target's ID on the BUS, with BSY, SEL, and I/O signals asserted. |
714 | * |
715 | * After ARBITRATION phase is completed, only SEL, BSY, and the |
716 | * target ID are asserted. A valid initiator ID is not on the bus |
717 | * until IO is asserted, so we must wait for that. |
718 | */ |
719 | clock = jiffies + 10; |
720 | for (;;) { |
721 | temp = STATUS(*(volatile unsigned char *) st0x_cr_sr); |
722 | if ((temp & STAT_IO0x04) && !(temp & STAT_BSY0x01)) |
723 | break; |
724 | |
725 | if (jiffies > clock) { |
726 | #if (DEBUG & PHASE_RESELECT0x800) |
727 | printk("scsi%d : RESELECT timed out while waiting for IO .\n", |
728 | hostno); |
729 | #endif |
730 | return (DID_BAD_INTR0x09 << 16); |
731 | } |
732 | } |
733 | |
734 | /* |
735 | * After I/O is asserted by the target, we can read our ID and its |
736 | * ID off of the BUS. |
737 | */ |
738 | |
739 | if (!((temp = DATA(*(volatile unsigned char *) st0x_dr)) & (controller_type == SEAGATE1 ? 0x80 : 0x40))) |
740 | { |
741 | #if (DEBUG & PHASE_RESELECT0x800) |
742 | printk("scsi%d : detected reconnect request to different target.\n" |
743 | "\tData bus = %d\n", hostno, temp); |
744 | #endif |
745 | return (DID_BAD_INTR0x09 << 16); |
746 | } |
747 | |
748 | if (!(temp & (1 << current_target))) |
749 | { |
750 | printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n", |
751 | hostno, temp); |
752 | return (DID_BAD_INTR0x09 << 16); |
753 | } |
754 | |
755 | buffer=current_buffer; |
756 | cmnd=current_cmnd; /* WDE add */ |
757 | data=current_data; /* WDE add */ |
758 | len=current_bufflen; /* WDE add */ |
759 | nobuffs=current_nobuffs; |
760 | |
761 | /* |
762 | * We have determined that we have been selected. At this point, |
763 | * we must respond to the reselection by asserting BSY ourselves |
764 | */ |
765 | |
766 | #if 1 |
767 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = (BASE_CMD0x20 | CMD_DRVR_ENABLE0x80 | CMD_BSY0x04); |
768 | #else |
769 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = (BASE_CMD0x20 | CMD_BSY0x04); |
770 | #endif |
771 | |
772 | /* |
773 | * The target will drop SEL, and raise BSY, at which time we must drop |
774 | * BSY. |
775 | */ |
776 | |
777 | for (clock = jiffies + 10; (jiffies < clock) && (STATUS(*(volatile unsigned char *) st0x_cr_sr) & STAT_SEL0x20);); |
778 | |
779 | if (jiffies >= clock) |
780 | { |
781 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = (BASE_CMD0x20 | CMD_INTR0x40); |
782 | #if (DEBUG & PHASE_RESELECT0x800) |
783 | printk("scsi%d : RESELECT timed out while waiting for SEL.\n", |
784 | hostno); |
785 | #endif |
786 | return (DID_BAD_INTR0x09 << 16); |
787 | } |
788 | |
789 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20; |
790 | |
791 | /* |
792 | * At this point, we have connected with the target and can get |
793 | * on with our lives. |
794 | */ |
795 | break; |
796 | case CAN_RECONNECT2: |
797 | |
798 | #ifdef LINKED |
799 | /* |
800 | * This is a bletcherous hack, just as bad as the Unix #! interpreter stuff. |
801 | * If it turns out we are using the wrong I_T_L nexus, the easiest way to deal |
802 | * with it is to go into our INFORMATION TRANSFER PHASE code, send a ABORT |
803 | * message on MESSAGE OUT phase, and then loop back to here. |
804 | */ |
805 | |
806 | connect_loop : |
807 | |
808 | #endif |
809 | |
810 | #if (DEBUG & PHASE_BUS_FREE1) |
811 | printk ("scsi%d : phase = BUS FREE \n", hostno); |
812 | #endif |
813 | |
814 | /* |
815 | * BUS FREE PHASE |
816 | * |
817 | * On entry, we make sure that the BUS is in a BUS FREE |
818 | * phase, by insuring that both BSY and SEL are low for |
819 | * at least one bus settle delay. Several reads help |
820 | * eliminate wire glitch. |
821 | */ |
822 | |
823 | clock = jiffies + ST0X_BUS_FREE_DELAY25; |
824 | |
825 | #if !defined (ARBITRATE) |
826 | while (((STATUS(*(volatile unsigned char *) st0x_cr_sr) | STATUS(*(volatile unsigned char *) st0x_cr_sr) | STATUS(*(volatile unsigned char *) st0x_cr_sr)) & |
827 | (STAT_BSY0x01 | STAT_SEL0x20)) && |
828 | (!st0x_aborted) && (jiffies < clock)); |
829 | |
830 | if (jiffies > clock) |
831 | return retcode(DID_BUS_BUSY)(((0x02) << 16) | (message << 8) | status); |
832 | else if (st0x_aborted) |
833 | return retcode(st0x_aborted)(((st0x_aborted) << 16) | (message << 8) | status ); |
834 | #endif |
835 | |
836 | #if (DEBUG & PHASE_SELECTION4) |
837 | printk("scsi%d : phase = SELECTION\n", hostno); |
838 | #endif |
839 | |
840 | clock = jiffies + ST0X_SELECTION_DELAY25; |
841 | |
842 | /* |
843 | * Arbitration/selection procedure : |
844 | * 1. Disable drivers |
845 | * 2. Write HOST adapter address bit |
846 | * 3. Set start arbitration. |
847 | * 4. We get either ARBITRATION COMPLETE or SELECT at this |
848 | * point. |
849 | * 5. OR our ID and targets on bus. |
850 | * 6. Enable SCSI drivers and asserted SEL and ATTN |
851 | */ |
852 | |
853 | #if defined(ARBITRATE) |
854 | cli()__asm__ __volatile__ ("cli": : :"memory"); |
855 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = 0; |
856 | DATA(*(volatile unsigned char *) st0x_dr) = (controller_type == SEAGATE1) ? 0x80 : 0x40; |
857 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = CMD_START_ARB0x10; |
858 | sti()__asm__ __volatile__ ("sti": : :"memory"); |
859 | while (!((status_read = STATUS(*(volatile unsigned char *) st0x_cr_sr)) & (STAT_ARB_CMPL0x80 | STAT_SEL0x20)) && |
860 | (jiffies < clock) && !st0x_aborted); |
861 | |
862 | if (!(status_read & STAT_ARB_CMPL0x80)) { |
863 | #if (DEBUG & PHASE_SELECTION4) |
864 | if (status_read & STAT_SEL0x20) |
865 | printk("scsi%d : arbitration lost\n", hostno); |
866 | else |
867 | printk("scsi%d : arbitration timeout.\n", hostno); |
868 | #endif |
869 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20; |
870 | return retcode(DID_NO_CONNECT)(((0x01) << 16) | (message << 8) | status); |
871 | }; |
872 | |
873 | #if (DEBUG & PHASE_SELECTION4) |
874 | printk("scsi%d : arbitration complete\n", hostno); |
875 | #endif |
876 | #endif |
877 | |
878 | |
879 | /* |
880 | * When the SCSI device decides that we're gawking at it, it will |
881 | * respond by asserting BUSY on the bus. |
882 | * |
883 | * Note : the Seagate ST-01/02 product manual says that we should |
884 | * twiddle the DATA register before the control register. However, |
885 | * this does not work reliably so we do it the other way around. |
886 | * |
887 | * Probably could be a problem with arbitration too, we really should |
888 | * try this with a SCSI protocol or logic analyzer to see what is |
889 | * going on. |
890 | */ |
891 | cli()__asm__ __volatile__ ("cli": : :"memory"); |
892 | DATA(*(volatile unsigned char *) st0x_dr) = (unsigned char) ((1 << target) | (controller_type == SEAGATE1 ? 0x80 : 0x40)); |
893 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20 | CMD_DRVR_ENABLE0x80 | CMD_SEL0x02 | |
894 | (reselect ? CMD_ATTN0x08 : 0); |
895 | sti()__asm__ __volatile__ ("sti": : :"memory"); |
896 | while (!((status_read = STATUS(*(volatile unsigned char *) st0x_cr_sr)) & STAT_BSY0x01) && |
897 | (jiffies < clock) && !st0x_aborted) |
898 | |
899 | #if 0 && (DEBUG & PHASE_SELECTION4) |
900 | { |
901 | temp = clock - jiffies; |
902 | |
903 | if (!(jiffies % 5)) |
904 | printk("seagate_st0x_timeout : %d \r",temp); |
905 | |
906 | } |
907 | printk("Done. \n"); |
908 | printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", |
909 | hostno, status_read, temp, st0x_aborted); |
910 | #else |
911 | ; |
912 | #endif |
913 | |
914 | |
915 | if ((jiffies >= clock) && !(status_read & STAT_BSY0x01)) |
916 | { |
917 | #if (DEBUG & PHASE_SELECTION4) |
918 | printk ("scsi%d : NO CONNECT with target %d, status = %x \n", |
919 | hostno, target, STATUS(*(volatile unsigned char *) st0x_cr_sr)); |
920 | #endif |
921 | return retcode(DID_NO_CONNECT)(((0x01) << 16) | (message << 8) | status); |
922 | } |
923 | |
924 | /* |
925 | * If we have been aborted, and we have a command in progress, IE the |
926 | * target still has BSY asserted, then we will reset the bus, and |
927 | * notify the midlevel driver to expect sense. |
928 | */ |
929 | |
930 | if (st0x_aborted) { |
931 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20; |
932 | if (STATUS(*(volatile unsigned char *) st0x_cr_sr) & STAT_BSY0x01) { |
933 | printk("scsi%d : BST asserted after we've been aborted.\n", |
934 | hostno); |
935 | seagate_st0x_reset(NULL((void *) 0), 0); |
936 | return retcode(DID_RESET)(((0x08) << 16) | (message << 8) | status); |
937 | } |
938 | return retcode(st0x_aborted)(((st0x_aborted) << 16) | (message << 8) | status ); |
939 | } |
940 | |
941 | /* Establish current pointers. Take into account scatter / gather */ |
942 | |
943 | if ((nobuffs = SCint->use_sg)) { |
944 | #if (DEBUG & DEBUG_SG0x2000) |
945 | { |
946 | int i; |
947 | printk("scsi%d : scatter gather requested, using %d buffers.\n", |
948 | hostno, nobuffs); |
949 | for (i = 0; i < nobuffs; ++i) |
950 | printk("scsi%d : buffer %d address = %08x length = %d\n", |
951 | hostno, i, buffer[i].address, buffer[i].length); |
952 | } |
953 | #endif |
954 | |
955 | buffer = (struct scatterlist *) SCint->buffer; |
956 | len = buffer->length; |
957 | data = (unsigned char *) buffer->address; |
958 | } else { |
959 | #if (DEBUG & DEBUG_SG0x2000) |
960 | printk("scsi%d : scatter gather not requested.\n", hostno); |
961 | #endif |
962 | buffer = NULL((void *) 0); |
963 | len = SCint->request_bufflen; |
964 | data = (unsigned char *) SCint->request_buffer; |
965 | } |
966 | |
967 | #if (DEBUG & (PHASE_DATAIN8 | PHASE_DATAOUT0x10)) |
968 | printk("scsi%d : len = %d\n", hostno, len); |
969 | #endif |
970 | |
971 | break; |
972 | #ifdef LINKED |
973 | case LINKED_RIGHT: |
974 | break; |
975 | case LINKED_WRONG: |
976 | break; |
977 | #endif |
978 | } |
979 | |
980 | /* |
981 | * There are several conditions under which we wish to send a message : |
982 | * 1. When we are allowing disconnect / reconnect, and need to establish |
983 | * the I_T_L nexus via an IDENTIFY with the DiscPriv bit set. |
984 | * |
985 | * 2. When we are doing linked commands, are have the wrong I_T_L nexus |
986 | * established and want to send an ABORT message. |
987 | */ |
988 | |
989 | |
990 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20 | CMD_DRVR_ENABLE0x80 | |
991 | (((reselect == CAN_RECONNECT2) |
992 | #ifdef LINKED |
993 | || (reselect == LINKED_WRONG) |
994 | #endif |
995 | ) ? CMD_ATTN0x08 : 0) ; |
996 | |
997 | /* |
998 | * INFORMATION TRANSFER PHASE |
999 | * |
1000 | * The nasty looking read / write inline assembler loops we use for |
1001 | * DATAIN and DATAOUT phases are approximately 4-5 times as fast as |
1002 | * the 'C' versions - since we're moving 1024 bytes of data, this |
1003 | * really adds up. |
1004 | */ |
1005 | |
1006 | #if ((DEBUG & PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) == PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) |
1007 | printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno); |
1008 | #endif |
1009 | |
1010 | incommand = 1; |
1011 | transfersize = SCint->transfersize; |
1012 | underflow = SCint->underflow; |
Value stored to 'underflow' is never read | |
1013 | |
1014 | |
1015 | /* |
1016 | * Now, we poll the device for status information, |
1017 | * and handle any requests it makes. Note that since we are unsure of |
1018 | * how much data will be flowing across the system, etc and cannot |
1019 | * make reasonable timeouts, that we will instead have the midlevel |
1020 | * driver handle any timeouts that occur in this phase. |
1021 | */ |
1022 | |
1023 | while (((status_read = STATUS(*(volatile unsigned char *) st0x_cr_sr)) & STAT_BSY0x01) && !st0x_aborted && !done) |
1024 | { |
1025 | #ifdef PARITY |
1026 | if (status_read & STAT_PARITY0x40) |
1027 | { |
1028 | printk("scsi%d : got parity error\n", hostno); |
1029 | st0x_aborted = DID_PARITY0x06; |
1030 | } |
1031 | #endif |
1032 | |
1033 | if (status_read & STAT_REQ0x10) |
1034 | { |
1035 | #if ((DEBUG & PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) == PHASE_ETC(8 | PHASE_DATA_OUT | 0x20 | 0x40 | 0x80 | 0x100)) |
1036 | if ((newphase = (status_read & REQ_MASK(0x08 | 0x04 | 0x02))) != phase) |
1037 | { |
1038 | phase = newphase; |
1039 | switch (phase) |
1040 | { |
1041 | case REQ_DATAOUT0: |
1042 | printk("scsi%d : phase = DATA OUT\n", |
1043 | hostno); |
1044 | break; |
1045 | case REQ_DATAIN0x04 : |
1046 | printk("scsi%d : phase = DATA IN\n", |
1047 | hostno); |
1048 | break; |
1049 | case REQ_CMDOUT0x08 : |
1050 | printk("scsi%d : phase = COMMAND OUT\n", |
1051 | hostno); |
1052 | break; |
1053 | case REQ_STATIN(0x08 | 0x04) : |
1054 | printk("scsi%d : phase = STATUS IN\n", |
1055 | hostno); |
1056 | break; |
1057 | case REQ_MSGOUT(0x02 | 0x08) : |
1058 | printk("scsi%d : phase = MESSAGE OUT\n", |
1059 | hostno); |
1060 | break; |
1061 | case REQ_MSGIN(0x02 | 0x08 | 0x04) : |
1062 | printk("scsi%d : phase = MESSAGE IN\n", |
1063 | hostno); |
1064 | break; |
1065 | default : |
1066 | printk("scsi%d : phase = UNKNOWN\n", |
1067 | hostno); |
1068 | st0x_aborted = DID_ERROR0x07; |
1069 | } |
1070 | } |
1071 | #endif |
1072 | switch (status_read & REQ_MASK(0x08 | 0x04 | 0x02)) |
1073 | { |
1074 | case REQ_DATAOUT0 : |
1075 | /* |
1076 | * If we are in fast mode, then we simply splat the data out |
1077 | * in word-sized chunks as fast as we can. |
1078 | */ |
1079 | |
1080 | #ifdef FAST |
1081 | if (!len) { |
1082 | #if 0 |
1083 | printk("scsi%d: underflow to target %d lun %d \n", |
1084 | hostno, target, lun); |
1085 | st0x_aborted = DID_ERROR0x07; |
1086 | fast = 0; |
1087 | #endif |
1088 | break; |
1089 | } |
1090 | |
1091 | if (fast && transfersize && !(len % transfersize) && (len >= transfersize) |
1092 | #ifdef FAST32 |
1093 | && !(transfersize % 4) |
1094 | #endif |
1095 | ) { |
1096 | #if (DEBUG & DEBUG_FAST0x1000) |
1097 | printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n" |
1098 | " len = %d, data = %08x\n", hostno, SCint->underflow, |
1099 | SCint->transfersize, len, data); |
1100 | #endif |
1101 | |
1102 | { |
1103 | #ifdef FAST32 |
1104 | unsigned int *iop = phys_to_virt (st0x_dr); |
1105 | const unsigned int *dp = (unsigned int *) data; |
1106 | int xferlen = transfersize >> 2; |
1107 | #else |
1108 | unsigned char *iop = phys_to_virt (st0x_dr); |
1109 | const unsigned char *dp = data; |
1110 | int xferlen = transfersize; |
1111 | #endif |
1112 | for (; xferlen; --xferlen) |
1113 | *iop = *dp++; |
1114 | } |
1115 | |
1116 | len -= transfersize; |
1117 | data += transfersize; |
1118 | |
1119 | #if (DEBUG & DEBUG_FAST0x1000) |
1120 | printk("scsi%d : FAST transfer complete len = %d data = %08x\n", |
1121 | hostno, len, data); |
1122 | #endif |
1123 | |
1124 | |
1125 | } else |
1126 | #endif |
1127 | |
1128 | { |
1129 | /* |
1130 | * We loop as long as we are in a data out phase, there is data to send, |
1131 | * and BSY is still active. |
1132 | */ |
1133 | |
1134 | while (len) |
1135 | { |
1136 | unsigned char stat; |
1137 | |
1138 | stat = STATUS(*(volatile unsigned char *) st0x_cr_sr); |
1139 | if (!(stat & STAT_BSY0x01) || ((stat & REQ_MASK(0x08 | 0x04 | 0x02)) != REQ_DATAOUT0)) |
1140 | break; |
1141 | if (stat & STAT_REQ0x10) |
1142 | { |
1143 | WRITE_DATA (*data++){ ((*(volatile unsigned char *) (st0x_dr)) = ((*data++))); }; |
1144 | --len; |
1145 | } |
1146 | } |
1147 | } |
1148 | |
1149 | if (!len && nobuffs) { |
1150 | --nobuffs; |
1151 | ++buffer; |
1152 | len = buffer->length; |
1153 | data = (unsigned char *) buffer->address; |
1154 | #if (DEBUG & DEBUG_SG0x2000) |
1155 | printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n", |
1156 | hostno, len, data); |
1157 | #endif |
1158 | } |
1159 | break; |
1160 | |
1161 | case REQ_DATAIN0x04 : |
1162 | #ifdef SLOW_HANDSHAKE |
1163 | if (borken) { |
1164 | #if (DEBUG & (PHASE_DATAIN8)) |
1165 | transfered += len; |
1166 | #endif |
1167 | for (; len && (STATUS(*(volatile unsigned char *) st0x_cr_sr) & (REQ_MASK(0x08 | 0x04 | 0x02) | STAT_REQ0x10)) == (REQ_DATAIN0x04 | |
1168 | STAT_REQ0x10); --len) { |
1169 | *data++ = DATA(*(volatile unsigned char *) st0x_dr); |
1170 | borken_wait(); |
1171 | } |
1172 | #if (DEBUG & (PHASE_DATAIN8)) |
1173 | transfered -= len; |
1174 | #endif |
1175 | } else |
1176 | #endif |
1177 | #ifdef FAST |
1178 | if (fast && transfersize && !(len % transfersize) && (len >= transfersize) |
1179 | #ifdef FAST32 |
1180 | && !(transfersize % 4) |
1181 | #endif |
1182 | ) { |
1183 | #if (DEBUG & DEBUG_FAST0x1000) |
1184 | printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n" |
1185 | " len = %d, data = %08x\n", hostno, SCint->underflow, |
1186 | SCint->transfersize, len, data); |
1187 | #endif |
1188 | { |
1189 | #ifdef FAST32 |
1190 | const unsigned int *iop = phys_to_virt (st0x_dr); |
1191 | unsigned int *dp = (unsigned int *) data; |
1192 | int xferlen = len >> 2; |
1193 | #else |
1194 | const unsigned char *iop = phys_to_virt (st0x_dr); |
1195 | unsigned char *dp = data; |
1196 | int xferlen = len; |
1197 | #endif |
1198 | for (; xferlen; --xferlen) |
1199 | *dp++ = *iop; |
1200 | } |
1201 | |
1202 | len -= transfersize; |
1203 | data += transfersize; |
1204 | |
1205 | #if (DEBUG & PHASE_DATAIN8) |
1206 | printk("scsi%d: transfered += %d\n", hostno, transfersize); |
1207 | transfered += transfersize; |
1208 | #endif |
1209 | |
1210 | #if (DEBUG & DEBUG_FAST0x1000) |
1211 | printk("scsi%d : FAST transfer complete len = %d data = %08x\n", |
1212 | hostno, len, data); |
1213 | #endif |
1214 | |
1215 | } else |
1216 | #endif |
1217 | { |
1218 | |
1219 | #if (DEBUG & PHASE_DATAIN8) |
1220 | printk("scsi%d: transfered += %d\n", hostno, len); |
1221 | transfered += len; /* Assume we'll transfer it all, then |
1222 | subtract what we *didn't* transfer */ |
1223 | #endif |
1224 | |
1225 | /* |
1226 | * We loop as long as we are in a data in phase, there is room to read, |
1227 | * and BSY is still active |
1228 | */ |
1229 | |
1230 | while (len) |
1231 | { |
1232 | unsigned char stat; |
1233 | |
1234 | stat = STATUS(*(volatile unsigned char *) st0x_cr_sr); |
1235 | if (!(stat & STAT_BSY0x01) || ((stat & REQ_MASK(0x08 | 0x04 | 0x02)) != REQ_DATAIN0x04)) |
1236 | break; |
1237 | if (stat & STAT_REQ0x10) |
1238 | { |
1239 | *data++ = DATA(*(volatile unsigned char *) st0x_dr); |
1240 | --len; |
1241 | } |
1242 | } |
1243 | |
1244 | #if (DEBUG & PHASE_DATAIN8) |
1245 | printk("scsi%d: transfered -= %d\n", hostno, len); |
1246 | transfered -= len; /* Since we assumed all of Len got |
1247 | * transfered, correct our mistake */ |
1248 | #endif |
1249 | } |
1250 | |
1251 | if (!len && nobuffs) { |
1252 | --nobuffs; |
1253 | ++buffer; |
1254 | len = buffer->length; |
1255 | data = (unsigned char *) buffer->address; |
1256 | #if (DEBUG & DEBUG_SG0x2000) |
1257 | printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n", |
1258 | hostno, len, data); |
1259 | #endif |
1260 | } |
1261 | |
1262 | break; |
1263 | |
1264 | case REQ_CMDOUT0x08 : |
1265 | while (((status_read = STATUS(*(volatile unsigned char *) st0x_cr_sr)) & STAT_BSY0x01) && |
1266 | ((status_read & REQ_MASK(0x08 | 0x04 | 0x02)) == REQ_CMDOUT0x08)) |
1267 | if (status_read & STAT_REQ0x10) { |
1268 | DATA(*(volatile unsigned char *) st0x_dr) = *(const unsigned char *) cmnd; |
1269 | cmnd = 1+(const unsigned char *) cmnd; |
1270 | #ifdef SLOW_HANDSHAKE |
1271 | if (borken) |
1272 | borken_wait(); |
1273 | #endif |
1274 | } |
1275 | break; |
1276 | |
1277 | case REQ_STATIN(0x08 | 0x04) : |
1278 | status = DATA(*(volatile unsigned char *) st0x_dr); |
1279 | break; |
1280 | |
1281 | case REQ_MSGOUT(0x02 | 0x08) : |
1282 | /* |
1283 | * We can only have sent a MSG OUT if we requested to do this |
1284 | * by raising ATTN. So, we must drop ATTN. |
1285 | */ |
1286 | |
1287 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20 | CMD_DRVR_ENABLE0x80; |
1288 | /* |
1289 | * If we are reconnecting, then we must send an IDENTIFY message in |
1290 | * response to MSGOUT. |
1291 | */ |
1292 | switch (reselect) { |
1293 | case CAN_RECONNECT2: |
1294 | DATA(*(volatile unsigned char *) st0x_dr) = IDENTIFY(1, lun)(0x80 | ((1) ? 0x40 : 0) | ((lun) & 0x07)); |
1295 | |
1296 | #if (DEBUG & (PHASE_RESELECT0x800 | PHASE_MSGOUT0x80)) |
1297 | printk("scsi%d : sent IDENTIFY message.\n", hostno); |
1298 | #endif |
1299 | break; |
1300 | #ifdef LINKED |
1301 | case LINKED_WRONG: |
1302 | DATA(*(volatile unsigned char *) st0x_dr) = ABORT0x06; |
1303 | linked_connected = 0; |
1304 | reselect = CAN_RECONNECT2; |
1305 | goto connect_loop; |
1306 | #if (DEBUG & (PHASE_MSGOUT0x80 | DEBUG_LINKED0x4000)) |
1307 | printk("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno); |
1308 | #endif |
1309 | #endif /* LINKED */ |
1310 | #if (DEBUG & DEBUG_LINKED0x4000) |
1311 | printk("correct\n"); |
1312 | #endif |
1313 | default: |
1314 | DATA(*(volatile unsigned char *) st0x_dr) = NOP0x08; |
1315 | printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target); |
1316 | } |
1317 | break; |
1318 | |
1319 | case REQ_MSGIN(0x02 | 0x08 | 0x04) : |
1320 | switch (message = DATA(*(volatile unsigned char *) st0x_dr)) { |
1321 | case DISCONNECT0x04 : |
1322 | should_reconnect = 1; |
1323 | current_data = data; /* WDE add */ |
1324 | current_buffer = buffer; |
1325 | current_bufflen = len; /* WDE add */ |
1326 | current_nobuffs = nobuffs; |
1327 | #ifdef LINKED |
1328 | linked_connected = 0; |
1329 | #endif |
1330 | done=1; |
1331 | #if (DEBUG & (PHASE_RESELECT0x800 | PHASE_MSGIN0x40)) |
1332 | printk("scsi%d : disconnected.\n", hostno); |
1333 | #endif |
1334 | break; |
1335 | |
1336 | #ifdef LINKED |
1337 | case LINKED_CMD_COMPLETE0x0a: |
1338 | case LINKED_FLG_CMD_COMPLETE0x0b: |
1339 | #endif |
1340 | case COMMAND_COMPLETE0x00 : |
1341 | /* |
1342 | * Note : we should check for underflow here. |
1343 | */ |
1344 | #if (DEBUG & PHASE_MSGIN0x40) |
1345 | printk("scsi%d : command complete.\n", hostno); |
1346 | #endif |
1347 | done = 1; |
1348 | break; |
1349 | case ABORT0x06 : |
1350 | #if (DEBUG & PHASE_MSGIN0x40) |
1351 | printk("scsi%d : abort message.\n", hostno); |
1352 | #endif |
1353 | done=1; |
1354 | break; |
1355 | case SAVE_POINTERS0x02 : |
1356 | current_buffer = buffer; |
1357 | current_bufflen = len; /* WDE add */ |
1358 | current_data = data; /* WDE mod */ |
1359 | current_nobuffs = nobuffs; |
1360 | #if (DEBUG & PHASE_MSGIN0x40) |
1361 | printk("scsi%d : pointers saved.\n", hostno); |
1362 | #endif |
1363 | break; |
1364 | case RESTORE_POINTERS0x03: |
1365 | buffer=current_buffer; |
1366 | cmnd=current_cmnd; |
1367 | data=current_data; /* WDE mod */ |
1368 | len=current_bufflen; |
1369 | nobuffs=current_nobuffs; |
1370 | #if (DEBUG & PHASE_MSGIN0x40) |
1371 | printk("scsi%d : pointers restored.\n", hostno); |
1372 | #endif |
1373 | break; |
1374 | default: |
1375 | |
1376 | /* |
1377 | * IDENTIFY distinguishes itself from the other messages by setting the |
1378 | * high byte. |
1379 | * |
1380 | * Note : we need to handle at least one outstanding command per LUN, |
1381 | * and need to hash the SCSI command for that I_T_L nexus based on the |
1382 | * known ID (at this point) and LUN. |
1383 | */ |
1384 | |
1385 | if (message & 0x80) { |
1386 | #if (DEBUG & PHASE_MSGIN0x40) |
1387 | printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n", |
1388 | hostno, target, message & 7); |
1389 | #endif |
1390 | } else { |
1391 | |
1392 | /* |
1393 | * We should go into a MESSAGE OUT phase, and send a MESSAGE_REJECT |
1394 | * if we run into a message that we don't like. The seagate driver |
1395 | * needs some serious restructuring first though. |
1396 | */ |
1397 | |
1398 | #if (DEBUG & PHASE_MSGIN0x40) |
1399 | printk("scsi%d : unknown message %d from target %d.\n", |
1400 | hostno, message, target); |
1401 | #endif |
1402 | } |
1403 | } |
1404 | break; |
1405 | |
1406 | default : |
1407 | printk("scsi%d : unknown phase.\n", hostno); |
1408 | st0x_aborted = DID_ERROR0x07; |
1409 | } |
1410 | |
1411 | #ifdef SLOW_HANDSHAKE |
1412 | /* |
1413 | * I really don't care to deal with borken devices in each single |
1414 | * byte transfer case (ie, message in, message out, status), so |
1415 | * I'll do the wait here if necessary. |
1416 | */ |
1417 | if (borken) |
1418 | borken_wait(); |
1419 | #endif |
1420 | |
1421 | } /* if ends */ |
1422 | } /* while ends */ |
1423 | |
1424 | #if (DEBUG & (PHASE_DATAIN8 | PHASE_DATAOUT0x10 | PHASE_EXIT0x400)) |
1425 | printk("scsi%d : Transfered %d bytes\n", hostno, transfered); |
1426 | #endif |
1427 | |
1428 | #if (DEBUG & PHASE_EXIT0x400) |
1429 | #if 0 /* Doesn't work for scatter / gather */ |
1430 | printk("Buffer : \n"); |
1431 | for (i = 0; i < 20; ++i) |
1432 | printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */ |
1433 | printk("\n"); |
1434 | #endif |
1435 | printk("scsi%d : status = ", hostno); |
1436 | print_status(status); |
1437 | printk("message = %02x\n", message); |
1438 | #endif |
1439 | |
1440 | |
1441 | /* We shouldn't reach this until *after* BSY has been deasserted */ |
1442 | #ifdef notyet |
1443 | if (st0x_aborted) { |
1444 | if (STATUS(*(volatile unsigned char *) st0x_cr_sr) & STAT_BSY0x01) { |
1445 | seagate_st0x_reset(NULL((void *) 0)); |
1446 | st0x_aborted = DID_RESET0x08; |
1447 | } |
1448 | abort_confirm = 1; |
1449 | } |
1450 | #endif |
1451 | |
1452 | #ifdef LINKED |
1453 | else { |
1454 | /* |
1455 | * Fix the message byte so that unsuspecting high level drivers don't |
1456 | * puke when they see a LINKED COMMAND message in place of the COMMAND |
1457 | * COMPLETE they may be expecting. Shouldn't be necessary, but it's |
1458 | * better to be on the safe side. |
1459 | * |
1460 | * A non LINKED* message byte will indicate that the command completed, |
1461 | * and we are now disconnected. |
1462 | */ |
1463 | |
1464 | switch (message) { |
1465 | case LINKED_CMD_COMPLETE0x0a : |
1466 | case LINKED_FLG_CMD_COMPLETE0x0b : |
1467 | message = COMMAND_COMPLETE0x00; |
1468 | linked_target = current_target; |
1469 | linked_lun = current_lun; |
1470 | linked_connected = 1; |
1471 | #if (DEBUG & DEBUG_LINKED0x4000) |
1472 | printk("scsi%d : keeping I_T_L nexus established for linked command.\n", |
1473 | hostno); |
1474 | #endif |
1475 | /* |
1476 | * We also will need to adjust status to accommodate intermediate conditions. |
1477 | */ |
1478 | if ((status == INTERMEDIATE_GOOD0x08) || |
1479 | (status == INTERMEDIATE_C_GOOD0x0a)) |
1480 | status = GOOD0x00; |
1481 | |
1482 | break; |
1483 | /* |
1484 | * We should also handle what are "normal" termination messages |
1485 | * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually, |
1486 | * and flake if things aren't right. |
1487 | */ |
1488 | |
1489 | default : |
1490 | #if (DEBUG & DEBUG_LINKED0x4000) |
1491 | printk("scsi%d : closing I_T_L nexus.\n", hostno); |
1492 | #endif |
1493 | linked_connected = 0; |
1494 | } |
1495 | } |
1496 | #endif /* LINKED */ |
1497 | |
1498 | |
1499 | |
1500 | |
1501 | if (should_reconnect) { |
1502 | #if (DEBUG & PHASE_RESELECT0x800) |
1503 | printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n", |
1504 | hostno); |
1505 | #endif |
1506 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20 | CMD_INTR0x40 ; |
1507 | } else |
1508 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20; |
1509 | |
1510 | return retcode (st0x_aborted)(((st0x_aborted) << 16) | (message << 8) | status ); |
1511 | } |
1512 | |
1513 | int seagate_st0x_abort (Scsi_Cmnd * SCpnt) |
1514 | { |
1515 | st0x_aborted = DID_ABORT0x05; |
1516 | |
1517 | return SCSI_ABORT_PENDING2; |
1518 | } |
1519 | |
1520 | /* |
1521 | the seagate_st0x_reset function resets the SCSI bus |
1522 | */ |
1523 | |
1524 | int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags) |
1525 | { |
1526 | unsigned clock; |
1527 | /* |
1528 | No timeouts - this command is going to fail because |
1529 | it was reset. |
1530 | */ |
1531 | |
1532 | #ifdef DEBUG |
1533 | printk("In seagate_st0x_reset()\n"); |
1534 | #endif |
1535 | |
1536 | |
1537 | /* assert RESET signal on SCSI bus. */ |
1538 | |
1539 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20 | CMD_RST0x01; |
1540 | clock=jiffies+2; |
1541 | |
1542 | |
1543 | /* Wait. */ |
1544 | |
1545 | while (jiffies < clock); |
1546 | |
1547 | CONTROL(*(volatile unsigned char *) st0x_cr_sr) = BASE_CMD0x20; |
1548 | |
1549 | st0x_aborted = DID_RESET0x08; |
1550 | |
1551 | #ifdef DEBUG |
1552 | printk("SCSI bus reset.\n"); |
1553 | #endif |
1554 | return SCSI_RESET_WAKEUP4; |
1555 | } |
1556 | |
1557 | #include <asm/segment.h> |
1558 | #include "sd.h" |
1559 | #include <scsi/scsi_ioctl.h> |
1560 | |
1561 | int seagate_st0x_biosparam(Disk * disk, kdev_t dev, int* ip) { |
1562 | unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page; |
1563 | int *sizes, result, formatted_sectors, total_sectors; |
1564 | int cylinders, heads, sectors; |
1565 | int capacity; |
1566 | |
1567 | /* |
1568 | * Only SCSI-I CCS drives and later implement the necessary mode sense |
1569 | * pages. |
1570 | */ |
1571 | |
1572 | if (disk->device->scsi_level < 2) |
1573 | return -1; |
1574 | |
1575 | sizes = (int *) buf; |
1576 | data = (unsigned char *) (sizes + 2); |
1577 | |
1578 | cmd[0] = MODE_SENSE0x1a; |
1579 | cmd[1] = (disk->device->lun << 5) & 0xe5; |
1580 | cmd[2] = 0x04; /* Read page 4, rigid disk geometry page current values */ |
1581 | cmd[3] = 0; |
1582 | cmd[4] = 255; |
1583 | cmd[5] = 0; |
1584 | |
1585 | /* |
1586 | * We are transferring 0 bytes in the out direction, and expect to get back |
1587 | * 24 bytes for each mode page. |
1588 | */ |
1589 | |
1590 | sizes[0] = 0; |
1591 | sizes[1] = 256; |
1592 | |
1593 | memcpy (data, cmd, 6)(__builtin_constant_p(6) ? __constant_memcpy((data),(cmd),(6) ) : __memcpy((data),(cmd),(6))); |
1594 | |
1595 | if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND1, (void *) buf))) { |
1596 | /* |
1597 | * The mode page lies beyond the MODE SENSE header, with length 4, and |
1598 | * the BLOCK DESCRIPTOR, with length header[3]. |
1599 | */ |
1600 | |
1601 | page = data + 4 + data[3]; |
1602 | heads = (int) page[5]; |
1603 | cylinders = (page[2] << 16) | (page[3] << 8) | page[4]; |
1604 | |
1605 | cmd[2] = 0x03; /* Read page 3, format page current values */ |
1606 | memcpy (data, cmd, 6)(__builtin_constant_p(6) ? __constant_memcpy((data),(cmd),(6) ) : __memcpy((data),(cmd),(6))); |
1607 | |
1608 | if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND1, (void *) buf))) { |
1609 | page = data + 4 + data[3]; |
1610 | sectors = (page[10] << 8) | page[11]; |
1611 | |
1612 | |
1613 | /* |
1614 | * Get the total number of formatted sectors from the block descriptor, |
1615 | * so we can tell how many are being used for alternates. |
1616 | */ |
1617 | |
1618 | formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) | |
1619 | data[4 + 3] ; |
1620 | |
1621 | total_sectors = (heads * cylinders * sectors); |
1622 | |
1623 | /* |
1624 | * Adjust the real geometry by subtracting |
1625 | * (spare sectors / (heads * tracks)) cylinders from the number of cylinders. |
1626 | * |
1627 | * It appears that the CE cylinder CAN be a partial cylinder. |
1628 | */ |
1629 | |
1630 | |
1631 | printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n", |
1632 | hostno, heads, cylinders, sectors, total_sectors, formatted_sectors); |
1633 | |
1634 | if (!heads || !sectors || !cylinders) |
1635 | result = -1; |
1636 | else |
1637 | cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors)); |
1638 | |
1639 | /* |
1640 | * Now, we need to do a sanity check on the geometry to see if it is |
1641 | * BIOS compatible. The maximum BIOS geometry is 1024 cylinders * |
1642 | * 256 heads * 64 sectors. |
1643 | */ |
1644 | |
1645 | if ((cylinders > 1024) || (sectors > 64)) { |
1646 | /* The Seagate's seem to have some mapping |
1647 | * Multiple heads * sectors * cyl to get capacity |
1648 | * Then start rounding down. */ |
1649 | capacity = heads * sectors * cylinders; |
1650 | sectors = 17; /* Old MFM Drives use this, so does the Seagate */ |
1651 | heads = 2; |
1652 | capacity = capacity / sectors; |
1653 | while (cylinders > 1024) |
1654 | { |
1655 | heads *= 2; /* For some reason, they go in multiples */ |
1656 | cylinders = capacity / heads; |
1657 | } |
1658 | } |
1659 | ip[0] = heads; |
1660 | ip[1] = sectors; |
1661 | ip[2] = cylinders; |
1662 | |
1663 | /* |
1664 | * There should be an alternate mapping for things the seagate doesn't |
1665 | * understand, but I couldn't say what it is with reasonable certainty. |
1666 | */ |
1667 | |
1668 | } |
1669 | } |
1670 | |
1671 | return result; |
1672 | } |
1673 | |
1674 | #ifdef MODULE |
1675 | /* Eventually this will go into an include file, but this will be later */ |
1676 | Scsi_Host_Template driver_template = SEAGATE_ST0X{ ((void *) 0), ((void *) 0), ((void *) 0), seagate_st0x_proc_info , ((void *) 0), seagate_st0x_detect, ((void *) 0), seagate_st0x_info , seagate_st0x_command, seagate_st0x_queue_command, seagate_st0x_abort , seagate_st0x_reset, ((void *) 0), seagate_st0x_biosparam, 1 , 7, 0xff, 1, 0, 0, 0}; |
1677 | |
1678 | #include "scsi_module.c" |
1679 | #endif |