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