This source file includes following definitions.
- st0x_setup
- tmc8xx_setup
- borken_init
- borken_wait
- seagate_st0x_detect
- seagate_st0x_info
- seagate_reconnect_intr
- seagate_st0x_queue_command
- seagate_st0x_command
- internal_command
- seagate_st0x_abort
- seagate_st0x_reset
- seagate_st0x_biosparam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include <asm/io.h>
51 #include <asm/system.h>
52 #include <linux/signal.h>
53 #include <linux/sched.h>
54 #include <linux/string.h>
55 #include <linux/config.h>
56
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 #ifdef notyet
100 static volatile int abort_confirm = 0;
101 #endif
102
103 static volatile void *st0x_cr_sr;
104
105
106
107
108
109
110
111
112
113
114 static volatile void *st0x_dr;
115
116
117
118
119
120 static volatile int st0x_aborted=0;
121
122
123
124 static unsigned char controller_type = 0;
125 static unsigned char irq = IRQ;
126
127 #define retcode(result) (((result) << 16) | (message << 8) | status)
128 #define STATUS (*(volatile unsigned char *) st0x_cr_sr)
129 #define CONTROL STATUS
130 #define DATA (*(volatile unsigned char *) st0x_dr)
131
132 void st0x_setup (char *str, int *ints) {
133 controller_type = SEAGATE;
134 base_address = (void *) ints[1];
135 irq = ints[2];
136 }
137
138 void tmc8xx_setup (char *str, int *ints) {
139 controller_type = FD;
140 base_address = (void *) ints[1];
141 irq = ints[2];
142 }
143
144
145 #ifndef OVERRIDE
146 static const char * seagate_bases[] = {
147 (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
148 (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
149 };
150
151 typedef struct {
152 char *signature ;
153 unsigned offset;
154 unsigned length;
155 unsigned char type;
156 } Signature;
157
158 static const Signature signatures[] = {
159 #ifdef CONFIG_SCSI_SEAGATE
160 {"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
161 {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
162
163
164
165
166
167
168
169
170 {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
171 {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
172
173
174
175
176
177
178 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
179 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
180 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
181 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
182 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
183 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
184 {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
185 {"FUTURE DOMAIN TMC-950", 5, 21, FD},
186 #endif
187 }
188 ;
189
190 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
191 #endif
192
193
194
195
196
197 static int hostno = -1;
198 static void seagate_reconnect_intr(int, struct pt_regs *);
199
200 #ifdef FAST
201 static int fast = 1;
202 #endif
203
204 #ifdef SLOW_HANDSHAKE
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
240
241
242 static int borken_calibration = 0;
243 static void borken_init (void) {
244 register int count = 0, start = jiffies + 1, stop = start + 25;
245
246 while (jiffies < start);
247 for (;jiffies < stop; ++count);
248
249
250
251
252
253
254 borken_calibration = (count * 4) / (SLOW_RATE*1024);
255
256 if (borken_calibration < 1)
257 borken_calibration = 1;
258 #if (DEBUG & DEBUG_BORKEN)
259 printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n",
260 hostno, BORKEN_RATE, borken_calibration);
261 #endif
262 }
263
264 static inline void borken_wait(void) {
265 register int count;
266 for (count = borken_calibration; count && (STATUS & STAT_REQ);
267 --count);
268 #if (DEBUG & DEBUG_BORKEN)
269 if (count)
270 printk("scsi%d : borken timeout\n", hostno);
271 #endif
272 }
273
274 #endif
275
276 int seagate_st0x_detect (Scsi_Host_Template * tpnt)
277 {
278 struct Scsi_Host *instance;
279 #ifndef OVERRIDE
280 int i,j;
281 #endif
282
283
284
285
286 #ifdef DEBUG
287 printk("Autodetecting ST0x / TMC-8xx\n");
288 #endif
289
290 if (hostno != -1)
291 {
292 printk ("ERROR : seagate_st0x_detect() called twice.\n");
293 return 0;
294 }
295
296
297
298
299 if (!controller_type) {
300 #ifdef OVERRIDE
301 base_address = (void *) OVERRIDE;
302
303
304 #ifdef CONTROLLER
305 controller_type = CONTROLLER;
306 #else
307 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
308 #endif
309 #ifdef DEBUG
310 printk("Base address overridden to %x, controller type is %s\n",
311 base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
312 #endif
313 #else
314
315
316
317
318
319
320
321
322
323
324 for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
325 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
326 if (!memcmp ((void *) (seagate_bases[i] +
327 signatures[j].offset), (void *) signatures[j].signature,
328 signatures[j].length)) {
329 base_address = (void *) seagate_bases[i];
330 controller_type = signatures[j].type;
331 }
332 #endif
333 }
334
335 tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
336 tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
337
338 if (base_address)
339 {
340 st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00));
341 st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
342 #ifdef DEBUG
343 printk("%s detected. Base address = %x, cr = %x, dr = %x\n", tpnt->name, base_address, st0x_cr_sr, st0x_dr);
344 #endif
345
346
347
348
349 instance = scsi_register(tpnt, 0);
350 hostno = instance->host_no;
351 if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
352 (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) {
353 printk("scsi%d : unable to allocate IRQ%d\n",
354 hostno, (int) irq);
355 return 0;
356 }
357 #ifdef SLOW_HANDSHAKE
358 borken_init();
359 #endif
360
361 printk("%s options:"
362 #ifdef ARBITRATE
363 " ARBITRATE"
364 #endif
365 #ifdef SLOW_HANDSHAKE
366 " SLOW_HANDSHAKE"
367 #endif
368 #ifdef FAST
369 #ifdef FAST32
370 " FAST32"
371 #else
372 " FAST"
373 #endif
374 #endif
375 #ifdef LINKED
376 " LINKED"
377 #endif
378 "\n", tpnt->name);
379 return 1;
380 }
381 else
382 {
383 #ifdef DEBUG
384 printk("ST0x / TMC-8xx not detected.\n");
385 #endif
386 return 0;
387 }
388 }
389
390 const char *seagate_st0x_info(struct Scsi_Host * shpnt) {
391 static char buffer[64];
392 sprintf(buffer, "%s at irq %d, address 0x%05X",
393 (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
394 irq, (unsigned int)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 irq, struct pt_regs * regs)
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[SCpnt->cmd_len] |= 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) SCint->device->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 clock = jiffies + 10;
674 for (;;) {
675 temp = STATUS;
676 if ((temp & STAT_IO) && !(temp & STAT_BSY))
677 break;
678
679 if (jiffies > clock) {
680 #if (DEBUG & PHASE_RESELECT)
681 printk("scsi%d : RESELECT timed out while waiting for IO .\n",
682 hostno);
683 #endif
684 return (DID_BAD_INTR << 16);
685 }
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 cancel 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_WAKEUP;
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 }