head 1.1; access; symbols perseant-exfatfs-base-20250801:1.1 perseant-exfatfs-base-20240630:1.1 perseant-exfatfs:1.1.0.140 perseant-exfatfs-base:1.1 bouyer-sunxi-drm:1.1.0.138 bouyer-sunxi-drm-base:1.1 cjep_sun2x:1.1.0.136 cjep_sun2x-base:1.1 cjep_staticlib_x-base1:1.1 cjep_staticlib_x:1.1.0.134 cjep_staticlib_x-base:1.1 thorpej-futex-base:1.1 bouyer-xenpvh-base2:1.1 phil-wifi-20200421:1.1 bouyer-xenpvh-base1:1.1 phil-wifi-20200411:1.1 bouyer-xenpvh:1.1.0.132 bouyer-xenpvh-base:1.1 phil-wifi-20200406:1.1 ad-namecache-base3:1.1 ad-namecache-base2:1.1 ad-namecache-base1:1.1 ad-namecache:1.1.0.130 ad-namecache-base:1.1 isaki-audio2:1.1.0.128 isaki-audio2-base:1.1 pgoyette-compat-merge-20190127:1.1 pgoyette-compat-20190127:1.1 pgoyette-compat-20190118:1.1 pgoyette-compat-1226:1.1 pgoyette-compat-1126:1.1 pgoyette-compat-1020:1.1 pgoyette-compat-0930:1.1 pgoyette-compat-0906:1.1 pgoyette-compat-0728:1.1 pgoyette-compat-0625:1.1 pgoyette-compat-0521:1.1 pgoyette-compat-0502:1.1 pgoyette-compat-0422:1.1 pgoyette-compat-0415:1.1 pgoyette-compat-0407:1.1 pgoyette-compat-0330:1.1 pgoyette-compat-0322:1.1 pgoyette-compat-0315:1.1 pgoyette-compat:1.1.0.10 pgoyette-compat-base:1.1 perseant-stdc-iso10646:1.1.0.126 perseant-stdc-iso10646-base:1.1 prg-localcount2-base3:1.1 prg-localcount2-base2:1.1 prg-localcount2-base1:1.1 prg-localcount2:1.1.0.124 prg-localcount2-base:1.1 pgoyette-localcount-20170426:1.1 bouyer-socketcan-base1:1.1 pgoyette-localcount-20170320:1.1 bouyer-socketcan:1.1.0.122 bouyer-socketcan-base:1.1 pgoyette-localcount-20170107:1.1 pgoyette-localcount-20161104:1.1 localcount-20160914:1.1 pgoyette-localcount-20160806:1.1 pgoyette-localcount-20160726:1.1 pgoyette-localcount:1.1.0.120 pgoyette-localcount-base:1.1 netbsd-5-2-3-RELEASE:1.1 netbsd-5-1-5-RELEASE:1.1 yamt-pagecache-base9:1.1 yamt-pagecache-tag8:1.1 tls-earlyentropy:1.1.0.118 tls-earlyentropy-base:1.1 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1 riastradh-drm2-base3:1.1 netbsd-5-2-2-RELEASE:1.1 netbsd-5-1-4-RELEASE:1.1 netbsd-5-2-1-RELEASE:1.1 netbsd-5-1-3-RELEASE:1.1 rmind-smpnet-nbase:1.1 rmind-smpnet:1.1.0.114 rmind-smpnet-base:1.1 agc-symver:1.1.0.116 agc-symver-base:1.1 tls-maxphys-base:1.1 yamt-pagecache-base8:1.1 netbsd-5-2:1.1.0.112 yamt-pagecache-base7:1.1 netbsd-5-2-RELEASE:1.1 netbsd-5-2-RC1:1.1 yamt-pagecache-base6:1.1 yamt-pagecache-base5:1.1 yamt-pagecache-base4:1.1 netbsd-5-1-2-RELEASE:1.1 netbsd-5-1-1-RELEASE:1.1 jmcneill-usbmp:1.1.0.110 jmcneill-usbmp-base:1.1 jmcneill-audiomp3:1.1.0.108 jmcneill-audiomp3-base:1.1 yamt-pagecache-base3:1.1 yamt-pagecache-base2:1.1 yamt-pagecache:1.1.0.106 yamt-pagecache-base:1.1 rmind-uvmplock-nbase:1.1 bouyer-quota2-nbase:1.1 bouyer-quota2:1.1.0.104 bouyer-quota2-base:1.1 jruoho-x86intr:1.1.0.102 jruoho-x86intr-base:1.1 matt-nb5-pq3:1.1.0.100 matt-nb5-pq3-base:1.1 netbsd-5-1:1.1.0.98 netbsd-5-1-RELEASE:1.1 yamt-nfs-mp-base11:1.1 netbsd-5-1-RC4:1.1 uebayasi-xip-base2:1.1 yamt-nfs-mp-base10:1.1 netbsd-5-1-RC3:1.1 netbsd-5-1-RC2:1.1 netbsd-5-1-RC1:1.1 rmind-uvmplock:1.1.0.96 rmind-uvmplock-base:1.1 yamt-nfs-mp-base9:1.1 uebayasi-xip:1.1.0.94 uebayasi-xip-base:1.1 netbsd-5-0-2-RELEASE:1.1 yamt-nfs-mp-base8:1.1 yamt-nfs-mp-base7:1.1 netbsd-5-0-1-RELEASE:1.1 jymxensuspend-base:1.1 yamt-nfs-mp-base6:1.1 yamt-nfs-mp-base5:1.1 yamt-nfs-mp-base4:1.1 jym-xensuspend-nbase:1.1 yamt-nfs-mp-base3:1.1 netbsd-5-0:1.1.0.92 netbsd-5-0-RELEASE:1.1 netbsd-5-0-RC4:1.1 netbsd-5-0-RC3:1.1 netbsd-5-0-RC2:1.1 jym-xensuspend:1.1.0.90 jym-xensuspend-base:1.1 netbsd-5-0-RC1:1.1 haad-dm-base2:1.1 haad-nbase2:1.1 ad-audiomp2:1.1.0.88 ad-audiomp2-base:1.1 netbsd-5:1.1.0.86 netbsd-5-base:1.1 haad-dm-base1:1.1 haad-dm:1.1.0.84 haad-dm-base:1.1 simonb-wapbl-nbase:1.1 yamt-pf42-base4:1.1 simonb-wapbl:1.1.0.82 simonb-wapbl-base:1.1 yamt-pf42-base3:1.1 hpcarm-cleanup-nbase:1.1 yamt-pf42-base2:1.1 yamt-nfs-mp-base2:1.1 yamt-nfs-mp:1.1.0.80 yamt-nfs-mp-base:1.1 yamt-pf42:1.1.0.78 yamt-pf42-base:1.1 ad-socklock-base1:1.1 yamt-lazymbuf-base15:1.1 yamt-lazymbuf-base14:1.1 keiichi-mipv6-nbase:1.1 mjf-devfs2:1.1.0.76 mjf-devfs2-base:1.1 keiichi-mipv6:1.1.0.74 keiichi-mipv6-base:1.1 bouyer-xeni386-merge1:1.1 vmlocking2-base3:1.1 bouyer-xeni386-nbase:1.1 yamt-kmem-base3:1.1 cube-autoconf:1.1.0.72 cube-autoconf-base:1.1 yamt-kmem-base2:1.1 bouyer-xeni386:1.1.0.70 bouyer-xeni386-base:1.1 yamt-kmem:1.1.0.68 yamt-kmem-base:1.1 vmlocking2-base2:1.1 reinoud-bufcleanup-nbase:1.1 vmlocking2:1.1.0.66 vmlocking2-base1:1.1 jmcneill-base:1.1 mjf-devfs:1.1.0.64 mjf-devfs-base:1.1 bouyer-xenamd64-base2:1.1 vmlocking-nbase:1.1 yamt-x86pmap-base4:1.1 bouyer-xenamd64:1.1.0.62 bouyer-xenamd64-base:1.1 yamt-x86pmap-base3:1.1 yamt-x86pmap-base2:1.1 yamt-x86pmap:1.1.0.60 yamt-x86pmap-base:1.1 jmcneill-pm:1.1.0.58 jmcneill-pm-base:1.1 hpcarm-cleanup:1.1.0.56 hpcarm-cleanup-base:1.1 mjf-ufs-trans-base:1.1 yamt-idlelwp-base8:1.1 reinoud-bufcleanup-base:1.1 vmlocking:1.1.0.54 vmlocking-base:1.1 ad-audiomp:1.1.0.52 ad-audiomp-base:1.1 yamt-idlelwp:1.1.0.50 post-newlock2-merge:1.1 newlock2-nbase:1.1 yamt-splraiseipl-base5:1.1 yamt-splraiseipl-base4:1.1 yamt-splraiseipl-base3:1.1 yamt-splraiseipl-base2:1.1 yamt-splraiseipl:1.1.0.48 yamt-splraiseipl-base:1.1 newlock2:1.1.0.46 newlock2-base:1.1 yamt-pdpolicy-base8:1.1 yamt-pdpolicy-base7:1.1 yamt-pdpolicy-base6:1.1 gdamore-uart:1.1.0.44 gdamore-uart-base:1.1 simonb-timcounters-final:1.1 yamt-pdpolicy-base5:1.1 elad-kernelauth-nbase:1.1 yamt-pdpolicy-base4:1.1 yamt-pdpolicy-base3:1.1 yamt-pdpolicy-base2:1.1 yamt-pdpolicy:1.1.0.42 yamt-pdpolicy-base:1.1 yamt-uio_vmspace-base5:1.1 simonb-timecounters:1.1.0.40 simonb-timecounters-base:1.1 rpaulo-netinet-merge-pcb:1.1.0.38 rpaulo-netinet-merge-pcb-base:1.1 yamt-uio_vmspace:1.1.0.36 yamt-readahead-base3:1.1 yamt-readahead-base2:1.1 yamt-readahead:1.1.0.34 yamt-readahead-base:1.1 yamt-vop-base3:1.1 yamt-vop-base2:1.1 thorpej-vnode-attr:1.1.0.32 thorpej-vnode-attr-base:1.1 yamt-vop:1.1.0.30 yamt-vop-base:1.1 yamt-lazymbuf:1.1.0.28 yamt-km-base4:1.1 yamt-km-base3:1.1 yamt-km-base2:1.1 yamt-km:1.1.0.26 yamt-km-base:1.1 kent-audio2:1.1.0.24 kent-audio2-base:1.1 ktrace-lwp:1.1.0.22 ktrace-lwp-base:1.1 nathanw_sa_before_merge:1.1 gmcgarry_ctxsw:1.1.0.20 gmcgarry_ctxsw_base:1.1 gmcgarry_ucred:1.1.0.18 gmcgarry_ucred_base:1.1 nathanw_sa_base:1.1 gehenna-devsw:1.1.0.16 gehenna-devsw-base:1.1 eeh-devprop:1.1.0.14 eeh-devprop-base:1.1 newlock:1.1.0.12 newlock-base:1.1 ifpoll-base:1.1 thorpej-mips-cache:1.1.0.8 thorpej-mips-cache-base:1.1 thorpej-devvp:1.1.0.6 thorpej-devvp-base:1.1 kqueue:1.1.0.4 kqueue-base:1.1 thorpej_scsipi_beforemerge:1.1 thorpej_scsipi_nbase:1.1 thorpej_scsipi_base:1.1 thorpej_scsipi:1.1.0.2; locks; strict; comment @# @; 1.1 date 2000.11.20.11.41.23; author bouyer; state dead; branches 1.1.2.1; next ; 1.1.2.1 date 2000.11.20.11.41.23; author bouyer; state Exp; branches; next 1.1.2.2; 1.1.2.2 date 2000.11.20.18.03.33; author bouyer; state dead; branches; next ; desc @@ 1.1 log @file wds.c.rej was initially added on branch thorpej_scsipi. @ text @@ 1.1.2.1 log @Update thorpej_scsipi to -current as of a month ago A i386 GENERIC kernel compiles without the siop, ahc and bha drivers (will be updated later). i386 IDE/ATAPI and ncr work, as well as sparc/esp_sbus. alpha should work as well (untested yet). siop, ahc and bha will be updated once I've updated the branch to current -current, as well as machine-dependant code. @ text @a0 498 *************** *** 662,708 **** * the hash table too otherwise either return an error or sleep. */ struct wds_scb * - wds_get_scb(sc, flags) struct wds_softc *sc; - int flags; { struct wds_scb *scb; int s; s = splbio(); - - /* - * If we can and have to, sleep waiting for one to come free - * but only if we can't allocate a new one. - */ - for (;;) { - scb = sc->sc_free_scb.tqh_first; - if (scb) { - TAILQ_REMOVE(&sc->sc_free_scb, scb, chain); - break; - } - if (sc->sc_numscbs < WDS_SCB_MAX) { - /* - * wds_create_scbs() might have managed to create - * one before it failed. If so, don't abort, - * just grab it and continue to hobble along. - */ - if (wds_create_scbs(sc, NULL, 0) != 0 && - sc->sc_free_scb.tqh_first == NULL) { - printf(": can't allocate scbs\n", - sc->sc_dev.dv_xname); - goto out; - } - continue; - } - if ((flags & XS_CTL_NOSLEEP) != 0) - goto out; - tsleep(&sc->sc_free_scb, PRIBIO, "wdsscb", 0); } - - scb->flags |= SCB_ALLOC; - - out: splx(s); return (scb); } --- 649,666 ---- * the hash table too otherwise either return an error or sleep. */ struct wds_scb * + wds_get_scb(sc) struct wds_softc *sc; { struct wds_scb *scb; int s; s = splbio(); + scb = TAILQ_FIRST(&sc->sc_free_scb); + if (scb != NULL) { + TAILQ_REMOVE(&sc->sc_free_scb, scb, chain); + scb->flags |= SCB_ALLOC; } splx(s); return (scb); } *************** *** 1164,1388 **** /* * Send a SCSI command. */ - int - wds_scsi_cmd(xs) - struct scsipi_xfer *xs; { - struct scsipi_link *sc_link = xs->sc_link; - struct wds_softc *sc = sc_link->adapter_softc; bus_dma_tag_t dmat = sc->sc_dmat; struct wds_scb *scb; struct wds_scat_gath *sg; int error, seg, flags, s; - int fromqueue = 0, dontqueue = 0; - #ifdef TFS - struct iovec *iovp; - #endif - - if (xs->xs_control & XS_CTL_RESET) { - /* XXX Fix me! */ - printf(": reset!\n", sc->sc_dev.dv_xname); - wds_init(sc, 1); - return COMPLETE; - } - s = splbio(); /* protect the queue */ - - /* - * If we're running the queue from wds_done(), we've been - * called with the first queue entry as our argument. - */ - if (xs == TAILQ_FIRST(&sc->sc_queue)) { - TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q); - fromqueue = 1; - goto get_scb; - } - - /* Polled requests can't be queued for later. */ - dontqueue = xs->xs_control & XS_CTL_POLL; - /* - * If there are jobs in the queue, run them first. - */ - if (TAILQ_FIRST(&sc->sc_queue) != NULL) { - /* - * If we can't queue, we have to abort, since - * we have to preserve order. - */ - if (dontqueue) { - splx(s); xs->error = XS_DRIVER_STUFFUP; - return (TRY_AGAIN_LATER); } - /* - * Swap with the first queue entry. - */ - TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q); - xs = TAILQ_FIRST(&sc->sc_queue); - TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q); - fromqueue = 1; - } - get_scb: - flags = xs->xs_control; - if ((scb = wds_get_scb(sc, flags)) == NULL) { /* - * If we can't queue, we lose. */ - if (dontqueue) { - splx(s); - xs->error = XS_DRIVER_STUFFUP; - return (TRY_AGAIN_LATER); } - - /* - * Stuff ourselves into the queue, in front - * if we came off in the first place. - */ - if (fromqueue) - TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q); - else - TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q); - splx(s); - return (SUCCESSFULLY_QUEUED); - } - - splx(s); /* done playing with the queue */ - scb->xs = xs; - scb->timeout = xs->timeout; - if (xs->xs_control & XS_CTL_DATA_UIO) { - /* XXX Fix me! */ - /* Let's not worry about UIO. There isn't any code for the * - * non-SG boards anyway! */ - printf(": UIO is untested and disabled!\n", - sc->sc_dev.dv_xname); - goto bad; - } - /* Zero out the command structure. */ - bzero(&scb->cmd, sizeof scb->cmd); - bcopy(xs->cmd, &scb->cmd.scb, xs->cmdlen < 12 ? xs->cmdlen : 12); - - /* Set up some of the command fields. */ - scb->cmd.targ = (xs->sc_link->scsipi_scsi.target << 5) | - xs->sc_link->scsipi_scsi.lun; - - /* NOTE: cmd.write may be OK as 0x40 (disable direction checking) - * on boards other than the WD-7000V-ASE. Need this for the ASE: - */ - scb->cmd.write = (xs->xs_control & XS_CTL_DATA_IN) ? 0x80 : 0x00; - if (xs->datalen) { - sg = scb->scat_gath; - seg = 0; #ifdef TFS - if (flags & XS_CTL_DATA_UIO) { - error = bus_Dmamap_load_uio(dmat, - scb->dmamap_xfer, (struct uio *)xs->data, - (flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : - BUS_DMA_WAITOK); - } else #endif /* TFS */ - { - error = bus_dmamap_load(dmat, - scb->dmamap_xfer, xs->data, xs->datalen, NULL, - (flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : - BUS_DMA_WAITOK); - } - if (error) { - if (error == EFBIG) { - printf(": wds_scsi_cmd, more than 0" - " dma segments\n", - sc->sc_dev.dv_xname, sc->sc_maxsegs); - } else { - printf(": wds_scsi_cmd, error 0 loading" - " dma map\n", sc->sc_dev.dv_xname, error); } - goto bad; - } - bus_dmamap_sync(dmat, scb->dmamap_xfer, 0, - scb->dmamap_xfer->dm_mapsize, - (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD : - BUS_DMASYNC_PREWRITE); - if (sc->sc_maxsegs > 1) { - /* - * Load the hardware scatter/gather map with the - * contents of the DMA map. - */ - for (seg = 0; seg < scb->dmamap_xfer->dm_nsegs; - seg++) { ltophys(scb->dmamap_xfer->dm_segs[seg].ds_addr, - scb->scat_gath[seg].seg_addr); ltophys(scb->dmamap_xfer->dm_segs[seg].ds_len, - scb->scat_gath[seg].seg_len); } - /* - * Set up for scatter/gather transfer. - */ - scb->cmd.opcode = WDSX_SCSISG; - ltophys(scb->dmamap_self->dm_segs[0].ds_addr + - offsetof(struct wds_scb, scat_gath), - scb->cmd.data); - ltophys(scb->dmamap_self->dm_nsegs * - sizeof(struct wds_scat_gath), scb->cmd.len); } else { /* - * This board is an ASC or an ASE, and the - * transfer has been mapped contig for us. */ - scb->cmd.opcode = WDSX_SCSICMD; - ltophys(scb->dmamap_xfer->dm_segs[0].ds_addr, - scb->cmd.data); - ltophys(scb->dmamap_xfer->dm_segs[0].ds_len, - scb->cmd.len); } - } else { - scb->cmd.opcode = WDSX_SCSICMD; - ltophys(0, scb->cmd.data); - ltophys(0, scb->cmd.len); - } - scb->cmd.stat = 0x00; - scb->cmd.venderr = 0x00; - ltophys(0, scb->cmd.link); - - /* XXX Do we really want to do this? */ - if (flags & XS_CTL_POLL) { - /* Will poll card, await result. */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, WDSH_DRQEN); - scb->flags |= SCB_POLLED; - } else { - /* Will send command, let interrupt routine handle result. */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, - WDSH_IRQEN | WDSH_DRQEN); - } - - s = splbio(); - wds_queue_scb(sc, scb); - splx(s); - if ((flags & XS_CTL_POLL) == 0) - return SUCCESSFULLY_QUEUED; - if (wds_poll(sc, xs, scb->timeout)) { - wds_timeout(scb); - if (wds_poll(sc, xs, scb->timeout)) wds_timeout(scb); - } - return COMPLETE; - bad: - xs->error = XS_DRIVER_STUFFUP; - wds_free_scb(sc, scb); - return COMPLETE; } /* --- 1110,1311 ---- /* * Send a SCSI command. */ + void + wds_scsipi_request(chan, req, arg) + struct scsipi_channel *chan; + scsipi_adapter_req_t req; + void *arg; { + struct scsipi_xfer *xs; + struct scsipi_periph *periph; + struct wds_softc *sc = (void *)chan->chan_adapter->adapt_dev; bus_dma_tag_t dmat = sc->sc_dmat; struct wds_scb *scb; struct wds_scat_gath *sg; int error, seg, flags, s; + switch (req) { + case ADAPTER_REQ_RUN_XFER: + xs = arg; + periph = xs->xs_periph; + + if (xs->xs_control & XS_CTL_RESET) { + /* XXX Fix me! */ + printf(": reset!\n", sc->sc_dev.dv_xname); + wds_init(sc, 1); + scsipi_done(xs); + return; + } + if (xs->xs_control & XS_CTL_DATA_UIO) { + /* XXX Fix me! */ + /* + * Let's not worry about UIO. There isn't any code + * for the non-SG boards anyway! + */ + printf(": UIO is untested and disabled!\n", + sc->sc_dev.dv_xname); xs->error = XS_DRIVER_STUFFUP; + scsipi_done(xs); + return; } + flags = xs->xs_control; + /* Get an SCB to use. */ + scb = wds_get_scb(sc); + #ifdef DIAGNOSTIC /* + * This should never happen as we track the resources + * in the mid-layer. */ + if (scb == NULL) { + scsipi_printaddr(periph); + printf("unable to allocate scb\n"); + panic("wds_scsipi_request"); } + #endif + scb->xs = xs; + scb->timeout = xs->timeout; + /* Zero out the command structure. */ + bzero(&scb->cmd, sizeof scb->cmd); + bcopy(xs->cmd, &scb->cmd.scb, + xs->cmdlen < 12 ? xs->cmdlen : 12); + + /* Set up some of the command fields. */ + scb->cmd.targ = (periph->periph_target << 5) | + periph->periph_lun; + /* + * NOTE: cmd.write may be OK as 0x40 (disable direction + * checking) on boards other than the WD-7000V-ASE. Need + * this for the ASE: + */ + scb->cmd.write = (xs->xs_control & XS_CTL_DATA_IN) ? + 0x80 : 0x00; + if (xs->datalen) { + sg = scb->scat_gath; + seg = 0; #ifdef TFS + if (flags & XS_CTL_DATA_UIO) { + error = bus_dmamap_load_uio(dmat, + scb->dmamap_xfer, (struct uio *)xs->data, + BUS_DMA_NOWAIT); + } else #endif /* TFS */ + { + error = bus_dmamap_load(dmat, + scb->dmamap_xfer, xs->data, xs->datalen, + NULL, BUS_DMA_NOWAIT); + } + switch (error) { + case 0: + break; + + case ENOMEM: + case EAGAIN: + xs->error = XS_RESOURCE_SHORTAGE; + goto out_bad; + + default: + xs->error = XS_DRIVER_STUFFUP; + printf(": error 0 loading DMA map\n", sc->sc_dev.dv_xname, error); + out_bad: + wds_free_scb(sc, scb); + scsipi_done(xs); + return; } + bus_dmamap_sync(dmat, scb->dmamap_xfer, 0, + scb->dmamap_xfer->dm_mapsize, + (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD : + BUS_DMASYNC_PREWRITE); + if (sc->sc_maxsegs > 1) { + /* + * Load the hardware scatter/gather map with the + * contents of the DMA map. + */ + for (seg = 0; + seg < scb->dmamap_xfer->dm_nsegs; seg++) { ltophys(scb->dmamap_xfer->dm_segs[seg].ds_addr, + scb->scat_gath[seg].seg_addr); ltophys(scb->dmamap_xfer->dm_segs[seg].ds_len, + scb->scat_gath[seg].seg_len); + } + + /* + * Set up for scatter/gather transfer. + */ + scb->cmd.opcode = WDSX_SCSISG; + ltophys(scb->dmamap_self->dm_segs[0].ds_addr + + offsetof(struct wds_scb, scat_gath), + scb->cmd.data); + ltophys(scb->dmamap_self->dm_nsegs * + sizeof(struct wds_scat_gath), scb->cmd.len); + } else { + /* + * This board is an ASC or an ASE, and the + * transfer has been mapped contig for us. + */ + scb->cmd.opcode = WDSX_SCSICMD; + ltophys(scb->dmamap_xfer->dm_segs[0].ds_addr, + scb->cmd.data); + ltophys(scb->dmamap_xfer->dm_segs[0].ds_len, + scb->cmd.len); } + } else { + scb->cmd.opcode = WDSX_SCSICMD; + ltophys(0, scb->cmd.data); + ltophys(0, scb->cmd.len); + } + scb->cmd.stat = 0x00; + scb->cmd.venderr = 0x00; + ltophys(0, scb->cmd.link); + + /* XXX Do we really want to do this? */ + if (flags & XS_CTL_POLL) { + /* Will poll card, await result. */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, + WDS_HCR, WDSH_DRQEN); + scb->flags |= SCB_POLLED; } else { /* + * Will send command, let interrupt routine + * handle result. */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, + WDSH_IRQEN | WDSH_DRQEN); } + s = splbio(); + wds_queue_scb(sc, scb); + splx(s); + if ((flags & XS_CTL_POLL) == 0) + return; + if (wds_poll(sc, xs, scb->timeout)) { wds_timeout(scb); + if (wds_poll(sc, xs, scb->timeout)) + wds_timeout(scb); + } + return; + case ADAPTER_REQ_GROW_RESOURCES: + /* XXX Not supported. */ + return; + + case ADAPTER_REQ_SET_XFER_MODE: + /* XXX How do we do this? */ + return; + } } /* @ 1.1.2.2 log @Remove files that should not have been added @ text @@