iir.c revision 170872
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 170872 2007-06-17 05:55:54Z scottl $");
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, &Giant,
506				     /*untagged*/1,
507                                     /*tagged*/GDT_MAXCMDS, devq);
508        if (xpt_bus_register(gdt->sims[i], gdt->sc_devnode, i) != CAM_SUCCESS) {
509            cam_sim_free(gdt->sims[i], /*free_devq*/i == 0);
510            break;
511        }
512
513        if (xpt_create_path(&gdt->paths[i], /*periph*/NULL,
514                            cam_sim_path(gdt->sims[i]),
515                            CAM_TARGET_WILDCARD,
516                            CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
517            xpt_bus_deregister(cam_sim_path(gdt->sims[i]));
518            cam_sim_free(gdt->sims[i], /*free_devq*/i == 0);
519            break;
520        }
521    }
522    if (i > 0)
523        EVENTHANDLER_REGISTER(shutdown_final, iir_shutdown,
524                              gdt, SHUTDOWN_PRI_DEFAULT);
525    /* iir_watchdog(gdt); */
526    gdt->sc_state = GDT_NORMAL;
527}
528
529static void
530gdt_eval_mapping(u_int32_t size, int *cyls, int *heads, int *secs)
531{
532    *cyls = size / GDT_HEADS / GDT_SECS;
533    if (*cyls < GDT_MAXCYLS) {
534        *heads = GDT_HEADS;
535        *secs = GDT_SECS;
536    } else {
537        /* Too high for 64 * 32 */
538        *cyls = size / GDT_MEDHEADS / GDT_MEDSECS;
539        if (*cyls < GDT_MAXCYLS) {
540            *heads = GDT_MEDHEADS;
541            *secs = GDT_MEDSECS;
542        } else {
543            /* Too high for 127 * 63 */
544            *cyls = size / GDT_BIGHEADS / GDT_BIGSECS;
545            *heads = GDT_BIGHEADS;
546            *secs = GDT_BIGSECS;
547        }
548    }
549}
550
551static int
552gdt_wait(struct gdt_softc *gdt, struct gdt_ccb *gccb,
553         int timeout)
554{
555    int rv = 0;
556
557    GDT_DPRINTF(GDT_D_INIT,
558                ("gdt_wait(%p, %p, %d)\n", gdt, gccb, timeout));
559
560    gdt->sc_state |= GDT_POLL_WAIT;
561    do {
562        iir_intr(gdt);
563        if (gdt == gdt_wait_gdt &&
564            gccb->gc_cmd_index == gdt_wait_index) {
565            rv = 1;
566            break;
567        }
568        DELAY(1);
569    } while (--timeout);
570    gdt->sc_state &= ~GDT_POLL_WAIT;
571
572    while (gdt->sc_test_busy(gdt))
573        DELAY(1);               /* XXX correct? */
574
575    return (rv);
576}
577
578static int
579gdt_internal_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb,
580                 u_int8_t service, u_int16_t opcode,
581                 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
582{
583    int retries;
584
585    GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d)\n",
586                            gdt, service, opcode, arg1, arg2, arg3));
587
588    bzero(gccb->gc_cmd, GDT_CMD_SZ);
589
590    for (retries = GDT_RETRIES; ; ) {
591        gccb->gc_service = service;
592        gccb->gc_flags = GDT_GCF_INTERNAL;
593
594        gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
595                  gccb->gc_cmd_index);
596        gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, opcode);
597
598        switch (service) {
599          case GDT_CACHESERVICE:
600            if (opcode == GDT_IOCTL) {
601                gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION +
602                          GDT_IOCTL_SUBFUNC, arg1);
603                gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION +
604                          GDT_IOCTL_CHANNEL, arg2);
605                gdt_enc16(gccb->gc_cmd + GDT_CMD_UNION +
606                          GDT_IOCTL_PARAM_SIZE, (u_int16_t)arg3);
607                gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_IOCTL_P_PARAM,
608                          gccb->gc_scratch_busbase);
609            } else {
610                gdt_enc16(gccb->gc_cmd + GDT_CMD_UNION +
611                          GDT_CACHE_DEVICENO, (u_int16_t)arg1);
612                gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION +
613                          GDT_CACHE_BLOCKNO, arg2);
614            }
615            break;
616
617          case GDT_SCSIRAWSERVICE:
618            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION +
619                      GDT_RAW_DIRECTION, arg1);
620            gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] =
621                (u_int8_t)arg2;
622            gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] =
623                (u_int8_t)arg3;
624            gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] =
625                (u_int8_t)(arg3 >> 8);
626        }
627
628        gdt->sc_set_sema0(gdt);
629        gccb->gc_cmd_len = GDT_CMD_SZ;
630        gdt->sc_cmd_off = 0;
631        gdt->sc_cmd_cnt = 0;
632        gdt->sc_copy_cmd(gdt, gccb);
633        gdt->sc_release_event(gdt);
634        DELAY(20);
635        if (!gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT))
636            return (0);
637        if (gdt->sc_status != GDT_S_BSY || --retries == 0)
638            break;
639        DELAY(1);
640    }
641    return (gdt->sc_status == GDT_S_OK);
642}
643
644static struct gdt_ccb *
645gdt_get_ccb(struct gdt_softc *gdt)
646{
647    struct gdt_ccb *gccb;
648    int lock;
649
650    GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p)\n", gdt));
651
652    lock = splcam();
653    gccb = SLIST_FIRST(&gdt->sc_free_gccb);
654    if (gccb != NULL) {
655        SLIST_REMOVE_HEAD(&gdt->sc_free_gccb, sle);
656        SLIST_INSERT_HEAD(&gdt->sc_pending_gccb, gccb, sle);
657        ++gdt_stat.cmd_index_act;
658        if (gdt_stat.cmd_index_act > gdt_stat.cmd_index_max)
659            gdt_stat.cmd_index_max = gdt_stat.cmd_index_act;
660    }
661    splx(lock);
662    return (gccb);
663}
664
665void
666gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb)
667{
668    int lock;
669
670    GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p)\n", gdt, gccb));
671
672    lock = splcam();
673    gccb->gc_flags = GDT_GCF_UNUSED;
674    SLIST_REMOVE(&gdt->sc_pending_gccb, gccb, gdt_ccb, sle);
675    SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle);
676    --gdt_stat.cmd_index_act;
677    splx(lock);
678    if (gdt->sc_state & GDT_SHUTDOWN)
679        wakeup(gccb);
680}
681
682void
683gdt_next(struct gdt_softc *gdt)
684{
685    int lock;
686    union ccb *ccb;
687    gdt_ucmd_t *ucmd;
688    struct cam_sim *sim;
689    int bus, target, lun;
690    int next_cmd;
691
692    struct ccb_scsiio *csio;
693    struct ccb_hdr *ccbh;
694    struct gdt_ccb *gccb = NULL;
695    u_int8_t cmd;
696
697    GDT_DPRINTF(GDT_D_QUEUE, ("gdt_next(%p)\n", gdt));
698
699    lock = splcam();
700    if (gdt->sc_test_busy(gdt)) {
701        if (!(gdt->sc_state & GDT_POLLING)) {
702            splx(lock);
703            return;
704        }
705        while (gdt->sc_test_busy(gdt))
706            DELAY(1);
707    }
708
709    gdt->sc_cmd_cnt = gdt->sc_cmd_off = 0;
710    next_cmd = TRUE;
711    for (;;) {
712        /* I/Os in queue? controller ready? */
713        if (!TAILQ_FIRST(&gdt->sc_ucmd_queue) &&
714            !TAILQ_FIRST(&gdt->sc_ccb_queue))
715            break;
716
717        /* 1.: I/Os without ccb (IOCTLs) */
718        ucmd = TAILQ_FIRST(&gdt->sc_ucmd_queue);
719        if (ucmd != NULL) {
720            TAILQ_REMOVE(&gdt->sc_ucmd_queue, ucmd, links);
721            if ((gccb = gdt_ioctl_cmd(gdt, ucmd, &lock)) == NULL) {
722                TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links);
723                break;
724            }
725            break;
726            /* wenn mehrere Kdos. zulassen: if (!gdt_polling) continue; */
727        }
728
729        /* 2.: I/Os with ccb */
730        ccb = (union ccb *)TAILQ_FIRST(&gdt->sc_ccb_queue);
731        /* ist dann immer != NULL, da oben getestet */
732        sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
733        bus = cam_sim_bus(sim);
734        target = ccb->ccb_h.target_id;
735        lun = ccb->ccb_h.target_lun;
736
737        TAILQ_REMOVE(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
738        --gdt_stat.req_queue_act;
739        /* ccb->ccb_h.func_code is XPT_SCSI_IO */
740        GDT_DPRINTF(GDT_D_QUEUE, ("XPT_SCSI_IO flags 0x%x)\n",
741                                  ccb->ccb_h.flags));
742        csio = &ccb->csio;
743        ccbh = &ccb->ccb_h;
744        cmd  = csio->cdb_io.cdb_bytes[0];
745        /* Max CDB length is 12 bytes */
746        if (csio->cdb_len > 12) {
747            ccbh->status = CAM_REQ_INVALID;
748            --gdt_stat.io_count_act;
749            xpt_done(ccb);
750        } else if (bus != gdt->sc_virt_bus) {
751            /* raw service command */
752            if ((gccb = gdt_raw_cmd(gdt, ccb, &lock)) == NULL) {
753                TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h,
754                                  sim_links.tqe);
755                ++gdt_stat.req_queue_act;
756                if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
757                    gdt_stat.req_queue_max = gdt_stat.req_queue_act;
758                next_cmd = FALSE;
759            }
760        } else if (target >= GDT_MAX_HDRIVES ||
761                   !gdt->sc_hdr[target].hd_present || lun != 0) {
762            ccbh->status = CAM_DEV_NOT_THERE;
763            --gdt_stat.io_count_act;
764            xpt_done(ccb);
765        } else {
766            /* cache service command */
767            if (cmd == READ_6  || cmd == WRITE_6 ||
768                cmd == READ_10 || cmd == WRITE_10) {
769                if ((gccb = gdt_cache_cmd(gdt, ccb, &lock)) == NULL) {
770                    TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h,
771                                      sim_links.tqe);
772                    ++gdt_stat.req_queue_act;
773                    if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
774                        gdt_stat.req_queue_max = gdt_stat.req_queue_act;
775                    next_cmd = FALSE;
776                }
777            } else {
778                splx(lock);
779                gdt_internal_cache_cmd(gdt, ccb);
780                lock = splcam();
781            }
782        }
783        if ((gdt->sc_state & GDT_POLLING) || !next_cmd)
784            break;
785    }
786    if (gdt->sc_cmd_cnt > 0)
787        gdt->sc_release_event(gdt);
788
789    splx(lock);
790
791    if ((gdt->sc_state & GDT_POLLING) && gdt->sc_cmd_cnt > 0) {
792        gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT);
793    }
794}
795
796static struct gdt_ccb *
797gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock)
798{
799    struct gdt_ccb *gccb;
800    struct cam_sim *sim;
801
802    GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_cmd(%p, %p)\n", gdt, ccb));
803
804    if (roundup(GDT_CMD_UNION + GDT_RAW_SZ, sizeof(u_int32_t)) +
805        gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET >
806        gdt->sc_ic_all_size) {
807        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_raw_cmd(): DPMEM overflow\n",
808                                    gdt->sc_hanum));
809        return (NULL);
810    }
811
812    gccb = gdt_get_ccb(gdt);
813    if (gccb == NULL) {
814        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: No free command index found\n",
815                                    gdt->sc_hanum));
816        return (gccb);
817    }
818    bzero(gccb->gc_cmd, GDT_CMD_SZ);
819    sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
820    gccb->gc_ccb = ccb;
821    gccb->gc_service = GDT_SCSIRAWSERVICE;
822    gccb->gc_flags = GDT_GCF_SCSI;
823
824    if (gdt->sc_cmd_cnt == 0)
825        gdt->sc_set_sema0(gdt);
826    splx(*lock);
827    gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
828              gccb->gc_cmd_index);
829    gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_WRITE);
830
831    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_DIRECTION,
832              (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN ?
833              GDT_DATA_IN : GDT_DATA_OUT);
834    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SDLEN,
835              ccb->csio.dxfer_len);
836    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_CLEN,
837              ccb->csio.cdb_len);
838    bcopy(ccb->csio.cdb_io.cdb_bytes, gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_CMD,
839          ccb->csio.cdb_len);
840    gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] =
841        ccb->ccb_h.target_id;
842    gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] =
843        ccb->ccb_h.target_lun;
844    gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] =
845        cam_sim_bus(sim);
846    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_LEN,
847              sizeof(struct scsi_sense_data));
848    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_DATA,
849              gccb->gc_scratch_busbase);
850
851    /*
852     * If we have any data to send with this command,
853     * map it into bus space.
854     */
855    /* Only use S/G if there is a transfer */
856    if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
857        if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
858            if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
859                int s;
860                int error;
861
862                /* vorher unlock von splcam() ??? */
863                s = splsoftvm();
864                error =
865                    bus_dmamap_load(gdt->sc_buffer_dmat,
866                                    gccb->gc_dmamap,
867                                    ccb->csio.data_ptr,
868                                    ccb->csio.dxfer_len,
869                                    gdtexecuteccb,
870                                    gccb, /*flags*/0);
871                if (error == EINPROGRESS) {
872                    xpt_freeze_simq(sim, 1);
873                    gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
874                }
875                splx(s);
876            } else {
877		panic("iir: CAM_DATA_PHYS not supported");
878            }
879        } else {
880            struct bus_dma_segment *segs;
881
882            if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0)
883                panic("iir%d: iir_action - Physical "
884                      "segment pointers unsupported", gdt->sc_hanum);
885
886            if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS)==0)
887                panic("iir%d: iir_action - Virtual "
888                      "segment addresses unsupported", gdt->sc_hanum);
889
890            /* Just use the segments provided */
891            segs = (struct bus_dma_segment *)ccb->csio.data_ptr;
892            gdtexecuteccb(gccb, segs, ccb->csio.sglist_cnt, 0);
893        }
894    } else {
895        gdtexecuteccb(gccb, NULL, 0, 0);
896    }
897
898    *lock = splcam();
899    return (gccb);
900}
901
902static struct gdt_ccb *
903gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock)
904{
905    struct gdt_ccb *gccb;
906    struct cam_sim *sim;
907    u_int8_t *cmdp;
908    u_int16_t opcode;
909    u_int32_t blockno, blockcnt;
910
911    GDT_DPRINTF(GDT_D_CMD, ("gdt_cache_cmd(%p, %p)\n", gdt, ccb));
912
913    if (roundup(GDT_CMD_UNION + GDT_CACHE_SZ, sizeof(u_int32_t)) +
914        gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET >
915        gdt->sc_ic_all_size) {
916        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_cache_cmd(): DPMEM overflow\n",
917                                    gdt->sc_hanum));
918        return (NULL);
919    }
920
921    gccb = gdt_get_ccb(gdt);
922    if (gccb == NULL) {
923        GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n",
924                                  gdt->sc_hanum));
925        return (gccb);
926    }
927    bzero(gccb->gc_cmd, GDT_CMD_SZ);
928    sim = (struct cam_sim *)ccb->ccb_h.ccb_sim_ptr;
929    gccb->gc_ccb = ccb;
930    gccb->gc_service = GDT_CACHESERVICE;
931    gccb->gc_flags = GDT_GCF_SCSI;
932
933    if (gdt->sc_cmd_cnt == 0)
934        gdt->sc_set_sema0(gdt);
935    splx(*lock);
936    gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
937              gccb->gc_cmd_index);
938    cmdp = ccb->csio.cdb_io.cdb_bytes;
939    opcode = (*cmdp == WRITE_6 || *cmdp == WRITE_10) ? GDT_WRITE : GDT_READ;
940    if ((gdt->sc_state & GDT_SHUTDOWN) && opcode == GDT_WRITE)
941        opcode = GDT_WRITE_THR;
942    gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, opcode);
943
944    gdt_enc16(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO,
945              ccb->ccb_h.target_id);
946    if (ccb->csio.cdb_len == 6) {
947        struct scsi_rw_6 *rw = (struct scsi_rw_6 *)cmdp;
948        blockno = scsi_3btoul(rw->addr) & ((SRW_TOPADDR<<16) | 0xffff);
949        blockcnt = rw->length ? rw->length : 0x100;
950    } else {
951        struct scsi_rw_10 *rw = (struct scsi_rw_10 *)cmdp;
952        blockno = scsi_4btoul(rw->addr);
953        blockcnt = scsi_2btoul(rw->length);
954    }
955    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
956              blockno);
957    gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT,
958              blockcnt);
959
960    /*
961     * If we have any data to send with this command,
962     * map it into bus space.
963     */
964    /* Only use S/G if there is a transfer */
965    if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
966        if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
967            int s;
968            int error;
969
970            /* vorher unlock von splcam() ??? */
971            s = splsoftvm();
972            error =
973                bus_dmamap_load(gdt->sc_buffer_dmat,
974                                gccb->gc_dmamap,
975                                ccb->csio.data_ptr,
976                                ccb->csio.dxfer_len,
977                                gdtexecuteccb,
978                                gccb, /*flags*/0);
979            if (error == EINPROGRESS) {
980                xpt_freeze_simq(sim, 1);
981                gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
982            }
983            splx(s);
984        } else {
985	    panic("iir: CAM_DATA_PHYS not supported");
986        }
987    } else {
988        struct bus_dma_segment *segs;
989
990        if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0)
991            panic("iir%d: iir_action - Physical "
992                  "segment pointers unsupported", gdt->sc_hanum);
993
994        if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS)==0)
995            panic("iir%d: iir_action - Virtual "
996                  "segment addresses unsupported", gdt->sc_hanum);
997
998        /* Just use the segments provided */
999        segs = (struct bus_dma_segment *)ccb->csio.data_ptr;
1000        gdtexecuteccb(gccb, segs, ccb->csio.sglist_cnt, 0);
1001    }
1002
1003    *lock = splcam();
1004    return (gccb);
1005}
1006
1007static struct gdt_ccb *
1008gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock)
1009{
1010    struct gdt_ccb *gccb;
1011    u_int32_t cnt;
1012
1013    GDT_DPRINTF(GDT_D_DEBUG, ("gdt_ioctl_cmd(%p, %p)\n", gdt, ucmd));
1014
1015    gccb = gdt_get_ccb(gdt);
1016    if (gccb == NULL) {
1017        GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n",
1018                                  gdt->sc_hanum));
1019        return (gccb);
1020    }
1021    bzero(gccb->gc_cmd, GDT_CMD_SZ);
1022    gccb->gc_ucmd = ucmd;
1023    gccb->gc_service = ucmd->service;
1024    gccb->gc_flags = GDT_GCF_IOCTL;
1025
1026    /* check DPMEM space, copy data buffer from user space */
1027    if (ucmd->service == GDT_CACHESERVICE) {
1028        if (ucmd->OpCode == GDT_IOCTL) {
1029            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_IOCTL_SZ,
1030                                      sizeof(u_int32_t));
1031            cnt = ucmd->u.ioctl.param_size;
1032            if (cnt > GDT_SCRATCH_SZ) {
1033                printf("iir%d: Scratch buffer too small (%d/%d)\n",
1034                       gdt->sc_hanum, GDT_SCRATCH_SZ, cnt);
1035                gdt_free_ccb(gdt, gccb);
1036                return (NULL);
1037            }
1038        } else {
1039            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST +
1040                                      GDT_SG_SZ, sizeof(u_int32_t));
1041            cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE;
1042            if (cnt > GDT_SCRATCH_SZ) {
1043                printf("iir%d: Scratch buffer too small (%d/%d)\n",
1044                       gdt->sc_hanum, GDT_SCRATCH_SZ, cnt);
1045                gdt_free_ccb(gdt, gccb);
1046                return (NULL);
1047            }
1048        }
1049    } else {
1050        gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_RAW_SG_LST +
1051                                  GDT_SG_SZ, sizeof(u_int32_t));
1052        cnt = ucmd->u.raw.sdlen;
1053        if (cnt + ucmd->u.raw.sense_len > GDT_SCRATCH_SZ) {
1054            printf("iir%d: Scratch buffer too small (%d/%d)\n",
1055                   gdt->sc_hanum, GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len);
1056            gdt_free_ccb(gdt, gccb);
1057            return (NULL);
1058        }
1059    }
1060    if (cnt != 0)
1061        bcopy(ucmd->data, gccb->gc_scratch, cnt);
1062
1063    if (gdt->sc_cmd_off + gccb->gc_cmd_len + GDT_DPMEM_COMMAND_OFFSET >
1064        gdt->sc_ic_all_size) {
1065        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_ioctl_cmd(): DPMEM overflow\n",
1066                                    gdt->sc_hanum));
1067        gdt_free_ccb(gdt, gccb);
1068        return (NULL);
1069    }
1070
1071    if (gdt->sc_cmd_cnt == 0)
1072        gdt->sc_set_sema0(gdt);
1073    splx(*lock);
1074
1075    /* fill cmd structure */
1076    gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1077              gccb->gc_cmd_index);
1078    gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE,
1079              ucmd->OpCode);
1080
1081    if (ucmd->service == GDT_CACHESERVICE) {
1082        if (ucmd->OpCode == GDT_IOCTL) {
1083            /* IOCTL */
1084            gdt_enc16(gccb->gc_cmd + GDT_CMD_UNION + GDT_IOCTL_PARAM_SIZE,
1085                      ucmd->u.ioctl.param_size);
1086            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_IOCTL_SUBFUNC,
1087                      ucmd->u.ioctl.subfunc);
1088            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_IOCTL_CHANNEL,
1089                      ucmd->u.ioctl.channel);
1090            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_IOCTL_P_PARAM,
1091                      gccb->gc_scratch_busbase);
1092        } else {
1093            /* cache service command */
1094            gdt_enc16(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO,
1095                      ucmd->u.cache.DeviceNo);
1096            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO,
1097                      ucmd->u.cache.BlockNo);
1098            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT,
1099                      ucmd->u.cache.BlockCnt);
1100            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR,
1101                      0xffffffffUL);
1102            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ,
1103                      1);
1104            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
1105                      GDT_SG_PTR, gccb->gc_scratch_busbase);
1106            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
1107                      GDT_SG_LEN, ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE);
1108        }
1109    } else {
1110        /* raw service command */
1111        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_DIRECTION,
1112                  ucmd->u.raw.direction);
1113        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SDATA,
1114                  0xffffffffUL);
1115        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SDLEN,
1116                  ucmd->u.raw.sdlen);
1117        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_CLEN,
1118                  ucmd->u.raw.clen);
1119        bcopy(ucmd->u.raw.cmd, gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_CMD,
1120              12);
1121        gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] =
1122            ucmd->u.raw.target;
1123        gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] =
1124            ucmd->u.raw.lun;
1125        gccb->gc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] =
1126            ucmd->u.raw.bus;
1127        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_LEN,
1128                  ucmd->u.raw.sense_len);
1129        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_DATA,
1130                  gccb->gc_scratch_busbase + ucmd->u.raw.sdlen);
1131        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_RANZ,
1132                  1);
1133        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
1134                  GDT_SG_PTR, gccb->gc_scratch_busbase);
1135        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
1136                  GDT_SG_LEN, ucmd->u.raw.sdlen);
1137    }
1138
1139    *lock = splcam();
1140    gdt_stat.sg_count_act = 1;
1141    gdt->sc_copy_cmd(gdt, gccb);
1142    return (gccb);
1143}
1144
1145static void
1146gdt_internal_cache_cmd(struct gdt_softc *gdt,union ccb *ccb)
1147{
1148    int t;
1149
1150    t = ccb->ccb_h.target_id;
1151    GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cache_cmd(%p, %p, 0x%x, %d)\n",
1152        gdt, ccb, ccb->csio.cdb_io.cdb_bytes[0], t));
1153
1154    switch (ccb->csio.cdb_io.cdb_bytes[0]) {
1155      case TEST_UNIT_READY:
1156      case START_STOP:
1157        break;
1158      case REQUEST_SENSE:
1159        GDT_DPRINTF(GDT_D_MISC, ("REQUEST_SENSE\n"));
1160        break;
1161      case INQUIRY:
1162        {
1163            struct scsi_inquiry_data *inq;
1164
1165            inq = (struct scsi_inquiry_data *)ccb->csio.data_ptr;
1166            bzero(inq, sizeof(struct scsi_inquiry_data));
1167            inq->device = (gdt->sc_hdr[t].hd_devtype & 4) ?
1168                T_CDROM : T_DIRECT;
1169            inq->dev_qual2 = (gdt->sc_hdr[t].hd_devtype & 1) ? 0x80 : 0;
1170            inq->version = SCSI_REV_2;
1171            inq->response_format = 2;
1172            inq->additional_length = 32;
1173            inq->flags = SID_CmdQue | SID_Sync;
1174            strcpy(inq->vendor, gdt->oem_name);
1175            sprintf(inq->product, "Host Drive   #%02d", t);
1176            strcpy(inq->revision, "   ");
1177            break;
1178        }
1179      case MODE_SENSE_6:
1180        {
1181            struct mpd_data {
1182                struct scsi_mode_hdr_6 hd;
1183                struct scsi_mode_block_descr bd;
1184                struct scsi_control_page cp;
1185            } *mpd;
1186            u_int8_t page;
1187
1188            mpd = (struct mpd_data *)ccb->csio.data_ptr;
1189            bzero(mpd, sizeof(struct mpd_data));
1190            mpd->hd.datalen = sizeof(struct scsi_mode_hdr_6) +
1191                sizeof(struct scsi_mode_block_descr);
1192            mpd->hd.dev_specific = (gdt->sc_hdr[t].hd_devtype & 2) ? 0x80 : 0;
1193            mpd->hd.block_descr_len = sizeof(struct scsi_mode_block_descr);
1194            mpd->bd.block_len[0] = (GDT_SECTOR_SIZE & 0x00ff0000) >> 16;
1195            mpd->bd.block_len[1] = (GDT_SECTOR_SIZE & 0x0000ff00) >> 8;
1196            mpd->bd.block_len[2] = (GDT_SECTOR_SIZE & 0x000000ff);
1197            page=((struct scsi_mode_sense_6 *)ccb->csio.cdb_io.cdb_bytes)->page;
1198            switch (page) {
1199              default:
1200                GDT_DPRINTF(GDT_D_MISC, ("MODE_SENSE_6: page 0x%x\n", page));
1201                break;
1202            }
1203            break;
1204        }
1205      case READ_CAPACITY:
1206        {
1207            struct scsi_read_capacity_data *rcd;
1208
1209            rcd = (struct scsi_read_capacity_data *)ccb->csio.data_ptr;
1210            bzero(rcd, sizeof(struct scsi_read_capacity_data));
1211            scsi_ulto4b(gdt->sc_hdr[t].hd_size - 1, rcd->addr);
1212            scsi_ulto4b(GDT_SECTOR_SIZE, rcd->length);
1213            break;
1214        }
1215      default:
1216        GDT_DPRINTF(GDT_D_MISC, ("gdt_internal_cache_cmd(%d) unknown\n",
1217                                    ccb->csio.cdb_io.cdb_bytes[0]));
1218        break;
1219    }
1220    ccb->ccb_h.status |= CAM_REQ_CMP;
1221    --gdt_stat.io_count_act;
1222    xpt_done(ccb);
1223}
1224
1225static void
1226gdtmapmem(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
1227{
1228    bus_addr_t *busaddrp;
1229
1230    busaddrp = (bus_addr_t *)arg;
1231    *busaddrp = dm_segs->ds_addr;
1232}
1233
1234static void
1235gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
1236{
1237    struct gdt_ccb *gccb;
1238    union ccb *ccb;
1239    struct gdt_softc *gdt;
1240    int i, lock;
1241
1242    lock = splcam();
1243
1244    gccb = (struct gdt_ccb *)arg;
1245    ccb = gccb->gc_ccb;
1246    gdt = cam_sim_softc((struct cam_sim *)ccb->ccb_h.ccb_sim_ptr);
1247
1248    GDT_DPRINTF(GDT_D_CMD, ("gdtexecuteccb(%p, %p, %p, %d, %d)\n",
1249                            gdt, gccb, dm_segs, nseg, error));
1250    gdt_stat.sg_count_act = nseg;
1251    if (nseg > gdt_stat.sg_count_max)
1252        gdt_stat.sg_count_max = nseg;
1253
1254    /* Copy the segments into our SG list */
1255    if (gccb->gc_service == GDT_CACHESERVICE) {
1256        for (i = 0; i < nseg; ++i) {
1257            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
1258                      i * GDT_SG_SZ + GDT_SG_PTR, dm_segs->ds_addr);
1259            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST +
1260                      i * GDT_SG_SZ + GDT_SG_LEN, dm_segs->ds_len);
1261            dm_segs++;
1262        }
1263        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ,
1264                  nseg);
1265        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR,
1266                  0xffffffffUL);
1267
1268        gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST +
1269                                  nseg * GDT_SG_SZ, sizeof(u_int32_t));
1270    } else {
1271        for (i = 0; i < nseg; ++i) {
1272            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
1273                      i * GDT_SG_SZ + GDT_SG_PTR, dm_segs->ds_addr);
1274            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_LST +
1275                      i * GDT_SG_SZ + GDT_SG_LEN, dm_segs->ds_len);
1276            dm_segs++;
1277        }
1278        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SG_RANZ,
1279                  nseg);
1280        gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SDATA,
1281                  0xffffffffUL);
1282
1283        gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_RAW_SG_LST +
1284                                  nseg * GDT_SG_SZ, sizeof(u_int32_t));
1285    }
1286
1287    if (nseg != 0) {
1288        bus_dmamap_sync(gdt->sc_buffer_dmat, gccb->gc_dmamap,
1289            (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN ?
1290            BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
1291    }
1292
1293    /* We must NOT abort the command here if CAM_REQ_INPROG is not set,
1294     * because command semaphore is already set!
1295     */
1296
1297    ccb->ccb_h.status |= CAM_SIM_QUEUED;
1298    /* timeout handling */
1299    ccb->ccb_h.timeout_ch =
1300        timeout(iir_timeout, (caddr_t)gccb,
1301                (ccb->ccb_h.timeout * hz) / 1000);
1302
1303    gdt->sc_copy_cmd(gdt, gccb);
1304    splx(lock);
1305}
1306
1307
1308static void
1309iir_action( struct cam_sim *sim, union ccb *ccb )
1310{
1311    struct gdt_softc *gdt;
1312    int lock, bus, target, lun;
1313
1314    gdt = (struct gdt_softc *)cam_sim_softc( sim );
1315    ccb->ccb_h.ccb_sim_ptr = sim;
1316    bus = cam_sim_bus(sim);
1317    target = ccb->ccb_h.target_id;
1318    lun = ccb->ccb_h.target_lun;
1319    GDT_DPRINTF(GDT_D_CMD,
1320                ("iir_action(%p) func 0x%x cmd 0x%x bus %d target %d lun %d\n",
1321                 gdt, ccb->ccb_h.func_code, ccb->csio.cdb_io.cdb_bytes[0],
1322                 bus, target, lun));
1323    ++gdt_stat.io_count_act;
1324    if (gdt_stat.io_count_act > gdt_stat.io_count_max)
1325        gdt_stat.io_count_max = gdt_stat.io_count_act;
1326
1327    switch (ccb->ccb_h.func_code) {
1328      case XPT_SCSI_IO:
1329        lock = splcam();
1330        TAILQ_INSERT_TAIL(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
1331        ++gdt_stat.req_queue_act;
1332        if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
1333            gdt_stat.req_queue_max = gdt_stat.req_queue_act;
1334        splx(lock);
1335        gdt_next(gdt);
1336        break;
1337      case XPT_RESET_DEV:   /* Bus Device Reset the specified SCSI device */
1338      case XPT_ABORT:                       /* Abort the specified CCB */
1339        /* XXX Implement */
1340        ccb->ccb_h.status = CAM_REQ_INVALID;
1341        --gdt_stat.io_count_act;
1342        xpt_done(ccb);
1343        break;
1344      case XPT_SET_TRAN_SETTINGS:
1345        ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1346        --gdt_stat.io_count_act;
1347        xpt_done(ccb);
1348        break;
1349      case XPT_GET_TRAN_SETTINGS:
1350        /* Get default/user set transfer settings for the target */
1351          {
1352              struct        ccb_trans_settings *cts = &ccb->cts;
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              --gdt_stat.io_count_act;
1379              xpt_done(ccb);
1380              break;
1381          }
1382      case XPT_CALC_GEOMETRY:
1383          {
1384              struct ccb_calc_geometry *ccg;
1385              u_int32_t secs_per_cylinder;
1386
1387              ccg = &ccb->ccg;
1388              ccg->heads = gdt->sc_hdr[target].hd_heads;
1389              ccg->secs_per_track = gdt->sc_hdr[target].hd_secs;
1390              secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1391              ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1392              ccb->ccb_h.status = CAM_REQ_CMP;
1393              --gdt_stat.io_count_act;
1394              xpt_done(ccb);
1395              break;
1396          }
1397      case XPT_RESET_BUS:           /* Reset the specified SCSI bus */
1398          {
1399              /* XXX Implement */
1400              ccb->ccb_h.status = CAM_REQ_CMP;
1401              --gdt_stat.io_count_act;
1402              xpt_done(ccb);
1403              break;
1404          }
1405      case XPT_TERM_IO:             /* Terminate the I/O process */
1406        /* XXX Implement */
1407        ccb->ccb_h.status = CAM_REQ_INVALID;
1408        --gdt_stat.io_count_act;
1409        xpt_done(ccb);
1410        break;
1411      case XPT_PATH_INQ:            /* Path routing inquiry */
1412          {
1413              struct ccb_pathinq *cpi = &ccb->cpi;
1414
1415              cpi->version_num = 1;
1416              cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
1417              cpi->hba_inquiry |= PI_WIDE_16;
1418              cpi->target_sprt = 1;
1419              cpi->hba_misc = 0;
1420              cpi->hba_eng_cnt = 0;
1421              if (bus == gdt->sc_virt_bus)
1422                  cpi->max_target = GDT_MAX_HDRIVES - 1;
1423              else if (gdt->sc_class & GDT_FC)
1424                  cpi->max_target = GDT_MAXID_FC - 1;
1425              else
1426                  cpi->max_target = GDT_MAXID - 1;
1427              cpi->max_lun = 7;
1428              cpi->unit_number = cam_sim_unit(sim);
1429              cpi->bus_id = bus;
1430              cpi->initiator_id =
1431                  (bus == gdt->sc_virt_bus ? 127 : gdt->sc_bus_id[bus]);
1432              cpi->base_transfer_speed = 3300;
1433              strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1434              if (gdt->sc_vendor == INTEL_VENDOR_ID)
1435                  strncpy(cpi->hba_vid, "Intel Corp.", HBA_IDLEN);
1436              else
1437                  strncpy(cpi->hba_vid, "ICP vortex ", HBA_IDLEN);
1438              strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1439              cpi->transport = XPORT_SPI;
1440              cpi->transport_version = 2;
1441              cpi->protocol = PROTO_SCSI;
1442              cpi->protocol_version = SCSI_REV_2;
1443              cpi->ccb_h.status = CAM_REQ_CMP;
1444              --gdt_stat.io_count_act;
1445              xpt_done(ccb);
1446              break;
1447          }
1448      default:
1449        GDT_DPRINTF(GDT_D_INVALID, ("gdt_next(%p) cmd 0x%x invalid\n",
1450                                    gdt, ccb->ccb_h.func_code));
1451        ccb->ccb_h.status = CAM_REQ_INVALID;
1452        --gdt_stat.io_count_act;
1453        xpt_done(ccb);
1454        break;
1455    }
1456}
1457
1458static void
1459iir_poll( struct cam_sim *sim )
1460{
1461    struct gdt_softc *gdt;
1462
1463    gdt = (struct gdt_softc *)cam_sim_softc( sim );
1464    GDT_DPRINTF(GDT_D_CMD, ("iir_poll sim %p gdt %p\n", sim, gdt));
1465    iir_intr(gdt);
1466}
1467
1468static void
1469iir_timeout(void *arg)
1470{
1471    GDT_DPRINTF(GDT_D_TIMEOUT, ("iir_timeout(%p)\n", gccb));
1472}
1473
1474static void
1475iir_watchdog(void *arg)
1476{
1477    struct gdt_softc *gdt;
1478
1479    gdt = (struct gdt_softc *)arg;
1480    GDT_DPRINTF(GDT_D_DEBUG, ("iir_watchdog(%p)\n", gdt));
1481
1482    {
1483        int ccbs = 0, ucmds = 0, frees = 0, pends = 0;
1484        struct gdt_ccb *p;
1485        struct ccb_hdr *h;
1486        struct gdt_ucmd *u;
1487
1488        for (h = TAILQ_FIRST(&gdt->sc_ccb_queue); h != NULL;
1489             h = TAILQ_NEXT(h, sim_links.tqe))
1490            ccbs++;
1491        for (u = TAILQ_FIRST(&gdt->sc_ucmd_queue); u != NULL;
1492             u = TAILQ_NEXT(u, links))
1493            ucmds++;
1494        for (p = SLIST_FIRST(&gdt->sc_free_gccb); p != NULL;
1495             p = SLIST_NEXT(p, sle))
1496            frees++;
1497        for (p = SLIST_FIRST(&gdt->sc_pending_gccb); p != NULL;
1498             p = SLIST_NEXT(p, sle))
1499            pends++;
1500
1501        GDT_DPRINTF(GDT_D_TIMEOUT, ("ccbs %d ucmds %d frees %d pends %d\n",
1502               ccbs, ucmds, frees, pends));
1503    }
1504
1505    timeout(iir_watchdog, (caddr_t)gdt, hz * 15);
1506}
1507
1508static void
1509iir_shutdown( void *arg, int howto )
1510{
1511    struct gdt_softc *gdt;
1512    struct gdt_ccb *gccb;
1513    gdt_ucmd_t *ucmd;
1514    int lock, i;
1515
1516    gdt = (struct gdt_softc *)arg;
1517    GDT_DPRINTF(GDT_D_CMD, ("iir_shutdown(%p, %d)\n", gdt, howto));
1518
1519    printf("iir%d: Flushing all Host Drives. Please wait ...  ",
1520           gdt->sc_hanum);
1521
1522    /* allocate ucmd buffer */
1523    ucmd = malloc(sizeof(gdt_ucmd_t), M_GDTBUF, M_NOWAIT);
1524    if (ucmd == NULL) {
1525        printf("iir%d: iir_shutdown(): Cannot allocate resource\n",
1526               gdt->sc_hanum);
1527        return;
1528    }
1529    bzero(ucmd, sizeof(gdt_ucmd_t));
1530
1531    /* wait for pending IOs */
1532    lock = splcam();
1533    gdt->sc_state = GDT_SHUTDOWN;
1534    splx(lock);
1535    if ((gccb = SLIST_FIRST(&gdt->sc_pending_gccb)) != NULL)
1536        (void) tsleep((void *)gccb, PCATCH | PRIBIO, "iirshw", 100 * hz);
1537
1538    /* flush */
1539    for (i = 0; i < GDT_MAX_HDRIVES; ++i) {
1540        if (gdt->sc_hdr[i].hd_present) {
1541            ucmd->service = GDT_CACHESERVICE;
1542            ucmd->OpCode = GDT_FLUSH;
1543            ucmd->u.cache.DeviceNo = i;
1544            lock = splcam();
1545            TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links);
1546            ucmd->complete_flag = FALSE;
1547            splx(lock);
1548            gdt_next(gdt);
1549            if (!ucmd->complete_flag)
1550                (void) tsleep((void *)ucmd, PCATCH|PRIBIO, "iirshw", 10*hz);
1551        }
1552    }
1553
1554    free(ucmd, M_DEVBUF);
1555    printf("Done.\n");
1556}
1557
1558void
1559iir_intr(void *arg)
1560{
1561    struct gdt_softc *gdt = arg;
1562    struct gdt_intr_ctx ctx;
1563    int lock = 0;
1564    struct gdt_ccb *gccb;
1565    gdt_ucmd_t *ucmd;
1566    u_int32_t cnt;
1567
1568    GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p)\n", gdt));
1569
1570    /* If polling and we were not called from gdt_wait, just return */
1571    if ((gdt->sc_state & GDT_POLLING) &&
1572        !(gdt->sc_state & GDT_POLL_WAIT))
1573        return;
1574
1575    if (!(gdt->sc_state & GDT_POLLING))
1576        lock = splcam();
1577    gdt_wait_index = 0;
1578
1579    ctx.istatus = gdt->sc_get_status(gdt);
1580    if (ctx.istatus == 0x00) {
1581        if (!(gdt->sc_state & GDT_POLLING))
1582            splx(lock);
1583        gdt->sc_status = GDT_S_NO_STATUS;
1584        return;
1585    }
1586
1587    gdt->sc_intr(gdt, &ctx);
1588
1589    gdt->sc_status = ctx.cmd_status;
1590    gdt->sc_service = ctx.service;
1591    gdt->sc_info = ctx.info;
1592    gdt->sc_info2 = ctx.info2;
1593
1594    if (gdt->sc_state & GDT_POLL_WAIT) {
1595        gdt_wait_gdt = gdt;
1596        gdt_wait_index = ctx.istatus;
1597    }
1598
1599    if (ctx.istatus == GDT_ASYNCINDEX) {
1600        gdt_async_event(gdt, ctx.service);
1601        if (!(gdt->sc_state & GDT_POLLING))
1602            splx(lock);
1603        return;
1604    }
1605    if (ctx.istatus == GDT_SPEZINDEX) {
1606        GDT_DPRINTF(GDT_D_INVALID,
1607                    ("iir%d: Service unknown or not initialized!\n",
1608                     gdt->sc_hanum));
1609        gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
1610        gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
1611        gdt_store_event(GDT_ES_DRIVER, 4, &gdt->sc_dvr);
1612        if (!(gdt->sc_state & GDT_POLLING))
1613            splx(lock);
1614        return;
1615    }
1616
1617    gccb = &gdt->sc_gccbs[ctx.istatus - 2];
1618    ctx.service = gccb->gc_service;
1619
1620    switch (gccb->gc_flags) {
1621      case GDT_GCF_UNUSED:
1622        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: Index (%d) to unused command!\n",
1623                    gdt->sc_hanum, ctx.istatus));
1624        gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
1625        gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
1626        gdt->sc_dvr.eu.driver.index = ctx.istatus;
1627        gdt_store_event(GDT_ES_DRIVER, 1, &gdt->sc_dvr);
1628        gdt_free_ccb(gdt, gccb);
1629        /* fallthrough */
1630
1631      case GDT_GCF_INTERNAL:
1632        if (!(gdt->sc_state & GDT_POLLING))
1633            splx(lock);
1634        break;
1635
1636      case GDT_GCF_IOCTL:
1637        ucmd = gccb->gc_ucmd;
1638        if (gdt->sc_status == GDT_S_BSY) {
1639            GDT_DPRINTF(GDT_D_DEBUG, ("iir_intr(%p) ioctl: gccb %p busy\n",
1640                                      gdt, gccb));
1641            TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links);
1642            if (!(gdt->sc_state & GDT_POLLING))
1643                splx(lock);
1644        } else {
1645            ucmd->status = gdt->sc_status;
1646            ucmd->info = gdt->sc_info;
1647            ucmd->complete_flag = TRUE;
1648            if (ucmd->service == GDT_CACHESERVICE) {
1649                if (ucmd->OpCode == GDT_IOCTL) {
1650                    cnt = ucmd->u.ioctl.param_size;
1651                    if (cnt != 0)
1652                        bcopy(gccb->gc_scratch, ucmd->data, cnt);
1653                } else {
1654                    cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE;
1655                    if (cnt != 0)
1656                        bcopy(gccb->gc_scratch, ucmd->data, cnt);
1657                }
1658            } else {
1659                cnt = ucmd->u.raw.sdlen;
1660                if (cnt != 0)
1661                    bcopy(gccb->gc_scratch, ucmd->data, cnt);
1662                if (ucmd->u.raw.sense_len != 0)
1663                    bcopy(gccb->gc_scratch, ucmd->data, cnt);
1664            }
1665            gdt_free_ccb(gdt, gccb);
1666            if (!(gdt->sc_state & GDT_POLLING))
1667                splx(lock);
1668            /* wakeup */
1669            wakeup(ucmd);
1670        }
1671        gdt_next(gdt);
1672        break;
1673
1674      default:
1675        gdt_free_ccb(gdt, gccb);
1676        gdt_sync_event(gdt, ctx.service, ctx.istatus, gccb);
1677        if (!(gdt->sc_state & GDT_POLLING))
1678            splx(lock);
1679        gdt_next(gdt);
1680        break;
1681    }
1682}
1683
1684int
1685gdt_async_event(struct gdt_softc *gdt, int service)
1686{
1687    struct gdt_ccb *gccb;
1688
1689    GDT_DPRINTF(GDT_D_INTR, ("gdt_async_event(%p, %d)\n", gdt, service));
1690
1691    if (service == GDT_SCREENSERVICE) {
1692        if (gdt->sc_status == GDT_MSG_REQUEST) {
1693            while (gdt->sc_test_busy(gdt))
1694                DELAY(1);
1695            gccb = gdt_get_ccb(gdt);
1696            if (gccb == NULL) {
1697                printf("iir%d: No free command index found\n",
1698                       gdt->sc_hanum);
1699                return (1);
1700            }
1701            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1702            gccb->gc_service = service;
1703            gccb->gc_flags = GDT_GCF_SCREEN;
1704            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1705                      gccb->gc_cmd_index);
1706            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_READ);
1707            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1708                      GDT_MSG_INV_HANDLE);
1709            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1710                      gccb->gc_scratch_busbase);
1711            gdt->sc_set_sema0(gdt);
1712            gdt->sc_cmd_off = 0;
1713            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1714                                      sizeof(u_int32_t));
1715            gdt->sc_cmd_cnt = 0;
1716            gdt->sc_copy_cmd(gdt, gccb);
1717            printf("iir%d: [PCI %d/%d] ",
1718                gdt->sc_hanum,gdt->sc_bus,gdt->sc_slot);
1719            gdt->sc_release_event(gdt);
1720        }
1721
1722    } else {
1723        if ((gdt->sc_fw_vers & 0xff) >= 0x1a) {
1724            gdt->sc_dvr.size = 0;
1725            gdt->sc_dvr.eu.async.ionode = gdt->sc_hanum;
1726            gdt->sc_dvr.eu.async.status  = gdt->sc_status;
1727            /* severity and event_string already set! */
1728        } else {
1729            gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.async);
1730            gdt->sc_dvr.eu.async.ionode   = gdt->sc_hanum;
1731            gdt->sc_dvr.eu.async.service = service;
1732            gdt->sc_dvr.eu.async.status  = gdt->sc_status;
1733            gdt->sc_dvr.eu.async.info    = gdt->sc_info;
1734            *(u_int32_t *)gdt->sc_dvr.eu.async.scsi_coord  = gdt->sc_info2;
1735        }
1736        gdt_store_event(GDT_ES_ASYNC, service, &gdt->sc_dvr);
1737        printf("iir%d: %s\n", gdt->sc_hanum, gdt->sc_dvr.event_string);
1738    }
1739
1740    return (0);
1741}
1742
1743int
1744gdt_sync_event(struct gdt_softc *gdt, int service,
1745               u_int8_t index, struct gdt_ccb *gccb)
1746{
1747    union ccb *ccb;
1748
1749    GDT_DPRINTF(GDT_D_INTR,
1750                ("gdt_sync_event(%p, %d, %d, %p)\n", gdt,service,index,gccb));
1751
1752    ccb = gccb->gc_ccb;
1753
1754    if (service == GDT_SCREENSERVICE) {
1755        u_int32_t msg_len;
1756
1757        msg_len = gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_LEN);
1758        if (msg_len)
1759            if (!(gccb->gc_scratch[GDT_SCR_MSG_ANSWER] &&
1760                  gccb->gc_scratch[GDT_SCR_MSG_EXT])) {
1761                gccb->gc_scratch[GDT_SCR_MSG_TEXT + msg_len] = '\0';
1762                printf("%s",&gccb->gc_scratch[GDT_SCR_MSG_TEXT]);
1763            }
1764
1765        if (gccb->gc_scratch[GDT_SCR_MSG_EXT] &&
1766            !gccb->gc_scratch[GDT_SCR_MSG_ANSWER]) {
1767            while (gdt->sc_test_busy(gdt))
1768                DELAY(1);
1769            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1770            gccb = gdt_get_ccb(gdt);
1771            if (gccb == NULL) {
1772                printf("iir%d: No free command index found\n",
1773                       gdt->sc_hanum);
1774                return (1);
1775            }
1776            gccb->gc_service = service;
1777            gccb->gc_flags = GDT_GCF_SCREEN;
1778            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1779                      gccb->gc_cmd_index);
1780            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_READ);
1781            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1782                      gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
1783            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1784                      gccb->gc_scratch_busbase);
1785            gdt->sc_set_sema0(gdt);
1786            gdt->sc_cmd_off = 0;
1787            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1788                                      sizeof(u_int32_t));
1789            gdt->sc_cmd_cnt = 0;
1790            gdt->sc_copy_cmd(gdt, gccb);
1791            gdt->sc_release_event(gdt);
1792            return (0);
1793        }
1794
1795        if (gccb->gc_scratch[GDT_SCR_MSG_ANSWER] &&
1796            gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN)) {
1797            /* default answers (getchar() not possible) */
1798            if (gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) == 1) {
1799                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN, 0);
1800                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 1);
1801                gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 0;
1802            } else {
1803                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN,
1804                          gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) - 2);
1805                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 2);
1806                gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 1;
1807                gccb->gc_scratch[GDT_SCR_MSG_TEXT + 1] = 0;
1808            }
1809            gccb->gc_scratch[GDT_SCR_MSG_EXT] = 0;
1810            gccb->gc_scratch[GDT_SCR_MSG_ANSWER] = 0;
1811            while (gdt->sc_test_busy(gdt))
1812                DELAY(1);
1813            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1814            gccb = gdt_get_ccb(gdt);
1815            if (gccb == NULL) {
1816                printf("iir%d: No free command index found\n",
1817                       gdt->sc_hanum);
1818                return (1);
1819            }
1820            gccb->gc_service = service;
1821            gccb->gc_flags = GDT_GCF_SCREEN;
1822            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1823                      gccb->gc_cmd_index);
1824            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_WRITE);
1825            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1826                      gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
1827            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1828                      gccb->gc_scratch_busbase);
1829            gdt->sc_set_sema0(gdt);
1830            gdt->sc_cmd_off = 0;
1831            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1832                                      sizeof(u_int32_t));
1833            gdt->sc_cmd_cnt = 0;
1834            gdt->sc_copy_cmd(gdt, gccb);
1835            gdt->sc_release_event(gdt);
1836            return (0);
1837        }
1838        printf("\n");
1839        return (0);
1840    } else {
1841        untimeout(iir_timeout, gccb, ccb->ccb_h.timeout_ch);
1842        if (gdt->sc_status == GDT_S_BSY) {
1843            GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n",
1844                                      gdt, gccb));
1845            TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
1846            ++gdt_stat.req_queue_act;
1847            if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
1848                gdt_stat.req_queue_max = gdt_stat.req_queue_act;
1849            return (2);
1850        }
1851
1852        bus_dmamap_sync(gdt->sc_buffer_dmat, gccb->gc_dmamap,
1853            (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN ?
1854            BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1855        bus_dmamap_unload(gdt->sc_buffer_dmat, gccb->gc_dmamap);
1856
1857        ccb->csio.resid = 0;
1858        if (gdt->sc_status == GDT_S_OK) {
1859            ccb->ccb_h.status |= CAM_REQ_CMP;
1860            ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1861        } else {
1862            /* error */
1863            if (gccb->gc_service == GDT_CACHESERVICE) {
1864                ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1865                ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1866                ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1867                bzero(&ccb->csio.sense_data, ccb->csio.sense_len);
1868                ccb->csio.sense_data.error_code =
1869                    SSD_CURRENT_ERROR | SSD_ERRCODE_VALID;
1870                ccb->csio.sense_data.flags = SSD_KEY_NOT_READY;
1871
1872                gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.sync);
1873                gdt->sc_dvr.eu.sync.ionode  = gdt->sc_hanum;
1874                gdt->sc_dvr.eu.sync.service = service;
1875                gdt->sc_dvr.eu.sync.status  = gdt->sc_status;
1876                gdt->sc_dvr.eu.sync.info    = gdt->sc_info;
1877                gdt->sc_dvr.eu.sync.hostdrive = ccb->ccb_h.target_id;
1878                if (gdt->sc_status >= 0x8000)
1879                    gdt_store_event(GDT_ES_SYNC, 0, &gdt->sc_dvr);
1880                else
1881                    gdt_store_event(GDT_ES_SYNC, service, &gdt->sc_dvr);
1882            } else {
1883                /* raw service */
1884                if (gdt->sc_status != GDT_S_RAW_SCSI || gdt->sc_info >= 0x100) {
1885                    ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1886                } else {
1887                    ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID;
1888                    ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1889                    ccb->csio.scsi_status = gdt->sc_info;
1890                    bcopy(gccb->gc_scratch, &ccb->csio.sense_data,
1891                          ccb->csio.sense_len);
1892                }
1893            }
1894        }
1895        --gdt_stat.io_count_act;
1896        xpt_done(ccb);
1897    }
1898    return (0);
1899}
1900
1901/* Controller event handling functions */
1902gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx,
1903                             gdt_evt_data *evt)
1904{
1905    gdt_evt_str *e;
1906    struct timeval tv;
1907
1908    GDT_DPRINTF(GDT_D_MISC, ("gdt_store_event(%d, %d)\n", source, idx));
1909    if (source == 0)                        /* no source -> no event */
1910        return 0;
1911
1912    if (ebuffer[elastidx].event_source == source &&
1913        ebuffer[elastidx].event_idx == idx &&
1914        ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 &&
1915          !memcmp((char *)&ebuffer[elastidx].event_data.eu,
1916                  (char *)&evt->eu, evt->size)) ||
1917         (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 &&
1918          !strcmp((char *)&ebuffer[elastidx].event_data.event_string,
1919                  (char *)&evt->event_string)))) {
1920        e = &ebuffer[elastidx];
1921        getmicrotime(&tv);
1922        e->last_stamp = tv.tv_sec;
1923        ++e->same_count;
1924    } else {
1925        if (ebuffer[elastidx].event_source != 0) {  /* entry not free ? */
1926            ++elastidx;
1927            if (elastidx == GDT_MAX_EVENTS)
1928                elastidx = 0;
1929            if (elastidx == eoldidx) {              /* reached mark ? */
1930                ++eoldidx;
1931                if (eoldidx == GDT_MAX_EVENTS)
1932                    eoldidx = 0;
1933            }
1934        }
1935        e = &ebuffer[elastidx];
1936        e->event_source = source;
1937        e->event_idx = idx;
1938        getmicrotime(&tv);
1939        e->first_stamp = e->last_stamp = tv.tv_sec;
1940        e->same_count = 1;
1941        e->event_data = *evt;
1942        e->application = 0;
1943    }
1944    return e;
1945}
1946
1947int gdt_read_event(int handle, gdt_evt_str *estr)
1948{
1949    gdt_evt_str *e;
1950    int eindex, lock;
1951
1952    GDT_DPRINTF(GDT_D_MISC, ("gdt_read_event(%d)\n", handle));
1953    lock = splcam();
1954    if (handle == -1)
1955        eindex = eoldidx;
1956    else
1957        eindex = handle;
1958    estr->event_source = 0;
1959
1960    if (eindex >= GDT_MAX_EVENTS) {
1961        splx(lock);
1962        return eindex;
1963    }
1964    e = &ebuffer[eindex];
1965    if (e->event_source != 0) {
1966        if (eindex != elastidx) {
1967            if (++eindex == GDT_MAX_EVENTS)
1968                eindex = 0;
1969        } else {
1970            eindex = -1;
1971        }
1972        memcpy(estr, e, sizeof(gdt_evt_str));
1973    }
1974    splx(lock);
1975    return eindex;
1976}
1977
1978void gdt_readapp_event(u_int8_t application, gdt_evt_str *estr)
1979{
1980    gdt_evt_str *e;
1981    int found = FALSE;
1982    int eindex, lock;
1983
1984    GDT_DPRINTF(GDT_D_MISC, ("gdt_readapp_event(%d)\n", application));
1985    lock = splcam();
1986    eindex = eoldidx;
1987    for (;;) {
1988        e = &ebuffer[eindex];
1989        if (e->event_source == 0)
1990            break;
1991        if ((e->application & application) == 0) {
1992            e->application |= application;
1993            found = TRUE;
1994            break;
1995        }
1996        if (eindex == elastidx)
1997            break;
1998        if (++eindex == GDT_MAX_EVENTS)
1999            eindex = 0;
2000    }
2001    if (found)
2002        memcpy(estr, e, sizeof(gdt_evt_str));
2003    else
2004        estr->event_source = 0;
2005    splx(lock);
2006}
2007
2008void gdt_clear_events()
2009{
2010    GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events\n"));
2011
2012    eoldidx = elastidx = 0;
2013    ebuffer[0].event_source = 0;
2014}
2015