Lines Matching refs:np

41 static void sym_int_ma (struct sym_hcb *np);
43 static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np);
44 static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
45 static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln);
46 static void sym_complete_error (struct sym_hcb *np, struct sym_ccb *cp);
47 static void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp);
48 static int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp);
68 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg) in sym_print_nego_msg() argument
70 struct sym_tcb *tp = &np->target[target]; in sym_print_nego_msg()
120 static void sym_chip_reset (struct sym_hcb *np) in sym_chip_reset() argument
122 OUTB(np, nc_istat, SRST); in sym_chip_reset()
123 INB(np, nc_mbox1); in sym_chip_reset()
125 OUTB(np, nc_istat, 0); in sym_chip_reset()
126 INB(np, nc_mbox1); in sym_chip_reset()
139 static void sym_soft_reset (struct sym_hcb *np) in sym_soft_reset() argument
144 if (!(np->features & FE_ISTAT1) || !(INB(np, nc_istat1) & SCRUN)) in sym_soft_reset()
147 OUTB(np, nc_istat, CABRT); in sym_soft_reset()
149 istat = INB(np, nc_istat); in sym_soft_reset()
151 INW(np, nc_sist); in sym_soft_reset()
154 if (INB(np, nc_dstat) & ABRT) in sym_soft_reset()
159 OUTB(np, nc_istat, 0); in sym_soft_reset()
162 "ISTAT=0x%02x.\n", sym_name(np), istat); in sym_soft_reset()
164 sym_chip_reset(np); in sym_soft_reset()
172 static void sym_start_reset(struct sym_hcb *np) in sym_start_reset() argument
174 sym_reset_scsi_bus(np, 1); in sym_start_reset()
177 int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int) in sym_reset_scsi_bus() argument
182 sym_soft_reset(np); /* Soft reset the chip */ in sym_reset_scsi_bus()
184 OUTW(np, nc_sien, RST); in sym_reset_scsi_bus()
189 OUTB(np, nc_stest3, TE); in sym_reset_scsi_bus()
190 OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM)); in sym_reset_scsi_bus()
191 OUTB(np, nc_scntl1, CRST); in sym_reset_scsi_bus()
192 INB(np, nc_mbox1); in sym_reset_scsi_bus()
203 term = INB(np, nc_sstat0); in sym_reset_scsi_bus()
205 term |= ((INB(np, nc_sstat2) & 0x01) << 26) | /* sdp1 */ in sym_reset_scsi_bus()
206 ((INW(np, nc_sbdl) & 0xff) << 9) | /* d7-0 */ in sym_reset_scsi_bus()
207 ((INW(np, nc_sbdl) & 0xff00) << 10) | /* d15-8 */ in sym_reset_scsi_bus()
208 INB(np, nc_sbcl); /* req ack bsy sel atn msg cd io */ in sym_reset_scsi_bus()
210 if (!np->maxwide) in sym_reset_scsi_bus()
215 sym_name(np)); in sym_reset_scsi_bus()
218 sym_name(np), in sym_reset_scsi_bus()
219 (np->features & FE_WIDE) ? "dp1,d15-8," : "", in sym_reset_scsi_bus()
225 OUTB(np, nc_scntl1, 0); in sym_reset_scsi_bus()
232 static void sym_selectclock(struct sym_hcb *np, u_char scntl3) in sym_selectclock() argument
237 if (np->multiplier <= 1) { in sym_selectclock()
238 OUTB(np, nc_scntl3, scntl3); in sym_selectclock()
243 printf ("%s: enabling clock multiplier\n", sym_name(np)); in sym_selectclock()
245 OUTB(np, nc_stest1, DBLEN); /* Enable clock multiplier */ in sym_selectclock()
250 if (np->features & FE_LCKFRQ) { in sym_selectclock()
252 while (!(INB(np, nc_stest4) & LCKFRQ) && --i > 0) in sym_selectclock()
256 sym_name(np)); in sym_selectclock()
258 INB(np, nc_mbox1); in sym_selectclock()
261 OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */ in sym_selectclock()
262 OUTB(np, nc_scntl3, scntl3); in sym_selectclock()
263 OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */ in sym_selectclock()
264 OUTB(np, nc_stest3, 0x00); /* Restart scsi clock */ in sym_selectclock()
289 static unsigned getfreq (struct sym_hcb *np, int gen) in getfreq() argument
309 OUTW(np, nc_sien, 0); /* mask all scsi interrupts */ in getfreq()
310 INW(np, nc_sist); /* clear pending scsi interrupt */ in getfreq()
311 OUTB(np, nc_dien, 0); /* mask all dma interrupts */ in getfreq()
312 INW(np, nc_sist); /* another one, just to be sure :) */ in getfreq()
318 if (np->features & FE_C10) { in getfreq()
319 OUTW(np, nc_sien, GEN); in getfreq()
320 OUTB(np, nc_istat1, SIRQD); in getfreq()
322 OUTB(np, nc_scntl3, 4); /* set pre-scaler to divide by 3 */ in getfreq()
323 OUTB(np, nc_stime1, 0); /* disable general purpose timer */ in getfreq()
324 OUTB(np, nc_stime1, gen); /* set to nominal delay of 1<<gen * 125us */ in getfreq()
325 while (!(INW(np, nc_sist) & GEN) && ms++ < 100000) in getfreq()
327 OUTB(np, nc_stime1, 0); /* disable general purpose timer */ in getfreq()
331 if (np->features & FE_C10) { in getfreq()
332 OUTW(np, nc_sien, 0); in getfreq()
333 OUTB(np, nc_istat1, 0); in getfreq()
340 OUTB(np, nc_scntl3, 0); in getfreq()
351 if (np->features & FE_C10) in getfreq()
356 sym_name(np), gen, ms/4, f); in getfreq()
361 static unsigned sym_getfreq (struct sym_hcb *np) in sym_getfreq() argument
366 getfreq (np, gen); /* throw away first result */ in sym_getfreq()
367 f1 = getfreq (np, gen); in sym_getfreq()
368 f2 = getfreq (np, gen); in sym_getfreq()
376 static void sym_getclock (struct sym_hcb *np, int mult) in sym_getclock() argument
378 unsigned char scntl3 = np->sv_scntl3; in sym_getclock()
379 unsigned char stest1 = np->sv_stest1; in sym_getclock()
382 np->multiplier = 1; in sym_getclock()
389 printf ("%s: clock multiplier found\n", sym_name(np)); in sym_getclock()
390 np->multiplier = mult; in sym_getclock()
398 if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) { in sym_getclock()
399 OUTB(np, nc_stest1, 0); /* make sure doubler is OFF */ in sym_getclock()
400 f1 = sym_getfreq (np); in sym_getclock()
403 printf ("%s: chip clock is %uKHz\n", sym_name(np), f1); in sym_getclock()
412 sym_name(np)); in sym_getclock()
413 np->multiplier = mult; in sym_getclock()
420 f1 /= np->multiplier; in sym_getclock()
426 f1 *= np->multiplier; in sym_getclock()
427 np->clock_khz = f1; in sym_getclock()
433 static int sym_getpciclock (struct sym_hcb *np) argument
442 if (np->features & FE_66MHZ) {
446 OUTB(np, nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */
447 f = sym_getfreq(np);
448 OUTB(np, nc_stest1, 0);
450 np->pciclk_khz = f;
469 sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) argument
471 u32 clk = np->clock_khz; /* SCSI clock frequency in kHz */
472 int div = np->clock_divn; /* Number of divisors supported */
500 if ((np->features & (FE_C10|FE_U3EN)) == FE_C10) {
513 if (div == np->clock_divn) { /* Are we too fast ? */
589 static inline void sym_init_burst(struct sym_hcb *np, u_char bc) argument
591 np->rv_ctest4 &= ~0x80;
592 np->rv_dmode &= ~(0x3 << 6);
593 np->rv_ctest5 &= ~0x4;
596 np->rv_ctest4 |= 0x80;
600 np->rv_dmode |= ((bc & 0x3) << 6);
601 np->rv_ctest5 |= (bc & 0x4);
614 static void sym_save_initial_setting (struct sym_hcb *np) argument
616 np->sv_scntl0 = INB(np, nc_scntl0) & 0x0a;
617 np->sv_scntl3 = INB(np, nc_scntl3) & 0x07;
618 np->sv_dmode = INB(np, nc_dmode) & 0xce;
619 np->sv_dcntl = INB(np, nc_dcntl) & 0xa8;
620 np->sv_ctest3 = INB(np, nc_ctest3) & 0x01;
621 np->sv_ctest4 = INB(np, nc_ctest4) & 0x80;
622 np->sv_gpcntl = INB(np, nc_gpcntl);
623 np->sv_stest1 = INB(np, nc_stest1);
624 np->sv_stest2 = INB(np, nc_stest2) & 0x20;
625 np->sv_stest4 = INB(np, nc_stest4);
626 if (np->features & FE_C10) { /* Always large DMA fifo + ultra3 */
627 np->sv_scntl4 = INB(np, nc_scntl4);
628 np->sv_ctest5 = INB(np, nc_ctest5) & 0x04;
631 np->sv_ctest5 = INB(np, nc_ctest5) & 0x24;
641 static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram) argument
643 if (np->scsi_mode)
646 np->scsi_mode = SMODE_SE;
647 if (np->features & (FE_ULTRA2|FE_ULTRA3))
648 np->scsi_mode = (np->sv_stest4 & SMODE);
649 else if (np->features & FE_DIFF) {
651 if (np->sv_scntl3) {
652 if (np->sv_stest2 & 0x20)
653 np->scsi_mode = SMODE_HVD;
655 if (!(INB(np, nc_gpreg) & 0x08))
656 np->scsi_mode = SMODE_HVD;
659 np->scsi_mode = SMODE_HVD;
661 if (np->scsi_mode == SMODE_HVD)
662 np->rv_stest2 |= 0x20;
669 static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) argument
677 np->maxwide = (np->features & FE_WIDE) ? 1 : 0;
682 if (np->features & (FE_ULTRA3 | FE_ULTRA2))
683 np->clock_khz = 160000;
684 else if (np->features & FE_ULTRA)
685 np->clock_khz = 80000;
687 np->clock_khz = 40000;
692 if (np->features & FE_QUAD)
693 np->multiplier = 4;
694 else if (np->features & FE_DBLR)
695 np->multiplier = 2;
697 np->multiplier = 1;
703 if (np->features & FE_VARCLK)
704 sym_getclock(np, np->multiplier);
709 i = np->clock_divn - 1;
711 if (10ul * SYM_CONF_MIN_ASYNC * np->clock_khz > div_10M[i]) {
716 np->rv_scntl3 = i+1;
722 if (np->features & FE_C10)
723 np->rv_scntl3 = 0;
729 period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
731 if (period <= 250) np->minsync = 10;
732 else if (period <= 303) np->minsync = 11;
733 else if (period <= 500) np->minsync = 12;
734 else np->minsync = (period + 40 - 1) / 40;
739 if (np->minsync < 25 &&
740 !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3)))
741 np->minsync = 25;
742 else if (np->minsync < 12 &&
743 !(np->features & (FE_ULTRA2|FE_ULTRA3)))
744 np->minsync = 12;
749 period = div64_ul(11 * div_10M[np->clock_divn - 1], 4 * np->clock_khz);
750 np->maxsync = period > 2540 ? 254 : period / 10;
755 if ((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) {
756 if (np->clock_khz == 160000) {
757 np->minsync_dt = 9;
758 np->maxsync_dt = 50;
759 np->maxoffs_dt = nvram->type ? 62 : 31;
766 if (np->features & FE_DAC) {
767 if (!use_dac(np))
768 np->rv_ccntl1 |= (DDAC);
770 np->rv_ccntl1 |= (XTIMOD | EXTIBMV);
772 np->rv_ccntl1 |= (0 | EXTIBMV);
778 if (np->features & FE_NOPM)
779 np->rv_ccntl0 |= (ENPMJ);
788 np->rv_ccntl0 |= DILS;
795 burst_max = burst_code(np->sv_dmode, np->sv_ctest4,
796 np->sv_ctest5);
799 if (burst_max > np->maxburst)
800 burst_max = np->maxburst;
814 np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
822 if (np->features & FE_ERL)
823 np->rv_dmode |= ERL; /* Enable Read Line */
824 if (np->features & FE_BOF)
825 np->rv_dmode |= BOF; /* Burst Opcode Fetch */
826 if (np->features & FE_ERMP)
827 np->rv_dmode |= ERMP; /* Enable Read Multiple */
829 if ((np->features & FE_PFEN) && !np->ram_ba)
831 if (np->features & FE_PFEN)
833 np->rv_dcntl |= PFEN; /* Prefetch Enable */
834 if (np->features & FE_CLSE)
835 np->rv_dcntl |= CLSE; /* Cache Line Size Enable */
836 if (np->features & FE_WRIE)
837 np->rv_ctest3 |= WRIE; /* Write and Invalidate */
838 if (np->features & FE_DFS)
839 np->rv_ctest5 |= DFS; /* Dma Fifo Size */
844 np->rv_ctest4 |= MPEE; /* Master parity checking */
845 np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */
850 np->myaddr = 255;
851 np->scsi_mode = 0;
852 sym_nvram_setup_host(shost, np, nvram);
857 if (np->myaddr == 255) {
858 np->myaddr = INB(np, nc_scid) & 0x07;
859 if (!np->myaddr)
860 np->myaddr = SYM_SETUP_HOST_ID;
866 sym_init_burst(np, burst_max);
868 sym_set_bus_mode(np, nvram);
880 !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))
881 np->features |= FE_LED0;
888 np->rv_dcntl |= IRQM;
891 np->rv_dcntl |= (np->sv_dcntl & IRQM);
902 struct sym_tcb *tp = &np->target[i];
906 tp->usr_width = np->maxwide;
918 printf("%s: %s, ID %d, Fast-%d, %s, %s\n", sym_name(np),
919 sym_nvram_type(nvram), np->myaddr,
920 (np->features & FE_ULTRA3) ? 80 :
921 (np->features & FE_ULTRA2) ? 40 :
922 (np->features & FE_ULTRA) ? 20 : 10,
923 sym_scsi_bus_mode(np->scsi_mode),
924 (np->rv_scntl0 & 0xa) ? "parity checking" : "NO parity");
930 sym_name(np),
931 np->rv_dcntl & IRQM ? "totem pole" : "open drain",
932 np->ram_ba ? ", using on-chip SRAM" : "");
933 printf("%s: using %s firmware.\n", sym_name(np), np->fw_name);
934 if (np->features & FE_NOPM)
936 sym_name(np));
944 sym_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl,
945 np->sv_ctest3, np->sv_ctest4, np->sv_ctest5);
949 sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
950 np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
962 static int sym_regtest(struct sym_hcb *np) argument
971 OUTL(np, nc_dstat, data);
972 data = INL(np, nc_dstat);
985 static inline int sym_regtest(struct sym_hcb *np) argument
991 static int sym_snooptest(struct sym_hcb *np) argument
996 err = sym_regtest(np);
1004 OUTB(np, nc_ctest4, (np->rv_ctest4 & MPEE));
1008 pc = SCRIPTZ_BA(np, snooptest);
1014 np->scratch = cpu_to_scr(host_wr);
1015 OUTL(np, nc_temp, sym_wr);
1019 OUTL(np, nc_dsa, np->hcb_ba);
1020 OUTL_DSP(np, pc);
1025 if (INB(np, nc_istat) & (INTF|SIP|DIP))
1034 dstat = INB(np, nc_dstat);
1036 if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {
1039 sym_name(np));
1040 np->rv_ctest4 &= ~MPEE;
1051 pc = INL(np, nc_dsp);
1055 host_rd = scr_to_cpu(np->scratch);
1056 sym_rd = INL(np, nc_scratcha);
1057 sym_bk = INL(np, nc_temp);
1061 if (pc != SCRIPTZ_BA(np, snoopend)+8) {
1064 (u_long) SCRIPTZ_BA(np, snooptest), (u_long) pc,
1065 (u_long) SCRIPTZ_BA(np, snoopend) +8);
1119 struct sym_hcb *np = sym_get_hcb(shost); local
1127 dsp = INL(np, nc_dsp);
1129 if (dsp > np->scripta_ba &&
1130 dsp <= np->scripta_ba + np->scripta_sz) {
1131 script_ofs = dsp - np->scripta_ba;
1132 script_size = np->scripta_sz;
1133 script_base = (u_char *) np->scripta0;
1136 else if (np->scriptb_ba < dsp &&
1137 dsp <= np->scriptb_ba + np->scriptb_sz) {
1138 script_ofs = dsp - np->scriptb_ba;
1139 script_size = np->scriptb_sz;
1140 script_base = (u_char *) np->scriptb0;
1150 sym_name(np), (unsigned)INB(np, nc_sdid)&0x0f, dstat, sist,
1151 (unsigned)INB(np, nc_socl), (unsigned)INB(np, nc_sbcl),
1152 (unsigned)INB(np, nc_sbdl), (unsigned)INB(np, nc_sxfer),
1153 (unsigned)INB(np, nc_scntl3),
1154 (np->features & FE_C10) ? (unsigned)INB(np, nc_scntl4) : 0,
1155 script_name, script_ofs, (unsigned)INL(np, nc_dbc));
1159 printf ("%s: script cmd = %08x\n", sym_name(np),
1163 printf("%s: regdump:", sym_name(np));
1165 printf(" %02x", (unsigned)INB_OFF(np, i));
1177 struct sym_hcb *np = sym_get_hcb(shost); local
1181 sist = INW(np, nc_sist);
1182 dstat = INB(np, nc_dstat);
1302 int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s) argument
1306 if (!use_dac(np))
1311 if (h == np->dmap_bah[i])
1315 if (!np->dmap_bah[s])
1319 if (!np->dmap_bah[s])
1326 np->dmap_bah[s] = h;
1327 np->dmap_dirty = 1;
1335 static void sym_update_dmap_regs(struct sym_hcb *np) argument
1339 if (!np->dmap_dirty)
1343 OUTL_OFF(np, o, np->dmap_bah[i]);
1346 np->dmap_dirty = 0;
1351 static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget, argument
1376 if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))
1382 if (goal->offset > np->maxoffs_dt)
1383 goal->offset = np->maxoffs_dt;
1384 if (goal->period < np->minsync_dt)
1385 goal->period = np->minsync_dt;
1386 if (goal->period > np->maxsync_dt)
1387 goal->period = np->maxsync_dt;
1390 if (goal->offset > np->maxoffs)
1391 goal->offset = np->maxoffs;
1392 if (goal->period < np->minsync)
1393 goal->period = np->minsync;
1394 if (goal->period > np->maxsync)
1395 goal->period = np->maxsync;
1406 static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr) argument
1408 struct sym_tcb *tp = &np->target[cp->target];
1414 sym_check_goals(np, starget, goal);
1454 sym_print_nego_msg(np, cp->target,
1467 void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) argument
1480 if (np->last_cp && np->iarb_count < np->iarb_max) {
1481 np->last_cp->host_flags |= HF_HINT_IARB;
1482 ++np->iarb_count;
1485 np->iarb_count = 0;
1486 np->last_cp = cp;
1494 if (np->dmap_dirty)
1502 qidx = np->squeueput + 2;
1505 np->squeue [qidx] = cpu_to_scr(np->idletask_ba);
1507 np->squeue [np->squeueput] = cpu_to_scr(cp->ccb_ba);
1509 np->squeueput = qidx;
1513 np->squeueput);
1520 OUTB(np, nc_istat, SIGP|np->istat_sem);
1527 void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn) argument
1555 cpu_to_scr(SCRIPTA_BA(np, resel_tag));
1564 cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
1569 sym_put_start_queue(np, cp);
1581 static int sym_wakeup_done (struct sym_hcb *np) argument
1588 i = np->dqueueget;
1592 dsa = scr_to_cpu(np->dqueue[i]);
1595 np->dqueue[i] = 0;
1599 cp = sym_ccb_from_dsa(np, dsa);
1602 sym_complete_ok (np, cp);
1607 sym_name(np), (u_int) dsa);
1609 np->dqueueget = i;
1628 static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status) argument
1633 while ((qp = sym_remque_head(&np->comp_ccbq)) != NULL) {
1636 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
1645 struct sym_tcb *tp = &np->target[cp->target];
1662 sym_free_ccb(np, cp);
1663 sym_xpt_done(np, cmd);
1671 static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status) argument
1677 sym_que_splice(&np->busy_ccbq, &np->comp_ccbq);
1678 sym_que_init(&np->busy_ccbq);
1679 sym_flush_comp_queue(np, cam_status);
1694 struct sym_hcb *np = sym_data->ncb; local
1702 sym_soft_reset(np);
1704 OUTB(np, nc_stest3, TE|CSF);
1705 OUTONB(np, nc_ctest3, CLF);
1711 phys = np->squeue_ba;
1713 np->squeue[i] = cpu_to_scr(np->idletask_ba);
1714 np->squeue[i+1] = cpu_to_scr(phys + (i+2)*4);
1716 np->squeue[MAX_QUEUE*2-1] = cpu_to_scr(phys);
1721 np->squeueput = 0;
1726 phys = np->dqueue_ba;
1728 np->dqueue[i] = 0;
1729 np->dqueue[i+1] = cpu_to_scr(phys + (i+2)*4);
1731 np->dqueue[MAX_QUEUE*2-1] = cpu_to_scr(phys);
1736 np->dqueueget = 0;
1743 np->fw_patch(shost);
1748 sym_flush_busy_queue(np, DID_RESET);
1753 OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */
1754 INB(np, nc_mbox1);
1757 OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
1759 OUTB(np, nc_scntl1, 0x00); /* odd parity, and remove CRST!! */
1761 sym_selectclock(np, np->rv_scntl3); /* Select SCSI clock */
1763 OUTB(np, nc_scid , RRE|np->myaddr); /* Adapter SCSI address */
1764 OUTW(np, nc_respid, 1ul<<np->myaddr); /* Id to respond to */
1765 OUTB(np, nc_istat , SIGP ); /* Signal Process */
1766 OUTB(np, nc_dmode , np->rv_dmode); /* Burst length, dma mode */
1767 OUTB(np, nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */
1769 OUTB(np, nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */
1770 OUTB(np, nc_ctest3, np->rv_ctest3); /* Write and invalidate */
1771 OUTB(np, nc_ctest4, np->rv_ctest4); /* Master parity checking */
1774 if (np->features & FE_C10)
1775 OUTB(np, nc_stest2, np->rv_stest2);
1777 OUTB(np, nc_stest2, EXT|np->rv_stest2);
1779 OUTB(np, nc_stest3, TE); /* TolerANT enable */
1780 OUTB(np, nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */
1786 OUTB(np, nc_aipcntl1, DISAIP);
1797 OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30);
1805 OUTB(np, nc_ctest0, (1<<5));
1807 np->rv_ccntl0 |= DPR;
1814 if (np->features & (FE_DAC|FE_NOPM)) {
1815 OUTB(np, nc_ccntl0, np->rv_ccntl0);
1816 OUTB(np, nc_ccntl1, np->rv_ccntl1);
1824 if (use_dac(np)) {
1825 np->dmap_bah[0] = 0; /* ??? */
1826 OUTL(np, nc_scrx[0], np->dmap_bah[0]);
1827 OUTL(np, nc_drs, np->dmap_bah[0]);
1835 if (np->features & FE_NOPM) {
1836 OUTL(np, nc_pmjad1, SCRIPTB_BA(np, pm_handle));
1837 OUTL(np, nc_pmjad2, SCRIPTB_BA(np, pm_handle));
1844 if (np->features & FE_LED0)
1845 OUTB(np, nc_gpcntl, INB(np, nc_gpcntl) & ~0x01);
1846 else if (np->features & FE_LEDC)
1847 OUTB(np, nc_gpcntl, (INB(np, nc_gpcntl) & ~0x41) | 0x20);
1852 OUTW(np, nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR);
1853 OUTB(np, nc_dien , MDPE|BF|SSI|SIR|IID);
1860 if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
1861 OUTONW(np, nc_sien, SBMC);
1863 INB(np, nc_mbox1);
1865 INW(np, nc_sist);
1867 np->scsi_mode = INB(np, nc_stest4) & SMODE;
1877 struct sym_tcb *tp = &np->target[i];
1881 tp->head.wval = np->rv_scntl3;
1901 phys = SCRIPTA_BA(np, init);
1902 if (np->ram_ba) {
1904 printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np));
1905 memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz);
1906 if (np->features & FE_RAM8K) {
1907 memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz);
1908 phys = scr_to_cpu(np->scr_ram_seg);
1909 OUTL(np, nc_mmws, phys);
1910 OUTL(np, nc_mmrs, phys);
1911 OUTL(np, nc_sfs, phys);
1912 phys = SCRIPTB_BA(np, start64);
1916 np->istat_sem = 0;
1918 OUTL(np, nc_dsa, np->hcb_ba);
1919 OUTL_DSP(np, phys);
1925 sym_xpt_async_bus_reset(np);
1931 static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs, argument
1936 struct sym_tcb *tp = &np->target[target];
1938 assert(target == (INB(np, nc_sdid) & 0x0f));
1946 sval, wval, uval, np->rv_scntl3);
1951 if (!(np->features & FE_C10))
1961 if (!(np->features & FE_C10))
1980 if (np->features & FE_C10) {
1983 assert(np->features & FE_U3EN);
2006 if (per < 50 && !(np->features & FE_C10))
2007 OUTOFFB(np, nc_stest2, EXT);
2012 OUTB(np, nc_sxfer, tp->head.sval);
2013 OUTB(np, nc_scntl3, tp->head.wval);
2015 if (np->features & FE_C10) {
2016 OUTB(np, nc_scntl4, tp->head.uval);
2022 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
2029 if (np->features & FE_C10) {
2062 static void sym_setwide(struct sym_hcb *np, int target, u_char wide) argument
2064 struct sym_tcb *tp = &np->target[target];
2067 sym_settrans(np, target, 0, 0, 0, wide, 0, 0);
2091 sym_setsync(struct sym_hcb *np, int target, argument
2094 struct sym_tcb *tp = &np->target[target];
2098 sym_settrans(np, target, 0, ofs, per, wide, div, fak);
2124 sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs, argument
2127 struct sym_tcb *tp = &np->target[target];
2130 sym_settrans(np, target, opts, ofs, per, wide, div, fak);
2173 static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts) argument
2175 u32 dsp = INL(np, nc_dsp);
2176 u32 dsa = INL(np, nc_dsa);
2177 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
2184 if ((!(dsp > SCRIPTA_BA(np, getjob_begin) &&
2185 dsp < SCRIPTA_BA(np, getjob_end) + 1)) &&
2186 (!(dsp > SCRIPTA_BA(np, ungetjob) &&
2187 dsp < SCRIPTA_BA(np, reselect) + 1)) &&
2188 (!(dsp > SCRIPTB_BA(np, sel_for_abort) &&
2189 dsp < SCRIPTB_BA(np, sel_for_abort_1) + 1)) &&
2190 (!(dsp > SCRIPTA_BA(np, done) &&
2191 dsp < SCRIPTA_BA(np, done_end) + 1))) {
2192 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
2193 OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */
2202 OUTL_DSP(np, SCRIPTA_BA(np, complete_error));
2208 OUTL(np, nc_dsa, 0xffffff);
2209 OUTL_DSP(np, SCRIPTA_BA(np, start));
2218 sym_start_reset(np);
2224 static void sym_int_sto (struct sym_hcb *np) argument
2226 u32 dsp = INL(np, nc_dsp);
2230 if (dsp == SCRIPTA_BA(np, wf_sel_done) + 8)
2231 sym_recover_scsi_int(np, HS_SEL_TIMEOUT);
2233 sym_start_reset(np);
2239 static void sym_int_udc (struct sym_hcb *np) argument
2241 printf ("%s: unexpected disconnect\n", sym_name(np));
2242 sym_recover_scsi_int(np, HS_UNEXPECTED);
2257 struct sym_hcb *np = sym_get_hcb(shost); local
2258 u_char scsi_mode = INB(np, nc_stest4) & SMODE;
2263 printf("%s: SCSI BUS mode change from %s to %s.\n", sym_name(np),
2264 sym_scsi_bus_mode(np->scsi_mode), sym_scsi_bus_mode(scsi_mode));
2297 static void sym_int_par (struct sym_hcb *np, u_short sist) argument
2299 u_char hsts = INB(np, HS_PRT);
2300 u32 dsp = INL(np, nc_dsp);
2301 u32 dbc = INL(np, nc_dbc);
2302 u32 dsa = INL(np, nc_dsa);
2303 u_char sbcl = INB(np, nc_sbcl);
2306 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
2310 sym_name(np), hsts, dbc, sbcl);
2315 if (!(INB(np, nc_scntl1) & ISCON)) {
2316 sym_recover_scsi_int(np, HS_UNEXPECTED);
2337 OUTONB(np, HF_PRT, HF_EXT_ERR);
2343 np->msgout[0] = (phase == 7) ? M_PARITY : M_ID_ERROR;
2354 if (dsp == SCRIPTB_BA(np, pm_handle))
2355 OUTL_DSP(np, dsp);
2358 sym_int_ma (np);
2361 sym_set_script_dp (np, cp, dsp);
2362 OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
2369 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
2372 OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
2376 sym_start_reset(np);
2386 static void sym_int_ma (struct sym_hcb *np) argument
2403 dsp = INL(np, nc_dsp);
2404 dbc = INL(np, nc_dbc);
2405 dsa = INL(np, nc_dsa);
2414 cp = sym_ccb_from_dsa(np, dsa);
2425 if (np->features & FE_DFBC)
2426 delta = INW(np, nc_dfbc);
2433 dfifo = INL(np, nc_dfifo);
2453 ss0 = INB(np, nc_sstat0);
2455 if (!(np->features & FE_C10))
2458 ss2 = INB(np, nc_sstat2);
2460 if (!(np->features & FE_C10))
2467 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */
2468 OUTB(np, nc_stest3, TE|CSF); /* scsi fifo */
2475 printf ("P%x%x RL=%d D=%d ", cmd&7, INB(np, nc_sbcl)&7,
2484 if (dsp > np->scripta_ba &&
2485 dsp <= np->scripta_ba + np->scripta_sz) {
2486 vdsp = (u32 *)((char*)np->scripta0 + (dsp-np->scripta_ba-8));
2489 else if (dsp > np->scriptb_ba &&
2490 dsp <= np->scriptb_ba + np->scriptb_sz) {
2491 vdsp = (u32 *)((char*)np->scriptb0 + (dsp-np->scriptb_ba-8));
2505 sym_name (np));
2511 sym_name (np));
2556 cmd&7, INB(np, nc_sbcl)&7, (unsigned)olen,
2569 hflags0 = INB(np, HF_PRT);
2584 newcmd = SCRIPTA_BA(np, pm0_data);
2588 newcmd = SCRIPTA_BA(np, pm1_data);
2593 OUTB(np, HF_PRT, hflags);
2608 nxtdsp = SCRIPTA_BA(np, dispatch);
2610 (INB(np, nc_scntl2) & WSR)) {
2636 nxtdsp = SCRIPTB_BA(np, wsr_ma_helper);
2650 sym_set_script_dp (np, cp, newcmd);
2651 OUTL_DSP(np, nxtdsp);
2687 nxtdsp = SCRIPTA_BA(np, dispatch);
2691 nxtdsp = SCRIPTA_BA(np, dispatch);
2701 if (dsp == SCRIPTA_BA(np, send_ident)) {
2704 np->msgout[0] = IDENTIFY(0, cp->lun);
2705 nxtdsp = SCRIPTB_BA(np, ident_break_atn);
2708 nxtdsp = SCRIPTB_BA(np, ident_break);
2710 else if (dsp == SCRIPTB_BA(np, send_wdtr) ||
2711 dsp == SCRIPTB_BA(np, send_sdtr) ||
2712 dsp == SCRIPTB_BA(np, send_ppr)) {
2713 nxtdsp = SCRIPTB_BA(np, nego_bad_phase);
2714 if (dsp == SCRIPTB_BA(np, send_ppr)) {
2722 nxtdsp = SCRIPTA_BA(np, clrack);
2728 OUTL_DSP(np, nxtdsp);
2733 sym_start_reset(np);
2802 struct sym_hcb *np = sym_data->ncb; local
2819 istat = INB(np, nc_istat);
2821 OUTB(np, nc_istat, (istat & SIGP) | INTF | np->istat_sem);
2822 istat |= INB(np, nc_istat); /* DUMMY READ */
2824 sym_wakeup_done(np);
2832 OUTB(np, nc_istat, CABRT);
2850 sist |= INW(np, nc_sist);
2852 dstat |= INB(np, nc_dstat);
2853 istatc = INB(np, nc_istat);
2866 (int)INB(np, nc_scr0),
2868 (unsigned)INL(np, nc_dsp),
2869 (unsigned)INL(np, nc_dbc));
2893 if (sist & PAR) sym_int_par (np, sist);
2894 else if (sist & MA) sym_int_ma (np);
2895 else if (dstat & SIR) sym_int_sir(np);
2913 printf("%s: SCSI BUS reset detected.\n", sym_name(np));
2918 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
2919 OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */
2924 else if (sist & STO) sym_int_sto (np);
2925 else if (sist & UDC) sym_int_udc (np);
2941 sym_start_reset(np);
2952 sym_name(np), istat, dstat, sist);
2965 sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task) argument
2980 while (i != np->squeueput) {
2981 cp = sym_ccb_from_dsa(np, scr_to_cpu(np->squeue[i]));
2996 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3000 np->squeue[j] = np->squeue[i];
3006 np->squeue[j] = np->squeue[i];
3007 np->squeueput = j; /* Update our current start queue pointer */
3030 static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb *cp) argument
3041 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3048 if (np->last_cp)
3049 np->last_cp = 0;
3064 sym_complete_error (np, cp);
3072 sym_complete_error (np, cp);
3080 sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3081 OUTL_DSP(np, SCRIPTA_BA(np, start));
3089 cp->sv_resid = sym_compute_residual(np, cp);
3110 msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]);
3143 startp = SCRIPTB_BA(np, sdata_in);
3157 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
3162 sym_put_start_queue(np, cp);
3167 sym_flush_comp_queue(np, 0);
3186 int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task) argument
3196 sym_que_splice(&np->busy_ccbq, &qtmp);
3197 sym_que_init(&np->busy_ccbq);
3213 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
3216 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3269 static void sym_sir_task_recovery(struct sym_hcb *np, int num) argument
3289 tp = &np->target[i];
3312 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3328 tp = &np->target[target];
3329 np->abrt_sel.sel_id = target;
3330 np->abrt_sel.sel_scntl3 = tp->head.wval;
3331 np->abrt_sel.sel_sxfer = tp->head.sval;
3332 OUTL(np, nc_dsa, np->hcb_ba);
3333 OUTL_DSP(np, SCRIPTB_BA(np, sel_for_abort));
3344 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3357 if (cp == np->last_cp) {
3371 np->istat_sem = 0;
3372 OUTB(np, nc_istat, SIGP);
3380 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3381 i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
3390 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
3403 sym_flush_comp_queue(np, 0);
3410 target = INB(np, nc_sdid) & 0xf;
3411 tp = &np->target[target];
3413 np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg));
3421 np->abrt_msg[0] = M_RESET;
3422 np->abrt_tbl.size = 1;
3448 np->abrt_msg[0] = IDENTIFY(0, lun);
3449 np->abrt_msg[1] = M_ABORT;
3450 np->abrt_tbl.size = 2;
3460 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
3480 np->abrt_msg[0] = M_ABORT;
3481 np->abrt_tbl.size = 1;
3489 np->abrt_msg[0] = IDENTIFY(0, cp->lun);
3498 np->abrt_msg[1] = M_ABORT;
3499 np->abrt_tbl.size = 2;
3501 np->abrt_msg[1] = cp->scsi_smsg[1];
3502 np->abrt_msg[2] = cp->scsi_smsg[2];
3503 np->abrt_msg[3] = M_ABORT_TAG;
3504 np->abrt_tbl.size = 4;
3521 target = INB(np, nc_sdid) & 0xf;
3522 tp = &np->target[target];
3528 if (np->abrt_msg[0] == M_ABORT)
3541 if (np->abrt_msg[0] == M_RESET) {
3543 tp->head.wval = np->rv_scntl3;
3562 lun = np->abrt_msg[0] & 0x3f;
3563 if (np->abrt_msg[1] == M_ABORT_TAG)
3564 task = np->abrt_msg[2];
3571 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
3572 sym_dequeue_from_squeue(np, i, target, lun, -1);
3573 sym_clear_tasks(np, DID_ABORT, target, lun, task);
3574 sym_flush_comp_queue(np, 0);
3579 if (np->abrt_msg[0] == M_RESET)
3590 sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
3591 np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
3627 static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int *ofs) argument
3640 if (dp_scr == SCRIPTA_BA(np, pm0_data))
3642 else if (dp_scr == SCRIPTA_BA(np, pm1_data))
3745 static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp, int ofs) argument
3748 u32 dp_scr = sym_get_script_dp (np, cp);
3765 dp_sg = sym_evaluate_dp(np, cp, dp_scr, &dp_ofs);
3788 hflags = INB(np, HF_PRT);
3795 dp_scr = SCRIPTA_BA(np, pm0_data);
3799 dp_scr = SCRIPTA_BA(np, pm1_data);
3804 OUTB(np, HF_PRT, hflags);
3820 sym_set_script_dp (np, cp, dp_scr);
3821 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
3825 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
3844 int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp) argument
3877 sym_evaluate_dp(np, cp, scr_to_cpu(cp->phys.head.lastp),
3945 sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) argument
3951 sym_print_nego_msg(np, target, "sync msgin", np->msgin);
3958 per = np->msgin[3];
3959 ofs = np->msgin[4];
3965 if (ofs > np->maxoffs)
3966 {chg = 1; ofs = np->maxoffs;}
3970 if (per < np->minsync)
3971 {chg = 1; per = np->minsync;}
3978 if (ofs && sym_getsync(np, 0, per, &div, &fak) < 0)
3997 sym_setsync (np, target, ofs, per, div, fak);
4008 spi_populate_sync_msg(np->msgout, per, ofs);
4011 sym_print_nego_msg(np, target, "sync msgout", np->msgout);
4014 np->msgin [0] = M_NOOP;
4019 sym_setsync (np, target, 0, 0, 0, 0);
4023 static void sym_sync_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) argument
4031 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4032 OUTB(np, HS_PRT, HS_BUSY);
4041 result = sym_sync_nego_check(np, req, cp);
4046 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4049 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4053 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4060 sym_ppr_nego_check(struct sym_hcb *np, int req, int target) argument
4062 struct sym_tcb *tp = &np->target[target];
4066 unsigned char per = np->msgin[3];
4067 unsigned char ofs = np->msgin[5];
4068 unsigned char wide = np->msgin[6];
4069 unsigned char opts = np->msgin[7] & PPR_OPT_MASK;
4072 sym_print_nego_msg(np, target, "ppr msgin", np->msgin);
4078 if (wide > np->maxwide) {
4080 wide = np->maxwide;
4082 if (!wide || !(np->features & FE_U3EN))
4085 if (opts != (np->msgin[7] & PPR_OPT_MASK))
4091 unsigned char maxoffs = dt ? np->maxoffs_dt : np->maxoffs;
4099 unsigned char minsync = dt ? np->minsync_dt : np->minsync;
4110 if (ofs && sym_getsync(np, dt, per, &div, &fak) < 0)
4123 sym_setpprot(np, target, opts, ofs, per, wide, div, fak);
4134 spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts);
4137 sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
4140 np->msgin [0] = M_NOOP;
4145 sym_setpprot (np, target, 0, 0, 0, 0, 0, 0);
4160 static void sym_ppr_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) argument
4168 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4169 OUTB(np, HS_PRT, HS_BUSY);
4178 result = sym_ppr_nego_check(np, req, cp->target);
4183 OUTL_DSP(np, SCRIPTB_BA(np, ppr_resp));
4186 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4190 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4197 sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) argument
4203 sym_print_nego_msg(np, target, "wide msgin", np->msgin);
4210 wide = np->msgin[3];
4215 if (wide > np->maxwide) {
4217 wide = np->maxwide;
4235 sym_setwide (np, target, wide);
4246 spi_populate_width_msg(np->msgout, wide);
4248 np->msgin [0] = M_NOOP;
4251 sym_print_nego_msg(np, target, "wide msgout", np->msgout);
4260 static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) argument
4268 if (INB(np, HS_PRT) == HS_NEGOTIATE) {
4269 OUTB(np, HS_PRT, HS_BUSY);
4278 result = sym_wide_nego_check(np, req, cp);
4283 OUTL_DSP(np, SCRIPTB_BA(np, wdtr_resp));
4291 spi_populate_sync_msg(np->msgout, tp->tgoal.period,
4295 sym_print_nego_msg(np, cp->target,
4296 "sync msgout", np->msgout);
4300 OUTB(np, HS_PRT, HS_NEGOTIATE);
4301 OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
4304 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4310 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4324 static void sym_nego_default(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) argument
4329 sym_setpprot (np, cp->target, 0, 0, 0, 0, 0, 0);
4331 if (tp->tgoal.period < np->minsync)
4332 tp->tgoal.period = np->minsync;
4333 if (tp->tgoal.offset > np->maxoffs)
4334 tp->tgoal.offset = np->maxoffs;
4340 sym_setsync (np, cp->target, 0, 0, 0, 0);
4343 sym_setwide (np, cp->target, 0);
4346 np->msgin [0] = M_NOOP;
4347 np->msgout[0] = M_NOOP;
4355 static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) argument
4357 sym_nego_default(np, tp, cp);
4358 OUTB(np, HS_PRT, HS_BUSY);
4371 static void sym_int_sir(struct sym_hcb *np) argument
4373 u_char num = INB(np, nc_dsps);
4374 u32 dsa = INL(np, nc_dsa);
4375 struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
4376 u_char target = INB(np, nc_sdid) & 0x0f;
4377 struct sym_tcb *tp = &np->target[target];
4389 sym_update_dmap_regs(np);
4397 sym_complete_error(np, cp);
4406 sym_sir_task_recovery(np, num);
4436 np->msgout[0] = M_RESET;
4443 np->msgout[0] = M_ABORT;
4449 np->msgout[0] = M_ABORT_TAG;
4456 np->lastmsg = np->msgout[0];
4457 np->msgout[0] = M_NOOP;
4459 "message %x sent on bad reselection\n", np->lastmsg);
4466 np->lastmsg = np->msgout[0];
4467 np->msgout[0] = M_NOOP;
4469 if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) {
4473 OUTOFFB(np, HF_PRT, HF_EXT_ERR);
4485 sym_sir_bad_scsi_status(np, num, cp);
4492 sym_print_msg(cp, "M_REJECT to send for ", np->msgin);
4493 np->msgout[0] = M_REJECT;
4503 OUTONB(np, HF_PRT, HF_EXT_ERR);
4514 OUTONB(np, HF_PRT, HF_EXT_ERR);
4526 OUTONB(np, HF_PRT, HF_EXT_ERR);
4528 cp->extra_bytes += INL(np, nc_scratcha);
4536 OUTONB(np, HF_PRT, HF_EXT_ERR);
4546 switch (np->msgin [0]) {
4553 switch (np->msgin [2]) {
4557 np->msgin);
4558 tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
4559 (np->msgin[5]<<8) + (np->msgin[6]);
4560 sym_modify_dp(np, tp, cp, tmp);
4563 sym_sync_nego(np, tp, cp);
4566 sym_ppr_nego(np, tp, cp);
4569 sym_wide_nego(np, tp, cp);
4584 sym_print_msg(cp, "1 or 2 byte ", np->msgin);
4586 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4588 sym_modify_dp(np, tp, cp, -1);
4591 if (INB(np, HS_PRT) == HS_NEGOTIATE)
4592 sym_nego_rejected(np, tp, cp);
4596 scr_to_cpu(np->lastmsg), np->msgout[0]);
4608 sym_print_msg(cp, "WEIRD message received", np->msgin);
4609 OUTL_DSP(np, SCRIPTB_BA(np, msg_weird));
4617 OUTB(np, HS_PRT, HS_BUSY);
4624 sym_nego_default(np, tp, cp);
4632 OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
4635 OUTL_DSP(np, SCRIPTA_BA(np, clrack));
4644 struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order) argument
4648 struct sym_tcb *tp = &np->target[tn];
4657 if (sym_que_empty(&np->free_ccbq))
4658 sym_alloc_ccb(np);
4659 qp = sym_remque_head(&np->free_ccbq);
4680 sym_alloc_lcb_tags(np, tn, ln);
4698 cpu_to_scr(SCRIPTA_BA(np, resel_tag));
4732 cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
4742 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
4764 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4771 void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp) argument
4773 struct sym_tcb *tp = &np->target[cp->target];
4802 lp->itlq_tbl[cp->tag] = cpu_to_scr(np->bad_itlq_ba);
4809 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
4817 cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
4833 if (cp == np->last_cp)
4834 np->last_cp = 0;
4843 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4848 sym_insque_tail(&cp->link2_ccbq, &np->dummy_ccbq);
4863 static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np) argument
4872 if (np->actccbs >= SYM_CONF_MAX_START)
4885 np->actccbs++;
4896 cp->link_ccbh = np->ccbh[hcode];
4897 np->ccbh[hcode] = cp;
4902 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, idle));
4903 cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
4908 cp->phys.smsg_ext.addr = cpu_to_scr(HCB_BA(np, msgin[2]));
4913 sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
4919 sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq);
4931 static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa) argument
4937 cp = np->ccbh[hcode];
4951 static void sym_init_tcb (struct sym_hcb *np, u_char tn) argument
4967 struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) argument
4969 struct sym_tcb *tp = &np->target[tn];
4975 sym_init_tcb (np, tn);
4985 memset32(tp->luntbl, cpu_to_scr(vtobus(&np->badlun_sa)), 64);
5019 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
5024 lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5048 static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln) argument
5050 struct sym_tcb *tp = &np->target[tn];
5071 memset32(lp->itlq_tbl, cpu_to_scr(np->notask_ba), SYM_CONF_MAX_TASK);
5094 int sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln) argument
5096 struct sym_tcb *tp = &np->target[tn];
5107 tp->head.luntbl_sa = cpu_to_scr(vtobus(np->badluntbl));
5109 tp->luntbl[ln] = cpu_to_scr(vtobus(&np->badlun_sa));
5114 tp->head.lun0_sa = cpu_to_scr(vtobus(&np->badlun_sa));
5130 int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) argument
5147 tp = &np->target[cp->target];
5221 msglen += sym_prepare_nego(np, cp, msgptr + msglen);
5227 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
5228 cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA(np, resel_dsa));
5265 return sym_setup_data_and_start(np, cmd, cp);
5271 int sym_reset_scsi_target(struct sym_hcb *np, int target) argument
5275 if (target == np->myaddr || (u_int)target >= SYM_CONF_MAX_TARGET)
5278 tp = &np->target[target];
5281 np->istat_sem = SEM;
5282 OUTB(np, nc_istat, SIGP|SEM);
5290 static int sym_abort_ccb(struct sym_hcb *np, struct sym_ccb *cp, int timed_out) argument
5303 sym_reset_scsi_bus(np, 1);
5315 np->istat_sem = SEM;
5316 OUTB(np, nc_istat, SIGP|SEM);
5320 int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out) argument
5329 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
5337 return sym_abort_ccb(np, cp, timed_out);
5350 void sym_complete_error(struct sym_hcb *np, struct sym_ccb *cp) argument
5378 tp = &np->target[cp->target];
5395 resid = sym_compute_residual(np, cp);
5410 i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
5411 i = sym_dequeue_from_squeue(np, i, cp->target, sdev->lun, -1);
5416 OUTL_DSP(np, SCRIPTA_BA(np, start));
5451 sym_set_cam_result_error(np, cp, resid);
5460 sym_insque_head(&cp->link_ccbq, &np->comp_ccbq);
5466 sym_flush_comp_queue(np, 0);
5472 sym_start_next_ccbs(np, lp, 1);
5485 void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp) argument
5510 tp = &np->target[cp->target];
5520 resid = sym_compute_residual(np, cp);
5560 sym_free_ccb (np, cp);
5567 sym_start_next_ccbs(np, lp, 2);
5572 sym_xpt_done(np, cmd);
5580 struct sym_hcb *np = sym_get_hcb(shost); local
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;
5597 sym_save_initial_setting (np);
5604 sym_chip_reset(np);
5610 sym_prepare_setting(shost, np, nvram);
5617 i = sym_getpciclock(np);
5618 if (i > 37000 && !(np->features & FE_66MHZ))
5620 sym_name(np), i);
5625 np->squeue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
5626 if (!np->squeue)
5628 np->squeue_ba = vtobus(np->squeue);
5633 np->dqueue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
5634 if (!np->dqueue)
5636 np->dqueue_ba = vtobus(np->dqueue);
5641 np->targtbl = sym_calloc_dma(256, "TARGTBL");
5642 if (!np->targtbl)
5644 np->targtbl_ba = vtobus(np->targtbl);
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)
5658 np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(*np->ccbh), GFP_KERNEL);
5659 if (!np->ccbh)
5665 sym_que_init(&np->free_ccbq);
5666 sym_que_init(&np->busy_ccbq);
5667 sym_que_init(&np->comp_ccbq);
5674 sym_que_init(&np->dummy_ccbq);
5679 if (!sym_alloc_ccb(np))
5686 np->scripta_ba = vtobus(np->scripta0);
5687 np->scriptb_ba = vtobus(np->scriptb0);
5688 np->scriptz_ba = vtobus(np->scriptz0);
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;
5695 np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32);
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);
5711 np->fw_setup(np, fw);
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);
5729 np->iarb_max = SYM_SETUP_IARB_MAX;
5731 np->iarb_max = 4;
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);
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);
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);
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);
5760 np->badluntbl = sym_calloc_dma(256, "BADLUNTBL");
5761 if (!np->badluntbl)
5764 np->badlun_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
5765 memset32(np->badluntbl, cpu_to_scr(vtobus(&np->badlun_sa)), 64);
5773 np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
5774 np->target[i].head.luntbl_sa =
5775 cpu_to_scr(vtobus(np->badluntbl));
5776 np->target[i].head.lun0_sa =
5777 cpu_to_scr(vtobus(&np->badlun_sa));
5783 if (sym_snooptest (np)) {
5784 printf("%s: CACHE INCORRECTLY CONFIGURED.\n", sym_name(np));
5800 void sym_hcb_free(struct sym_hcb *np) argument
5807 if (np->scriptz0)
5808 sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
5809 if (np->scriptb0)
5810 sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
5811 if (np->scripta0)
5812 sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
5813 if (np->squeue)
5814 sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
5815 if (np->dqueue)
5816 sym_mfree_dma(np->dqueue, sizeof(u32)*(MAX_QUEUE*2), "DQUEUE");
5818 if (np->actccbs) {
5819 while ((qp = sym_remque_head(&np->free_ccbq)) != NULL) {
5824 kfree(np->ccbh);
5826 if (np->badluntbl)
5827 sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
5830 tp = &np->target[target];
5837 if (np->targtbl)
5838 sym_mfree_dma(np->targtbl, 256, "TARGTBL");