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