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