Lines Matching +full:my +full:- +full:dma +full:- +full:window

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
5 * PCI-SCSI controllers.
7 * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
9 * This driver also supports the following Symbios/LSI PCI-SCSI chips:
14 * This driver for FreeBSD-CAM is derived from the Linux sym53c8xx driver.
15 * Copyright (C) 1998-1999 Gerard Roudier
18 * a port of the FreeBSD ncr driver to Linux-1.2.13.
22 * Stefan Esser <se@mi.Uni-Koeln.de>
26 * FreeBSD-CAM services is based on the aic7xxx driver for FreeBSD-CAM
34 *-----------------------------------------------------------------------------
61 #define SYM_DRIVER_NAME "sym-1.6.5-20000902"
141 * A la VMS/CAM-3 queue management.
149 (ptr)->flink = (ptr); (ptr)->blink = (ptr); \
156 flink->blink = new; in __sym_que_add()
157 new->flink = flink; in __sym_que_add()
158 new->blink = blink; in __sym_que_add()
159 blink->flink = new; in __sym_que_add()
165 flink->blink = blink; in __sym_que_del()
166 blink->flink = flink; in __sym_que_del()
171 return head->flink == head; in sym_que_empty()
177 struct sym_quehead *first = list->flink; in sym_que_splice()
180 struct sym_quehead *last = list->blink; in sym_que_splice()
181 struct sym_quehead *at = head->flink; in sym_que_splice()
183 first->blink = head; in sym_que_splice()
184 head->flink = first; in sym_que_splice()
186 last->flink = at; in sym_que_splice()
187 at->blink = last; in sym_que_splice()
192 ((type *)((char *)(ptr)-(size_t)(&((type *)0)->member)))
194 #define sym_insque(new, pos) __sym_que_add(new, pos, (pos)->flink)
196 #define sym_remque(el) __sym_que_del((el)->blink, (el)->flink)
198 #define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink)
202 struct sym_quehead *elem = head->flink; in sym_remque_head()
205 __sym_que_del(head, elem->flink); in sym_remque_head()
211 #define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head)
217 for (qp = (head)->flink; qp != (head); qp = qp->flink)
270 * Asynchronous pre-scaler (ns). Shall be 40 for
285 #define SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2)
292 #define SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2)
296 * For this one, we want a short name :-)
324 #define sym_verbose (np->verbose)
327 * Insert a delay in micro-seconds and milli-seconds.
330 static void MDELAY(int ms) { while (ms--) UDELAY(1000); } in MDELAY()
333 * Simple power of two buddy-like allocator.
357 #define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1)
362 typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */
377 #define VTOB_HASH_MASK (VTOB_HASH_SIZE-1)
388 #define M_GETP() mp->getp(mp)
389 #define M_FREEP(p) mp->freep(mp, p)
393 struct m_link h[MEMO_CLUSTER_SHIFT - MEMO_SHIFT + 1];
402 m_link_s *h = mp->h; in ___sym_malloc()
417 h[j].next->next = NULL; in ___sym_malloc()
425 h[j].next = h[j].next->next; in ___sym_malloc()
427 j -= 1; in ___sym_malloc()
430 h[j].next->next = NULL; in ___sym_malloc()
445 m_link_s *h = mp->h; in ___sym_mfree()
470 while (q->next && q->next != (m_link_s *) b) { in ___sym_mfree()
471 q = q->next; in ___sym_mfree()
473 if (!q->next) { in ___sym_mfree()
474 ((m_link_s *) a)->next = h[i].next; in ___sym_mfree()
478 q->next = q->next->next; in ___sym_mfree()
492 printf ("new %-10s[%4d] @%p.\n", name, size, p); in __sym_calloc2()
507 printf ("freeing %-10s[%4d] @%p.\n", name, size, ptr); in __sym_mfree()
514 * Default memory pool we donnot need to involve in DMA.
517 * With the `bus dma abstraction', we use a separate pool for
518 * memory we donnot need to involve in DMA.
524 ++mp->nump; in ___mp0_getp()
532 --mp->nump; in ___mp0_freep()
543 * Actual memory allocation routine for non-DMAed memory.
555 * Actual memory allocation routine for non-DMAed memory.
568 * With `bus dma abstraction', we use a separate pool per parent
577 KASSERT(nseg == 1, ("%s: too many DMA segments (%d)", __func__, nseg)); in getbaddrcb()
583 *baddr = segs->ds_addr; in getbaddrcb()
596 if (bus_dmamem_alloc(mp->dmat, &vaddr, in ___dma_getp()
597 BUS_DMA_COHERENT | BUS_DMA_WAITOK, &vbp->dmamap)) in ___dma_getp()
599 bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr, in ___dma_getp()
603 vbp->vaddr = (m_addr_t) vaddr; in ___dma_getp()
604 vbp->baddr = (m_addr_t) baddr; in ___dma_getp()
605 vbp->next = mp->vtob[hc]; in ___dma_getp()
606 mp->vtob[hc] = vbp; in ___dma_getp()
607 ++mp->nump; in ___dma_getp()
612 bus_dmamem_free(mp->dmat, vaddr, vbp->dmamap); in ___dma_getp()
624 vbpp = &mp->vtob[hc]; in ___dma_freep()
625 while (*vbpp && (*vbpp)->vaddr != m) in ___dma_freep()
626 vbpp = &(*vbpp)->next; in ___dma_freep()
629 *vbpp = (*vbpp)->next; in ___dma_freep()
630 bus_dmamap_unload(mp->dmat, vbp->dmamap); in ___dma_freep()
631 bus_dmamem_free(mp->dmat, (void *) vbp->vaddr, vbp->dmamap); in ___dma_freep()
633 --mp->nump; in ___dma_freep()
641 for (mp = mp0.next; mp && mp->dev_dmat != dev_dmat; mp = mp->next); in ___get_dma_pool()
651 mp->dev_dmat = dev_dmat; in ___cre_dma_pool()
657 NULL, NULL, &mp->dmat)) { in ___cre_dma_pool()
658 mp->getp = ___dma_getp; in ___cre_dma_pool()
660 mp->freep = ___dma_freep; in ___cre_dma_pool()
662 mp->next = mp0.next; in ___cre_dma_pool()
678 pp = &(*pp)->next; in ___del_dma_pool()
680 *pp = (*pp)->next; in ___del_dma_pool()
681 bus_dma_tag_destroy(p->dmat); in ___del_dma_pool()
699 if (mp && !mp->nump) in __sym_calloc_dma()
717 if (mp && !mp->nump) in __sym_mfree_dma()
733 vp = mp->vtob[hc]; in __vtobus()
734 while (vp && (m_addr_t) vp->vaddr != a) in __vtobus()
735 vp = vp->next; in __vtobus()
740 return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; in __vtobus()
749 #define _sym_calloc_dma(np, s, n) __sym_calloc_dma(np->bus_dmat, s, n)
751 __sym_mfree_dma(np->bus_dmat, _uvptv_(p), s, n)
754 #define _vtobus(np, p) __vtobus(np->bus_dmat, _uvptv_(p))
762 while (n-- > 0) in sym_printb_hex()
813 * This one is hopefully useless, but actually useful. :-)
841 * Access to the chip IO registers and on-chip RAM.
842 * We use the `bus space' interface under FreeBSD-4 and
847 #define INB_OFF(o) bus_read_1(np->io_res, (o))
848 #define INW_OFF(o) bus_read_2(np->io_res, (o))
849 #define INL_OFF(o) bus_read_4(np->io_res, (o))
851 #define OUTB_OFF(o, v) bus_write_1(np->io_res, (o), (v))
852 #define OUTW_OFF(o, v) bus_write_2(np->io_res, (o), (v))
853 #define OUTL_OFF(o, v) bus_write_4(np->io_res, (o), (v))
857 #define INB_OFF(o) bus_read_1(np->mmio_res, (o))
858 #define INW_OFF(o) bus_read_2(np->mmio_res, (o))
859 #define INL_OFF(o) bus_read_4(np->mmio_res, (o))
861 #define OUTB_OFF(o, v) bus_write_1(np->mmio_res, (o), (v))
862 #define OUTW_OFF(o, v) bus_write_2(np->mmio_res, (o), (v))
863 #define OUTL_OFF(o, v) bus_write_4(np->mmio_res, (o), (v))
868 bus_write_region_1(np->ram_res, (o), (a), (l))
971 #define CCB_HASH_MASK (CCB_HASH_SIZE-1)
1003 #define SYM_LOCK() mtx_lock(&np->mtx)
1004 #define SYM_LOCK_ASSERT(_what) mtx_assert(&np->mtx, (_what))
1005 #define SYM_LOCK_DESTROY() mtx_destroy(&np->mtx)
1006 #define SYM_LOCK_INIT() mtx_init(&np->mtx, "sym_lock", NULL, MTX_DEF)
1007 #define SYM_LOCK_INITIALIZED() mtx_initialized(&np->mtx)
1008 #define SYM_UNLOCK() mtx_unlock(&np->mtx)
1017 * Back-pointer from the CAM CCB to our data structures.
1064 * LUN #0 is a special case, since multi-lun devices are rare,
1065 * and we we want to speed-up the general case and not waste
1075 /*0*/ u_char uval; /* -> SCNTL4 register */
1076 /*1*/ u_char sval; /* -> SXFER io register */
1078 /*3*/ u_char wval; /* -> SCNTL3 io register */
1251 #define sym_lp(tp, lun) (!lun) ? (tp)->lun0p : 0
1254 (!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[(lun)] : 0
1416 * Map for the DMA of user data.
1419 bus_dmamap_t dmamap; /* DMA map for user data */
1441 #define CCB_BA(cp,lbl) (cp->ccb_ba + offsetof(struct sym_ccb, lbl))
1480 * Bit 32-63 of the on-chip RAM bus address in LE format.
1543 * My understanding of PCI is that all agents must share the
1546 * brain-deaded stuff that makes shit.
1553 * DMA stuff.
1555 bus_dma_tag_t bus_dmat; /* DMA tag from parent BUS */
1556 bus_dma_tag_t data_dmat; /* DMA tag for user data */
1561 int mmio_ws; /* MMIO Window size */
1564 int ram_ws; /* RAM window size */
1568 * 'script' is loaded in the on-chip RAM if present.
1570 * 53C895A, 53C896 and 53C1010 that provide 8K on-chip RAM.
1630 * Miscellaneous buffers accessed by the scripts-processor.
1696 #define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl))
1703 return device_get_nameunit(np->device); in sym_name()
1706 /*--------------------------------------------------------------------------*/
1707 /*------------------------------ FIRMWARES ---------------------------------*/
1708 /*--------------------------------------------------------------------------*/
1772 scripta0 = (struct sym_fw1a_scr *) np->scripta0; in sym_fw1_patch()
1773 scriptb0 = (struct sym_fw1b_scr *) np->scriptb0; in sym_fw1_patch()
1778 if (!(np->features & FE_LED0)) { in sym_fw1_patch()
1779 scripta0->idle[0] = cpu_to_scr(SCR_NO_OP); in sym_fw1_patch()
1780 scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP); in sym_fw1_patch()
1781 scripta0->start[0] = cpu_to_scr(SCR_NO_OP); in sym_fw1_patch()
1791 scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP); in sym_fw1_patch()
1795 * - start and done queue initial bus address. in sym_fw1_patch()
1796 * - target bus address table bus address. in sym_fw1_patch()
1798 scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba); in sym_fw1_patch()
1799 scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba); in sym_fw1_patch()
1800 scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba); in sym_fw1_patch()
1813 scripta0 = (struct sym_fw2a_scr *) np->scripta0; in sym_fw2_patch()
1814 scriptb0 = (struct sym_fw2b_scr *) np->scriptb0; in sym_fw2_patch()
1819 if (!(np->features & FE_LED0)) { in sym_fw2_patch()
1820 scripta0->idle[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1821 scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1822 scripta0->start[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1832 scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1836 * - start and done queue initial bus address. in sym_fw2_patch()
1837 * - target bus address table bus address. in sym_fw2_patch()
1839 scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba); in sym_fw2_patch()
1840 scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba); in sym_fw2_patch()
1841 scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba); in sym_fw2_patch()
1846 if (!(np->features & FE_C10)) { in sym_fw2_patch()
1847 scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1848 scripta0->resel_scntl4[1] = cpu_to_scr(0); in sym_fw2_patch()
1852 * Remove a couple of work-arounds specific to C1010 if in sym_fw2_patch()
1855 if (!(np->device_id == PCI_ID_LSI53C1010_2 && in sym_fw2_patch()
1856 np->revision_id < 0x1 && in sym_fw2_patch()
1857 np->pciclk_khz < 60000)) { in sym_fw2_patch()
1858 scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1859 scripta0->datao_phase[1] = cpu_to_scr(0); in sym_fw2_patch()
1861 if (!(np->device_id == PCI_ID_LSI53C1010 && in sym_fw2_patch()
1862 /* np->revision_id < 0xff */ 1)) { in sym_fw2_patch()
1863 scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); in sym_fw2_patch()
1864 scripta0->sel_done[1] = cpu_to_scr(0); in sym_fw2_patch()
1871 scriptb0->pm0_data_addr[0] = in sym_fw2_patch()
1872 cpu_to_scr(np->scripta_ba + in sym_fw2_patch()
1874 scriptb0->pm1_data_addr[0] = in sym_fw2_patch()
1875 cpu_to_scr(np->scripta_ba + in sym_fw2_patch()
1911 po = (const u_short *) fw->a_ofs; in sym_fw_setup_bus_addresses()
1912 pa = (u32 *) &np->fwa_bas; in sym_fw_setup_bus_addresses()
1913 for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++) in sym_fw_setup_bus_addresses()
1914 pa[i] = np->scripta_ba + po[i]; in sym_fw_setup_bus_addresses()
1919 po = (const u_short *) fw->b_ofs; in sym_fw_setup_bus_addresses()
1920 pa = (u32 *) &np->fwb_bas; in sym_fw_setup_bus_addresses()
1921 for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++) in sym_fw_setup_bus_addresses()
1922 pa[i] = np->scriptb_ba + po[i]; in sym_fw_setup_bus_addresses()
1934 scripta0 = (struct sym_fw1a_scr *) np->scripta0; in sym_fw1_setup()
1939 sym_fw_fill_data(scripta0->data_in, scripta0->data_out); in sym_fw1_setup()
1956 scripta0 = (struct sym_fw2a_scr *) np->scripta0; in sym_fw2_setup()
1961 sym_fw_fill_data(scripta0->data_in, scripta0->data_out); in sym_fw2_setup()
1973 static const struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
1975 static const struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
1983 if (chip->features & FE_LDSTR) in sym_find_firmware()
1986 else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC))) in sym_find_firmware()
2016 sym_name(np), (int) (cur-start)); in sym_fw_bind_script()
2023 * We use the bogus value 0xf00ff00f ;-) in sym_fw_bind_script()
2032 printf ("%d: <%x>\n", (int) (cur-start), in sym_fw_bind_script()
2060 sym_name(np), (int) (cur-start)); in sym_fw_bind_script()
2068 !(np->features & FE_PFEN)) { in sym_fw_bind_script()
2076 if (!(np->features & FE_WIDE)) in sym_fw_bind_script()
2084 if (!(np->features & FE_WIDE)) in sym_fw_bind_script()
2091 * dont't relocate if relative :-) in sym_fw_bind_script()
2129 while (relocs--) { in sym_fw_bind_script()
2134 new = (old & ~RELOC_MASK) + np->mmio_ba; in sym_fw_bind_script()
2137 new = (old & ~RELOC_MASK) + np->scripta_ba; in sym_fw_bind_script()
2140 new = (old & ~RELOC_MASK) + np->scriptb_ba; in sym_fw_bind_script()
2143 new = (old & ~RELOC_MASK) + np->hcb_ba; in sym_fw_bind_script()
2149 * script self-modified areas. in sym_fw_bind_script()
2168 /*---------------------------------------------------------------------------*/
2169 /*--------------------------- END OF FIRMWARES -----------------------------*/
2170 /*---------------------------------------------------------------------------*/
2278 if (cp && cp->cam_ccb) in PRINT_ADDR()
2279 xpt_print_path(cp->cam_ccb->ccb_h.path); in PRINT_ADDR()
2287 if (!(ccb->ccb_h.flags & CAM_DEV_QFRZDIS)) { in sym_freeze_cam_ccb()
2288 if (!(ccb->ccb_h.status & CAM_DEV_QFRZN)) { in sym_freeze_cam_ccb()
2289 ccb->ccb_h.status |= CAM_DEV_QFRZN; in sym_freeze_cam_ccb()
2290 xpt_freeze_devq(ccb->ccb_h.path, 1); in sym_freeze_cam_ccb()
2300 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in sym_set_cam_status()
2301 ccb->ccb_h.status |= status; in sym_set_cam_status()
2309 return ccb->ccb_h.status & CAM_STATUS_MASK; in sym_get_cam_status()
2320 ccb = cp->cam_ccb; in sym_enqueue_cam_ccb()
2321 np = (hcb_p) cp->arg; in sym_enqueue_cam_ccb()
2323 assert(!(ccb->ccb_h.status & CAM_SIM_QUEUED)); in sym_enqueue_cam_ccb()
2324 ccb->ccb_h.status = CAM_REQ_INPROG; in sym_enqueue_cam_ccb()
2326 callout_reset_sbt(&cp->ch, SBT_1MS * ccb->ccb_h.timeout, 0, sym_callout, in sym_enqueue_cam_ccb()
2328 ccb->ccb_h.status |= CAM_SIM_QUEUED; in sym_enqueue_cam_ccb()
2329 ccb->ccb_h.sym_hcb_ptr = np; in sym_enqueue_cam_ccb()
2331 sym_insque_tail(sym_qptr(&ccb->ccb_h.sim_links), &np->cam_ccbq); in sym_enqueue_cam_ccb()
2343 if (ccb->ccb_h.status & CAM_SIM_QUEUED) { in sym_xpt_done()
2344 callout_stop(&cp->ch); in sym_xpt_done()
2345 sym_remque(sym_qptr(&ccb->ccb_h.sim_links)); in sym_xpt_done()
2346 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; in sym_xpt_done()
2347 ccb->ccb_h.sym_hcb_ptr = NULL; in sym_xpt_done()
2402 np->rv_ctest4 &= ~0x80; in sym_init_burst()
2403 np->rv_dmode &= ~(0x3 << 6); in sym_init_burst()
2404 np->rv_ctest5 &= ~0x4; in sym_init_burst()
2407 np->rv_ctest4 |= 0x80; in sym_init_burst()
2410 --bc; in sym_init_burst()
2411 np->rv_dmode |= ((bc & 0x3) << 6); in sym_init_burst()
2412 np->rv_ctest5 |= (bc & 0x4); in sym_init_burst()
2425 if (i == np->myaddr) in sym_print_targets_flag()
2427 if (np->target[i].usrflags & mask) { in sym_print_targets_flag()
2449 np->sv_scntl0 = INB(nc_scntl0) & 0x0a; in sym_save_initial_setting()
2450 np->sv_scntl3 = INB(nc_scntl3) & 0x07; in sym_save_initial_setting()
2451 np->sv_dmode = INB(nc_dmode) & 0xce; in sym_save_initial_setting()
2452 np->sv_dcntl = INB(nc_dcntl) & 0xa8; in sym_save_initial_setting()
2453 np->sv_ctest3 = INB(nc_ctest3) & 0x01; in sym_save_initial_setting()
2454 np->sv_ctest4 = INB(nc_ctest4) & 0x80; in sym_save_initial_setting()
2455 np->sv_gpcntl = INB(nc_gpcntl); in sym_save_initial_setting()
2456 np->sv_stest1 = INB(nc_stest1); in sym_save_initial_setting()
2457 np->sv_stest2 = INB(nc_stest2) & 0x20; in sym_save_initial_setting()
2458 np->sv_stest4 = INB(nc_stest4); in sym_save_initial_setting()
2459 if (np->features & FE_C10) { /* Always large DMA fifo + ultra3 */ in sym_save_initial_setting()
2460 np->sv_scntl4 = INB(nc_scntl4); in sym_save_initial_setting()
2461 np->sv_ctest5 = INB(nc_ctest5) & 0x04; in sym_save_initial_setting()
2464 np->sv_ctest5 = INB(nc_ctest5) & 0x24; in sym_save_initial_setting()
2480 np->maxwide = (np->features & FE_WIDE)? 1 : 0; in sym_prepare_setting()
2485 if (np->features & FE_QUAD) in sym_prepare_setting()
2486 np->multiplier = 4; in sym_prepare_setting()
2487 else if (np->features & FE_DBLR) in sym_prepare_setting()
2488 np->multiplier = 2; in sym_prepare_setting()
2490 np->multiplier = 1; in sym_prepare_setting()
2492 np->clock_khz = (np->features & FE_CLK80)? 80000 : 40000; in sym_prepare_setting()
2493 np->clock_khz *= np->multiplier; in sym_prepare_setting()
2495 if (np->clock_khz != 40000) in sym_prepare_setting()
2496 sym_getclock(np, np->multiplier); in sym_prepare_setting()
2499 * Divisor to be used for async (timer pre-scaler). in sym_prepare_setting()
2501 i = np->clock_divn - 1; in sym_prepare_setting()
2502 while (--i >= 0) { in sym_prepare_setting()
2503 if (10ul * SYM_CONF_MIN_ASYNC * np->clock_khz > div_10M[i]) { in sym_prepare_setting()
2508 np->rv_scntl3 = i+1; in sym_prepare_setting()
2512 * So, we just throw away, the async. divisor.:-) in sym_prepare_setting()
2514 if (np->features & FE_C10) in sym_prepare_setting()
2515 np->rv_scntl3 = 0; in sym_prepare_setting()
2521 period = howmany(4 * div_10M[0], np->clock_khz); in sym_prepare_setting()
2522 if (period <= 250) np->minsync = 10; in sym_prepare_setting()
2523 else if (period <= 303) np->minsync = 11; in sym_prepare_setting()
2524 else if (period <= 500) np->minsync = 12; in sym_prepare_setting()
2525 else np->minsync = howmany(period, 40); in sym_prepare_setting()
2528 * Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2). in sym_prepare_setting()
2530 if (np->minsync < 25 && in sym_prepare_setting()
2531 !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3))) in sym_prepare_setting()
2532 np->minsync = 25; in sym_prepare_setting()
2533 else if (np->minsync < 12 && in sym_prepare_setting()
2534 !(np->features & (FE_ULTRA2|FE_ULTRA3))) in sym_prepare_setting()
2535 np->minsync = 12; in sym_prepare_setting()
2540 period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz); in sym_prepare_setting()
2541 np->maxsync = period > 2540 ? 254 : period / 10; in sym_prepare_setting()
2546 if ((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) { in sym_prepare_setting()
2547 if (np->clock_khz == 160000) { in sym_prepare_setting()
2548 np->minsync_dt = 9; in sym_prepare_setting()
2549 np->maxsync_dt = 50; in sym_prepare_setting()
2550 np->maxoffs_dt = 62; in sym_prepare_setting()
2557 if (np->features & FE_DAC) in sym_prepare_setting()
2559 np->rv_ccntl1 |= (XTIMOD | EXTIBMV); in sym_prepare_setting()
2561 np->rv_ccntl1 |= (DDAC); in sym_prepare_setting()
2567 if (np->features & FE_NOPM) in sym_prepare_setting()
2568 np->rv_ccntl0 |= (ENPMJ); in sym_prepare_setting()
2575 if (np->device_id == PCI_ID_LSI53C1010 && in sym_prepare_setting()
2576 np->revision_id < 0x2) in sym_prepare_setting()
2577 np->rv_ccntl0 |= DILS; in sym_prepare_setting()
2584 burst_max = burst_code(np->sv_dmode, np->sv_ctest4, in sym_prepare_setting()
2585 np->sv_ctest5); in sym_prepare_setting()
2588 if (burst_max > np->maxburst) in sym_prepare_setting()
2589 burst_max = np->maxburst; in sym_prepare_setting()
2592 * DEL 352 - 53C810 Rev x11 - Part Number 609-0392140 - ITEM 2. in sym_prepare_setting()
2597 * LOAD/STORE instructions does not need this work-around. in sym_prepare_setting()
2599 if ((np->device_id == PCI_ID_SYM53C810 && in sym_prepare_setting()
2600 np->revision_id >= 0x10 && np->revision_id <= 0x11) || in sym_prepare_setting()
2601 (np->device_id == PCI_ID_SYM53C860 && in sym_prepare_setting()
2602 np->revision_id <= 0x1)) in sym_prepare_setting()
2603 np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); in sym_prepare_setting()
2607 * If we are using on-board RAM for scripts, prefetch (PFEN) in sym_prepare_setting()
2611 if (np->features & FE_ERL) in sym_prepare_setting()
2612 np->rv_dmode |= ERL; /* Enable Read Line */ in sym_prepare_setting()
2613 if (np->features & FE_BOF) in sym_prepare_setting()
2614 np->rv_dmode |= BOF; /* Burst Opcode Fetch */ in sym_prepare_setting()
2615 if (np->features & FE_ERMP) in sym_prepare_setting()
2616 np->rv_dmode |= ERMP; /* Enable Read Multiple */ in sym_prepare_setting()
2618 if ((np->features & FE_PFEN) && !np->ram_ba) in sym_prepare_setting()
2620 if (np->features & FE_PFEN) in sym_prepare_setting()
2622 np->rv_dcntl |= PFEN; /* Prefetch Enable */ in sym_prepare_setting()
2623 if (np->features & FE_CLSE) in sym_prepare_setting()
2624 np->rv_dcntl |= CLSE; /* Cache Line Size Enable */ in sym_prepare_setting()
2625 if (np->features & FE_WRIE) in sym_prepare_setting()
2626 np->rv_ctest3 |= WRIE; /* Write and Invalidate */ in sym_prepare_setting()
2627 if (np->features & FE_DFS) in sym_prepare_setting()
2628 np->rv_ctest5 |= DFS; /* Dma Fifo Size */ in sym_prepare_setting()
2634 np->rv_ctest4 |= MPEE; /* Master parity checking */ in sym_prepare_setting()
2636 np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */ in sym_prepare_setting()
2641 np->myaddr = 255; in sym_prepare_setting()
2647 if (np->myaddr == 255) { in sym_prepare_setting()
2648 np->myaddr = INB(nc_scid) & 0x07; in sym_prepare_setting()
2649 if (!np->myaddr) in sym_prepare_setting()
2650 np->myaddr = SYM_SETUP_HOST_ID; in sym_prepare_setting()
2660 * - LVD capable chips (895/895A/896/1010) report the in sym_prepare_setting()
2662 * - For previous generation chips (825/825A/875), in sym_prepare_setting()
2666 np->scsi_mode = SMODE_SE; in sym_prepare_setting()
2667 if (np->features & (FE_ULTRA2|FE_ULTRA3)) in sym_prepare_setting()
2668 np->scsi_mode = (np->sv_stest4 & SMODE); in sym_prepare_setting()
2669 else if (np->features & FE_DIFF) { in sym_prepare_setting()
2671 if (np->sv_scntl3) { in sym_prepare_setting()
2672 if (np->sv_stest2 & 0x20) in sym_prepare_setting()
2673 np->scsi_mode = SMODE_HVD; in sym_prepare_setting()
2675 else if (nvram->type == SYM_SYMBIOS_NVRAM) { in sym_prepare_setting()
2677 np->scsi_mode = SMODE_HVD; in sym_prepare_setting()
2681 np->scsi_mode = SMODE_HVD; in sym_prepare_setting()
2683 if (np->scsi_mode == SMODE_HVD) in sym_prepare_setting()
2684 np->rv_stest2 |= 0x20; in sym_prepare_setting()
2693 (nvram->type == SYM_SYMBIOS_NVRAM || in sym_prepare_setting()
2694 (nvram->type == SYM_TEKRAM_NVRAM && in sym_prepare_setting()
2695 np->device_id == PCI_ID_SYM53C895))) && in sym_prepare_setting()
2696 !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) in sym_prepare_setting()
2697 np->features |= FE_LED0; in sym_prepare_setting()
2704 np->rv_dcntl |= IRQM; in sym_prepare_setting()
2707 np->rv_dcntl |= (np->sv_dcntl & IRQM); in sym_prepare_setting()
2718 tcb_p tp = &np->target[i]; in sym_prepare_setting()
2720 tp->tinfo.user.scsi_version = tp->tinfo.current.scsi_version= 2; in sym_prepare_setting()
2721 tp->tinfo.user.spi_version = tp->tinfo.current.spi_version = 2; in sym_prepare_setting()
2722 tp->tinfo.user.period = np->minsync; in sym_prepare_setting()
2723 if (np->features & FE_ULTRA3) in sym_prepare_setting()
2724 tp->tinfo.user.period = np->minsync_dt; in sym_prepare_setting()
2725 tp->tinfo.user.offset = np->maxoffs; in sym_prepare_setting()
2726 tp->tinfo.user.width = np->maxwide ? BUS_16_BIT : BUS_8_BIT; in sym_prepare_setting()
2727 tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); in sym_prepare_setting()
2728 tp->usrtags = SYM_SETUP_MAX_TAG; in sym_prepare_setting()
2736 if (np->features & FE_ULTRA3) { in sym_prepare_setting()
2737 if (tp->tinfo.user.period <= 9 && in sym_prepare_setting()
2738 tp->tinfo.user.width == BUS_16_BIT) { in sym_prepare_setting()
2739 tp->tinfo.user.options |= PPR_OPT_DT; in sym_prepare_setting()
2740 tp->tinfo.user.offset = np->maxoffs_dt; in sym_prepare_setting()
2741 tp->tinfo.user.spi_version = 3; in sym_prepare_setting()
2745 if (!tp->usrtags) in sym_prepare_setting()
2746 tp->usrflags &= ~SYM_TAGS_ENABLED; in sym_prepare_setting()
2752 i = nvram->type; in sym_prepare_setting()
2753 printf("%s: %s NVRAM, ID %d, Fast-%d, %s, %s\n", sym_name(np), in sym_prepare_setting()
2756 np->myaddr, in sym_prepare_setting()
2757 (np->features & FE_ULTRA3) ? 80 : in sym_prepare_setting()
2758 (np->features & FE_ULTRA2) ? 40 : in sym_prepare_setting()
2759 (np->features & FE_ULTRA) ? 20 : 10, in sym_prepare_setting()
2760 sym_scsi_bus_mode(np->scsi_mode), in sym_prepare_setting()
2761 (np->rv_scntl0 & 0xa) ? "parity checking" : "NO parity"); in sym_prepare_setting()
2768 np->rv_dcntl & IRQM ? "totem pole" : "open drain", in sym_prepare_setting()
2769 np->ram_ba ? ", using on-chip SRAM" : ""); in sym_prepare_setting()
2770 printf("%s: using %s firmware.\n", sym_name(np), np->fw_name); in sym_prepare_setting()
2771 if (np->features & FE_NOPM) in sym_prepare_setting()
2781 sym_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl, in sym_prepare_setting()
2782 np->sv_ctest3, np->sv_ctest4, np->sv_ctest5); in sym_prepare_setting()
2786 sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl, in sym_prepare_setting()
2787 np->rv_ctest3, np->rv_ctest4, np->rv_ctest5); in sym_prepare_setting()
2809 tcb_p tp = &np->target[cp->target]; in sym_prepare_nego()
2813 * Early C1010 chips need a work-around for DT in sym_prepare_nego()
2816 if (!(np->features & FE_U3EN)) in sym_prepare_nego()
2817 tp->tinfo.goal.options = 0; in sym_prepare_nego()
2821 if (tp->tinfo.goal.options & PPR_OPT_MASK) in sym_prepare_nego()
2826 else if (tp->tinfo.current.width != tp->tinfo.goal.width) in sym_prepare_nego()
2831 else if (tp->tinfo.current.period != tp->tinfo.goal.period || in sym_prepare_nego()
2832 tp->tinfo.current.offset != tp->tinfo.goal.offset) in sym_prepare_nego()
2840 msgptr[msglen++] = tp->tinfo.goal.period; in sym_prepare_nego()
2841 msgptr[msglen++] = tp->tinfo.goal.offset; in sym_prepare_nego()
2847 msgptr[msglen++] = tp->tinfo.goal.width; in sym_prepare_nego()
2853 msgptr[msglen++] = tp->tinfo.goal.period; in sym_prepare_nego()
2855 msgptr[msglen++] = tp->tinfo.goal.offset; in sym_prepare_nego()
2856 msgptr[msglen++] = tp->tinfo.goal.width; in sym_prepare_nego()
2857 msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_DT; in sym_prepare_nego()
2861 cp->nego_status = nego; in sym_prepare_nego()
2864 tp->nego_cp = cp; /* Keep track a nego will be performed */ in sym_prepare_nego()
2891 if (np->last_cp && np->iarb_count < np->iarb_max) { in sym_put_start_queue()
2892 np->last_cp->host_flags |= HF_HINT_IARB; in sym_put_start_queue()
2893 ++np->iarb_count; in sym_put_start_queue()
2896 np->iarb_count = 0; in sym_put_start_queue()
2897 np->last_cp = cp; in sym_put_start_queue()
2904 qidx = np->squeueput + 2; in sym_put_start_queue()
2907 np->squeue [qidx] = cpu_to_scr(np->idletask_ba); in sym_put_start_queue()
2909 np->squeue [np->squeueput] = cpu_to_scr(cp->ccb_ba); in sym_put_start_queue()
2911 np->squeueput = qidx; in sym_put_start_queue()
2914 printf ("%s: queuepos=%d.\n", sym_name (np), np->squeueput); in sym_put_start_queue()
2921 OUTB (nc_istat, SIGP|np->istat_sem); in sym_put_start_queue()
2943 * Some 896 and 876 chip revisions may hang-up if we set
2955 for (i = 1000000 ; i ; --i) { in sym_soft_reset()
2996 OUTB (nc_dcntl, (np->rv_dcntl & IRQM)); in sym_reset_scsi_bus()
3011 ((INW(nc_sbdl) & 0xff) << 9) | /* d7-0 */ in sym_reset_scsi_bus()
3012 ((INW(nc_sbdl) & 0xff00) << 10) | /* d15-8 */ in sym_reset_scsi_bus()
3015 if (!(np->features & FE_WIDE)) in sym_reset_scsi_bus()
3021 printf("%s: %sdp0,d7-0,rst,req,ack,bsy,sel,atn,msg,c/d,i/o = " in sym_reset_scsi_bus()
3024 (np->features & FE_WIDE) ? "dp1,d15-8," : "", in sym_reset_scsi_bus()
3040 * so-called `flag' and prior to dealing with the data.
3051 i = np->dqueueget; in sym_wakeup_done()
3053 dsa = scr_to_cpu(np->dqueue[i]); in sym_wakeup_done()
3056 np->dqueue[i] = 0; in sym_wakeup_done()
3070 np->dqueueget = i; in sym_wakeup_done()
3085 sym_que_splice(&np->busy_ccbq, &np->comp_ccbq); in sym_flush_busy_queue()
3086 sym_que_init(&np->busy_ccbq); in sym_flush_busy_queue()
3118 phys = np->squeue_ba; in sym_init()
3120 np->squeue[i] = cpu_to_scr(np->idletask_ba); in sym_init()
3121 np->squeue[i+1] = cpu_to_scr(phys + (i+2)*4); in sym_init()
3123 np->squeue[MAX_QUEUE*2-1] = cpu_to_scr(phys); in sym_init()
3128 np->squeueput = 0; in sym_init()
3133 phys = np->dqueue_ba; in sym_init()
3135 np->dqueue[i] = 0; in sym_init()
3136 np->dqueue[i+1] = cpu_to_scr(phys + (i+2)*4); in sym_init()
3138 np->dqueue[MAX_QUEUE*2-1] = cpu_to_scr(phys); in sym_init()
3143 np->dqueueget = 0; in sym_init()
3150 np->fw_patch(np); in sym_init()
3163 OUTB (nc_scntl0, np->rv_scntl0 | 0xc0); in sym_init()
3164 /* full arb., ena parity, par->ATN */ in sym_init()
3167 sym_selectclock(np, np->rv_scntl3); /* Select SCSI clock */ in sym_init()
3169 OUTB (nc_scid , RRE|np->myaddr); /* Adapter SCSI address */ in sym_init()
3170 OUTW (nc_respid, 1ul<<np->myaddr); /* Id to respond to */ in sym_init()
3172 OUTB (nc_dmode , np->rv_dmode); /* Burst length, dma mode */ in sym_init()
3173 OUTB (nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */ in sym_init()
3175 OUTB (nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */ in sym_init()
3176 OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */ in sym_init()
3177 OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */ in sym_init()
3180 if (np->features & FE_C10) in sym_init()
3181 OUTB (nc_stest2, np->rv_stest2); in sym_init()
3183 OUTB (nc_stest2, EXT|np->rv_stest2); in sym_init()
3189 * For now, disable AIP generation on C1010-66. in sym_init()
3191 if (np->device_id == PCI_ID_LSI53C1010_2) in sym_init()
3201 if (np->device_id == PCI_ID_LSI53C1010 && in sym_init()
3202 /* np->revision_id < 0xff */ 1) in sym_init()
3206 * DEL 441 - 53C876 Rev 5 - Part Number 609-0392787/2788 - ITEM 2. in sym_init()
3208 * regardless revision id (kind of post-chip-design feature. ;-)) in sym_init()
3210 if (np->device_id == PCI_ID_SYM53C875) in sym_init()
3212 else if (np->device_id == PCI_ID_SYM53C896) in sym_init()
3213 np->rv_ccntl0 |= DPR; in sym_init()
3220 if (np->features & (FE_DAC|FE_NOPM)) { in sym_init()
3221 OUTB (nc_ccntl0, np->rv_ccntl0); in sym_init()
3222 OUTB (nc_ccntl1, np->rv_ccntl1); in sym_init()
3229 if (np->features & FE_NOPM) { in sym_init()
3238 if (np->features & FE_LED0) in sym_init()
3240 else if (np->features & FE_LEDC) in sym_init()
3254 if (np->features & (FE_ULTRA2|FE_ULTRA3)) { in sym_init()
3260 np->scsi_mode = INB (nc_stest4) & SMODE; in sym_init()
3270 tcb_p tp = &np->target[i]; in sym_init()
3272 tp->to_reset = 0; in sym_init()
3273 tp->head.sval = 0; in sym_init()
3274 tp->head.wval = np->rv_scntl3; in sym_init()
3275 tp->head.uval = 0; in sym_init()
3277 tp->tinfo.current.period = 0; in sym_init()
3278 tp->tinfo.current.offset = 0; in sym_init()
3279 tp->tinfo.current.width = BUS_8_BIT; in sym_init()
3280 tp->tinfo.current.options = 0; in sym_init()
3284 * Download SCSI SCRIPTS to on-chip RAM if present, in sym_init()
3287 if (np->ram_ba) { in sym_init()
3291 if (np->ram_ws == 8192) { in sym_init()
3292 OUTRAM_OFF(4096, np->scriptb0, np->scriptb_sz); in sym_init()
3293 OUTL (nc_mmws, np->scr_ram_seg); in sym_init()
3294 OUTL (nc_mmrs, np->scr_ram_seg); in sym_init()
3295 OUTL (nc_sfs, np->scr_ram_seg); in sym_init()
3300 OUTRAM_OFF(0, np->scripta0, np->scripta_sz); in sym_init()
3305 np->istat_sem = 0; in sym_init()
3307 OUTL (nc_dsa, np->hcb_ba); in sym_init()
3314 xpt_async(AC_BUS_RESET, np->path, NULL); in sym_init()
3324 u32 clk = np->clock_khz; /* SCSI clock frequency in kHz */ in sym_getsync()
3325 int div = np->clock_divn; /* Number of divisors supported */ in sym_getsync()
3332 * Compute the synchronous period in tenths of nano-seconds in sym_getsync()
3349 * to 5 Mega-transfers per second and may result in in sym_getsync()
3353 if ((np->features & (FE_C10|FE_U3EN)) == FE_C10) { in sym_getsync()
3359 --div; in sym_getsync()
3366 if (div == np->clock_divn) { /* Are we too fast ? */ in sym_getsync()
3367 ret = -1; in sym_getsync()
3379 while (div-- > 0) in sym_getsync()
3389 fak = (kpc - 1) / (div_10M[div] << 1) + 1 - 2; in sym_getsync()
3390 /* ret = ((2+fak)*div_10M[div])/np->clock_khz; */ in sym_getsync()
3393 fak = (kpc - 1) / div_10M[div] + 1 - 4; in sym_getsync()
3394 /* ret = ((4+fak)*div_10M[div])/np->clock_khz; */ in sym_getsync()
3400 if (fak > 2) {fak = 2; ret = -1;} in sym_getsync()
3420 tcb_p tp = &np->target[target]; in sym_xpt_async_transfer_neg()
3422 sts = xpt_create_path(&path, NULL, cam_sim_path(np->sim), target, in sym_xpt_async_transfer_neg()
3435 cts.protocol_version = tp->tinfo.current.scsi_version; in sym_xpt_async_transfer_neg()
3436 cts.transport_version = tp->tinfo.current.spi_version; in sym_xpt_async_transfer_neg()
3440 cts__spi.sync_period = tp->tinfo.current.period; in sym_xpt_async_transfer_neg()
3442 cts__spi.sync_offset = tp->tinfo.current.offset; in sym_xpt_async_transfer_neg()
3444 cts__spi.bus_width = tp->tinfo.current.width; in sym_xpt_async_transfer_neg()
3446 cts__spi.ppr_options = tp->tinfo.current.options; in sym_xpt_async_transfer_neg()
3473 tcb_p tp = &np->target[cp->target]; in sym_setwide()
3480 tp->tinfo.goal.width = tp->tinfo.current.width = wide; in sym_setwide()
3481 tp->tinfo.current.offset = 0; in sym_setwide()
3482 tp->tinfo.current.period = 0; in sym_setwide()
3483 tp->tinfo.current.options = 0; in sym_setwide()
3485 sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_WDTR); in sym_setwide()
3495 tcb_p tp = &np->target[cp->target]; in sym_setsync()
3496 u_char wide = (cp->phys.select.sel_scntl3 & EWS) ? 1 : 0; in sym_setsync()
3503 tp->tinfo.goal.period = tp->tinfo.current.period = per; in sym_setsync()
3504 tp->tinfo.goal.offset = tp->tinfo.current.offset = ofs; in sym_setsync()
3505 tp->tinfo.goal.options = tp->tinfo.current.options = 0; in sym_setsync()
3507 sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_SDTR); in sym_setsync()
3517 tcb_p tp = &np->target[cp->target]; in sym_setpprot()
3524 tp->tinfo.goal.width = tp->tinfo.current.width = wide; in sym_setpprot()
3525 tp->tinfo.goal.period = tp->tinfo.current.period = per; in sym_setpprot()
3526 tp->tinfo.goal.offset = tp->tinfo.current.offset = ofs; in sym_setpprot()
3527 tp->tinfo.goal.options = tp->tinfo.current.options = dt; in sym_setpprot()
3529 sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_PPR); in sym_setpprot()
3546 ccb = cp->cam_ccb; in sym_settrans()
3549 assert (target == (cp->target & 0xf)); in sym_settrans()
3550 tp = &np->target[target]; in sym_settrans()
3552 sval = tp->head.sval; in sym_settrans()
3553 wval = tp->head.wval; in sym_settrans()
3554 uval = tp->head.uval; in sym_settrans()
3558 sval, wval, uval, np->rv_scntl3); in sym_settrans()
3563 if (!(np->features & FE_C10)) in sym_settrans()
3573 if (!(np->features & FE_C10)) in sym_settrans()
3592 if (np->features & FE_C10) { in sym_settrans()
3595 assert(np->features & FE_U3EN); in sym_settrans()
3607 if (tp->head.sval == sval && in sym_settrans()
3608 tp->head.wval == wval && in sym_settrans()
3609 tp->head.uval == uval) in sym_settrans()
3611 tp->head.sval = sval; in sym_settrans()
3612 tp->head.wval = wval; in sym_settrans()
3613 tp->head.uval = uval; in sym_settrans()
3619 if (per < 50 && !(np->features & FE_C10)) in sym_settrans()
3625 OUTB (nc_sxfer, tp->head.sval); in sym_settrans()
3626 OUTB (nc_scntl3, tp->head.wval); in sym_settrans()
3628 if (np->features & FE_C10) { in sym_settrans()
3629 OUTB (nc_scntl4, tp->head.uval); in sym_settrans()
3635 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { in sym_settrans()
3637 if (cp->target != target) in sym_settrans()
3639 cp->phys.select.sel_scntl3 = tp->head.wval; in sym_settrans()
3640 cp->phys.select.sel_sxfer = tp->head.sval; in sym_settrans()
3641 if (np->features & FE_C10) { in sym_settrans()
3642 cp->phys.select.sel_scntl4 = tp->head.uval; in sym_settrans()
3650 * sym0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ name (dsp:dbc).
3684 if (dsp > np->scripta_ba && in sym_log_hard_error()
3685 dsp <= np->scripta_ba + np->scripta_sz) { in sym_log_hard_error()
3686 script_ofs = dsp - np->scripta_ba; in sym_log_hard_error()
3687 script_size = np->scripta_sz; in sym_log_hard_error()
3688 script_base = (u_char *) np->scripta0; in sym_log_hard_error()
3691 else if (np->scriptb_ba < dsp && in sym_log_hard_error()
3692 dsp <= np->scriptb_ba + np->scriptb_sz) { in sym_log_hard_error()
3693 script_ofs = dsp - np->scriptb_ba; in sym_log_hard_error()
3694 script_size = np->scriptb_sz; in sym_log_hard_error()
3695 script_base = (u_char *) np->scriptb0; in sym_log_hard_error()
3704 printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n", in sym_log_hard_error()
3727 pci_sts = pci_read_config(np->device, PCIR_STATUS, 2); in sym_log_hard_error()
3729 pci_write_config(np->device, PCIR_STATUS, pci_sts, 2); in sym_log_hard_error()
3749 * SIP or DIP flag is set, there is a small window of time
3755 * - SCSI parity error + Phase mismatch (PAR|MA)
3757 * and the device switches to msg-in phase inside a
3759 * - SCSI parity error + Unexpected disconnect (PAR|UDC)
3762 * - Some combinations of STO, PAR, UDC, ...
3795 * ask me for any guarantee that it will never fail. :-)
3815 OUTB (nc_istat, (istat & SIGP) | INTF | np->istat_sem); in sym_intr1()
3835 * Even if DMA interrupt stacking is very unlikely to in sym_intr1()
3894 * On STO and UDC, we complete the CCB with the corres- in sym_intr1()
3898 xpt_print_path(np->path); in sym_intr1()
3904 OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ in sym_intr1()
3965 * the DMA fifo for a write to memory that was executing.
3978 * allocated from the same 4 GB memory window, so there
4004 OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ in sym_recover_scsi_int()
4013 cp->host_status = hsts; in sym_recover_scsi_int()
4060 * spi2-r12 11.2.3 says a transceiver mode change must
4074 xpt_print_path(np->path); in sym_int_sbmc()
4076 sym_scsi_bus_mode(np->scsi_mode), sym_scsi_bus_mode(scsi_mode)); in sym_int_sbmc()
4094 * - The complete scatter entry has been transferred
4099 * - A phase mismatch occurs before the MOV finished
4104 * - A phase mismatch occurs before the MOV finished and
4149 cp->xerr_status |= XE_PARITY_ERR; in sym_int_par()
4154 np->msgout[0] = (phase == 7) ? M_PARITY : M_ID_ERROR; in sym_int_par()
4221 * Donnot take into account dma fifo and various buffers in in sym_int_ma()
4229 if (np->features & FE_DFBC) in sym_int_ma()
4235 * Read DFIFO, CTEST[4-6] using 1 PCI bus ownership. in sym_int_ma()
4240 * Calculate remaining bytes in DMA fifo. in sym_int_ma()
4245 (dfifo & 0xff)) - rest) & 0x3ff; in sym_int_ma()
4247 delta = ((dfifo & 0xff) - rest) & 0x7f; in sym_int_ma()
4251 * The data in the dma fifo has not been transferred to in sym_int_ma()
4252 * the target -> add the amount to the rest in sym_int_ma()
4259 if (!(np->features & FE_C10)) in sym_int_ma()
4261 if (cp && (cp->phys.select.sel_scntl3 & EWS)) { in sym_int_ma()
4264 if (!(np->features & FE_C10)) in sym_int_ma()
4271 OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */ in sym_int_ma()
4288 if (dsp > np->scripta_ba && in sym_int_ma()
4289 dsp <= np->scripta_ba + np->scripta_sz) { in sym_int_ma()
4290 vdsp = (u32 *)((char*)np->scripta0 + (dsp-np->scripta_ba-8)); in sym_int_ma()
4293 else if (dsp > np->scriptb_ba && in sym_int_ma()
4294 dsp <= np->scriptb_ba + np->scriptb_sz) { in sym_int_ma()
4295 vdsp = (u32 *)((char*)np->scriptb0 + (dsp-np->scriptb_ba-8)); in sym_int_ma()
4325 tblp = (u32 *) ((char*) &cp->phys + oadr); in sym_int_ma()
4359 printf ("phase change %x-%x %d@%08x resid=%d.\n", in sym_int_ma()
4378 nxtdsp = scr_to_cpu(cp->phys.pm0.ret); in sym_int_ma()
4380 nxtdsp = scr_to_cpu(cp->phys.pm1.ret); in sym_int_ma()
4387 pm = &cp->phys.pm0; in sym_int_ma()
4391 pm = &cp->phys.pm1; in sym_int_ma()
4402 pm->sg.addr = cpu_to_scr(oadr + olen - rest); in sym_int_ma()
4403 pm->sg.size = cpu_to_scr(rest); in sym_int_ma()
4404 pm->ret = cpu_to_scr(nxtdsp); in sym_int_ma()
4408 * - prepare the address to write the SWIDE from SCRIPTS, in sym_int_ma()
4409 * - compute the SCRIPTS address to restart from, in sym_int_ma()
4410 * - move current data pointer context by one byte. in sym_int_ma()
4413 if ((cmd & 7) == 1 && cp && (cp->phys.select.sel_scntl3 & EWS) && in sym_int_ma()
4422 tmp = scr_to_cpu(pm->sg.addr); in sym_int_ma()
4423 cp->phys.wresid.addr = cpu_to_scr(tmp); in sym_int_ma()
4424 pm->sg.addr = cpu_to_scr(tmp + 1); in sym_int_ma()
4425 tmp = scr_to_cpu(pm->sg.size); in sym_int_ma()
4426 cp->phys.wresid.size = cpu_to_scr((tmp&0xff000000) | 1); in sym_int_ma()
4427 pm->sg.size = cpu_to_scr(tmp - 1); in sym_int_ma()
4434 newcmd = pm->ret; in sym_int_ma()
4447 (unsigned)scr_to_cpu(pm->sg.addr), in sym_int_ma()
4448 (unsigned)scr_to_cpu(pm->sg.size), in sym_int_ma()
4449 (unsigned)scr_to_cpu(pm->ret)); in sym_int_ma()
4467 * COMMAND --> MSG IN SCSI parity error detected by target. in sym_int_ma()
4468 * COMMAND --> STATUS Bad command or refused by target. in sym_int_ma()
4469 * MSG OUT --> MSG IN Message rejected by target. in sym_int_ma()
4470 * MSG OUT --> COMMAND Bogus target that discards extended in sym_int_ma()
4487 dsp -= 8; in sym_int_ma()
4507 if (cp->tag != NO_TAG && olen - rest <= 3) { in sym_int_ma()
4508 cp->host_status = HS_BUSY; in sym_int_ma()
4509 np->msgout[0] = M_IDENTIFY | cp->lun; in sym_int_ma()
4539 * a given target/lun/task condition (-1 means all),
4561 while (i != np->squeueput) { in sym_dequeue_from_squeue()
4562 cp = sym_ccb_from_dsa(np, scr_to_cpu(np->squeue[i])); in sym_dequeue_from_squeue()
4566 cp->host_flags &= ~HF_HINT_IARB; in sym_dequeue_from_squeue()
4568 if ((target == -1 || cp->target == target) && in sym_dequeue_from_squeue()
4569 (lun == -1 || cp->lun == lun) && in sym_dequeue_from_squeue()
4570 (task == -1 || cp->tag == task)) { in sym_dequeue_from_squeue()
4571 sym_set_cam_status(cp->cam_ccb, CAM_REQUEUE_REQ); in sym_dequeue_from_squeue()
4572 sym_remque(&cp->link_ccbq); in sym_dequeue_from_squeue()
4573 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq); in sym_dequeue_from_squeue()
4577 np->squeue[j] = np->squeue[i]; in sym_dequeue_from_squeue()
4583 np->squeue[j] = np->squeue[i]; in sym_dequeue_from_squeue()
4584 np->squeueput = j; /* Update our current start queue pointer */ in sym_dequeue_from_squeue()
4586 return (i - j) / 2; in sym_dequeue_from_squeue()
4593 * - Not to be referenced either by devices or
4594 * SCRIPTS-related queues and datas.
4595 * - To have to be completed with an error condition
4609 while ((qp = sym_remque_head(&np->comp_ccbq)) != NULL) { in sym_flush_comp_queue()
4612 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); in sym_flush_comp_queue()
4614 if (cp->host_status == HS_WAIT) in sym_flush_comp_queue()
4616 ccb = cp->cam_ccb; in sym_flush_comp_queue()
4645 tcb_p tp = &np->target[cp->target]; in sym_sir_bad_scsi_status()
4647 u_char s_status = cp->ssss_status; in sym_sir_bad_scsi_status()
4648 u_char h_flags = cp->host_flags; in sym_sir_bad_scsi_status()
4658 i = (INL (nc_scratcha) - np->squeue_ba) / 4; in sym_sir_bad_scsi_status()
4665 if (np->last_cp) in sym_sir_bad_scsi_status()
4666 np->last_cp = NULL; in sym_sir_bad_scsi_status()
4697 (void) sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); in sym_sir_bad_scsi_status()
4704 cp->sv_scsi_status = cp->ssss_status; in sym_sir_bad_scsi_status()
4705 cp->sv_xerr_status = cp->xerr_status; in sym_sir_bad_scsi_status()
4706 cp->sv_resid = sym_compute_residual(np, cp); in sym_sir_bad_scsi_status()
4716 cp->scsi_smsg2[0] = M_IDENTIFY | cp->lun; in sym_sir_bad_scsi_status()
4727 * cp->nego_status is filled by sym_prepare_nego(). in sym_sir_bad_scsi_status()
4729 cp->nego_status = 0; in sym_sir_bad_scsi_status()
4731 if (tp->tinfo.current.options & PPR_OPT_MASK) in sym_sir_bad_scsi_status()
4733 else if (tp->tinfo.current.width != BUS_8_BIT) in sym_sir_bad_scsi_status()
4735 else if (tp->tinfo.current.offset != 0) in sym_sir_bad_scsi_status()
4739 sym_prepare_nego (np,cp, nego, &cp->scsi_smsg2[msglen]); in sym_sir_bad_scsi_status()
4743 cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg2)); in sym_sir_bad_scsi_status()
4744 cp->phys.smsg.size = cpu_to_scr(msglen); in sym_sir_bad_scsi_status()
4749 cp->phys.cmd.addr = cpu_to_scr(CCB_BA (cp, sensecmd)); in sym_sir_bad_scsi_status()
4750 cp->phys.cmd.size = cpu_to_scr(6); in sym_sir_bad_scsi_status()
4755 cp->sensecmd[0] = 0x03; in sym_sir_bad_scsi_status()
4756 cp->sensecmd[1] = cp->lun << 5; in sym_sir_bad_scsi_status()
4757 if (tp->tinfo.current.scsi_version > 2 || cp->lun > 7) in sym_sir_bad_scsi_status()
4758 cp->sensecmd[1] = 0; in sym_sir_bad_scsi_status()
4759 cp->sensecmd[4] = SYM_SNS_BBUF_LEN; in sym_sir_bad_scsi_status()
4760 cp->data_len = SYM_SNS_BBUF_LEN; in sym_sir_bad_scsi_status()
4765 bzero(cp->sns_bbuf, SYM_SNS_BBUF_LEN); in sym_sir_bad_scsi_status()
4766 cp->phys.sense.addr = cpu_to_scr(vtobus(cp->sns_bbuf)); in sym_sir_bad_scsi_status()
4767 cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN); in sym_sir_bad_scsi_status()
4774 cp->phys.head.savep = cpu_to_scr(startp); in sym_sir_bad_scsi_status()
4775 cp->phys.head.goalp = cpu_to_scr(startp + 16); in sym_sir_bad_scsi_status()
4776 cp->phys.head.lastp = cpu_to_scr(startp); in sym_sir_bad_scsi_status()
4777 cp->startp = cpu_to_scr(startp); in sym_sir_bad_scsi_status()
4779 cp->actualquirks = SYM_QUIRK_AUTOSAVE; in sym_sir_bad_scsi_status()
4780 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY; in sym_sir_bad_scsi_status()
4781 cp->ssss_status = S_ILLEGAL; in sym_sir_bad_scsi_status()
4782 cp->host_flags = (HF_SENSE|HF_DATA_IN); in sym_sir_bad_scsi_status()
4783 cp->xerr_status = 0; in sym_sir_bad_scsi_status()
4784 cp->extra_bytes = 0; in sym_sir_bad_scsi_status()
4786 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select)); in sym_sir_bad_scsi_status()
4812 * - lun=-1 means any logical UNIT otherwise a given one.
4813 * - task=-1 means any task, otherwise a given one.
4826 sym_que_splice(&np->busy_ccbq, &qtmp); in sym_clear_tasks()
4827 sym_que_init(&np->busy_ccbq); in sym_clear_tasks()
4837 ccb = cp->cam_ccb; in sym_clear_tasks()
4838 if (cp->host_status != HS_DISCONNECT || in sym_clear_tasks()
4839 cp->target != target || in sym_clear_tasks()
4840 (lun != -1 && cp->lun != lun) || in sym_clear_tasks()
4841 (task != -1 && in sym_clear_tasks()
4842 (cp->tag != NO_TAG && cp->scsi_smsg[2] != task))) { in sym_clear_tasks()
4843 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); in sym_clear_tasks()
4846 sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq); in sym_clear_tasks()
4881 * - If nothing, we just sent a M_ABORT message to the
4884 * - If the target is to be reset, we send it a M_RESET
4886 * - If a logical UNIT is to be cleared , we send the
4888 * - If an untagged task is to be aborted, we send the
4890 * - If a tagged task is to be aborted, we send the
4904 int target=-1, lun=-1, task; in sym_sir_task_recovery()
4918 tp = &np->target[i]; in sym_sir_task_recovery()
4919 if (tp->to_reset || in sym_sir_task_recovery()
4920 (tp->lun0p && tp->lun0p->to_clear)) { in sym_sir_task_recovery()
4924 if (!tp->lunmp) in sym_sir_task_recovery()
4927 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) { in sym_sir_task_recovery()
4932 if (target != -1) in sym_sir_task_recovery()
4940 if (target == -1) { in sym_sir_task_recovery()
4941 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { in sym_sir_task_recovery()
4943 if (cp->host_status != HS_DISCONNECT) in sym_sir_task_recovery()
4945 if (cp->to_abort) { in sym_sir_task_recovery()
4946 target = cp->target; in sym_sir_task_recovery()
4956 if (target != -1) { in sym_sir_task_recovery()
4957 tp = &np->target[target]; in sym_sir_task_recovery()
4958 np->abrt_sel.sel_id = target; in sym_sir_task_recovery()
4959 np->abrt_sel.sel_scntl3 = tp->head.wval; in sym_sir_task_recovery()
4960 np->abrt_sel.sel_sxfer = tp->head.sval; in sym_sir_task_recovery()
4961 OUTL(nc_dsa, np->hcb_ba); in sym_sir_task_recovery()
4973 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { in sym_sir_task_recovery()
4975 if (cp->host_status != HS_BUSY && in sym_sir_task_recovery()
4976 cp->host_status != HS_NEGOTIATE) in sym_sir_task_recovery()
4978 if (!cp->to_abort) in sym_sir_task_recovery()
4986 if (cp == np->last_cp) { in sym_sir_task_recovery()
4987 cp->to_abort = 0; in sym_sir_task_recovery()
5000 np->istat_sem = 0; in sym_sir_task_recovery()
5009 i = (INL (nc_scratcha) - np->squeue_ba) / 4; in sym_sir_task_recovery()
5010 i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); in sym_sir_task_recovery()
5015 assert(i && sym_get_cam_status(cp->cam_ccb) == CAM_REQUEUE_REQ); in sym_sir_task_recovery()
5020 if (cp->to_abort == 2) in sym_sir_task_recovery()
5021 sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT); in sym_sir_task_recovery()
5023 sym_set_cam_status(cp->cam_ccb, CAM_REQ_ABORTED); in sym_sir_task_recovery()
5036 tp = &np->target[target]; in sym_sir_task_recovery()
5038 np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg)); in sym_sir_task_recovery()
5045 if (tp->to_reset) { in sym_sir_task_recovery()
5046 np->abrt_msg[0] = M_RESET; in sym_sir_task_recovery()
5047 np->abrt_tbl.size = 1; in sym_sir_task_recovery()
5048 tp->to_reset = 0; in sym_sir_task_recovery()
5055 if (tp->lun0p && tp->lun0p->to_clear) in sym_sir_task_recovery()
5057 else if (tp->lunmp) { in sym_sir_task_recovery()
5059 if (tp->lunmp[k] && tp->lunmp[k]->to_clear) { in sym_sir_task_recovery()
5070 if (lun != -1) { in sym_sir_task_recovery()
5072 lp->to_clear = 0; /* We donnot expect to fail here */ in sym_sir_task_recovery()
5073 np->abrt_msg[0] = M_IDENTIFY | lun; in sym_sir_task_recovery()
5074 np->abrt_msg[1] = M_ABORT; in sym_sir_task_recovery()
5075 np->abrt_tbl.size = 2; in sym_sir_task_recovery()
5085 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { in sym_sir_task_recovery()
5087 if (cp->host_status != HS_DISCONNECT) in sym_sir_task_recovery()
5089 if (cp->target != target) in sym_sir_task_recovery()
5091 if (!cp->to_abort) in sym_sir_task_recovery()
5105 np->abrt_msg[0] = M_ABORT; in sym_sir_task_recovery()
5106 np->abrt_tbl.size = 1; in sym_sir_task_recovery()
5114 np->abrt_msg[0] = M_IDENTIFY | cp->lun; in sym_sir_task_recovery()
5122 if (cp->tag == NO_TAG) { in sym_sir_task_recovery()
5123 np->abrt_msg[1] = M_ABORT; in sym_sir_task_recovery()
5124 np->abrt_tbl.size = 2; in sym_sir_task_recovery()
5127 np->abrt_msg[1] = cp->scsi_smsg[1]; in sym_sir_task_recovery()
5128 np->abrt_msg[2] = cp->scsi_smsg[2]; in sym_sir_task_recovery()
5129 np->abrt_msg[3] = M_ABORT_TAG; in sym_sir_task_recovery()
5130 np->abrt_tbl.size = 4; in sym_sir_task_recovery()
5137 if (cp->to_abort == 2) in sym_sir_task_recovery()
5138 sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT); in sym_sir_task_recovery()
5139 cp->to_abort = 0; /* We donnot expect to fail here */ in sym_sir_task_recovery()
5148 tp = &np->target[target]; in sym_sir_task_recovery()
5153 if (np->abrt_msg[0] == M_ABORT) in sym_sir_task_recovery()
5159 * - Reset everything to async 8 bit in sym_sir_task_recovery()
5160 * - Tell ourself to negotiate next time :-) in sym_sir_task_recovery()
5161 * - Prepare to clear all disconnected CCBs for in sym_sir_task_recovery()
5162 * this target from our task list (lun=task=-1) in sym_sir_task_recovery()
5164 lun = -1; in sym_sir_task_recovery()
5165 task = -1; in sym_sir_task_recovery()
5166 if (np->abrt_msg[0] == M_RESET) { in sym_sir_task_recovery()
5167 tp->head.sval = 0; in sym_sir_task_recovery()
5168 tp->head.wval = np->rv_scntl3; in sym_sir_task_recovery()
5169 tp->head.uval = 0; in sym_sir_task_recovery()
5170 tp->tinfo.current.period = 0; in sym_sir_task_recovery()
5171 tp->tinfo.current.offset = 0; in sym_sir_task_recovery()
5172 tp->tinfo.current.width = BUS_8_BIT; in sym_sir_task_recovery()
5173 tp->tinfo.current.options = 0; in sym_sir_task_recovery()
5180 * or an ABORT message :-) in sym_sir_task_recovery()
5183 lun = np->abrt_msg[0] & 0x3f; in sym_sir_task_recovery()
5184 if (np->abrt_msg[1] == M_ABORT_TAG) in sym_sir_task_recovery()
5185 task = np->abrt_msg[2]; in sym_sir_task_recovery()
5192 i = (INL (nc_scratcha) - np->squeue_ba) / 4; in sym_sir_task_recovery()
5193 (void) sym_dequeue_from_squeue(np, i, target, lun, -1); in sym_sir_task_recovery()
5200 if (np->abrt_msg[0] == M_RESET) in sym_sir_task_recovery()
5201 xpt_async(AC_SENT_BDR, np->path, NULL); in sym_sir_task_recovery()
5210 sym_printl_hex("control msgout:", np->abrt_msg, in sym_sir_task_recovery()
5211 np->abrt_tbl.size); in sym_sir_task_recovery()
5212 np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size); in sym_sir_task_recovery()
5232 * - dp_sg = SYM_CONF_MAX_SG
5234 * - dp_sg < SYM_CONF_MAX_SG
5237 * - dp_ofs < 0
5240 * - dp_ofs = 0
5261 pm = &cp->phys.pm0; in sym_evaluate_dp()
5263 pm = &cp->phys.pm1; in sym_evaluate_dp()
5268 dp_scr = scr_to_cpu(pm->ret); in sym_evaluate_dp()
5269 dp_ofs -= scr_to_cpu(pm->sg.size); in sym_evaluate_dp()
5273 * If we are auto-sensing, then we are done. in sym_evaluate_dp()
5275 if (cp->host_flags & HF_SENSE) { in sym_evaluate_dp()
5286 tmp = scr_to_cpu(cp->phys.head.goalp); in sym_evaluate_dp()
5289 dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4); in sym_evaluate_dp()
5290 dp_sgmin = SYM_CONF_MAX_SG - cp->segments; in sym_evaluate_dp()
5307 --dp_sg; in sym_evaluate_dp()
5308 tmp = scr_to_cpu(cp->phys.data[dp_sg].size); in sym_evaluate_dp()
5319 tmp = scr_to_cpu(cp->phys.data[dp_sg].size); in sym_evaluate_dp()
5320 dp_ofs -= (tmp & 0xffffff); in sym_evaluate_dp()
5340 if (dp_sg > cp->ext_sg || in sym_evaluate_dp()
5341 (dp_sg == cp->ext_sg && dp_ofs > cp->ext_ofs)) { in sym_evaluate_dp()
5342 cp->ext_sg = dp_sg; in sym_evaluate_dp()
5343 cp->ext_ofs = dp_ofs; in sym_evaluate_dp()
5353 return -1; in sym_evaluate_dp()
5362 * is equivalent to a MODIFY DATA POINTER (offset=-1).
5375 * Not supported for auto-sense. in sym_modify_dp()
5377 if (cp->host_flags & HF_SENSE) in sym_modify_dp()
5392 dp_ret = cpu_to_scr(cp->phys.head.goalp); in sym_modify_dp()
5393 dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4); in sym_modify_dp()
5413 pm = &cp->phys.pm0; in sym_modify_dp()
5417 pm = &cp->phys.pm1; in sym_modify_dp()
5429 * corresponding to index dp_sg-1 prior to returning in sym_modify_dp()
5432 pm->ret = cpu_to_scr(dp_ret); in sym_modify_dp()
5433 tmp = scr_to_cpu(cp->phys.data[dp_sg-1].addr); in sym_modify_dp()
5434 tmp += scr_to_cpu(cp->phys.data[dp_sg-1].size) + dp_ofs; in sym_modify_dp()
5435 pm->sg.addr = cpu_to_scr(tmp); in sym_modify_dp()
5436 pm->sg.size = cpu_to_scr(-dp_ofs); in sym_modify_dp()
5471 * than our residual be zero. :-) in sym_compute_residual()
5473 if (cp->xerr_status & (XE_EXTRA_DATA|XE_SODL_UNRUN|XE_SWIDE_OVRUN)) { in sym_compute_residual()
5474 if (cp->xerr_status & XE_EXTRA_DATA) in sym_compute_residual()
5475 resid -= cp->extra_bytes; in sym_compute_residual()
5476 if (cp->xerr_status & XE_SODL_UNRUN) in sym_compute_residual()
5478 if (cp->xerr_status & XE_SWIDE_OVRUN) in sym_compute_residual()
5479 --resid; in sym_compute_residual()
5486 if (cp->phys.head.lastp == cp->phys.head.goalp) in sym_compute_residual()
5493 if (cp->startp == cp->phys.head.lastp || in sym_compute_residual()
5494 sym_evaluate_dp(np, cp, scr_to_cpu(cp->phys.head.lastp), in sym_compute_residual()
5496 return cp->data_len; in sym_compute_residual()
5500 * If we were auto-sensing, then we are done. in sym_compute_residual()
5502 if (cp->host_flags & HF_SENSE) { in sym_compute_residual()
5503 return -dp_ofs; in sym_compute_residual()
5510 resid = -cp->ext_ofs; in sym_compute_residual()
5511 for (dp_sg = cp->ext_sg; dp_sg < SYM_CONF_MAX_SG; ++dp_sg) { in sym_compute_residual()
5512 u_int tmp = scr_to_cpu(cp->phys.data[dp_sg].size); in sym_compute_residual()
5531 if (i-1>msg[1]) break; in sym_show_msg()
5532 printf ("-%x",msg[i]); in sym_show_msg()
5536 printf ("-%x",msg[1]); in sym_show_msg()
5598 sym_print_msg(cp, "sync msgin", np->msgin); in sym_sync_nego()
5606 if (cp->nego_status && cp->nego_status != NS_SYNC) in sym_sync_nego()
5615 per = np->msgin[3]; in sym_sync_nego()
5616 ofs = np->msgin[4]; in sym_sync_nego()
5622 if (ofs > np->maxoffs) in sym_sync_nego()
5623 {chg = 1; ofs = np->maxoffs;} in sym_sync_nego()
5625 if (ofs > tp->tinfo.user.offset) in sym_sync_nego()
5626 {chg = 1; ofs = tp->tinfo.user.offset;} in sym_sync_nego()
5631 if (per < np->minsync) in sym_sync_nego()
5632 {chg = 1; per = np->minsync;} in sym_sync_nego()
5634 if (per < tp->tinfo.user.period) in sym_sync_nego()
5635 {chg = 1; per = tp->tinfo.user.period;} in sym_sync_nego()
5666 np->msgout[0] = M_EXTENDED; in sym_sync_nego()
5667 np->msgout[1] = 3; in sym_sync_nego()
5668 np->msgout[2] = M_X_SYNC_REQ; in sym_sync_nego()
5669 np->msgout[3] = per; in sym_sync_nego()
5670 np->msgout[4] = ofs; in sym_sync_nego()
5672 cp->nego_status = NS_SYNC; in sym_sync_nego()
5675 sym_print_msg(cp, "sync msgout", np->msgout); in sym_sync_nego()
5678 np->msgin [0] = M_NOOP; in sym_sync_nego()
5699 sym_print_msg(cp, "ppr msgin", np->msgin); in sym_ppr_nego()
5706 per = np->msgin[3]; in sym_ppr_nego()
5707 ofs = np->msgin[5]; in sym_ppr_nego()
5708 wide = np->msgin[6]; in sym_ppr_nego()
5709 dt = np->msgin[7] & PPR_OPT_DT; in sym_ppr_nego()
5716 if (cp->nego_status && cp->nego_status != NS_PPR) in sym_ppr_nego()
5724 if (wide > np->maxwide) in sym_ppr_nego()
5725 {chg = 1; wide = np->maxwide;} in sym_ppr_nego()
5726 if (!wide || !(np->features & FE_ULTRA3)) in sym_ppr_nego()
5729 if (wide > tp->tinfo.user.width) in sym_ppr_nego()
5730 {chg = 1; wide = tp->tinfo.user.width;} in sym_ppr_nego()
5733 if (!(np->features & FE_U3EN)) /* Broken U3EN bit not supported */ in sym_ppr_nego()
5736 if (dt != (np->msgin[7] & PPR_OPT_MASK)) chg = 1; in sym_ppr_nego()
5740 if (ofs > np->maxoffs_dt) in sym_ppr_nego()
5741 {chg = 1; ofs = np->maxoffs_dt;} in sym_ppr_nego()
5743 else if (ofs > np->maxoffs) in sym_ppr_nego()
5744 {chg = 1; ofs = np->maxoffs;} in sym_ppr_nego()
5746 if (ofs > tp->tinfo.user.offset) in sym_ppr_nego()
5747 {chg = 1; ofs = tp->tinfo.user.offset;} in sym_ppr_nego()
5753 if (per < np->minsync_dt) in sym_ppr_nego()
5754 {chg = 1; per = np->minsync_dt;} in sym_ppr_nego()
5756 else if (per < np->minsync) in sym_ppr_nego()
5757 {chg = 1; per = np->minsync;} in sym_ppr_nego()
5759 if (per < tp->tinfo.user.period) in sym_ppr_nego()
5760 {chg = 1; per = tp->tinfo.user.period;} in sym_ppr_nego()
5792 np->msgout[0] = M_EXTENDED; in sym_ppr_nego()
5793 np->msgout[1] = 6; in sym_ppr_nego()
5794 np->msgout[2] = M_X_PPR_REQ; in sym_ppr_nego()
5795 np->msgout[3] = per; in sym_ppr_nego()
5796 np->msgout[4] = 0; in sym_ppr_nego()
5797 np->msgout[5] = ofs; in sym_ppr_nego()
5798 np->msgout[6] = wide; in sym_ppr_nego()
5799 np->msgout[7] = dt; in sym_ppr_nego()
5801 cp->nego_status = NS_PPR; in sym_ppr_nego()
5804 sym_print_msg(cp, "ppr msgout", np->msgout); in sym_ppr_nego()
5807 np->msgin [0] = M_NOOP; in sym_ppr_nego()
5819 tp->tinfo.goal.options = 0; in sym_ppr_nego()
5820 tp->tinfo.goal.width = wide; in sym_ppr_nego()
5821 tp->tinfo.goal.period = per; in sym_ppr_nego()
5822 tp->tinfo.goal.offset = ofs; in sym_ppr_nego()
5838 sym_print_msg(cp, "wide msgin", np->msgin); in sym_wide_nego()
5846 if (cp->nego_status && cp->nego_status != NS_WIDE) in sym_wide_nego()
5855 wide = np->msgin[3]; in sym_wide_nego()
5860 if (wide > np->maxwide) in sym_wide_nego()
5861 {chg = 1; wide = np->maxwide;} in sym_wide_nego()
5863 if (wide > tp->tinfo.user.width) in sym_wide_nego()
5864 {chg = 1; wide = tp->tinfo.user.width;} in sym_wide_nego()
5885 if (tp->tinfo.goal.offset) { in sym_wide_nego()
5886 np->msgout[0] = M_EXTENDED; in sym_wide_nego()
5887 np->msgout[1] = 3; in sym_wide_nego()
5888 np->msgout[2] = M_X_SYNC_REQ; in sym_wide_nego()
5889 np->msgout[3] = tp->tinfo.goal.period; in sym_wide_nego()
5890 np->msgout[4] = tp->tinfo.goal.offset; in sym_wide_nego()
5893 sym_print_msg(cp, "sync msgout", np->msgout); in sym_wide_nego()
5896 cp->nego_status = NS_SYNC; in sym_wide_nego()
5912 np->msgout[0] = M_EXTENDED; in sym_wide_nego()
5913 np->msgout[1] = 2; in sym_wide_nego()
5914 np->msgout[2] = M_X_WIDE_REQ; in sym_wide_nego()
5915 np->msgout[3] = wide; in sym_wide_nego()
5917 np->msgin [0] = M_NOOP; in sym_wide_nego()
5919 cp->nego_status = NS_WIDE; in sym_wide_nego()
5922 sym_print_msg(cp, "wide msgout", np->msgout); in sym_wide_nego()
5946 switch (cp->nego_status) { in sym_nego_default()
5951 tp->tinfo.goal.options = 0; in sym_nego_default()
5952 if (tp->tinfo.goal.period < np->minsync) in sym_nego_default()
5953 tp->tinfo.goal.period = np->minsync; in sym_nego_default()
5954 if (tp->tinfo.goal.offset > np->maxoffs) in sym_nego_default()
5955 tp->tinfo.goal.offset = np->maxoffs; in sym_nego_default()
5965 np->msgin [0] = M_NOOP; in sym_nego_default()
5966 np->msgout[0] = M_NOOP; in sym_nego_default()
5967 cp->nego_status = 0; in sym_nego_default()
5989 tcb_p tp = &np->target[target]; in sym_int_sir()
5999 * or has been auto-sensed. in sym_int_sir()
6044 np->msgout[0] = M_RESET; in sym_int_sir()
6051 np->msgout[0] = M_ABORT; in sym_int_sir()
6058 np->msgout[0] = M_ABORT_TAG; in sym_int_sir()
6065 np->lastmsg = np->msgout[0]; in sym_int_sir()
6066 np->msgout[0] = M_NOOP; in sym_int_sir()
6068 sym_name (np), target, np->lastmsg); in sym_int_sir()
6075 np->lastmsg = np->msgout[0]; in sym_int_sir()
6076 np->msgout[0] = M_NOOP; in sym_int_sir()
6078 if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) { in sym_int_sir()
6080 cp->xerr_status &= ~XE_PARITY_ERR; in sym_int_sir()
6081 if (!cp->xerr_status) in sym_int_sir()
6101 sym_print_msg(cp, "M_REJECT to send for ", np->msgin); in sym_int_sir()
6102 np->msgout[0] = M_REJECT; in sym_int_sir()
6113 cp->xerr_status |= XE_SWIDE_OVRUN; in sym_int_sir()
6124 cp->xerr_status |= XE_SODL_UNRUN; in sym_int_sir()
6136 cp->xerr_status |= XE_EXTRA_DATA; in sym_int_sir()
6137 cp->extra_bytes += INL (nc_scratcha); in sym_int_sir()
6146 cp->xerr_status |= XE_BAD_PHASE; in sym_int_sir()
6155 switch (np->msgin [0]) { in sym_int_sir()
6162 switch (np->msgin [2]) { in sym_int_sir()
6165 sym_print_msg(cp,"modify DP",np->msgin); in sym_int_sir()
6166 tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + in sym_int_sir()
6167 (np->msgin[5]<<8) + (np->msgin[6]); in sym_int_sir()
6188 * WIDE RESIDUE messages are aliased as MODIFY DP (-1). in sym_int_sir()
6192 sym_print_msg(cp,"ign wide residue", np->msgin); in sym_int_sir()
6193 sym_modify_dp(np, cp, -1); in sym_int_sir()
6201 scr_to_cpu(np->lastmsg), np->msgout[0]); in sym_int_sir()
6214 sym_print_msg(cp, "WEIRD message received", np->msgin); in sym_int_sir()
6253 tcb_p tp = &np->target[tn]; in sym_get_ccb()
6262 if (sym_que_empty(&np->free_ccbq)) in sym_get_ccb()
6264 qp = sym_remque_head(&np->free_ccbq); in sym_get_ccb()
6273 if (!lp && sym_is_bit(tp->lun_map, ln)) { in sym_get_ccb()
6286 if (!sym_is_bit(tp->busy0_map, ln)) in sym_get_ccb()
6287 sym_set_bit(tp->busy0_map, ln); in sym_get_ccb()
6296 if (lp->busy_itl != 0) in sym_get_ccb()
6301 if (!lp->cb_tags) { in sym_get_ccb()
6303 if (!lp->cb_tags) in sym_get_ccb()
6312 if (lp->busy_itlq < SYM_CONF_MAX_TASK) { in sym_get_ccb()
6313 tag = lp->cb_tags[lp->ia_tag]; in sym_get_ccb()
6314 if (++lp->ia_tag == SYM_CONF_MAX_TASK) in sym_get_ccb()
6315 lp->ia_tag = 0; in sym_get_ccb()
6316 lp->itlq_tbl[tag] = cpu_to_scr(cp->ccb_ba); in sym_get_ccb()
6317 ++lp->busy_itlq; in sym_get_ccb()
6318 lp->head.resel_sa = in sym_get_ccb()
6330 if (lp->busy_itlq != 0 || lp->busy_itl != 0) in sym_get_ccb()
6337 lp->busy_itl = 1; in sym_get_ccb()
6338 lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba); in sym_get_ccb()
6339 lp->head.resel_sa = in sym_get_ccb()
6346 sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); in sym_get_ccb()
6351 cp->to_abort = 0; in sym_get_ccb()
6352 cp->tag = tag; in sym_get_ccb()
6353 cp->target = tn; in sym_get_ccb()
6354 cp->lun = ln; in sym_get_ccb()
6364 sym_insque_head(&cp->link_ccbq, &np->free_ccbq); in sym_get_ccb()
6373 tcb_p tp = &np->target[cp->target]; in sym_free_ccb()
6374 lcb_p lp = sym_lp(tp, cp->lun); in sym_free_ccb()
6377 PRINT_LUN(np, cp->target, cp->lun); in sym_free_ccb()
6378 printf ("ccb @%p freeing tag %d.\n", cp, cp->tag); in sym_free_ccb()
6388 if (cp->tag != NO_TAG) { in sym_free_ccb()
6392 lp->cb_tags[lp->if_tag] = cp->tag; in sym_free_ccb()
6393 if (++lp->if_tag == SYM_CONF_MAX_TASK) in sym_free_ccb()
6394 lp->if_tag = 0; in sym_free_ccb()
6399 lp->itlq_tbl[cp->tag] = cpu_to_scr(np->bad_itlq_ba); in sym_free_ccb()
6400 --lp->busy_itlq; in sym_free_ccb()
6406 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba); in sym_free_ccb()
6407 lp->busy_itl = 0; in sym_free_ccb()
6412 if (lp->busy_itlq == 0 && lp->busy_itl == 0) in sym_free_ccb()
6413 lp->head.resel_sa = in sym_free_ccb()
6421 sym_clr_bit(tp->busy0_map, cp->lun); in sym_free_ccb()
6428 if (cp == tp->nego_cp) in sym_free_ccb()
6429 tp->nego_cp = NULL; in sym_free_ccb()
6436 if (cp == np->last_cp) in sym_free_ccb()
6437 np->last_cp = NULL; in sym_free_ccb()
6441 * Unmap user data from DMA map if needed. in sym_free_ccb()
6443 if (cp->dmamapped) { in sym_free_ccb()
6444 bus_dmamap_unload(np->data_dmat, cp->dmamap); in sym_free_ccb()
6445 cp->dmamapped = 0; in sym_free_ccb()
6451 cp->cam_ccb = NULL; in sym_free_ccb()
6452 cp->host_status = HS_IDLE; in sym_free_ccb()
6453 sym_remque(&cp->link_ccbq); in sym_free_ccb()
6454 sym_insque_head(&cp->link_ccbq, &np->free_ccbq); in sym_free_ccb()
6471 if (np->actccbs >= SYM_CONF_MAX_START) in sym_alloc_ccb()
6484 cp->sns_bbuf = sym_calloc_dma(SYM_SNS_BBUF_LEN, "SNS_BBUF"); in sym_alloc_ccb()
6485 if (!cp->sns_bbuf) in sym_alloc_ccb()
6489 * Allocate a map for the DMA of user data. in sym_alloc_ccb()
6491 if (bus_dmamap_create(np->data_dmat, 0, &cp->dmamap)) in sym_alloc_ccb()
6496 np->actccbs++; in sym_alloc_ccb()
6501 callout_init(&cp->ch, 1); in sym_alloc_ccb()
6506 cp->ccb_ba = vtobus(cp); in sym_alloc_ccb()
6511 hcode = CCB_HASH_CODE(cp->ccb_ba); in sym_alloc_ccb()
6512 cp->link_ccbh = np->ccbh[hcode]; in sym_alloc_ccb()
6513 np->ccbh[hcode] = cp; in sym_alloc_ccb()
6518 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, idle)); in sym_alloc_ccb()
6519 cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l)); in sym_alloc_ccb()
6524 cp->phys.smsg_ext.addr = cpu_to_scr(HCB_BA(np, msgin[2])); in sym_alloc_ccb()
6529 sym_insque_head(&cp->link_ccbq, &np->free_ccbq); in sym_alloc_ccb()
6533 if (cp->sns_bbuf) in sym_alloc_ccb()
6534 sym_mfree_dma(cp->sns_bbuf, SYM_SNS_BBUF_LEN, "SNS_BBUF"); in sym_alloc_ccb()
6548 cp = np->ccbh[hcode]; in sym_ccb_from_dsa()
6550 if (cp->ccb_ba == dsa) in sym_ccb_from_dsa()
6552 cp = cp->link_ccbh; in sym_ccb_from_dsa()
6563 tcb_p tp = &np->target[tn]; in sym_alloc_lcb()
6574 assert(!sym_is_bit(tp->busy0_map, ln)); in sym_alloc_lcb()
6580 if (ln && !tp->luntbl) { in sym_alloc_lcb()
6583 tp->luntbl = sym_calloc_dma(256, "LUNTBL"); in sym_alloc_lcb()
6584 if (!tp->luntbl) in sym_alloc_lcb()
6587 tp->luntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa)); in sym_alloc_lcb()
6588 tp->head.luntbl_sa = cpu_to_scr(vtobus(tp->luntbl)); in sym_alloc_lcb()
6594 if (ln && !tp->lunmp) { in sym_alloc_lcb()
6595 tp->lunmp = sym_calloc(SYM_CONF_MAX_LUN * sizeof(lcb_p), in sym_alloc_lcb()
6597 if (!tp->lunmp) in sym_alloc_lcb()
6609 tp->lunmp[ln] = lp; in sym_alloc_lcb()
6610 tp->luntbl[ln] = cpu_to_scr(vtobus(lp)); in sym_alloc_lcb()
6613 tp->lun0p = lp; in sym_alloc_lcb()
6614 tp->head.lun0_sa = cpu_to_scr(vtobus(lp)); in sym_alloc_lcb()
6620 lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba); in sym_alloc_lcb()
6625 lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun)); in sym_alloc_lcb()
6630 lp->user_flags = tp->usrflags & (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); in sym_alloc_lcb()
6641 tcb_p tp = &np->target[tn]; in sym_alloc_lcb_tags()
6655 lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL"); in sym_alloc_lcb_tags()
6656 if (!lp->itlq_tbl) in sym_alloc_lcb_tags()
6658 lp->cb_tags = sym_calloc(SYM_CONF_MAX_TASK, "CB_TAGS"); in sym_alloc_lcb_tags()
6659 if (!lp->cb_tags) { in sym_alloc_lcb_tags()
6660 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL"); in sym_alloc_lcb_tags()
6661 lp->itlq_tbl = NULL; in sym_alloc_lcb_tags()
6669 lp->itlq_tbl[i] = cpu_to_scr(np->notask_ba); in sym_alloc_lcb_tags()
6675 lp->cb_tags[i] = i; in sym_alloc_lcb_tags()
6681 lp->head.itlq_tbl_sa = cpu_to_scr(vtobus(lp->itlq_tbl)); in sym_alloc_lcb_tags()
6685 * Test the pci bus snoop logic :-(
6706 printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
6727 OUTB (nc_ctest4, (np->rv_ctest4 & MPEE));
6737 np->cache = cpu_to_scr(host_wr);
6742 OUTL (nc_dsa, np->hcb_ba);
6755 * Check for fatal DMA errors.
6759 if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {
6760 printf ("%s: PCI DATA PARITY ERROR DETECTED - "
6763 np->rv_ctest4 &= ~MPEE;
6768 printf ("CACHE TEST FAILED: DMA error (dstat=0x%02x).", dstat);
6778 host_rd = scr_to_cpu(np->cache);
6840 if (np->multiplier <= 1) {
6851 * Otherwise wait 20 micro-seconds.
6853 if (np->features & FE_LCKFRQ) {
6855 while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
6893 OUTB (nc_dien , 0); /* mask all dma interrupts */
6895 OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */
6904 * to set divide by 3.5 mode in my 53c810 ...
6937 unsigned char scntl3 = np->sv_scntl3;
6938 unsigned char stest1 = np->sv_stest1;
6944 if (np->features & FE_C10) {
6945 np->multiplier = mult;
6946 np->clock_khz = 40000 * mult;
6950 np->multiplier = 1;
6958 np->multiplier = mult;
6966 if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
6981 np->multiplier = mult;
6988 f1 /= np->multiplier;
6994 f1 *= np->multiplier;
6995 np->clock_khz = f1;
7006 * For the C1010-33, this doesn't work.
7007 * For the C1010-66, this will be tested when I'll have
7010 if (!(np->features & FE_C10)) {
7015 np->pciclk_khz = f;
7070 * error, SCSI status error, or having been auto-sensed.
7089 if (!cp || !cp->cam_ccb)
7094 cp->host_status, cp->ssss_status, cp->host_flags,
7095 cp->target, cp->lun);
7102 csio = &cp->cam_ccb->csio;
7107 if (cp->xerr_status) {
7109 sym_print_xerr(cp, cp->xerr_status);
7110 if (cp->host_status == HS_COMPLETE)
7111 cp->host_status = HS_COMP_ERR;
7117 csio->sense_resid = 0;
7118 csio->resid = sym_compute_residual(np, cp);
7121 csio->resid = 0; /* throw them away. :) */
7122 cp->sv_resid = 0;
7125 if (cp->host_flags & HF_SENSE) { /* Auto sense */
7126 csio->scsi_status = cp->sv_scsi_status; /* Restore status */
7127 csio->sense_resid = csio->resid; /* Swap residuals */
7128 csio->resid = cp->sv_resid;
7129 cp->sv_resid = 0;
7130 if (sym_verbose && cp->sv_xerr_status)
7131 sym_print_xerr(cp, cp->sv_xerr_status);
7132 if (cp->host_status == HS_COMPLETE &&
7133 cp->ssss_status == S_GOOD &&
7134 cp->xerr_status == 0) {
7136 cp->sv_xerr_status);
7142 bzero(&csio->sense_data, sizeof(csio->sense_data));
7143 sense_returned = SYM_SNS_BBUF_LEN - csio->sense_resid;
7144 if (sense_returned < csio->sense_len)
7145 csio->sense_resid = csio->sense_len -
7148 csio->sense_resid = 0;
7149 bcopy(cp->sns_bbuf, &csio->sense_data,
7150 MIN(csio->sense_len, sense_returned));
7159 p = (u_char *) csio->sense_data;
7162 cp->target,cp->lun, -1);
7169 else if (cp->host_status == HS_COMPLETE) { /* Bad SCSI status */
7170 csio->scsi_status = cp->ssss_status;
7173 else if (cp->host_status == HS_SEL_TIMEOUT) /* Selection timeout */
7175 else if (cp->host_status == HS_UNEXPECTED) /* Unexpected BUS FREE*/
7181 cp->host_status, cp->ssss_status,
7182 cp->xerr_status);
7184 csio->scsi_status = cp->ssss_status;
7189 cp->xerr_status);
7196 i = (INL (nc_scratcha) - np->squeue_ba) / 4;
7197 (void) sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
7205 * Synchronize DMA map if needed.
7207 if (cp->dmamapped) {
7208 bus_dmamap_sync(np->data_dmat, cp->dmamap,
7209 (cp->dmamapped == SYM_DMA_READ ?
7218 sym_remque(&cp->link_ccbq);
7219 sym_insque_head(&cp->link_ccbq, &np->comp_ccbq);
7243 if (!cp || !cp->cam_ccb)
7245 assert (cp->host_status == HS_COMPLETE);
7250 csio = &cp->cam_ccb->csio;
7251 tp = &np->target[cp->target];
7252 lp = sym_lp(tp, cp->lun);
7258 sym_set_bit(tp->lun_map, cp->lun);
7264 csio->resid = 0;
7265 if (cp->phys.head.lastp != cp->phys.head.goalp)
7266 csio->resid = sym_compute_residual(np, cp);
7274 csio->resid = 0;
7277 * Synchronize DMA map if needed.
7279 if (cp->dmamapped) {
7280 bus_dmamap_sync(np->data_dmat, cp->dmamap,
7281 (cp->dmamapped == SYM_DMA_READ ?
7287 csio->scsi_status = cp->ssss_status;
7299 hcb_p np = ccb->ccb_h.sym_hcb_ptr;
7309 switch(ccb->ccb_h.func_code) {
7334 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
7336 if (cp2->cam_ccb == ccb) {
7341 if (!cp || cp->host_status == HS_WAIT)
7342 return -1;
7348 if (cp->to_abort) {
7356 cp->to_abort = timed_out ? 2 : 1;
7357 callout_reset(&cp->ch, 10 * hz, sym_callout, (caddr_t) ccb);
7362 np->istat_sem = SEM;
7373 struct ccb_hdr *ccb_h = &ccb->ccb_h;
7377 if (ccb_h->target_id == np->myaddr ||
7378 ccb_h->target_id >= SYM_CONF_MAX_TARGET ||
7379 ccb_h->target_lun >= SYM_CONF_MAX_LUN) {
7384 tp = &np->target[ccb_h->target_id];
7386 tp->to_reset = 1;
7389 np->istat_sem = SEM;
7408 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("sym_action\n"));
7421 if (ccb->ccb_h.func_code != XPT_SCSI_IO) {
7425 csio = &ccb->csio;
7426 ccb_h = &csio->ccb_h;
7431 if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
7440 if (ccb_h->target_id == np->myaddr ||
7441 ccb_h->target_id >= SYM_CONF_MAX_TARGET ||
7442 ccb_h->target_lun >= SYM_CONF_MAX_LUN) {
7450 tp = &np->target[ccb_h->target_id];
7451 lp = sym_lp(tp, ccb_h->target_lun);
7461 * for SCAN LUNS in the NVRAM since some mono-lun
7463 * zero LUN. Btw, this is an absolute hack.:-)
7465 if (!(ccb_h->flags & CAM_CDB_PHYS) &&
7466 (0x12 == ((ccb_h->flags & CAM_CDB_POINTER) ?
7467 csio->cdb_io.cdb_ptr[0] : csio->cdb_io.cdb_bytes[0]))) {
7468 if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
7469 ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) &&
7470 ccb_h->target_lun != 0)) {
7471 tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
7480 tmp = ((ccb_h->flags & CAM_TAG_ACTION_VALID) != 0);
7481 cp = sym_get_ccb(np, ccb_h->target_id, ccb_h->target_lun, tmp);
7490 cp->cam_ccb = ccb;
7495 idmsg = M_IDENTIFY | cp->lun;
7496 if (cp->tag != NO_TAG || (lp && (lp->current_flags & SYM_DISC_ENABLED)))
7499 msgptr = cp->scsi_smsg;
7506 if (cp->tag != NO_TAG) {
7507 u_char order = csio->tag_action;
7527 msgptr[msglen++] = cp->tag;
7529 msgptr[msglen++] = (cp->tag << 1) + 1;
7537 cp->nego_status = 0;
7538 if (tp->tinfo.current.width != tp->tinfo.goal.width ||
7539 tp->tinfo.current.period != tp->tinfo.goal.period ||
7540 tp->tinfo.current.offset != tp->tinfo.goal.offset ||
7541 tp->tinfo.current.options != tp->tinfo.goal.options) {
7542 if (!tp->nego_cp && lp)
7553 cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select));
7554 cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA (np, resel_dsa));
7559 cp->phys.select.sel_id = cp->target;
7560 cp->phys.select.sel_scntl3 = tp->head.wval;
7561 cp->phys.select.sel_sxfer = tp->head.sval;
7562 cp->phys.select.sel_scntl4 = tp->head.uval;
7567 cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg));
7568 cp->phys.smsg.size = cpu_to_scr(msglen);
7583 cp->actualquirks = tp->quirks;
7585 cp->actualquirks = SYM_QUIRK_AUTOSAVE;
7586 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
7587 cp->ssss_status = S_ILLEGAL;
7588 cp->xerr_status = 0;
7589 cp->host_flags = 0;
7590 cp->extra_bytes = 0;
7594 * shall be positive, so -1 is lower than lowest.:)
7596 cp->ext_sg = -1;
7597 cp->ext_ofs = 0;
7619 ccb_h = &csio->ccb_h;
7624 if (csio->cdb_len > sizeof(cp->cdb_buf)) {
7625 sym_set_cam_status(cp->cam_ccb, CAM_REQ_INVALID);
7626 return -1;
7628 cmd_len = csio->cdb_len;
7630 if (ccb_h->flags & CAM_CDB_POINTER) {
7632 if (!(ccb_h->flags & CAM_CDB_PHYS)) {
7634 bcopy(csio->cdb_io.cdb_ptr, cp->cdb_buf, cmd_len);
7639 cmd_ba = ((u32)csio->cdb_io.cdb_ptr) & 0xffffffff;
7641 sym_set_cam_status(cp->cam_ccb, CAM_REQ_INVALID);
7642 return -1;
7647 bcopy(csio->cdb_io.cdb_bytes, cp->cdb_buf, cmd_len);
7651 cp->phys.cmd.addr = cpu_to_scr(cmd_ba);
7652 cp->phys.cmd.size = cpu_to_scr(cmd_len);
7670 if (!cp->segments)
7679 lastp = goalp - 8 - (cp->segments * (2*4));
7682 cp->host_flags |= HF_DATA_IN;
7684 lastp = goalp - 8 - (cp->segments * (2*4));
7692 cp->phys.head.lastp = cpu_to_scr(lastp);
7693 cp->phys.head.goalp = cpu_to_scr(goalp);
7694 cp->phys.head.savep = cpu_to_scr(lastp);
7695 cp->startp = cp->phys.head.savep;
7699 * Call back routine for the DMA map service.
7711 ccb = cp->cam_ccb;
7712 np = (hcb_p) cp->arg;
7726 cp->dmamapped = 0;
7727 sym_set_cam_status(cp->cam_ccb, CAM_REQ_ABORTED);
7737 if (np->device_id == PCI_ID_SYM53C896 && np->revision_id <= 1)
7742 sym_set_cam_status(cp->cam_ccb, CAM_REQ_TOO_BIG);
7748 * Synchronize the DMA map only if we have
7751 if (cp->dmamapped) {
7752 bus_dmamap_sync(np->data_dmat, cp->dmamap,
7753 (cp->dmamapped == SYM_DMA_READ ?
7761 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
7766 sym_setup_data_pointers(np, cp, (ccb->ccb_h.flags & CAM_DIR_MASK));
7780 switch (cp->cdb_buf[0]) {
7801 * The Bus Dma stuff makes things still more complex.
7811 ccb_h = &csio->ccb_h;
7816 cp->data_len = csio->dxfer_len;
7817 cp->arg = np;
7822 dir = (ccb_h->flags & CAM_DIR_MASK);
7828 cp->dmamapped = (dir == CAM_DIR_IN) ? SYM_DMA_READ : SYM_DMA_WRITE;
7829 retv = bus_dmamap_load_ccb(np->data_dmat, cp->dmamap,
7832 cp->host_status = HS_WAIT;
7833 xpt_freeze_simq(np->sim, 1);
7834 csio->ccb_h.status |= CAM_RELEASE_SIMQ;
7851 return -1;
7853 data = &cp->phys.data[SYM_CONF_MAX_SG-1];
7854 psegs2 = &psegs[nsegs-1];
7855 cp->segments = nsegs;
7858 data->addr = cpu_to_scr(psegs2->ds_addr);
7859 data->size = cpu_to_scr(psegs2->ds_len);
7862 sym_name(np), (long) psegs2->ds_addr,
7863 (long) psegs2->ds_len);
7866 --data;
7867 --psegs2;
7887 s = SYM_CONF_MAX_SG - 1;
7888 t = nsegs - 1;
7893 pn = rounddown2(pe - 1, SYM_CONF_DMA_BOUNDARY);
7896 k = pe - pn;
7901 cp->phys.data[s].addr = cpu_to_scr(pn);
7902 cp->phys.data[s].size = cpu_to_scr(k);
7903 --s;
7905 if (--t < 0)
7914 cp->segments = SYM_CONF_MAX_SG - 1 - s;
7916 return t >= 0 ? -1 : 0;
7941 ccb_h = &ccb->ccb_h;
7943 switch (ccb_h->func_code) {
7945 cts = &ccb->cts;
7946 tp = &np->target[ccb_h->target_id];
7952 lp = sym_lp(tp, ccb_h->target_lun);
7953 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
7954 sym_update_trans(np, &tp->tinfo.goal, cts);
7956 sym_update_dflags(np, &lp->current_flags, cts);
7958 if (cts->type == CTS_TYPE_USER_SETTINGS) {
7959 sym_update_trans(np, &tp->tinfo.user, cts);
7961 sym_update_dflags(np, &lp->user_flags, cts);
7967 cts = &ccb->cts;
7968 tp = &np->target[ccb_h->target_id];
7969 lp = sym_lp(tp, ccb_h->target_lun);
7971 #define cts__scsi (&cts->proto_specific.scsi)
7972 #define cts__spi (&cts->xport_specific.spi)
7973 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
7974 tip = &tp->tinfo.current;
7975 dflags = lp ? lp->current_flags : 0;
7978 tip = &tp->tinfo.user;
7979 dflags = lp ? lp->user_flags : tp->usrflags;
7982 cts->protocol = PROTO_SCSI;
7983 cts->transport = XPORT_SPI;
7984 cts->protocol_version = tip->scsi_version;
7985 cts->transport_version = tip->spi_version;
7987 cts__spi->sync_period = tip->period;
7988 cts__spi->sync_offset = tip->offset;
7989 cts__spi->bus_width = tip->width;
7990 cts__spi->ppr_options = tip->options;
7992 cts__spi->valid = CTS_SPI_VALID_SYNC_RATE
7997 cts__spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
7999 cts__spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
8000 cts__spi->valid |= CTS_SPI_VALID_DISC;
8002 cts__scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
8004 cts__scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
8005 cts__scsi->valid |= CTS_SCSI_VALID_TQ;
8011 cam_calc_geometry(&ccb->ccg, /*extended*/1);
8015 cpi = &ccb->cpi;
8016 cpi->version_num = 1;
8017 cpi->hba_inquiry = PI_MDP_ABLE|PI_SDTR_ABLE|PI_TAG_ABLE;
8018 if ((np->features & FE_WIDE) != 0)
8019 cpi->hba_inquiry |= PI_WIDE_16;
8020 cpi->target_sprt = 0;
8021 cpi->hba_misc = PIM_UNMAPPED;
8022 if (np->usrflags & SYM_SCAN_TARGETS_HILO)
8023 cpi->hba_misc |= PIM_SCANHILO;
8024 if (np->usrflags & SYM_AVOID_BUS_RESET)
8025 cpi->hba_misc |= PIM_NOBUSRESET;
8026 cpi->hba_eng_cnt = 0;
8027 cpi->max_target = (np->features & FE_WIDE) ? 15 : 7;
8028 /* Semantic problem:)LUN number max = max number of LUNs - 1 */
8029 cpi->max_lun = SYM_CONF_MAX_LUN-1;
8031 cpi->max_lun = SYM_SETUP_MAX_LUN-1;
8032 cpi->bus_id = cam_sim_bus(sim);
8033 cpi->initiator_id = np->myaddr;
8034 cpi->base_transfer_speed = 3300;
8035 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
8036 strlcpy(cpi->hba_vid, "Symbios", HBA_IDLEN);
8037 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
8038 cpi->unit_number = cam_sim_unit(sim);
8040 cpi->protocol = PROTO_SCSI;
8041 cpi->protocol_version = SCSI_REV_2;
8042 cpi->transport = XPORT_SPI;
8043 cpi->transport_version = 2;
8044 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST;
8045 if (np->features & FE_ULTRA3) {
8046 cpi->transport_version = 3;
8047 cpi->xport_specific.spi.ppr_options =
8050 cpi->maxio = SYM_CONF_MAX_SG * PAGE_SIZE;
8054 abort_ccb = ccb->cab.abort_ccb;
8055 switch(abort_ccb->ccb_h.func_code) {
8072 xpt_print_path(np->path);
8107 tp = &np->target[tn];
8109 tp->to_reset = 0;
8110 tp->head.sval = 0;
8111 tp->head.wval = np->rv_scntl3;
8112 tp->head.uval = 0;
8114 tp->tinfo.current.period = tp->tinfo.goal.period = 0;
8115 tp->tinfo.current.offset = tp->tinfo.goal.offset = 0;
8116 tp->tinfo.current.width = tp->tinfo.goal.width = BUS_8_BIT;
8117 tp->tinfo.current.options = tp->tinfo.goal.options = 0;
8137 #define cts__spi (&cts->xport_specific.spi)
8138 if ((cts__spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
8139 tip->width = cts__spi->bus_width;
8140 if ((cts__spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
8141 tip->offset = cts__spi->sync_offset;
8142 if ((cts__spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0)
8143 tip->period = cts__spi->sync_period;
8144 if ((cts__spi->valid & CTS_SPI_VALID_PPR_OPTIONS) != 0)
8145 tip->options = (cts__spi->ppr_options & PPR_OPT_DT);
8146 if (cts->protocol_version != PROTO_VERSION_UNSPECIFIED &&
8147 cts->protocol_version != PROTO_VERSION_UNKNOWN)
8148 tip->scsi_version = cts->protocol_version;
8149 if (cts->transport_version != XPORT_VERSION_UNSPECIFIED &&
8150 cts->transport_version != XPORT_VERSION_UNKNOWN)
8151 tip->spi_version = cts->transport_version;
8156 if (tip->width > SYM_SETUP_MAX_WIDE) tip->width = SYM_SETUP_MAX_WIDE;
8157 if (tip->period && tip->offset) {
8158 if (tip->offset > SYM_SETUP_MAX_OFFS) tip->offset = SYM_SETUP_MAX_OFFS;
8159 if (tip->period < SYM_SETUP_MIN_SYNC) tip->period = SYM_SETUP_MIN_SYNC;
8161 tip->offset = 0;
8162 tip->period = 0;
8168 if (tip->width > np->maxwide)
8169 tip->width = np->maxwide;
8174 if (!((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) ||
8175 !(tip->width == BUS_16_BIT && tip->offset)) {
8176 tip->options &= ~PPR_OPT_DT;
8182 if (tip->offset && tip->period) {
8183 if (tip->options & PPR_OPT_DT) {
8184 if (tip->period < np->minsync_dt)
8185 tip->period = np->minsync_dt;
8186 if (tip->period > np->maxsync_dt)
8187 tip->period = np->maxsync_dt;
8188 if (tip->offset > np->maxoffs_dt)
8189 tip->offset = np->maxoffs_dt;
8192 if (tip->period < np->minsync)
8193 tip->period = np->minsync;
8194 if (tip->period > np->maxsync)
8195 tip->period = np->maxsync;
8196 if (tip->offset > np->maxoffs)
8197 tip->offset = np->maxoffs;
8211 #define cts__scsi (&cts->proto_specific.scsi)
8212 #define cts__spi (&cts->xport_specific.spi)
8213 if ((cts__spi->valid & CTS_SPI_VALID_DISC) != 0) {
8214 if ((cts__spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
8220 if ((cts__scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
8221 if ((cts__scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
8308 {PCI_ID_LSI53C1010, 0x00, "1010-33", 6, 31, 7, 8,
8313 {PCI_ID_LSI53C1010, 0xff, "1010-33", 6, 31, 7, 8,
8318 {PCI_ID_LSI53C1010_2, 0xff, "1010-66", 6, 31, 7, 8,
8350 if (device_id != chip->device_id)
8352 if (revision > chip->revision_id)
8370 device_set_desc(dev, chip->name);
8409 np->bus_dmat = bus_dmat;
8419 np->hcb_ba = vtobus(np);
8420 np->verbose = bootverbose;
8421 np->device = dev;
8422 np->device_id = pci_get_device(dev);
8423 np->revision_id = pci_get_revid(dev);
8424 np->features = chip->features;
8425 np->clock_divn = chip->nr_divisor;
8426 np->maxoffs = chip->offset_max;
8427 np->maxburst = chip->burst_max;
8428 np->scripta_sz = fw->a_size;
8429 np->scriptb_sz = fw->b_size;
8430 np->fw_setup = fw->setup;
8431 np->fw_patch = fw->patch;
8432 np->fw_name = fw->name;
8435 np->target = sym_calloc_dma(SYM_CONF_MAX_TARGET * sizeof(*(np->target)),
8437 if (!np->target)
8444 sym_que_init(&np->free_ccbq);
8445 sym_que_init(&np->busy_ccbq);
8446 sym_que_init(&np->comp_ccbq);
8447 sym_que_init(&np->cam_ccbq);
8450 * Allocate a tag for the DMA of user data.
8452 if (bus_dma_tag_create(np->bus_dmat, 1, SYM_CONF_DMA_BOUNDARY,
8455 0, busdma_lock_mutex, &np->mtx, &np->data_dmat)) {
8456 device_printf(dev, "failed to create DMA tag.\n");
8461 * Read and apply some fix-ups to the PCI COMMAND
8463 * - BUS mastering
8464 * - PCI parity checking (reporting would also be fine)
8465 * - Write And Invalidate.
8486 np->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
8488 if (!np->mmio_res) {
8492 np->mmio_ba = rman_get_start(np->mmio_res);
8498 np->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
8500 if (!np->irq_res) {
8511 np->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &i, RF_ACTIVE);
8512 if (!np->io_res) {
8523 if (np->features & (FE_RAM|FE_RAM8K)) {
8525 if (np->features & FE_64BIT)
8527 np->ram_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
8529 if (!np->ram_res) {
8533 np->ram_id = regs_id;
8534 np->ram_ba = rman_get_start(np->ram_res);
8551 * Try to read the user set-up.
8557 * to chip features, user set-up and driver set-up.
8573 np->squeue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
8574 if (!np->squeue)
8576 np->squeue_ba = vtobus(np->squeue);
8581 np->dqueue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
8582 if (!np->dqueue)
8584 np->dqueue_ba = vtobus(np->dqueue);
8589 np->targtbl = (u32 *) sym_calloc_dma(256, "TARGTBL");
8590 if (!np->targtbl)
8592 np->targtbl_ba = vtobus(np->targtbl);
8597 np->scripta0 = sym_calloc_dma(np->scripta_sz, "SCRIPTA0");
8598 np->scriptb0 = sym_calloc_dma(np->scriptb_sz, "SCRIPTB0");
8599 if (!np->scripta0 || !np->scriptb0)
8614 np->scripta_ba = vtobus(np->scripta0);
8615 np->scriptb_ba = vtobus(np->scriptb0);
8616 np->scriptb0_ba = np->scriptb_ba;
8618 if (np->ram_ba) {
8619 np->scripta_ba = np->ram_ba;
8620 if (np->features & FE_RAM8K) {
8621 np->ram_ws = 8192;
8622 np->scriptb_ba = np->scripta_ba + 4096;
8624 np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32);
8628 np->ram_ws = 4096;
8634 bcopy(fw->a_base, np->scripta0, np->scripta_sz);
8635 bcopy(fw->b_base, np->scriptb0, np->scriptb_sz);
8641 np->fw_setup(np, fw);
8647 sym_fw_bind_script(np, (u32 *) np->scripta0, np->scripta_sz);
8648 sym_fw_bind_script(np, (u32 *) np->scriptb0, np->scriptb_sz);
8658 np->iarb_max = SYM_SETUP_IARB_MAX;
8660 np->iarb_max = 4;
8667 np->idletask.start = cpu_to_scr(SCRIPTA_BA (np, idle));
8668 np->idletask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
8669 np->idletask_ba = vtobus(&np->idletask);
8671 np->notask.start = cpu_to_scr(SCRIPTA_BA (np, idle));
8672 np->notask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
8673 np->notask_ba = vtobus(&np->notask);
8675 np->bad_itl.start = cpu_to_scr(SCRIPTA_BA (np, idle));
8676 np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
8677 np->bad_itl_ba = vtobus(&np->bad_itl);
8679 np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA (np, idle));
8680 np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA (np,bad_i_t_l_q));
8681 np->bad_itlq_ba = vtobus(&np->bad_itlq);
8689 np->badluntbl = sym_calloc_dma(256, "BADLUNTBL");
8690 if (!np->badluntbl)
8693 np->badlun_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun));
8695 np->badluntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa));
8703 np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
8704 np->target[i].head.luntbl_sa =
8705 cpu_to_scr(vtobus(np->badluntbl));
8706 np->target[i].head.lun0_sa =
8707 cpu_to_scr(vtobus(&np->badlun_sa));
8762 if (np->ram_res)
8763 bus_release_resource(np->device, SYS_RES_MEMORY,
8764 np->ram_id, np->ram_res);
8765 if (np->mmio_res)
8766 bus_release_resource(np->device, SYS_RES_MEMORY,
8767 SYM_PCI_MMIO, np->mmio_res);
8768 if (np->io_res)
8769 bus_release_resource(np->device, SYS_RES_IOPORT,
8770 SYM_PCI_IO, np->io_res);
8771 if (np->irq_res)
8772 bus_release_resource(np->device, SYS_RES_IRQ,
8773 0, np->irq_res);
8775 if (np->scriptb0)
8776 sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
8777 if (np->scripta0)
8778 sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
8779 if (np->squeue)
8780 sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
8781 if (np->dqueue)
8782 sym_mfree_dma(np->dqueue, sizeof(u32)*(MAX_QUEUE*2), "DQUEUE");
8784 while ((qp = sym_remque_head(&np->free_ccbq)) != NULL) {
8786 bus_dmamap_destroy(np->data_dmat, cp->dmamap);
8787 sym_mfree_dma(cp->sns_bbuf, SYM_SNS_BBUF_LEN, "SNS_BBUF");
8791 if (np->badluntbl)
8792 sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
8795 tp = &np->target[target];
8800 if (lp->itlq_tbl)
8801 sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
8803 if (lp->cb_tags)
8804 sym_mfree(lp->cb_tags, SYM_CONF_MAX_TASK,
8809 if (tp->lunmp)
8810 sym_mfree(tp->lunmp, SYM_CONF_MAX_LUN*sizeof(lcb_p),
8815 if (np->target)
8816 sym_mfree_dma(np->target,
8817 SYM_CONF_MAX_TARGET * sizeof(*(np->target)), "TARGET");
8819 if (np->targtbl)
8820 sym_mfree_dma(np->targtbl, 256, "TARGTBL");
8821 if (np->data_dmat)
8822 bus_dma_tag_destroy(np->data_dmat);
8825 device_set_softc(np->device, NULL);
8842 err = bus_setup_intr(np->device, np->irq_res,
8844 NULL, sym_intr, np, &np->intr);
8846 device_printf(np->device, "bus_setup_intr() failed: %d\n",
8862 device_get_unit(np->device),
8863 &np->mtx, 1, SYM_SETUP_MAX_TAG, devq);
8869 if (xpt_bus_register(sim, np->device, 0) != CAM_SUCCESS)
8871 np->sim = sim;
8875 cam_sim_path(np->sim), CAM_TARGET_WILDCARD,
8879 np->path = path;
8884 if (xpt_register_async(AC_LOST_DEVICE, sym_async, np->sim, path) !=
8920 if (np->intr) {
8921 bus_teardown_intr(np->device, np->irq_res, np->intr);
8922 np->intr = NULL;
8927 if (np->sim) {
8928 xpt_bus_deregister(cam_sim_path(np->sim));
8929 cam_sim_free(np->sim, /*free_devq*/ TRUE);
8930 np->sim = NULL;
8932 if (np->path) {
8933 xpt_free_path(np->path);
8934 np->path = NULL;
8952 switch(nvram->type) {
8954 if (!(nvram->data.Symbios.flags & SYMBIOS_PARITY_ENABLE))
8955 np->rv_scntl0 &= ~0x0a;
8956 np->myaddr = nvram->data.Symbios.host_id & 0x0f;
8957 if (nvram->data.Symbios.flags & SYMBIOS_VERBOSE_MSGS)
8958 np->verbose += 1;
8959 if (nvram->data.Symbios.flags1 & SYMBIOS_SCAN_HI_LO)
8960 np->usrflags |= SYM_SCAN_TARGETS_HILO;
8961 if (nvram->data.Symbios.flags2 & SYMBIOS_AVOID_BUS_RESET)
8962 np->usrflags |= SYM_AVOID_BUS_RESET;
8965 np->myaddr = nvram->data.Tekram.host_id & 0x0f;
8985 switch(nvp->type) {
8987 sym_Symbios_setup_target (np, target, &nvp->data.Symbios);
8990 sym_Tekram_setup_target (np, target, &nvp->data.Tekram);
9000 * Get target set-up from Symbios format NVRAM.
9005 tcb_p tp = &np->target[target];
9006 Symbios_target *tn = &nvram->target[target];
9008 tp->tinfo.user.period = tn->sync_period ? (tn->sync_period + 3) / 4 : 0;
9009 tp->tinfo.user.width = tn->bus_width == 0x10 ? BUS_16_BIT : BUS_8_BIT;
9010 tp->usrtags =
9011 (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
9013 if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
9014 tp->usrflags &= ~SYM_DISC_ENABLED;
9015 if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
9016 tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
9017 if (!(tn->flags & SYMBIOS_SCAN_LUNS))
9018 tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
9022 * Get target set-up from Tekram format NVRAM.
9027 tcb_p tp = &np->target[target];
9028 struct Tekram_target *tn = &nvram->target[target];
9031 if (tn->flags & TEKRAM_SYNC_NEGO) {
9032 i = tn->sync_index & 0xf;
9033 tp->tinfo.user.period = Tekram_sync[i];
9036 tp->tinfo.user.width =
9037 (tn->flags & TEKRAM_WIDE_NEGO) ? BUS_16_BIT : BUS_8_BIT;
9039 if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
9040 tp->usrtags = 2 << nvram->max_tags_index;
9043 if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
9044 tp->usrflags |= SYM_DISC_ENABLED;
9047 if (!(tn->flags & TEKRAM_PARITY_CHECK))
9048 np->rv_scntl0 &= ~0x0a; /* SCSI parity checking disabled */
9061 sym_name(np), nvram->host_id & 0x0f,
9062 (nvram->flags & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
9063 (nvram->flags & SYMBIOS_PARITY_ENABLE) ? " PARITY" :"",
9064 (nvram->flags & SYMBIOS_VERBOSE_MSGS) ? " VERBOSE" :"",
9065 (nvram->flags & SYMBIOS_CHS_MAPPING) ? " CHS_ALT" :"",
9066 (nvram->flags2 & SYMBIOS_AVOID_BUS_RESET)?" NO_RESET" :"",
9067 (nvram->flags1 & SYMBIOS_SCAN_HI_LO) ? " HI_LO" :"");
9071 struct Symbios_target *tn = &nvram->target[i];
9072 printf("%s-%d:%s%s%s%s WIDTH=%d SYNC=%d TMO=%d\n",
9074 (tn->flags & SYMBIOS_DISCONNECT_ENABLE) ? " DISC" : "",
9075 (tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME) ? " SCAN_BOOT" : "",
9076 (tn->flags & SYMBIOS_SCAN_LUNS) ? " SCAN_LUNS" : "",
9077 (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? " TCQ" : "",
9078 tn->bus_width,
9079 tn->sync_period / 4,
9080 tn->timeout);
9094 tags = 2 << nvram->max_tags_index;
9096 if (nvram->boot_delay_index < 6)
9097 boot_delay = Tekram_boot_delay[nvram->boot_delay_index];
9098 switch((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
9106 sym_name(np), nvram->host_id & 0x0f,
9107 (nvram->flags1 & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
9108 (nvram->flags & TEKRAM_MORE_THAN_2_DRIVES) ? " >2DRIVES" :"",
9109 (nvram->flags & TEKRAM_DRIVES_SUP_1GB) ? " >1GB" :"",
9110 (nvram->flags & TEKRAM_RESET_ON_POWER_ON) ? " RESET" :"",
9111 (nvram->flags & TEKRAM_ACTIVE_NEGATION) ? " ACT_NEG" :"",
9112 (nvram->flags & TEKRAM_IMMEDIATE_SEEK) ? " IMM_SEEK" :"",
9113 (nvram->flags & TEKRAM_SCAN_LUNS) ? " SCAN_LUNS" :"",
9114 (nvram->flags1 & TEKRAM_F2_F6_ENABLED) ? " F2_F6" :"",
9120 struct Tekram_target *tn = &nvram->target[i];
9121 j = tn->sync_index & 0xf;
9123 printf("%s-%d:%s%s%s%s%s%s PERIOD=%d\n",
9125 (tn->flags & TEKRAM_PARITY_CHECK) ? " PARITY" : "",
9126 (tn->flags & TEKRAM_SYNC_NEGO) ? " SYNC" : "",
9127 (tn->flags & TEKRAM_DISCONNECT_ENABLE) ? " DISC" : "",
9128 (tn->flags & TEKRAM_START_CMD) ? " START" : "",
9129 (tn->flags & TEKRAM_TAGGED_COMMANDS) ? " TCQ" : "",
9130 (tn->flags & TEKRAM_WIDE_NEGO) ? " WIDE" : "",
9153 !sym_read_Symbios_nvram (np, &nvp->data.Symbios)) {
9154 nvp->type = SYM_SYMBIOS_NVRAM;
9156 sym_display_Symbios_nvram(np, &nvp->data.Symbios);
9160 !sym_read_Tekram_nvram (np, &nvp->data.Tekram)) {
9161 nvp->type = SYM_TEKRAM_NVRAM;
9163 sym_display_Tekram_nvram(np, &nvp->data.Tekram);
9167 nvp->type = 0;
9169 nvp->type = 0;
9171 return nvp->type;
9178 * GPOI0 - data in/data out
9179 * GPIO1 - clock
9225 * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZzzzz!!
9282 S24C16_do_bit(np, 0, (write_data >> (7 - x)) & 0x01, gpreg);
9300 *read_data |= ((read_bit & 0x01) << (7 - x));
9362 /* input all requested data - only part of total NVRAM */
9364 S24C16_read_byte(np, &data[x], (x == (len-1)), &gpreg, &gpcntl);
9401 if (nvram->type != 0 ||
9402 bcmp(nvram->trailer, Symbios_trailer, 6) ||
9403 nvram->byte_count != len - 12)
9407 for (x = 6, csum = 0; x < len - 6; x++)
9409 if (csum != nvram->checksum)
9418 * GPOI0 - data in
9419 * GPIO1 - data out
9420 * GPIO2 - clock
9421 * GPIO4 - chip select
9465 * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZZzzz!!
9486 T93C46_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);
9504 *nvram_data |= (0x01 << (15 - x));
9506 *nvram_data &= ~(0x01 << (15 - x));
9572 switch (np->device_id) {
9592 for (x = 0, csum = 0; x < len - 1; x += 2)