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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/vme/xd.c

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

    1 /*      $NetBSD: xd.c,v 1.54 2003/09/29 09:50:22 wiz Exp $      */
    2 
    3 /*
    4  *
    5  * Copyright (c) 1995 Charles D. Cranor
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Charles D. Cranor.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  *
   36  * x d . c   x y l o g i c s   7 5 3 / 7 0 5 3   v m e / s m d   d r i v e r
   37  *
   38  * author: Chuck Cranor <chuck@ccrc.wustl.edu>
   39  * started: 27-Feb-95
   40  * references: [1] Xylogics Model 753 User's Manual
   41  *                 part number: 166-753-001, Revision B, May 21, 1988.
   42  *                 "Your Partner For Performance"
   43  *             [2] other NetBSD disk device drivers
   44  *
   45  * Special thanks go to Scott E. Campbell of Xylogics, Inc. for taking
   46  * the time to answer some of my questions about the 753/7053.
   47  *
   48  * note: the 753 and the 7053 are programmed the same way, but are
   49  * different sizes.   the 753 is a 6U VME card, while the 7053 is a 9U
   50  * VME card (found in many VME based suns).
   51  */
   52 
   53 #include <sys/cdefs.h>
   54 __KERNEL_RCSID(0, "$NetBSD: xd.c,v 1.54 2003/09/29 09:50:22 wiz Exp $");
   55 
   56 #undef XDC_DEBUG                /* full debug */
   57 #define XDC_DIAG                /* extra sanity checks */
   58 #if defined(DIAGNOSTIC) && !defined(XDC_DIAG)
   59 #define XDC_DIAG                /* link in with master DIAG option */
   60 #endif
   61 
   62 #include <sys/param.h>
   63 #include <sys/proc.h>
   64 #include <sys/systm.h>
   65 #include <sys/kernel.h>
   66 #include <sys/file.h>
   67 #include <sys/stat.h>
   68 #include <sys/ioctl.h>
   69 #include <sys/buf.h>
   70 #include <sys/uio.h>
   71 #include <sys/malloc.h>
   72 #include <sys/device.h>
   73 #include <sys/disklabel.h>
   74 #include <sys/disk.h>
   75 #include <sys/syslog.h>
   76 #include <sys/dkbad.h>
   77 #include <sys/conf.h>
   78 
   79 #include <machine/bus.h>
   80 #include <machine/intr.h>
   81 
   82 #if defined(__sparc__) || defined(sun3)
   83 #include <dev/sun/disklabel.h>
   84 #endif
   85 
   86 #include <dev/vme/vmereg.h>
   87 #include <dev/vme/vmevar.h>
   88 
   89 #include <dev/vme/xdreg.h>
   90 #include <dev/vme/xdvar.h>
   91 #include <dev/vme/xio.h>
   92 
   93 #include "locators.h"
   94 
   95 /*
   96  * macros
   97  */
   98 
   99 /*
  100  * XDC_TWAIT: add iorq "N" to tail of SC's wait queue
  101  */
  102 #define XDC_TWAIT(SC, N) { \
  103         (SC)->waitq[(SC)->waitend] = (N); \
  104         (SC)->waitend = ((SC)->waitend + 1) % XDC_MAXIOPB; \
  105         (SC)->nwait++; \
  106 }
  107 
  108 /*
  109  * XDC_HWAIT: add iorq "N" to head of SC's wait queue
  110  */
  111 #define XDC_HWAIT(SC, N) { \
  112         (SC)->waithead = ((SC)->waithead == 0) ? \
  113                 (XDC_MAXIOPB - 1) : ((SC)->waithead - 1); \
  114         (SC)->waitq[(SC)->waithead] = (N); \
  115         (SC)->nwait++; \
  116 }
  117 
  118 /*
  119  * XDC_GET_WAITER: gets the first request waiting on the waitq
  120  * and removes it (so it can be submitted)
  121  */
  122 #define XDC_GET_WAITER(XDCSC, RQ) { \
  123         (RQ) = (XDCSC)->waitq[(XDCSC)->waithead]; \
  124         (XDCSC)->waithead = ((XDCSC)->waithead + 1) % XDC_MAXIOPB; \
  125         xdcsc->nwait--; \
  126 }
  127 
  128 /*
  129  * XDC_FREE: add iorq "N" to SC's free list
  130  */
  131 #define XDC_FREE(SC, N) { \
  132         (SC)->freereq[(SC)->nfree++] = (N); \
  133         (SC)->reqs[N].mode = 0; \
  134         if ((SC)->nfree == 1) wakeup(&(SC)->nfree); \
  135 }
  136 
  137 
  138 /*
  139  * XDC_RQALLOC: allocate an iorq off the free list (assume nfree > 0).
  140  */
  141 #define XDC_RQALLOC(XDCSC) (XDCSC)->freereq[--((XDCSC)->nfree)]
  142 
  143 /*
  144  * XDC_GO: start iopb ADDR (DVMA addr in a u_long) on XDC
  145  */
  146 #define XDC_GO(XDC, ADDR) { \
  147         (XDC)->xdc_iopbaddr0 = ((ADDR) & 0xff); \
  148         (ADDR) = ((ADDR) >> 8); \
  149         (XDC)->xdc_iopbaddr1 = ((ADDR) & 0xff); \
  150         (ADDR) = ((ADDR) >> 8); \
  151         (XDC)->xdc_iopbaddr2 = ((ADDR) & 0xff); \
  152         (ADDR) = ((ADDR) >> 8); \
  153         (XDC)->xdc_iopbaddr3 = (ADDR); \
  154         (XDC)->xdc_iopbamod = XDC_ADDRMOD; \
  155         (XDC)->xdc_csr = XDC_ADDIOPB; /* go! */ \
  156 }
  157 
  158 /*
  159  * XDC_WAIT: wait for XDC's csr "BITS" to come on in "TIME".
  160  *   LCV is a counter.  If it goes to zero then we timed out.
  161  */
  162 #define XDC_WAIT(XDC, LCV, TIME, BITS) { \
  163         (LCV) = (TIME); \
  164         while ((LCV) > 0) { \
  165                 if ((XDC)->xdc_csr & (BITS)) break; \
  166                 (LCV) = (LCV) - 1; \
  167                 DELAY(1); \
  168         } \
  169 }
  170 
  171 /*
  172  * XDC_DONE: don't need IORQ, get error code and free (done after xdc_cmd)
  173  */
  174 #define XDC_DONE(SC,RQ,ER) { \
  175         if ((RQ) == XD_ERR_FAIL) { \
  176                 (ER) = (RQ); \
  177         } else { \
  178                 if ((SC)->ndone-- == XDC_SUBWAITLIM) \
  179                 wakeup(&(SC)->ndone); \
  180                 (ER) = (SC)->reqs[RQ].errno; \
  181                 XDC_FREE((SC), (RQ)); \
  182         } \
  183 }
  184 
  185 /*
  186  * XDC_ADVANCE: advance iorq's pointers by a number of sectors
  187  */
  188 #define XDC_ADVANCE(IORQ, N) { \
  189         if (N) { \
  190                 (IORQ)->sectcnt -= (N); \
  191                 (IORQ)->blockno += (N); \
  192                 (IORQ)->dbuf += ((N)*XDFM_BPS); \
  193         } \
  194 }
  195 
  196 /*
  197  * note - addresses you can sleep on:
  198  *   [1] & of xd_softc's "state" (waiting for a chance to attach a drive)
  199  *   [2] & of xdc_softc's "nfree" (waiting for a free iorq/iopb)
  200  *   [3] & of xdc_softc's "ndone" (waiting for number of done iorq/iopb's
  201  *                                 to drop below XDC_SUBWAITLIM)
  202  *   [4] & an iorq (waiting for an XD_SUB_WAIT iorq to finish)
  203  */
  204 
  205 
  206 /*
  207  * function prototypes
  208  * "xdc_*" functions are internal, all others are external interfaces
  209  */
  210 
  211 extern int pil_to_vme[];        /* from obio.c */
  212 
  213 /* internals */
  214 int     xdc_cmd __P((struct xdc_softc *, int, int, int, int, int, char *, int));
  215 char   *xdc_e2str __P((int));
  216 int     xdc_error __P((struct xdc_softc *, struct xd_iorq *,
  217                    struct xd_iopb *, int, int));
  218 int     xdc_ioctlcmd __P((struct xd_softc *, dev_t dev, struct xd_iocmd *));
  219 void    xdc_perror __P((struct xd_iorq *, struct xd_iopb *, int));
  220 int     xdc_piodriver __P((struct xdc_softc *, int, int));
  221 int     xdc_remove_iorq __P((struct xdc_softc *));
  222 int     xdc_reset __P((struct xdc_softc *, int, int, int, struct xd_softc *));
  223 inline void xdc_rqinit __P((struct xd_iorq *, struct xdc_softc *,
  224                             struct xd_softc *, int, u_long, int,
  225                             caddr_t, struct buf *));
  226 void    xdc_rqtopb __P((struct xd_iorq *, struct xd_iopb *, int, int));
  227 void    xdc_start __P((struct xdc_softc *, int));
  228 int     xdc_startbuf __P((struct xdc_softc *, struct xd_softc *, struct buf *));
  229 int     xdc_submit_iorq __P((struct xdc_softc *, int, int));
  230 void    xdc_tick __P((void *));
  231 void    xdc_xdreset __P((struct xdc_softc *, struct xd_softc *));
  232 int     xd_dmamem_alloc(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *,
  233                         int *, bus_size_t, caddr_t *, bus_addr_t *);
  234 void    xd_dmamem_free(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *,
  235                         int, bus_size_t, caddr_t);
  236 
  237 
  238 /* machine interrupt hook */
  239 int     xdcintr __P((void *));
  240 
  241 /* autoconf */
  242 int     xdcmatch __P((struct device *, struct cfdata *, void *));
  243 void    xdcattach __P((struct device *, struct device *, void *));
  244 int     xdmatch __P((struct device *, struct cfdata *, void *));
  245 void    xdattach __P((struct device *, struct device *, void *));
  246 static  int xdc_probe __P((void *, bus_space_tag_t, bus_space_handle_t));
  247 
  248 static  void xddummystrat __P((struct buf *));
  249 int     xdgetdisklabel __P((struct xd_softc *, void *));
  250 
  251 /* XXX - think about this more.. xd_machdep? */
  252 void xdc_md_setup __P((void));
  253 int     XDC_DELAY;
  254 
  255 #if defined(__sparc__)
  256 #include <sparc/sparc/vaddrs.h>
  257 #include <sparc/sparc/cpuvar.h>
  258 void xdc_md_setup()
  259 {
  260         if (CPU_ISSUN4 && cpuinfo.cpu_type == CPUTYP_4_300)
  261                 XDC_DELAY = XDC_DELAY_4_300;
  262         else
  263                 XDC_DELAY = XDC_DELAY_SPARC;
  264 }
  265 #elif defined(sun3)
  266 void xdc_md_setup()
  267 {
  268         XDC_DELAY = XDC_DELAY_SUN3;
  269 }
  270 #else
  271 void xdc_md_setup()
  272 {
  273         XDC_DELAY = 0;
  274 }
  275 #endif
  276 
  277 /*
  278  * cfattach's: device driver interface to autoconfig
  279  */
  280 
  281 CFATTACH_DECL(xdc, sizeof(struct xdc_softc),
  282     xdcmatch, xdcattach, NULL, NULL);
  283 
  284 CFATTACH_DECL(xd, sizeof(struct xd_softc),
  285     xdmatch, xdattach, NULL, NULL);
  286 
  287 extern struct cfdriver xd_cd;
  288 
  289 dev_type_open(xdopen);
  290 dev_type_close(xdclose);
  291 dev_type_read(xdread);
  292 dev_type_write(xdwrite);
  293 dev_type_ioctl(xdioctl);
  294 dev_type_strategy(xdstrategy);
  295 dev_type_dump(xddump);
  296 dev_type_size(xdsize);
  297 
  298 const struct bdevsw xd_bdevsw = {
  299         xdopen, xdclose, xdstrategy, xdioctl, xddump, xdsize, D_DISK
  300 };
  301 
  302 const struct cdevsw xd_cdevsw = {
  303         xdopen, xdclose, xdread, xdwrite, xdioctl,
  304         nostop, notty, nopoll, nommap, nokqfilter, D_DISK
  305 };
  306 
  307 struct xdc_attach_args {        /* this is the "aux" args to xdattach */
  308         int     driveno;        /* unit number */
  309         int     fullmode;       /* submit mode */
  310         int     booting;        /* are we booting or not? */
  311 };
  312 
  313 /*
  314  * dkdriver
  315  */
  316 
  317 struct dkdriver xddkdriver = {xdstrategy};
  318 
  319 /*
  320  * start: disk label fix code (XXX)
  321  */
  322 
  323 static void *xd_labeldata;
  324 
  325 static void
  326 xddummystrat(bp)
  327         struct buf *bp;
  328 {
  329         if (bp->b_bcount != XDFM_BPS)
  330                 panic("xddummystrat");
  331         bcopy(xd_labeldata, bp->b_data, XDFM_BPS);
  332         bp->b_flags |= B_DONE;
  333         bp->b_flags &= ~B_BUSY;
  334 }
  335 
  336 int
  337 xdgetdisklabel(xd, b)
  338         struct xd_softc *xd;
  339         void *b;
  340 {
  341         const char *err;
  342 #if defined(__sparc__) || defined(sun3)
  343         struct sun_disklabel *sdl;
  344 #endif
  345 
  346         /* We already have the label data in `b'; setup for dummy strategy */
  347         xd_labeldata = b;
  348 
  349         /* Required parameter for readdisklabel() */
  350         xd->sc_dk.dk_label->d_secsize = XDFM_BPS;
  351 
  352         err = readdisklabel(MAKEDISKDEV(0, xd->sc_dev.dv_unit, RAW_PART),
  353                             xddummystrat,
  354                             xd->sc_dk.dk_label, xd->sc_dk.dk_cpulabel);
  355         if (err) {
  356                 printf("%s: %s\n", xd->sc_dev.dv_xname, err);
  357                 return(XD_ERR_FAIL);
  358         }
  359 
  360 #if defined(__sparc__) || defined(sun3)
  361         /* Ok, we have the label; fill in `pcyl' if there's SunOS magic */
  362         sdl = (struct sun_disklabel *)xd->sc_dk.dk_cpulabel->cd_block;
  363         if (sdl->sl_magic == SUN_DKMAGIC) {
  364                 xd->pcyl = sdl->sl_pcylinders;
  365         } else
  366 #endif
  367         {
  368                 printf("%s: WARNING: no `pcyl' in disk label.\n",
  369                                                         xd->sc_dev.dv_xname);
  370                 xd->pcyl = xd->sc_dk.dk_label->d_ncylinders +
  371                         xd->sc_dk.dk_label->d_acylinders;
  372                 printf("%s: WARNING: guessing pcyl=%d (ncyl+acyl)\n",
  373                         xd->sc_dev.dv_xname, xd->pcyl);
  374         }
  375 
  376         xd->ncyl = xd->sc_dk.dk_label->d_ncylinders;
  377         xd->acyl = xd->sc_dk.dk_label->d_acylinders;
  378         xd->nhead = xd->sc_dk.dk_label->d_ntracks;
  379         xd->nsect = xd->sc_dk.dk_label->d_nsectors;
  380         xd->sectpercyl = xd->nhead * xd->nsect;
  381         xd->sc_dk.dk_label->d_secsize = XDFM_BPS; /* not handled by
  382                                                   * sun->bsd */
  383         return(XD_ERR_AOK);
  384 }
  385 
  386 /*
  387  * end: disk label fix code (XXX)
  388  */
  389 
  390 /*
  391  * Shorthand for allocating, mapping and loading a DMA buffer
  392  */
  393 int
  394 xd_dmamem_alloc(tag, map, seg, nsegp, len, kvap, dmap)
  395         bus_dma_tag_t           tag;
  396         bus_dmamap_t            map;
  397         bus_dma_segment_t       *seg;
  398         int                     *nsegp;
  399         bus_size_t              len;
  400         caddr_t                 *kvap;
  401         bus_addr_t              *dmap;
  402 {
  403         int nseg;
  404         int error;
  405 
  406         if ((error = bus_dmamem_alloc(tag, len, 0, 0,
  407                                       seg, 1, &nseg, BUS_DMA_NOWAIT)) != 0) {
  408                 return (error);
  409         }
  410 
  411         if ((error = bus_dmamem_map(tag, seg, nseg,
  412                                     len, kvap,
  413                                     BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  414                 bus_dmamem_free(tag, seg, nseg);
  415                 return (error);
  416         }
  417 
  418         if ((error = bus_dmamap_load(tag, map,
  419                                      *kvap, len, NULL,
  420                                      BUS_DMA_NOWAIT)) != 0) {
  421                 bus_dmamem_unmap(tag, *kvap, len);
  422                 bus_dmamem_free(tag, seg, nseg);
  423                 return (error);
  424         }
  425 
  426         *dmap = map->dm_segs[0].ds_addr;
  427         *nsegp = nseg;
  428         return (0);
  429 }
  430 
  431 void
  432 xd_dmamem_free(tag, map, seg, nseg, len, kva)
  433         bus_dma_tag_t           tag;
  434         bus_dmamap_t            map;
  435         bus_dma_segment_t       *seg;
  436         int                     nseg;
  437         bus_size_t              len;
  438         caddr_t                 kva;
  439 {
  440 
  441         bus_dmamap_unload(tag, map);
  442         bus_dmamem_unmap(tag, kva, len);
  443         bus_dmamem_free(tag, seg, nseg);
  444 }
  445 
  446 
  447 /*
  448  * a u t o c o n f i g   f u n c t i o n s
  449  */
  450 
  451 /*
  452  * xdcmatch: determine if xdc is present or not.   we do a
  453  * soft reset to detect the xdc.
  454  */
  455 
  456 int
  457 xdc_probe(arg, tag, handle)
  458         void *arg;
  459         bus_space_tag_t tag;
  460         bus_space_handle_t handle;
  461 {
  462         struct xdc *xdc = (void *)handle; /* XXX */
  463         int del = 0;
  464 
  465         xdc->xdc_csr = XDC_RESET;
  466         XDC_WAIT(xdc, del, XDC_RESETUSEC, XDC_RESET);
  467         return (del > 0 ? 0 : EIO);
  468 }
  469 
  470 int xdcmatch(parent, cf, aux)
  471         struct device *parent;
  472         struct cfdata *cf;
  473         void *aux;
  474 {
  475         struct vme_attach_args  *va = aux;
  476         vme_chipset_tag_t       ct = va->va_vct;
  477         vme_am_t                mod;
  478         int error;
  479 
  480         mod = VME_AM_A16 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA;
  481         if (vme_space_alloc(ct, va->r[0].offset, sizeof(struct xdc), mod))
  482                 return (0);
  483 
  484         error = vme_probe(ct, va->r[0].offset, sizeof(struct xdc),
  485                           mod, VME_D32, xdc_probe, 0);
  486         vme_space_free(va->va_vct, va->r[0].offset, sizeof(struct xdc), mod);
  487 
  488         return (error == 0);
  489 }
  490 
  491 /*
  492  * xdcattach: attach controller
  493  */
  494 void
  495 xdcattach(parent, self, aux)
  496         struct device *parent, *self;
  497         void   *aux;
  498 
  499 {
  500         struct vme_attach_args  *va = aux;
  501         vme_chipset_tag_t       ct = va->va_vct;
  502         bus_space_tag_t         bt;
  503         bus_space_handle_t      bh;
  504         vme_intr_handle_t       ih;
  505         vme_am_t                mod;
  506         struct xdc_softc        *xdc = (void *) self;
  507         struct xdc_attach_args  xa;
  508         int                     lcv, rqno, error;
  509         struct xd_iopb_ctrl     *ctl;
  510         bus_dma_segment_t       seg;
  511         int                     rseg;
  512         vme_mapresc_t resc;
  513         bus_addr_t              busaddr;
  514 
  515         xdc_md_setup();
  516 
  517         /* get addressing and intr level stuff from autoconfig and load it
  518          * into our xdc_softc. */
  519 
  520         xdc->dmatag = va->va_bdt;
  521         mod = VME_AM_A16 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA;
  522 
  523         if (vme_space_alloc(ct, va->r[0].offset, sizeof(struct xdc), mod))
  524                 panic("xdc: vme alloc");
  525 
  526         if (vme_space_map(ct, va->r[0].offset, sizeof(struct xdc),
  527                           mod, VME_D32, 0, &bt, &bh, &resc) != 0)
  528                 panic("xdc: vme_map");
  529 
  530         xdc->xdc = (struct xdc *) bh; /* XXX */
  531         xdc->ipl = va->ilevel;
  532         xdc->vector = va->ivector;
  533 
  534         for (lcv = 0; lcv < XDC_MAXDEV; lcv++)
  535                 xdc->sc_drives[lcv] = (struct xd_softc *) 0;
  536 
  537         /*
  538          * allocate and zero buffers
  539          *
  540          * note: we simplify the code by allocating the max number of iopbs and
  541          * iorq's up front.   thus, we avoid linked lists and the costs
  542          * associated with them in exchange for wasting a little memory.
  543          */
  544 
  545         /* Get DMA handle for misc. transfers */
  546         if ((error = vme_dmamap_create(
  547                                 ct,             /* VME chip tag */
  548                                 MAXPHYS,        /* size */
  549                                 VME_AM_A24,     /* address modifier */
  550                                 VME_D32,        /* data size */
  551                                 0,              /* swap */
  552                                 1,              /* nsegments */
  553                                 MAXPHYS,        /* maxsegsz */
  554                                 0,              /* boundary */
  555                                 BUS_DMA_NOWAIT,
  556                                 &xdc->auxmap)) != 0) {
  557 
  558                 printf("%s: DMA buffer map create error %d\n",
  559                         xdc->sc_dev.dv_xname, error);
  560                 return;
  561         }
  562 
  563 
  564         /* Get DMA handle for mapping iorq descriptors */
  565         if ((error = vme_dmamap_create(
  566                                 ct,             /* VME chip tag */
  567                                 XDC_MAXIOPB * sizeof(struct xd_iopb),
  568                                 VME_AM_A24,     /* address modifier */
  569                                 VME_D32,        /* data size */
  570                                 0,              /* swap */
  571                                 1,              /* nsegments */
  572                                 XDC_MAXIOPB * sizeof(struct xd_iopb),
  573                                 0,              /* boundary */
  574                                 BUS_DMA_NOWAIT,
  575                                 &xdc->iopmap)) != 0) {
  576 
  577                 printf("%s: DMA buffer map create error %d\n",
  578                         xdc->sc_dev.dv_xname, error);
  579                 return;
  580         }
  581 
  582         /* Get DMA buffer for iorq descriptors */
  583         if ((error = xd_dmamem_alloc(xdc->dmatag, xdc->iopmap, &seg, &rseg,
  584                                      XDC_MAXIOPB * sizeof(struct xd_iopb),
  585                                      (caddr_t *)&xdc->iopbase,
  586                                      &busaddr)) != 0) {
  587                 printf("%s: DMA buffer alloc error %d\n",
  588                         xdc->sc_dev.dv_xname, error);
  589                 return;
  590         }
  591         xdc->dvmaiopb = (struct xd_iopb *)(u_long)BUS_ADDR_PADDR(busaddr);
  592 
  593         bzero(xdc->iopbase, XDC_MAXIOPB * sizeof(struct xd_iopb));
  594 
  595         xdc->reqs = (struct xd_iorq *)
  596             malloc(XDC_MAXIOPB * sizeof(struct xd_iorq),
  597             M_DEVBUF, M_NOWAIT|M_ZERO);
  598         if (xdc->reqs == NULL)
  599                 panic("xdc malloc");
  600 
  601         /* init free list, iorq to iopb pointers, and non-zero fields in the
  602          * iopb which never change. */
  603 
  604         for (lcv = 0; lcv < XDC_MAXIOPB; lcv++) {
  605                 xdc->reqs[lcv].iopb = &xdc->iopbase[lcv];
  606                 xdc->reqs[lcv].dmaiopb = &xdc->dvmaiopb[lcv];
  607                 xdc->freereq[lcv] = lcv;
  608                 xdc->iopbase[lcv].fixd = 1;     /* always the same */
  609                 xdc->iopbase[lcv].naddrmod = XDC_ADDRMOD; /* always the same */
  610                 xdc->iopbase[lcv].intr_vec = xdc->vector; /* always the same */
  611 
  612                 if ((error = vme_dmamap_create(
  613                                 ct,             /* VME chip tag */
  614                                 MAXPHYS,        /* size */
  615                                 VME_AM_A24,     /* address modifier */
  616                                 VME_D32,        /* data size */
  617                                 0,              /* swap */
  618                                 1,              /* nsegments */
  619                                 MAXPHYS,        /* maxsegsz */
  620                                 0,              /* boundary */
  621                                 BUS_DMA_NOWAIT,
  622                                 &xdc->reqs[lcv].dmamap)) != 0) {
  623 
  624                         printf("%s: DMA buffer map create error %d\n",
  625                                 xdc->sc_dev.dv_xname, error);
  626                         return;
  627                 }
  628         }
  629         xdc->nfree = XDC_MAXIOPB;
  630         xdc->nrun = 0;
  631         xdc->waithead = xdc->waitend = xdc->nwait = 0;
  632         xdc->ndone = 0;
  633 
  634         /* init queue of waiting bufs */
  635 
  636         bufq_alloc(&xdc->sc_wq, BUFQ_FCFS);
  637         callout_init(&xdc->sc_tick_ch);
  638 
  639         /*
  640          * section 7 of the manual tells us how to init the controller:
  641          * - read controller parameters (6/0)
  642          * - write controller parameters (5/0)
  643          */
  644 
  645         /* read controller parameters and insure we have a 753/7053 */
  646 
  647         rqno = xdc_cmd(xdc, XDCMD_RDP, XDFUN_CTL, 0, 0, 0, 0, XD_SUB_POLL);
  648         if (rqno == XD_ERR_FAIL) {
  649                 printf(": couldn't read controller params\n");
  650                 return;         /* shouldn't ever happen */
  651         }
  652         ctl = (struct xd_iopb_ctrl *) &xdc->iopbase[rqno];
  653         if (ctl->ctype != XDCT_753) {
  654                 if (xdc->reqs[rqno].errno)
  655                         printf(": %s: ", xdc_e2str(xdc->reqs[rqno].errno));
  656                 printf(": doesn't identify as a 753/7053\n");
  657                 XDC_DONE(xdc, rqno, error);
  658                 return;
  659         }
  660         printf(": Xylogics 753/7053, PROM=0x%x.%02x.%02x\n",
  661             ctl->eprom_partno, ctl->eprom_lvl, ctl->eprom_rev);
  662         XDC_DONE(xdc, rqno, error);
  663 
  664         /* now write controller parameters (xdc_cmd sets all params for us) */
  665 
  666         rqno = xdc_cmd(xdc, XDCMD_WRP, XDFUN_CTL, 0, 0, 0, 0, XD_SUB_POLL);
  667         XDC_DONE(xdc, rqno, error);
  668         if (error) {
  669                 printf("%s: controller config error: %s\n",
  670                         xdc->sc_dev.dv_xname, xdc_e2str(error));
  671                 return;
  672         }
  673 
  674         /* link in interrupt with higher level software */
  675         vme_intr_map(ct, va->ilevel, va->ivector, &ih);
  676         vme_intr_establish(ct, ih, IPL_BIO, xdcintr, xdc);
  677         evcnt_attach_dynamic(&xdc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
  678             xdc->sc_dev.dv_xname, "intr");
  679 
  680 
  681         /* now we must look for disks using autoconfig */
  682         xa.fullmode = XD_SUB_POLL;
  683         xa.booting = 1;
  684 
  685         for (xa.driveno = 0; xa.driveno < XDC_MAXDEV; xa.driveno++)
  686                 (void) config_found(self, (void *) &xa, NULL);
  687 
  688         /* start the watchdog clock */
  689         callout_reset(&xdc->sc_tick_ch, XDC_TICKCNT, xdc_tick, xdc);
  690 
  691 }
  692 
  693 /*
  694  * xdmatch: probe for disk.
  695  *
  696  * note: we almost always say disk is present.   this allows us to
  697  * spin up and configure a disk after the system is booted (we can
  698  * call xdattach!).
  699  */
  700 int
  701 xdmatch(parent, cf, aux)
  702         struct device *parent;
  703         struct cfdata *cf;
  704         void *aux;
  705 {
  706         struct xdc_attach_args *xa = aux;
  707 
  708         /* looking for autoconf wildcard or exact match */
  709 
  710         if (cf->cf_loc[XDCCF_DRIVE] != XDCCF_DRIVE_DEFAULT &&
  711             cf->cf_loc[XDCCF_DRIVE] != xa->driveno)
  712                 return 0;
  713 
  714         return 1;
  715 
  716 }
  717 
  718 /*
  719  * xdattach: attach a disk.   this can be called from autoconf and also
  720  * from xdopen/xdstrategy.
  721  */
  722 void
  723 xdattach(parent, self, aux)
  724         struct device *parent, *self;
  725         void   *aux;
  726 
  727 {
  728         struct xd_softc *xd = (void *) self;
  729         struct xdc_softc *xdc = (void *) parent;
  730         struct xdc_attach_args *xa = aux;
  731         int     rqno, spt = 0, mb, blk, lcv, fmode, s = 0, newstate;
  732         struct xd_iopb_drive *driopb;
  733         struct dkbad *dkb;
  734         int                     rseg, error;
  735         bus_dma_segment_t       seg;
  736         bus_addr_t              busaddr;
  737         caddr_t                 dmaddr;
  738         caddr_t                 buf;
  739 
  740         /*
  741          * Always re-initialize the disk structure.  We want statistics
  742          * to start with a clean slate.
  743          */
  744         bzero(&xd->sc_dk, sizeof(xd->sc_dk));
  745         xd->sc_dk.dk_driver = &xddkdriver;
  746         xd->sc_dk.dk_name = xd->sc_dev.dv_xname;
  747 
  748         /* if booting, init the xd_softc */
  749 
  750         if (xa->booting) {
  751                 xd->state = XD_DRIVE_UNKNOWN;   /* to start */
  752                 xd->flags = 0;
  753                 xd->parent = xdc;
  754         }
  755         xd->xd_drive = xa->driveno;
  756         fmode = xa->fullmode;
  757         xdc->sc_drives[xa->driveno] = xd;
  758 
  759         /* if not booting, make sure we are the only process in the attach for
  760          * this drive.   if locked out, sleep on it. */
  761 
  762         if (!xa->booting) {
  763                 s = splbio();
  764                 while (xd->state == XD_DRIVE_ATTACHING) {
  765                         if (tsleep(&xd->state, PRIBIO, "xdattach", 0)) {
  766                                 splx(s);
  767                                 return;
  768                         }
  769                 }
  770                 printf("%s at %s",
  771                         xd->sc_dev.dv_xname, xd->parent->sc_dev.dv_xname);
  772         }
  773 
  774         /* we now have control */
  775         xd->state = XD_DRIVE_ATTACHING;
  776         newstate = XD_DRIVE_UNKNOWN;
  777 
  778         buf = NULL;
  779         if ((error = xd_dmamem_alloc(xdc->dmatag, xdc->auxmap, &seg, &rseg,
  780                                      XDFM_BPS,
  781                                      (caddr_t *)&buf,
  782                                      &busaddr)) != 0) {
  783                 printf("%s: DMA buffer alloc error %d\n",
  784                         xdc->sc_dev.dv_xname, error);
  785                 return;
  786         }
  787         dmaddr = (caddr_t)(u_long)BUS_ADDR_PADDR(busaddr);
  788 
  789         /* first try and reset the drive */
  790 
  791         rqno = xdc_cmd(xdc, XDCMD_RST, 0, xd->xd_drive, 0, 0, 0, fmode);
  792         XDC_DONE(xdc, rqno, error);
  793         if (error == XD_ERR_NRDY) {
  794                 printf(" drive %d: off-line\n", xa->driveno);
  795                 goto done;
  796         }
  797         if (error) {
  798                 printf(": ERROR 0x%02x (%s)\n", error, xdc_e2str(error));
  799                 goto done;
  800         }
  801         printf(" drive %d: ready\n", xa->driveno);
  802 
  803         /* now set format parameters */
  804 
  805         rqno = xdc_cmd(xdc, XDCMD_WRP, XDFUN_FMT, xd->xd_drive, 0, 0, 0, fmode);
  806         XDC_DONE(xdc, rqno, error);
  807         if (error) {
  808                 printf("%s: write format parameters failed: %s\n",
  809                         xd->sc_dev.dv_xname, xdc_e2str(error));
  810                 goto done;
  811         }
  812 
  813         /* get drive parameters */
  814         rqno = xdc_cmd(xdc, XDCMD_RDP, XDFUN_DRV, xd->xd_drive, 0, 0, 0, fmode);
  815         if (rqno != XD_ERR_FAIL) {
  816                 driopb = (struct xd_iopb_drive *) &xdc->iopbase[rqno];
  817                 spt = driopb->sectpertrk;
  818         }
  819         XDC_DONE(xdc, rqno, error);
  820         if (error) {
  821                 printf("%s: read drive parameters failed: %s\n",
  822                         xd->sc_dev.dv_xname, xdc_e2str(error));
  823                 goto done;
  824         }
  825 
  826         /*
  827          * now set drive parameters (to semi-bogus values) so we can read the
  828          * disk label.
  829          */
  830         xd->pcyl = xd->ncyl = 1;
  831         xd->acyl = 0;
  832         xd->nhead = 1;
  833         xd->nsect = 1;
  834         xd->sectpercyl = 1;
  835         for (lcv = 0; lcv < 126; lcv++) /* init empty bad144 table */
  836                 xd->dkb.bt_bad[lcv].bt_cyl = xd->dkb.bt_bad[lcv].bt_trksec = 0xffff;
  837         rqno = xdc_cmd(xdc, XDCMD_WRP, XDFUN_DRV, xd->xd_drive, 0, 0, 0, fmode);
  838         XDC_DONE(xdc, rqno, error);
  839         if (error) {
  840                 printf("%s: write drive parameters failed: %s\n",
  841                         xd->sc_dev.dv_xname, xdc_e2str(error));
  842                 goto done;
  843         }
  844 
  845         /* read disk label */
  846         rqno = xdc_cmd(xdc, XDCMD_RD, 0, xd->xd_drive, 0, 1, dmaddr, fmode);
  847         XDC_DONE(xdc, rqno, error);
  848         if (error) {
  849                 printf("%s: reading disk label failed: %s\n",
  850                         xd->sc_dev.dv_xname, xdc_e2str(error));
  851                 goto done;
  852         }
  853         newstate = XD_DRIVE_NOLABEL;
  854 
  855         xd->hw_spt = spt;
  856         /* Attach the disk: must be before getdisklabel to malloc label */
  857         disk_attach(&xd->sc_dk);
  858 
  859         if (xdgetdisklabel(xd, buf) != XD_ERR_AOK)
  860                 goto done;
  861 
  862         /* inform the user of what is up */
  863         printf("%s: <%s>, pcyl %d, hw_spt %d\n", xd->sc_dev.dv_xname,
  864                 buf, xd->pcyl, spt);
  865         mb = xd->ncyl * (xd->nhead * xd->nsect) / (1048576 / XDFM_BPS);
  866         printf("%s: %dMB, %d cyl, %d head, %d sec, %d bytes/sec\n",
  867                 xd->sc_dev.dv_xname, mb, xd->ncyl, xd->nhead, xd->nsect,
  868                 XDFM_BPS);
  869 
  870         /* now set the real drive parameters! */
  871 
  872         rqno = xdc_cmd(xdc, XDCMD_WRP, XDFUN_DRV, xd->xd_drive, 0, 0, 0, fmode);
  873         XDC_DONE(xdc, rqno, error);
  874         if (error) {
  875                 printf("%s: write real drive parameters failed: %s\n",
  876                         xd->sc_dev.dv_xname, xdc_e2str(error));
  877                 goto done;
  878         }
  879         newstate = XD_DRIVE_ONLINE;
  880 
  881         /*
  882          * read bad144 table. this table resides on the first sector of the
  883          * last track of the disk (i.e. second cyl of "acyl" area).
  884          */
  885 
  886         blk = (xd->ncyl + xd->acyl - 1) * (xd->nhead * xd->nsect) + /* last cyl */
  887             (xd->nhead - 1) * xd->nsect;        /* last head */
  888         rqno = xdc_cmd(xdc, XDCMD_RD, 0, xd->xd_drive, blk, 1, dmaddr, fmode);
  889         XDC_DONE(xdc, rqno, error);
  890         if (error) {
  891                 printf("%s: reading bad144 failed: %s\n",
  892                         xd->sc_dev.dv_xname, xdc_e2str(error));
  893                 goto done;
  894         }
  895 
  896         /* check dkbad for sanity */
  897         dkb = (struct dkbad *) buf;
  898         for (lcv = 0; lcv < 126; lcv++) {
  899                 if ((dkb->bt_bad[lcv].bt_cyl == 0xffff ||
  900                                 dkb->bt_bad[lcv].bt_cyl == 0) &&
  901                      dkb->bt_bad[lcv].bt_trksec == 0xffff)
  902                         continue;       /* blank */
  903                 if (dkb->bt_bad[lcv].bt_cyl >= xd->ncyl)
  904                         break;
  905                 if ((dkb->bt_bad[lcv].bt_trksec >> 8) >= xd->nhead)
  906                         break;
  907                 if ((dkb->bt_bad[lcv].bt_trksec & 0xff) >= xd->nsect)
  908                         break;
  909         }
  910         if (lcv != 126) {
  911                 printf("%s: warning: invalid bad144 sector!\n",
  912                         xd->sc_dev.dv_xname);
  913         } else {
  914                 bcopy(buf, &xd->dkb, XDFM_BPS);
  915         }
  916 
  917 done:
  918         if (buf != NULL) {
  919                 xd_dmamem_free(xdc->dmatag, xdc->auxmap,
  920                                 &seg, rseg, XDFM_BPS, buf);
  921         }
  922 
  923         xd->state = newstate;
  924         if (!xa->booting) {
  925                 wakeup(&xd->state);
  926                 splx(s);
  927         }
  928 }
  929 
  930 /*
  931  * end of autoconfig functions
  932  */
  933 
  934 /*
  935  * { b , c } d e v s w   f u n c t i o n s
  936  */
  937 
  938 /*
  939  * xdclose: close device
  940  */
  941 int
  942 xdclose(dev, flag, fmt, p)
  943         dev_t   dev;
  944         int     flag, fmt;
  945         struct proc *p;
  946 {
  947         struct xd_softc *xd = xd_cd.cd_devs[DISKUNIT(dev)];
  948         int     part = DISKPART(dev);
  949 
  950         /* clear mask bits */
  951 
  952         switch (fmt) {
  953         case S_IFCHR:
  954                 xd->sc_dk.dk_copenmask &= ~(1 << part);
  955                 break;
  956         case S_IFBLK:
  957                 xd->sc_dk.dk_bopenmask &= ~(1 << part);
  958                 break;
  959         }
  960         xd->sc_dk.dk_openmask = xd->sc_dk.dk_copenmask | xd->sc_dk.dk_bopenmask;
  961 
  962         return 0;
  963 }
  964 
  965 /*
  966  * xddump: crash dump system
  967  */
  968 int
  969 xddump(dev, blkno, va, size)
  970         dev_t dev;
  971         daddr_t blkno;
  972         caddr_t va;
  973         size_t size;
  974 {
  975         int     unit, part;
  976         struct xd_softc *xd;
  977 
  978         unit = DISKUNIT(dev);
  979         if (unit >= xd_cd.cd_ndevs)
  980                 return ENXIO;
  981         part = DISKPART(dev);
  982 
  983         xd = xd_cd.cd_devs[unit];
  984 
  985         printf("%s%c: crash dump not supported (yet)\n", xd->sc_dev.dv_xname,
  986             'a' + part);
  987 
  988         return ENXIO;
  989 
  990         /* outline: globals: "dumplo" == sector number of partition to start
  991          * dump at (convert to physical sector with partition table)
  992          * "dumpsize" == size of dump in clicks "physmem" == size of physical
  993          * memory (clicks, ctob() to get bytes) (normal case: dumpsize ==
  994          * physmem)
  995          *
  996          * dump a copy of physical memory to the dump device starting at sector
  997          * "dumplo" in the swap partition (make sure > 0).   map in pages as
  998          * we go.   use polled I/O.
  999          *
 1000          * XXX how to handle NON_CONTIG? */
 1001 
 1002 }
 1003 
 1004 /*
 1005  * xdioctl: ioctls on XD drives.   based on ioctl's of other netbsd disks.
 1006  */
 1007 int
 1008 xdioctl(dev, command, addr, flag, p)
 1009         dev_t   dev;
 1010         u_long  command;
 1011         caddr_t addr;
 1012         int     flag;
 1013         struct proc *p;
 1014 
 1015 {
 1016         struct xd_softc *xd;
 1017         struct xd_iocmd *xio;
 1018         int     error, s, unit;
 1019 #ifdef __HAVE_OLD_DISKLABEL
 1020         struct disklabel newlabel;
 1021 #endif
 1022         struct disklabel *lp;
 1023 
 1024         unit = DISKUNIT(dev);
 1025 
 1026         if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == NULL)
 1027                 return (ENXIO);
 1028 
 1029         /* switch on ioctl type */
 1030 
 1031         switch (command) {
 1032         case DIOCSBAD:          /* set bad144 info */
 1033                 if ((flag & FWRITE) == 0)
 1034                         return EBADF;
 1035                 s = splbio();
 1036                 bcopy(addr, &xd->dkb, sizeof(xd->dkb));
 1037                 splx(s);
 1038                 return 0;
 1039 
 1040         case DIOCGDINFO:        /* get disk label */
 1041                 bcopy(xd->sc_dk.dk_label, addr, sizeof(struct disklabel));
 1042                 return 0;
 1043 #ifdef __HAVE_OLD_DISKLABEL
 1044         case ODIOCGDINFO:
 1045                 newlabel = *(xd->sc_dk.dk_label);
 1046                 if (newlabel.d_npartitions > OLDMAXPARTITIONS)
 1047                         return ENOTTY;
 1048                 memcpy(addr, &newlabel, sizeof (struct olddisklabel));
 1049                 return 0;
 1050 #endif
 1051 
 1052         case DIOCGPART: /* get partition info */
 1053                 ((struct partinfo *) addr)->disklab = xd->sc_dk.dk_label;
 1054                 ((struct partinfo *) addr)->part =
 1055                     &xd->sc_dk.dk_label->d_partitions[DISKPART(dev)];
 1056                 return 0;
 1057 
 1058         case DIOCSDINFO:        /* set disk label */
 1059 #ifdef __HAVE_OLD_DISKLABEL
 1060         case ODIOCSDINFO:
 1061                 if (command == ODIOCSDINFO) {
 1062                         memset(&newlabel, 0, sizeof newlabel);
 1063                         memcpy(&newlabel, addr, sizeof (struct olddisklabel));
 1064                         lp = &newlabel;
 1065                 } else
 1066 #endif
 1067                 lp = (struct disklabel *)addr;
 1068 
 1069                 if ((flag & FWRITE) == 0)
 1070                         return EBADF;
 1071                 error = setdisklabel(xd->sc_dk.dk_label,
 1072                     lp, /* xd->sc_dk.dk_openmask : */ 0,
 1073                     xd->sc_dk.dk_cpulabel);
 1074                 if (error == 0) {
 1075                         if (xd->state == XD_DRIVE_NOLABEL)
 1076                                 xd->state = XD_DRIVE_ONLINE;
 1077                 }
 1078                 return error;
 1079 
 1080         case DIOCWLABEL:        /* change write status of disk label */
 1081                 if ((flag & FWRITE) == 0)
 1082                         return EBADF;
 1083                 if (*(int *) addr)
 1084                         xd->flags |= XD_WLABEL;
 1085                 else
 1086                         xd->flags &= ~XD_WLABEL;
 1087                 return 0;
 1088 
 1089         case DIOCWDINFO:        /* write disk label */
 1090 #ifdef __HAVE_OLD_DISKLABEL
 1091         case ODIOCWDINFO:
 1092                 if (command == ODIOCWDINFO) {
 1093                         memset(&newlabel, 0, sizeof newlabel);
 1094                         memcpy(&newlabel, addr, sizeof (struct olddisklabel));
 1095                         lp = &newlabel;
 1096                 } else
 1097 #endif
 1098                 lp = (struct disklabel *)addr;
 1099 
 1100                 if ((flag & FWRITE) == 0)
 1101                         return EBADF;
 1102                 error = setdisklabel(xd->sc_dk.dk_label,
 1103                     lp, /* xd->sc_dk.dk_openmask : */ 0,
 1104                     xd->sc_dk.dk_cpulabel);
 1105                 if (error == 0) {
 1106                         if (xd->state == XD_DRIVE_NOLABEL)
 1107                                 xd->state = XD_DRIVE_ONLINE;
 1108 
 1109                         /* Simulate opening partition 0 so write succeeds. */
 1110                         xd->sc_dk.dk_openmask |= (1 << 0);
 1111                         error = writedisklabel(MAKEDISKDEV(major(dev),
 1112                             DISKUNIT(dev), RAW_PART),
 1113                             xdstrategy, xd->sc_dk.dk_label,
 1114                             xd->sc_dk.dk_cpulabel);
 1115                         xd->sc_dk.dk_openmask =
 1116                             xd->sc_dk.dk_copenmask | xd->sc_dk.dk_bopenmask;
 1117                 }
 1118                 return error;
 1119 
 1120         case DIOSXDCMD:
 1121                 xio = (struct xd_iocmd *) addr;
 1122                 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
 1123                         return (error);
 1124                 return (xdc_ioctlcmd(xd, dev, xio));
 1125 
 1126         default:
 1127                 return ENOTTY;
 1128         }
 1129 }
 1130 /*
 1131  * xdopen: open drive
 1132  */
 1133 
 1134 int
 1135 xdopen(dev, flag, fmt, p)
 1136         dev_t   dev;
 1137         int     flag, fmt;
 1138         struct proc *p;
 1139 {
 1140         int     unit, part;
 1141         struct xd_softc *xd;
 1142         struct xdc_attach_args xa;
 1143 
 1144         /* first, could it be a valid target? */
 1145 
 1146         unit = DISKUNIT(dev);
 1147         if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == NULL)
 1148                 return (ENXIO);
 1149         part = DISKPART(dev);
 1150 
 1151         /* do we need to attach the drive? */
 1152 
 1153         if (xd->state == XD_DRIVE_UNKNOWN) {
 1154                 xa.driveno = xd->xd_drive;
 1155                 xa.fullmode = XD_SUB_WAIT;
 1156                 xa.booting = 0;
 1157                 xdattach((struct device *) xd->parent, (struct device *) xd, &xa);
 1158                 if (xd->state == XD_DRIVE_UNKNOWN) {
 1159                         return (EIO);
 1160                 }
 1161         }
 1162         /* check for partition */
 1163 
 1164         if (part != RAW_PART &&
 1165             (part >= xd->sc_dk.dk_label->d_npartitions ||
 1166                 xd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
 1167                 return (ENXIO);
 1168         }
 1169         /* set open masks */
 1170 
 1171         switch (fmt) {
 1172         case S_IFCHR:
 1173                 xd->sc_dk.dk_copenmask |= (1 << part);
 1174                 break;
 1175         case S_IFBLK:
 1176                 xd->sc_dk.dk_bopenmask |= (1 << part);
 1177                 break;
 1178         }
 1179         xd->sc_dk.dk_openmask = xd->sc_dk.dk_copenmask | xd->sc_dk.dk_bopenmask;
 1180 
 1181         return 0;
 1182 }
 1183 
 1184 int
 1185 xdread(dev, uio, flags)
 1186         dev_t   dev;
 1187         struct uio *uio;
 1188         int flags;
 1189 {
 1190 
 1191         return (physio(xdstrategy, NULL, dev, B_READ, minphys, uio));
 1192 }
 1193 
 1194 int
 1195 xdwrite(dev, uio, flags)
 1196         dev_t   dev;
 1197         struct uio *uio;
 1198         int flags;
 1199 {
 1200 
 1201         return (physio(xdstrategy, NULL, dev, B_WRITE, minphys, uio));
 1202 }
 1203 
 1204 
 1205 /*
 1206  * xdsize: return size of a partition for a dump
 1207  */
 1208 
 1209 int
 1210 xdsize(dev)
 1211         dev_t   dev;
 1212 
 1213 {
 1214         struct xd_softc *xdsc;
 1215         int     unit, part, size, omask;
 1216 
 1217         /* valid unit? */
 1218         unit = DISKUNIT(dev);
 1219         if (unit >= xd_cd.cd_ndevs || (xdsc = xd_cd.cd_devs[unit]) == NULL)
 1220                 return (-1);
 1221 
 1222         part = DISKPART(dev);
 1223         omask = xdsc->sc_dk.dk_openmask & (1 << part);
 1224 
 1225         if (omask == 0 && xdopen(dev, 0, S_IFBLK, NULL) != 0)
 1226                 return (-1);
 1227 
 1228         /* do it */
 1229         if (xdsc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
 1230                 size = -1;      /* only give valid size for swap partitions */
 1231         else
 1232                 size = xdsc->sc_dk.dk_label->d_partitions[part].p_size *
 1233                     (xdsc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
 1234         if (omask == 0 && xdclose(dev, 0, S_IFBLK, NULL) != 0)
 1235                 return (-1);
 1236         return (size);
 1237 }
 1238 /*
 1239  * xdstrategy: buffering system interface to xd.
 1240  */
 1241 
 1242 void
 1243 xdstrategy(bp)
 1244         struct buf *bp;
 1245 
 1246 {
 1247         struct xd_softc *xd;
 1248         struct xdc_softc *parent;
 1249         int     s, unit;
 1250         struct xdc_attach_args xa;
 1251 
 1252         unit = DISKUNIT(bp->b_dev);
 1253 
 1254         /* check for live device */
 1255 
 1256         if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == 0 ||
 1257             bp->b_blkno < 0 ||
 1258             (bp->b_bcount % xd->sc_dk.dk_label->d_secsize) != 0) {
 1259                 bp->b_error = EINVAL;
 1260                 goto bad;
 1261         }
 1262         /* do we need to attach the drive? */
 1263 
 1264         if (xd->state == XD_DRIVE_UNKNOWN) {
 1265                 xa.driveno = xd->xd_drive;
 1266                 xa.fullmode = XD_SUB_WAIT;
 1267                 xa.booting = 0;
 1268                 xdattach((struct device *)xd->parent, (struct device *)xd, &xa);
 1269                 if (xd->state == XD_DRIVE_UNKNOWN) {
 1270                         bp->b_error = EIO;
 1271                         goto bad;
 1272                 }
 1273         }
 1274         if (xd->state != XD_DRIVE_ONLINE && DISKPART(bp->b_dev) != RAW_PART) {
 1275                 /* no I/O to unlabeled disks, unless raw partition */
 1276                 bp->b_error = EIO;
 1277                 goto bad;
 1278         }
 1279         /* short circuit zero length request */
 1280 
 1281         if (bp->b_bcount == 0)
 1282                 goto done;
 1283 
 1284         /* check bounds with label (disksubr.c).  Determine the size of the
 1285          * transfer, and make sure it is within the boundaries of the
 1286          * partition. Adjust transfer if needed, and signal errors or early
 1287          * completion. */
 1288 
 1289         if (bounds_check_with_label(&xd->sc_dk, bp,
 1290                 (xd->flags & XD_WLABEL) != 0) <= 0)
 1291                 goto done;
 1292 
 1293         /*
 1294          * now we know we have a valid buf structure that we need to do I/O
 1295          * on.
 1296          *
 1297          * note that we don't disksort because the controller has a sorting
 1298          * algorithm built into the hardware.
 1299          */
 1300 
 1301         s = splbio();           /* protect the queues */
 1302 
 1303         /* first, give jobs in front of us a chance */
 1304         parent = xd->parent;
 1305         while (parent->nfree > 0 && BUFQ_PEEK(&parent->sc_wq) != NULL)
 1306                 if (xdc_startbuf(parent, NULL, NULL) != XD_ERR_AOK)
 1307                         break;
 1308 
 1309         /* if there are no free iorq's, then we just queue and return. the
 1310          * buffs will get picked up later by xdcintr().
 1311          */
 1312 
 1313         if (parent->nfree == 0) {
 1314                 BUFQ_PUT(&parent->sc_wq, bp);
 1315                 splx(s);
 1316                 return;
 1317         }
 1318 
 1319         /* now we have free iopb's and we are at splbio... start 'em up */
 1320         if (xdc_startbuf(parent, xd, bp) != XD_ERR_AOK) {
 1321                 return;
 1322         }
 1323 
 1324         /* done! */
 1325 
 1326         splx(s);
 1327         return;
 1328 
 1329 bad:                            /* tells upper layers we have an error */
 1330         bp->b_flags |= B_ERROR;
 1331 done:                           /* tells upper layers we are done with this
 1332                                  * buf */
 1333         bp->b_resid = bp->b_bcount;
 1334         biodone(bp);
 1335 }
 1336 /*
 1337  * end of {b,c}devsw functions
 1338  */
 1339 
 1340 /*
 1341  * i n t e r r u p t   f u n c t i o n
 1342  *
 1343  * xdcintr: hardware interrupt.
 1344  */
 1345 int
 1346 xdcintr(v)
 1347         void   *v;
 1348 
 1349 {
 1350         struct xdc_softc *xdcsc = v;
 1351 
 1352         /* kick the event counter */
 1353 
 1354         xdcsc->sc_intrcnt.ev_count++;
 1355 
 1356         /* remove as many done IOPBs as possible */
 1357 
 1358         xdc_remove_iorq(xdcsc);
 1359 
 1360         /* start any iorq's already waiting */
 1361 
 1362         xdc_start(xdcsc, XDC_MAXIOPB);
 1363 
 1364         /* fill up any remaining iorq's with queue'd buffers */
 1365 
 1366         while (xdcsc->nfree > 0 && BUFQ_PEEK(&xdcsc->sc_wq) != NULL)
 1367                 if (xdc_startbuf(xdcsc, NULL, NULL) != XD_ERR_AOK)
 1368                         break;
 1369 
 1370         return (1);
 1371 }
 1372 /*
 1373  * end of interrupt function
 1374  */
 1375 
 1376 /*
 1377  * i n t e r n a l   f u n c t i o n s
 1378  */
 1379 
 1380 /*
 1381  * xdc_rqinit: fill out the fields of an I/O request
 1382  */
 1383 
 1384 inline void
 1385 xdc_rqinit(rq, xdc, xd, md, blk, cnt, db, bp)
 1386         struct xd_iorq *rq;
 1387         struct xdc_softc *xdc;
 1388         struct xd_softc *xd;
 1389         int     md;
 1390         u_long  blk;
 1391         int     cnt;
 1392         caddr_t db;
 1393         struct buf *bp;
 1394 {
 1395         rq->xdc = xdc;
 1396         rq->xd = xd;
 1397         rq->ttl = XDC_MAXTTL + 10;
 1398         rq->mode = md;
 1399         rq->tries = rq->errno = rq->lasterror = 0;
 1400         rq->blockno = blk;
 1401         rq->sectcnt = cnt;
 1402         rq->dbuf = db;
 1403         rq->buf = bp;
 1404 }
 1405 /*
 1406  * xdc_rqtopb: load up an IOPB based on an iorq
 1407  */
 1408 
 1409 void
 1410 xdc_rqtopb(iorq, iopb, cmd, subfun)
 1411         struct xd_iorq *iorq;
 1412         struct xd_iopb *iopb;
 1413         int     cmd, subfun;
 1414 
 1415 {
 1416         u_long  block, dp;
 1417 
 1418         /* standard stuff */
 1419 
 1420         iopb->errs = iopb->done = 0;
 1421         iopb->comm = cmd;
 1422         iopb->errno = iopb->status = 0;
 1423         iopb->subfun = subfun;
 1424         if (iorq->xd)
 1425                 iopb->unit = iorq->xd->xd_drive;
 1426         else
 1427                 iopb->unit = 0;
 1428 
 1429         /* check for alternate IOPB format */
 1430 
 1431         if (cmd == XDCMD_WRP) {
 1432                 switch (subfun) {
 1433                 case XDFUN_CTL:{
 1434                         struct xd_iopb_ctrl *ctrl =
 1435                                 (struct xd_iopb_ctrl *) iopb;
 1436                         iopb->lll = 0;
 1437                         iopb->intl = (XD_STATE(iorq->mode) == XD_SUB_POLL)
 1438                                         ? 0
 1439                                         : iorq->xdc->ipl;
 1440                         ctrl->param_a = XDPA_TMOD | XDPA_DACF;
 1441                         ctrl->param_b = XDPB_ROR | XDPB_TDT_3_2USEC;
 1442                         ctrl->param_c = XDPC_OVS | XDPC_COP | XDPC_ASR |
 1443                                         XDPC_RBC | XDPC_ECC2;
 1444                         ctrl->throttle = XDC_THROTTLE;
 1445                         ctrl->delay = XDC_DELAY;
 1446                         break;
 1447                         }
 1448                 case XDFUN_DRV:{
 1449                         struct xd_iopb_drive *drv =
 1450                                 (struct xd_iopb_drive *)iopb;
 1451                         /* we assume that the disk label has the right
 1452                          * info */
 1453                         if (XD_STATE(iorq->mode) == XD_SUB_POLL)
 1454                                 drv->dparam_ipl = (XDC_DPARAM << 3);
 1455                         else
 1456                                 drv->dparam_ipl = (XDC_DPARAM << 3) |
 1457                                                   iorq->xdc->ipl;
 1458                         drv->maxsect = iorq->xd->nsect - 1;
 1459                         drv->maxsector = drv->maxsect;
 1460                         /* note: maxsector != maxsect only if you are
 1461                          * doing cyl sparing */
 1462                         drv->headoff = 0;
 1463                         drv->maxcyl = iorq->xd->pcyl - 1;
 1464                         drv->maxhead = iorq->xd->nhead - 1;
 1465                         break;
 1466                         }
 1467                 case XDFUN_FMT:{
 1468                         struct xd_iopb_format *form =
 1469                                         (struct xd_iopb_format *) iopb;
 1470                         if (XD_STATE(iorq->mode) == XD_SUB_POLL)
 1471                                 form->interleave_ipl = (XDC_INTERLEAVE << 3);
 1472                         else
 1473                                 form->interleave_ipl = (XDC_INTERLEAVE << 3) |
 1474                                                        iorq->xdc->ipl;
 1475                         form->field1 = XDFM_FIELD1;
 1476                         form->field2 = XDFM_FIELD2;
 1477                         form->field3 = XDFM_FIELD3;
 1478                         form->field4 = XDFM_FIELD4;
 1479                         form->bytespersec = XDFM_BPS;
 1480                         form->field6 = XDFM_FIELD6;
 1481                         form->field7 = XDFM_FIELD7;
 1482                         break;
 1483                         }
 1484                 }
 1485         } else {
 1486 
 1487                 /* normal IOPB case (harmless to RDP command) */
 1488 
 1489                 iopb->lll = 0;
 1490                 iopb->intl = (XD_STATE(iorq->mode) == XD_SUB_POLL)
 1491                                 ? 0
 1492                                 : iorq->xdc->ipl;
 1493                 iopb->sectcnt = iorq->sectcnt;
 1494                 block = iorq->blockno;
 1495                 if (iorq->xd == NULL || block == 0) {
 1496                         iopb->sectno = iopb->headno = iopb->cylno = 0;
 1497                 } else {
 1498                         iopb->sectno = block % iorq->xd->nsect;
 1499                         block = block / iorq->xd->nsect;
 1500                         iopb->headno = block % iorq->xd->nhead;
 1501                         block = block / iorq->xd->nhead;
 1502                         iopb->cylno = block;
 1503                 }
 1504                 dp = (u_long) iorq->dbuf;
 1505                 dp = iopb->daddr = (iorq->dbuf == NULL) ? 0 : dp;
 1506                 iopb->addrmod = ((dp + (XDFM_BPS * iorq->sectcnt)) > 0x1000000)
 1507                                         ? XDC_ADDRMOD32
 1508                                         : XDC_ADDRMOD;
 1509         }
 1510 }
 1511 
 1512 /*
 1513  * xdc_cmd: front end for POLL'd and WAIT'd commands.  Returns rqno.
 1514  * If you've already got an IORQ, you can call submit directly (currently
 1515  * there is no need to do this).    NORM requests are handled separately.
 1516  */
 1517 int
 1518 xdc_cmd(xdcsc, cmd, subfn, unit, block, scnt, dptr, fullmode)
 1519         struct xdc_softc *xdcsc;
 1520         int     cmd, subfn, unit, block, scnt;
 1521         char   *dptr;
 1522         int     fullmode;
 1523 
 1524 {
 1525         int     rqno, submode = XD_STATE(fullmode), retry;
 1526         struct xd_iorq *iorq;
 1527         struct xd_iopb *iopb;
 1528 
 1529         /* get iorq/iopb */
 1530         switch (submode) {
 1531         case XD_SUB_POLL:
 1532                 while (xdcsc->nfree == 0) {
 1533                         if (xdc_piodriver(xdcsc, 0, 1) != XD_ERR_AOK)
 1534                                 return (XD_ERR_FAIL);
 1535                 }
 1536                 break;
 1537         case XD_SUB_WAIT:
 1538                 retry = 1;
 1539                 while (retry) {
 1540                         while (xdcsc->nfree == 0) {
 1541                             if (tsleep(&xdcsc->nfree, PRIBIO, "xdnfree", 0))
 1542                                 return (XD_ERR_FAIL);
 1543                         }
 1544                         while (xdcsc->ndone > XDC_SUBWAITLIM) {
 1545                             if (tsleep(&xdcsc->ndone, PRIBIO, "xdsubwait", 0))
 1546                                 return (XD_ERR_FAIL);
 1547                         }
 1548                         if (xdcsc->nfree)
 1549                                 retry = 0;      /* got it */
 1550                 }
 1551                 break;
 1552         default:
 1553                 return (XD_ERR_FAIL);   /* illegal */
 1554         }
 1555         if (xdcsc->nfree == 0)
 1556                 panic("xdcmd nfree");
 1557         rqno = XDC_RQALLOC(xdcsc);
 1558         iorq = &xdcsc->reqs[rqno];
 1559         iopb = iorq->iopb;
 1560 
 1561 
 1562         /* init iorq/iopb */
 1563 
 1564         xdc_rqinit(iorq, xdcsc,
 1565             (unit == XDC_NOUNIT) ? NULL : xdcsc->sc_drives[unit],
 1566             fullmode, block, scnt, dptr, NULL);
 1567 
 1568         /* load IOPB from iorq */
 1569 
 1570         xdc_rqtopb(iorq, iopb, cmd, subfn);
 1571 
 1572         /* submit it for processing */
 1573 
 1574         xdc_submit_iorq(xdcsc, rqno, fullmode); /* error code will be in iorq */
 1575 
 1576         return (rqno);
 1577 }
 1578 /*
 1579  * xdc_startbuf
 1580  * start a buffer running, assumes nfree > 0
 1581  */
 1582 
 1583 int
 1584 xdc_startbuf(xdcsc, xdsc, bp)
 1585         struct xdc_softc *xdcsc;
 1586         struct xd_softc *xdsc;
 1587         struct buf *bp;
 1588 
 1589 {
 1590         int     rqno, partno;
 1591         struct xd_iorq *iorq;
 1592         struct xd_iopb *iopb;
 1593         u_long  block;
 1594 /*      caddr_t dbuf;*/
 1595         int error;
 1596 
 1597         if (!xdcsc->nfree)
 1598                 panic("xdc_startbuf free");
 1599         rqno = XDC_RQALLOC(xdcsc);
 1600         iorq = &xdcsc->reqs[rqno];
 1601         iopb = iorq->iopb;
 1602 
 1603         /* get buf */
 1604 
 1605         if (bp == NULL) {
 1606                 bp = BUFQ_GET(&xdcsc->sc_wq);
 1607                 if (bp == NULL)
 1608                         panic("xdc_startbuf bp");
 1609                 xdsc = xdcsc->sc_drives[DISKUNIT(bp->b_dev)];
 1610         }
 1611         partno = DISKPART(bp->b_dev);
 1612 #ifdef XDC_DEBUG
 1613         printf("xdc_startbuf: %s%c: %s block %d\n", xdsc->sc_dev.dv_xname,
 1614             'a' + partno, (bp->b_flags & B_READ) ? "read" : "write", bp->b_blkno);
 1615         printf("xdc_startbuf: b_bcount %d, b_data 0x%x\n",
 1616             bp->b_bcount, bp->b_data);
 1617 #endif
 1618 
 1619         /*
 1620          * load request.  we have to calculate the correct block number based
 1621          * on partition info.
 1622          *
 1623          * note that iorq points to the buffer as mapped into DVMA space,
 1624          * where as the bp->b_data points to its non-DVMA mapping.
 1625          */
 1626 
 1627         block = bp->b_blkno + ((partno == RAW_PART) ? 0 :
 1628             xdsc->sc_dk.dk_label->d_partitions[partno].p_offset);
 1629 
 1630         error = bus_dmamap_load(xdcsc->dmatag, iorq->dmamap,
 1631                          bp->b_data, bp->b_bcount, 0, BUS_DMA_NOWAIT);
 1632         if (error != 0) {
 1633                 printf("%s: warning: cannot load DMA map\n",
 1634                         xdcsc->sc_dev.dv_xname);
 1635                 XDC_FREE(xdcsc, rqno);
 1636                 BUFQ_PUT(&xdcsc->sc_wq, bp);
 1637                 return (XD_ERR_FAIL);   /* XXX: need some sort of
 1638                                          * call-back scheme here? */
 1639         }
 1640         bus_dmamap_sync(xdcsc->dmatag, iorq->dmamap, 0,
 1641                         iorq->dmamap->dm_mapsize, (bp->b_flags & B_READ)
 1642                                 ? BUS_DMASYNC_PREREAD
 1643                                 : BUS_DMASYNC_PREWRITE);
 1644 
 1645         /* init iorq and load iopb from it */
 1646         xdc_rqinit(iorq, xdcsc, xdsc, XD_SUB_NORM | XD_MODE_VERBO, block,
 1647                    bp->b_bcount / XDFM_BPS,
 1648                    (caddr_t)(u_long)iorq->dmamap->dm_segs[0].ds_addr,
 1649                    bp);
 1650 
 1651         xdc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XDCMD_RD : XDCMD_WR, 0);
 1652 
 1653         /* Instrumentation. */
 1654         disk_busy(&xdsc->sc_dk);
 1655 
 1656         /* now submit [note that xdc_submit_iorq can never fail on NORM reqs] */
 1657 
 1658         xdc_submit_iorq(xdcsc, rqno, XD_SUB_NORM);
 1659         return (XD_ERR_AOK);
 1660 }
 1661 
 1662 
 1663 /*
 1664  * xdc_submit_iorq: submit an iorq for processing.  returns XD_ERR_AOK
 1665  * if ok.  if it fail returns an error code.  type is XD_SUB_*.
 1666  *
 1667  * note: caller frees iorq in all cases except NORM
 1668  *
 1669  * return value:
 1670  *   NORM: XD_AOK (req pending), XD_FAIL (couldn't submit request)
 1671  *   WAIT: XD_AOK (success), <error-code> (failed)
 1672  *   POLL: <same as WAIT>
 1673  *   NOQ : <same as NORM>
 1674  *
 1675  * there are three sources for i/o requests:
 1676  * [1] xdstrategy: normal block I/O, using "struct buf" system.
 1677  * [2] autoconfig/crash dump: these are polled I/O requests, no interrupts.
 1678  * [3] open/ioctl: these are I/O requests done in the context of a process,
 1679  *                 and the process should block until they are done.
 1680  *
 1681  * software state is stored in the iorq structure.  each iorq has an
 1682  * iopb structure.  the hardware understands the iopb structure.
 1683  * every command must go through an iopb.  a 7053 can only handle
 1684  * XDC_MAXIOPB (31) active iopbs at one time.  iopbs are allocated in
 1685  * DVMA space at boot up time.  what happens if we run out of iopb's?
 1686  * for i/o type [1], the buffers are queued at the "buff" layer and
 1687  * picked up later by the interrupt routine.  for case [2] the
 1688  * programmed i/o driver is called with a special flag that says
 1689  * return when one iopb is free.  for case [3] the process can sleep
 1690  * on the iorq free list until some iopbs are available.
 1691  */
 1692 
 1693 
 1694 int
 1695 xdc_submit_iorq(xdcsc, iorqno, type)
 1696         struct xdc_softc *xdcsc;
 1697         int     iorqno;
 1698         int     type;
 1699 
 1700 {
 1701         u_long  iopbaddr;
 1702         struct xd_iorq *iorq = &xdcsc->reqs[iorqno];
 1703 
 1704 #ifdef XDC_DEBUG
 1705         printf("xdc_submit_iorq(%s, no=%d, type=%d)\n", xdcsc->sc_dev.dv_xname,
 1706             iorqno, type);
 1707 #endif
 1708 
 1709         /* first check and see if controller is busy */
 1710         if (xdcsc->xdc->xdc_csr & XDC_ADDING) {
 1711 #ifdef XDC_DEBUG
 1712                 printf("xdc_submit_iorq: XDC not ready (ADDING)\n");
 1713 #endif
 1714                 if (type == XD_SUB_NOQ)
 1715                         return (XD_ERR_FAIL);   /* failed */
 1716                 XDC_TWAIT(xdcsc, iorqno);       /* put at end of waitq */
 1717                 switch (type) {
 1718                 case XD_SUB_NORM:
 1719                         return XD_ERR_AOK;      /* success */
 1720                 case XD_SUB_WAIT:
 1721                         while (iorq->iopb->done == 0) {
 1722                                 (void) tsleep(iorq, PRIBIO, "xdciorq", 0);
 1723                         }
 1724                         return (iorq->errno);
 1725                 case XD_SUB_POLL:
 1726                         return (xdc_piodriver(xdcsc, iorqno, 0));
 1727                 default:
 1728                         panic("xdc_submit_iorq adding");
 1729                 }
 1730         }
 1731 #ifdef XDC_DEBUG
 1732         {
 1733                 u_char *rio = (u_char *) iorq->iopb;
 1734                 int     sz = sizeof(struct xd_iopb), lcv;
 1735                 printf("%s: aio #%d [",
 1736                         xdcsc->sc_dev.dv_xname, iorq - xdcsc->reqs);
 1737                 for (lcv = 0; lcv < sz; lcv++)
 1738                         printf(" %02x", rio[lcv]);
 1739                 printf("]\n");
 1740         }
 1741 #endif                          /* XDC_DEBUG */
 1742 
 1743         /* controller not busy, start command */
 1744         iopbaddr = (u_long) iorq->dmaiopb;
 1745         XDC_GO(xdcsc->xdc, iopbaddr);   /* go! */
 1746         xdcsc->nrun++;
 1747         /* command now running, wrap it up */
 1748         switch (type) {
 1749         case XD_SUB_NORM:
 1750         case XD_SUB_NOQ:
 1751                 return (XD_ERR_AOK);    /* success */
 1752         case XD_SUB_WAIT:
 1753                 while (iorq->iopb->done == 0) {
 1754                         (void) tsleep(iorq, PRIBIO, "xdciorq", 0);
 1755                 }
 1756                 return (iorq->errno);
 1757         case XD_SUB_POLL:
 1758                 return (xdc_piodriver(xdcsc, iorqno, 0));
 1759         default:
 1760                 panic("xdc_submit_iorq wrap up");
 1761         }
 1762         panic("xdc_submit_iorq");
 1763         return 0;       /* not reached */
 1764 }
 1765 
 1766 
 1767 /*
 1768  * xdc_piodriver
 1769  *
 1770  * programmed i/o driver.   this function takes over the computer
 1771  * and drains off all i/o requests.   it returns the status of the iorq
 1772  * the caller is interesting in.   if freeone is true, then it returns
 1773  * when there is a free iorq.
 1774  */
 1775 int
 1776 xdc_piodriver(xdcsc, iorqno, freeone)
 1777         struct  xdc_softc *xdcsc;
 1778         int     iorqno;
 1779         int     freeone;
 1780 
 1781 {
 1782         int     nreset = 0;
 1783         int     retval = 0;
 1784         u_long  count;
 1785         struct  xdc *xdc = xdcsc->xdc;
 1786 #ifdef XDC_DEBUG
 1787         printf("xdc_piodriver(%s, %d, freeone=%d)\n", xdcsc->sc_dev.dv_xname,
 1788             iorqno, freeone);
 1789 #endif
 1790 
 1791         while (xdcsc->nwait || xdcsc->nrun) {
 1792 #ifdef XDC_DEBUG
 1793                 printf("xdc_piodriver: wait=%d, run=%d\n",
 1794                         xdcsc->nwait, xdcsc->nrun);
 1795 #endif
 1796                 XDC_WAIT(xdc, count, XDC_MAXTIME, (XDC_REMIOPB | XDC_F_ERROR));
 1797 #ifdef XDC_DEBUG
 1798                 printf("xdc_piodriver: done wait with count = %d\n", count);
 1799 #endif
 1800                 /* we expect some progress soon */
 1801                 if (count == 0 && nreset >= 2) {
 1802                         xdc_reset(xdcsc, 0, XD_RSET_ALL, XD_ERR_FAIL, 0);
 1803 #ifdef XDC_DEBUG
 1804                         printf("xdc_piodriver: timeout\n");
 1805 #endif
 1806                         return (XD_ERR_FAIL);
 1807                 }
 1808                 if (count == 0) {
 1809                         if (xdc_reset(xdcsc, 0,
 1810                                       (nreset++ == 0) ? XD_RSET_NONE : iorqno,
 1811                                       XD_ERR_FAIL,
 1812                                       0) == XD_ERR_FAIL)
 1813                                 return (XD_ERR_FAIL);   /* flushes all but POLL
 1814                                                          * requests, resets */
 1815                         continue;
 1816                 }
 1817                 xdc_remove_iorq(xdcsc); /* could resubmit request */
 1818                 if (freeone) {
 1819                         if (xdcsc->nrun < XDC_MAXIOPB) {
 1820 #ifdef XDC_DEBUG
 1821                                 printf("xdc_piodriver: done: one free\n");
 1822 #endif
 1823                                 return (XD_ERR_AOK);
 1824                         }
 1825                         continue;       /* don't xdc_start */
 1826                 }
 1827                 xdc_start(xdcsc, XDC_MAXIOPB);
 1828         }
 1829 
 1830         /* get return value */
 1831 
 1832         retval = xdcsc->reqs[iorqno].errno;
 1833 
 1834 #ifdef XDC_DEBUG
 1835         printf("xdc_piodriver: done, retval = 0x%x (%s)\n",
 1836             xdcsc->reqs[iorqno].errno, xdc_e2str(xdcsc->reqs[iorqno].errno));
 1837 #endif
 1838 
 1839         /* now that we've drained everything, start up any bufs that have
 1840          * queued */
 1841 
 1842         while (xdcsc->nfree > 0 && BUFQ_PEEK(&xdcsc->sc_wq) != NULL)
 1843                 if (xdc_startbuf(xdcsc, NULL, NULL) != XD_ERR_AOK)
 1844                         break;
 1845 
 1846         return (retval);
 1847 }
 1848 
 1849 /*
 1850  * xdc_reset: reset one drive.   NOTE: assumes xdc was just reset.
 1851  * we steal iopb[0] for this, but we put it back when we are done.
 1852  */
 1853 void
 1854 xdc_xdreset(xdcsc, xdsc)
 1855         struct xdc_softc *xdcsc;
 1856         struct xd_softc *xdsc;
 1857 
 1858 {
 1859         struct xd_iopb tmpiopb;
 1860         u_long  addr;
 1861         int     del;
 1862         bcopy(xdcsc->iopbase, &tmpiopb, sizeof(tmpiopb));
 1863         bzero(xdcsc->iopbase, sizeof(tmpiopb));
 1864         xdcsc->iopbase->comm = XDCMD_RST;
 1865         xdcsc->iopbase->unit = xdsc->xd_drive;
 1866         addr = (u_long) xdcsc->dvmaiopb;
 1867         XDC_GO(xdcsc->xdc, addr);       /* go! */
 1868         XDC_WAIT(xdcsc->xdc, del, XDC_RESETUSEC, XDC_REMIOPB);
 1869         if (del <= 0 || xdcsc->iopbase->errs) {
 1870                 printf("%s: off-line: %s\n", xdcsc->sc_dev.dv_xname,
 1871                     xdc_e2str(xdcsc->iopbase->errno));
 1872                 xdcsc->xdc->xdc_csr = XDC_RESET;
 1873                 XDC_WAIT(xdcsc->xdc, del, XDC_RESETUSEC, XDC_RESET);
 1874                 if (del <= 0)
 1875                         panic("xdc_reset");
 1876         } else {
 1877                 xdcsc->xdc->xdc_csr = XDC_CLRRIO;       /* clear RIO */
 1878         }
 1879         bcopy(&tmpiopb, xdcsc->iopbase, sizeof(tmpiopb));
 1880 }
 1881 
 1882 
 1883 /*
 1884  * xdc_reset: reset everything: requests are marked as errors except
 1885  * a polled request (which is resubmitted)
 1886  */
 1887 int
 1888 xdc_reset(xdcsc, quiet, blastmode, error, xdsc)
 1889         struct xdc_softc *xdcsc;
 1890         int     quiet, blastmode, error;
 1891         struct xd_softc *xdsc;
 1892 
 1893 {
 1894         int     del = 0, lcv, retval = XD_ERR_AOK;
 1895         int     oldfree = xdcsc->nfree;
 1896 
 1897         /* soft reset hardware */
 1898 
 1899         if (!quiet)
 1900                 printf("%s: soft reset\n", xdcsc->sc_dev.dv_xname);
 1901         xdcsc->xdc->xdc_csr = XDC_RESET;
 1902         XDC_WAIT(xdcsc->xdc, del, XDC_RESETUSEC, XDC_RESET);
 1903         if (del <= 0) {
 1904                 blastmode = XD_RSET_ALL;        /* dead, flush all requests */
 1905                 retval = XD_ERR_FAIL;
 1906         }
 1907         if (xdsc)
 1908                 xdc_xdreset(xdcsc, xdsc);
 1909 
 1910         /* fix queues based on "blast-mode" */
 1911 
 1912         for (lcv = 0; lcv < XDC_MAXIOPB; lcv++) {
 1913                 register struct xd_iorq *iorq = &xdcsc->reqs[lcv];
 1914 
 1915                 if (XD_STATE(iorq->mode) != XD_SUB_POLL &&
 1916                     XD_STATE(iorq->mode) != XD_SUB_WAIT &&
 1917                     XD_STATE(iorq->mode) != XD_SUB_NORM)
 1918                         /* is it active? */
 1919                         continue;
 1920 
 1921                 xdcsc->nrun--;  /* it isn't running any more */
 1922                 if (blastmode == XD_RSET_ALL || blastmode != lcv) {
 1923                         /* failed */
 1924                         iorq->errno = error;
 1925                         xdcsc->iopbase[lcv].done = xdcsc->iopbase[lcv].errs = 1;
 1926                         switch (XD_STATE(xdcsc->reqs[lcv].mode)) {
 1927                         case XD_SUB_NORM:
 1928                             iorq->buf->b_error = EIO;
 1929                             iorq->buf->b_flags |= B_ERROR;
 1930                             iorq->buf->b_resid =
 1931                                iorq->sectcnt * XDFM_BPS;
 1932 
 1933                             bus_dmamap_sync(xdcsc->dmatag, iorq->dmamap, 0,
 1934                                             iorq->dmamap->dm_mapsize,
 1935                                             (iorq->buf->b_flags & B_READ)
 1936                                                 ? BUS_DMASYNC_POSTREAD
 1937                                                 : BUS_DMASYNC_POSTWRITE);
 1938 
 1939                             bus_dmamap_unload(xdcsc->dmatag, iorq->dmamap);
 1940 
 1941                             disk_unbusy(&xdcsc->reqs[lcv].xd->sc_dk,
 1942                                 (xdcsc->reqs[lcv].buf->b_bcount -
 1943                                 xdcsc->reqs[lcv].buf->b_resid),
 1944                                 (iorq->buf->b_flags & B_READ));
 1945                             biodone(iorq->buf);
 1946                             XDC_FREE(xdcsc, lcv);       /* add to free list */
 1947                             break;
 1948                         case XD_SUB_WAIT:
 1949                             wakeup(iorq);
 1950                         case XD_SUB_POLL:
 1951                             xdcsc->ndone++;
 1952                             iorq->mode =
 1953                                 XD_NEWSTATE(iorq->mode, XD_SUB_DONE);
 1954                             break;
 1955                         }
 1956 
 1957                 } else {
 1958 
 1959                         /* resubmit, put at front of wait queue */
 1960                         XDC_HWAIT(xdcsc, lcv);
 1961                 }
 1962         }
 1963 
 1964         /*
 1965          * now, if stuff is waiting, start it.
 1966          * since we just reset it should go
 1967          */
 1968         xdc_start(xdcsc, XDC_MAXIOPB);
 1969 
 1970         /* ok, we did it */
 1971         if (oldfree == 0 && xdcsc->nfree)
 1972                 wakeup(&xdcsc->nfree);
 1973 
 1974 #ifdef XDC_DIAG
 1975         del = xdcsc->nwait + xdcsc->nrun + xdcsc->nfree + xdcsc->ndone;
 1976         if (del != XDC_MAXIOPB)
 1977                 printf("%s: diag: xdc_reset miscount (%d should be %d)!\n",
 1978                     xdcsc->sc_dev.dv_xname, del, XDC_MAXIOPB);
 1979         else
 1980                 if (xdcsc->ndone > XDC_MAXIOPB - XDC_SUBWAITLIM)
 1981                         printf("%s: diag: lots of done jobs (%d)\n",
 1982                             xdcsc->sc_dev.dv_xname, xdcsc->ndone);
 1983 #endif
 1984         printf("RESET DONE\n");
 1985         return (retval);
 1986 }
 1987 /*
 1988  * xdc_start: start all waiting buffers
 1989  */
 1990 
 1991 void
 1992 xdc_start(xdcsc, maxio)
 1993         struct xdc_softc *xdcsc;
 1994         int     maxio;
 1995 
 1996 {
 1997         int     rqno;
 1998         while (maxio && xdcsc->nwait &&
 1999                 (xdcsc->xdc->xdc_csr & XDC_ADDING) == 0) {
 2000                 XDC_GET_WAITER(xdcsc, rqno);    /* note: rqno is an "out"
 2001                                                  * param */
 2002                 if (xdc_submit_iorq(xdcsc, rqno, XD_SUB_NOQ) != XD_ERR_AOK)
 2003                         panic("xdc_start");     /* should never happen */
 2004                 maxio--;
 2005         }
 2006 }
 2007 /*
 2008  * xdc_remove_iorq: remove "done" IOPB's.
 2009  */
 2010 
 2011 int
 2012 xdc_remove_iorq(xdcsc)
 2013         struct xdc_softc *xdcsc;
 2014 
 2015 {
 2016         int     errno, rqno, comm, errs;
 2017         struct xdc *xdc = xdcsc->xdc;
 2018         struct xd_iopb *iopb;
 2019         struct xd_iorq *iorq;
 2020         struct buf *bp;
 2021 
 2022         if (xdc->xdc_csr & XDC_F_ERROR) {
 2023                 /*
 2024                  * FATAL ERROR: should never happen under normal use. This
 2025                  * error is so bad, you can't even tell which IOPB is bad, so
 2026                  * we dump them all.
 2027                  */
 2028                 errno = xdc->xdc_f_err;
 2029                 printf("%s: fatal error 0x%02x: %s\n", xdcsc->sc_dev.dv_xname,
 2030                     errno, xdc_e2str(errno));
 2031                 if (xdc_reset(xdcsc, 0, XD_RSET_ALL, errno, 0) != XD_ERR_AOK) {
 2032                         printf("%s: soft reset failed!\n",
 2033                                 xdcsc->sc_dev.dv_xname);
 2034                         panic("xdc_remove_iorq: controller DEAD");
 2035                 }
 2036                 return (XD_ERR_AOK);
 2037         }
 2038 
 2039         /*
 2040          * get iopb that is done
 2041          *
 2042          * hmm... I used to read the address of the done IOPB off the VME
 2043          * registers and calculate the rqno directly from that.   that worked
 2044          * until I started putting a load on the controller.   when loaded, i
 2045          * would get interrupts but neither the REMIOPB or F_ERROR bits would
 2046          * be set, even after DELAY'ing a while!   later on the timeout
 2047          * routine would detect IOPBs that were marked "running" but their
 2048          * "done" bit was set.   rather than dealing directly with this
 2049          * problem, it is just easier to look at all running IOPB's for the
 2050          * done bit.
 2051          */
 2052         if (xdc->xdc_csr & XDC_REMIOPB) {
 2053                 xdc->xdc_csr = XDC_CLRRIO;
 2054         }
 2055 
 2056         for (rqno = 0; rqno < XDC_MAXIOPB; rqno++) {
 2057                 iorq = &xdcsc->reqs[rqno];
 2058                 if (iorq->mode == 0 || XD_STATE(iorq->mode) == XD_SUB_DONE)
 2059                         continue;       /* free, or done */
 2060                 iopb = &xdcsc->iopbase[rqno];
 2061                 if (iopb->done == 0)
 2062                         continue;       /* not done yet */
 2063 
 2064 #ifdef XDC_DEBUG
 2065                 {
 2066                         u_char *rio = (u_char *) iopb;
 2067                         int     sz = sizeof(struct xd_iopb), lcv;
 2068                         printf("%s: rio #%d [", xdcsc->sc_dev.dv_xname, rqno);
 2069                         for (lcv = 0; lcv < sz; lcv++)
 2070                                 printf(" %02x", rio[lcv]);
 2071                         printf("]\n");
 2072                 }
 2073 #endif                          /* XDC_DEBUG */
 2074 
 2075                 xdcsc->nrun--;
 2076 
 2077                 comm = iopb->comm;
 2078                 errs = iopb->errs;
 2079 
 2080                 if (errs)
 2081                         iorq->errno = iopb->errno;
 2082                 else
 2083                         iorq->errno = 0;
 2084 
 2085                 /* handle non-fatal errors */
 2086 
 2087                 if (errs &&
 2088                     xdc_error(xdcsc, iorq, iopb, rqno, comm) == XD_ERR_AOK)
 2089                         continue;       /* AOK: we resubmitted it */
 2090 
 2091 
 2092                 /* this iorq is now done (hasn't been restarted or anything) */
 2093 
 2094                 if ((iorq->mode & XD_MODE_VERBO) && iorq->lasterror)
 2095                         xdc_perror(iorq, iopb, 0);
 2096 
 2097                 /* now, if read/write check to make sure we got all the data
 2098                  * we needed. (this may not be the case if we got an error in
 2099                  * the middle of a multisector request).   */
 2100 
 2101                 if ((iorq->mode & XD_MODE_B144) != 0 && errs == 0 &&
 2102                     (comm == XDCMD_RD || comm == XDCMD_WR)) {
 2103                         /* we just successfully processed a bad144 sector
 2104                          * note: if we are in bad 144 mode, the pointers have
 2105                          * been advanced already (see above) and are pointing
 2106                          * at the bad144 sector.   to exit bad144 mode, we
 2107                          * must advance the pointers 1 sector and issue a new
 2108                          * request if there are still sectors left to process
 2109                          *
 2110                          */
 2111                         XDC_ADVANCE(iorq, 1);   /* advance 1 sector */
 2112 
 2113                         /* exit b144 mode */
 2114                         iorq->mode = iorq->mode & (~XD_MODE_B144);
 2115 
 2116                         if (iorq->sectcnt) {    /* more to go! */
 2117                                 iorq->lasterror = iorq->errno = iopb->errno = 0;
 2118                                 iopb->errs = iopb->done = 0;
 2119                                 iorq->tries = 0;
 2120                                 iopb->sectcnt = iorq->sectcnt;
 2121                                 iopb->cylno = iorq->blockno /
 2122                                                 iorq->xd->sectpercyl;
 2123                                 iopb->headno =
 2124                                         (iorq->blockno / iorq->xd->nhead) %
 2125                                                 iorq->xd->nhead;
 2126                                 iopb->sectno = iorq->blockno % XDFM_BPS;
 2127                                 iopb->daddr = (u_long) iorq->dbuf;
 2128                                 XDC_HWAIT(xdcsc, rqno);
 2129                                 xdc_start(xdcsc, 1);    /* resubmit */
 2130                                 continue;
 2131                         }
 2132                 }
 2133                 /* final cleanup, totally done with this request */
 2134 
 2135                 switch (XD_STATE(iorq->mode)) {
 2136                 case XD_SUB_NORM:
 2137                         bp = iorq->buf;
 2138                         if (errs) {
 2139                                 bp->b_error = EIO;
 2140                                 bp->b_flags |= B_ERROR;
 2141                                 bp->b_resid = iorq->sectcnt * XDFM_BPS;
 2142                         } else {
 2143                                 bp->b_resid = 0;        /* done */
 2144                         }
 2145                         bus_dmamap_sync(xdcsc->dmatag, iorq->dmamap, 0,
 2146                                         iorq->dmamap->dm_mapsize,
 2147                                         (bp->b_flags & B_READ)
 2148                                                 ? BUS_DMASYNC_POSTREAD
 2149                                                 : BUS_DMASYNC_POSTWRITE);
 2150                         bus_dmamap_unload(xdcsc->dmatag, iorq->dmamap);
 2151 
 2152                         disk_unbusy(&iorq->xd->sc_dk,
 2153                             (bp->b_bcount - bp->b_resid),
 2154                             (bp->b_flags & B_READ));
 2155                         XDC_FREE(xdcsc, rqno);
 2156                         biodone(bp);
 2157                         break;
 2158                 case XD_SUB_WAIT:
 2159                         iorq->mode = XD_NEWSTATE(iorq->mode, XD_SUB_DONE);
 2160                         xdcsc->ndone++;
 2161                         wakeup(iorq);
 2162                         break;
 2163                 case XD_SUB_POLL:
 2164                         iorq->mode = XD_NEWSTATE(iorq->mode, XD_SUB_DONE);
 2165                         xdcsc->ndone++;
 2166                         break;
 2167                 }
 2168         }
 2169 
 2170         return (XD_ERR_AOK);
 2171 }
 2172 
 2173 /*
 2174  * xdc_perror: print error.
 2175  * - if still_trying is true: we got an error, retried and got a
 2176  *   different error.  in that case lasterror is the old error,
 2177  *   and errno is the new one.
 2178  * - if still_trying is not true, then if we ever had an error it
 2179  *   is in lasterror. also, if iorq->errno == 0, then we recovered
 2180  *   from that error (otherwise iorq->errno == iorq->lasterror).
 2181  */
 2182 void
 2183 xdc_perror(iorq, iopb, still_trying)
 2184         struct xd_iorq *iorq;
 2185         struct xd_iopb *iopb;
 2186         int     still_trying;
 2187 
 2188 {
 2189 
 2190         int     error = iorq->lasterror;
 2191 
 2192         printf("%s", (iorq->xd) ? iorq->xd->sc_dev.dv_xname
 2193             : iorq->xdc->sc_dev.dv_xname);
 2194         if (iorq->buf)
 2195                 printf("%c: ", 'a' + DISKPART(iorq->buf->b_dev));
 2196         if (iopb->comm == XDCMD_RD || iopb->comm == XDCMD_WR)
 2197                 printf("%s %d/%d/%d: ",
 2198                         (iopb->comm == XDCMD_RD) ? "read" : "write",
 2199                         iopb->cylno, iopb->headno, iopb->sectno);
 2200         printf("%s", xdc_e2str(error));
 2201 
 2202         if (still_trying)
 2203                 printf(" [still trying, new error=%s]", xdc_e2str(iorq->errno));
 2204         else
 2205                 if (iorq->errno == 0)
 2206                         printf(" [recovered in %d tries]", iorq->tries);
 2207 
 2208         printf("\n");
 2209 }
 2210 
 2211 /*
 2212  * xdc_error: non-fatal error encountered... recover.
 2213  * return AOK if resubmitted, return FAIL if this iopb is done
 2214  */
 2215 int
 2216 xdc_error(xdcsc, iorq, iopb, rqno, comm)
 2217         struct xdc_softc *xdcsc;
 2218         struct xd_iorq *iorq;
 2219         struct xd_iopb *iopb;
 2220         int     rqno, comm;
 2221 
 2222 {
 2223         int     errno = iorq->errno;
 2224         int     erract = errno & XD_ERA_MASK;
 2225         int     oldmode, advance;
 2226 #ifdef __sparc__
 2227         int i;
 2228 #endif
 2229 
 2230         if (erract == XD_ERA_RSET) {    /* some errors require a reset */
 2231                 oldmode = iorq->mode;
 2232                 iorq->mode = XD_SUB_DONE | (~XD_SUB_MASK & oldmode);
 2233                 xdcsc->ndone++;
 2234                 /* make xdc_start ignore us */
 2235                 xdc_reset(xdcsc, 1, XD_RSET_NONE, errno, iorq->xd);
 2236                 iorq->mode = oldmode;
 2237                 xdcsc->ndone--;
 2238         }
 2239         /* check for read/write to a sector in bad144 table if bad: redirect
 2240          * request to bad144 area */
 2241 
 2242         if ((comm == XDCMD_RD || comm == XDCMD_WR) &&
 2243             (iorq->mode & XD_MODE_B144) == 0) {
 2244                 advance = iorq->sectcnt - iopb->sectcnt;
 2245                 XDC_ADVANCE(iorq, advance);
 2246 #ifdef __sparc__
 2247                 if ((i = isbad(&iorq->xd->dkb, iorq->blockno / iorq->xd->sectpercyl,
 2248                             (iorq->blockno / iorq->xd->nsect) % iorq->xd->nhead,
 2249                             iorq->blockno % iorq->xd->nsect)) != -1) {
 2250                         iorq->mode |= XD_MODE_B144;     /* enter bad144 mode &
 2251                                                          * redirect */
 2252                         iopb->errno = iopb->done = iopb->errs = 0;
 2253                         iopb->sectcnt = 1;
 2254                         iopb->cylno = (iorq->xd->ncyl + iorq->xd->acyl) - 2;
 2255                         /* second to last acyl */
 2256                         i = iorq->xd->sectpercyl - 1 - i;       /* follow bad144
 2257                                                                  * standard */
 2258                         iopb->headno = i / iorq->xd->nhead;
 2259                         iopb->sectno = i % iorq->xd->nhead;
 2260                         XDC_HWAIT(xdcsc, rqno);
 2261                         xdc_start(xdcsc, 1);    /* resubmit */
 2262                         return (XD_ERR_AOK);    /* recovered! */
 2263                 }
 2264 #endif
 2265         }
 2266 
 2267         /*
 2268          * it isn't a bad144 sector, must be real error! see if we can retry
 2269          * it?
 2270          */
 2271         if ((iorq->mode & XD_MODE_VERBO) && iorq->lasterror)
 2272                 xdc_perror(iorq, iopb, 1);      /* inform of error state
 2273                                                  * change */
 2274         iorq->lasterror = errno;
 2275 
 2276         if ((erract == XD_ERA_RSET || erract == XD_ERA_HARD)
 2277             && iorq->tries < XDC_MAXTRIES) {    /* retry? */
 2278                 iorq->tries++;
 2279                 iorq->errno = iopb->errno = iopb->done = iopb->errs = 0;
 2280                 XDC_HWAIT(xdcsc, rqno);
 2281                 xdc_start(xdcsc, 1);    /* restart */
 2282                 return (XD_ERR_AOK);    /* recovered! */
 2283         }
 2284 
 2285         /* failed to recover from this error */
 2286         return (XD_ERR_FAIL);
 2287 }
 2288 
 2289 /*
 2290  * xdc_tick: make sure xd is still alive and ticking (err, kicking).
 2291  */
 2292 void
 2293 xdc_tick(arg)
 2294         void   *arg;
 2295 
 2296 {
 2297         struct xdc_softc *xdcsc = arg;
 2298         int     lcv, s, reset = 0;
 2299 #ifdef XDC_DIAG
 2300         int     wait, run, free, done, whd = 0;
 2301         u_char  fqc[XDC_MAXIOPB], wqc[XDC_MAXIOPB], mark[XDC_MAXIOPB];
 2302         s = splbio();
 2303         wait = xdcsc->nwait;
 2304         run = xdcsc->nrun;
 2305         free = xdcsc->nfree;
 2306         done = xdcsc->ndone;
 2307         bcopy(xdcsc->waitq, wqc, sizeof(wqc));
 2308         bcopy(xdcsc->freereq, fqc, sizeof(fqc));
 2309         splx(s);
 2310         if (wait + run + free + done != XDC_MAXIOPB) {
 2311                 printf("%s: diag: IOPB miscount (got w/f/r/d %d/%d/%d/%d, wanted %d)\n",
 2312                     xdcsc->sc_dev.dv_xname, wait, free, run, done, XDC_MAXIOPB);
 2313                 bzero(mark, sizeof(mark));
 2314                 printf("FREE: ");
 2315                 for (lcv = free; lcv > 0; lcv--) {
 2316                         printf("%d ", fqc[lcv - 1]);
 2317                         mark[fqc[lcv - 1]] = 1;
 2318                 }
 2319                 printf("\nWAIT: ");
 2320                 lcv = wait;
 2321                 while (lcv > 0) {
 2322                         printf("%d ", wqc[whd]);
 2323                         mark[wqc[whd]] = 1;
 2324                         whd = (whd + 1) % XDC_MAXIOPB;
 2325                         lcv--;
 2326                 }
 2327                 printf("\n");
 2328                 for (lcv = 0; lcv < XDC_MAXIOPB; lcv++) {
 2329                         if (mark[lcv] == 0)
 2330                                 printf("MARK: running %d: mode %d done %d errs %d errno 0x%x ttl %d buf %p\n",
 2331                                 lcv, xdcsc->reqs[lcv].mode,
 2332                                 xdcsc->iopbase[lcv].done,
 2333                                 xdcsc->iopbase[lcv].errs,
 2334                                 xdcsc->iopbase[lcv].errno,
 2335                                 xdcsc->reqs[lcv].ttl, xdcsc->reqs[lcv].buf);
 2336                 }
 2337         } else
 2338                 if (done > XDC_MAXIOPB - XDC_SUBWAITLIM)
 2339                         printf("%s: diag: lots of done jobs (%d)\n",
 2340                                 xdcsc->sc_dev.dv_xname, done);
 2341 
 2342 #endif
 2343 #ifdef XDC_DEBUG
 2344         printf("%s: tick: csr 0x%x, w/f/r/d %d/%d/%d/%d\n",
 2345                 xdcsc->sc_dev.dv_xname,
 2346                 xdcsc->xdc->xdc_csr, xdcsc->nwait, xdcsc->nfree, xdcsc->nrun,
 2347                 xdcsc->ndone);
 2348         for (lcv = 0; lcv < XDC_MAXIOPB; lcv++) {
 2349                 if (xdcsc->reqs[lcv].mode)
 2350                   printf("running %d: mode %d done %d errs %d errno 0x%x\n",
 2351                          lcv,
 2352                          xdcsc->reqs[lcv].mode, xdcsc->iopbase[lcv].done,
 2353                          xdcsc->iopbase[lcv].errs, xdcsc->iopbase[lcv].errno);
 2354         }
 2355 #endif
 2356 
 2357         /* reduce ttl for each request if one goes to zero, reset xdc */
 2358         s = splbio();
 2359         for (lcv = 0; lcv < XDC_MAXIOPB; lcv++) {
 2360                 if (xdcsc->reqs[lcv].mode == 0 ||
 2361                     XD_STATE(xdcsc->reqs[lcv].mode) == XD_SUB_DONE)
 2362                         continue;
 2363                 xdcsc->reqs[lcv].ttl--;
 2364                 if (xdcsc->reqs[lcv].ttl == 0)
 2365                         reset = 1;
 2366         }
 2367         if (reset) {
 2368                 printf("%s: watchdog timeout\n", xdcsc->sc_dev.dv_xname);
 2369                 xdc_reset(xdcsc, 0, XD_RSET_NONE, XD_ERR_FAIL, NULL);
 2370         }
 2371         splx(s);
 2372 
 2373         /* until next time */
 2374 
 2375         callout_reset(&xdcsc->sc_tick_ch, XDC_TICKCNT, xdc_tick, xdcsc);
 2376 }
 2377 
 2378 /*
 2379  * xdc_ioctlcmd: this function provides a user level interface to the
 2380  * controller via ioctl.   this allows "format" programs to be written
 2381  * in user code, and is also useful for some debugging.   we return
 2382  * an error code.   called at user priority.
 2383  */
 2384 int
 2385 xdc_ioctlcmd(xd, dev, xio)
 2386         struct xd_softc *xd;
 2387         dev_t   dev;
 2388         struct xd_iocmd *xio;
 2389 
 2390 {
 2391         int     s, rqno, dummy;
 2392         caddr_t dvmabuf = NULL, buf = NULL;
 2393         struct xdc_softc *xdcsc;
 2394         int                     rseg, error;
 2395         bus_dma_segment_t       seg;
 2396 
 2397         /* check sanity of requested command */
 2398 
 2399         switch (xio->cmd) {
 2400 
 2401         case XDCMD_NOP: /* no op: everything should be zero */
 2402                 if (xio->subfn || xio->dptr || xio->dlen ||
 2403                     xio->block || xio->sectcnt)
 2404                         return (EINVAL);
 2405                 break;
 2406 
 2407         case XDCMD_RD:          /* read / write sectors (up to XD_IOCMD_MAXS) */
 2408         case XDCMD_WR:
 2409                 if (xio->subfn || xio->sectcnt > XD_IOCMD_MAXS ||
 2410                     xio->sectcnt * XDFM_BPS != xio->dlen || xio->dptr == NULL)
 2411                         return (EINVAL);
 2412                 break;
 2413 
 2414         case XDCMD_SK:          /* seek: doesn't seem useful to export this */
 2415                 return (EINVAL);
 2416 
 2417         case XDCMD_WRP: /* write parameters */
 2418                 return (EINVAL);/* not useful, except maybe drive
 2419                                  * parameters... but drive parameters should
 2420                                  * go via disklabel changes */
 2421 
 2422         case XDCMD_RDP: /* read parameters */
 2423                 if (xio->subfn != XDFUN_DRV ||
 2424                     xio->dlen || xio->block || xio->dptr)
 2425                         return (EINVAL);        /* allow read drive params to
 2426                                                  * get hw_spt */
 2427                 xio->sectcnt = xd->hw_spt;      /* we already know the answer */
 2428                 return (0);
 2429                 break;
 2430 
 2431         case XDCMD_XRD: /* extended read/write */
 2432         case XDCMD_XWR:
 2433 
 2434                 switch (xio->subfn) {
 2435 
 2436                 case XDFUN_THD:/* track headers */
 2437                         if (xio->sectcnt != xd->hw_spt ||
 2438                             (xio->block % xd->nsect) != 0 ||
 2439                             xio->dlen != XD_IOCMD_HSZ * xd->hw_spt ||
 2440                             xio->dptr == NULL)
 2441                                 return (EINVAL);
 2442                         xio->sectcnt = 0;
 2443                         break;
 2444 
 2445                 case XDFUN_FMT:/* NOTE: also XDFUN_VFY */
 2446                         if (xio->cmd == XDCMD_XRD)
 2447                                 return (EINVAL);        /* no XDFUN_VFY */
 2448                         if (xio->sectcnt || xio->dlen ||
 2449                             (xio->block % xd->nsect) != 0 || xio->dptr)
 2450                                 return (EINVAL);
 2451                         break;
 2452 
 2453                 case XDFUN_HDR:/* header, header verify, data, data ECC */
 2454                         return (EINVAL);        /* not yet */
 2455 
 2456                 case XDFUN_DM:  /* defect map */
 2457                 case XDFUN_DMX:/* defect map (alternate location) */
 2458                         if (xio->sectcnt || xio->dlen != XD_IOCMD_DMSZ ||
 2459                             (xio->block % xd->nsect) != 0 || xio->dptr == NULL)
 2460                                 return (EINVAL);
 2461                         break;
 2462 
 2463                 default:
 2464                         return (EINVAL);
 2465                 }
 2466                 break;
 2467 
 2468         case XDCMD_TST: /* diagnostics */
 2469                 return (EINVAL);
 2470 
 2471         default:
 2472                 return (EINVAL);/* ??? */
 2473         }
 2474 
 2475         xdcsc = xd->parent;
 2476 
 2477         /* create DVMA buffer for request if needed */
 2478         if (xio->dlen) {
 2479                 bus_addr_t busbuf;
 2480 
 2481                 if ((error = xd_dmamem_alloc(xdcsc->dmatag, xdcsc->auxmap,
 2482                                              &seg, &rseg,
 2483                                              xio->dlen, &buf,
 2484                                              &busbuf)) != 0) {
 2485                         return (error);
 2486                 }
 2487                 dvmabuf = (caddr_t)(u_long)BUS_ADDR_PADDR(busbuf);
 2488 
 2489                 if (xio->cmd == XDCMD_WR || xio->cmd == XDCMD_XWR) {
 2490                         if ((error = copyin(xio->dptr, buf, xio->dlen)) != 0) {
 2491                                 bus_dmamem_unmap(xdcsc->dmatag, buf, xio->dlen);
 2492                                 bus_dmamem_free(xdcsc->dmatag, &seg, rseg);
 2493                                 return (error);
 2494                         }
 2495                 }
 2496         }
 2497 
 2498         /* do it! */
 2499 
 2500         error = 0;
 2501         s = splbio();
 2502         rqno = xdc_cmd(xdcsc, xio->cmd, xio->subfn, xd->xd_drive, xio->block,
 2503             xio->sectcnt, dvmabuf, XD_SUB_WAIT);
 2504         if (rqno == XD_ERR_FAIL) {
 2505                 error = EIO;
 2506                 goto done;
 2507         }
 2508         xio->errno = xdcsc->reqs[rqno].errno;
 2509         xio->tries = xdcsc->reqs[rqno].tries;
 2510         XDC_DONE(xdcsc, rqno, dummy);
 2511 
 2512         if (xio->cmd == XDCMD_RD || xio->cmd == XDCMD_XRD)
 2513                 error = copyout(buf, xio->dptr, xio->dlen);
 2514 
 2515 done:
 2516         splx(s);
 2517         if (dvmabuf) {
 2518                 xd_dmamem_free(xdcsc->dmatag, xdcsc->auxmap, &seg, rseg,
 2519                                 xio->dlen, buf);
 2520         }
 2521         return (error);
 2522 }
 2523 
 2524 /*
 2525  * xdc_e2str: convert error code number into an error string
 2526  */
 2527 char *
 2528 xdc_e2str(no)
 2529         int     no;
 2530 {
 2531         switch (no) {
 2532         case XD_ERR_FAIL:
 2533                 return ("Software fatal error");
 2534         case XD_ERR_AOK:
 2535                 return ("Successful completion");
 2536         case XD_ERR_ICYL:
 2537                 return ("Illegal cylinder address");
 2538         case XD_ERR_IHD:
 2539                 return ("Illegal head address");
 2540         case XD_ERR_ISEC:
 2541                 return ("Illgal sector address");
 2542         case XD_ERR_CZER:
 2543                 return ("Count zero");
 2544         case XD_ERR_UIMP:
 2545                 return ("Unimplemented command");
 2546         case XD_ERR_IF1:
 2547                 return ("Illegal field length 1");
 2548         case XD_ERR_IF2:
 2549                 return ("Illegal field length 2");
 2550         case XD_ERR_IF3:
 2551                 return ("Illegal field length 3");
 2552         case XD_ERR_IF4:
 2553                 return ("Illegal field length 4");
 2554         case XD_ERR_IF5:
 2555                 return ("Illegal field length 5");
 2556         case XD_ERR_IF6:
 2557                 return ("Illegal field length 6");
 2558         case XD_ERR_IF7:
 2559                 return ("Illegal field length 7");
 2560         case XD_ERR_ISG:
 2561                 return ("Illegal scatter/gather length");
 2562         case XD_ERR_ISPT:
 2563                 return ("Not enough sectors per track");
 2564         case XD_ERR_ALGN:
 2565                 return ("Next IOPB address alignment error");
 2566         case XD_ERR_SGAL:
 2567                 return ("Scatter/gather address alignment error");
 2568         case XD_ERR_SGEC:
 2569                 return ("Scatter/gather with auto-ECC");
 2570         case XD_ERR_SECC:
 2571                 return ("Soft ECC corrected");
 2572         case XD_ERR_SIGN:
 2573                 return ("ECC ignored");
 2574         case XD_ERR_ASEK:
 2575                 return ("Auto-seek retry recovered");
 2576         case XD_ERR_RTRY:
 2577                 return ("Soft retry recovered");
 2578         case XD_ERR_HECC:
 2579                 return ("Hard data ECC");
 2580         case XD_ERR_NHDR:
 2581                 return ("Header not found");
 2582         case XD_ERR_NRDY:
 2583                 return ("Drive not ready");
 2584         case XD_ERR_TOUT:
 2585                 return ("Operation timeout");
 2586         case XD_ERR_VTIM:
 2587                 return ("VMEDMA timeout");
 2588         case XD_ERR_DSEQ:
 2589                 return ("Disk sequencer error");
 2590         case XD_ERR_HDEC:
 2591                 return ("Header ECC error");
 2592         case XD_ERR_RVFY:
 2593                 return ("Read verify");
 2594         case XD_ERR_VFER:
 2595                 return ("Fatail VMEDMA error");
 2596         case XD_ERR_VBUS:
 2597                 return ("VMEbus error");
 2598         case XD_ERR_DFLT:
 2599                 return ("Drive faulted");
 2600         case XD_ERR_HECY:
 2601                 return ("Header error/cyliner");
 2602         case XD_ERR_HEHD:
 2603                 return ("Header error/head");
 2604         case XD_ERR_NOCY:
 2605                 return ("Drive not on-cylinder");
 2606         case XD_ERR_SEEK:
 2607                 return ("Seek error");
 2608         case XD_ERR_ILSS:
 2609                 return ("Illegal sector size");
 2610         case XD_ERR_SEC:
 2611                 return ("Soft ECC");
 2612         case XD_ERR_WPER:
 2613                 return ("Write-protect error");
 2614         case XD_ERR_IRAM:
 2615                 return ("IRAM self test failure");
 2616         case XD_ERR_MT3:
 2617                 return ("Maintenance test 3 failure (DSKCEL RAM)");
 2618         case XD_ERR_MT4:
 2619                 return ("Maintenance test 4 failure (header shift reg)");
 2620         case XD_ERR_MT5:
 2621                 return ("Maintenance test 5 failure (VMEDMA regs)");
 2622         case XD_ERR_MT6:
 2623                 return ("Maintenance test 6 failure (REGCEL chip)");
 2624         case XD_ERR_MT7:
 2625                 return ("Maintenance test 7 failure (buffer parity)");
 2626         case XD_ERR_MT8:
 2627                 return ("Maintenance test 8 failure (disk FIFO)");
 2628         case XD_ERR_IOCK:
 2629                 return ("IOPB checksum miscompare");
 2630         case XD_ERR_IODM:
 2631                 return ("IOPB DMA fatal");
 2632         case XD_ERR_IOAL:
 2633                 return ("IOPB address alignment error");
 2634         case XD_ERR_FIRM:
 2635                 return ("Firmware error");
 2636         case XD_ERR_MMOD:
 2637                 return ("Illegal maintenance mode test number");
 2638         case XD_ERR_ACFL:
 2639                 return ("ACFAIL asserted");
 2640         default:
 2641                 return ("Unknown error");
 2642         }
 2643 }

Cache object: c13c24864bef7bc43c3da6fddbbf6e63


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


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