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