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/i2o/ld_iop.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ld_iop.c,v 1.16 2005/02/27 00:27:00 perry Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * I2O front-end for ld(4) driver, supporting random block storage class
   41  * devices.  Currently, this doesn't handle anything more complex than
   42  * fixed direct-access devices.
   43  */
   44 
   45 #include <sys/cdefs.h>
   46 __KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.16 2005/02/27 00:27:00 perry Exp $");
   47 
   48 #include "opt_i2o.h"
   49 #include "rnd.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/kernel.h>
   54 #include <sys/device.h>
   55 #include <sys/buf.h>
   56 #include <sys/bufq.h>
   57 #include <sys/endian.h>
   58 #include <sys/dkio.h>
   59 #include <sys/disk.h>
   60 #include <sys/proc.h>
   61 #if NRND > 0
   62 #include <sys/rnd.h>
   63 #endif
   64 
   65 #include <machine/bus.h>
   66 
   67 #include <dev/ldvar.h>
   68 
   69 #include <dev/i2o/i2o.h>
   70 #include <dev/i2o/iopio.h>
   71 #include <dev/i2o/iopvar.h>
   72 
   73 #define LD_IOP_TIMEOUT          30*1000
   74 
   75 #define LD_IOP_CLAIMED          0x01
   76 #define LD_IOP_NEW_EVTMASK      0x02
   77 
   78 struct ld_iop_softc {
   79         struct  ld_softc sc_ld;
   80         struct  iop_initiator sc_ii;
   81         struct  iop_initiator sc_eventii;
   82         int     sc_flags;
   83 };
   84 
   85 static void     ld_iop_adjqparam(struct device *, int);
   86 static void     ld_iop_attach(struct device *, struct device *, void *);
   87 static int      ld_iop_detach(struct device *, int);
   88 static int      ld_iop_dump(struct ld_softc *, void *, int, int);
   89 static int      ld_iop_flush(struct ld_softc *);
   90 static void     ld_iop_intr(struct device *, struct iop_msg *, void *);
   91 static void     ld_iop_intr_event(struct device *, struct iop_msg *, void *);
   92 static int      ld_iop_match(struct device *, struct cfdata *, void *);
   93 static int      ld_iop_start(struct ld_softc *, struct buf *);
   94 static void     ld_iop_unconfig(struct ld_iop_softc *, int);
   95 
   96 CFATTACH_DECL(ld_iop, sizeof(struct ld_iop_softc),
   97     ld_iop_match, ld_iop_attach, ld_iop_detach, NULL);
   98 
   99 #ifdef I2OVERBOSE
  100 static const char * const ld_iop_errors[] = {
  101         "success",
  102         "media error",
  103         "access error",
  104         "device failure",
  105         "device not ready",
  106         "media not present",
  107         "media locked",
  108         "media failure",
  109         "protocol failure",
  110         "bus failure",
  111         "access violation",
  112         "media write protected",
  113         "device reset",
  114         "volume changed, waiting for acknowledgement",
  115         "timeout",
  116 };
  117 #endif
  118 
  119 static int
  120 ld_iop_match(struct device *parent, struct cfdata *match, void *aux)
  121 {
  122         struct iop_attach_args *ia;
  123 
  124         ia = aux;
  125 
  126         return (ia->ia_class == I2O_CLASS_RANDOM_BLOCK_STORAGE);
  127 }
  128 
  129 static void
  130 ld_iop_attach(struct device *parent, struct device *self, void *aux)
  131 {
  132         struct iop_attach_args *ia;
  133         struct ld_softc *ld;
  134         struct ld_iop_softc *sc;
  135         struct iop_softc *iop;
  136         int rv, evreg, enable;
  137         char *typestr, *fixedstr;
  138         u_int cachesz;
  139         u_int32_t timeoutbase, rwvtimeoutbase, rwvtimeout;
  140         struct {
  141                 struct  i2o_param_op_results pr;
  142                 struct  i2o_param_read_results prr;
  143                 union {
  144                         struct  i2o_param_rbs_cache_control cc;
  145                         struct  i2o_param_rbs_device_info bdi;
  146                 } p;
  147         } __attribute__ ((__packed__)) param;
  148 
  149         sc = (struct ld_iop_softc *)self;
  150         ld = &sc->sc_ld;
  151         iop = (struct iop_softc *)parent;
  152         ia = (struct iop_attach_args *)aux;
  153         evreg = 0;
  154 
  155         /* Register us as an initiator. */
  156         sc->sc_ii.ii_dv = self;
  157         sc->sc_ii.ii_intr = ld_iop_intr;
  158         sc->sc_ii.ii_adjqparam = ld_iop_adjqparam;
  159         sc->sc_ii.ii_flags = 0;
  160         sc->sc_ii.ii_tid = ia->ia_tid;
  161         iop_initiator_register(iop, &sc->sc_ii);
  162 
  163         /* Register another initiator to handle events from the device. */
  164         sc->sc_eventii.ii_dv = self;
  165         sc->sc_eventii.ii_intr = ld_iop_intr_event;
  166         sc->sc_eventii.ii_flags = II_NOTCTX | II_UTILITY;
  167         sc->sc_eventii.ii_tid = ia->ia_tid;
  168         iop_initiator_register(iop, &sc->sc_eventii);
  169 
  170         rv = iop_util_eventreg(iop, &sc->sc_eventii,
  171             I2O_EVENT_GEN_EVENT_MASK_MODIFIED |
  172             I2O_EVENT_GEN_DEVICE_RESET |
  173             I2O_EVENT_GEN_STATE_CHANGE |
  174             I2O_EVENT_GEN_GENERAL_WARNING);
  175         if (rv != 0) {
  176                 printf("%s: unable to register for events", self->dv_xname);
  177                 goto bad;
  178         }
  179         evreg = 1;
  180 
  181         /*
  182          * Start out with one queued command.  The `iop' driver will adjust
  183          * the queue parameters once we're up and running.
  184          */
  185         ld->sc_maxqueuecnt = 1;
  186 
  187         ld->sc_maxxfer = IOP_MAX_XFER;
  188         ld->sc_dump = ld_iop_dump;
  189         ld->sc_flush = ld_iop_flush;
  190         ld->sc_start = ld_iop_start;
  191 
  192         /* Say what the device is. */
  193         printf(":");
  194         iop_print_ident(iop, ia->ia_tid);
  195 
  196         /*
  197          * Claim the device so that we don't get any nasty surprises.  Allow
  198          * failure.
  199          */
  200         rv = iop_util_claim(iop, &sc->sc_ii, 0,
  201             I2O_UTIL_CLAIM_CAPACITY_SENSITIVE |
  202             I2O_UTIL_CLAIM_NO_PEER_SERVICE |
  203             I2O_UTIL_CLAIM_NO_MANAGEMENT_SERVICE |
  204             I2O_UTIL_CLAIM_PRIMARY_USER);
  205         sc->sc_flags = rv ? 0 : LD_IOP_CLAIMED;
  206 
  207         rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_RBS_DEVICE_INFO,
  208             &param, sizeof(param), NULL);
  209         if (rv != 0)
  210                 goto bad;
  211 
  212         ld->sc_secsize = le32toh(param.p.bdi.blocksize);
  213         ld->sc_secperunit = (int)
  214             (le64toh(param.p.bdi.capacity) / ld->sc_secsize);
  215 
  216         switch (param.p.bdi.type) {
  217         case I2O_RBS_TYPE_DIRECT:
  218                 typestr = "direct access";
  219                 enable = 1;
  220                 break;
  221         case I2O_RBS_TYPE_WORM:
  222                 typestr = "WORM";
  223                 enable = 0;
  224                 break;
  225         case I2O_RBS_TYPE_CDROM:
  226                 typestr = "CD-ROM";
  227                 enable = 0;
  228                 break;
  229         case I2O_RBS_TYPE_OPTICAL:
  230                 typestr = "optical";
  231                 enable = 0;
  232                 break;
  233         default:
  234                 typestr = "unknown";
  235                 enable = 0;
  236                 break;
  237         }
  238 
  239         if ((le32toh(param.p.bdi.capabilities) & I2O_RBS_CAP_REMOVABLE_MEDIA)
  240             != 0) {
  241                 /* ld->sc_flags = LDF_REMOVABLE; */
  242                 fixedstr = "removable";
  243                 enable = 0;
  244         } else
  245                 fixedstr = "fixed";
  246 
  247         printf(" %s, %s", typestr, fixedstr);
  248 
  249         /*
  250          * Determine if the device has an private cache.  If so, print the
  251          * cache size.  Even if the device doesn't appear to have a cache,
  252          * we perform a flush at shutdown.
  253          */
  254         rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_RBS_CACHE_CONTROL,
  255             &param, sizeof(param), NULL);
  256         if (rv != 0)
  257                 goto bad;
  258 
  259         if ((cachesz = le32toh(param.p.cc.totalcachesize)) != 0)
  260                 printf(", %dkB cache", cachesz >> 10);
  261 
  262         printf("\n");
  263 
  264         /*
  265          * Configure the DDM's timeout functions to time out all commands
  266          * after 30 seconds.
  267          */
  268         timeoutbase = htole32(LD_IOP_TIMEOUT * 1000);
  269         rwvtimeoutbase = htole32(LD_IOP_TIMEOUT * 1000);
  270         rwvtimeout = 0;
  271 
  272         iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
  273             &timeoutbase, sizeof(timeoutbase),
  274             I2O_PARAM_RBS_OPERATION_timeoutbase);
  275         iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
  276             &rwvtimeoutbase, sizeof(rwvtimeoutbase),
  277             I2O_PARAM_RBS_OPERATION_rwvtimeoutbase);
  278         iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
  279             &rwvtimeout, sizeof(rwvtimeout),
  280             I2O_PARAM_RBS_OPERATION_rwvtimeoutbase);
  281 
  282         if (enable)
  283                 ld->sc_flags |= LDF_ENABLED;
  284         else
  285                 printf("%s: device not yet supported\n", self->dv_xname);
  286 
  287         ldattach(ld);
  288         return;
  289 
  290  bad:
  291         ld_iop_unconfig(sc, evreg);
  292 }
  293 
  294 static void
  295 ld_iop_unconfig(struct ld_iop_softc *sc, int evreg)
  296 {
  297         struct iop_softc *iop;
  298         int s;
  299 
  300         iop = (struct iop_softc *)sc->sc_ld.sc_dv.dv_parent;
  301 
  302         if ((sc->sc_flags & LD_IOP_CLAIMED) != 0)
  303                 iop_util_claim(iop, &sc->sc_ii, 1,
  304                     I2O_UTIL_CLAIM_PRIMARY_USER);
  305 
  306         if (evreg) {
  307                 /*
  308                  * Mask off events, and wait up to 5 seconds for a reply.
  309                  * Note that some adapters won't reply to this (XXX We
  310                  * should check the event capabilities).
  311                  */
  312                 sc->sc_flags &= ~LD_IOP_NEW_EVTMASK;
  313                 iop_util_eventreg(iop, &sc->sc_eventii,
  314                     I2O_EVENT_GEN_EVENT_MASK_MODIFIED);
  315                 s = splbio();
  316                 if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0)
  317                         tsleep(&sc->sc_eventii, PRIBIO, "ld_iopevt", hz * 5);
  318                 splx(s);
  319 #ifdef I2ODEBUG
  320                 if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0)
  321                         printf("%s: didn't reply to event unregister",
  322                             sc->sc_ld.sc_dv.dv_xname);
  323 #endif
  324         }
  325 
  326         iop_initiator_unregister(iop, &sc->sc_eventii);
  327         iop_initiator_unregister(iop, &sc->sc_ii);
  328 }
  329 
  330 static int
  331 ld_iop_detach(struct device *self, int flags)
  332 {
  333         struct ld_iop_softc *sc;
  334         struct iop_softc *iop;
  335         int rv;
  336 
  337         sc = (struct ld_iop_softc *)self;
  338         iop = (struct iop_softc *)self->dv_parent;
  339 
  340         if ((rv = ldbegindetach(&sc->sc_ld, flags)) != 0)
  341                 return (rv);
  342 
  343         /*
  344          * Abort any requests queued with the IOP, but allow requests that
  345          * are already in progress to complete.
  346          */
  347         if ((sc->sc_ld.sc_flags & LDF_ENABLED) != 0)
  348                 iop_util_abort(iop, &sc->sc_ii, 0, 0,
  349                     I2O_UTIL_ABORT_WILD | I2O_UTIL_ABORT_CLEAN);
  350 
  351         ldenddetach(&sc->sc_ld);
  352 
  353         /* Un-claim the target, and un-register our initiators. */
  354         if ((sc->sc_ld.sc_flags & LDF_ENABLED) != 0)
  355                 ld_iop_unconfig(sc, 1);
  356 
  357         return (0);
  358 }
  359 
  360 static int
  361 ld_iop_start(struct ld_softc *ld, struct buf *bp)
  362 {
  363         struct iop_msg *im;
  364         struct iop_softc *iop;
  365         struct ld_iop_softc *sc;
  366         struct i2o_rbs_block_read *mf;
  367         u_int rv, flags, write;
  368         u_int64_t ba;
  369         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
  370 
  371         sc = (struct ld_iop_softc *)ld;
  372         iop = (struct iop_softc *)ld->sc_dv.dv_parent;
  373 
  374         im = iop_msg_alloc(iop, 0);
  375         im->im_dvcontext = bp;
  376 
  377         write = ((bp->b_flags & B_READ) == 0);
  378         ba = (u_int64_t)bp->b_rawblkno * ld->sc_secsize;
  379 
  380         /*
  381          * Write through the cache when performing synchronous writes.  When
  382          * performing a read, we don't request that the DDM cache the data,
  383          * as there's little advantage to it.
  384          */
  385         if (write) {
  386                 if ((bp->b_flags & B_ASYNC) == 0)
  387                         flags = I2O_RBS_BLOCK_WRITE_CACHE_WT;
  388                 else
  389                         flags = I2O_RBS_BLOCK_WRITE_CACHE_WB;
  390         } else
  391                 flags = 0;
  392 
  393         /*
  394          * Fill the message frame.  We can use the block_read structure for
  395          * both reads and writes, as it's almost identical to the
  396          * block_write structure.
  397          */
  398         mf = (struct i2o_rbs_block_read *)mb;
  399         mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_read);
  400         mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid,
  401             write ? I2O_RBS_BLOCK_WRITE : I2O_RBS_BLOCK_READ);
  402         mf->msgictx = sc->sc_ii.ii_ictx;
  403         mf->msgtctx = im->im_tctx;
  404         mf->flags = flags | (1 << 16);          /* flags & time multiplier */
  405         mf->datasize = bp->b_bcount;
  406         mf->lowoffset = (u_int32_t)ba;
  407         mf->highoffset = (u_int32_t)(ba >> 32);
  408 
  409         /* Map the data transfer and enqueue the command. */
  410         rv = iop_msg_map_bio(iop, im, mb, bp->b_data, bp->b_bcount, write);
  411         if (rv == 0) {
  412                 if ((rv = iop_post(iop, mb)) != 0) {
  413                         iop_msg_unmap(iop, im);
  414                         iop_msg_free(iop, im);
  415                 }
  416         }
  417         return (rv);
  418 }
  419 
  420 static int
  421 ld_iop_dump(struct ld_softc *ld, void *data, int blkno, int blkcnt)
  422 {
  423         struct iop_msg *im;
  424         struct iop_softc *iop;
  425         struct ld_iop_softc *sc;
  426         struct i2o_rbs_block_write *mf;
  427         int rv, bcount;
  428         u_int64_t ba;
  429         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
  430 
  431         sc = (struct ld_iop_softc *)ld;
  432         iop = (struct iop_softc *)ld->sc_dv.dv_parent;
  433         bcount = blkcnt * ld->sc_secsize;
  434         ba = (u_int64_t)blkno * ld->sc_secsize;
  435         im = iop_msg_alloc(iop, IM_POLL);
  436 
  437         mf = (struct i2o_rbs_block_write *)mb;
  438         mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_write);
  439         mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_RBS_BLOCK_WRITE);
  440         mf->msgictx = sc->sc_ii.ii_ictx;
  441         mf->msgtctx = im->im_tctx;
  442         mf->flags = I2O_RBS_BLOCK_WRITE_CACHE_WT | (1 << 16);
  443         mf->datasize = bcount;
  444         mf->lowoffset = (u_int32_t)ba;
  445         mf->highoffset = (u_int32_t)(ba >> 32);
  446 
  447         if ((rv = iop_msg_map(iop, im, mb, data, bcount, 1, NULL)) != 0) {
  448                 iop_msg_free(iop, im);
  449                 return (rv);
  450         }
  451 
  452         rv = iop_msg_post(iop, im, mb, LD_IOP_TIMEOUT * 2);
  453         iop_msg_unmap(iop, im);
  454         iop_msg_free(iop, im);
  455         return (rv);
  456 }
  457 
  458 static int
  459 ld_iop_flush(struct ld_softc *ld)
  460 {
  461         struct iop_msg *im;
  462         struct iop_softc *iop;
  463         struct ld_iop_softc *sc;
  464         struct i2o_rbs_cache_flush mf;
  465         int rv;
  466 
  467         sc = (struct ld_iop_softc *)ld;
  468         iop = (struct iop_softc *)ld->sc_dv.dv_parent;
  469         im = iop_msg_alloc(iop, IM_WAIT);
  470 
  471         mf.msgflags = I2O_MSGFLAGS(i2o_rbs_cache_flush);
  472         mf.msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_RBS_CACHE_FLUSH);
  473         mf.msgictx = sc->sc_ii.ii_ictx;
  474         mf.msgtctx = im->im_tctx;
  475         mf.flags = 1 << 16;                     /* time multiplier */
  476 
  477         /* XXX Aincent disks will return an error here. */
  478         rv = iop_msg_post(iop, im, &mf, LD_IOP_TIMEOUT * 2);
  479         iop_msg_free(iop, im);
  480         return (rv);
  481 }
  482 
  483 void
  484 ld_iop_intr(struct device *dv, struct iop_msg *im, void *reply)
  485 {
  486         struct i2o_rbs_reply *rb;
  487         struct buf *bp;
  488         struct ld_iop_softc *sc;
  489         struct iop_softc *iop;
  490         int err, detail;
  491 #ifdef I2OVERBOSE
  492         const char *errstr;
  493 #endif
  494 
  495         rb = reply;
  496         bp = im->im_dvcontext;
  497         sc = (struct ld_iop_softc *)dv;
  498         iop = (struct iop_softc *)dv->dv_parent;
  499 
  500         err = ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0);
  501 
  502         if (!err && rb->reqstatus != I2O_STATUS_SUCCESS) {
  503                 detail = le16toh(rb->detail);
  504 #ifdef I2OVERBOSE
  505                 if (detail > sizeof(ld_iop_errors) / sizeof(ld_iop_errors[0]))
  506                         errstr = "<unknown>";
  507                 else
  508                         errstr = ld_iop_errors[detail];
  509                 printf("%s: error 0x%04x: %s\n", dv->dv_xname, detail, errstr);
  510 #else
  511                 printf("%s: error 0x%04x\n", dv->dv_xname, detail);
  512 #endif
  513                 err = 1;
  514         }
  515 
  516         if (err) {
  517                 bp->b_flags |= B_ERROR;
  518                 bp->b_error = EIO;
  519                 bp->b_resid = bp->b_bcount;
  520         } else
  521                 bp->b_resid = bp->b_bcount - le32toh(rb->transfercount);
  522 
  523         iop_msg_unmap(iop, im);
  524         iop_msg_free(iop, im);
  525         lddone(&sc->sc_ld, bp);
  526 }
  527 
  528 static void
  529 ld_iop_intr_event(struct device *dv, struct iop_msg *im, void *reply)
  530 {
  531         struct i2o_util_event_register_reply *rb;
  532         struct ld_iop_softc *sc;
  533         u_int event;
  534 
  535         rb = reply;
  536 
  537         if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
  538                 return;
  539 
  540         event = le32toh(rb->event);
  541         sc = (struct ld_iop_softc *)dv;
  542 
  543         if (event == I2O_EVENT_GEN_EVENT_MASK_MODIFIED) {
  544                 sc->sc_flags |= LD_IOP_NEW_EVTMASK;
  545                 wakeup(&sc->sc_eventii);
  546 #ifndef I2ODEBUG
  547                 return;
  548 #endif
  549         }
  550 
  551         printf("%s: event 0x%08x received\n", dv->dv_xname, event);
  552 }
  553 
  554 static void
  555 ld_iop_adjqparam(struct device *dv, int mpi)
  556 {
  557         struct iop_softc *iop;
  558 
  559         /*
  560          * AMI controllers seem to loose the plot if you hand off lots of
  561          * queued commands.
  562          */
  563         iop = (struct iop_softc *)dv->dv_parent;
  564         if (le16toh(I2O_ORG_AMI) == iop->sc_status.orgid && mpi > 64)
  565                 mpi = 64;
  566 
  567         ldadjqparam((struct ld_softc *)dv, mpi);
  568 }

Cache object: 3514d6a9ec6f37186f1171f68453ca27


[ 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.