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