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