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