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