This source file includes following definitions.
- borken_init
- borken_wait
- seagate_st0x_detect
- seagate_st0x_info
- seagate_reconnect_intr
- seagate_st0x_queue_command
- seagate_st0x_command
- internal_command
- seagate_st0x_abort
- seagate_st0x_reset
- seagate_st0x_biosparam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include <linux/config.h>
39
40 #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
41 #include <asm/io.h>
42 #include <asm/system.h>
43 #include <linux/signal.h>
44 #include <linux/sched.h>
45 #include "../blk.h"
46 #include "scsi.h"
47 #include "hosts.h"
48 #include "seagate.h"
49 #include "constants.h"
50
51
52 #ifndef IRQ
53 #define IRQ 5
54 #endif
55
56 #if (defined(FAST32) && !defined(FAST))
57 #define FAST
58 #endif
59
60 #if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
61 #define SLOW_HANDSHAKE
62 #endif
63
64 #if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
65 #define SLOW_RATE 50
66 #endif
67
68
69 #if defined(LINKED)
70 #undef LINKED
71 #endif
72
73 static int internal_command(unsigned char target, unsigned char lun,
74 const void *cmnd,
75 void *buff, int bufflen, int reselect);
76
77 static int incommand;
78
79
80
81
82 static void *base_address = NULL;
83
84
85
86
87 static volatile int abort_confirm = 0;
88
89 static volatile void *st0x_cr_sr;
90
91
92
93
94
95
96
97
98
99
100 static volatile void *st0x_dr;
101
102
103
104
105
106 static volatile int st0x_aborted=0;
107
108
109
110
111
112
113
114
115 static unsigned char controller_type;
116
117 #define retcode(result) (((result) << 16) | (message << 8) | status)
118 #define STATUS (*(volatile unsigned char *) st0x_cr_sr)
119 #define CONTROL STATUS
120 #define DATA (*(volatile unsigned char *) st0x_dr)
121
122
123 #ifndef OVERRIDE
124 static const char * seagate_bases[] = {
125 (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
126 (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
127 };
128
129 typedef struct {
130 char *signature ;
131 unsigned offset;
132 unsigned length;
133 unsigned char type;
134 } Signature;
135
136 static const Signature signatures[] = {
137 #ifdef CONFIG_SCSI_SEAGATE
138 {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
139
140
141
142
143
144
145
146
147
148 {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
149 {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
150
151
152
153
154
155
156
157
158 {"FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88",5,48, FD},
159 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
160 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
161 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
162 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
163 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
164 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
165 #endif
166 }
167 ;
168
169
170
171
172
173
174
175
176
177 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
178 #endif
179
180
181
182
183
184 static int hostno = -1;
185 static void seagate_reconnect_intr(int);
186
187 #ifdef FAST
188 static int fast = 1;
189 #endif
190
191 #ifdef SLOW_HANDSHAKE
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 static int borken_calibration = 0;
230 static void borken_init (void) {
231 register int count = 0, start = jiffies + 1, stop = start + 25;
232
233 while (jiffies < start);
234 for (;jiffies < stop; ++count);
235
236
237
238
239
240
241 borken_calibration = (count * 4) / (SLOW_RATE*1024);
242
243 if (borken_calibration < 1)
244 borken_calibration = 1;
245 #if (DEBUG & DEBUG_BORKEN)
246 printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n",
247 hostno, BORKEN_RATE, borken_calibration);
248 #endif
249 }
250
251 static inline void borken_wait(void) {
252 register int count;
253 for (count = borken_calibration; count && (STATUS & STAT_REQ);
254 --count);
255 if (count)
256 #if (DEBUG & DEBUG_BORKEN)
257 printk("scsi%d : borken timeout\n", hostno);
258 #else
259 ;
260 #endif
261 }
262
263 #endif
264
265 int seagate_st0x_detect (int hostnum)
266 {
267 #ifndef OVERRIDE
268 int i,j;
269 #endif
270 static struct sigaction seagate_sigaction = {
271 &seagate_reconnect_intr,
272 0,
273 SA_INTERRUPT,
274 NULL
275 };
276
277
278
279
280 #ifdef DEBUG
281 printk("Autodetecting seagate ST0x\n");
282 #endif
283
284 if (hostno != -1)
285 {
286 printk ("ERROR : seagate_st0x_detect() called twice.\n");
287 return 0;
288 }
289
290 base_address = NULL;
291 #ifdef OVERRIDE
292 base_address = (void *) OVERRIDE;
293
294
295 #ifdef CONTROLLER
296 controller_type = CONTROLLER;
297 #else
298 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
299 #endif
300 #ifdef DEBUG
301 printk("Base address overridden to %x, controller type is %s\n",
302 base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
303 #endif
304 #else
305
306
307
308
309
310
311
312
313
314
315 for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
316 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
317 if (!memcmp ((void *) (seagate_bases[i] +
318 signatures[j].offset), (void *) signatures[j].signature,
319 signatures[j].length)) {
320 base_address = (void *) seagate_bases[i];
321 controller_type = signatures[j].type;
322 }
323 #endif
324
325 scsi_hosts[hostnum].this_id = (controller_type == SEAGATE) ? 7 : 6;
326
327 if (base_address)
328 {
329 st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00));
330 st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
331 #ifdef DEBUG
332 printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
333 #endif
334
335
336
337
338 hostno = hostnum;
339 if (irqaction(IRQ, &seagate_sigaction)) {
340 printk("scsi%d : unable to allocate IRQ%d\n",
341 hostno, IRQ);
342 return 0;
343 }
344 #ifdef SLOW_HANDSHAKE
345 borken_init();
346 #endif
347
348 return -1;
349 }
350 else
351 {
352 #ifdef DEBUG
353 printk("ST0x not detected.\n");
354 #endif
355 return 0;
356 }
357 }
358
359 const char *seagate_st0x_info(void) {
360 static char buffer[256];
361 sprintf(buffer, "scsi%d : %s at irq %d address %p options :"
362 #ifdef ARBITRATE
363 " ARBITRATE"
364 #endif
365 #ifdef SLOW_HANDSHAKE
366 " SLOW_HANDSHAKE"
367 #endif
368 #ifdef FAST
369 #ifdef FAST32
370 " FAST32"
371 #else
372 " FAST"
373 #endif
374 #endif
375
376 #ifdef LINKED
377 " LINKED"
378 #endif
379 "\n", hostno, (controller_type == SEAGATE) ? "seagate" :
380 "FD TMC-950", IRQ, base_address);
381 return buffer;
382 }
383
384
385
386
387
388
389 static unsigned char current_target, current_lun;
390 static unsigned char *current_cmnd, *current_data;
391 static int current_nobuffs;
392 static struct scatterlist *current_buffer;
393 static int current_bufflen;
394
395 #ifdef LINKED
396
397
398
399
400
401
402
403 static int linked_connected = 0;
404 static unsigned char linked_target, linked_lun;
405 #endif
406
407
408 static void (*done_fn)(Scsi_Cmnd *) = NULL;
409 static Scsi_Cmnd * SCint = NULL;
410
411
412
413
414
415
416 #define NO_RECONNECT 0
417 #define RECONNECT_NOW 1
418 #define CAN_RECONNECT 2
419
420 #ifdef LINKED
421
422
423
424
425
426
427
428 #define LINKED_RIGHT 3
429 #define LINKED_WRONG 4
430 #endif
431
432
433
434
435
436 static int should_reconnect = 0;
437
438
439
440
441
442
443
444 static void seagate_reconnect_intr (int unused)
445 {
446 int temp;
447 Scsi_Cmnd * SCtmp;
448
449
450 sti();
451 #if (DEBUG & PHASE_RESELECT)
452 printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
453 #endif
454
455 if (!should_reconnect)
456 printk("scsi%d: unexpected interrupt.\n", hostno);
457 else {
458 should_reconnect = 0;
459
460 #if (DEBUG & PHASE_RESELECT)
461 printk("scsi%d : internal_command("
462 "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
463 current_target, current_data, current_bufflen);
464 #endif
465
466 temp = internal_command (current_target, current_lun,
467 current_cmnd, current_data, current_bufflen,
468 RECONNECT_NOW);
469
470 if (msg_byte(temp) != DISCONNECT) {
471 if (done_fn) {
472 #if (DEBUG & PHASE_RESELECT)
473 printk("scsi%d : done_fn(%d,%08x)", hostno,
474 hostno, temp);
475 #endif
476 if(!SCint) panic("SCint == NULL in seagate");
477 SCtmp = SCint;
478 SCint = NULL;
479 SCtmp->result = temp;
480 done_fn (SCtmp);
481 } else
482 printk("done_fn() not defined.\n");
483 }
484 }
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498 static int recursion_depth = 0;
499
500 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
501 {
502 int result, reconnect;
503 Scsi_Cmnd * SCtmp;
504
505 done_fn = done;
506 current_target = SCpnt->target;
507 current_lun = SCpnt->lun;
508 (const void *) current_cmnd = SCpnt->cmnd;
509 current_data = (unsigned char *) SCpnt->request_buffer;
510 current_bufflen = SCpnt->request_bufflen;
511 SCint = SCpnt;
512 if(recursion_depth) {
513 return 0;
514 };
515 recursion_depth++;
516 do{
517 #ifdef LINKED
518
519
520
521
522 current_cmnd[COMMAND_SIZE(current_cmnd[0])] |= 0x01;
523 if (linked_connected) {
524 #if (DEBUG & DEBUG_LINKED)
525 printk("scsi%d : using linked commands, current I_T_L nexus is ",
526 hostno);
527 #endif
528 if ((linked_target == current_target) &&
529 (linked_lun == current_lun)) {
530 #if (DEBUG & DEBUG_LINKED)
531 printk("correct\n");
532 #endif
533 reconnect = LINKED_RIGHT;
534 } else {
535 #if (DEBUG & DEBUG_LINKED)
536 printk("incorrect\n");
537 #endif
538 reconnect = LINKED_WRONG;
539 }
540 } else
541 #endif
542 reconnect = CAN_RECONNECT;
543
544
545
546
547
548 result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
549 SCint->request_bufflen,
550 reconnect);
551 if (msg_byte(result) == DISCONNECT) break;
552 SCtmp = SCint;
553 SCint = NULL;
554 SCtmp->result = result;
555 done_fn (SCtmp);
556 } while(SCint);
557 recursion_depth--;
558 return 0;
559 }
560
561 int seagate_st0x_command (Scsi_Cmnd * SCpnt) {
562 return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
563 SCpnt->request_bufflen,
564 (int) NO_RECONNECT);
565 }
566
567 static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
568 void *buff, int bufflen, int reselect) {
569 int len;
570 unsigned char *data;
571 struct scatterlist *buffer;
572 int nobuffs;
573 int clock;
574 int temp;
575 #ifdef SLOW_HANDSHAKE
576 int borken;
577 #endif
578
579
580 #if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT)
581 int transfered = 0;
582 #endif
583
584 #if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
585 (DEBUG & PHASE_EXIT))
586 int i;
587 #endif
588
589 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
590 int phase=0, newphase;
591 #endif
592
593 int done = 0;
594 unsigned char status = 0;
595 unsigned char message = 0;
596 register unsigned char status_read;
597
598 unsigned transfersize = 0, underflow = 0;
599
600 incommand = 0;
601 st0x_aborted = 0;
602
603 #ifdef SLOW_HANDSHAKE
604 borken = (int) scsi_devices[SCint->index].borken;
605 #endif
606
607 #if (DEBUG & PRINT_COMMAND)
608 printk ("scsi%d : target = %d, command = ", hostno, target);
609 print_command((unsigned char *) cmnd);
610 printk("\n");
611 #endif
612
613 #if (DEBUG & PHASE_RESELECT)
614 switch (reselect) {
615 case RECONNECT_NOW :
616 printk("scsi%d : reconnecting\n", hostno);
617 break;
618 #ifdef LINKED
619 case LINKED_RIGHT :
620 printk("scsi%d : connected, can reconnect\n", hostno);
621 break;
622 case LINKED_WRONG :
623 printk("scsi%d : connected to wrong target, can reconnect\n",
624 hostno);
625 break;
626 #endif
627 case CAN_RECONNECT :
628 printk("scsi%d : allowed to reconnect\n", hostno);
629 break;
630 default :
631 printk("scsi%d : not allowed to reconnect\n", hostno);
632 }
633 #endif
634
635
636 if (target == (controller_type == SEAGATE ? 7 : 6))
637 return DID_BAD_TARGET;
638
639
640
641
642
643
644
645 switch (reselect) {
646 case RECONNECT_NOW:
647 #if (DEBUG & PHASE_RESELECT)
648 printk("scsi%d : phase RESELECT \n", hostno);
649 #endif
650
651
652
653
654
655
656
657
658
659
660 for (clock = jiffies + 10, temp = 0; (jiffies < clock) &&
661 !(STATUS & STAT_IO););
662
663 if (jiffies >= clock)
664 {
665 #if (DEBUG & PHASE_RESELECT)
666 printk("scsi%d : RESELECT timed out while waiting for IO .\n",
667 hostno);
668 #endif
669 return (DID_BAD_INTR << 16);
670 }
671
672
673
674
675
676
677 if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
678 {
679 #if (DEBUG & PHASE_RESELECT)
680 printk("scsi%d : detected reconnect request to different target.\n"
681 "\tData bus = %d\n", hostno, temp);
682 #endif
683 return (DID_BAD_INTR << 16);
684 }
685
686 if (!(temp & (1 << current_target)))
687 {
688 printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
689 hostno, temp);
690 return (DID_BAD_INTR << 16);
691 }
692
693 buffer=current_buffer;
694 cmnd=current_cmnd;
695 data=current_data;
696 len=current_bufflen;
697 nobuffs=current_nobuffs;
698
699
700
701
702
703
704 #if 1
705 CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
706 #else
707 CONTROL = (BASE_CMD | CMD_BSY);
708 #endif
709
710
711
712
713
714
715 for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL););
716
717 if (jiffies >= clock)
718 {
719 CONTROL = (BASE_CMD | CMD_INTR);
720 #if (DEBUG & PHASE_RESELECT)
721 printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
722 hostno);
723 #endif
724 return (DID_BAD_INTR << 16);
725 }
726
727 CONTROL = BASE_CMD;
728
729
730
731
732
733 break;
734 case CAN_RECONNECT:
735
736 #ifdef LINKED
737
738
739
740
741
742
743
744 connect_loop :
745
746 #endif
747
748 #if (DEBUG & PHASE_BUS_FREE)
749 printk ("scsi%d : phase = BUS FREE \n", hostno);
750 #endif
751
752
753
754
755
756
757
758
759
760
761 clock = jiffies + ST0X_BUS_FREE_DELAY;
762
763 #if !defined (ARBITRATE)
764 while (((STATUS | STATUS | STATUS) &
765 (STAT_BSY | STAT_SEL)) &&
766 (!st0x_aborted) && (jiffies < clock));
767
768 if (jiffies > clock)
769 return retcode(DID_BUS_BUSY);
770 else if (st0x_aborted)
771 return retcode(st0x_aborted);
772 #endif
773
774 #if (DEBUG & PHASE_SELECTION)
775 printk("scsi%d : phase = SELECTION\n", hostno);
776 #endif
777
778 clock = jiffies + ST0X_SELECTION_DELAY;
779
780
781
782
783
784
785
786
787
788
789
790
791 #if defined(ARBITRATE)
792 cli();
793 CONTROL = 0;
794 DATA = (controller_type == SEAGATE) ? 0x80 : 0x40;
795 CONTROL = CMD_START_ARB;
796 sti();
797 while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
798 (jiffies < clock) && !st0x_aborted);
799
800 if (!(status_read & STAT_ARB_CMPL)) {
801 #if (DEBUG & PHASE_SELECTION)
802 if (status_read & STAT_SEL)
803 printk("scsi%d : arbitration lost\n", hostno);
804 else
805 printk("scsi%d : arbitration timeout.\n", hostno);
806 #endif
807 CONTROL = BASE_CMD;
808 return retcode(DID_NO_CONNECT);
809 };
810
811 #if (DEBUG & PHASE_SELECTION)
812 printk("scsi%d : arbitration complete\n", hostno);
813 #endif
814 #endif
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829 cli();
830 DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
831 CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
832 (reselect ? CMD_ATTN : 0);
833 sti();
834 while (!((status_read = STATUS) & STAT_BSY) &&
835 (jiffies < clock) && !st0x_aborted)
836
837 #if 0 && (DEBUG & PHASE_SELECTION)
838 {
839 temp = clock - jiffies;
840
841 if (!(jiffies % 5))
842 printk("seagate_st0x_timeout : %d \r",temp);
843
844 }
845 printk("Done. \n");
846 printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
847 hostno, status_read, temp, st0x_aborted);
848 #else
849 ;
850 #endif
851
852
853 if ((jiffies >= clock) && !(status_read & STAT_BSY))
854 {
855 #if (DEBUG & PHASE_SELECTION)
856 printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
857 hostno, target, STATUS);
858 #endif
859 return retcode(DID_NO_CONNECT);
860 }
861
862
863
864
865
866
867
868 if (st0x_aborted) {
869 CONTROL = BASE_CMD;
870 if (STATUS & STAT_BSY) {
871 printk("scsi%d : BST asserted after we've been aborted.\n",
872 hostno);
873 seagate_st0x_reset();
874 return retcode(DID_RESET);
875 }
876 return retcode(st0x_aborted);
877 }
878
879
880
881 if ((nobuffs = SCint->use_sg)) {
882 #if (DEBUG & DEBUG_SG)
883 {
884 int i;
885 printk("scsi%d : scatter gather requested, using %d buffers.\n",
886 hostno, nobuffs);
887 for (i = 0; i < nobuffs; ++i)
888 printk("scsi%d : buffer %d address = %08x length = %d\n",
889 hostno, i, buffer[i].address, buffer[i].length);
890 }
891 #endif
892
893 buffer = (struct scatterlist *) SCint->buffer;
894 len = buffer->length;
895 data = (unsigned char *) buffer->address;
896 } else {
897 #if (DEBUG & DEBUG_SG)
898 printk("scsi%d : scatter gather not requested.\n", hostno);
899 #endif
900 buffer = NULL;
901 len = SCint->request_bufflen;
902 data = (unsigned char *) SCint->request_buffer;
903 }
904
905 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
906 printk("scsi%d : len = %d\n", hostno, len);
907 #endif
908
909 break;
910 #ifdef LINKED
911 case LINKED_RIGHT:
912 break;
913 case LINKED_WRONG:
914 break;
915 #endif
916 }
917
918
919
920
921
922
923
924
925
926
927
928 CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
929 (((reselect == CAN_RECONNECT)
930 #ifdef LINKED
931 || (reselect == LINKED_WRONG)
932 #endif
933 ) ? CMD_ATTN : 0) ;
934
935
936
937
938
939
940
941
942
943
944 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
945 printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
946 #endif
947
948 incommand = 1;
949 transfersize = SCint->transfersize;
950 underflow = SCint->underflow;
951
952
953
954
955
956
957
958
959
960
961 while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
962 {
963 #ifdef PARITY
964 if (status_read & STAT_PARITY)
965 {
966 printk("scsi%d : got parity error\n", hostno);
967 st0x_aborted = DID_PARITY;
968 }
969 #endif
970
971 if (status_read & STAT_REQ)
972 {
973 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
974 if ((newphase = (status_read & REQ_MASK)) != phase)
975 {
976 phase = newphase;
977 switch (phase)
978 {
979 case REQ_DATAOUT:
980 printk("scsi%d : phase = DATA OUT\n",
981 hostno);
982 break;
983 case REQ_DATAIN :
984 printk("scsi%d : phase = DATA IN\n",
985 hostno);
986 break;
987 case REQ_CMDOUT :
988 printk("scsi%d : phase = COMMAND OUT\n",
989 hostno);
990 break;
991 case REQ_STATIN :
992 printk("scsi%d : phase = STATUS IN\n",
993 hostno);
994 break;
995 case REQ_MSGOUT :
996 printk("scsi%d : phase = MESSAGE OUT\n",
997 hostno);
998 break;
999 case REQ_MSGIN :
1000 printk("scsi%d : phase = MESSAGE IN\n",
1001 hostno);
1002 break;
1003 default :
1004 printk("scsi%d : phase = UNKNOWN\n",
1005 hostno);
1006 st0x_aborted = DID_ERROR;
1007 }
1008 }
1009 #endif
1010 switch (status_read & REQ_MASK)
1011 {
1012 case REQ_DATAOUT :
1013
1014
1015
1016
1017
1018 #ifdef FAST
1019 if (!len) {
1020 #if 0
1021 printk("scsi%d: underflow to target %d lun %d \n",
1022 hostno, target, lun);
1023 st0x_aborted = DID_ERROR;
1024 fast = 0;
1025 #endif
1026 break;
1027 }
1028
1029 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1030 #ifdef FAST32
1031 && !(transfersize % 4)
1032 #endif
1033 ) {
1034 #if (DEBUG & DEBUG_FAST)
1035 printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1036 " len = %d, data = %08x\n", hostno, SCint->underflow,
1037 SCint->transfersize, len, data);
1038 #endif
1039
1040 __asm__("
1041 cld;
1042 "
1043 #ifdef FAST32
1044 " shr $2, %%ecx;
1045 1: lodsl;
1046 movl %%eax, (%%edi);
1047 "
1048 #else
1049 "1: lodsb;
1050 movb %%al, (%%edi);
1051 "
1052 #endif
1053 " loop 1b;" : :
1054
1055 "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
1056
1057 "eax", "ecx", "esi" );
1058
1059 len -= transfersize;
1060 data += transfersize;
1061
1062 #if (DEBUG & DEBUG_FAST)
1063 printk("scsi%d : FAST transfer complete len = %d data = %08x\n",
1064 hostno, len, data);
1065 #endif
1066
1067
1068 } else
1069 #endif
1070
1071 {
1072
1073
1074
1075
1076 __asm__ (
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 "\torl %%ecx, %%ecx
1088 jz 2f
1089
1090 cld
1091
1092 movl _st0x_cr_sr, %%ebx
1093 movl _st0x_dr, %%edi
1094
1095 1: movb (%%ebx), %%al\n"
1096
1097
1098
1099
1100 "\ttest $1, %%al
1101 jz 2f\n"
1102
1103
1104
1105
1106 "\ttest $0xe, %%al
1107 jnz 2f \n"
1108
1109
1110
1111 "\ttest $0x10, %%al
1112 jz 1b
1113 lodsb
1114 movb %%al, (%%edi)
1115 loop 1b
1116
1117 2:
1118 ":
1119
1120 "=S" (data), "=c" (len) :
1121
1122 "0" (data), "1" (len) :
1123
1124 "eax", "ebx", "edi");
1125 }
1126
1127 if (!len && nobuffs) {
1128 --nobuffs;
1129 ++buffer;
1130 len = buffer->length;
1131 data = (unsigned char *) buffer->address;
1132 #if (DEBUG & DEBUG_SG)
1133 printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1134 hostno, len, data);
1135 #endif
1136 }
1137 break;
1138
1139 case REQ_DATAIN :
1140 #ifdef SLOW_HANDSHAKE
1141 if (borken) {
1142 #if (DEBUG & (PHASE_DATAIN))
1143 transfered += len;
1144 #endif
1145 for (; len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
1146 STAT_REQ); --len) {
1147 *data++ = DATA;
1148 borken_wait();
1149 }
1150 #if (DEBUG & (PHASE_DATAIN))
1151 transfered -= len;
1152 #endif
1153 } else
1154 #endif
1155 #ifdef FAST
1156 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1157 #ifdef FAST32
1158 && !(transfersize % 4)
1159 #endif
1160 ) {
1161 #if (DEBUG & DEBUG_FAST)
1162 printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1163 " len = %d, data = %08x\n", hostno, SCint->underflow,
1164 SCint->transfersize, len, data);
1165 #endif
1166 __asm__("
1167 cld;
1168 "
1169 #ifdef FAST32
1170 " shr $2, %%ecx;
1171 1: movl (%%esi), %%eax;
1172 stosl;
1173 "
1174 #else
1175 "1: movb (%%esi), %%al;
1176 stosb;
1177 "
1178 #endif
1179
1180 " loop 1b;" : :
1181
1182 "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
1183
1184 "eax", "ecx", "edi");
1185
1186 len -= transfersize;
1187 data += transfersize;
1188
1189 #if (DEBUG & PHASE_DATAIN)
1190 printk("scsi%d: transfered += %d\n", hostno, transfersize);
1191 transfered += transfersize;
1192 #endif
1193
1194 #if (DEBUG & DEBUG_FAST)
1195 printk("scsi%d : FAST transfer complete len = %d data = %08x\n",
1196 hostno, len, data);
1197 #endif
1198
1199 } else
1200 #endif
1201 {
1202
1203 #if (DEBUG & PHASE_DATAIN)
1204 printk("scsi%d: transfered += %d\n", hostno, len);
1205 transfered += len;
1206
1207 #endif
1208
1209
1210
1211
1212
1213
1214 __asm__ (
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224 "\torl %%ecx, %%ecx
1225 jz 2f
1226
1227 cld
1228 movl _st0x_cr_sr, %%esi
1229 movl _st0x_dr, %%ebx
1230
1231 1: movb (%%esi), %%al\n"
1232
1233
1234
1235
1236 "\ttest $1, %%al
1237 jz 2f\n"
1238
1239
1240
1241
1242 "\tmovb $0xe, %%ah
1243 andb %%al, %%ah
1244 cmpb $0x04, %%ah
1245 jne 2f\n"
1246
1247
1248
1249
1250 "\ttest $0x10, %%al
1251 jz 1b
1252
1253 movb (%%ebx), %%al
1254 stosb
1255 loop 1b\n"
1256
1257 "2:\n"
1258 :
1259
1260 "=D" (data), "=c" (len) :
1261
1262 "0" (data), "1" (len) :
1263
1264 "eax","ebx", "esi");
1265
1266 #if (DEBUG & PHASE_DATAIN)
1267 printk("scsi%d: transfered -= %d\n", hostno, len);
1268 transfered -= len;
1269
1270 #endif
1271 }
1272
1273 if (!len && nobuffs) {
1274 --nobuffs;
1275 ++buffer;
1276 len = buffer->length;
1277 data = (unsigned char *) buffer->address;
1278 #if (DEBUG & DEBUG_SG)
1279 printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1280 hostno, len, data);
1281 #endif
1282 }
1283
1284 break;
1285
1286 case REQ_CMDOUT :
1287 while (((status_read = STATUS) & STAT_BSY) &&
1288 ((status_read & REQ_MASK) == REQ_CMDOUT))
1289 if (status_read & STAT_REQ) {
1290 DATA = *(unsigned char *) cmnd;
1291 cmnd = 1+(unsigned char *) cmnd;
1292 #ifdef SLOW_HANDSHAKE
1293 if (borken)
1294 borken_wait();
1295 #endif
1296 }
1297 break;
1298
1299 case REQ_STATIN :
1300 status = DATA;
1301 break;
1302
1303 case REQ_MSGOUT :
1304
1305
1306
1307
1308
1309 CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
1310
1311
1312
1313
1314 switch (reselect) {
1315 case CAN_RECONNECT:
1316 DATA = IDENTIFY(1, lun);
1317
1318 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
1319 printk("scsi%d : sent IDENTIFY message.\n", hostno);
1320 #endif
1321 break;
1322 #ifdef LINKED
1323 case LINKED_WRONG:
1324 DATA = ABORT;
1325 linked_connected = 0;
1326 reselect = CAN_RECONNECT;
1327 goto connect_loop;
1328 #if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
1329 printk("scsi%d : sent ABORT message to cancle incorrect I_T_L nexus.\n", hostno);
1330 #endif
1331 #endif
1332 #if (DEBUG & DEBUG_LINKED)
1333 printk("correct\n");
1334 #endif
1335 default:
1336 DATA = NOP;
1337 printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
1338 }
1339 break;
1340
1341 case REQ_MSGIN :
1342 switch (message = DATA) {
1343 case DISCONNECT :
1344 should_reconnect = 1;
1345 current_data = data;
1346 current_buffer = buffer;
1347 current_bufflen = len;
1348 current_nobuffs = nobuffs;
1349 #ifdef LINKED
1350 linked_connected = 0;
1351 #endif
1352 done=1;
1353 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
1354 printk("scsi%d : disconnected.\n", hostno);
1355 #endif
1356 break;
1357
1358 #ifdef LINKED
1359 case LINKED_CMD_COMPLETE:
1360 case LINKED_FLG_CMD_COMPLETE:
1361 #endif
1362 case COMMAND_COMPLETE :
1363
1364
1365
1366 #if (DEBUG & PHASE_MSGIN)
1367 printk("scsi%d : command complete.\n", hostno);
1368 #endif
1369 done = 1;
1370 break;
1371 case ABORT :
1372 #if (DEBUG & PHASE_MSGIN)
1373 printk("scsi%d : abort message.\n", hostno);
1374 #endif
1375 done=1;
1376 break;
1377 case SAVE_POINTERS :
1378 current_buffer = buffer;
1379 current_bufflen = len;
1380 current_data = data;
1381 current_nobuffs = nobuffs;
1382 #if (DEBUG & PHASE_MSGIN)
1383 printk("scsi%d : pointers saved.\n", hostno);
1384 #endif
1385 break;
1386 case RESTORE_POINTERS:
1387 buffer=current_buffer;
1388 cmnd=current_cmnd;
1389 data=current_data;
1390 len=current_bufflen;
1391 nobuffs=current_nobuffs;
1392 #if (DEBUG & PHASE_MSGIN)
1393 printk("scsi%d : pointers restored.\n", hostno);
1394 #endif
1395 break;
1396 default:
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407 if (message & 0x80) {
1408 #if (DEBUG & PHASE_MSGIN)
1409 printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
1410 hostno, target, message & 7);
1411 #endif
1412 } else {
1413
1414
1415
1416
1417
1418
1419
1420 #if (DEBUG & PHASE_MSGIN)
1421 printk("scsi%d : unknown message %d from target %d.\n",
1422 hostno, message, target);
1423 #endif
1424 }
1425 }
1426 break;
1427
1428 default :
1429 printk("scsi%d : unknown phase.\n", hostno);
1430 st0x_aborted = DID_ERROR;
1431 }
1432
1433 #ifdef SLOW_HANDSHAKE
1434
1435
1436
1437
1438
1439 if (borken)
1440 borken_wait();
1441 #endif
1442
1443 }
1444 }
1445
1446 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
1447 printk("scsi%d : Transfered %d bytes\n", hostno, transfered);
1448 #endif
1449
1450 #if (DEBUG & PHASE_EXIT)
1451 #if 0
1452 printk("Buffer : \n");
1453 for (i = 0; i < 20; ++i)
1454 printk ("%02x ", ((unsigned char *) data)[i]);
1455 printk("\n");
1456 #endif
1457 printk("scsi%d : status = ", hostno);
1458 print_status(status);
1459 printk("message = %02x\n", message);
1460 #endif
1461
1462
1463
1464 #ifdef notyet
1465 if (st0x_aborted) {
1466 if (STATUS & STAT_BSY) {
1467 seagate_st0x_reset();
1468 st0x_aborted = DID_RESET;
1469 }
1470 abort_confirm = 1;
1471 }
1472 #endif
1473
1474 #ifdef LINKED
1475 else {
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486 switch (message) {
1487 case LINKED_CMD_COMPLETE :
1488 case LINKED_FLG_CMD_COMPLETE :
1489 message = COMMAND_COMPLETE;
1490 linked_target = current_target;
1491 linked_lun = current_lun;
1492 linked_connected = 1;
1493 #if (DEBUG & DEBUG_LINKED)
1494 printk("scsi%d : keeping I_T_L nexus established for linked command.\n",
1495 hostno);
1496 #endif
1497
1498
1499
1500 if ((status == INTERMEDIATE_GOOD) ||
1501 (status == INTERMEDIATE_C_GOOD))
1502 status = GOOD;
1503
1504 break;
1505
1506
1507
1508
1509
1510
1511 default :
1512 #if (DEBUG & DEBUG_LINKED)
1513 printk("scsi%d : closing I_T_L nexus.\n", hostno);
1514 #endif
1515 linked_connected = 0;
1516 }
1517 }
1518 #endif
1519
1520
1521
1522
1523 if (should_reconnect) {
1524 #if (DEBUG & PHASE_RESELECT)
1525 printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
1526 hostno);
1527 #endif
1528 CONTROL = BASE_CMD | CMD_INTR ;
1529 } else
1530 CONTROL = BASE_CMD;
1531
1532 return retcode (st0x_aborted);
1533 }
1534
1535 int seagate_st0x_abort (Scsi_Cmnd * SCpnt, int code)
1536 {
1537 if (code)
1538 st0x_aborted = code;
1539 else
1540 st0x_aborted = DID_ABORT;
1541
1542 return 0;
1543 }
1544
1545
1546
1547
1548
1549 int seagate_st0x_reset (void)
1550 {
1551 unsigned clock;
1552
1553
1554
1555
1556
1557 #ifdef DEBUG
1558 printk("In seagate_st0x_reset()\n");
1559 #endif
1560
1561
1562
1563
1564 CONTROL = BASE_CMD | CMD_RST;
1565 clock=jiffies+2;
1566
1567
1568
1569
1570 while (jiffies < clock);
1571
1572 CONTROL = BASE_CMD;
1573
1574 st0x_aborted = DID_RESET;
1575
1576 #ifdef DEBUG
1577 printk("SCSI bus reset.\n");
1578 #endif
1579 return 0;
1580 }
1581
1582 #ifdef CONFIG_BLK_DEV_SD
1583
1584 #include <asm/segment.h>
1585 #include "sd.h"
1586 #include "scsi_ioctl.h"
1587
1588 int seagate_st0x_biosparam(int size, int dev, int* ip) {
1589 unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page;
1590 int *sizes, result, formatted_sectors, total_sectors;
1591 int cylinders, heads, sectors;
1592
1593 Scsi_Device *disk;
1594
1595 disk = rscsi_disks[MINOR(dev) >> 4].device;
1596
1597
1598
1599
1600
1601
1602 if (disk->scsi_level < 2)
1603 return -1;
1604
1605 sizes = (int *) buf;
1606 data = (unsigned char *) (sizes + 2);
1607
1608 cmd[0] = MODE_SENSE;
1609 cmd[1] = (disk->lun << 5) & 0xe5;
1610 cmd[2] = 0x04;
1611 cmd[3] = 0;
1612 cmd[4] = 255;
1613 cmd[5] = 0;
1614
1615
1616
1617
1618
1619
1620 sizes[0] = 0;
1621 sizes[1] = 256;
1622
1623 memcpy (data, cmd, 6);
1624
1625 if (!(result = kernel_scsi_ioctl (disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1626
1627
1628
1629
1630
1631 page = data + 4 + data[3];
1632 heads = (int) page[5];
1633 cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
1634
1635 cmd[2] = 0x03;
1636 memcpy (data, cmd, 6);
1637
1638 if (!(result = kernel_scsi_ioctl (disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1639 page = data + 4 + data[3];
1640 sectors = (page[10] << 8) | page[11];
1641
1642
1643
1644
1645
1646
1647
1648 formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) |
1649 data[4 + 3] ;
1650
1651 total_sectors = (heads * cylinders * sectors);
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661 printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
1662 hostno, heads, cylinders, sectors, total_sectors, formatted_sectors);
1663
1664 if (!heads || !sectors)
1665 cylinders = 1025;
1666 else
1667 cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
1668
1669
1670
1671
1672
1673
1674
1675 if ((cylinders > 1024) || (sectors > 64))
1676 result = -1;
1677 else {
1678 ip[0] = heads;
1679 ip[1] = sectors;
1680 ip[2] = cylinders;
1681 }
1682
1683
1684
1685
1686
1687
1688 }
1689 }
1690
1691 return result;
1692 }
1693 #endif
1694
1695 #endif
1696