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/iir/iir.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 /* $FreeBSD$ */
    2 /*
    3  *       Copyright (c) 2000-01 Intel Corporation
    4  *       All Rights Reserved
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions, and the following disclaimer,
   11  *    without modification, immediately at the beginning of the file.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   22  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 /*
   32  * iir.c: SCSI dependant code for the Intel Integrated RAID Controller driver
   33  *
   34  * Written by: Achim Leubner <achim.leubner@intel.com>
   35  * Fixes/Additions: Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>
   36  *
   37  * credits:     Niklas Hallqvist;       OpenBSD driver for the ICP Controllers.
   38  *              Mike Smith;             Some driver source code.
   39  *              FreeBSD.ORG;            Great O/S to work on and for.
   40  *
   41  * TODO:     
   42  */
   43 
   44 #ident "$Id: iir.c 1.2 2001/06/21 20:28:32 achim Exp $"
   45 
   46 #define _IIR_C_
   47 
   48 /* #include "opt_iir.h" */
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/eventhandler.h>
   52 #include <sys/malloc.h>
   53 #include <sys/kernel.h>
   54 #include <sys/bus.h>
   55 
   56 #include <stddef.h>     /* For offsetof */
   57 
   58 #include <machine/bus_memio.h>
   59 #include <machine/bus_pio.h>
   60 #include <machine/bus.h>
   61 #include <machine/clock.h>
   62 #include <machine/stdarg.h>
   63 
   64 #include <cam/cam.h>
   65 #include <cam/cam_ccb.h>
   66 #include <cam/cam_sim.h>
   67 #include <cam/cam_xpt_sim.h>
   68 #include <cam/cam_debug.h>
   69 #include <cam/scsi/scsi_all.h>
   70 #include <cam/scsi/scsi_message.h>
   71 
   72 #include <vm/vm.h>
   73 #include <vm/pmap.h>
   74 
   75 #include <dev/iir/iir.h>
   76 
   77 struct gdt_softc *gdt_wait_gdt;
   78 int     gdt_wait_index;
   79 
   80 #ifdef GDT_DEBUG
   81 int     gdt_debug = GDT_DEBUG;
   82 #ifdef __SERIAL__
   83 #define MAX_SERBUF 160
   84 static void ser_init(void);
   85 static void ser_puts(char *str);
   86 static void ser_putc(int c);
   87 static char strbuf[MAX_SERBUF+1];
   88 #ifdef __COM2__
   89 #define COM_BASE 0x2f8
   90 #else
   91 #define COM_BASE 0x3f8
   92 #endif
   93 static void ser_init()
   94 {
   95     unsigned port=COM_BASE;
   96 
   97     outb(port+3, 0x80);
   98     outb(port+1, 0);
   99     /* 19200 Baud, if 9600: outb(12,port) */
  100     outb(port, 6);
  101     outb(port+3, 3);
  102     outb(port+1, 0);
  103 }
  104 
  105 static void ser_puts(char *str)
  106 {
  107     char *ptr;
  108 
  109     ser_init();
  110     for (ptr=str;*ptr;++ptr)
  111         ser_putc((int)(*ptr));
  112 }
  113 
  114 static void ser_putc(int c)
  115 {
  116     unsigned port=COM_BASE;
  117 
  118     while ((inb(port+5) & 0x20)==0);
  119     outb(port, c);
  120     if (c==0x0a)
  121     {
  122         while ((inb(port+5) & 0x20)==0);
  123         outb(port, 0x0d);
  124     }
  125 }
  126 
  127 int ser_printf(const char *fmt, ...)
  128 {
  129     va_list args;
  130     int i;
  131 
  132     va_start(args,fmt);
  133     i = vsprintf(strbuf,fmt,args);
  134     ser_puts(strbuf);
  135     va_end(args);
  136     return i;
  137 }
  138 #endif
  139 #endif
  140 
  141 /* The linked list of softc structures */
  142 struct gdt_softc_list gdt_softcs = TAILQ_HEAD_INITIALIZER(gdt_softcs);
  143 /* controller cnt. */
  144 int gdt_cnt = 0;
  145 /* event buffer */
  146 static gdt_evt_str ebuffer[GDT_MAX_EVENTS];
  147 static int elastidx, eoldidx;
  148 /* statistics */
  149 gdt_statist_t gdt_stat;
  150 
  151 /* Definitions for our use of the SIM private CCB area */
  152 #define ccb_sim_ptr     spriv_ptr0
  153 #define ccb_priority    spriv_field1
  154 
  155 static void     iir_action(struct cam_sim *sim, union ccb *ccb);
  156 static void     iir_poll(struct cam_sim *sim);
  157 static void     iir_shutdown(void *arg, int howto);
  158 static void     iir_timeout(void *arg);
  159 static void     iir_watchdog(void *arg);
  160 
  161 static void     gdt_eval_mapping(u_int32_t size, int *cyls, int *heads, 
  162                                  int *secs);
  163 static int      gdt_internal_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb, 
  164                                  u_int8_t service, u_int16_t opcode, 
  165                                  u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
  166 static int      gdt_wait(struct gdt_softc *gdt, struct gdt_ccb *ccb, 
  167                          int timeout);
  168 
  169 static struct gdt_ccb *gdt_get_ccb(struct gdt_softc *gdt);
  170 static u_int32_t gdt_ccb_vtop(struct gdt_softc *gdt, 
  171                               struct gdt_ccb *gccb);
  172 
  173 static int      gdt_sync_event(struct gdt_softc *gdt, int service, 
  174                                u_int8_t index, struct gdt_ccb *gccb);
  175 static int      gdt_async_event(struct gdt_softc *gdt, int service);
  176 static struct gdt_ccb *gdt_raw_cmd(struct gdt_softc *gdt, 
  177                                    union ccb *ccb, int *lock);
  178 static struct gdt_ccb *gdt_cache_cmd(struct gdt_softc *gdt, 
  179                                      union ccb *ccb, int *lock);
  180 static struct gdt_ccb *gdt_ioctl_cmd(struct gdt_softc *gdt, 
  181                                      gdt_ucmd_t *ucmd, int *lock);
  182 static void     gdt_internal_cache_cmd(struct gdt_softc *gdt,union ccb *ccb);
  183 
  184 static void     gdtmapmem(void *arg, bus_dma_segment_t *dm_segs,
  185                           int nseg, int error);
  186 static void     gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs,
  187                               int nseg, int error);
  188 
  189 int
  190 iir_init(struct gdt_softc *gdt)
  191 {
  192     u_int16_t cdev_cnt;
  193     int i, id, drv_cyls, drv_hds, drv_secs;
  194     struct gdt_ccb *gccb;
  195 
  196     GDT_DPRINTF(GDT_D_DEBUG, ("iir_init()\n"));
  197 
  198     gdt->sc_state = GDT_POLLING;
  199     gdt_clear_events(); 
  200     bzero(&gdt_stat, sizeof(gdt_statist_t));
  201 
  202     SLIST_INIT(&gdt->sc_free_gccb);
  203     SLIST_INIT(&gdt->sc_pending_gccb);
  204     TAILQ_INIT(&gdt->sc_ccb_queue);
  205     TAILQ_INIT(&gdt->sc_ucmd_queue);
  206     TAILQ_INSERT_TAIL(&gdt_softcs, gdt, links);
  207 
  208     /* DMA tag for mapping buffers into device visible space. */
  209     if (bus_dma_tag_create(gdt->sc_parent_dmat, /*alignment*/1, /*boundary*/0,
  210                            /*lowaddr*/BUS_SPACE_MAXADDR,
  211                            /*highaddr*/BUS_SPACE_MAXADDR,
  212                            /*filter*/NULL, /*filterarg*/NULL,
  213                            /*maxsize*/MAXBSIZE, /*nsegments*/GDT_MAXSG,
  214                            /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  215                            /*flags*/BUS_DMA_ALLOCNOW,
  216                            &gdt->sc_buffer_dmat) != 0) {
  217         printf("iir%d: bus_dma_tag_create(...,gdt->sc_buffer_dmat) failed\n",
  218                gdt->sc_hanum);
  219         return (1);
  220     }
  221     gdt->sc_init_level++;
  222 
  223     /* DMA tag for our ccb structures */
  224     if (bus_dma_tag_create(gdt->sc_parent_dmat, /*alignment*/1, /*boundary*/0,
  225                            /*lowaddr*/BUS_SPACE_MAXADDR,
  226                            /*highaddr*/BUS_SPACE_MAXADDR,
  227                            /*filter*/NULL, /*filterarg*/NULL,
  228                            GDT_MAXCMDS * sizeof(struct gdt_ccb),
  229                            /*nsegments*/1,
  230                            /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  231                            /*flags*/0, &gdt->sc_gccb_dmat) != 0) {
  232         printf("iir%d: bus_dma_tag_create(...,gdt->sc_gccb_dmat) failed\n",
  233                gdt->sc_hanum);
  234         return (1);
  235     }
  236     gdt->sc_init_level++;
  237 
  238     /* Allocation for our ccbs */
  239     if (bus_dmamem_alloc(gdt->sc_gccb_dmat, (void **)&gdt->sc_gccbs,
  240                          BUS_DMA_NOWAIT, &gdt->sc_gccb_dmamap) != 0) {
  241         printf("iir%d: bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n",
  242                gdt->sc_hanum);
  243         return (1);
  244     }
  245     gdt->sc_init_level++;
  246 
  247     /* And permanently map them */
  248     bus_dmamap_load(gdt->sc_gccb_dmat, gdt->sc_gccb_dmamap,
  249                     gdt->sc_gccbs, GDT_MAXCMDS * sizeof(struct gdt_ccb),
  250                     gdtmapmem, &gdt->sc_gccb_busbase, /*flags*/0);
  251     gdt->sc_init_level++;
  252 
  253     /* Clear them out. */
  254     bzero(gdt->sc_gccbs, GDT_MAXCMDS * sizeof(struct gdt_ccb));
  255 
  256     /* Initialize the ccbs */
  257     for (i = GDT_MAXCMDS-1; i >= 0; i--) {
  258         gdt->sc_gccbs[i].gc_cmd_index = i + 2;
  259         gdt->sc_gccbs[i].gc_flags = GDT_GCF_UNUSED;
  260         gdt->sc_gccbs[i].gc_map_flag = FALSE;
  261         if (bus_dmamap_create(gdt->sc_buffer_dmat, /*flags*/0,
  262                               &gdt->sc_gccbs[i].gc_dmamap) != 0)
  263             return(1);
  264         gdt->sc_gccbs[i].gc_map_flag = TRUE;
  265         SLIST_INSERT_HEAD(&gdt->sc_free_gccb, &gdt->sc_gccbs[i], sle);
  266     }
  267     gdt->sc_init_level++;
  268 
  269     /* create the control device */
  270     gdt->sc_dev = gdt_make_dev(gdt->sc_hanum);
  271 
  272     /* allocate ccb for gdt_internal_cmd() */
  273     gccb = gdt_get_ccb(gdt);
  274     if (gccb == NULL) {
  275         printf("iir%d: No free command index found\n",
  276                gdt->sc_hanum);
  277         return (1);
  278     }
  279 
  280     if (!gdt_internal_cmd(gdt, gccb, GDT_SCREENSERVICE, GDT_INIT, 
  281                           0, 0, 0)) {
  282         printf("iir%d: Screen service initialization error %d\n",
  283                gdt->sc_hanum, gdt->sc_status);
  284         gdt_free_ccb(gdt, gccb);
  285         return (1);
  286     }
  287 
  288     if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_INIT, 
  289                           GDT_LINUX_OS, 0, 0)) {
  290         printf("iir%d: Cache service initialization error %d\n",
  291                gdt->sc_hanum, gdt->sc_status);
  292         gdt_free_ccb(gdt, gccb);
  293         return (1);
  294     }
  295     gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_UNFREEZE_IO,
  296                      0, 0, 0);
  297 
  298     if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_MOUNT, 
  299                           0xffff, 1, 0)) {
  300         printf("iir%d: Cache service mount error %d\n",
  301                gdt->sc_hanum, gdt->sc_status);
  302         gdt_free_ccb(gdt, gccb);
  303         return (1);
  304     }
  305 
  306     if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_INIT, 
  307                           GDT_LINUX_OS, 0, 0)) {
  308         printf("iir%d: Cache service post-mount initialization error %d\n",
  309                gdt->sc_hanum, gdt->sc_status);
  310         gdt_free_ccb(gdt, gccb);
  311         return (1);
  312     }
  313     cdev_cnt = (u_int16_t)gdt->sc_info;
  314     gdt->sc_fw_vers = gdt->sc_service;
  315 
  316     /* Detect number of buses */
  317     gdt_enc32(gccb->gc_scratch + GDT_IOC_VERSION, GDT_IOC_NEWEST);
  318     gccb->gc_scratch[GDT_IOC_LIST_ENTRIES] = GDT_MAXBUS;
  319     gccb->gc_scratch[GDT_IOC_FIRST_CHAN] = 0;
  320     gccb->gc_scratch[GDT_IOC_LAST_CHAN] = GDT_MAXBUS - 1;
  321     gdt_enc32(gccb->gc_scratch + GDT_IOC_LIST_OFFSET, GDT_IOC_HDR_SZ);
  322     if (gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_IOCTL,
  323                          GDT_IOCHAN_RAW_DESC, GDT_INVALID_CHANNEL,
  324                          GDT_IOC_HDR_SZ + GDT_MAXBUS * GDT_RAWIOC_SZ)) {
  325         gdt->sc_bus_cnt = gccb->gc_scratch[GDT_IOC_CHAN_COUNT];
  326         for (i = 0; i < gdt->sc_bus_cnt; i++) {
  327             id = gccb->gc_scratch[GDT_IOC_HDR_SZ +
  328                                  i * GDT_RAWIOC_SZ + GDT_RAWIOC_PROC_ID];
  329             gdt->sc_bus_id[i] = id < GDT_MAXID_FC ? id : 0xff;
  330         }
  331     } else {
  332         /* New method failed, use fallback. */
  333         for (i = 0; i < GDT_MAXBUS; i++) {
  334             gdt_enc32(gccb->gc_scratch + GDT_GETCH_CHANNEL_NO, i);
  335             if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_IOCTL,
  336                                   GDT_SCSI_CHAN_CNT | GDT_L_CTRL_PATTERN,
  337                                   GDT_IO_CHANNEL | GDT_INVALID_CHANNEL,
  338                                   GDT_GETCH_SZ)) {
  339                 if (i == 0) {
  340                     printf("iir%d: Cannot get channel count, "
  341                            "error %d\n", gdt->sc_hanum, gdt->sc_status);
  342                     gdt_free_ccb(gdt, gccb);
  343                     return (1);
  344                 }
  345                 break;
  346             }
  347             gdt->sc_bus_id[i] =
  348                 (gccb->gc_scratch[GDT_GETCH_SIOP_ID] < GDT_MAXID_FC) ?
  349                 gccb->gc_scratch[GDT_GETCH_SIOP_ID] : 0xff;
  350         }
  351         gdt->sc_bus_cnt = i;
  352     }
  353     /* add one "virtual" channel for the host drives */
  354     gdt->sc_virt_bus = gdt->sc_bus_cnt;
  355     gdt->sc_bus_cnt++;
  356 
  357     if (!gdt_internal_cmd(gdt, gccb, GDT_SCSIRAWSERVICE, GDT_INIT, 
  358                           0, 0, 0)) {
  359             printf("iir%d: Raw service initialization error %d\n",
  360                    gdt->sc_hanum, gdt->sc_status);
  361             gdt_free_ccb(gdt, gccb);
  362             return (1);
  363     }
  364 
  365     /* Set/get features raw service (scatter/gather) */
  366     gdt->sc_raw_feat = 0;
  367     if (gdt_internal_cmd(gdt, gccb, GDT_SCSIRAWSERVICE, GDT_SET_FEAT,
  368                          GDT_SCATTER_GATHER, 0, 0)) {
  369         if (gdt_internal_cmd(gdt, gccb, GDT_SCSIRAWSERVICE, GDT_GET_FEAT, 
  370                              0, 0, 0)) {
  371             gdt->sc_raw_feat = gdt->sc_info;
  372             if (!(gdt->sc_info & GDT_SCATTER_GATHER)) {
  373                 panic("iir%d: Scatter/Gather Raw Service "
  374                       "required but not supported!\n", gdt->sc_hanum);
  375                 gdt_free_ccb(gdt, gccb);
  376                 return (1);
  377             }
  378         }
  379     }
  380 
  381     /* Set/get features cache service (scatter/gather) */
  382     gdt->sc_cache_feat = 0;
  383     if (gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_SET_FEAT, 
  384                          0, GDT_SCATTER_GATHER, 0)) {
  385         if (gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_GET_FEAT, 
  386                              0, 0, 0)) {
  387             gdt->sc_cache_feat = gdt->sc_info;
  388             if (!(gdt->sc_info & GDT_SCATTER_GATHER)) {
  389                 panic("iir%d: Scatter/Gather Cache Service "
  390                   "required but not supported!\n", gdt->sc_hanum);
  391                 gdt_free_ccb(gdt, gccb);
  392                 return (1);
  393             }
  394         }
  395     }
  396 
  397     /* Scan for cache devices */
  398     for (i = 0; i < cdev_cnt && i < GDT_MAX_HDRIVES; i++) {
  399         if (gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_INFO, 
  400                              i, 0, 0)) {
  401             gdt->sc_hdr[i].hd_present = 1;
  402             gdt->sc_hdr[i].hd_size = gdt->sc_info;
  403             
  404             /*
  405              * Evaluate mapping (sectors per head, heads per cyl)
  406              */
  407             gdt->sc_hdr[i].hd_size &= ~GDT_SECS32;
  408             if (gdt->sc_info2 == 0)
  409                 gdt_eval_mapping(gdt->sc_hdr[i].hd_size,
  410                                  &drv_cyls, &drv_hds, &drv_secs);
  411             else {
  412                 drv_hds = gdt->sc_info2 & 0xff;
  413                 drv_secs = (gdt->sc_info2 >> 8) & 0xff;
  414                 drv_cyls = gdt->sc_hdr[i].hd_size / drv_hds /
  415                     drv_secs;
  416             }
  417             gdt->sc_hdr[i].hd_heads = drv_hds;
  418             gdt->sc_hdr[i].hd_secs = drv_secs;
  419             /* Round the size */
  420             gdt->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
  421             
  422             if (gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE,
  423                                  GDT_DEVTYPE, i, 0, 0))
  424                 gdt->sc_hdr[i].hd_devtype = gdt->sc_info;
  425         }
  426     }
  427     
  428     GDT_DPRINTF(GDT_D_INIT, ("dpmem %x %d-bus %d cache device%s\n", 
  429                              gdt->sc_dpmembase,
  430                              gdt->sc_bus_cnt, cdev_cnt, 
  431                              cdev_cnt == 1 ? "" : "s"));
  432     gdt_free_ccb(gdt, gccb);
  433 
  434     gdt_cnt++;
  435     return (0);
  436 }
  437 
  438 void
  439 iir_free(struct gdt_softc *gdt)
  440 {
  441     int i;
  442 
  443     GDT_DPRINTF(GDT_D_INIT, ("iir_free()\n"));
  444 
  445     switch (gdt->sc_init_level) {
  446       default:
  447         gdt_destroy_dev(gdt->sc_dev);
  448       case 5:
  449         for (i = GDT_MAXCMDS-1; i >= 0; i--) 
  450             if (gdt->sc_gccbs[i].gc_map_flag)
  451                 bus_dmamap_destroy(gdt->sc_buffer_dmat,
  452                                    gdt->sc_gccbs[i].gc_dmamap);
  453         bus_dmamap_unload(gdt->sc_gccb_dmat, gdt->sc_gccb_dmamap);
  454       case 4:
  455         bus_dmamem_free(gdt->sc_gccb_dmat, gdt->sc_gccbs, gdt->sc_gccb_dmamap);
  456       case 3:
  457         bus_dma_tag_destroy(gdt->sc_gccb_dmat);
  458       case 2:
  459         bus_dma_tag_destroy(gdt->sc_buffer_dmat);
  460       case 1:
  461         bus_dma_tag_destroy(gdt->sc_parent_dmat);
  462       case 0:
  463         break;
  464     }
  465     TAILQ_REMOVE(&gdt_softcs, gdt, links);
  466 }
  467 
  468 void
  469 iir_attach(struct gdt_softc *gdt)
  470 {
  471     struct cam_devq *devq;
  472     int i;
  473 
  474     GDT_DPRINTF(GDT_D_INIT, ("iir_attach()\n"));
  475 
  476     /*
  477      * Create the device queue for our SIM.
  478      */
  479     devq = cam_simq_alloc(GDT_MAXCMDS);
  480     if (devq == NULL)
  481         return;
  482 
  483     for (i = 0; i < gdt->sc_bus_cnt; i++) {
  484         /*
  485          * Construct our SIM entry
  486          */
  487         gdt->sims[i] = cam_sim_alloc(iir_action, iir_poll, "iir",
  488                                      gdt, gdt->sc_hanum, /*untagged*/2,
  489                                      /*tagged*/GDT_MAXCMDS, devq);
  490         if (xpt_bus_register(gdt->sims[i], i) != CAM_SUCCESS) {
  491             cam_sim_free(gdt->sims[i], /*free_devq*/i == 0);
  492             break;
  493         }
  494 
  495         if (xpt_create_path(&gdt->paths[i], /*periph*/NULL,
  496                             cam_sim_path(gdt->sims[i]),
  497                             CAM_TARGET_WILDCARD,
  498                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
  499             xpt_bus_deregister(cam_sim_path(gdt->sims[i]));
  500             cam_sim_free(gdt->sims[i], /*free_devq*/i == 0);
  501             break;
  502         }
  503     }
  504     if (i > 0)
  505         EVENTHANDLER_REGISTER(shutdown_final, iir_shutdown,
  506                               gdt, SHUTDOWN_PRI_DEFAULT);
  507     /* iir_watchdog(gdt); */
  508     gdt->sc_state = GDT_NORMAL;
  509 }
  510 
  511 static void
  512 gdt_eval_mapping(u_int32_t size, int *cyls, int *heads, int *secs)
  513 {
  514     *cyls = size / GDT_HEADS / GDT_SECS;
  515     if (*cyls < GDT_MAXCYLS) {
  516         *heads = GDT_HEADS;
  517         *secs = GDT_SECS;
  518     } else {
  519         /* Too high for 64 * 32 */
  520         *cyls = size / GDT_MEDHEADS / GDT_MEDSECS;
  521         if (*cyls < GDT_MAXCYLS) {
  522             *heads = GDT_MEDHEADS;
  523             *secs = GDT_MEDSECS;
  524         } else {
  525             /* Too high for 127 * 63 */
  526             *cyls = size / GDT_BIGHEADS / GDT_BIGSECS;
  527             *heads = GDT_BIGHEADS;
  528             *secs = GDT_BIGSECS;
  529         }
  530     }
  531 }
  532 
  533 static int
  534 gdt_wait(struct gdt_softc *gdt, struct gdt_ccb *gccb, 
  535          int timeout)
  536 {
  537     int rv = 0;
  538 
  539     GDT_DPRINTF(GDT_D_INIT,
  540                 ("gdt_wait(%p, %p, %d)\n", gdt, gccb, timeout));
  541 
  542     gdt->sc_state |= GDT_POLL_WAIT;
  543     do {
  544         iir_intr(gdt);
  545         if (gdt == gdt_wait_gdt &&
  546             gccb->gc_cmd_index == gdt_wait_index) {
  547             rv = 1;
  548             break;
  549         }
  550         DELAY(1);
  551     } while (--timeout);
  552     gdt->sc_state &= ~GDT_POLL_WAIT;
  553     
  554     while (gdt->sc_test_busy(gdt))
  555         DELAY(1);               /* XXX correct? */
  556 
  557     return (rv);
  558 }
  559 
  560 static int
  561 gdt_internal_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb,
  562                  u_int8_t service, u_int16_t opcode, 
  563                  u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
  564 {
  565     int retries;
  566     
  567     GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d)\n",
  568                             gdt, service, opcode, arg1, arg2, arg3));
  569 
  570     bzero(gdt->sc_cmd, GDT_CMD_SZ);
  571 
  572     for (retries = GDT_RETRIES; ; ) {
  573         gccb->gc_service = service;
  574         gccb->gc_flags = GDT_GCF_INTERNAL;
  575         
  576         gdt->sc_set_sema0(gdt);
  577         gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
  578                   gccb->gc_cmd_index);
  579         gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, opcode);
  580 
  581         switch (service) {
  582           case GDT_CACHESERVICE:
  583             if (opcode == GDT_IOCTL) {
  584                 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
  585                           GDT_IOCTL_SUBFUNC, arg1);
  586                 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
  587                           GDT_IOCTL_CHANNEL, arg2);
  588                 gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION +
  589                           GDT_IOCTL_PARAM_SIZE, (u_int16_t)arg3);
  590                 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_IOCTL_P_PARAM,
  591                           gdt_ccb_vtop(gdt, gccb) + 
  592                           offsetof(struct gdt_ccb, gc_scratch[0]));
  593             } else {
  594                 gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION +
  595                           GDT_CACHE_DEVICENO, (u_int16_t)arg1);
  596                 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
  597                           GDT_CACHE_BLOCKNO, arg2);
  598             }
  599             break;
  600 
  601           case GDT_SCSIRAWSERVICE:
  602             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
  603                       GDT_RAW_DIRECTION, arg1);
  604             gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] =
  605                 (u_int8_t)arg2;
  606             gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] =
  607                 (u_int8_t)arg3;
  608             gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] =
  609                 (u_int8_t)(arg3 >> 8);
  610         }
  611 
  612         gdt->sc_cmd_len = GDT_CMD_SZ;
  613         gdt->sc_cmd_off = 0;
  614         gdt->sc_cmd_cnt = 0;
  615         gdt->sc_copy_cmd(gdt, gccb);
  616         gdt->sc_release_event(gdt);
  617         DELAY(20);
  618         if (!gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT))
  619             return (0);
  620         if (gdt->sc_status != GDT_S_BSY || --retries == 0)
  621             break;
  622         DELAY(1);
  623     }
  624     return (gdt->sc_status == GDT_S_OK);
  625 }
  626 
  627 static struct gdt_ccb *
  628 gdt_get_ccb(struct gdt_softc *gdt)
  629 {
  630     struct gdt_ccb *gccb;
  631     int lock;
  632     
  633     GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p)\n", gdt));
  634 
  635     lock = splcam();
  636     gccb = SLIST_FIRST(&gdt->sc_free_gccb);
  637     if (gccb != NULL) {
  638         SLIST_REMOVE_HEAD(&gdt->sc_free_gccb, sle);
  639         SLIST_INSERT_HEAD(&gdt->sc_pending_gccb, gccb, sle);
  640         ++gdt_stat.cmd_index_act;
  641         if (gdt_stat.cmd_index_act > gdt_stat.cmd_index_max)
  642             gdt_stat.cmd_index_max = gdt_stat.cmd_index_act;
  643     }
  644     splx(lock);
  645     return (gccb);
  646 }
  647 
  648 void
  649 gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb)
  650 {
  651     int lock;
  652 
  653     GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p)\n", gdt, gccb));
  654     
  655     lock = splcam();
  656     gccb->gc_flags = GDT_GCF_UNUSED;
  657     SLIST_REMOVE(&gdt->sc_pending_gccb, gccb, gdt_ccb, sle);
  658     SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle);
  659     --gdt_stat.cmd_index_act;
  660     splx(lock);
  661     if (gdt->sc_state & GDT_SHUTDOWN)
  662         wakeup(gccb);
  663 }
  664 
  665 static u_int32_t
  666 gdt_ccb_vtop(struct gdt_softc *gdt, struct gdt_ccb *gccb)
  667 {
  668     return (gdt->sc_gccb_busbase
  669             + (u_int32_t)((caddr_t)gccb - (caddr_t)gdt->sc_gccbs));
  670 }
  671 
  672 void    
  673 gdt_next(struct gdt_softc *gdt)
  674 {
  675     int lock;
  676     union ccb *ccb;
  677     gdt_ucmd_t *ucmd;
  678     struct cam_sim *sim;
  679     int bus, target, lun;
  680     int next_cmd;
  681 
  682     struct ccb_scsiio *csio;
  683     struct ccb_hdr *ccbh;
  684     struct gdt_ccb *gccb = NULL;
  685     u_int8_t cmd;
  686 
  687     GDT_DPRINTF(GDT_D_QUEUE, ("gdt_next(%p)\n", gdt));
  688 
  689     lock = splcam();
  690     if (gdt->sc_test_busy(gdt)) {
  691         if (!(gdt->sc_state & GDT_POLLING)) {
  692             splx(lock);
  693             return;
  694         }
  695         while (gdt->sc_test_busy(gdt))
  696             DELAY(1);
  697     }
  698 
  699     gdt->sc_cmd_cnt = gdt->sc_cmd_off = 0;
  700     next_cmd = TRUE;
  701     for (;;) {
  702         /* I/Os in queue? controller ready? */
  703         if (!TAILQ_FIRST(&gdt->sc_ucmd_queue) &&
  704             !TAILQ_FIRST(&gdt->sc_ccb_queue))
  705             break;
  706 
  707         /* 1.: I/Os without ccb (IOCTLs) */
  708         ucmd = TAILQ_FIRST(&gdt->sc_ucmd_queue);
  709         if (ucmd != NULL) {
  710             TAILQ_REMOVE(&gdt->sc_ucmd_queue, ucmd, links);
  711             if ((gccb = gdt_ioctl_cmd(gdt, ucmd, &lock)) == NULL) {
  712                 TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links);
  713                 break;
  714             }
  715             break;      
  716             /* wenn mehrere Kdos. zulassen: if (!gdt_polling) continue; */
  717         }
  718 
  719         /* 2.: I/Os with ccb */
  720         ccb = (union ccb *)TAILQ_FIRST(&gdt->sc_ccb_queue); 
  721         /* ist dann immer != NULL, da oben getestet */
  722         sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
  723         bus = cam_sim_bus(sim);
  724         target = ccb->ccb_h.target_id;
  725         lun = ccb->ccb_h.target_lun;
  726     
  727         TAILQ_REMOVE(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
  728         --gdt_stat.req_queue_act;
  729         /* ccb->ccb_h.func_code is XPT_SCSI_IO */
  730         GDT_DPRINTF(GDT_D_QUEUE, ("XPT_SCSI_IO flags 0x%x)\n", 
  731                                   ccb->ccb_h.flags));
  732         csio = &ccb->csio;
  733         ccbh = &ccb->ccb_h;
  734         cmd  = csio->cdb_io.cdb_bytes[0];
  735         /* Max CDB length is 12 bytes */
  736         if (csio->cdb_len > 12) { 
  737             ccbh->status = CAM_REQ_INVALID;
  738             --gdt_stat.io_count_act;
  739             xpt_done(ccb);
  740         } else if (bus != gdt->sc_virt_bus) {
  741             /* raw service command */
  742             if ((gccb = gdt_raw_cmd(gdt, ccb, &lock)) == NULL) {
  743                 TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, 
  744                                   sim_links.tqe);
  745                 ++gdt_stat.req_queue_act;
  746                 if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
  747                     gdt_stat.req_queue_max = gdt_stat.req_queue_act;
  748                 next_cmd = FALSE;
  749             }
  750         } else if (target >= GDT_MAX_HDRIVES || 
  751                    !gdt->sc_hdr[target].hd_present || lun != 0) {
  752             ccbh->status = CAM_SEL_TIMEOUT;
  753             --gdt_stat.io_count_act;
  754             xpt_done(ccb);
  755         } else {
  756             /* cache service command */
  757             if (cmd == READ_6  || cmd == WRITE_6 ||
  758                 cmd == READ_10 || cmd == WRITE_10) {
  759                 if ((gccb = gdt_cache_cmd(gdt, ccb, &lock)) == NULL) {
  760                     TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, 
  761                                       sim_links.tqe);
  762                     ++gdt_stat.req_queue_act;
  763                     if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
  764                         gdt_stat.req_queue_max = gdt_stat.req_queue_act;
  765                     next_cmd = FALSE;
  766                 }
  767             } else {
  768                 splx(lock);
  769                 gdt_internal_cache_cmd(gdt, ccb);
  770                 lock = splcam();
  771             }
  772         }           
  773         if ((gdt->sc_state & GDT_POLLING) || !next_cmd)
  774             break;
  775     }
  776     if (gdt->sc_cmd_cnt > 0)
  777         gdt->sc_release_event(gdt);
  778 
  779     splx(lock);
  780 
  781     if ((gdt->sc_state & GDT_POLLING) && gdt->sc_cmd_cnt > 0) {
  782         gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT);
  783     }
  784 }
  785 
  786 static struct gdt_ccb *
  787 gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock)
  788 {
  789     struct gdt_ccb *gccb;
  790     struct cam_sim *sim;
  791 
  792     GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_cmd(%p, %p)\n", gdt, ccb));
  793 
  794     if (roundup(GDT_CMD_UNION + GDT_RAW_SZ, sizeof(u_int32_t)) +
  795         gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET >
  796         gdt->sc_ic_all_size) {
  797         GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_raw_cmd(): DPMEM overflow\n", 
  798                                     gdt->sc_hanum));
  799         return (NULL);
  800     }
  801 
  802     bzero(gdt->sc_cmd, GDT_CMD_SZ);
  803 
  804     gccb = gdt_get_ccb(gdt);
  805     if (gccb == NULL) {
  806         GDT_DPRINTF(GDT_D_INVALID, ("iir%d: No free command index found\n",
  807                                     gdt->sc_hanum));
  808         return (gccb);
  809     }
  810     sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
  811     gccb->gc_ccb = ccb;
  812     gccb->gc_service = GDT_SCSIRAWSERVICE;
  813     gccb->gc_flags = GDT_GCF_SCSI;
  814         
  815     if (gdt->sc_cmd_cnt == 0)
  816         gdt->sc_set_sema0(gdt);
  817     splx(*lock);
  818     gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
  819               gccb->gc_cmd_index);
  820     gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, GDT_WRITE);
  821 
  822     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_DIRECTION,
  823               (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN ?
  824               GDT_DATA_IN : GDT_DATA_OUT);
  825     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SDLEN,
  826               ccb->csio.dxfer_len);
  827     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_CLEN,
  828               ccb->csio.cdb_len);
  829     bcopy(ccb->csio.cdb_io.cdb_bytes, gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_CMD,
  830           ccb->csio.cdb_len);
  831     gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] = 
  832         ccb->ccb_h.target_id;
  833     gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] = 
  834         ccb->ccb_h.target_lun;
  835     gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] = 
  836         cam_sim_bus(sim);
  837     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_LEN,
  838               sizeof(struct scsi_sense_data));
  839     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_DATA,
  840               gdt_ccb_vtop(gdt, gccb) + 
  841               offsetof(struct gdt_ccb, gc_scratch[0]));
  842  
  843     /*
  844      * If we have any data to send with this command,
  845      * map it into bus space.
  846      */
  847     /* Only use S/G if there is a transfer */
  848     if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
  849         if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { 
  850             if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
  851                 int s;
  852                 int error;
  853             
  854                 /* vorher unlock von splcam() ??? */
  855                 s = splsoftvm();
  856                 error =
  857                     bus_dmamap_load(gdt->sc_buffer_dmat,
  858                                     gccb->gc_dmamap,
  859                                     ccb->csio.data_ptr,
  860                                     ccb->csio.dxfer_len,
  861                                     gdtexecuteccb,
  862                                     gccb, /*flags*/0);
  863                 if (error == EINPROGRESS) {
  864                     xpt_freeze_simq(sim, 1);
  865                     gccb->gc_state |= CAM_RELEASE_SIMQ;
  866                 }
  867                 splx(s);
  868             } else {
  869                 struct bus_dma_segment seg; 
  870             
  871                 /* Pointer to physical buffer */
  872                 seg.ds_addr =
  873                     (bus_addr_t)ccb->csio.data_ptr;
  874                 seg.ds_len = ccb->csio.dxfer_len;
  875                 gdtexecuteccb(gccb, &seg, 1, 0);
  876             }
  877         } else {
  878             struct bus_dma_segment *segs;
  879 
  880             if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0)
  881                 panic("iir%d: iir_action - Physical "
  882                       "segment pointers unsupported", gdt->sc_hanum);
  883 
  884             if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS)==0)
  885                 panic("iir%d: iir_action - Virtual "
  886                       "segment addresses unsupported", gdt->sc_hanum);
  887 
  888             /* Just use the segments provided */
  889             segs = (struct bus_dma_segment *)ccb->csio.data_ptr;
  890             gdtexecuteccb(gccb, segs, ccb->csio.sglist_cnt, 0);
  891         }
  892     } else {
  893         gdtexecuteccb(gccb, NULL, 0, 0);
  894     }
  895 
  896     *lock = splcam();
  897     return (gccb);
  898 }
  899 
  900 static struct gdt_ccb *
  901 gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock)
  902 {
  903     struct gdt_ccb *gccb;
  904     struct cam_sim *sim;
  905     u_int8_t *cmdp;
  906     u_int16_t opcode;
  907     u_int32_t blockno, blockcnt;
  908 
  909     GDT_DPRINTF(GDT_D_CMD, ("gdt_cache_cmd(%p, %p)\n", gdt, ccb));
  910 
  911     if (roundup(GDT_CMD_UNION + GDT_CACHE_SZ, sizeof(u_int32_t)) +
  912         gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET >
  913         gdt->sc_ic_all_size) {
  914         GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_cache_cmd(): DPMEM overflow\n", 
  915                                     gdt->sc_hanum));
  916         return (NULL);
  917     }
  918 
  919     bzero(gdt->sc_cmd, GDT_CMD_SZ);
  920 
  921     gccb = gdt_get_ccb(gdt);
  922     if (gccb == NULL) {
  923         GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n",
  924                                   gdt->sc_hanum));
  925         return (gccb);
  926     }
  927     sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
  928     gccb->gc_ccb = ccb;
  929     gccb->gc_service = GDT_CACHESERVICE;
  930     gccb->gc_flags = GDT_GCF_SCSI;
  931         
  932     if (gdt->sc_cmd_cnt == 0)
  933         gdt->sc_set_sema0(gdt);
  934     splx(*lock);
  935     gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
  936               gccb->gc_cmd_index);
  937     cmdp = ccb->csio.cdb_io.cdb_bytes;
  938     opcode = (*cmdp == WRITE_6 || *cmdp == WRITE_10) ? GDT_WRITE : GDT_READ;
  939     if ((gdt->sc_state & GDT_SHUTDOWN) && opcode == GDT_WRITE)
  940         opcode = GDT_WRITE_THR;
  941     gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, opcode);
  942  
  943     gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO,
  944               ccb->ccb_h.target_id);
  945     if (ccb->csio.cdb_len == 6) {
  946         struct scsi_rw_6 *rw = (struct scsi_rw_6 *)cmdp;
  947         blockno = scsi_3btoul(rw->addr) & ((SRW_TOPADDR<<16) | 0xffff);
  948         blockcnt = rw->length ? rw->length : 0x100;
  949     } else {
  950         struct scsi_rw_10 *rw = (struct scsi_rw_10 *)cmdp;
  951         blockno = scsi_4btoul(rw->addr);
  952         blockcnt = scsi_2btoul(rw->length);
  953     }
  954     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
  955               blockno);
  956     gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT,
  957               blockcnt);
  958 
  959     /*
  960      * If we have any data to send with this command,
  961      * map it into bus space.
  962      */
  963     /* Only use S/G if there is a transfer */
  964     if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { 
  965         if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
  966             int s;
  967             int error;
  968             
  969             /* vorher unlock von splcam() ??? */
  970             s = splsoftvm();
  971             error =
  972                 bus_dmamap_load(gdt->sc_buffer_dmat,
  973                                 gccb->gc_dmamap,
  974                                 ccb->csio.data_ptr,
  975                                 ccb->csio.dxfer_len,
  976                                 gdtexecuteccb,
  977                                 gccb, /*flags*/0);
  978             if (error == EINPROGRESS) {
  979                 xpt_freeze_simq(sim, 1);
  980                 gccb->gc_state |= CAM_RELEASE_SIMQ;
  981             }
  982             splx(s);
  983         } else {
  984             struct bus_dma_segment seg; 
  985             
  986             /* Pointer to physical buffer */
  987             seg.ds_addr =
  988                 (bus_addr_t)ccb->csio.data_ptr;
  989             seg.ds_len = ccb->csio.dxfer_len;
  990             gdtexecuteccb(gccb, &seg, 1, 0);
  991         }
  992     } else {
  993         struct bus_dma_segment *segs;
  994 
  995         if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0)
  996             panic("iir%d: iir_action - Physical "
  997                   "segment pointers unsupported", gdt->sc_hanum);
  998 
  999         if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS)==0)
 1000             panic("iir%d: iir_action - Virtual "
 1001                   "segment addresses unsupported", gdt->sc_hanum);
 1002 
 1003         /* Just use the segments provided */
 1004         segs = (struct bus_dma_segment *)ccb->csio.data_ptr;
 1005         gdtexecuteccb(gccb, segs, ccb->csio.sglist_cnt, 0);
 1006     }
 1007 
 1008     *lock = splcam();
 1009     return (gccb);
 1010 }
 1011 
 1012 static struct gdt_ccb *
 1013 gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock)
 1014 {
 1015     struct gdt_ccb *gccb;
 1016     u_int32_t cnt;
 1017 
 1018     GDT_DPRINTF(GDT_D_DEBUG, ("gdt_ioctl_cmd(%p, %p)\n", gdt, ucmd));
 1019 
 1020     bzero(gdt->sc_cmd, GDT_CMD_SZ);
 1021 
 1022     gccb = gdt_get_ccb(gdt);
 1023     if (gccb == NULL) {
 1024         GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n",
 1025                                   gdt->sc_hanum));
 1026         return (gccb);
 1027     }
 1028     gccb->gc_ucmd = ucmd;
 1029     gccb->gc_service = ucmd->service;
 1030     gccb->gc_flags = GDT_GCF_IOCTL;
 1031         
 1032     /* check DPMEM space, copy data buffer from user space */
 1033     if (ucmd->service == GDT_CACHESERVICE) {
 1034         if (ucmd->OpCode == GDT_IOCTL) {
 1035             gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_IOCTL_SZ,
 1036                                       sizeof(u_int32_t));
 1037             cnt = ucmd->u.ioctl.param_size;
 1038             if (cnt > GDT_SCRATCH_SZ) {
 1039                 printf("iir%d: Scratch buffer too small (%d/%d)\n", 
 1040                        gdt->sc_hanum, GDT_SCRATCH_SZ, cnt);
 1041                 gdt_free_ccb(gdt, gccb);
 1042                 return (NULL);
 1043             }
 1044         } else {
 1045             gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST +
 1046                                       GDT_SG_SZ, sizeof(u_int32_t));
 1047             cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE;
 1048             if (cnt > GDT_SCRATCH_SZ) {
 1049                 printf("iir%d: Scratch buffer too small (%d/%d)\n", 
 1050                        gdt->sc_hanum, GDT_SCRATCH_SZ, cnt);
 1051                 gdt_free_ccb(gdt, gccb);
 1052                 return (NULL);
 1053             }
 1054         }
 1055     } else {
 1056         gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_RAW_SG_LST +
 1057                                   GDT_SG_SZ, sizeof(u_int32_t));
 1058         cnt = ucmd->u.raw.sdlen;
 1059         if (cnt + ucmd->u.raw.sense_len > GDT_SCRATCH_SZ) {
 1060             printf("iir%d: Scratch buffer too small (%d/%d)\n", 
 1061                    gdt->sc_hanum, GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len);
 1062             gdt_free_ccb(gdt, gccb);
 1063             return (NULL);
 1064         }
 1065     }
 1066     if (cnt != 0) 
 1067         bcopy(ucmd->data, gccb->gc_scratch, cnt);
 1068 
 1069     if (gdt->sc_cmd_off + gdt->sc_cmd_len + GDT_DPMEM_COMMAND_OFFSET >
 1070         gdt->sc_ic_all_size) {
 1071         GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_ioctl_cmd(): DPMEM overflow\n", 
 1072                                     gdt->sc_hanum));
 1073         gdt_free_ccb(gdt, gccb);
 1074         return (NULL);
 1075     }
 1076 
 1077     if (gdt->sc_cmd_cnt == 0)
 1078         gdt->sc_set_sema0(gdt);
 1079     splx(*lock);
 1080 
 1081     /* fill cmd structure */
 1082     gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
 1083               gccb->gc_cmd_index);
 1084     gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, 
 1085               ucmd->OpCode);
 1086 
 1087     if (ucmd->service == GDT_CACHESERVICE) {
 1088         if (ucmd->OpCode == GDT_IOCTL) {
 1089             /* IOCTL */
 1090             gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + GDT_IOCTL_PARAM_SIZE,
 1091                       ucmd->u.ioctl.param_size);
 1092             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_IOCTL_SUBFUNC,
 1093                       ucmd->u.ioctl.subfunc);
 1094             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_IOCTL_CHANNEL,
 1095                       ucmd->u.ioctl.channel);
 1096             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_IOCTL_P_PARAM,
 1097                       gdt_ccb_vtop(gdt, gccb) + 
 1098                       offsetof(struct gdt_ccb, gc_scratch[0]));
 1099         } else {
 1100             /* cache service command */
 1101             gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO,
 1102                       ucmd->u.cache.DeviceNo);
 1103             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
 1104                       ucmd->u.cache.BlockNo);
 1105             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT,
 1106                       ucmd->u.cache.BlockCnt);
 1107             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR,
 1108                       0xffffffffUL);
 1109             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ,
 1110                       1);
 1111             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST + 
 1112                       GDT_SG_PTR, gdt_ccb_vtop(gdt, gccb) + 
 1113                       offsetof(struct gdt_ccb, gc_scratch[0]));
 1114             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
 1115                       GDT_SG_LEN, ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE);
 1116         }
 1117     } else {
 1118         /* raw service command */
 1119         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_DIRECTION,
 1120                   ucmd->u.raw.direction);
 1121         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SDATA,
 1122                   0xffffffffUL);
 1123         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SDLEN,
 1124                   ucmd->u.raw.sdlen);
 1125         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_CLEN,
 1126                   ucmd->u.raw.clen);
 1127         bcopy(ucmd->u.raw.cmd, gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_CMD,
 1128               12);
 1129         gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] = 
 1130             ucmd->u.raw.target;
 1131         gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] = 
 1132             ucmd->u.raw.lun;
 1133         gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] = 
 1134             ucmd->u.raw.bus;
 1135         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_LEN,
 1136                   ucmd->u.raw.sense_len);
 1137         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_DATA,
 1138                   gdt_ccb_vtop(gdt, gccb) + 
 1139                   offsetof(struct gdt_ccb, gc_scratch[ucmd->u.raw.sdlen]));
 1140         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_RANZ,
 1141                   1);
 1142         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST + 
 1143                   GDT_SG_PTR, gdt_ccb_vtop(gdt, gccb) + 
 1144                   offsetof(struct gdt_ccb, gc_scratch[0]));
 1145         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
 1146                   GDT_SG_LEN, ucmd->u.raw.sdlen);
 1147     }
 1148 
 1149     *lock = splcam();
 1150     gdt_stat.sg_count_act = 1;
 1151     gdt->sc_copy_cmd(gdt, gccb);
 1152     return (gccb);
 1153 }
 1154 
 1155 static void 
 1156 gdt_internal_cache_cmd(struct gdt_softc *gdt,union ccb *ccb)
 1157 {
 1158     int t;
 1159 
 1160     t = ccb->ccb_h.target_id;
 1161     GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cache_cmd(%p, %p, 0x%x, %d)\n", 
 1162         gdt, ccb, ccb->csio.cdb_io.cdb_bytes[0], t));
 1163 
 1164     switch (ccb->csio.cdb_io.cdb_bytes[0]) {
 1165       case TEST_UNIT_READY:
 1166       case START_STOP:
 1167         break;
 1168       case REQUEST_SENSE:
 1169         GDT_DPRINTF(GDT_D_MISC, ("REQUEST_SENSE\n"));
 1170         break;
 1171       case INQUIRY:
 1172         {
 1173             struct scsi_inquiry_data *inq;
 1174 
 1175             inq = (struct scsi_inquiry_data *)ccb->csio.data_ptr;       
 1176             bzero(inq, sizeof(struct scsi_inquiry_data));
 1177             inq->device = (gdt->sc_hdr[t].hd_devtype & 4) ?
 1178                 T_CDROM : T_DIRECT;
 1179             inq->dev_qual2 = (gdt->sc_hdr[t].hd_devtype & 1) ? 0x80 : 0;
 1180             inq->version = SCSI_REV_2;
 1181             inq->response_format = 2; 
 1182             inq->additional_length = 32; 
 1183             inq->flags = SID_CmdQue | SID_Sync; 
 1184             strcpy(inq->vendor, "IIR     ");
 1185             sprintf(inq->product, "Host Drive   #%02d", t);
 1186             strcpy(inq->revision, "   ");
 1187             break;
 1188         }
 1189       case MODE_SENSE_6:
 1190         {
 1191             struct mpd_data {
 1192                 struct scsi_mode_hdr_6 hd;
 1193                 struct scsi_mode_block_descr bd;
 1194                 struct scsi_control_page cp;
 1195             } *mpd;
 1196             u_int8_t page;
 1197 
 1198             mpd = (struct mpd_data *)ccb->csio.data_ptr;        
 1199             bzero(mpd, sizeof(struct mpd_data));
 1200             mpd->hd.datalen = sizeof(struct scsi_mode_hdr_6) +
 1201                 sizeof(struct scsi_mode_block_descr);
 1202             mpd->hd.dev_specific = (gdt->sc_hdr[t].hd_devtype & 2) ? 0x80 : 0;
 1203             mpd->hd.block_descr_len = sizeof(struct scsi_mode_block_descr);
 1204             mpd->bd.block_len[0] = (GDT_SECTOR_SIZE & 0x00ff0000) >> 16;
 1205             mpd->bd.block_len[1] = (GDT_SECTOR_SIZE & 0x0000ff00) >> 8;
 1206             mpd->bd.block_len[2] = (GDT_SECTOR_SIZE & 0x000000ff);
 1207             page=((struct scsi_mode_sense_6 *)ccb->csio.cdb_io.cdb_bytes)->page;
 1208             switch (page) {
 1209               default:
 1210                 GDT_DPRINTF(GDT_D_MISC, ("MODE_SENSE_6: page 0x%x\n", page));
 1211                 break;
 1212             }
 1213             break;
 1214         }
 1215       case READ_CAPACITY:
 1216         {
 1217             struct scsi_read_capacity_data *rcd;
 1218               
 1219             rcd = (struct scsi_read_capacity_data *)ccb->csio.data_ptr; 
 1220             bzero(rcd, sizeof(struct scsi_read_capacity_data));
 1221             scsi_ulto4b(gdt->sc_hdr[t].hd_size - 1, rcd->addr);
 1222             scsi_ulto4b(GDT_SECTOR_SIZE, rcd->length);
 1223             break;
 1224         }
 1225       default:
 1226         GDT_DPRINTF(GDT_D_MISC, ("gdt_internal_cache_cmd(%d) unknown\n", 
 1227                                     ccb->csio.cdb_io.cdb_bytes[0]));
 1228         break;
 1229     }
 1230     ccb->ccb_h.status = CAM_REQ_CMP;
 1231     --gdt_stat.io_count_act;
 1232     xpt_done(ccb);
 1233 }
 1234 
 1235 static void     
 1236 gdtmapmem(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 1237 {
 1238     bus_addr_t *busaddrp;
 1239     
 1240     busaddrp = (bus_addr_t *)arg;
 1241     *busaddrp = dm_segs->ds_addr;
 1242 }
 1243 
 1244 static void     
 1245 gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 1246 {
 1247     struct gdt_ccb *gccb;
 1248     union ccb *ccb;
 1249     struct gdt_softc *gdt;
 1250     int i, lock;
 1251 
 1252     lock = splcam();
 1253 
 1254     gccb = (struct gdt_ccb *)arg;
 1255     ccb = gccb->gc_ccb;
 1256     gdt = cam_sim_softc((struct cam_sim *)ccb->ccb_h.ccb_sim_ptr);
 1257 
 1258     GDT_DPRINTF(GDT_D_CMD, ("gdtexecuteccb(%p, %p, %p, %d, %d)\n", 
 1259                             gdt, gccb, dm_segs, nseg, error));
 1260     gdt_stat.sg_count_act = nseg;
 1261     if (nseg > gdt_stat.sg_count_max)
 1262         gdt_stat.sg_count_max = nseg;
 1263 
 1264     /* Copy the segments into our SG list */
 1265     if (gccb->gc_service == GDT_CACHESERVICE) {
 1266         for (i = 0; i < nseg; ++i) {
 1267             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
 1268                       i * GDT_SG_SZ + GDT_SG_PTR, dm_segs->ds_addr);
 1269             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
 1270                       i * GDT_SG_SZ + GDT_SG_LEN, dm_segs->ds_len);
 1271             dm_segs++;
 1272         }
 1273         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ,      
 1274                   nseg);
 1275         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR, 
 1276                   0xffffffffUL);
 1277 
 1278         gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST +
 1279                                   nseg * GDT_SG_SZ, sizeof(u_int32_t));
 1280     } else {
 1281         for (i = 0; i < nseg; ++i) {
 1282             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
 1283                       i * GDT_SG_SZ + GDT_SG_PTR, dm_segs->ds_addr);
 1284             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
 1285                       i * GDT_SG_SZ + GDT_SG_LEN, dm_segs->ds_len);
 1286             dm_segs++;
 1287         }
 1288         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SG_RANZ,        
 1289                   nseg);
 1290         gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_RAW_SDATA, 
 1291                   0xffffffffUL);
 1292 
 1293         gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_RAW_SG_LST +
 1294                                   nseg * GDT_SG_SZ, sizeof(u_int32_t));
 1295     }
 1296 
 1297     if (nseg != 0) {
 1298         bus_dmasync_op_t op;
 1299 
 1300         if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 1301             op = BUS_DMASYNC_PREREAD;
 1302         else
 1303             op = BUS_DMASYNC_PREWRITE;
 1304         bus_dmamap_sync(gdt->sc_buffer_dmat, gccb->gc_dmamap, op);
 1305     }
 1306     
 1307     /* We must NOT abort the command here if CAM_REQ_INPROG is not set,
 1308      * because command semaphore is already set!
 1309      */
 1310     
 1311     ccb->ccb_h.status |= CAM_SIM_QUEUED;
 1312     /* timeout handling */
 1313     ccb->ccb_h.timeout_ch =
 1314         timeout(iir_timeout, (caddr_t)gccb,
 1315                 (ccb->ccb_h.timeout * hz) / 1000);
 1316 
 1317     gdt->sc_copy_cmd(gdt, gccb);
 1318     splx(lock);
 1319 }
 1320 
 1321 
 1322 static void     
 1323 iir_action( struct cam_sim *sim, union ccb *ccb )
 1324 {
 1325     struct gdt_softc *gdt;
 1326     int lock, bus, target, lun;
 1327 
 1328     gdt = (struct gdt_softc *)cam_sim_softc( sim );
 1329     ccb->ccb_h.ccb_sim_ptr = sim;
 1330     bus = cam_sim_bus(sim);
 1331     target = ccb->ccb_h.target_id;
 1332     lun = ccb->ccb_h.target_lun;
 1333     GDT_DPRINTF(GDT_D_CMD, 
 1334                 ("iir_action(%p) func 0x%x cmd 0x%x bus %d target %d lun %d\n", 
 1335                  gdt, ccb->ccb_h.func_code, ccb->csio.cdb_io.cdb_bytes[0], 
 1336                  bus, target, lun)); 
 1337     ++gdt_stat.io_count_act;
 1338     if (gdt_stat.io_count_act > gdt_stat.io_count_max)
 1339         gdt_stat.io_count_max = gdt_stat.io_count_act;
 1340 
 1341     switch (ccb->ccb_h.func_code) {
 1342       case XPT_SCSI_IO:
 1343         lock = splcam();
 1344         TAILQ_INSERT_TAIL(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
 1345         ++gdt_stat.req_queue_act;
 1346         if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
 1347             gdt_stat.req_queue_max = gdt_stat.req_queue_act;
 1348         splx(lock);
 1349         gdt_next(gdt);
 1350         break;
 1351       case XPT_RESET_DEV:   /* Bus Device Reset the specified SCSI device */
 1352       case XPT_ABORT:                       /* Abort the specified CCB */
 1353         /* XXX Implement */
 1354         ccb->ccb_h.status = CAM_REQ_INVALID;
 1355         --gdt_stat.io_count_act;
 1356         xpt_done(ccb);
 1357         break;
 1358       case XPT_SET_TRAN_SETTINGS:
 1359         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 1360         --gdt_stat.io_count_act;
 1361         xpt_done(ccb);  
 1362         break;
 1363       case XPT_GET_TRAN_SETTINGS:
 1364         /* Get default/user set transfer settings for the target */
 1365           {
 1366               struct        ccb_trans_settings *cts;
 1367               u_int target_mask;
 1368               
 1369               cts = &ccb->cts;
 1370               target_mask = 0x01 << target;
 1371               if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 
 1372                   cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB;
 1373                   cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 1374                   cts->sync_period = 25; /* 10MHz */
 1375                   if (cts->sync_period != 0)
 1376                       cts->sync_offset = 15;
 1377                   
 1378                   cts->valid = CCB_TRANS_SYNC_RATE_VALID
 1379                       | CCB_TRANS_SYNC_OFFSET_VALID
 1380                       | CCB_TRANS_BUS_WIDTH_VALID
 1381                       | CCB_TRANS_DISC_VALID
 1382                       | CCB_TRANS_TQ_VALID;
 1383                   ccb->ccb_h.status = CAM_REQ_CMP;
 1384               } else {
 1385                   ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 1386               }
 1387               --gdt_stat.io_count_act;
 1388               xpt_done(ccb);
 1389               break;
 1390           }
 1391       case XPT_CALC_GEOMETRY:
 1392           {
 1393               struct ccb_calc_geometry *ccg;
 1394               u_int32_t secs_per_cylinder;
 1395 
 1396               ccg = &ccb->ccg;
 1397               ccg->heads = gdt->sc_hdr[target].hd_heads;
 1398               ccg->secs_per_track = gdt->sc_hdr[target].hd_secs;
 1399               secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 1400               ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 1401               ccb->ccb_h.status = CAM_REQ_CMP;
 1402               --gdt_stat.io_count_act;
 1403               xpt_done(ccb);
 1404               break;
 1405           }
 1406       case XPT_RESET_BUS:           /* Reset the specified SCSI bus */
 1407           {
 1408               /* XXX Implement */
 1409               ccb->ccb_h.status = CAM_REQ_CMP;
 1410               --gdt_stat.io_count_act;
 1411               xpt_done(ccb);
 1412               break;
 1413           }
 1414       case XPT_TERM_IO:             /* Terminate the I/O process */
 1415         /* XXX Implement */
 1416         ccb->ccb_h.status = CAM_REQ_INVALID;
 1417         --gdt_stat.io_count_act;
 1418         xpt_done(ccb);
 1419         break;
 1420       case XPT_PATH_INQ:            /* Path routing inquiry */
 1421           {
 1422               struct ccb_pathinq *cpi = &ccb->cpi;
 1423               
 1424               cpi->version_num = 1;
 1425               cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
 1426               cpi->hba_inquiry |= PI_WIDE_16;
 1427               cpi->target_sprt = 1;
 1428               cpi->hba_misc = 0;
 1429               cpi->hba_eng_cnt = 0;
 1430               if (bus == gdt->sc_virt_bus)
 1431                   cpi->max_target = GDT_MAX_HDRIVES - 1;
 1432               else if (gdt->sc_class & GDT_FC)
 1433                   cpi->max_target = GDT_MAXID_FC - 1;
 1434               else
 1435                   cpi->max_target = GDT_MAXID - 1;
 1436               cpi->max_lun = 7;
 1437               cpi->unit_number = cam_sim_unit(sim);
 1438               cpi->bus_id = bus;
 1439               cpi->initiator_id = 
 1440                   (bus == gdt->sc_virt_bus ? 127 : gdt->sc_bus_id[bus]);
 1441               cpi->base_transfer_speed = 3300;
 1442               strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 1443               strncpy(cpi->hba_vid, "Intel Corp.", HBA_IDLEN);
 1444               strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 1445               cpi->ccb_h.status = CAM_REQ_CMP;
 1446               --gdt_stat.io_count_act;
 1447               xpt_done(ccb);
 1448               break;
 1449           }
 1450       default:
 1451         GDT_DPRINTF(GDT_D_INVALID, ("gdt_next(%p) cmd 0x%x invalid\n", 
 1452                                     gdt, ccb->ccb_h.func_code));
 1453         ccb->ccb_h.status = CAM_REQ_INVALID;
 1454         --gdt_stat.io_count_act;
 1455         xpt_done(ccb);
 1456         break;
 1457     }
 1458 }
 1459 
 1460 static void     
 1461 iir_poll( struct cam_sim *sim )
 1462 {
 1463     struct gdt_softc *gdt;
 1464 
 1465     gdt = (struct gdt_softc *)cam_sim_softc( sim );
 1466     GDT_DPRINTF(GDT_D_CMD, ("iir_poll sim %p gdt %p\n", sim, gdt));
 1467     iir_intr(gdt);
 1468 }
 1469 
 1470 static void     
 1471 iir_timeout(void *arg)
 1472 {
 1473     GDT_DPRINTF(GDT_D_TIMEOUT, ("iir_timeout(%p)\n", arg));
 1474 }
 1475 
 1476 static void
 1477 iir_watchdog(void *arg)
 1478 {
 1479     struct gdt_softc *gdt;
 1480 
 1481     gdt = (struct gdt_softc *)arg;
 1482     GDT_DPRINTF(GDT_D_DEBUG, ("iir_watchdog(%p)\n", gdt));
 1483 
 1484     {
 1485         int ccbs = 0, ucmds = 0, frees = 0, pends = 0;
 1486         struct gdt_ccb *p;
 1487         struct ccb_hdr *h;
 1488         struct gdt_ucmd *u;
 1489 
 1490         for (h = TAILQ_FIRST(&gdt->sc_ccb_queue); h != NULL; 
 1491              h = TAILQ_NEXT(h, sim_links.tqe))
 1492             ccbs++;
 1493         for (u = TAILQ_FIRST(&gdt->sc_ucmd_queue); u != NULL; 
 1494              u = TAILQ_NEXT(u, links))
 1495             ucmds++;
 1496         for (p = SLIST_FIRST(&gdt->sc_free_gccb); p != NULL; 
 1497              p = SLIST_NEXT(p, sle))
 1498             frees++;
 1499         for (p = SLIST_FIRST(&gdt->sc_pending_gccb); p != NULL; 
 1500              p = SLIST_NEXT(p, sle))
 1501             pends++;
 1502 
 1503         GDT_DPRINTF(GDT_D_TIMEOUT, ("ccbs %d ucmds %d frees %d pends %d\n",
 1504                                     ccbs, ucmds, frees, pends));
 1505     }
 1506 
 1507     timeout(iir_watchdog, (caddr_t)gdt, hz * 15);
 1508 }
 1509 
 1510 static void     
 1511 iir_shutdown( void *arg, int howto )
 1512 {
 1513     struct gdt_softc *gdt;
 1514     struct gdt_ccb *gccb;
 1515     gdt_ucmd_t *ucmd;
 1516     int lock, i;
 1517 
 1518     gdt = (struct gdt_softc *)arg;
 1519     GDT_DPRINTF(GDT_D_CMD, ("iir_shutdown(%p, %d)\n", gdt, howto));
 1520 
 1521     printf("iir%d: Flushing all Host Drives. Please wait ...  ",
 1522            gdt->sc_hanum);
 1523 
 1524     /* allocate ucmd buffer */
 1525     ucmd = malloc(sizeof(gdt_ucmd_t), M_DEVBUF, M_NOWAIT);
 1526     if (ucmd == NULL) {
 1527         printf("iir%d: iir_shutdown(): Cannot allocate resource\n",
 1528                gdt->sc_hanum);
 1529         return;
 1530     }
 1531     bzero(ucmd, sizeof(gdt_ucmd_t));
 1532 
 1533     /* wait for pending IOs */
 1534     lock = splcam();
 1535     gdt->sc_state = GDT_SHUTDOWN;
 1536     splx(lock);
 1537     if ((gccb = SLIST_FIRST(&gdt->sc_pending_gccb)) != NULL)
 1538         (void) tsleep((void *)gccb, PCATCH | PRIBIO, "iirshw", 100 * hz);
 1539 
 1540     /* flush */
 1541     for (i = 0; i < GDT_MAX_HDRIVES; ++i) {
 1542         if (gdt->sc_hdr[i].hd_present) {
 1543             ucmd->service = GDT_CACHESERVICE;
 1544             ucmd->OpCode = GDT_FLUSH;
 1545             ucmd->u.cache.DeviceNo = i;
 1546             lock = splcam();
 1547             TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links);
 1548             ucmd->complete_flag = FALSE;
 1549             splx(lock);
 1550             gdt_next(gdt);
 1551             if (!ucmd->complete_flag)
 1552                 (void) tsleep((void *)ucmd, PCATCH|PRIBIO, "iirshw", 10*hz);
 1553         }
 1554     }
 1555 
 1556     free(ucmd, M_DEVBUF);
 1557     printf("Done.\n");
 1558 }
 1559 
 1560 void
 1561 iir_intr(void *arg)
 1562 {
 1563     struct gdt_softc *gdt = arg;
 1564     struct gdt_intr_ctx ctx;
 1565     int lock = 0;
 1566     struct gdt_ccb *gccb;
 1567     gdt_ucmd_t *ucmd;
 1568     u_int32_t cnt;
 1569 
 1570     GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p)\n", gdt));
 1571 
 1572     /* If polling and we were not called from gdt_wait, just return */
 1573     if ((gdt->sc_state & GDT_POLLING) &&
 1574         !(gdt->sc_state & GDT_POLL_WAIT))
 1575         return;
 1576 
 1577     if (!(gdt->sc_state & GDT_POLLING)) 
 1578         lock = splcam();
 1579     gdt_wait_index = 0;
 1580 
 1581     ctx.istatus = gdt->sc_get_status(gdt);
 1582     if (!ctx.istatus) {
 1583         if (!(gdt->sc_state & GDT_POLLING)) 
 1584             splx(lock);
 1585         gdt->sc_status = GDT_S_NO_STATUS;
 1586         return;
 1587     }
 1588 
 1589     gdt->sc_intr(gdt, &ctx);
 1590 
 1591     gdt->sc_status = ctx.cmd_status;
 1592     gdt->sc_service = ctx.service;
 1593     gdt->sc_info = ctx.info;
 1594     gdt->sc_info2 = ctx.info2;
 1595 
 1596     if (gdt->sc_state & GDT_POLL_WAIT) { 
 1597         gdt_wait_gdt = gdt;
 1598         gdt_wait_index = ctx.istatus;
 1599     }
 1600 
 1601     if (ctx.istatus == GDT_ASYNCINDEX) {
 1602         gdt_async_event(gdt, ctx.service);
 1603         if (!(gdt->sc_state & GDT_POLLING)) 
 1604             splx(lock);
 1605         return;
 1606     }
 1607     if (ctx.istatus == GDT_SPEZINDEX) {
 1608         GDT_DPRINTF(GDT_D_INVALID, 
 1609                     ("iir%d: Service unknown or not initialized!\n", 
 1610                      gdt->sc_hanum));   
 1611         gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
 1612         gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
 1613         gdt_store_event(GDT_ES_DRIVER, 4, &gdt->sc_dvr);
 1614         if (!(gdt->sc_state & GDT_POLLING)) 
 1615             splx(lock);
 1616         return;
 1617     }
 1618 
 1619     gccb = &gdt->sc_gccbs[ctx.istatus - 2];
 1620     ctx.service = gccb->gc_service;
 1621 
 1622     switch (gccb->gc_flags) {
 1623       case GDT_GCF_UNUSED:
 1624         GDT_DPRINTF(GDT_D_INVALID, ("iir%d: Index (%d) to unused command!\n",
 1625                     gdt->sc_hanum, ctx.istatus));
 1626         gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
 1627         gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
 1628         gdt->sc_dvr.eu.driver.index = ctx.istatus;
 1629         gdt_store_event(GDT_ES_DRIVER, 1, &gdt->sc_dvr);
 1630         gdt_free_ccb(gdt, gccb);
 1631         /* fallthrough */
 1632 
 1633       case GDT_GCF_INTERNAL:
 1634         if (!(gdt->sc_state & GDT_POLLING)) 
 1635             splx(lock);
 1636         break;
 1637 
 1638       case GDT_GCF_IOCTL:
 1639         ucmd = gccb->gc_ucmd; 
 1640         if (gdt->sc_status == GDT_S_BSY) {
 1641             GDT_DPRINTF(GDT_D_DEBUG, ("iir_intr(%p) ioctl: gccb %p busy\n", 
 1642                                       gdt, gccb));
 1643             TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links);
 1644             if (!(gdt->sc_state & GDT_POLLING)) 
 1645                 splx(lock);
 1646         } else {
 1647             ucmd->status = gdt->sc_status;
 1648             ucmd->info = gdt->sc_info;
 1649             ucmd->complete_flag = TRUE;
 1650             if (ucmd->service == GDT_CACHESERVICE) {
 1651                 if (ucmd->OpCode == GDT_IOCTL) {
 1652                     cnt = ucmd->u.ioctl.param_size;
 1653                     if (cnt != 0)
 1654                         bcopy(gccb->gc_scratch, ucmd->data, cnt);
 1655                 } else {
 1656                     cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE;
 1657                     if (cnt != 0)
 1658                         bcopy(gccb->gc_scratch, ucmd->data, cnt);
 1659                 }
 1660             } else {
 1661                 cnt = ucmd->u.raw.sdlen;
 1662                 if (cnt != 0)
 1663                     bcopy(gccb->gc_scratch, ucmd->data, cnt);
 1664                 if (ucmd->u.raw.sense_len != 0) 
 1665                     bcopy(gccb->gc_scratch, ucmd->data, cnt);
 1666             }
 1667             gdt_free_ccb(gdt, gccb);
 1668             if (!(gdt->sc_state & GDT_POLLING)) 
 1669                 splx(lock);
 1670             /* wakeup */
 1671             wakeup(ucmd);
 1672         }
 1673         gdt_next(gdt); 
 1674         break;
 1675 
 1676       default:
 1677         gdt_free_ccb(gdt, gccb);
 1678         gdt_sync_event(gdt, ctx.service, ctx.istatus, gccb);
 1679         if (!(gdt->sc_state & GDT_POLLING)) 
 1680             splx(lock);
 1681         gdt_next(gdt); 
 1682         break;
 1683     }
 1684 }
 1685 
 1686 int
 1687 gdt_async_event(struct gdt_softc *gdt, int service)
 1688 {
 1689     struct gdt_ccb *gccb;
 1690 
 1691     GDT_DPRINTF(GDT_D_INTR, ("gdt_async_event(%p, %d)\n", gdt, service));
 1692 
 1693     if (service == GDT_SCREENSERVICE) {
 1694         if (gdt->sc_status == GDT_MSG_REQUEST) {
 1695             while (gdt->sc_test_busy(gdt))
 1696                 DELAY(1);
 1697             bzero(gdt->sc_cmd, GDT_CMD_SZ);
 1698             gccb = gdt_get_ccb(gdt);
 1699             if (gccb == NULL) {
 1700                 printf("iir%d: No free command index found\n",
 1701                        gdt->sc_hanum);
 1702                 return (1);
 1703             }
 1704             gccb->gc_service = service;
 1705             gccb->gc_flags = GDT_GCF_SCREEN;
 1706             gdt->sc_set_sema0(gdt);
 1707             gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
 1708                       gccb->gc_cmd_index);
 1709             gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, GDT_READ);
 1710             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
 1711                       GDT_MSG_INV_HANDLE);
 1712             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
 1713                       gdt_ccb_vtop(gdt, gccb) + 
 1714                       offsetof(struct gdt_ccb, gc_scratch[0]));
 1715             gdt->sc_cmd_off = 0;
 1716             gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ, 
 1717                                       sizeof(u_int32_t));
 1718             gdt->sc_cmd_cnt = 0;
 1719             gdt->sc_copy_cmd(gdt, gccb);
 1720             printf("iir%d: [PCI %d/%d] ",
 1721                 gdt->sc_hanum,gdt->sc_bus,gdt->sc_slot);
 1722             gdt->sc_release_event(gdt);
 1723         }
 1724 
 1725     } else {
 1726         if ((gdt->sc_fw_vers & 0xff) >= 0x1a) {
 1727             gdt->sc_dvr.size = 0;
 1728             gdt->sc_dvr.eu.async.ionode = gdt->sc_hanum;
 1729             gdt->sc_dvr.eu.async.status  = gdt->sc_status;
 1730             /* severity and event_string already set! */
 1731         } else {        
 1732             gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.async);
 1733             gdt->sc_dvr.eu.async.ionode   = gdt->sc_hanum;
 1734             gdt->sc_dvr.eu.async.service = service;
 1735             gdt->sc_dvr.eu.async.status  = gdt->sc_status;
 1736             gdt->sc_dvr.eu.async.info    = gdt->sc_info;
 1737             *(u_int32_t *)gdt->sc_dvr.eu.async.scsi_coord  = gdt->sc_info2;
 1738         }
 1739         gdt_store_event(GDT_ES_ASYNC, service, &gdt->sc_dvr);
 1740         printf("iir%d: %s\n", gdt->sc_hanum, gdt->sc_dvr.event_string);
 1741     }
 1742     
 1743     return (0);
 1744 }
 1745 
 1746 int
 1747 gdt_sync_event(struct gdt_softc *gdt, int service, 
 1748                u_int8_t index, struct gdt_ccb *gccb)
 1749 {
 1750     union ccb *ccb;
 1751     bus_dmasync_op_t op;
 1752 
 1753     GDT_DPRINTF(GDT_D_INTR,
 1754                 ("gdt_sync_event(%p, %d, %d, %p)\n", gdt,service,index,gccb));
 1755 
 1756     ccb = gccb->gc_ccb;
 1757 
 1758     if (service == GDT_SCREENSERVICE) {
 1759         u_int32_t msg_len;
 1760 
 1761         msg_len = gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_LEN);
 1762         if (msg_len)
 1763             if (!(gccb->gc_scratch[GDT_SCR_MSG_ANSWER] && 
 1764                   gccb->gc_scratch[GDT_SCR_MSG_EXT])) {
 1765                 gccb->gc_scratch[GDT_SCR_MSG_TEXT + msg_len] = '\0';
 1766                 printf("%s",&gccb->gc_scratch[GDT_SCR_MSG_TEXT]);
 1767             }
 1768 
 1769         if (gccb->gc_scratch[GDT_SCR_MSG_EXT] && 
 1770             !gccb->gc_scratch[GDT_SCR_MSG_ANSWER]) {
 1771             while (gdt->sc_test_busy(gdt))
 1772                 DELAY(1);
 1773             bzero(gdt->sc_cmd, GDT_CMD_SZ);
 1774             gccb = gdt_get_ccb(gdt);
 1775             if (gccb == NULL) {
 1776                 printf("iir%d: No free command index found\n",
 1777                        gdt->sc_hanum);
 1778                 return (1);
 1779             }
 1780             gccb->gc_service = service;
 1781             gccb->gc_flags = GDT_GCF_SCREEN;
 1782             gdt->sc_set_sema0(gdt);
 1783             gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
 1784                       gccb->gc_cmd_index);
 1785             gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, GDT_READ);
 1786             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
 1787                       gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
 1788             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
 1789                       gdt_ccb_vtop(gdt, gccb) + 
 1790                       offsetof(struct gdt_ccb, gc_scratch[0]));
 1791             gdt->sc_cmd_off = 0;
 1792             gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ, 
 1793                                       sizeof(u_int32_t));
 1794             gdt->sc_cmd_cnt = 0;
 1795             gdt->sc_copy_cmd(gdt, gccb);
 1796             gdt->sc_release_event(gdt);
 1797             return (0);
 1798         }
 1799 
 1800         if (gccb->gc_scratch[GDT_SCR_MSG_ANSWER] && 
 1801             gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN)) {
 1802             /* default answers (getchar() not possible) */
 1803             if (gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) == 1) {
 1804                 gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN, 0);
 1805                 gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 1);
 1806                 gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 0;
 1807             } else {
 1808                 gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN, 
 1809                           gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) - 2);
 1810                 gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 2);
 1811                 gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 1;
 1812                 gccb->gc_scratch[GDT_SCR_MSG_TEXT + 1] = 0;
 1813             }
 1814             gccb->gc_scratch[GDT_SCR_MSG_EXT] = 0;
 1815             gccb->gc_scratch[GDT_SCR_MSG_ANSWER] = 0;
 1816             while (gdt->sc_test_busy(gdt))
 1817                 DELAY(1);
 1818             bzero(gdt->sc_cmd, GDT_CMD_SZ);
 1819             gccb = gdt_get_ccb(gdt);
 1820             if (gccb == NULL) {
 1821                 printf("iir%d: No free command index found\n",
 1822                        gdt->sc_hanum);
 1823                 return (1);
 1824             }
 1825             gccb->gc_service = service;
 1826             gccb->gc_flags = GDT_GCF_SCREEN;
 1827             gdt->sc_set_sema0(gdt);
 1828             gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
 1829                       gccb->gc_cmd_index);
 1830             gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, GDT_WRITE);
 1831             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
 1832                       gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
 1833             gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
 1834                       gdt_ccb_vtop(gdt, gccb) + 
 1835                       offsetof(struct gdt_ccb, gc_scratch[0]));
 1836             gdt->sc_cmd_off = 0;
 1837             gdt->sc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ, 
 1838                                       sizeof(u_int32_t));
 1839             gdt->sc_cmd_cnt = 0;
 1840             gdt->sc_copy_cmd(gdt, gccb);
 1841             gdt->sc_release_event(gdt);
 1842             return (0);
 1843         }
 1844         printf("\n");
 1845         return (0);
 1846     } else {
 1847         untimeout(iir_timeout, gccb, ccb->ccb_h.timeout_ch);
 1848         if (gdt->sc_status == GDT_S_BSY) {
 1849             GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n", 
 1850                                       gdt, gccb));
 1851             TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
 1852             ++gdt_stat.req_queue_act;
 1853             if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
 1854                 gdt_stat.req_queue_max = gdt_stat.req_queue_act;
 1855             return (2);
 1856         }
 1857 
 1858         if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 1859             op = BUS_DMASYNC_POSTREAD;
 1860         else
 1861             op = BUS_DMASYNC_POSTWRITE;
 1862         bus_dmamap_sync(gdt->sc_buffer_dmat, gccb->gc_dmamap, op);
 1863 
 1864         ccb->csio.resid = 0;
 1865         if (gdt->sc_status == GDT_S_OK) {
 1866             ccb->ccb_h.status = CAM_REQ_CMP;
 1867         } else {
 1868             /* error */
 1869             if (gccb->gc_service == GDT_CACHESERVICE) {
 1870                 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
 1871                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 1872                 bzero(&ccb->csio.sense_data, ccb->csio.sense_len);
 1873                 ccb->csio.sense_data.error_code =
 1874                     SSD_CURRENT_ERROR | SSD_ERRCODE_VALID;
 1875                 ccb->csio.sense_data.flags = SSD_KEY_NOT_READY;
 1876 
 1877                 gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.sync);
 1878                 gdt->sc_dvr.eu.sync.ionode  = gdt->sc_hanum;
 1879                 gdt->sc_dvr.eu.sync.service = service;
 1880                 gdt->sc_dvr.eu.sync.status  = gdt->sc_status;
 1881                 gdt->sc_dvr.eu.sync.info    = gdt->sc_info;
 1882                 gdt->sc_dvr.eu.sync.hostdrive = ccb->ccb_h.target_id;
 1883                 if (gdt->sc_status >= 0x8000)
 1884                     gdt_store_event(GDT_ES_SYNC, 0, &gdt->sc_dvr);
 1885                 else
 1886                     gdt_store_event(GDT_ES_SYNC, service, &gdt->sc_dvr);
 1887             } else {
 1888                 /* raw service */
 1889                 if (gdt->sc_status != GDT_S_RAW_SCSI || gdt->sc_info >= 0x100) {
 1890                     ccb->ccb_h.status = CAM_SEL_TIMEOUT;
 1891                 } else {
 1892                     ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID;
 1893                     ccb->csio.scsi_status = gdt->sc_info;
 1894                     bcopy(gccb->gc_scratch, &ccb->csio.sense_data,
 1895                           ccb->csio.sense_len);
 1896                 }
 1897             }
 1898         }
 1899         --gdt_stat.io_count_act;
 1900         xpt_done(ccb);
 1901     }
 1902     return (0);
 1903 }
 1904 
 1905 /* Controller event handling functions */
 1906 gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx,
 1907                              gdt_evt_data *evt)
 1908 {
 1909     gdt_evt_str *e;
 1910     struct timeval tv;
 1911 
 1912     GDT_DPRINTF(GDT_D_MISC, ("gdt_store_event(%d, %d)\n", source, idx));
 1913     if (source == 0)                        /* no source -> no event */
 1914         return 0;
 1915 
 1916     if (ebuffer[elastidx].event_source == source &&
 1917         ebuffer[elastidx].event_idx == idx &&
 1918         ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 &&
 1919           !memcmp((char *)&ebuffer[elastidx].event_data.eu,
 1920                   (char *)&evt->eu, evt->size)) ||
 1921          (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 &&
 1922           !strcmp((char *)&ebuffer[elastidx].event_data.event_string,
 1923                   (char *)&evt->event_string)))) { 
 1924         e = &ebuffer[elastidx];
 1925         getmicrotime(&tv);
 1926         e->last_stamp = tv.tv_sec;
 1927         ++e->same_count;
 1928     } else {
 1929         if (ebuffer[elastidx].event_source != 0) {  /* entry not free ? */
 1930             ++elastidx;
 1931             if (elastidx == GDT_MAX_EVENTS)
 1932                 elastidx = 0;
 1933             if (elastidx == eoldidx) {              /* reached mark ? */
 1934                 ++eoldidx;
 1935                 if (eoldidx == GDT_MAX_EVENTS)
 1936                     eoldidx = 0;
 1937             }
 1938         }
 1939         e = &ebuffer[elastidx];
 1940         e->event_source = source;
 1941         e->event_idx = idx;
 1942         getmicrotime(&tv);
 1943         e->first_stamp = e->last_stamp = tv.tv_sec;
 1944         e->same_count = 1;
 1945         e->event_data = *evt;
 1946         e->application = 0;
 1947     }
 1948     return e;
 1949 }
 1950 
 1951 int gdt_read_event(int handle, gdt_evt_str *estr)
 1952 {
 1953     gdt_evt_str *e;
 1954     int eindex, lock;
 1955     
 1956     GDT_DPRINTF(GDT_D_MISC, ("gdt_read_event(%d)\n", handle));
 1957     lock = splcam();
 1958     if (handle == -1)
 1959         eindex = eoldidx;
 1960     else
 1961         eindex = handle;
 1962     estr->event_source = 0;
 1963 
 1964     if (eindex >= GDT_MAX_EVENTS) {
 1965         splx(lock);
 1966         return eindex;
 1967     }
 1968     e = &ebuffer[eindex];
 1969     if (e->event_source != 0) {
 1970         if (eindex != elastidx) {
 1971             if (++eindex == GDT_MAX_EVENTS)
 1972                 eindex = 0;
 1973         } else {
 1974             eindex = -1;
 1975         }
 1976         memcpy(estr, e, sizeof(gdt_evt_str));
 1977     }
 1978     splx(lock);
 1979     return eindex;
 1980 }
 1981 
 1982 void gdt_readapp_event(u_int8_t application, gdt_evt_str *estr)
 1983 {
 1984     gdt_evt_str *e;
 1985     int found = FALSE;
 1986     int eindex, lock;
 1987     
 1988     GDT_DPRINTF(GDT_D_MISC, ("gdt_readapp_event(%d)\n", application));
 1989     lock = splcam();
 1990     eindex = eoldidx;
 1991     for (;;) {
 1992         e = &ebuffer[eindex];
 1993         if (e->event_source == 0)
 1994             break;
 1995         if ((e->application & application) == 0) {
 1996             e->application |= application;
 1997             found = TRUE;
 1998             break;
 1999         }
 2000         if (eindex == elastidx)
 2001             break;
 2002         if (++eindex == GDT_MAX_EVENTS)
 2003             eindex = 0;
 2004     }
 2005     if (found)
 2006         memcpy(estr, e, sizeof(gdt_evt_str));
 2007     else
 2008         estr->event_source = 0;
 2009     splx(lock);
 2010 }
 2011 
 2012 void gdt_clear_events()
 2013 {
 2014     GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events\n"));
 2015 
 2016     eoldidx = elastidx = 0;
 2017     ebuffer[0].event_source = 0;
 2018 }

Cache object: 928dc8d8bb35bb247a2c8fb44c5258d2


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