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