[BACK]Return to gdt_common.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/gdt_common.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: gdt_common.c,v 1.39 2007/04/28 00:35:16 deraadt Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1999, 2000, 2003 Niklas Hallqvist.  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:  * 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:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     20:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     21:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     22:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     23:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     24:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: /*
                     28:  * This driver would not have written if it was not for the hardware donations
                     29:  * from both ICP-Vortex and Öko.neT.  I want to thank them for their support.
                     30:  */
                     31:
                     32: #include <sys/param.h>
                     33: #include <sys/buf.h>
                     34: #include <sys/device.h>
                     35: #include <sys/ioctl.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/malloc.h>
                     38: #include <sys/systm.h>
                     39:
                     40: #include <machine/bus.h>
                     41:
                     42: #include <uvm/uvm_extern.h>
                     43:
                     44: #include <scsi/scsi_all.h>
                     45: #include <scsi/scsi_disk.h>
                     46: #include <scsi/scsiconf.h>
                     47:
                     48: #include <dev/biovar.h>
                     49: #include <dev/ic/gdtreg.h>
                     50: #include <dev/ic/gdtvar.h>
                     51:
                     52: #include "bio.h"
                     53:
                     54: #ifdef GDT_DEBUG
                     55: int gdt_maxcmds = GDT_MAXCMDS;
                     56: #undef GDT_MAXCMDS
                     57: #define GDT_MAXCMDS gdt_maxcmds
                     58: #endif
                     59:
                     60: #define GDT_DRIVER_VERSION 1
                     61: #define GDT_DRIVER_SUBVERSION 2
                     62:
                     63: int    gdt_async_event(struct gdt_softc *, int);
                     64: void   gdt_chain(struct gdt_softc *);
                     65: void   gdt_clear_events(struct gdt_softc *);
                     66: void   gdt_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t);
                     67: struct scsi_xfer *gdt_dequeue(struct gdt_softc *);
                     68: void   gdt_enqueue(struct gdt_softc *, struct scsi_xfer *, int);
                     69: void   gdt_enqueue_ccb(struct gdt_softc *, struct gdt_ccb *);
                     70: void   gdt_eval_mapping(u_int32_t, int *, int *, int *);
                     71: int    gdt_exec_ccb(struct gdt_ccb *);
                     72: void   gdt_free_ccb(struct gdt_softc *, struct gdt_ccb *);
                     73: struct gdt_ccb *gdt_get_ccb(struct gdt_softc *, int);
                     74: void   gdt_internal_cache_cmd(struct scsi_xfer *);
                     75: int    gdt_internal_cmd(struct gdt_softc *, u_int8_t, u_int16_t,
                     76:     u_int32_t, u_int32_t, u_int32_t);
                     77: #if NBIO > 0
                     78: int    gdt_ioctl(struct device *, u_long, caddr_t);
                     79: int    gdt_ioctl_inq(struct gdt_softc *, struct bioc_inq *);
                     80: int    gdt_ioctl_vol(struct gdt_softc *, struct bioc_vol *);
                     81: int    gdt_ioctl_disk(struct gdt_softc *, struct bioc_disk *);
                     82: int    gdt_ioctl_alarm(struct gdt_softc *, struct bioc_alarm *);
                     83: int    gdt_ioctl_setstate(struct gdt_softc *, struct bioc_setstate *);
                     84: #endif /* NBIO > 0 */
                     85: int    gdt_raw_scsi_cmd(struct scsi_xfer *);
                     86: int    gdt_scsi_cmd(struct scsi_xfer *);
                     87: void   gdt_start_ccbs(struct gdt_softc *);
                     88: int    gdt_sync_event(struct gdt_softc *, int, u_int8_t,
                     89:     struct scsi_xfer *);
                     90: void   gdt_timeout(void *);
                     91: int    gdt_wait(struct gdt_softc *, struct gdt_ccb *, int);
                     92: void   gdt_watchdog(void *);
                     93:
                     94: struct cfdriver gdt_cd = {
                     95:        NULL, "gdt", DV_DULL
                     96: };
                     97:
                     98: struct scsi_adapter gdt_switch = {
                     99:        gdt_scsi_cmd, gdtminphys, 0, 0,
                    100: };
                    101:
                    102: struct scsi_adapter gdt_raw_switch = {
                    103:        gdt_raw_scsi_cmd, gdtminphys, 0, 0,
                    104: };
                    105:
                    106: struct scsi_device gdt_dev = {
                    107:        NULL, NULL, NULL, NULL
                    108: };
                    109:
                    110: int gdt_cnt = 0;
                    111: u_int8_t gdt_polling;
                    112: u_int8_t gdt_from_wait;
                    113: struct gdt_softc *gdt_wait_gdt;
                    114: int    gdt_wait_index;
                    115: #ifdef GDT_DEBUG
                    116: int    gdt_debug = GDT_DEBUG;
                    117: #endif
                    118:
                    119: int
                    120: gdt_attach(gdt)
                    121:        struct gdt_softc *gdt;
                    122: {
                    123:        struct scsibus_attach_args saa;
                    124:        u_int16_t cdev_cnt;
                    125:        int i, id, drv_cyls, drv_hds, drv_secs, error, nsegs;
                    126:
                    127:        gdt_polling = 1;
                    128:        gdt_from_wait = 0;
                    129:
                    130:        if (bus_dmamem_alloc(gdt->sc_dmat, GDT_SCRATCH_SZ, PAGE_SIZE, 0,
                    131:            &gdt->sc_scratch_seg, 1, &nsegs, BUS_DMA_NOWAIT))
                    132:            panic("%s: bus_dmamem_alloc failed", DEVNAME(gdt));
                    133:        if (bus_dmamem_map(gdt->sc_dmat, &gdt->sc_scratch_seg, 1,
                    134:            GDT_SCRATCH_SZ, &gdt->sc_scratch, BUS_DMA_NOWAIT))
                    135:            panic("%s: bus_dmamem_map failed", DEVNAME(gdt));
                    136:
                    137:        gdt_clear_events(gdt);
                    138:
                    139:        TAILQ_INIT(&gdt->sc_free_ccb);
                    140:        TAILQ_INIT(&gdt->sc_ccbq);
                    141:        TAILQ_INIT(&gdt->sc_ucmdq);
                    142:        LIST_INIT(&gdt->sc_queue);
                    143:
                    144:        /* Initialize the ccbs */
                    145:        for (i = 0; i < GDT_MAXCMDS; i++) {
                    146:                gdt->sc_ccbs[i].gc_cmd_index = i + 2;
                    147:                error = bus_dmamap_create(gdt->sc_dmat,
                    148:                    (GDT_MAXOFFSETS - 1) << PGSHIFT, GDT_MAXOFFSETS,
                    149:                    (GDT_MAXOFFSETS - 1) << PGSHIFT, 0,
                    150:                    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    151:                    &gdt->sc_ccbs[i].gc_dmamap_xfer);
                    152:                if (error) {
                    153:                        printf("%s: cannot create ccb dmamap (%d)",
                    154:                            DEVNAME(gdt), error);
                    155:                        return (1);
                    156:                }
                    157:                (void)gdt_ccb_set_cmd(gdt->sc_ccbs + i, GDT_GCF_UNUSED);
                    158:                TAILQ_INSERT_TAIL(&gdt->sc_free_ccb, &gdt->sc_ccbs[i],
                    159:                    gc_chain);
                    160:        }
                    161:
                    162:        /* Fill in the prototype scsi_link. */
                    163:        gdt->sc_link.adapter_softc = gdt;
                    164:        gdt->sc_link.adapter = &gdt_switch;
                    165:        gdt->sc_link.device = &gdt_dev;
                    166:        /* openings will be filled in later. */
                    167:        gdt->sc_link.adapter_buswidth =
                    168:            (gdt->sc_class & GDT_FC) ? GDT_MAXID : GDT_MAX_HDRIVES;
                    169:        gdt->sc_link.adapter_target = gdt->sc_link.adapter_buswidth;
                    170:
                    171:        if (!gdt_internal_cmd(gdt, GDT_SCREENSERVICE, GDT_INIT, 0, 0, 0)) {
                    172:                printf("screen service initialization error %d\n",
                    173:                     gdt->sc_status);
                    174:                return (1);
                    175:        }
                    176:
                    177:        if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0,
                    178:            0)) {
                    179:                printf("cache service initialization error %d\n",
                    180:                    gdt->sc_status);
                    181:                return (1);
                    182:        }
                    183:
                    184:        cdev_cnt = (u_int16_t)gdt->sc_info;
                    185:
                    186:        /* Detect number of busses */
                    187:        gdt_enc32(gdt->sc_scratch + GDT_IOC_VERSION, GDT_IOC_NEWEST);
                    188:        gdt->sc_scratch[GDT_IOC_LIST_ENTRIES] = GDT_MAXBUS;
                    189:        gdt->sc_scratch[GDT_IOC_FIRST_CHAN] = 0;
                    190:        gdt->sc_scratch[GDT_IOC_LAST_CHAN] = GDT_MAXBUS - 1;
                    191:        gdt_enc32(gdt->sc_scratch + GDT_IOC_LIST_OFFSET, GDT_IOC_HDR_SZ);
                    192:        if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,
                    193:            GDT_IOCHAN_RAW_DESC, GDT_INVALID_CHANNEL,
                    194:            GDT_IOC_HDR_SZ + GDT_RAWIOC_SZ)) {
                    195:                gdt->sc_bus_cnt = gdt->sc_scratch[GDT_IOC_CHAN_COUNT];
                    196:                for (i = 0; i < gdt->sc_bus_cnt; i++) {
                    197:                        id = gdt->sc_scratch[GDT_IOC_HDR_SZ +
                    198:                            i * GDT_RAWIOC_SZ + GDT_RAWIOC_PROC_ID];
                    199:                        gdt->sc_bus_id[id] = id < GDT_MAXBUS ? id : 0xff;
                    200:                }
                    201:
                    202:        } else {
                    203:                /* New method failed, use fallback. */
                    204:                gdt_enc32(gdt->sc_scratch + GDT_GETCH_CHANNEL_NO, i);
                    205:                for (i = 0; i < GDT_MAXBUS; i++) {
                    206:                        if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,
                    207:                            GDT_SCSI_CHAN_CNT | GDT_L_CTRL_PATTERN,
                    208:                            GDT_IO_CHANNEL | GDT_INVALID_CHANNEL,
                    209:                            GDT_GETCH_SZ)) {
                    210:                                if (i == 0) {
                    211:                                        printf("cannot get channel count, "
                    212:                                            "error %d\n", gdt->sc_status);
                    213:                                        return (1);
                    214:                                }
                    215:                                break;
                    216:                        }
                    217:                        gdt->sc_bus_id[i] =
                    218:                            (gdt->sc_scratch[GDT_GETCH_SIOP_ID] < GDT_MAXID) ?
                    219:                            gdt->sc_scratch[GDT_GETCH_SIOP_ID] : 0xff;
                    220:                }
                    221:                gdt->sc_bus_cnt = i;
                    222:        }
                    223:
                    224:        /* Read cache configuration */
                    225:        if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_CACHE_INFO,
                    226:            GDT_INVALID_CHANNEL, GDT_CINFO_SZ)) {
                    227:                printf("cannot get cache info, error %d\n", gdt->sc_status);
                    228:                return (1);
                    229:        }
                    230:        gdt->sc_cpar.cp_version =
                    231:            gdt_dec32(gdt->sc_scratch + GDT_CPAR_VERSION);
                    232:        gdt->sc_cpar.cp_state = gdt_dec16(gdt->sc_scratch + GDT_CPAR_STATE);
                    233:        gdt->sc_cpar.cp_strategy =
                    234:            gdt_dec16(gdt->sc_scratch + GDT_CPAR_STRATEGY);
                    235:        gdt->sc_cpar.cp_write_back =
                    236:            gdt_dec16(gdt->sc_scratch + GDT_CPAR_WRITE_BACK);
                    237:        gdt->sc_cpar.cp_block_size =
                    238:            gdt_dec16(gdt->sc_scratch + GDT_CPAR_BLOCK_SIZE);
                    239:
                    240:        /* Read board information and features */
                    241:        gdt->sc_more_proc = 0;
                    242:        if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_BOARD_INFO,
                    243:            GDT_INVALID_CHANNEL, GDT_BINFO_SZ)) {
                    244:                /* XXX A lot of these assignments can probably go later */
                    245:                gdt->sc_binfo.bi_ser_no =
                    246:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_SER_NO);
                    247:                bcopy(gdt->sc_scratch + GDT_BINFO_OEM_ID,
                    248:                    gdt->sc_binfo.bi_oem_id, sizeof gdt->sc_binfo.bi_oem_id);
                    249:                gdt->sc_binfo.bi_ep_flags =
                    250:                    gdt_dec16(gdt->sc_scratch + GDT_BINFO_EP_FLAGS);
                    251:                gdt->sc_binfo.bi_proc_id =
                    252:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_PROC_ID);
                    253:                gdt->sc_binfo.bi_memsize =
                    254:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEMSIZE);
                    255:                gdt->sc_binfo.bi_mem_banks =
                    256:                    gdt->sc_scratch[GDT_BINFO_MEM_BANKS];
                    257:                gdt->sc_binfo.bi_chan_type =
                    258:                    gdt->sc_scratch[GDT_BINFO_CHAN_TYPE];
                    259:                gdt->sc_binfo.bi_chan_count =
                    260:                    gdt->sc_scratch[GDT_BINFO_CHAN_COUNT];
                    261:                gdt->sc_binfo.bi_rdongle_pres =
                    262:                    gdt->sc_scratch[GDT_BINFO_RDONGLE_PRES];
                    263:                gdt->sc_binfo.bi_epr_fw_ver =
                    264:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_EPR_FW_VER);
                    265:                gdt->sc_binfo.bi_upd_fw_ver =
                    266:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_FW_VER);
                    267:                gdt->sc_binfo.bi_upd_revision =
                    268:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_REVISION);
                    269:                bcopy(gdt->sc_scratch + GDT_BINFO_TYPE_STRING,
                    270:                    gdt->sc_binfo.bi_type_string,
                    271:                    sizeof gdt->sc_binfo.bi_type_string);
                    272:                bcopy(gdt->sc_scratch + GDT_BINFO_RAID_STRING,
                    273:                    gdt->sc_binfo.bi_raid_string,
                    274:                    sizeof gdt->sc_binfo.bi_raid_string);
                    275:                gdt->sc_binfo.bi_update_pres =
                    276:                    gdt->sc_scratch[GDT_BINFO_UPDATE_PRES];
                    277:                gdt->sc_binfo.bi_xor_pres =
                    278:                    gdt->sc_scratch[GDT_BINFO_XOR_PRES];
                    279:                gdt->sc_binfo.bi_prom_type =
                    280:                    gdt->sc_scratch[GDT_BINFO_PROM_TYPE];
                    281:                gdt->sc_binfo.bi_prom_count =
                    282:                    gdt->sc_scratch[GDT_BINFO_PROM_COUNT];
                    283:                gdt->sc_binfo.bi_dup_pres =
                    284:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_DUP_PRES);
                    285:                gdt->sc_binfo.bi_chan_pres =
                    286:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_CHAN_PRES);
                    287:                gdt->sc_binfo.bi_mem_pres =
                    288:                    gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEM_PRES);
                    289:                gdt->sc_binfo.bi_ft_bus_system =
                    290:                    gdt->sc_scratch[GDT_BINFO_FT_BUS_SYSTEM];
                    291:                gdt->sc_binfo.bi_subtype_valid =
                    292:                    gdt->sc_scratch[GDT_BINFO_SUBTYPE_VALID];
                    293:                gdt->sc_binfo.bi_board_subtype =
                    294:                    gdt->sc_scratch[GDT_BINFO_BOARD_SUBTYPE];
                    295:                gdt->sc_binfo.bi_rampar_pres =
                    296:                    gdt->sc_scratch[GDT_BINFO_RAMPAR_PRES];
                    297:
                    298:                if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,
                    299:                    GDT_BOARD_FEATURES, GDT_INVALID_CHANNEL, GDT_BFEAT_SZ)) {
                    300:                        gdt->sc_bfeat.bf_chaining =
                    301:                            gdt->sc_scratch[GDT_BFEAT_CHAINING];
                    302:                        gdt->sc_bfeat.bf_striping =
                    303:                            gdt->sc_scratch[GDT_BFEAT_STRIPING];
                    304:                        gdt->sc_bfeat.bf_mirroring =
                    305:                            gdt->sc_scratch[GDT_BFEAT_MIRRORING];
                    306:                        gdt->sc_bfeat.bf_raid =
                    307:                            gdt->sc_scratch[GDT_BFEAT_RAID];
                    308:                        gdt->sc_more_proc = 1;
                    309:                }
                    310:        } else {
                    311:                /* XXX Not implemented yet */
                    312:        }
                    313:
                    314:        /* Read more information */
                    315:        if (gdt->sc_more_proc) {
                    316:                int bus, j;
                    317:                /* physical drives, channel addresses */
                    318:                /* step 1: get magical bus number from firmware */
                    319:                gdt_enc32(gdt->sc_scratch + GDT_IOC_VERSION, GDT_IOC_NEWEST);
                    320:                gdt->sc_scratch[GDT_IOC_LIST_ENTRIES] = GDT_MAXBUS;
                    321:                gdt->sc_scratch[GDT_IOC_FIRST_CHAN] = 0;
                    322:                gdt->sc_scratch[GDT_IOC_LAST_CHAN] = GDT_MAXBUS - 1;
                    323:                gdt_enc32(gdt->sc_scratch + GDT_IOC_LIST_OFFSET, GDT_IOC_HDR_SZ);
                    324:                if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,
                    325:                    GDT_IOCHAN_DESC, GDT_INVALID_CHANNEL,
                    326:                    GDT_IOC_HDR_SZ + GDT_IOC_SZ * GDT_MAXBUS)) {
                    327:                        GDT_DPRINTF(GDT_D_INFO, ("method 1\n"));
                    328:                        for (bus = 0; bus < gdt->sc_bus_cnt; bus++) {
                    329:                                gdt->sc_raw[bus].ra_address =
                    330:                                    gdt_dec32(gdt->sc_scratch +
                    331:                                    GDT_IOC_HDR_SZ +
                    332:                                    GDT_IOC_SZ * bus +
                    333:                                    GDT_IOC_ADDRESS);
                    334:                                gdt->sc_raw[bus].ra_local_no =
                    335:                                    gdt_dec8(gdt->sc_scratch +
                    336:                                    GDT_IOC_HDR_SZ +
                    337:                                    GDT_IOC_SZ * bus +
                    338:                                    GDT_IOC_LOCAL_NO);
                    339:                                GDT_DPRINTF(GDT_D_INFO, (
                    340:                                    "bus: %d address: %x local: %x\n",
                    341:                                    bus,
                    342:                                    gdt->sc_raw[bus].ra_address,
                    343:                                    gdt->sc_raw[bus].ra_local_no));
                    344:                        }
                    345:                } else {
                    346:                        GDT_DPRINTF(GDT_D_INFO, ("method 2\n"));
                    347:                        for (bus = 0; bus < gdt->sc_bus_cnt; bus++) {
                    348:                                gdt->sc_raw[bus].ra_address = GDT_IO_CHANNEL;
                    349:                                gdt->sc_raw[bus].ra_local_no = bus;
                    350:                                GDT_DPRINTF(GDT_D_INFO, (
                    351:                                    "bus: %d address: %x local: %x\n",
                    352:                                    bus,
                    353:                                    gdt->sc_raw[bus].ra_address,
                    354:                                    gdt->sc_raw[bus].ra_local_no));
                    355:                        }
                    356:                }
                    357:                /* step 2: use magical bus number to get nr of phys disks */
                    358:                for (bus = 0; bus < gdt->sc_bus_cnt; bus++) {
                    359:                        gdt_enc32(gdt->sc_scratch + GDT_GETCH_CHANNEL_NO,
                    360:                            gdt->sc_raw[bus].ra_local_no);
                    361:                        if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,
                    362:                            GDT_SCSI_CHAN_CNT | GDT_L_CTRL_PATTERN,
                    363:                            gdt->sc_raw[bus].ra_address | GDT_INVALID_CHANNEL,
                    364:                            GDT_GETCH_SZ)) {
                    365:                                gdt->sc_raw[bus].ra_phys_cnt =
                    366:                                    gdt_dec32(gdt->sc_scratch +
                    367:                                    GDT_GETCH_DRIVE_CNT);
                    368:                                GDT_DPRINTF(GDT_D_INFO, ("chan: %d disks: %d\n",
                    369:                                    bus, gdt->sc_raw[bus].ra_phys_cnt));
                    370:                        }
                    371:
                    372:                        /* step 3: get scsi disk nr */
                    373:                        if (gdt->sc_raw[bus].ra_phys_cnt > 0) {
                    374:                                gdt_enc32(gdt->sc_scratch +
                    375:                                    GDT_GETSCSI_CHAN,
                    376:                                    gdt->sc_raw[bus].ra_local_no);
                    377:                                gdt_enc32(gdt->sc_scratch +
                    378:                                    GDT_GETSCSI_CNT,
                    379:                                    gdt->sc_raw[bus].ra_phys_cnt);
                    380:                                if (gdt_internal_cmd(gdt, GDT_CACHESERVICE,
                    381:                                    GDT_IOCTL,
                    382:                                    GDT_SCSI_DR_LIST | GDT_L_CTRL_PATTERN,
                    383:                                    gdt->sc_raw[bus].ra_address |
                    384:                                    GDT_INVALID_CHANNEL,
                    385:                                    GDT_GETSCSI_SZ))
                    386:                                        for (j = 0;
                    387:                                            j < gdt->sc_raw[bus].ra_phys_cnt;
                    388:                                            j++) {
                    389:                                                gdt->sc_raw[bus].ra_id_list[j] =
                    390:                                                    gdt_dec32(gdt->sc_scratch +
                    391:                                                    GDT_GETSCSI_LIST +
                    392:                                                    GDT_GETSCSI_LIST_SZ * j);
                    393:                                                GDT_DPRINTF(GDT_D_INFO,
                    394:                                                    ("  diskid: %d\n",
                    395:                                                    gdt->sc_raw[bus].ra_id_list[j]));
                    396:                                        }
                    397:                                else
                    398:                                        gdt->sc_raw[bus].ra_phys_cnt = 0;
                    399:                        }
                    400:                        /* add found disks to grand total */
                    401:                        gdt->sc_total_disks += gdt->sc_raw[bus].ra_phys_cnt;
                    402:                }
                    403:        } /* if (gdt->sc_more_proc) */
                    404:
                    405:        if (!gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_INIT, 0, 0, 0)) {
                    406:                printf("raw service initialization error %d\n",
                    407:                    gdt->sc_status);
                    408:                return (1);
                    409:        }
                    410:
                    411:        /* Set/get features raw service (scatter/gather) */
                    412:        gdt->sc_raw_feat = 0;
                    413:        if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_SET_FEAT,
                    414:            GDT_SCATTER_GATHER, 0, 0))
                    415:                if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_GET_FEAT, 0,
                    416:                    0, 0))
                    417:                        gdt->sc_raw_feat = gdt->sc_info;
                    418:
                    419:        /* Set/get features cache service (scatter/gather) */
                    420:        gdt->sc_cache_feat = 0;
                    421:        if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_SET_FEAT, 0,
                    422:            GDT_SCATTER_GATHER, 0))
                    423:                if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_GET_FEAT, 0, 0,
                    424:                    0))
                    425:                        gdt->sc_cache_feat = gdt->sc_info;
                    426:
                    427:        /* XXX Linux reserve drives here, potentially */
                    428:
                    429:        gdt->sc_ndevs = 0;
                    430:        /* Scan for cache devices */
                    431:        for (i = 0; i < cdev_cnt && i < GDT_MAX_HDRIVES; i++)
                    432:                if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INFO, i, 0,
                    433:                    0)) {
                    434:                        gdt->sc_hdr[i].hd_present = 1;
                    435:                        gdt->sc_hdr[i].hd_size = gdt->sc_info;
                    436:
                    437:                        if (gdt->sc_hdr[i].hd_size > 0)
                    438:                                gdt->sc_ndevs++;
                    439:
                    440:                        /*
                    441:                         * Evaluate mapping (sectors per head, heads per cyl)
                    442:                         */
                    443:                        gdt->sc_hdr[i].hd_size &= ~GDT_SECS32;
                    444:                        if (gdt->sc_info2 == 0)
                    445:                                gdt_eval_mapping(gdt->sc_hdr[i].hd_size,
                    446:                                    &drv_cyls, &drv_hds, &drv_secs);
                    447:                        else {
                    448:                                drv_hds = gdt->sc_info2 & 0xff;
                    449:                                drv_secs = (gdt->sc_info2 >> 8) & 0xff;
                    450:                                drv_cyls = gdt->sc_hdr[i].hd_size / drv_hds /
                    451:                                    drv_secs;
                    452:                        }
                    453:                        gdt->sc_hdr[i].hd_heads = drv_hds;
                    454:                        gdt->sc_hdr[i].hd_secs = drv_secs;
                    455:                        /* Round the size */
                    456:                        gdt->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
                    457:
                    458:                        if (gdt_internal_cmd(gdt, GDT_CACHESERVICE,
                    459:                            GDT_DEVTYPE, i, 0, 0))
                    460:                                gdt->sc_hdr[i].hd_devtype = gdt->sc_info;
                    461:                }
                    462:
                    463:        if (gdt->sc_ndevs == 0)
                    464:                gdt->sc_link.openings = 0;
                    465:        else
                    466:                gdt->sc_link.openings = (GDT_MAXCMDS - GDT_CMD_RESERVE) /
                    467:                    gdt->sc_ndevs;
                    468:
                    469:        printf("dpmem %llx %d-bus %d cache device%s\n",
                    470:            (long long)gdt->sc_dpmembase,
                    471:            gdt->sc_bus_cnt, cdev_cnt, cdev_cnt == 1 ? "" : "s");
                    472:        printf("%s: ver %x, cache %s, strategy %d, writeback %s, blksz %d\n",
                    473:            DEVNAME(gdt), gdt->sc_cpar.cp_version,
                    474:            gdt->sc_cpar.cp_state ? "on" : "off", gdt->sc_cpar.cp_strategy,
                    475:            gdt->sc_cpar.cp_write_back ? "on" : "off",
                    476:            gdt->sc_cpar.cp_block_size);
                    477: #if 1
                    478:        printf("%s: raw feat %x cache feat %x\n", DEVNAME(gdt),
                    479:            gdt->sc_raw_feat, gdt->sc_cache_feat);
                    480: #endif
                    481:
                    482: #if NBIO > 0
                    483:        if (bio_register(&gdt->sc_dev, gdt_ioctl) != 0)
                    484:                panic("%s: controller registration failed", DEVNAME(gdt));
                    485: #endif
                    486:        gdt_cnt++;
                    487:
                    488:        bzero(&saa, sizeof(saa));
                    489:        saa.saa_sc_link = &gdt->sc_link;
                    490:
                    491:        config_found(&gdt->sc_dev, &saa, scsiprint);
                    492:
                    493:        gdt->sc_raw_link = malloc(gdt->sc_bus_cnt * sizeof (struct scsi_link),
                    494:                                  M_DEVBUF, M_NOWAIT);
                    495:        if (gdt->sc_raw_link == NULL)
                    496:                panic("gdt_attach");
                    497:        bzero(gdt->sc_raw_link, gdt->sc_bus_cnt * sizeof (struct scsi_link));
                    498:
                    499:        for (i = 0; i < gdt->sc_bus_cnt; i++) {
                    500:                /* Fill in the prototype scsi_link. */
                    501:                gdt->sc_raw_link[i].adapter_softc = gdt;
                    502:                gdt->sc_raw_link[i].adapter = &gdt_raw_switch;
                    503:                gdt->sc_raw_link[i].adapter_target = 7;
                    504:                gdt->sc_raw_link[i].device = &gdt_dev;
                    505:                gdt->sc_raw_link[i].openings = 4;       /* XXX a guess */
                    506:                gdt->sc_raw_link[i].adapter_buswidth =
                    507:                    (gdt->sc_class & GDT_FC) ? GDT_MAXID : 16;  /* XXX */
                    508:
                    509:                bzero(&saa, sizeof(saa));
                    510:                saa.saa_sc_link = &gdt->sc_raw_link[i];
                    511:
                    512:                config_found(&gdt->sc_dev, &saa, scsiprint);
                    513:        }
                    514:
                    515:        gdt_polling = 0;
                    516:        return (0);
                    517: }
                    518:
                    519: void
                    520: gdt_eval_mapping(size, cyls, heads, secs)
                    521:        u_int32_t size;
                    522:        int *cyls, *heads, *secs;
                    523: {
                    524:        *cyls = size / GDT_HEADS / GDT_SECS;
                    525:        if (*cyls < GDT_MAXCYLS) {
                    526:                *heads = GDT_HEADS;
                    527:                *secs = GDT_SECS;
                    528:        } else {
                    529:                /* Too high for 64 * 32 */
                    530:                *cyls = size / GDT_MEDHEADS / GDT_MEDSECS;
                    531:                if (*cyls < GDT_MAXCYLS) {
                    532:                        *heads = GDT_MEDHEADS;
                    533:                        *secs = GDT_MEDSECS;
                    534:                } else {
                    535:                        /* Too high for 127 * 63 */
                    536:                        *cyls = size / GDT_BIGHEADS / GDT_BIGSECS;
                    537:                        *heads = GDT_BIGHEADS;
                    538:                        *secs = GDT_BIGSECS;
                    539:                }
                    540:        }
                    541: }
                    542:
                    543: /*
                    544:  * Insert a command into the driver queue, either at the front or at the tail.
                    545:  * It's ok to overload the freelist link as these structures are never on
                    546:  * the freelist at this time.
                    547:  */
                    548: void
                    549: gdt_enqueue(gdt, xs, infront)
                    550:        struct gdt_softc *gdt;
                    551:        struct scsi_xfer *xs;
                    552:        int infront;
                    553: {
                    554:        if (infront || LIST_FIRST(&gdt->sc_queue) == NULL) {
                    555:                if (LIST_FIRST(&gdt->sc_queue) == NULL)
                    556:                        gdt->sc_queuelast = xs;
                    557:                LIST_INSERT_HEAD(&gdt->sc_queue, xs, free_list);
                    558:                return;
                    559:        }
                    560:        LIST_INSERT_AFTER(gdt->sc_queuelast, xs, free_list);
                    561:        gdt->sc_queuelast = xs;
                    562: }
                    563:
                    564: /*
                    565:  * Pull a command off the front of the driver queue.
                    566:  */
                    567: struct scsi_xfer *
                    568: gdt_dequeue(gdt)
                    569:        struct gdt_softc *gdt;
                    570: {
                    571:        struct scsi_xfer *xs;
                    572:
                    573:        xs = LIST_FIRST(&gdt->sc_queue);
                    574:        if (xs == NULL)
                    575:                return (NULL);
                    576:        LIST_REMOVE(xs, free_list);
                    577:
                    578:        if (LIST_FIRST(&gdt->sc_queue) == NULL)
                    579:                gdt->sc_queuelast = NULL;
                    580:
                    581:        return (xs);
                    582: }
                    583:
                    584: /*
                    585:  * Start a SCSI operation on a cache device.
                    586:  * XXX Polled operation is not yet complete.  What kind of locking do we need?
                    587:  */
                    588: int
                    589: gdt_scsi_cmd(xs)
                    590:        struct scsi_xfer *xs;
                    591: {
                    592:        struct scsi_link *link = xs->sc_link;
                    593:        struct gdt_softc *gdt = link->adapter_softc;
                    594:        u_int8_t target = link->target;
                    595:        struct gdt_ccb *ccb;
                    596: #if 0
                    597:        struct gdt_ucmd *ucmd;
                    598: #endif
                    599:        u_int32_t blockno, blockcnt;
                    600:        struct scsi_rw *rw;
                    601:        struct scsi_rw_big *rwb;
                    602:        bus_dmamap_t xfer;
                    603:        int error, retval = SUCCESSFULLY_QUEUED;
                    604:        int s;
                    605:
                    606:        GDT_DPRINTF(GDT_D_CMD, ("gdt_scsi_cmd "));
                    607:
                    608:        xs->error = XS_NOERROR;
                    609:
                    610:        if (target >= GDT_MAX_HDRIVES || !gdt->sc_hdr[target].hd_present ||
                    611:            link->lun != 0) {
                    612:                /*
                    613:                 * XXX Should be XS_SENSE but that would require setting up a
                    614:                 * faked sense too.
                    615:                 */
                    616:                xs->error = XS_DRIVER_STUFFUP;
                    617:                xs->flags |= ITSDONE;
                    618:                s = splbio();
                    619:                scsi_done(xs);
                    620:                splx(s);
                    621:                return (COMPLETE);
                    622:        }
                    623:
                    624:        s = splbio();
                    625:
                    626:        /* Don't double enqueue if we came from gdt_chain. */
                    627:        if (xs != LIST_FIRST(&gdt->sc_queue))
                    628:                gdt_enqueue(gdt, xs, 0);
                    629:
                    630:        while ((xs = gdt_dequeue(gdt)) != NULL) {
                    631:                xs->error = XS_NOERROR;
                    632:                ccb = NULL;
                    633:                link = xs->sc_link;
                    634:                target = link->target;
                    635:
                    636:                if (!gdt_polling && !(xs->flags & SCSI_POLL) &&
                    637:                    gdt->sc_test_busy(gdt)) {
                    638:                        /*
                    639:                         * Put it back in front.  XXX Should we instead
                    640:                         * set xs->error to XS_BUSY?
                    641:                         */
                    642:                        gdt_enqueue(gdt, xs, 1);
                    643:                        break;
                    644:                }
                    645:
                    646:                switch (xs->cmd->opcode) {
                    647:                case TEST_UNIT_READY:
                    648:                case REQUEST_SENSE:
                    649:                case INQUIRY:
                    650:                case MODE_SENSE:
                    651:                case START_STOP:
                    652:                case READ_CAPACITY:
                    653: #if 0
                    654:                case VERIFY:
                    655: #endif
                    656:                        gdt_internal_cache_cmd(xs);
                    657:                        xs->flags |= ITSDONE;
                    658:                        scsi_done(xs);
                    659:                        goto ready;
                    660:
                    661:                case PREVENT_ALLOW:
                    662:                        GDT_DPRINTF(GDT_D_CMD, ("PREVENT/ALLOW "));
                    663:                        /* XXX Not yet implemented */
                    664:                        xs->error = XS_NOERROR;
                    665:                        xs->flags |= ITSDONE;
                    666:                        scsi_done(xs);
                    667:                        goto ready;
                    668:
                    669:                default:
                    670:                        GDT_DPRINTF(GDT_D_CMD,
                    671:                            ("unknown opc %d ", xs->cmd->opcode));
                    672:                        /* XXX Not yet implemented */
                    673:                        xs->error = XS_DRIVER_STUFFUP;
                    674:                        xs->flags |= ITSDONE;
                    675:                        scsi_done(xs);
                    676:                        goto ready;
                    677:
                    678:                case READ_COMMAND:
                    679:                case READ_BIG:
                    680:                case WRITE_COMMAND:
                    681:                case WRITE_BIG:
                    682:                case SYNCHRONIZE_CACHE:
                    683:                        /*
                    684:                         * A new command chain, start from the beginning.
                    685:                         */
                    686:                        gdt->sc_cmd_off = 0;
                    687:
                    688:                        if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
                    689:                                /* A read or write operation. */
                    690:                                if (xs->cmdlen == 6) {
                    691:                                        rw = (struct scsi_rw *)xs->cmd;
                    692:                                        blockno = _3btol(rw->addr) &
                    693:                                            (SRW_TOPADDR << 16 | 0xffff);
                    694:                                        blockcnt =
                    695:                                            rw->length ? rw->length : 0x100;
                    696:                                } else {
                    697:                                        rwb = (struct scsi_rw_big *)xs->cmd;
                    698:                                        blockno = _4btol(rwb->addr);
                    699:                                        blockcnt = _2btol(rwb->length);
                    700:                                }
                    701:                                if (blockno >= gdt->sc_hdr[target].hd_size ||
                    702:                                    blockno + blockcnt >
                    703:                                    gdt->sc_hdr[target].hd_size) {
                    704:                                        printf(
                    705:                                            "%s: out of bounds %u-%u >= %u\n",
                    706:                                            DEVNAME(gdt), blockno,
                    707:                                            blockcnt,
                    708:                                            gdt->sc_hdr[target].hd_size);
                    709:                                        /*
                    710:                                         * XXX Should be XS_SENSE but that
                    711:                                         * would require setting up a faked
                    712:                                         * sense too.
                    713:                                         */
                    714:                                        xs->error = XS_DRIVER_STUFFUP;
                    715:                                        xs->flags |= ITSDONE;
                    716:                                        scsi_done(xs);
                    717:                                        goto ready;
                    718:                                }
                    719:                        }
                    720:
                    721:                        ccb = gdt_get_ccb(gdt, xs->flags);
                    722:                        /*
                    723:                         * We are out of commands, try again in a little while.
                    724:                         */
                    725:                        if (ccb == NULL) {
                    726:                                splx(s);
                    727:                                return (TRY_AGAIN_LATER);
                    728:                        }
                    729:
                    730:                        ccb->gc_blockno = blockno;
                    731:                        ccb->gc_blockcnt = blockcnt;
                    732:                        ccb->gc_xs = xs;
                    733:                        ccb->gc_timeout = xs->timeout;
                    734:                        ccb->gc_service = GDT_CACHESERVICE;
                    735:                        gdt_ccb_set_cmd(ccb, GDT_GCF_SCSI);
                    736:
                    737:                        if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
                    738:                                xfer = ccb->gc_dmamap_xfer;
                    739:                                error = bus_dmamap_load(gdt->sc_dmat, xfer,
                    740:                                    xs->data, xs->datalen, NULL,
                    741:                                    (xs->flags & SCSI_NOSLEEP) ?
                    742:                                    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                    743:                                if (error) {
                    744:                                        printf("%s: gdt_scsi_cmd: ",
                    745:                                            DEVNAME(gdt));
                    746:                                        if (error == EFBIG)
                    747:                                                printf(
                    748:                                                    "more than %d dma segs\n",
                    749:                                                    GDT_MAXOFFSETS);
                    750:                                        else
                    751:                                                printf("error %d "
                    752:                                                    "loading dma map\n",
                    753:                                                    error);
                    754:
                    755:                                        gdt_free_ccb(gdt, ccb);
                    756:                                        xs->error = XS_DRIVER_STUFFUP;
                    757:                                        xs->flags |= ITSDONE;
                    758:                                        scsi_done(xs);
                    759:                                        goto ready;
                    760:                                }
                    761:                                bus_dmamap_sync(gdt->sc_dmat, xfer, 0,
                    762:                                    xfer->dm_mapsize,
                    763:                                    (xs->flags & SCSI_DATA_IN) ?
                    764:                                    BUS_DMASYNC_PREREAD :
                    765:                                    BUS_DMASYNC_PREWRITE);
                    766:                        }
                    767:
                    768:                        gdt_enqueue_ccb(gdt, ccb);
                    769:                        /* XXX what if enqueue did not start a transfer? */
                    770:                        if (gdt_polling || (xs->flags & SCSI_POLL)) {
                    771:                                if (!gdt_wait(gdt, ccb, ccb->gc_timeout)) {
                    772:                                        splx(s);
                    773:                                        printf("%s: command %d timed out\n",
                    774:                                            DEVNAME(gdt),
                    775:                                            ccb->gc_cmd_index);
                    776:                                        return (TRY_AGAIN_LATER);
                    777:                                }
                    778:                                xs->flags |= ITSDONE;
                    779:                                scsi_done(xs);
                    780:                        }
                    781:                }
                    782:
                    783:        ready:
                    784:                /*
                    785:                 * Don't process the queue if we are polling.
                    786:                 */
                    787:                if (xs->flags & SCSI_POLL) {
                    788:                        retval = COMPLETE;
                    789:                        break;
                    790:                }
                    791:        }
                    792:
                    793:        splx(s);
                    794:        return (retval);
                    795: }
                    796:
                    797: /* XXX Currently only for cacheservice, returns 0 if busy */
                    798: int
                    799: gdt_exec_ccb(ccb)
                    800:        struct gdt_ccb *ccb;
                    801: {
                    802:        struct scsi_xfer *xs = ccb->gc_xs;
                    803:        struct scsi_link *link = xs->sc_link;
                    804:        struct gdt_softc *gdt = link->adapter_softc;
                    805:        u_int8_t target = link->target;
                    806:        u_int32_t sg_canz;
                    807:        bus_dmamap_t xfer;
                    808:        int i;
                    809: #if 1 /* XXX */
                    810:        static int __level = 0;
                    811:
                    812:        if (__level++ > 0)
                    813:                panic("level > 0");
                    814: #endif
                    815:        GDT_DPRINTF(GDT_D_CMD, ("gdt_exec_ccb(%p, %p) ", xs, ccb));
                    816:
                    817:        gdt->sc_cmd_cnt = 0;
                    818:
                    819:        /*
                    820:         * XXX Yeah I know it's an always-true condition, but that may change
                    821:         * later.
                    822:         */
                    823:        if (gdt->sc_cmd_cnt == 0)
                    824:                gdt->sc_set_sema0(gdt);
                    825:
                    826:        gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX, ccb->gc_cmd_index);
                    827:        gdt_enc32(gdt->sc_cmd + GDT_CMD_BOARDNODE, GDT_LOCALBOARD);
                    828:        gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO,
                    829:            target);
                    830:
                    831:        switch (xs->cmd->opcode) {
                    832:        case PREVENT_ALLOW:
                    833:        case SYNCHRONIZE_CACHE:
                    834:                if (xs->cmd->opcode == PREVENT_ALLOW) {
                    835:                        /* XXX PREVENT_ALLOW support goes here */
                    836:                } else {
                    837:                        GDT_DPRINTF(GDT_D_CMD,
                    838:                            ("SYNCHRONIZE CACHE tgt %d ", target));
                    839:                        gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_FLUSH;
                    840:                }
                    841:                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
                    842:                    1);
                    843:                sg_canz = 0;
                    844:                break;
                    845:
                    846:        case WRITE_COMMAND:
                    847:        case WRITE_BIG:
                    848:                /* XXX WRITE_THR could be supported too */
                    849:                gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_WRITE;
                    850:                break;
                    851:
                    852:        case READ_COMMAND:
                    853:        case READ_BIG:
                    854:                gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_READ;
                    855:                break;
                    856:        }
                    857:
                    858:        if (xs->cmd->opcode != PREVENT_ALLOW &&
                    859:            xs->cmd->opcode != SYNCHRONIZE_CACHE) {
                    860:                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
                    861:                    ccb->gc_blockno);
                    862:                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT,
                    863:                    ccb->gc_blockcnt);
                    864:
                    865:                xfer = ccb->gc_dmamap_xfer;
                    866:                if (gdt->sc_cache_feat & GDT_SCATTER_GATHER) {
                    867:                        gdt_enc32(
                    868:                            gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR,
                    869:                            0xffffffff);
                    870:                        for (i = 0; i < xfer->dm_nsegs; i++) {
                    871:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                    872:                                    GDT_CACHE_SG_LST + i * GDT_SG_SZ +
                    873:                                    GDT_SG_PTR,
                    874:                                    xfer->dm_segs[i].ds_addr);
                    875:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                    876:                                    GDT_CACHE_SG_LST + i * GDT_SG_SZ +
                    877:                                    GDT_SG_LEN,
                    878:                                    xfer->dm_segs[i].ds_len);
                    879:                                GDT_DPRINTF(GDT_D_IO,
                    880:                                    ("#%d va %p pa %p len %x\n", i, buf,
                    881:                                    xfer->dm_segs[i].ds_addr,
                    882:                                    xfer->dm_segs[i].ds_len));
                    883:                        }
                    884:                        sg_canz = xfer->dm_nsegs;
                    885:                        gdt_enc32(
                    886:                            gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
                    887:                            sg_canz * GDT_SG_SZ + GDT_SG_LEN, 0);
                    888:                } else {
                    889:                        /* XXX Hardly correct */
                    890:                        gdt_enc32(
                    891:                            gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR,
                    892:                            xfer->dm_segs[0].ds_addr);
                    893:                        sg_canz = 0;
                    894:                }
                    895:        }
                    896:        gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ, sg_canz);
                    897:
                    898:        gdt->sc_cmd_len =
                    899:            roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST + sg_canz * GDT_SG_SZ,
                    900:            sizeof (u_int32_t));
                    901:
                    902:        if (gdt->sc_cmd_cnt > 0 &&
                    903:            gdt->sc_cmd_off + gdt->sc_cmd_len + GDT_DPMEM_COMMAND_OFFSET >
                    904:            gdt->sc_ic_all_size) {
                    905:                printf("%s: DPMEM overflow\n", DEVNAME(gdt));
                    906:                gdt_free_ccb(gdt, ccb);
                    907:                xs->error = XS_BUSY;
                    908: #if 1 /* XXX */
                    909:                __level--;
                    910: #endif
                    911:                return (0);
                    912:        }
                    913:
                    914:        gdt->sc_copy_cmd(gdt, ccb);
                    915:        gdt->sc_release_event(gdt, ccb);
                    916:
                    917:        xs->error = XS_NOERROR;
                    918:        xs->resid = 0;
                    919: #if 1 /* XXX */
                    920:        __level--;
                    921: #endif
                    922:        return (1);
                    923: }
                    924:
                    925: void
                    926: gdt_copy_internal_data(xs, data, size)
                    927:        struct scsi_xfer *xs;
                    928:        u_int8_t *data;
                    929:        size_t size;
                    930: {
                    931:        size_t copy_cnt;
                    932:
                    933:        GDT_DPRINTF(GDT_D_MISC, ("gdt_copy_internal_data "));
                    934:
                    935:        if (!xs->datalen)
                    936:                printf("uio move not yet supported\n");
                    937:        else {
                    938:                copy_cnt = MIN(size, xs->datalen);
                    939:                bcopy(data, xs->data, copy_cnt);
                    940:        }
                    941: }
                    942:
                    943: /* Emulated SCSI operation on cache device */
                    944: void
                    945: gdt_internal_cache_cmd(xs)
                    946:        struct scsi_xfer *xs;
                    947: {
                    948:        struct scsi_link *link = xs->sc_link;
                    949:        struct gdt_softc *gdt = link->adapter_softc;
                    950:        struct scsi_inquiry_data inq;
                    951:        struct scsi_sense_data sd;
                    952:        struct scsi_read_cap_data rcd;
                    953:        u_int8_t target = link->target;
                    954:
                    955:        GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cache_cmd "));
                    956:
                    957:        switch (xs->cmd->opcode) {
                    958:        case TEST_UNIT_READY:
                    959:        case START_STOP:
                    960: #if 0
                    961:        case VERIFY:
                    962: #endif
                    963:                GDT_DPRINTF(GDT_D_CMD, ("opc %d tgt %d ", xs->cmd->opcode,
                    964:                    target));
                    965:                break;
                    966:
                    967:        case REQUEST_SENSE:
                    968:                GDT_DPRINTF(GDT_D_CMD, ("REQUEST SENSE tgt %d ", target));
                    969:                bzero(&sd, sizeof sd);
                    970:                sd.error_code = 0x70;
                    971:                sd.segment = 0;
                    972:                sd.flags = SKEY_NO_SENSE;
                    973:                gdt_enc32(sd.info, 0);
                    974:                sd.extra_len = 0;
                    975:                gdt_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
                    976:                break;
                    977:
                    978:        case INQUIRY:
                    979:                GDT_DPRINTF(GDT_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
                    980:                    gdt->sc_hdr[target].hd_devtype));
                    981:                bzero(&inq, sizeof inq);
                    982:                inq.device =
                    983:                    (gdt->sc_hdr[target].hd_devtype & 4) ? T_CDROM : T_DIRECT;
                    984:                inq.dev_qual2 =
                    985:                    (gdt->sc_hdr[target].hd_devtype & 1) ? SID_REMOVABLE : 0;
                    986:                inq.version = 2;
                    987:                inq.response_format = 2;
                    988:                inq.additional_length = 32;
                    989:                strlcpy(inq.vendor, "ICP           ", sizeof inq.vendor);
                    990:                snprintf(inq.product, sizeof inq.product, "Host drive  #%02d",
                    991:                    target);
                    992:                strlcpy(inq.revision, "  ", sizeof inq.revision);
                    993:                gdt_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
                    994:                break;
                    995:
                    996:        case READ_CAPACITY:
                    997:                GDT_DPRINTF(GDT_D_CMD, ("READ CAPACITY tgt %d ", target));
                    998:                bzero(&rcd, sizeof rcd);
                    999:                _lto4b(gdt->sc_hdr[target].hd_size - 1, rcd.addr);
                   1000:                _lto4b(GDT_SECTOR_SIZE, rcd.length);
                   1001:                gdt_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
                   1002:                break;
                   1003:
                   1004:        default:
                   1005:                GDT_DPRINTF(GDT_D_CMD, ("unsupported scsi command %#x tgt %d ",
                   1006:                    xs->cmd->opcode, target));
                   1007:                xs->error = XS_DRIVER_STUFFUP;
                   1008:                return;
                   1009:        }
                   1010:
                   1011:        xs->error = XS_NOERROR;
                   1012: }
                   1013:
                   1014: /* Start a raw SCSI operation */
                   1015: int
                   1016: gdt_raw_scsi_cmd(xs)
                   1017:        struct scsi_xfer *xs;
                   1018: {
                   1019:        struct scsi_link *link = xs->sc_link;
                   1020:        struct gdt_softc *gdt = link->adapter_softc;
                   1021:        struct gdt_ccb *ccb;
                   1022:        int s;
                   1023:
                   1024:        GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_scsi_cmd "));
                   1025:
                   1026:        if (xs->cmdlen > 12 /* XXX create #define */) {
                   1027:                GDT_DPRINTF(GDT_D_CMD, ("CDB too big %p ", xs));
                   1028:                bzero(&xs->sense, sizeof(xs->sense));
                   1029:                xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
                   1030:                xs->sense.flags = SKEY_ILLEGAL_REQUEST;
                   1031:                xs->sense.add_sense_code = 0x20; /* illcmd, 0x24 illfield */
                   1032:                xs->error = XS_SENSE;
                   1033:                s = splbio();
                   1034:                scsi_done(xs);
                   1035:                splx(s);
                   1036:                return (COMPLETE);
                   1037:        }
                   1038:
                   1039:        if ((ccb = gdt_get_ccb(gdt, xs->flags)) == NULL) {
                   1040:                GDT_DPRINTF(GDT_D_CMD, ("no ccb available for %p ", xs));
                   1041:                xs->error = XS_DRIVER_STUFFUP;
                   1042:                s = splbio();
                   1043:                scsi_done(xs);
                   1044:                splx(s);
                   1045:                return (COMPLETE);
                   1046:        }
                   1047:
                   1048:        xs->error = XS_DRIVER_STUFFUP;
                   1049:        xs->flags |= ITSDONE;
                   1050:        s = splbio();
                   1051:        scsi_done(xs);
                   1052:        gdt_free_ccb(gdt, ccb);
                   1053:
                   1054:        splx(s);
                   1055:
                   1056:        return (COMPLETE);
                   1057: }
                   1058:
                   1059: void
                   1060: gdt_clear_events(gdt)
                   1061:        struct gdt_softc *gdt;
                   1062: {
                   1063:        GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events(%p) ", gdt));
                   1064:
                   1065:        /* XXX To be implemented */
                   1066: }
                   1067:
                   1068: int
                   1069: gdt_async_event(gdt, service)
                   1070:        struct gdt_softc *gdt;
                   1071:        int service;
                   1072: {
                   1073:        GDT_DPRINTF(GDT_D_INTR, ("gdt_async_event(%p, %d) ", gdt, service));
                   1074:
                   1075:        if (service == GDT_SCREENSERVICE) {
                   1076:                /* XXX To be implemented */
                   1077:        } else {
                   1078:                /* XXX To be implemented */
                   1079:        }
                   1080:
                   1081:        return (0);
                   1082: }
                   1083:
                   1084: int
                   1085: gdt_sync_event(gdt, service, index, xs)
                   1086:        struct gdt_softc *gdt;
                   1087:        int service;
                   1088:        u_int8_t index;
                   1089:        struct scsi_xfer *xs;
                   1090: {
                   1091:        GDT_DPRINTF(GDT_D_INTR,
                   1092:            ("gdt_sync_event(%p, %d, %d, %p) ", gdt, service, index, xs));
                   1093:
                   1094:        if (service == GDT_SCREENSERVICE) {
                   1095:                GDT_DPRINTF(GDT_D_INTR, ("service == GDT_SCREENSERVICE "));
                   1096:                /* XXX To be implemented */
                   1097:                return (0);
                   1098:        } else {
                   1099:                switch (gdt->sc_status) {
                   1100:                case GDT_S_OK:
                   1101:                        GDT_DPRINTF(GDT_D_INTR, ("sc_status == GDT_S_OK "));
                   1102:                        /* XXX To be implemented */
                   1103:                        break;
                   1104:                case GDT_S_BSY:
                   1105:                        GDT_DPRINTF(GDT_D_INTR, ("sc_status == GDT_S_BSY "));
                   1106:                        /* XXX To be implemented */
                   1107:                        return (2);
                   1108:                default:
                   1109:                        GDT_DPRINTF(GDT_D_INTR, ("sc_status is %d ",
                   1110:                            gdt->sc_status));
                   1111:                        /* XXX To be implemented */
                   1112:                        return (0);
                   1113:                }
                   1114:        }
                   1115:
                   1116:        return (1);
                   1117: }
                   1118:
                   1119: int
                   1120: gdt_intr(arg)
                   1121:        void *arg;
                   1122: {
                   1123:        struct gdt_softc *gdt = arg;
                   1124:        struct gdt_intr_ctx ctx;
                   1125:        int chain = 1;
                   1126:        int sync_val = 0;
                   1127:        struct scsi_xfer *xs;
                   1128:        int prev_cmd;
                   1129:        struct gdt_ccb *ccb;
                   1130:        int s;
                   1131:
                   1132:        GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p) ", gdt));
                   1133:
                   1134:        /* If polling and we were not called from gdt_wait, just return */
                   1135:        if (gdt_polling && !gdt_from_wait)
                   1136:                return (0);
                   1137:
                   1138:        if (!gdt_polling)
                   1139:                s = splbio();
                   1140:
                   1141:        ctx.istatus = gdt->sc_get_status(gdt);
                   1142:        if (!ctx.istatus) {
                   1143:                if (!gdt_polling)
                   1144:                        splx(s);
                   1145:                gdt->sc_status = GDT_S_NO_STATUS;
                   1146:                return (0);
                   1147:        }
                   1148:
                   1149:        gdt_wait_index = 0;
                   1150:        ctx.service = ctx.info2 = 0;
                   1151:
                   1152:        gdt->sc_intr(gdt, &ctx);
                   1153:
                   1154:        gdt->sc_status = ctx.cmd_status;
                   1155:        gdt->sc_info = ctx.info;
                   1156:        gdt->sc_info2 = ctx.info2;
                   1157:
                   1158:        if (gdt_from_wait) {
                   1159:                gdt_wait_gdt = gdt;
                   1160:                gdt_wait_index = ctx.istatus;
                   1161:        }
                   1162:
                   1163:        switch (ctx.istatus) {
                   1164:        case GDT_ASYNCINDEX:
                   1165:                gdt_async_event(gdt, ctx.service);
                   1166:                goto finish;
                   1167:
                   1168:        case GDT_SPEZINDEX:
                   1169:                printf("%s: uninitialized or unknown service (%d %d)\n",
                   1170:                    DEVNAME(gdt), ctx.info, ctx.info2);
                   1171:                chain = 0;
                   1172:                goto finish;
                   1173:        }
                   1174:
                   1175:        ccb = &gdt->sc_ccbs[ctx.istatus - 2];
                   1176:        xs = ccb->gc_xs;
                   1177:        if (!gdt_polling)
                   1178:                timeout_del(&xs->stimeout);
                   1179:        ctx.service = ccb->gc_service;
                   1180:        prev_cmd = ccb->gc_flags & GDT_GCF_CMD_MASK;
                   1181:        if (xs && xs->cmd->opcode != PREVENT_ALLOW &&
                   1182:            xs->cmd->opcode != SYNCHRONIZE_CACHE) {
                   1183:                bus_dmamap_sync(gdt->sc_dmat, ccb->gc_dmamap_xfer, 0,
                   1184:                    ccb->gc_dmamap_xfer->dm_mapsize,
                   1185:                    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
                   1186:                    BUS_DMASYNC_POSTWRITE);
                   1187:                bus_dmamap_unload(gdt->sc_dmat, ccb->gc_dmamap_xfer);
                   1188:        }
                   1189:        gdt_free_ccb(gdt, ccb);
                   1190:        switch (prev_cmd) {
                   1191:        case GDT_GCF_UNUSED:
                   1192:                /* XXX Not yet implemented */
                   1193:                chain = 0;
                   1194:                goto finish;
                   1195:        case GDT_GCF_INTERNAL:
                   1196:                chain = 0;
                   1197:                goto finish;
                   1198:        }
                   1199:
                   1200:        sync_val = gdt_sync_event(gdt, ctx.service, ctx.istatus, xs);
                   1201:
                   1202:  finish:
                   1203:        if (!gdt_polling)
                   1204:                splx(s);
                   1205:
                   1206:        switch (sync_val) {
                   1207:        case 1:
                   1208:                xs->flags |= ITSDONE;
                   1209:                scsi_done(xs);
                   1210:                break;
                   1211:
                   1212:        case 2:
                   1213:                gdt_enqueue(gdt, xs, 0);
                   1214:        }
                   1215:
                   1216:        if (chain)
                   1217:                gdt_chain(gdt);
                   1218:        return (1);
                   1219: }
                   1220:
                   1221: void
                   1222: gdtminphys(bp)
                   1223:        struct buf *bp;
                   1224: {
                   1225:        GDT_DPRINTF(GDT_D_MISC, ("gdtminphys(0x%x) ", bp));
                   1226:
                   1227:        /* As this is way more than MAXPHYS it's really not necessary. */
                   1228:        if ((GDT_MAXOFFSETS - 1) * PAGE_SIZE < MAXPHYS &&
                   1229:            bp->b_bcount > ((GDT_MAXOFFSETS - 1) * PAGE_SIZE))
                   1230:                bp->b_bcount = ((GDT_MAXOFFSETS - 1) * PAGE_SIZE);
                   1231:
                   1232:        minphys(bp);
                   1233: }
                   1234:
                   1235: int
                   1236: gdt_wait(gdt, ccb, timeout)
                   1237:        struct gdt_softc *gdt;
                   1238:        struct gdt_ccb *ccb;
                   1239:        int timeout;
                   1240: {
                   1241:        int rv = 0;
                   1242:
                   1243:        GDT_DPRINTF(GDT_D_MISC,
                   1244:            ("gdt_wait(%p, %p, %d) ", gdt, ccb, timeout));
                   1245:
                   1246:        gdt_from_wait = 1;
                   1247:        do {
                   1248:                if (gdt_intr(gdt) && gdt == gdt_wait_gdt &&
                   1249:                    ccb->gc_cmd_index == gdt_wait_index) {
                   1250:                        rv = 1;
                   1251:                        break;
                   1252:                }
                   1253:                DELAY(1);
                   1254:        } while (--timeout);
                   1255:        gdt_from_wait = 0;
                   1256:
                   1257:        while (gdt->sc_test_busy(gdt))
                   1258:                DELAY(0);               /* XXX correct? */
                   1259:
                   1260:        return (rv);
                   1261: }
                   1262:
                   1263: int
                   1264: gdt_internal_cmd(gdt, service, opcode, arg1, arg2, arg3)
                   1265:        struct gdt_softc *gdt;
                   1266:        u_int8_t service;
                   1267:        u_int16_t opcode;
                   1268:        u_int32_t arg1, arg2, arg3;
                   1269: {
                   1270:        int retries;
                   1271:        struct gdt_ccb *ccb;
                   1272:
                   1273:        GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d) ",
                   1274:            gdt, service, opcode, arg1, arg2, arg3));
                   1275:
                   1276:        bzero(gdt->sc_cmd, GDT_CMD_SZ);
                   1277:
                   1278:        for (retries = GDT_RETRIES; ; ) {
                   1279:                ccb = gdt_get_ccb(gdt, SCSI_NOSLEEP);
                   1280:                if (ccb == NULL) {
                   1281:                        printf("%s: no free command index found\n",
                   1282:                            DEVNAME(gdt));
                   1283:                        return (0);
                   1284:                }
                   1285:                ccb->gc_service = service;
                   1286:                gdt_ccb_set_cmd(ccb, GDT_GCF_INTERNAL);
                   1287:
                   1288:                gdt->sc_set_sema0(gdt);
                   1289:                gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX,
                   1290:                    ccb->gc_cmd_index);
                   1291:                gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, opcode);
                   1292:                gdt_enc32(gdt->sc_cmd + GDT_CMD_BOARDNODE, GDT_LOCALBOARD);
                   1293:
                   1294:                switch (service) {
                   1295:                case GDT_CACHESERVICE:
                   1296:                        if (opcode == GDT_IOCTL) {
                   1297:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                   1298:                                    GDT_IOCTL_SUBFUNC, arg1);
                   1299:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                   1300:                                    GDT_IOCTL_CHANNEL, arg2);
                   1301:                                gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION +
                   1302:                                    GDT_IOCTL_PARAM_SIZE, (u_int16_t)arg3);
                   1303:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                   1304:                                    GDT_IOCTL_P_PARAM,
                   1305:                                    gdt->sc_scratch_seg.ds_addr);
                   1306:                        } else {
                   1307:                                gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION +
                   1308:                                    GDT_CACHE_DEVICENO, (u_int16_t)arg1);
                   1309:                                gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                   1310:                                    GDT_CACHE_BLOCKNO, arg2);
                   1311:                        }
                   1312:                        break;
                   1313:
                   1314:                case GDT_SCSIRAWSERVICE:
                   1315:                        gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION +
                   1316:                            GDT_RAW_DIRECTION, arg1);
                   1317:                        gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] =
                   1318:                            (u_int8_t)arg2;
                   1319:                        gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] =
                   1320:                            (u_int8_t)arg3;
                   1321:                        gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] =
                   1322:                            (u_int8_t)(arg3 >> 8);
                   1323:                }
                   1324:
                   1325:                gdt->sc_cmd_len = GDT_CMD_SZ;
                   1326:                gdt->sc_cmd_off = 0;
                   1327:                gdt->sc_cmd_cnt = 0;
                   1328:                gdt->sc_copy_cmd(gdt, ccb);
                   1329:                gdt->sc_release_event(gdt, ccb);
                   1330:                DELAY(20);
                   1331:                if (!gdt_wait(gdt, ccb, GDT_POLL_TIMEOUT))
                   1332:                        return (0);
                   1333:                if (gdt->sc_status != GDT_S_BSY || --retries == 0)
                   1334:                        break;
                   1335:                DELAY(1);
                   1336:        }
                   1337:        return (gdt->sc_status == GDT_S_OK);
                   1338: }
                   1339:
                   1340: struct gdt_ccb *
                   1341: gdt_get_ccb(gdt, flags)
                   1342:        struct gdt_softc *gdt;
                   1343:        int flags;
                   1344: {
                   1345:        struct gdt_ccb *ccb;
                   1346:        int s;
                   1347:
                   1348:        GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p, 0x%x) ", gdt, flags));
                   1349:
                   1350:        s = splbio();
                   1351:
                   1352:        for (;;) {
                   1353:                ccb = TAILQ_FIRST(&gdt->sc_free_ccb);
                   1354:                if (ccb != NULL)
                   1355:                        break;
                   1356:                if (flags & SCSI_NOSLEEP)
                   1357:                        goto bail_out;
                   1358:                tsleep(&gdt->sc_free_ccb, PRIBIO, "gdt_ccb", 0);
                   1359:        }
                   1360:
                   1361:        TAILQ_REMOVE(&gdt->sc_free_ccb, ccb, gc_chain);
                   1362:
                   1363:  bail_out:
                   1364:        splx(s);
                   1365:        return (ccb);
                   1366: }
                   1367:
                   1368: void
                   1369: gdt_free_ccb(gdt, ccb)
                   1370:        struct gdt_softc *gdt;
                   1371:        struct gdt_ccb *ccb;
                   1372: {
                   1373:        int s;
                   1374:
                   1375:        GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p) ", gdt, ccb));
                   1376:
                   1377:        s = splbio();
                   1378:
                   1379:        TAILQ_INSERT_HEAD(&gdt->sc_free_ccb, ccb, gc_chain);
                   1380:
                   1381:        /* If the free list was empty, wake up potential waiters. */
                   1382:        if (TAILQ_NEXT(ccb, gc_chain) == NULL)
                   1383:                wakeup(&gdt->sc_free_ccb);
                   1384:
                   1385:        splx(s);
                   1386: }
                   1387:
                   1388: void
                   1389: gdt_enqueue_ccb(gdt, ccb)
                   1390:        struct gdt_softc *gdt;
                   1391:        struct gdt_ccb *ccb;
                   1392: {
                   1393:        GDT_DPRINTF(GDT_D_QUEUE, ("gdt_enqueue_ccb(%p, %p) ", gdt, ccb));
                   1394:
                   1395:        timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb);
                   1396:        TAILQ_INSERT_TAIL(&gdt->sc_ccbq, ccb, gc_chain);
                   1397:        gdt_start_ccbs(gdt);
                   1398: }
                   1399:
                   1400: void
                   1401: gdt_start_ccbs(gdt)
                   1402:        struct gdt_softc *gdt;
                   1403: {
                   1404:        struct gdt_ccb *ccb;
                   1405:        struct scsi_xfer *xs;
                   1406:
                   1407:        GDT_DPRINTF(GDT_D_QUEUE, ("gdt_start_ccbs(%p) ", gdt));
                   1408:
                   1409:        while ((ccb = TAILQ_FIRST(&gdt->sc_ccbq)) != NULL) {
                   1410:
                   1411:                xs = ccb->gc_xs;
                   1412:                if (ccb->gc_flags & GDT_GCF_WATCHDOG)
                   1413:                        timeout_del(&xs->stimeout);
                   1414:
                   1415:                if (gdt_exec_ccb(ccb) == 0) {
                   1416:                        ccb->gc_flags |= GDT_GCF_WATCHDOG;
                   1417:                        timeout_set(&ccb->gc_xs->stimeout, gdt_watchdog, ccb);
                   1418:                        timeout_add(&xs->stimeout,
                   1419:                            (GDT_WATCH_TIMEOUT * hz) / 1000);
                   1420:                        break;
                   1421:                }
                   1422:                TAILQ_REMOVE(&gdt->sc_ccbq, ccb, gc_chain);
                   1423:
                   1424:                if ((xs->flags & SCSI_POLL) == 0) {
                   1425:                        timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb);
                   1426:                        timeout_add(&xs->stimeout,
                   1427:                            (ccb->gc_timeout * hz) / 1000);
                   1428:                }
                   1429:        }
                   1430: }
                   1431:
                   1432: void
                   1433: gdt_chain(gdt)
                   1434:        struct gdt_softc *gdt;
                   1435: {
                   1436:        GDT_DPRINTF(GDT_D_INTR, ("gdt_chain(%p) ", gdt));
                   1437:
                   1438:        if (LIST_FIRST(&gdt->sc_queue))
                   1439:                gdt_scsi_cmd(LIST_FIRST(&gdt->sc_queue));
                   1440: }
                   1441:
                   1442: void
                   1443: gdt_timeout(arg)
                   1444:        void *arg;
                   1445: {
                   1446:        struct gdt_ccb *ccb = arg;
                   1447:        struct scsi_link *link = ccb->gc_xs->sc_link;
                   1448:        struct gdt_softc *gdt = link->adapter_softc;
                   1449:        int s;
                   1450:
                   1451:        sc_print_addr(link);
                   1452:        printf("timed out\n");
                   1453:
                   1454:        /* XXX Test for multiple timeouts */
                   1455:
                   1456:        ccb->gc_xs->error = XS_TIMEOUT;
                   1457:        s = splbio();
                   1458:        gdt_enqueue_ccb(gdt, ccb);
                   1459:        splx(s);
                   1460: }
                   1461:
                   1462: void
                   1463: gdt_watchdog(arg)
                   1464:        void *arg;
                   1465: {
                   1466:        struct gdt_ccb *ccb = arg;
                   1467:        struct scsi_link *link = ccb->gc_xs->sc_link;
                   1468:        struct gdt_softc *gdt = link->adapter_softc;
                   1469:        int s;
                   1470:
                   1471:        s = splbio();
                   1472:        ccb->gc_flags &= ~GDT_GCF_WATCHDOG;
                   1473:        gdt_start_ccbs(gdt);
                   1474:        splx(s);
                   1475: }
                   1476:
                   1477: #if NBIO > 0
                   1478: int
                   1479: gdt_ioctl(struct device *dev, u_long cmd, caddr_t addr)
                   1480: {
                   1481:        struct gdt_softc *sc = (struct gdt_softc *)dev;
                   1482:        int error = 0;
                   1483:
                   1484:        GDT_DPRINTF(GDT_D_IOCTL, ("%s: ioctl ", DEVNAME(sc)));
                   1485:
                   1486:        switch (cmd) {
                   1487:        case BIOCINQ:
                   1488:                GDT_DPRINTF(GDT_D_IOCTL, ("inq "));
                   1489:                error = gdt_ioctl_inq(sc, (struct bioc_inq *)addr);
                   1490:                break;
                   1491:
                   1492:        case BIOCVOL:
                   1493:                GDT_DPRINTF(GDT_D_IOCTL, ("vol "));
                   1494:                error = gdt_ioctl_vol(sc, (struct bioc_vol *)addr);
                   1495:                break;
                   1496:
                   1497:        case BIOCDISK:
                   1498:                GDT_DPRINTF(GDT_D_IOCTL, ("disk "));
                   1499:                error = gdt_ioctl_disk(sc, (struct bioc_disk *)addr);
                   1500:                break;
                   1501:
                   1502:        case BIOCALARM:
                   1503:                GDT_DPRINTF(GDT_D_IOCTL, ("alarm "));
                   1504:                error = gdt_ioctl_alarm(sc, (struct bioc_alarm *)addr);
                   1505:                break;
                   1506:
                   1507:        case BIOCSETSTATE:
                   1508:                GDT_DPRINTF(GDT_D_IOCTL, ("setstate "));
                   1509:                error = gdt_ioctl_setstate(sc, (struct bioc_setstate *)addr);
                   1510:                break;
                   1511:
                   1512:        default:
                   1513:                GDT_DPRINTF(GDT_D_IOCTL, (" invalid ioctl\n"));
                   1514:                error = EINVAL;
                   1515:        }
                   1516:
                   1517:        return (error);
                   1518: }
                   1519:
                   1520: int
                   1521: gdt_ioctl_inq(struct gdt_softc *sc, struct bioc_inq *bi)
                   1522: {
                   1523:        bi->bi_novol = sc->sc_ndevs;
                   1524:        bi->bi_nodisk = sc->sc_total_disks;
                   1525:
                   1526:        strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
                   1527:
                   1528:        return (0);
                   1529: }
                   1530:
                   1531: int
                   1532: gdt_ioctl_vol(struct gdt_softc *sc, struct bioc_vol *bv)
                   1533: {
                   1534:        return (1); /* XXX not yet */
                   1535: }
                   1536:
                   1537: int
                   1538: gdt_ioctl_disk(struct gdt_softc *sc, struct bioc_disk *bd)
                   1539: {
                   1540:        return (1); /* XXX not yet */
                   1541: }
                   1542:
                   1543: int
                   1544: gdt_ioctl_alarm(struct gdt_softc *sc, struct bioc_alarm *ba)
                   1545: {
                   1546:        return (1); /* XXX not yet */
                   1547: }
                   1548:
                   1549: int
                   1550: gdt_ioctl_setstate(struct gdt_softc *sc, struct bioc_setstate *bs)
                   1551: {
                   1552:        return (1); /* XXX not yet */
                   1553: }
                   1554:
                   1555: #if 0
                   1556: int
                   1557: gdt_ioctl(dev, cmd, addr)
                   1558:        struct device *dev;
                   1559:        u_long cmd;
                   1560:        caddr_t addr;
                   1561: {
                   1562:        int error = 0;
                   1563:        struct gdt_dummy *dummy;
                   1564:
                   1565:        switch (cmd) {
                   1566:        case GDT_IOCTL_DUMMY:
                   1567:                dummy = (struct gdt_dummy *)addr;
                   1568:                printf("%s: GDT_IOCTL_DUMMY %d\n", dev->dv_xname, dummy->x++);
                   1569:                break;
                   1570:
                   1571:        case GDT_IOCTL_GENERAL: {
                   1572:                gdt_ucmd_t *ucmd;
                   1573:                struct gdt_softc *gdt = (struct gdt_softc *)dev;
                   1574:                int s;
                   1575:
                   1576:                ucmd = (gdt_ucmd_t *)addr;
                   1577:                s = splbio();
                   1578:                TAILQ_INSERT_TAIL(&gdt->sc_ucmdq, ucmd, links);
                   1579:                ucmd->complete_flag = FALSE;
                   1580:                splx(s);
                   1581:                gdt_chain(gdt);
                   1582:                if (!ucmd->complete_flag)
                   1583:                        (void)tsleep((void *)ucmd, PCATCH | PRIBIO, "gdtucw",
                   1584:                            0);
                   1585:                break;
                   1586:        }
                   1587:
                   1588:        case GDT_IOCTL_DRVERS:
                   1589:                ((gdt_drvers_t *)addr)->vers =
                   1590:                    (GDT_DRIVER_VERSION << 8) | GDT_DRIVER_SUBVERSION;
                   1591:                break;
                   1592:
                   1593:        case GDT_IOCTL_CTRCNT:
                   1594:                ((gdt_ctrcnt_t *)addr)->cnt = gdt_cnt;
                   1595:                break;
                   1596:
                   1597: #ifdef notyet
                   1598:        case GDT_IOCTL_CTRTYPE: {
                   1599:                gdt_ctrt_t *p;
                   1600:                struct gdt_softc *gdt = (struct gdt_softc *)dev;
                   1601:
                   1602:                p = (gdt_ctrt_t *)addr;
                   1603:                p->oem_id = 0x8000;
                   1604:                p->type = 0xfd;
                   1605:                p->info = (gdt->sc_bus << 8) | (gdt->sc_slot << 3);
                   1606:                p->ext_type = 0x6000 | gdt->sc_subdevice;
                   1607:                p->device_id = gdt->sc_device;
                   1608:                p->sub_device_id = gdt->sc_subdevice;
                   1609:                break;
                   1610:        }
                   1611: #endif
                   1612:
                   1613:        case GDT_IOCTL_OSVERS: {
                   1614:                gdt_osv_t *p;
                   1615:
                   1616:                p = (gdt_osv_t *)addr;
                   1617:                p->oscode = 10;
                   1618:                p->version = osrelease[0] - '0';
                   1619:                if (osrelease[1] == '.')
                   1620:                        p->subversion = osrelease[2] - '0';
                   1621:                else
                   1622:                        p->subversion = 0;
                   1623:                if (osrelease[3] == '.')
                   1624:                        p->revision = osrelease[4] - '0';
                   1625:                else
                   1626:                        p->revision = 0;
                   1627:                strlcpy(p->name, ostype, sizeof p->name);
                   1628:                break;
                   1629:        }
                   1630:
                   1631: #ifdef notyet
                   1632:        case GDT_IOCTL_EVENT: {
                   1633:                gdt_event_t *p;
                   1634:                int s;
                   1635:
                   1636:                p = (gdt_event_t *)addr;
                   1637:                if (p->erase == 0xff) {
                   1638:                        if (p->dvr.event_source == GDT_ES_TEST)
                   1639:                                p->dvr.event_data.size =
                   1640:                                    sizeof(p->dvr.event_data.eu.test);
                   1641:                        else if (p->dvr.event_source == GDT_ES_DRIVER)
                   1642:                                p->dvr.event_data.size =
                   1643:                                    sizeof(p->dvr.event_data.eu.driver);
                   1644:                        else if (p->dvr.event_source == GDT_ES_SYNC)
                   1645:                                p->dvr.event_data.size =
                   1646:                                    sizeof(p->dvr.event_data.eu.sync);
                   1647:                        else
                   1648:                                p->dvr.event_data.size =
                   1649:                                    sizeof(p->dvr.event_data.eu.async);
                   1650:                        s = splbio();
                   1651:                        gdt_store_event(p->dvr.event_source, p->dvr.event_idx,
                   1652:                            &p->dvr.event_data);
                   1653:                        splx(s);
                   1654:                } else if (p->erase == 0xfe) {
                   1655:                        s = splbio();
                   1656:                        gdt_clear_events();
                   1657:                        splx(s);
                   1658:                } else if (p->erase == 0) {
                   1659:                        p->handle = gdt_read_event(p->handle, &p->dvr);
                   1660:                } else {
                   1661:                        gdt_readapp_event((u_int8_t)p->erase, &p->dvr);
                   1662:                }
                   1663:                break;
                   1664:        }
                   1665: #endif
                   1666:
                   1667:        case GDT_IOCTL_STATIST:
                   1668: #if 0
                   1669:                bcopy(&gdt_stat, (gdt_statist_t *)addr, sizeof gdt_stat);
                   1670: #else
                   1671:                error = EOPNOTSUPP;
                   1672: #endif
                   1673:                break;
                   1674:
                   1675:        default:
                   1676:                error = EINVAL;
                   1677:        }
                   1678:        return (error);
                   1679: }
                   1680: #endif /* 0 */
                   1681: #endif /* NBIO > 0 */

CVSweb