The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/ciss.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ciss.c,v 1.6 2006/11/16 01:32:51 christos Exp $        */
    2 /*      $OpenBSD: ciss.c,v 1.14 2006/03/13 16:02:23 mickey 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.6 2006/11/16 01:32:51 christos 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 
  457                 CISS_DPRINTF(CISS_D_DMA, ("> "));
  458 
  459                 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
  460                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  461         } else
  462                 cmd->sgin = 0;
  463         cmd->sglen = htole16((u_int16_t)cmd->sgin);
  464         bzero(&ccb->ccb_err, sizeof(ccb->ccb_err));
  465 
  466         bus_dmamap_sync(sc->sc_dmat, sc->cmdmap, 0, sc->cmdmap->dm_mapsize,
  467             BUS_DMASYNC_PREWRITE);
  468 
  469         if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP))
  470                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR,
  471                     bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) | sc->iem);
  472 
  473         TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link);
  474         ccb->ccb_state = CISS_CCB_ONQ;
  475         CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id));
  476         bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ, ccb->ccb_cmdpa);
  477 
  478         if (wait & XS_CTL_POLL) {
  479                 int etick;
  480                 CISS_DPRINTF(CISS_D_CMD, ("waiting "));
  481 
  482                 i = ccb->ccb_xs? ccb->ccb_xs->timeout : 60000;
  483                 tohz = (i / 1000) * hz + (i % 1000) * (hz / 1000);
  484                 if (tohz == 0)
  485                         tohz = 1;
  486                 for (i *= 100, etick = tick + tohz; i--; ) {
  487                         if (!(wait & XS_CTL_NOSLEEP)) {
  488                                 ccb->ccb_state = CISS_CCB_POLL;
  489                                 CISS_DPRINTF(CISS_D_CMD, ("tsleep(%d) ", tohz));
  490                                 if (tsleep(ccb, PRIBIO + 1, "ciss_cmd",
  491                                     tohz) == EWOULDBLOCK) {
  492                                         break;
  493                                 }
  494                                 if (ccb->ccb_state != CISS_CCB_ONQ) {
  495                                         tohz = etick - tick;
  496                                         if (tohz <= 0)
  497                                                 break;
  498                                         CISS_DPRINTF(CISS_D_CMD, ("T"));
  499                                         continue;
  500                                 }
  501                                 ccb1 = ccb;
  502                         } else {
  503                                 DELAY(10);
  504 
  505                                 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  506                                     CISS_ISR) & sc->iem)) {
  507                                         CISS_DPRINTF(CISS_D_CMD, ("N"));
  508                                         continue;
  509                                 }
  510 
  511                                 if ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  512                                     CISS_OUTQ)) == 0xffffffff) {
  513                                         CISS_DPRINTF(CISS_D_CMD, ("Q"));
  514                                         continue;
  515                                 }
  516 
  517                                 CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
  518                                 ccb1 = (struct ciss_ccb *)
  519                                         (sc->ccbs + (id >> 2) * sc->ccblen);
  520                                 ccb1->ccb_cmd.id = htole32(id);
  521                         }
  522 
  523                         error = ciss_done(ccb1);
  524                         if (ccb1 == ccb)
  525                                 break;
  526                 }
  527 
  528                 /* if never got a chance to be done above... */
  529                 if (ccb->ccb_state != CISS_CCB_FREE) {
  530                         ccb->ccb_err.cmd_stat = CISS_ERR_TMO;
  531                         error = ciss_done(ccb);
  532                 }
  533 
  534                 CISS_DPRINTF(CISS_D_CMD, ("done %d:%d",
  535                     ccb->ccb_err.cmd_stat, ccb->ccb_err.scsi_stat));
  536         }
  537 
  538         if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP))
  539                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR,
  540                     bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) & ~sc->iem);
  541 
  542         return (error);
  543 }
  544 
  545 static int
  546 ciss_done(struct ciss_ccb *ccb)
  547 {
  548         struct ciss_softc *sc = ccb->ccb_sc;
  549         struct scsipi_xfer *xs = ccb->ccb_xs;
  550         struct ciss_cmd *cmd;
  551         ciss_lock_t lock;
  552         int error = 0;
  553 
  554         CISS_DPRINTF(CISS_D_CMD, ("ciss_done(%p) ", ccb));
  555 
  556         if (ccb->ccb_state != CISS_CCB_ONQ) {
  557                 printf("%s: unqueued ccb %p ready, state=0x%x\n",
  558                     sc->sc_dev.dv_xname, ccb, ccb->ccb_state);
  559                 return 1;
  560         }
  561 
  562         lock = CISS_LOCK(sc);
  563         ccb->ccb_state = CISS_CCB_READY;
  564         TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link);
  565 
  566         if (ccb->ccb_cmd.id & CISS_CMD_ERR)
  567                 error = ciss_error(ccb);
  568 
  569         cmd = &ccb->ccb_cmd;
  570         if (ccb->ccb_data) {
  571                 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
  572                     ccb->ccb_dmamap->dm_mapsize, (cmd->flags & CISS_CDB_IN) ?
  573                     BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
  574                 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
  575                 ccb->ccb_xs = NULL;
  576                 ccb->ccb_data = NULL;
  577         }
  578 
  579         ciss_put_ccb(ccb);
  580 
  581         if (xs) {
  582                 xs->resid = 0;
  583                 CISS_DPRINTF(CISS_D_CMD, ("scsipi_done(%p) ", xs));
  584                 scsipi_done(xs);
  585         }
  586         CISS_UNLOCK(sc, lock);
  587 
  588         return error;
  589 }
  590 
  591 static int
  592 ciss_error(struct ciss_ccb *ccb)
  593 {
  594         struct ciss_softc *sc = ccb->ccb_sc;
  595         struct ciss_error *err = &ccb->ccb_err;
  596         struct scsipi_xfer *xs = ccb->ccb_xs;
  597         int rv;
  598 
  599         switch ((rv = le16toh(err->cmd_stat))) {
  600         case CISS_ERR_OK:
  601                 break;
  602 
  603         case CISS_ERR_INVCMD:
  604                 printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n",
  605                     sc->sc_dev.dv_xname, ccb->ccb_cmd.id,
  606                     err->err_info, err->err_type[3], err->err_type[2]);
  607                 if (xs) {
  608                         bzero(&xs->sense, sizeof(xs->sense));
  609                         xs->sense.scsi_sense.response_code =
  610                                 SSD_RCODE_CURRENT | SSD_RCODE_VALID;
  611                         xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
  612                         xs->sense.scsi_sense.asc = 0x24; /* ill field */
  613                         xs->sense.scsi_sense.ascq = 0x0;
  614                         xs->error = XS_SENSE;
  615                 }
  616                 break;
  617 
  618         case CISS_ERR_TMO:
  619                 xs->error = XS_TIMEOUT;
  620                 break;
  621 
  622         case CISS_ERR_UNRUN:
  623                 /* Underrun */
  624                 xs->resid = le32toh(err->resid);
  625                 CISS_DPRINTF(CISS_D_CMD, (" underrun resid=0x%x ",
  626                                           xs->resid));
  627                 break;
  628         default:
  629                 if (xs) {
  630                         CISS_DPRINTF(CISS_D_CMD, ("scsi_stat=%x ", err->scsi_stat));
  631                         switch (err->scsi_stat) {
  632                         case SCSI_CHECK:
  633                                 xs->error = XS_SENSE;
  634                                 bcopy(&err->sense[0], &xs->sense,
  635                                     sizeof(xs->sense));
  636                                 CISS_DPRINTF(CISS_D_CMD, (" sense=%02x %02x %02x %02x ",
  637                                              err->sense[0], err->sense[1], err->sense[2], err->sense[3]));
  638                                 break;
  639 
  640                         case XS_BUSY:
  641                                 xs->error = XS_BUSY;
  642                                 break;
  643 
  644                         default:
  645                                 CISS_DPRINTF(CISS_D_ERR, ("%s: "
  646                                     "cmd_stat=%x scsi_stat=0x%x resid=0x%x\n",
  647                                     sc->sc_dev.dv_xname, rv, err->scsi_stat,
  648                                     le32toh(err->resid)));
  649                                 printf("ciss driver stuffup in %s:%d: %s()\n",
  650                                        __FILE__, __LINE__, __FUNCTION__);
  651                                 xs->error = XS_DRIVER_STUFFUP;
  652                                 break;
  653                         }
  654                         xs->resid = le32toh(err->resid);
  655                 }
  656         }
  657         ccb->ccb_cmd.id &= htole32(~3);
  658 
  659         return rv;
  660 }
  661 
  662 static int
  663 ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq)
  664 {
  665         struct ciss_ccb *ccb;
  666         struct ciss_cmd *cmd;
  667 
  668         ccb = ciss_get_ccb(sc);
  669         ccb->ccb_len = sizeof(*inq);
  670         ccb->ccb_data = inq;
  671         ccb->ccb_xs = NULL;
  672         cmd = &ccb->ccb_cmd;
  673         cmd->tgt = htole32(CISS_CMD_MODE_PERIPH);
  674         cmd->tgt2 = 0;
  675         cmd->cdblen = 10;
  676         cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN;
  677         cmd->tmo = htole16(0);
  678         bzero(&cmd->cdb[0], sizeof(cmd->cdb));
  679         cmd->cdb[0] = CISS_CMD_CTRL_GET;
  680         cmd->cdb[6] = CISS_CMS_CTRL_CTRL;
  681         cmd->cdb[7] = sizeof(*inq) >> 8;        /* biiiig endian */
  682         cmd->cdb[8] = sizeof(*inq) & 0xff;
  683 
  684         return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
  685 }
  686 
  687 static int
  688 ciss_ldmap(struct ciss_softc *sc)
  689 {
  690         struct ciss_ccb *ccb;
  691         struct ciss_cmd *cmd;
  692         struct ciss_ldmap *lmap;
  693         ciss_lock_t lock;
  694         int total, rv;
  695 
  696         lock = CISS_LOCK_SCRATCH(sc);
  697         lmap = sc->scratch;
  698         lmap->size = htobe32(sc->maxunits * sizeof(lmap->map));
  699         total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map);
  700 
  701         ccb = ciss_get_ccb(sc);
  702         ccb->ccb_len = total;
  703         ccb->ccb_data = lmap;
  704         ccb->ccb_xs = NULL;
  705         cmd = &ccb->ccb_cmd;
  706         cmd->tgt = CISS_CMD_MODE_PERIPH;
  707         cmd->tgt2 = 0;
  708         cmd->cdblen = 12;
  709         cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN;
  710         cmd->tmo = htole16(30);
  711         bzero(&cmd->cdb[0], sizeof(cmd->cdb));
  712         cmd->cdb[0] = CISS_CMD_LDMAP;
  713         cmd->cdb[8] = total >> 8;       /* biiiig endian */
  714         cmd->cdb[9] = total & 0xff;
  715 
  716         rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
  717         CISS_UNLOCK_SCRATCH(sc, lock);
  718 
  719         if (rv)
  720                 return rv;
  721 
  722         CISS_DPRINTF(CISS_D_MISC, ("lmap %x:%x\n",
  723             lmap->map[0].tgt, lmap->map[0].tgt2));
  724 
  725         return 0;
  726 }
  727 
  728 static int
  729 ciss_sync(struct ciss_softc *sc)
  730 {
  731         struct ciss_ccb *ccb;
  732         struct ciss_cmd *cmd;
  733         struct ciss_flush *flush;
  734         ciss_lock_t lock;
  735         int rv;
  736 
  737         lock = CISS_LOCK_SCRATCH(sc);
  738         flush = sc->scratch;
  739         bzero(flush, sizeof(*flush));
  740         flush->flush = sc->sc_flush;
  741 
  742         ccb = ciss_get_ccb(sc);
  743         ccb->ccb_len = sizeof(*flush);
  744         ccb->ccb_data = flush;
  745         ccb->ccb_xs = NULL;
  746         cmd = &ccb->ccb_cmd;
  747         cmd->tgt = CISS_CMD_MODE_PERIPH;
  748         cmd->tgt2 = 0;
  749         cmd->cdblen = 10;
  750         cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_OUT;
  751         cmd->tmo = 0;
  752         bzero(&cmd->cdb[0], sizeof(cmd->cdb));
  753         cmd->cdb[0] = CISS_CMD_CTRL_SET;
  754         cmd->cdb[6] = CISS_CMS_CTRL_FLUSH;
  755         cmd->cdb[7] = sizeof(*flush) >> 8;      /* biiiig endian */
  756         cmd->cdb[8] = sizeof(*flush) & 0xff;
  757 
  758         rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP);
  759         CISS_UNLOCK_SCRATCH(sc, lock);
  760 
  761         return rv;
  762 }
  763 
  764 #if 0
  765 static void
  766 ciss_scsi_raw_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
  767         void *arg)                              /* TODO */
  768 {
  769         struct scsipi_xfer *xs = (struct scsipi_xfer *) arg;
  770         struct ciss_rawsoftc *rsc =
  771                 (struct ciss_rawsoftc *) chan->chan_adapter->adapt_dev;
  772         struct ciss_softc *sc = rsc->sc_softc;
  773         struct ciss_ccb *ccb;
  774         struct ciss_cmd *cmd;
  775         ciss_lock_t lock;
  776         int error;
  777 
  778         CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_raw_cmd "));
  779 
  780         switch (req)
  781         {
  782         case ADAPTER_REQ_RUN_XFER:
  783                 if (xs->cmdlen > CISS_MAX_CDB) {
  784                         CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
  785                         bzero(&xs->sense, sizeof(xs->sense));
  786                         printf("ciss driver stuffup in %s:%d: %s()\n",
  787                                __FILE__, __LINE__, __FUNCTION__);
  788                         xs->error = XS_DRIVER_STUFFUP;
  789                         scsipi_done(xs);
  790                         break;
  791                 }
  792 
  793                 lock = CISS_LOCK(sc);
  794                 error = 0;
  795                 xs->error = XS_NOERROR;
  796 
  797                 /* TODO check this target has not yet employed w/ any volume */
  798 
  799                 ccb = ciss_get_ccb(sc);
  800                 cmd = &ccb->ccb_cmd;
  801                 ccb->ccb_len = xs->datalen;
  802                 ccb->ccb_data = xs->data;
  803                 ccb->ccb_xs = xs;
  804 
  805                 cmd->cdblen = xs->cmdlen;
  806                 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL;
  807                 if (xs->xs_control & XS_CTL_DATA_IN)
  808                         cmd->flags |= CISS_CDB_IN;
  809                 else if (xs->xs_control & XS_CTL_DATA_OUT)
  810                         cmd->flags |= CISS_CDB_OUT;
  811                 cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000;
  812                 bzero(&cmd->cdb[0], sizeof(cmd->cdb));
  813                 bcopy(xs->cmd, &cmd->cdb[0], CISS_MAX_CDB);
  814 
  815                 if (ciss_cmd(ccb, BUS_DMA_WAITOK,
  816                     xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) {
  817                         printf("ciss driver stuffup in %s:%d: %s()\n",
  818                                __FILE__, __LINE__, __FUNCTION__);
  819                         xs->error = XS_DRIVER_STUFFUP;
  820                         scsipi_done(xs);
  821                         CISS_UNLOCK(sc, lock);
  822                         break;
  823                 }
  824 
  825                 CISS_UNLOCK(sc, lock);
  826                 break;
  827 
  828         case ADAPTER_REQ_GROW_RESOURCES:
  829                 /*
  830                  * Not supported.
  831                  */
  832                 break;
  833 
  834         case ADAPTER_REQ_SET_XFER_MODE:
  835                 /*
  836                  * We can't change the transfer mode, but at least let
  837                  * scsipi know what the adapter has negociated.
  838                  */
  839                  /* Get xfer mode and return it */
  840                 break;
  841         }
  842 }
  843 #endif
  844 
  845 static void
  846 ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
  847         void *arg)
  848 {
  849         struct scsipi_xfer *xs = (struct scsipi_xfer *) arg;
  850         struct ciss_softc *sc =
  851                 (struct ciss_softc *) chan->chan_adapter->adapt_dev;
  852         u_int8_t target;
  853         struct ciss_ccb *ccb;
  854         struct ciss_cmd *cmd;
  855         int error;
  856         ciss_lock_t lock;
  857 
  858         CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_cmd "));
  859 
  860         switch (req)
  861         {
  862         case ADAPTER_REQ_RUN_XFER:
  863                 target = xs->xs_periph->periph_target;
  864                 CISS_DPRINTF(CISS_D_CMD, ("targ=%d ", target));
  865                 if (xs->cmdlen > CISS_MAX_CDB) {
  866                         CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
  867                         bzero(&xs->sense, sizeof(xs->sense));
  868                         printf("ciss driver stuffup in %s:%d: %s()\n",
  869                                __FILE__, __LINE__, __FUNCTION__);
  870                         xs->error = XS_DRIVER_STUFFUP;
  871                         scsipi_done(xs);
  872                         break;
  873                 }
  874 
  875                 lock = CISS_LOCK(sc);
  876                 error = 0;
  877                 xs->error = XS_NOERROR;
  878 
  879                 /* XXX emulate SYNCHRONIZE_CACHE ??? */
  880 
  881                 ccb = ciss_get_ccb(sc);
  882                 cmd = &ccb->ccb_cmd;
  883                 ccb->ccb_len = xs->datalen;
  884                 ccb->ccb_data = xs->data;
  885                 ccb->ccb_xs = xs;
  886                 cmd->tgt = CISS_CMD_MODE_LD | target;
  887                 cmd->tgt2 = 0;
  888                 cmd->cdblen = xs->cmdlen;
  889                 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL;
  890                 if (xs->xs_control & XS_CTL_DATA_IN)
  891                         cmd->flags |= CISS_CDB_IN;
  892                 else if (xs->xs_control & XS_CTL_DATA_OUT)
  893                         cmd->flags |= CISS_CDB_OUT;
  894                 cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000;
  895                 bzero(&cmd->cdb[0], sizeof(cmd->cdb));
  896                 bcopy(xs->cmd, &cmd->cdb[0], CISS_MAX_CDB);
  897                 CISS_DPRINTF(CISS_D_CMD, ("cmd=%02x %02x %02x %02x %02x %02x ",
  898                              cmd->cdb[0], cmd->cdb[1], cmd->cdb[2],
  899                              cmd->cdb[3], cmd->cdb[4], cmd->cdb[5]));
  900 
  901                 if (ciss_cmd(ccb, BUS_DMA_WAITOK,
  902                     xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) {
  903                         printf("ciss driver stuffup in %s:%d: %s()\n",
  904                                __FILE__, __LINE__, __FUNCTION__);
  905                         xs->error = XS_DRIVER_STUFFUP;
  906                         scsipi_done(xs);
  907                         CISS_UNLOCK(sc, lock);
  908                         return;
  909                 }
  910 
  911                 CISS_UNLOCK(sc, lock);
  912                 break;
  913         case ADAPTER_REQ_GROW_RESOURCES:
  914                 /*
  915                  * Not supported.
  916                  */
  917                 break;
  918         case ADAPTER_REQ_SET_XFER_MODE:
  919                 /*
  920                  * We can't change the transfer mode, but at least let
  921                  * scsipi know what the adapter has negociated.
  922                  */
  923                 /* FIXME: get xfer mode and write it into arg */
  924                 break;
  925         }
  926 }
  927 
  928 int
  929 ciss_intr(void *v)
  930 {
  931         struct ciss_softc *sc = v;
  932         struct ciss_ccb *ccb;
  933         ciss_lock_t lock;
  934         u_int32_t id;
  935         int hit = 0;
  936 
  937         CISS_DPRINTF(CISS_D_INTR, ("intr "));
  938 
  939         if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem))
  940                 return 0;
  941 
  942         lock = CISS_LOCK(sc);
  943         while ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ)) !=
  944             0xffffffff) {
  945 
  946                 ccb = (struct ciss_ccb *) (sc->ccbs + (id >> 2) * sc->ccblen);
  947                 ccb->ccb_cmd.id = htole32(id);
  948                 if (ccb->ccb_state == CISS_CCB_POLL) {
  949                         ccb->ccb_state = CISS_CCB_ONQ;
  950                         wakeup(ccb);
  951                 } else
  952                         ciss_done(ccb);
  953 
  954                 hit = 1;
  955         }
  956         CISS_UNLOCK(sc, lock);
  957 
  958         CISS_DPRINTF(CISS_D_INTR, ("exit\n"));
  959         return hit;
  960 }
  961 
  962 static void
  963 ciss_heartbeat(void *v)
  964 {
  965         struct ciss_softc *sc = v;
  966         u_int32_t hb;
  967 
  968         hb = bus_space_read_4(sc->sc_iot, sc->cfg_ioh,
  969             sc->cfgoff + offsetof(struct ciss_config, heartbeat));
  970         if (hb == sc->heartbeat)
  971                 panic("ciss: dead");    /* XX reset! */
  972         else
  973                 sc->heartbeat = hb;
  974 
  975         callout_schedule(&sc->sc_hb, hz * 3);
  976 }
  977 
  978 #if 0
  979 static void
  980 ciss_kthread(void *v)
  981 {
  982         struct ciss_softc *sc = v;
  983         ciss_lock_t lock;
  984 
  985         for (;;) {
  986                 tsleep(sc, PRIBIO, sc->sc_dev.dv_xname, 0);
  987 
  988                 lock = CISS_LOCK(sc);
  989 
  990 
  991 
  992                 CISS_UNLOCK(sc, lock);
  993         }
  994 }
  995 #endif
  996 
  997 static int
  998 ciss_scsi_ioctl(struct scsipi_channel *chan, u_long cmd,
  999     caddr_t addr, int flag, struct proc *p)
 1000 {
 1001 #if NBIO > 0
 1002         return ciss_ioctl(chan->chan_adapter->adapt_dev, cmd, addr);
 1003 #else
 1004         return ENOTTY;
 1005 #endif
 1006 }
 1007 
 1008 #if NBIO > 0
 1009 static int
 1010 ciss_ioctl(struct device *dev, u_long cmd, caddr_t addr)        /* TODO */
 1011 {
 1012         /* struct ciss_softc *sc = (struct ciss_softc *)dev; */
 1013         ciss_lock_t lock;
 1014         int error;
 1015 
 1016         lock = CISS_LOCK(sc);
 1017         switch (cmd) {
 1018         case BIOCINQ:
 1019         case BIOCVOL:
 1020         case BIOCDISK:
 1021         case BIOCALARM:
 1022         case BIOCBLINK:
 1023         case BIOCSETSTATE:
 1024         default:
 1025                 CISS_DPRINTF(CISS_D_IOCTL, ("%s: invalid ioctl\n",
 1026                     sc->sc_dev.dv_xname));
 1027                 error = ENOTTY;
 1028         }
 1029         CISS_UNLOCK(sc, lock);
 1030 
 1031         return error;
 1032 }
 1033 #endif

Cache object: e0ed36d1a127713df3c676b2a9a1ab0c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.