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