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