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