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