1 /*
2 * seagate.c Copyright (C) 1992 Drew Eckhardt
3 * low level scsi driver for ST01/ST02 by
4 * Drew Eckhardt
5 *
6 * <drew@colorado.edu>
7 */
8
9 #include <linux/config.h>
10
11 #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
12 #include <asm/io.h>
13 #include <asm/system.h>
14 #include <linux/sched.h>
15 #include "seagate.h"
16 #include "scsi.h"
17 #include "hosts.h"
18
19 extern void seagate_intr(void);
20 static int internal_command(unsigned char target, const void *cmnd,
21 void *buff, int bufflen, int reselect);
22 void (*do_seagate)(void) = NULL;
23
24 static int incommand; /*
25 set if arbitration has finished and we are
26 in some command phase.
27 */
28
29 static void *base_address = NULL; /*
30 Where the card ROM starts,
31 used to calculate memory mapped
32 register location.
33 */
34 static volatile int abort_confirm = 0;
35
36 static volatile void *st0x_cr_sr; /*
37 control register write,
38 status register read.
39 256 bytes in length.
40
41 Read is status of SCSI BUS,
42 as per STAT masks.
43
44 */
45
46
47 static volatile void *st0x_dr; /*
48 data register, read write
49 256 bytes in length.
50 */
51
52
53 static volatile int st0x_aborted=0; /*
54 set when we are aborted, ie by a time out, etc.
55 */
56
57 /*
58 In theory, we have a nice auto
59 detect routine - but this
60 overides it.
61 */
62
63
64 #define retcode(result) (((result) << 16) | (message << 8) | status)
65 #define STATUS (*(unsigned char *) st0x_cr_sr)
66 #define CONTROL STATUS
67 #define DATA (*(unsigned char *) st0x_dr)
68
69 #ifndef OVERRIDE
70 static const char * seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000,
71 (char *) 0xdc000, (char *) 0xde000};
72 typedef struct
73 {
74 char *signature ;
75 unsigned offset;
76 unsigned length;
77 } Signature;
78
79 static const Signature signatures[] = {
80 #ifdef CONFIG_SCSI_SEAGATE
81 {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40},
82
83 /*
84 The following two lines are NOT mistakes. One detects
85 ROM revision 3.0.0, the other 3.2. Since seagate
86 has only one type of SCSI adapter, and this is not
87 going to change, the "SEAGATE" and "SCSI" together
88 are probably "good enough"
89 */
90
91 {"SEAGATE SCSI BIOS ",16, 17},
92 {"SEAGATE SCSI BIOS ",17, 17},
93 #endif
94
95 /*
96 This is for the Future Domain 88x series. I've been told that
97 the Seagate controllers are just repackages of these, and seeing
98 early seagate BIOS bearing the Future Domain copyright,
99 I believe it.
100 */
101
102 #ifdef CONFIG_SCSI_FD_88x
103 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 5, 46},
104 #endif
105 }
106 ;
107 /*
108 Note that the last signature handles BIOS revisions 3.0.0 and
109 3.2 - the real ID's are
110
111 SEAGATE SCSI BIOS REVISION 3.0.0
112 SEAGATE SCSI BIOS REVISION 3.2
113
114 */
115
116 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
117 #endif
118
119 /*
120 * hostno stores the hostnumber, as told to us by the init routine.
121 */
122
123 static int hostno = -1;
124
125 int seagate_st0x_detect (int hostnum)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
126 {
127 #ifndef OVERRIDE
128 int i,j;
129 #endif
130
131 /*
132 * First, we try for the manual override.
133 */
134 #ifdef DEBUG
135 printk("Autodetecting seagate ST0x\n");
136 #endif
137
138 if (hostno != -1)
139 {
140 printk ("ERROR : seagate_st0x_detect() called twice.\n");
141 return 0;
142 }
143
144 base_address = NULL;
145 #ifdef OVERRIDE
146 base_address = (void *) OVERRIDE;
147 #ifdef DEBUG
148 printk("Base address overridden to %x\n", base_address);
149 #endif
150 #else
151 /*
152 * To detect this card, we simply look for the signature
153 * from the BIOS version notice in all the possible locations
154 * of the ROM's. This has a nice sideeffect of not trashing
155 * any register locations that might be used by something else.
156 */
157
158 for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
159 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
160 if (!memcmp ((void *) (seagate_bases[i] +
161 signatures[j].offset), (void *) signatures[j].signature,
162 signatures[j].length))
163 base_address = (void *) seagate_bases[i];
164 #endif
165
166 if (base_address)
167 {
168 st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00);
169 st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
170 #ifdef DEBUG
171 printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
172 #endif
173 hostno = hostnum;
174
175 /*
176 * At all times, we will use IRQ 5.
177 */
178
179 #if 1
180 set_intr_gate (0x25, seagate_intr);
181 __asm__("
182 inb $0x21, %%al
183 andb $0xdf, %%al
184 outb %%al, $0x21"::);
185 #endif
186 return -1;
187 }
188 else
189 {
190 #ifdef DEBUG
191 printk("ST0x not detected.\n");
192 #endif
193 return 0;
194 }
195 }
196
197 char *seagate_st0x_info(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
198 {
199 static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
200 "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/07/24 06:27:38 root Exp root $\n";
201 return buffer;
202 }
203
204 /*
205 * These are our saved pointers for the outstanding command that is
206 * waiting for a reconnect
207 */
208
209 static unsigned char current_target;
210 static unsigned char *current_cmnd, *current_data;
211 static int current_bufflen;
212 static void (*done_fn)(int, int) = NULL;
213
214 /*
215 * These control weather or not disconnect / reconnect will be attempted,
216 * or are being attempted.
217 */
218
219 #define NO_RECONNECT 0
220 #define RECONNECT_NOW 1
221 #define CAN_RECONNECT 2
222
223 /*
224 * This determines if we are expecting to reconnect or not.
225 */
226
227 static int should_reconnect = 0;
228
229 void seagate_unexpected_intr (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
230 {
231 printk("scsi%d: unexpected interrupt.\n", hostno);
232 }
233
234 /*
235 * The seagate_reconnect_intr routine is called when a target reselects the
236 * host adapter. This occurs on the interrupt triggered by the target
237 * asserting SEL.
238 */
239
240 void seagate_reconnect_intr (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
241 {
242 int temp;
243
244 #if (DEBUG & PHASE_RESELECT)
245 printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
246 #endif
247
248 if (!should_reconnect)
249 seagate_unexpected_intr();
250 else
251 {
252 should_reconnect = 0;
253
254 #if (DEBUG & PHASE_RESELECT)
255 printk("scsi%d : internal_command("
256 "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
257 current_target, current_data, current_bufflen);
258 #endif
259
260 temp = internal_command (current_target,
261 current_cmnd, current_data, current_bufflen,
262 RECONNECT_NOW);
263
264 if (msg_byte(temp) != DISCONNECT)
265 {
266 if (done_fn)
267 {
268 #if (DEBUG & PHASE_RESELECT)
269 printk("scsi%d : done_fn(%d,%08x)", hostno,
270 hostno, temp);
271 #endif
272 done_fn (hostno, temp);
273 }
274 else
275 printk("done_fn() not defined.\n");
276 }
277 }
278 }
279
280 /*
281 * The seagate_st0x_queue_command() function provides a queued interface
282 * to the seagate SCSI driver. Basically, it just passes control onto the
283 * seagate_command() function, after fixing it so that the done_fn()
284 * is set to the one passed to the function.
285 */
286
287 int seagate_st0x_queue_command (unsigned char target, const void *cmnd,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
288 void *buff, int bufflen, void (*fn)(int,
289 int))
290 {
291 int result;
292
293 done_fn = fn;
294 current_target = target;
295 (const void *) current_cmnd = cmnd;
296 current_data = buff;
297 current_bufflen = bufflen;
298
299 result = internal_command (target, cmnd, buff, bufflen,
300 CAN_RECONNECT);
301 if (msg_byte(result) == DISCONNECT)
302 return 0;
303 else
304 {
305 done_fn (hostno, result);
306 return 1;
307 }
308 }
309
310 int seagate_st0x_command (unsigned char target, const void *cmnd,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
311 void *buff, int bufflen)
312 {
313 return internal_command (target, cmnd, buff, bufflen,
314 (int) NO_RECONNECT);
315 }
316
317 static int internal_command(unsigned char target, const void *cmnd,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
318 void *buff, int bufflen, int reselect)
319 {
320 int len;
321 unsigned char *data;
322 int clock;
323 int temp;
324
325
326 #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))
327 int i;
328 #endif
329
330 #if (DEBUG & PHASE_ETC)
331 int phase=0, newphase;
332 #endif
333
334 int done = 0;
335 unsigned char status = 0;
336 unsigned char message = 0;
337 register unsigned char status_read;
338
339 do_seagate = seagate_unexpected_intr;
340
341 len=bufflen;
342 data=(unsigned char *) buff;
343
344 incommand = 0;
345 st0x_aborted = 0;
346
347 #if (DEBUG & PRINT_COMMAND)
348 printk ("scsi%d : target = %d, command = ", hostno, target);
349 for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
350 printk("%02x ", ((unsigned char *) cmnd)[i]);
351 printk("\n");
352 #endif
353
354 #if (DEBUG & PHASE_RESELECT)
355 switch (reselect)
356 {
357 case RECONNECT_NOW :
358 printk("scsi%d : reconnecting\n", hostno);
359 break;
360 case CAN_RECONNECT :
361 printk("scsi%d : allowed to reconnect\n", hostno);
362 break;
363 default :
364 printk("scsi%d : not allowed to reconnect\n", hostno);
365 }
366 #endif
367
368
369 if (target > 6)
370 {
371 if (reselect == RECONNECT_NOW)
372 eoi();
373 return DID_BAD_TARGET;
374 }
375
376 /*
377 * We work it differently depending on if this is is "the first time,"
378 * or a reconnect. If this is a reselct phase, then SEL will
379 * be asserted, and we must skip selection / arbitration phases.
380 */
381
382 if (reselect == RECONNECT_NOW)
383 {
384 #if (DEBUG & PHASE_RESELECT)
385 printk("scsi%d : phase RESELECT \n", hostno);
386 #endif
387
388 /*
389 * At this point, we should find the logical or of our ID and the original
390 * target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
391 *
392 * After ARBITRATION phase is completed, only SEL, BSY, and the
393 * target ID are asserted. A valid initator ID is not on the bus
394 * until IO is asserted, so we must wait for that.
395 */
396
397 for (clock = jiffies + 10, temp = 0; (jiffies < clock) &&
398 !(STATUS & STAT_IO););
399
400 if (jiffies >= clock)
401 {
402 #if (DEBUG & PHASE_RESELECT)
403 printk("scsi%d : RESELECT timed out while waiting for IO .\n",
404 hostno);
405 #endif
406 eoi();
407 return (DID_BAD_INTR << 16);
408 }
409
410 /*
411 * After I/O is asserted by the target, we can read our ID and its
412 * ID off of the BUS.
413 */
414
415 if (!((temp = DATA) & 0x80))
416 {
417 #if (DEBUG & PHASE_RESELECT)
418 printk("scsi%d : detected reconnect request to different target.\n"
419 "\tData bus = %d\n", hostno, temp);
420 #endif
421 eoi();
422 return (DID_BAD_INTR << 16);
423 }
424
425 if (!(temp & (1 << current_target)))
426 {
427 printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
428 hostno, temp);
429 eoi();
430 return (DID_BAD_INTR << 16);
431 }
432 data=current_data; /* WDE add */
433 cmnd=current_cmnd; /* WDE add */
434 len=current_bufflen; /* WDE add */
435
436 /*
437 * We have determined that we have been selected. At this point,
438 * we must respond to the reselection by asserting BSY ourselves
439 */
440
441 CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
442
443 /*
444 * The target will drop SEL, and raise BSY, at which time we must drop
445 * BSY.
446 */
447
448 for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL););
449
450 if (jiffies >= clock)
451 {
452 CONTROL = (BASE_CMD | CMD_INTR);
453 #if (DEBUG & PHASE_RESELECT)
454 printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
455 hostno);
456 #endif
457 eoi();
458 return (DID_BAD_INTR << 16);
459 }
460
461 CONTROL = BASE_CMD;
462
463 /*
464 * At this point, we have connected with the target and can get
465 * on with our lives.
466 */
467 eoi();
468 }
469 else
470 {
471 #if (DEBUG & PHASE_BUS_FREE)
472 printk ("scsi%d : phase = BUS FREE \n", hostno);
473 #endif
474
475 /*
476 * BUS FREE PHASE
477 *
478 * On entry, we make sure that the BUS is in a BUS FREE
479 * phase, by insuring that both BSY and SEL are low for
480 * at least one bus settle delay. Several reads help
481 * eliminate wire glitch.
482 */
483
484 clock = jiffies + ST0X_BUS_FREE_DELAY;
485
486 while (((STATUS | STATUS | STATUS) &
487 (STAT_BSY | STAT_SEL)) &&
488 (!st0x_aborted) && (jiffies < clock));
489
490 if (jiffies > clock)
491 return retcode(DID_BUS_BUSY);
492 else if (st0x_aborted)
493 return retcode(st0x_aborted);
494
495 /*
496 * Bus free has been detected, within BUS settle. I used to
497 * support an arbitration phase - however, on the Seagate, this
498 * degraded performance by a factor > 10 - so it is no more.
499 */
500
501 /*
502 * SELECTION PHASE
503 *
504 * Now, we select the disk, giving it the SCSI ID at data
505 * and a command of PARITY if necessary, and we raise SEL.
506 */
507
508 #if (DEBUG & PHASE_SELECTION)
509 printk("scsi%d : phase = SELECTION\n", hostno);
510 #endif
511
512 clock = jiffies + ST0X_SELECTION_DELAY;
513
514 /*
515 * If we wish to disconnect, we should request a MESSAGE OUT
516 * at this point. Technically, ATTN should be raised before
517 * SEL = true and BSY = false (from arbitration), but I think this
518 * should do.
519 */
520 if (reselect)
521 CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
522 CMD_ATTN;
523
524 /*
525 * We must assert both our ID and our target's ID on the bus.
526 */
527 DATA = (unsigned char) ((1 << target) | 0x80);
528
529 /*
530 * If we are allowing ourselves to reconnect, then I will keep
531 * ATTN raised so we get MSG OUT.
532 */
533 CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
534 (reselect ? CMD_ATTN : 0);
535
536 /*
537 * When the SCSI device decides that we're gawking at it, it will
538 * respond by asserting BUSY on the bus.
539 */
540 while (!((status_read = STATUS) & STAT_BSY) &&
541 (jiffies < clock) && !st0x_aborted)
542
543 #if (DEBUG & PHASE_SELECTION)
544 {
545 temp = clock - jiffies;
546
547 if (!(jiffies % 5))
548 printk("seagate_st0x_timeout : %d \r",temp);
549
550 }
551 printk("Done. \n\r");
552 printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
553 hostno, status_read, temp, st0x_aborted);
554 #else
555 ;
556 #endif
557
558
559 if ((jiffies > clock) || (!st0x_aborted &&
560 !(status_read & STAT_BSY)))
561 {
562 #if (DEBUG & PHASE_SELECT)
563 printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
564 hostno, target, STATUS);
565 #endif
566 return retcode(DID_NO_CONNECT);
567 }
568
569 /*
570 * If we have been aborted, and we have a command in progress, IE the
571 * target still has BSY asserted, then we will reset the bus, and
572 * notify the midlevel driver to expect sense.
573 */
574
575 if (st0x_aborted)
576 {
577 CONTROL = BASE_CMD;
578 if (STATUS & STAT_BSY)
579 {
580 seagate_st0x_reset();
581 return retcode(DID_RESET);
582 }
583 return retcode(st0x_aborted);
584 }
585 }
586
587 CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
588 ((reselect == CAN_RECONNECT) ? CMD_ATTN : 0) ;
589
590 /*
591 * INFORMATION TRANSFER PHASE
592 *
593 * The nasty looking read / write inline assembler loops we use for
594 * DATAIN and DATAOUT phases are approximately 4-5 times as fast as
595 * the 'C' versions - since we're moving 1024 bytes of data, this
596 * really adds up.
597 */
598
599 #if (DEBUG & PHASE_ETC)
600 printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
601 #endif
602
603 incommand = 1;
604
605
606 /*
607 * Now, we poll the device for status information,
608 * and handle any requests it makes. Note that since we are unsure of
609 * how much data will be flowing across the system, etc and cannot
610 * make reasonable timeouts, that we will instead have the midlevel
611 * driver handle any timeouts that occur in this phase.
612 */
613
614 while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
615 {
616 #ifdef PARITY
617 if (status_read & STAT_PARITY)
618 {
619 done = 1;
620 st0x_aborted = DID_PARITY;
621 }
622 #endif
623
624 if (status_read & STAT_REQ)
625 {
626 #if (DEBUG & PHASE_ETC)
627 if ((newphase = (status_read & REQ_MASK)) != phase)
628 {
629 phase = newphase;
630 switch (phase)
631 {
632 case REQ_DATAOUT:
633 printk("scsi%d : phase = DATA OUT\n",
634 hostno);
635 break;
636 case REQ_DATAIN :
637 printk("scsi%d : phase = DATA IN\n",
638 hostno);
639 break;
640 case REQ_CMDOUT :
641 printk("scsi%d : phase = COMMAND OUT\n",
642 hostno);
643 break;
644 case REQ_STATIN :
645 printk("scsi%d : phase = STATUS IN\n",
646 hostno);
647 break;
648 case REQ_MSGOUT :
649 printk("scsi%d : phase = MESSAGE OUT\n",
650 hostno);
651 break;
652 case REQ_MSGIN :
653 printk("scsi%d : phase = MESSAGE IN\n",
654 hostno);
655 break;
656 default :
657 printk("scsi%d : phase = UNKNOWN\n",
658 hostno);
659 st0x_aborted = 1;
660 done = 1;
661 }
662 }
663 #endif
664
665 switch (status_read & REQ_MASK)
666 {
667 case REQ_DATAOUT :
668
669 /*
670 * We loop as long as we are in a data out phase, there is data to send,
671 * and BSY is still active.
672 */
673 __asm__ ("
674
675 /*
676 Local variables :
677 len = ecx
678 data = esi
679 st0x_cr_sr = ebx
680 st0x_dr = edi
681
682 Test for any data here at all.
683 */
684 movl %0, %%esi /* local value of data */
685 movl %1, %%ecx /* local value of len */
686 orl %%ecx, %%ecx
687 jz 2f
688
689 cld
690
691 movl _st0x_cr_sr, %%ebx
692 movl _st0x_dr, %%edi
693
694 1: movb (%%ebx), %%al
695 /*
696 Test for BSY
697 */
698
699 test $1, %%al
700 jz 2f
701
702 /*
703 Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
704 */
705 test $0xe, %%al
706 jnz 2f
707 /*
708 Test for REQ
709 */
710 test $0x10, %%al
711 jz 1b
712 lodsb
713 movb %%al, (%%edi)
714 loop 1b
715
716 2:
717 movl %%esi, %2
718 movl %%ecx, %3
719 ":
720 /* output */
721 "=r" (data), "=r" (len) :
722 /* input */
723 "0" (data), "1" (len) :
724 /* clobbered */
725 "ebx", "ecx", "edi", "esi");
726
727 break;
728
729 case REQ_DATAIN :
730 /*
731 * We loop as long as we are in a data in phase, there is room to read,
732 * and BSY is still active
733 */
734
735 __asm__ ("
736 /*
737 Local variables :
738 ecx = len
739 edi = data
740 esi = st0x_cr_sr
741 ebx = st0x_dr
742
743 Test for room to read
744 */
745
746 movl %0, %%edi /* data */
747 movl %1, %%ecx /* len */
748 orl %%ecx, %%ecx
749 jz 2f
750
751 cld
752 movl _st0x_cr_sr, %%esi
753 movl _st0x_dr, %%ebx
754
755 1: movb (%%esi), %%al
756 /*
757 Test for BSY
758 */
759
760 test $1, %%al
761 jz 2f
762
763 /*
764 Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
765 */
766 movb $0xe, %%ah
767 andb %%al, %%ah
768 cmpb $0x04, %%ah
769 jne 2f
770
771 /*
772 Test for REQ
773 */
774 test $0x10, %%al
775 jz 1b
776
777 movb (%%ebx), %%al
778 stosb
779 loop 1b
780
781 2: movl %%edi, %2 /* data */
782 movl %%ecx, %3 /* len */
783 ":
784 /* output */
785 "=r" (data), "=r" (len) :
786 /* input */
787 "0" (data), "1" (len) :
788 /* clobbered */
789 "ebx", "ecx", "edi", "esi");
790 break;
791
792 case REQ_CMDOUT :
793 while (((status_read = STATUS) & STAT_BSY) &&
794 ((status_read & REQ_MASK) == REQ_CMDOUT))
795 if (status_read & STAT_REQ)
796 DATA = *(unsigned char *) cmnd ++;
797 break;
798
799 case REQ_STATIN :
800 status = DATA;
801 break;
802
803 case REQ_MSGOUT :
804 /*
805 * We can only have sent a MSG OUT if we requested to do this
806 * by raising ATTN. So, we must drop ATTN.
807 */
808
809 CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
810 /*
811 * If we are reconecting, then we must send an IDENTIFY message in
812 * response to MSGOUT.
813 */
814 if (reselect)
815 {
816 DATA = IDENTIFY(1,0);
817 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
818 printk("scsi%d : sent IDENTIFY message.\n", hostno);
819 #endif
820 }
821 else
822 {
823 DATA = MESSAGE_REJECT;
824
825 #if (DEBUG & PHASE_MSGOUT)
826 printk("scsi%d : sent MESSAGE REJECT message.\n", hostno);
827 #endif
828 }
829 break;
830
831 case REQ_MSGIN :
832 switch (message = DATA)
833 {
834 case DISCONNECT :
835 should_reconnect = 1;
836 current_data = data; /* WDE add */
837 current_bufflen = len; /* WDE add */
838 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
839 printk("scsi%d : disconnected.\n", hostno);
840 done=1;
841 break;
842 #endif
843 case COMMAND_COMPLETE :
844 #if (DEBUG & PHASE_MSGIN)
845 printk("scsi%d : command complete.\n", hostno);
846 done=1;
847 break;
848 #endif
849 case ABORT :
850 #if (DEBUG & PHASE_MSGIN)
851 printk("scsi%d : abort message.\n", hostno);
852 #endif
853 done=1;
854 break;
855 case SAVE_POINTERS :
856 current_data = data; /* WDE mod */
857 current_bufflen = len; /* WDE add */
858 #if (DEBUG & PHASE_MSGIN)
859 printk("scsi%d : pointers saved.\n", hostno);
860 #endif
861 break;
862 case RESTORE_POINTERS:
863 data=current_data; /* WDE mod */
864 cmnd=current_cmnd;
865 #if (DEBUG & PHASE_MSGIN)
866 printk("scsi%d : pointers restored.\n", hostno);
867 #endif
868 break;
869 default:
870
871 /*
872 * IDENTIFY distinguishes itself from the other messages by setting the
873 * high byte.
874 */
875
876 if (message & 0x80)
877 {
878 #if (DEBUG & PHASE_MSGIN)
879 printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
880 hostno, target, message & 7);
881 #endif
882 }
883 else
884 {
885
886 #if (DEBUG & PHASE_MSGIN)
887 printk("scsi%d : unknown message %d from target %d.\n",
888 hostno, message, target);
889 #endif
890 }
891 }
892 break;
893
894 default :
895 printk("scsi%d : unknown phase.\n", hostno);
896 st0x_aborted = DID_ERROR;
897 }
898 } /* while ends */
899 } /* if ends */
900
901 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
902 printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
903 #endif
904
905 #if (DEBUG & PHASE_EXIT)
906 printk("Buffer : \n");
907 for (i = 0; i < 20; ++i)
908 printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */
909 printk("\n");
910 printk("Status = %02x, message = %02x\n", status, message);
911 #endif
912
913
914 if (st0x_aborted)
915 {
916 if (STATUS & STAT_BSY)
917 {
918 seagate_st0x_reset();
919 st0x_aborted = DID_RESET;
920 }
921 abort_confirm = 1;
922 }
923
924 if (should_reconnect)
925 {
926 #if (DEBUG & PHASE_RESELECT)
927 printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
928 hostno);
929 #endif
930 do_seagate = seagate_reconnect_intr;
931 CONTROL = BASE_CMD | CMD_INTR ;
932 }
933 else
934 CONTROL = BASE_CMD;
935
936 return retcode (st0x_aborted);
937 }
938
939 int seagate_st0x_abort (int code)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
940 {
941 if (code)
942 st0x_aborted = code;
943 else
944 st0x_aborted = DID_ABORT;
945
946 return 0;
947 }
948
949 /*
950 the seagate_st0x_reset function resets the SCSI bus
951 */
952
953 int seagate_st0x_reset (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
954 {
955 unsigned clock;
956 /*
957 No timeouts - this command is going to fail because
958 it was reset.
959 */
960
961 #ifdef DEBUG
962 printk("In seagate_st0x_reset()\n");
963 #endif
964
965
966 /* assert RESET signal on SCSI bus. */
967
968 CONTROL = BASE_CMD | CMD_RST;
969 clock=jiffies+2;
970
971
972 /* Wait. */
973
974 while (jiffies < clock);
975
976 CONTROL = BASE_CMD;
977
978 st0x_aborted = DID_RESET;
979
980 #ifdef DEBUG
981 printk("SCSI bus reset.\n");
982 #endif
983 return 0;
984 }
985
986 #endif
987