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