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/i386/isa/ida.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 /*
    2  * Copyright (c) 1996, 1997, 1998, 1999
    3  *    Mark Dawson and David James. All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice immediately at the beginning of the file, without modification,
   10  *    this list of conditions, and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * $FreeBSD$
   30  *
   31  */
   32 
   33 /*
   34  * Compaq SMART disk array controller driver for FreeBSD.
   35  * Supports the Compaq SMART-2 and SMART-3 families of disk
   36  * array controllers.
   37  *
   38  */
   39 
   40 #include "id.h"
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/kernel.h>
   44 #include <sys/conf.h>
   45 #include <sys/errno.h>
   46 #include <sys/malloc.h>
   47 #include <sys/buf.h>
   48 #include <sys/file.h>
   49 #include <sys/stat.h>
   50 #include <sys/proc.h>
   51 #include <sys/sysctl.h>
   52 #include <i386/isa/isa.h>
   53 #include <i386/isa/isa_device.h>
   54 #ifdef DEVFS
   55 #include <sys/devfsext.h>
   56 #endif /*DEVFS*/
   57 /*#include <sys/dkbad.h>*/
   58 #include <sys/devicestat.h>
   59 #include <sys/disklabel.h>
   60 #include <sys/diskslice.h>
   61 #include <vm/vm.h>
   62 #include <vm/vm_param.h>
   63 #include <vm/vm_prot.h>
   64 #include <vm/pmap.h>
   65 
   66 #include <pci.h>
   67 #include <pci/pcireg.h>
   68 #include <pci/pcivar.h>
   69 
   70 #include <sys/reboot.h>
   71 extern u_long bootdev;
   72 
   73 #define IDA_VERSION 1
   74 
   75 #define PAGESIZ 4096
   76 
   77 /* IDA wdc vector stealing (cuckoo) control */
   78 #define IDA_CUCKOO_NEVER 0              /* never steal wdc vectors */
   79 #define IDA_CUCKOO_ROOTWD 1             /* steal iff rootdev is wd device */
   80 #define IDA_CUCKOO_ROOTNOTIDA 2         /* steal if rootdev not ida device */
   81 #define IDA_CUCKOO_ALWAYS 3             /* always steal wdc vectors */
   82 
   83 #ifndef IDA_CUCKOO_MODE
   84 #define IDA_CUCKOO_MODE IDA_CUCKOO_ALWAYS
   85 #endif
   86 
   87 /* IDA PCI controller */
   88 
   89 #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae100e11ul
   90 #define PCI_CONTROLLER(ctlp) (ctlp->ident == PCI_DEVICE_ID_COMPAQ_SMART2P)
   91 
   92 typedef struct ida_pci_reg {
   93   u_long unknown;
   94   u_long initiate_fifo;
   95 #define IDA_PCI_BUSY 1
   96   u_long complete_fifo;
   97   u_long interrupt;
   98 #define IDA_PCI_ENABLE_INTS 1
   99 #define IDA_PCI_DISABLE_INTS 0
  100   u_long status;
  101 #define IDA_PCI_PENDING 1
  102 #define IDA_PCI_READY 2
  103 } ida_pci_reg_t;
  104 
  105 /* IDA controller register definitions */
  106 
  107 #define R_ID0           0xc80   /* id byte 0 */
  108 #define R_ID1           0xc81   /* id byte 1 */
  109 #define R_ID2           0xc82   /* id byte 2 */
  110 #define R_ID3           0xc83   /* id byte 3 */
  111 #define R_CONF          0xc88   /* global configuration */
  112 #define R_SYSINT        0xc89   /* system interrupt enable/ctrl */
  113 #define R_SEM0          0xc8a   /* semaphore port 0 */
  114 #define R_SEM1          0xc8b   /* semaphore port 1 */
  115 #define R_LBELL_E       0xc8c   /* local doorbell enable */
  116 #define R_LBELL_I       0xc8d   /* local doorbell int/status */
  117 #define R_EBELL_E       0xc8e   /* EISA doorbell enable */
  118 #define R_EBELL_I       0xc8f   /* EISA doorbell int/status */
  119 #define R_SUB_ADDR      0xc90   /* submit address */
  120 #define R_SUB_LEN       0xc94   /* submit cmdlist size */
  121 #define R_COM_ADDR      0xc98   /* completion address */
  122 #define R_COM_OFF       0xc9c   /* completion request offset */
  123 #define R_COM_STAT      0xc9e   /* completion cmdlist status */
  124 #define R_INTDEF        0xcc0   /* interrupt definition */
  125 
  126 /*
  127  * BMIC doorbell status codes
  128  */
  129 
  130 #define BMIC_DATA_READY         0x01    /* data ready bit */
  131 #define BMIC_CHAN_CLEAR         0x02    /* channel clear bit */
  132 
  133 
  134 /* IDA controller command list return status values */
  135 
  136 #define IDA_COMPL_OK            0x01    /* command list completed ok */
  137 #define IDA_NON_FATAL           0x02    /* non-fatal error */
  138 #define IDA_FATAL               0x04    /* fatal error */
  139 #define IDA_ABORTED             0x08    /* command list aborted */
  140 #define IDA_INVAL_REQ           0x10    /* bad request block */
  141 #define IDA_INVAL_LIST          0x20    /* bad command list */
  142 #define IDA_AARGH_LIST          0x40    /* totally disastrous command list */
  143 
  144 
  145 /* IDA controller command codes */
  146 
  147 #define IDA_GET_DRV_INFO        0x10
  148 #define IDA_GET_CTL_INFO        0x11
  149 #define IDA_READ_DATA           0x20
  150 #define IDA_WRITE_DATA          0x30
  151 #define IDA_FLUSH_CACHE         0xc2
  152 
  153 
  154 /* Interrupt definition codes */
  155 
  156 #define IDA_IRQ_MASK            0xfc
  157 #define IDA_IRQ_10              0x20
  158 #define IDA_IRQ_11              0x10
  159 #define IDA_IRQ_14              0x40
  160 #define IDA_IRQ_15              0x80
  161 
  162 
  163 /* IDA controller hardware command structure definitions */
  164 
  165 typedef u_long physaddr_t;
  166 
  167 struct ida_hdr {
  168   u_long drive:8;               /* logical drive */
  169   u_long priority:8;            /* block priority */
  170   u_long flags:16;              /* control flags */
  171 };
  172 
  173 struct ida_req {
  174   u_long next:16;               /* offset of next request */
  175   u_long command:8;             /* command */
  176   u_long error:8;               /* return error code */
  177   u_long blkno;                 /* block number */
  178   u_short bcount;               /* block count */
  179   u_short sgcount;              /* number of scatter gather entries */
  180 
  181   /* a struct ida_req is followed physically by an array of struct ida_sgb */
  182 };
  183 
  184 struct ida_sgb {
  185   u_long len;                   /* length of scatter gather segmmentk */
  186   physaddr_t addr;              /* physical address of block */
  187 };
  188 
  189 
  190 /* first some handy definitions as FreeBSD gcc doesn't do #pragma pack() */
  191 
  192 #define pack_char(name)  u_char name[1]
  193 #define pack_short(name) u_char name[2]
  194 #define pack_int(name)   u_char name[4]
  195 #define pack_long(name)  u_char name[4]
  196 
  197 /* ugly, but not inefficient, as it gets evaluated at compile time by gcc */
  198 
  199 #define u_unpack(member) ( \
  200                           (sizeof(member) == 1) ? *(u_char *)(member) \
  201                           : (sizeof(member) == 2) ? *(u_short *)(member) \
  202                           : *(u_int *)(member) \
  203                            )
  204 
  205 #define s_unpack(member) ( \
  206                           (sizeof(member) == 1) ? *(char *)(member) \
  207                           : (sizeof(member) == 2) ? *(short *)(member) \
  208                           : *(int *)(member) \
  209                            )
  210 
  211 /* IDA controller hardware returned data structure definitions */
  212 
  213 struct ida_ctl_info {
  214   pack_char(num_drvs);
  215   pack_long(signature);
  216   pack_long(firm_rev);
  217 };
  218 
  219 struct ida_drv_info {
  220   pack_short(secsize);
  221   pack_long(secperunit);
  222   pack_short(ncylinders);
  223   pack_char(ntracks);
  224   pack_char(signature);
  225   pack_char(psectors);
  226   pack_short(wprecomp);
  227   pack_char(max_acc);
  228   pack_char(control);
  229   pack_short(pcylinders);
  230   pack_char(ptracks);
  231   pack_short(landing_zone);
  232   pack_char(nsectors);
  233   pack_char(checksum);
  234   pack_char(mirror);
  235 };
  236 
  237 
  238 /* IDA driver queue command block */
  239 
  240 #define IDA_MAX_SGLEN 32        /* maximum entries in scatter gather list */
  241 #define IDA_MAX_DRVS_CTLR 8     /* maximum logical drives per controller */
  242 #define IDA_DEF_PRIORITY 16     /* default priority for command list */
  243 
  244 #define IDA_SCSI_TARGET_ID 7
  245 #define IDA_QCB_MAX 256
  246 
  247 struct ida_qcb {
  248   /* first some hardware specific fields ... */
  249 
  250   struct ida_hdr hdr;
  251   struct ida_req req;
  252   struct ida_sgb sglist[IDA_MAX_SGLEN];
  253 
  254   /* and then some driver queue managment stuff */
  255 
  256   u_int flags;                  /* qcb type */
  257 #define QCB_FREE       0        /* ready for a new command */
  258 #define QCB_ACTIVE     1        /* waiting to be sent to the controller */
  259 #define QCB_SENT       2        /* waiting for interrupt from the controller */
  260 #define QCB_IMMED      4        /* immediate (non-queued) command */
  261 #define QCB_IMMED_FAIL 8
  262   struct ida_qcb *next;         /* next ida command block of this type */
  263   struct ida_qcb *last;         /* last ida command block of this type */
  264   struct buf *buf;              /* buf associated with this qcb */
  265   physaddr_t paddr;             /* physical address of this struct */
  266   struct ida_qcb *nexthash;     /* next ida command block with same hash value */
  267 };
  268 typedef struct ida_qcb qcb_t;
  269 
  270 
  271 /* IDA driver controller and drive information blocks */
  272 
  273 #define QCB_HASH_SIZE 257 /* some suitable prime number */
  274 #define QCB_HASH(h) ((h) % QCB_HASH_SIZE)
  275 
  276 struct ida_drv {
  277   u_int flags;
  278 #define ID_INIT      0x0001
  279 #define ID_WRITEPROT 0x0002
  280 #define ID_DEV_OPEN  0x0004
  281   u_int ctl_unit;               /* which controller is this drive on */
  282   u_int drv_unit;               /* number of this virtual disk */
  283   struct ida_drv_info drv_info; /* data from the controller */
  284   struct diskslices *slices;    /* new slice code */
  285   struct devstat dk_stats;      /* devstat entry */
  286 };
  287 
  288 struct ida_ctl {
  289   u_int ident;                  /* controller identifier */
  290   u_int flags;
  291   u_int iobase;
  292   u_short inside;               /* number of qcbs in the controller */
  293   u_short max_inside;           /* maximum number simulaneously active */
  294   u_short num_qcbs;             /* number of qcbs allocated */
  295   u_char num_drvs;
  296   u_char irq;
  297   u_char com_status;            /* status of last completed command list */
  298   physaddr_t com_addr;          /* address of last completed command list */
  299   u_short com_offset;           /* offset of last completed command list */
  300   qcb_t *freelist;              /* linked list of free qcbs */
  301   qcb_t *send_next;             /* doubly-linked list of unsent qcbs */
  302   qcb_t *send_last;             /* because we must treat all jobs equally */
  303   qcb_t *hashlist[QCB_HASH_SIZE];
  304 };
  305 
  306 extern struct ida_ctl *idadata[NIDA];
  307 
  308 
  309 /* Useful IDA controller IO macro definitions */
  310 
  311 #define IDA_DISABLE_INTERRUPT(iobase) outb(iobase + R_SYSINT, 0)
  312 #define IDA_ENABLE_INTERRUPT(ctlp) outb(ctlp->iobase + R_SYSINT, 1)
  313 
  314 #define IDA_SET_READY(ctlp) outb(ctlp->iobase + R_EBELL_E, 1)
  315 
  316 #define IDA_DATA_READY(ctlp) ((inb(ctlp->iobase + R_EBELL_I) & 1))
  317 #define IDA_CHAN_CLEAR(ctlp) ((inb(ctlp->iobase + R_EBELL_I) & 2))
  318 
  319 /* enable/disable interrupts on a change of channel clear status (?) */
  320 
  321 #define IDA_ENABLE_CHAN(ctlp) \
  322 outb(ctlp->iobase + R_EBELL_E, inb(ctlp->iobase + R_EBELL_E) | 2)
  323 #define IDA_DISABLE_CHAN(ctlp) \
  324 outb(ctlp->iobase + R_EBELL_E, inb(ctlp->iobase + R_EBELL_E) & ~0x2)
  325 
  326 /* acknowledge the completion of a command */
  327 
  328 #define IDA_ACK_CMD_COM(ctlp) \
  329 (outb(ctlp->iobase + R_EBELL_I, 1), outb(ctlp->iobase + R_LBELL_I, 2))
  330 
  331 /* set submission details for a command list */
  332 
  333 #define IDA_SET_SUB_ADDR(ctlp, addr) outl(ctlp->iobase + R_SUB_ADDR, addr)
  334 #define IDA_SET_SUB_LEN(ctlp, size) outw(ctlp->iobase + R_SUB_LEN, size)
  335 
  336 /* get completion details for a command list */
  337 
  338 #define IDA_GET_COM_ADDR(ctlp) inl(ctlp->iobase + R_COM_ADDR)
  339 #define IDA_GET_COM_OFFSET(ctlp) inw(ctlp->iobase + R_COM_OFF)
  340 #define IDA_GET_COM_STATUS(ctlp) inb(ctlp->iobase + R_COM_STAT)
  341 
  342 
  343 #define IDA_READ_EBELL_I(ctlp) inb(ctlp->iobase + R_EBELL_I)
  344 #define IDA_READ_EBELL_E(ctlp) inb(ctlp->iobase + R_EBELL_E)
  345 #define IDA_READ_LBELL_I(ctlp) inb(ctlp->iobase + R_LBELL_I)
  346 #define IDA_SET_EBELL_I(ctlp, n) outb(ctlp->iobase + R_EBELL_I, n)
  347 #define IDA_SET_LBELL_I(ctlp, n) outb(ctlp->iobase + R_LBELL_I, n)
  348 
  349 #define JOB_SUCCESS 0
  350 #define JOB_FAILURE 1
  351 #define JOB_ABORTED 2
  352 
  353 /* debugging aids */
  354 
  355 #ifdef IDADEBUG
  356 # define IDA_MAXQCBS  (1<<0)
  357 # define IDA_SHOWQCBS (1<<1)
  358 # define IDA_SHOWSUBS (1<<2)
  359 # define IDA_SHOWINTS (1<<3)
  360 # define IDA_SHOWCMDS (1<<4)
  361 # define IDA_SHOWMISC (1<<5)
  362 void ida_print_qcb(qcb_t *qcbp);
  363 void ida_print_active_qcb(int unit);
  364 static int ida_debug = 0;
  365 SYSCTL_INT(_debug, OID_AUTO, ida_debug, CTLFLAG_RW, &ida_debug, 0, "");
  366 #endif
  367 
  368 static int ida_soft_errors = 0;
  369 SYSCTL_INT(_debug, OID_AUTO, ida_soft_errors,
  370            CTLFLAG_RW, &ida_soft_errors, 0, "");
  371 
  372 /* EISA probe and board identification definitions */
  373 
  374 #define MAX_EISA_SLOT 16
  375 #define IDA_EISA_PROD_ID 0x40
  376 
  377 union eisa_id {
  378   u_int value;
  379   struct {
  380     u_int rev:8;
  381     u_int prod:8;
  382     u_int mfr2:5;
  383     u_int mfr1:5;
  384     u_int mfr0:5;
  385   } split;
  386 };
  387 
  388 
  389 /* test the manufacturer ID within an EISA board ID */
  390 
  391 #define EISA_MFR_EQ(ident, mfr) ( \
  392                                  (ident).split.mfr0 + '@' == (mfr)[0] && \
  393                                  (ident).split.mfr1 + '@' == (mfr)[1] && \
  394                                  (ident).split.mfr2 + '@' == (mfr)[2] \
  395                                   )
  396 
  397 /* generates a list of EISA board ID values, suitable for a printf */
  398 
  399 #define EISA_ID_LIST(ident) \
  400 (ident).split.mfr0 + '@', \
  401   (ident).split.mfr1 + '@', \
  402   (ident).split.mfr2 + '@', \
  403   (ident).split.prod, \
  404   (ident).split.rev
  405 
  406 extern void DELAY(int millisecs);
  407 
  408 /* FreeBSD IDA driver forward function definitions */
  409 
  410 static  d_open_t        idopen;
  411 static  d_read_t        idread;
  412 static  d_write_t       idwrite;
  413 static  d_close_t       idclose;
  414 static  d_strategy_t    idstrategy;
  415 static  d_ioctl_t       idioctl;
  416 static  d_dump_t        iddump;
  417 static  d_psize_t       idsize;
  418 
  419 static pci_inthand_t idaintr;
  420 
  421 static const char *ida_pci_probe(pcici_t tag, pcidi_t type);
  422 static void ida_pci_attach(pcici_t config_id, int unit);
  423 
  424 static int ida_eisa_probe __P((struct isa_device *dev));
  425 static int ida_eisa_attach __P((struct isa_device *dev));
  426 static int ida_poll __P((int unit, int wait));
  427 
  428 static void idaminphys __P((struct buf *bp));
  429 static void ida_start __P((int unit));
  430 
  431 static int ida_get_ctl_info(int unit);
  432 static int ida_attach_drives(int unit);
  433 void ida_done(int cntlr, qcb_t *qcbp, int state);
  434 static void ida_queue_buf(int cntlr, struct buf *bp);
  435 static void ida_newqueue(int cntlr);
  436 static qcb_t *ida_dequeue(int cntlr);
  437 static void ida_enqueue(int cntlr, qcb_t *qcbp);
  438 static int ida_submit(int unit, qcb_t *qcbp, int size);
  439 static int ida_submit_wait(int unit, qcb_t *qcbp, int size);
  440 static qcb_t *ida_get_qcb(int unit);
  441 static void ida_free_qcb(int unit, qcb_t *qcbp);
  442 static qcb_t *ida_qcb_phys_kv(struct ida_ctl *ida, physaddr_t ida_qcb_phys);
  443 
  444 static struct cdevsw id_cdevsw;
  445 
  446 struct isa_driver idadriver = {
  447   ida_eisa_probe,
  448   ida_eisa_attach,
  449   "ida"
  450 };
  451 
  452 static u_long ida_pci_count;
  453 
  454 static struct  pci_device ida_pci_driver = {
  455   "ida",
  456   ida_pci_probe,
  457   ida_pci_attach,
  458   &ida_pci_count
  459 };
  460 
  461 DATA_SET (pcidevice_set, ida_pci_driver);
  462 
  463 /* definitions for stealing wd driver's vectors */
  464 
  465 #define ID_BDMAJ 29
  466 #define ID_CDMAJ 109
  467 #define WD_BDMAJ 0
  468 #define WD_CDMAJ 3
  469 
  470 struct isa_driver wdcdriver;
  471 static int stub_probe __P((struct isa_device *dev));
  472 static int stub_attach __P((struct isa_device *dev));
  473 
  474 static struct isa_driver nodriver = {
  475   stub_probe,
  476   stub_attach,
  477   "stub"
  478 };
  479 
  480 /* steal the wdc driver's vectors if we have booted off a wd device */
  481 
  482 static
  483 void
  484 ida_cuckoo_wdc(void)
  485 {
  486   int cuckoo = IDA_CUCKOO_MODE;
  487   int steal = 0;
  488   char *mode;
  489   int major = B_TYPE(bootdev);
  490 
  491   if (cuckoo == IDA_CUCKOO_NEVER) {
  492     mode = "never";
  493   } else if (cuckoo == IDA_CUCKOO_ROOTWD) {
  494     mode = "rootwd";
  495     steal = (major == WD_BDMAJ);
  496   } else if (cuckoo == IDA_CUCKOO_ROOTNOTIDA) {
  497     mode = "notida";
  498     /* check for magic value of 3 rather than ID_BDMAJ as boot code
  499      * pretends we are a wt device (not normally bootable)
  500      */
  501     steal = (major != 3);
  502   } else {
  503     mode = "always";
  504     steal = 1;
  505   }
  506 
  507   printf("ida: wdc vector stealing %s (mode = %s, boot major = %d)\n",
  508          (steal ? "on" : "off"), mode, major);
  509   if (!steal) return;
  510 
  511   /* OK - we have a controller, so steal wd driver's vectors */
  512   wdcdriver = nodriver;
  513   bdevsw[WD_BDMAJ]->d_open     = cdevsw[WD_CDMAJ]->d_open     = idopen;
  514   bdevsw[WD_BDMAJ]->d_close    = cdevsw[WD_CDMAJ]->d_close    = idclose;
  515   bdevsw[WD_BDMAJ]->d_read     = cdevsw[WD_CDMAJ]->d_read     = idread;
  516   bdevsw[WD_BDMAJ]->d_write    = cdevsw[WD_CDMAJ]->d_write    = idwrite;
  517   bdevsw[WD_BDMAJ]->d_strategy = cdevsw[WD_CDMAJ]->d_strategy = idstrategy;
  518   bdevsw[WD_BDMAJ]->d_ioctl    = cdevsw[WD_CDMAJ]->d_ioctl    = idioctl;
  519   bdevsw[WD_BDMAJ]->d_dump     = iddump;
  520   bdevsw[WD_BDMAJ]->d_psize    = idsize;
  521   return;
  522 }
  523 
  524 static struct ida_ctl *idadata[NIDA];   /* controller structures */
  525 static struct ida_drv *id_drive[NID];   /* table of drives */
  526 static int id_unit = 0;                 /* number of drives found */
  527 
  528 /* general purpose data buffer for 'special' IDA driver commands */
  529 
  530 union ida_buf {
  531   char pad[512];
  532   struct ida_ctl_info ctl;
  533   struct ida_drv_info drv;
  534 } ida_buf;
  535 
  536 static int
  537 stub_probe(struct isa_device *dev)
  538 {
  539   return 0;
  540 }
  541 
  542 static int
  543 stub_attach(struct isa_device *dev)
  544 {
  545   return 0;
  546 }
  547 
  548 const char *
  549 ida_pci_probe(pcici_t tag, pcidi_t type)
  550 {
  551   switch (type) {
  552   case PCI_DEVICE_ID_COMPAQ_SMART2P:
  553     return "Compaq SMART-2/P array controller";
  554     break;
  555   default:
  556     break;
  557   }
  558   return NULL;
  559 }
  560 
  561 static void
  562 ida_pci_attach(pcici_t config_id, int unit)
  563 {
  564   ida_pci_reg_t *reg;
  565   struct ida_ctl *ctlp;
  566   u_long id;
  567   vm_offset_t paddr, vaddr;
  568 
  569   id = pci_conf_read(config_id, PCI_ID_REG);
  570   switch (id) {
  571   case PCI_DEVICE_ID_COMPAQ_SMART2P:
  572     break;
  573   default:
  574     break;
  575   }
  576 
  577   if (!pci_map_mem(config_id, 0x14, &vaddr, &paddr)) {
  578     printf("ida: map failed.\n");
  579     return;
  580   }
  581 
  582   /* allocate and initialise a storage area for this controller */
  583   if (idadata[unit]) {
  584     printf("ida%d: controller structure already allocated\n", unit);
  585     return;
  586   }
  587   if ((ctlp = malloc(sizeof(struct ida_ctl), M_TEMP, M_NOWAIT)) == NULL) {
  588     printf("ida%d: unable to allocate controller structure\n", unit);
  589     return;
  590   }
  591 
  592   idadata[unit] = ctlp;
  593   bzero(ctlp, sizeof(struct ida_ctl));
  594   ctlp->ident = id;
  595   ctlp->iobase = vaddr;
  596 
  597   /* Install the interrupt handler. */
  598   if (!pci_map_int (config_id, idaintr, (void *)unit, &bio_imask)) {
  599     printf ("ida%d: failed to assign an interrupt handler\n", unit);
  600     free((caddr_t)ctlp, M_DEVBUF);
  601     idadata[unit] = 0;
  602     return;
  603   }
  604 
  605   if (!(ida_get_ctl_info(unit) && ida_attach_drives(unit))) {
  606     return;
  607   }
  608 
  609   reg = (ida_pci_reg_t *) vaddr;
  610   reg->interrupt = IDA_PCI_ENABLE_INTS;
  611   ida_cuckoo_wdc();
  612   return;
  613 }
  614 
  615 int
  616 ida_eisa_probe(struct isa_device *dev)
  617 {
  618   static u_int ida_used = 0;
  619   u_int slot;
  620   u_int port;
  621   u_char intdef;
  622   u_char irq;
  623   int unit = dev->id_unit;
  624   union eisa_id ident;
  625   struct ida_ctl *ctlp;
  626 
  627   if (dev->id_iobase) {
  628     /* check out the configured iobase if given one */
  629     slot = dev->id_iobase / 0x1000;
  630     if (slot == 0 || slot > MAX_EISA_SLOT) {
  631       printf("ida: port address (0x%x) out of range\n", dev->id_iobase);
  632       return 0;
  633     }
  634   } else {
  635     /* otherwise, search from the beginning for an unused slot to check out */
  636     slot = 1;
  637   }
  638 
  639   while (1) {
  640     while (ida_used & (1 << slot)) {
  641       if (slot++ == MAX_EISA_SLOT) return 0;
  642     }
  643 
  644     ida_used |= (1 << slot);
  645     port = slot * 0x1000;
  646 
  647     /* read the EISA identification bytes */
  648     ident.value = inb(port + R_ID0);
  649     ident.value <<= 8;
  650     ident.value |= inb(port + R_ID1);
  651     ident.value <<= 8;
  652     ident.value |= inb(port + R_ID2);
  653     ident.value <<= 8;
  654     ident.value |= inb(port + R_ID3);
  655   
  656     /* check that the card is the right type ? */
  657     if (EISA_MFR_EQ(ident, "CPQ") && ident.split.prod == IDA_EISA_PROD_ID) {
  658       break;
  659     }
  660 
  661     /* if we were config'ed with an iobase, then don't probe any more slots */
  662     if (dev->id_iobase) return 0;
  663   }
  664 
  665   /* disable interrupts and find out what interrupt this controller uses */
  666   IDA_DISABLE_INTERRUPT(port);
  667 
  668   intdef = inb(port + R_INTDEF);
  669   switch (intdef & IDA_IRQ_MASK) {
  670   case IDA_IRQ_10:
  671     irq = 10;
  672     break;
  673 
  674   case IDA_IRQ_11:
  675     irq = 11;
  676     break;
  677 
  678   case IDA_IRQ_14:
  679     irq = 14;
  680     break;
  681 
  682   case IDA_IRQ_15:
  683     irq = 15;
  684     break;
  685 
  686   default:
  687     printf("ida: slot %d bogus interrupt setting (0x%02x)\n", slot, intdef);
  688     return 0;
  689   }
  690   dev->id_irq = (1 << irq);
  691   dev->id_drq = -1;
  692 
  693   /* allocate and initialise a storage area for this controller */
  694   if (idadata[unit]) {
  695     printf("ida%d: controller structure already allocated\n", unit);
  696     return 0;
  697   }
  698   if ((ctlp = malloc(sizeof(struct ida_ctl), M_TEMP, M_NOWAIT)) == NULL) {
  699     printf("ida%d: unable to allocate controller structure\n", unit);
  700     return 0;
  701   }
  702   idadata[unit] = ctlp;
  703 
  704   bzero(ctlp, sizeof(struct ida_ctl));
  705   ctlp->iobase = dev->id_iobase = port;
  706   ctlp->ident = ident.value;
  707   ctlp->irq = irq;
  708 
  709   if (ida_get_ctl_info(unit) == 0) {
  710     return 0;
  711   }
  712 
  713   /* return range of io ports used */
  714   return 0x1000;
  715 }
  716 
  717 int
  718 ida_get_ctl_info(int unit)
  719 {
  720   struct ida_ctl *ctlp = idadata[unit];
  721   qcb_t qcb;
  722   qcb_t *qcbp = &qcb;
  723 
  724   ida_newqueue(unit);
  725   /* controller capacity statistics */
  726   ctlp->inside = 0;
  727   ctlp->max_inside = 0;
  728     
  729   /* ask the controller to tell us about itself with an IDA_GET_CTL_INFO */
  730   bzero(qcbp, sizeof(qcb_t));
  731   qcbp->paddr = vtophys(qcbp);
  732   if (PCI_CONTROLLER(ctlp)) {
  733     qcbp->hdr.priority = 0x00;
  734     qcbp->hdr.flags = 0x24;
  735   } else {
  736     qcbp->hdr.priority = IDA_DEF_PRIORITY;
  737     qcbp->hdr.flags = 0x12;
  738   }
  739   qcbp->req.command = IDA_GET_CTL_INFO;
  740   qcbp->req.bcount = 1;
  741   qcbp->req.sgcount = 1;
  742   qcbp->sglist[0].len = sizeof(ida_buf);
  743   qcbp->sglist[0].addr = vtophys(&ida_buf);
  744 
  745   if (ida_submit_wait(unit, qcbp, sizeof(struct ida_qcb))) {
  746     printf("ida%d: idasubmit failed on IDA_GET_CTL_INFO\n", unit);
  747     return 0;
  748   }
  749 
  750   if (!PCI_CONTROLLER(ctlp)) {
  751     if (ctlp->com_status != IDA_COMPL_OK) {
  752       printf("ida%d: bad status 0x%02x from IDA_GET_CTL_INFO\n",
  753              unit, ctlp->com_status);
  754       return 0;
  755     }
  756   }
  757 
  758   /* got the information at last, print it and note the number of drives */
  759   printf("ida%d: drvs=%d firm_rev=%c%c%c%c\n", unit,
  760          u_unpack(ida_buf.ctl.num_drvs), ida_buf.ctl.firm_rev[0],
  761          ida_buf.ctl.firm_rev[1], ida_buf.ctl.firm_rev[2],
  762          ida_buf.ctl.firm_rev[3]);
  763   ctlp->num_drvs = u_unpack(ida_buf.ctl.num_drvs);
  764 
  765   return 1;
  766 }
  767 
  768 int
  769 ida_attach_drives(int cntlr)
  770 {
  771   struct ida_ctl *ctlp = idadata[cntlr];
  772   qcb_t qcb;
  773   qcb_t *qcbp = &qcb;
  774   struct ida_drv *drv;
  775   int drive;
  776   int unit;
  777 
  778   /* prepare to interrogate the drives */
  779   bzero(qcbp, sizeof(qcb_t));
  780   qcbp->req.command = IDA_GET_DRV_INFO;
  781   qcbp->paddr = vtophys(qcbp);
  782   if (PCI_CONTROLLER(ctlp)) {
  783     qcbp->hdr.priority = 0x00;
  784     qcbp->hdr.flags = 0x24;
  785   } else {
  786     qcbp->hdr.priority = IDA_DEF_PRIORITY;
  787     qcbp->hdr.flags = 0x12;
  788   }
  789   qcbp->req.bcount = 1;
  790   qcbp->req.sgcount = 1;
  791   qcbp->sglist[0].len = sizeof(ida_buf);
  792   qcbp->sglist[0].addr = vtophys(&ida_buf);
  793 
  794   for (drive = 0 ; drive < ctlp->num_drvs ; drive++) {
  795     qcbp->hdr.drive = drive;
  796 
  797     if (ida_submit_wait(cntlr, qcbp, sizeof(struct ida_qcb))) {
  798       printf("ida%d: ida_submit_wait failed on IDA_GET_DRV_INFO\n", cntlr);
  799       return 0;
  800     }
  801 
  802     if (!PCI_CONTROLLER(ctlp)) {
  803       if (ctlp->com_status != IDA_COMPL_OK) {
  804         printf("ida%d: bad status 0x%02x from IDA_GET_DRV_INFO\n",
  805                cntlr, ctlp->com_status);
  806         return 0;
  807       }
  808     }
  809 
  810     if ((drv = malloc(sizeof(struct ida_drv), M_TEMP, M_NOWAIT)) == NULL) {
  811       printf("ida%d: unable to allocate drive structure\n", cntlr);
  812       return 0;
  813     }
  814 
  815     bzero(drv, sizeof(struct ida_drv));
  816     drv->ctl_unit = cntlr;
  817     drv->drv_unit = drive;
  818     drv->drv_info = ida_buf.drv;
  819     drv->flags |= ID_INIT;
  820 
  821     unit = id_unit;
  822     id_unit++; /* XXX unsure if this is the right way to do things */
  823     id_drive[unit] = drv;
  824 
  825     printf("ida%d: unit %d (id%d): <%s>\n",
  826            cntlr, drive, unit, "Compaq Logical Drive");
  827     printf("id%d: %luMB (%lu total sec), ",
  828            unit,
  829            (u_long)(u_unpack(drv->drv_info.secperunit) / 2048)
  830            * (u_unpack(drv->drv_info.secsize) / 512),
  831            (u_long)u_unpack(drv->drv_info.secperunit));
  832     printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n",
  833            (u_long)u_unpack(drv->drv_info.ncylinders),
  834            (u_long)u_unpack(drv->drv_info.ntracks),
  835            (u_long)u_unpack(drv->drv_info.nsectors),
  836            (u_long)u_unpack(drv->drv_info.secsize));           
  837     
  838     /*
  839      * Export the drive to the devstat interface.
  840      */
  841     devstat_add_entry(&drv->dk_stats, "id", 
  842                       unit, (u_int32_t)drv->drv_info.secsize,
  843                       DEVSTAT_NO_ORDERED_TAGS,
  844                       DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
  845                       DEVSTAT_PRIORITY_DA);
  846 
  847 #ifdef IDADEBUG
  848     if (ida_debug & IDA_SHOWMISC) {
  849       printf("ida%d: drive %d secsize=%d secperunit=%d ncylinders=%d ntracks=%d\n",
  850              unit,
  851              drive,
  852              u_unpack(ida_buf.drv.secsize),
  853              u_unpack(ida_buf.drv.secperunit),
  854              u_unpack(ida_buf.drv.ncylinders),
  855              u_unpack(ida_buf.drv.ntracks));
  856       printf("         signature=0x%02x psectors=%d wprecomp=%d max_acc=%d control=0x%02x\n",
  857              u_unpack(ida_buf.drv.signature),
  858              u_unpack(ida_buf.drv.psectors),
  859              u_unpack(ida_buf.drv.wprecomp),
  860              u_unpack(ida_buf.drv.max_acc),
  861              u_unpack(ida_buf.drv.control));
  862       printf("         pcylinders=%d ptracks=%d landing_zone=%d nsectors=%d checksum=0x%02x\n",
  863              u_unpack(ida_buf.drv.pcylinders),
  864              u_unpack(ida_buf.drv.ptracks),
  865              u_unpack(ida_buf.drv.landing_zone),
  866              u_unpack(ida_buf.drv.nsectors),
  867              u_unpack(ida_buf.drv.checksum));
  868     }
  869 #endif
  870   }
  871 
  872   return 1;
  873 }
  874 
  875 /* Attach all the sub-devices we can find. */
  876 int
  877 ida_eisa_attach(struct isa_device *dev)
  878 {
  879   int cntlr = dev->id_unit;
  880   struct ida_ctl *ctlp = idadata[cntlr];
  881 
  882   if (ida_attach_drives(cntlr)) {
  883     IDA_ENABLE_INTERRUPT(ctlp);
  884     IDA_SET_READY(ctlp);
  885     ida_cuckoo_wdc();
  886     return 1;
  887   } else {
  888     return 0;
  889   }
  890 }
  891 
  892 /*
  893  * Initialize a drive.
  894  */
  895 int
  896 idopen(dev_t dev, int flags, int fmt, struct proc *p)
  897 {
  898   struct ida_drv *drv;
  899   int part = dkpart(dev);
  900   int unit = dkunit(dev);
  901   struct disklabel label;
  902   int err;
  903 
  904   if (unit >= NID || part >= MAXPARTITIONS) /* bounds check */
  905     return(ENXIO);
  906 
  907   drv = id_drive[unit];
  908   if (!drv || !(drv->flags & ID_INIT)) /* drive not initialised */
  909     return(ENXIO);
  910 
  911   drv->flags |= ID_DEV_OPEN;
  912 
  913   /* knock up a label for the whole disk. */
  914   bzero(&label, sizeof label);
  915   label.d_secsize = u_unpack(drv->drv_info.secsize);
  916   label.d_nsectors = u_unpack(drv->drv_info.nsectors);
  917   label.d_ntracks = u_unpack(drv->drv_info.ntracks);
  918   label.d_ncylinders = u_unpack(drv->drv_info.ncylinders);
  919   label.d_secpercyl =
  920     u_unpack(drv->drv_info.ntracks) * u_unpack(drv->drv_info.nsectors);
  921   if (label.d_secpercyl == 0)
  922     label.d_secpercyl = 100; /* prevent accidental division by zero */
  923   label.d_secperunit = u_unpack(drv->drv_info.secperunit);
  924 
  925   /* Initialize slice tables. */
  926   if ((err = dsopen("id", dev, fmt, 0, &drv->slices, &label, idstrategy,
  927                     (ds_setgeom_t *)NULL, &id_cdevsw)) == NULL) {
  928     return 0;
  929   }
  930 
  931   if (!dsisopen(drv->slices)) {
  932     drv->flags &= ~ID_DEV_OPEN;
  933   }
  934   return err;
  935 }
  936 
  937 /* ARGSUSED */
  938 int
  939 idclose(dev_t dev, int flags, int fmt, struct proc *p)
  940 {
  941   struct ida_drv *drv;
  942   int   part = dkpart(dev);
  943   int unit = dkunit(dev);
  944 
  945   if (unit >= NID || part >= MAXPARTITIONS) /* bounds check */
  946     return(ENXIO);
  947 
  948   drv = id_drive[unit];
  949   dsclose(dev, fmt, drv->slices);
  950   if (!dsisopen(drv->slices)) {
  951     drv->flags &= ~ID_DEV_OPEN;
  952   }
  953   return 0;
  954 }
  955 
  956 
  957 
  958 int
  959 idioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  960 {
  961   struct ida_drv *drv;
  962   int part = dkpart(dev);
  963   int unit = dkunit(dev);
  964   int err;
  965 
  966   if (unit >= NID || part >= MAXPARTITIONS ||
  967       !(drv = id_drive[unit]) || !(drv->flags & ID_INIT)) /* sanity check */
  968     return(ENXIO);
  969 
  970   err = dsioctl("id", dev, cmd, addr, flag, &drv->slices,
  971                 idstrategy, (ds_setgeom_t *)NULL);
  972 
  973   if (err != -1)
  974     return (err);
  975 
  976   if (dkpart(dev) != RAW_PART)
  977     return (ENOTTY);
  978 
  979   return (0);
  980 }
  981 static int
  982 idread(dev_t dev, struct uio *uio, int ioflag)
  983 {
  984   return (physio(idstrategy, NULL, dev, 1, minphys, uio));
  985 }
  986 
  987 static int
  988 idwrite(dev_t dev, struct uio *uio, int ioflag)
  989 {
  990   return (physio(idstrategy, NULL, dev, 0, minphys, uio));
  991 }
  992 
  993 
  994 /* Read/write routine for a buffer.  Finds the proper unit, range checks
  995  * arguments, and schedules the transfer.  Does not wait for the transfer
  996  * to complete.  Multi-page transfers are supported.  All I/O requests must
  997  * be a multiple of a sector in length.
  998  */
  999 void
 1000 idstrategy(struct buf *bp)
 1001 {
 1002   int unit = dkunit(bp->b_dev);
 1003   struct ida_drv *drv;
 1004   int opri;
 1005 
 1006   if (unit >= NID) {
 1007     printf("ida: unit out of range\n");
 1008     bp->b_error = EINVAL;
 1009     goto bad;
 1010   }
 1011 
 1012   if (!(drv = id_drive[unit]) || !(drv->flags & ID_INIT)) {
 1013     printf("id%d: drive not initialised\n", unit);
 1014     bp->b_error = EINVAL;
 1015     goto bad;
 1016   }
 1017 
 1018   if (bp->b_blkno < 0) {
 1019     printf("id%d: negative block requested\n", unit);
 1020     bp->b_error = EINVAL;
 1021     goto bad;
 1022   }
 1023 
 1024   if (bp->b_bcount % DEV_BSIZE != 0) { /* bounds check */
 1025     printf("id%d: count (%lu) not a multiple of a block\n",
 1026            unit, bp->b_bcount);
 1027     bp->b_error = EINVAL;
 1028     goto bad;
 1029   }
 1030 
 1031   idaminphys(bp); /* adjust the transfer size */
 1032 
 1033   /* "soft" write protect check */
 1034   if ((drv->flags & ID_WRITEPROT) && (bp->b_flags & B_READ) == 0) {
 1035     bp->b_error = EROFS;
 1036     goto bad;
 1037   }
 1038 
 1039   /* If it's a null transfer, return immediately */
 1040   if (bp->b_bcount == 0) {
 1041     goto done;
 1042   }
 1043 
 1044   if (dscheck(bp, drv->slices) <= 0) {
 1045     goto done;
 1046   }
 1047    
 1048   opri = splbio();
 1049   ida_queue_buf(unit, bp);
 1050   devstat_start_transaction(&drv->dk_stats);
 1051   ida_start(drv->ctl_unit); /* hit the appropriate controller */
 1052   splx(opri);
 1053 
 1054   return /**/;
 1055 
 1056 bad:
 1057   bp->b_flags |= B_ERROR;
 1058  
 1059 done:
 1060   /* correctly set the buf to indicate a completed xfer */
 1061   bp->b_resid = bp->b_bcount;
 1062   biodone(bp);
 1063   return /**/;
 1064 }
 1065 
 1066 
 1067 void
 1068 idaminphys(bp)
 1069 struct buf *bp;
 1070 {
 1071   /* assumes each page requires an sgb entry */
 1072   int max = (IDA_MAX_SGLEN - 1) * PAGESIZ;
 1073   if (bp->b_bcount > max) {
 1074     bp->b_bcount = max;
 1075   }
 1076 }
 1077 
 1078 
 1079 /* Get a free qcb.
 1080  * If there are none, see if we can allocate a new one.
 1081  * If so, put it in the hash table too,
 1082  * otherwise either return an error or sleep.
 1083  */
 1084 static qcb_t *
 1085 ida_get_qcb(int unit)
 1086 {
 1087   struct ida_ctl *ida = idadata[unit];
 1088   unsigned opri = 0;
 1089   qcb_t *qcbp;
 1090   int hashnum;
 1091     
 1092   opri = splbio();
 1093 
 1094   /* if the freelist is empty - create a qcb until limit is reached */
 1095   while (!(qcbp = ida->freelist)) {
 1096     if (ida->num_qcbs < IDA_QCB_MAX) {
 1097       qcbp = (qcb_t *)malloc(sizeof(qcb_t), M_TEMP, M_NOWAIT);
 1098       if (qcbp) {
 1099         bzero(qcbp, sizeof(qcb_t));
 1100         ida->num_qcbs++;
 1101         qcbp->flags = QCB_ACTIVE;
 1102 #ifdef IDADEBUG
 1103         if (ida_debug & IDA_SHOWQCBS)
 1104           printf("ida_get_qcb%d: qcb %d created\n",
 1105                  unit, ida->num_qcbs);
 1106 #endif
 1107         /* Put in the phystokv hash table. */
 1108         /* Never gets taken out. */
 1109         qcbp->paddr = vtophys(qcbp);
 1110         hashnum = QCB_HASH(qcbp->paddr);
 1111         qcbp->nexthash = ida->hashlist[hashnum];
 1112         ida->hashlist[hashnum] = qcbp;
 1113       } else {
 1114         printf("ida%d: Can't malloc QCB\n", unit);
 1115       } goto gottit;
 1116     } else {
 1117       /* reached maximum allocation of qcbs - sleep until one is freed */
 1118       tsleep((caddr_t)&ida->freelist, PRIBIO, "idaqcb", 0);
 1119     }
 1120   } if (qcbp) {
 1121     /* qet the qcb from from the (non-empty) free list */
 1122     ida->freelist = qcbp->next;
 1123     qcbp->flags = QCB_ACTIVE;
 1124   }
 1125 gottit:
 1126   splx(opri);
 1127 
 1128 #ifdef IDADEBUG
 1129   if (ida_debug & IDA_SHOWQCBS)
 1130     printf("ida_get_qcb%d: returns 0x%x\n", unit, qcbp);
 1131 #endif
 1132 
 1133   return (qcbp);
 1134 }
 1135 
 1136 
 1137 /* Return a qcb to the free list */
 1138 static void
 1139 ida_free_qcb(int unit, qcb_t *qcbp)
 1140 {
 1141   unsigned int opri = 0;
 1142   struct ida_ctl *ida = idadata[unit];
 1143 
 1144 #ifdef IDADEBUG
 1145   if (ida_debug & IDA_SHOWQCBS)
 1146     printf("ida_free_qcb%d: freeing 0x%x\n", unit, qcbp);
 1147 #endif
 1148 
 1149   opri = splbio();
 1150 
 1151   qcbp->next = ida->freelist;
 1152   ida->freelist = qcbp;
 1153   qcbp->flags = QCB_FREE;
 1154 
 1155   /* if the free list was empty, wakeup anyone sleeping */
 1156 
 1157   if (!qcbp->next) {
 1158 #ifdef IDADEBUG
 1159     if (ida_debug & IDA_SHOWQCBS)
 1160       printf("ida_free_qcb%d: about to wakeup 0x%x queue\n",
 1161              unit, &ida->freelist);
 1162 #endif
 1163     wakeup((caddr_t)&ida->freelist);
 1164   }
 1165 
 1166   splx(opri);
 1167 }
 1168 
 1169 /* Find the ida_qcb having a given physical address */
 1170 qcb_t *
 1171 ida_qcb_phys_kv(ida, ida_qcb_phys)
 1172 struct ida_ctl *ida;
 1173 physaddr_t ida_qcb_phys;
 1174 {
 1175   int hash = QCB_HASH(ida_qcb_phys);
 1176   qcb_t *qcbp = ida->hashlist[hash];
 1177     
 1178   while (qcbp) {
 1179     if (qcbp->paddr == ida_qcb_phys)
 1180       break;
 1181     qcbp = qcbp->nexthash;
 1182   }
 1183 
 1184 #ifdef IDADEBUG
 1185   if (ida_debug & IDA_SHOWQCBS)
 1186     printf("ida?: ida_qcb_phys_kv(0x%x) = 0x%x\n", ida_qcb_phys, qcbp);
 1187 #endif
 1188 
 1189   return qcbp;
 1190 }
 1191 
 1192 void
 1193 ida_queue_buf(int unit, struct buf *bp)
 1194 {
 1195   struct ida_drv *drv = id_drive[unit];
 1196   int cntlr = drv->ctl_unit;
 1197   qcb_t *qcbp = ida_get_qcb(cntlr); /* may cause us to wait */
 1198   struct ida_ctl *ida = idadata[cntlr];
 1199   unsigned int datalen = bp->b_bcount;
 1200   int thiskv = (int)bp->b_data;
 1201   physaddr_t thisphys = vtophys(thiskv);
 1202   int nsgb = 0; /* number of scatter/gather blocks used */
 1203   struct ida_sgb *sg = &(qcbp->sglist[0]);
 1204 
 1205   /* fill in the qcb command header */
 1206 
 1207   if (PCI_CONTROLLER(ida)) {
 1208     qcbp->hdr.priority = 0x00;
 1209     qcbp->hdr.flags =
 1210       (sizeof(struct ida_req) + sizeof(struct ida_sgb) * IDA_MAX_SGLEN) >> 2;
 1211   } else {
 1212     qcbp->hdr.priority = IDA_DEF_PRIORITY;
 1213     qcbp->hdr.flags = 0x10;
 1214   }
 1215   qcbp->hdr.drive = drv->drv_unit; /* logical drive number */
 1216   qcbp->buf = bp; /* the buf this command came from */
 1217 
 1218   /* set up the scatter-gather list in the qcb */
 1219 
 1220   while ((datalen) && (nsgb < IDA_MAX_SGLEN)) {
 1221     int bytes_this_seg = 0;
 1222     physaddr_t nextphys;
 1223         
 1224     /* put in the base address */
 1225     sg->addr = thisphys;
 1226 
 1227     /* do it at least once */
 1228     nextphys = thisphys;
 1229     while ((datalen) && (thisphys == nextphys)) {
 1230       int bytes_this_page;
 1231 
 1232       /* This page is contiguous (physically) with the the last, */
 1233       /* just extend the length */
 1234             
 1235       /* how far to the end of the page ... */
 1236       nextphys = (thisphys & (~(PAGESIZ - 1))) + PAGESIZ;
 1237       bytes_this_page = nextphys - thisphys;
 1238       /* ... or to the end of the data */
 1239       bytes_this_page = min(bytes_this_page, datalen);
 1240       bytes_this_seg += bytes_this_page;
 1241       datalen -= bytes_this_page;
 1242 
 1243       /* get ready for the next page */
 1244       thiskv = (thiskv & (~(PAGESIZ - 1))) + PAGESIZ;
 1245       if (datalen)
 1246         thisphys = vtophys(thiskv);
 1247     }
 1248 
 1249     /* next page isn't contiguous, finish the seg */
 1250     sg->len = bytes_this_seg;
 1251     sg++;
 1252     nsgb++;
 1253   }
 1254 
 1255   if (datalen) { /* still data => command block too small */
 1256     printf("ida_queue_buf%d: more than %d scatter/gather blocks needed\n",
 1257            cntlr, IDA_MAX_SGLEN);
 1258     bp->b_error = EIO;
 1259     bp->b_flags |= B_ERROR;
 1260     biodone(bp);
 1261     return;
 1262   }
 1263 
 1264   /* fill-in the I/O request block */
 1265 
 1266   qcbp->req.error = 0;
 1267   qcbp->req.next = 0;
 1268   qcbp->req.blkno = bp->b_pblkno;
 1269   qcbp->req.bcount = bp->b_bcount >> 9;
 1270   qcbp->req.sgcount = nsgb;
 1271   qcbp->req.command = (bp->b_flags & B_READ ? IDA_READ_DATA : IDA_WRITE_DATA);
 1272 
 1273 #ifdef IDADEBUG
 1274   if (ida_debug & IDA_SHOWQCBS) {
 1275     printf("ida_rw%d: queuing:\n", cntlr);
 1276     ida_print_qcb(qcbp);
 1277   }
 1278 #endif
 1279 
 1280   /* queue for submission to the controller */
 1281   ida_enqueue(cntlr, qcbp);
 1282 }
 1283 
 1284 
 1285 void
 1286 ida_start(int cntlr)
 1287 {
 1288   struct ida_ctl *ida = idadata[cntlr];
 1289   qcb_t *qcbp;
 1290   int count = 0;
 1291   int opri = splbio();
 1292 
 1293   if (!ida->send_next) { /* check there is a job in the queue */
 1294     splx(opri);
 1295     return;
 1296   }
 1297 
 1298   if (PCI_CONTROLLER(ida)) {
 1299     ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
 1300     u_int fifo = reg->initiate_fifo;
 1301     if (fifo == 1) {
 1302       splx(opri);
 1303       return;                        /* not sent - must try again later */
 1304     }
 1305 
 1306     /* submit upto 16 jobs at once into the initiate fifo */
 1307     while (count < 16 && (fifo = reg->initiate_fifo) != 1
 1308            && (qcbp = ida_dequeue(cntlr))) {
 1309       reg->initiate_fifo = qcbp->paddr;
 1310       qcbp->flags = QCB_SENT;
 1311       ida->inside++;
 1312       count++;
 1313     }
 1314   } else {
 1315 
 1316     if (!IDA_CHAN_CLEAR(ida)) {
 1317       IDA_ENABLE_CHAN(ida);
 1318       splx(opri);
 1319       return;
 1320     }
 1321 
 1322     qcbp = ida_dequeue(cntlr);
 1323 
 1324 #ifdef IDADEBUG
 1325     if (ida_debug & IDA_SHOWQCBS)
 1326       printf("ida%d: ida_start: sending 0x%x\n", cntlr, qcbp);
 1327 #endif
 1328 
 1329     IDA_SET_EBELL_I(ida, 2);
 1330     IDA_SET_SUB_ADDR(ida, qcbp->paddr); /* physical address of this qcb */
 1331     IDA_SET_SUB_LEN(ida, sizeof(qcb_t));
 1332     IDA_SET_LBELL_I(ida, 1);    
 1333 
 1334     qcbp->flags = QCB_SENT;
 1335     ida->inside++;
 1336     count++;
 1337   }
 1338 
 1339   if (ida->inside > ida->max_inside) {
 1340     ida->max_inside = ida->inside; /* new maximum */
 1341     splx(opri);
 1342 
 1343 #ifdef IDADEBUG
 1344     if (ida_debug & IDA_MAXQCBS)
 1345       printf("ida%d: qcbs %d/%d\n", cntlr, ida->inside, ida->num_qcbs);
 1346 #endif
 1347   } else {
 1348     splx(opri);
 1349   }
 1350 
 1351 #ifdef IDADEBUG
 1352   if ((ida_debug & IDA_SHOWSUBS) && count > 1)
 1353     printf("ida%d: %d jobs submitted (queue %s).\n",
 1354            cntlr, count, ida->send_next ? "not emptied" : "emptied");
 1355 #endif
 1356 }
 1357 
 1358 void
 1359 ida_newqueue(int cntlr)
 1360 {
 1361   struct ida_ctl *ida = idadata[cntlr];
 1362   ida->send_next = 0;
 1363   ida->send_last = 0;
 1364 }
 1365 
 1366 qcb_t *
 1367 ida_dequeue(int cntlr)
 1368 {
 1369   struct ida_ctl *ida = idadata[cntlr];
 1370   qcb_t *qcbp = ida->send_next; /* who is next? */
 1371 
 1372   if (qcbp) {   /* queue is not empty */
 1373     qcb_t* nextp = qcbp->next;
 1374 
 1375     if (nextp) { /* more than one element in the queue */
 1376       nextp->last = 0; /* we are the first */
 1377       ida->send_next = nextp; /* hence first to go */
 1378     } else { /* exactly one element in the queue */
 1379       ida->send_last = ida->send_next = 0;
 1380     }
 1381   }
 1382 
 1383   return qcbp;
 1384 }
 1385 
 1386 static void
 1387 ida_enqueue(int cntlr, qcb_t *qcbp)
 1388 {
 1389   struct ida_ctl *ida = idadata[cntlr];
 1390   qcb_t *lastp = ida->send_last; /* who is last? */
 1391   int opri = splbio();
 1392 
 1393   if (lastp) { /* if the queue is not empty */
 1394     lastp->next = qcbp; /* then we go after the last */
 1395   } else { /* if the queue was empty */
 1396     ida->send_next = qcbp; /* then we go next */
 1397   }
 1398 
 1399   qcbp->last = lastp; /* we follow the last */
 1400   qcbp->next = 0;       /* and nothing follows us */
 1401 
 1402   ida->send_last = qcbp; /* we go last */
 1403   splx(opri);
 1404 }
 1405 
 1406 void
 1407 idaintr(void *arg)
 1408 {
 1409   int cntlr = (int)arg;
 1410   qcb_t *qcbp;
 1411   struct ida_ctl *ida = idadata[cntlr];
 1412   u_char status;
 1413   physaddr_t paddr, paddr1;     /* physical address of the qcb */
 1414   int offset;                   /* qcb offset */
 1415   u_char cstat;                 /* job status */
 1416 
 1417   if (PCI_CONTROLLER(ida)) { /*pci:*/
 1418     ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
 1419     int status = reg->status;
 1420 #ifdef IDADEBUG
 1421     if (ida_debug & IDA_SHOWINTS)
 1422       printf("ida%d: idaintr: status=%x (before complete)\n"
 1423              , cntlr, status);
 1424 #endif
 1425     while (status & IDA_PCI_PENDING) {
 1426       paddr1 = reg->complete_fifo;
 1427       paddr = paddr1 & ~3;
 1428       qcbp = ida_qcb_phys_kv(ida, paddr);
 1429 #ifdef IDADEBUG
 1430       if (ida_debug & IDA_SHOWQCBS) {
 1431         printf("ida%d: idaintr: qcb(%x) completed\n", cntlr, qcbp);
 1432         ida_print_qcb(qcbp);
 1433       }
 1434 #endif
 1435       if (qcbp) {
 1436         if (qcbp->req.error & 3) ida_soft_errors++;
 1437         ida_done(cntlr, qcbp, (qcbp->req.error>>2) ? JOB_FAILURE : JOB_SUCCESS);
 1438       } else {
 1439         printf("ida%d: idaintr: completion (%x) ignored\n", cntlr, paddr1);
 1440       }
 1441       status = reg->status;
 1442     }
 1443 #ifdef IDADEBUG
 1444     if (ida_debug & IDA_SHOWINTS)
 1445       printf("ida%d: idaintr: status=%x (before initiate)\n"
 1446              , cntlr, status);
 1447 #endif
 1448     if (status & IDA_PCI_READY) {
 1449       ida_start(cntlr);
 1450     }
 1451   } else { 
 1452     while(1) {
 1453       status = IDA_READ_EBELL_I(ida) & IDA_READ_EBELL_E(ida);
 1454 
 1455 #ifdef IDADEBUG
 1456       if (ida_debug & IDA_SHOWINTS)
 1457         printf("ida%d: idaintr: status = 0x%x\n", cntlr, status);
 1458 #endif
 1459 
 1460       if ((status & (BMIC_DATA_READY | BMIC_CHAN_CLEAR)) == 0) break;
 1461 
 1462       if (status & BMIC_DATA_READY) { /* data ready */
 1463         int job_status;
 1464 
 1465         if (IDA_READ_LBELL_I(ida) & JOB_ABORTED) {
 1466           printf("ida%d: idaintr: status:%x local channel should be busy! ",
 1467                  cntlr, status);
 1468         }
 1469 
 1470         paddr = IDA_GET_COM_ADDR(ida);
 1471         offset = IDA_GET_COM_OFFSET(ida);
 1472         cstat = IDA_GET_COM_STATUS(ida);
 1473 
 1474         /* acknowledge interrupt */
 1475         IDA_ACK_CMD_COM(ida);
 1476 
 1477         /* determine which job completed */
 1478         qcbp = ida_qcb_phys_kv(ida, paddr);
 1479 
 1480         /* analyse the job status code */
 1481         if (cstat & IDA_COMPL_OK) {
 1482           job_status = JOB_SUCCESS;
 1483         } else {
 1484           printf("ida%d: idaintr: return code %x=", cntlr, cstat);
 1485           if (cstat & IDA_NON_FATAL) printf("recoverable error! ");
 1486           if (cstat & IDA_FATAL) printf("fatal error! ");
 1487           if (cstat & IDA_ABORTED) printf("aborted! ");
 1488           if (cstat & IDA_INVAL_REQ) printf("invalid request block! ");
 1489           if (cstat & IDA_INVAL_LIST) printf("cmd list error! ");
 1490           if (cstat & IDA_AARGH_LIST) printf("really bad cmd list! ");
 1491           job_status = JOB_FAILURE;
 1492         }
 1493 
 1494 #ifdef IDADEBUG
 1495         if (ida_debug & IDA_SHOWQCBS) {
 1496           printf("ida%d: idaintr: qcb(%x) returned.\n", cntlr, qcbp);
 1497           ida_print_qcb(qcbp);
 1498         }
 1499 #endif
 1500 
 1501         ida_done(cntlr, qcbp, job_status); /* retire the job */
 1502         ida_start(cntlr);               /* send the controller another job */
 1503       }
 1504 
 1505       if (status & BMIC_CHAN_CLEAR) {
 1506         /* channel not clear */
 1507         IDA_DISABLE_CHAN(ida);
 1508         ida_start(cntlr);               /* send the controller another job */
 1509       }
 1510     } /*eisa*/
 1511   }
 1512 }
 1513 
 1514 
 1515 int
 1516 ida_poll(cntlr, wait)
 1517 int cntlr;
 1518 int wait;                       /* delay in milliseconds */
 1519 {
 1520   struct ida_ctl *ctlp = idadata[cntlr];
 1521 
 1522   if (PCI_CONTROLLER(ctlp)) {
 1523     printf("ida%d: error: ida_poll called on a PCI controller\n", cntlr);
 1524     return EIO;
 1525   }
 1526 
 1527   while (wait-- > 0) {
 1528     if (IDA_DATA_READY(ctlp)) {
 1529       ctlp->com_addr = IDA_GET_COM_ADDR(ctlp);
 1530       ctlp->com_offset = IDA_GET_COM_OFFSET(ctlp);
 1531       ctlp->com_status = IDA_GET_COM_STATUS(ctlp);
 1532       IDA_ACK_CMD_COM(ctlp);
 1533 
 1534       if (0) printf("ida_poll: addr=0x%08x off=0x%04x cmdstatus=0x%02x\n",
 1535                     (u_int)ctlp->com_addr,
 1536                     ctlp->com_offset,
 1537                     ctlp->com_status);
 1538 
 1539       return 0;
 1540     }
 1541     DELAY(1000);
 1542   }
 1543 
 1544   printf("ida%d: board not responding\n", cntlr);
 1545   return EIO;
 1546 }
 1547 
 1548 
 1549 int
 1550 ida_submit(int cntlr, qcb_t *qcbp, int size)
 1551 {
 1552   struct ida_ctl *ida = idadata[cntlr];
 1553   int s = splbio();
 1554 
 1555   if (PCI_CONTROLLER(ida)) {
 1556     ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
 1557     u_int fifo = reg->initiate_fifo;
 1558     if (fifo == 1) {
 1559       splx(s);
 1560 #ifdef IDADEBUG
 1561       if (ida_debug & IDA_SHOWSUBS)
 1562         printf("ida%d: ida_submit(%x): fifo=1 not submitting\n",
 1563                cntlr, qcbp, fifo);
 1564 #endif
 1565       return(1);                        /* not sent - must try again later */
 1566     }
 1567 #ifdef IDADEBUG
 1568     if (ida_debug & IDA_SHOWSUBS)
 1569       printf("ida%d: ida_submit(%x): fifo=%d submitting\n", cntlr, qcbp, fifo);
 1570 #endif
 1571     reg->initiate_fifo = qcbp->paddr;
 1572 
 1573   } else {
 1574     if (!IDA_CHAN_CLEAR(ida)) {
 1575       IDA_ENABLE_CHAN(ida);
 1576       splx(s);
 1577       return(1);                        /* not sent - must try again later */
 1578     }
 1579 
 1580     IDA_SET_EBELL_I(ida, 2);
 1581     IDA_SET_SUB_ADDR(ida, qcbp->paddr); /* physical address of this qcb */
 1582     IDA_SET_SUB_LEN(ida, size);
 1583     IDA_SET_LBELL_I(ida, 1);
 1584   }
 1585 
 1586   splx(s);
 1587   return(0);                    /* sent */
 1588 }
 1589 
 1590 static
 1591 void
 1592 ida_empty_pci_complete_fifo(int cntlr, ida_pci_reg_t *reg) {
 1593   u_long paddr;
 1594   if (paddr = reg->complete_fifo) {
 1595     int count = 200;
 1596     while (paddr && count > 0) {
 1597       printf("ida%d: command completion discarded (0x%x).\n",
 1598              cntlr, (u_int)paddr);
 1599       if (paddr = reg->complete_fifo) {
 1600         DELAY(100);
 1601         count--;
 1602       }
 1603     }
 1604   }
 1605   return;
 1606 }
 1607 
 1608 static
 1609 u_long
 1610 ida_complete_pci_command(int cntlr, ida_pci_reg_t *reg) {
 1611   int count = 1;
 1612   u_long paddr;
 1613   while (count < 1000000) {
 1614     if (reg->status & IDA_PCI_PENDING) {
 1615       if ((paddr = reg->complete_fifo) == 0)
 1616         printf("ida%d: ida_complete_pci_command: zero address returned.\n",
 1617                cntlr);
 1618       else
 1619         return paddr;
 1620     }
 1621     DELAY(10);
 1622   }
 1623   return 1;
 1624 }
 1625 
 1626 static
 1627 int
 1628 ida_submit_wait(int cntlr, qcb_t *qcbp, int size)
 1629 {
 1630   struct ida_ctl *ida = idadata[cntlr];
 1631 
 1632   if (PCI_CONTROLLER(ida)) {
 1633     ida_pci_reg_t *reg = (ida_pci_reg_t *)ida->iobase;
 1634     int i, count = 1000000;
 1635     u_long paddr;
 1636     ida_empty_pci_complete_fifo(cntlr, reg);
 1637     reg->interrupt = IDA_PCI_DISABLE_INTS;
 1638     while (count > 0 && (i = reg->initiate_fifo) > 16) {
 1639       DELAY(10);
 1640       count--;
 1641     }
 1642     if (count == 0) {
 1643       printf("ida%d: ida_pci_submit_wait: fifo failed to clear - controller has failed.\n", cntlr);
 1644       return 1;
 1645     }
 1646     reg->initiate_fifo = qcbp->paddr;
 1647     paddr = ida_complete_pci_command(cntlr, reg);
 1648     if (paddr == 1) {
 1649       printf("ida%d: ida_pci_submit_wait timeout.  No command list returned.\n",
 1650              cntlr);
 1651       return 1;
 1652     }
 1653     if (paddr != qcbp->paddr) {
 1654       printf("ida%d: ida_pci_submit_wait error. Invalid command list returned.\n",
 1655              cntlr);
 1656       return 1;
 1657     }
 1658     if (qcbp->req.error != 0xfe && qcbp->req.error == 0x40) {
 1659       printf("ida%d: ida_pci_submit_wait: Job error.\n", cntlr);
 1660       return 1;
 1661     }
 1662   } else {
 1663     if (ida_submit(cntlr, qcbp, size)) {
 1664       return 1;
 1665     }
 1666     if (ida_poll(cntlr, 10)) {
 1667       return 1;
 1668     }
 1669   }
 1670 
 1671   return 0;                     /* sent */
 1672 }
 1673 
 1674 
 1675 void
 1676 ida_done(int cntlr, qcb_t *qcbp, int state)
 1677 {
 1678   struct buf *bp = qcbp->buf;
 1679 
 1680   if (idadata[cntlr] > 0)
 1681     idadata[cntlr]->inside--; /* one less job inside the controller */
 1682 
 1683   if (state != JOB_SUCCESS) {
 1684 #ifdef IDADEBUG
 1685     if (ida_debug & IDA_SHOWMISC)
 1686       printf("ida%d: ida_done: job failed 0x%x\n", cntlr, state);
 1687 #endif
 1688     /* we had a problem */
 1689     bp->b_error = EIO;
 1690     bp->b_flags |= B_ERROR;
 1691   } else {
 1692     struct ida_drv *drv = id_drive[dkunit(bp->b_dev)];
 1693     bp->b_resid = 0;
 1694     /* Update device stats */
 1695     devstat_end_transaction(&drv->dk_stats,
 1696                             bp->b_bcount - bp->b_resid,
 1697                             DEVSTAT_TAG_NONE,
 1698                             (bp->b_flags & B_READ) ? DEVSTAT_READ : DEVSTAT_WRITE);
 1699   }
 1700 
 1701   ida_free_qcb(cntlr, qcbp);
 1702   biodone(bp);
 1703 }
 1704 
 1705 
 1706 int
 1707 idsize(dev_t dev)
 1708 {
 1709   int unit = dkunit(dev);
 1710   struct ida_drv *drv;
 1711 
 1712   if (unit >= NID)
 1713     return (-1);
 1714 
 1715   drv = id_drive[unit];
 1716   if (!drv || !(drv->flags & ID_INIT))
 1717     return (-1);
 1718 
 1719   return (dssize(dev, &drv->slices, idopen, idclose));
 1720 }
 1721 
 1722 /*
 1723  * dump all of physical memory into the partition specified, starting
 1724  * at offset 'dumplo' into the partition.
 1725  */
 1726 int
 1727 iddump(dev_t dev)
 1728 {                               /* dump core after a system crash */
 1729   return 0; /* XXX */
 1730 }
 1731 
 1732 static id_devsw_installed = 0;
 1733 
 1734 static void
 1735 id_drvinit(void *unused)
 1736 {
 1737   if( ! id_devsw_installed ) {
 1738     cdevsw_add_generic(ID_BDMAJ,ID_CDMAJ, &id_cdevsw);
 1739     id_devsw_installed = 1;
 1740   }
 1741 }
 1742 
 1743 SYSINIT(iddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+ID_CDMAJ,id_drvinit,NULL)
 1744 
 1745 #ifdef IDADEBUG
 1746 void
 1747 ida_print_qcb(qcb_t *qcbp)
 1748 {
 1749   int i;
 1750   printf("qcb(%x): drive=%x priority=%x flags=%x sgcount=%d\n"
 1751          ,qcbp
 1752          ,qcbp->hdr.drive
 1753          ,qcbp->hdr.priority
 1754          ,qcbp->hdr.flags
 1755          ,qcbp->req.sgcount);
 1756   printf("qcb(%x): next=%x command=%x error=%x blkno=%x bcount=%x\n"
 1757          ,qcbp
 1758          ,qcbp->req.next
 1759          ,qcbp->req.command
 1760          ,qcbp->req.error
 1761          ,qcbp->req.blkno
 1762          ,qcbp->req.bcount);
 1763   for (i=0; i < qcbp->req.sgcount; i++)
 1764     printf("qcb(%x): %x len=%x addr=%x\n"
 1765            ,qcbp
 1766            ,i
 1767            ,qcbp->sglist[i].len
 1768            ,qcbp->sglist[i].addr);
 1769 }
 1770 
 1771 void
 1772 ida_print_active_qcb(int cntlr)
 1773 {
 1774   struct ida_ctl *ida = idadata[cntlr];
 1775   int i;
 1776 
 1777   for (i=0; i < QCB_HASH_SIZE; i++) {
 1778     qcb_t *qcbp = ida->hashlist[i];
 1779     while (qcbp) {
 1780       if (qcbp->flags != QCB_FREE) {
 1781         ida_print_qcb(qcbp);
 1782       }
 1783       qcbp = qcbp->nexthash;
 1784     }
 1785   }
 1786 }
 1787 #endif /*IDADEBUG */
 1788 

Cache object: 39a99f7f03151629f3512572feb8d71a


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