This source file includes following definitions.
- splx
- internal_setup
- setup_wrapper
- normal_init
- pci_init
- NCR53c7xx_detect
- NCR53c8x0_init_fixup
- NCR53c8xx_run_tests
- NCR53c8xx_dsa_fixup
- abnormal_finished
- intr_break
- asynchronous
- synchronous
- NCR53c8x0_dstat_sir_intr
- debugger_fn_bc
- debugger_fn_bl
- debugger_fn_bs
- debugger_user_write
- debugger_user_read
- debugger_kernel_write
- NCR53c8x0_soft_reset
- create_cmd
- NCR53c7xx_queue_command
- fix_pointers
- intr_scsi
- NCR53c7x0_intr
- abort_connected
- intr_phase_mismatch
- intr_dma
- print_insn
- NCR53c7xx_abort
- NCR53c7xx_reset
- print_dsa
1
2
3
4
5
6
7
8 #define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
9
10
11
12
13
14
15 #define SCSI_MALLOC
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 #include <asm/io.h>
160 #include <asm/system.h>
161 #include <linux/delay.h>
162 #include <linux/signal.h>
163 #include <linux/sched.h>
164 #include <linux/errno.h>
165 #include <linux/bios32.h>
166 #include <linux/pci.h>
167 #include <linux/string.h>
168 #include <linux/mm.h>
169 #include "../block/blk.h"
170 #include "scsi.h"
171 #include "hosts.h"
172 #include "53c7,8xx.h"
173 #include "constants.h"
174 #include "sd.h"
175
176 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
177 static int NCR53c8xx_run_tests (struct Scsi_Host *host);
178 static int NCR53c8xx_script_len;
179 static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
180 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
181 *cmd);
182 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
183 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa);
184 static int print_insn (struct Scsi_Host *host, unsigned long *insn,
185 char *prefix, int kernel);
186
187 static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
188 static void NCR53c8x0_init_fixup (struct Scsi_Host *host);
189 static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
190 NCR53c7x0_cmd *cmd);
191 static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
192
193 static struct Scsi_Host *first_host = NULL;
194 static Scsi_Host_Template *the_template = NULL;
195
196
197
198 static long NCR53c7xx_zero = 0;
199 static long NCR53c7xx_sink;
200 static char NCR53c7xx_msg_reject = MESSAGE_REJECT;
201 static char NCR53c7xx_msg_abort = ABORT;
202 static char NCR53c7xx_msg_nop = NOP;
203
204
205
206
207
208 static int scan_scsis_buf_busy = 0;
209 static char scan_scsis_buf[512];
210
211
212
213
214
215
216 static int splx (int new_level)
217 {
218 register int old_level, tmp;
219 save_flags(tmp);
220 old_level = (tmp & 0x200) ? 7 : 0;
221 if (new_level)
222 sti();
223 else
224 cli();
225 return old_level;
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 struct pci_chip {
297 unsigned short pci_device_id;
298 int chip;
299 int max_revision;
300 int min_revision;
301 };
302
303 static struct pci_chip pci_chip_ids[] = {
304 {PCI_DEVICE_ID_NCR_53C810, 810, 1, 1},
305 {PCI_DEVICE_ID_NCR_53C815, 815, 2, 3},
306 {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},
307 {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}
308 };
309
310 #define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))
311
312
313
314
315 static struct override {
316 int chip;
317 int board;
318 unsigned pci:1;
319 union {
320 struct {
321 int base;
322 int io_port;
323 int irq;
324 int dma;
325 } normal;
326 struct {
327 int bus;
328 int device;
329 int function;
330 } pci;
331 } data;
332 int options;
333 } overrides [4] = {{0,},};
334 static int commandline_current = 0;
335 static int no_overrides = 0;
336
337 #if 0
338 #define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))
339 #else
340 #define OVERRIDE_LIMIT commandline_current
341 #endif
342
343
344
345
346
347
348
349
350
351
352
353
354 static void internal_setup(int board, int chip, char *str, int *ints) {
355 unsigned char pci;
356
357
358 pci = (str && !strcmp (str, "pci")) ? 1 : 0;
359
360
361
362
363
364
365
366 if (commandline_current < OVERRIDE_LIMIT) {
367 overrides[commandline_current].pci = pci ? 1 : 0;
368 if (!pci) {
369 overrides[commandline_current].data.normal.base = ints[1];
370 overrides[commandline_current].data.normal.io_port = ints[2];
371 overrides[commandline_current].data.normal.irq = ints[3];
372 overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?
373 ints[4] : DMA_NONE;
374 overrides[commandline_current].options = (ints[0] >= 5) ?
375 ints[5] : 0;
376 } else {
377 overrides[commandline_current].data.pci.bus = ints[1];
378 overrides[commandline_current].data.pci.device = ints[2];
379 overrides[commandline_current].data.pci.device = ints[3];
380 overrides[commandline_current].options = (ints[0] >= 4) ?
381 ints[4] : 0;
382 }
383 overrides[commandline_current].board = board;
384 overrides[commandline_current].chip = chip;
385 ++commandline_current;
386 ++no_overrides;
387 } else {
388 printk ("53c7,7x0.c:internal_setup() : too many overrides\n");
389 }
390 }
391
392
393
394
395
396
397
398 #define setup_wrapper(x) \
399 void ncr53c##x##_setup (char *str, int *ints) { \
400 internal_setup (BOARD_GENERIC, x, str, ints); \
401 }
402
403 setup_wrapper(700)
404 setup_wrapper(70066)
405 setup_wrapper(710)
406 setup_wrapper(720)
407 setup_wrapper(810)
408 setup_wrapper(815)
409 setup_wrapper(820)
410 setup_wrapper(825)
411
412
413
414
415
416
417
418
419
420
421
422
423 static int NCR53c7x0_init (struct Scsi_Host *host) {
424 NCR53c7x0_local_declare();
425
426 int i, j, ccf;
427 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
428 host->hostdata;
429 struct Scsi_Host *search;
430 NCR53c7x0_local_setup(host);
431
432 switch (hostdata->chip) {
433 case 810:
434 case 815:
435 case 820:
436 case 825:
437 hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;
438 hostdata->init_save_regs = NULL;
439 hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;
440 hostdata->init_fixup = NCR53c8x0_init_fixup;
441 hostdata->soft_reset = NCR53c8x0_soft_reset;
442 hostdata->run_tests = NCR53c8xx_run_tests;
443
444 hostdata->scsi_clock = 40000000;
445 break;
446 default:
447 printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
448 host->host_no, hostdata->chip);
449 scsi_unregister (host);
450 return -1;
451 }
452
453
454
455
456
457
458 for (search = first_host; search && (search->hostt == the_template) &&
459 (search->irq != host->irq); search=search->next);
460
461 if (!search) {
462 if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
463 printk("scsi%d : IRQ%d not free, detaching\n",
464 host->host_no, host->irq);
465 scsi_unregister (host);
466 return -1;
467 }
468 } else {
469 printk("scsi%d : using interrupt handler previously installed for scsi%d\n",
470 host->host_no, search->host_no);
471 }
472
473 printk ("scsi%d : using %s mapped access\n", host->host_no,
474 (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" :
475 "io");
476
477 hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ?
478 DMODE_REG_00 : DMODE_REG_10;
479 hostdata->istat = ((hostdata->chip / 100) == 8) ?
480 ISTAT_REG_800 : ISTAT_REG_700;
481
482
483
484
485
486
487
488
489
490 #if 0
491 tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
492 for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
493 #else
494 host->this_id = NCR53c7x0_read8(SCID_REG) & 7;
495 hostdata->this_id_mask = 1 << host->this_id;
496 #endif
497
498 printk("scsi%d : using initiator ID %d\n", host->host_no,
499 host->this_id);
500
501
502
503
504
505 if ((hostdata->chip / 100) == 8) {
506
507
508
509 hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) &
510 CTEST4_800_SAVE;
511 } else {
512
513
514
515
516 hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
517 }
518
519
520
521
522
523 hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
524
525 if ((hostdata->chip / 100) == 8)
526 printk ("scsi%d : using %s interrupts.\n", host->host_no,
527 (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "level active" :
528 "edge triggered");
529
530
531
532
533
534 hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
535
536
537
538
539
540
541 if ((hostdata->chip / 100) == 8) {
542 if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {
543 printk ("scsi%d : burst mode disabled\n", host->host_no);
544 } else {
545 switch (hostdata->saved_dmode & DMODE_BL_MASK) {
546 case DMODE_BL_2: i = 2; break;
547 case DMODE_BL_4: i = 4; break;
548 case DMODE_BL_8: i = 8; break;
549 case DMODE_BL_16: i = 16; break;
550 }
551 printk ("scsi%d ; burst length %d\n", host->host_no, i);
552 }
553 }
554
555
556
557
558
559 if (hostdata->chip / 100 == 8) {
560 hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);
561 ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;
562 } else
563 ccf = 0;
564
565
566
567
568
569
570
571
572 if (!hostdata->scsi_clock)
573 switch(ccf) {
574 case 1: hostdata->scsi_clock = 25000000; break;
575 case 2: hostdata->scsi_clock = 37500000; break;
576 case 3: hostdata->scsi_clock = 50000000; break;
577 case 0:
578 case 4: hostdata->scsi_clock = 66000000; break;
579 default:
580 printk ("scsi%d : clock conversion factor %d unknown.\n"
581 " synchronous transfers disabled\n",
582 host->host_no, ccf);
583 hostdata->options &= ~OPTION_SYNCHRONOUS;
584 hostdata->scsi_clock = 0;
585 }
586
587 printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no,
588 hostdata->scsi_clock / 1000000);
589
590
591
592
593
594 for (i = 0; i < 8; ++i) {
595 for (j = 0; j < 8; ++j)
596 hostdata->busy[i][j] = 0;
597
598
599
600
601
602 if (hostdata->chip != 700 && hostdata->chip != 70066) {
603 hostdata->sync[i].select_indirect |= (i << 16);
604
605 hostdata->sync[i].script[0] = (DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24 |
606 DBC_TCI_TRUE;
607 switch (hostdata->chip) {
608
609 case 825:
610 case 820:
611
612 case 815:
613 case 810:
614 hostdata->sync[i].select_indirect |= (hostdata->saved_scntl3) << 24;
615 break;
616 default:
617 }
618 }
619 }
620
621 hostdata->issue_queue = hostdata->running_list =
622 hostdata->finished_queue = NULL;
623 hostdata->issue_dsa_head =
624 hostdata->issue_dsa_tail = NULL;
625
626 if (hostdata->init_save_regs)
627 hostdata->init_save_regs (host);
628 if (hostdata->init_fixup)
629 hostdata->init_fixup (host);
630
631 if (!the_template) {
632 the_template = host->hostt;
633 first_host = host;
634 }
635
636 hostdata->idle = 1;
637
638
639
640
641
642
643
644
645
646
647
648 hostdata->soft_reset (host);
649
650 hostdata->debug_count_limit = -1;
651 hostdata->intrs = -1;
652 hostdata->expecting_iid = 0;
653 hostdata->expecting_sto = 0;
654
655 if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
656 (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
657
658 scsi_unregister (host);
659 return -1;
660 } else
661 return 0;
662 }
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685 static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
686 int base, int io_port, int irq, int dma, int pci_valid,
687 unsigned char pci_bus, unsigned char pci_device_fn, int options) {
688 struct Scsi_Host *instance;
689 struct NCR53c7x0_hostdata *hostdata;
690 char chip_str[80];
691 int script_len = 0, size = 0;
692 int ok = 0;
693
694
695 options |= PERM_OPTIONS;
696
697 switch (chip) {
698 case 825:
699 case 820:
700 case 815:
701 case 810:
702 script_len = NCR53c8xx_script_len;
703 options |= OPTION_INTFLY;
704 sprintf (chip_str, "NCR53c%d", chip);
705 break;
706 default:
707 printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);
708 return -1;
709 }
710
711 printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",
712 chip_str, base, io_port, irq);
713 if (dma == DMA_NONE)
714 printk("\n");
715 else
716 printk(", dma %d\n", dma);
717
718 if ((chip / 100 == 8) && !pci_valid)
719 printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n"
720 " PCI override instead.\n"
721 " Syntax : ncr53c8{10,20,25}=pci,<bus>,<device>,<function>\n"
722 " <bus> and <device> are usually 0.\n");
723
724 if (options & OPTION_DEBUG_PROBE_ONLY) {
725 printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");
726 return -1;
727 }
728
729 size = sizeof(struct NCR53c7x0_hostdata) + script_len;
730
731 instance = scsi_register (tpnt, size);
732 hostdata = (struct NCR53c7x0_hostdata *)
733 instance->hostdata;
734 hostdata->size = size;
735 hostdata->script_count = script_len / sizeof(long);
736 hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;
737 hostdata->board = board;
738 hostdata->chip = chip;
739 if ((hostdata->pci_valid = pci_valid)) {
740 hostdata->pci_bus = pci_bus;
741 hostdata->pci_device_fn = pci_device_fn;
742 }
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758 if (base) {
759 instance->base = (unsigned char *) base;
760
761 if (!(options & OPTION_IO_MAPPED)) {
762 options |= OPTION_MEMORY_MAPPED;
763 ok = 1;
764 }
765 } else {
766 options &= ~OPTION_MEMORY_MAPPED;
767 }
768
769 if (io_port) {
770 instance->io_port = io_port;
771 options |= OPTION_IO_MAPPED;
772 ok = 1;
773 } else {
774 options &= ~OPTION_IO_MAPPED;
775 }
776
777 if (!ok) {
778 printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
779 instance->host_no);
780 scsi_unregister (instance);
781 return -1;
782 }
783 instance->irq = irq;
784 instance->dma_channel = dma;
785
786 hostdata->options = options;
787
788 return NCR53c7x0_init(instance);
789 }
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813 static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
814 unsigned char bus, unsigned char device_fn, int options) {
815 unsigned short vendor_id, device_id, command;
816 unsigned long base, io_port;
817 unsigned char irq, revision;
818 int error, expected_chip, expected_id, max_revision, min_revision;
819 int i;
820
821 printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
822 bus, (int) (device_fn & 0xf8) >> 3,
823 (int) device_fn & 7);
824
825 if (!pcibios_present) {
826 printk("scsi-ncr53c7,8xx : not initializing due to lack of PCI BIOS,\n"
827 " try using memory, port, irq override instead.\n");
828 return -1;
829 }
830
831 if ((error = pcibios_read_config_word (bus, device_fn, PCI_VENDOR_ID,
832 &vendor_id)) ||
833 (error = pcibios_read_config_word (bus, device_fn, PCI_DEVICE_ID,
834 &device_id)) ||
835 (error = pcibios_read_config_word (bus, device_fn, PCI_COMMAND,
836 &command)) ||
837 (error = pcibios_read_config_dword (bus, device_fn,
838 PCI_BASE_ADDRESS_0, &io_port)) ||
839 (error = pcibios_read_config_dword (bus, device_fn,
840 PCI_BASE_ADDRESS_1, &base)) ||
841 (error = pcibios_read_config_byte (bus, device_fn, PCI_CLASS_REVISION,
842 &revision)) ||
843 (error = pcibios_read_config_byte (bus, device_fn, PCI_INTERRUPT_LINE,
844 &irq))) {
845 printk ("scsi-ncr53c7,8xx : error %s not initializing due to error reading configuration space\n"
846 " perhaps you specified an incorrect PCI bus, device, or function.\n"
847 , pcibios_strerror(error));
848 return -1;
849 }
850
851
852
853 if (vendor_id != PCI_VENDOR_ID_NCR) {
854 printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",
855 (int) vendor_id);
856 return -1;
857 }
858
859
860
861
862
863
864
865
866 if (command & PCI_COMMAND_IO) {
867 if ((io_port & 3) != 1) {
868 printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base address 0 (0x%lx)\n"
869 " bits 0..1 indicate a non-IO mapping\n", io_port);
870 io_port = 0;
871 } else
872 io_port &= PCI_BASE_ADDRESS_IO_MASK;
873 }
874
875 if (command & PCI_COMMAND_MEMORY) {
876 if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
877 printk("scsi-ncr53c7,8xx : disabling memory mapping since base address 1\n"
878 " contains a non-memory mapping\n");
879 base = 0;
880 } else
881 base &= PCI_BASE_ADDRESS_MEM_MASK;
882 }
883
884 if (!io_port && !base) {
885 printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");
886 return -1;
887 }
888
889 if (!(command & PCI_COMMAND_MASTER)) {
890 printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");
891 return -1;
892 }
893
894 for (i = 0; i < NPCI_CHIP_IDS; ++i) {
895 if (device_id == pci_chip_ids[i].pci_device_id) {
896 max_revision = pci_chip_ids[i].max_revision;
897 min_revision = pci_chip_ids[i].min_revision;
898 expected_chip = pci_chip_ids[i].chip;
899 }
900 if (chip == pci_chip_ids[i].chip)
901 expected_id = pci_chip_ids[i].pci_device_id;
902 }
903
904 if (chip && device_id != expected_id)
905 printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"
906 " match expected 0x%04x\n",
907 (unsigned int) device_id, (unsigned int) expected_id );
908
909 if (max_revision != -1 && revision > max_revision)
910 printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",
911 (int) revision, max_revision);
912 else if (min_revision != -1 && revision < min_revision)
913 printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",
914 (int) revision, min_revision);
915
916 return normal_init (tpnt, board, chip, (int) base, (int) io_port,
917 (int) irq, DMA_NONE, 1, bus, device_fn, options);
918 }
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934 int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
935 short current_chip;
936 int i;
937 int current_override;
938 int count;
939 unsigned char pci_bus, pci_device_fn;
940 static short pci_index=0;
941
942
943 for (current_override = count = 0; current_override < OVERRIDE_LIMIT;
944 ++current_override) {
945 if (overrides[current_override].pci ?
946 !pci_init (tpnt, overrides[current_override].board,
947 overrides[current_override].chip,
948 (unsigned char) overrides[current_override].data.pci.bus,
949 (((overrides[current_override].data.pci.device
950 << 3) & 0xf8)|(overrides[current_override].data.pci.function &
951 7)), overrides[current_override].options):
952 !normal_init (tpnt, overrides[current_override].board,
953 overrides[current_override].chip,
954 overrides[current_override].data.normal.base,
955 overrides[current_override].data.normal.io_port,
956 overrides[current_override].data.normal.irq,
957 overrides[current_override].data.normal.dma,
958 0 , 0 ,
959 0 ,
960 overrides[current_override].options)) {
961 ++count;
962 }
963 }
964
965 if (pcibios_present()) {
966 for (i = 0; i < NPCI_CHIP_IDS; ++i)
967 for (pci_index = 0;
968 !pcibios_find_device (PCI_VENDOR_ID_NCR,
969 pci_chip_ids[i].pci_device_id, pci_index, &pci_bus,
970 &pci_device_fn) &&
971 !pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip,
972 pci_bus, pci_device_fn, 0);
973 ++count, ++pci_index);
974 }
975 return count;
976 }
977
978
979
980 #include "53c8xx_d.h"
981 static int NCR53c8xx_script_len = sizeof (SCRIPT);
982
983
984
985
986
987
988
989
990
991
992 static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
993 NCR53c7x0_local_declare();
994 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
995 host->hostdata;
996 unsigned char tmp;
997 int i, ncr_to_memory, memory_to_ncr, ncr_to_ncr;
998 unsigned long base;
999 NCR53c7x0_local_setup(host);
1000
1001
1002
1003
1004
1005 memcpy ((void *) hostdata->script, (void *) SCRIPT,
1006 sizeof(SCRIPT));
1007
1008 for (i = 0; i < PATCHES; ++i)
1009 hostdata->script[LABELPATCHES[i]] +=
1010 (unsigned long) hostdata->script;
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 tmp = NCR53c7x0_read8(DMODE_REG_10);
1028 tmp &= (DMODE_800_ERL | DMODE_BL_MASK);
1029
1030 if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
1031 base = (long) host->io_port;
1032 memory_to_ncr = tmp|DMODE_800_DIOM;
1033 ncr_to_memory = tmp|DMODE_800_SIOM;
1034 ncr_to_ncr = tmp|DMODE_800_DIOM|DMODE_800_SIOM;
1035 } else {
1036 base = (long) host->base;
1037 ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp;
1038 }
1039
1040 printk ("scsi%d : m_to_n = 0x%x, n_to_m = 0x%x, n_to_n = 0x%x\n",
1041 (int) host->host_no, (int) memory_to_ncr, (int)
1042 ncr_to_memory, ncr_to_ncr);
1043
1044 patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
1045 patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG);
1046 patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
1058 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
1059 patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
1060 patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr);
1061
1062 patch_abs_32 (hostdata->script, 0, issue_dsa_head, (long) &(hostdata->issue_dsa_head));
1063 patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf));
1064 patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, (long) &(hostdata->reconnect_dsa_head));
1065 patch_abs_32 (hostdata->script, 0, reselected_identify, (long) &(hostdata->reselected_identify));
1066 patch_abs_32 (hostdata->script, 0, reselected_tag, (long) &(hostdata->reselected_tag));
1067
1068 patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest));
1069 patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source));
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 hostdata->E_accept_message = Ent_accept_message;
1082 hostdata->E_command_complete = Ent_command_complete;
1083 hostdata->E_debug_break = Ent_debug_break;
1084 hostdata->E_dsa_code_template = Ent_dsa_code_template;
1085 hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
1086 hostdata->E_initiator_abort = Ent_initiator_abort;
1087 hostdata->E_msg_in = Ent_msg_in;
1088 hostdata->E_other_transfer = Ent_other_transfer;
1089 hostdata->E_reject_message = Ent_reject_message;
1090 hostdata->E_respond_message = Ent_respond_message;
1091 hostdata->E_schedule = Ent_schedule;
1092 hostdata->E_select = Ent_select;
1093 hostdata->E_select_msgout = Ent_select_msgout;
1094 hostdata->E_target_abort = Ent_target_abort;
1095 #ifdef Ent_test_0
1096 hostdata->E_test_0 = Ent_test_0;
1097 #endif
1098 hostdata->E_test_1 = Ent_test_1;
1099 hostdata->E_test_2 = Ent_test_2;
1100 #ifdef Ent_test_3
1101 hostdata->E_test_3 = Ent_test_3;
1102 #endif
1103
1104 hostdata->dsa_cmdout = A_dsa_cmdout;
1105 hostdata->dsa_cmnd = A_dsa_cmnd;
1106 hostdata->dsa_datain = A_dsa_datain;
1107 hostdata->dsa_dataout = A_dsa_dataout;
1108 hostdata->dsa_end = A_dsa_end;
1109 hostdata->dsa_msgin = A_dsa_msgin;
1110 hostdata->dsa_msgout = A_dsa_msgout;
1111 hostdata->dsa_msgout_other = A_dsa_msgout_other;
1112 hostdata->dsa_next = A_dsa_next;
1113 hostdata->dsa_select = A_dsa_select;
1114 hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
1115 hostdata->dsa_status = A_dsa_status;
1116
1117
1118 if (A_dsa_fields_start != Ent_dsa_code_template_end -
1119 Ent_dsa_zero)
1120 printk("scsi%d : NCR dsa_fields start is %d not %d\n",
1121 host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -
1122 Ent_dsa_zero);
1123
1124 printk("scsi%d : NCR code relocated to 0x%lx\n", host->host_no,
1125 (unsigned long) hostdata->script);
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
1144 NCR53c7x0_local_declare();
1145 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1146 host->hostdata;
1147 unsigned long timeout, start;
1148 int old_level, failed, i;
1149 NCR53c7x0_local_setup(host);
1150
1151 printk("scsi%d : testing\n", host->host_no);
1152
1153
1154
1155 old_level = splx(0);
1156 if (!hostdata->idle) {
1157 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1158 splx(old_level);
1159 return -1;
1160 }
1161
1162
1163
1164
1165
1166
1167 if (hostdata->issue_dsa_head) {
1168 printk ("scsi%d : hostdata->issue_dsa_head corrupt before test 1\n",
1169 host->host_no);
1170 hostdata->issue_dsa_head = NULL;
1171 }
1172
1173 if (hostdata->options & OPTION_DEBUG_TEST1) {
1174 hostdata->idle = 0;
1175 hostdata->test_running = 1;
1176 hostdata->test_completed = -1;
1177 hostdata->test_dest = 0;
1178 hostdata->test_source = 0xdeadbeef;
1179 start = ((unsigned long) hostdata->script) + hostdata->E_test_1;
1180 hostdata->state = STATE_RUNNING;
1181 printk ("scsi%d : test 1", host->host_no);
1182 NCR53c7x0_write32 (DSP_REG, start);
1183 printk (" started\n");
1184 splx(7);
1185
1186 timeout = jiffies + 50;
1187 while ((hostdata->test_completed == -1) && jiffies < timeout);
1188
1189 failed = 1;
1190 if (hostdata->test_completed == -1)
1191 printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
1192 (hostdata->test_dest == 0xdeadbeef) ?
1193 " due to lost interrupt.\n"
1194 " Please verify that the correct IRQ is being used for your board,\n"
1195 " and that the motherboard IRQ jumpering matches the PCI setup on\n"
1196 " PCI systems.\n"
1197 " If you are using a NCR53c810 board in a PCI system, you should\n"
1198 " also verify that the board is jumpered to use PCI INTA, since\n"
1199 " most PCI motherboards lack support for INTB, INTC, and INTD.\n"
1200 : "");
1201 else if (hostdata->test_completed != 1)
1202 printk ("scsi%d : test 1 bad interrupt value (%ld)\n", host->host_no,
1203 hostdata->test_completed);
1204 else
1205 failed = (hostdata->test_dest != 0xdeadbeef);
1206
1207 if (hostdata->test_dest != 0xdeadbeef) {
1208 printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1209 " probable cache invalidation problem. Please configure caching\n"
1210 " as write-through or disabled\n",
1211 host->host_no, hostdata->test_dest);
1212 }
1213
1214 if (failed) {
1215 printk ("scsi%d : DSP = 0x%lx (script at 0x%lx, start at 0x%lx)\n",
1216 host->host_no, (unsigned long) NCR53c7x0_read32(DSP_REG),
1217 (unsigned long) hostdata->script, start);
1218 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
1219 (unsigned long) NCR53c7x0_read32(DSPS_REG));
1220 splx(old_level);
1221 return -1;
1222 }
1223 hostdata->test_running = 0;
1224 }
1225
1226 if (hostdata->issue_dsa_head) {
1227 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 1\n",
1228 host->host_no);
1229 hostdata->issue_dsa_head = NULL;
1230 }
1231
1232 if (hostdata->options & OPTION_DEBUG_TEST2) {
1233 unsigned long dsa[48];
1234 unsigned char identify = IDENTIFY(0, 0);
1235 unsigned char cmd[6];
1236 unsigned char data[36];
1237 unsigned char status = 0xff;
1238 unsigned char msg = 0xff;
1239
1240 cmd[0] = INQUIRY;
1241 cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
1242 cmd[4] = sizeof(data);
1243
1244 dsa[2] = 1;
1245 dsa[3] = (unsigned long) &identify;
1246 dsa[4] = 6;
1247 dsa[5] = (unsigned long) &cmd;
1248 dsa[6] = sizeof(data);
1249 dsa[7] = (unsigned long) &data;
1250 dsa[8] = 1;
1251 dsa[9] = (unsigned long) &status;
1252 dsa[10] = 1;
1253 dsa[11] = (unsigned long) &msg;
1254
1255 for (i = 0; i < 3; ++i) {
1256 splx(0);
1257 if (!hostdata->idle) {
1258 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1259 splx(old_level);
1260 return -1;
1261 }
1262
1263
1264 dsa[0] = (0x33 << 24) | (i << 16) ;
1265 hostdata->idle = 0;
1266 hostdata->test_running = 2;
1267 hostdata->test_completed = -1;
1268 start = ((unsigned long) hostdata->script) + hostdata->E_test_2;
1269 hostdata->state = STATE_RUNNING;
1270 NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
1271 NCR53c7x0_write32 (DSP_REG, start);
1272 splx(7);
1273
1274 timeout = jiffies + 500;
1275 while ((hostdata->test_completed == -1) && jiffies < timeout);
1276 NCR53c7x0_write32 (DSA_REG, 0);
1277
1278 if (hostdata->test_completed == 2) {
1279 data[35] = 0;
1280 printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1281 host->host_no, i, data + 8);
1282 printk ("scsi%d : status ", host->host_no);
1283 print_status (status);
1284 printk ("\nscsi%d : message ", host->host_no);
1285 print_msg (&msg);
1286 printk ("\n");
1287 } else if (hostdata->test_completed == 3) {
1288 printk("scsi%d : test 2 no connection with target %d\n",
1289 host->host_no, i);
1290 if (!hostdata->idle) {
1291 printk("scsi%d : not idle\n", host->host_no);
1292 splx(old_level);
1293 return -1;
1294 }
1295 } else if (hostdata->test_completed == -1) {
1296 printk ("scsi%d : test 2 timed out\n", host->host_no);
1297 splx(old_level);
1298 return -1;
1299 }
1300 hostdata->test_running = 0;
1301 if (hostdata->issue_dsa_head) {
1302 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 2 id %d\n",
1303 host->host_no, i);
1304 hostdata->issue_dsa_head = NULL;
1305 }
1306 }
1307 }
1308 printk ("scsi%d : tests complete.\n", host->host_no);
1309
1310 splx(old_level);
1311 return 0;
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
1325 Scsi_Cmnd *c = cmd->cmd;
1326 struct Scsi_Host *host = c->host;
1327 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1328 host->hostdata;
1329 int i;
1330
1331 memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
1332 hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
1333
1334 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1335 dsa_temp_jump_resume, ((unsigned long) cmd->dsa) +
1336 Ent_dsa_jump_resume - Ent_dsa_zero);
1337 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1338 dsa_temp_lun, c->lun);
1339 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1340 dsa_temp_dsa_next, ((unsigned long) cmd->dsa) + A_dsa_next);
1341 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1342 dsa_temp_sync, hostdata->sync[c->target].select_indirect);
1343 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1344 dsa_temp_target, c->target);
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
1363 Scsi_Cmnd *c = cmd->cmd;
1364 struct Scsi_Host *host = c->host;
1365 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1366 host->hostdata;
1367 int old_level;
1368 char **prev, *search;
1369 int i;
1370
1371 old_level = splx(0);
1372 for (i = 0; i < 2; ++i) {
1373 for (search = (char *) (i ? hostdata->issue_dsa_head :
1374 hostdata->reconnect_dsa_head), prev = (char **) (i ?
1375 &(hostdata->issue_dsa_head) : &(hostdata->reconnect_dsa_head));
1376 search && (search + hostdata->dsa_start) != (char *) cmd->dsa;
1377 prev = (char **) (search + hostdata->dsa_next),
1378 search = *prev);
1379
1380 if (search)
1381 *prev = *(char **) (search + hostdata->dsa_next);
1382 }
1383
1384 if (cmd->prev)
1385 cmd->prev->next = cmd->next;
1386
1387 if (cmd->next)
1388 cmd->next->prev = cmd->prev;
1389
1390 if (hostdata->running_list == cmd)
1391 hostdata->running_list = cmd->next;
1392
1393 if (!scan_scsis_buf_busy) {
1394 #ifdef SCSI_MALLOC
1395 scsi_free ((void *) cmd->real, cmd->size);
1396 #else
1397 kfree_s (cmd->real, cmd->size);
1398 #endif
1399 } else {
1400 scan_scsis_buf_busy = 0;
1401 }
1402
1403 c->host_scribble = NULL;
1404 c->result = result;
1405 c->scsi_done(c);
1406
1407 splx(old_level);
1408 }
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 static void intr_break (struct Scsi_Host *host, struct
1423 NCR53c7x0_cmd *cmd) {
1424 NCR53c7x0_local_declare();
1425 struct NCR53c7x0_break *bp;
1426 #if 0
1427 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1428 #endif
1429 unsigned long *dsp;
1430 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1431 host->hostdata;
1432 int old_level;
1433 NCR53c7x0_local_setup(host);
1434
1435
1436
1437
1438
1439
1440
1441 old_level = splx(0);
1442 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1443 for (bp = hostdata->breakpoints; bp && bp->address != dsp;
1444 bp = bp->next);
1445 if (!bp)
1446 panic("scsi%d : break point interrupt from %p with no breakpoint!",
1447 host->host_no, dsp);
1448
1449
1450
1451
1452
1453
1454
1455 NCR53c7x0_write8 (hostdata->dmode,
1456 NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
1457
1458
1459
1460
1461
1462
1463 splx(old_level);
1464 }
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477 static int asynchronous (struct Scsi_Host *host, int target) {
1478 NCR53c7x0_local_declare();
1479 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1480 host->hostdata;
1481 NCR53c7x0_local_setup(host);
1482
1483 if ((hostdata->chip / 100) == 8) {
1484 hostdata->sync[target].select_indirect = (hostdata->saved_scntl3 << 24)
1485 | (target << 16);
1486
1487 } else if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1488 hostdata->sync[target].select_indirect = (1 << (target & 7)) << 16;
1489 }
1490
1491
1492
1493
1494
1495
1496 if (hostdata->state == STATE_HALTED) {
1497 if ((hostdata->chip / 100) == 8) {
1498 NCR53c7x0_write8 (SCNTL3_REG_800, hostdata->saved_scntl3);
1499 }
1500
1501 NCR53c7x0_write8 (SXFER_REG, 0);
1502 }
1503 return 0;
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514 static const struct {
1515 int div;
1516 unsigned char scf;
1517 unsigned char tp;
1518 } syncs[] = {
1519
1520 { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
1521 { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
1522 { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
1523 { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
1524 { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
1525 { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
1526 { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
1527 { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
1528 };
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545 static void synchronous (struct Scsi_Host *host, int target, char *msg) {
1546 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1547 host->hostdata;
1548 int desire, divisor, i, limit;
1549 unsigned long *script;
1550 unsigned char scntl3, sxfer;
1551
1552
1553 desire = 1000000000L / (msg[3] * 4);
1554 divisor = desire / (hostdata->scsi_clock / 10);
1555
1556 if (msg[4] > 8)
1557 msg[4] = 8;
1558
1559 printk("scsi%d : optimal synchronous divisor of %d.%01d\n", host->host_no,
1560 divisor / 10, divisor % 10);
1561
1562 limit = (sizeof(syncs) / sizeof(syncs[0])) - 1;
1563 for (i = 0; (i < limit) && (divisor < syncs[i + 1].div); ++i);
1564
1565 printk("scsi%d : selected synchronous divisor of %d.%01d\n", host->host_no,
1566 syncs[i].div / 10, syncs[i].div % 10);
1567
1568 msg[3] = (1000000000 / divisor / 10 / 4);
1569
1570 scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 &
1571 ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
1572 sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
1573
1574 if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1575 hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) |
1576 (sxfer << 8);
1577
1578 script = hostdata->sync[target].script;
1579
1580
1581 if ((hostdata->chip / 100) == 8) {
1582 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1583 DCMD_RWRI_OP_MOVE) << 24) |
1584 (SCNTL3_REG_800 << 16) | (scntl3 << 8);
1585 script[1] = 0;
1586 script += 2;
1587 }
1588
1589 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1590 DCMD_RWRI_OP_MOVE) << 24) |
1591 (SXFER_REG << 16) | (sxfer << 8);
1592 script[1] = 0;
1593 script += 2;
1594
1595 script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
1596 script[1] = 0;
1597 script += 2;
1598 }
1599 }
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614 static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
1615 NCR53c7x0_cmd *cmd) {
1616 NCR53c7x0_local_declare();
1617 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1618 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1619 host->hostdata;
1620 unsigned long dsps,*dsp;
1621 NCR53c7x0_local_setup(host);
1622 dsps = NCR53c7x0_read32(DSPS_REG);
1623 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1624
1625 if (hostdata->options & OPTION_DEBUG_INTR)
1626 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no, dsps);
1627
1628 switch (dsps) {
1629 case A_int_msg_1:
1630 printk ("scsi%d : message", host->host_no);
1631 if (cmd)
1632 printk (" from target %d lun %d", c->target, c->lun);
1633 print_msg (hostdata->msg_buf);
1634 printk("\n");
1635 switch (hostdata->msg_buf[0]) {
1636
1637
1638
1639
1640 case MESSAGE_REJECT:
1641 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1642 sizeof(long);
1643 hostdata->dsp_changed = 1;
1644 break;
1645 case INITIATE_RECOVERY:
1646 printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
1647 host->host_no);
1648 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1649 sizeof(long);
1650 hostdata->dsp_changed = 1;
1651 }
1652 return SPECIFIC_INT_NOTHING;
1653 case A_int_msg_sdtr:
1654 if (cmd) {
1655 printk ("scsi%d : target %d %s synchronous transfer period %dns, offset%d\n",
1656 host->host_no, c->target, (cmd->flags & CMD_FLAG_SDTR) ? "accepting" :
1657 "requesting", hostdata->msg_buf[3] * 4, hostdata->msg_buf[4]);
1658
1659
1660
1661
1662
1663
1664
1665
1666 if (cmd->flags & CMD_FLAG_SDTR) {
1667 cmd->flags &= ~CMD_FLAG_SDTR;
1668 synchronous (host, c->target, hostdata->msg_buf);
1669 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1670 sizeof(long);
1671 hostdata->dsp_changed = 1;
1672 return SPECIFIC_INT_NOTHING;
1673 } else {
1674 if (hostdata->options & OPTION_SYNCHRONOUS) {
1675 cmd->flags |= CMD_FLAG_DID_SDTR;
1676 synchronous (host, c->target, hostdata->msg_buf);
1677 } else {
1678 hostdata->msg_buf[4] = 0;
1679 }
1680
1681 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
1682 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1,
1683 hostdata->msg_buf);
1684 hostdata->dsp = hostdata->script +
1685 hostdata->E_respond_message / sizeof(long);
1686 hostdata->dsp_changed = 1;
1687 }
1688
1689 if (hostdata->msg_buf[4]) {
1690 int Hz = 1000000000 / (hostdata->msg_buf[3] * 4);
1691 printk ("scsi%d : setting target %d to %d.%02dMhz %s SCSI%s\n"
1692 " period = %dns, max offset = %d\n",
1693 host->host_no, c->target, Hz / 1000000, Hz % 1000000,
1694 ((hostdata->msg_buf[3] < 200) ? "FAST " :
1695 "synchronous") ,
1696 ((hostdata->msg_buf[3] < 200) ? "-II" : ""),
1697 (int) hostdata->msg_buf[3] * 4, (int)
1698 hostdata->msg_buf[4]);
1699 } else {
1700 printk ("scsi%d : setting target %d to asynchronous SCSI\n",
1701 host->host_no, c->target);
1702 }
1703 return SPECIFIC_INT_NOTHING;
1704 }
1705
1706 case A_int_msg_wdtr:
1707 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1708 sizeof(long);
1709 hostdata->dsp_changed = 1;
1710 return SPECIFIC_INT_NOTHING;
1711 case A_int_err_unexpected_phase:
1712 if (hostdata->options & OPTION_DEBUG_INTR)
1713 printk ("scsi%d : unexpected phase\n", host->host_no);
1714 return SPECIFIC_INT_ABORT;
1715 case A_int_err_selected:
1716 printk ("scsi%d : selected by target %d\n", host->host_no,
1717 (int) NCR53c7x0_read8(SSID_REG_800) &7);
1718 hostdata->dsp = hostdata->script + hostdata->E_target_abort /
1719 sizeof(long);
1720 hostdata->dsp_changed = 1;
1721 return SPECIFIC_INT_NOTHING;
1722 case A_int_err_unexpected_reselect:
1723 printk ("scsi%d : unexpected reselect by target %d\n", host->host_no,
1724 (int) NCR53c7x0_read8(SSID_REG_800));
1725 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
1726 sizeof(long);
1727 hostdata->dsp_changed = 1;
1728 return SPECIFIC_INT_NOTHING;
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738 case A_int_err_check_condition:
1739 #if 0
1740 if (hostdata->options & OPTION_DEBUG_INTR)
1741 #endif
1742 printk ("scsi%d : CHECK CONDITION\n", host->host_no);
1743 if (!c) {
1744 printk("scsi%d : CHECK CONDITION with no SCSI command\n",
1745 host->host_no);
1746 return SPECIFIC_INT_PANIC;
1747 }
1748
1749
1750
1751
1752
1753
1754 asynchronous (host, c->target);
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766 patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
1767
1768
1769
1770
1771
1772
1773 patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
1774
1775 c->cmnd[0] = REQUEST_SENSE;
1776 c->cmnd[1] &= 0xe0;
1777 c->cmnd[2] = 0;
1778 c->cmnd[3] = 0;
1779 c->cmnd[4] = sizeof(c->sense_buffer);
1780 c->cmnd[5] = 0;
1781
1782
1783
1784
1785
1786
1787
1788 patch_dsa_32 (cmd->dsa, dsa_dataout, 0, hostdata->E_other_transfer);
1789 patch_dsa_32 (cmd->dsa, dsa_datain, 0, cmd->data_transfer_start);
1790 cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
1791 DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
1792 cmd->data_transfer_start[1] = (unsigned long) c->sense_buffer;
1793
1794 cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
1795 << 24) | DBC_TCI_TRUE;
1796 cmd->data_transfer_start[3] = hostdata->E_other_transfer;
1797
1798
1799
1800
1801
1802
1803
1804
1805 cmd->cmd->result = 0xffff;
1806
1807
1808
1809
1810 hostdata->dsp = hostdata->script + hostdata->E_select /
1811 sizeof(long);
1812 hostdata->dsp_changed = 1;
1813 return SPECIFIC_INT_NOTHING;
1814 case A_int_debug_break:
1815 return SPECIFIC_INT_BREAK;
1816 case A_int_norm_aborted:
1817 hostdata->dsp = hostdata->script + hostdata->E_schedule /
1818 sizeof(long);
1819 hostdata->dsp_changed = 1;
1820 if (cmd)
1821 abnormal_finished (cmd, DID_ERROR << 16);
1822 return SPECIFIC_INT_NOTHING;
1823 case A_int_test_1:
1824 case A_int_test_2:
1825 hostdata->idle = 1;
1826 hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
1827 if (hostdata->options & OPTION_DEBUG_INTR)
1828 printk("scsi%d : test%ld complete\n", host->host_no,
1829 hostdata->test_completed);
1830 return SPECIFIC_INT_NOTHING;
1831 #ifdef A_int_debug_scheduled
1832 case A_int_debug_scheduled:
1833 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1834 printk("scsi%d : new I/O 0x%lx scheduled\n", host->host_no,
1835 NCR53c7x0_read32(DSA_REG));
1836 }
1837 return SPECIFIC_INT_RESTART;
1838 #endif
1839 #ifdef A_int_debug_idle
1840 case A_int_debug_idle:
1841 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1842 printk("scsi%d : idle\n", host->host_no);
1843 }
1844 return SPECIFIC_INT_RESTART;
1845 #endif
1846 #ifdef A_int_debug_cmd
1847 case A_int_debug_cmd:
1848 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1849 printk("scsi%d : command sent\n");
1850 }
1851 return SPECIFIC_INT_RESTART;
1852 #endif
1853 #ifdef A_int_debug_dsa_loaded
1854 case A_int_debug_dsa_loaded:
1855 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1856 printk("scsi%d : DSA loaded with 0x%lx\n", host->host_no,
1857 NCR53c7x0_read32(DSA_REG));
1858 }
1859 return SPECIFIC_INT_RESTART;
1860 #endif
1861 #ifdef A_int_debug_reselected
1862 case A_int_debug_reselected:
1863 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1864 printk("scsi%d : reselected by target %d lun %d\n",
1865 host->host_no, (int) NCR53c7x0_read8(SSID_REG_800),
1866 (int) hostdata->reselected_identify & 7);
1867 }
1868 return SPECIFIC_INT_RESTART;
1869 #endif
1870 #ifdef A_int_debug_head
1871 case A_int_debug_head:
1872 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1873 printk("scsi%d : issue_dsa_head now 0x%lx\n",
1874 host->host_no, (unsigned long) hostdata->issue_dsa_head);
1875 }
1876 return SPECIFIC_INT_RESTART;
1877 #endif
1878 default:
1879 if ((dsps & 0xff000000) == 0x03000000) {
1880 printk ("scsi%d : misc debug interrupt 0x%lx\n",
1881 host->host_no, dsps);
1882 return SPECIFIC_INT_RESTART;
1883 }
1884
1885 printk ("scsi%d : unknown user interrupt 0x%x\n",
1886 host->host_no, (unsigned) dsps);
1887 return SPECIFIC_INT_PANIC;
1888 }
1889 }
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905 #include "53c8xx_u.h"
1906
1907
1908
1909
1910 #ifdef NCR_DEBUG
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925 static const char debugger_help =
1926 "bc <addr> - clear breakpoint\n"
1927 "bl - list breakpoints\n"
1928 "bs <addr> - set breakpoint\n"
1929 "g - start\n"
1930 "h - halt\n"
1931 "? - this message\n"
1932 "i - info\n"
1933 "mp <addr> <size> - print memory\n"
1934 "ms <addr> <size> <value> - store memory\n"
1935 "rp <num> <size> - print register\n"
1936 "rs <num> <size> <value> - store register\n"
1937 "s - single step\n"
1938 "tb - begin trace \n"
1939 "te - end trace\n";
1940
1941
1942
1943
1944
1945
1946 static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
1947 unsigned long args[]) {
1948 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1949 instance->hostdata;
1950 struct NCR53c7x0_break *bp, **prev;
1951 int old_level;
1952 old_level = splx(0);
1953 for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
1954 prev = (struct NCR53c7x0_break **) &instance->breakpoints;
1955 bp; prev = (struct NCR53c7x0_break **) &(bp->next),
1956 bp = (struct NCR53c7x0_break *) bp->next);
1957
1958 if (!bp) {
1959 splx(old_level);
1960 return -EIO;
1961 }
1962
1963
1964
1965
1966
1967
1968 memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
1969 if (prev)
1970 *prev = bp->next;
1971
1972 splx(old_level);
1973 return 0;
1974 }
1975
1976
1977 static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
1978 unsigned long args[]) {
1979 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1980 host->hostdata;
1981 struct NCR53c7x0_break *bp;
1982 char buf[80];
1983 size_t len;
1984 int old_level;
1985
1986
1987
1988
1989
1990
1991 sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
1992 host->host_no);
1993 debugger_kernel_write (host, buf, strlen(buf));
1994
1995 old_level=splx(0);
1996 for (bp = (struct NCR53c7x0_break *) host->breakpoints;
1997 bp; bp = (struct NCR53c7x0_break *) bp->next); {
1998 sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
1999 bp->addr, bp->old[0], bp->old[1]);
2000 len = strlen(buf);
2001 if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
2002 (DCMD_TYPE_MMI << 24)) {
2003 sprintf(buf + len, "%08x\n", * (long *) bp->addr);
2004 } else {
2005 sprintf(buf + len, "\n");
2006 }
2007 len = strlen(buf);
2008 debugger_kernel_write (host, buf, len);
2009 }
2010 splx(old_level);
2011 return 0;
2012 }
2013
2014 static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
2015 unsigned long args[]) {
2016 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2017 host->hostdata;
2018 struct NCR53c7x0_break *bp;
2019 char buf[80];
2020 size_t len;
2021 int old_level;
2022 old_level=splx(0);
2023
2024 if (hostdata->state != STATE_HALTED) {
2025 sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
2026 debugger_kernel_write (host, buf, strlen(buf));
2027 splx(old_level);
2028 return -1;
2029 }
2030
2031 if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
2032 printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
2033 host->host_no, sizeof(struct NCR53c7x0_break));
2034 splx(old_level);
2035 return -1;
2036 }
2037
2038 bp->address = (unsigned long *) args[0];
2039 memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
2040 bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
2041 DCMD_TYPE_MMI ? 3 : 2;
2042 bp->next = hostdata->breakpoints;
2043 hostdata->breakpoints = bp->next;
2044 memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
2045
2046 splx(old_level);
2047 return 0;
2048 }
2049
2050 #define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
2051 static const struct debugger_token {
2052 char *name;
2053 int numargs;
2054 int (*fn)(struct debugger_token *token, unsigned long args[]);
2055 } debugger_tokens[] = {
2056 TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
2057 {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2),
2058 TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
2059 };
2060
2061 #define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
2062
2063 static struct Scsi_Host * inode_to_host (struct inode *inode) {$
2064 int dev;
2065 struct Scsi_Host *tmp;
2066 for (dev = MINOR(inode->rdev), host = first_host;
2067 (host->hostt == the_template); --dev, host = host->next)
2068 if (!dev) return host;
2069 return NULL;
2070 }
2071
2072
2073 static debugger_user_write (struct inode *inode,struct file *filp,
2074 char *buf,int count) {
2075 struct Scsi_Host *host;
2076 struct NCR53c7x0_hostadata *hostdata;
2077 char input_buf[80],
2078 *ptr;
2079 unsigned long args[3];
2080 int i, j, error, len;
2081
2082 if (!(host = inode_to_host(inode)))
2083 return -ENXIO;
2084
2085 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
2086
2087 if (error = verify_area(VERIFY_READ,buf,count))
2088 return error;
2089
2090 if (count > 80)
2091 return -EIO;
2092
2093 memcpy_from_fs(input_buf, buf, count);
2094
2095 if (input_buf[count - 1] != '\n')
2096 return -EIO;
2097
2098 input_buf[count - 1]=0;
2099
2100 for (i = 0; i < NDT; ++i) {
2101 len = strlen (debugger_tokens[i].name);
2102 if (!strncmp(input_buf, debugger_tokens[i].name, len))
2103 break;
2104 };
2105
2106 if (i == NDT)
2107 return -EIO;
2108
2109 for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
2110 if (*ptr == ' ' || *ptr == '\t') {
2111 ++ptr;
2112 } else if (isdigit(*ptr)) {
2113 args[j++] = simple_strtoul (ptr, &ptr, 0);
2114 } else {
2115 return -EIO;
2116 }
2117 }
2118
2119 if (j != debugger_tokens[i].nargs)
2120 return -EIO;
2121
2122 return count;
2123 }
2124
2125 static debugger_user_read (struct inode *inode,struct file *filp,
2126 char *buf,int count) {
2127 struct Scsi_Host *instance;
2128
2129 }
2130
2131 static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
2132 buflen) {
2133 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2134 host->hostdata;
2135 int copy, left, old_level;
2136
2137 old_level = splx(0);
2138 while (buflen) {
2139 left = (hostdata->debug_buf + hostdata->debug_size - 1) -
2140 hostdata->debug_write;
2141 copy = (buflen <= left) ? buflen : left;
2142 memcpy (hostdata->debug_write, buf, copy);
2143 buf += copy;
2144 buflen -= copy;
2145 hostdata->debug_count += copy;
2146 if ((hostdata->debug_write += copy) ==
2147 (hostdata->debug_buf + hostdata->debug_size))
2148 hosdata->debug_write = hostdata->debug_buf;
2149 }
2150 (void) splx(old_level);
2151 }
2152
2153 #endif
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167 static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
2168 NCR53c7x0_local_declare();
2169 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2170 host->hostdata;
2171 NCR53c7x0_local_setup(host);
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184 NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
2185 NCR53c7x0_write8(ISTAT_REG_800, 0);
2186 NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197 NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
2198 NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
2199
2200
2201
2202
2203
2204
2205 NCR53c7x0_write8(STIME0_REG_800,
2206 ((14 << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)
2207
2208 #if 0
2209 | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK)
2210 #endif
2211 );
2212
2213
2214
2215
2216
2217
2218
2219
2220 NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
2221 DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
2222
2223
2224 NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
2225 SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_800_SEL |
2226 SIEN_800_RESEL | SIEN_MA);
2227 NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
2228
2229
2230
2231
2232
2233
2234 NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
2235 NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
2236
2237
2238 NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
2239
2240
2241 }
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258 static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
2259 NCR53c7x0_local_declare();
2260 struct Scsi_Host *host = cmd->host;
2261 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2262 host->hostdata;
2263 int size;
2264 struct NCR53c7x0_cmd *tmp;
2265 int datain,
2266 dataout;
2267 int data_transfer_instructions,
2268 i,
2269 alignment;
2270 unsigned long *cmd_datain,
2271 *cmd_dataout;
2272 void *real;
2273 NCR53c7x0_local_setup(cmd->host);
2274
2275
2276
2277
2278
2279
2280
2281 switch (cmd->cmnd[0]) {
2282
2283 case INQUIRY:
2284 case MODE_SENSE:
2285 case READ_6:
2286 case READ_10:
2287 case READ_CAPACITY:
2288 case REQUEST_SENSE:
2289 datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2290 dataout = 0;
2291 break;
2292
2293 case MODE_SELECT:
2294 case WRITE_6:
2295 case WRITE_10:
2296 #if 0
2297 printk("scsi%d : command is ", host->host_no);
2298 print_command(cmd->cmnd);
2299 #endif
2300 #if 0
2301 printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
2302 cmd->use_sg);
2303 #endif
2304 datain = 0;
2305 dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2306 #if 0
2307 hostdata->options |= OPTION_DEBUG_INTR;
2308 #endif
2309 break;
2310
2311
2312
2313
2314 case START_STOP:
2315 case TEST_UNIT_READY:
2316 datain = dataout = 0;
2317 break;
2318
2319
2320
2321
2322 default:
2323 datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2324 }
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336 data_transfer_instructions = datain + dataout;
2337
2338
2339
2340
2341
2342
2343
2344 if (data_transfer_instructions < 2)
2345 data_transfer_instructions = 2;
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355 #ifdef SCSI_MALLOC
2356 size = ((sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end -
2357 hostdata->dsa_start) + 2 * sizeof(long) *
2358 data_transfer_instructions + 4 + 511) / 512) * 512;
2359 #else
2360 size = sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end -
2361 hostdata->dsa_start) + 2 * sizeof(long) *
2362 data_transfer_instructions + 4;
2363 #endif
2364
2365
2366 #if 0
2367 if (size > 512) {
2368 printk("scsi%d : size = %d\n", host->host_no, size);
2369 }
2370 #endif
2371
2372 #ifdef SCSI_MALLOC
2373 real = in_scan_scsis ? NULL : scsi_malloc (size);
2374 #else
2375 real = kmalloc (size, GFP_ATOMIC);
2376 #endif
2377
2378 if (!real) {
2379 if (!scan_scsis_buf_busy && size <= sizeof(scan_scsis_buf)) {
2380 scan_scsis_buf_busy = 1;
2381 real = scan_scsis_buf;
2382 } else {
2383 panic ("scsi%d : scan_scsis_buf too small (need %d bytes)\n",
2384 host->host_no, size);
2385 }
2386 }
2387
2388 alignment = 4 - (((unsigned) real) & 3);
2389
2390 tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
2391
2392 tmp->real = real;
2393
2394
2395 if (((unsigned long) tmp->dsa) & 0x3)
2396 panic ("scsi%d : pid %d dsa structure not dword aligned!\n",
2397 host->host_no, cmd->pid);
2398
2399
2400
2401
2402
2403 tmp->size = size;
2404 tmp->cmd = cmd;
2405 tmp->next = NULL;
2406 tmp->prev = NULL;
2407
2408
2409
2410
2411
2412 tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
2413 hostdata->dsa_start) / sizeof(long);
2414 tmp->data_transfer_end = tmp->data_transfer_start +
2415 2 * data_transfer_instructions;
2416
2417 cmd_datain = datain ? tmp->data_transfer_start : NULL;
2418 cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
2419 data_transfer_start) : NULL;
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429 if (hostdata->dsa_fixup)
2430 hostdata->dsa_fixup(tmp);
2431
2432 patch_dsa_32(tmp->dsa, dsa_next, 0, NULL);
2433 patch_dsa_32(tmp->dsa, dsa_cmnd, 0, cmd);
2434 patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
2435 select_indirect);
2436
2437
2438
2439
2440 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
2441 #if 0
2442 tmp->select[0] = IDENTIFY (1, cmd->lun);
2443 #else
2444 tmp->select[0] = IDENTIFY (0, cmd->lun);
2445 #endif
2446 patch_dsa_32(tmp->dsa, dsa_msgout, 1, tmp->select);
2447 patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
2448 patch_dsa_32(tmp->dsa, dsa_cmdout, 1, cmd->cmnd);
2449 patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
2450 cmd_dataout : hostdata->script + hostdata->E_other_transfer /
2451 sizeof (long));
2452 patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
2453 cmd_datain : hostdata->script + hostdata->E_other_transfer /
2454 sizeof (long));
2455
2456
2457
2458
2459 patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
2460 patch_dsa_32(tmp->dsa, dsa_msgin, 1, (((unsigned long) &cmd->result) + 1));
2461 patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
2462 patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
2463 patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
2464 patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
2465 &NCR53c7xx_msg_nop);
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480 #if 0
2481 if (datain) {
2482 cmd_datain[0] = 0x98080000;
2483 cmd_datain[1] = 0x03ffd00d;
2484 cmd_datain += 2;
2485 }
2486 #endif
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503 for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
2504 cmd_dataout += 4, ++i) {
2505 unsigned long buf = (unsigned long) (cmd->use_sg ?
2506 ((struct scatterlist *)cmd->buffer)[i].address :
2507 cmd->request_buffer);
2508 unsigned long count = (unsigned long) (cmd->use_sg ?
2509 ((struct scatterlist *)cmd->buffer)[i].length :
2510 cmd->request_bufflen);
2511
2512 if (datain) {
2513 cmd_datain[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
2514 << 24) | count;
2515 cmd_datain[1] = buf;
2516 cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2517 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2518 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2519 cmd_datain[3] = hostdata->script + hostdata->E_msg_in /
2520 sizeof(long);
2521 #if 0
2522 print_insn (host, cmd_datain, "dynamic ", 1);
2523 print_insn (host, cmd_datain + 2, "dynamic ", 1);
2524 #endif
2525 }
2526 if (dataout) {
2527 cmd_dataout[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
2528 | count;
2529 cmd_dataout[1] = buf;
2530 cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2531 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2532 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2533 cmd_dataout[3] = hostdata->script + hostdata->E_msg_in /
2534 sizeof(long);
2535 #if 0
2536 print_insn (host, cmd_dataout, "dynamic ", 1);
2537 print_insn (host, cmd_dataout + 2, "dynamic ", 1);
2538 #endif
2539 }
2540 }
2541
2542
2543
2544
2545
2546
2547
2548 if (datain) {
2549 cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2550 DBC_TCI_TRUE;
2551 cmd_datain[1] = hostdata->script + hostdata->E_other_transfer
2552 / sizeof(long);
2553 #if 0
2554 print_insn (host, cmd_datain, "dynamic jump ", 1);
2555 #endif
2556 cmd_datain += 2;
2557 }
2558 #if 0
2559 if (datain) {
2560 cmd_datain[0] = 0x98080000;
2561 cmd_datain[1] = 0x03ffdeed;
2562 cmd_datain += 2;
2563 }
2564 #endif
2565
2566
2567 if (dataout) {
2568 cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2569 DBC_TCI_TRUE;
2570 cmd_dataout[1] = hostdata->script + hostdata->E_other_transfer
2571 / sizeof(long);
2572 #if 0
2573 print_insn (host, cmd_dataout, "dynamic jump ", 1);
2574 #endif
2575 cmd_dataout += 2;
2576 }
2577
2578
2579 return tmp;
2580 }
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600 int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
2601 NCR53c7x0_local_declare();
2602 struct NCR53c7x0_cmd *tmp;
2603 struct Scsi_Host *host = cmd->host;
2604 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2605 host->hostdata;
2606 int old_level;
2607 unsigned char target_was_busy;
2608 NCR53c7x0_local_setup(host);
2609
2610 if (((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) ||
2611 ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
2612 !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun)))) ||
2613 cmd->target > 7) {
2614 printk("scsi%d : disabled target %d lun %d\n", host->host_no,
2615 cmd->target, cmd->lun);
2616 cmd->result = (DID_BAD_TARGET << 16);
2617 done(cmd);
2618 return 0;
2619 }
2620
2621 if (hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) {
2622 if (hostdata->debug_count_limit == 0) {
2623 printk("scsi%d : maximum commands exceeded\n", host->host_no);
2624 cmd->result = (DID_BAD_TARGET << 16);
2625 done(cmd);
2626 return 0;
2627 } else if (hostdata->debug_count_limit != -1)
2628 --hostdata->debug_count_limit;
2629 }
2630
2631 if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
2632 switch (cmd->cmnd[0]) {
2633 case WRITE_6:
2634 case WRITE_10:
2635 printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
2636 host->host_no);
2637 cmd->result = (DID_BAD_TARGET << 16);
2638 done(cmd);
2639 return 0;
2640 }
2641 }
2642
2643 cmd->scsi_done = done;
2644 cmd->result = 0xffff;
2645
2646
2647 cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674 old_level = splx(0);
2675
2676
2677
2678
2679
2680
2681
2682
2683 target_was_busy = hostdata->busy[cmd->target][cmd->lun]
2684 #ifdef LUN_BUSY
2685 ++
2686 #endif
2687 ;
2688
2689 if (!(hostdata->options & OPTION_700) &&
2690 !target_was_busy) {
2691 unsigned char *dsa = ((unsigned char *) tmp->dsa)
2692 - hostdata->dsa_start;
2693
2694 #if 0
2695 printk("scsi%d : new dsa is 0x%x\n", host->host_no, (unsigned) dsa);
2696 #endif
2697
2698 if (hostdata->running_list)
2699 hostdata->running_list->prev = tmp;
2700
2701 tmp->next = hostdata->running_list;
2702
2703 if (!hostdata->running_list)
2704 hostdata->running_list = tmp;
2705
2706
2707 if (hostdata->idle) {
2708 hostdata->idle = 0;
2709 hostdata->state = STATE_RUNNING;
2710 NCR53c7x0_write32 (DSP_REG, ((unsigned long) hostdata->script) +
2711 hostdata->E_schedule);
2712 }
2713
2714
2715 for (;;) {
2716
2717
2718
2719
2720
2721
2722 if (!hostdata->issue_dsa_head) {
2723 #if 0
2724 printk ("scsi%d : no issue queue\n", host->host_no);
2725 #endif
2726 hostdata->issue_dsa_tail = hostdata->issue_dsa_head = dsa;
2727 NCR53c7x0_write8(hostdata->istat,
2728 NCR53c7x0_read8(hostdata->istat) | ISTAT_10_SIGP);
2729 break;
2730
2731
2732
2733
2734
2735
2736
2737 } else {
2738 printk ("scsi%d : existing issue queue\n", host->host_no);
2739
2740 hostdata->issue_dsa_tail = *((unsigned char **)
2741 (hostdata->issue_dsa_tail + hostdata->dsa_next)) = dsa;
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753 if (hostdata->issue_dsa_head)
2754 break;
2755 }
2756 }
2757
2758 } else {
2759 #if 1
2760 printk ("scsi%d : using issue_queue instead of issue_dsa_head!\n",
2761 host->host_no);
2762 #endif
2763 for (tmp = (struct NCR53c7x0_cmd *) hostdata->issue_queue;
2764 tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
2765 tmp->next = tmp;
2766 }
2767 splx(old_level);
2768 return 0;
2769 }
2770
2771
2772 int fix_pointers (unsigned long dsa) {
2773 return 0;
2774 }
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787 static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
2788 NCR53c7x0_local_declare();
2789 struct NCR53c7x0_hostdata *hostdata =
2790 (struct NCR53c7x0_hostdata *) host->hostdata;
2791 unsigned char sstat0_sist0, sist1,
2792 fatal;
2793
2794 NCR53c7x0_local_setup(host);
2795
2796 fatal = 0;
2797
2798 if ((hostdata->chip / 100) == 8) {
2799 sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
2800 udelay(1);
2801 sist1 = NCR53c7x0_read8(SIST1_REG_800);
2802 } else {
2803 sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
2804 sist1 = 0;
2805 }
2806
2807 if (hostdata->options & OPTION_DEBUG_INTR)
2808 printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
2809 sstat0_sist0, sist1);
2810
2811
2812 if ((((hostdata->chip / 100) == 8) && (sist1 & SIST1_800_STO)) ||
2813 (((hostdata->chip / 100) != 8) && sstat0_sist0 && SSTAT0_700_STO)) {
2814 fatal = 1;
2815 if (hostdata->options & OPTION_DEBUG_INTR) {
2816 printk ("scsi%d : Selection Timeout\n", host->host_no);
2817 if (cmd) {
2818 printk("scsi%d : target %d, lun %d, command ",
2819 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2820 print_command (cmd->cmd->cmnd);
2821 printk("scsi%d : dsp = 0x%x\n", host->host_no,
2822 (unsigned) NCR53c7x0_read32(DSP_REG));
2823 } else {
2824 printk("scsi%d : no command\n", host->host_no);
2825 }
2826 }
2827
2828
2829
2830
2831
2832
2833 if (1) {
2834 hostdata->idle = 1;
2835 hostdata->expecting_sto = 0;
2836
2837 if (hostdata->test_running) {
2838 hostdata->test_running = 0;
2839 hostdata->test_completed = 3;
2840 } else if (cmd) {
2841 abnormal_finished(cmd, DID_BAD_TARGET << 16);
2842 }
2843 #if 0
2844 hostdata->intrs = 0;
2845 #endif
2846 }
2847 }
2848
2849 if (sstat0_sist0 & SSTAT0_UDC) {
2850 fatal = 1;
2851 printk("scsi%d : target %d lun %d unexpected disconnect\n",
2852 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2853 if (cmd) {
2854 abnormal_finished(cmd, DID_ERROR << 16);
2855 }
2856 hostdata->dsp = hostdata->script + hostdata->E_schedule /
2857 sizeof(long);
2858 hostdata->dsp_changed = 1;
2859
2860 }
2861
2862 if (sstat0_sist0 & SSTAT0_PAR) {
2863 fatal = 1;
2864 if (cmd && cmd->cmd) {
2865 printk("scsi%d : target %d lun %d parity error.\n",
2866 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2867 abnormal_finished (cmd, DID_PARITY << 16);
2868 } else
2869 printk("scsi%d : parity error\n", host->host_no);
2870
2871
2872
2873 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2874 sizeof(long);
2875 hostdata->dsp_changed = 1;
2876
2877 }
2878
2879 if (sstat0_sist0 & SSTAT0_SGE) {
2880 fatal = 1;
2881 printk("scsi%d : gross error\n", host->host_no);
2882
2883 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2884 sizeof(long);
2885 hostdata->dsp_changed = 1;
2886
2887 }
2888
2889 if (sstat0_sist0 & SSTAT0_MA) {
2890 fatal = 1;
2891 if (hostdata->options & OPTION_DEBUG_INTR)
2892 printk ("scsi%d : SSTAT0_MA\n", host->host_no);
2893 intr_phase_mismatch (host, cmd);
2894 }
2895
2896 #if 1
2897
2898
2899
2900
2901
2902 if (fatal) {
2903 if (!hostdata->dstat_valid) {
2904 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
2905 hostdata->dstat_valid = 1;
2906 }
2907
2908
2909 if (!(hostdata->dstat & DSTAT_DFE)) {
2910 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
2911 #if 0
2912 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
2913 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
2914 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
2915 DSTAT_DFE));
2916 } else
2917 #endif
2918 {
2919 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
2920 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
2921 }
2922 }
2923
2924 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
2925 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
2926 }
2927 #endif
2928 }
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941 static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
2942 NCR53c7x0_local_declare();
2943 struct Scsi_Host *host;
2944 unsigned char istat;
2945 struct NCR53c7x0_hostdata *hostdata;
2946 struct NCR53c7x0_cmd *cmd,
2947 **cmd_prev_ptr;
2948 unsigned long *dsa;
2949 int done = 1;
2950
2951 int interrupted = 0;
2952
2953 int old_level;
2954
2955 #ifdef NCR_DEBUG
2956 char buf[80];
2957 size_t buflen;
2958 #endif
2959
2960 #if 0
2961 printk("interrupt %d received\n", irq);
2962 #endif
2963
2964 do {
2965 done = 1;
2966 for (host = first_host; host; host = hostdata->next ?
2967 hostdata->next : NULL) {
2968 NCR53c7x0_local_setup(host);
2969
2970 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
2971 hostdata->dsp_changed = 0;
2972 interrupted = 0;
2973
2974
2975 do {
2976 hostdata->dstat_valid = 0;
2977 interrupted = 0;
2978
2979
2980
2981
2982 istat = NCR53c7x0_read8(hostdata->istat);
2983
2984
2985
2986
2987
2988
2989
2990
2991 if ((hostdata->options & OPTION_INTFLY) &&
2992 ((hostdata->chip / 100) == 8 && (istat & ISTAT_800_INTF))) {
2993 char search_found = 0;
2994 done = 0;
2995 interrupted = 1;
2996
2997
2998
2999
3000
3001 NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
3002
3003 if (hostdata->options & OPTION_DEBUG_INTR)
3004 printk ("scsi%d : INTFLY\n", host->host_no);
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014 old_level = splx(0);
3015 restart:
3016 for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
3017 &(hostdata->running_list), cmd = (struct NCR53c7x0_cmd *)
3018 hostdata->running_list; cmd ; cmd_prev_ptr =
3019 &(cmd->next), cmd = (struct NCR53c7x0_cmd *) cmd->next) {
3020 Scsi_Cmnd *tmp;
3021
3022 if (!cmd) {
3023 printk("scsi%d : very weird.\n", host->host_no);
3024 break;
3025 }
3026
3027 if (!(tmp = cmd->cmd)) {
3028 printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
3029 host->host_no);
3030 continue;
3031 }
3032 #if 0
3033 printk ("scsi%d : looking at result of 0x%x\n",
3034 host->host_no, cmd->cmd->result);
3035 #endif
3036
3037 if (((tmp->result & 0xff) == 0xff) ||
3038 ((tmp->result & 0xff00) == 0xff00))
3039 continue;
3040
3041 search_found = 1;
3042
3043
3044
3045 if (cmd->prev)
3046 cmd->prev->next = cmd->next;
3047 if (cmd_prev_ptr)
3048 *cmd_prev_ptr = cmd->next;
3049
3050 #ifdef LUN_BUSY
3051
3052 if (--hostdata->busy[tmp->target][tmp->lun]) {
3053 }
3054 #endif
3055
3056
3057 if (!scan_scsis_buf_busy) {
3058 #ifdef SCSI_MALLOC
3059 scsi_free ((void *) cmd->real, cmd->size);
3060 #else
3061 kfree_s ((void *) cmd->real, cmd->size);
3062 #endif
3063 } else {
3064 scan_scsis_buf_busy = 0;
3065 }
3066
3067
3068 tmp->host_scribble = NULL;
3069
3070 if (hostdata->options & OPTION_DEBUG_INTR) {
3071 printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
3072 host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
3073 print_command (tmp->cmnd);
3074 }
3075
3076
3077 #if 0
3078 hostdata->options &= ~OPTION_DEBUG_INTR;
3079 #endif
3080 tmp->scsi_done(tmp);
3081 goto restart;
3082
3083 }
3084 splx(old_level);
3085
3086 if (!search_found) {
3087 printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
3088 host->host_no);
3089 }
3090 }
3091
3092 if (istat & (ISTAT_SIP|ISTAT_DIP)) {
3093 done = 0;
3094 interrupted = 1;
3095 hostdata->state = STATE_HALTED;
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106 if (hostdata->options & OPTION_700) {
3107 cmd = (struct NCR53c7x0_cmd *) hostdata->current;
3108 } else {
3109 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3110 for (cmd = (struct NCR53c7x0_cmd *)
3111 hostdata->running_list; cmd &&
3112 (dsa + (hostdata->dsa_start / sizeof(long))) !=
3113 cmd->dsa;
3114 cmd = (struct NCR53c7x0_cmd *)(cmd->next));
3115 }
3116 if (hostdata->options & OPTION_DEBUG_INTR) {
3117 if (cmd) {
3118 printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
3119 host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
3120 (int) cmd->cmd->lun);
3121 print_command (cmd->cmd->cmnd);
3122 } else {
3123 printk("scsi%d : no active command\n", host->host_no);
3124 }
3125 }
3126
3127 if (istat & ISTAT_SIP) {
3128 if (hostdata->options & OPTION_DEBUG_INTR)
3129 printk ("scsi%d : ISTAT_SIP\n", host->host_no);
3130 intr_scsi (host, cmd);
3131 }
3132
3133 if (istat & ISTAT_DIP) {
3134 if (hostdata->options & OPTION_DEBUG_INTR)
3135 printk ("scsi%d : ISTAT_DIP\n", host->host_no);
3136 intr_dma (host, cmd);
3137 }
3138
3139 if (!hostdata->dstat_valid) {
3140 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3141 hostdata->dstat_valid = 1;
3142 }
3143
3144 #if 1
3145
3146 if (!(hostdata->dstat & DSTAT_DFE)) {
3147 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
3148 #if 0
3149 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
3150 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
3151 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
3152 DSTAT_DFE));
3153 } else
3154 #endif
3155 {
3156 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
3157 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
3158 }
3159 }
3160 #endif
3161 }
3162 } while (interrupted);
3163
3164
3165
3166 if (hostdata->intrs != -1)
3167 hostdata->intrs++;
3168 #if 0
3169 if (hostdata->intrs > 4) {
3170 printk("scsi%d : too many interrupts, halting", host->host_no);
3171 hostdata->idle = 1;
3172 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3173 panic("dying...\n");
3174 }
3175 #endif
3176
3177 if (!hostdata->idle && hostdata->state == STATE_HALTED) {
3178 if (!hostdata->dsp_changed) {
3179 hostdata->dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3180 }
3181
3182 #if 0
3183 printk("scsi%d : new dsp is 0x%lx\n", host->host_no,
3184 (long) hostdata->dsp);
3185 #endif
3186
3187 hostdata->state = STATE_RUNNING;
3188 NCR53c7x0_write32 (DSP_REG, (unsigned long) hostdata->dsp);
3189 }
3190 }
3191 } while (!done);
3192 }
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207 static int abort_connected (struct Scsi_Host *host) {
3208 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3209 host->hostdata;
3210
3211 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
3212 sizeof(long);
3213 hostdata->dsp_changed = 1;
3214 printk ("scsi%d : DANGER : abort_connected() called \n",
3215 host->host_no);
3216
3217
3218
3219 return 0;
3220 }
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
3240 *cmd) {
3241 NCR53c7x0_local_declare();
3242 unsigned long dbc_dcmd, *dsp, *dsp_next;
3243 unsigned char dcmd, sbcl;
3244 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3245 host->hostdata;
3246 char *phase;
3247 NCR53c7x0_local_setup(host);
3248
3249 if (!cmd) {
3250 printk ("scsi%d : phase mismatch interrupt occurred with no current command.\n",
3251 host->host_no);
3252 abort_connected(host);
3253 return;
3254 }
3255
3256
3257
3258
3259
3260
3261 dsp_next = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3262
3263
3264
3265
3266
3267
3268
3269 dbc_dcmd = NCR53c7x0_read32(DBC_REG);
3270 dcmd = (dbc_dcmd & 0xff000000) >> 24;
3271 dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
3272
3273
3274
3275
3276
3277
3278
3279 sbcl = NCR53c7x0_read8(SBCL_REG);
3280 switch (sbcl) {
3281 case SBCL_PHASE_DATAIN:
3282 phase = "DATAIN";
3283 break;
3284 case SBCL_PHASE_DATAOUT:
3285 phase = "DATAOUT";
3286 break;
3287 case SBCL_PHASE_MSGIN:
3288 phase = "MSGIN";
3289 break;
3290 case SBCL_PHASE_MSGOUT:
3291 phase = "MSGOUT";
3292 break;
3293 case SBCL_PHASE_CMDOUT:
3294 phase = "CMDOUT";
3295 break;
3296 case SBCL_PHASE_STATIN:
3297 phase = "STATUSIN";
3298 break;
3299 default:
3300 phase = "unknown";
3301 break;
3302 }
3303
3304
3305
3306
3307
3308
3309
3310 if (dsp >= cmd->data_transfer_start & dsp < cmd->data_transfer_end) {
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320 switch (sbcl & SBCL_PHASE_MASK) {
3321
3322
3323
3324
3325 case SBCL_PHASE_STATIN:
3326 if (hostdata->options & OPTION_DEBUG_INTR)
3327 printk ("scsi%d : new phase = STATIN\n", host->host_no);
3328 hostdata->dsp = hostdata->script + hostdata->E_command_complete /
3329 sizeof(long);
3330 hostdata->dsp_changed = 1;
3331 return;
3332
3333
3334
3335
3336
3337
3338
3339 case SBCL_PHASE_MSGIN:
3340 if (hostdata->options & OPTION_DEBUG_INTR)
3341 printk ("scsi%d : new phase = MSGIN\n", host->host_no);
3342 if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
3343 DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
3344 DCMD_BMI_OP_MOVE_I)) {
3345 dsp[0] = dbc_dcmd;
3346 dsp[1] = NCR53c7x0_read32(DNAD_REG);
3347 NCR53c7x0_write32(TEMP_REG, (unsigned long) dsp);
3348 hostdata->dsp = hostdata->script + hostdata->E_msg_in /
3349 sizeof(long);
3350 hostdata->dsp_changed = 1;
3351 } else {
3352 printk("scsi%d : unexpected MSGIN in dynamic NCR code, dcmd=0x%x.\n",
3353 host->host_no, dcmd);
3354 print_insn (host, dsp, "", 1);
3355 print_insn (host, dsp_next, "", 1);
3356 abort_connected (host);
3357 }
3358 return;
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369 default:
3370 printk ("scsi%d : unexpected phase %s in data routine\n",
3371 host->host_no, phase);
3372 abort_connected(host);
3373 }
3374
3375
3376
3377 } else {
3378 printk ("scsi%d : unexpected phase %s at dsp = 0x%x\n",
3379 host->host_no, phase, (unsigned) dsp);
3380 print_insn (host, dsp, "", 1);
3381 print_insn (host, dsp_next, "", 1);
3382 abort_connected(host);
3383 }
3384 }
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
3398 NCR53c7x0_local_declare();
3399 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3400 host->hostdata;
3401 unsigned char dstat,
3402 dbc_dcmd;
3403 unsigned long *dsp,
3404 *next_dsp,
3405 *dsa;
3406
3407
3408 int ipl,
3409 tmp;
3410 NCR53c7x0_local_setup(host);
3411
3412 if (!hostdata->dstat_valid) {
3413 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3414 hostdata->dstat_valid = 1;
3415 }
3416
3417 dstat = hostdata->dstat;
3418
3419 if (hostdata->options & OPTION_DEBUG_INTR)
3420 printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
3421
3422 dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
3423 next_dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3424 dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
3425
3426 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439 if (dstat & DSTAT_ABRT) {
3440 #if 0
3441
3442 if ((hostdata->options & OPTION_700) && (hostdata->state ==
3443 STATE_ABORTING) {
3444 } else
3445 #endif
3446 {
3447 printk("scsi%d : unexpected abort interrupt at\n"
3448 " ", host->host_no);
3449 print_insn (host, dsp, "s ", 1);
3450 panic(" ");
3451 }
3452 }
3453
3454
3455
3456
3457
3458
3459 if (dstat & DSTAT_SSI) {
3460 if (hostdata->options & OPTION_DEBUG_TRACE) {
3461 } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
3462 print_insn (host, dsp, "s ", 0);
3463 ipl = splx(0);
3464
3465
3466 NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
3467 ~DCNTL_SSM) | DCNTL_STD);
3468 splx(ipl);
3469 } else {
3470 printk("scsi%d : unexpected single step interrupt at\n"
3471 " ", host->host_no);
3472 print_insn (host, dsp, "", 1);
3473 panic(" mail drew@colorad.edu\n");
3474 }
3475 }
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487 if (dstat & DSTAT_OPC) {
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500 if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(long))) &&
3501 (dsp <= (hostdata->script + hostdata->E_select_msgout /
3502 sizeof(long) + 8))) || (hostdata->test_running == 2)) {
3503 if (hostdata->options & OPTION_DEBUG_INTR)
3504 printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
3505 host->host_no);
3506 if (hostdata->expecting_iid) {
3507 hostdata->expecting_iid = 0;
3508 hostdata->idle = 1;
3509 if (hostdata->test_running == 2) {
3510 hostdata->test_running = 0;
3511 hostdata->test_completed = 3;
3512 } else if (cmd)
3513 abnormal_finished (cmd, DID_BAD_TARGET << 16);
3514 } else {
3515 hostdata->expecting_sto = 1;
3516 }
3517 } else {
3518 printk("scsi%d : illegal instruction ", host->host_no);
3519 print_insn (host, dsp, "", 1);
3520 printk("scsi%d : DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3521 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x,\n"
3522 " DNAD=0x%lx\n",
3523 host->host_no, (unsigned long) dsp, dbc_dcmd,
3524 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3525 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode),
3526 NCR53c7x0_read32(DNAD_REG));
3527 panic(" mail drew@Colorado.EDU\n");
3528 }
3529 }
3530
3531
3532
3533
3534
3535
3536 if (dstat & DSTAT_800_BF) {
3537 printk("scsi%d : BUS FAULT, DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3538 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x\n",
3539 host->host_no, (unsigned long) dsp, NCR53c7x0_read32(DBC_REG),
3540 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3541 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode));
3542 print_dsa (host, dsa);
3543 printk("scsi%d : DSP->\n", host->host_no);
3544 print_insn(host, dsp, "", 1);
3545 print_insn(host, next_dsp, "", 1);
3546 #if 0
3547 panic(" mail drew@Colorado.EDU\n");
3548 #else
3549 hostdata->idle = 1;
3550 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3551 #endif
3552 }
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563 if (dstat & DSTAT_SIR) {
3564 if (hostdata->options & OPTION_DEBUG_INTR)
3565 printk ("scsi%d : DSTAT_SIR\n", host->host_no);
3566 switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
3567 case SPECIFIC_INT_NOTHING:
3568 case SPECIFIC_INT_RESTART:
3569 break;
3570 case SPECIFIC_INT_ABORT:
3571 abort_connected(host);
3572 break;
3573 case SPECIFIC_INT_PANIC:
3574 printk("scsi%d : failure at ", host->host_no);
3575 print_insn (host, dsp, "", 1);
3576 panic(" dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
3577 break;
3578 case SPECIFIC_INT_BREAK:
3579 intr_break (host, cmd);
3580 break;
3581 default:
3582 printk("scsi%d : failure at ", host->host_no);
3583 print_insn (host, dsp, "", 1);
3584 panic(" dstat_sir_intr() returned unknown value %d\n",
3585 tmp);
3586 }
3587 }
3588
3589
3590 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
3591 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
3592 }
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611 static int print_insn (struct Scsi_Host *host, unsigned long *insn,
3612 char *prefix, int kernel) {
3613 char buf[80],
3614 *tmp;
3615 unsigned char dcmd;
3616 int size;
3617
3618 dcmd = (insn[0] >> 24) & 0xff;
3619 sprintf(buf, "%s%08lx : 0x%08lx 0x%08lx", (prefix ? prefix : ""),
3620 (unsigned long) insn, insn[0], insn[1]);
3621 tmp = buf + strlen(buf);
3622 if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
3623 sprintf (tmp, " 0x%08lx\n", insn[2]);
3624 size = 3;
3625 } else {
3626 sprintf (tmp, "\n");
3627 size = 2;
3628 }
3629
3630 if (kernel)
3631 printk ("%s", buf);
3632 #ifdef NCR_DEBUG
3633 else {
3634 size_t len = strlen(buf);
3635 debugger_kernel_write(host, buf, len);
3636 }
3637 #endif
3638 return size;
3639 }
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653 int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
3654 struct Scsi_Host *host = cmd->host;
3655 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3656 host->hostdata;
3657 int old_level;
3658 struct NCR53c7x0_cmd *curr, **prev;
3659 old_level = splx(0);
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 for (curr = hostdata->issue_queue, prev = &(hostdata->issue_queue);
3672 curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
3673
3674 if (curr) {
3675 *prev = curr->next;
3676
3677 if (curr->prev)
3678 curr->prev->next = curr->next;
3679
3680 if (!scan_scsis_buf_busy) {
3681 #ifdef SCSI_MALLOC
3682 scsi_free ((void *) curr->real, curr->size);
3683 #else
3684 kfree_s ((void *) curr->real, curr->size);
3685 #endif
3686 } else {
3687 scan_scsis_buf_busy = 0;
3688 }
3689
3690 cmd->result = 0;
3691 cmd->scsi_done(cmd);
3692 splx(old_level);
3693 return SCSI_ABORT_SUCCESS;
3694 }
3695
3696
3697
3698
3699
3700
3701 for (curr = hostdata->running_list, prev = &(hostdata->running_list);
3702 curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
3703
3704 if (curr) {
3705 splx(old_level);
3706 printk ("scsi%d : DANGER : command in running list, can not abort.\n",
3707 cmd->host->host_no);
3708 return SCSI_ABORT_SNOOZE;
3709 }
3710
3711
3712
3713
3714
3715
3716
3717 curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
3718
3719 if (!scan_scsis_buf_busy) {
3720 #ifdef SCSI_MALLOC
3721 scsi_free ((void *) curr->real, curr->size);
3722 #else
3723 kfree_s ((void *) curr->real, curr->size);
3724 #endif
3725 } else {
3726 scan_scsis_buf_busy = 0;
3727 }
3728
3729 if (((cmd->result & 0xff00) == 0xff00) ||
3730 ((cmd->result & 0xff) == 0xff)) {
3731 printk ("scsi%d : did this command ever run?\n", host->host_no);
3732 } else {
3733 printk ("scsi%d : probably lost INTFLY, normal completion\n",
3734 host->host_no);
3735 }
3736 cmd->scsi_done(cmd);
3737 splx(old_level);
3738 return SCSI_ABORT_SNOOZE;
3739 }
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752 int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
3753 NCR53c7x0_local_declare();
3754 struct Scsi_Host *host = cmd ? cmd->host : NULL;
3755 struct NCR53c7x0_hostdata *hostdata = host ?
3756 (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
3757 if (host) NCR53c7x0_local_setup(host);
3758
3759
3760 printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
3761 cmd->host->host_no);
3762 return SCSI_RESET_SNOOZE;
3763 }
3764
3765
3766
3767
3768
3769
3770 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
3771 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3772 host->hostdata;
3773 Scsi_Cmnd * cmd;
3774 struct NCR53c7x0_cmd * c;
3775 int i, len;
3776 char *ptr;
3777
3778 printk("scsi%d : dsa at 0x%x\n"
3779 " + %d : dsa_msgout length = %d, data = 0x%x\n" ,
3780 host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
3781 dsa[hostdata->dsa_msgout / sizeof(long)],
3782 dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
3783
3784 for (i = dsa[hostdata->dsa_msgout / sizeof(long)],
3785 ptr = (char *) dsa[hostdata->dsa_msgout / sizeof(long) + 1]; i > 0;
3786 ptr += len, i -= len) {
3787 printk(" ");
3788 len = print_msg (ptr);
3789 printk("\n");
3790 }
3791 }
3792