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