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