root/dev/i2o/iop.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iop_inl
  2. iop_outl
  3. iop_init
  4. iop_config_interrupts
  5. iop_create_reconf_thread
  6. iop_reconf_thread
  7. iop_reconfigure
  8. iop_configure_devices
  9. iop_adjqparam
  10. iop_devinfo
  11. iop_print
  12. iop_vendor_print
  13. iop_submatch
  14. iop_shutdown
  15. iop_status_get
  16. iop_ofifo_init
  17. iop_hrt_get0
  18. iop_hrt_get
  19. iop_lct_get0
  20. iop_lct_get
  21. iop_param_op
  22. iop_simple_cmd
  23. iop_systab_set
  24. iop_reset
  25. iop_initiator_register
  26. iop_initiator_unregister
  27. iop_handle_reply
  28. iop_intr
  29. iop_intr_event
  30. iop_msg_alloc
  31. iop_msg_free
  32. iop_msg_map
  33. iop_msg_map_bio
  34. iop_msg_unmap
  35. iop_post
  36. iop_msg_post
  37. iop_msg_poll
  38. iop_msg_wait
  39. iop_release_mfa
  40. iop_reply_print
  41. iop_tfn_print
  42. iop_strvis
  43. iop_print_ident
  44. iop_util_claim
  45. iop_util_abort
  46. iop_util_eventreg
  47. iopopen
  48. iopclose
  49. iopioctl
  50. iop_passthrough

    1 /*      $OpenBSD: iop.c,v 1.29 2006/11/29 12:24:17 miod Exp $   */
    2 /*      $NetBSD: iop.c,v 1.12 2001/03/21 14:27:05 ad Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Andrew Doran.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Support for I2O IOPs (intelligent I/O processors).
   42  */
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/device.h>
   48 #include <sys/queue.h>
   49 #include <sys/proc.h>
   50 #include <sys/malloc.h>
   51 #include <sys/ioctl.h>
   52 #include <sys/endian.h>
   53 #include <sys/conf.h>
   54 #include <sys/kthread.h>
   55 
   56 #include <uvm/uvm_extern.h>
   57 
   58 #include <machine/bus.h>
   59 
   60 #include <dev/i2o/i2o.h>
   61 #include <dev/i2o/iopio.h>
   62 #include <dev/i2o/iopreg.h>
   63 #include <dev/i2o/iopvar.h>
   64 
   65 #define POLL(ms, cond)                          \
   66 do {                                            \
   67         int i;                                  \
   68         for (i = (ms) * 10; i; i--) {           \
   69                 if (cond)                       \
   70                         break;                  \
   71                 DELAY(100);                     \
   72         }                                       \
   73 } while (/* CONSTCOND */0);
   74 
   75 #ifdef I2ODEBUG
   76 #define DPRINTF(x)      printf x
   77 #else
   78 #define DPRINTF(x)
   79 #endif
   80 
   81 #ifdef I2OVERBOSE
   82 #define IFVERBOSE(x)    x
   83 #define COMMENT(x)      NULL
   84 #else
   85 #define IFVERBOSE(x)
   86 #define COMMENT(x)
   87 #endif
   88 
   89 #define IOP_ICTXHASH_NBUCKETS   16
   90 #define IOP_ICTXHASH(ictx)      (&iop_ictxhashtbl[(ictx) & iop_ictxhash])
   91 
   92 #define IOP_MAX_SEGS    (((IOP_MAX_XFER + PAGE_SIZE - 1) / PAGE_SIZE) + 1)
   93 
   94 #define IOP_TCTX_SHIFT  12
   95 #define IOP_TCTX_MASK   ((1 << IOP_TCTX_SHIFT) - 1)
   96 
   97 LIST_HEAD(, iop_initiator) *iop_ictxhashtbl;
   98 u_long  iop_ictxhash;
   99 void    *iop_sdh;
  100 struct  i2o_systab *iop_systab;
  101 int     iop_systab_size;
  102 
  103 struct cfdriver iop_cd = {
  104         NULL, "iop", DV_DULL
  105 };
  106 
  107 #define IC_CONFIGURE    0x01
  108 #define IC_PRIORITY     0x02
  109 
  110 struct iop_class {
  111         u_short ic_class;
  112         u_short ic_flags;
  113 #ifdef I2OVERBOSE
  114         const char      *ic_caption;
  115 #endif
  116 } static const iop_class[] = {
  117         {       
  118                 I2O_CLASS_EXECUTIVE,
  119                 0,
  120                 COMMENT("executive")
  121         },
  122         {
  123                 I2O_CLASS_DDM,
  124                 0,
  125                 COMMENT("device driver module")
  126         },
  127         {
  128                 I2O_CLASS_RANDOM_BLOCK_STORAGE,
  129                 IC_CONFIGURE | IC_PRIORITY,
  130                 IFVERBOSE("random block storage")
  131         },
  132         {
  133                 I2O_CLASS_SEQUENTIAL_STORAGE,
  134                 IC_CONFIGURE | IC_PRIORITY,
  135                 IFVERBOSE("sequential storage")
  136         },
  137         {
  138                 I2O_CLASS_LAN,
  139                 IC_CONFIGURE | IC_PRIORITY,
  140                 IFVERBOSE("LAN port")
  141         },
  142         {
  143                 I2O_CLASS_WAN,
  144                 IC_CONFIGURE | IC_PRIORITY,
  145                 IFVERBOSE("WAN port")
  146         },
  147         {
  148                 I2O_CLASS_FIBRE_CHANNEL_PORT,
  149                 IC_CONFIGURE,
  150                 IFVERBOSE("fibrechannel port")
  151         },
  152         {
  153                 I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL,
  154                 0,
  155                 COMMENT("fibrechannel peripheral")
  156         },
  157         {
  158                 I2O_CLASS_SCSI_PERIPHERAL,
  159                 0,
  160                 COMMENT("SCSI peripheral")
  161         },
  162         {
  163                 I2O_CLASS_ATE_PORT,
  164                 IC_CONFIGURE,
  165                 IFVERBOSE("ATE port")
  166         },
  167         {       
  168                 I2O_CLASS_ATE_PERIPHERAL,
  169                 0,
  170                 COMMENT("ATE peripheral")
  171         },
  172         {       
  173                 I2O_CLASS_FLOPPY_CONTROLLER,
  174                 IC_CONFIGURE,
  175                 IFVERBOSE("floppy controller")
  176         },
  177         {
  178                 I2O_CLASS_FLOPPY_DEVICE,
  179                 0,
  180                 COMMENT("floppy device")
  181         },
  182         {
  183                 I2O_CLASS_BUS_ADAPTER_PORT,
  184                 IC_CONFIGURE,
  185                 IFVERBOSE("bus adapter port" )
  186         },
  187 };
  188 
  189 #if defined(I2ODEBUG) && defined(I2OVERBOSE)
  190 static const char * const iop_status[] = {
  191         "success",
  192         "abort (dirty)",
  193         "abort (no data transfer)",
  194         "abort (partial transfer)",
  195         "error (dirty)",
  196         "error (no data transfer)",
  197         "error (partial transfer)",
  198         "undefined error code",
  199         "process abort (dirty)",
  200         "process abort (no data transfer)",
  201         "process abort (partial transfer)",
  202         "transaction error",
  203 };
  204 #endif
  205 
  206 static inline u_int32_t iop_inl(struct iop_softc *, int);
  207 static inline void      iop_outl(struct iop_softc *, int, u_int32_t);
  208 
  209 void    iop_config_interrupts(struct device *);
  210 void    iop_configure_devices(struct iop_softc *, int, int);
  211 void    iop_devinfo(int, char *, size_t);
  212 int     iop_print(void *, const char *);
  213 int     iop_reconfigure(struct iop_softc *, u_int);
  214 void    iop_shutdown(void *);
  215 int     iop_submatch(struct device *, void *, void *);
  216 #ifdef notyet
  217 int     iop_vendor_print(void *, const char *);
  218 #endif
  219 
  220 void    iop_adjqparam(struct iop_softc *, int);
  221 void    iop_create_reconf_thread(void *);
  222 int     iop_handle_reply(struct iop_softc *, u_int32_t);
  223 int     iop_hrt_get(struct iop_softc *);
  224 int     iop_hrt_get0(struct iop_softc *, struct i2o_hrt *, size_t);
  225 void    iop_intr_event(struct device *, struct iop_msg *, void *);
  226 int     iop_lct_get0(struct iop_softc *, struct i2o_lct *, size_t, u_int32_t);
  227 void    iop_msg_poll(struct iop_softc *, struct iop_msg *, int);
  228 void    iop_msg_wait(struct iop_softc *, struct iop_msg *, int);
  229 int     iop_ofifo_init(struct iop_softc *);
  230 int     iop_passthrough(struct iop_softc *, struct ioppt *);
  231 int     iop_post(struct iop_softc *, u_int32_t *);
  232 void    iop_reconf_thread(void *);
  233 void    iop_release_mfa(struct iop_softc *, u_int32_t);
  234 int     iop_reset(struct iop_softc *);
  235 int     iop_status_get(struct iop_softc *, int);
  236 int     iop_systab_set(struct iop_softc *);
  237 void    iop_tfn_print(struct iop_softc *, struct i2o_fault_notify *);
  238 
  239 #ifdef I2ODEBUG
  240 void    iop_reply_print(struct iop_softc *, struct i2o_reply *);
  241 #endif
  242 
  243 cdev_decl(iop);
  244 
  245 static inline u_int32_t
  246 iop_inl(struct iop_softc *sc, int off)
  247 {
  248 
  249         bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4,
  250             BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
  251         return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, off));
  252 }
  253 
  254 static inline void
  255 iop_outl(struct iop_softc *sc, int off, u_int32_t val)
  256 {
  257 
  258         bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
  259         bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4,
  260             BUS_SPACE_BARRIER_WRITE);
  261 }
  262 
  263 /*
  264  * Initialise the IOP and our interface.
  265  */
  266 void
  267 iop_init(struct iop_softc *sc, const char *intrstr)
  268 {
  269         struct iop_msg *im;
  270         u_int32_t mask;
  271         char ident[64];
  272         int rv, i, nsegs;
  273         int state = 0;
  274 
  275         if (iop_ictxhashtbl == NULL) {
  276                 iop_ictxhashtbl = hashinit(IOP_ICTXHASH_NBUCKETS, M_DEVBUF,
  277                     M_NOWAIT, &iop_ictxhash);
  278                 if (iop_ictxhashtbl == NULL) {
  279                         printf("%s: cannot allocate hashtable\n",
  280                             sc->sc_dv.dv_xname);
  281                         return;
  282                 }
  283         }
  284 
  285         /* Reset the IOP and request status. */
  286         printf("I2O adapter");
  287 
  288         /* Allocate a scratch DMA map for small miscellaneous shared data. */
  289         if (bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
  290             BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_scr_dmamap) != 0) {
  291                 printf("%s: cannot create scratch dmamap\n",
  292                     sc->sc_dv.dv_xname);
  293                 return;
  294         }
  295         state++;
  296 
  297         if (bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
  298             sc->sc_scr_seg, 1, &nsegs, BUS_DMA_NOWAIT) != 0) {
  299                 printf("%s: cannot alloc scratch dmamem\n",
  300                     sc->sc_dv.dv_xname);
  301                 goto bail_out;
  302         }
  303         state++;
  304 
  305         if (bus_dmamem_map(sc->sc_dmat, sc->sc_scr_seg, nsegs, PAGE_SIZE,
  306             &sc->sc_scr, 0)) {
  307                 printf("%s: cannot map scratch dmamem\n", sc->sc_dv.dv_xname);
  308                 goto bail_out;
  309         }
  310         state++;
  311 
  312         if (bus_dmamap_load(sc->sc_dmat, sc->sc_scr_dmamap, sc->sc_scr,
  313             PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) {
  314                 printf("%s: cannot load scratch dmamap\n", sc->sc_dv.dv_xname);
  315                 goto bail_out;
  316         }
  317         state++;
  318 
  319         if ((rv = iop_reset(sc)) != 0) {
  320                 printf("%s: not responding (reset)\n", sc->sc_dv.dv_xname);
  321                 goto bail_out;
  322         }
  323         if ((rv = iop_status_get(sc, 1)) != 0) {
  324                 printf("%s: not responding (get status)\n",
  325                     sc->sc_dv.dv_xname);
  326                 goto bail_out;
  327         }
  328         sc->sc_flags |= IOP_HAVESTATUS;
  329         iop_strvis(sc, sc->sc_status.productid,
  330             sizeof(sc->sc_status.productid), ident, sizeof(ident));
  331         printf(" <%s>\n", ident);
  332 
  333 #ifdef I2ODEBUG
  334         printf("%s: orgid=0x%04x version=%d\n", sc->sc_dv.dv_xname,
  335             letoh16(sc->sc_status.orgid),
  336             (letoh32(sc->sc_status.segnumber) >> 12) & 15);
  337         printf("%s: type want have cbase\n", sc->sc_dv.dv_xname);
  338         printf("%s: mem  %04x %04x %08x\n", sc->sc_dv.dv_xname,
  339             letoh32(sc->sc_status.desiredprivmemsize),
  340             letoh32(sc->sc_status.currentprivmemsize),
  341             letoh32(sc->sc_status.currentprivmembase));
  342         printf("%s: i/o  %04x %04x %08x\n", sc->sc_dv.dv_xname,
  343             letoh32(sc->sc_status.desiredpriviosize),
  344             letoh32(sc->sc_status.currentpriviosize),
  345             letoh32(sc->sc_status.currentpriviobase));
  346 #endif
  347 
  348         sc->sc_maxob = letoh32(sc->sc_status.maxoutboundmframes);
  349         if (sc->sc_maxob > IOP_MAX_OUTBOUND)
  350                 sc->sc_maxob = IOP_MAX_OUTBOUND;
  351         sc->sc_maxib = letoh32(sc->sc_status.maxinboundmframes);
  352         if (sc->sc_maxib > IOP_MAX_INBOUND)
  353                 sc->sc_maxib = IOP_MAX_INBOUND;
  354 
  355         /* Allocate message wrappers. */
  356         im = malloc(sizeof(*im) * sc->sc_maxib, M_DEVBUF, M_NOWAIT);
  357         if (!im) {
  358                 printf("%s: couldn't allocate message", sc->sc_dv.dv_xname);
  359                 goto bail_out;
  360         }
  361         state++;
  362 
  363         bzero(im, sizeof(*im) * sc->sc_maxib);
  364         sc->sc_ims = im;
  365         SLIST_INIT(&sc->sc_im_freelist);
  366 
  367         for (i = 0; i < sc->sc_maxib; i++, im++) {
  368                 rv = bus_dmamap_create(sc->sc_dmat, IOP_MAX_XFER,
  369                     IOP_MAX_SEGS, IOP_MAX_XFER, 0,
  370                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
  371                     &im->im_xfer[0].ix_map);
  372                 if (rv != 0) {
  373                         printf("%s: couldn't create dmamap (%d)",
  374                             sc->sc_dv.dv_xname, rv);
  375                         goto bail_out;
  376                 }
  377 
  378                 im->im_tctx = i;
  379                 SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain);
  380         }
  381 
  382         /* Initalise the IOP's outbound FIFO. */
  383         if (iop_ofifo_init(sc) != 0) {
  384                 printf("%s: unable to init outbound FIFO\n",
  385                     sc->sc_dv.dv_xname);
  386                 goto bail_out;
  387         }
  388 
  389         /* Configure shutdown hook before we start any device activity. */
  390         if (iop_sdh == NULL)
  391                 iop_sdh = shutdownhook_establish(iop_shutdown, NULL);
  392 
  393         /* Ensure interrupts are enabled at the IOP. */
  394         mask = iop_inl(sc, IOP_REG_INTR_MASK);
  395         iop_outl(sc, IOP_REG_INTR_MASK, mask & ~IOP_INTR_OFIFO);
  396 
  397         if (intrstr != NULL)
  398                 printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname,
  399                     intrstr);
  400 
  401 #ifdef I2ODEBUG
  402         printf("%s: queue depths: inbound %d/%d, outbound %d/%d\n",
  403             sc->sc_dv.dv_xname, sc->sc_maxib,
  404             letoh32(sc->sc_status.maxinboundmframes),
  405             sc->sc_maxob, letoh32(sc->sc_status.maxoutboundmframes));
  406 #endif
  407 
  408         lockinit(&sc->sc_conflock, PRIBIO, "iopconf", 0, 0);
  409 
  410         startuphook_establish((void (*)(void *))iop_config_interrupts, sc);
  411         return;
  412 
  413  bail_out:
  414         if (state > 4)
  415                 free(im, M_DEVBUF);
  416         if (state > 3)
  417                 bus_dmamap_unload(sc->sc_dmat, sc->sc_scr_dmamap);
  418         if (state > 2)
  419                 bus_dmamem_unmap(sc->sc_dmat, sc->sc_scr, PAGE_SIZE);
  420         if (state > 1)
  421                 bus_dmamem_free(sc->sc_dmat, sc->sc_scr_seg, nsegs);
  422         if (state > 0)
  423                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_scr_dmamap);
  424 }
  425 
  426 /*
  427  * Perform autoconfiguration tasks.
  428  */
  429 void
  430 iop_config_interrupts(struct device *self)
  431 {
  432         struct iop_softc *sc, *iop;
  433         struct i2o_systab_entry *ste;
  434         int rv, i, niop;
  435 
  436         sc = (struct iop_softc *)self;
  437         LIST_INIT(&sc->sc_iilist);
  438 
  439         printf("%s: configuring...\n", sc->sc_dv.dv_xname);
  440 
  441         if (iop_hrt_get(sc) != 0) {
  442                 printf("%s: unable to retrieve HRT\n", sc->sc_dv.dv_xname);
  443                 return;
  444         }
  445 
  446         /*
  447          * Build the system table.
  448          */
  449         if (iop_systab == NULL) {
  450                 for (i = 0, niop = 0; i < iop_cd.cd_ndevs; i++) {
  451                         iop = (struct iop_softc *)device_lookup(&iop_cd, i);
  452                         if (iop == NULL)
  453                                 continue;
  454                         if ((iop->sc_flags & IOP_HAVESTATUS) == 0)
  455                                 continue;
  456                         if (iop_status_get(iop, 1) != 0) {
  457                                 printf("%s: unable to retrieve status\n",
  458                                     sc->sc_dv.dv_xname);
  459                                 iop->sc_flags &= ~IOP_HAVESTATUS;
  460                                 continue;
  461                         }
  462                         niop++;
  463                 }
  464                 if (niop == 0)
  465                         return;
  466 
  467                 i = sizeof(struct i2o_systab_entry) * (niop - 1) +
  468                     sizeof(struct i2o_systab);
  469                 iop_systab_size = i;
  470                 iop_systab = malloc(i, M_DEVBUF, M_NOWAIT);
  471                 if (!iop_systab)
  472                         return;
  473 
  474                 bzero(iop_systab, i);
  475                 iop_systab->numentries = niop;
  476                 iop_systab->version = I2O_VERSION_11;
  477 
  478                 for (i = 0, ste = iop_systab->entry; i < iop_cd.cd_ndevs; i++)
  479                     {
  480                         iop = (struct iop_softc *)device_lookup(&iop_cd, i);
  481                         if (iop == NULL)
  482                                 continue;
  483                         if ((iop->sc_flags & IOP_HAVESTATUS) == 0)
  484                                 continue;
  485 
  486                         ste->orgid = iop->sc_status.orgid;
  487                         ste->iopid = iop->sc_dv.dv_unit + 2;
  488                         ste->segnumber =
  489                             htole32(letoh32(iop->sc_status.segnumber) & ~4095);
  490                         ste->iopcaps = iop->sc_status.iopcaps;
  491                         ste->inboundmsgframesize =
  492                             iop->sc_status.inboundmframesize;
  493                         ste->inboundmsgportaddresslow =
  494                             htole32(iop->sc_memaddr + IOP_REG_IFIFO);
  495                         ste++;
  496                 }
  497         }
  498 
  499         /*
  500          * Post the system table to the IOP and bring it to the OPERATIONAL
  501          * state.
  502          */
  503         if (iop_systab_set(sc) != 0) {
  504                 printf("%s: unable to set system table\n", sc->sc_dv.dv_xname);
  505                 return;
  506         }
  507         if (iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_SYS_ENABLE, IOP_ICTX, 1,
  508             30000) != 0) {
  509                 printf("%s: unable to enable system\n", sc->sc_dv.dv_xname);
  510                 return;
  511         }
  512 
  513         /*
  514          * Set up an event handler for this IOP.
  515          */
  516         sc->sc_eventii.ii_dv = self;
  517         sc->sc_eventii.ii_intr = iop_intr_event;
  518         sc->sc_eventii.ii_flags = II_DISCARD | II_UTILITY;
  519         sc->sc_eventii.ii_tid = I2O_TID_IOP;
  520         iop_initiator_register(sc, &sc->sc_eventii);
  521 
  522         rv = iop_util_eventreg(sc, &sc->sc_eventii,
  523             I2O_EVENT_EXEC_RESOURCE_LIMITS |
  524             I2O_EVENT_EXEC_CONNECTION_FAIL |
  525             I2O_EVENT_EXEC_ADAPTER_FAULT |
  526             I2O_EVENT_EXEC_POWER_FAIL |
  527             I2O_EVENT_EXEC_RESET_PENDING |
  528             I2O_EVENT_EXEC_RESET_IMMINENT |
  529             I2O_EVENT_EXEC_HARDWARE_FAIL |
  530             I2O_EVENT_EXEC_XCT_CHANGE |
  531             I2O_EVENT_EXEC_DDM_AVAILIBILITY |
  532             I2O_EVENT_GEN_DEVICE_RESET |
  533             I2O_EVENT_GEN_STATE_CHANGE |
  534             I2O_EVENT_GEN_GENERAL_WARNING);
  535         if (rv != 0) {
  536                 printf("%s: unable to register for events",
  537                     sc->sc_dv.dv_xname);
  538                 return;
  539         }
  540 
  541 #ifdef notyet
  542         /* Attempt to match and attach a product-specific extension. */
  543         ia.ia_class = I2O_CLASS_ANY;
  544         ia.ia_tid = I2O_TID_IOP;
  545         config_found_sm(self, &ia, iop_vendor_print, iop_submatch);
  546 #endif
  547 
  548         lockmgr(&sc->sc_conflock, LK_EXCLUSIVE, NULL);
  549         if ((rv = iop_reconfigure(sc, 0)) == -1) {
  550                 printf("%s: configure failed (%d)\n", sc->sc_dv.dv_xname, rv);
  551                 return;
  552         }
  553         lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
  554         kthread_create_deferred(iop_create_reconf_thread, sc);
  555 }
  556 
  557 /*
  558  * Create the reconfiguration thread.  Called after the standard kernel
  559  * threads have been created.
  560  */
  561 void
  562 iop_create_reconf_thread(void *cookie)
  563 {
  564         struct iop_softc *sc;
  565         int rv;
  566 
  567         sc = cookie;
  568         sc->sc_flags |= IOP_ONLINE;
  569 
  570         rv = kthread_create(iop_reconf_thread, sc, &sc->sc_reconf_proc,
  571             "%s", sc->sc_dv.dv_xname);
  572         if (rv != 0) {
  573                 printf("%s: unable to create reconfiguration thread (%d)",
  574                     sc->sc_dv.dv_xname, rv);
  575                 return;
  576         }
  577 }
  578 
  579 /*
  580  * Reconfiguration thread; listens for LCT change notification, and
  581  * initiates re-configuration if received.
  582  */
  583 void
  584 iop_reconf_thread(void *cookie)
  585 {
  586         struct iop_softc *sc = cookie;
  587         struct i2o_lct lct;
  588         u_int32_t chgind;
  589         int rv;
  590 
  591         chgind = sc->sc_chgind + 1;
  592 
  593         for (;;) {
  594                 DPRINTF(("%s: async reconfig: requested 0x%08x\n",
  595                     sc->sc_dv.dv_xname, chgind));
  596 
  597                 rv = iop_lct_get0(sc, &lct, sizeof(lct), chgind);
  598 
  599                 DPRINTF(("%s: async reconfig: notified (0x%08x, %d)\n",
  600                     sc->sc_dv.dv_xname, letoh32(lct.changeindicator), rv));
  601 
  602                 if (rv == 0 &&
  603                     lockmgr(&sc->sc_conflock, LK_EXCLUSIVE, NULL) == 0) {
  604                         iop_reconfigure(sc, letoh32(lct.changeindicator));
  605                         chgind = sc->sc_chgind + 1;
  606                         lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
  607                 }
  608 
  609                 tsleep(iop_reconf_thread, PWAIT, "iopzzz", hz * 5);
  610         }
  611 }
  612 
  613 /*
  614  * Reconfigure: find new and removed devices.
  615  */
  616 int
  617 iop_reconfigure(struct iop_softc *sc, u_int chgind)
  618 {
  619         struct iop_msg *im;
  620         struct i2o_hba_bus_scan mf;
  621         struct i2o_lct_entry *le;
  622         struct iop_initiator *ii, *nextii;
  623         int rv, tid, i;
  624 
  625         /*
  626          * If the reconfiguration request isn't the result of LCT change
  627          * notification, then be more thorough: ask all bus ports to scan
  628          * their busses.  Wait up to 5 minutes for each bus port to complete
  629          * the request.
  630          */
  631         if (chgind == 0) {
  632                 if ((rv = iop_lct_get(sc)) != 0) {
  633                         DPRINTF(("iop_reconfigure: unable to read LCT\n"));
  634                         return (rv);
  635                 }
  636 
  637                 le = sc->sc_lct->entry;
  638                 for (i = 0; i < sc->sc_nlctent; i++, le++) {
  639                         if ((letoh16(le->classid) & I2O_CLASS_MASK) !=
  640                             I2O_CLASS_BUS_ADAPTER_PORT)
  641                                 continue;
  642                         tid = letoh16(le->localtid) & I2O_CLASS_MASK;
  643 
  644                         im = iop_msg_alloc(sc, NULL, IM_WAIT);
  645 
  646                         mf.msgflags = I2O_MSGFLAGS(i2o_hba_bus_scan);
  647                         mf.msgfunc = I2O_MSGFUNC(tid, I2O_HBA_BUS_SCAN);
  648                         mf.msgictx = IOP_ICTX;
  649                         mf.msgtctx = im->im_tctx;
  650 
  651                         DPRINTF(("%s: scanning bus %d\n", sc->sc_dv.dv_xname,
  652                             tid));
  653 
  654                         rv = iop_msg_post(sc, im, &mf, 5*60*1000);
  655                         iop_msg_free(sc, im);
  656 #ifdef I2ODEBUG
  657                         if (rv != 0)
  658                                 printf("%s: bus scan failed, status =%d\n",
  659                                     sc->sc_dv.dv_xname, rv);
  660 #endif
  661                 }
  662         } else if (chgind <= sc->sc_chgind) {
  663                 DPRINTF(("%s: LCT unchanged (async)\n", sc->sc_dv.dv_xname));
  664                 return (0);
  665         }
  666 
  667         /* Re-read the LCT and determine if it has changed. */
  668         if ((rv = iop_lct_get(sc)) != 0) {
  669                 DPRINTF(("iop_reconfigure: unable to re-read LCT\n"));
  670                 return (rv);
  671         }
  672         DPRINTF(("%s: %d LCT entries\n", sc->sc_dv.dv_xname, sc->sc_nlctent));
  673 
  674         chgind = letoh32(sc->sc_lct->changeindicator);
  675         if (chgind == sc->sc_chgind) {
  676                 DPRINTF(("%s: LCT unchanged\n", sc->sc_dv.dv_xname));
  677                 return (0);
  678         }
  679         DPRINTF(("%s: LCT changed\n", sc->sc_dv.dv_xname));
  680         sc->sc_chgind = chgind;
  681 
  682         if (sc->sc_tidmap != NULL)
  683                 free(sc->sc_tidmap, M_DEVBUF);
  684         sc->sc_tidmap = malloc(sc->sc_nlctent * sizeof(struct iop_tidmap),
  685             M_DEVBUF, M_NOWAIT);
  686         if (!sc->sc_tidmap) {
  687                 DPRINTF(("iop_reconfigure: out of memory\n"));
  688                 return (ENOMEM);
  689         }
  690         bzero(sc->sc_tidmap, sc->sc_nlctent * sizeof(struct iop_tidmap));
  691 
  692         /* Allow 1 queued command per device while we're configuring. */
  693         iop_adjqparam(sc, 1);
  694 
  695         /*
  696          * Match and attach child devices.  We configure high-level devices
  697          * first so that any claims will propagate throughout the LCT,
  698          * hopefully masking off aliased devices as a result.
  699          *
  700          * Re-reading the LCT at this point is a little dangerous, but we'll
  701          * trust the IOP (and the operator) to behave itself...
  702          */
  703         iop_configure_devices(sc, IC_CONFIGURE | IC_PRIORITY,
  704             IC_CONFIGURE | IC_PRIORITY);
  705         if ((rv = iop_lct_get(sc)) != 0)
  706                 DPRINTF(("iop_reconfigure: unable to re-read LCT\n"));
  707         iop_configure_devices(sc, IC_CONFIGURE | IC_PRIORITY,
  708             IC_CONFIGURE);
  709 
  710         for (ii = LIST_FIRST(&sc->sc_iilist); ii != NULL; ii = nextii) {
  711                 nextii = LIST_NEXT(ii, ii_list);
  712 
  713                 /* Detach devices that were configured, but are now gone. */
  714                 for (i = 0; i < sc->sc_nlctent; i++)
  715                         if (ii->ii_tid == sc->sc_tidmap[i].it_tid)
  716                                 break;
  717                 if (i == sc->sc_nlctent ||
  718                     (sc->sc_tidmap[i].it_flags & IT_CONFIGURED) == 0)
  719                         config_detach(ii->ii_dv, DETACH_FORCE);
  720 
  721                 /*
  722                  * Tell initiators that existed before the re-configuration
  723                  * to re-configure.
  724                  */
  725                 if (ii->ii_reconfig == NULL)
  726                         continue;
  727                 if ((rv = (*ii->ii_reconfig)(ii->ii_dv)) != 0)
  728                         printf("%s: %s failed reconfigure (%d)\n",
  729                             sc->sc_dv.dv_xname, ii->ii_dv->dv_xname, rv);
  730         }
  731 
  732         /* Re-adjust queue parameters and return. */
  733         if (sc->sc_nii != 0)
  734                 iop_adjqparam(sc, (sc->sc_maxib - sc->sc_nuii - IOP_MF_RESERVE)
  735                     / sc->sc_nii);
  736 
  737         return (0);
  738 }
  739 
  740 /*
  741  * Configure I2O devices into the system.
  742  */
  743 void
  744 iop_configure_devices(struct iop_softc *sc, int mask, int maskval)
  745 {
  746         struct iop_attach_args ia;
  747         struct iop_initiator *ii;
  748         const struct i2o_lct_entry *le;
  749         struct device *dv;
  750         int i, j, nent;
  751         u_int usertid;
  752 
  753         nent = sc->sc_nlctent;
  754         for (i = 0, le = sc->sc_lct->entry; i < nent; i++, le++) {
  755                 sc->sc_tidmap[i].it_tid =
  756                     letoh16(le->localtid) & I2O_LCT_ENTRY_TID_MASK;
  757 
  758                 /* Ignore the device if it's in use. */
  759                 usertid = letoh32(le->usertid) & I2O_LCT_ENTRY_TID_MASK;
  760                 if (usertid != I2O_TID_NONE && usertid != I2O_TID_HOST)
  761                         continue;
  762 
  763                 ia.ia_class = letoh16(le->classid) & I2O_CLASS_MASK;
  764                 ia.ia_tid = sc->sc_tidmap[i].it_tid;
  765 
  766                 /* Ignore uninteresting devices. */
  767                 for (j = 0; j < sizeof(iop_class) / sizeof(iop_class[0]); j++)
  768                         if (iop_class[j].ic_class == ia.ia_class)
  769                                 break;
  770                 if (j < sizeof(iop_class) / sizeof(iop_class[0]) &&
  771                     (iop_class[j].ic_flags & mask) != maskval)
  772                         continue;
  773 
  774                 /*
  775                  * Try to configure the device only if it's not already
  776                  * configured.
  777                  */
  778                 LIST_FOREACH(ii, &sc->sc_iilist, ii_list) {
  779                         if (ia.ia_tid == ii->ii_tid) {
  780                                 sc->sc_tidmap[i].it_flags |= IT_CONFIGURED;
  781                                 strlcpy(sc->sc_tidmap[i].it_dvname,
  782                                     ii->ii_dv->dv_xname,
  783                                     sizeof sc->sc_tidmap[i].it_dvname);
  784                                 break;
  785                         }
  786                 }
  787                 if (ii != NULL)
  788                         continue;
  789                 dv = config_found_sm(&sc->sc_dv, &ia, iop_print, iop_submatch);
  790                 if (dv != NULL) {
  791                         sc->sc_tidmap[i].it_flags |= IT_CONFIGURED;
  792                         strlcpy(sc->sc_tidmap[i].it_dvname, dv->dv_xname,
  793                             sizeof sc->sc_tidmap[i].it_dvname);
  794                 }
  795         }
  796 }
  797 
  798 /*
  799  * Adjust queue parameters for all child devices.
  800  */
  801 void
  802 iop_adjqparam(struct iop_softc *sc, int mpi)
  803 {
  804         struct iop_initiator *ii;
  805 
  806         LIST_FOREACH(ii, &sc->sc_iilist, ii_list)
  807                 if (ii->ii_adjqparam != NULL)
  808                         (*ii->ii_adjqparam)(ii->ii_dv, mpi);
  809 }
  810 
  811 void
  812 iop_devinfo(int class, char *devinfo, size_t di_len)
  813 {
  814 #ifdef I2OVERBOSE
  815         int i;
  816 
  817         for (i = 0; i < sizeof(iop_class) / sizeof(iop_class[0]); i++)
  818                 if (class == iop_class[i].ic_class)
  819                         break;
  820         
  821         if (i == sizeof(iop_class) / sizeof(iop_class[0]))
  822                 snprintf(devinfo, di_len, "device (class 0x%x)", class);
  823         else
  824                 strlcpy(devinfo, iop_class[i].ic_caption, di_len);
  825 #else
  826 
  827         snprintf(devinfo, di_len, "device (class 0x%x)", class);
  828 #endif
  829 }
  830 
  831 int
  832 iop_print(void *aux, const char *pnp)
  833 {
  834         struct iop_attach_args *ia;
  835         char devinfo[256];
  836 
  837         ia = aux;
  838 
  839         if (pnp != NULL) {
  840                 iop_devinfo(ia->ia_class, devinfo, sizeof devinfo);
  841                 printf("%s at %s", devinfo, pnp);
  842         }
  843         printf(" tid %d", ia->ia_tid);
  844         return (UNCONF);
  845 }
  846 
  847 #ifdef notyet
  848 int
  849 iop_vendor_print(void *aux, const char *pnp)
  850 {
  851 
  852         if (pnp != NULL)
  853                 printf("vendor specific extension at %s", pnp);
  854         return (UNCONF);
  855 }
  856 #endif
  857 
  858 int
  859 iop_submatch(struct device *parent, void *vcf, void *aux)
  860 {
  861         struct cfdata *cf = vcf;
  862         struct iop_attach_args *ia;
  863         
  864         ia = aux;
  865 
  866         if (cf->iopcf_tid != IOPCF_TID_DEFAULT && cf->iopcf_tid != ia->ia_tid)
  867                 return (0);
  868 
  869         return ((*cf->cf_attach->ca_match)(parent, cf, aux));
  870 }
  871 
  872 /*
  873  * Shut down all configured IOPs.
  874  */ 
  875 void
  876 iop_shutdown(void *junk)
  877 {
  878         struct iop_softc *sc;
  879         int i;
  880 
  881         printf("shutting down iop devices...");
  882 
  883         for (i = 0; i < iop_cd.cd_ndevs; i++) {
  884                 if (!(sc = (struct iop_softc *)device_lookup(&iop_cd, i)))
  885                         continue;
  886                 if ((sc->sc_flags & IOP_ONLINE) == 0)
  887                         continue;
  888 
  889                 iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_SYS_QUIESCE, IOP_ICTX,
  890                     0, 5000);
  891 
  892                 if (letoh16(sc->sc_status.orgid) != I2O_ORG_AMI) {
  893                         /*
  894                          * Some AMI firmware revisions will go to sleep and
  895                          * never come back after this.
  896                          */
  897                         iop_simple_cmd(sc, I2O_TID_IOP, I2O_EXEC_IOP_CLEAR,
  898                             IOP_ICTX, 0, 1000);
  899                 }
  900         }
  901 
  902         /* Wait.  Some boards could still be flushing, stupidly enough. */
  903         delay(5000*1000);
  904         printf(" done.\n");
  905 }
  906 
  907 /*
  908  * Retrieve IOP status.
  909  */
  910 int
  911 iop_status_get(struct iop_softc *sc, int nosleep)
  912 {
  913         struct i2o_exec_status_get mf;
  914         paddr_t pa = sc->sc_scr_seg->ds_addr;
  915         struct i2o_status *st = (struct i2o_status *)sc->sc_scr;
  916         int rv;
  917 
  918         mf.msgflags = I2O_MSGFLAGS(i2o_exec_status_get);
  919         mf.msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_STATUS_GET);
  920         mf.reserved[0] = 0;
  921         mf.reserved[1] = 0;
  922         mf.reserved[2] = 0;
  923         mf.reserved[3] = 0;
  924         mf.addrlow = pa & ~(u_int32_t)0;
  925         mf.addrhigh = sizeof pa > sizeof mf.addrlow ? pa >> 32 : 0;
  926         mf.length = sizeof(*st);
  927 
  928         bzero(st, sizeof(*st));
  929         bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*st),
  930             BUS_DMASYNC_PREREAD);
  931 
  932         if ((rv = iop_post(sc, (u_int32_t *)&mf)))
  933                 return (rv);
  934 
  935         /* XXX */
  936         POLL(2500,
  937             (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0,
  938                 sizeof(*st), BUS_DMASYNC_POSTREAD), st->syncbyte == 0xff));
  939 
  940         if (st->syncbyte != 0xff)
  941                 return (EIO);
  942 
  943         bcopy(st, &sc->sc_status, sizeof(sc->sc_status));
  944         return (0);
  945 }
  946 
  947 /*
  948  * Initalize and populate the IOP's outbound FIFO.
  949  */
  950 int
  951 iop_ofifo_init(struct iop_softc *sc)
  952 {
  953         bus_addr_t addr;
  954         bus_dma_segment_t seg;
  955         struct i2o_exec_outbound_init *mf;
  956         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
  957         u_int32_t *sw = (u_int32_t *)sc->sc_scr;
  958         int i, rseg, rv;
  959 
  960         mf = (struct i2o_exec_outbound_init *)mb;
  961         mf->msgflags = I2O_MSGFLAGS(i2o_exec_outbound_init);
  962         mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_OUTBOUND_INIT);
  963         mf->msgictx = IOP_ICTX;
  964         mf->msgtctx = 0;
  965         mf->pagesize = PAGE_SIZE;
  966         mf->flags = IOP_INIT_CODE | ((IOP_MAX_MSG_SIZE >> 2) << 16);
  967         mb[sizeof(*mf) / sizeof(u_int32_t) + 0] = sizeof(*sw) |
  968             I2O_SGL_SIMPLE | I2O_SGL_END_BUFFER | I2O_SGL_END;
  969         mb[sizeof(*mf) / sizeof(u_int32_t) + 1] = sc->sc_scr_seg->ds_addr;
  970         mb[0] += 2 << 16;
  971 
  972         *sw = 0;
  973         bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
  974             BUS_DMASYNC_PREREAD);
  975 
  976         /*
  977          * The I2O spec says that there are two SGLs: one for the status
  978          * word, and one for a list of discarded MFAs.  It continues to say
  979          * that if you don't want to get the list of MFAs, an IGNORE SGL is
  980          * necessary; this isn't the case (and is in fact a bad thing).
  981          */
  982         if ((rv = iop_post(sc, mb)))
  983                 return (rv);
  984 
  985         /* XXX */
  986         POLL(5000,
  987             (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
  988             BUS_DMASYNC_POSTREAD),
  989             *sw == htole32(I2O_EXEC_OUTBOUND_INIT_COMPLETE)));
  990         if (*sw != htole32(I2O_EXEC_OUTBOUND_INIT_COMPLETE)) {
  991                 printf("%s: outbound FIFO init failed (%d)\n",
  992                     sc->sc_dv.dv_xname, letoh32(*sw));
  993                 return (EIO);
  994         }
  995 
  996         /* Allocate DMA safe memory for the reply frames. */
  997         if (sc->sc_rep_phys == 0) {
  998                 sc->sc_rep_size = sc->sc_maxob * IOP_MAX_MSG_SIZE;
  999 
 1000                 rv = bus_dmamem_alloc(sc->sc_dmat, sc->sc_rep_size, PAGE_SIZE,
 1001                     0, &seg, 1, &rseg, BUS_DMA_NOWAIT);
 1002                 if (rv != 0) {
 1003                         printf("%s: dma alloc = %d\n", sc->sc_dv.dv_xname,
 1004                            rv);
 1005                         return (rv);
 1006                 }
 1007 
 1008                 rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, sc->sc_rep_size,
 1009                     &sc->sc_rep, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 1010                 if (rv != 0) {
 1011                         printf("%s: dma map = %d\n", sc->sc_dv.dv_xname, rv);
 1012                         return (rv);
 1013                 }
 1014 
 1015                 rv = bus_dmamap_create(sc->sc_dmat, sc->sc_rep_size, 1,
 1016                     sc->sc_rep_size, 0, BUS_DMA_NOWAIT, &sc->sc_rep_dmamap);
 1017                 if (rv != 0) {
 1018                         printf("%s: dma create = %d\n", sc->sc_dv.dv_xname,
 1019                             rv);
 1020                         return (rv);
 1021                 }
 1022 
 1023                 rv = bus_dmamap_load(sc->sc_dmat, sc->sc_rep_dmamap,
 1024                     sc->sc_rep, sc->sc_rep_size, NULL, BUS_DMA_NOWAIT);
 1025                 if (rv != 0) {
 1026                         printf("%s: dma load = %d\n", sc->sc_dv.dv_xname, rv);
 1027                         return (rv);
 1028                 }
 1029 
 1030                 sc->sc_rep_phys = sc->sc_rep_dmamap->dm_segs[0].ds_addr;
 1031         }
 1032 
 1033         /* Populate the outbound FIFO. */
 1034         for (i = sc->sc_maxob, addr = sc->sc_rep_phys; i != 0; i--) {
 1035                 iop_outl(sc, IOP_REG_OFIFO, (u_int32_t)addr);
 1036                 addr += IOP_MAX_MSG_SIZE;
 1037         }
 1038 
 1039         return (0);
 1040 }
 1041 
 1042 /*
 1043  * Read the specified number of bytes from the IOP's hardware resource table.
 1044  */
 1045 int
 1046 iop_hrt_get0(struct iop_softc *sc, struct i2o_hrt *hrt, size_t size)
 1047 {
 1048         struct iop_msg *im;
 1049         struct i2o_exec_hrt_get *mf;
 1050         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
 1051         int rv;
 1052 
 1053         im = iop_msg_alloc(sc, NULL, IM_WAIT);
 1054         mf = (struct i2o_exec_hrt_get *)mb;
 1055         mf->msgflags = I2O_MSGFLAGS(i2o_exec_hrt_get);
 1056         mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_HRT_GET);
 1057         mf->msgictx = IOP_ICTX;
 1058         mf->msgtctx = im->im_tctx;
 1059 
 1060         iop_msg_map(sc, im, mb, hrt, size, 0);
 1061         rv = iop_msg_post(sc, im, mb, 30000);
 1062         iop_msg_unmap(sc, im);
 1063         iop_msg_free(sc, im);
 1064         return (rv);
 1065 }
 1066 
 1067 /*
 1068  * Read the IOP's hardware resource table.
 1069  */
 1070 int
 1071 iop_hrt_get(struct iop_softc *sc)
 1072 {
 1073         struct i2o_hrt hrthdr, *hrt;
 1074         size_t size;
 1075         int rv;
 1076 
 1077         rv = iop_hrt_get0(sc, &hrthdr, sizeof(hrthdr));
 1078         if (rv != 0)
 1079                 return (rv);
 1080 
 1081         DPRINTF(("%s: %d hrt entries\n", sc->sc_dv.dv_xname,
 1082             letoh16(hrthdr.numentries)));
 1083 
 1084         size = sizeof(struct i2o_hrt) + 
 1085             (letoh16(hrthdr.numentries) - 1) * sizeof(struct i2o_hrt_entry);
 1086         hrt = (struct i2o_hrt *)malloc(size, M_DEVBUF, M_NOWAIT);
 1087         if (!hrt)
 1088                 return (ENOMEM);
 1089 
 1090         if ((rv = iop_hrt_get0(sc, hrt, size)) != 0) {
 1091                 free(hrt, M_DEVBUF);
 1092                 return (rv);
 1093         }
 1094 
 1095         if (sc->sc_hrt != NULL)
 1096                 free(sc->sc_hrt, M_DEVBUF);
 1097         sc->sc_hrt = hrt;
 1098         return (0);
 1099 }
 1100 
 1101 /*
 1102  * Request the specified number of bytes from the IOP's logical
 1103  * configuration table.  If a change indicator is specified, this
 1104  * is a verbatim notification request, so the caller is prepared
 1105  * to wait indefinitely.
 1106  */
 1107 int
 1108 iop_lct_get0(struct iop_softc *sc, struct i2o_lct *lct, size_t size,
 1109              u_int32_t chgind)
 1110 {
 1111         struct iop_msg *im;
 1112         struct i2o_exec_lct_notify *mf;
 1113         int rv;
 1114         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
 1115 
 1116         im = iop_msg_alloc(sc, NULL, IM_WAIT);
 1117         memset(lct, 0, size);
 1118 
 1119         mf = (struct i2o_exec_lct_notify *)mb;
 1120         mf->msgflags = I2O_MSGFLAGS(i2o_exec_lct_notify);
 1121         mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_LCT_NOTIFY);
 1122         mf->msgictx = IOP_ICTX;
 1123         mf->msgtctx = im->im_tctx;
 1124         mf->classid = I2O_CLASS_ANY;
 1125         mf->changeindicator = chgind;
 1126 
 1127 #ifdef I2ODEBUG
 1128         printf("iop_lct_get0: reading LCT");
 1129         if (chgind != 0)
 1130                 printf(" (async)");
 1131         printf("\n");
 1132 #endif
 1133 
 1134         iop_msg_map(sc, im, mb, lct, size, 0);
 1135         rv = iop_msg_post(sc, im, mb, (chgind == 0 ? 120*1000 : 0));
 1136         iop_msg_unmap(sc, im);
 1137         iop_msg_free(sc, im);
 1138         return (rv);
 1139 }
 1140 
 1141 /*
 1142  * Read the IOP's logical configuration table.
 1143  */
 1144 int
 1145 iop_lct_get(struct iop_softc *sc)
 1146 {
 1147         size_t esize, size;
 1148         int rv;
 1149         struct i2o_lct *lct;
 1150 
 1151         esize = letoh32(sc->sc_status.expectedlctsize);
 1152         lct = (struct i2o_lct *)malloc(esize, M_DEVBUF, M_WAITOK);
 1153         if (lct == NULL)
 1154                 return (ENOMEM);
 1155 
 1156         if ((rv = iop_lct_get0(sc, lct, esize, 0)) != 0) {
 1157                 free(lct, M_DEVBUF);
 1158                 return (rv);
 1159         }
 1160 
 1161         size = letoh16(lct->tablesize) << 2;
 1162         if (esize != size) {
 1163                 free(lct, M_DEVBUF);
 1164                 lct = (struct i2o_lct *)malloc(size, M_DEVBUF, M_WAITOK);
 1165                 if (lct == NULL)
 1166                         return (ENOMEM);
 1167 
 1168                 if ((rv = iop_lct_get0(sc, lct, size, 0)) != 0) {
 1169                         free(lct, M_DEVBUF);
 1170                         return (rv);
 1171                 }
 1172         }
 1173 
 1174         /* Swap in the new LCT. */
 1175         if (sc->sc_lct != NULL)
 1176                 free(sc->sc_lct, M_DEVBUF);
 1177         sc->sc_lct = lct;
 1178         sc->sc_nlctent = ((letoh16(sc->sc_lct->tablesize) << 2) -
 1179             sizeof(struct i2o_lct) + sizeof(struct i2o_lct_entry)) /
 1180             sizeof(struct i2o_lct_entry);
 1181         return (0);
 1182 }
 1183 
 1184 /*
 1185  * Request the specified parameter group from the target.  If an initiator
 1186  * is specified (a) don't wait for the operation to complete, but instead
 1187  * let the initiator's interrupt handler deal with the reply and (b) place a
 1188  * pointer to the parameter group op in the wrapper's `im_dvcontext' field.
 1189  */
 1190 int
 1191 iop_param_op(struct iop_softc *sc, int tid, struct iop_initiator *ii,
 1192     int write, int group, void *buf, size_t size)
 1193 {
 1194         struct iop_msg *im;
 1195         struct i2o_util_params_op *mf;
 1196         struct i2o_reply *rf;
 1197         int rv, func, op;
 1198         struct iop_pgop *pgop;
 1199         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
 1200 
 1201         im = iop_msg_alloc(sc, ii, (ii == NULL ? IM_WAIT : 0) | IM_NOSTATUS);
 1202         if ((pgop = malloc(sizeof(*pgop), M_DEVBUF, M_WAITOK)) == NULL) {
 1203                 iop_msg_free(sc, im);
 1204                 return (ENOMEM);
 1205         }
 1206         if ((rf = malloc(sizeof(*rf), M_DEVBUF, M_WAITOK)) == NULL) {
 1207                 iop_msg_free(sc, im);
 1208                 free(pgop, M_DEVBUF);
 1209                 return (ENOMEM);
 1210         }
 1211         im->im_dvcontext = pgop;
 1212         im->im_rb = rf;
 1213 
 1214         if (write) {
 1215                 func = I2O_UTIL_PARAMS_SET;
 1216                 op = I2O_PARAMS_OP_FIELD_SET;
 1217         } else {
 1218                 func = I2O_UTIL_PARAMS_GET;
 1219                 op = I2O_PARAMS_OP_FIELD_GET;
 1220         }
 1221 
 1222         mf = (struct i2o_util_params_op *)mb;
 1223         mf->msgflags = I2O_MSGFLAGS(i2o_util_params_op);
 1224         mf->msgfunc = I2O_MSGFUNC(tid, func);
 1225         mf->msgictx = IOP_ICTX;
 1226         mf->msgtctx = im->im_tctx;
 1227         mf->flags = 0;
 1228 
 1229         pgop->olh.count = htole16(1);
 1230         pgop->olh.reserved = htole16(0);
 1231         pgop->oat.operation = htole16(op);
 1232         pgop->oat.fieldcount = htole16(0xffff);
 1233         pgop->oat.group = htole16(group);
 1234 
 1235         memset(buf, 0, size);
 1236         iop_msg_map(sc, im, mb, pgop, sizeof(*pgop), 1);
 1237         iop_msg_map(sc, im, mb, buf, size, write);
 1238         rv = iop_msg_post(sc, im, mb, (ii == NULL ? 30000 : 0));
 1239 
 1240         /* Detect errors; let partial transfers to count as success. */
 1241         if (ii == NULL && rv == 0) {
 1242                 if (rf->reqstatus == I2O_STATUS_ERROR_PARTIAL_XFER &&
 1243                     rf->detail == htole16(I2O_DSC_UNKNOWN_ERROR))
 1244                         rv = 0;
 1245                 else
 1246                         rv = (rf->reqstatus != 0 ? EIO : 0);
 1247         }
 1248 
 1249         if (ii == NULL || rv != 0) {
 1250                 iop_msg_unmap(sc, im);
 1251                 iop_msg_free(sc, im);
 1252                 free(pgop, M_DEVBUF);
 1253                 free(rf, M_DEVBUF);
 1254         }
 1255 
 1256         return (rv);
 1257 }
 1258 
 1259 /*
 1260  * Execute a simple command (no parameters).
 1261  */
 1262 int
 1263 iop_simple_cmd(struct iop_softc *sc, int tid, int function, int ictx,
 1264                int async, int timo)
 1265 {
 1266         struct iop_msg *im;
 1267         struct i2o_msg mf;
 1268         int rv, fl;
 1269 
 1270         fl = (async != 0 ? IM_WAIT : IM_POLL);
 1271         im = iop_msg_alloc(sc, NULL, fl);
 1272 
 1273         mf.msgflags = I2O_MSGFLAGS(i2o_msg);
 1274         mf.msgfunc = I2O_MSGFUNC(tid, function);
 1275         mf.msgictx = ictx;
 1276         mf.msgtctx = im->im_tctx;
 1277 
 1278         rv = iop_msg_post(sc, im, &mf, timo);
 1279         iop_msg_free(sc, im);
 1280         return (rv);
 1281 }
 1282 
 1283 /*
 1284  * Post the system table to the IOP.
 1285  */
 1286 int
 1287 iop_systab_set(struct iop_softc *sc)
 1288 {
 1289         struct i2o_exec_sys_tab_set *mf;
 1290         struct iop_msg *im;
 1291         bus_space_handle_t bsh;
 1292         bus_addr_t boo;
 1293         u_int32_t mema[2], ioa[2];
 1294         int rv;
 1295         u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
 1296 
 1297         im = iop_msg_alloc(sc, NULL, IM_WAIT);
 1298 
 1299         mf = (struct i2o_exec_sys_tab_set *)mb;
 1300         mf->msgflags = I2O_MSGFLAGS(i2o_exec_sys_tab_set);
 1301         mf->msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_SYS_TAB_SET);
 1302         mf->msgictx = IOP_ICTX;
 1303         mf->msgtctx = im->im_tctx;
 1304         mf->iopid = (sc->sc_dv.dv_unit + 2) << 12;
 1305         mf->segnumber = 0;
 1306 
 1307         mema[1] = sc->sc_status.desiredprivmemsize;
 1308         ioa[1] = sc->sc_status.desiredpriviosize;
 1309 
 1310         if (mema[1] != 0) {
 1311                 /*
 1312                  * XXX This will waste virtual memory.  We need a flag to tell
 1313                  * bus_space_alloc to just reserve, not actually map the area.
 1314                  */
 1315                 rv = bus_space_alloc(sc->sc_bus_memt, 0, 0xffffffff,
 1316                     letoh32(mema[1]), PAGE_SIZE, 0, 0, &boo, &bsh);
 1317                 mema[0] = htole32(boo);
 1318                 if (rv != 0) {
 1319                         printf("%s: can't alloc priv mem space, err = %d\n",
 1320                             sc->sc_dv.dv_xname, rv);
 1321                         mema[0] = 0;
 1322                         mema[1] = 0;
 1323                 }
 1324         }
 1325 
 1326         if (ioa[1] != 0) {
 1327                 /*
 1328                  * XXX This will potentially waste virtual memory.  We
 1329                  * need a flag to tell bus_space_alloc to just
 1330                  * reserve, not actually map the area.
 1331                  */
 1332                 rv = bus_space_alloc(sc->sc_bus_iot, 0, 0xffff,
 1333                     letoh32(ioa[1]), 0, 0, 0, &boo, &bsh);
 1334                 ioa[0] = htole32(boo);
 1335                 if (rv != 0) {
 1336                         printf("%s: can't alloc priv i/o space, err = %d\n",
 1337                             sc->sc_dv.dv_xname, rv);
 1338                         ioa[0] = 0;
 1339                         ioa[1] = 0;
 1340                 }
 1341         }
 1342 
 1343         iop_msg_map(sc, im, mb, iop_systab, iop_systab_size, 1);
 1344         iop_msg_map(sc, im, mb, mema, sizeof(mema), 1);
 1345         iop_msg_map(sc, im, mb, ioa, sizeof(ioa), 1);
 1346         rv = iop_msg_post(sc, im, mb, 5000);
 1347         iop_msg_unmap(sc, im);
 1348         iop_msg_free(sc, im);
 1349         return (rv);
 1350 }
 1351 
 1352 /*
 1353  * Reset the IOP.  Must be called with interrupts disabled.
 1354  */
 1355 int
 1356 iop_reset(struct iop_softc *sc)
 1357 {
 1358         struct i2o_exec_iop_reset mf;
 1359         paddr_t pa = sc->sc_scr_seg->ds_addr;
 1360         u_int32_t *sw = (u_int32_t *)sc->sc_scr;
 1361         u_int32_t mfa;
 1362         int rv = 0;
 1363 
 1364         mf.msgflags = I2O_MSGFLAGS(i2o_exec_iop_reset);
 1365         mf.msgfunc = I2O_MSGFUNC(I2O_TID_IOP, I2O_EXEC_IOP_RESET);
 1366         mf.reserved[0] = 0;
 1367         mf.reserved[1] = 0;
 1368         mf.reserved[2] = 0;
 1369         mf.reserved[3] = 0;
 1370         mf.statuslow = pa & ~(u_int32_t)0;
 1371         mf.statushigh = sizeof pa > sizeof mf.statuslow ? pa >> 32 : 0;
 1372 
 1373         *sw = htole32(0);
 1374         bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
 1375             BUS_DMASYNC_PREREAD);
 1376 
 1377         if ((rv = iop_post(sc, (u_int32_t *)&mf)))
 1378                 return (rv);
 1379 
 1380         /* XXX */
 1381         POLL(2500,
 1382             (bus_dmamap_sync(sc->sc_dmat, sc->sc_scr_dmamap, 0, sizeof(*sw),
 1383             BUS_DMASYNC_POSTREAD), *sw != htole32(0)));
 1384         if (*sw != htole32(I2O_RESET_IN_PROGRESS)) {
 1385                 printf("%s: reset rejected, status 0x%x\n",
 1386                     sc->sc_dv.dv_xname, letoh32(*sw));
 1387                 return (EIO);
 1388         }
 1389 
 1390         /* 
 1391          * IOP is now in the INIT state.  Wait no more than 10 seconds for
 1392          * the inbound queue to become responsive.
 1393          */
 1394         POLL(10000, (mfa = iop_inl(sc, IOP_REG_IFIFO)) != IOP_MFA_EMPTY);
 1395         if (mfa == IOP_MFA_EMPTY) {
 1396                 printf("%s: reset failed\n", sc->sc_dv.dv_xname);
 1397                 return (EIO);
 1398         }
 1399 
 1400         iop_release_mfa(sc, mfa);
 1401 
 1402         return (0);
 1403 }
 1404 
 1405 /*
 1406  * Register a new initiator.  Must be called with the configuration lock
 1407  * held.
 1408  */
 1409 void
 1410 iop_initiator_register(struct iop_softc *sc, struct iop_initiator *ii)
 1411 {
 1412         static int ictxgen;
 1413         int s;
 1414 
 1415         /* 0 is reserved (by us) for system messages. */
 1416         ii->ii_ictx = ++ictxgen;
 1417 
 1418         /*
 1419          * `Utility initiators' don't make it onto the per-IOP initiator list
 1420          * (which is used only for configuration), but do get one slot on
 1421          * the inbound queue.
 1422          */
 1423         if ((ii->ii_flags & II_UTILITY) == 0) {
 1424                 LIST_INSERT_HEAD(&sc->sc_iilist, ii, ii_list);
 1425                 sc->sc_nii++;
 1426         } else
 1427                 sc->sc_nuii++;
 1428 
 1429         s = splbio();
 1430         LIST_INSERT_HEAD(IOP_ICTXHASH(ii->ii_ictx), ii, ii_hash);
 1431         splx(s);
 1432 }
 1433 
 1434 /*
 1435  * Unregister an initiator.  Must be called with the configuration lock
 1436  * held.
 1437  */
 1438 void
 1439 iop_initiator_unregister(struct iop_softc *sc, struct iop_initiator *ii)
 1440 {
 1441         int s;
 1442 
 1443         if ((ii->ii_flags & II_UTILITY) == 0) {
 1444                 LIST_REMOVE(ii, ii_list);
 1445                 sc->sc_nii--;
 1446         } else
 1447                 sc->sc_nuii--;
 1448 
 1449         s = splbio();
 1450         LIST_REMOVE(ii, ii_hash);
 1451         splx(s);
 1452 }
 1453 
 1454 /*
 1455  * Handle a reply frame from the IOP.
 1456  */
 1457 int
 1458 iop_handle_reply(struct iop_softc *sc, u_int32_t rmfa)
 1459 {
 1460         struct iop_msg *im;
 1461         struct i2o_reply *rb;
 1462         struct i2o_fault_notify *fn;
 1463         struct iop_initiator *ii;
 1464         u_int off, ictx, tctx, status, size;
 1465 
 1466         off = (int)(rmfa - sc->sc_rep_phys);
 1467         rb = (struct i2o_reply *)(sc->sc_rep + off);
 1468 
 1469         /* Perform reply queue DMA synchronisation.  XXX This is rubbish. */
 1470         bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, off,
 1471             sc->sc_rep_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1472         if (--sc->sc_curib != 0)
 1473                 bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, 0,
 1474                     sc->sc_rep_size, BUS_DMASYNC_PREREAD);
 1475 
 1476 #ifdef I2ODEBUG
 1477         if ((letoh32(rb->msgflags) & I2O_MSGFLAGS_64BIT) != 0)
 1478                 panic("iop_handle_reply: 64-bit reply");
 1479 #endif
 1480         /* 
 1481          * Find the initiator.
 1482          */
 1483         ictx = letoh32(rb->msgictx);
 1484         if (ictx == IOP_ICTX)
 1485                 ii = NULL;
 1486         else {
 1487                 ii = LIST_FIRST(IOP_ICTXHASH(ictx));
 1488                 for (; ii != NULL; ii = LIST_NEXT(ii, ii_hash))
 1489                         if (ii->ii_ictx == ictx)
 1490                                 break;
 1491                 if (ii == NULL) {
 1492 #ifdef I2ODEBUG
 1493                         iop_reply_print(sc, rb);
 1494 #endif
 1495                         printf("%s: WARNING: bad ictx returned (%x)\n",
 1496                             sc->sc_dv.dv_xname, ictx);
 1497                         return (-1);
 1498                 }
 1499         }
 1500 
 1501         /*
 1502          * If we received a transport failure notice, we've got to dig the
 1503          * transaction context (if any) out of the original message frame,
 1504          * and then release the original MFA back to the inbound FIFO.
 1505          */
 1506         if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0) {
 1507                 status = I2O_STATUS_SUCCESS;
 1508 
 1509                 fn = (struct i2o_fault_notify *)rb;
 1510                 tctx = iop_inl(sc, fn->lowmfa + 12);    /* XXX */
 1511                 iop_release_mfa(sc, fn->lowmfa);
 1512                 iop_tfn_print(sc, fn);
 1513         } else {
 1514                 status = rb->reqstatus;
 1515                 tctx = letoh32(rb->msgtctx);
 1516         }
 1517 
 1518         if (ii == NULL || (ii->ii_flags & II_DISCARD) == 0) {
 1519                 /*
 1520                  * This initiator tracks state using message wrappers.
 1521                  *
 1522                  * Find the originating message wrapper, and if requested
 1523                  * notify the initiator.
 1524                  */
 1525                 im = sc->sc_ims + (tctx & IOP_TCTX_MASK);
 1526                 if ((tctx & IOP_TCTX_MASK) > sc->sc_maxib ||
 1527                     (im->im_flags & IM_ALLOCED) == 0 ||
 1528                     tctx != im->im_tctx) {
 1529                         printf("%s: WARNING: bad tctx returned (0x%08x, %p)\n",
 1530                             sc->sc_dv.dv_xname, tctx, im);
 1531                         if (im != NULL)
 1532                                 printf("%s: flags=0x%08x tctx=0x%08x\n",
 1533                                     sc->sc_dv.dv_xname, im->im_flags,
 1534                                     im->im_tctx);
 1535 #ifdef I2ODEBUG
 1536                         if ((rb->msgflags & I2O_MSGFLAGS_FAIL) == 0)
 1537                                 iop_reply_print(sc, rb);
 1538 #endif
 1539                         return (-1);
 1540                 }
 1541 
 1542                 if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
 1543                         im->im_flags |= IM_FAIL;
 1544 
 1545 #ifdef I2ODEBUG
 1546                 if ((im->im_flags & IM_REPLIED) != 0)
 1547                         panic("%s: dup reply", sc->sc_dv.dv_xname);
 1548 #endif
 1549                 im->im_flags |= IM_REPLIED;
 1550 
 1551 #ifdef I2ODEBUG
 1552                 if (status != I2O_STATUS_SUCCESS)
 1553                         iop_reply_print(sc, rb);
 1554 #endif
 1555                 im->im_reqstatus = status;
 1556 
 1557                 /* Copy the reply frame, if requested. */
 1558                 if (im->im_rb != NULL) {
 1559                         size = (letoh32(rb->msgflags) >> 14) & ~3;
 1560 #ifdef I2ODEBUG
 1561                         if (size > IOP_MAX_MSG_SIZE)
 1562                                 panic("iop_handle_reply: reply too large");
 1563 #endif
 1564                         memcpy(im->im_rb, rb, size);
 1565                 }
 1566 
 1567                 /* Notify the initiator. */
 1568                 if ((im->im_flags & IM_WAIT) != 0)
 1569                         wakeup(im);
 1570                 else if ((im->im_flags & (IM_POLL | IM_POLL_INTR)) != IM_POLL)
 1571                         (*ii->ii_intr)(ii->ii_dv, im, rb);
 1572         } else {
 1573                 /*
 1574                  * This initiator discards message wrappers.
 1575                  *
 1576                  * Simply pass the reply frame to the initiator.
 1577                  */
 1578                 (*ii->ii_intr)(ii->ii_dv, NULL, rb);
 1579         }
 1580 
 1581         return (status);
 1582 }
 1583 
 1584 /*
 1585  * Handle an interrupt from the IOP.
 1586  */
 1587 int
 1588 iop_intr(void *arg)
 1589 {
 1590         struct iop_softc *sc;
 1591         u_int32_t rmfa;
 1592 
 1593         sc = arg;
 1594 
 1595         if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) == 0)
 1596                 return (0);
 1597 
 1598         for (;;) {
 1599                 /* Double read to account for IOP bug. */
 1600                 if ((rmfa = iop_inl(sc, IOP_REG_OFIFO)) == IOP_MFA_EMPTY) {
 1601                         rmfa = iop_inl(sc, IOP_REG_OFIFO);
 1602                         if (rmfa == IOP_MFA_EMPTY)
 1603                                 break;
 1604                 }
 1605                 iop_handle_reply(sc, rmfa);
 1606                 iop_outl(sc, IOP_REG_OFIFO, rmfa);
 1607         }
 1608 
 1609         return (1);
 1610 }
 1611 
 1612 /*
 1613  * Handle an event signalled by the executive.
 1614  */
 1615 void
 1616 iop_intr_event(struct device *dv, struct iop_msg *im, void *reply)
 1617 {
 1618         struct i2o_util_event_register_reply *rb;
 1619         struct iop_softc *sc;
 1620         u_int event;
 1621 
 1622         sc = (struct iop_softc *)dv;
 1623         rb = reply;
 1624 
 1625         if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
 1626                 return;
 1627 
 1628         event = letoh32(rb->event);
 1629         printf("%s: event 0x%08x received\n", dv->dv_xname, event);
 1630 }
 1631 
 1632 /* 
 1633  * Allocate a message wrapper.
 1634  */
 1635 struct iop_msg *
 1636 iop_msg_alloc(struct iop_softc *sc, struct iop_initiator *ii, int flags)
 1637 {
 1638         struct iop_msg *im;
 1639         static u_int tctxgen;
 1640         int s, i;
 1641 
 1642 #ifdef I2ODEBUG
 1643         if ((flags & IM_SYSMASK) != 0)
 1644                 panic("iop_msg_alloc: system flags specified");
 1645 #endif
 1646 
 1647         s = splbio();   /* XXX */
 1648         im = SLIST_FIRST(&sc->sc_im_freelist);
 1649 #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
 1650         if (im == NULL)
 1651                 panic("iop_msg_alloc: no free wrappers");
 1652 #endif
 1653         SLIST_REMOVE_HEAD(&sc->sc_im_freelist, im_chain);
 1654         splx(s);
 1655 
 1656         if (ii != NULL && (ii->ii_flags & II_DISCARD) != 0)
 1657                 flags |= IM_DISCARD;
 1658 
 1659         im->im_tctx = (im->im_tctx & IOP_TCTX_MASK) | tctxgen;
 1660         tctxgen += (1 << IOP_TCTX_SHIFT);
 1661         im->im_flags = flags | IM_ALLOCED;
 1662         im->im_rb = NULL;
 1663         i = 0;
 1664         do {
 1665                 im->im_xfer[i++].ix_size = 0;
 1666         } while (i < IOP_MAX_MSG_XFERS);
 1667 
 1668         return (im);
 1669 }
 1670 
 1671 /* 
 1672  * Free a message wrapper.
 1673  */
 1674 void
 1675 iop_msg_free(struct iop_softc *sc, struct iop_msg *im)
 1676 {
 1677         int s;
 1678 
 1679 #ifdef I2ODEBUG
 1680         if ((im->im_flags & IM_ALLOCED) == 0)
 1681                 panic("iop_msg_free: wrapper not allocated");
 1682 #endif
 1683 
 1684         im->im_flags = 0;
 1685         s = splbio();
 1686         SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain);
 1687         splx(s);
 1688 }
 1689 
 1690 /*
 1691  * Map a data transfer.  Write a scatter-gather list into the message frame. 
 1692  */
 1693 int
 1694 iop_msg_map(struct iop_softc *sc, struct iop_msg *im, u_int32_t *mb,
 1695     void *xferaddr, size_t xfersize, int out)
 1696 {
 1697         bus_dmamap_t dm;
 1698         bus_dma_segment_t *ds;
 1699         struct iop_xfer *ix;
 1700         u_int rv, i, nsegs, flg, off, xn;
 1701         u_int32_t *p;
 1702 
 1703         for (xn = 0, ix = im->im_xfer; xn < IOP_MAX_MSG_XFERS; xn++, ix++)
 1704                 if (ix->ix_size == 0)
 1705                         break;
 1706 
 1707 #ifdef I2ODEBUG
 1708         if (xfersize == 0)
 1709                 panic("iop_msg_map: null transfer");
 1710         if (xfersize > IOP_MAX_XFER)
 1711                 panic("iop_msg_map: transfer too large");
 1712         if (xn == IOP_MAX_MSG_XFERS)
 1713                 panic("iop_msg_map: too many xfers");
 1714 #endif
 1715 
 1716         /*
 1717          * Only the first DMA map is static.
 1718          */
 1719         if (xn != 0) {
 1720                 rv = bus_dmamap_create(sc->sc_dmat, IOP_MAX_XFER,
 1721                     IOP_MAX_SEGS, IOP_MAX_XFER, 0,
 1722                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ix->ix_map);
 1723                 if (rv != 0)
 1724                         return (rv);
 1725         }
 1726 
 1727         dm = ix->ix_map;
 1728         rv = bus_dmamap_load(sc->sc_dmat, dm, xferaddr, xfersize, NULL, 0);
 1729         if (rv != 0)
 1730                 goto bad;
 1731 
 1732         /*
 1733          * How many SIMPLE SG elements can we fit in this message?
 1734          */
 1735         off = mb[0] >> 16;
 1736         p = mb + off;
 1737         nsegs = ((IOP_MAX_MSG_SIZE / sizeof *mb) - off) >> 1;
 1738 
 1739         if (dm->dm_nsegs > nsegs) {
 1740                 bus_dmamap_unload(sc->sc_dmat, ix->ix_map);
 1741                 rv = EFBIG;
 1742                 DPRINTF(("iop_msg_map: too many segs\n"));
 1743                 goto bad;
 1744         }
 1745 
 1746         nsegs = dm->dm_nsegs;
 1747         xfersize = 0;
 1748 
 1749         /*
 1750          * Write out the SG list.
 1751          */
 1752         if (out)
 1753                 flg = I2O_SGL_SIMPLE | I2O_SGL_DATA_OUT;
 1754         else
 1755                 flg = I2O_SGL_SIMPLE;
 1756 
 1757         for (i = nsegs, ds = dm->dm_segs; i > 1; i--, p += 2, ds++) {
 1758                 p[0] = (u_int32_t)ds->ds_len | flg;
 1759                 p[1] = (u_int32_t)ds->ds_addr;
 1760                 xfersize += ds->ds_len;
 1761         }
 1762 
 1763         p[0] = (u_int32_t)ds->ds_len | flg | I2O_SGL_END_BUFFER;
 1764         p[1] = (u_int32_t)ds->ds_addr;
 1765         xfersize += ds->ds_len;
 1766 
 1767         /* Fix up the transfer record, and sync the map. */
 1768         ix->ix_flags = (out ? IX_OUT : IX_IN);
 1769         ix->ix_size = xfersize;
 1770         bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0, xfersize,
 1771             out ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_POSTREAD);
 1772 
 1773         /*
 1774          * If this is the first xfer we've mapped for this message, adjust
 1775          * the SGL offset field in the message header.
 1776          */
 1777         if ((im->im_flags & IM_SGLOFFADJ) == 0) {
 1778                 mb[0] += (mb[0] >> 12) & 0xf0;
 1779                 im->im_flags |= IM_SGLOFFADJ;
 1780         }
 1781         mb[0] += (nsegs << 17);
 1782         return (0);
 1783 
 1784  bad:
 1785         if (xn != 0)
 1786                 bus_dmamap_destroy(sc->sc_dmat, ix->ix_map);
 1787         return (rv);
 1788 }
 1789 
 1790 /*
 1791  * Map a block I/O data transfer (different in that there's only one per
 1792  * message maximum, and PAGE addressing may be used).  Write a scatter
 1793  * gather list into the message frame.
 1794  */
 1795 int
 1796 iop_msg_map_bio(struct iop_softc *sc, struct iop_msg *im, u_int32_t *mb,
 1797                 void *xferaddr, int xfersize, int out)
 1798 {
 1799         bus_dma_segment_t *ds;
 1800         bus_dmamap_t dm;
 1801         struct iop_xfer *ix;
 1802         u_int rv, i, nsegs, off, slen, tlen, flg;
 1803         paddr_t saddr, eaddr;
 1804         u_int32_t *p;
 1805 
 1806 #ifdef I2ODEBUG
 1807         if (xfersize == 0)
 1808                 panic("iop_msg_map_bio: null transfer");
 1809         if (xfersize > IOP_MAX_XFER)
 1810                 panic("iop_msg_map_bio: transfer too large");
 1811         if ((im->im_flags & IM_SGLOFFADJ) != 0)
 1812                 panic("iop_msg_map_bio: SGLOFFADJ");
 1813 #endif
 1814 
 1815         ix = im->im_xfer;
 1816         dm = ix->ix_map;
 1817         rv = bus_dmamap_load(sc->sc_dmat, dm, xferaddr, xfersize, NULL, 0);
 1818         if (rv != 0)
 1819                 return (rv);
 1820 
 1821         off = mb[0] >> 16;
 1822         nsegs = ((IOP_MAX_MSG_SIZE / 4) - off) >> 1;
 1823 
 1824         /*
 1825          * If the transfer is highly fragmented and won't fit using SIMPLE
 1826          * elements, use PAGE_LIST elements instead.  SIMPLE elements are
 1827          * potentially more efficient, both for us and the IOP.
 1828          */
 1829         if (dm->dm_nsegs > nsegs) {
 1830                 nsegs = 1;
 1831                 p = mb + off + 1;
 1832 
 1833                 /* XXX This should be done with a bus_space flag. */
 1834                 for (i = dm->dm_nsegs, ds = dm->dm_segs; i > 0; i--, ds++) {
 1835                         slen = ds->ds_len;
 1836                         saddr = ds->ds_addr;
 1837 
 1838                         while (slen > 0) {
 1839                                 eaddr = (saddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
 1840                                 tlen = min(eaddr - saddr, slen);
 1841                                 slen -= tlen;
 1842                                 *p++ = letoh32(saddr);
 1843                                 saddr = eaddr;
 1844                                 nsegs++;
 1845                         }
 1846                 }
 1847 
 1848                 mb[off] = xfersize | I2O_SGL_PAGE_LIST | I2O_SGL_END_BUFFER |
 1849                     I2O_SGL_END;
 1850                 if (out)
 1851                         mb[off] |= I2O_SGL_DATA_OUT;
 1852         } else {
 1853                 p = mb + off;
 1854                 nsegs = dm->dm_nsegs;
 1855 
 1856                 if (out)
 1857                         flg = I2O_SGL_SIMPLE | I2O_SGL_DATA_OUT;
 1858                 else
 1859                         flg = I2O_SGL_SIMPLE;
 1860 
 1861                 for (i = nsegs, ds = dm->dm_segs; i > 1; i--, p += 2, ds++) {
 1862                         p[0] = (u_int32_t)ds->ds_len | flg;
 1863                         p[1] = (u_int32_t)ds->ds_addr;
 1864                 }
 1865 
 1866                 p[0] = (u_int32_t)ds->ds_len | flg | I2O_SGL_END_BUFFER |
 1867                     I2O_SGL_END;
 1868                 p[1] = (u_int32_t)ds->ds_addr;
 1869                 nsegs <<= 1;
 1870         }
 1871 
 1872         /* Fix up the transfer record, and sync the map. */
 1873         ix->ix_flags = (out ? IX_OUT : IX_IN);
 1874         ix->ix_size = xfersize;
 1875         bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0,
 1876             ix->ix_map->dm_mapsize,
 1877             out ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_POSTREAD);
 1878 
 1879         /*
 1880          * Adjust the SGL offset and total message size fields.  We don't
 1881          * set IM_SGLOFFADJ, since it's used only for SIMPLE elements.
 1882          */
 1883         mb[0] += ((off << 4) + (nsegs << 16));
 1884         return (0);
 1885 }
 1886 
 1887 /*
 1888  * Unmap all data transfers associated with a message wrapper.
 1889  */
 1890 void
 1891 iop_msg_unmap(struct iop_softc *sc, struct iop_msg *im)
 1892 {
 1893         struct iop_xfer *ix;
 1894         int i;
 1895 
 1896 #ifdef I2ODEBUG 
 1897         if (im->im_xfer[0].ix_size == 0)
 1898                 panic("iop_msg_unmap: no transfers mapped");
 1899 #endif
 1900 
 1901         for (ix = im->im_xfer, i = 0;;) {
 1902                 bus_dmamap_sync(sc->sc_dmat, ix->ix_map, 0, ix->ix_size,
 1903                     ix->ix_flags & IX_OUT ? BUS_DMASYNC_POSTWRITE :
 1904                     BUS_DMASYNC_POSTREAD);
 1905                 bus_dmamap_unload(sc->sc_dmat, ix->ix_map);
 1906 
 1907                 /* Only the first DMA map is static. */
 1908                 if (i != 0)
 1909                         bus_dmamap_destroy(sc->sc_dmat, ix->ix_map);
 1910                 if ((++ix)->ix_size == 0) 
 1911                         break;
 1912                 if (++i >= IOP_MAX_MSG_XFERS)
 1913                         break;
 1914         }
 1915 }
 1916 
 1917 /*
 1918  * Post a message frame to the IOP's inbound queue.
 1919  */
 1920 int
 1921 iop_post(struct iop_softc *sc, u_int32_t *mb)
 1922 {
 1923         u_int32_t mfa;
 1924         int s;
 1925         size_t size = mb[0] >> 14 & ~3;
 1926 
 1927         /* ZZZ */
 1928         if (size > IOP_MAX_MSG_SIZE)
 1929                 panic("iop_post: frame too large");
 1930 
 1931 #ifdef I2ODEBUG
 1932         {
 1933                 int i;
 1934 
 1935                 printf("\niop_post\n");
 1936                 for (i = 0; i < size / sizeof *mb; i++)
 1937                         printf("%4d %08x\n", i, mb[i]);
 1938         }
 1939 #endif
 1940 
 1941         s = splbio();   /* XXX */
 1942 
 1943         /* Allocate a slot with the IOP. */
 1944         if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY)
 1945                 if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY) {
 1946                         splx(s);
 1947                         printf("%s: mfa not forthcoming\n",
 1948                             sc->sc_dv.dv_xname);
 1949                         return (EAGAIN);
 1950                 }
 1951 
 1952 #ifdef I2ODEBUG
 1953         printf("mfa = %u\n", mfa);
 1954 #endif
 1955 
 1956         /* Copy out the message frame. */
 1957         bus_space_write_region_4(sc->sc_iot, sc->sc_ioh, mfa, mb,
 1958             size / sizeof *mb);
 1959         bus_space_barrier(sc->sc_iot, sc->sc_ioh, mfa, size,
 1960             BUS_SPACE_BARRIER_WRITE);
 1961 
 1962         /* Post the MFA back to the IOP. */
 1963         iop_outl(sc, IOP_REG_IFIFO, mfa);
 1964 
 1965         splx(s);
 1966         return (0);
 1967 }
 1968 
 1969 /*
 1970  * Post a message to the IOP and deal with completion.
 1971  */
 1972 int
 1973 iop_msg_post(struct iop_softc *sc, struct iop_msg *im, void *xmb, int timo)
 1974 {
 1975         u_int32_t *mb = xmb;
 1976         int rv, s;
 1977         size_t size = mb[0] >> 14 & 3;
 1978 
 1979         /* Terminate the scatter/gather list chain. */
 1980         if ((im->im_flags & IM_SGLOFFADJ) != 0)
 1981                 mb[size - 2] |= I2O_SGL_END;
 1982 
 1983         /* Perform reply buffer DMA synchronisation. */
 1984         if (sc->sc_curib++ == 0)
 1985                 bus_dmamap_sync(sc->sc_dmat, sc->sc_rep_dmamap, 0,
 1986                     sc->sc_rep_size, BUS_DMASYNC_PREREAD);
 1987 
 1988         if ((rv = iop_post(sc, mb)) != 0)
 1989                 return (rv);
 1990 
 1991         if ((im->im_flags & IM_DISCARD) != 0)
 1992                 iop_msg_free(sc, im);
 1993         else if ((im->im_flags & IM_POLL) != 0 && timo == 0) {
 1994                 /* XXX For ofifo_init(). */
 1995                 rv = 0;
 1996         } else if ((im->im_flags & (IM_POLL | IM_WAIT)) != 0) {
 1997                 if ((im->im_flags & IM_POLL) != 0)
 1998                         iop_msg_poll(sc, im, timo);
 1999                 else
 2000                         iop_msg_wait(sc, im, timo);
 2001 
 2002                 s = splbio();
 2003                 if ((im->im_flags & IM_REPLIED) != 0) {
 2004                         if ((im->im_flags & IM_NOSTATUS) != 0)
 2005                                 rv = 0;
 2006                         else if ((im->im_flags & IM_FAIL) != 0)
 2007                                 rv = ENXIO;
 2008                         else if (im->im_reqstatus != I2O_STATUS_SUCCESS)
 2009                                 rv = EIO;
 2010                         else
 2011                                 rv = 0;
 2012                 } else
 2013                         rv = EBUSY;
 2014                 splx(s);
 2015         } else
 2016                 rv = 0;
 2017 
 2018         return (rv);
 2019 }
 2020 
 2021 /* 
 2022  * Spin until the specified message is replied to.
 2023  */
 2024 void
 2025 iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo)
 2026 {
 2027         u_int32_t rmfa;
 2028         int s, status;
 2029 
 2030         s = splbio();   /* XXX */
 2031 
 2032         /* Wait for completion. */
 2033         for (timo *= 10; timo != 0; timo--) {
 2034                 if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) != 0) {
 2035                         /* Double read to account for IOP bug. */
 2036                         rmfa = iop_inl(sc, IOP_REG_OFIFO);
 2037                         if (rmfa == IOP_MFA_EMPTY)
 2038                                 rmfa = iop_inl(sc, IOP_REG_OFIFO);
 2039                         if (rmfa != IOP_MFA_EMPTY) {
 2040                                 status = iop_handle_reply(sc, rmfa);
 2041 
 2042                                 /*
 2043                                  * Return the reply frame to the IOP's
 2044                                  * outbound FIFO.
 2045                                  */
 2046                                 iop_outl(sc, IOP_REG_OFIFO, rmfa);
 2047                         }
 2048                 }
 2049                 if ((im->im_flags & IM_REPLIED) != 0)
 2050                         break;
 2051                 DELAY(100);
 2052         }
 2053 
 2054         if (timo == 0) {
 2055 #ifdef I2ODEBUG
 2056                 printf("%s: poll - no reply\n", sc->sc_dv.dv_xname);
 2057                 if (iop_status_get(sc, 1) != 0)
 2058                         printf("iop_msg_poll: unable to retrieve status\n");
 2059                 else
 2060                         printf("iop_msg_poll: IOP state = %d\n",
 2061                             (letoh32(sc->sc_status.segnumber) >> 16) & 0xff); 
 2062 #endif
 2063         }
 2064 
 2065         splx(s);
 2066 }
 2067 
 2068 /*
 2069  * Sleep until the specified message is replied to.
 2070  */
 2071 void
 2072 iop_msg_wait(struct iop_softc *sc, struct iop_msg *im, int timo)
 2073 {
 2074         int s, rv;
 2075 
 2076         s = splbio();
 2077         if ((im->im_flags & IM_REPLIED) != 0) {
 2078                 splx(s);
 2079                 return;
 2080         }
 2081         rv = tsleep(im, PRIBIO, "iopmsg", timo * hz / 1000);
 2082         splx(s);
 2083 
 2084 #ifdef I2ODEBUG
 2085         if (rv != 0) {
 2086                 printf("iop_msg_wait: tsleep() == %d\n", rv);
 2087                 if (iop_status_get(sc, 0) != 0)
 2088                         printf("iop_msg_wait: unable to retrieve status\n");
 2089                 else
 2090                         printf("iop_msg_wait: IOP state = %d\n",
 2091                             (letoh32(sc->sc_status.segnumber) >> 16) & 0xff); 
 2092         }
 2093 #endif
 2094 }
 2095 
 2096 /*
 2097  * Release an unused message frame back to the IOP's inbound fifo.
 2098  */
 2099 void
 2100 iop_release_mfa(struct iop_softc *sc, u_int32_t mfa)
 2101 {
 2102 
 2103         /* Use the frame to issue a no-op. */
 2104         iop_outl(sc, mfa, I2O_VERSION_11 | (4 << 16));
 2105         iop_outl(sc, mfa + 4, I2O_MSGFUNC(I2O_TID_IOP, I2O_UTIL_NOP));
 2106         iop_outl(sc, mfa + 8, 0);
 2107         iop_outl(sc, mfa + 12, 0);
 2108 
 2109         iop_outl(sc, IOP_REG_IFIFO, mfa);
 2110 }
 2111 
 2112 #ifdef I2ODEBUG
 2113 /*
 2114  * Dump a reply frame header.
 2115  */
 2116 void
 2117 iop_reply_print(struct iop_softc *sc, struct i2o_reply *rb)
 2118 {
 2119         u_int function, detail;
 2120 #ifdef I2OVERBOSE
 2121         const char *statusstr;
 2122 #endif
 2123 
 2124         function = (letoh32(rb->msgfunc) >> 24) & 0xff;
 2125         detail = letoh16(rb->detail);
 2126 
 2127         printf("%s: reply:\n", sc->sc_dv.dv_xname);
 2128 
 2129 #ifdef I2OVERBOSE
 2130         if (rb->reqstatus < sizeof(iop_status) / sizeof(iop_status[0]))
 2131                 statusstr = iop_status[rb->reqstatus];
 2132         else
 2133                 statusstr = "undefined error code";
 2134 
 2135         printf("%s:   function=0x%02x status=0x%02x (%s)\n", 
 2136             sc->sc_dv.dv_xname, function, rb->reqstatus, statusstr);
 2137 #else
 2138         printf("%s:   function=0x%02x status=0x%02x\n", 
 2139             sc->sc_dv.dv_xname, function, rb->reqstatus);
 2140 #endif
 2141         printf("%s:   detail=0x%04x ictx=0x%08x tctx=0x%08x\n",
 2142             sc->sc_dv.dv_xname, detail, letoh32(rb->msgictx),
 2143             letoh32(rb->msgtctx));
 2144         printf("%s:   tidi=%d tidt=%d flags=0x%02x\n", sc->sc_dv.dv_xname,
 2145             (letoh32(rb->msgfunc) >> 12) & 4095, letoh32(rb->msgfunc) & 4095,
 2146             (letoh32(rb->msgflags) >> 8) & 0xff);
 2147 }
 2148 #endif
 2149 
 2150 /*
 2151  * Dump a transport failure reply.
 2152  */
 2153 void
 2154 iop_tfn_print(struct iop_softc *sc, struct i2o_fault_notify *fn)
 2155 {
 2156 
 2157         printf("%s: WARNING: transport failure:\n", sc->sc_dv.dv_xname);
 2158 
 2159         printf("%s:   ictx=0x%08x tctx=0x%08x\n", sc->sc_dv.dv_xname,
 2160             letoh32(fn->msgictx), letoh32(fn->msgtctx));
 2161         printf("%s:  failurecode=0x%02x severity=0x%02x\n",
 2162             sc->sc_dv.dv_xname, fn->failurecode, fn->severity);
 2163         printf("%s:  highestver=0x%02x lowestver=0x%02x\n",
 2164             sc->sc_dv.dv_xname, fn->highestver, fn->lowestver);
 2165 }
 2166 
 2167 /*
 2168  * Translate an I2O ASCII field into a C string.
 2169  */
 2170 void
 2171 iop_strvis(struct iop_softc *sc, const char *src, int slen, char *dst, int dlen)
 2172 {
 2173         int hc, lc, i, nit;
 2174 
 2175         dlen--;
 2176         lc = 0;
 2177         hc = 0;
 2178         i = 0;
 2179 
 2180         /*
 2181          * DPT use NUL as a space, whereas AMI use it as a terminator.  The
 2182          * spec has nothing to say about it.  Since AMI fields are usually
 2183          * filled with junk after the terminator, ...
 2184          */
 2185         nit = (letoh16(sc->sc_status.orgid) != I2O_ORG_DPT);
 2186 
 2187         while (slen-- != 0 && dlen-- != 0) {
 2188                 if (nit && *src == '\0')
 2189                         break;
 2190                 else if (*src <= 0x20 || *src >= 0x7f) {
 2191                         if (hc)
 2192                                 dst[i++] = ' ';
 2193                 } else {
 2194                         hc = 1;
 2195                         dst[i++] = *src;
 2196                         lc = i;
 2197                 }
 2198                 src++;
 2199         }
 2200         
 2201         dst[lc] = '\0';
 2202 }
 2203 
 2204 /*
 2205  * Retrieve the DEVICE_IDENTITY parameter group from the target and dump it.
 2206  */
 2207 int
 2208 iop_print_ident(struct iop_softc *sc, int tid)
 2209 {
 2210         struct {
 2211                 struct  i2o_param_op_results pr;
 2212                 struct  i2o_param_read_results prr;
 2213                 struct  i2o_param_device_identity di;
 2214         } __attribute__ ((__packed__)) p;
 2215         char buf[32];
 2216         int rv;
 2217 
 2218         rv = iop_param_op(sc, tid, NULL, 0, I2O_PARAM_DEVICE_IDENTITY, &p,
 2219             sizeof(p));
 2220         if (rv != 0)
 2221                 return (rv);
 2222 
 2223         iop_strvis(sc, p.di.vendorinfo, sizeof(p.di.vendorinfo), buf,
 2224             sizeof(buf));
 2225         printf(" <%s, ", buf);
 2226         iop_strvis(sc, p.di.productinfo, sizeof(p.di.productinfo), buf,
 2227             sizeof(buf));
 2228         printf("%s, ", buf);
 2229         iop_strvis(sc, p.di.revlevel, sizeof(p.di.revlevel), buf, sizeof(buf));
 2230         printf("%s>", buf);
 2231 
 2232         return (0);
 2233 }
 2234 
 2235 /*
 2236  * Claim or unclaim the specified TID.
 2237  */
 2238 int
 2239 iop_util_claim(struct iop_softc *sc, struct iop_initiator *ii, int release,
 2240               int flags)
 2241 {
 2242         struct iop_msg *im;
 2243         struct i2o_util_claim mf;
 2244         int rv, func;
 2245 
 2246         func = release ? I2O_UTIL_CLAIM_RELEASE : I2O_UTIL_CLAIM;
 2247         im = iop_msg_alloc(sc, ii, IM_WAIT);
 2248 
 2249         /* We can use the same structure, as they're identical. */
 2250         mf.msgflags = I2O_MSGFLAGS(i2o_util_claim);
 2251         mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, func);
 2252         mf.msgictx = ii->ii_ictx;
 2253         mf.msgtctx = im->im_tctx;
 2254         mf.flags = flags;
 2255 
 2256         rv = iop_msg_post(sc, im, &mf, 5000);
 2257         iop_msg_free(sc, im);
 2258         return (rv);
 2259 }       
 2260 
 2261 /*
 2262  * Perform an abort.
 2263  */
 2264 int iop_util_abort(struct iop_softc *sc, struct iop_initiator *ii, int func,
 2265                   int tctxabort, int flags)
 2266 {
 2267         struct iop_msg *im;
 2268         struct i2o_util_abort mf;
 2269         int rv;
 2270 
 2271         im = iop_msg_alloc(sc, ii, IM_WAIT);
 2272 
 2273         mf.msgflags = I2O_MSGFLAGS(i2o_util_abort);
 2274         mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, I2O_UTIL_ABORT);
 2275         mf.msgictx = ii->ii_ictx;
 2276         mf.msgtctx = im->im_tctx;
 2277         mf.flags = (func << 24) | flags;
 2278         mf.tctxabort = tctxabort;
 2279 
 2280         rv = iop_msg_post(sc, im, &mf, 5000);
 2281         iop_msg_free(sc, im);
 2282         return (rv);
 2283 }
 2284 
 2285 /*
 2286  * Enable or disable reception of events for the specified device.
 2287  */
 2288 int iop_util_eventreg(struct iop_softc *sc, struct iop_initiator *ii, int mask)
 2289 {
 2290         struct iop_msg *im;
 2291         struct i2o_util_event_register mf;
 2292 
 2293         im = iop_msg_alloc(sc, ii, 0);
 2294 
 2295         mf.msgflags = I2O_MSGFLAGS(i2o_util_event_register);
 2296         mf.msgfunc = I2O_MSGFUNC(ii->ii_tid, I2O_UTIL_EVENT_REGISTER);
 2297         mf.msgictx = ii->ii_ictx;
 2298         mf.msgtctx = im->im_tctx;
 2299         mf.eventmask = mask;
 2300 
 2301         /* This message is replied to only when events are signalled. */
 2302         return (iop_msg_post(sc, im, &mf, 0));
 2303 }
 2304 
 2305 int
 2306 iopopen(dev_t dev, int flag, int mode, struct proc *p)
 2307 {
 2308         struct iop_softc *sc;
 2309 
 2310         if (!(sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev))))
 2311                 return (ENXIO);
 2312         if ((sc->sc_flags & IOP_ONLINE) == 0)
 2313                 return (ENXIO);
 2314         if ((sc->sc_flags & IOP_OPEN) != 0)
 2315                 return (EBUSY);
 2316         sc->sc_flags |= IOP_OPEN;
 2317 
 2318         sc->sc_ptb = malloc(IOP_MAX_XFER * IOP_MAX_MSG_XFERS, M_DEVBUF,
 2319             M_WAITOK);
 2320         if (sc->sc_ptb == NULL) {
 2321                 sc->sc_flags ^= IOP_OPEN;
 2322                 return (ENOMEM);
 2323         }
 2324 
 2325         return (0);
 2326 }
 2327 
 2328 int
 2329 iopclose(dev_t dev, int flag, int mode, struct proc *p)
 2330 {
 2331         struct iop_softc *sc;
 2332 
 2333         sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev)); /* XXX */
 2334         free(sc->sc_ptb, M_DEVBUF);
 2335         sc->sc_flags &= ~IOP_OPEN;
 2336         return (0);
 2337 }
 2338 
 2339 int
 2340 iopioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 2341 {
 2342         struct iop_softc *sc;
 2343         struct iovec *iov;
 2344         int rv, i;
 2345 
 2346         if (securelevel >= 2)
 2347                 return (EPERM);
 2348 
 2349         sc = (struct iop_softc *)device_lookup(&iop_cd, minor(dev)); /* XXX */
 2350 
 2351         switch (cmd) {
 2352         case IOPIOCPT:
 2353                 return (iop_passthrough(sc, (struct ioppt *)data));
 2354 
 2355         case IOPIOCGSTATUS:
 2356                 iov = (struct iovec *)data;
 2357                 i = sizeof(struct i2o_status);
 2358                 if (i > iov->iov_len)
 2359                         i = iov->iov_len;
 2360                 else
 2361                         iov->iov_len = i;
 2362                 if ((rv = iop_status_get(sc, 0)) == 0)
 2363                         rv = copyout(&sc->sc_status, iov->iov_base, i);
 2364                 return (rv);
 2365 
 2366         case IOPIOCGLCT:
 2367         case IOPIOCGTIDMAP:
 2368         case IOPIOCRECONFIG:
 2369                 break;
 2370 
 2371         default:
 2372 #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
 2373                 printf("%s: unknown ioctl %lx\n", sc->sc_dv.dv_xname, cmd);
 2374 #endif
 2375                 return (ENOTTY);
 2376         }
 2377 
 2378         if ((rv = lockmgr(&sc->sc_conflock, LK_SHARED, NULL)) != 0)
 2379                 return (rv);
 2380 
 2381         switch (cmd) {
 2382         case IOPIOCGLCT:
 2383                 iov = (struct iovec *)data;
 2384                 i = letoh16(sc->sc_lct->tablesize) << 2;
 2385                 if (i > iov->iov_len)
 2386                         i = iov->iov_len;
 2387                 else
 2388                         iov->iov_len = i;
 2389                 rv = copyout(sc->sc_lct, iov->iov_base, i);
 2390                 break;
 2391 
 2392         case IOPIOCRECONFIG:
 2393                 rv = iop_reconfigure(sc, 0);
 2394                 break;
 2395 
 2396         case IOPIOCGTIDMAP:
 2397                 iov = (struct iovec *)data;
 2398                 i = sizeof(struct iop_tidmap) * sc->sc_nlctent;
 2399                 if (i > iov->iov_len)
 2400                         i = iov->iov_len;
 2401                 else
 2402                         iov->iov_len = i;
 2403                 rv = copyout(sc->sc_tidmap, iov->iov_base, i);
 2404                 break;
 2405         }
 2406 
 2407         lockmgr(&sc->sc_conflock, LK_RELEASE, NULL);
 2408         return (rv);
 2409 }
 2410 
 2411 int
 2412 iop_passthrough(struct iop_softc *sc, struct ioppt *pt)
 2413 {
 2414         struct iop_msg *im;
 2415         struct i2o_msg *mf;
 2416         struct ioppt_buf *ptb;
 2417         int rv, i, mapped;
 2418         void *buf;
 2419 
 2420         mf = NULL;
 2421         im = NULL;
 2422         mapped = 1;
 2423 
 2424         if (pt->pt_msglen > IOP_MAX_MSG_SIZE ||
 2425             pt->pt_msglen > (letoh16(sc->sc_status.inboundmframesize) << 2) ||
 2426             pt->pt_msglen < sizeof(struct i2o_msg) ||
 2427             pt->pt_nbufs > IOP_MAX_MSG_XFERS ||
 2428             pt->pt_nbufs < 0 || pt->pt_replylen < 0 ||
 2429             pt->pt_timo < 1000 || pt->pt_timo > 5*60*1000)
 2430                 return (EINVAL);
 2431 
 2432         for (i = 0; i < pt->pt_nbufs; i++)
 2433                 if (pt->pt_bufs[i].ptb_datalen > IOP_MAX_XFER) {
 2434                         rv = ENOMEM;
 2435                         goto bad;
 2436                 }
 2437 
 2438         mf = malloc(IOP_MAX_MSG_SIZE, M_DEVBUF, M_WAITOK);
 2439         if (mf == NULL)
 2440                 return (ENOMEM);
 2441 
 2442         if ((rv = copyin(pt->pt_msg, mf, pt->pt_msglen)) != 0)
 2443                 goto bad;
 2444 
 2445         im = iop_msg_alloc(sc, NULL, IM_WAIT | IM_NOSTATUS);
 2446         im->im_rb = (struct i2o_reply *)mf;
 2447         mf->msgictx = IOP_ICTX;
 2448         mf->msgtctx = im->im_tctx;
 2449 
 2450         for (i = 0; i < pt->pt_nbufs; i++) {
 2451                 ptb = &pt->pt_bufs[i];
 2452                 buf = sc->sc_ptb + i * IOP_MAX_XFER;
 2453 
 2454                 if ((u_int)ptb->ptb_datalen > IOP_MAX_XFER) {
 2455                         rv = EINVAL;
 2456                         goto bad;
 2457                 }
 2458 
 2459                 if (ptb->ptb_out != 0) {
 2460                         rv = copyin(ptb->ptb_data, buf, ptb->ptb_datalen);
 2461                         if (rv != 0)
 2462                                 goto bad;
 2463                 }
 2464 
 2465                 rv = iop_msg_map(sc, im, (u_int32_t *)mf, buf,
 2466                     ptb->ptb_datalen, ptb->ptb_out != 0);
 2467                 if (rv != 0)
 2468                         goto bad;
 2469                 mapped = 1;
 2470         }
 2471 
 2472         if ((rv = iop_msg_post(sc, im, mf, pt->pt_timo)) != 0)
 2473                 goto bad;
 2474 
 2475         i = (letoh32(im->im_rb->msgflags) >> 14) & ~3;
 2476         if (i > IOP_MAX_MSG_SIZE)
 2477                 i = IOP_MAX_MSG_SIZE;
 2478         if (i > pt->pt_replylen)
 2479                 i = pt->pt_replylen;
 2480         if ((rv = copyout(im->im_rb, pt->pt_reply, i)) != 0)
 2481                 goto bad;
 2482 
 2483         iop_msg_unmap(sc, im);
 2484         mapped = 0;
 2485 
 2486         for (i = 0; i < pt->pt_nbufs; i++) {
 2487                 ptb = &pt->pt_bufs[i];
 2488                 if (ptb->ptb_out != 0)
 2489                         continue;
 2490                 buf = sc->sc_ptb + i * IOP_MAX_XFER;
 2491                 rv = copyout(buf, ptb->ptb_data, ptb->ptb_datalen);
 2492                 if (rv != 0)
 2493                         break;
 2494         }
 2495 
 2496  bad:
 2497         if (mapped != 0)
 2498                 iop_msg_unmap(sc, im);
 2499         if (im != NULL)
 2500                 iop_msg_free(sc, im);
 2501         if (mf != NULL)
 2502                 free(mf, M_DEVBUF);
 2503         return (rv);
 2504 }

/* [<][>][^][v][top][bottom][index][help] */