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