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 sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
3004 sym_remque(&cp->link_ccbq);
3005 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3006 }
3007 else {
3008 if (i != j)
3009 np->squeue[j] = np->squeue[i];
3010 if ((j += 2) >= MAX_QUEUE*2) j = 0;
3011 }
3012 if ((i += 2) >= MAX_QUEUE*2) i = 0;
3013 }
3014 if (i != j)
3015 np->squeue[j] = np->squeue[i];
3016 np->squeueput = j;
3017
3018 return (i - j) / 2;
3019}
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb *cp)
3040{
3041 u32 startp;
3042 u_char s_status = cp->ssss_status;
3043 u_char h_flags = cp->host_flags;
3044 int msglen;
3045 int i;
3046
3047
3048
3049
3050 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3051
3052
3053
3054
3055
3056#ifdef SYM_CONF_IARB_SUPPORT
3057 if (np->last_cp)
3058 np->last_cp = 0;
3059#endif
3060
3061
3062
3063
3064 switch(s_status) {
3065 case S_BUSY:
3066 case S_QUEUE_FULL:
3067 if (sym_verbose >= 2) {
3068 sym_print_addr(cp->cmd, "%s\n",
3069 s_status == S_BUSY ? "BUSY" : "QUEUE FULL\n");
3070 }
3071 default:
3072 sym_complete_error (np, cp);
3073 break;
3074 case S_TERMINATED:
3075 case S_CHECK_COND:
3076
3077
3078
3079 if (h_flags & HF_SENSE) {
3080 sym_complete_error (np, cp);
3081 break;
3082 }
3083
3084
3085
3086
3087
3088 sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3089 OUTL_DSP(np, SCRIPTA_BA(np, start));
3090
3091
3092
3093
3094
3095 cp->sv_scsi_status = cp->ssss_status;
3096 cp->sv_xerr_status = cp->xerr_status;
3097 cp->sv_resid = sym_compute_residual(np, cp);
3098
3099
3100
3101
3102
3103
3104 cp->scsi_smsg2[0] = IDENTIFY(0, cp->lun);
3105 msglen = 1;
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117 cp->nego_status = 0;
3118 msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]);
3119
3120
3121
3122 cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2);
3123 cp->phys.smsg.size = cpu_to_scr(msglen);
3124
3125
3126
3127
3128 cp->phys.cmd.addr = CCB_BA(cp, sensecmd);
3129 cp->phys.cmd.size = cpu_to_scr(6);
3130
3131
3132
3133
3134 cp->sensecmd[0] = REQUEST_SENSE;
3135 cp->sensecmd[1] = 0;
3136 if (cp->cmd->device->scsi_level <= SCSI_2 && cp->lun <= 7)
3137 cp->sensecmd[1] = cp->lun << 5;
3138 cp->sensecmd[4] = SYM_SNS_BBUF_LEN;
3139 cp->data_len = SYM_SNS_BBUF_LEN;
3140
3141
3142
3143
3144 memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
3145 cp->phys.sense.addr = CCB_BA(cp, sns_bbuf);
3146 cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
3147
3148
3149
3150
3151 startp = SCRIPTB_BA(np, sdata_in);
3152
3153 cp->phys.head.savep = cpu_to_scr(startp);
3154 cp->phys.head.lastp = cpu_to_scr(startp);
3155 cp->startp = cpu_to_scr(startp);
3156 cp->goalp = cpu_to_scr(startp + 16);
3157
3158 cp->host_xflags = 0;
3159 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
3160 cp->ssss_status = S_ILLEGAL;
3161 cp->host_flags = (HF_SENSE|HF_DATA_IN);
3162 cp->xerr_status = 0;
3163 cp->extra_bytes = 0;
3164
3165 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
3166
3167
3168
3169
3170 sym_put_start_queue(np, cp);
3171
3172
3173
3174
3175 sym_flush_comp_queue(np, 0);
3176 break;
3177 }
3178}
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task)
3195{
3196 SYM_QUEHEAD qtmp, *qp;
3197 int i = 0;
3198 struct sym_ccb *cp;
3199
3200
3201
3202
3203 sym_que_init(&qtmp);
3204 sym_que_splice(&np->busy_ccbq, &qtmp);
3205 sym_que_init(&np->busy_ccbq);
3206
3207
3208
3209
3210
3211
3212 while ((qp = sym_remque_head(&qtmp)) != NULL) {
3213 struct scsi_cmnd *cmd;
3214 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3215 cmd = cp->cmd;
3216 if (cp->host_status != HS_DISCONNECT ||
3217 cp->target != target ||
3218 (lun != -1 && cp->lun != lun) ||
3219 (task != -1 &&
3220 (cp->tag != NO_TAG && cp->scsi_smsg[2] != task))) {
3221 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
3222 continue;
3223 }
3224 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3225
3226
3227 if (sym_get_cam_status(cmd) != DID_TIME_OUT)
3228 sym_set_cam_status(cmd, cam_status);
3229 ++i;
3230#if 0
3231printf("XXXX TASK @%p CLEARED\n", cp);
3232#endif
3233 }
3234 return i;
3235}
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277static void sym_sir_task_recovery(struct sym_hcb *np, int num)
3278{
3279 SYM_QUEHEAD *qp;
3280 struct sym_ccb *cp;
3281 struct sym_tcb *tp = NULL;
3282 struct scsi_target *starget;
3283 int target=-1, lun=-1, task;
3284 int i, k;
3285
3286 switch(num) {
3287
3288
3289
3290
3291
3292 case SIR_SCRIPT_STOPPED:
3293
3294
3295
3296 for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
3297 tp = &np->target[i];
3298 if (tp->to_reset ||
3299 (tp->lun0p && tp->lun0p->to_clear)) {
3300 target = i;
3301 break;
3302 }
3303 if (!tp->lunmp)
3304 continue;
3305 for (k = 1 ; k < SYM_CONF_MAX_LUN ; k++) {
3306 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) {
3307 target = i;
3308 break;
3309 }
3310 }
3311 if (target != -1)
3312 break;
3313 }
3314
3315
3316
3317
3318
3319 if (target == -1) {
3320 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3321 cp = sym_que_entry(qp,struct sym_ccb,link_ccbq);
3322 if (cp->host_status != HS_DISCONNECT)
3323 continue;
3324 if (cp->to_abort) {
3325 target = cp->target;
3326 break;
3327 }
3328 }
3329 }
3330
3331
3332
3333
3334
3335 if (target != -1) {
3336 tp = &np->target[target];
3337 np->abrt_sel.sel_id = target;
3338 np->abrt_sel.sel_scntl3 = tp->head.wval;
3339 np->abrt_sel.sel_sxfer = tp->head.sval;
3340 OUTL(np, nc_dsa, np->hcb_ba);
3341 OUTL_DSP(np, SCRIPTB_BA(np, sel_for_abort));
3342 return;
3343 }
3344
3345
3346
3347
3348
3349
3350 i = 0;
3351 cp = NULL;
3352 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3353 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3354 if (cp->host_status != HS_BUSY &&
3355 cp->host_status != HS_NEGOTIATE)
3356 continue;
3357 if (!cp->to_abort)
3358 continue;
3359#ifdef SYM_CONF_IARB_SUPPORT
3360
3361
3362
3363
3364
3365 if (cp == np->last_cp) {
3366 cp->to_abort = 0;
3367 continue;
3368 }
3369#endif
3370 i = 1;
3371 break;
3372 }
3373 if (!i) {
3374
3375
3376
3377
3378
3379 np->istat_sem = 0;
3380 OUTB(np, nc_istat, SIGP);
3381 break;
3382 }
3383
3384
3385
3386
3387
3388 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3389 i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3390
3391
3392
3393
3394#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
3395 assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
3396#else
3397 sym_remque(&cp->link_ccbq);
3398 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3399#endif
3400
3401
3402
3403 if (cp->to_abort == 2)
3404 sym_set_cam_status(cp->cmd, DID_TIME_OUT);
3405 else
3406 sym_set_cam_status(cp->cmd, DID_ABORT);
3407
3408
3409
3410
3411 sym_flush_comp_queue(np, 0);
3412 break;
3413
3414
3415
3416
3417 case SIR_TARGET_SELECTED:
3418 target = INB(np, nc_sdid) & 0xf;
3419 tp = &np->target[target];
3420
3421 np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg));
3422
3423
3424
3425
3426
3427
3428 if (tp->to_reset) {
3429 np->abrt_msg[0] = M_RESET;
3430 np->abrt_tbl.size = 1;
3431 tp->to_reset = 0;
3432 break;
3433 }
3434
3435
3436
3437
3438 if (tp->lun0p && tp->lun0p->to_clear)
3439 lun = 0;
3440 else if (tp->lunmp) {
3441 for (k = 1 ; k < SYM_CONF_MAX_LUN ; k++) {
3442 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) {
3443 lun = k;
3444 break;
3445 }
3446 }
3447 }
3448
3449
3450
3451
3452
3453 if (lun != -1) {
3454 struct sym_lcb *lp = sym_lp(tp, lun);
3455 lp->to_clear = 0;
3456 np->abrt_msg[0] = IDENTIFY(0, lun);
3457 np->abrt_msg[1] = M_ABORT;
3458 np->abrt_tbl.size = 2;
3459 break;
3460 }
3461
3462
3463
3464
3465
3466 i = 0;
3467 cp = NULL;
3468 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3469 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
3470 if (cp->host_status != HS_DISCONNECT)
3471 continue;
3472 if (cp->target != target)
3473 continue;
3474 if (!cp->to_abort)
3475 continue;
3476 i = 1;
3477 break;
3478 }
3479
3480
3481
3482
3483
3484
3485
3486
3487 if (!i) {
3488 np->abrt_msg[0] = M_ABORT;
3489 np->abrt_tbl.size = 1;
3490 break;
3491 }
3492
3493
3494
3495
3496
3497 np->abrt_msg[0] = IDENTIFY(0, cp->lun);
3498
3499
3500
3501
3502
3503
3504
3505 if (cp->tag == NO_TAG) {
3506 np->abrt_msg[1] = M_ABORT;
3507 np->abrt_tbl.size = 2;
3508 } else {
3509 np->abrt_msg[1] = cp->scsi_smsg[1];
3510 np->abrt_msg[2] = cp->scsi_smsg[2];
3511 np->abrt_msg[3] = M_ABORT_TAG;
3512 np->abrt_tbl.size = 4;
3513 }
3514
3515
3516
3517
3518
3519 if (cp->to_abort == 2)
3520 sym_set_cam_status(cp->cmd, DID_TIME_OUT);
3521 cp->to_abort = 0;
3522 break;
3523
3524
3525
3526
3527
3528 case SIR_ABORT_SENT:
3529 target = INB(np, nc_sdid) & 0xf;
3530 tp = &np->target[target];
3531 starget = tp->starget;
3532
3533
3534
3535
3536 if (np->abrt_msg[0] == M_ABORT)
3537 break;
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547 lun = -1;
3548 task = -1;
3549 if (np->abrt_msg[0] == M_RESET) {
3550 tp->head.sval = 0;
3551 tp->head.wval = np->rv_scntl3;
3552 tp->head.uval = 0;
3553 spi_period(starget) = 0;
3554 spi_offset(starget) = 0;
3555 spi_width(starget) = 0;
3556 spi_iu(starget) = 0;
3557 spi_dt(starget) = 0;
3558 spi_qas(starget) = 0;
3559 tp->tgoal.check_nego = 1;
3560 tp->tgoal.renego = 0;
3561 }
3562
3563
3564
3565
3566
3567
3568
3569 else {
3570 lun = np->abrt_msg[0] & 0x3f;
3571 if (np->abrt_msg[1] == M_ABORT_TAG)
3572 task = np->abrt_msg[2];
3573 }
3574
3575
3576
3577
3578
3579 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3580 sym_dequeue_from_squeue(np, i, target, lun, -1);
3581 sym_clear_tasks(np, DID_ABORT, target, lun, task);
3582 sym_flush_comp_queue(np, 0);
3583
3584
3585
3586
3587 if (np->abrt_msg[0] == M_RESET)
3588 starget_printk(KERN_NOTICE, starget,
3589 "has been reset\n");
3590 break;
3591 }
3592
3593
3594
3595
3596 if (num == SIR_TARGET_SELECTED) {
3597 dev_info(&tp->starget->dev, "control msgout:");
3598 sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
3599 np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
3600 }
3601
3602
3603
3604
3605 OUTONB_STD();
3606}
3607
3608
3609
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
3635static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int *ofs)
3636{
3637 u32 dp_scr;
3638 int dp_ofs, dp_sg, dp_sgmin;
3639 int tmp;
3640 struct sym_pmc *pm;
3641
3642
3643
3644
3645
3646 dp_scr = scr;
3647 dp_ofs = *ofs;
3648 if (dp_scr == SCRIPTA_BA(np, pm0_data))
3649 pm = &cp->phys.pm0;
3650 else if (dp_scr == SCRIPTA_BA(np, pm1_data))
3651 pm = &cp->phys.pm1;
3652 else
3653 pm = NULL;
3654
3655 if (pm) {
3656 dp_scr = scr_to_cpu(pm->ret);
3657 dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff;
3658 }
3659
3660
3661
3662
3663 if (cp->host_flags & HF_SENSE) {
3664 *ofs = dp_ofs;
3665 return 0;
3666 }
3667
3668
3669
3670
3671
3672
3673
3674 tmp = scr_to_cpu(cp->goalp);
3675 dp_sg = SYM_CONF_MAX_SG;
3676 if (dp_scr != tmp)
3677 dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
3678 dp_sgmin = SYM_CONF_MAX_SG - cp->segments;
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692 if (dp_ofs < 0) {
3693 int n;
3694 while (dp_sg > dp_sgmin) {
3695 --dp_sg;
3696 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3697 n = dp_ofs + (tmp & 0xffffff);
3698 if (n > 0) {
3699 ++dp_sg;
3700 break;
3701 }
3702 dp_ofs = n;
3703 }
3704 }
3705 else if (dp_ofs > 0) {
3706 while (dp_sg < SYM_CONF_MAX_SG) {
3707 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3708 dp_ofs -= (tmp & 0xffffff);
3709 ++dp_sg;
3710 if (dp_ofs <= 0)
3711 break;
3712 }
3713 }
3714
3715
3716
3717
3718
3719 if (dp_sg < dp_sgmin || (dp_sg == dp_sgmin && dp_ofs < 0))
3720 goto out_err;
3721 else if (dp_sg > SYM_CONF_MAX_SG ||
3722 (dp_sg == SYM_CONF_MAX_SG && dp_ofs > 0))
3723 goto out_err;
3724
3725
3726
3727
3728 if (dp_sg > cp->ext_sg ||
3729 (dp_sg == cp->ext_sg && dp_ofs > cp->ext_ofs)) {
3730 cp->ext_sg = dp_sg;
3731 cp->ext_ofs = dp_ofs;
3732 }
3733
3734
3735
3736
3737 *ofs = dp_ofs;
3738 return dp_sg;
3739
3740out_err:
3741 return -1;
3742}
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp, int ofs)
3754{
3755 int dp_ofs = ofs;
3756 u32 dp_scr = sym_get_script_dp (np, cp);
3757 u32 dp_ret;
3758 u32 tmp;
3759 u_char hflags;
3760 int dp_sg;
3761 struct sym_pmc *pm;
3762
3763
3764
3765
3766 if (cp->host_flags & HF_SENSE)
3767 goto out_reject;
3768
3769
3770
3771
3772
3773 dp_sg = sym_evaluate_dp(np, cp, dp_scr, &dp_ofs);
3774 if (dp_sg < 0)
3775 goto out_reject;
3776
3777
3778
3779
3780
3781 dp_ret = cpu_to_scr(cp->goalp);
3782 dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
3783
3784
3785
3786
3787
3788 if (dp_ofs == 0) {
3789 dp_scr = dp_ret;
3790 goto out_ok;
3791 }
3792
3793
3794
3795
3796 hflags = INB(np, HF_PRT);
3797
3798 if (hflags & HF_DP_SAVED)
3799 hflags ^= HF_ACT_PM;
3800
3801 if (!(hflags & HF_ACT_PM)) {
3802 pm = &cp->phys.pm0;
3803 dp_scr = SCRIPTA_BA(np, pm0_data);
3804 }
3805 else {
3806 pm = &cp->phys.pm1;
3807 dp_scr = SCRIPTA_BA(np, pm1_data);
3808 }
3809
3810 hflags &= ~(HF_DP_SAVED);
3811
3812 OUTB(np, HF_PRT, hflags);
3813
3814
3815
3816
3817
3818
3819
3820
3821 pm->ret = cpu_to_scr(dp_ret);
3822 tmp = scr_to_cpu(cp->phys.data[dp_sg-1].addr);
3823 tmp += scr_to_cpu(cp->phys.data[dp_sg-1].size) + dp_ofs;
3824 pm->sg.addr = cpu_to_scr(tmp);
3825 pm->sg.size = cpu_to_scr(-dp_ofs);
3826
3827out_ok:
3828 sym_set_script_dp (np, cp, dp_scr);
3829 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
3830 return;
3831
3832out_reject:
3833 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
3834}
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
3853{
3854 int dp_sg, dp_sgmin, resid = 0;
3855 int dp_ofs = 0;
3856
3857
3858
3859
3860
3861
3862
3863
3864 if (cp->xerr_status & (XE_EXTRA_DATA|XE_SODL_UNRUN|XE_SWIDE_OVRUN)) {
3865 if (cp->xerr_status & XE_EXTRA_DATA)
3866 resid -= cp->extra_bytes;
3867 if (cp->xerr_status & XE_SODL_UNRUN)
3868 ++resid;
3869 if (cp->xerr_status & XE_SWIDE_OVRUN)
3870 --resid;
3871 }
3872
3873
3874
3875
3876
3877 if (cp->phys.head.lastp == cp->goalp)
3878 return resid;
3879
3880
3881
3882
3883
3884 if (cp->startp == cp->phys.head.lastp ||
3885 sym_evaluate_dp(np, cp, scr_to_cpu(cp->phys.head.lastp),
3886 &dp_ofs) < 0) {
3887 return cp->data_len - cp->odd_byte_adjustment;
3888 }
3889
3890
3891
3892
3893 if (cp->host_flags & HF_SENSE) {
3894 return -dp_ofs;
3895 }
3896
3897
3898
3899
3900
3901 dp_sgmin = SYM_CONF_MAX_SG - cp->segments;
3902 resid = -cp->ext_ofs;
3903 for (dp_sg = cp->ext_sg; dp_sg < SYM_CONF_MAX_SG; ++dp_sg) {
3904 u_int tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
3905 resid += (tmp & 0xffffff);
3906 }
3907
3908 resid -= cp->odd_byte_adjustment;
3909
3910
3911
3912
3913 return resid;
3914}
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953static int
3954sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
3955{
3956 int target = cp->target;
3957 u_char chg, ofs, per, fak, div;
3958
3959 if (DEBUG_FLAGS & DEBUG_NEGO) {
3960 sym_print_nego_msg(np, target, "sync msgin", np->msgin);
3961 }
3962
3963
3964
3965
3966 chg = 0;
3967 per = np->msgin[3];
3968 ofs = np->msgin[4];
3969
3970
3971
3972
3973 if (ofs) {
3974 if (ofs > np->maxoffs)
3975 {chg = 1; ofs = np->maxoffs;}
3976 }
3977
3978 if (ofs) {
3979 if (per < np->minsync)
3980 {chg = 1; per = np->minsync;}
3981 }
3982
3983
3984
3985
3986 div = fak = 0;
3987 if (ofs && sym_getsync(np, 0, per, &div, &fak) < 0)
3988 goto reject_it;
3989
3990 if (DEBUG_FLAGS & DEBUG_NEGO) {
3991 sym_print_addr(cp->cmd,
3992 "sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n",
3993 ofs, per, div, fak, chg);
3994 }
3995
3996
3997
3998
3999
4000 if (!req && chg)
4001 goto reject_it;
4002
4003
4004
4005
4006 sym_setsync (np, target, ofs, per, div, fak);
4007
4008
4009
4010
4011 if (!req)
4012 return 0;
4013
4014
4015
4016
4017 spi_populate_sync_msg(np->msgout, per, ofs);
4018
4019 if (DEBUG_FLAGS & DEBUG_NEGO) {
4020 sym_print_nego_msg(np, target, "sync msgout", np->msgout);
4021 }
4022
4023 np->msgin [0] = M_NOOP;
4024
4025 return 0;
4026
4027reject_it:
4028 sym_setsync (np, target, 0, 0, 0, 0);
4029 return -1;
4030}
4031
4032static void sym_sync_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4033{
4034 int req = 1;
4035 int result;
4036
4037
4038
4039
4040 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4041 OUTB(np, HS_PRT, HS_BUSY);
4042 if (cp->nego_status && cp->nego_status != NS_SYNC)
4043 goto reject_it;
4044 req = 0;
4045 }
4046
4047
4048
4049
4050 result = sym_sync_nego_check(np, req, cp);
4051 if (result)
4052 goto reject_it;
4053 if (req) {
4054 cp->nego_status = NS_SYNC;
4055 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4056 }
4057 else
4058 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4059 return;
4060
4061reject_it:
4062 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4063}
4064
4065
4066
4067
4068static int
4069sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
4070{
4071 struct sym_tcb *tp = &np->target[target];
4072 unsigned char fak, div;
4073 int dt, chg = 0;
4074
4075 unsigned char per = np->msgin[3];
4076 unsigned char ofs = np->msgin[5];
4077 unsigned char wide = np->msgin[6];
4078 unsigned char opts = np->msgin[7] & PPR_OPT_MASK;
4079
4080 if (DEBUG_FLAGS & DEBUG_NEGO) {
4081 sym_print_nego_msg(np, target, "ppr msgin", np->msgin);
4082 }
4083
4084
4085
4086
4087 if (wide > np->maxwide) {
4088 chg = 1;
4089 wide = np->maxwide;
4090 }
4091 if (!wide || !(np->features & FE_U3EN))
4092 opts = 0;
4093
4094 if (opts != (np->msgin[7] & PPR_OPT_MASK))
4095 chg = 1;
4096
4097 dt = opts & PPR_OPT_DT;
4098
4099 if (ofs) {
4100 unsigned char maxoffs = dt ? np->maxoffs_dt : np->maxoffs;
4101 if (ofs > maxoffs) {
4102 chg = 1;
4103 ofs = maxoffs;
4104 }
4105 }
4106
4107 if (ofs) {
4108 unsigned char minsync = dt ? np->minsync_dt : np->minsync;
4109 if (per < minsync) {
4110 chg = 1;
4111 per = minsync;
4112 }
4113 }
4114
4115
4116
4117
4118 div = fak = 0;
4119 if (ofs && sym_getsync(np, dt, per, &div, &fak) < 0)
4120 goto reject_it;
4121
4122
4123
4124
4125
4126 if (!req && chg)
4127 goto reject_it;
4128
4129
4130
4131
4132 sym_setpprot(np, target, opts, ofs, per, wide, div, fak);
4133
4134
4135
4136
4137 if (!req)
4138 return 0;
4139
4140
4141
4142
4143 spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts);
4144
4145 if (DEBUG_FLAGS & DEBUG_NEGO) {
4146 sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
4147 }
4148
4149 np->msgin [0] = M_NOOP;
4150
4151 return 0;
4152
4153reject_it:
4154 sym_setpprot (np, target, 0, 0, 0, 0, 0, 0);
4155
4156
4157
4158
4159 if (!req && !opts) {
4160 tp->tgoal.period = per;
4161 tp->tgoal.offset = ofs;
4162 tp->tgoal.width = wide;
4163 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
4164 tp->tgoal.check_nego = 1;
4165 }
4166 return -1;
4167}
4168
4169static void sym_ppr_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4170{
4171 int req = 1;
4172 int result;
4173
4174
4175
4176
4177 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4178 OUTB(np, HS_PRT, HS_BUSY);
4179 if (cp->nego_status && cp->nego_status != NS_PPR)
4180 goto reject_it;
4181 req = 0;
4182 }
4183
4184
4185
4186
4187 result = sym_ppr_nego_check(np, req, cp->target);
4188 if (result)
4189 goto reject_it;
4190 if (req) {
4191 cp->nego_status = NS_PPR;
4192 OUTL_DSP(np, SCRIPTB_BA(np, ppr_resp));
4193 }
4194 else
4195 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4196 return;
4197
4198reject_it:
4199 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4200}
4201
4202
4203
4204
4205static int
4206sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
4207{
4208 int target = cp->target;
4209 u_char chg, wide;
4210
4211 if (DEBUG_FLAGS & DEBUG_NEGO) {
4212 sym_print_nego_msg(np, target, "wide msgin", np->msgin);
4213 }
4214
4215
4216
4217
4218 chg = 0;
4219 wide = np->msgin[3];
4220
4221
4222
4223
4224 if (wide > np->maxwide) {
4225 chg = 1;
4226 wide = np->maxwide;
4227 }
4228
4229 if (DEBUG_FLAGS & DEBUG_NEGO) {
4230 sym_print_addr(cp->cmd, "wdtr: wide=%d chg=%d.\n",
4231 wide, chg);
4232 }
4233
4234
4235
4236
4237
4238 if (!req && chg)
4239 goto reject_it;
4240
4241
4242
4243
4244 sym_setwide (np, target, wide);
4245
4246
4247
4248
4249 if (!req)
4250 return 0;
4251
4252
4253
4254
4255 spi_populate_width_msg(np->msgout, wide);
4256
4257 np->msgin [0] = M_NOOP;
4258
4259 if (DEBUG_FLAGS & DEBUG_NEGO) {
4260 sym_print_nego_msg(np, target, "wide msgout", np->msgout);
4261 }
4262
4263 return 0;
4264
4265reject_it:
4266 return -1;
4267}
4268
4269static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4270{
4271 int req = 1;
4272 int result;
4273
4274
4275
4276
4277 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4278 OUTB(np, HS_PRT, HS_BUSY);
4279 if (cp->nego_status && cp->nego_status != NS_WIDE)
4280 goto reject_it;
4281 req = 0;
4282 }
4283
4284
4285
4286
4287 result = sym_wide_nego_check(np, req, cp);
4288 if (result)
4289 goto reject_it;
4290 if (req) {
4291 cp->nego_status = NS_WIDE;
4292 OUTL_DSP(np, SCRIPTB_BA(np, wdtr_resp));
4293 } else {
4294
4295
4296
4297
4298
4299 if (tp->tgoal.offset) {
4300 spi_populate_sync_msg(np->msgout, tp->tgoal.period,
4301 tp->tgoal.offset);
4302
4303 if (DEBUG_FLAGS & DEBUG_NEGO) {
4304 sym_print_nego_msg(np, cp->target,
4305 "sync msgout", np->msgout);
4306 }
4307
4308 cp->nego_status = NS_SYNC;
4309 OUTB(np, HS_PRT, HS_NEGOTIATE);
4310 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4311 return;
4312 } else
4313 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4314 }
4315
4316 return;
4317
4318reject_it:
4319 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4320}
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333static void sym_nego_default(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4334{
4335 switch (cp->nego_status) {
4336 case NS_PPR:
4337#if 0
4338 sym_setpprot (np, cp->target, 0, 0, 0, 0, 0, 0);
4339#else
4340 if (tp->tgoal.period < np->minsync)
4341 tp->tgoal.period = np->minsync;
4342 if (tp->tgoal.offset > np->maxoffs)
4343 tp->tgoal.offset = np->maxoffs;
4344 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
4345 tp->tgoal.check_nego = 1;
4346#endif
4347 break;
4348 case NS_SYNC:
4349 sym_setsync (np, cp->target, 0, 0, 0, 0);
4350 break;
4351 case NS_WIDE:
4352 sym_setwide (np, cp->target, 0);
4353 break;
4354 }
4355 np->msgin [0] = M_NOOP;
4356 np->msgout[0] = M_NOOP;
4357 cp->nego_status = 0;
4358}
4359
4360
4361
4362
4363
4364static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
4365{
4366 sym_nego_default(np, tp, cp);
4367 OUTB(np, HS_PRT, HS_BUSY);
4368}
4369
4370
4371
4372
4373static void sym_int_sir(struct sym_hcb *np)
4374{
4375 u_char num = INB(np, nc_dsps);
4376 u32 dsa = INL(np, nc_dsa);
4377 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
4378 u_char target = INB(np, nc_sdid) & 0x0f;
4379 struct sym_tcb *tp = &np->target[target];
4380 int tmp;
4381
4382 if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
4383
4384 switch (num) {
4385#if SYM_CONF_DMA_ADDRESSING_MODE == 2
4386
4387
4388
4389
4390 case SIR_DMAP_DIRTY:
4391 sym_update_dmap_regs(np);
4392 goto out;
4393#endif
4394
4395
4396
4397
4398 case SIR_COMPLETE_ERROR:
4399 sym_complete_error(np, cp);
4400 return;
4401
4402
4403
4404
4405 case SIR_SCRIPT_STOPPED:
4406 case SIR_TARGET_SELECTED:
4407 case SIR_ABORT_SENT:
4408 sym_sir_task_recovery(np, num);
4409 return;
4410
4411
4412
4413
4414 case SIR_SEL_ATN_NO_MSG_OUT:
4415 scmd_printk(KERN_WARNING, cp->cmd,
4416 "No MSG OUT phase after selection with ATN\n");
4417 goto out_stuck;
4418
4419
4420
4421
4422 case SIR_RESEL_NO_MSG_IN:
4423 scmd_printk(KERN_WARNING, cp->cmd,
4424 "No MSG IN phase after reselection\n");
4425 goto out_stuck;
4426
4427
4428
4429
4430 case SIR_RESEL_NO_IDENTIFY:
4431 scmd_printk(KERN_WARNING, cp->cmd,
4432 "No IDENTIFY after reselection\n");
4433 goto out_stuck;
4434
4435
4436
4437 case SIR_RESEL_BAD_LUN:
4438 np->msgout[0] = M_RESET;
4439 goto out;
4440
4441
4442
4443
4444 case SIR_RESEL_BAD_I_T_L:
4445 np->msgout[0] = M_ABORT;
4446 goto out;
4447
4448
4449
4450 case SIR_RESEL_BAD_I_T_L_Q:
4451 np->msgout[0] = M_ABORT_TAG;
4452 goto out;
4453
4454
4455
4456
4457 case SIR_RESEL_ABORTED:
4458 np->lastmsg = np->msgout[0];
4459 np->msgout[0] = M_NOOP;
4460 scmd_printk(KERN_WARNING, cp->cmd,
4461 "message %x sent on bad reselection\n", np->lastmsg);
4462 goto out;
4463
4464
4465
4466
4467 case SIR_MSG_OUT_DONE:
4468 np->lastmsg = np->msgout[0];
4469 np->msgout[0] = M_NOOP;
4470
4471 if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) {
4472 if (cp) {
4473 cp->xerr_status &= ~XE_PARITY_ERR;
4474 if (!cp->xerr_status)
4475 OUTOFFB(np, HF_PRT, HF_EXT_ERR);
4476 }
4477 }
4478 goto out;
4479
4480
4481
4482
4483
4484 case SIR_BAD_SCSI_STATUS:
4485 if (!cp)
4486 goto out;
4487 sym_sir_bad_scsi_status(np, num, cp);
4488 return;
4489
4490
4491
4492
4493 case SIR_REJECT_TO_SEND:
4494 sym_print_msg(cp, "M_REJECT to send for ", np->msgin);
4495 np->msgout[0] = M_REJECT;
4496 goto out;
4497
4498
4499
4500
4501
4502
4503 case SIR_SWIDE_OVERRUN:
4504 if (cp) {
4505 OUTONB(np, HF_PRT, HF_EXT_ERR);
4506 cp->xerr_status |= XE_SWIDE_OVRUN;
4507 }
4508 goto out;
4509
4510
4511
4512
4513
4514 case SIR_SODL_UNDERRUN:
4515 if (cp) {
4516 OUTONB(np, HF_PRT, HF_EXT_ERR);
4517 cp->xerr_status |= XE_SODL_UNRUN;
4518 }
4519 goto out;
4520
4521
4522
4523
4524
4525
4526 case SIR_DATA_OVERRUN:
4527 if (cp) {
4528 OUTONB(np, HF_PRT, HF_EXT_ERR);
4529 cp->xerr_status |= XE_EXTRA_DATA;
4530 cp->extra_bytes += INL(np, nc_scratcha);
4531 }
4532 goto out;
4533
4534
4535
4536 case SIR_BAD_PHASE:
4537 if (cp) {
4538 OUTONB(np, HF_PRT, HF_EXT_ERR);
4539 cp->xerr_status |= XE_BAD_PHASE;
4540 }
4541 goto out;
4542
4543
4544
4545 case SIR_MSG_RECEIVED:
4546 if (!cp)
4547 goto out_stuck;
4548 switch (np->msgin [0]) {
4549
4550
4551
4552
4553
4554 case M_EXTENDED:
4555 switch (np->msgin [2]) {
4556 case M_X_MODIFY_DP:
4557 if (DEBUG_FLAGS & DEBUG_POINTER)
4558 sym_print_msg(cp, "extended msg ",
4559 np->msgin);
4560 tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
4561 (np->msgin[5]<<8) + (np->msgin[6]);
4562 sym_modify_dp(np, tp, cp, tmp);
4563 return;
4564 case M_X_SYNC_REQ:
4565 sym_sync_nego(np, tp, cp);
4566 return;
4567 case M_X_PPR_REQ:
4568 sym_ppr_nego(np, tp, cp);
4569 return;
4570 case M_X_WIDE_REQ:
4571 sym_wide_nego(np, tp, cp);
4572 return;
4573 default:
4574 goto out_reject;
4575 }
4576 break;
4577
4578
4579
4580
4581
4582
4583
4584 case M_IGN_RESIDUE:
4585 if (DEBUG_FLAGS & DEBUG_POINTER)
4586 sym_print_msg(cp, "1 or 2 byte ", np->msgin);
4587 if (cp->host_flags & HF_SENSE)
4588 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4589 else
4590 sym_modify_dp(np, tp, cp, -1);
4591 return;
4592 case M_REJECT:
4593 if (INB(np, HS_PRT) == HS_NEGOTIATE)
4594 sym_nego_rejected(np, tp, cp);
4595 else {
4596 sym_print_addr(cp->cmd,
4597 "M_REJECT received (%x:%x).\n",
4598 scr_to_cpu(np->lastmsg), np->msgout[0]);
4599 }
4600 goto out_clrack;
4601 break;
4602 default:
4603 goto out_reject;
4604 }
4605 break;
4606
4607
4608
4609
4610 case SIR_MSG_WEIRD:
4611 sym_print_msg(cp, "WEIRD message received", np->msgin);
4612 OUTL_DSP(np, SCRIPTB_BA(np, msg_weird));
4613 return;
4614
4615
4616
4617
4618
4619 case SIR_NEGO_FAILED:
4620 OUTB(np, HS_PRT, HS_BUSY);
4621
4622
4623
4624
4625 case SIR_NEGO_PROTO:
4626 sym_nego_default(np, tp, cp);
4627 goto out;
4628 }
4629
4630out:
4631 OUTONB_STD();
4632 return;
4633out_reject:
4634 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4635 return;
4636out_clrack:
4637 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4638 return;
4639out_stuck:
4640 return;
4641}
4642
4643
4644
4645
4646struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order)
4647{
4648 u_char tn = cmd->device->id;
4649 u_char ln = cmd->device->lun;
4650 struct sym_tcb *tp = &np->target[tn];
4651 struct sym_lcb *lp = sym_lp(tp, ln);
4652 u_short tag = NO_TAG;
4653 SYM_QUEHEAD *qp;
4654 struct sym_ccb *cp = NULL;
4655
4656
4657
4658
4659 if (sym_que_empty(&np->free_ccbq))
4660 sym_alloc_ccb(np);
4661 qp = sym_remque_head(&np->free_ccbq);
4662 if (!qp)
4663 goto out;
4664 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
4665
4666 {
4667
4668
4669
4670 if (tag_order) {
4671
4672
4673
4674#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4675 if (lp->busy_itl != 0)
4676 goto out_free;
4677#endif
4678
4679
4680
4681 if (!lp->cb_tags) {
4682 sym_alloc_lcb_tags(np, tn, ln);
4683 if (!lp->cb_tags)
4684 goto out_free;
4685 }
4686
4687
4688
4689
4690
4691
4692 if (lp->busy_itlq < SYM_CONF_MAX_TASK) {
4693 tag = lp->cb_tags[lp->ia_tag];
4694 if (++lp->ia_tag == SYM_CONF_MAX_TASK)
4695 lp->ia_tag = 0;
4696 ++lp->busy_itlq;
4697#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4698 lp->itlq_tbl[tag] = cpu_to_scr(cp->ccb_ba);
4699 lp->head.resel_sa =
4700 cpu_to_scr(SCRIPTA_BA(np, resel_tag));
4701#endif
4702#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
4703 cp->tags_si = lp->tags_si;
4704 ++lp->tags_sum[cp->tags_si];
4705 ++lp->tags_since;
4706#endif
4707 }
4708 else
4709 goto out_free;
4710 }
4711
4712
4713
4714
4715
4716 else {
4717
4718
4719
4720#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4721 if (lp->busy_itl != 0 || lp->busy_itlq != 0)
4722 goto out_free;
4723#endif
4724
4725
4726
4727
4728
4729 ++lp->busy_itl;
4730#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
4731 if (lp->busy_itl == 1) {
4732 lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
4733 lp->head.resel_sa =
4734 cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
4735 }
4736 else
4737 goto out_free;
4738#endif
4739 }
4740 }
4741
4742
4743
4744 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
4745#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4746 if (lp) {
4747 sym_remque(&cp->link2_ccbq);
4748 sym_insque_tail(&cp->link2_ccbq, &lp->waiting_ccbq);
4749 }
4750
4751#endif
4752 cp->to_abort = 0;
4753 cp->odd_byte_adjustment = 0;
4754 cp->tag = tag;
4755 cp->order = tag_order;
4756 cp->target = tn;
4757 cp->lun = ln;
4758
4759 if (DEBUG_FLAGS & DEBUG_TAGS) {
4760 sym_print_addr(cmd, "ccb @%p using tag %d.\n", cp, tag);
4761 }
4762
4763out:
4764 return cp;
4765out_free:
4766 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4767 return NULL;
4768}
4769
4770
4771
4772
4773void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
4774{
4775 struct sym_tcb *tp = &np->target[cp->target];
4776 struct sym_lcb *lp = sym_lp(tp, cp->lun);
4777
4778 if (DEBUG_FLAGS & DEBUG_TAGS) {
4779 sym_print_addr(cp->cmd, "ccb @%p freeing tag %d.\n",
4780 cp, cp->tag);
4781 }
4782
4783
4784
4785
4786 if (lp) {
4787
4788
4789
4790 if (cp->tag != NO_TAG) {
4791#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
4792 --lp->tags_sum[cp->tags_si];
4793#endif
4794
4795
4796
4797 lp->cb_tags[lp->if_tag] = cp->tag;
4798 if (++lp->if_tag == SYM_CONF_MAX_TASK)
4799 lp->if_tag = 0;
4800
4801
4802
4803
4804 lp->itlq_tbl[cp->tag] = cpu_to_scr(np->bad_itlq_ba);
4805 --lp->busy_itlq;
4806 } else {
4807
4808
4809
4810
4811 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
4812 --lp->busy_itl;
4813 }
4814
4815
4816
4817 if (lp->busy_itlq == 0 && lp->busy_itl == 0)
4818 lp->head.resel_sa =
4819 cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
4820 }
4821
4822
4823
4824
4825
4826
4827 if (cp == tp->nego_cp)
4828 tp->nego_cp = NULL;
4829
4830#ifdef SYM_CONF_IARB_SUPPORT
4831
4832
4833
4834
4835 if (cp == np->last_cp)
4836 np->last_cp = 0;
4837#endif
4838
4839
4840
4841
4842 cp->cmd = NULL;
4843 cp->host_status = HS_IDLE;
4844 sym_remque(&cp->link_ccbq);
4845 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4846
4847#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4848 if (lp) {
4849 sym_remque(&cp->link2_ccbq);
4850 sym_insque_tail(&cp->link2_ccbq, &np->dummy_ccbq);
4851 if (cp->started) {
4852 if (cp->tag != NO_TAG)
4853 --lp->started_tags;
4854 else
4855 --lp->started_no_tag;
4856 }
4857 }
4858 cp->started = 0;
4859#endif
4860}
4861
4862
4863
4864
4865static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np)
4866{
4867 struct sym_ccb *cp = NULL;
4868 int hcode;
4869
4870
4871
4872
4873
4874 if (np->actccbs >= SYM_CONF_MAX_START)
4875 return NULL;
4876
4877
4878
4879
4880 cp = sym_calloc_dma(sizeof(struct sym_ccb), "CCB");
4881 if (!cp)
4882 goto out_free;
4883
4884
4885
4886
4887 np->actccbs++;
4888
4889
4890
4891
4892 cp->ccb_ba = vtobus(cp);
4893
4894
4895
4896
4897 hcode = CCB_HASH_CODE(cp->ccb_ba);
4898 cp->link_ccbh = np->ccbh[hcode];
4899 np->ccbh[hcode] = cp;
4900
4901
4902
4903
4904 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, idle));
4905 cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
4906
4907
4908
4909
4910 cp->phys.smsg_ext.addr = cpu_to_scr(HCB_BA(np, msgin[2]));
4911
4912
4913
4914
4915 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4916
4917
4918
4919
4920#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
4921 sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq);
4922#endif
4923 return cp;
4924out_free:
4925 if (cp)
4926 sym_mfree_dma(cp, sizeof(*cp), "CCB");
4927 return NULL;
4928}
4929
4930
4931
4932
4933static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
4934{
4935 int hcode;
4936 struct sym_ccb *cp;
4937
4938 hcode = CCB_HASH_CODE(dsa);
4939 cp = np->ccbh[hcode];
4940 while (cp) {
4941 if (cp->ccb_ba == dsa)
4942 break;
4943 cp = cp->link_ccbh;
4944 }
4945
4946 return cp;
4947}
4948
4949
4950
4951
4952
4953static void sym_init_tcb (struct sym_hcb *np, u_char tn)
4954{
4955#if 0
4956
4957
4958
4959 assert (((offsetof(struct sym_reg, nc_sxfer) ^
4960 offsetof(struct sym_tcb, head.sval)) &3) == 0);
4961 assert (((offsetof(struct sym_reg, nc_scntl3) ^
4962 offsetof(struct sym_tcb, head.wval)) &3) == 0);
4963#endif
4964}
4965
4966
4967
4968
4969struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
4970{
4971 struct sym_tcb *tp = &np->target[tn];
4972 struct sym_lcb *lp = NULL;
4973
4974
4975
4976
4977 sym_init_tcb (np, tn);
4978
4979
4980
4981
4982
4983 if (ln && !tp->luntbl) {
4984 int i;
4985
4986 tp->luntbl = sym_calloc_dma(256, "LUNTBL");
4987 if (!tp->luntbl)
4988 goto fail;
4989 for (i = 0 ; i < 64 ; i++)
4990 tp->luntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa));
4991 tp->head.luntbl_sa = cpu_to_scr(vtobus(tp->luntbl));
4992 }
4993
4994
4995
4996
4997 if (ln && !tp->lunmp) {
4998 tp->lunmp = kcalloc(SYM_CONF_MAX_LUN, sizeof(struct sym_lcb *),
4999 GFP_ATOMIC);
5000 if (!tp->lunmp)
5001 goto fail;
5002 }
5003
5004
5005
5006
5007
5008 lp = sym_calloc_dma(sizeof(struct sym_lcb), "LCB");
5009 if (!lp)
5010 goto fail;
5011 if (ln) {
5012 tp->lunmp[ln] = lp;
5013 tp->luntbl[ln] = cpu_to_scr(vtobus(lp));
5014 }
5015 else {
5016 tp->lun0p = lp;
5017 tp->head.lun0_sa = cpu_to_scr(vtobus(lp));
5018 }
5019 tp->nlcb++;
5020
5021
5022
5023
5024 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
5025
5026
5027
5028
5029 lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5030
5031
5032
5033
5034 lp->user_flags = tp->usrflags & (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
5035
5036#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5037
5038
5039
5040 sym_que_init(&lp->waiting_ccbq);
5041 sym_que_init(&lp->started_ccbq);
5042 lp->started_max = SYM_CONF_MAX_TASK;
5043 lp->started_limit = SYM_CONF_MAX_TASK;
5044#endif
5045
5046fail:
5047 return lp;
5048}
5049
5050
5051
5052
5053static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
5054{
5055 struct sym_tcb *tp = &np->target[tn];
5056 struct sym_lcb *lp = sym_lp(tp, ln);
5057 int i;
5058
5059
5060
5061
5062
5063 lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5064 if (!lp->itlq_tbl)
5065 goto fail;
5066 lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
5067 if (!lp->cb_tags) {
5068 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5069 lp->itlq_tbl = NULL;
5070 goto fail;
5071 }
5072
5073
5074
5075
5076 for (i = 0 ; i < SYM_CONF_MAX_TASK ; i++)
5077 lp->itlq_tbl[i] = cpu_to_scr(np->notask_ba);
5078
5079
5080
5081
5082 for (i = 0 ; i < SYM_CONF_MAX_TASK ; i++)
5083 lp->cb_tags[i] = i;
5084
5085
5086
5087
5088
5089 lp->head.itlq_tbl_sa = cpu_to_scr(vtobus(lp->itlq_tbl));
5090
5091 return;
5092fail:
5093 return;
5094}
5095
5096
5097
5098
5099
5100int sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln)
5101{
5102 struct sym_tcb *tp = &np->target[tn];
5103 struct sym_lcb *lp = sym_lp(tp, ln);
5104
5105 tp->nlcb--;
5106
5107 if (ln) {
5108 if (!tp->nlcb) {
5109 kfree(tp->lunmp);
5110 sym_mfree_dma(tp->luntbl, 256, "LUNTBL");
5111 tp->lunmp = NULL;
5112 tp->luntbl = NULL;
5113 tp->head.luntbl_sa = cpu_to_scr(vtobus(np->badluntbl));
5114 } else {
5115 tp->luntbl[ln] = cpu_to_scr(vtobus(&np->badlun_sa));
5116 tp->lunmp[ln] = NULL;
5117 }
5118 } else {
5119 tp->lun0p = NULL;
5120 tp->head.lun0_sa = cpu_to_scr(vtobus(&np->badlun_sa));
5121 }
5122
5123 if (lp->itlq_tbl) {
5124 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
5125 kfree(lp->cb_tags);
5126 }
5127
5128 sym_mfree_dma(lp, sizeof(*lp), "LCB");
5129
5130 return tp->nlcb;
5131}
5132
5133
5134
5135
5136int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
5137{
5138 struct scsi_device *sdev = cmd->device;
5139 struct sym_tcb *tp;
5140 struct sym_lcb *lp;
5141 u_char *msgptr;
5142 u_int msglen;
5143 int can_disconnect;
5144
5145
5146
5147
5148 cp->cmd = cmd;
5149
5150
5151
5152
5153 tp = &np->target[cp->target];
5154
5155
5156
5157
5158 lp = sym_lp(tp, sdev->lun);
5159
5160 can_disconnect = (cp->tag != NO_TAG) ||
5161 (lp && (lp->curr_flags & SYM_DISC_ENABLED));
5162
5163 msgptr = cp->scsi_smsg;
5164 msglen = 0;
5165 msgptr[msglen++] = IDENTIFY(can_disconnect, sdev->lun);
5166
5167
5168
5169
5170 if (cp->tag != NO_TAG) {
5171 u_char order = cp->order;
5172
5173 switch(order) {
5174 case M_ORDERED_TAG:
5175 break;
5176 case M_HEAD_TAG:
5177 break;
5178 default:
5179 order = M_SIMPLE_TAG;
5180 }
5181#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
5182
5183
5184
5185
5186
5187
5188 if (lp && lp->tags_since > 3*SYM_CONF_MAX_TAG) {
5189 lp->tags_si = !(lp->tags_si);
5190 if (lp->tags_sum[lp->tags_si]) {
5191 order = M_ORDERED_TAG;
5192 if ((DEBUG_FLAGS & DEBUG_TAGS)||sym_verbose>1) {
5193 sym_print_addr(cmd,
5194 "ordered tag forced.\n");
5195 }
5196 }
5197 lp->tags_since = 0;
5198 }
5199#endif
5200 msgptr[msglen++] = order;
5201
5202
5203
5204
5205
5206
5207
5208
5209#if SYM_CONF_MAX_TASK > (512/4)
5210 msgptr[msglen++] = cp->tag;
5211#else
5212 msgptr[msglen++] = (cp->tag << 1) + 1;
5213#endif
5214 }
5215
5216
5217
5218
5219
5220
5221
5222
5223 cp->nego_status = 0;
5224 if ((tp->tgoal.check_nego ||
5225 cmd->cmnd[0] == INQUIRY || cmd->cmnd[0] == REQUEST_SENSE) &&
5226 !tp->nego_cp && lp) {
5227 msglen += sym_prepare_nego(np, cp, msgptr + msglen);
5228 }
5229
5230
5231
5232
5233 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
5234 cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA(np, resel_dsa));
5235
5236
5237
5238
5239 cp->phys.select.sel_id = cp->target;
5240 cp->phys.select.sel_scntl3 = tp->head.wval;
5241 cp->phys.select.sel_sxfer = tp->head.sval;
5242 cp->phys.select.sel_scntl4 = tp->head.uval;
5243
5244
5245
5246
5247 cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg);
5248 cp->phys.smsg.size = cpu_to_scr(msglen);
5249
5250
5251
5252
5253 cp->host_xflags = 0;
5254 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
5255 cp->ssss_status = S_ILLEGAL;
5256 cp->xerr_status = 0;
5257 cp->host_flags = 0;
5258 cp->extra_bytes = 0;
5259
5260
5261
5262
5263
5264 cp->ext_sg = -1;
5265 cp->ext_ofs = 0;
5266
5267
5268
5269
5270
5271 return sym_setup_data_and_start(np, cmd, cp);
5272}
5273
5274
5275
5276
5277int sym_reset_scsi_target(struct sym_hcb *np, int target)
5278{
5279 struct sym_tcb *tp;
5280
5281 if (target == np->myaddr || (u_int)target >= SYM_CONF_MAX_TARGET)
5282 return -1;
5283
5284 tp = &np->target[target];
5285 tp->to_reset = 1;
5286
5287 np->istat_sem = SEM;
5288 OUTB(np, nc_istat, SIGP|SEM);
5289
5290 return 0;
5291}
5292
5293
5294
5295
5296static int sym_abort_ccb(struct sym_hcb *np, struct sym_ccb *cp, int timed_out)
5297{
5298
5299
5300
5301 if (!cp || !cp->host_status || cp->host_status == HS_WAIT)
5302 return -1;
5303
5304
5305
5306
5307
5308 if (cp->to_abort) {
5309 sym_reset_scsi_bus(np, 1);
5310 return 0;
5311 }
5312
5313
5314
5315
5316 cp->to_abort = timed_out ? 2 : 1;
5317
5318
5319
5320
5321 np->istat_sem = SEM;
5322 OUTB(np, nc_istat, SIGP|SEM);
5323 return 0;
5324}
5325
5326int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out)
5327{
5328 struct sym_ccb *cp;
5329 SYM_QUEHEAD *qp;
5330
5331
5332
5333
5334 cp = NULL;
5335 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
5336 struct sym_ccb *cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq);
5337 if (cp2->cmd == cmd) {
5338 cp = cp2;
5339 break;
5340 }
5341 }
5342
5343 return sym_abort_ccb(np, cp, timed_out);
5344}
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356void sym_complete_error(struct sym_hcb *np, struct sym_ccb *cp)
5357{
5358 struct scsi_device *sdev;
5359 struct scsi_cmnd *cmd;
5360 struct sym_tcb *tp;
5361 struct sym_lcb *lp;
5362 int resid;
5363 int i;
5364
5365
5366
5367
5368 if (!cp || !cp->cmd)
5369 return;
5370
5371 cmd = cp->cmd;
5372 sdev = cmd->device;
5373 if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_RESULT)) {
5374 dev_info(&sdev->sdev_gendev, "CCB=%p STAT=%x/%x/%x\n", cp,
5375 cp->host_status, cp->ssss_status, cp->host_flags);
5376 }
5377
5378
5379
5380
5381 tp = &np->target[cp->target];
5382 lp = sym_lp(tp, sdev->lun);
5383
5384
5385
5386
5387 if (cp->xerr_status) {
5388 if (sym_verbose)
5389 sym_print_xerr(cmd, cp->xerr_status);
5390 if (cp->host_status == HS_COMPLETE)
5391 cp->host_status = HS_COMP_ERR;
5392 }
5393
5394
5395
5396
5397 resid = sym_compute_residual(np, cp);
5398
5399 if (!SYM_SETUP_RESIDUAL_SUPPORT) {
5400 resid = 0;
5401 cp->sv_resid = 0;
5402 }
5403#ifdef DEBUG_2_0_X
5404if (resid)
5405 printf("XXXX RESID= %d - 0x%x\n", resid, resid);
5406#endif
5407
5408
5409
5410
5411
5412 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
5413 i = sym_dequeue_from_squeue(np, i, cp->target, sdev->lun, -1);
5414
5415
5416
5417
5418 OUTL_DSP(np, SCRIPTA_BA(np, start));
5419
5420#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5421 if (cp->host_status == HS_COMPLETE &&
5422 cp->ssss_status == S_QUEUE_FULL) {
5423 if (!lp || lp->started_tags - i < 2)
5424 goto weirdness;
5425
5426
5427
5428 lp->started_max = lp->started_tags - i - 1;
5429 lp->num_sgood = 0;
5430
5431 if (sym_verbose >= 2) {
5432 sym_print_addr(cmd, " queue depth is now %d\n",
5433 lp->started_max);
5434 }
5435
5436
5437
5438
5439 cp->host_status = HS_BUSY;
5440 cp->ssss_status = S_ILLEGAL;
5441
5442
5443
5444
5445 sym_set_cam_status(cmd, DID_SOFT_ERROR);
5446 goto finish;
5447 }
5448weirdness:
5449#endif
5450
5451
5452
5453 sym_set_cam_result_error(np, cp, resid);
5454
5455#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5456finish:
5457#endif
5458
5459
5460
5461 sym_remque(&cp->link_ccbq);
5462 sym_insque_head(&cp->link_ccbq, &np->comp_ccbq);
5463
5464
5465
5466
5467
5468 sym_flush_comp_queue(np, 0);
5469
5470#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5471
5472
5473
5474 sym_start_next_ccbs(np, lp, 1);
5475#endif
5476}
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
5488{
5489 struct sym_tcb *tp;
5490 struct sym_lcb *lp;
5491 struct scsi_cmnd *cmd;
5492 int resid;
5493
5494
5495
5496
5497 if (!cp || !cp->cmd)
5498 return;
5499 assert (cp->host_status == HS_COMPLETE);
5500
5501
5502
5503
5504 cmd = cp->cmd;
5505
5506
5507
5508
5509 tp = &np->target[cp->target];
5510 lp = sym_lp(tp, cp->lun);
5511
5512
5513
5514
5515
5516 resid = 0;
5517 if (cp->phys.head.lastp != cp->goalp)
5518 resid = sym_compute_residual(np, cp);
5519
5520
5521
5522
5523
5524
5525 if (!SYM_SETUP_RESIDUAL_SUPPORT)
5526 resid = 0;
5527#ifdef DEBUG_2_0_X
5528if (resid)
5529 printf("XXXX RESID= %d - 0x%x\n", resid, resid);
5530#endif
5531
5532
5533
5534
5535 sym_set_cam_result_ok(cp, cmd, resid);
5536
5537#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5538
5539
5540
5541
5542 if (lp && lp->started_max < lp->started_limit) {
5543 ++lp->num_sgood;
5544 if (lp->num_sgood >= 200) {
5545 lp->num_sgood = 0;
5546 ++lp->started_max;
5547 if (sym_verbose >= 2) {
5548 sym_print_addr(cmd, " queue depth is now %d\n",
5549 lp->started_max);
5550 }
5551 }
5552 }
5553#endif
5554
5555
5556
5557
5558 sym_free_ccb (np, cp);
5559
5560#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5561
5562
5563
5564 if (!sym_que_empty(&lp->waiting_ccbq))
5565 sym_start_next_ccbs(np, lp, 2);
5566#endif
5567
5568
5569
5570 sym_xpt_done(np, cmd);
5571}
5572
5573
5574
5575
5576int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram)
5577{
5578 struct sym_hcb *np = sym_get_hcb(shost);
5579 int i;
5580
5581
5582
5583
5584 np->scripta_sz = fw->a_size;
5585 np->scriptb_sz = fw->b_size;
5586 np->scriptz_sz = fw->z_size;
5587 np->fw_setup = fw->setup;
5588 np->fw_patch = fw->patch;
5589 np->fw_name = fw->name;
5590
5591
5592
5593
5594
5595 sym_save_initial_setting (np);
5596
5597
5598
5599
5600
5601
5602 sym_chip_reset(np);
5603
5604
5605
5606
5607
5608 sym_prepare_setting(shost, np, nvram);
5609
5610
5611
5612
5613
5614
5615 i = sym_getpciclock(np);
5616 if (i > 37000 && !(np->features & FE_66MHZ))
5617 printf("%s: PCI BUS clock seems too high: %u KHz.\n",
5618 sym_name(np), i);
5619
5620
5621
5622
5623 np->squeue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
5624 if (!np->squeue)
5625 goto attach_failed;
5626 np->squeue_ba = vtobus(np->squeue);
5627
5628
5629
5630
5631 np->dqueue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
5632 if (!np->dqueue)
5633 goto attach_failed;
5634 np->dqueue_ba = vtobus(np->dqueue);
5635
5636
5637
5638
5639 np->targtbl = sym_calloc_dma(256, "TARGTBL");
5640 if (!np->targtbl)
5641 goto attach_failed;
5642 np->targtbl_ba = vtobus(np->targtbl);
5643
5644
5645
5646
5647 np->scripta0 = sym_calloc_dma(np->scripta_sz, "SCRIPTA0");
5648 np->scriptb0 = sym_calloc_dma(np->scriptb_sz, "SCRIPTB0");
5649 np->scriptz0 = sym_calloc_dma(np->scriptz_sz, "SCRIPTZ0");
5650 if (!np->scripta0 || !np->scriptb0 || !np->scriptz0)
5651 goto attach_failed;
5652
5653
5654
5655
5656 np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(struct sym_ccb **), GFP_KERNEL);
5657 if (!np->ccbh)
5658 goto attach_failed;
5659
5660
5661
5662
5663 sym_que_init(&np->free_ccbq);
5664 sym_que_init(&np->busy_ccbq);
5665 sym_que_init(&np->comp_ccbq);
5666
5667
5668
5669
5670
5671#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5672 sym_que_init(&np->dummy_ccbq);
5673#endif
5674
5675
5676
5677 if (!sym_alloc_ccb(np))
5678 goto attach_failed;
5679
5680
5681
5682
5683
5684 np->scripta_ba = vtobus(np->scripta0);
5685 np->scriptb_ba = vtobus(np->scriptb0);
5686 np->scriptz_ba = vtobus(np->scriptz0);
5687
5688 if (np->ram_ba) {
5689 np->scripta_ba = np->ram_ba;
5690 if (np->features & FE_RAM8K) {
5691 np->scriptb_ba = np->scripta_ba + 4096;
5692#if 0
5693 np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32);
5694#endif
5695 }
5696 }
5697
5698
5699
5700
5701 memcpy(np->scripta0, fw->a_base, np->scripta_sz);
5702 memcpy(np->scriptb0, fw->b_base, np->scriptb_sz);
5703 memcpy(np->scriptz0, fw->z_base, np->scriptz_sz);
5704
5705
5706
5707
5708
5709 np->fw_setup(np, fw);
5710
5711
5712
5713
5714
5715 sym_fw_bind_script(np, (u32 *) np->scripta0, np->scripta_sz);
5716 sym_fw_bind_script(np, (u32 *) np->scriptb0, np->scriptb_sz);
5717 sym_fw_bind_script(np, (u32 *) np->scriptz0, np->scriptz_sz);
5718
5719#ifdef SYM_CONF_IARB_SUPPORT
5720
5721
5722
5723
5724
5725
5726#ifdef SYM_SETUP_IARB_MAX
5727 np->iarb_max = SYM_SETUP_IARB_MAX;
5728#else
5729 np->iarb_max = 4;
5730#endif
5731#endif
5732
5733
5734
5735
5736 np->idletask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5737 np->idletask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5738 np->idletask_ba = vtobus(&np->idletask);
5739
5740 np->notask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5741 np->notask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5742 np->notask_ba = vtobus(&np->notask);
5743
5744 np->bad_itl.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5745 np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
5746 np->bad_itl_ba = vtobus(&np->bad_itl);
5747
5748 np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA(np, idle));
5749 np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA(np,bad_i_t_l_q));
5750 np->bad_itlq_ba = vtobus(&np->bad_itlq);
5751
5752
5753
5754
5755
5756
5757
5758 np->badluntbl = sym_calloc_dma(256, "BADLUNTBL");
5759 if (!np->badluntbl)
5760 goto attach_failed;
5761
5762 np->badlun_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5763 for (i = 0 ; i < 64 ; i++)
5764 np->badluntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa));
5765
5766
5767
5768
5769
5770
5771 for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
5772 np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
5773 np->target[i].head.luntbl_sa =
5774 cpu_to_scr(vtobus(np->badluntbl));
5775 np->target[i].head.lun0_sa =
5776 cpu_to_scr(vtobus(&np->badlun_sa));
5777 }
5778
5779
5780
5781
5782 if (sym_snooptest (np)) {
5783 printf("%s: CACHE INCORRECTLY CONFIGURED.\n", sym_name(np));
5784 goto attach_failed;
5785 }
5786
5787
5788
5789
5790 return 0;
5791
5792attach_failed:
5793 return -ENXIO;
5794}
5795
5796
5797
5798
5799void sym_hcb_free(struct sym_hcb *np)
5800{
5801 SYM_QUEHEAD *qp;
5802 struct sym_ccb *cp;
5803 struct sym_tcb *tp;
5804 int target;
5805
5806 if (np->scriptz0)
5807 sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
5808 if (np->scriptb0)
5809 sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
5810 if (np->scripta0)
5811 sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
5812 if (np->squeue)
5813 sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
5814 if (np->dqueue)
5815 sym_mfree_dma(np->dqueue, sizeof(u32)*(MAX_QUEUE*2), "DQUEUE");
5816
5817 if (np->actccbs) {
5818 while ((qp = sym_remque_head(&np->free_ccbq)) != NULL) {
5819 cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
5820 sym_mfree_dma(cp, sizeof(*cp), "CCB");
5821 }
5822 }
5823 kfree(np->ccbh);
5824
5825 if (np->badluntbl)
5826 sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
5827
5828 for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
5829 tp = &np->target[target];
5830 if (tp->luntbl)
5831 sym_mfree_dma(tp->luntbl, 256, "LUNTBL");
5832#if SYM_CONF_MAX_LUN > 1
5833 kfree(tp->lunmp);
5834#endif
5835 }
5836 if (np->targtbl)
5837 sym_mfree_dma(np->targtbl, 256, "TARGTBL");
5838}
5839