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