1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/slab.h>
29#include <asm/param.h>
30
31#include "sym_glue.h"
32#include "sym_nvram.h"
33
34#if 0
35#define SYM_DEBUG_GENERIC_SUPPORT
36#endif
37
38
39
40
41static void sym_int_ma (struct sym_hcb *np);
42static void sym_int_sir(struct sym_hcb *);
43static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np);
44static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
45static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln);
46static void sym_complete_error (struct sym_hcb *np, struct sym_ccb *cp);
47static void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp);
48static int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp);
49
50
51
52
53static void sym_printl_hex(u_char *p, int n)
54{
55 while (n-- > 0)
56 printf (" %x", *p++);
57 printf (".\n");
58}
59
60static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
61{
62 sym_print_addr(cp->cmd, "%s: ", label);
63
64 spi_print_msg(msg);
65 printf("\n");
66}
67
68static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
69{
70 struct sym_tcb *tp = &np->target[target];
71 dev_info(&tp->starget->dev, "%s: ", label);
72
73 spi_print_msg(msg);
74 printf("\n");
75}
76
77
78
79
80void sym_print_xerr(struct scsi_cmnd *cmd, int x_status)
81{
82 if (x_status & XE_PARITY_ERR) {
83 sym_print_addr(cmd, "unrecovered SCSI parity error.\n");
84 }
85 if (x_status & XE_EXTRA_DATA) {
86 sym_print_addr(cmd, "extraneous data discarded.\n");
87 }
88 if (x_status & XE_BAD_PHASE) {
89 sym_print_addr(cmd, "illegal scsi phase (4/5).\n");
90 }
91 if (x_status & XE_SODL_UNRUN) {
92 sym_print_addr(cmd, "ODD transfer in DATA OUT phase.\n");
93 }
94 if (x_status & XE_SWIDE_OVRUN) {
95 sym_print_addr(cmd, "ODD transfer in DATA IN phase.\n");
96 }
97}
98
99
100
101
102static char *sym_scsi_bus_mode(int mode)
103{
104 switch(mode) {
105 case SMODE_HVD: return "HVD";
106 case SMODE_SE: return "SE";
107 case SMODE_LVD: return "LVD";
108 }
109 return "??";
110}
111
112
113
114
115
116
117
118
119
120static void sym_chip_reset (struct sym_hcb *np)
121{
122 OUTB(np, nc_istat, SRST);
123 INB(np, nc_mbox1);
124 udelay(10);
125 OUTB(np, nc_istat, 0);
126 INB(np, nc_mbox1);
127 udelay(2000);
128}
129
130
131
132
133
134
135
136
137
138
139static void sym_soft_reset (struct sym_hcb *np)
140{
141 u_char istat = 0;
142 int i;
143
144 if (!(np->features & FE_ISTAT1) || !(INB(np, nc_istat1) & SCRUN))
145 goto do_chip_reset;
146
147 OUTB(np, nc_istat, CABRT);
148 for (i = 100000 ; i ; --i) {
149 istat = INB(np, nc_istat);
150 if (istat & SIP) {
151 INW(np, nc_sist);
152 }
153 else if (istat & DIP) {
154 if (INB(np, nc_dstat) & ABRT)
155 break;
156 }
157 udelay(5);
158 }
159 OUTB(np, nc_istat, 0);
160 if (!i)
161 printf("%s: unable to abort current chip operation, "
162 "ISTAT=0x%02x.\n", sym_name(np), istat);
163do_chip_reset:
164 sym_chip_reset(np);
165}
166
167
168
169
170
171
172static void sym_start_reset(struct sym_hcb *np)
173{
174 sym_reset_scsi_bus(np, 1);
175}
176
177int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
178{
179 u32 term;
180 int retv = 0;
181
182 sym_soft_reset(np);
183 if (enab_int)
184 OUTW(np, nc_sien, RST);
185
186
187
188
189 OUTB(np, nc_stest3, TE);
190 OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
191 OUTB(np, nc_scntl1, CRST);
192 INB(np, nc_mbox1);
193 udelay(200);
194
195 if (!SYM_SETUP_SCSI_BUS_CHECK)
196 goto out;
197
198
199
200
201
202
203 term = INB(np, nc_sstat0);
204 term = ((term & 2) << 7) + ((term & 1) << 17);
205 term |= ((INB(np, nc_sstat2) & 0x01) << 26) |
206 ((INW(np, nc_sbdl) & 0xff) << 9) |
207 ((INW(np, nc_sbdl) & 0xff00) << 10) |
208 INB(np, nc_sbcl);
209
210 if (!np->maxwide)
211 term &= 0x3ffff;
212
213 if (term != (2<<7)) {
214 printf("%s: suspicious SCSI data while resetting the BUS.\n",
215 sym_name(np));
216 printf("%s: %sdp0,d7-0,rst,req,ack,bsy,sel,atn,msg,c/d,i/o = "
217 "0x%lx, expecting 0x%lx\n",
218 sym_name(np),
219 (np->features & FE_WIDE) ? "dp1,d15-8," : "",
220 (u_long)term, (u_long)(2<<7));
221 if (SYM_SETUP_SCSI_BUS_CHECK == 1)
222 retv = 1;
223 }
224out:
225 OUTB(np, nc_scntl1, 0);
226 return retv;
227}
228
229
230
231
232static void sym_selectclock(struct sym_hcb *np, u_char scntl3)
233{
234
235
236
237 if (np->multiplier <= 1) {
238 OUTB(np, nc_scntl3, scntl3);
239 return;
240 }
241
242 if (sym_verbose >= 2)
243 printf ("%s: enabling clock multiplier\n", sym_name(np));
244
245 OUTB(np, nc_stest1, DBLEN);
246
247
248
249
250 if (np->features & FE_LCKFRQ) {
251 int i = 20;
252 while (!(INB(np, nc_stest4) & LCKFRQ) && --i > 0)
253 udelay(20);
254 if (!i)
255 printf("%s: the chip cannot lock the frequency\n",
256 sym_name(np));
257 } else {
258 INB(np, nc_mbox1);
259 udelay(50+10);
260 }
261 OUTB(np, nc_stest3, HSC);
262 OUTB(np, nc_scntl3, scntl3);
263 OUTB(np, nc_stest1, (DBLEN|DBLSEL));
264 OUTB(np, nc_stest3, 0x00);
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289static unsigned getfreq (struct sym_hcb *np, int gen)
290{
291 unsigned int ms = 0;
292 unsigned int f;
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309 OUTW(np, nc_sien, 0);
310 INW(np, nc_sist);
311 OUTB(np, nc_dien, 0);
312 INW(np, nc_sist);
313
314
315
316
317
318 if (np->features & FE_C10) {
319 OUTW(np, nc_sien, GEN);
320 OUTB(np, nc_istat1, SIRQD);
321 }
322 OUTB(np, nc_scntl3, 4);
323 OUTB(np, nc_stime1, 0);
324 OUTB(np, nc_stime1, gen);
325 while (!(INW(np, nc_sist) & GEN) && ms++ < 100000)
326 udelay(1000/4);
327 OUTB(np, nc_stime1, 0);
328
329
330
331 if (np->features & FE_C10) {
332 OUTW(np, nc_sien, 0);
333 OUTB(np, nc_istat1, 0);
334 }
335
336
337
338
339
340 OUTB(np, nc_scntl3, 0);
341
342
343
344
345 f = ms ? ((1 << gen) * (4340*4)) / ms : 0;
346
347
348
349
350
351 if (np->features & FE_C10)
352 f = (f * 2) / 3;
353
354 if (sym_verbose >= 2)
355 printf ("%s: Delay (GEN=%d): %u msec, %u KHz\n",
356 sym_name(np), gen, ms/4, f);
357
358 return f;
359}
360
361static unsigned sym_getfreq (struct sym_hcb *np)
362{
363 u_int f1, f2;
364 int gen = 8;
365
366 getfreq (np, gen);
367 f1 = getfreq (np, gen);
368 f2 = getfreq (np, gen);
369 if (f1 > f2) f1 = f2;
370 return f1;
371}
372
373
374
375
376static void sym_getclock (struct sym_hcb *np, int mult)
377{
378 unsigned char scntl3 = np->sv_scntl3;
379 unsigned char stest1 = np->sv_stest1;
380 unsigned f1;
381
382 np->multiplier = 1;
383 f1 = 40000;
384
385
386
387 if (mult > 1 && (stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) {
388 if (sym_verbose >= 2)
389 printf ("%s: clock multiplier found\n", sym_name(np));
390 np->multiplier = mult;
391 }
392
393
394
395
396
397
398 if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
399 OUTB(np, nc_stest1, 0);
400 f1 = sym_getfreq (np);
401
402 if (sym_verbose)
403 printf ("%s: chip clock is %uKHz\n", sym_name(np), f1);
404
405 if (f1 < 45000) f1 = 40000;
406 else if (f1 < 55000) f1 = 50000;
407 else f1 = 80000;
408
409 if (f1 < 80000 && mult > 1) {
410 if (sym_verbose >= 2)
411 printf ("%s: clock multiplier assumed\n",
412 sym_name(np));
413 np->multiplier = mult;
414 }
415 } else {
416 if ((scntl3 & 7) == 3) f1 = 40000;
417 else if ((scntl3 & 7) == 5) f1 = 80000;
418 else f1 = 160000;
419
420 f1 /= np->multiplier;
421 }
422
423
424
425
426 f1 *= np->multiplier;
427 np->clock_khz = f1;
428}
429
430
431
432
433static int sym_getpciclock (struct sym_hcb *np)
434{
435 int f = 0;
436
437
438
439
440
441#if 1
442 if (np->features & FE_66MHZ) {
443#else
444 if (1) {
445#endif
446 OUTB(np, nc_stest1, SCLK);
447 f = sym_getfreq(np);
448 OUTB(np, nc_stest1, 0);
449 }
450 np->pciclk_khz = f;
451
452 return f;
453}
454
455
456
457
458
459
460
461#define _5M 5000000
462static const u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
463
464
465
466
467
468static int
469sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
470{
471 u32 clk = np->clock_khz;
472 int div = np->clock_divn;
473 u32 fak;
474 u32 per;
475 u32 kpc;
476 int ret;
477
478
479
480
481 if (dt && sfac <= 9) per = 125;
482 else if (sfac <= 10) per = 250;
483 else if (sfac == 11) per = 303;
484 else if (sfac == 12) per = 500;
485 else per = 40 * sfac;
486 ret = per;
487
488 kpc = per * clk;
489 if (dt)
490 kpc <<= 1;
491
492
493
494
495
496
497
498
499#if 1
500 if ((np->features & (FE_C10|FE_U3EN)) == FE_C10) {
501
502
503
504
505 while (div > 0) {
506 --div;
507 if (kpc > (div_10M[div] << 2)) {
508 ++div;
509 break;
510 }
511 }
512 fak = 0;
513 if (div == np->clock_divn) {
514 ret = -1;
515 }
516 *divp = div;
517 *fakp = fak;
518 return ret;
519 }
520#endif
521
522
523
524
525
526 while (--div > 0)
527 if (kpc >= (div_10M[div] << 2)) break;
528
529
530
531
532
533
534
535 if (dt) {
536 fak = (kpc - 1) / (div_10M[div] << 1) + 1 - 2;
537
538 } else {
539 fak = (kpc - 1) / div_10M[div] + 1 - 4;
540
541 }
542
543
544
545
546 if (fak > 2) {
547 fak = 2;
548 ret = -1;
549 }
550
551
552
553
554 *divp = div;
555 *fakp = fak;
556
557 return ret;
558}
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578#define burst_length(bc) (!(bc))? 0 : 1 << (bc)
579
580
581
582
583#define burst_code(dmode, ctest4, ctest5) \
584 (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
585
586
587
588
589static inline void sym_init_burst(struct sym_hcb *np, u_char bc)
590{
591 np->rv_ctest4 &= ~0x80;
592 np->rv_dmode &= ~(0x3 << 6);
593 np->rv_ctest5 &= ~0x4;
594
595 if (!bc) {
596 np->rv_ctest4 |= 0x80;
597 }
598 else {
599 --bc;
600 np->rv_dmode |= ((bc & 0x3) << 6);
601 np->rv_ctest5 |= (bc & 0x4);
602 }
603}
604
605
606
607
608
609
610
611
612
613
614static void sym_save_initial_setting (struct sym_hcb *np)
615{
616 np->sv_scntl0 = INB(np, nc_scntl0) & 0x0a;
617 np->sv_scntl3 = INB(np, nc_scntl3) & 0x07;
618 np->sv_dmode = INB(np, nc_dmode) & 0xce;
619 np->sv_dcntl = INB(np, nc_dcntl) & 0xa8;
620 np->sv_ctest3 = INB(np, nc_ctest3) & 0x01;
621 np->sv_ctest4 = INB(np, nc_ctest4) & 0x80;
622 np->sv_gpcntl = INB(np, nc_gpcntl);
623 np->sv_stest1 = INB(np, nc_stest1);
624 np->sv_stest2 = INB(np, nc_stest2) & 0x20;
625 np->sv_stest4 = INB(np, nc_stest4);
626 if (np->features & FE_C10) {
627 np->sv_scntl4 = INB(np, nc_scntl4);
628 np->sv_ctest5 = INB(np, nc_ctest5) & 0x04;
629 }
630 else
631 np->sv_ctest5 = INB(np, nc_ctest5) & 0x24;
632}
633
634
635
636
637
638
639
640
641static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram)
642{
643 if (np->scsi_mode)
644 return;
645
646 np->scsi_mode = SMODE_SE;
647 if (np->features & (FE_ULTRA2|FE_ULTRA3))
648 np->scsi_mode = (np->sv_stest4 & SMODE);
649 else if (np->features & FE_DIFF) {
650 if (SYM_SETUP_SCSI_DIFF == 1) {
651 if (np->sv_scntl3) {
652 if (np->sv_stest2 & 0x20)
653 np->scsi_mode = SMODE_HVD;
654 } else if (nvram->type == SYM_SYMBIOS_NVRAM) {
655 if (!(INB(np, nc_gpreg) & 0x08))
656 np->scsi_mode = SMODE_HVD;
657 }
658 } else if (SYM_SETUP_SCSI_DIFF == 2)
659 np->scsi_mode = SMODE_HVD;
660 }
661 if (np->scsi_mode == SMODE_HVD)
662 np->rv_stest2 |= 0x20;
663}
664
665
666
667
668
669static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram)
670{
671 struct sym_data *sym_data = shost_priv(shost);
672 struct pci_dev *pdev = sym_data->pdev;
673 u_char burst_max;
674 u32 period;
675 int i;
676
677 np->maxwide = (np->features & FE_WIDE) ? 1 : 0;
678
679
680
681
682 if (np->features & (FE_ULTRA3 | FE_ULTRA2))
683 np->clock_khz = 160000;
684 else if (np->features & FE_ULTRA)
685 np->clock_khz = 80000;
686 else
687 np->clock_khz = 40000;
688
689
690
691
692 if (np->features & FE_QUAD)
693 np->multiplier = 4;
694 else if (np->features & FE_DBLR)
695 np->multiplier = 2;
696 else
697 np->multiplier = 1;
698
699
700
701
702
703 if (np->features & FE_VARCLK)
704 sym_getclock(np, np->multiplier);
705
706
707
708
709 i = np->clock_divn - 1;
710 while (--i >= 0) {
711 if (10ul * SYM_CONF_MIN_ASYNC * np->clock_khz > div_10M[i]) {
712 ++i;
713 break;
714 }
715 }
716 np->rv_scntl3 = i+1;
717
718
719
720
721
722 if (np->features & FE_C10)
723 np->rv_scntl3 = 0;
724
725
726
727
728
729 period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
730
731 if (period <= 250) np->minsync = 10;
732 else if (period <= 303) np->minsync = 11;
733 else if (period <= 500) np->minsync = 12;
734 else np->minsync = (period + 40 - 1) / 40;
735
736
737
738
739 if (np->minsync < 25 &&
740 !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3)))
741 np->minsync = 25;
742 else if (np->minsync < 12 &&
743 !(np->features & (FE_ULTRA2|FE_ULTRA3)))
744 np->minsync = 12;
745
746
747
748
749 period = div64_ul(11 * div_10M[np->clock_divn - 1], 4 * np->clock_khz);
750 np->maxsync = period > 2540 ? 254 : period / 10;
751
752
753
754
755 if ((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) {
756 if (np->clock_khz == 160000) {
757 np->minsync_dt = 9;
758 np->maxsync_dt = 50;
759 np->maxoffs_dt = nvram->type ? 62 : 31;
760 }
761 }
762
763
764
765
766 if (np->features & FE_DAC) {
767 if (!use_dac(np))
768 np->rv_ccntl1 |= (DDAC);
769 else if (SYM_CONF_DMA_ADDRESSING_MODE == 1)
770 np->rv_ccntl1 |= (XTIMOD | EXTIBMV);
771 else if (SYM_CONF_DMA_ADDRESSING_MODE == 2)
772 np->rv_ccntl1 |= (0 | EXTIBMV);
773 }
774
775
776
777
778 if (np->features & FE_NOPM)
779 np->rv_ccntl0 |= (ENPMJ);
780
781
782
783
784
785
786 if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 &&
787 pdev->revision < 0x1)
788 np->rv_ccntl0 |= DILS;
789
790
791
792
793 burst_max = SYM_SETUP_BURST_ORDER;
794 if (burst_max == 255)
795 burst_max = burst_code(np->sv_dmode, np->sv_ctest4,
796 np->sv_ctest5);
797 if (burst_max > 7)
798 burst_max = 7;
799 if (burst_max > np->maxburst)
800 burst_max = np->maxburst;
801
802
803
804
805
806
807
808
809
810 if ((pdev->device == PCI_DEVICE_ID_NCR_53C810 &&
811 pdev->revision >= 0x10 && pdev->revision <= 0x11) ||
812 (pdev->device == PCI_DEVICE_ID_NCR_53C860 &&
813 pdev->revision <= 0x1))
814 np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
815
816
817
818
819
820
821
822 if (np->features & FE_ERL)
823 np->rv_dmode |= ERL;
824 if (np->features & FE_BOF)
825 np->rv_dmode |= BOF;
826 if (np->features & FE_ERMP)
827 np->rv_dmode |= ERMP;
828#if 1
829 if ((np->features & FE_PFEN) && !np->ram_ba)
830#else
831 if (np->features & FE_PFEN)
832#endif
833 np->rv_dcntl |= PFEN;
834 if (np->features & FE_CLSE)
835 np->rv_dcntl |= CLSE;
836 if (np->features & FE_WRIE)
837 np->rv_ctest3 |= WRIE;
838 if (np->features & FE_DFS)
839 np->rv_ctest5 |= DFS;
840
841
842
843
844 np->rv_ctest4 |= MPEE;
845 np->rv_scntl0 |= 0x0a;
846
847
848
849
850 np->myaddr = 255;
851 np->scsi_mode = 0;
852 sym_nvram_setup_host(shost, np, nvram);
853
854
855
856
857 if (np->myaddr == 255) {
858 np->myaddr = INB(np, nc_scid) & 0x07;
859 if (!np->myaddr)
860 np->myaddr = SYM_SETUP_HOST_ID;
861 }
862
863
864
865
866 sym_init_burst(np, burst_max);
867
868 sym_set_bus_mode(np, nvram);
869
870
871
872
873
874
875
876 if ((SYM_SETUP_SCSI_LED ||
877 (nvram->type == SYM_SYMBIOS_NVRAM ||
878 (nvram->type == SYM_TEKRAM_NVRAM &&
879 pdev->device == PCI_DEVICE_ID_NCR_53C895))) &&
880 !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))
881 np->features |= FE_LED0;
882
883
884
885
886 switch(SYM_SETUP_IRQ_MODE & 3) {
887 case 2:
888 np->rv_dcntl |= IRQM;
889 break;
890 case 1:
891 np->rv_dcntl |= (np->sv_dcntl & IRQM);
892 break;
893 default:
894 break;
895 }
896
897
898
899
900
901 for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
902 struct sym_tcb *tp = &np->target[i];
903
904 tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
905 tp->usrtags = SYM_SETUP_MAX_TAG;
906 tp->usr_width = np->maxwide;
907 tp->usr_period = 9;
908
909 sym_nvram_setup_target(tp, i, nvram);
910
911 if (!tp->usrtags)
912 tp->usrflags &= ~SYM_TAGS_ENABLED;
913 }
914
915
916
917
918 printf("%s: %s, ID %d, Fast-%d, %s, %s\n", sym_name(np),
919 sym_nvram_type(nvram), np->myaddr,
920 (np->features & FE_ULTRA3) ? 80 :
921 (np->features & FE_ULTRA2) ? 40 :
922 (np->features & FE_ULTRA) ? 20 : 10,
923 sym_scsi_bus_mode(np->scsi_mode),
924 (np->rv_scntl0 & 0xa) ? "parity checking" : "NO parity");
925
926
927
928 if (sym_verbose) {
929 printf("%s: %s IRQ line driver%s\n",
930 sym_name(np),
931 np->rv_dcntl & IRQM ? "totem pole" : "open drain",
932 np->ram_ba ? ", using on-chip SRAM" : "");
933 printf("%s: using %s firmware.\n", sym_name(np), np->fw_name);
934 if (np->features & FE_NOPM)
935 printf("%s: handling phase mismatch from SCRIPTS.\n",
936 sym_name(np));
937 }
938
939
940
941 if (sym_verbose >= 2) {
942 printf ("%s: initial SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
943 "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
944 sym_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl,
945 np->sv_ctest3, np->sv_ctest4, np->sv_ctest5);
946
947 printf ("%s: final SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
948 "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
949 sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
950 np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
951 }
952
953 return 0;
954}
955
956
957
958
959
960
961#ifdef CONFIG_SCSI_SYM53C8XX_MMIO
962static int sym_regtest(struct sym_hcb *np)
963{
964 register volatile u32 data;
965
966
967
968
969
970 data = 0xffffffff;
971 OUTL(np, nc_dstat, data);
972 data = INL(np, nc_dstat);
973#if 1
974 if (data == 0xffffffff) {
975#else
976 if ((data & 0xe2f0fffd) != 0x02000080) {
977#endif
978 printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
979 (unsigned) data);
980 return 0x10;
981 }
982 return 0;
983}
984#else
985static inline int sym_regtest(struct sym_hcb *np)
986{
987 return 0;
988}
989#endif
990
991static int sym_snooptest(struct sym_hcb *np)
992{
993 u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
994 int i, err;
995
996 err = sym_regtest(np);
997 if (err)
998 return err;
999restart_test:
1000
1001
1002
1003
1004 OUTB(np, nc_ctest4, (np->rv_ctest4 & MPEE));
1005
1006
1007
1008 pc = SCRIPTZ_BA(np, snooptest);
1009 host_wr = 1;
1010 sym_wr = 2;
1011
1012
1013
1014 np->scratch = cpu_to_scr(host_wr);
1015 OUTL(np, nc_temp, sym_wr);
1016
1017
1018
1019 OUTL(np, nc_dsa, np->hcb_ba);
1020 OUTL_DSP(np, pc);
1021
1022
1023
1024 for (i=0; i<SYM_SNOOP_TIMEOUT; i++)
1025 if (INB(np, nc_istat) & (INTF|SIP|DIP))
1026 break;
1027 if (i>=SYM_SNOOP_TIMEOUT) {
1028 printf ("CACHE TEST FAILED: timeout.\n");
1029 return (0x20);
1030 }
1031
1032
1033
1034 dstat = INB(np, nc_dstat);
1035#if 1
1036 if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {
1037 printf ("%s: PCI DATA PARITY ERROR DETECTED - "
1038 "DISABLING MASTER DATA PARITY CHECKING.\n",
1039 sym_name(np));
1040 np->rv_ctest4 &= ~MPEE;
1041 goto restart_test;
1042 }
1043#endif
1044 if (dstat & (MDPE|BF|IID)) {
1045 printf ("CACHE TEST FAILED: DMA error (dstat=0x%02x).", dstat);
1046 return (0x80);
1047 }
1048
1049
1050
1051 pc = INL(np, nc_dsp);
1052
1053
1054
1055 host_rd = scr_to_cpu(np->scratch);
1056 sym_rd = INL(np, nc_scratcha);
1057 sym_bk = INL(np, nc_temp);
1058
1059
1060
1061 if (pc != SCRIPTZ_BA(np, snoopend)+8) {
1062 printf ("CACHE TEST FAILED: script execution failed.\n");
1063 printf ("start=%08lx, pc=%08lx, end=%08lx\n",
1064 (u_long) SCRIPTZ_BA(np, snooptest), (u_long) pc,
1065 (u_long) SCRIPTZ_BA(np, snoopend) +8);
1066 return (0x40);
1067 }
1068
1069
1070
1071 if (host_wr != sym_rd) {
1072 printf ("CACHE TEST FAILED: host wrote %d, chip read %d.\n",
1073 (int) host_wr, (int) sym_rd);
1074 err |= 1;
1075 }
1076 if (host_rd != sym_wr) {
1077 printf ("CACHE TEST FAILED: chip wrote %d, host read %d.\n",
1078 (int) sym_wr, (int) host_rd);
1079 err |= 2;
1080 }
1081 if (sym_bk != sym_wr) {
1082 printf ("CACHE TEST FAILED: chip wrote %d, read back %d.\n",
1083 (int) sym_wr, (int) sym_bk);
1084 err |= 4;
1085 }
1086
1087 return err;
1088}
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117static void sym_log_hard_error(struct Scsi_Host *shost, u_short sist, u_char dstat)
1118{
1119 struct sym_hcb *np = sym_get_hcb(shost);
1120 u32 dsp;
1121 int script_ofs;
1122 int script_size;
1123 char *script_name;
1124 u_char *script_base;
1125 int i;
1126
1127 dsp = INL(np, nc_dsp);
1128
1129 if (dsp > np->scripta_ba &&
1130 dsp <= np->scripta_ba + np->scripta_sz) {
1131 script_ofs = dsp - np->scripta_ba;
1132 script_size = np->scripta_sz;
1133 script_base = (u_char *) np->scripta0;
1134 script_name = "scripta";
1135 }
1136 else if (np->scriptb_ba < dsp &&
1137 dsp <= np->scriptb_ba + np->scriptb_sz) {
1138 script_ofs = dsp - np->scriptb_ba;
1139 script_size = np->scriptb_sz;
1140 script_base = (u_char *) np->scriptb0;
1141 script_name = "scriptb";
1142 } else {
1143 script_ofs = dsp;
1144 script_size = 0;
1145 script_base = NULL;
1146 script_name = "mem";
1147 }
1148
1149 printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x/%x) @ (%s %x:%08x).\n",
1150 sym_name(np), (unsigned)INB(np, nc_sdid)&0x0f, dstat, sist,
1151 (unsigned)INB(np, nc_socl), (unsigned)INB(np, nc_sbcl),
1152 (unsigned)INB(np, nc_sbdl), (unsigned)INB(np, nc_sxfer),
1153 (unsigned)INB(np, nc_scntl3),
1154 (np->features & FE_C10) ? (unsigned)INB(np, nc_scntl4) : 0,
1155 script_name, script_ofs, (unsigned)INL(np, nc_dbc));
1156
1157 if (((script_ofs & 3) == 0) &&
1158 (unsigned)script_ofs < script_size) {
1159 printf ("%s: script cmd = %08x\n", sym_name(np),
1160 scr_to_cpu((int) *(u32 *)(script_base + script_ofs)));
1161 }
1162
1163 printf("%s: regdump:", sym_name(np));
1164 for (i = 0; i < 24; i++)
1165 printf(" %02x", (unsigned)INB_OFF(np, i));
1166 printf(".\n");
1167
1168
1169
1170
1171 if (dstat & (MDPE|BF))
1172 sym_log_bus_error(shost);
1173}
1174
1175void sym_dump_registers(struct Scsi_Host *shost)
1176{
1177 struct sym_hcb *np = sym_get_hcb(shost);
1178 u_short sist;
1179 u_char dstat;
1180
1181 sist = INW(np, nc_sist);
1182 dstat = INB(np, nc_dstat);
1183 sym_log_hard_error(shost, sist, dstat);
1184}
1185
1186static struct sym_chip sym_dev_table[] = {
1187 {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64,
1188 FE_ERL}
1189 ,
1190#ifdef SYM_DEBUG_GENERIC_SUPPORT
1191 {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1,
1192 FE_BOF}
1193 ,
1194#else
1195 {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1,
1196 FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF}
1197 ,
1198#endif
1199 {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4, 8, 4, 64,
1200 FE_BOF|FE_ERL}
1201 ,
1202 {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6, 8, 4, 64,
1203 FE_WIDE|FE_BOF|FE_ERL|FE_DIFF}
1204 ,
1205 {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6, 8, 4, 2,
1206 FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF}
1207 ,
1208 {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4, 8, 5, 1,
1209 FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN}
1210 ,
1211 {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2,
1212 FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1213 FE_RAM|FE_DIFF|FE_VARCLK}
1214 ,
1215 {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2,
1216 FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1217 FE_RAM|FE_DIFF|FE_VARCLK}
1218 ,
1219 {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2,
1220 FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1221 FE_RAM|FE_DIFF|FE_VARCLK}
1222 ,
1223 {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2,
1224 FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1225 FE_RAM|FE_DIFF|FE_VARCLK}
1226 ,
1227#ifdef SYM_DEBUG_GENERIC_SUPPORT
1228 {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
1229 FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|
1230 FE_RAM|FE_LCKFRQ}
1231 ,
1232#else
1233 {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
1234 FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1235 FE_RAM|FE_LCKFRQ}
1236 ,
1237#endif
1238 {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4,
1239 FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1240 FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
1241 ,
1242 {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4,
1243 FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1244 FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
1245 ,
1246 {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4,
1247 FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1248 FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
1249 ,
1250 {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
1251 FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
1252 FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
1253 FE_C10}
1254 ,
1255 {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
1256 FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
1257 FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
1258 FE_C10|FE_U3EN}
1259 ,
1260 {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
1261 FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
1262 FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC|
1263 FE_C10|FE_U3EN}
1264 ,
1265 {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4,
1266 FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
1267 FE_RAM|FE_IO256|FE_LEDC}
1268};
1269
1270#define sym_num_devs (ARRAY_SIZE(sym_dev_table))
1271
1272
1273
1274
1275
1276
1277
1278struct sym_chip *
1279sym_lookup_chip_table (u_short device_id, u_char revision)
1280{
1281 struct sym_chip *chip;
1282 int i;
1283
1284 for (i = 0; i < sym_num_devs; i++) {
1285 chip = &sym_dev_table[i];
1286 if (device_id != chip->device_id)
1287 continue;
1288 if (revision > chip->revision_id)
1289 continue;
1290 return chip;
1291 }
1292
1293 return NULL;
1294}
1295
1296#if SYM_CONF_DMA_ADDRESSING_MODE == 2
1297
1298
1299
1300
1301
1302int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s)
1303{
1304 int i;
1305
1306 if (!use_dac(np))
1307 goto weird;
1308
1309
1310 for (i = SYM_DMAP_SIZE-1; i > 0; i--) {
1311 if (h == np->dmap_bah[i])
1312 return i;
1313 }
1314
1315 if (!np->dmap_bah[s])
1316 goto new;
1317
1318 for (s = SYM_DMAP_SIZE-1; s > 0; s--) {
1319 if (!np->dmap_bah[s])
1320 goto new;
1321 }
1322weird:
1323 panic("sym: ran out of 64 bit DMA segment registers");
1324 return -1;
1325new:
1326 np->dmap_bah[s] = h;
1327 np->dmap_dirty = 1;
1328 return s;
1329}
1330
1331
1332
1333
1334
1335static void sym_update_dmap_regs(struct sym_hcb *np)
1336{
1337 int o, i;
1338
1339 if (!np->dmap_dirty)
1340 return;
1341 o = offsetof(struct sym_reg, nc_scrx[0]);
1342 for (i = 0; i < SYM_DMAP_SIZE; i++) {
1343 OUTL_OFF(np, o, np->dmap_bah[i]);
1344 o += 4;
1345 }
1346 np->dmap_dirty = 0;
1347}
1348#endif
1349
1350
1351static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
1352 struct sym_trans *goal)
1353{
1354 if (!spi_support_wide(starget))
1355 goal->width = 0;
1356
1357 if (!spi_support_sync(starget)) {
1358 goal->iu = 0;
1359 goal->dt = 0;
1360 goal->qas = 0;
1361 goal->offset = 0;
1362 return;
1363 }
1364
1365 if (spi_support_dt(starget)) {
1366 if (spi_support_dt_only(starget))
1367 goal->dt = 1;
1368
1369 if (goal->offset == 0)
1370 goal->dt = 0;
1371 } else {
1372 goal->dt = 0;
1373 }
1374
1375
1376 if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))
1377 goal->dt = 0;
1378
1379 if (goal->dt) {
1380
1381 goal->width = 1;
1382 if (goal->offset > np->maxoffs_dt)
1383 goal->offset = np->maxoffs_dt;
1384 if (goal->period < np->minsync_dt)
1385 goal->period = np->minsync_dt;
1386 if (goal->period > np->maxsync_dt)
1387 goal->period = np->maxsync_dt;
1388 } else {
1389 goal->iu = goal->qas = 0;
1390 if (goal->offset > np->maxoffs)
1391 goal->offset = np->maxoffs;
1392 if (goal->period < np->minsync)
1393 goal->period = np->minsync;
1394 if (goal->period > np->maxsync)
1395 goal->period = np->maxsync;
1396 }
1397}
1398
1399
1400
1401
1402
1403
1404
1405
1406static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
1407{
1408 struct sym_tcb *tp = &np->target[cp->target];
1409 struct scsi_target *starget = tp->starget;
1410 struct sym_trans *goal = &tp->tgoal;
1411 int msglen = 0;
1412 int nego;
1413
1414 sym_check_goals(np, starget, goal);
1415
1416
1417
1418
1419
1420 if (goal->renego == NS_PPR || (goal->offset &&
1421 (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)))) {
1422 nego = NS_PPR;
1423 } else if (goal->renego == NS_WIDE || goal->width) {
1424 nego = NS_WIDE;
1425 } else if (goal->renego == NS_SYNC || goal->offset) {
1426 nego = NS_SYNC;
1427 } else {
1428 goal->check_nego = 0;
1429 nego = 0;
1430 }
1431
1432 switch (nego) {
1433 case NS_SYNC:
1434 msglen += spi_populate_sync_msg(msgptr + msglen, goal->period,
1435 goal->offset);
1436 break;
1437 case NS_WIDE:
1438 msglen += spi_populate_width_msg(msgptr + msglen, goal->width);
1439 break;
1440 case NS_PPR:
1441 msglen += spi_populate_ppr_msg(msgptr + msglen, goal->period,
1442 goal->offset, goal->width,
1443 (goal->iu ? PPR_OPT_IU : 0) |
1444 (goal->dt ? PPR_OPT_DT : 0) |
1445 (goal->qas ? PPR_OPT_QAS : 0));
1446 break;
1447 }
1448
1449 cp->nego_status = nego;
1450
1451 if (nego) {
1452 tp->nego_cp = cp;
1453 if (DEBUG_FLAGS & DEBUG_NEGO) {
1454 sym_print_nego_msg(np, cp->target,
1455 nego == NS_SYNC ? "sync msgout" :
1456 nego == NS_WIDE ? "wide msgout" :
1457 "ppr msgout", msgptr);
1458 }
1459 }
1460
1461 return msglen;
1462}
1463
1464
1465
1466
1467void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
1468{
1469 u_short qidx;
1470
1471#ifdef SYM_CONF_IARB_SUPPORT
1472
1473
1474
1475
1476
1477
1478
1479
1480 if (np->last_cp && np->iarb_count < np->iarb_max) {
1481 np->last_cp->host_flags |= HF_HINT_IARB;
1482 ++np->iarb_count;
1483 }
1484 else
1485 np->iarb_count = 0;
1486 np->last_cp = cp;
1487#endif
1488
1489#if SYM_CONF_DMA_ADDRESSING_MODE == 2
1490
1491
1492
1493
1494 if (np->dmap_dirty)
1495 cp->host_xflags |= HX_DMAP_DIRTY;
1496#endif
1497
1498
1499
1500
1501
1502 qidx = np->squeueput + 2;
1503 if (qidx >= MAX_QUEUE*2) qidx = 0;
1504
1505 np->squeue [qidx] = cpu_to_scr(np->idletask_ba);
1506 MEMORY_WRITE_BARRIER();
1507 np->squeue [np->squeueput] = cpu_to_scr(cp->ccb_ba);
1508
1509 np->squeueput = qidx;
1510
1511 if (DEBUG_FLAGS & DEBUG_QUEUE)
1512 scmd_printk(KERN_DEBUG, cp->cmd, "queuepos=%d\n",
1513 np->squeueput);
1514
1515
1516
1517
1518
1519 MEMORY_WRITE_BARRIER();
1520 OUTB(np, nc_istat, SIGP|np->istat_sem);
1521}
1522
1523#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
1524
1525
1526
1527void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn)
1528{
1529 SYM_QUEHEAD *qp;
1530 struct sym_ccb *cp;
1531
1532
1533
1534
1535 assert(!lp->started_tags || !lp->started_no_tag);
1536
1537
1538
1539
1540
1541
1542 while (maxn--) {
1543 qp = sym_remque_head(&lp->waiting_ccbq);
1544 if (!qp)
1545 break;
1546 cp = sym_que_entry(qp, struct sym_ccb, link2_ccbq);
1547 if (cp->tag != NO_TAG) {
1548 if (lp->started_no_tag ||
1549 lp->started_tags >= lp->started_max) {
1550 sym_insque_head(qp, &lp->waiting_ccbq);
1551 break;
1552 }
1553 lp->itlq_tbl[cp->tag] = cpu_to_scr(cp->ccb_ba);
1554 lp->head.resel_sa =
1555 cpu_to_scr(SCRIPTA_BA(np, resel_tag));
1556 ++lp->started_tags;
1557 } else {
1558 if (lp->started_no_tag || lp->started_tags) {
1559 sym_insque_head(qp, &lp->waiting_ccbq);
1560 break;
1561 }
1562 lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
1563 lp->head.resel_sa =
1564 cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
1565 ++lp->started_no_tag;
1566 }
1567 cp->started = 1;
1568 sym_insque_tail(qp, &lp->started_ccbq);
1569 sym_put_start_queue(np, cp);
1570 }
1571}
1572#endif
1573
1574
1575
1576
1577
1578
1579
1580
1581static int sym_wakeup_done (struct sym_hcb *np)
1582{
1583 struct sym_ccb *cp;
1584 int i, n;
1585 u32 dsa;
1586
1587 n = 0;
1588 i = np->dqueueget;
1589
1590
1591 while (1) {
1592 dsa = scr_to_cpu(np->dqueue[i]);
1593 if (!dsa)
1594 break;
1595 np->dqueue[i] = 0;
1596 if ((i = i+2) >= MAX_QUEUE*2)
1597 i = 0;
1598
1599 cp = sym_ccb_from_dsa(np, dsa);
1600 if (cp) {
1601 MEMORY_READ_BARRIER();
1602 sym_complete_ok (np, cp);
1603 ++n;
1604 }
1605 else
1606 printf ("%s: bad DSA (%x) in done queue.\n",
1607 sym_name(np), (u_int) dsa);
1608 }
1609 np->dqueueget = i;
1610
1611 return n;
1612}
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
1629{
1630 SYM_QUEHEAD *qp;
1631 struct sym_ccb *cp;
1632
1633 while ((qp = sym_remque_head(&np->comp_ccbq)) != NULL) {
1634 struct scsi_cmnd *cmd;
1635 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
1636 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
1637
1638 if (cp->host_status == HS_WAIT)
1639 continue;
1640 cmd = cp->cmd;
1641 if (cam_status)
1642 sym_set_cam_status(cmd, cam_status);
1643#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
1644 if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) {
1645 struct sym_tcb *tp = &np->target[cp->target];
1646 struct sym_lcb *lp = sym_lp(tp, cp->lun);
1647 if (lp) {
1648 sym_remque(&cp->link2_ccbq);
1649 sym_insque_tail(&cp->link2_ccbq,
1650 &lp->waiting_ccbq);
1651 if (cp->started) {
1652 if (cp->tag != NO_TAG)
1653 --lp->started_tags;
1654 else
1655 --lp->started_no_tag;
1656 }
1657 }
1658 cp->started = 0;
1659 continue;
1660 }
1661#endif
1662 sym_free_ccb(np, cp);
1663 sym_xpt_done(np, cmd);
1664 }
1665}
1666
1667
1668
1669
1670
1671static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status)
1672{
1673
1674
1675
1676
1677 sym_que_splice(&np->busy_ccbq, &np->comp_ccbq);
1678 sym_que_init(&np->busy_ccbq);
1679 sym_flush_comp_queue(np, cam_status);
1680}
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690void sym_start_up(struct Scsi_Host *shost, int reason)
1691{
1692 struct sym_data *sym_data = shost_priv(shost);
1693 struct pci_dev *pdev = sym_data->pdev;
1694 struct sym_hcb *np = sym_data->ncb;
1695 int i;
1696 u32 phys;
1697
1698
1699
1700
1701 if (reason == 1)
1702 sym_soft_reset(np);
1703 else {
1704 OUTB(np, nc_stest3, TE|CSF);
1705 OUTONB(np, nc_ctest3, CLF);
1706 }
1707
1708
1709
1710
1711 phys = np->squeue_ba;
1712 for (i = 0; i < MAX_QUEUE*2; i += 2) {
1713 np->squeue[i] = cpu_to_scr(np->idletask_ba);
1714 np->squeue[i+1] = cpu_to_scr(phys + (i+2)*4);
1715 }
1716 np->squeue[MAX_QUEUE*2-1] = cpu_to_scr(phys);
1717
1718
1719
1720
1721 np->squeueput = 0;
1722
1723
1724
1725
1726 phys = np->dqueue_ba;
1727 for (i = 0; i < MAX_QUEUE*2; i += 2) {
1728 np->dqueue[i] = 0;
1729 np->dqueue[i+1] = cpu_to_scr(phys + (i+2)*4);
1730 }
1731 np->dqueue[MAX_QUEUE*2-1] = cpu_to_scr(phys);
1732
1733
1734
1735
1736 np->dqueueget = 0;
1737
1738
1739
1740
1741
1742
1743 np->fw_patch(shost);
1744
1745
1746
1747
1748 sym_flush_busy_queue(np, DID_RESET);
1749
1750
1751
1752
1753 OUTB(np, nc_istat, 0x00);
1754 INB(np, nc_mbox1);
1755 udelay(2000);
1756
1757 OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
1758
1759 OUTB(np, nc_scntl1, 0x00);
1760
1761 sym_selectclock(np, np->rv_scntl3);
1762
1763 OUTB(np, nc_scid , RRE|np->myaddr);
1764 OUTW(np, nc_respid, 1ul<<np->myaddr);
1765 OUTB(np, nc_istat , SIGP );
1766 OUTB(np, nc_dmode , np->rv_dmode);
1767 OUTB(np, nc_ctest5, np->rv_ctest5);
1768
1769 OUTB(np, nc_dcntl , NOCOM|np->rv_dcntl);
1770 OUTB(np, nc_ctest3, np->rv_ctest3);
1771 OUTB(np, nc_ctest4, np->rv_ctest4);
1772
1773
1774 if (np->features & FE_C10)
1775 OUTB(np, nc_stest2, np->rv_stest2);
1776 else
1777 OUTB(np, nc_stest2, EXT|np->rv_stest2);
1778
1779 OUTB(np, nc_stest3, TE);
1780 OUTB(np, nc_stime0, 0x0c);
1781
1782
1783
1784
1785 if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_66)
1786 OUTB(np, nc_aipcntl1, DISAIP);
1787
1788
1789
1790
1791
1792
1793
1794
1795 if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 &&
1796 pdev->revision < 1)
1797 OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30);
1798
1799
1800
1801
1802
1803
1804 if (pdev->device == PCI_DEVICE_ID_NCR_53C875)
1805 OUTB(np, nc_ctest0, (1<<5));
1806 else if (pdev->device == PCI_DEVICE_ID_NCR_53C896)
1807 np->rv_ccntl0 |= DPR;
1808
1809
1810
1811
1812
1813
1814 if (np->features & (FE_DAC|FE_NOPM)) {
1815 OUTB(np, nc_ccntl0, np->rv_ccntl0);
1816 OUTB(np, nc_ccntl1, np->rv_ccntl1);
1817 }
1818
1819#if SYM_CONF_DMA_ADDRESSING_MODE == 2
1820
1821
1822
1823
1824 if (use_dac(np)) {
1825 np->dmap_bah[0] = 0;
1826 OUTL(np, nc_scrx[0], np->dmap_bah[0]);
1827 OUTL(np, nc_drs, np->dmap_bah[0]);
1828 }
1829#endif
1830
1831
1832
1833
1834
1835 if (np->features & FE_NOPM) {
1836 OUTL(np, nc_pmjad1, SCRIPTB_BA(np, pm_handle));
1837 OUTL(np, nc_pmjad2, SCRIPTB_BA(np, pm_handle));
1838 }
1839
1840
1841
1842
1843
1844 if (np->features & FE_LED0)
1845 OUTB(np, nc_gpcntl, INB(np, nc_gpcntl) & ~0x01);
1846 else if (np->features & FE_LEDC)
1847 OUTB(np, nc_gpcntl, (INB(np, nc_gpcntl) & ~0x41) | 0x20);
1848
1849
1850
1851
1852 OUTW(np, nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR);
1853 OUTB(np, nc_dien , MDPE|BF|SSI|SIR|IID);
1854
1855
1856
1857
1858
1859
1860 if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
1861 OUTONW(np, nc_sien, SBMC);
1862 if (reason == 0) {
1863 INB(np, nc_mbox1);
1864 mdelay(100);
1865 INW(np, nc_sist);
1866 }
1867 np->scsi_mode = INB(np, nc_stest4) & SMODE;
1868 }
1869
1870
1871
1872
1873
1874
1875
1876 for (i=0;i<SYM_CONF_MAX_TARGET;i++) {
1877 struct sym_tcb *tp = &np->target[i];
1878
1879 tp->to_reset = 0;
1880 tp->head.sval = 0;
1881 tp->head.wval = np->rv_scntl3;
1882 tp->head.uval = 0;
1883 if (tp->lun0p)
1884 tp->lun0p->to_clear = 0;
1885 if (tp->lunmp) {
1886 int ln;
1887
1888 for (ln = 1; ln < SYM_CONF_MAX_LUN; ln++)
1889 if (tp->lunmp[ln])
1890 tp->lunmp[ln]->to_clear = 0;
1891 }
1892 }
1893
1894
1895
1896
1897
1898
1899
1900
1901 phys = SCRIPTA_BA(np, init);
1902 if (np->ram_ba) {
1903 if (sym_verbose >= 2)
1904 printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np));
1905 memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz);
1906 if (np->features & FE_RAM8K) {
1907 memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz);
1908 phys = scr_to_cpu(np->scr_ram_seg);
1909 OUTL(np, nc_mmws, phys);
1910 OUTL(np, nc_mmrs, phys);
1911 OUTL(np, nc_sfs, phys);
1912 phys = SCRIPTB_BA(np, start64);
1913 }
1914 }
1915
1916 np->istat_sem = 0;
1917
1918 OUTL(np, nc_dsa, np->hcb_ba);
1919 OUTL_DSP(np, phys);
1920
1921
1922
1923
1924 if (reason != 0)
1925 sym_xpt_async_bus_reset(np);
1926}
1927
1928
1929
1930
1931static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs,
1932 u_char per, u_char wide, u_char div, u_char fak)
1933{
1934 SYM_QUEHEAD *qp;
1935 u_char sval, wval, uval;
1936 struct sym_tcb *tp = &np->target[target];
1937
1938 assert(target == (INB(np, nc_sdid) & 0x0f));
1939
1940 sval = tp->head.sval;
1941 wval = tp->head.wval;
1942 uval = tp->head.uval;
1943
1944#if 0
1945 printf("XXXX sval=%x wval=%x uval=%x (%x)\n",
1946 sval, wval, uval, np->rv_scntl3);
1947#endif
1948
1949
1950
1951 if (!(np->features & FE_C10))
1952 sval = (sval & ~0x1f) | ofs;
1953 else
1954 sval = (sval & ~0x3f) | ofs;
1955
1956
1957
1958
1959 if (ofs != 0) {
1960 wval = (wval & ~0x70) | ((div+1) << 4);
1961 if (!(np->features & FE_C10))
1962 sval = (sval & ~0xe0) | (fak << 5);
1963 else {
1964 uval = uval & ~(XCLKH_ST|XCLKH_DT|XCLKS_ST|XCLKS_DT);
1965 if (fak >= 1) uval |= (XCLKH_ST|XCLKH_DT);
1966 if (fak >= 2) uval |= (XCLKS_ST|XCLKS_DT);
1967 }
1968 }
1969
1970
1971
1972
1973 wval = wval & ~EWS;
1974 if (wide != 0)
1975 wval |= EWS;
1976
1977
1978
1979
1980 if (np->features & FE_C10) {
1981 uval = uval & ~(U3EN|AIPCKEN);
1982 if (opts) {
1983 assert(np->features & FE_U3EN);
1984 uval |= U3EN;
1985 }
1986 } else {
1987 wval = wval & ~ULTRA;
1988 if (per <= 12) wval |= ULTRA;
1989 }
1990
1991
1992
1993
1994 if (tp->head.sval == sval &&
1995 tp->head.wval == wval &&
1996 tp->head.uval == uval)
1997 return;
1998 tp->head.sval = sval;
1999 tp->head.wval = wval;
2000 tp->head.uval = uval;
2001
2002
2003
2004
2005
2006 if (per < 50 && !(np->features & FE_C10))
2007 OUTOFFB(np, nc_stest2, EXT);
2008
2009
2010
2011
2012 OUTB(np, nc_sxfer, tp->head.sval);
2013 OUTB(np, nc_scntl3, tp->head.wval);
2014
2015 if (np->features & FE_C10) {
2016 OUTB(np, nc_scntl4, tp->head.uval);
2017 }
2018
2019
2020
2021
2022 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
2023 struct sym_ccb *cp;
2024 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
2025 if (cp->target != target)
2026 continue;
2027 cp->phys.select.sel_scntl3 = tp->head.wval;
2028 cp->phys.select.sel_sxfer = tp->head.sval;
2029 if (np->features & FE_C10) {
2030 cp->phys.select.sel_scntl4 = tp->head.uval;
2031 }
2032 }
2033}
2034
2035static void sym_announce_transfer_rate(struct sym_tcb *tp)
2036{
2037 struct scsi_target *starget = tp->starget;
2038
2039 if (tp->tprint.period != spi_period(starget) ||
2040 tp->tprint.offset != spi_offset(starget) ||
2041 tp->tprint.width != spi_width(starget) ||
2042 tp->tprint.iu != spi_iu(starget) ||
2043 tp->tprint.dt != spi_dt(starget) ||
2044 tp->tprint.qas != spi_qas(starget) ||
2045 !tp->tprint.check_nego) {
2046 tp->tprint.period = spi_period(starget);
2047 tp->tprint.offset = spi_offset(starget);
2048 tp->tprint.width = spi_width(starget);
2049 tp->tprint.iu = spi_iu(starget);
2050 tp->tprint.dt = spi_dt(starget);
2051 tp->tprint.qas = spi_qas(starget);
2052 tp->tprint.check_nego = 1;
2053
2054 spi_display_xfer_agreement(starget);
2055 }
2056}
2057
2058
2059
2060
2061
2062static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
2063{
2064 struct sym_tcb *tp = &np->target[target];
2065 struct scsi_target *starget = tp->starget;
2066
2067 sym_settrans(np, target, 0, 0, 0, wide, 0, 0);
2068
2069 if (wide)
2070 tp->tgoal.renego = NS_WIDE;
2071 else
2072 tp->tgoal.renego = 0;
2073 tp->tgoal.check_nego = 0;
2074 tp->tgoal.width = wide;
2075 spi_offset(starget) = 0;
2076 spi_period(starget) = 0;
2077 spi_width(starget) = wide;
2078 spi_iu(starget) = 0;
2079 spi_dt(starget) = 0;
2080 spi_qas(starget) = 0;
2081
2082 if (sym_verbose >= 3)
2083 sym_announce_transfer_rate(tp);
2084}
2085
2086
2087
2088
2089
2090static void
2091sym_setsync(struct sym_hcb *np, int target,
2092 u_char ofs, u_char per, u_char div, u_char fak)
2093{
2094 struct sym_tcb *tp = &np->target[target];
2095 struct scsi_target *starget = tp->starget;
2096 u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
2097
2098 sym_settrans(np, target, 0, ofs, per, wide, div, fak);
2099
2100 if (wide)
2101 tp->tgoal.renego = NS_WIDE;
2102 else if (ofs)
2103 tp->tgoal.renego = NS_SYNC;
2104 else
2105 tp->tgoal.renego = 0;
2106 spi_period(starget) = per;
2107 spi_offset(starget) = ofs;
2108 spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0;
2109
2110 if (!tp->tgoal.dt && !tp->tgoal.iu && !tp->tgoal.qas) {
2111 tp->tgoal.period = per;
2112 tp->tgoal.offset = ofs;
2113 tp->tgoal.check_nego = 0;
2114 }
2115
2116 sym_announce_transfer_rate(tp);
2117}
2118
2119
2120
2121
2122
2123static void
2124sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
2125 u_char per, u_char wide, u_char div, u_char fak)
2126{
2127 struct sym_tcb *tp = &np->target[target];
2128 struct scsi_target *starget = tp->starget;
2129
2130 sym_settrans(np, target, opts, ofs, per, wide, div, fak);
2131
2132 if (wide || ofs)
2133 tp->tgoal.renego = NS_PPR;
2134 else
2135 tp->tgoal.renego = 0;
2136 spi_width(starget) = tp->tgoal.width = wide;
2137 spi_period(starget) = tp->tgoal.period = per;
2138 spi_offset(starget) = tp->tgoal.offset = ofs;
2139 spi_iu(starget) = tp->tgoal.iu = !!(opts & PPR_OPT_IU);
2140 spi_dt(starget) = tp->tgoal.dt = !!(opts & PPR_OPT_DT);
2141 spi_qas(starget) = tp->tgoal.qas = !!(opts & PPR_OPT_QAS);
2142 tp->tgoal.check_nego = 0;
2143
2144 sym_announce_transfer_rate(tp);
2145}
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts)
2174{
2175 u32 dsp = INL(np, nc_dsp);
2176 u32 dsa = INL(np, nc_dsa);
2177 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
2178
2179
2180
2181
2182
2183
2184 if ((!(dsp > SCRIPTA_BA(np, getjob_begin) &&
2185 dsp < SCRIPTA_BA(np, getjob_end) + 1)) &&
2186 (!(dsp > SCRIPTA_BA(np, ungetjob) &&
2187 dsp < SCRIPTA_BA(np, reselect) + 1)) &&
2188 (!(dsp > SCRIPTB_BA(np, sel_for_abort) &&
2189 dsp < SCRIPTB_BA(np, sel_for_abort_1) + 1)) &&
2190 (!(dsp > SCRIPTA_BA(np, done) &&
2191 dsp < SCRIPTA_BA(np, done_end) + 1))) {
2192 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF);
2193 OUTB(np, nc_stest3, TE|CSF);
2194
2195
2196
2197
2198
2199
2200 if (cp) {
2201 cp->host_status = hsts;
2202 OUTL_DSP(np, SCRIPTA_BA(np, complete_error));
2203 }
2204
2205
2206
2207 else {
2208 OUTL(np, nc_dsa, 0xffffff);
2209 OUTL_DSP(np, SCRIPTA_BA(np, start));
2210 }
2211 }
2212 else
2213 goto reset_all;
2214
2215 return;
2216
2217reset_all:
2218 sym_start_reset(np);
2219}
2220
2221
2222
2223
2224static void sym_int_sto (struct sym_hcb *np)
2225{
2226 u32 dsp = INL(np, nc_dsp);
2227
2228 if (DEBUG_FLAGS & DEBUG_TINY) printf ("T");
2229
2230 if (dsp == SCRIPTA_BA(np, wf_sel_done) + 8)
2231 sym_recover_scsi_int(np, HS_SEL_TIMEOUT);
2232 else
2233 sym_start_reset(np);
2234}
2235
2236
2237
2238
2239static void sym_int_udc (struct sym_hcb *np)
2240{
2241 printf ("%s: unexpected disconnect\n", sym_name(np));
2242 sym_recover_scsi_int(np, HS_UNEXPECTED);
2243}
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255static void sym_int_sbmc(struct Scsi_Host *shost)
2256{
2257 struct sym_hcb *np = sym_get_hcb(shost);
2258 u_char scsi_mode = INB(np, nc_stest4) & SMODE;
2259
2260
2261
2262
2263 printf("%s: SCSI BUS mode change from %s to %s.\n", sym_name(np),
2264 sym_scsi_bus_mode(np->scsi_mode), sym_scsi_bus_mode(scsi_mode));
2265
2266
2267
2268
2269
2270 sym_start_up(shost, 2);
2271}
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297static void sym_int_par (struct sym_hcb *np, u_short sist)
2298{
2299 u_char hsts = INB(np, HS_PRT);
2300 u32 dsp = INL(np, nc_dsp);
2301 u32 dbc = INL(np, nc_dbc);
2302 u32 dsa = INL(np, nc_dsa);
2303 u_char sbcl = INB(np, nc_sbcl);
2304 u_char cmd = dbc >> 24;
2305 int phase = cmd & 7;
2306 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
2307
2308 if (printk_ratelimit())
2309 printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
2310 sym_name(np), hsts, dbc, sbcl);
2311
2312
2313
2314
2315 if (!(INB(np, nc_scntl1) & ISCON)) {
2316 sym_recover_scsi_int(np, HS_UNEXPECTED);
2317 return;
2318 }
2319
2320
2321
2322
2323
2324 if (!cp)
2325 goto reset_all;
2326
2327
2328
2329
2330
2331 if ((cmd & 0xc0) || !(phase & 1) || !(sbcl & 0x8))
2332 goto reset_all;
2333
2334
2335
2336
2337 OUTONB(np, HF_PRT, HF_EXT_ERR);
2338 cp->xerr_status |= XE_PARITY_ERR;
2339
2340
2341
2342
2343 np->msgout[0] = (phase == 7) ? M_PARITY : M_ID_ERROR;
2344
2345
2346
2347
2348
2349
2350
2351
2352 if (phase == 1 || phase == 5) {
2353
2354 if (dsp == SCRIPTB_BA(np, pm_handle))
2355 OUTL_DSP(np, dsp);
2356
2357 else if (sist & MA)
2358 sym_int_ma (np);
2359
2360 else {
2361 sym_set_script_dp (np, cp, dsp);
2362 OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
2363 }
2364 }
2365 else if (phase == 7)
2366#if 1
2367 goto reset_all;
2368#else
2369 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
2370#endif
2371 else
2372 OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
2373 return;
2374
2375reset_all:
2376 sym_start_reset(np);
2377 return;
2378}
2379
2380
2381
2382
2383
2384
2385
2386static void sym_int_ma (struct sym_hcb *np)
2387{
2388 u32 dbc;
2389 u32 rest;
2390 u32 dsp;
2391 u32 dsa;
2392 u32 nxtdsp;
2393 u32 *vdsp;
2394 u32 oadr, olen;
2395 u32 *tblp;
2396 u32 newcmd;
2397 u_int delta;
2398 u_char cmd;
2399 u_char hflags, hflags0;
2400 struct sym_pmc *pm;
2401 struct sym_ccb *cp;
2402
2403 dsp = INL(np, nc_dsp);
2404 dbc = INL(np, nc_dbc);
2405 dsa = INL(np, nc_dsa);
2406
2407 cmd = dbc >> 24;
2408 rest = dbc & 0xffffff;
2409 delta = 0;
2410
2411
2412
2413
2414 cp = sym_ccb_from_dsa(np, dsa);
2415
2416
2417
2418
2419
2420
2421
2422 if ((cmd & 7) != 1 && (cmd & 7) != 5) {
2423 u_char ss0, ss2;
2424
2425 if (np->features & FE_DFBC)
2426 delta = INW(np, nc_dfbc);
2427 else {
2428 u32 dfifo;
2429
2430
2431
2432
2433 dfifo = INL(np, nc_dfifo);
2434
2435
2436
2437
2438
2439 if (dfifo & (DFS << 16))
2440 delta = ((((dfifo >> 8) & 0x300) |
2441 (dfifo & 0xff)) - rest) & 0x3ff;
2442 else
2443 delta = ((dfifo & 0xff) - rest) & 0x7f;
2444 }
2445
2446
2447
2448
2449
2450
2451
2452 rest += delta;
2453 ss0 = INB(np, nc_sstat0);
2454 if (ss0 & OLF) rest++;
2455 if (!(np->features & FE_C10))
2456 if (ss0 & ORF) rest++;
2457 if (cp && (cp->phys.select.sel_scntl3 & EWS)) {
2458 ss2 = INB(np, nc_sstat2);
2459 if (ss2 & OLF1) rest++;
2460 if (!(np->features & FE_C10))
2461 if (ss2 & ORF1) rest++;
2462 }
2463
2464
2465
2466
2467 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF);
2468 OUTB(np, nc_stest3, TE|CSF);
2469 }
2470
2471
2472
2473
2474 if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
2475 printf ("P%x%x RL=%d D=%d ", cmd&7, INB(np, nc_sbcl)&7,
2476 (unsigned) rest, (unsigned) delta);
2477
2478
2479
2480
2481
2482 vdsp = NULL;
2483 nxtdsp = 0;
2484 if (dsp > np->scripta_ba &&
2485 dsp <= np->scripta_ba + np->scripta_sz) {
2486 vdsp = (u32 *)((char*)np->scripta0 + (dsp-np->scripta_ba-8));
2487 nxtdsp = dsp;
2488 }
2489 else if (dsp > np->scriptb_ba &&
2490 dsp <= np->scriptb_ba + np->scriptb_sz) {
2491 vdsp = (u32 *)((char*)np->scriptb0 + (dsp-np->scriptb_ba-8));
2492 nxtdsp = dsp;
2493 }
2494
2495
2496
2497
2498 if (DEBUG_FLAGS & DEBUG_PHASE) {
2499 printf ("\nCP=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
2500 cp, (unsigned)dsp, (unsigned)nxtdsp, vdsp, cmd);
2501 }
2502
2503 if (!vdsp) {
2504 printf ("%s: interrupted SCRIPT address not found.\n",
2505 sym_name (np));
2506 goto reset_all;
2507 }
2508
2509 if (!cp) {
2510 printf ("%s: SCSI phase error fixup: CCB already dequeued.\n",
2511 sym_name (np));
2512 goto reset_all;
2513 }
2514
2515
2516
2517
2518 oadr = scr_to_cpu(vdsp[1]);
2519
2520 if (cmd & 0x10) {
2521 tblp = (u32 *) ((char*) &cp->phys + oadr);
2522 olen = scr_to_cpu(tblp[0]);
2523 oadr = scr_to_cpu(tblp[1]);
2524 } else {
2525 tblp = (u32 *) 0;
2526 olen = scr_to_cpu(vdsp[0]) & 0xffffff;
2527 }
2528
2529 if (DEBUG_FLAGS & DEBUG_PHASE) {
2530 printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
2531 (unsigned) (scr_to_cpu(vdsp[0]) >> 24),
2532 tblp,
2533 (unsigned) olen,
2534 (unsigned) oadr);
2535 }
2536
2537
2538
2539
2540
2541
2542 if (((cmd & 2) ? cmd : (cmd & ~4)) != (scr_to_cpu(vdsp[0]) >> 24)) {
2543 sym_print_addr(cp->cmd,
2544 "internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
2545 cmd, scr_to_cpu(vdsp[0]) >> 24);
2546
2547 goto reset_all;
2548 }
2549
2550
2551
2552
2553 if (cmd & 2) {
2554 sym_print_addr(cp->cmd,
2555 "phase change %x-%x %d@%08x resid=%d.\n",
2556 cmd&7, INB(np, nc_sbcl)&7, (unsigned)olen,
2557 (unsigned)oadr, (unsigned)rest);
2558 goto unexpected_phase;
2559 }
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569 hflags0 = INB(np, HF_PRT);
2570 hflags = hflags0;
2571
2572 if (hflags & (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED)) {
2573 if (hflags & HF_IN_PM0)
2574 nxtdsp = scr_to_cpu(cp->phys.pm0.ret);
2575 else if (hflags & HF_IN_PM1)
2576 nxtdsp = scr_to_cpu(cp->phys.pm1.ret);
2577
2578 if (hflags & HF_DP_SAVED)
2579 hflags ^= HF_ACT_PM;
2580 }
2581
2582 if (!(hflags & HF_ACT_PM)) {
2583 pm = &cp->phys.pm0;
2584 newcmd = SCRIPTA_BA(np, pm0_data);
2585 }
2586 else {
2587 pm = &cp->phys.pm1;
2588 newcmd = SCRIPTA_BA(np, pm1_data);
2589 }
2590
2591 hflags &= ~(HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED);
2592 if (hflags != hflags0)
2593 OUTB(np, HF_PRT, hflags);
2594
2595
2596
2597
2598 pm->sg.addr = cpu_to_scr(oadr + olen - rest);
2599 pm->sg.size = cpu_to_scr(rest);
2600 pm->ret = cpu_to_scr(nxtdsp);
2601
2602
2603
2604
2605
2606
2607
2608 nxtdsp = SCRIPTA_BA(np, dispatch);
2609 if ((cmd & 7) == 1 && cp && (cp->phys.select.sel_scntl3 & EWS) &&
2610 (INB(np, nc_scntl2) & WSR)) {
2611 u32 tmp;
2612
2613
2614
2615
2616
2617
2618 tmp = scr_to_cpu(pm->sg.addr);
2619 cp->phys.wresid.addr = cpu_to_scr(tmp);
2620 pm->sg.addr = cpu_to_scr(tmp + 1);
2621 tmp = scr_to_cpu(pm->sg.size);
2622 cp->phys.wresid.size = cpu_to_scr((tmp&0xff000000) | 1);
2623 pm->sg.size = cpu_to_scr(tmp - 1);
2624
2625
2626
2627
2628
2629 if ((tmp&0xffffff) == 1)
2630 newcmd = pm->ret;
2631
2632
2633
2634
2635
2636 nxtdsp = SCRIPTB_BA(np, wsr_ma_helper);
2637 }
2638
2639 if (DEBUG_FLAGS & DEBUG_PHASE) {
2640 sym_print_addr(cp->cmd, "PM %x %x %x / %x %x %x.\n",
2641 hflags0, hflags, newcmd,
2642 (unsigned)scr_to_cpu(pm->sg.addr),
2643 (unsigned)scr_to_cpu(pm->sg.size),
2644 (unsigned)scr_to_cpu(pm->ret));
2645 }
2646
2647
2648
2649
2650 sym_set_script_dp (np, cp, newcmd);
2651 OUTL_DSP(np, nxtdsp);
2652 return;
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681unexpected_phase:
2682 dsp -= 8;
2683 nxtdsp = 0;
2684
2685 switch (cmd & 7) {
2686 case 2:
2687 nxtdsp = SCRIPTA_BA(np, dispatch);
2688 break;
2689#if 0
2690 case 3:
2691 nxtdsp = SCRIPTA_BA(np, dispatch);
2692 break;
2693#endif
2694 case 6:
2695
2696
2697
2698
2699
2700
2701 if (dsp == SCRIPTA_BA(np, send_ident)) {
2702 if (cp->tag != NO_TAG && olen - rest <= 3) {
2703 cp->host_status = HS_BUSY;
2704 np->msgout[0] = IDENTIFY(0, cp->lun);
2705 nxtdsp = SCRIPTB_BA(np, ident_break_atn);
2706 }
2707 else
2708 nxtdsp = SCRIPTB_BA(np, ident_break);
2709 }
2710 else if (dsp == SCRIPTB_BA(np, send_wdtr) ||
2711 dsp == SCRIPTB_BA(np, send_sdtr) ||
2712 dsp == SCRIPTB_BA(np, send_ppr)) {
2713 nxtdsp = SCRIPTB_BA(np, nego_bad_phase);
2714 if (dsp == SCRIPTB_BA(np, send_ppr)) {
2715 struct scsi_device *dev = cp->cmd->device;
2716 dev->ppr = 0;
2717 }
2718 }
2719 break;
2720#if 0
2721 case 7:
2722 nxtdsp = SCRIPTA_BA(np, clrack);
2723 break;
2724#endif
2725 }
2726
2727 if (nxtdsp) {
2728 OUTL_DSP(np, nxtdsp);
2729 return;
2730 }
2731
2732reset_all:
2733 sym_start_reset(np);
2734}
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799irqreturn_t sym_interrupt(struct Scsi_Host *shost)
2800{
2801 struct sym_data *sym_data = shost_priv(shost);
2802 struct sym_hcb *np = sym_data->ncb;
2803 struct pci_dev *pdev = sym_data->pdev;
2804 u_char istat, istatc;
2805 u_char dstat;
2806 u_short sist;
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819 istat = INB(np, nc_istat);
2820 if (istat & INTF) {
2821 OUTB(np, nc_istat, (istat & SIGP) | INTF | np->istat_sem);
2822 istat |= INB(np, nc_istat);
2823 if (DEBUG_FLAGS & DEBUG_TINY) printf ("F ");
2824 sym_wakeup_done(np);
2825 }
2826
2827 if (!(istat & (SIP|DIP)))
2828 return (istat & INTF) ? IRQ_HANDLED : IRQ_NONE;
2829
2830#if 0
2831 if (istat & CABRT)
2832 OUTB(np, nc_istat, CABRT);
2833#endif
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845 sist = 0;
2846 dstat = 0;
2847 istatc = istat;
2848 do {
2849 if (istatc & SIP)
2850 sist |= INW(np, nc_sist);
2851 if (istatc & DIP)
2852 dstat |= INB(np, nc_dstat);
2853 istatc = INB(np, nc_istat);
2854 istat |= istatc;
2855
2856
2857
2858 if (unlikely(sist == 0xffff && dstat == 0xff)) {
2859 if (pci_channel_offline(pdev))
2860 return IRQ_NONE;
2861 }
2862 } while (istatc & (SIP|DIP));
2863
2864 if (DEBUG_FLAGS & DEBUG_TINY)
2865 printf ("<%d|%x:%x|%x:%x>",
2866 (int)INB(np, nc_scr0),
2867 dstat,sist,
2868 (unsigned)INL(np, nc_dsp),
2869 (unsigned)INL(np, nc_dbc));
2870
2871
2872
2873
2874
2875
2876 MEMORY_READ_BARRIER();
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891 if (!(sist & (STO|GEN|HTH|SGE|UDC|SBMC|RST)) &&
2892 !(dstat & (MDPE|BF|ABRT|IID))) {
2893 if (sist & PAR) sym_int_par (np, sist);
2894 else if (sist & MA) sym_int_ma (np);
2895 else if (dstat & SIR) sym_int_sir(np);
2896 else if (dstat & SSI) OUTONB_STD();
2897 else goto unknown_int;
2898 return IRQ_HANDLED;
2899 }
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912 if (sist & RST) {
2913 printf("%s: SCSI BUS reset detected.\n", sym_name(np));
2914 sym_start_up(shost, 1);
2915 return IRQ_HANDLED;
2916 }
2917
2918 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF);
2919 OUTB(np, nc_stest3, TE|CSF);
2920
2921 if (!(sist & (GEN|HTH|SGE)) &&
2922 !(dstat & (MDPE|BF|ABRT|IID))) {
2923 if (sist & SBMC) sym_int_sbmc(shost);
2924 else if (sist & STO) sym_int_sto (np);
2925 else if (sist & UDC) sym_int_udc (np);
2926 else goto unknown_int;
2927 return IRQ_HANDLED;
2928 }
2929
2930
2931
2932
2933
2934
2935
2936
2937 sym_log_hard_error(shost, sist, dstat);
2938
2939 if ((sist & (GEN|HTH|SGE)) ||
2940 (dstat & (MDPE|BF|ABRT|IID))) {
2941 sym_start_reset(np);
2942 return IRQ_HANDLED;
2943 }
2944
2945unknown_int:
2946
2947
2948
2949
2950 printf( "%s: unknown interrupt(s) ignored, "
2951 "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n",
2952 sym_name(np), istat, dstat, sist);
2953 return IRQ_NONE;
2954}
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964static int
2965sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task)
2966{
2967 int j;
2968 struct sym_ccb *cp;
2969
2970
2971
2972
2973 assert((i >= 0) && (i < 2*MAX_QUEUE));
2974
2975
2976
2977
2978
2979 j = i;
2980 while (i != np->squeueput) {
2981 cp = sym_ccb_from_dsa(np, scr_to_cpu(np->squeue[i]));
2982 assert(cp);
2983#ifdef SYM_CONF_IARB_SUPPORT
2984
2985 cp->host_flags &= ~HF_HINT_IARB;
2986#endif
2987 if ((target == -1 || cp->target == target) &&
2988 (lun == -1 || cp->lun == lun) &&
2989 (task == -1 || cp->tag == task)) {
2990#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
2991 sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
2992#else
2993 sym_set_cam_status(cp->cmd, DID_REQUEUE);
2994#endif
2995 sym_remque(&cp->link_ccbq);
2996 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
2997 }
2998 else {
2999 if (i != j)
3000 np->squeue[j] = np->squeue[i];
3001 if ((j += 2) >= MAX_QUEUE*2) j = 0;
3002 }
3003 if ((i += 2) >= MAX_QUEUE*2) i = 0;
3004 }
3005 if (i != j)
3006 np->squeue[j] = np->squeue[i];
3007 np->squeueput = j;
3008
3009 return (i - j) / 2;
3010}
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb *cp)
3031{
3032 u32 startp;
3033 u_char s_status = cp->ssss_status;
3034 u_char h_flags = cp->host_flags;
3035 int msglen;
3036 int i;
3037
3038
3039
3040
3041 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3042
3043
3044
3045
3046
3047#ifdef SYM_CONF_IARB_SUPPORT
3048 if (np->last_cp)
3049 np->last_cp = 0;
3050#endif
3051
3052
3053
3054
3055 switch(s_status) {
3056 case S_BUSY:
3057 case S_QUEUE_FULL:
3058 if (sym_verbose >= 2) {
3059 sym_print_addr(cp->cmd, "%s\n",
3060 s_status == S_BUSY ? "BUSY" : "QUEUE FULL\n");
3061 }
3062 fallthrough;
3063 default:
3064 sym_complete_error (np, cp);
3065 break;
3066 case S_TERMINATED:
3067 case S_CHECK_COND:
3068
3069
3070
3071 if (h_flags & HF_SENSE) {
3072 sym_complete_error (np, cp);
3073 break;
3074 }
3075
3076
3077
3078
3079
3080 sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3081 OUTL_DSP(np, SCRIPTA_BA(np, start));
3082
3083
3084
3085
3086
3087 cp->sv_scsi_status = cp->ssss_status;
3088 cp->sv_xerr_status = cp->xerr_status;
3089 cp->sv_resid = sym_compute_residual(np, cp);
3090
3091
3092
3093
3094
3095
3096 cp->scsi_smsg2[0] = IDENTIFY(0, cp->lun);
3097 msglen = 1;
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109 cp->nego_status = 0;
3110 msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]);
3111
3112
3113
3114 cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2);
3115 cp->phys.smsg.size = cpu_to_scr(msglen);
3116
3117
3118
3119
3120 cp->phys.cmd.addr = CCB_BA(cp, sensecmd);
3121 cp->phys.cmd.size = cpu_to_scr(6);
3122
3123
3124
3125
3126 cp->sensecmd[0] = REQUEST_SENSE;
3127 cp->sensecmd[1] = 0;
3128 if (cp->cmd->device->scsi_level <= SCSI_2 && cp->lun <= 7)
3129 cp->sensecmd[1] = cp->lun << 5;
3130 cp->sensecmd[4] = SYM_SNS_BBUF_LEN;
3131 cp->data_len = SYM_SNS_BBUF_LEN;
3132
3133
3134
3135
3136 memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
3137 cp->phys.sense.addr = CCB_BA(cp, sns_bbuf);
3138 cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
3139
3140
3141
3142
3143 startp = SCRIPTB_BA(np, sdata_in);
3144
3145 cp->phys.head.savep = cpu_to_scr(startp);
3146 cp->phys.head.lastp = cpu_to_scr(startp);
3147 cp->startp = cpu_to_scr(startp);
3148 cp->goalp = cpu_to_scr(startp + 16);
3149
3150 cp->host_xflags = 0;
3151 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
3152 cp->ssss_status = S_ILLEGAL;
3153 cp->host_flags = (HF_SENSE|HF_DATA_IN);
3154 cp->xerr_status = 0;
3155 cp->extra_bytes = 0;
3156
3157 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
3158
3159
3160
3161
3162 sym_put_start_queue(np, cp);
3163
3164
3165
3166
3167 sym_flush_comp_queue(np, 0);
3168 break;
3169 }
3170}
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task)
3187{
3188 SYM_QUEHEAD qtmp, *qp;
3189 int i = 0;
3190 struct sym_ccb *cp;
3191
3192
3193
3194
3195 sym_que_init(&qtmp);
3196 sym_que_splice(&np->busy_ccbq, &qtmp);
3197 sym_que_init(&np->busy_ccbq);
3198
3199
3200
3201
3202
3203
3204 while ((qp = sym_remque_head(&qtmp)) != NULL) {
3205 struct scsi_cmnd *cmd;
3206 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3207 cmd = cp->cmd;
3208 if (cp->host_status != HS_DISCONNECT ||
3209 cp->target != target ||
3210 (lun != -1 && cp->lun != lun) ||
3211 (task != -1 &&
3212 (cp->tag != NO_TAG && cp->scsi_smsg[2] != task))) {
3213 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
3214 continue;
3215 }
3216 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3217
3218
3219 if (sym_get_cam_status(cmd) != DID_TIME_OUT)
3220 sym_set_cam_status(cmd, cam_status);
3221 ++i;
3222#if 0
3223printf("XXXX TASK @%p CLEARED\n", cp);
3224#endif
3225 }
3226 return i;
3227}
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269static void sym_sir_task_recovery(struct sym_hcb *np, int num)
3270{
3271 SYM_QUEHEAD *qp;
3272 struct sym_ccb *cp;
3273 struct sym_tcb *tp = NULL;
3274 struct scsi_target *starget;
3275 int target=-1, lun=-1, task;
3276 int i, k;
3277
3278 switch(num) {
3279
3280
3281
3282
3283
3284 case SIR_SCRIPT_STOPPED:
3285
3286
3287
3288 for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
3289 tp = &np->target[i];
3290 if (tp->to_reset ||
3291 (tp->lun0p && tp->lun0p->to_clear)) {
3292 target = i;
3293 break;
3294 }
3295 if (!tp->lunmp)
3296 continue;
3297 for (k = 1 ; k < SYM_CONF_MAX_LUN ; k++) {
3298 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) {
3299 target = i;
3300 break;
3301 }
3302 }
3303 if (target != -1)
3304 break;
3305 }
3306
3307
3308
3309
3310
3311 if (target == -1) {
3312 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3313 cp = sym_que_entry(qp,struct sym_ccb,link_ccbq);
3314 if (cp->host_status != HS_DISCONNECT)
3315 continue;
3316 if (cp->to_abort) {
3317 target = cp->target;
3318 break;
3319 }
3320 }
3321 }
3322
3323
3324
3325
3326
3327 if (target != -1) {
3328 tp = &np->target[target];
3329 np->abrt_sel.sel_id = target;
3330 np->abrt_sel.sel_scntl3 = tp->head.wval;
3331 np->abrt_sel.sel_sxfer = tp->head.sval;
3332 OUTL(np, nc_dsa, np->hcb_ba);
3333 OUTL_DSP(np, SCRIPTB_BA(np, sel_for_abort));
3334 return;
3335 }
3336
3337
3338
3339
3340
3341
3342 i = 0;
3343 cp = NULL;
3344 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3345 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3346 if (cp->host_status != HS_BUSY &&
3347 cp->host_status != HS_NEGOTIATE)
3348 continue;
3349 if (!cp->to_abort)
3350 continue;
3351#ifdef SYM_CONF_IARB_SUPPORT
3352
3353
3354
3355
3356
3357 if (cp == np->last_cp) {
3358 cp->to_abort = 0;
3359 continue;
3360 }
3361#endif
3362 i = 1;
3363 break;
3364 }
3365 if (!i) {
3366
3367
3368
3369
3370
3371 np->istat_sem = 0;
3372 OUTB(np, nc_istat, SIGP);
3373 break;
3374 }
3375
3376
3377
3378
3379
3380 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3381 i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3382
3383
3384
3385
3386#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
3387 assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
3388#else
3389 sym_remque(&cp->link_ccbq);
3390 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3391#endif
3392
3393
3394
3395 if (cp->to_abort == 2)
3396 sym_set_cam_status(cp->cmd, DID_TIME_OUT);
3397 else
3398 sym_set_cam_status(cp->cmd, DID_ABORT);
3399
3400
3401
3402
3403 sym_flush_comp_queue(np, 0);
3404 break;
3405
3406
3407
3408
3409 case SIR_TARGET_SELECTED:
3410 target = INB(np, nc_sdid) & 0xf;
3411 tp = &np->target[target];
3412
3413 np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg));
3414
3415
3416
3417
3418
3419
3420 if (tp->to_reset) {
3421 np->abrt_msg[0] = M_RESET;
3422 np->abrt_tbl.size = 1;
3423 tp->to_reset = 0;
3424 break;
3425 }
3426
3427
3428
3429
3430 if (tp->lun0p && tp->lun0p->to_clear)
3431 lun = 0;
3432 else if (tp->lunmp) {
3433 for (k = 1 ; k < SYM_CONF_MAX_LUN ; k++) {
3434 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) {
3435 lun = k;
3436 break;
3437 }
3438 }
3439 }
3440
3441
3442
3443
3444
3445 if (lun != -1) {
3446 struct sym_lcb *lp = sym_lp(tp, lun);
3447 lp->to_clear = 0;
3448 np->abrt_msg[0] = IDENTIFY(0, lun);
3449 np->abrt_msg[1] = M_ABORT;
3450 np->abrt_tbl.size = 2;
3451 break;
3452 }
3453
3454
3455
3456
3457
3458 i = 0;
3459 cp = NULL;
3460 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3461 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3462 if (cp->host_status != HS_DISCONNECT)
3463 continue;
3464 if (cp->target != target)
3465 continue;
3466 if (!cp->to_abort)
3467 continue;
3468 i = 1;
3469 break;
3470 }
3471
3472
3473
3474
3475
3476
3477
3478
3479 if (!i) {
3480 np->abrt_msg[0] = M_ABORT;
3481 np->abrt_tbl.size = 1;
3482 break;
3483 }
3484
3485
3486
3487
3488
3489 np->abrt_msg[0] = IDENTIFY(0, cp->lun);
3490
3491
3492
3493
3494
3495
3496
3497 if (cp->tag == NO_TAG) {
3498 np->abrt_msg[1] = M_ABORT;
3499 np->abrt_tbl.size = 2;
3500 } else {
3501 np->abrt_msg[1] = cp->scsi_smsg[1];
3502 np->abrt_msg[2] = cp->scsi_smsg[2];
3503 np->abrt_msg[3] = M_ABORT_TAG;
3504 np->abrt_tbl.size = 4;
3505 }
3506
3507
3508
3509
3510
3511 if (cp->to_abort == 2)
3512 sym_set_cam_status(cp->cmd, DID_TIME_OUT);
3513 cp->to_abort = 0;
3514 break;
3515
3516
3517
3518
3519
3520 case SIR_ABORT_SENT:
3521 target = INB(np, nc_sdid) & 0xf;
3522 tp = &np->target[target];
3523 starget = tp->starget;
3524
3525
3526
3527
3528 if (np->abrt_msg[0] == M_ABORT)
3529 break;
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539 lun = -1;
3540 task = -1;
3541 if (np->abrt_msg[0] == M_RESET) {
3542 tp->head.sval = 0;
3543 tp->head.wval = np->rv_scntl3;
3544 tp->head.uval = 0;
3545 spi_period(starget) = 0;
3546 spi_offset(starget) = 0;
3547 spi_width(starget) = 0;
3548 spi_iu(starget) = 0;
3549 spi_dt(starget) = 0;
3550 spi_qas(starget) = 0;
3551 tp->tgoal.check_nego = 1;
3552 tp->tgoal.renego = 0;
3553 }
3554
3555
3556
3557
3558
3559
3560
3561 else {
3562 lun = np->abrt_msg[0] & 0x3f;
3563 if (np->abrt_msg[1] == M_ABORT_TAG)
3564 task = np->abrt_msg[2];
3565 }
3566
3567
3568
3569
3570
3571 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3572 sym_dequeue_from_squeue(np, i, target, lun, -1);
3573 sym_clear_tasks(np, DID_ABORT, target, lun, task);
3574 sym_flush_comp_queue(np, 0);
3575
3576
3577
3578
3579 if (np->abrt_msg[0] == M_RESET)
3580 starget_printk(KERN_NOTICE, starget,
3581 "has been reset\n");
3582 break;
3583 }
3584
3585
3586
3587
3588 if (num == SIR_TARGET_SELECTED) {
3589 dev_info(&tp->starget->dev, "control msgout:");
3590 sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
3591 np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
3592 }
3593
3594
3595
3596
3597 OUTONB_STD();
3598}
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int *ofs)
3628{
3629 u32 dp_scr;
3630 int dp_ofs, dp_sg, dp_sgmin;
3631 int tmp;
3632 struct sym_pmc *pm;
3633
3634
3635
3636
3637
3638 dp_scr = scr;
3639 dp_ofs = *ofs;
3640 if (dp_scr == SCRIPTA_BA(np, pm0_data))
3641 pm = &cp->phys.pm0;
3642 else if (dp_scr == SCRIPTA_BA(np, pm1_data))
3643 pm = &cp->phys.pm1;
3644 else
3645 pm = NULL;
3646
3647 if (pm) {
3648 dp_scr = scr_to_cpu(pm->ret);
3649 dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff;
3650 }
3651
3652
3653
3654
3655 if (cp->host_flags & HF_SENSE) {
3656 *ofs = dp_ofs;
3657 return 0;
3658 }
3659
3660
3661
3662
3663
3664
3665
3666 tmp = scr_to_cpu(cp->goalp);
3667 dp_sg = SYM_CONF_MAX_SG;
3668 if (dp_scr != tmp)
3669 dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
3670 dp_sgmin = SYM_CONF_MAX_SG - cp->segments;
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684 if (dp_ofs < 0) {
3685 int n;
3686 while (dp_sg > dp_sgmin) {
3687 --dp_sg;
3688 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3689 n = dp_ofs + (tmp & 0xffffff);
3690 if (n > 0) {
3691 ++dp_sg;
3692 break;
3693 }
3694 dp_ofs = n;
3695 }
3696 }
3697 else if (dp_ofs > 0) {
3698 while (dp_sg < SYM_CONF_MAX_SG) {
3699 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3700 dp_ofs -= (tmp & 0xffffff);
3701 ++dp_sg;
3702 if (dp_ofs <= 0)
3703 break;
3704 }
3705 }
3706
3707
3708
3709
3710
3711 if (dp_sg < dp_sgmin || (dp_sg == dp_sgmin && dp_ofs < 0))
3712 goto out_err;
3713 else if (dp_sg > SYM_CONF_MAX_SG ||
3714 (dp_sg == SYM_CONF_MAX_SG && dp_ofs > 0))
3715 goto out_err;
3716
3717
3718
3719
3720 if (dp_sg > cp->ext_sg ||
3721 (dp_sg == cp->ext_sg && dp_ofs > cp->ext_ofs)) {
3722 cp->ext_sg = dp_sg;
3723 cp->ext_ofs = dp_ofs;
3724 }
3725
3726
3727
3728
3729 *ofs = dp_ofs;
3730 return dp_sg;
3731
3732out_err:
3733 return -1;
3734}
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp, int ofs)
3746{
3747 int dp_ofs = ofs;
3748 u32 dp_scr = sym_get_script_dp (np, cp);
3749 u32 dp_ret;
3750 u32 tmp;
3751 u_char hflags;
3752 int dp_sg;
3753 struct sym_pmc *pm;
3754
3755
3756
3757
3758 if (cp->host_flags & HF_SENSE)
3759 goto out_reject;
3760
3761
3762
3763
3764
3765 dp_sg = sym_evaluate_dp(np, cp, dp_scr, &dp_ofs);
3766 if (dp_sg < 0)
3767 goto out_reject;
3768
3769
3770
3771
3772
3773 dp_ret = cpu_to_scr(cp->goalp);
3774 dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
3775
3776
3777
3778
3779
3780 if (dp_ofs == 0) {
3781 dp_scr = dp_ret;
3782 goto out_ok;
3783 }
3784
3785
3786
3787
3788 hflags = INB(np, HF_PRT);
3789
3790 if (hflags & HF_DP_SAVED)
3791 hflags ^= HF_ACT_PM;
3792
3793 if (!(hflags & HF_ACT_PM)) {
3794 pm = &cp->phys.pm0;
3795 dp_scr = SCRIPTA_BA(np, pm0_data);
3796 }
3797 else {
3798 pm = &cp->phys.pm1;
3799 dp_scr = SCRIPTA_BA(np, pm1_data);
3800 }
3801
3802 hflags &= ~(HF_DP_SAVED);
3803
3804 OUTB(np, HF_PRT, hflags);
3805
3806
3807
3808
3809
3810
3811
3812
3813 pm->ret = cpu_to_scr(dp_ret);
3814 tmp = scr_to_cpu(cp->phys.data[dp_sg-1].addr);
3815 tmp += scr_to_cpu(cp->phys.data[dp_sg-1].size) + dp_ofs;
3816 pm->sg.addr = cpu_to_scr(tmp);
3817 pm->sg.size = cpu_to_scr(-dp_ofs);
3818
3819out_ok:
3820 sym_set_script_dp (np, cp, dp_scr);
3821 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
3822 return;
3823
3824out_reject:
3825 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
3826}
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
3845{
3846 int dp_sg, resid = 0;
3847 int dp_ofs = 0;
3848
3849
3850
3851
3852
3853
3854
3855
3856 if (cp->xerr_status & (XE_EXTRA_DATA|XE_SODL_UNRUN|XE_SWIDE_OVRUN)) {
3857 if (cp->xerr_status & XE_EXTRA_DATA)
3858 resid -= cp->extra_bytes;
3859 if (cp->xerr_status & XE_SODL_UNRUN)
3860 ++resid;
3861 if (cp->xerr_status & XE_SWIDE_OVRUN)
3862 --resid;
3863 }
3864
3865
3866
3867
3868
3869 if (cp->phys.head.lastp == cp->goalp)
3870 return resid;
3871
3872
3873
3874
3875
3876 if (cp->startp == cp->phys.head.lastp ||
3877 sym_evaluate_dp(np, cp, scr_to_cpu(cp->phys.head.lastp),
3878 &dp_ofs) < 0) {
3879 return cp->data_len - cp->odd_byte_adjustment;
3880 }
3881
3882
3883
3884
3885 if (cp->host_flags & HF_SENSE) {
3886 return -dp_ofs;
3887 }
3888
3889
3890
3891
3892
3893 resid = -cp->ext_ofs;
3894 for (dp_sg = cp->ext_sg; dp_sg < SYM_CONF_MAX_SG; ++dp_sg) {
3895 u_int tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3896 resid += (tmp & 0xffffff);
3897 }
3898
3899 resid -= cp->odd_byte_adjustment;
3900
3901
3902
3903
3904 return resid;
3905}
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944static int
3945sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
3946{
3947 int target = cp->target;
3948 u_char chg, ofs, per, fak, div;
3949
3950 if (DEBUG_FLAGS & DEBUG_NEGO) {
3951 sym_print_nego_msg(np, target, "sync msgin", np->msgin);
3952 }
3953
3954
3955
3956
3957 chg = 0;
3958 per = np->msgin[3];
3959 ofs = np->msgin[4];
3960
3961
3962
3963
3964 if (ofs) {
3965 if (ofs > np->maxoffs)
3966 {chg = 1; ofs = np->maxoffs;}
3967 }
3968
3969 if (ofs) {
3970 if (per < np->minsync)
3971 {chg = 1; per = np->minsync;}
3972 }
3973
3974
3975
3976
3977 div = fak = 0;
3978 if (ofs && sym_getsync(np, 0, per, &div, &fak) < 0)
3979 goto reject_it;
3980
3981 if (DEBUG_FLAGS & DEBUG_NEGO) {
3982 sym_print_addr(cp->cmd,
3983 "sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n",
3984 ofs, per, div, fak, chg);
3985 }
3986
3987
3988
3989
3990
3991 if (!req && chg)
3992 goto reject_it;
3993
3994
3995
3996
3997 sym_setsync (np, target, ofs, per, div, fak);
3998
3999
4000
4001
4002 if (!req)
4003 return 0;
4004
4005
4006
4007
4008 spi_populate_sync_msg(np->msgout, per, ofs);
4009
4010 if (DEBUG_FLAGS & DEBUG_NEGO) {
4011 sym_print_nego_msg(np, target, "sync msgout", np->msgout);
4012 }
4013
4014 np->msgin [0] = M_NOOP;
4015
4016 return 0;
4017
4018reject_it:
4019 sym_setsync (np, target, 0, 0, 0, 0);
4020 return -1;
4021}
4022
4023static void sym_sync_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4024{
4025 int req = 1;
4026 int result;
4027
4028
4029
4030
4031 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4032 OUTB(np, HS_PRT, HS_BUSY);
4033 if (cp->nego_status && cp->nego_status != NS_SYNC)
4034 goto reject_it;
4035 req = 0;
4036 }
4037
4038
4039
4040
4041 result = sym_sync_nego_check(np, req, cp);
4042 if (result)
4043 goto reject_it;
4044 if (req) {
4045 cp->nego_status = NS_SYNC;
4046 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4047 }
4048 else
4049 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4050 return;
4051
4052reject_it:
4053 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4054}
4055
4056
4057
4058
4059static int
4060sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
4061{
4062 struct sym_tcb *tp = &np->target[target];
4063 unsigned char fak, div;
4064 int dt, chg = 0;
4065
4066 unsigned char per = np->msgin[3];
4067 unsigned char ofs = np->msgin[5];
4068 unsigned char wide = np->msgin[6];
4069 unsigned char opts = np->msgin[7] & PPR_OPT_MASK;
4070
4071 if (DEBUG_FLAGS & DEBUG_NEGO) {
4072 sym_print_nego_msg(np, target, "ppr msgin", np->msgin);
4073 }
4074
4075
4076
4077
4078 if (wide > np->maxwide) {
4079 chg = 1;
4080 wide = np->maxwide;
4081 }
4082 if (!wide || !(np->features & FE_U3EN))
4083 opts = 0;
4084
4085 if (opts != (np->msgin[7] & PPR_OPT_MASK))
4086 chg = 1;
4087
4088 dt = opts & PPR_OPT_DT;
4089
4090 if (ofs) {
4091 unsigned char maxoffs = dt ? np->maxoffs_dt : np->maxoffs;
4092 if (ofs > maxoffs) {
4093 chg = 1;
4094 ofs = maxoffs;
4095 }
4096 }
4097
4098 if (ofs) {
4099 unsigned char minsync = dt ? np->minsync_dt : np->minsync;
4100 if (per < minsync) {
4101 chg = 1;
4102 per = minsync;
4103 }
4104 }
4105
4106
4107
4108
4109 div = fak = 0;
4110 if (ofs && sym_getsync(np, dt, per, &div, &fak) < 0)
4111 goto reject_it;
4112
4113
4114
4115
4116
4117 if (!req && chg)
4118 goto reject_it;
4119
4120
4121
4122
4123 sym_setpprot(np, target, opts, ofs, per, wide, div, fak);
4124
4125
4126
4127
4128 if (!req)
4129 return 0;
4130
4131
4132
4133
4134 spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts);
4135
4136 if (DEBUG_FLAGS & DEBUG_NEGO) {
4137 sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
4138 }
4139
4140 np->msgin [0] = M_NOOP;
4141
4142 return 0;
4143
4144reject_it:
4145 sym_setpprot (np, target, 0, 0, 0, 0, 0, 0);
4146
4147
4148
4149
4150 if (!req && !opts) {
4151 tp->tgoal.period = per;
4152 tp->tgoal.offset = ofs;
4153 tp->tgoal.width = wide;
4154 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
4155 tp->tgoal.check_nego = 1;
4156 }
4157 return -1;
4158}
4159
4160static void sym_ppr_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4161{
4162 int req = 1;
4163 int result;
4164
4165
4166
4167
4168 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4169 OUTB(np, HS_PRT, HS_BUSY);
4170 if (cp->nego_status && cp->nego_status != NS_PPR)
4171 goto reject_it;
4172 req = 0;
4173 }
4174
4175
4176
4177
4178 result = sym_ppr_nego_check(np, req, cp->target);
4179 if (result)
4180 goto reject_it;
4181 if (req) {
4182 cp->nego_status = NS_PPR;
4183 OUTL_DSP(np, SCRIPTB_BA(np, ppr_resp));
4184 }
4185 else
4186 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4187 return;
4188
4189reject_it:
4190 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4191}
4192
4193
4194
4195
4196static int
4197sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
4198{
4199 int target = cp->target;
4200 u_char chg, wide;
4201
4202 if (DEBUG_FLAGS & DEBUG_NEGO) {
4203 sym_print_nego_msg(np, target, "wide msgin", np->msgin);
4204 }
4205
4206
4207
4208
4209 chg = 0;
4210 wide = np->msgin[3];
4211
4212
4213
4214
4215 if (wide > np->maxwide) {
4216 chg = 1;
4217 wide = np->maxwide;
4218 }
4219
4220 if (DEBUG_FLAGS & DEBUG_NEGO) {
4221 sym_print_addr(cp->cmd, "wdtr: wide=%d chg=%d.\n",
4222 wide, chg);
4223 }
4224
4225
4226
4227
4228
4229 if (!req && chg)
4230 goto reject_it;
4231
4232
4233
4234
4235 sym_setwide (np, target, wide);
4236
4237
4238
4239
4240 if (!req)
4241 return 0;
4242
4243
4244
4245
4246 spi_populate_width_msg(np->msgout, wide);
4247
4248 np->msgin [0] = M_NOOP;
4249
4250 if (DEBUG_FLAGS & DEBUG_NEGO) {
4251 sym_print_nego_msg(np, target, "wide msgout", np->msgout);
4252 }
4253
4254 return 0;
4255
4256reject_it:
4257 return -1;
4258}
4259
4260static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4261{
4262 int req = 1;
4263 int result;
4264
4265
4266
4267
4268 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4269 OUTB(np, HS_PRT, HS_BUSY);
4270 if (cp->nego_status && cp->nego_status != NS_WIDE)
4271 goto reject_it;
4272 req = 0;
4273 }
4274
4275
4276
4277
4278 result = sym_wide_nego_check(np, req, cp);
4279 if (result)
4280 goto reject_it;
4281 if (req) {
4282 cp->nego_status = NS_WIDE;
4283 OUTL_DSP(np, SCRIPTB_BA(np, wdtr_resp));
4284 } else {
4285
4286
4287
4288
4289
4290 if (tp->tgoal.offset) {
4291 spi_populate_sync_msg(np->msgout, tp->tgoal.period,
4292 tp->tgoal.offset);
4293
4294 if (DEBUG_FLAGS & DEBUG_NEGO) {
4295 sym_print_nego_msg(np, cp->target,
4296 "sync msgout", np->msgout);
4297 }
4298
4299 cp->nego_status = NS_SYNC;
4300 OUTB(np, HS_PRT, HS_NEGOTIATE);
4301 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4302 return;
4303 } else
4304 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4305 }
4306
4307 return;
4308
4309reject_it:
4310 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4311}
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324static void sym_nego_default(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4325{
4326 switch (cp->nego_status) {
4327 case NS_PPR:
4328#if 0
4329 sym_setpprot (np, cp->target, 0, 0, 0, 0, 0, 0);
4330#else
4331 if (tp->tgoal.period < np->minsync)
4332 tp->tgoal.period = np->minsync;
4333 if (tp->tgoal.offset > np->maxoffs)
4334 tp->tgoal.offset = np->maxoffs;
4335 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
4336 tp->tgoal.check_nego = 1;
4337#endif
4338 break;
4339 case NS_SYNC:
4340 sym_setsync (np, cp->target, 0, 0, 0, 0);
4341 break;
4342 case NS_WIDE:
4343 sym_setwide (np, cp->target, 0);
4344 break;
4345 }
4346 np->msgin [0] = M_NOOP;
4347 np->msgout[0] = M_NOOP;
4348 cp->nego_status = 0;
4349}
4350
4351
4352
4353
4354
4355static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4356{
4357 sym_nego_default(np, tp, cp);
4358 OUTB(np, HS_PRT, HS_BUSY);
4359}
4360
4361#define sym_printk(lvl, tp, cp, fmt, v...) do { \
4362 if (cp) \
4363 scmd_printk(lvl, cp->cmd, fmt, ##v); \
4364 else \
4365 starget_printk(lvl, tp->starget, fmt, ##v); \
4366} while (0)
4367
4368
4369
4370
4371static void sym_int_sir(struct sym_hcb *np)
4372{
4373 u_char num = INB(np, nc_dsps);
4374 u32 dsa = INL(np, nc_dsa);
4375 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
4376 u_char target = INB(np, nc_sdid) & 0x0f;
4377 struct sym_tcb *tp = &np->target[target];
4378 int tmp;
4379
4380 if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
4381
4382 switch (num) {
4383#if SYM_CONF_DMA_ADDRESSING_MODE == 2
4384
4385
4386
4387
4388 case SIR_DMAP_DIRTY:
4389 sym_update_dmap_regs(np);
4390 goto out;
4391#endif
4392
4393
4394
4395
4396 case SIR_COMPLETE_ERROR:
4397 sym_complete_error(np, cp);
4398 return;
4399
4400
4401
4402
4403 case SIR_SCRIPT_STOPPED:
4404 case SIR_TARGET_SELECTED:
4405 case SIR_ABORT_SENT:
4406 sym_sir_task_recovery(np, num);
4407 return;
4408
4409
4410
4411
4412 case SIR_SEL_ATN_NO_MSG_OUT:
4413 sym_printk(KERN_WARNING, tp, cp,
4414 "No MSG OUT phase after selection with ATN\n");
4415 goto out_stuck;
4416
4417
4418
4419
4420 case SIR_RESEL_NO_MSG_IN:
4421 sym_printk(KERN_WARNING, tp, cp,
4422 "No MSG IN phase after reselection\n");
4423 goto out_stuck;
4424
4425
4426
4427
4428 case SIR_RESEL_NO_IDENTIFY:
4429 sym_printk(KERN_WARNING, tp, cp,
4430 "No IDENTIFY after reselection\n");
4431 goto out_stuck;
4432
4433
4434
4435 case SIR_RESEL_BAD_LUN:
4436 np->msgout[0] = M_RESET;
4437 goto out;
4438
4439
4440
4441
4442 case SIR_RESEL_BAD_I_T_L:
4443 np->msgout[0] = M_ABORT;
4444 goto out;
4445
4446
4447
4448 case SIR_RESEL_BAD_I_T_L_Q:
4449 np->msgout[0] = M_ABORT_TAG;
4450 goto out;
4451
4452
4453
4454
4455 case SIR_RESEL_ABORTED:
4456 np->lastmsg = np->msgout[0];
4457 np->msgout[0] = M_NOOP;
4458 sym_printk(KERN_WARNING, tp, cp,
4459 "message %x sent on bad reselection\n", np->lastmsg);
4460 goto out;
4461
4462
4463
4464
4465 case SIR_MSG_OUT_DONE:
4466 np->lastmsg = np->msgout[0];
4467 np->msgout[0] = M_NOOP;
4468
4469 if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) {
4470 if (cp) {
4471 cp->xerr_status &= ~XE_PARITY_ERR;
4472 if (!cp->xerr_status)
4473 OUTOFFB(np, HF_PRT, HF_EXT_ERR);
4474 }
4475 }
4476 goto out;
4477
4478
4479
4480
4481
4482 case SIR_BAD_SCSI_STATUS:
4483 if (!cp)
4484 goto out;
4485 sym_sir_bad_scsi_status(np, num, cp);
4486 return;
4487
4488
4489
4490
4491 case SIR_REJECT_TO_SEND:
4492 sym_print_msg(cp, "M_REJECT to send for ", np->msgin);
4493 np->msgout[0] = M_REJECT;
4494 goto out;
4495
4496
4497
4498
4499
4500
4501 case SIR_SWIDE_OVERRUN:
4502 if (cp) {
4503 OUTONB(np, HF_PRT, HF_EXT_ERR);
4504 cp->xerr_status |= XE_SWIDE_OVRUN;
4505 }
4506 goto out;
4507
4508
4509
4510
4511
4512 case SIR_SODL_UNDERRUN:
4513 if (cp) {
4514 OUTONB(np, HF_PRT, HF_EXT_ERR);
4515 cp->xerr_status |= XE_SODL_UNRUN;
4516 }
4517 goto out;
4518
4519
4520
4521
4522
4523
4524 case SIR_DATA_OVERRUN:
4525 if (cp) {
4526 OUTONB(np, HF_PRT, HF_EXT_ERR);
4527 cp->xerr_status |= XE_EXTRA_DATA;
4528 cp->extra_bytes += INL(np, nc_scratcha);
4529 }
4530 goto out;
4531
4532
4533
4534 case SIR_BAD_PHASE:
4535 if (cp) {
4536 OUTONB(np, HF_PRT, HF_EXT_ERR);
4537 cp->xerr_status |= XE_BAD_PHASE;
4538 }
4539 goto out;
4540
4541
4542
4543 case SIR_MSG_RECEIVED:
4544 if (!cp)
4545 goto out_stuck;
4546 switch (np->msgin [0]) {
4547
4548
4549
4550
4551
4552 case M_EXTENDED:
4553 switch (np->msgin [2]) {
4554 case M_X_MODIFY_DP:
4555 if (DEBUG_FLAGS & DEBUG_POINTER)
4556 sym_print_msg(cp, "extended msg ",
4557 np->msgin);
4558 tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
4559 (np->msgin[5]<<8) + (np->msgin[6]);
4560 sym_modify_dp(np, tp, cp, tmp);
4561 return;
4562 case M_X_SYNC_REQ:
4563 sym_sync_nego(np, tp, cp);
4564 return;
4565 case M_X_PPR_REQ:
4566 sym_ppr_nego(np, tp, cp);
4567 return;
4568 case M_X_WIDE_REQ:
4569 sym_wide_nego(np, tp, cp);
4570 return;
4571 default:
4572 goto out_reject;
4573 }
4574 break;
4575
4576
4577
4578
4579
4580
4581
4582 case M_IGN_RESIDUE:
4583 if (DEBUG_FLAGS & DEBUG_POINTER)
4584 sym_print_msg(cp, "1 or 2 byte ", np->msgin);
4585 if (cp->host_flags & HF_SENSE)
4586 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4587 else
4588 sym_modify_dp(np, tp, cp, -1);
4589 return;
4590 case M_REJECT:
4591 if (INB(np, HS_PRT) == HS_NEGOTIATE)
4592 sym_nego_rejected(np, tp, cp);
4593 else {
4594 sym_print_addr(cp->cmd,
4595 "M_REJECT received (%x:%x).\n",
4596 scr_to_cpu(np->lastmsg), np->msgout[0]);
4597 }
4598 goto out_clrack;
4599 default:
4600 goto out_reject;
4601 }
4602 break;
4603
4604
4605
4606
4607 case SIR_MSG_WEIRD:
4608 sym_print_msg(cp, "WEIRD message received", np->msgin);
4609 OUTL_DSP(np, SCRIPTB_BA(np, msg_weird));
4610 return;
4611
4612
4613
4614
4615
4616 case SIR_NEGO_FAILED:
4617 OUTB(np, HS_PRT, HS_BUSY);
4618
4619
4620
4621
4622 fallthrough;
4623 case SIR_NEGO_PROTO:
4624 sym_nego_default(np, tp, cp);
4625 goto out;
4626 }
4627
4628out:
4629 OUTONB_STD();
4630 return;
4631out_reject:
4632 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4633 return;
4634out_clrack:
4635 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4636 return;
4637out_stuck:
4638 return;
4639}
4640
4641
4642
4643
4644struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order)
4645{
4646 u_char tn = cmd->device->id;
4647 u_char ln = cmd->device->lun;
4648 struct sym_tcb *tp = &np->target[tn];
4649 struct sym_lcb *lp = sym_lp(tp, ln);
4650 u_short tag = NO_TAG;
4651 SYM_QUEHEAD *qp;
4652 struct sym_ccb *cp = NULL;
4653
4654
4655
4656
4657 if (sym_que_empty(&np->free_ccbq))
4658 sym_alloc_ccb(np);
4659 qp = sym_remque_head(&np->free_ccbq);
4660 if (!qp)
4661 goto out;
4662 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
4663
4664 {
4665
4666
4667
4668 if (tag_order) {
4669
4670
4671
4672#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4673 if (lp->busy_itl != 0)
4674 goto out_free;
4675#endif
4676
4677
4678
4679 if (!lp->cb_tags) {
4680 sym_alloc_lcb_tags(np, tn, ln);
4681 if (!lp->cb_tags)
4682 goto out_free;
4683 }
4684
4685
4686
4687
4688
4689
4690 if (lp->busy_itlq < SYM_CONF_MAX_TASK) {
4691 tag = lp->cb_tags[lp->ia_tag];
4692 if (++lp->ia_tag == SYM_CONF_MAX_TASK)
4693 lp->ia_tag = 0;
4694 ++lp->busy_itlq;
4695#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4696 lp->itlq_tbl[tag] = cpu_to_scr(cp->ccb_ba);
4697 lp->head.resel_sa =
4698 cpu_to_scr(SCRIPTA_BA(np, resel_tag));
4699#endif
4700#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
4701 cp->tags_si = lp->tags_si;
4702 ++lp->tags_sum[cp->tags_si];
4703 ++lp->tags_since;
4704#endif
4705 }
4706 else
4707 goto out_free;
4708 }
4709
4710
4711
4712
4713
4714 else {
4715
4716
4717
4718#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4719 if (lp->busy_itl != 0 || lp->busy_itlq != 0)
4720 goto out_free;
4721#endif
4722
4723
4724
4725
4726
4727 ++lp->busy_itl;
4728#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4729 if (lp->busy_itl == 1) {
4730 lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
4731 lp->head.resel_sa =
4732 cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
4733 }
4734 else
4735 goto out_free;
4736#endif
4737 }
4738 }
4739
4740
4741
4742 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
4743#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4744 if (lp) {
4745 sym_remque(&cp->link2_ccbq);
4746 sym_insque_tail(&cp->link2_ccbq, &lp->waiting_ccbq);
4747 }
4748
4749#endif
4750 cp->to_abort = 0;
4751 cp->odd_byte_adjustment = 0;
4752 cp->tag = tag;
4753 cp->order = tag_order;
4754 cp->target = tn;
4755 cp->lun = ln;
4756
4757 if (DEBUG_FLAGS & DEBUG_TAGS) {
4758 sym_print_addr(cmd, "ccb @%p using tag %d.\n", cp, tag);
4759 }
4760
4761out:
4762 return cp;
4763out_free:
4764 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4765 return NULL;
4766}
4767
4768
4769
4770
4771void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
4772{
4773 struct sym_tcb *tp = &np->target[cp->target];
4774 struct sym_lcb *lp = sym_lp(tp, cp->lun);
4775
4776 if (DEBUG_FLAGS & DEBUG_TAGS) {
4777 sym_print_addr(cp->cmd, "ccb @%p freeing tag %d.\n",
4778 cp, cp->tag);
4779 }
4780
4781
4782
4783
4784 if (lp) {
4785
4786
4787
4788 if (cp->tag != NO_TAG) {
4789#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
4790 --lp->tags_sum[cp->tags_si];
4791#endif
4792
4793
4794
4795 lp->cb_tags[lp->if_tag] = cp->tag;
4796 if (++lp->if_tag == SYM_CONF_MAX_TASK)
4797 lp->if_tag = 0;
4798
4799
4800
4801
4802 lp->itlq_tbl[cp->tag] = cpu_to_scr(np->bad_itlq_ba);
4803 --lp->busy_itlq;
4804 } else {
4805
4806
4807
4808
4809 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
4810 --lp->busy_itl;
4811 }
4812
4813
4814
4815 if (lp->busy_itlq == 0 && lp->busy_itl == 0)
4816 lp->head.resel_sa =
4817 cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
4818 }
4819
4820
4821
4822
4823
4824
4825 if (cp == tp->nego_cp)
4826 tp->nego_cp = NULL;
4827
4828#ifdef SYM_CONF_IARB_SUPPORT
4829
4830
4831
4832
4833 if (cp == np->last_cp)
4834 np->last_cp = 0;
4835#endif
4836
4837
4838
4839
4840 cp->cmd = NULL;
4841 cp->host_status = HS_IDLE;
4842 sym_remque(&cp->link_ccbq);
4843 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4844
4845#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4846 if (lp) {
4847 sym_remque(&cp->link2_ccbq);
4848 sym_insque_tail(&cp->link2_ccbq, &np->dummy_ccbq);
4849 if (cp->started) {
4850 if (cp->tag != NO_TAG)
4851 --lp->started_tags;
4852 else
4853 --lp->started_no_tag;
4854 }
4855 }
4856 cp->started = 0;
4857#endif
4858}
4859
4860
4861
4862
4863static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np)
4864{
4865 struct sym_ccb *cp = NULL;
4866 int hcode;
4867
4868
4869
4870
4871
4872 if (np->actccbs >= SYM_CONF_MAX_START)
4873 return NULL;
4874
4875
4876
4877
4878 cp = sym_calloc_dma(sizeof(struct sym_ccb), "CCB");
4879 if (!cp)
4880 goto out_free;
4881
4882
4883
4884
4885 np->actccbs++;
4886
4887
4888
4889
4890 cp->ccb_ba = vtobus(cp);
4891
4892
4893
4894
4895 hcode = CCB_HASH_CODE(cp->ccb_ba);
4896 cp->link_ccbh = np->ccbh[hcode];
4897 np->ccbh[hcode] = cp;
4898
4899
4900
4901
4902 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, idle));
4903 cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
4904
4905
4906
4907
4908 cp->phys.smsg_ext.addr = cpu_to_scr(HCB_BA(np, msgin[2]));
4909
4910
4911
4912
4913 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4914
4915
4916
4917
4918#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4919 sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq);
4920#endif
4921 return cp;
4922out_free:
4923 if (cp)
4924 sym_mfree_dma(cp, sizeof(*cp), "CCB");
4925 return NULL;
4926}
4927
4928
4929
4930
4931static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
4932{
4933 int hcode;
4934 struct sym_ccb *cp;
4935
4936 hcode = CCB_HASH_CODE(dsa);
4937 cp = np->ccbh[hcode];
4938 while (cp) {
4939 if (cp->ccb_ba == dsa)
4940 break;
4941 cp = cp->link_ccbh;
4942 }
4943
4944 return cp;
4945}
4946
4947
4948
4949
4950
4951static void sym_init_tcb (struct sym_hcb *np, u_char tn)
4952{
4953#if 0
4954
4955
4956
4957 assert (((offsetof(struct sym_reg, nc_sxfer) ^
4958 offsetof(struct sym_tcb, head.sval)) &3) == 0);
4959 assert (((offsetof(struct sym_reg, nc_scntl3) ^
4960 offsetof(struct sym_tcb, head.wval)) &3) == 0);
4961#endif
4962}
4963
4964
4965
4966
4967struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
4968{
4969 struct sym_tcb *tp = &np->target[tn];
4970 struct sym_lcb *lp = NULL;
4971
4972
4973
4974
4975 sym_init_tcb (np, tn);
4976
4977
4978
4979
4980
4981 if (ln && !tp->luntbl) {
4982 tp->luntbl = sym_calloc_dma(256, "LUNTBL");
4983 if (!tp->luntbl)
4984 goto fail;
4985 memset32(tp->luntbl, cpu_to_scr(vtobus(&np->badlun_sa)), 64);
4986 tp->head.luntbl_sa = cpu_to_scr(vtobus(tp->luntbl));
4987 }
4988
4989
4990
4991
4992 if (ln && !tp->lunmp) {
4993 tp->lunmp = kcalloc(SYM_CONF_MAX_LUN, sizeof(struct sym_lcb *),
4994 GFP_ATOMIC);
4995 if (!tp->lunmp)
4996 goto fail;
4997 }
4998
4999
5000
5001
5002
5003 lp = sym_calloc_dma(sizeof(struct sym_lcb), "LCB");
5004 if (!lp)
5005 goto fail;
5006 if (ln) {
5007 tp->lunmp[ln] = lp;
5008 tp->luntbl[ln] = cpu_to_scr(vtobus(lp));
5009 }
5010 else {
5011 tp->lun0p = lp;
5012 tp->head.lun0_sa = cpu_to_scr(vtobus(lp));
5013 }
5014 tp->nlcb++;
5015
5016
5017
5018
5019 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
5020
5021
5022
5023
5024 lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5025
5026
5027
5028
5029 lp->user_flags = tp->usrflags & (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
5030
5031#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5032
5033
5034
5035 sym_que_init(&lp->waiting_ccbq);
5036 sym_que_init(&lp->started_ccbq);
5037 lp->started_max = SYM_CONF_MAX_TASK;
5038 lp->started_limit = SYM_CONF_MAX_TASK;
5039#endif
5040
5041fail:
5042 return lp;
5043}
5044
5045
5046
5047
5048static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
5049{
5050 struct sym_tcb *tp = &np->target[tn];
5051 struct sym_lcb *lp = sym_lp(tp, ln);
5052 int i;
5053
5054
5055
5056
5057
5058 lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5059 if (!lp->itlq_tbl)
5060 goto fail;
5061 lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
5062 if (!lp->cb_tags) {
5063 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5064 lp->itlq_tbl = NULL;
5065 goto fail;
5066 }
5067
5068
5069
5070
5071 memset32(lp->itlq_tbl, cpu_to_scr(np->notask_ba), SYM_CONF_MAX_TASK);
5072
5073
5074
5075
5076 for (i = 0 ; i < SYM_CONF_MAX_TASK ; i++)
5077 lp->cb_tags[i] = i;
5078
5079
5080
5081
5082
5083 lp->head.itlq_tbl_sa = cpu_to_scr(vtobus(lp->itlq_tbl));
5084
5085 return;
5086fail:
5087 return;
5088}
5089
5090
5091
5092
5093
5094int sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln)
5095{
5096 struct sym_tcb *tp = &np->target[tn];
5097 struct sym_lcb *lp = sym_lp(tp, ln);
5098
5099 tp->nlcb--;
5100
5101 if (ln) {
5102 if (!tp->nlcb) {
5103 kfree(tp->lunmp);
5104 sym_mfree_dma(tp->luntbl, 256, "LUNTBL");
5105 tp->lunmp = NULL;
5106 tp->luntbl = NULL;
5107 tp->head.luntbl_sa = cpu_to_scr(vtobus(np->badluntbl));
5108 } else {
5109 tp->luntbl[ln] = cpu_to_scr(vtobus(&np->badlun_sa));
5110 tp->lunmp[ln] = NULL;
5111 }
5112 } else {
5113 tp->lun0p = NULL;
5114 tp->head.lun0_sa = cpu_to_scr(vtobus(&np->badlun_sa));
5115 }
5116
5117 if (lp->itlq_tbl) {
5118 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5119 kfree(lp->cb_tags);
5120 }
5121
5122 sym_mfree_dma(lp, sizeof(*lp), "LCB");
5123
5124 return tp->nlcb;
5125}
5126
5127
5128
5129
5130int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
5131{
5132 struct scsi_device *sdev = cmd->device;
5133 struct sym_tcb *tp;
5134 struct sym_lcb *lp;
5135 u_char *msgptr;
5136 u_int msglen;
5137 int can_disconnect;
5138
5139
5140
5141
5142 cp->cmd = cmd;
5143
5144
5145
5146
5147 tp = &np->target[cp->target];
5148
5149
5150
5151
5152 lp = sym_lp(tp, sdev->lun);
5153
5154 can_disconnect = (cp->tag != NO_TAG) ||
5155 (lp && (lp->curr_flags & SYM_DISC_ENABLED));
5156
5157 msgptr = cp->scsi_smsg;
5158 msglen = 0;
5159 msgptr[msglen++] = IDENTIFY(can_disconnect, sdev->lun);
5160
5161
5162
5163
5164 if (cp->tag != NO_TAG) {
5165 u_char order = cp->order;
5166
5167 switch(order) {
5168 case M_ORDERED_TAG:
5169 break;
5170 case M_HEAD_TAG:
5171 break;
5172 default:
5173 order = M_SIMPLE_TAG;
5174 }
5175#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
5176
5177
5178
5179
5180
5181
5182 if (lp && lp->tags_since > 3*SYM_CONF_MAX_TAG) {
5183 lp->tags_si = !(lp->tags_si);
5184 if (lp->tags_sum[lp->tags_si]) {
5185 order = M_ORDERED_TAG;
5186 if ((DEBUG_FLAGS & DEBUG_TAGS)||sym_verbose>1) {
5187 sym_print_addr(cmd,
5188 "ordered tag forced.\n");
5189 }
5190 }
5191 lp->tags_since = 0;
5192 }
5193#endif
5194 msgptr[msglen++] = order;
5195
5196
5197
5198
5199
5200
5201
5202
5203#if SYM_CONF_MAX_TASK > (512/4)
5204 msgptr[msglen++] = cp->tag;
5205#else
5206 msgptr[msglen++] = (cp->tag << 1) + 1;
5207#endif
5208 }
5209
5210
5211
5212
5213
5214
5215
5216
5217 cp->nego_status = 0;
5218 if ((tp->tgoal.check_nego ||
5219 cmd->cmnd[0] == INQUIRY || cmd->cmnd[0] == REQUEST_SENSE) &&
5220 !tp->nego_cp && lp) {
5221 msglen += sym_prepare_nego(np, cp, msgptr + msglen);
5222 }
5223
5224
5225
5226
5227 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
5228 cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA(np, resel_dsa));
5229
5230
5231
5232
5233 cp->phys.select.sel_id = cp->target;
5234 cp->phys.select.sel_scntl3 = tp->head.wval;
5235 cp->phys.select.sel_sxfer = tp->head.sval;
5236 cp->phys.select.sel_scntl4 = tp->head.uval;
5237
5238
5239
5240
5241 cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg);
5242 cp->phys.smsg.size = cpu_to_scr(msglen);
5243
5244
5245
5246
5247 cp->host_xflags = 0;
5248 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
5249 cp->ssss_status = S_ILLEGAL;
5250 cp->xerr_status = 0;
5251 cp->host_flags = 0;
5252 cp->extra_bytes = 0;
5253
5254
5255
5256
5257
5258 cp->ext_sg = -1;
5259 cp->ext_ofs = 0;
5260
5261
5262
5263
5264
5265 return sym_setup_data_and_start(np, cmd, cp);
5266}
5267
5268
5269
5270
5271int sym_reset_scsi_target(struct sym_hcb *np, int target)
5272{
5273 struct sym_tcb *tp;
5274
5275 if (target == np->myaddr || (u_int)target >= SYM_CONF_MAX_TARGET)
5276 return -1;
5277
5278 tp = &np->target[target];
5279 tp->to_reset = 1;
5280
5281 np->istat_sem = SEM;
5282 OUTB(np, nc_istat, SIGP|SEM);
5283
5284 return 0;
5285}
5286
5287
5288
5289
5290static int sym_abort_ccb(struct sym_hcb *np, struct sym_ccb *cp, int timed_out)
5291{
5292
5293
5294
5295 if (!cp || !cp->host_status || cp->host_status == HS_WAIT)
5296 return -1;
5297
5298
5299
5300
5301
5302 if (cp->to_abort) {
5303 sym_reset_scsi_bus(np, 1);
5304 return 0;
5305 }
5306
5307
5308
5309
5310 cp->to_abort = timed_out ? 2 : 1;
5311
5312
5313
5314
5315 np->istat_sem = SEM;
5316 OUTB(np, nc_istat, SIGP|SEM);
5317 return 0;
5318}
5319
5320int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out)
5321{
5322 struct sym_ccb *cp;
5323 SYM_QUEHEAD *qp;
5324
5325
5326
5327
5328 cp = NULL;
5329 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
5330 struct sym_ccb *cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq);
5331 if (cp2->cmd == cmd) {
5332 cp = cp2;
5333 break;
5334 }
5335 }
5336
5337 return sym_abort_ccb(np, cp, timed_out);
5338}
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350void sym_complete_error(struct sym_hcb *np, struct sym_ccb *cp)
5351{
5352 struct scsi_device *sdev;
5353 struct scsi_cmnd *cmd;
5354#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5355 struct sym_tcb *tp;
5356 struct sym_lcb *lp;
5357#endif
5358 int resid;
5359 int i;
5360
5361
5362
5363
5364 if (!cp || !cp->cmd)
5365 return;
5366
5367 cmd = cp->cmd;
5368 sdev = cmd->device;
5369 if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_RESULT)) {
5370 dev_info(&sdev->sdev_gendev, "CCB=%p STAT=%x/%x/%x\n", cp,
5371 cp->host_status, cp->ssss_status, cp->host_flags);
5372 }
5373
5374#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5375
5376
5377
5378 tp = &np->target[cp->target];
5379 lp = sym_lp(tp, sdev->lun);
5380#endif
5381
5382
5383
5384
5385 if (cp->xerr_status) {
5386 if (sym_verbose)
5387 sym_print_xerr(cmd, cp->xerr_status);
5388 if (cp->host_status == HS_COMPLETE)
5389 cp->host_status = HS_COMP_ERR;
5390 }
5391
5392
5393
5394
5395 resid = sym_compute_residual(np, cp);
5396
5397 if (!SYM_SETUP_RESIDUAL_SUPPORT) {
5398 resid = 0;
5399 cp->sv_resid = 0;
5400 }
5401#ifdef DEBUG_2_0_X
5402if (resid)
5403 printf("XXXX RESID= %d - 0x%x\n", resid, resid);
5404#endif
5405
5406
5407
5408
5409
5410 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
5411 i = sym_dequeue_from_squeue(np, i, cp->target, sdev->lun, -1);
5412
5413
5414
5415
5416 OUTL_DSP(np, SCRIPTA_BA(np, start));
5417
5418#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5419 if (cp->host_status == HS_COMPLETE &&
5420 cp->ssss_status == S_QUEUE_FULL) {
5421 if (!lp || lp->started_tags - i < 2)
5422 goto weirdness;
5423
5424
5425
5426 lp->started_max = lp->started_tags - i - 1;
5427 lp->num_sgood = 0;
5428
5429 if (sym_verbose >= 2) {
5430 sym_print_addr(cmd, " queue depth is now %d\n",
5431 lp->started_max);
5432 }
5433
5434
5435
5436
5437 cp->host_status = HS_BUSY;
5438 cp->ssss_status = S_ILLEGAL;
5439
5440
5441
5442
5443 sym_set_cam_status(cmd, DID_SOFT_ERROR);
5444 goto finish;
5445 }
5446weirdness:
5447#endif
5448
5449
5450
5451 sym_set_cam_result_error(np, cp, resid);
5452
5453#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5454finish:
5455#endif
5456
5457
5458
5459 sym_remque(&cp->link_ccbq);
5460 sym_insque_head(&cp->link_ccbq, &np->comp_ccbq);
5461
5462
5463
5464
5465
5466 sym_flush_comp_queue(np, 0);
5467
5468#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5469
5470
5471
5472 sym_start_next_ccbs(np, lp, 1);
5473#endif
5474}
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
5486{
5487#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5488 struct sym_tcb *tp;
5489 struct sym_lcb *lp;
5490#endif
5491 struct scsi_cmnd *cmd;
5492 int resid;
5493
5494
5495
5496
5497 if (!cp || !cp->cmd)
5498 return;
5499 assert (cp->host_status == HS_COMPLETE);
5500
5501
5502
5503
5504 cmd = cp->cmd;
5505
5506#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5507
5508
5509
5510 tp = &np->target[cp->target];
5511 lp = sym_lp(tp, cp->lun);
5512#endif
5513
5514
5515
5516
5517
5518 resid = 0;
5519 if (cp->phys.head.lastp != cp->goalp)
5520 resid = sym_compute_residual(np, cp);
5521
5522
5523
5524
5525
5526
5527 if (!SYM_SETUP_RESIDUAL_SUPPORT)
5528 resid = 0;
5529#ifdef DEBUG_2_0_X
5530if (resid)
5531 printf("XXXX RESID= %d - 0x%x\n", resid, resid);
5532#endif
5533
5534
5535
5536
5537 sym_set_cam_result_ok(cp, cmd, resid);
5538
5539#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5540
5541
5542
5543
5544 if (lp && lp->started_max < lp->started_limit) {
5545 ++lp->num_sgood;
5546 if (lp->num_sgood >= 200) {
5547 lp->num_sgood = 0;
5548 ++lp->started_max;
5549 if (sym_verbose >= 2) {
5550 sym_print_addr(cmd, " queue depth is now %d\n",
5551 lp->started_max);
5552 }
5553 }
5554 }
5555#endif
5556
5557
5558
5559
5560 sym_free_ccb (np, cp);
5561
5562#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5563
5564
5565
5566 if (!sym_que_empty(&lp->waiting_ccbq))
5567 sym_start_next_ccbs(np, lp, 2);
5568#endif
5569
5570
5571
5572 sym_xpt_done(np, cmd);
5573}
5574
5575
5576
5577
5578int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram)
5579{
5580 struct sym_hcb *np = sym_get_hcb(shost);
5581 int i;
5582
5583
5584
5585
5586 np->scripta_sz = fw->a_size;
5587 np->scriptb_sz = fw->b_size;
5588 np->scriptz_sz = fw->z_size;
5589 np->fw_setup = fw->setup;
5590 np->fw_patch = fw->patch;
5591 np->fw_name = fw->name;
5592
5593
5594
5595
5596
5597 sym_save_initial_setting (np);
5598
5599
5600
5601
5602
5603
5604 sym_chip_reset(np);
5605
5606
5607
5608
5609
5610 sym_prepare_setting(shost, np, nvram);
5611
5612
5613
5614
5615
5616
5617 i = sym_getpciclock(np);
5618 if (i > 37000 && !(np->features & FE_66MHZ))
5619 printf("%s: PCI BUS clock seems too high: %u KHz.\n",
5620 sym_name(np), i);
5621
5622
5623
5624
5625 np->squeue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
5626 if (!np->squeue)
5627 goto attach_failed;
5628 np->squeue_ba = vtobus(np->squeue);
5629
5630
5631
5632
5633 np->dqueue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
5634 if (!np->dqueue)
5635 goto attach_failed;
5636 np->dqueue_ba = vtobus(np->dqueue);
5637
5638
5639
5640
5641 np->targtbl = sym_calloc_dma(256, "TARGTBL");
5642 if (!np->targtbl)
5643 goto attach_failed;
5644 np->targtbl_ba = vtobus(np->targtbl);
5645
5646
5647
5648
5649 np->scripta0 = sym_calloc_dma(np->scripta_sz, "SCRIPTA0");
5650 np->scriptb0 = sym_calloc_dma(np->scriptb_sz, "SCRIPTB0");
5651 np->scriptz0 = sym_calloc_dma(np->scriptz_sz, "SCRIPTZ0");
5652 if (!np->scripta0 || !np->scriptb0 || !np->scriptz0)
5653 goto attach_failed;
5654
5655
5656
5657
5658 np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(*np->ccbh), GFP_KERNEL);
5659 if (!np->ccbh)
5660 goto attach_failed;
5661
5662
5663
5664
5665 sym_que_init(&np->free_ccbq);
5666 sym_que_init(&np->busy_ccbq);
5667 sym_que_init(&np->comp_ccbq);
5668
5669
5670
5671
5672
5673#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5674 sym_que_init(&np->dummy_ccbq);
5675#endif
5676
5677
5678
5679 if (!sym_alloc_ccb(np))
5680 goto attach_failed;
5681
5682
5683
5684
5685
5686 np->scripta_ba = vtobus(np->scripta0);
5687 np->scriptb_ba = vtobus(np->scriptb0);
5688 np->scriptz_ba = vtobus(np->scriptz0);
5689
5690 if (np->ram_ba) {
5691 np->scripta_ba = np->ram_ba;
5692 if (np->features & FE_RAM8K) {
5693 np->scriptb_ba = np->scripta_ba + 4096;
5694#if 0
5695 np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32);
5696#endif
5697 }
5698 }
5699
5700
5701
5702
5703 memcpy(np->scripta0, fw->a_base, np->scripta_sz);
5704 memcpy(np->scriptb0, fw->b_base, np->scriptb_sz);
5705 memcpy(np->scriptz0, fw->z_base, np->scriptz_sz);
5706
5707
5708
5709
5710
5711 np->fw_setup(np, fw);
5712
5713
5714
5715
5716
5717 sym_fw_bind_script(np, (u32 *) np->scripta0, np->scripta_sz);
5718 sym_fw_bind_script(np, (u32 *) np->scriptb0, np->scriptb_sz);
5719 sym_fw_bind_script(np, (u32 *) np->scriptz0, np->scriptz_sz);
5720
5721#ifdef SYM_CONF_IARB_SUPPORT
5722
5723
5724
5725
5726
5727
5728#ifdef SYM_SETUP_IARB_MAX
5729 np->iarb_max = SYM_SETUP_IARB_MAX;
5730#else
5731 np->iarb_max = 4;
5732#endif
5733#endif
5734
5735
5736
5737
5738 np->idletask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5739 np->idletask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5740 np->idletask_ba = vtobus(&np->idletask);
5741
5742 np->notask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5743 np->notask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5744 np->notask_ba = vtobus(&np->notask);
5745
5746 np->bad_itl.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5747 np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5748 np->bad_itl_ba = vtobus(&np->bad_itl);
5749
5750 np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5751 np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA(np,bad_i_t_l_q));
5752 np->bad_itlq_ba = vtobus(&np->bad_itlq);
5753
5754
5755
5756
5757
5758
5759
5760 np->badluntbl = sym_calloc_dma(256, "BADLUNTBL");
5761 if (!np->badluntbl)
5762 goto attach_failed;
5763
5764 np->badlun_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5765 memset32(np->badluntbl, cpu_to_scr(vtobus(&np->badlun_sa)), 64);
5766
5767
5768
5769
5770
5771
5772 for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
5773 np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
5774 np->target[i].head.luntbl_sa =
5775 cpu_to_scr(vtobus(np->badluntbl));
5776 np->target[i].head.lun0_sa =
5777 cpu_to_scr(vtobus(&np->badlun_sa));
5778 }
5779
5780
5781
5782
5783 if (sym_snooptest (np)) {
5784 printf("%s: CACHE INCORRECTLY CONFIGURED.\n", sym_name(np));
5785 goto attach_failed;
5786 }
5787
5788
5789
5790
5791 return 0;
5792
5793attach_failed:
5794 return -ENXIO;
5795}
5796
5797
5798
5799
5800void sym_hcb_free(struct sym_hcb *np)
5801{
5802 SYM_QUEHEAD *qp;
5803 struct sym_ccb *cp;
5804 struct sym_tcb *tp;
5805 int target;
5806
5807 if (np->scriptz0)
5808 sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
5809 if (np->scriptb0)
5810 sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
5811 if (np->scripta0)
5812 sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
5813 if (np->squeue)
5814 sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
5815 if (np->dqueue)
5816 sym_mfree_dma(np->dqueue, sizeof(u32)*(MAX_QUEUE*2), "DQUEUE");
5817
5818 if (np->actccbs) {
5819 while ((qp = sym_remque_head(&np->free_ccbq)) != NULL) {
5820 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
5821 sym_mfree_dma(cp, sizeof(*cp), "CCB");
5822 }
5823 }
5824 kfree(np->ccbh);
5825
5826 if (np->badluntbl)
5827 sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
5828
5829 for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
5830 tp = &np->target[target];
5831 if (tp->luntbl)
5832 sym_mfree_dma(tp->luntbl, 256, "LUNTBL");
5833#if SYM_CONF_MAX_LUN > 1
5834 kfree(tp->lunmp);
5835#endif
5836 }
5837 if (np->targtbl)
5838 sym_mfree_dma(np->targtbl, 256, "TARGTBL");
5839}
5840