Home | History | Annotate | Line # | Download | only in ic
ciss.c revision 1.1
      1 /*	$NetBSD: ciss.c,v 1.1 2006/03/21 20:42:14 he Exp $	*/
      2 /*	$OpenBSD: ciss.c,v 1.13 2006/02/02 22:13:04 brad Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 2005 Michael Shalayeff
      6  * All rights reserved.
      7  *
      8  * Permission to use, copy, modify, and distribute this software for any
      9  * purpose with or without fee is hereby granted, provided that the above
     10  * copyright notice and this permission notice appear in all copies.
     11  *
     12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     16  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
     17  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     18  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     19  */
     20 
     21 #include <sys/cdefs.h>
     22 __KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.1 2006/03/21 20:42:14 he Exp $");
     23 
     24 /* #define CISS_DEBUG */
     25 
     26 #include <sys/param.h>
     27 #include <sys/systm.h>
     28 #include <sys/buf.h>
     29 #include <sys/ioctl.h>
     30 #include <sys/device.h>
     31 #include <sys/kernel.h>
     32 #include <sys/malloc.h>
     33 #include <sys/proc.h>
     34 #include <sys/kthread.h>
     35 
     36 #include <uvm/uvm_extern.h>
     37 
     38 #include <machine/bus.h>
     39 
     40 #include <dev/scsipi/scsi_all.h>
     41 #include <dev/scsipi/scsi_disk.h>
     42 #include <dev/scsipi/scsiconf.h>
     43 
     44 #include <dev/ic/cissreg.h>
     45 #include <dev/ic/cissvar.h>
     46 
     47 #ifdef CISS_DEBUG
     48 #define	CISS_DPRINTF(m,a)	if (ciss_debug & (m)) printf a
     49 #define	CISS_D_CMD	0x0001
     50 #define	CISS_D_INTR	0x0002
     51 #define	CISS_D_MISC	0x0004
     52 #define	CISS_D_DMA	0x0008
     53 #define	CISS_D_IOCTL	0x0010
     54 #define	CISS_D_ERR	0x0020
     55 int ciss_debug = 0
     56 	| CISS_D_CMD
     57 	| CISS_D_INTR
     58 	| CISS_D_MISC
     59 	| CISS_D_DMA
     60 	| CISS_D_IOCTL
     61 	| CISS_D_ERR
     62 	;
     63 #else
     64 #define	CISS_DPRINTF(m,a)	/* m, a */
     65 #endif
     66 
     67 static void	ciss_scsi_cmd(struct scsipi_channel *chan,
     68 			scsipi_adapter_req_t req, void *arg);
     69 static int	ciss_scsi_ioctl(struct scsipi_channel *chan, u_long cmd,
     70 	    caddr_t addr, int flag, struct proc *p);
     71 static void	cissminphys(struct buf *bp);
     72 
     73 #if 0
     74 static void	ciss_scsi_raw_cmd(struct scsipi_channel *chan,
     75 			scsipi_adapter_req_t req, void *arg);
     76 #endif
     77 
     78 #if NBIO > 0
     79 static int	ciss_ioctl(struct device *, u_long, caddr_t);
     80 #endif
     81 static int	ciss_sync(struct ciss_softc *sc);
     82 static void	ciss_heartbeat(void *v);
     83 static void	ciss_shutdown(void *v);
     84 #if 0
     85 static void	ciss_kthread(void *v);
     86 #endif
     87 
     88 static struct ciss_ccb *ciss_get_ccb(struct ciss_softc *sc);
     89 static void	ciss_put_ccb(struct ciss_ccb *ccb);
     90 static int	ciss_cmd(struct ciss_ccb *ccb, int flags, int wait);
     91 static int	ciss_done(struct ciss_ccb *ccb);
     92 static int	ciss_error(struct ciss_ccb *ccb);
     93 static int	ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq);
     94 static int	ciss_ldmap(struct ciss_softc *sc);
     95 
     96 static struct ciss_ccb *
     97 ciss_get_ccb(struct ciss_softc *sc)
     98 {
     99 	struct ciss_ccb *ccb;
    100 
    101 	if ((ccb = TAILQ_LAST(&sc->sc_free_ccb, ciss_queue_head))) {
    102 		TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_link);
    103 		ccb->ccb_state = CISS_CCB_READY;
    104 	}
    105 	return ccb;
    106 }
    107 
    108 static void
    109 ciss_put_ccb(struct ciss_ccb *ccb)
    110 {
    111 	struct ciss_softc *sc = ccb->ccb_sc;
    112 
    113 	ccb->ccb_state = CISS_CCB_FREE;
    114 	TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link);
    115 }
    116 
    117 int
    118 ciss_attach(struct ciss_softc *sc)
    119 {
    120 	struct ciss_ccb *ccb;
    121 	struct ciss_cmd *cmd;
    122 	struct ciss_inquiry *inq;
    123 	bus_dma_segment_t seg[1];
    124 	int error, i, total, rseg, maxfer;
    125 	ciss_lock_t lock;
    126 	paddr_t pa;
    127 
    128 	bus_space_read_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff,
    129 	    (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4);
    130 
    131 	if (sc->cfg.signature != CISS_SIGNATURE) {
    132 		printf(": bad sign 0x%08x\n", sc->cfg.signature);
    133 		return -1;
    134 	}
    135 
    136 	if (!(sc->cfg.methods & CISS_METH_SIMPL)) {
    137 		printf(": not simple 0x%08x\n", sc->cfg.methods);
    138 		return -1;
    139 	}
    140 
    141 	sc->cfg.rmethod = CISS_METH_SIMPL;
    142 	sc->cfg.paddr_lim = 0;			/* 32bit addrs */
    143 	sc->cfg.int_delay = 0;			/* disable coalescing */
    144 	sc->cfg.int_count = 0;
    145 	strlcpy(sc->cfg.hostname, "HUMPPA", sizeof(sc->cfg.hostname));
    146 	sc->cfg.driverf |= CISS_DRV_PRF;	/* enable prefetch */
    147 	if (!sc->cfg.maxsg)
    148 		sc->cfg.maxsg = MAXPHYS / PAGE_SIZE + 1;
    149 
    150 	bus_space_write_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff,
    151 	    (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4);
    152 	bus_space_barrier(sc->sc_iot, sc->cfg_ioh, sc->cfgoff, sizeof(sc->cfg),
    153 	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
    154 
    155 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IDB, CISS_IDB_CFG);
    156 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, CISS_IDB, 4,
    157 	    BUS_SPACE_BARRIER_WRITE);
    158 	for (i = 1000; i--; DELAY(1000)) {
    159 		/* XXX maybe IDB is really 64bit? - hp dl380 needs this */
    160 		(void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB + 4);
    161 		if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB) & CISS_IDB_CFG))
    162 			break;
    163 		bus_space_barrier(sc->sc_iot, sc->sc_ioh, CISS_IDB, 4,
    164 		    BUS_SPACE_BARRIER_READ);
    165 	}
    166 
    167 	if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB) & CISS_IDB_CFG) {
    168 		printf(": cannot set config\n");
    169 		return -1;
    170 	}
    171 
    172 	bus_space_read_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff,
    173 	    (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4);
    174 
    175 	if (!(sc->cfg.amethod & CISS_METH_SIMPL)) {
    176 		printf(": cannot simplify 0x%08x\n", sc->cfg.amethod);
    177 		return -1;
    178 	}
    179 
    180 	/* i'm ready for you and i hope you're ready for me */
    181 	for (i = 30000; i--; DELAY(1000)) {
    182 		if (bus_space_read_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff +
    183 		    offsetof(struct ciss_config, amethod)) & CISS_METH_READY)
    184 			break;
    185 		bus_space_barrier(sc->sc_iot, sc->cfg_ioh, sc->cfgoff +
    186 		    offsetof(struct ciss_config, amethod), 4,
    187 		    BUS_SPACE_BARRIER_READ);
    188 	}
    189 
    190 	if (!(bus_space_read_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff +
    191 	    offsetof(struct ciss_config, amethod)) & CISS_METH_READY)) {
    192 		printf(": she never came ready for me 0x%08x\n",
    193 		    sc->cfg.amethod);
    194 		return -1;
    195 	}
    196 
    197 	sc->maxcmd = sc->cfg.maxcmd;
    198 	sc->maxsg = sc->cfg.maxsg;
    199 	if (sc->maxsg > MAXPHYS / PAGE_SIZE + 1)
    200 		sc->maxsg = MAXPHYS / PAGE_SIZE + 1;
    201 	i = sizeof(struct ciss_ccb) +
    202 	    sizeof(ccb->ccb_cmd.sgl[0]) * (sc->maxsg - 1);
    203 	for (sc->ccblen = 0x10; sc->ccblen < i; sc->ccblen <<= 1);
    204 
    205 	total = sc->ccblen * sc->maxcmd;
    206 	if ((error = bus_dmamem_alloc(sc->sc_dmat, total, PAGE_SIZE, 0,
    207 	    sc->cmdseg, 1, &rseg, BUS_DMA_NOWAIT))) {
    208 		printf(": cannot allocate CCBs (%d)\n", error);
    209 		return -1;
    210 	}
    211 
    212 	if ((error = bus_dmamem_map(sc->sc_dmat, sc->cmdseg, rseg, total,
    213 	    (caddr_t *)&sc->ccbs, BUS_DMA_NOWAIT))) {
    214 		printf(": cannot map CCBs (%d)\n", error);
    215 		return -1;
    216 	}
    217 	bzero(sc->ccbs, total);
    218 
    219 	if ((error = bus_dmamap_create(sc->sc_dmat, total, 1,
    220 	    total, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->cmdmap))) {
    221 		printf(": cannot create CCBs dmamap (%d)\n", error);
    222 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    223 		return -1;
    224 	}
    225 
    226 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->cmdmap, sc->ccbs, total,
    227 	    NULL, BUS_DMA_NOWAIT))) {
    228 		printf(": cannot load CCBs dmamap (%d)\n", error);
    229 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    230 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    231 		return -1;
    232 	}
    233 
    234 	TAILQ_INIT(&sc->sc_ccbq);
    235 	TAILQ_INIT(&sc->sc_ccbdone);
    236 	TAILQ_INIT(&sc->sc_free_ccb);
    237 
    238 	maxfer = sc->maxsg * PAGE_SIZE;
    239 	for (i = 0; total > 0 && i < sc->maxcmd; i++, total -= sc->ccblen) {
    240 		ccb = (struct ciss_ccb *) (sc->ccbs + i * sc->ccblen);
    241 		cmd = &ccb->ccb_cmd;
    242 		pa = sc->cmdseg[0].ds_addr + i * sc->ccblen;
    243 
    244 		ccb->ccb_sc = sc;
    245 		ccb->ccb_cmdpa = pa + offsetof(struct ciss_ccb, ccb_cmd);
    246 		ccb->ccb_state = CISS_CCB_FREE;
    247 
    248 		cmd->id = htole32(i << 2);
    249 		cmd->id_hi = htole32(0);
    250 		cmd->sgin = sc->maxsg;
    251 		cmd->sglen = htole16((u_int16_t)cmd->sgin);
    252 		cmd->err_len = htole32(sizeof(ccb->ccb_err));
    253 		pa += offsetof(struct ciss_ccb, ccb_err);
    254 		cmd->err_pa = htole64((u_int64_t)pa);
    255 
    256 		if ((error = bus_dmamap_create(sc->sc_dmat, maxfer, sc->maxsg,
    257 		    maxfer, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
    258 		    &ccb->ccb_dmamap)))
    259 			break;
    260 
    261 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link);
    262 	}
    263 
    264 	if (i < sc->maxcmd) {
    265 		printf(": cannot create ccb#%d dmamap (%d)\n", i, error);
    266 		if (i == 0) {
    267 			/* TODO leaking cmd's dmamaps and shitz */
    268 			bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    269 			bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    270 			return -1;
    271 		}
    272 	}
    273 
    274 	if ((error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
    275 	    seg, 1, &rseg, BUS_DMA_NOWAIT))) {
    276 		printf(": cannot allocate scratch buffer (%d)\n", error);
    277 		return -1;
    278 	}
    279 
    280 	if ((error = bus_dmamem_map(sc->sc_dmat, seg, rseg, PAGE_SIZE,
    281 	    (caddr_t *)&sc->scratch, BUS_DMA_NOWAIT))) {
    282 		printf(": cannot map scratch buffer (%d)\n", error);
    283 		return -1;
    284 	}
    285 	bzero(sc->scratch, PAGE_SIZE);
    286 
    287 	lock = CISS_LOCK_SCRATCH(sc);
    288 	inq = sc->scratch;
    289 	if (ciss_inq(sc, inq)) {
    290 		printf(": adapter inquiry failed\n");
    291 		CISS_UNLOCK_SCRATCH(sc, lock);
    292 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    293 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    294 		return -1;
    295 	}
    296 
    297 	if (!(inq->flags & CISS_INQ_BIGMAP)) {
    298 		printf(": big map is not supported, flags=0x%x\n",
    299 		    inq->flags);
    300 		CISS_UNLOCK_SCRATCH(sc, lock);
    301 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    302 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    303 		return -1;
    304 	}
    305 
    306 	sc->maxunits = inq->numld;
    307 	sc->nbus = inq->nscsi_bus;
    308 	sc->ndrives = inq->buswidth;
    309 	printf(": %d LD%s, HW rev %d, FW %4.4s/%4.4s\n",
    310 	    inq->numld, inq->numld == 1? "" : "s",
    311 	    inq->hw_rev, inq->fw_running, inq->fw_stored);
    312 
    313 	CISS_UNLOCK_SCRATCH(sc, lock);
    314 
    315 	callout_init(&sc->sc_hb);
    316 	callout_setfunc(&sc->sc_hb, ciss_heartbeat, sc);
    317 	callout_schedule(&sc->sc_hb, hz * 3);
    318 
    319 	/* map LDs */
    320 	if (ciss_ldmap(sc)) {
    321 		printf("%s: adapter LD map failed\n", sc->sc_dev.dv_xname);
    322 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    323 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    324 		return -1;
    325 	}
    326 
    327 /* TODO scan all physdev */
    328 /* TODO scan all logdev */
    329 
    330 	sc->sc_flush = CISS_FLUSH_ENABLE;
    331 	if (!(sc->sc_sh = shutdownhook_establish(ciss_shutdown, sc))) {
    332 		printf(": unable to establish shutdown hook\n");
    333 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    334 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    335 		return -1;
    336 	}
    337 
    338 #if 0
    339 	if (kthread_create(ciss_kthread, sc, NULL, "%s", sc->sc_dev.dv_xname)) {
    340 		printf(": unable to create kernel thread\n");
    341 		shutdownhook_disestablish(sc->sc_sh);
    342 		bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1);
    343 		bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap);
    344 		return -1;
    345 	}
    346 #endif
    347 
    348 	sc->sc_channel.chan_adapter = &sc->sc_adapter;
    349 	sc->sc_channel.chan_bustype = &scsi_bustype;
    350 	sc->sc_channel.chan_channel = 0;
    351 	sc->sc_channel.chan_ntargets = sc->maxunits;
    352 	sc->sc_channel.chan_nluns = 8;
    353 	sc->sc_channel.chan_openings = sc->maxcmd / (sc->maxunits? sc->maxunits : 1);
    354 	sc->sc_channel.chan_flags = 0;
    355 	sc->sc_channel.chan_id = sc->maxunits;
    356 
    357 	sc->sc_adapter.adapt_dev = (struct device *) sc;
    358 	sc->sc_adapter.adapt_openings = sc->maxcmd / (sc->maxunits? sc->maxunits : 1);
    359 	sc->sc_adapter.adapt_max_periph = sc->maxunits;
    360 	sc->sc_adapter.adapt_request = ciss_scsi_cmd;
    361 	sc->sc_adapter.adapt_minphys = cissminphys;
    362 	sc->sc_adapter.adapt_ioctl = ciss_scsi_ioctl;
    363 	sc->sc_adapter.adapt_nchannels = 1;
    364 	config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
    365 
    366 #if 0
    367 	sc->sc_link_raw.adapter_softc = sc;
    368 	sc->sc_link.openings = sc->maxcmd / (sc->maxunits? sc->maxunits : 1);
    369 	sc->sc_link_raw.adapter = &ciss_raw_switch;
    370 	sc->sc_link_raw.adapter_target = sc->ndrives;
    371 	sc->sc_link_raw.adapter_buswidth = sc->ndrives;
    372 	config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
    373 #endif
    374 
    375 #if NBIO1 > 0
    376 	if (bio_register(&sc->sc_dev, ciss_ioctl) != 0)
    377 		printf("%s: controller registration failed",
    378 		    sc->sc_dev.dv_xname);
    379 #endif
    380 
    381 	return 0;
    382 }
    383 
    384 static void
    385 ciss_shutdown(void *v)
    386 {
    387 	struct ciss_softc *sc = v;
    388 
    389 	sc->sc_flush = CISS_FLUSH_DISABLE;
    390 	/* timeout_del(&sc->sc_hb); */
    391 	ciss_sync(sc);
    392 }
    393 
    394 static void
    395 cissminphys(struct buf *bp)
    396 {
    397 #if 0	/* TOSO */
    398 #define	CISS_MAXFER	(PAGE_SIZE * (sc->maxsg + 1))
    399 	if (bp->b_bcount > CISS_MAXFER)
    400 		bp->b_bcount = CISS_MAXFER;
    401 #endif
    402 	minphys(bp);
    403 }
    404 
    405 /*
    406  * submit a command and optionally wait for completition.
    407  * wait arg abuses XS_CTL_POLL|XS_CTL_NOSLEEP flags to request
    408  * to wait (XS_CTL_POLL) and to allow tsleep() (!XS_CTL_NOSLEEP)
    409  * instead of busy loop waiting
    410  */
    411 static int
    412 ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
    413 {
    414 	struct ciss_softc *sc = ccb->ccb_sc;
    415 	struct ciss_cmd *cmd = &ccb->ccb_cmd;
    416 	struct ciss_ccb *ccb1;
    417 	bus_dmamap_t dmap = ccb->ccb_dmamap;
    418 	u_int32_t id;
    419 	int i, tohz, error = 0;
    420 
    421 	if (ccb->ccb_state != CISS_CCB_READY) {
    422 		printf("%s: ccb %d not ready state=0x%x\n", sc->sc_dev.dv_xname,
    423 		    cmd->id, ccb->ccb_state);
    424 		return (EINVAL);
    425 	}
    426 
    427 	if (ccb->ccb_data) {
    428 		bus_dma_segment_t *sgd;
    429 
    430 		if ((error = bus_dmamap_load(sc->sc_dmat, dmap, ccb->ccb_data,
    431 		    ccb->ccb_len, NULL, flags))) {
    432 			if (error == EFBIG)
    433 				printf("more than %d dma segs\n", sc->maxsg);
    434 			else
    435 				printf("error %d loading dma map\n", error);
    436 			ciss_put_ccb(ccb);
    437 			return (error);
    438 		}
    439 		cmd->sgin = dmap->dm_nsegs;
    440 
    441 		sgd = dmap->dm_segs;
    442 		CISS_DPRINTF(CISS_D_DMA, ("data=%p/%u<0x%lx/%lu",
    443 		    ccb->ccb_data, ccb->ccb_len, sgd->ds_addr, sgd->ds_len));
    444 
    445 		for (i = 0; i < dmap->dm_nsegs; sgd++, i++) {
    446 			cmd->sgl[i].addr_lo = htole32(sgd->ds_addr);
    447 			cmd->sgl[i].addr_hi =
    448 			    htole32((u_int64_t)sgd->ds_addr >> 32);
    449 			cmd->sgl[i].len = htole32(sgd->ds_len);
    450 			cmd->sgl[i].flags = htole32(0);
    451 			if (i)
    452 				CISS_DPRINTF(CISS_D_DMA,
    453 				    (",0x%lx/%lu", sgd->ds_addr, sgd->ds_len));
    454 		}
    455 
    456 		CISS_DPRINTF(CISS_D_DMA, ("> "));
    457 
    458 		bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
    459 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    460 	} else
    461 		cmd->sgin = 0;
    462 	cmd->sglen = htole16((u_int16_t)cmd->sgin);
    463 	bzero(&ccb->ccb_err, sizeof(ccb->ccb_err));
    464 
    465 	bus_dmamap_sync(sc->sc_dmat, sc->cmdmap, 0, sc->cmdmap->dm_mapsize,
    466 	    BUS_DMASYNC_PREWRITE);
    467 
    468 	if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP))
    469 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR,
    470 		    bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) | sc->iem);
    471 
    472 	TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link);
    473 	ccb->ccb_state = CISS_CCB_ONQ;
    474 	CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id));
    475 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ, ccb->ccb_cmdpa);
    476 
    477 	if (wait & XS_CTL_POLL) {
    478 		int etick;
    479 		CISS_DPRINTF(CISS_D_CMD, ("waiting "));
    480 
    481 		i = ccb->ccb_xs? ccb->ccb_xs->timeout : 60000;
    482 		tohz = (i / 1000) * hz + (i % 1000) * (hz / 1000);
    483 		if (tohz == 0)
    484 			tohz = 1;
    485 		for (i *= 100, etick = tick + tohz; i--; ) {
    486 			if (!(wait & XS_CTL_NOSLEEP)) {
    487 				ccb->ccb_state = CISS_CCB_POLL;
    488 				CISS_DPRINTF(CISS_D_CMD, ("tsleep(%d) ", tohz));
    489 				if (tsleep(ccb, PRIBIO + 1, "ciss_cmd",
    490 				    tohz) == EWOULDBLOCK) {
    491 					break;
    492 				}
    493 				if (ccb->ccb_state != CISS_CCB_ONQ) {
    494 					tohz = etick - tick;
    495 					if (tohz <= 0)
    496 						break;
    497 					CISS_DPRINTF(CISS_D_CMD, ("T"));
    498 					continue;
    499 				}
    500 				ccb1 = ccb;
    501 			} else {
    502 				DELAY(10);
    503 
    504 				if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    505 				    CISS_ISR) & sc->iem)) {
    506 					CISS_DPRINTF(CISS_D_CMD, ("N"));
    507 					continue;
    508 				}
    509 
    510 				if ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    511 				    CISS_OUTQ)) == 0xffffffff) {
    512 					CISS_DPRINTF(CISS_D_CMD, ("Q"));
    513 					continue;
    514 				}
    515 
    516 				CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
    517 				ccb1 = (struct ciss_ccb *)
    518 					(sc->ccbs + (id >> 2) * sc->ccblen);
    519 				ccb1->ccb_cmd.id = htole32(id);
    520 			}
    521 
    522 			error = ciss_done(ccb1);
    523 			if (ccb1 == ccb)
    524 				break;
    525 		}
    526 
    527 		/* if never got a chance to be done above... */
    528 		if (ccb->ccb_state != CISS_CCB_FREE) {
    529 			ccb->ccb_err.cmd_stat = CISS_ERR_TMO;
    530 			error = ciss_done(ccb);
    531 		}
    532 
    533 		CISS_DPRINTF(CISS_D_CMD, ("done %d:%d",
    534 		    ccb->ccb_err.cmd_stat, ccb->ccb_err.scsi_stat));
    535 	}
    536 
    537 	if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP))
    538 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR,
    539 		    bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) & ~sc->iem);
    540 
    541 	return (error);
    542 }
    543 
    544 static int
    545 ciss_done(struct ciss_ccb *ccb)
    546 {
    547 	struct ciss_softc *sc = ccb->ccb_sc;
    548 	struct scsipi_xfer *xs = ccb->ccb_xs;
    549 	ciss_lock_t lock;
    550 	int error = 0;
    551 
    552 	CISS_DPRINTF(CISS_D_CMD, ("ciss_done(%p) ", ccb));
    553 
    554 	if (ccb->ccb_state != CISS_CCB_ONQ) {
    555 		printf("%s: unqueued ccb %p ready, state=0x%x\n",
    556 		    sc->sc_dev.dv_xname, ccb, ccb->ccb_state);
    557 		return 1;
    558 	}
    559 
    560 	lock = CISS_LOCK(sc);
    561 	ccb->ccb_state = CISS_CCB_READY;
    562 	TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link);
    563 
    564 	if (ccb->ccb_cmd.id & CISS_CMD_ERR)
    565 		error = ciss_error(ccb);
    566 
    567 	if (ccb->ccb_data) {
    568 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
    569 		    ccb->ccb_dmamap->dm_mapsize,
    570 		    (xs  && xs->xs_control & XS_CTL_DATA_IN) ?
    571 		     BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
    572 		bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
    573 		ccb->ccb_xs = NULL;
    574 		ccb->ccb_data = NULL;
    575 	}
    576 
    577 	ciss_put_ccb(ccb);
    578 
    579 	if (xs) {
    580 		xs->resid = 0;
    581 		xs->xs_status |= XS_STS_DONE;
    582 		CISS_DPRINTF(CISS_D_CMD, ("scsipi_done(%p) ", xs));
    583 		scsipi_done(xs);
    584 	}
    585 	CISS_UNLOCK(sc, lock);
    586 
    587 	return error;
    588 }
    589 
    590 static int
    591 ciss_error(struct ciss_ccb *ccb)
    592 {
    593 	struct ciss_softc *sc = ccb->ccb_sc;
    594 	struct ciss_error *err = &ccb->ccb_err;
    595 	struct scsipi_xfer *xs = ccb->ccb_xs;
    596 	int rv;
    597 
    598 	switch ((rv = le16toh(err->cmd_stat))) {
    599 	case CISS_ERR_OK:
    600 		break;
    601 
    602 	case CISS_ERR_INVCMD:
    603 		printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n",
    604 		    sc->sc_dev.dv_xname, ccb->ccb_cmd.id,
    605 		    err->err_info, err->err_type[3], err->err_type[2]);
    606 		if (xs) {
    607 			bzero(&xs->sense, sizeof(xs->sense));
    608 			xs->sense.scsi_sense.response_code =
    609 				SSD_RCODE_CURRENT | SSD_RCODE_VALID;
    610 			xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
    611 			xs->sense.scsi_sense.asc = 0x24; /* ill field */
    612 			xs->sense.scsi_sense.ascq = 0x0;
    613 			xs->error = XS_SENSE;
    614 		}
    615 		break;
    616 
    617 	case CISS_ERR_TMO:
    618 		xs->error = XS_TIMEOUT;
    619 		break;
    620 
    621 	case CISS_ERR_UNRUN:
    622 		/* Underrun */
    623 		xs->resid = le32toh(err->resid);
    624 		CISS_DPRINTF(CISS_D_CMD, (" underrun resid=0x%x ",
    625 					  xs->resid));
    626 		break;
    627 	default:
    628 		if (xs) {
    629 			CISS_DPRINTF(CISS_D_CMD, ("scsi_stat=%x ", err->scsi_stat));
    630 			switch (err->scsi_stat) {
    631 			case SCSI_CHECK:
    632 				xs->error = XS_SENSE;
    633 				bcopy(&err->sense[0], &xs->sense,
    634 				    sizeof(xs->sense));
    635 				CISS_DPRINTF(CISS_D_CMD, (" sense=%02x %02x %02x %02x ",
    636 					     err->sense[0], err->sense[1], err->sense[2], err->sense[3]));
    637 				break;
    638 
    639 			case XS_BUSY:
    640 				xs->error = XS_BUSY;
    641 				break;
    642 
    643 			default:
    644 				CISS_DPRINTF(CISS_D_ERR, ("%s: "
    645 				    "cmd_stat=%x scsi_stat=0x%x resid=0x%x\n",
    646 				    sc->sc_dev.dv_xname, rv, err->scsi_stat,
    647 				    le32toh(err->resid)));
    648 				printf("ciss driver stuffup in %s:%d: %s()\n",
    649 				       __FILE__, __LINE__, __FUNCTION__);
    650 				xs->error = XS_DRIVER_STUFFUP;
    651 				break;
    652 			}
    653 			xs->resid = le32toh(err->resid);
    654 		}
    655 	}
    656 	ccb->ccb_cmd.id &= htole32(~3);
    657 
    658 	return rv;
    659 }
    660 
    661 static int
    662 ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq)
    663 {
    664 	struct ciss_ccb *ccb;
    665 	struct ciss_cmd *cmd;
    666 
    667 	ccb = ciss_get_ccb(sc);
    668 	ccb->ccb_len = sizeof(*inq);
    669 	ccb->ccb_data = inq;
    670 	cmd = &ccb->ccb_cmd;
    671 	cmd->tgt = htole32(CISS_CMD_MODE_PERIPH);
    672 	cmd->tgt2 = 0;
    673 	cmd->cdblen = 10;
    674 	cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN;
    675 	cmd->tmo = htole16(0);
    676 	bzero(&cmd->cdb[0], sizeof(cmd->cdb));
    677 	cmd->cdb[0] = CISS_CMD_CTRL_GET;
    678 	cmd->cdb[6] = CISS_CMS_CTRL_CTRL;
    679 	cmd->cdb[7] = sizeof(*inq) >> 8;	/* biiiig endian */
    680 	cmd->cdb[8] = sizeof(*inq) & 0xff;
    681 
    682 	return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
    683 }
    684 
    685 static int
    686 ciss_ldmap(struct ciss_softc *sc)
    687 {
    688 	struct ciss_ccb *ccb;
    689 	struct ciss_cmd *cmd;
    690 	struct ciss_ldmap *lmap;
    691 	ciss_lock_t lock;
    692 	int total, rv;
    693 
    694 	lock = CISS_LOCK_SCRATCH(sc);
    695 	lmap = sc->scratch;
    696 	lmap->size = htobe32(sc->maxunits * sizeof(lmap->map));
    697 	total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map);
    698 
    699 	ccb = ciss_get_ccb(sc);
    700 	ccb->ccb_len = total;
    701 	ccb->ccb_data = lmap;
    702 	cmd = &ccb->ccb_cmd;
    703 	cmd->tgt = CISS_CMD_MODE_PERIPH;
    704 	cmd->tgt2 = 0;
    705 	cmd->cdblen = 12;
    706 	cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN;
    707 	cmd->tmo = htole16(30);
    708 	bzero(&cmd->cdb[0], sizeof(cmd->cdb));
    709 	cmd->cdb[0] = CISS_CMD_LDMAP;
    710 	cmd->cdb[8] = total >> 8;	/* biiiig endian */
    711 	cmd->cdb[9] = total & 0xff;
    712 
    713 	rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
    714 	CISS_UNLOCK_SCRATCH(sc, lock);
    715 
    716 	if (rv)
    717 		return rv;
    718 
    719 	CISS_DPRINTF(CISS_D_MISC, ("lmap %x:%x\n",
    720 	    lmap->map[0].tgt, lmap->map[0].tgt2));
    721 
    722 	return 0;
    723 }
    724 
    725 static int
    726 ciss_sync(struct ciss_softc *sc)
    727 {
    728 	struct ciss_ccb *ccb;
    729 	struct ciss_cmd *cmd;
    730 	struct ciss_flush *flush;
    731 	ciss_lock_t lock;
    732 	int rv;
    733 
    734 	lock = CISS_LOCK_SCRATCH(sc);
    735 	flush = sc->scratch;
    736 	bzero(flush, sizeof(*flush));
    737 	flush->flush = sc->sc_flush;
    738 
    739 	ccb = ciss_get_ccb(sc);
    740 	ccb->ccb_len = sizeof(*flush);
    741 	ccb->ccb_data = flush;
    742 	cmd = &ccb->ccb_cmd;
    743 	cmd->tgt = CISS_CMD_MODE_PERIPH;
    744 	cmd->tgt2 = 0;
    745 	cmd->cdblen = 10;
    746 	cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_OUT;
    747 	cmd->tmo = 0;
    748 	bzero(&cmd->cdb[0], sizeof(cmd->cdb));
    749 	cmd->cdb[0] = CISS_CMD_CTRL_SET;
    750 	cmd->cdb[6] = CISS_CMS_CTRL_FLUSH;
    751 	cmd->cdb[7] = sizeof(*flush) >> 8;	/* biiiig endian */
    752 	cmd->cdb[8] = sizeof(*flush) & 0xff;
    753 
    754 	rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
    755 	CISS_UNLOCK_SCRATCH(sc, lock);
    756 
    757 	return rv;
    758 }
    759 
    760 #if 0
    761 static void
    762 ciss_scsi_raw_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
    763 	void *arg)				/* TODO */
    764 {
    765 	struct scsipi_xfer *xs = (struct scsipi_xfer *) arg;
    766 	struct ciss_rawsoftc *rsc =
    767 		(struct ciss_rawsoftc *) chan->chan_adapter->adapt_dev;
    768 	struct ciss_softc *sc = rsc->sc_softc;
    769 	struct ciss_ccb *ccb;
    770 	struct ciss_cmd *cmd;
    771 	ciss_lock_t lock;
    772 	int error;
    773 
    774 	CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_raw_cmd "));
    775 
    776 	switch (req)
    777 	{
    778 	case ADAPTER_REQ_RUN_XFER:
    779 		if (xs->cmdlen > CISS_MAX_CDB) {
    780 			CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
    781 			bzero(&xs->sense, sizeof(xs->sense));
    782 			printf("ciss driver stuffup in %s:%d: %s()\n",
    783 			       __FILE__, __LINE__, __FUNCTION__);
    784 			xs->error = XS_DRIVER_STUFFUP;
    785 			scsipi_done(xs);
    786 			break;
    787 		}
    788 
    789 		lock = CISS_LOCK(sc);
    790 		error = 0;
    791 		xs->error = XS_NOERROR;
    792 
    793 		/* TODO check this target has not yet employed w/ any volume */
    794 
    795 		ccb = ciss_get_ccb(sc);
    796 		cmd = &ccb->ccb_cmd;
    797 		ccb->ccb_len = xs->datalen;
    798 		ccb->ccb_data = xs->data;
    799 		ccb->ccb_xs = xs;
    800 
    801 		cmd->cdblen = xs->cmdlen;
    802 		cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL;
    803 		if (xs->xs_control & XS_CTL_DATA_IN)
    804 			cmd->flags |= CISS_CDB_IN;
    805 		else if (xs->xs_control & XS_CTL_DATA_OUT)
    806 			cmd->flags |= CISS_CDB_OUT;
    807 		cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000;
    808 		bzero(&cmd->cdb[0], sizeof(cmd->cdb));
    809 		bcopy(xs->cmd, &cmd->cdb[0], CISS_MAX_CDB);
    810 
    811 		if (ciss_cmd(ccb, BUS_DMA_WAITOK,
    812 		    xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) {
    813 			printf("ciss driver stuffup in %s:%d: %s()\n",
    814 			       __FILE__, __LINE__, __FUNCTION__);
    815 			xs->error = XS_DRIVER_STUFFUP;
    816 			scsipi_done(xs);
    817 			CISS_UNLOCK(sc, lock);
    818 			break;
    819 		}
    820 
    821 		CISS_UNLOCK(sc, lock);
    822 		break;
    823 
    824 	case ADAPTER_REQ_GROW_RESOURCES:
    825 		/*
    826 		 * Not supported.
    827 		 */
    828 		break;
    829 
    830 	case ADAPTER_REQ_SET_XFER_MODE:
    831 		/*
    832 		 * We can't change the transfer mode, but at least let
    833 		 * scsipi know what the adapter has negociated.
    834 		 */
    835 		 /* Get xfer mode and return it */
    836 		break;
    837 	}
    838 }
    839 #endif
    840 
    841 static void
    842 ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
    843 	void *arg)
    844 {
    845 	struct scsipi_xfer *xs = (struct scsipi_xfer *) arg;
    846 	struct ciss_softc *sc =
    847 		(struct ciss_softc *) chan->chan_adapter->adapt_dev;
    848 	u_int8_t target;
    849 	struct ciss_ccb *ccb;
    850 	struct ciss_cmd *cmd;
    851 	int error;
    852 	ciss_lock_t lock;
    853 
    854 	CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_cmd "));
    855 
    856 	switch (req)
    857 	{
    858 	case ADAPTER_REQ_RUN_XFER:
    859 		target = xs->xs_periph->periph_target;
    860 		CISS_DPRINTF(CISS_D_CMD, ("targ=%d ", target));
    861 		if (xs->cmdlen > CISS_MAX_CDB) {
    862 			CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
    863 			bzero(&xs->sense, sizeof(xs->sense));
    864 			printf("ciss driver stuffup in %s:%d: %s()\n",
    865 			       __FILE__, __LINE__, __FUNCTION__);
    866 			xs->error = XS_DRIVER_STUFFUP;
    867 			scsipi_done(xs);
    868 			break;
    869 		}
    870 
    871 		lock = CISS_LOCK(sc);
    872 		error = 0;
    873 		xs->error = XS_NOERROR;
    874 
    875 		/* XXX emulate SYNCHRONIZE_CACHE ??? */
    876 
    877 		ccb = ciss_get_ccb(sc);
    878 		cmd = &ccb->ccb_cmd;
    879 		ccb->ccb_len = xs->datalen;
    880 		ccb->ccb_data = xs->data;
    881 		ccb->ccb_xs = xs;
    882 		cmd->tgt = CISS_CMD_MODE_LD | target;
    883 		cmd->tgt2 = 0;
    884 		cmd->cdblen = xs->cmdlen;
    885 		cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL;
    886 		if (xs->xs_control & XS_CTL_DATA_IN)
    887 			cmd->flags |= CISS_CDB_IN;
    888 		else if (xs->xs_control & XS_CTL_DATA_OUT)
    889 			cmd->flags |= CISS_CDB_OUT;
    890 		cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000;
    891 		bzero(&cmd->cdb[0], sizeof(cmd->cdb));
    892 		bcopy(xs->cmd, &cmd->cdb[0], CISS_MAX_CDB);
    893 		CISS_DPRINTF(CISS_D_CMD, ("cmd=%02x %02x %02x %02x %02x %02x ",
    894 			     cmd->cdb[0], cmd->cdb[1], cmd->cdb[2],
    895 			     cmd->cdb[3], cmd->cdb[4], cmd->cdb[5]));
    896 
    897 		if (ciss_cmd(ccb, BUS_DMA_WAITOK,
    898 		    xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) {
    899 			printf("ciss driver stuffup in %s:%d: %s()\n",
    900 			       __FILE__, __LINE__, __FUNCTION__);
    901 			xs->error = XS_DRIVER_STUFFUP;
    902 			scsipi_done(xs);
    903 			CISS_UNLOCK(sc, lock);
    904 			return;
    905 		}
    906 
    907 		CISS_UNLOCK(sc, lock);
    908 		break;
    909 	case ADAPTER_REQ_GROW_RESOURCES:
    910 		/*
    911 		 * Not supported.
    912 		 */
    913 		break;
    914 	case ADAPTER_REQ_SET_XFER_MODE:
    915 		/*
    916 		 * We can't change the transfer mode, but at least let
    917 		 * scsipi know what the adapter has negociated.
    918 		 */
    919 		/* FIXME: get xfer mode and write it into arg */
    920 		break;
    921 	}
    922 }
    923 
    924 int
    925 ciss_intr(void *v)
    926 {
    927 	struct ciss_softc *sc = v;
    928 	struct ciss_ccb *ccb;
    929 	ciss_lock_t lock;
    930 	u_int32_t id;
    931 	int hit = 0;
    932 
    933 	CISS_DPRINTF(CISS_D_INTR, ("intr "));
    934 
    935 	if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem))
    936 		return 0;
    937 
    938 	lock = CISS_LOCK(sc);
    939 	while ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ)) !=
    940 	    0xffffffff) {
    941 
    942 		ccb = (struct ciss_ccb *) (sc->ccbs + (id >> 2) * sc->ccblen);
    943 		ccb->ccb_cmd.id = htole32(id);
    944 		if (ccb->ccb_state == CISS_CCB_POLL) {
    945 			ccb->ccb_state = CISS_CCB_ONQ;
    946 			wakeup(ccb);
    947 		} else
    948 			ciss_done(ccb);
    949 
    950 		hit = 1;
    951 	}
    952 	CISS_UNLOCK(sc, lock);
    953 
    954 	CISS_DPRINTF(CISS_D_INTR, ("exit\n"));
    955 	return hit;
    956 }
    957 
    958 static void
    959 ciss_heartbeat(void *v)
    960 {
    961 	struct ciss_softc *sc = v;
    962 	u_int32_t hb;
    963 
    964 	hb = bus_space_read_4(sc->sc_iot, sc->cfg_ioh,
    965 	    sc->cfgoff + offsetof(struct ciss_config, heartbeat));
    966 	if (hb == sc->heartbeat)
    967 		panic("ciss: dead");	/* XX reset! */
    968 	else
    969 		sc->heartbeat = hb;
    970 
    971 	callout_schedule(&sc->sc_hb, hz * 3);
    972 }
    973 
    974 #if 0
    975 static void
    976 ciss_kthread(void *v)
    977 {
    978 	struct ciss_softc *sc = v;
    979 	ciss_lock_t lock;
    980 
    981 	for (;;) {
    982 		tsleep(sc, PRIBIO, sc->sc_dev.dv_xname, 0);
    983 
    984 		lock = CISS_LOCK(sc);
    985 
    986 
    987 
    988 		CISS_UNLOCK(sc, lock);
    989 	}
    990 }
    991 #endif
    992 
    993 static int
    994 ciss_scsi_ioctl(struct scsipi_channel *chan, u_long cmd,
    995     caddr_t addr, int flag, struct proc *p)
    996 {
    997 #if NBIO > 0
    998 	return ciss_ioctl(chan->chan_adapter->adapt_dev, cmd, addr);
    999 #else
   1000 	return ENOTTY;
   1001 #endif
   1002 }
   1003 
   1004 #if NBIO > 0
   1005 static int
   1006 ciss_ioctl(struct device *dev, u_long cmd, caddr_t addr)	/* TODO */
   1007 {
   1008 	/* struct ciss_softc *sc = (struct ciss_softc *)dev; */
   1009 	ciss_lock_t lock;
   1010 	int error;
   1011 
   1012 	lock = CISS_LOCK(sc);
   1013 	switch (cmd) {
   1014 	case BIOCINQ:
   1015 	case BIOCVOL:
   1016 	case BIOCDISK:
   1017 	case BIOCALARM:
   1018 	case BIOCBLINK:
   1019 	case BIOCSETSTATE:
   1020 	default:
   1021 		CISS_DPRINTF(CISS_D_IOCTL, ("%s: invalid ioctl\n",
   1022 		    sc->sc_dev.dv_xname));
   1023 		error = ENOTTY;
   1024 	}
   1025 	CISS_UNLOCK(sc, lock);
   1026 
   1027 	return error;
   1028 }
   1029 #endif
   1030