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