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