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