Index: arch/arc/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/arc/conf/GENERIC,v retrieving revision 1.78 diff -u -r1.78 GENERIC --- arch/arc/conf/GENERIC 2002/12/07 21:55:44 1.78 +++ arch/arc/conf/GENERIC 2003/02/18 14:42:14 @@ -196,9 +196,9 @@ osiop1 at jazzio? flags 0x00000 scsibus* at osiop? -#oosiop0 at jazzio? # NCR53C700 SCSI -#oosiop1 at jazzio? -#scsibus* at oosiop? +oosiop0 at jazzio? # NCR53C700 SCSI +oosiop1 at jazzio? +scsibus* at oosiop? #### ISA bus devices Index: arch/arc/conf/MIMORI =================================================================== RCS file: /cvsroot/src/sys/arch/arc/conf/MIMORI,v retrieving revision 1.19 diff -u -r1.19 MIMORI --- arch/arc/conf/MIMORI 2002/09/18 02:43:55 1.19 +++ arch/arc/conf/MIMORI 2003/02/18 14:42:14 @@ -151,9 +151,8 @@ fdc0 at jazzio? fd* at fdc? drive ? -#oosiop0 at jazzio? # NCR53C700 SCSI -#oosiop1 at jazzio? -#scsibus* at oosiop? +oosiop* at jazzio? # NCR53C700 SCSI +scsibus* at oosiop? #### PCI bus devices Index: arch/arc/conf/files.arc =================================================================== RCS file: /cvsroot/src/sys/arch/arc/conf/files.arc,v retrieving revision 1.41 diff -u -r1.41 files.arc --- arch/arc/conf/files.arc 2002/11/30 19:23:46 1.41 +++ arch/arc/conf/files.arc 2003/02/18 14:42:14 @@ -168,6 +168,10 @@ attach osiop at jazzio with osiop_jazzio file arch/arc/jazz/osiop_jazzio.c osiop_jazzio +# NCR53C700 SCSI I/O processor on Jazz-Internal bus +attach oosiop at jazzio with oosiop_jazzio +file arch/arc/jazz/oosiop_jazzio.c oosiop_jazzio + # Floppy disk controller on Jazz-internal bus device fdc {drive = -1} file arch/arc/jazz/fd.c fdc needs-flag Index: arch/hp700/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/conf/GENERIC,v retrieving revision 1.11 diff -u -r1.11 GENERIC --- arch/hp700/conf/GENERIC 2002/11/22 12:21:01 1.11 +++ arch/hp700/conf/GENERIC 2003/02/18 14:42:18 @@ -286,7 +286,8 @@ # SCSI Controllers and Devices # GSC SCSI controllers -osiop* at gsc? flags 0xffff # NCR 53c700 or NCR 53c710 +oosiop* at gsc? # NCR 53c700 +osiop* at gsc? # NCR 53c710 #siop* at gsc? # NCR 53c720 (Fast/Wide) # EISA SCSI controllers Index: arch/hp700/conf/files.hp700 =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/conf/files.hp700,v retrieving revision 1.4 diff -u -r1.4 files.hp700 --- arch/hp700/conf/files.hp700 2002/11/28 05:53:23 1.4 +++ arch/hp700/conf/files.hp700 2003/02/18 14:42:18 @@ -100,7 +100,7 @@ attach dino at mainbus file arch/hp700/dev/dino.c dino -device sti: wsemuldisplaydev +#device sti: wsemuldisplaydev attach sti at mainbus with sti_sgc file arch/hp700/dev/sti_sgc.c sti_sgc @@ -138,11 +138,14 @@ attach ie at gsc with ie_gsc file arch/hp700/gsc/if_ie_gsc.c ie_gsc -attach siop at gsc -file arch/hp700/gsc/siop_gsc.c siop +#attach siop at gsc with siop_gsc +#file arch/hp700/gsc/siop_gsc.c siop_gsc attach osiop at gsc with osiop_gsc -file arch/hp700/gsc/osiop_gsc.c osiop +file arch/hp700/gsc/osiop_gsc.c osiop_gsc + +attach oosiop at gsc with oosiop_gsc +file arch/hp700/gsc/oosiop_gsc.c oosiop_gsc device hil: tty attach hil at gsc Index: arch/hp700/conf/ld.script =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/conf/ld.script,v retrieving revision 1.3 diff -u -r1.3 ld.script --- arch/hp700/conf/ld.script 2002/11/28 05:56:51 1.3 +++ arch/hp700/conf/ld.script 2003/02/18 14:42:18 @@ -13,6 +13,7 @@ { kernel_text = . ; *(.text) + *(.text.*) *(.rodata) *(.rodata1) *(.reginfo) *(.init) @@ -26,6 +27,13 @@ } = 0 /* 0x08000240 nop filled, does not work */ etext = ABSOLUTE(.); . = ALIGN(0x200000); + + link_set_evcnts : + { + __start_link_set_evcnts = ALIGN (0x4); + *(link_set_evcnts) + __stop_link_set_evcnts = . ; + } .data : { Index: arch/hp700/gsc/osiop_gsc.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/gsc/osiop_gsc.c,v retrieving revision 1.6 diff -u -r1.6 osiop_gsc.c --- arch/hp700/gsc/osiop_gsc.c 2002/10/02 05:17:50 1.6 +++ arch/hp700/gsc/osiop_gsc.c 2003/02/18 14:42:18 @@ -2,7 +2,7 @@ /* * Copyright (c) 2001 Matt Fredette. All rights reserved. - * Copyright (c) 2001 Izumi Tsutsui. All rights reserved. + * Copyright (c) 2001,2002 Izumi Tsutsui. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -103,12 +103,11 @@ int rv = 1; if (ga->ga_type.iodc_type != HPPA_TYPE_FIO || - (ga->ga_type.iodc_sv_model != HPPA_FIO_GSCSI && - ga->ga_type.iodc_sv_model != HPPA_FIO_SCSI)) + (ga->ga_type.iodc_sv_model != HPPA_FIO_GSCSI)) return 0; if (bus_space_map(ga->ga_iot, ga->ga_hpa, - OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh)) + OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh)) return 0; @@ -121,34 +120,25 @@ struct device *parent, *self; void *aux; { - register struct osiop_softc *sc = (void *)self; - register struct gsc_attach_args *ga = aux; + struct osiop_softc *sc = (void *)self; + struct gsc_attach_args *ga = aux; bus_space_handle_t ioh; sc->sc_bst = ga->ga_iot; sc->sc_dmat = ga->ga_dmatag; if (bus_space_map(sc->sc_bst, ga->ga_hpa, - OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh)) + OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh)) panic("osiop_gsc_attach: couldn't map I/O ports"); if (bus_space_subregion(sc->sc_bst, ioh, - OSIOP_GSC_OFFSET, OSIOP_NREGS, &sc->sc_reg)) + OSIOP_GSC_OFFSET, OSIOP_NREGS, &sc->sc_reg)) panic("osiop_gsc_attach: couldn't get chip ports"); sc->sc_clock_freq = ga->ga_ca.ca_pdc_iodc_read->filler2[14] / 1000000; if (!sc->sc_clock_freq) sc->sc_clock_freq = 50; - if (ga->ga_ca.ca_type.iodc_sv_model == HPPA_FIO_GSCSI) { - sc->sc_rev = OSIOP_VARIANT_NCR53C710; - sc->sc_byteorder = OSIOP_BYTEORDER_NATIVE; - sc->sc_ctest7 = 0; /* | OSIOP_CTEST7_TT1 */ - sc->sc_dcntl = OSIOP_DCNTL_EA; - } else { - sc->sc_rev = OSIOP_VARIANT_NCR53C700; - sc->sc_byteorder = OSIOP_BYTEORDER_NONNATIVE; - sc->sc_ctest7 = 0; - sc->sc_dcntl = 0; - } + sc->sc_ctest7 = 0; /* | OSIOP_CTEST7_TT1 */ + sc->sc_dcntl = OSIOP_DCNTL_EA; sc->sc_flags = 0; sc->sc_id = ga->ga_scsi_target; @@ -170,9 +160,8 @@ #endif /* OSIOP_DEBUG */ osiop_attach(sc); - (void) hp700_intr_establish(&sc->sc_dev, IPL_BIO, - osiop_gsc_intr, sc, - ga->ga_int_reg, ga->ga_irq); + (void)hp700_intr_establish(&sc->sc_dev, IPL_BIO, + osiop_gsc_intr, sc, ga->ga_int_reg, ga->ga_irq); } /* Index: arch/hp700/hp700/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/hp700/machdep.c,v retrieving revision 1.8 diff -u -r1.8 machdep.c --- arch/hp700/hp700/machdep.c 2002/12/14 05:23:19 1.8 +++ arch/hp700/hp700/machdep.c 2003/02/18 14:42:19 @@ -1417,9 +1417,16 @@ if (howto & RB_HALT) { haltsys: +#ifndef DEBUG printf("System halted!\n"); __asm __volatile("stwas %0, 0(%1)" :: "r" (CMD_STOP), "r" (LBCAST_ADDR + iomod_command)); +#else /* DEBUG */ + printf("rebooting..."); + DELAY(1000000); + __asm __volatile("stwas %0, 0(%1)" + :: "r" (CMD_RESET), "r" (LBCAST_ADDR + iomod_command)); +#endif /* DEBUG */ } else { printf("rebooting..."); DELAY(1000000); Index: arch/hp700/hp700/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/hp700/mainbus.c,v retrieving revision 1.8 diff -u -r1.8 mainbus.c --- arch/hp700/hp700/mainbus.c 2002/10/02 05:17:51 1.8 +++ arch/hp700/hp700/mainbus.c 2003/02/18 14:42:19 @@ -160,6 +160,7 @@ int mbus_dmamap_load_mbuf __P((void *, bus_dmamap_t, struct mbuf *, int)); int mbus_dmamap_load_uio __P((void *, bus_dmamap_t, struct uio *, int)); int mbus_dmamap_load_raw __P((void *, bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int)); +int mbus_dmamap_load_buffer __P((void *, bus_dmamap_t, void *, bus_size_t, struct proc *, int, paddr_t *, int *, int)); void mbus_dmamap_unload __P((void *, bus_dmamap_t)); void mbus_dmamap_sync __P((void *, bus_dmamap_t, bus_addr_t, bus_size_t, int)); int mbus_dmamem_alloc __P((void *, bus_size_t, bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, int)); @@ -773,7 +774,7 @@ * DMA map creation functions. */ int -mbus_dmamap_create(void *v, bus_size_t size, int nsegments, +mbus_dmamap_create(void *cookie, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) { @@ -818,81 +819,221 @@ * DMA map destruction functions. */ void -mbus_dmamap_destroy(void *v, bus_dmamap_t map) +mbus_dmamap_destroy(void *cookie, bus_dmamap_t map) { /* * If the handle contains a valid mapping, unload it. */ if (map->dm_mapsize != 0) - mbus_dmamap_unload(v, map); + mbus_dmamap_unload(cookie, map); free(map, M_DMAMAP); } /* + * Utility function to load a linear buffer. lastaddrp holds state + * between invocations (for multiple-buffer loads). segp contains + * the starting segment on entrance, and the ending segment on exit. + * first indicates if this is the first invocation of this function. + */ +int +mbus_dmamap_load_buffer(void *cookie, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags, + paddr_t *lastaddrp, int *segp, int first) +{ + bus_size_t sgsize; + bus_addr_t curaddr, lastaddr, baddr, bmask; + vaddr_t vaddr = (vaddr_t)buf; + int seg; + + lastaddr = *lastaddrp; + bmask = ~(map->_dm_boundary - 1); + + for (seg = *segp; buflen > 0 ; ) { + /* + * Get the physical address for this segment. + */ + if (p != NULL) + (void) pmap_extract(p->p_vmspace->vm_map.pmap, + vaddr, (void *)&curaddr); + else + curaddr = kvtop((void *)vaddr); + + /* + * Compute the segment size, and adjust counts. + */ + sgsize = NBPG - ((u_long)vaddr & PGOFSET); + if (buflen < sgsize) + sgsize = buflen; + + /* + * Make sure we don't cross any boundaries. + */ + if (map->_dm_boundary > 0) { + baddr = (curaddr + map->_dm_boundary) & bmask; + if (sgsize > (baddr - curaddr)) + sgsize = (baddr - curaddr); + } + + /* + * Insert chunk into a segment, coalescing with + * the previous segment if possible. + */ + if (first) { + map->dm_segs[seg].ds_addr = curaddr; + map->dm_segs[seg].ds_len = sgsize; + map->dm_segs[seg]._ds_va = vaddr; + + first = 0; + } else { + if (curaddr == lastaddr && + (map->dm_segs[seg].ds_len + sgsize) <= + map->_dm_maxsegsz && + (map->_dm_boundary == 0 || + (map->dm_segs[seg].ds_addr & bmask) == + (curaddr & bmask))) + map->dm_segs[seg].ds_len += sgsize; + else { + if (++seg >= map->_dm_segcnt) + break; + map->dm_segs[seg].ds_addr = curaddr; + map->dm_segs[seg].ds_len = sgsize; + map->dm_segs[seg]._ds_va = vaddr; + } + } + + lastaddr = curaddr + sgsize; + vaddr += sgsize; + buflen -= sgsize; + } + + *segp = seg; + *lastaddrp = lastaddr; + + /* + * Did we fit? + */ + if (buflen != 0) + return (EFBIG); /* XXX better return value here? */ + + return (0); +} + +/* * load DMA map with a linear buffer. */ int -mbus_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size, - struct proc *p, int flags) +mbus_dmamap_load(void *cookie, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags) { - paddr_t pa, pa_next; - bus_size_t mapsize; - bus_size_t off, pagesz; - int seg; + paddr_t lastaddr; + int seg, error; /* * Make sure that on error condition we return "no valid mappings". */ map->dm_nsegs = 0; map->dm_mapsize = 0; - - /* Stash the buffer address in the first segment. */ - map->dm_segs[0]._ds_va = (vaddr_t)addr; - /* Load the memory. */ - pa_next = 0; - seg = -1; - mapsize = size; - off = (bus_size_t)addr & (PAGE_SIZE - 1); - addr = (void *) ((caddr_t)addr - off); - for(; size > 0; ) { + if (buflen > map->_dm_size) + return (EINVAL); - pa = kvtop(addr); - if (pa != pa_next) { - if (++seg >= map->_dm_segcnt) - panic("mbus_dmamap_load: nsegs botch"); - map->dm_segs[seg].ds_addr = pa + off; - map->dm_segs[seg].ds_len = 0; - } - pa_next = pa + PAGE_SIZE; - pagesz = PAGE_SIZE - off; - if (size < pagesz) - pagesz = size; - map->dm_segs[seg].ds_len += pagesz; - size -= pagesz; - addr = (caddr_t)addr + off + pagesz; - off = 0; + seg = 0; + error = mbus_dmamap_load_buffer(cookie, map, buf, buflen, p, flags, + &lastaddr, &seg, 1); + if (error == 0) { + map->dm_mapsize = buflen; + map->dm_nsegs = seg + 1; } - - /* Make the map truly valid. */ - map->dm_nsegs = seg + 1; - map->dm_mapsize = mapsize; - - return (0); + return (error); } int -mbus_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags) +mbus_dmamap_load_mbuf(void *cookie, bus_dmamap_t map, struct mbuf *m0, int flags) { - panic("_dmamap_load_mbuf: not implemented"); + paddr_t lastaddr; + int seg, error, first; + struct mbuf *m; + + /* + * Make sure that on error condition we return "no valid mappings." + */ + map->dm_mapsize = 0; + map->dm_nsegs = 0; + +#ifdef DIAGNOSTIC + if ((m0->m_flags & M_PKTHDR) == 0) + panic("_bus_dmamap_load_mbuf: no packet header"); +#endif + + if (m0->m_pkthdr.len > map->_dm_size) + return (EINVAL); + + first = 1; + seg = 0; + error = 0; + for (m = m0; m != NULL && error == 0; m = m->m_next) { + error = mbus_dmamap_load_buffer(cookie, map, + m->m_data, m->m_len, NULL, flags, &lastaddr, &seg, first); + first = 0; + } + if (error == 0) { + map->dm_mapsize = m0->m_pkthdr.len; + map->dm_nsegs = seg + 1; + } + return (error); } int -mbus_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags) +mbus_dmamap_load_uio(void *cookie, bus_dmamap_t map, struct uio *uio, int flags) { - panic("_dmamap_load_uio: not implemented"); + paddr_t lastaddr; + int seg, i, error, first; + bus_size_t minlen, resid; + struct proc *p = NULL; + struct iovec *iov; + caddr_t addr; + + /* + * Make sure that on error condition we return "no valid mappings." + */ + map->dm_mapsize = 0; + map->dm_nsegs = 0; + + resid = uio->uio_resid; + iov = uio->uio_iov; + + if (uio->uio_segflg == UIO_USERSPACE) { + p = uio->uio_procp; +#ifdef DIAGNOSTIC + if (p == NULL) + panic("_bus_dmamap_load_uio: USERSPACE but no proc"); +#endif + } + + first = 1; + seg = 0; + error = 0; + for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) { + /* + * Now at the first iovec to load. Load each iovec + * until we have exhausted the residual count. + */ + minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len; + addr = (caddr_t)iov[i].iov_base; + + error = mbus_dmamap_load_buffer(cookie, map, addr, minlen, + p, flags, &lastaddr, &seg, first); + first = 0; + + resid -= minlen; + } + if (error == 0) { + map->dm_mapsize = uio->uio_resid; + map->dm_nsegs = seg + 1; + } + return (error); } /* @@ -900,7 +1041,7 @@ * bus_dmamem_alloc(). */ int -mbus_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs, +mbus_dmamap_load_raw(void *cookie, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) { struct pglist *mlist; @@ -929,7 +1070,7 @@ pa = VM_PAGE_TO_PHYS(m); if (pa != pa_next) { if (++seg >= map->_dm_segcnt) - panic("mbus_dmamem_load_raw: nsegs botch"); + return (EFBIG); map->dm_segs[seg].ds_addr = pa; map->dm_segs[seg].ds_len = 0; } @@ -951,8 +1092,9 @@ * unload a DMA map. */ void -mbus_dmamap_unload(void *v, bus_dmamap_t map) +mbus_dmamap_unload(void *cookie, bus_dmamap_t map) { + /* * If this map was loaded with mbus_dmamap_load, * we don't need to do anything. If this map was @@ -966,25 +1108,89 @@ } void -mbus_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t addr, bus_size_t size, int ops) +mbus_dmamap_sync(void *cookie, bus_dmamap_t map, bus_addr_t offset, bus_size_t len, int ops) { + bus_size_t minlen; + bus_addr_t addr; + int i; + /* - * XXX - for now, we flush the whole map. + * Mixing PRE and POST operations is not allowed. */ + if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 && + (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0) + panic("_bus_dmamap_sync: mix PRE and POST"); + +#ifdef DIAGNOSTIC + if (offset >= map->dm_mapsize) + panic("mbus_dmamap_sync: bad offset %lu (map size is %lu)", + offset, map->dm_mapsize); + if (len == 0 || (offset + len) > map->dm_mapsize) + panic("mbus_dmamap_sync: bad length"); +#endif + + /* + * Since we're dealing with a virtually-indexed, write-back + * cache, we need to do the following things: + * + * PREREAD -- Invalidate D-cache. Note we might have + * to also write-back here if the buffer start/end is not + * cache-line aligned. + * + * PREWRITE -- Write-back the D-cache. + * + * POSTREAD -- Nothing. + * + * POSTWRITE -- Nothing. + */ + + ops &= (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + if (ops == 0) + return; +#if notyet /* - * For everything except BUS_DMASYNC_POSTWRITE, flush - * the map from the cache. For BUS_DMASYNC_PREREAD and - * BUS_DMASYNC_POSTREAD we should only need to purge the - * map, but this isn't good enough for the osiop driver, - * at least. + * If the mapping is of COHERENT DMA-safe memory, no cache + * flush is necessary. */ - if (ops & (BUS_DMASYNC_PREWRITE | - BUS_DMASYNC_PREREAD | - BUS_DMASYNC_POSTREAD)) { - fdcache(HPPA_SID_KERNEL, map->dm_segs[0]._ds_va, - map->dm_mapsize); - sync_caches(); + if (map->_dm_flags & HPPA_DMAMAP_COHERENT) + return; +#endif + + for (i = 0; i < map->dm_nsegs && len != 0; i++) { + /* Find the beginning segment. */ + if (offset >= map->dm_segs[i].ds_len) { + offset -= map->dm_segs[i].ds_len; + continue; + } + + /* + * Now at the first segment to sync; nail + * each segment until we have exhausted the + * length. + */ + minlen = len < map->dm_segs[i].ds_len - offset ? + len : map->dm_segs[i].ds_len - offset; + + addr = map->dm_segs[i]._ds_va; + + switch (ops) { + case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: + case BUS_DMASYNC_PREWRITE: + fdcache(HPPA_SID_KERNEL, addr + offset, minlen); + sync_caches(); + break; + + case BUS_DMASYNC_PREREAD: + if (cache_align(addr + offset) == 0 && + cache_align(addr + offset + minlen) == 0) + pdcache(HPPA_SID_KERNEL, addr + offset, minlen); + else + fdcache(HPPA_SID_KERNEL, addr + offset, minlen); + break; + } + offset = 0; + len -= minlen; } } @@ -993,7 +1199,7 @@ * by bus-specific DMA memory allocation functions. */ int -mbus_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment, +mbus_dmamem_alloc(void *cookie, bus_size_t size, bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags) { @@ -1096,7 +1302,7 @@ } void -mbus_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs) +mbus_dmamem_free(void *cookie, bus_dma_segment_t *segs, int nsegs) { /* @@ -1116,8 +1322,7 @@ * bus-specific DMA memory map functions. */ int -mbus_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size, - caddr_t *kvap, int flags) +mbus_dmamem_map(void *cookie, bus_dma_segment_t *segs, int nsegs, size_t size, caddr_t *kvap, int flags) { struct vm_page *m; vaddr_t va; @@ -1162,8 +1367,18 @@ pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE); -#if notused - pmap_changebit(va, TLB_UNCACHEABLE, 0); /* XXX for now */ + +#if notyet + if (flags & BUS_DMA_COHERENT) + /* + * If the memory must remain coherent with the + * cache then we must make the memory uncacheable + * in order to maintain virtual cache coherency. + * We must also guarentee the cache does not already + * contain the virtal addresses we are making + * uncacheable. + */ + /*pmap_changebit(va, TLB_UNCACHEABLE, 0);*/ #endif va += PAGE_SIZE; @@ -1179,7 +1394,7 @@ * bus-specific DMA memory unmapping functions. */ void -mbus_dmamem_unmap(void *v, caddr_t kva, size_t size) +mbus_dmamem_unmap(void *cookie, caddr_t kva, size_t size) { #ifdef DIAGNOSTIC @@ -1203,7 +1418,7 @@ * bus-specific DMA mmap(2)'ing functions. */ paddr_t -mbus_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off, +mbus_dmamem_mmap(void *cookie, bus_dma_segment_t *segs, int nsegs, off_t off, int prot, int flags) { panic("_dmamem_mmap: not implemented"); Index: arch/hppa/hppa/vm_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/hppa/hppa/vm_machdep.c,v retrieving revision 1.2 diff -u -r1.2 vm_machdep.c --- arch/hppa/hppa/vm_machdep.c 2002/07/01 16:10:03 1.2 +++ arch/hppa/hppa/vm_machdep.c 2003/02/18 14:42:21 @@ -276,54 +276,41 @@ struct buf *bp; vsize_t len; { - vaddr_t addr, kva; - paddr_t pa; - vsize_t size, off; - int npf; - struct proc *p; - struct vm_map *map; + struct pmap *upmap, *kpmap; + vaddr_t uva; /* User VA (map from) */ + vaddr_t kva; /* Kernel VA (new to) */ + paddr_t pa; /* physical address */ + vsize_t off; #ifdef DIAGNOSTIC if ((bp->b_flags & B_PHYS) == 0) panic("vmapbuf"); #endif - p = bp->b_proc; - map = &p->p_vmspace->vm_map; bp->b_saveaddr = bp->b_data; - addr = (vaddr_t)bp->b_saveaddr; - off = addr & PGOFSET; - size = round_page(bp->b_bcount + off); + uva = trunc_page((vaddr_t)bp->b_saveaddr); + off = (vaddr_t)bp->b_data - uva; + len = round_page(off + len); /* - * Note that this is an expanded version of: - * kva = uvm_km_valloc_wait(kernel_map, size); * We do it on our own here to be able to specify an offset to uvm_map * so that we can get all benefits of PMAP_PREFER. * - art@ */ - while (1) { - kva = vm_map_min(phys_map); - if (uvm_map(phys_map, &kva, size, NULL, addr, 0, - UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, - UVM_INH_NONE, UVM_ADV_RANDOM, 0)) == 0) - break; - tsleep(phys_map, PVM, "vallocwait", 0); - } - + kva = uvm_km_valloc_prefer_wait(phys_map, len, uva); bp->b_data = (caddr_t)(kva + off); - addr = trunc_page(addr); - npf = btoc(size); - while (npf--) { - /* not needed, thanks to PMAP_PREFER() */ - /* fdcache(vm_map_pmap(map)->pmap_space, addr, PAGE_SIZE); */ + upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map); + kpmap = vm_map_pmap(phys_map); + fdcache(upmap->pmap_space, uva, len); - if (pmap_extract(vm_map_pmap(map), addr, &pa) == FALSE) + while (len) { + if (pmap_extract(upmap, uva, &pa) == FALSE) panic("vmapbuf: null page frame"); - pmap_enter(vm_map_pmap(phys_map), kva, pa, + pmap_enter(kpmap, kva, pa, VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED); - addr += PAGE_SIZE; + uva += PAGE_SIZE; kva += PAGE_SIZE; + len -= PAGE_SIZE; } } @@ -335,16 +322,19 @@ struct buf *bp; vsize_t len; { - vaddr_t addr, off; + vaddr_t kva; + vsize_t off; #ifdef DIAGNOSTIC if ((bp->b_flags & B_PHYS) == 0) panic("vunmapbuf"); #endif - addr = trunc_page((vaddr_t)bp->b_data); - off = (vaddr_t)bp->b_data - addr; + kva = trunc_page((vaddr_t)bp->b_data); + off = (vaddr_t)bp->b_data - kva; len = round_page(off + len); - uvm_km_free_wakeup(phys_map, addr, len); + pmap_remove(vm_map_pmap(phys_map), kva, kva + len); + pmap_update(pmap_kernel()); + uvm_km_free_wakeup(phys_map, kva, len); bp->b_data = bp->b_saveaddr; bp->b_saveaddr = NULL; } Index: conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.587 diff -u -r1.587 files --- conf/files 2002/12/26 12:31:24 1.587 +++ conf/files 2003/02/18 14:42:31 @@ -375,6 +375,10 @@ device lfmiop: scsi file dev/ic/lfmiop.c lfmiop +# Symbios/NCR 53c700 SCSI controllers +device oosiop: scsi +file dev/ic/oosiop.c oosiop + # Symbios/NCR 53c710 SCSI controllers # device osiop: scsi @@ -784,6 +788,11 @@ device igsfb: wsemuldisplaydev, wsrasteremulops, rasops8 file dev/ic/igsfb.c igsfb file dev/ic/igsfb_subr.c igsfb + +# STI (HP graphics) +# +device sti: wsemuldisplaydev +file dev/ic/sti.c sti & (sti_pci|sti_sgc) needs-flag # Attributes which machine-independent bus support can be attached to. # These should be defined here, because some of these busses can have Index: dev/DEVNAMES =================================================================== RCS file: /cvsroot/src/sys/dev/DEVNAMES,v retrieving revision 1.127 diff -u -r1.127 DEVNAMES --- dev/DEVNAMES 2002/12/09 12:56:15 1.127 +++ dev/DEVNAMES 2003/02/18 14:42:31 @@ -804,6 +804,7 @@ oldscsibus pmax olms i386 omms i386 +oosiop MI openfirm arm32 openfirm macppc openfirm ofppc Index: dev/microcode/siop/oosiop.out =================================================================== RCS file: /cvsroot/src/sys/dev/microcode/siop/oosiop.out,v retrieving revision 1.2 diff -u -r1.2 oosiop.out --- dev/microcode/siop/oosiop.out 2002/07/07 23:01:51 1.2 +++ dev/microcode/siop/oosiop.out 2003/02/18 14:42:33 @@ -1,298 +1,82 @@ -/* $NetBSD: oosiop.out,v 1.2 2002/07/07 23:01:51 fredette Exp $ */ +/* $NetBSD: ncr53cxxx.c,v 1.6 2001/04/29 11:20:44 tsutsui Exp $ */ /* * DO NOT EDIT - this file is automatically generated. - * created from oosiop.ss on Sun Jul 7 19:00:49 2002 + * created from oosiop.ss on Sun Dec 8 02:59:25 2002 */ const u_int32_t oosiop_script[] = { - 0x41000000, 0x00000130, /* 000 - 0 */ - 0x870b0000, 0x00000040, /* 008 - 8 */ - 0x860a0000, 0x00000190, /* 010 - 16 */ - 0x820a0000, 0x000001a0, /* 018 - 24 */ - 0x800a0000, 0x000001b8, /* 020 - 32 */ - 0x810a0000, 0x000002c8, /* 028 - 40 */ - 0x830a0000, 0x000003d8, /* 030 - 48 */ - 0x98080000, 0x0000ff05, /* 038 - 56 */ - 0x0f000000, 0x00000000, /* 040 - 64 */ - 0x800c0001, 0x00000090, /* 048 - 72 */ - 0x800c0004, 0x000000e0, /* 050 - 80 */ - 0x800c0002, 0x000000f8, /* 058 - 88 */ - 0x800c0007, 0x00000078, /* 060 - 96 */ - 0x800c0003, 0x00000078, /* 068 - 104 */ - 0x98080000, 0x0000ff06, /* 070 - 112 */ - 0x60000040, 0x00000000, /* 078 - 120 */ - 0x60000008, 0x00000000, /* 080 - 128 */ - 0x80080000, 0x00000008, /* 088 - 136 */ - 0x60000040, 0x00000000, /* 090 - 144 */ - 0x0f000000, 0x00000000, /* 098 - 152 */ - 0x800c0003, 0x000000b0, /* 0a0 - 160 */ - 0x98080000, 0x0000ff07, /* 0a8 - 168 */ - 0x60000040, 0x00000000, /* 0b0 - 176 */ - 0x0f000000, 0x00000000, /* 0b8 - 184 */ - 0x98080000, 0x0000ff0b, /* 0c0 - 192 */ - 0x58000008, 0x00000000, /* 0c8 - 200 */ - 0x60000040, 0x00000000, /* 0d0 - 208 */ - 0x80080000, 0x00000008, /* 0d8 - 216 */ - 0x60000040, 0x00000000, /* 0e0 - 224 */ - 0x48000000, 0x00000000, /* 0e8 - 232 */ - 0x98080000, 0x0000ff02, /* 0f0 - 240 */ - 0x60000040, 0x00000000, /* 0f8 - 248 */ - 0x87030000, 0x00000008, /* 100 - 256 */ - 0x0f000000, 0x00000000, /* 108 - 264 */ - 0x98040004, 0x0000ff08, /* 110 - 272 */ + 0x54000000, 0x00000008, /* 000 - 0 */ + 0x98080000, 0xbeef0003, /* 008 - 8 */ + 0x98080000, 0xbeef0005, /* 010 - 16 */ + 0x9f030000, 0xdeadbeef, /* 018 - 24 */ + 0x0f000000, 0x00000000, /* 020 - 32 */ + 0x98080000, 0xbeef0004, /* 028 - 40 */ + 0x45000000, 0xffffffc8, /* 030 - 48 */ + 0x878b0000, 0x00000030, /* 038 - 56 */ + 0x868b0000, 0x00000078, /* 040 - 64 */ + 0x838b0000, 0x000000a0, /* 048 - 72 */ + 0x828b0000, 0x00000080, /* 050 - 80 */ + 0x810b0000, 0x00000000, /* 058 - 88 */ + 0x800b0000, 0x00000000, /* 060 - 96 */ + 0x98080000, 0xdeadbeef, /* 068 - 104 */ + 0x60000008, 0x00000000, /* 070 - 112 */ + 0x0f000000, 0x00000000, /* 078 - 120 */ + 0x808c0000, 0x00000090, /* 080 - 128 */ + 0x808c0001, 0x000000a0, /* 088 - 136 */ + 0x808c0004, 0x00000068, /* 090 - 144 */ + 0x98080000, 0xbeef0001, /* 098 - 152 */ + 0x60000040, 0x00000000, /* 0a0 - 160 */ + 0x80880000, 0xffffff88, /* 0a8 - 168 */ + 0x58000008, 0x00000000, /* 0b0 - 176 */ + 0x60000040, 0x00000000, /* 0b8 - 184 */ + 0x0e000000, 0x00000000, /* 0c0 - 192 */ + 0x60000008, 0x00000000, /* 0c8 - 200 */ + 0x80880000, 0xffffff60, /* 0d0 - 208 */ + 0x60000008, 0x00000000, /* 0d8 - 216 */ + 0x0a000000, 0x00000000, /* 0e0 - 224 */ + 0x80880000, 0xffffff48, /* 0e8 - 232 */ + 0x0b000000, 0x00000000, /* 0f0 - 240 */ + 0x80880000, 0xffffff38, /* 0f8 - 248 */ + 0x60000040, 0x00000000, /* 100 - 256 */ + 0x48000000, 0x00000000, /* 108 - 264 */ + 0x98080000, 0xbeef0006, /* 110 - 272 */ 0x60000040, 0x00000000, /* 118 - 280 */ 0x48000000, 0x00000000, /* 120 - 288 */ - 0x98080000, 0x0000ff01, /* 128 - 296 */ - 0x50000000, 0x00000170, /* 130 - 304 */ - 0x80000000, 0x00000000, /* 138 - 312 */ - 0x80000000, 0x00000000, /* 140 - 320 */ - 0x9f030000, 0x0000ff09, /* 148 - 328 */ - 0x0f000000, 0x00000000, /* 150 - 336 */ - 0x98080000, 0x0000ff03, /* 158 - 344 */ - 0x60000040, 0x00000000, /* 160 - 352 */ - 0x80080000, 0x00000008, /* 168 - 360 */ - 0x74011000, 0x00000000, /* 170 - 368 */ - 0x980c0000, 0x0000ff04, /* 178 - 376 */ - 0x80000000, 0x00000000, /* 180 - 384 */ - 0x80080000, 0x00000130, /* 188 - 392 */ - 0x0e000000, 0x00000000, /* 190 - 400 */ - 0x80080000, 0x00000008, /* 198 - 408 */ - 0x60000008, 0x00000000, /* 1a0 - 416 */ - 0x0a000000, 0x00000000, /* 1a8 - 424 */ - 0x80080000, 0x00000008, /* 1b0 - 432 */ - 0x08000000, 0x00000000, /* 1b8 - 440 */ - 0x88030000, 0x00000008, /* 1c0 - 448 */ - 0x08000000, 0x00000000, /* 1c8 - 456 */ - 0x88030000, 0x00000008, /* 1d0 - 464 */ - 0x08000000, 0x00000000, /* 1d8 - 472 */ - 0x88030000, 0x00000008, /* 1e0 - 480 */ - 0x08000000, 0x00000000, /* 1e8 - 488 */ - 0x88030000, 0x00000008, /* 1f0 - 496 */ - 0x08000000, 0x00000000, /* 1f8 - 504 */ - 0x88030000, 0x00000008, /* 200 - 512 */ - 0x08000000, 0x00000000, /* 208 - 520 */ - 0x88030000, 0x00000008, /* 210 - 528 */ - 0x08000000, 0x00000000, /* 218 - 536 */ - 0x88030000, 0x00000008, /* 220 - 544 */ - 0x08000000, 0x00000000, /* 228 - 552 */ - 0x88030000, 0x00000008, /* 230 - 560 */ - 0x08000000, 0x00000000, /* 238 - 568 */ - 0x88030000, 0x00000008, /* 240 - 576 */ - 0x08000000, 0x00000000, /* 248 - 584 */ - 0x88030000, 0x00000008, /* 250 - 592 */ - 0x08000000, 0x00000000, /* 258 - 600 */ - 0x88030000, 0x00000008, /* 260 - 608 */ - 0x08000000, 0x00000000, /* 268 - 616 */ - 0x88030000, 0x00000008, /* 270 - 624 */ - 0x08000000, 0x00000000, /* 278 - 632 */ - 0x88030000, 0x00000008, /* 280 - 640 */ - 0x08000000, 0x00000000, /* 288 - 648 */ - 0x88030000, 0x00000008, /* 290 - 656 */ - 0x08000000, 0x00000000, /* 298 - 664 */ - 0x88030000, 0x00000008, /* 2a0 - 672 */ - 0x08000000, 0x00000000, /* 2a8 - 680 */ - 0x88030000, 0x00000008, /* 2b0 - 688 */ - 0x08000000, 0x00000000, /* 2b8 - 696 */ - 0x88080000, 0x00000008, /* 2c0 - 704 */ - 0x09000000, 0x00000000, /* 2c8 - 712 */ - 0x89030000, 0x00000008, /* 2d0 - 720 */ - 0x09000000, 0x00000000, /* 2d8 - 728 */ - 0x89030000, 0x00000008, /* 2e0 - 736 */ - 0x09000000, 0x00000000, /* 2e8 - 744 */ - 0x89030000, 0x00000008, /* 2f0 - 752 */ - 0x09000000, 0x00000000, /* 2f8 - 760 */ - 0x89030000, 0x00000008, /* 300 - 768 */ - 0x09000000, 0x00000000, /* 308 - 776 */ - 0x89030000, 0x00000008, /* 310 - 784 */ - 0x09000000, 0x00000000, /* 318 - 792 */ - 0x89030000, 0x00000008, /* 320 - 800 */ - 0x09000000, 0x00000000, /* 328 - 808 */ - 0x89030000, 0x00000008, /* 330 - 816 */ - 0x09000000, 0x00000000, /* 338 - 824 */ - 0x89030000, 0x00000008, /* 340 - 832 */ - 0x09000000, 0x00000000, /* 348 - 840 */ - 0x89030000, 0x00000008, /* 350 - 848 */ - 0x09000000, 0x00000000, /* 358 - 856 */ - 0x89030000, 0x00000008, /* 360 - 864 */ - 0x09000000, 0x00000000, /* 368 - 872 */ - 0x89030000, 0x00000008, /* 370 - 880 */ - 0x09000000, 0x00000000, /* 378 - 888 */ - 0x89030000, 0x00000008, /* 380 - 896 */ - 0x09000000, 0x00000000, /* 388 - 904 */ - 0x89030000, 0x00000008, /* 390 - 912 */ - 0x09000000, 0x00000000, /* 398 - 920 */ - 0x89030000, 0x00000008, /* 3a0 - 928 */ - 0x09000000, 0x00000000, /* 3a8 - 936 */ - 0x89030000, 0x00000008, /* 3b0 - 944 */ - 0x09000000, 0x00000000, /* 3b8 - 952 */ - 0x89030000, 0x00000008, /* 3c0 - 960 */ - 0x09000000, 0x00000000, /* 3c8 - 968 */ - 0x88080000, 0x00000008, /* 3d0 - 976 */ - 0x0b000000, 0x00000000, /* 3d8 - 984 */ - 0x9f030000, 0x0000ff0a, /* 3e0 - 992 */ - 0x0f000000, 0x00000000, /* 3e8 - 1000 */ - 0x60000040, 0x00000000, /* 3f0 - 1008 */ - 0x48000000, 0x00000000, /* 3f8 - 1016 */ - 0x98080000, 0x0000ff00, /* 400 - 1024 */ - 0x80080000, 0x00000130, /* 408 - 1032 */ -}; - -#define E_ds_Device 0x00000000 -u_int32_t E_ds_Device_Used[] = { - 0x00000001, -}; - -#define E_ds_MsgOut 0x00000000 -u_int32_t E_ds_MsgOut_Used[] = { - 0x00000065, -}; - -#define E_ds_Cmd 0x00000000 -u_int32_t E_ds_Cmd_Used[] = { - 0x0000006b, -}; - -#define E_ds_Status 0x00000000 -u_int32_t E_ds_Status_Used[] = { - 0x000000f7, -}; - -#define E_ds_Msg 0x00000000 -u_int32_t E_ds_Msg_Used[] = { - 0x00000055, - 0x000000fb, -}; - -#define E_ds_MsgIn 0x00000000 -u_int32_t E_ds_MsgIn_Used[] = { - 0x00000011, -}; - -#define E_ds_ExtMsg 0x00000000 -u_int32_t E_ds_ExtMsg_Used[] = { - 0x00000027, - 0x00000043, -}; - -#define E_ds_SyncMsg 0x00000000 -u_int32_t E_ds_SyncMsg_Used[] = { - 0x0000002f, -}; - -#define E_ds_Data1 0x00000000 -u_int32_t E_ds_Data1_Used[] = { - 0x0000006f, - 0x00000073, - 0x00000077, - 0x0000007b, - 0x0000007f, - 0x00000083, - 0x00000087, - 0x0000008b, - 0x0000008f, - 0x00000093, - 0x00000097, - 0x0000009b, - 0x0000009f, - 0x000000a3, - 0x000000a7, - 0x000000ab, - 0x000000af, - 0x000000b3, - 0x000000b7, - 0x000000bb, - 0x000000bf, - 0x000000c3, - 0x000000c7, - 0x000000cb, - 0x000000cf, - 0x000000d3, - 0x000000d7, - 0x000000db, - 0x000000df, - 0x000000e3, - 0x000000e7, - 0x000000eb, - 0x000000ef, - 0x000000f3, -}; - -#define A_ok 0x0000ff00 -#define A_int_disc 0x0000ff01 -#define A_int_disc_wodp 0x0000ff02 -#define A_int_reconnect 0x0000ff03 -#define A_int_connect 0x0000ff04 -#define A_int_phase 0x0000ff05 -#define A_int_msgin 0x0000ff06 -#define A_int_extmsg 0x0000ff07 -#define A_int_msgsdp 0x0000ff08 -#define A_int_identify 0x0000ff09 -#define A_int_status 0x0000ff0a -#define A_int_syncmsg 0x0000ff0b -#define Ent_scripts 0x00000000 -#define Ent_switch 0x00000008 -#define Ent_wait_reselect 0x00000130 -#define Ent_dataout 0x000001b8 -#define Ent_datain 0x000002c8 -#define Ent_clear_ack 0x00000078 - -u_int32_t INSTRUCTIONS = 0x00000082; -u_int32_t PATCHES = 0x00000038; -u_int32_t LABELPATCHES[] = { - 0x00000001, - 0x00000003, - 0x00000005, - 0x00000007, - 0x00000009, - 0x0000000b, - 0x0000000d, - 0x00000013, - 0x00000015, - 0x00000017, - 0x00000019, - 0x0000001b, - 0x00000023, - 0x00000029, - 0x00000037, - 0x00000041, - 0x0000004d, - 0x0000005b, - 0x00000063, - 0x00000067, - 0x0000006d, - 0x00000071, - 0x00000075, - 0x00000079, - 0x0000007d, - 0x00000081, - 0x00000085, - 0x00000089, - 0x0000008d, - 0x00000091, - 0x00000095, - 0x00000099, - 0x0000009d, - 0x000000a1, - 0x000000a5, - 0x000000a9, - 0x000000ad, - 0x000000b1, - 0x000000b5, - 0x000000b9, - 0x000000bd, - 0x000000c1, - 0x000000c5, - 0x000000c9, - 0x000000cd, - 0x000000d1, - 0x000000d5, - 0x000000d9, - 0x000000dd, - 0x000000e1, - 0x000000e5, - 0x000000e9, - 0x000000ed, - 0x000000f1, - 0x000000f5, - 0x00000103, -}; + 0x98080000, 0xbeef0000, /* 128 - 296 */ + 0x60000040, 0x00000000, /* 130 - 304 */ + 0x9f020000, 0xdeadbeef, /* 138 - 312 */ + 0x0f000000, 0x00000000, /* 140 - 320 */ + 0x98080000, 0xbeef0002, /* 148 - 328 */ + 0x60000040, 0x00000000, /* 150 - 336 */ + 0x9f020000, 0xdeadbeef, /* 158 - 344 */ + 0x0f000000, 0x00000000, /* 160 - 352 */ + 0x98080000, 0xbeef0001, /* 168 - 360 */ +}; + +#define A_int_done 0xbeef0000 +#define A_int_msgin 0xbeef0001 +#define A_int_extmsg 0xbeef0002 +#define A_int_resel 0xbeef0003 +#define A_int_res_id 0xbeef0004 +#define A_int_resfail 0xbeef0005 +#define A_int_disc 0xbeef0006 +#define A_int_err 0xdeadbeef +#define Ent_p_resel_msgin_move 0x00000020 +#define Ent_p_select 0x00000030 +#define Ent_p_datain_jump 0x00000058 +#define Ent_p_dataout_jump 0x00000060 +#define Ent_p_msgin_move 0x00000078 +#define Ent_p_msgout_move 0x000000c0 +#define Ent_p_cmdout_move 0x000000e0 +#define Ent_p_status_move 0x000000f0 +#define Ent_p_extmsglen_move 0x00000140 +#define Ent_p_extmsgin_move 0x00000160 +#define Ent_wait_reselect 0x00000000 +#define Ent_wait_resel_identify 0x00000018 +#define Ent_start_select 0x00000030 +#define Ent_phasedispatch 0x00000038 +#define Ent_ack_msgin 0x000000a0 +#define Ent_sendmsg 0x000000b0 +#define Ent_rcv_extmsg 0x00000150 +u_int32_t INSTRUCTIONS = 0x0000002e; +u_int32_t PATCHES = 0x00000000; Index: dev/microcode/siop/oosiop.ss =================================================================== RCS file: /cvsroot/src/sys/dev/microcode/siop/oosiop.ss,v retrieving revision 1.1 diff -u -r1.1 oosiop.ss --- dev/microcode/siop/oosiop.ss 2001/12/05 18:27:13 1.1 +++ dev/microcode/siop/oosiop.ss 2003/02/18 14:42:33 @@ -1,243 +1,119 @@ -; $NetBSD: oosiop.ss,v 1.1 2001/12/05 18:27:13 fredette Exp $ +ARCH 700 -; -; Copyright (c) 2001 Matt Fredette -; Copyright (c) 1995 Michael L. Hitch -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions -; are met: -; 1. Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; 2. Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; 3. All advertising materials mentioning features or use of this software -; must display the following acknowledgement: -; This product includes software developed by Michael L. Hitch. -; 4. The name of the author may not be used to endorse or promote products -; derived from this software without specific prior written permission -; -; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -; +; interrupt codes +ABSOLUTE int_done = 0xbeef0000 +ABSOLUTE int_msgin = 0xbeef0001 +ABSOLUTE int_extmsg = 0xbeef0002 +ABSOLUTE int_resel = 0xbeef0003 +ABSOLUTE int_res_id = 0xbeef0004 +ABSOLUTE int_resfail = 0xbeef0005 +ABSOLUTE int_disc = 0xbeef0006 +ABSOLUTE int_err = 0xdeadbeef + +; patch entries +ENTRY p_resel_msgin_move +ENTRY p_select +ENTRY p_datain_jump +ENTRY p_dataout_jump +ENTRY p_msgin_move +ENTRY p_msgout_move +ENTRY p_cmdout_move +ENTRY p_status_move +ENTRY p_extmsglen_move +ENTRY p_extmsgin_move -; NCR 53c700 script -; -ARCH 700 -; -EXTERNAL ds_Device -EXTERNAL ds_MsgOut -EXTERNAL ds_Cmd -EXTERNAL ds_Status -EXTERNAL ds_Msg -EXTERNAL ds_MsgIn -EXTERNAL ds_ExtMsg -EXTERNAL ds_SyncMsg -EXTERNAL ds_Data1 - - -ABSOLUTE ok = 0xff00 -ABSOLUTE int_disc = 0xff01 -ABSOLUTE int_disc_wodp = 0xff02 -ABSOLUTE int_reconnect = 0xff03 -ABSOLUTE int_connect = 0xff04 -ABSOLUTE int_phase = 0xff05 -ABSOLUTE int_msgin = 0xff06 -ABSOLUTE int_extmsg = 0xff07 -ABSOLUTE int_msgsdp = 0xff08 -ABSOLUTE int_identify = 0xff09 -ABSOLUTE int_status = 0xff0a -ABSOLUTE int_syncmsg = 0xff0b - -ENTRY scripts -ENTRY switch -ENTRY wait_reselect -ENTRY dataout -ENTRY datain -ENTRY clear_ack - -PROC oosiop_script: - -scripts: - - SELECT ATN ds_Device, reselect -; -switch: - JUMP msgin, WHEN MSG_IN - JUMP msgout, IF MSG_OUT - JUMP command_phase, IF CMD - JUMP dataout, IF DATA_OUT - JUMP datain, IF DATA_IN - JUMP end, IF STATUS - INT int_phase ; Unrecognized phase +PROC oosiop_script: +ENTRY wait_reselect +wait_reselect: + WAIT RESELECT REL(reselect_fail) + INT int_resel +reselect_fail: + INT int_resfail + +ENTRY wait_resel_identify +wait_resel_identify: + INT int_err, WHEN NOT MSG_IN +p_resel_msgin_move: + MOVE 0, 0, WHEN MSG_IN + INT int_res_id + +ENTRY start_select +start_select: +p_select: + SELECT ATN 0, REL(wait_reselect) + +ENTRY phasedispatch +phasedispatch: + JUMP REL(msgin), WHEN MSG_IN + JUMP REL(msgout), WHEN MSG_OUT + JUMP REL(status), WHEN STATUS + JUMP REL(cmdout), WHEN CMD +p_datain_jump: + JUMP 0, WHEN DATA_IN +p_dataout_jump: + JUMP 0, WHEN DATA_OUT + INT int_err + msgin: - MOVE 0, ds_MsgIn, WHEN MSG_IN - JUMP ext_msg, IF 0x01 ; extended message - JUMP disc, IF 0x04 ; disconnect message - JUMP msg_sdp, IF 0x02 ; save data pointers - JUMP msg_rej, IF 0x07 ; message reject - JUMP msg_rdp, IF 0x03 ; restore data pointers - INT int_msgin ; unrecognized message - -msg_rej: -; Do we need to interrupt host here to let it handle the reject? -msg_rdp: -clear_ack: - CLEAR ACK CLEAR ATN - JUMP switch +p_msgin_move: + MOVE 0, 0, WHEN MSG_IN + JUMP REL(complete), IF 0x00 + JUMP REL(extmsgsetup), IF 0x01 + JUMP REL(disconnect), IF 0x04 + INT int_msgin -ext_msg: +ENTRY ack_msgin +ack_msgin: CLEAR ACK - MOVE 0, ds_ExtMsg, WHEN MSG_IN - JUMP sync_msg, IF 0x03 - int int_extmsg ; extended message not SDTR + JUMP REL(phasedispatch) -sync_msg: - CLEAR ACK - MOVE 0, ds_SyncMsg, WHEN MSG_IN - int int_syncmsg ; Let host handle the message -; If we continue from the interrupt, the host has set up a response -; message to be sent. Set ATN, clear ACK, and continue. +ENTRY sendmsg +sendmsg: SET ATN CLEAR ACK - JUMP switch +msgout: +p_msgout_move: + MOVE 0, 0, WHEN MSG_OUT + CLEAR ATN + JUMP REL(phasedispatch) + +cmdout: + CLEAR ATN +p_cmdout_move: + MOVE 0, 0, WHEN CMD + JUMP REL(phasedispatch) + +status: +p_status_move: + MOVE 0, 0, WHEN STATUS + JUMP REL(phasedispatch) -disc: +disconnect: CLEAR ACK WAIT DISCONNECT + INT int_disc - int int_disc_wodp ; signal disconnect w/o save DP - -msg_sdp: - CLEAR ACK ; acknowledge message - JUMP switch, WHEN NOT MSG_IN - MOVE 0, ds_ExtMsg, WHEN MSG_IN - INT int_msgsdp, IF NOT 0x04 ; interrupt if not disconnect +complete: CLEAR ACK WAIT DISCONNECT - - INT int_disc ; signal disconnect + INT int_done -reselect: -wait_reselect: - WAIT RESELECT select_adr - ; NB: these NOPs are CRITICAL to preserve the 1:1 - ; correspondence between instructions in this script - ; and instructions in the osiop (53c710) script: - NOP - NOP ; reselect ID already in SFBR - - INT int_identify, WHEN NOT MSG_IN - MOVE 0, ds_Msg, WHEN MSG_IN - INT int_reconnect ; let host know about reconnect - CLEAR ACK ; acknowlege the message - JUMP switch - -select_adr: - MOVE SCNTL1 & 0x10 to SFBR ; get connected status - INT int_connect, IF 0x00 ; tell host if not connected - NOP ; Sig_P doesn't exist on the 53c700 - JUMP wait_reselect ; and try reselect again - -msgout: - MOVE 0, ds_MsgOut, WHEN MSG_OUT - JUMP switch - -command_phase: - CLEAR ATN - MOVE 0, ds_Cmd, WHEN CMD - JUMP switch - -dataout: - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch, WHEN NOT DATA_OUT - MOVE 0, ds_Data1, WHEN DATA_OUT - CALL switch - -datain: - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch, WHEN NOT DATA_IN - MOVE 0, ds_Data1, WHEN DATA_IN - CALL switch - -end: - MOVE 0, ds_Status, WHEN STATUS - int int_status, WHEN NOT MSG_IN ; status not followed by msg - MOVE 0, ds_Msg, WHEN MSG_IN +; receive extended message length +extmsgsetup: CLEAR ACK - WAIT DISCONNECT - INT ok ; signal completion - JUMP wait_reselect + INT int_err, IF NOT MSG_IN +p_extmsglen_move: + MOVE 0, 0, WHEN MSG_IN + INT int_extmsg + +; receive extended message +ENTRY rcv_extmsg +rcv_extmsg: + CLEAR ACK + INT int_err, IF NOT MSG_IN +p_extmsgin_move: + MOVE 0, 0, WHEN MSG_IN + INT int_msgin --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ arch/arc/jazz/oosiop_jazzio.c 2003-02-16 16:20:25.000000000 +0900 @@ -0,0 +1,107 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2001 Shuichiro URATA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +int oosiop_jazzio_match(struct device *, struct cfdata *, void *); +void oosiop_jazzio_attach(struct device *, struct device *, void *); + +CFATTACH_DECL(oosiop_jazzio, sizeof(struct oosiop_softc), + oosiop_jazzio_match, oosiop_jazzio_attach, NULL, NULL); +extern struct cfdriver oosiop_cd; + +/* + * Match driver based on name + */ +int +oosiop_jazzio_match(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + struct jazzio_attach_args *ja = aux; + + if (strcmp(ja->ja_name, "NCRC700") != 0) + return (0); + + return (1); +} + +void +oosiop_jazzio_attach(parent, self, aux) + struct device *parent; + struct device *self; + void *aux; +{ + struct jazzio_attach_args *ja = aux; + struct oosiop_softc *sc = (void *)self; + int i, scid; + + sc->sc_bst = ja->ja_bust; + sc->sc_dmat = ja->ja_dmat; + + if (bus_space_map(sc->sc_bst, ja->ja_addr, + OOSIOP_NREGS, 0, &sc->sc_bsh) != 0) { + printf(": failed to map regsters\n"); + return; + } + + sc->sc_chip = OOSIOP_700_66; + sc->sc_freq = 50000000; + + /* Preserve host id */ + scid = oosiop_read_1(sc, OOSIOP_SCID); + for (i = 0; i < OOSIOP_NTGT; i++) + if (scid & (1 << i)) + break; + if (i == OOSIOP_NTGT) + i = OOSIOP_NTGT - 1; + + sc->sc_id = i; + + jazzio_intr_establish(ja->ja_intr, (intr_handler_t)oosiop_intr, sc); + + oosiop_attach(sc); +} --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ arch/hp700/gsc/oosiop_gsc.c 2003-02-16 16:20:25.000000000 +0900 @@ -0,0 +1,174 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2001 Matt Fredette. All rights reserved. + * Copyright (c) 2001,2002 Izumi Tsutsui. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $OpenBSD: siop_gsc.c,v 1.1 1998/11/04 17:01:35 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define OOSIOP_GSC_RESET 0x0000 +#define OOSIOP_GSC_OFFSET 0x0100 + +int oosiop_gsc_match(struct device *, struct cfdata *, void *); +void oosiop_gsc_attach(struct device *, struct device *, void *); +int oosiop_gsc_intr(void *); + +CFATTACH_DECL(oosiop_gsc, sizeof(struct oosiop_softc), + oosiop_gsc_match, oosiop_gsc_attach, NULL, NULL); + +int +oosiop_gsc_match(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + struct gsc_attach_args *ga = aux; + bus_space_handle_t ioh; + int rv = 1; + + if (ga->ga_type.iodc_type != HPPA_TYPE_FIO || + ga->ga_type.iodc_sv_model != HPPA_FIO_SCSI) + return 0; + + if (bus_space_map(ga->ga_iot, ga->ga_hpa, + OOSIOP_GSC_OFFSET + OOSIOP_NREGS, 0, &ioh)) + return 0; + + + bus_space_unmap(ga->ga_iot, ioh, OOSIOP_GSC_OFFSET + OOSIOP_NREGS); + return rv; +} + +void +oosiop_gsc_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct oosiop_softc *sc = (void *)self; + struct gsc_attach_args *ga = aux; + bus_space_handle_t ioh; + + sc->sc_bst = ga->ga_iot; + sc->sc_dmat = ga->ga_dmatag; + if (bus_space_map(sc->sc_bst, ga->ga_hpa, + OOSIOP_GSC_OFFSET + OOSIOP_NREGS, 0, &ioh)) + panic("oosiop_gsc_attach: couldn't map I/O ports"); + if (bus_space_subregion(sc->sc_bst, ioh, + OOSIOP_GSC_OFFSET, OOSIOP_NREGS, &sc->sc_bsh)) + panic("oosiop_gsc_attach: couldn't get chip ports"); + + sc->sc_freq = ga->ga_ca.ca_pdc_iodc_read->filler2[14]; + if (sc->sc_freq == 0) + sc->sc_freq = 50000000; + + sc->sc_chip = OOSIOP_700; + sc->sc_id = ga->ga_scsi_target; + + /* + * Reset SCSI subsystem. + */ + bus_space_write_1(sc->sc_bst, ioh, OOSIOP_GSC_RESET, 0); + DELAY(1000); + + /* + * Call common attachment + */ + oosiop_attach(sc); + + (void)hp700_intr_establish(&sc->sc_dev, IPL_BIO, + oosiop_gsc_intr, sc, ga->ga_int_reg, ga->ga_irq); +} + +/* + * interrupt handler + */ +int +oosiop_gsc_intr(arg) + void *arg; +{ + struct oosiop_softc *sc = arg; + int rv; + + rv = oosiop_intr(sc); + + /* Blink the LED. */ + hp700_led_blink(HP700_LED_DISK); + + return rv; +} --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/oosiop.c 2003-02-18 02:07:36.000000000 +0900 @@ -0,0 +1,1308 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2001 Shuichiro URATA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * NCR53C700 SCSI I/O processor (OOSIOP) driver + * + * TODO: + * - More better error handling. + * - Write probe routine. + * - Write man page. + * - Implement tagged queueing. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static int oosiop_alloc_cb(struct oosiop_softc *, int); + +static __inline void oosiop_relocate_io(struct oosiop_softc *, bus_addr_t); +static __inline void oosiop_relocate_tc(struct oosiop_softc *, bus_addr_t); +static __inline void oosiop_fixup_select(struct oosiop_softc *, bus_addr_t, + int); +static __inline void oosiop_fixup_jump(struct oosiop_softc *, bus_addr_t, + bus_addr_t); +static __inline void oosiop_fixup_move(struct oosiop_softc *, bus_addr_t, + bus_size_t, bus_addr_t); + +static void oosiop_load_script(struct oosiop_softc *); +static void oosiop_setup_sgdma(struct oosiop_softc *, struct oosiop_cb *); +static void oosiop_setup_dma(struct oosiop_softc *); +static void oosiop_flush_fifo(struct oosiop_softc *); +static void oosiop_clear_fifo(struct oosiop_softc *); +static void oosiop_phasemismatch(struct oosiop_softc *); +static void oosiop_setup_syncxfer(struct oosiop_softc *); +static void oosiop_set_syncparam(struct oosiop_softc *, int, int, int); +static void oosiop_minphys(struct buf *); +static void oosiop_scsipi_request(struct scsipi_channel *, + scsipi_adapter_req_t, void *); +static void oosiop_done(struct oosiop_softc *, struct oosiop_cb *); +static void oosiop_timeout(void *); +static void oosiop_reset(struct oosiop_softc *); +static void oosiop_reset_bus(struct oosiop_softc *); +static void oosiop_scriptintr(struct oosiop_softc *); +static void oosiop_msgin(struct oosiop_softc *, struct oosiop_cb *); + +/* Trap interrupt code for unexpected data I/O */ +#define DATAIN_TRAP 0xdead0001 +#define DATAOUT_TRAP 0xdead0002 + +/* Possible TP and SCF conbination */ +static const struct { + u_int8_t tp; + u_int8_t scf; +} synctbl[] = { + {0, 1}, /* SCLK / 4.0 */ + {1, 1}, /* SCLK / 5.0 */ + {2, 1}, /* SCLK / 6.0 */ + {3, 1}, /* SCLK / 7.0 */ + {1, 2}, /* SCLK / 7.5 */ + {4, 1}, /* SCLK / 8.0 */ + {5, 1}, /* SCLK / 9.0 */ + {6, 1}, /* SCLK / 10.0 */ + {3, 2}, /* SCLK / 10.5 */ + {7, 1}, /* SCLK / 11.0 */ + {4, 2}, /* SCLK / 12.0 */ + {5, 2}, /* SCLK / 13.5 */ + {3, 3}, /* SCLK / 14.0 */ + {6, 2}, /* SCLK / 15.0 */ + {4, 3}, /* SCLK / 16.0 */ + {7, 2}, /* SCLK / 16.5 */ + {5, 3}, /* SCLK / 18.0 */ + {6, 3}, /* SCLK / 20.0 */ + {7, 3} /* SCLK / 22.0 */ +}; +#define NSYNCTBL (sizeof(synctbl) / sizeof(synctbl[0])) + +#define oosiop_period(sc, tp, scf) \ + (((1000000000 / (sc)->sc_freq) * (tp) * (scf)) / 40) + +void +oosiop_attach(struct oosiop_softc *sc) +{ + bus_size_t scrsize; + bus_dma_segment_t seg; + struct oosiop_cb *cb; + int err, i, nseg; + + /* + * Allocate DMA-safe memory for the script and map it. + */ + scrsize = sizeof(oosiop_script); + err = bus_dmamem_alloc(sc->sc_dmat, scrsize, PAGE_SIZE, 0, &seg, 1, + &nseg, BUS_DMA_NOWAIT); + if (err) { + printf(": failed to allocate script memory, err=%d\n", err); + return; + } + err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, scrsize, + (caddr_t *)&sc->sc_scr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); + if (err) { + printf(": failed to map script memory, err=%d\n", err); + return; + } + err = bus_dmamap_create(sc->sc_dmat, scrsize, 1, scrsize, 0, + BUS_DMA_NOWAIT, &sc->sc_scrdma); + if (err) { + printf(": failed to create script map, err=%d\n", err); + return; + } + err = bus_dmamap_load(sc->sc_dmat, sc->sc_scrdma, sc->sc_scr, scrsize, + NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE); + if (err) { + printf(": failed to load script map, err=%d\n", err); + return; + } + sc->sc_scrbase = sc->sc_scrdma->dm_segs[0].ds_addr; + + /* Initialize command block array */ + TAILQ_INIT(&sc->sc_free_cb); + TAILQ_INIT(&sc->sc_cbq); + if (oosiop_alloc_cb(sc, OOSIOP_NCB) != 0) + return; + + /* Use first cb to reselection msgin buffer */ + cb = TAILQ_FIRST(&sc->sc_free_cb); + sc->sc_reselbuf = cb->xferdma->dm_segs[0].ds_addr + + offsetof(struct oosiop_xfer, msgin[0]); + + for (i = 0; i < OOSIOP_NTGT; i++) { + sc->sc_tgt[i].nexus = NULL; + sc->sc_tgt[i].flags = 0; + } + + /* Setup asynchronous clock divisor parameters */ + if (sc->sc_freq <= 25000000) { + sc->sc_ccf = 10; + sc->sc_dcntl = OOSIOP_DCNTL_CF_1; + } else if (sc->sc_freq <= 37500000) { + sc->sc_ccf = 15; + sc->sc_dcntl = OOSIOP_DCNTL_CF_1_5; + } else if (sc->sc_freq <= 50000000) { + sc->sc_ccf = 20; + sc->sc_dcntl = OOSIOP_DCNTL_CF_2; + } else { + sc->sc_ccf = 30; + sc->sc_dcntl = OOSIOP_DCNTL_CF_3; + } + + if (sc->sc_chip == OOSIOP_700) + sc->sc_minperiod = oosiop_period(sc, 4, sc->sc_ccf); + else + sc->sc_minperiod = oosiop_period(sc, 4, 10); + + if (sc->sc_minperiod < 25) + sc->sc_minperiod = 25; /* limit to 10MB/s */ + + printf(": NCR53C700%s rev %d, %dMHz, SCSI ID %d\n", + sc->sc_chip == OOSIOP_700_66 ? "-66" : "", + oosiop_read_1(sc, OOSIOP_CTEST7) >> 4, + sc->sc_freq / 1000000, sc->sc_id); + /* + * Reset all + */ + oosiop_reset(sc); + oosiop_reset_bus(sc); + + /* + * Start SCRIPTS processor + */ + oosiop_load_script(sc); + sc->sc_active = 0; + oosiop_write_4(sc, OOSIOP_DSP, sc->sc_scrbase + Ent_wait_reselect); + + /* + * Fill in the scsipi_adapter. + */ + sc->sc_adapter.adapt_dev = &sc->sc_dev; + sc->sc_adapter.adapt_nchannels = 1; + sc->sc_adapter.adapt_openings = OOSIOP_NCB; + sc->sc_adapter.adapt_max_periph = 1; + sc->sc_adapter.adapt_ioctl = NULL; + sc->sc_adapter.adapt_minphys = oosiop_minphys; + sc->sc_adapter.adapt_request = oosiop_scsipi_request; + + /* + * Fill in the scsipi_channel. + */ + sc->sc_channel.chan_adapter = &sc->sc_adapter; + sc->sc_channel.chan_bustype = &scsi_bustype; + sc->sc_channel.chan_channel = 0; + sc->sc_channel.chan_ntargets = OOSIOP_NTGT; + sc->sc_channel.chan_nluns = 8; + sc->sc_channel.chan_id = sc->sc_id; + + /* + * Now try to attach all the sub devices. + */ + config_found(&sc->sc_dev, &sc->sc_channel, scsiprint); +} + +static int +oosiop_alloc_cb(struct oosiop_softc *sc, int ncb) +{ + struct oosiop_cb *cb; + struct oosiop_xfer *xfer; + bus_size_t xfersize; + bus_dma_segment_t seg; + int i, s, err, nseg; + + /* + * Allocate oosiop_cb. + */ + cb = malloc(sizeof(struct oosiop_cb) * ncb, M_DEVBUF, M_NOWAIT|M_ZERO); + if (cb == NULL) { + printf(": failed to allocate cb memory\n"); + return (ENOMEM); + } + + /* + * Allocate DMA-safe memory for the oosiop_xfer and map it. + */ + xfersize = sizeof(struct oosiop_xfer) * ncb; + err = bus_dmamem_alloc(sc->sc_dmat, xfersize, PAGE_SIZE, 0, &seg, 1, + &nseg, BUS_DMA_NOWAIT); + if (err) { + printf(": failed to allocate xfer block memory, err=%d\n", err); + return (err); + } + err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, xfersize, + (caddr_t *)&xfer, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); + if (err) { + printf(": failed to map xfer block memory, err=%d\n", err); + return (err); + } + + /* Initialize each command block */ + for (i = 0; i < ncb; i++) { + err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, + 0, BUS_DMA_NOWAIT, &cb->cmddma); + if (err) { + printf(": failed to create cmddma map, err=%d\n", err); + return (err); + } + err = bus_dmamap_create(sc->sc_dmat, OOSIOP_MAX_XFER, + OOSIOP_NSG, OOSIOP_DBC_MAX, 0, BUS_DMA_NOWAIT, + &cb->datadma); + if (err) { + printf(": failed to create datadma map, err=%d\n", err); + return (err); + } + + err = bus_dmamap_create(sc->sc_dmat, + sizeof(struct oosiop_xfer), 1, sizeof(struct oosiop_xfer), + 0, BUS_DMA_NOWAIT, &cb->xferdma); + if (err) { + printf(": failed to create xfer block map, err=%d\n", + err); + return (err); + } + err = bus_dmamap_load(sc->sc_dmat, cb->xferdma, xfer, + sizeof(struct oosiop_xfer), NULL, BUS_DMA_NOWAIT); + if (err) { + printf(": failed to load xfer block, err=%d\n", err); + return (err); + } + + cb->xfer = xfer; + + s = splbio(); + TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); + splx(s); + + cb++; + xfer++; + } + + return (0); +} + +static __inline void +oosiop_relocate_io(struct oosiop_softc *sc, bus_addr_t addr) +{ + u_int32_t dcmd; + u_int32_t dsps; + + dcmd = le32toh(sc->sc_scr[addr / 4 + 0]); + dsps = le32toh(sc->sc_scr[addr / 4 + 1]); + + /* convert relative to absolute */ + if (dcmd & 0x04000000) { + dcmd &= ~0x04000000; + sc->sc_scr[addr / 4 + 0] = htole32(dcmd); + /*dsps &= 0x00ffffff;*/ + dsps += addr + 8; + } + + sc->sc_scr[addr / 4 + 1] = htole32(dsps + sc->sc_scrbase); +} + +static __inline void +oosiop_relocate_tc(struct oosiop_softc *sc, bus_addr_t addr) +{ + u_int32_t dcmd; + u_int32_t dsps; + + dcmd = le32toh(sc->sc_scr[addr / 4 + 0]); + dsps = le32toh(sc->sc_scr[addr / 4 + 1]); + + /* convert relative to absolute */ + if (dcmd & 0x00800000) { + dcmd &= ~0x00800000; + sc->sc_scr[addr / 4] = htole32(dcmd); + /*dsps &= 0x00ffffff;*/ + dsps += addr + 8; + } + + sc->sc_scr[addr / 4 + 1] = htole32(dsps + sc->sc_scrbase); +} + +static __inline void +oosiop_fixup_select(struct oosiop_softc *sc, bus_addr_t addr, int id) +{ + u_int32_t dcmd; + + dcmd = le32toh(sc->sc_scr[addr / 4]); + dcmd &= 0xff00ffff; + dcmd |= 0x00010000 << id; + sc->sc_scr[addr / 4] = htole32(dcmd); +} + +static __inline void +oosiop_fixup_jump(struct oosiop_softc *sc, bus_addr_t addr, bus_addr_t dst) +{ + + sc->sc_scr[addr / 4 + 1] = htole32(dst); +} + +static __inline void +oosiop_fixup_move(struct oosiop_softc *sc, bus_addr_t addr, bus_size_t dbc, + bus_addr_t dsps) +{ + u_int32_t dcmd; + + dcmd = le32toh(sc->sc_scr[addr / 4]); + dcmd &= 0xff000000; + dcmd |= dbc & 0x00ffffff; + sc->sc_scr[addr / 4 + 0] = htole32(dcmd); + sc->sc_scr[addr / 4 + 1] = htole32(dsps); +} + +static void +oosiop_load_script(struct oosiop_softc *sc) +{ + int i; + + /* load script */ + for (i = 0; i < sizeof(oosiop_script) / sizeof(oosiop_script[0]); i++) + sc->sc_scr[i] = htole32(oosiop_script[i]); + + /* relocate script */ + for (i = 0; i < (sizeof(oosiop_script) / 8); i++) { + switch (oosiop_script[i * 2] >> 27) { + case 0x08: /* select */ + case 0x0a: /* wait reselect */ + oosiop_relocate_io(sc, i * 8); + break; + case 0x10: /* jump */ + case 0x11: /* call */ + oosiop_relocate_tc(sc, i * 8); + break; + } + } + + oosiop_fixup_move(sc, Ent_p_resel_msgin_move, 1, sc->sc_reselbuf); + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE); +} + +static void +oosiop_setup_sgdma(struct oosiop_softc *sc, struct oosiop_cb *cb) +{ + int i, n, off; + struct oosiop_xfer *xfer; + + OOSIOP_XFERSCR_SYNC(sc, cb, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + off = cb->curdp; + xfer = cb->xfer; + + /* Find start segment */ + if (cb->xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { + for (i = 0; i < cb->datadma->dm_nsegs; i++) { + if (off < cb->datadma->dm_segs[i].ds_len) + break; + off -= cb->datadma->dm_segs[i].ds_len; + } + } + + /* build MOVE block */ + if (cb->xs->xs_control & XS_CTL_DATA_IN) { + n = 0; + while (i < cb->datadma->dm_nsegs) { + xfer->datain_scr[n * 2 + 0] = htole32(0x09000000 | + (cb->datadma->dm_segs[i].ds_len - off)); + xfer->datain_scr[n * 2 + 1] = + htole32(cb->datadma->dm_segs[i].ds_addr + off); + n++; + i++; + off = 0; + } + xfer->datain_scr[n * 2 + 0] = htole32(0x80080000); + xfer->datain_scr[n * 2 + 1] = + htole32(sc->sc_scrbase + Ent_phasedispatch); + } else { + xfer->datain_scr[0] = htole32(0x98080000); + xfer->datain_scr[1] = htole32(DATAIN_TRAP); + } + + if (cb->xs->xs_control & XS_CTL_DATA_OUT) { + n = 0; + while (i < cb->datadma->dm_nsegs) { + xfer->dataout_scr[n * 2 + 0] = htole32(0x08000000 | + (cb->datadma->dm_segs[i].ds_len - off)); + xfer->dataout_scr[n * 2 + 1] = + htole32(cb->datadma->dm_segs[i].ds_addr + off); + n++; + i++; + off = 0; + } + xfer->dataout_scr[n * 2 + 0] = htole32(0x80080000); + xfer->dataout_scr[n * 2 + 1] = + htole32(sc->sc_scrbase + Ent_phasedispatch); + } else { + xfer->dataout_scr[0] = htole32(0x98080000); + xfer->dataout_scr[1] = htole32(DATAOUT_TRAP); + } + OOSIOP_XFERSCR_SYNC(sc, cb, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); +} + +/* + * Setup DMA pointer into script. + */ +static void +oosiop_setup_dma(struct oosiop_softc *sc) +{ + struct oosiop_cb *cb; + bus_addr_t xferbase; + + cb = sc->sc_curcb; + xferbase = cb->xferdma->dm_segs[0].ds_addr; + + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE); + + oosiop_fixup_select(sc, Ent_p_select, cb->id); + oosiop_fixup_jump(sc, Ent_p_datain_jump, xferbase + + offsetof(struct oosiop_xfer, datain_scr[0])); + oosiop_fixup_jump(sc, Ent_p_dataout_jump, xferbase + + offsetof(struct oosiop_xfer, dataout_scr[0])); + oosiop_fixup_move(sc, Ent_p_msgin_move, 1, xferbase + + offsetof(struct oosiop_xfer, msgin[0])); + oosiop_fixup_move(sc, Ent_p_extmsglen_move, 1, xferbase + + offsetof(struct oosiop_xfer, msgin[1])); + oosiop_fixup_move(sc, Ent_p_msgout_move, cb->msgoutlen, xferbase + + offsetof(struct oosiop_xfer, msgout[0])); + oosiop_fixup_move(sc, Ent_p_status_move, 1, xferbase + + offsetof(struct oosiop_xfer, status)); + oosiop_fixup_move(sc, Ent_p_cmdout_move, cb->xs->cmdlen, + cb->cmddma->dm_segs[0].ds_addr); + + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE); +} + +static void +oosiop_flush_fifo(struct oosiop_softc *sc) +{ + + oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) | + OOSIOP_DFIFO_FLF); + while ((oosiop_read_1(sc, OOSIOP_CTEST1) & OOSIOP_CTEST1_FMT) != + OOSIOP_CTEST1_FMT) + ; + oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) & + ~OOSIOP_DFIFO_FLF); +} + +static void +oosiop_clear_fifo(struct oosiop_softc *sc) +{ + + oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) | + OOSIOP_DFIFO_CLF); + while ((oosiop_read_1(sc, OOSIOP_CTEST1) & OOSIOP_CTEST1_FMT) != + OOSIOP_CTEST1_FMT) + ; + oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) & + ~OOSIOP_DFIFO_CLF); +} + +static void +oosiop_phasemismatch(struct oosiop_softc *sc) +{ + struct oosiop_cb *cb; + u_int32_t dsp, dbc, n, i, len; + u_int8_t dfifo, sstat1; + + cb = sc->sc_curcb; + if (cb == NULL) + return; + + dsp = oosiop_read_4(sc, OOSIOP_DSP); + dbc = oosiop_read_4(sc, OOSIOP_DBC) & OOSIOP_DBC_MAX; + len = 0; + + n = dsp - cb->xferdma->dm_segs[0].ds_addr - 8; + if (n >= offsetof(struct oosiop_xfer, datain_scr[0]) && + n < offsetof(struct oosiop_xfer, datain_scr[OOSIOP_NSG * 2])) { + n -= offsetof(struct oosiop_xfer, datain_scr[0]); + n >>= 3; + OOSIOP_DINSCR_SYNC(sc, cb, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + for (i = 0; i <= n; i++) + len += le32toh(cb->xfer->datain_scr[i * 2]) & + 0x00ffffff; + OOSIOP_DINSCR_SYNC(sc, cb, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* All data in the chip are already flushed */ + } else if (n >= offsetof(struct oosiop_xfer, dataout_scr[0]) && + n < offsetof(struct oosiop_xfer, dataout_scr[OOSIOP_NSG * 2])) { + n -= offsetof(struct oosiop_xfer, dataout_scr[0]); + n >>= 3; + OOSIOP_DOUTSCR_SYNC(sc, cb, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + for (i = 0; i <= n; i++) + len += le32toh(cb->xfer->dataout_scr[i * 2]) & + 0x00ffffff; + OOSIOP_DOUTSCR_SYNC(sc, cb, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + dfifo = oosiop_read_1(sc, OOSIOP_DFIFO); + dbc += ((dfifo & OOSIOP_DFIFO_BO) - (dbc & OOSIOP_DFIFO_BO)) & + OOSIOP_DFIFO_BO; + + sstat1 = oosiop_read_1(sc, OOSIOP_SSTAT1); + if (sstat1 & OOSIOP_SSTAT1_OLF) + dbc++; + if ((sc->sc_tgt[cb->id].sxfer != 0) && + (sstat1 & OOSIOP_SSTAT1_ORF) != 0) + dbc++; + + oosiop_clear_fifo(sc); + } else { + printf("%s: phase mismatch addr=%08x\n", sc->sc_dev.dv_xname, + oosiop_read_4(sc, OOSIOP_DSP) - 8); + oosiop_clear_fifo(sc); + return; + } + + len -= dbc; + if (len) { + cb->curdp += len; + oosiop_setup_sgdma(sc, cb); + } +} + +static void +oosiop_setup_syncxfer(struct oosiop_softc *sc) +{ + int id; + + id = sc->sc_curcb->id; + if (sc->sc_chip != OOSIOP_700) + oosiop_write_1(sc, OOSIOP_SBCL, sc->sc_tgt[id].scf); + + oosiop_write_1(sc, OOSIOP_SXFER, sc->sc_tgt[id].sxfer); +} + +static void +oosiop_set_syncparam(struct oosiop_softc *sc, int id, int period, int offset) +{ + int i, p; + struct scsipi_xfer_mode xm; + + xm.xm_target = id; + xm.xm_mode = 0; + xm.xm_period = 0; + xm.xm_offset = 0; + + if (offset == 0) { + /* Asynchronous */ + sc->sc_tgt[id].scf = 0; + sc->sc_tgt[id].sxfer = 0; + } else { + /* Synchronous */ + if (sc->sc_chip == OOSIOP_700) { + for (i = 4; i < 12; i++) { + p = oosiop_period(sc, i, sc->sc_ccf); + if (p >= period) + break; + } + if (i == 12) { + printf("%s: target %d period too large\n", + sc->sc_dev.dv_xname, id); + i = 11; /* XXX */ + } + sc->sc_tgt[id].scf = 0; + sc->sc_tgt[id].sxfer = ((i - 4) << 4) | offset; + } else { + for (i = 0; i < NSYNCTBL; i++) { + p = oosiop_period(sc, synctbl[i].tp + 4, + (synctbl[i].scf + 1) * 5); + if (p >= period) + break; + } + if (i == NSYNCTBL) { + printf("%s: target %d period too large\n", + sc->sc_dev.dv_xname, id); + i = NSYNCTBL - 1; /* XXX */ + } + sc->sc_tgt[id].scf = synctbl[i].scf; + sc->sc_tgt[id].sxfer = (synctbl[i].tp << 4) | offset; + } + + xm.xm_mode |= PERIPH_CAP_SYNC; + xm.xm_period = period; + xm.xm_offset = offset; + } + + scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm); +} + +static void +oosiop_minphys(struct buf *bp) +{ + + if (bp->b_bcount > OOSIOP_MAX_XFER) + bp->b_bcount = OOSIOP_MAX_XFER; + minphys(bp); +} + +static void +oosiop_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, + void *arg) +{ + struct scsipi_xfer *xs; + struct oosiop_softc *sc; + struct oosiop_cb *cb; + struct oosiop_xfer *xfer; + struct scsipi_xfer_mode *xm; + int s, err; + + sc = (struct oosiop_softc *)chan->chan_adapter->adapt_dev; + + switch (req) { + case ADAPTER_REQ_RUN_XFER: + xs = arg; + + s = splbio(); + cb = TAILQ_FIRST(&sc->sc_free_cb); + TAILQ_REMOVE(&sc->sc_free_cb, cb, chain); + splx(s); + + cb->xs = xs; + cb->flags = 0; + cb->id = xs->xs_periph->periph_target; + cb->lun = xs->xs_periph->periph_lun; + cb->curdp = 0; + cb->savedp = 0; + xfer = cb->xfer; + + /* Setup SCSI command buffer DMA */ + err = bus_dmamap_load(sc->sc_dmat, cb->cmddma, xs->cmd, + xs->cmdlen, NULL, ((xs->xs_control & XS_CTL_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | BUS_DMA_WRITE); + if (err) { + printf("%s: unable to load cmd DMA map: %d", + sc->sc_dev.dv_xname, err); + xs->error = XS_RESOURCE_SHORTAGE; + TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); + scsipi_done(xs); + return; + } + bus_dmamap_sync(sc->sc_dmat, cb->cmddma, 0, xs->cmdlen, + BUS_DMASYNC_PREWRITE); + + /* Setup data buffer DMA */ + if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { + err = bus_dmamap_load(sc->sc_dmat, cb->datadma, + xs->data, xs->datalen, NULL, + ((xs->xs_control & XS_CTL_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | + BUS_DMA_STREAMING | + ((xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMA_READ : + BUS_DMA_WRITE)); + if (err) { + printf("%s: unable to load data DMA map: %d", + sc->sc_dev.dv_xname, err); + xs->error = XS_RESOURCE_SHORTAGE; + bus_dmamap_unload(sc->sc_dmat, cb->cmddma); + TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); + scsipi_done(xs); + return; + } + bus_dmamap_sync(sc->sc_dmat, cb->datadma, + 0, xs->datalen, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } + + oosiop_setup_sgdma(sc, cb); + + /* Setup msgout buffer */ + OOSIOP_XFERMSG_SYNC(sc, cb, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + xfer->msgout[0] = MSG_IDENTIFY(cb->lun, + (xs->xs_control & XS_CTL_REQSENSE) == 0); + cb->msgoutlen = 1; + + if (sc->sc_tgt[cb->id].flags & TGTF_SYNCNEG) { + /* Send SDTR */ + xfer->msgout[1] = MSG_EXTENDED; + xfer->msgout[2] = MSG_EXT_SDTR_LEN; + xfer->msgout[3] = MSG_EXT_SDTR; + xfer->msgout[4] = sc->sc_minperiod; + xfer->msgout[5] = OOSIOP_MAX_OFFSET; + cb->msgoutlen = 6; + sc->sc_tgt[cb->id].flags &= ~TGTF_SYNCNEG; + sc->sc_tgt[cb->id].flags |= TGTF_WAITSDTR; + } + + xfer->status = 0xff; + + OOSIOP_XFERMSG_SYNC(sc, cb, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + s = splbio(); + + TAILQ_INSERT_TAIL(&sc->sc_cbq, cb, chain); + + if (!sc->sc_active) { + /* Abort script to start selection */ + oosiop_write_1(sc, OOSIOP_ISTAT, OOSIOP_ISTAT_ABRT); + } + if (xs->xs_control & XS_CTL_POLL) { + /* Poll for command completion */ + while ((xs->xs_status & XS_STS_DONE) == 0) { + delay(1000); + oosiop_intr(sc); + } + } + + splx(s); + + return; + + case ADAPTER_REQ_GROW_RESOURCES: + return; + + case ADAPTER_REQ_SET_XFER_MODE: + xm = arg; + if (xm->xm_mode & PERIPH_CAP_SYNC) + sc->sc_tgt[xm->xm_target].flags |= TGTF_SYNCNEG; + else + oosiop_set_syncparam(sc, xm->xm_target, 0, 0); + + return; + } +} + +static void +oosiop_done(struct oosiop_softc *sc, struct oosiop_cb *cb) +{ + struct scsipi_xfer *xs; + + xs = cb->xs; + if (cb == sc->sc_curcb) + sc->sc_curcb = NULL; + if (cb == sc->sc_lastcb) + sc->sc_lastcb = NULL; + sc->sc_tgt[cb->id].nexus = NULL; + + callout_stop(&xs->xs_callout); + + bus_dmamap_sync(sc->sc_dmat, cb->cmddma, 0, xs->cmdlen, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, cb->cmddma); + + if (xs->datalen > 0) { + bus_dmamap_sync(sc->sc_dmat, cb->datadma, 0, xs->datalen, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, cb->datadma); + } + + xs->status = cb->xfer->status; + xs->resid = 0; /* XXX */ + + if (cb->flags & CBF_SELTOUT) + xs->error = XS_SELTIMEOUT; + else if (cb->flags & CBF_TIMEOUT) + xs->error = XS_TIMEOUT; + else switch (xs->status) { + case SCSI_OK: + xs->error = XS_NOERROR; + break; + + case SCSI_BUSY: + case SCSI_CHECK: + xs->error = XS_BUSY; + break; + + default: + xs->error = XS_RESET; + break; + } + + scsipi_done(xs); + + /* Put it on the free list. */ + TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); +} + +static void +oosiop_timeout(void *arg) +{ + struct oosiop_cb *cb; + struct scsipi_periph *periph; + struct oosiop_softc *sc; + int s; + + cb = arg; + periph = cb->xs->xs_periph; + sc = (void *)periph->periph_channel->chan_adapter->adapt_dev; + scsipi_printaddr(periph); + printf("timed out\n"); + + s = splbio(); + + cb->flags |= CBF_TIMEOUT; + oosiop_done(sc, cb); + + splx(s); +} + +static void +oosiop_reset(struct oosiop_softc *sc) +{ + int i, s; + + s = splbio(); + + /* Stop SCRIPTS processor */ + oosiop_write_1(sc, OOSIOP_ISTAT, OOSIOP_ISTAT_ABRT); + delay(100); + oosiop_write_1(sc, OOSIOP_ISTAT, 0); + + /* Reset the chip */ + oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl | OOSIOP_DCNTL_RST); + delay(100); + oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl); + delay(10000); + + /* Set up various chip parameters */ + oosiop_write_1(sc, OOSIOP_SCNTL0, OOSIOP_ARB_FULL | OOSIOP_SCNTL0_EPG); + oosiop_write_1(sc, OOSIOP_SCNTL1, OOSIOP_SCNTL1_ESR); + oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl); + oosiop_write_1(sc, OOSIOP_DMODE, OOSIOP_DMODE_BL_8); + oosiop_write_1(sc, OOSIOP_SCID, OOSIOP_SCID_VALUE(sc->sc_id)); + oosiop_write_1(sc, OOSIOP_DWT, 0xff); /* Enable DMA timeout */ + oosiop_write_1(sc, OOSIOP_CTEST7, 0); + oosiop_write_1(sc, OOSIOP_SXFER, 0); + + /* Clear all interrupts */ + (void)oosiop_read_1(sc, OOSIOP_SSTAT0); + (void)oosiop_read_1(sc, OOSIOP_SSTAT1); + (void)oosiop_read_1(sc, OOSIOP_DSTAT); + + /* Enable interrupts */ + oosiop_write_1(sc, OOSIOP_SIEN, + OOSIOP_SIEN_M_A | OOSIOP_SIEN_STO | OOSIOP_SIEN_SGE | + OOSIOP_SIEN_UDC | OOSIOP_SIEN_RST | OOSIOP_SIEN_PAR); + oosiop_write_1(sc, OOSIOP_DIEN, + OOSIOP_DIEN_ABRT | OOSIOP_DIEN_SSI | OOSIOP_DIEN_SIR | + OOSIOP_DIEN_WTD | OOSIOP_DIEN_IID); + + /* Set target state to asynchronous */ + for (i = 0; i < OOSIOP_NTGT; i++) { + sc->sc_tgt[i].flags = 0; + sc->sc_tgt[i].scf = 0; + sc->sc_tgt[i].sxfer = 0; + } + + splx(s); +} + +static void +oosiop_reset_bus(struct oosiop_softc *sc) +{ + int s, i; + + s = splbio(); + + /* Assert SCSI RST */ + oosiop_write_1(sc, OOSIOP_SCNTL1, OOSIOP_SCNTL1_RST); + delay(25); /* Reset hold time (25us) */ + oosiop_write_1(sc, OOSIOP_SCNTL1, 0); + + /* Remove all nexuses */ + for (i = 0; i < OOSIOP_NTGT; i++) { + if (sc->sc_tgt[i].nexus) { + sc->sc_tgt[i].nexus->xfer->status = 0xff; /* XXX */ + oosiop_done(sc, sc->sc_tgt[i].nexus); + } + } + + sc->sc_curcb = NULL; + + delay(250000); /* Reset to selection (250ms) */ + + splx(s); +} + +/* + * interrupt handler + */ +int +oosiop_intr(struct oosiop_softc *sc) +{ + struct oosiop_cb *cb; + u_int32_t dcmd; + int timeout; + u_int8_t istat, dstat, sstat0; + + istat = oosiop_read_1(sc, OOSIOP_ISTAT); + + if ((istat & (OOSIOP_ISTAT_SIP | OOSIOP_ISTAT_DIP)) == 0) + return (0); + + sc->sc_nextdsp = Ent_wait_reselect; + + /* DMA interrupts */ + if (istat & OOSIOP_ISTAT_DIP) { + oosiop_write_1(sc, OOSIOP_ISTAT, 0); + + dstat = oosiop_read_1(sc, OOSIOP_DSTAT); + + if (dstat & OOSIOP_DSTAT_ABRT) { + sc->sc_nextdsp = oosiop_read_4(sc, OOSIOP_DSP) - + sc->sc_scrbase - 8; + + if (sc->sc_nextdsp == Ent_p_resel_msgin_move && + (oosiop_read_1(sc, OOSIOP_SBCL) & OOSIOP_ACK)) { + if ((dstat & OOSIOP_DSTAT_DFE) == 0) + oosiop_flush_fifo(sc); + sc->sc_nextdsp += 8; + } + } + + if (dstat & OOSIOP_DSTAT_SSI) { + sc->sc_nextdsp = oosiop_read_4(sc, OOSIOP_DSP) - + sc->sc_scrbase; + printf("%s: single step %08x\n", sc->sc_dev.dv_xname, + sc->sc_nextdsp); + } + + if (dstat & OOSIOP_DSTAT_SIR) { + if ((dstat & OOSIOP_DSTAT_DFE) == 0) + oosiop_flush_fifo(sc); + oosiop_scriptintr(sc); + } + + if (dstat & OOSIOP_DSTAT_WTD) { + printf("%s: DMA time out\n", sc->sc_dev.dv_xname); + oosiop_reset(sc); + } + + if (dstat & OOSIOP_DSTAT_IID) { + dcmd = oosiop_read_4(sc, OOSIOP_DBC); + if ((dcmd & 0xf8000000) == 0x48000000) { + printf("%s: REQ asserted on WAIT DISCONNECT\n", + sc->sc_dev.dv_xname); + sc->sc_nextdsp = Ent_phasedispatch; /* XXX */ + } else { + printf("%s: invalid SCRIPTS instruction " + "addr=%08x dcmd=%08x dsps=%08x\n", + sc->sc_dev.dv_xname, + oosiop_read_4(sc, OOSIOP_DSP) - 8, dcmd, + oosiop_read_4(sc, OOSIOP_DSPS)); + oosiop_reset(sc); + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE); + oosiop_load_script(sc); + } + } + + if ((dstat & OOSIOP_DSTAT_DFE) == 0) + oosiop_clear_fifo(sc); + } + + /* SCSI interrupts */ + if (istat & OOSIOP_ISTAT_SIP) { + if (istat & OOSIOP_ISTAT_DIP) + delay(1); + sstat0 = oosiop_read_1(sc, OOSIOP_SSTAT0); + + if (sstat0 & OOSIOP_SSTAT0_M_A) { + /* SCSI phase mismatch during MOVE operation */ + oosiop_phasemismatch(sc); + sc->sc_nextdsp = Ent_phasedispatch; + } + + if (sstat0 & OOSIOP_SSTAT0_STO) { + if (sc->sc_curcb) { + sc->sc_curcb->flags |= CBF_SELTOUT; + oosiop_done(sc, sc->sc_curcb); + } + } + + if (sstat0 & OOSIOP_SSTAT0_SGE) { + printf("%s: SCSI gross error\n", sc->sc_dev.dv_xname); + oosiop_reset(sc); + } + + if (sstat0 & OOSIOP_SSTAT0_UDC) { + /* XXX */ + if (sc->sc_curcb) { + printf("%s: unexpected disconnect\n", + sc->sc_dev.dv_xname); + oosiop_done(sc, sc->sc_curcb); + } + } + + if (sstat0 & OOSIOP_SSTAT0_RST) + oosiop_reset(sc); + + if (sstat0 & OOSIOP_SSTAT0_PAR) + printf("%s: parity error\n", sc->sc_dev.dv_xname); + } + + /* Start next command if available */ + if (sc->sc_nextdsp == Ent_wait_reselect && TAILQ_FIRST(&sc->sc_cbq)) { + cb = sc->sc_curcb = TAILQ_FIRST(&sc->sc_cbq); + TAILQ_REMOVE(&sc->sc_cbq, cb, chain); + sc->sc_tgt[cb->id].nexus = cb; + + oosiop_setup_dma(sc); + oosiop_setup_syncxfer(sc); + sc->sc_lastcb = cb; + sc->sc_nextdsp = Ent_start_select; + + /* Schedule timeout */ + if ((cb->xs->xs_control & XS_CTL_POLL) == 0) { + timeout = mstohz(cb->xs->timeout) + 1; + callout_reset(&cb->xs->xs_callout, timeout, + oosiop_timeout, cb); + } + } + + sc->sc_active = (sc->sc_nextdsp != Ent_wait_reselect); + + /* Restart script */ + oosiop_write_4(sc, OOSIOP_DSP, sc->sc_nextdsp + sc->sc_scrbase); + + return (1); +} + +static void +oosiop_scriptintr(struct oosiop_softc *sc) +{ + struct oosiop_cb *cb; + u_int32_t icode; + u_int32_t dsp; + int i; + u_int8_t sfbr, resid, resmsg; + + cb = sc->sc_curcb; + icode = oosiop_read_4(sc, OOSIOP_DSPS); + + switch (icode) { + case A_int_done: + if (cb) + oosiop_done(sc, cb); + break; + + case A_int_msgin: + if (cb) + oosiop_msgin(sc, cb); + break; + + case A_int_extmsg: + /* extended message in DMA setup request */ + sfbr = oosiop_read_1(sc, OOSIOP_SFBR); + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE); + oosiop_fixup_move(sc, Ent_p_extmsgin_move, sfbr, + cb->xferdma->dm_segs[0].ds_addr + + offsetof(struct oosiop_xfer, msgin[2])); + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE); + sc->sc_nextdsp = Ent_rcv_extmsg; + break; + + case A_int_resel: + /* reselected */ + resid = oosiop_read_1(sc, OOSIOP_SFBR); + for (i = 0; i < OOSIOP_NTGT; i++) + if (resid & (1 << i)) + break; + if (i == OOSIOP_NTGT) { + printf("%s: missing reselection target id\n", + sc->sc_dev.dv_xname); + break; + } + sc->sc_resid = i; + sc->sc_nextdsp = Ent_wait_resel_identify; + + if (cb) { + /* Current command was lost arbitration */ + sc->sc_tgt[cb->id].nexus = NULL; + TAILQ_INSERT_HEAD(&sc->sc_cbq, cb, chain); + sc->sc_curcb = NULL; + } + + break; + + case A_int_res_id: + cb = sc->sc_tgt[sc->sc_resid].nexus; + resmsg = oosiop_read_1(sc, OOSIOP_SFBR); + if (MSG_ISIDENTIFY(resmsg) && cb && + (resmsg & MSG_IDENTIFY_LUNMASK) == cb->lun) { + sc->sc_curcb = cb; + if (cb != sc->sc_lastcb) { + oosiop_setup_dma(sc); + oosiop_setup_syncxfer(sc); + sc->sc_lastcb = cb; + } + if (cb->curdp != cb->savedp) { + cb->curdp = cb->savedp; + oosiop_setup_sgdma(sc, cb); + } + sc->sc_nextdsp = Ent_ack_msgin; + } else { + /* Reselection from invalid target */ + oosiop_reset_bus(sc); + } + break; + + case A_int_resfail: + /* reselect failed */ + break; + + case A_int_disc: + /* disconnected */ + sc->sc_curcb = NULL; + break; + + case A_int_err: + /* generic error */ + dsp = oosiop_read_4(sc, OOSIOP_DSP); + printf("%s: script error at 0x%08x\n", sc->sc_dev.dv_xname, + dsp - 8); + sc->sc_curcb = NULL; + break; + + case DATAIN_TRAP: + printf("%s: unexpected datain\n", sc->sc_dev.dv_xname); + /* XXX: need to reset? */ + break; + + case DATAOUT_TRAP: + printf("%s: unexpected dataout\n", sc->sc_dev.dv_xname); + /* XXX: need to reset? */ + break; + + default: + printf("%s: unknown intr code %08x\n", sc->sc_dev.dv_xname, + icode); + break; + } +} + +static void +oosiop_msgin(struct oosiop_softc *sc, struct oosiop_cb *cb) +{ + struct oosiop_xfer *xfer; + int msgout; + + xfer = cb->xfer; + sc->sc_nextdsp = Ent_ack_msgin; + msgout = 0; + + OOSIOP_XFERMSG_SYNC(sc, cb, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + switch (xfer->msgin[0]) { + case MSG_EXTENDED: + switch (xfer->msgin[2]) { + case MSG_EXT_SDTR: + if (sc->sc_tgt[cb->id].flags & TGTF_WAITSDTR) { + /* Host initiated SDTR */ + sc->sc_tgt[cb->id].flags &= ~TGTF_WAITSDTR; + } else { + /* Target initiated SDTR */ + if (xfer->msgin[3] < sc->sc_minperiod) + xfer->msgin[3] = sc->sc_minperiod; + if (xfer->msgin[4] > OOSIOP_MAX_OFFSET) + xfer->msgin[4] = OOSIOP_MAX_OFFSET; + xfer->msgout[0] = MSG_EXTENDED; + xfer->msgout[1] = MSG_EXT_SDTR_LEN; + xfer->msgout[2] = MSG_EXT_SDTR; + xfer->msgout[3] = xfer->msgin[3]; + xfer->msgout[4] = xfer->msgin[4]; + cb->msgoutlen = 5; + msgout = 1; + } + oosiop_set_syncparam(sc, cb->id, (int)xfer->msgin[3], + (int)xfer->msgin[4]); + oosiop_setup_syncxfer(sc); + break; + + default: + /* Reject message */ + xfer->msgout[0] = MSG_MESSAGE_REJECT; + cb->msgoutlen = 1; + msgout = 1; + break; + } + break; + + case MSG_SAVEDATAPOINTER: + cb->savedp = cb->curdp; + break; + + case MSG_RESTOREPOINTERS: + if (cb->curdp != cb->savedp) { + cb->curdp = cb->savedp; + oosiop_setup_sgdma(sc, cb); + } + break; + + case MSG_MESSAGE_REJECT: + if (sc->sc_tgt[cb->id].flags & TGTF_WAITSDTR) { + /* SDTR rejected */ + sc->sc_tgt[cb->id].flags &= ~TGTF_WAITSDTR; + oosiop_set_syncparam(sc, cb->id, 0, 0); + oosiop_setup_syncxfer(sc); + } + break; + + default: + /* Reject message */ + xfer->msgout[0] = MSG_MESSAGE_REJECT; + cb->msgoutlen = 1; + msgout = 1; + } + + OOSIOP_XFERMSG_SYNC(sc, cb, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + if (msgout) { + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE); + oosiop_fixup_move(sc, Ent_p_msgout_move, cb->msgoutlen, + cb->xferdma->dm_segs[0].ds_addr + + offsetof(struct oosiop_xfer, msgout[0])); + OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE); + sc->sc_nextdsp = Ent_sendmsg; + } +} --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/oosiopreg.h 2003-02-18 02:04:50.000000000 +0900 @@ -0,0 +1,324 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Van Jacobson of Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)siopreg.h 7.3 (Berkeley) 2/5/91 + */ + +/* + * NCR 53C700 SCSI interface hardware description. + * + * From the Mach scsi driver for the 53C700 and amiga siop driver + */ + +#define OOSIOP_SCNTL0 0x00 /* rw: SCSI control reg 0 */ +#define OOSIOP_SCNTL1 0x01 /* rw: SCSI control reg 1 */ +#define OOSIOP_SDID 0x02 /* rw: SCSI destination ID */ +#define OOSIOP_SIEN 0x03 /* rw: SCSI interrupt enable */ +#define OOSIOP_SCID 0x04 /* rw: SCSI Chip ID reg */ +#define OOSIOP_SXFER 0x05 /* rw: SCSI Transfer reg */ +#define OOSIOP_SODL 0x06 /* rw: SCSI Output Data Latch */ +#define OOSIOP_SOCL 0x07 /* rw: SCSI Output Control Latch */ +#define OOSIOP_SFBR 0x08 /* ro: SCSI First Byte Received */ +#define OOSIOP_SIDL 0x09 /* ro: SCSI Input Data Latch */ +#define OOSIOP_SBDL 0x0a /* ro: SCSI Bus Data Lines */ +#define OOSIOP_SBCL 0x0b /* rw: SCSI Bus Control Lines */ +#define OOSIOP_DSTAT 0x0c /* ro: DMA status */ +#define OOSIOP_SSTAT0 0x0d /* ro: SCSI status reg 0 */ +#define OOSIOP_SSTAT1 0x0e /* ro: SCSI status reg 1 */ +#define OOSIOP_SSTAT2 0x0f /* ro: SCSI status reg 2 */ +#define OOSIOP_SCRA0 0x10 /* rw: Scratch A */ +#define OOSIOP_SCRA1 0x11 +#define OOSIOP_SCRA2 0x12 +#define OOSIOP_SCRA3 0x13 +#define OOSIOP_CTEST0 0x14 /* ro: Chip test register 0 */ +#define OOSIOP_CTEST1 0x15 /* ro: Chip test register 1 */ +#define OOSIOP_CTEST2 0x16 /* ro: Chip test register 2 */ +#define OOSIOP_CTEST3 0x17 /* ro: Chip test register 3 */ +#define OOSIOP_CTEST4 0x18 /* rw: Chip test register 4 */ +#define OOSIOP_CTEST5 0x19 /* rw: Chip test register 5 */ +#define OOSIOP_CTEST6 0x1a /* rw: Chip test register 6 */ +#define OOSIOP_CTEST7 0x1b /* rw: Chip test register 7 */ +#define OOSIOP_TEMP 0x1c /* rw: Temporary Stack reg */ +#define OOSIOP_DFIFO 0x20 /* rw: DMA FIFO */ +#define OOSIOP_ISTAT 0x21 /* rw: Interrupt Status reg */ +#define OOSIOP_CTEST8 0x22 /* rw: Chip test register 8 */ +#define OOSIOP_CTEST9 0x23 /* ro: Chip test register 9 */ +#define OOSIOP_DBC 0x24 /* rw: DMA Byte Counter reg */ +#define OOSIOP_DCMD 0x27 /* rw: DMA Command Register */ +#define OOSIOP_DNAD 0x28 /* rw: DMA Next Address */ +#define OOSIOP_DSP 0x2c /* rw: DMA SCRIPTS Pointer reg */ +#define OOSIOP_DSPS 0x30 /* rw: DMA SCRIPTS Pointer Save reg */ +#define OOSIOP_DMODE 0x34 /* rw: DMA Mode reg */ +#define OOSIOP_RES35 0x35 +#define OOSIOP_RES36 0x36 +#define OOSIOP_RES37 0x37 +#define OOSIOP_RES38 0x38 +#define OOSIOP_DIEN 0x39 /* rw: DMA Interrupt Enable */ +#define OOSIOP_DWT 0x3a /* rw: DMA Watchdog Timer */ +#define OOSIOP_DCNTL 0x3b /* rw: DMA Control reg */ +#define OOSIOP_SCRB0 0x3c /* rw: Scratch B */ +#define OOSIOP_SCRB1 0x3d +#define OOSIOP_SCRB2 0x3e +#define OOSIOP_SCRB3 0x3f + +#define OOSIOP_NREGS 0x40 + + +/* + * Register defines + */ + +/* Scsi control register 0 (scntl0) */ + +#define OOSIOP_SCNTL0_ARB 0xc0 /* Arbitration mode */ +#define OOSIOP_ARB_SIMPLE 0x00 +#define OOSIOP_ARB_FULL 0xc0 +#define OOSIOP_SCNTL0_START 0x20 /* Start Sequence */ +#define OOSIOP_SCNTL0_WATN 0x10 /* (Select) With ATN */ +#define OOSIOP_SCNTL0_EPC 0x08 /* Enable Parity Checking */ +#define OOSIOP_SCNTL0_EPG 0x04 /* Enable Parity Generation */ +#define OOSIOP_SCNTL0_AAP 0x02 /* Assert ATN on Parity Error */ +#define OOSIOP_SCNTL0_TRG 0x01 /* Target Mode */ + +/* Scsi control register 1 (scntl1) */ + +#define OOSIOP_SCNTL1_EXC 0x80 /* Extra Clock Cycle of data setup */ +#define OOSIOP_SCNTL1_ADB 0x40 /* Assert Data Bus */ +#define OOSIOP_SCNTL1_ESR 0x20 /* Enable Selection/Reselection */ +#define OOSIOP_SCNTL1_CON 0x10 /* Connected */ +#define OOSIOP_SCNTL1_RST 0x08 /* Assert RST */ +#define OOSIOP_SCNTL1_AESP 0x04 /* Assert even SCSI parity */ +#define OOSIOP_SCNTL1_SND 0x02 /* Start Send operation */ +#define OOSIOP_SCNTL1_RCV 0x01 /* Start Receive operation */ + +/* Scsi interrupt enable register (sien) */ + +#define OOSIOP_SIEN_M_A 0x80 /* Phase Mismatch or ATN active */ +#define OOSIOP_SIEN_FC 0x40 /* Function Complete */ +#define OOSIOP_SIEN_STO 0x20 /* (Re)Selection timeout */ +#define OOSIOP_SIEN_SEL 0x10 /* (Re)Selected */ +#define OOSIOP_SIEN_SGE 0x08 /* SCSI Gross Error */ +#define OOSIOP_SIEN_UDC 0x04 /* Unexpected Disconnect */ +#define OOSIOP_SIEN_RST 0x02 /* RST asserted */ +#define OOSIOP_SIEN_PAR 0x01 /* Parity Error */ + +/* Scsi chip ID (scid) */ + +#define OOSIOP_SCID_VALUE(i) (1 << i) + +/* Scsi transfer register (sxfer) */ + +#define OOSIOP_SXFER_DHP 0x80 /* Disable Halt on Parity error/ + ATN asserted */ +#define OOSIOP_SXFER_TP 0x70 /* Synch Transfer Period */ + /* see specs for formulas: + Period = TCP * (4 + XFERP ) + TCP = 1 + CLK + 1..2; + */ +#define OOSIOP_SXFER_MO 0x0f /* Synch Max Offset */ +#define OOSIOP_MAX_OFFSET 8 + +/* Scsi output data latch register (sodl) */ + +/* Scsi output control latch register (socl) */ + +#define OOSIOP_REQ 0x80 /* SCSI signal asserted */ +#define OOSIOP_ACK 0x40 +#define OOSIOP_BSY 0x20 +#define OOSIOP_SEL 0x10 +#define OOSIOP_ATN 0x08 +#define OOSIOP_MSG 0x04 +#define OOSIOP_CD 0x02 +#define OOSIOP_IO 0x01 + +#define OOSIOP_PHASE(socl) SCSI_PHASE(socl) + +/* Scsi first byte received register (sfbr) */ + +/* Scsi input data latch register (sidl) */ + +/* Scsi bus data lines register (sbdl) */ + +/* Scsi bus control lines register (sbcl). Same as socl */ + +#define OOSIOP_SBCL_SSCF1 0x02 /* wo */ +#define OOSIOP_SBCL_SSCF0 0x01 /* wo */ + +/* DMA status register (dstat) */ + +#define OOSIOP_DSTAT_DFE 0x80 /* DMA FIFO empty */ +#define OOSIOP_DSTAT_ABRT 0x10 /* Aborted */ +#define OOSIOP_DSTAT_SSI 0x08 /* SCRIPT Single Step */ +#define OOSIOP_DSTAT_SIR 0x04 /* SCRIPT Interrupt Instruction */ +#define OOSIOP_DSTAT_WTD 0x02 /* Watchdog Timeout Detected */ +#define OOSIOP_DSTAT_IID 0x01 /* Invalid Instruction Detected */ + +/* Scsi status register 0 (sstat0) */ + +#define OOSIOP_SSTAT0_M_A 0x80 /* Phase Mismatch or ATN active */ +#define OOSIOP_SSTAT0_FC 0x40 /* Function Complete */ +#define OOSIOP_SSTAT0_STO 0x20 /* (Re)Selection timeout */ +#define OOSIOP_SSTAT0_SEL 0x10 /* (Re)Selected */ +#define OOSIOP_SSTAT0_SGE 0x08 /* SCSI Gross Error */ +#define OOSIOP_SSTAT0_UDC 0x04 /* Unexpected Disconnect */ +#define OOSIOP_SSTAT0_RST 0x02 /* RST asserted */ +#define OOSIOP_SSTAT0_PAR 0x01 /* Parity Error */ + +/* Scsi status register 1 (sstat1) */ + +#define OOSIOP_SSTAT1_ILF 0x80 /* Input latch (sidl) full */ +#define OOSIOP_SSTAT1_ORF 0x40 /* output reg (sodr) full */ +#define OOSIOP_SSTAT1_OLF 0x20 /* output latch (sodl) full */ +#define OOSIOP_SSTAT1_AIP 0x10 /* Arbitration in progress */ +#define OOSIOP_SSTAT1_LOA 0x08 /* Lost arbitration */ +#define OOSIOP_SSTAT1_WOA 0x04 /* Won arbitration */ +#define OOSIOP_SSTAT1_RST 0x02 /* SCSI RST current value */ +#define OOSIOP_SSTAT1_SDP 0x01 /* SCSI SDP current value */ + +/* Scsi status register 2 (sstat2) */ + +#define OOSIOP_SSTAT2_FF 0xf0 /* SCSI FIFO flags (bytecount) */ +#define OOSIOP_SCSI_FIFO_DEEP 8 +#define OOSIOP_SSTAT2_SDP 0x08 /* Latched (on REQ) SCSI SDP */ +#define OOSIOP_SSTAT2_MSG 0x04 /* Latched SCSI phase */ +#define OOSIOP_SSTAT2_CD 0x02 +#define OOSIOP_SSTAT2_IO 0x01 + +/* Chip test register 0 (ctest0) */ + +#define OOSIOP_CTEST0_RTRG 0x02 /* Real Target Mode */ +#define OOSIOP_CTEST0_DDIR 0x01 /* Xfer direction (1-> from SCSI bus) */ + +/* Chip test register 1 (ctest1) */ + +#define OOSIOP_CTEST1_FMT 0xf0 /* Byte empty in DMA FIFO bottom (high->byte3) */ +#define OOSIOP_CTEST1_FFL 0x0f /* Byte full in DMA FIFO top, same */ + +/* Chip test register 2 (ctest2) */ + +#define OOSIOP_CTEST2_SOFF 0x20 /* Synch Offset compare (1-> zero Init, max Tgt */ +#define OOSIOP_CTEST2_SFP 0x10 /* SCSI FIFO Parity */ +#define OOSIOP_CTEST2_DFP 0x08 /* DMA FIFO Parity */ +#define OOSIOP_CTEST2_TEOP 0x04 /* True EOP (a-la 5380) */ +#define OOSIOP_CTEST2_DREQ 0x02 /* DREQ status */ +#define OOSIOP_CTEST2_DACK 0x01 /* DACK status */ + +/* Chip test register 3 (ctest3) read-only, top of SCSI FIFO */ + +/* Chip test register 4 (ctest4) */ + +#define OOSIOP_CTEST4_ZMOD 0x40 /* High-impedance outputs */ +#define OOSIOP_CTEST4_SZM 0x20 /* ditto, SCSI "outputs" */ +#define OOSIOP_CTEST4_SLBE 0x10 /* SCSI loobpack enable */ +#define OOSIOP_CTEST4_SFWR 0x08 /* SCSI FIFO write enable (from sodl) */ +#define OOSIOP_CTEST4_FBL 0x07 /* DMA FIFO Byte Lane select (from ctest6) + 4->0, .. 7->3 */ + +/* Chip test register 5 (ctest5) */ + +#define OOSIOP_CTEST5_ADCK 0x80 /* Clock Address Incrementor */ +#define OOSIOP_CTEST5_BBCK 0x40 /* Clock Byte counter */ +#define OOSIOP_CTEST5_ROFF 0x20 /* Reset SCSI offset */ +#define OOSIOP_CTEST5_MASR 0x10 /* Master set/reset pulses (of bits 3-0) */ +#define OOSIOP_CTEST5_DDIR 0x08 /* (re)set internal DMA direction */ +#define OOSIOP_CTEST5_EOP 0x04 /* (re)set internal EOP */ +#define OOSIOP_CTEST5_DREQ 0x02 /* (re)set internal REQ */ +#define OOSIOP_CTEST5_DACK 0x01 /* (re)set internal ACK */ + +/* Chip test register 6 (ctest6) DMA FIFO access */ + +/* Chip test register 7 (ctest7) */ + +#define OOSIOP_CTEST7_STD 0x10 /* Selection timeout disable */ +#define OOSIOP_CTEST7_DFP 0x08 /* DMA FIFO parity bit */ +#define OOSIOP_CTEST7_EVP 0x04 /* Even parity (to host bus) */ +#define OOSIOP_CTEST7_DIFF 0x01 /* Differential mode */ + +/* DMA FIFO register (dfifo) */ + +#define OOSIOP_DFIFO_FLF 0x80 /* Flush (spill) DMA FIFO */ +#define OOSIOP_DFIFO_CLF 0x40 /* Clear DMA and SCSI FIFOs */ +#define OOSIOP_DFIFO_BO 0x3f /* FIFO byte offset counter */ + +/* Interrupt status register (istat) */ + +#define OOSIOP_ISTAT_ABRT 0x80 /* Abort operation */ +#define OOSIOP_ISTAT_CON 0x08 /* Connected */ +#define OOSIOP_ISTAT_PRE 0x04 /* Pointer register empty */ +#define OOSIOP_ISTAT_SIP 0x02 /* SCSI Interrupt pending */ +#define OOSIOP_ISTAT_DIP 0x01 /* DMA Interrupt pending */ + +/* Chip test register 8 (ctest8) */ + +/* DMA Byte Counter register (dbc) */ +#define OOSIOP_DBC_MAX 0xffffff + +/* DMA Mode register (dmode) */ + +#define OOSIOP_DMODE_BL_MASK 0xc0 /* 0->1 1->2 2->4 3->8 */ +#define OOSIOP_DMODE_BL_1 0x00 +#define OOSIOP_DMODE_BL_2 0x40 +#define OOSIOP_DMODE_BL_4 0x80 +#define OOSIOP_DMODE_BL_8 0xc0 +#define OOSIOP_DMODE_BW16 0x20 /* Bus Width is 16 bits */ +#define OOSIOP_DMODE_286 0x10 /* 286 mode */ +#define OOSIOP_DMODE_IO_M 0x08 /* xfer data to memory or I/O space */ +#define OOSIOP_DMODE_FAM 0x04 /* fixed address mode */ +#define OOSIOP_DMODE_PIPE 0x02 /* SCRIPTS in Pipeline mode */ +#define OOSIOP_DMODE_MAN 0x01 /* SCRIPTS in Manual start mode */ + +/* DMA interrupt enable register (dien) */ + +#define OOSIOP_DIEN_BF 0x20 /* On Bus Fault */ +#define OOSIOP_DIEN_ABRT 0x10 /* On Abort */ +#define OOSIOP_DIEN_SSI 0x08 /* On SCRIPTS sstep */ +#define OOSIOP_DIEN_SIR 0x04 /* On SCRIPTS intr instruction */ +#define OOSIOP_DIEN_WTD 0x02 /* On watchdog timeout */ +#define OOSIOP_DIEN_IID 0x01 /* On illegal instruction detected */ + +/* DMA control register (dcntl) */ + +#define OOSIOP_DCNTL_CF_MASK 0xc0 /* Clock frequency dividers: */ +#define OOSIOP_DCNTL_CF_2 0x00 /* 0 --> 37.51..50.00 MHz, div=2 */ +#define OOSIOP_DCNTL_CF_1_5 0x40 /* 1 --> 25.01..37.50 MHz, div=1.5 */ +#define OOSIOP_DCNTL_CF_1 0x80 /* 2 --> 16.67..25.00 MHz, div=1 */ +#define OOSIOP_DCNTL_CF_3 0xc0 /* 3 --> 50.01..66.67 MHz, div=3 */ +#define OOSIOP_DCNTL_S16 0x20 /* SCRIPTS fetches 16bits at a time */ +#define OOSIOP_DCNTL_SSM 0x10 /* Single step mode */ +#define OOSIOP_DCNTL_LLM 0x08 /* Enable SCSI Low-level mode */ +#define OOSIOP_DCNTL_STD 0x04 /* Start DMA operation */ +#define OOSIOP_DCNTL_RST 0x01 /* Software reset */ --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/oosiopvar.h 2003-02-18 02:02:28.000000000 +0900 @@ -0,0 +1,155 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2001 Shuichiro URATA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define OOSIOP_NTGT 8 /* Max targets */ +#define OOSIOP_NCB 32 /* Initial command buffers */ +#define OOSIOP_NSG (MIN(btoc(MAXPHYS) + 1, 32)) /* Max S/G operation */ +#define OOSIOP_MAX_XFER ctob(OOSIOP_NSG - 1) + +struct oosiop_xfer { + /* script for scatter/gather DMA (move*nsg+jump) */ + u_int32_t datain_scr[(OOSIOP_NSG + 1) * 2]; + u_int32_t dataout_scr[(OOSIOP_NSG + 1) * 2]; + + u_int8_t msgin[8]; + u_int8_t msgout[8]; + u_int8_t status; + u_int8_t pad[7]; +}; + +#define OOSIOP_XFEROFF(x) offsetof(struct oosiop_xfer, x) +#define OOSIOP_DINSCROFF OOSIOP_XFEROFF(datain_scr[0]) +#define OOSIOP_DOUTSCROFF OOSIOP_XFEROFF(dataout_scr[0]) +#define OOSIOP_MSGINOFF OOSIOP_XFEROFF(msgin[0]) +#define OOSIOP_MSGOUTOFF OOSIOP_XFEROFF(msgout[0]) + +#define OOSIOP_XFERSCR_SYNC(sc, cb, ops) \ + bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF, \ + OOSIOP_MSGINOFF - OOSIOP_DINSCROFF, (ops)) +#define OOSIOP_DINSCR_SYNC(sc, cb, ops) \ + bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF, \ + OOSIOP_DOUTSCROFF - OOSIOP_DINSCROFF, (ops)) +#define OOSIOP_DOUTSCR_SYNC(sc, cb, ops) \ + bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DOUTSCROFF,\ + OOSIOP_MSGINOFF - OOSIOP_DOUTSCROFF, (ops)) +#define OOSIOP_XFERMSG_SYNC(sc, cb, ops) \ + bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_MSGINOFF, \ + sizeof(struct oosiop_xfer) - OOSIOP_MSGINOFF, (ops)) + +#define OOSIOP_SCRIPT_SYNC(sc, ops) \ + bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_scrdma, \ + 0, sizeof(oosiop_script), (ops)) + +struct oosiop_cb { + TAILQ_ENTRY(oosiop_cb) chain; + + struct scsipi_xfer *xs; /* SCSI xfer ctrl block from above */ + int flags; + int id; /* target scsi id */ + int lun; /* target lun */ + + bus_dmamap_t cmddma; /* DMA map for command out */ + bus_dmamap_t datadma; /* DMA map for data I/O */ + bus_dmamap_t xferdma; /* DMA map for xfer block */ + + int curdp; /* current data pointer */ + int savedp; /* saved data pointer */ + int msgoutlen; + + struct oosiop_xfer *xfer; /* DMA xfer block */ +}; + +/* oosiop_cb flags */ +#define CBF_SELTOUT 0x01 /* Selection timeout */ +#define CBF_TIMEOUT 0x02 /* Command timeout */ + +TAILQ_HEAD(oosiop_cb_queue, oosiop_cb); + +struct oosiop_target { + struct oosiop_cb *nexus; + int flags; + u_int8_t scf; /* synchronous clock divisor */ + u_int8_t sxfer; /* synchronous period and offset */ +}; + +/* target flags */ +#define TGTF_SYNCNEG 0x01 /* Trigger synchronous negotiation */ +#define TGTF_WAITSDTR 0x02 /* Waiting SDTR from target */ + +struct oosiop_softc { + struct device sc_dev; + + bus_space_tag_t sc_bst; /* bus space tag */ + bus_space_handle_t sc_bsh; /* bus space handle */ + + bus_dma_tag_t sc_dmat; /* bus dma tag */ + bus_dmamap_t sc_scrdma; /* script dma map */ + + bus_addr_t sc_scrbase; /* script dma base address */ + u_int32_t *sc_scr; /* ptr to script memory */ + + int sc_chip; /* 700 or 700-66 */ +#define OOSIOP_700 0 +#define OOSIOP_700_66 1 + + int sc_id; /* SCSI ID of this interface */ + int sc_freq; /* SCLK frequency */ + int sc_ccf; /* asynchronous divisor (*10) */ + u_int8_t sc_dcntl; + u_int8_t sc_minperiod; + + struct oosiop_target sc_tgt[OOSIOP_NTGT]; + + struct scsipi_adapter sc_adapter; + struct scsipi_channel sc_channel; + + /* Lists of command blocks */ + struct oosiop_cb_queue sc_free_cb; + struct oosiop_cb_queue sc_cbq; /* command issue queue */ + struct oosiop_cb *sc_curcb; /* current command */ + struct oosiop_cb *sc_lastcb; /* last activated command */ + + bus_addr_t sc_reselbuf; /* msgin buffer for reselection */ + int sc_resid; /* reselected target id */ + + int sc_active; + int sc_nextdsp; +}; + +#define oosiop_read_1(sc, addr) \ + bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (addr)) +#define oosiop_write_1(sc, addr, data) \ + bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (addr), (data)) +/* XXX byte swapping should be handled by MD bus_space(9)? */ +#define oosiop_read_4(sc, addr) \ + le32toh(bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (addr))) +#define oosiop_write_4(sc, addr, data) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (addr), htole32(data)) + +void oosiop_attach(struct oosiop_softc *); +int oosiop_intr(struct oosiop_softc *); --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/sti.c 2003-02-16 16:23:58.000000000 +0900 @@ -0,0 +1,628 @@ +/* $NetBSD$ */ +/* $OpenBSD: sti.c,v 1.6 2001/09/19 20:50:58 mickey Exp $ */ + +/* + * Copyright (c) 2000-2001 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * TODO: + * call sti procs asynchronously; + * implement console scroll-back; + * X11 support. + */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +/* XXX fredette - this isn't very MI: */ +#include + +#include +#include + +void sti_cursor __P((void *v, int on, int row, int col)); +int sti_mapchar __P((void *v, int uni, u_int *index)); +void sti_putchar __P((void *v, int row, int col, u_int uc, long attr)); +void sti_copycols __P((void *v, int row, int srccol, int dstcol, int ncols)); +void sti_erasecols __P((void *v, int row, int startcol, int ncols, long attr)); +void sti_copyrows __P((void *v, int srcrow, int dstrow, int nrows)); +void sti_eraserows __P((void *v, int row, int nrows, long attr)); +int sti_alloc_attr __P((void *v, int fg, int bg, int flags, long *)); + +struct wsdisplay_emulops sti_emulops = { + sti_cursor, + sti_mapchar, + sti_putchar, + sti_copycols, + sti_erasecols, + sti_copyrows, + sti_eraserows, + sti_alloc_attr +}; + +int sti_ioctl __P((void *v, u_long cmd, caddr_t data, int flag, struct proc *p)); +paddr_t sti_mmap __P((void *v, off_t offset, int prot)); +int sti_alloc_screen __P((void *v, const struct wsscreen_descr *type, + void **cookiep, int *cxp, int *cyp, long *defattr)); + void sti_free_screen __P((void *v, void *cookie)); +int sti_show_screen __P((void *v, void *cookie, int waitok, + void (*cb) __P((void *, int, int)), void *cbarg)); +int sti_load_font __P((void *v, void *cookie, struct wsdisplay_font *)); + +const struct wsdisplay_accessops sti_accessops = { + sti_ioctl, + sti_mmap, + sti_alloc_screen, + sti_free_screen, + sti_show_screen, + sti_load_font +}; + +struct wsscreen_descr sti_default_screen = { + "default", 0, 0, + &sti_emulops, + 0, 0, + WSSCREEN_REVERSE | WSSCREEN_UNDERLINE +}; + +const struct wsscreen_descr *sti_default_scrlist[] = { + &sti_default_screen +}; + +struct wsscreen_list sti_default_screenlist = { + sizeof(sti_default_scrlist) / sizeof(sti_default_scrlist[0]), + sti_default_scrlist +}; + +enum sti_bmove_funcs { + bmf_clear, bmf_copy, bmf_invert, bmf_underline +}; + +int sti_init __P((struct sti_softc *sc, int mode)); +int sti_inqcfg __P((struct sti_softc *sc, struct sti_inqconfout *out)); +void sti_bmove __P((struct sti_softc *sc, int, int, int, int, int, int, + enum sti_bmove_funcs)); + +void +sti_attach_common(sc) + struct sti_softc *sc; +{ + struct sti_inqconfout cfg; + bus_space_handle_t fbh; + struct wsemuldisplaydev_attach_args waa; + struct sti_dd *dd; + struct sti_cfg *cc; + struct sti_fontcfg *ff; + int error, size, i; + + dd = &sc->sc_dd; + if (sc->sc_devtype == STI_DEVTYPE1) { +#define parseshort(o) \ + ((bus_space_read_1(sc->memt, sc->romh, (o) + 3) << 8) | \ + (bus_space_read_1(sc->memt, sc->romh, (o) + 7))) +#define parseword(o) \ + ((bus_space_read_1(sc->memt, sc->romh, (o) + 3) << 24) | \ + (bus_space_read_1(sc->memt, sc->romh, (o) + 7) << 16) | \ + (bus_space_read_1(sc->memt, sc->romh, (o) + 11) << 8) | \ + (bus_space_read_1(sc->memt, sc->romh, (o) + 15))) + + dd->dd_type = bus_space_read_1(sc->memt, sc->romh, 3); + dd->dd_nmon = bus_space_read_1(sc->memt, sc->romh, 7); + dd->dd_grrev = bus_space_read_1(sc->memt, sc->romh, 11); + dd->dd_lrrev = bus_space_read_1(sc->memt, sc->romh, 15); + dd->dd_grid[0] = parseword(0x10); + dd->dd_grid[1] = parseword(0x20); + dd->dd_fntaddr = parseword(0x30) & ~3; + dd->dd_maxst = parseword(0x40); + dd->dd_romend = parseword(0x50) & ~3; + dd->dd_reglst = parseword(0x60) & ~3; + dd->dd_maxreent= parseshort(0x70); + dd->dd_maxtimo = parseshort(0x78); + /* what happened to 0x80 ? */ + dd->dd_montbl = parseword(0x90); + dd->dd_udaddr = parseword(0xa0) & ~3; + dd->dd_stimemreq=parseword(0xb0); + dd->dd_udsize = parseword(0xc0); + dd->dd_pwruse = parseshort(0xd0); + dd->dd_bussup = bus_space_read_1(sc->memt, sc->romh, 0xdb); + dd->dd_ebussup = bus_space_read_1(sc->memt, sc->romh, 0xdf); + dd->dd_altcodet= bus_space_read_1(sc->memt, sc->romh, 0xe3); + dd->dd_cfbaddr = parseword(0xf0) & ~3; + + dd->dd_pacode[0x0] = parseword(0x100) & ~3; + dd->dd_pacode[0x1] = parseword(0x110) & ~3; + dd->dd_pacode[0x2] = parseword(0x120) & ~3; + dd->dd_pacode[0x3] = parseword(0x130) & ~3; + dd->dd_pacode[0x4] = parseword(0x140) & ~3; + dd->dd_pacode[0x5] = parseword(0x150) & ~3; + dd->dd_pacode[0x6] = parseword(0x160) & ~3; + dd->dd_pacode[0x7] = parseword(0x170) & ~3; + dd->dd_pacode[0x8] = parseword(0x180) & ~3; + dd->dd_pacode[0x9] = parseword(0x190) & ~3; + dd->dd_pacode[0xa] = parseword(0x1a0) & ~3; + dd->dd_pacode[0xb] = parseword(0x1b0) & ~3; + dd->dd_pacode[0xc] = parseword(0x1c0) & ~3; + dd->dd_pacode[0xd] = parseword(0x1d0) & ~3; + dd->dd_pacode[0xe] = parseword(0x1e0) & ~3; + dd->dd_pacode[0xf] = parseword(0x1f0) & ~3; + } else /* STI_DEVTYPE4 */ + bus_space_read_region_4(sc->memt, sc->romh, 0, (u_int32_t *)dd, + sizeof(*dd) / 4); + +#ifdef STIDEBUG + printf("dd:\n" + "devtype=%x, rev=%x;%d, gid=%x%x, font=%x, mss=%x\n" + "end=%x, mmap=%x, msto=%x, timo=%d, mont=%x, ua=%x\n" + "memrq=%x, pwr=%d, bus=%x, ebus=%x, altt=%x, cfb=%x\n" + "code=", + dd->dd_type, dd->dd_grrev, dd->dd_lrrev, + dd->dd_grid[0], dd->dd_grid[1], + dd->dd_fntaddr, dd->dd_maxst, dd->dd_romend, + dd->dd_reglst, dd->dd_maxreent, + dd->dd_maxtimo, dd->dd_montbl, dd->dd_udaddr, + dd->dd_stimemreq, dd->dd_udsize, dd->dd_pwruse, + dd->dd_bussup, dd->dd_altcodet, dd->dd_cfbaddr); + printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", + dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], + dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], + dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], + dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], + dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], + dd->dd_pacode[0xf]); +#endif + /* divine code size, could be less than STI_END entries */ + for (i = STI_END; !dd->dd_pacode[i]; i--); + size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; + if (sc->sc_devtype == STI_DEVTYPE1) + size = (size + 3) / 4; + if (!(sc->sc_code = uvm_km_kmemalloc(kernel_map, + uvm.kernel_object, round_page(size), UVM_KMF_NOWAIT))) { + printf(": cannot allocate %u bytes for code\n", size); + return; + } + + /* copy code into memory */ + if (sc->sc_devtype == STI_DEVTYPE1) { + register u_int8_t *p = (u_int8_t *)sc->sc_code; + + for (i = 0; i < size; i++) + *p++ = bus_space_read_1(sc->memt, sc->romh, + dd->dd_pacode[0] + i * 4 + 3); + + } else /* STI_DEVTYPE4 */ + bus_space_read_region_4(sc->memt, sc->romh, dd->dd_pacode[0], + (u_int32_t *)sc->sc_code, size / 4); + + /* flush from cache */ + MD_CACHE_CTL(sc->sc_code, size, MD_CACHE_FLUSH); + +#define O(i) (dd->dd_pacode[(i)]? (sc->sc_code + \ + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ + (sc->sc_devtype == STI_DEVTYPE1? 4 : 1)) : NULL) + sc->init = (sti_init_t) O(STI_INIT_GRAPH); + sc->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); + sc->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); + sc->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); + sc->test = (sti_test_t) O(STI_SELF_TEST); + sc->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); + sc->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); + sc->scment = (sti_scment_t)O(STI_SCM_ENT); + sc->dmac = (sti_dmac_t) O(STI_DMA_CTRL); + sc->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); + sc->utiming = (sti_utiming_t)O(STI_UTIMING); + sc->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); + sc->util = (sti_util_t) O(STI_UTIL); + + pmap_protect(pmap_kernel(), sc->sc_code, + sc->sc_code + round_page(size), VM_PROT_READ|VM_PROT_EXECUTE); + + cc = &sc->sc_cfg; + bzero(cc, sizeof (*cc)); + { + register int i = dd->dd_reglst; + register u_int32_t *p; + struct sti_region r; + +#ifdef STIDEBUG + printf ("stiregions @%p:\n", i); +#endif + r.last = 0; + for (p = cc->regions; !r.last && + p < &cc->regions[STI_REGION_MAX]; p++) { + + if (sc->sc_devtype == STI_DEVTYPE1) + *(u_int *)&r = parseword(i), i+= 16; + else + *(u_int *)&r = bus_space_read_4(sc->memt, sc->romh, i), i += 4; + + *p = (p == cc->regions? sc->romh : sc->ioh) + + (r.offset << PGSHIFT); +#ifdef STIDEBUG + printf("%x @ 0x%x %s%s%s%s\n", + r.length << PGSHIFT, *p, r.sys_only? "sys " : "", + r.cache? "cache " : "", r.btlb? "btlb " : "", + r.last? "last" : ""); +#endif + + /* rom was already mapped */ + if (p != cc->regions) { + if (bus_space_map(sc->memt, *p, + r.length << PGSHIFT, 0, &fbh)) { +#ifdef STIDEBUG + printf("cannot map region\n"); +#endif + /* who cares: return; */ + } else if (p - cc->regions == 1) + sc->fbh = fbh; + } + } + } + + if ((error = sti_init(sc, 0))) { + printf (": can not initialize (%d)\n", error); + return; + } + + if ((error = sti_inqcfg(sc, &cfg))) { + printf (": error %d inquiring config\n", error); + return; + } + + if ((error = sti_init(sc, STI_TEXTMODE))) { + printf (": can not initialize (%d)\n", error); + return; + } + + ff = &sc->sc_fontcfg; + if (sc->sc_devtype == STI_DEVTYPE1) { + i = dd->dd_fntaddr; + ff->first = parseshort(i + 0x00); + ff->last = parseshort(i + 0x08); + ff->width = bus_space_read_1(sc->memt, sc->romh, i + 0x13); + ff->height = bus_space_read_1(sc->memt, sc->romh, i + 0x17); + ff->type = bus_space_read_1(sc->memt, sc->romh, i + 0x1b); + ff->bpc = bus_space_read_1(sc->memt, sc->romh, i + 0x1f); + ff->uheight= bus_space_read_1(sc->memt, sc->romh, i + 0x33); + ff->uoffset= bus_space_read_1(sc->memt, sc->romh, i + 0x37); + } else /* STI_DEVTYPE4 */ + bus_space_read_region_4(sc->memt, sc->romh, dd->dd_fntaddr, + (u_int32_t *)ff, sizeof(*ff) / 4); + + printf(": %s rev %d.%02d;%d\n" + "%s: %dx%d frame buffer, %dx%dx%d display, offset %dx%d\n" + "%s: %dx%d font type %d, %d bpc, charset %d-%d\n", cfg.name, + dd->dd_grrev >> 4, dd->dd_grrev & 0xf, dd->dd_lrrev, + sc->sc_dev.dv_xname, cfg.fbwidth, cfg.fbheight, + cfg.width, cfg.height, cfg.bpp, cfg.owidth, cfg.oheight, + sc->sc_dev.dv_xname, + ff->width, ff->height, ff->type, ff->bpc, ff->first, ff->last); + + /* + * parse screen descriptions: + * figure number of fonts supported; + * allocate wscons structures; + * calculate dimentions. + */ + + sti_default_screen.ncols = cfg.width / ff->width; + sti_default_screen.nrows = cfg.height / ff->height; + sti_default_screen.fontwidth = ff->width; + sti_default_screen.fontheight = ff->height; + + /* attach WSDISPLAY */ + waa.console = sc->sc_dev.dv_unit; + waa.scrdata = &sti_default_screenlist; + waa.accessops = &sti_accessops; + waa.accesscookie = sc; + + config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint); +} + +int +sti_init(sc, mode) + struct sti_softc *sc; + int mode; +{ + struct { + struct sti_initflags flags; + struct sti_initin in; + struct sti_initout out; + } a; + + bzero(&a, sizeof(a)); + + a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | + (mode & STI_TEXTMODE? STI_INITF_TEXT | STI_INITF_PBET | + STI_INITF_PBETI | STI_INITF_ICMT : 0); + a.in.text_planes = 1; +#ifdef STIDEBUG + printf("%s: init,%p(%x, %p, %p, %p)\n", sc->sc_dev.dv_xname, + sc->init, a.flags.flags, &a.in, &a.out, &sc->sc_cfg); +#endif + (*sc->init)(&a.flags, &a.in, &a.out, &sc->sc_cfg); + return (a.out.text_planes != a.in.text_planes || a.out.errno); +} + +int +sti_inqcfg(sc, out) + struct sti_softc *sc; + struct sti_inqconfout *out; +{ + struct { + struct sti_inqconfflags flags; + struct sti_inqconfin in; + } a; + + bzero(&a, sizeof(a)); + bzero(out, sizeof(*out)); + + a.flags.flags = STI_INQCONFF_WAIT; + (*sc->inqconf)(&a.flags, &a.in, out, &sc->sc_cfg); + + return out->errno; +} + +void +sti_bmove(sc, x1, y1, x2, y2, h, w, f) + struct sti_softc *sc; + int x1, y1, x2, y2, h, w; + enum sti_bmove_funcs f; +{ + struct { + struct sti_blkmvflags flags; + struct sti_blkmvin in; + struct sti_blkmvout out; + } a; + + bzero(&a, sizeof(a)); + + a.flags.flags = STI_BLKMVF_WAIT; + switch (f) { + case bmf_clear: + a.flags.flags |= STI_BLKMVF_CLR; + a.in.bg_colour = 0; + break; + case bmf_underline: + case bmf_copy: + a.in.fg_colour = 1; + a.in.bg_colour = 0; + break; + case bmf_invert: + a.in.fg_colour = 0; + a.in.bg_colour = 1; + break; + } + a.in.srcx = x1; + a.in.srcy = y1; + a.in.dstx = x2; + a.in.dsty = y2; + a.in.height = h; + a.in.width = w; + + (*sc->blkmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); +#ifdef STIDEBUG + if (a.out.errno) + printf ("%s: blkmv returned %d\n", + sc->sc_dev.dv_xname, a.out.errno); +#endif +} + +int +sti_ioctl(v, cmd, data, flag, p) + void *v; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + /* register struct sti_softc *sc; */ + + return -1; +} + +paddr_t +sti_mmap(v, offset, prot) + void *v; + off_t offset; + int prot; +{ + /* XXX not finished */ + return offset; +} + +int +sti_alloc_screen(v, type, cookiep, cxp, cyp, defattr) + void *v; + const struct wsscreen_descr *type; + void **cookiep; + int *cxp, *cyp; + long *defattr; +{ + return -1; +} + +void +sti_free_screen(v, cookie) + void *v; + void *cookie; +{ +} + +int +sti_show_screen(v, cookie, waitok, cb, cbarg) + void *v; + void *cookie; + int waitok; + void (*cb) __P((void *, int, int)); + void *cbarg; +{ + return 0; +} + +int +sti_load_font(v, cookie, font) + void *v; + void *cookie; + struct wsdisplay_font *font; +{ + return -1; +} + +void +sti_cursor(v, on, row, col) + void *v; + int on, row, col; +{ + register struct sti_softc *sc = v; + + sti_bmove(sc, row * sc->sc_fontcfg.height, col * sc->sc_fontcfg.width, + row * sc->sc_fontcfg.height, col * sc->sc_fontcfg.width, + sc->sc_fontcfg.width, sc->sc_fontcfg.height, bmf_invert); +} + +int +sti_mapchar(v, uni, index) + void *v; + int uni; + u_int *index; +{ + if (uni < 256) + *index = uni; + + return 1; +} + +void +sti_putchar(v, row, col, uc, attr) + void *v; + int row, col; + u_int uc; + long attr; +{ + register struct sti_softc *sc = v; + struct { + struct sti_unpmvflags flags; + struct sti_unpmvin in; + struct sti_unpmvout out; + } a; + + bzero(&a, sizeof(a)); + + a.flags.flags = STI_UNPMVF_WAIT; + /* XXX does not handle text attributes */ + a.in.fg_colour = 1; + a.in.bg_colour = 0; + a.in.x = col * sc->sc_fontcfg.width; + a.in.y = row * sc->sc_fontcfg.height; + a.in.font_addr = 0/*STI_FONTAD(sc->sc_devtype, sc->sc_rom)*/; + a.in.index = uc; + (*sc->unpmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); +} + +void +sti_copycols(v, row, srccol, dstcol, ncols) + void *v; + int row, srccol, dstcol, ncols; +{ + register struct sti_softc *sc = v; + + sti_bmove(sc, + row * sc->sc_fontcfg.height, srccol * sc->sc_fontcfg.width, + row * sc->sc_fontcfg.height, dstcol * sc->sc_fontcfg.width, + ncols * sc->sc_fontcfg.width, sc->sc_fontcfg.height, + bmf_copy); +} + +void +sti_erasecols(v, row, startcol, ncols, attr) + void *v; + int row, startcol, ncols; + long attr; +{ + register struct sti_softc *sc = v; + + sti_bmove(sc, + row * sc->sc_fontcfg.height, startcol * sc->sc_fontcfg.width, + row * sc->sc_fontcfg.height, startcol * sc->sc_fontcfg.width, + ncols * sc->sc_fontcfg.width, sc->sc_fontcfg.height, + bmf_clear); +} + +void +sti_copyrows(v, srcrow, dstrow, nrows) + void *v; + int srcrow, dstrow, nrows; +{ + register struct sti_softc *sc = v; + + sti_bmove(sc, + srcrow * sc->sc_fontcfg.height, 0, + dstrow * sc->sc_fontcfg.height, 0, + sc->sc_cfg.fb_width, nrows + sc->sc_fontcfg.height, + bmf_copy); +} + +void +sti_eraserows(v, srcrow, nrows, attr) + void *v; + int srcrow, nrows; + long attr; +{ + register struct sti_softc *sc = v; + + sti_bmove(sc, + srcrow * sc->sc_fontcfg.height, 0, + srcrow * sc->sc_fontcfg.height, 0, + sc->sc_cfg.fb_width, nrows + sc->sc_fontcfg.height, + bmf_clear); +} + +int +sti_alloc_attr(v, fg, bg, flags, pattr) + void *v; + int fg, bg, flags; + long *pattr; +{ + /* register struct sti_softc *sc = v; */ + + *pattr = 0; + + return 0; +} + --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/stireg.h 2003-02-16 16:23:58.000000000 +0900 @@ -0,0 +1,589 @@ +/* $NetBSD$ */ + +/* $OpenBSD: stireg.h,v 1.3 2001/01/11 21:30:30 mickey Exp $ */ + +/* + * Copyright (c) 2000 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IC_STIREG_H_ +#define _IC_STIREG_H_ + +/* #define STIDEBUG */ + +#define STI_REGION_MAX 8 +#define STI_MONITOR_MAX 256 +#define STI_DEVNAME_LEN 32 + +/* code ROM definitions */ +#define STI_BEGIN 0 +#define STI_INIT_GRAPH 0 +#define STI_STATE_MGMT 1 +#define STI_FONT_UNPMV 2 +#define STI_BLOCK_MOVE 3 +#define STI_SELF_TEST 4 +#define STI_EXCEP_HDLR 5 +#define STI_INQ_CONF 6 +#define STI_SCM_ENT 7 +#define STI_DMA_CTRL 8 +#define STI_FLOW_CTRL 9 +#define STI_UTIMING 10 +#define STI_PROC_MGR 11 +#define STI_UTIL 12 +#define STI_END 13 +#define STI_CODECNT 16 + +/* sti returns */ +#define STI_OK 0 +#define STI_FAIL -1 +#define STI_NRDY 1 + +/* sti errno */ +#define STI_NOERRNO 0 /* no error */ +#define STI_BADREENTLVL 1 /* bad reentry level */ +#define STI_NOREGIONSDEF 2 /* region table is not setup */ +#define STI_ILLNPLANES 3 /* invalid num of text planes */ +#define STI_ILLINDEX 4 /* invalid fond index */ +#define STI_ILLLOC 5 /* invalid font location */ +#define STI_ILLCOLOUR 6 /* invalid colour */ +#define STI_ILLBLKMVFROM 7 /* invalid from in blkmv */ +#define STI_ILLBLKMVTO 8 /* invalid to in blkmv */ +#define STI_ILLBLKMVSIZE 9 /* invalid siz in blkmv */ +#define STI_BEIUNSUPP 10 /* bus error ints unsupported */ +#define STI_UNXPBE 11 /* unexpected bus error */ +#define STI_UNXHWF 12 /* unexpected hardware failure */ +#define STI_NEGCFG 13 /* no ext global config struct */ +#define STI_NEIG 14 /* no ext init struct */ +#define STI_ILLSCME 15 /* invalid set cmap entry */ +#define STI_ILLCMVAL 16 /* invalid cmap value */ +#define STI_NORESMEM 17 /* no requested global memory */ +#define STI_RESMEMCORR 18 /* reserved memory corrupted */ +#define STI_ILLNTBLKMV 19 /* invalid non-text blkmv */ +#define STI_ILLMONITOR 20 /* monitor selection is out of range */ +#define STI_ILLEXCADDR 21 /* invalid excpt handler addr */ +#define STI_ILLEXCFLAGS 22 /* invalid excpt handler flags */ +#define STI_NOEHE 23 /* no ext exhdl struct */ +#define STI_NOINQCE 24 /* no ext inq cfg struct */ +#define STI_ILLRGNPTR 25 /* invalid region pointer */ +#define STI_ILLUTLOP 26 /* invalid util opcode */ +#define STI_UNKNOWN 250 /* unknown error */ +#define STI_NOCFGPTR 251 /* no config ptr defined */ +#define STI_NOFLPTR 252 /* no flag ptr defined */ +#define STI_NOINPTR 253 /* no in ptr defined */ +#define STI_NOOUTPTR 254 /* no way you can get it */ +#define STI_NOLOCK 255 /* kernel dishonour graphics lock */ + +/* colours */ +#define STI_COLOUR_BLACK 0 +#define STI_COLOUR_WHITE 1 +#define STI_COLOUR_RED 2 +#define STI_COLOUR_YELLOW 3 +#define STI_COLOUR_GREEN 4 +#define STI_COLOUR_CYAN 5 +#define STI_COLOUR_BLUE 6 +#define STI_COLOUR_MAGENTA 7 + +#pragma pack(1) + + /* LSB high */ +struct sti_dd { + u_int32_t dd_type; /* 0x00 device type */ +#define STI_DEVTYPE1 1 +#define STI_DEVTYPE4 3 + u_int8_t dd_unused; + u_int8_t dd_nmon; /* 0x05 number monitor rates */ + u_int8_t dd_grrev; /* 0x06 global rom revision */ + u_int8_t dd_lrrev; /* 0x07 local rom revision */ + u_int8_t dd_grid[8]; /* 0x08 graphics id */ + u_int32_t dd_fntaddr; /* 0x10 font start address */ + u_int32_t dd_maxst; /* 0x14 max state storage */ + u_int32_t dd_romend; /* 0x18 rom last address */ + u_int32_t dd_reglst; /* 0x1c device region list */ + u_int16_t dd_maxreent; /* 0x20 max reent storage */ + u_int16_t dd_maxtimo; /* 0x22 max execution timeout .1 sec */ + u_int32_t dd_montbl; /* 0x24 mon table address, array of + names num of dd_nmon */ + u_int32_t dd_udaddr; /* 0x28 user data address */ + u_int32_t dd_stimemreq; /* 0x2c sti memory request */ + u_int32_t dd_udsize; /* 0x30 user data size */ + u_int16_t dd_pwruse; /* 0x34 power usage */ + u_int8_t dd_bussup; /* 0x36 bus support */ +#define STI_BUSSUPPORT_GSCINTL 0x01 /* supports pulling INTL for int */ +#define STI_BUSSUPPORT_GSC15X 0x02 /* supports GSC 1.5X */ +#define STI_BUSSUPPORT_GSC2X 0x04 /* supports GSC 2.X */ +#define STI_BUSSUPPORT_PCIIOEIM 0x08 /* will use directed int */ +#define STI_BUSSUPPORT_PCISTD 0x10 /* will use std PCI int */ +#define STI_BUSSUPPORT_ILOCK 0x20 /* supports implicit locking */ +#define STI_BUSSUPPORT_ROMMAP 0x40 /* rom is only in pci erom space */ +#define STI_BUSSUPPORT_2DECODE 0x80 /* single address decoder */ + u_int8_t dd_ebussup; /* 0x37 extended bus support */ +#define STI_EBUSSUPPORT_DMA 0x01 /* supports dma */ +#define STI_EBUSSUPPORT_PIOLOCK 0x02 /* no implicit locking for dma */ + u_int8_t dd_altcodet; /* 0x38 alternate code type */ +#define STI_ALTCODE_UNKNOWN 0x00 +#define STI_ALTCODE_PA64 0x01 /* alt code is in pa64 */ + u_int8_t dd_eddst[3]; /* 0x39 extended DD struct */ + u_int32_t dd_cfbaddr; /* 0x3c CFB address, location of + X11 driver to be used for + servers w/o accel */ + u_int32_t dd_pacode[16]; /* 0x40 routines for pa-risc */ + u_int32_t dd_altcode[16]; /* 0x80 routines for m68k/i386 */ +}; + +/* after the last region there is one indirect list ptr */ +struct sti_region { + u_int offset :14; /* page offset dev io space relative */ + u_int sys_only: 1; /* whether allow user access */ + u_int cache : 1; /* map in cache */ + u_int btlb : 1; /* should use BTLB if available */ + u_int last : 1; /* last region in the list */ + u_int length :14; /* size in pages */ +}; + +struct sti_font { + u_int16_t first; + u_int16_t last; + u_int8_t width; + u_int8_t height; + u_int8_t type; +#define STI_FONT_HPROMAN8 1 +#define STI_FONT_KANA8 2 + u_int8_t bpc; + u_int32_t next; + u_int8_t uheight; + u_int8_t uoffset; + u_int8_t unused[2]; +}; + +struct sti_fontcfg { + u_int16_t first; + u_int16_t last; + u_int8_t width; + u_int8_t height; + u_int8_t type; + u_int8_t bpc; + u_int8_t uheight; + u_int8_t uoffset; +}; + +typedef struct sti_ecfg { + u_int8_t current_monitor; + u_int8_t uf_boot; + u_int16_t power; /* power dissipation Watts */ + u_int32_t freq_ref; + u_int32_t *addr; /* memory block of size dd_stimemreq */ + void *future; +} *sti_ecfg_t; + +typedef struct sti_cfg { + u_int32_t text_planes; + u_int16_t scr_width; + u_int16_t scr_height; + u_int16_t oscr_width; + u_int16_t oscr_height; + u_int16_t fb_width; + u_int16_t fb_height; + u_int32_t regions[STI_REGION_MAX]; + u_int32_t reent_level; + u_int32_t *save_addr; + sti_ecfg_t ext_cfg; +} *sti_cfg_t; + + +/* routine types */ +#define STI_DEP(n) \ + typedef int (*sti_##n##_t) __P(( \ + sti_##n##flags_t, sti_##n##in_t, sti_##n##out_t, sti_cfg_t)); + +typedef struct sti_initflags { + u_int32_t flags; +#define STI_INITF_WAIT 0x80000000 +#define STI_INITF_RESET 0x40000000 +#define STI_INITF_TEXT 0x20000000 +#define STI_INITF_NTEXT 0x10000000 +#define STI_INITF_CLEAR 0x08000000 +#define STI_INITF_CMB 0x04000000 /* non-text planes cmap black */ +#define STI_INITF_EBET 0x02000000 /* enable bus error timer */ +#define STI_INITF_EBETI 0x01000000 /* enable bus error timer interrupt */ +#define STI_INITF_PTS 0x00800000 /* preserve text settings */ +#define STI_INITF_PNTS 0x00400000 /* preserve non-text settings */ +#define STI_INITF_PBET 0x00200000 /* preserve BET settings */ +#define STI_INITF_PBETI 0x00100000 /* preserve BETI settings */ +#define STI_INITF_ICMT 0x00080000 /* init cmap for text planes */ +#define STI_INITF_SCMT 0x00040000 /* change current monitor type */ +#define STI_INITF_RIE 0x00020000 /* retain int enables */ + void *future; +} *sti_initflags_t; + +typedef struct sti_einitin { + u_int8_t mon_type; + u_int8_t pad; + u_int16_t inflight; /* possible on pci */ + void *future; +} *sti_einitin_t; + +typedef struct sti_initin { + u_int32_t text_planes; /* number of planes for text */ + sti_einitin_t ext_in; +} *sti_initin_t; + +typedef struct sti_initout { + int32_t errno; + u_int32_t text_planes; /* number of planes used for text */ + void *future; +} *sti_initout_t; + +STI_DEP(init); + +typedef struct sti_mgmtflags { + u_int32_t flags; +#define STI_MGMTF_WAIT 0x80000000 +#define STI_MGMTF_SAVE 0x40000000 +#define STI_MGMTF_RALL 0x20000000 /* restore all display planes */ + void *future; +} *sti_mgmtflags_t; + +typedef struct sti_mgmtin { + void *addr; + void *future; +} *sti_mgmtin_t; + +typedef struct sti_mgmtout { + int32_t errno; + void *future; +} *sti_mgmtout_t; + +STI_DEP(mgmt); + +typedef struct sti_unpmvflags { + u_int32_t flags; +#define STI_UNPMVF_WAIT 0x80000000 +#define STI_UNPMVF_NTXT 0x40000000 /* intp non-text planes */ + void *future; +} *sti_unpmvflags_t; + +typedef struct sti_unpmvin { + u_int32_t *font_addr; /* font */ + u_int16_t index; /* character index in the font */ + u_int8_t fg_colour; + u_int8_t bg_colour; + u_int16_t x, y; + void *future; +} *sti_unpmvin_t; + +typedef struct sti_unpmvout { + u_int32_t errno; + void *future; +} *sti_unpmvout_t; + +STI_DEP(unpmv); + +typedef struct sti_blkmvflags { + u_int32_t flags; +#define STI_BLKMVF_WAIT 0x80000000 +#define STI_BLKMVF_COLR 0x40000000 /* change colour on move */ +#define STI_BLKMVF_CLR 0x20000000 /* clear on move */ +#define STI_BLKMVF_NTXT 0x10000000 /* move in non-text planes */ + void *future; +} *sti_blkmvflags_t; + +typedef struct sti_blkmvin { + u_int8_t fg_colour; + u_int8_t bg_colour; + u_int16_t srcx, srcy, dstx, dsty; + u_int16_t width, height; + void *future; +} *sti_blkmvin_t; + +typedef struct sti_blkmvout { + u_int32_t errno; + void *future; +} *sti_blkmvout_t; + +STI_DEP(blkmv); + +typedef struct sti_testflags { + u_int32_t flags; +#define STI_TESTF_WAIT 0x80000000 +#define STI_TESTF_ETST 0x40000000 + void *future; +} *sti_testflags_t; + +typedef struct sti_testin { + void *future; +} *sti_testin_t; + +typedef struct sti_testout { + u_int32_t errno; + u_int32_t result; + void *future; +} *sti_testout_t; + +STI_DEP(test); + +typedef struct sti_exhdlflags { + u_int32_t flags; +#define STI_EXHDLF_WAIT 0x80000000 +#define STI_EXHDLF_CINT 0x40000000 /* clear int */ +#define STI_EXHDLF_CBE 0x20000000 /* clear BE */ +#define STI_EXHDLF_PINT 0x10000000 /* preserve int */ +#define STI_EXHDLF_RINT 0x08000000 /* restore int */ +#define STI_EXHDLF_WEIM 0x04000000 /* write eim w/ sti_eexhdlin */ +#define STI_EXHDLF_REIM 0x02000000 /* read eim to sti_eexhdlout */ +#define STI_EXHDLF_GIE 0x01000000 /* global int enable */ +#define STI_EXHDLF_PGIE 0x00800000 +#define STI_EXHDLF_WIEM 0x00400000 +#define STI_EXHDLF_EIEM 0x00200000 +#define STI_EXHDLF_BIC 0x00100000 /* begin int cycle */ +#define STI_EXHDLF_EIC 0x00080000 /* end int cycle */ +#define STI_EXHDLF_RIE 0x00040000 /* reset do not clear int enables */ + void *future; +} *sti_exhdlflags_t; + +typedef struct sti_eexhdlin { + u_int32_t eim_addr; + u_int32_t eim_data; + u_int32_t iem; /* enable mask */ + u_int32_t icm; /* clear mask */ + void *future; +} *sti_eexhdlin_t; + +typedef struct sti_exhdlint { + u_int32_t flags; +#define STI_EXHDLINT_BET 0x80000000 /* bus error timer */ +#define STI_EXHDLINT_HW 0x40000000 /* high water */ +#define STI_EXHDLINT_LW 0x20000000 /* low water */ +#define STI_EXHDLINT_TM 0x10000000 /* texture map */ +#define STI_EXHDLINT_VB 0x08000000 /* vertical blank */ +#define STI_EXHDLINT_UDC 0x04000000 /* unbuffered dma complete */ +#define STI_EXHDLINT_BDC 0x02000000 /* buffered dma complete */ +#define STI_EXHDLINT_UDPC 0x01000000 /* unbuf priv dma complete */ +#define STI_EXHDLINT_BDPC 0x00800000 /* buffered priv dma complete */ +} *sti_exhdlint_t; + +typedef struct sti_exhdlin { + sti_exhdlint_t addr; + sti_eexhdlin_t ext; +} *sti_exhdlin_t; + +typedef struct sti_eexhdlout { + u_int32_t eim_addr; + u_int32_t eim_data; + u_int32_t iem; /* enable mask */ + u_int32_t icm; /* clear mask */ + void *future; +} *sti_eexhdlout_t; + +typedef struct sti_exhdlout { + u_int32_t errno; + u_int32_t flags; +#define STI_EXHDLO_BE 0x80000000 /* BE was intercepted */ +#define STI_EXHDLO_IP 0x40000000 /* there is int pending */ +#define STI_EXHDLO_IE 0x20000000 /* global enable set */ + sti_eexhdlout_t ext; +} *sti_exhdlout_t; + +STI_DEP(exhdl); + +typedef struct sti_inqconfflags { + u_int32_t flags; +#define STI_INQCONFF_WAIT 0x80000000 + void *future; +} *sti_inqconfflags_t; + +typedef struct sti_inqconfin { + void *future; +} *sti_inqconfin_t; + +typedef struct sti_einqconfout { + u_int32_t crt_config[3]; + u_int32_t crt_hw[3]; + void *future; +} *sti_einqconfout_t; + +typedef struct sti_inqconfout { + u_int32_t errno; + u_int16_t width, height, owidth, oheight, fbwidth, fbheight; + u_int32_t bpp; /* bits per pixel */ + u_int32_t bppu; /* accessible bpp */ + u_int32_t planes; + u_int8_t name[STI_DEVNAME_LEN]; + u_int32_t attributes; + sti_einqconfout_t ext; +} *sti_inqconfout_t; + +STI_DEP(inqconf); + +typedef struct sti_scmentflags { + u_int32_t flags; +#define STI_SCMENTF_WAIT 0x80000000 + void *future; +} *sti_scmentflags_t; + +typedef struct sti_scmentin { + u_int32_t entry; + u_int32_t value; + void *future; +} *sti_scmentin_t; + +typedef struct sti_scmentout { + u_int32_t errno; + void *future; +} *sti_scmentout_t; + +STI_DEP(scment); + +typedef struct sti_dmacflags { + u_int32_t flags; +#define STI_DMACF_WAIT 0x80000000 +#define STI_DMACF_PRIV 0x40000000 /* priv dma */ +#define STI_DMACF_DIS 0x20000000 /* disable */ +#define STI_DMACF_BUF 0x10000000 /* buffered */ +#define STI_DMACF_MRK 0x08000000 /* write a marker */ +#define STI_DMACF_ABRT 0x04000000 /* abort dma xfer */ + void *future; +} *sti_dmacflags_t; + +typedef struct sti_dmacin { + u_int32_t pa_upper; + u_int32_t pa_lower; + u_int32_t len; + u_int32_t mrk_data; + u_int32_t mrk_off; + void *future; +} *sti_dmacin_t; + +typedef struct sti_dmacout { + u_int32_t errno; + void *future; +} *sti_dmacout_t; + +STI_DEP(dmac); + +typedef struct sti_flowcflags { + u_int32_t flags; +#define STI_FLOWCF_WAIT 0x80000000 +#define STI_FLOWCF_CHW 0x40000000 /* check high water */ +#define STI_FLOWCF_WHW 0x20000000 /* write high water */ +#define STI_FLOWCF_WLW 0x10000000 /* write low water */ +#define STI_FLOWCF_PCSE 0x08000000 /* preserve cse */ +#define STI_FLOWCF_CSE 0x04000000 +#define STI_FLOWCF_CSWF 0x02000000 /* cs write fine */ +#define STI_FLOWCF_CSWC 0x01000000 /* cs write coarse */ +#define STI_FLOWCF_CSWQ 0x00800000 /* cs write fifo */ + void *future; +} *sti_flowcflags_t; + +typedef struct sti_flowcin { + u_int32_t retry; + u_int32_t bufz; + u_int32_t hwcnt; + u_int32_t lwcnt; + u_int32_t csfv; /* cs fine value */ + u_int32_t cscv; /* cs coarse value */ + u_int32_t csqc; /* cs fifo count */ + void *future; +} *sti_flowcin_t; + +typedef struct sti_flowcout { + u_int32_t errno; + u_int32_t retry_result; + u_int32_t fifo_size; + void *future; +} *sti_flowcout_t; + +STI_DEP(flowc); + +typedef struct sti_utimingflags { + u_int32_t flags; +#define STI_UTIMF_WAIT 0x80000000 +#define STI_UTIMF_HKS 0x40000000 /* has kbuf_size */ + void *future; +} *sti_utimingflags_t; + +typedef struct sti_utimingin { + void *data; + void *kbuf; + void *future; +} *sti_utimingin_t; + +typedef struct sti_utimingout { + u_int32_t errno; + u_int32_t kbuf_size; /* buffer required size */ + void *future; +} *sti_utimingout_t; + +STI_DEP(utiming); + +typedef struct sti_pmgrflags { + u_int32_t flags; +#define STI_UTIMF_WAIT 0x80000000 +#define STI_UTIMOP_CLEANUP 0x00000000 +#define STI_UTIMOP_BAC 0x10000000 +#define STI_UTIMF_CRIT 0x04000000 +#define STI_UTIMF_BUFF 0x02000000 +#define STI_UTIMF_IBUFF 0x01000000 + void *future; +} *sti_pmgrflags_t; + +typedef struct sti_pmgrin { + u_int32_t reserved[4]; + void *future; +} *sti_pmgrin_t; + +typedef struct sti_pmgrout { + int32_t errno; + void *future; +} *sti_pmgrout_t; + +STI_DEP(pmgr); + +typedef struct sti_utilflags { + u_int32_t flags; +#define STI_UTILF_ROOT 0x80000000 /* was called as root */ + void *future; +} *sti_utilflags_t; + +typedef struct sti_utilin { + u_int32_t in_size; + u_int32_t out_size; + u_int8_t *buf; +} *sti_utilin_t; + +typedef struct sti_utilout { + int32_t errno; + void *future; +} *sti_utilout_t; + +STI_DEP(util); + +#pragma pack() + +#endif /* _IC_STIREG_H_ */ --- /dev/null 2003-02-18 22:07:40.000000000 +0900 +++ dev/ic/stivar.h 2003-02-16 16:23:58.000000000 +0900 @@ -0,0 +1,79 @@ +/* $NetBSD$ */ + +/* $OpenBSD: stivar.h,v 1.3 2001/03/20 08:32:20 mickey Exp $ */ + +/* + * Copyright (c) 2000 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IC_STIVAR_H_ +#define _IC_STIVAR_H_ + +/* #define STIDEBUG */ + +struct sti_softc { + struct device sc_dev; + void *sc_ih; + + u_int sc_flags; +#define STI_TEXTMODE 0x0001 +#define STI_CLEARSCR 0x0002 + int sc_devtype; + + bus_space_tag_t iot, memt; + bus_space_handle_t ioh, romh, fbh; + + struct sti_dd sc_dd; /* in word format */ + struct sti_font *sc_fonts; /* in word format */ + struct sti_cfg sc_cfg; + struct sti_ecfg sc_ecfg; + struct sti_fontcfg sc_fontcfg; + + vaddr_t sc_code; + + sti_init_t init; + sti_mgmt_t mgmt; + sti_unpmv_t unpmv; + sti_blkmv_t blkmv; + sti_test_t test; + sti_exhdl_t exhdl; + sti_inqconf_t inqconf; + sti_scment_t scment; + sti_dmac_t dmac; + sti_flowc_t flowc; + sti_utiming_t utiming; + sti_pmgr_t pmgr; + sti_util_t util; +}; + +void sti_attach_common __P((struct sti_softc *sc)); +int sti_intr __P((void *v)); + +#endif /* _IC_STIVAR_H_ */