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