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