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