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