iir.c revision 158651
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 158651 2006-05-16 14:37:58Z phk $");
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;
1352              u_int target_mask;
1353
1354              cts = &ccb->cts;
1355              target_mask = 0x01 << target;
1356              if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
1357                  cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB;
1358                  cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1359                  cts->sync_period = 25; /* 10MHz */
1360                  if (cts->sync_period != 0)
1361                      cts->sync_offset = 15;
1362
1363                  cts->valid = CCB_TRANS_SYNC_RATE_VALID
1364                      | CCB_TRANS_SYNC_OFFSET_VALID
1365                      | CCB_TRANS_BUS_WIDTH_VALID
1366                      | CCB_TRANS_DISC_VALID
1367                      | CCB_TRANS_TQ_VALID;
1368                  ccb->ccb_h.status = CAM_REQ_CMP;
1369              } else {
1370                  ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1371              }
1372              --gdt_stat.io_count_act;
1373              xpt_done(ccb);
1374              break;
1375          }
1376      case XPT_CALC_GEOMETRY:
1377          {
1378              struct ccb_calc_geometry *ccg;
1379              u_int32_t secs_per_cylinder;
1380
1381              ccg = &ccb->ccg;
1382              ccg->heads = gdt->sc_hdr[target].hd_heads;
1383              ccg->secs_per_track = gdt->sc_hdr[target].hd_secs;
1384              secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1385              ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1386              ccb->ccb_h.status = CAM_REQ_CMP;
1387              --gdt_stat.io_count_act;
1388              xpt_done(ccb);
1389              break;
1390          }
1391      case XPT_RESET_BUS:           /* Reset the specified SCSI bus */
1392          {
1393              /* XXX Implement */
1394              ccb->ccb_h.status = CAM_REQ_CMP;
1395              --gdt_stat.io_count_act;
1396              xpt_done(ccb);
1397              break;
1398          }
1399      case XPT_TERM_IO:             /* Terminate the I/O process */
1400        /* XXX Implement */
1401        ccb->ccb_h.status = CAM_REQ_INVALID;
1402        --gdt_stat.io_count_act;
1403        xpt_done(ccb);
1404        break;
1405      case XPT_PATH_INQ:            /* Path routing inquiry */
1406          {
1407              struct ccb_pathinq *cpi = &ccb->cpi;
1408
1409              cpi->version_num = 1;
1410              cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
1411              cpi->hba_inquiry |= PI_WIDE_16;
1412              cpi->target_sprt = 1;
1413              cpi->hba_misc = 0;
1414              cpi->hba_eng_cnt = 0;
1415              if (bus == gdt->sc_virt_bus)
1416                  cpi->max_target = GDT_MAX_HDRIVES - 1;
1417              else if (gdt->sc_class & GDT_FC)
1418                  cpi->max_target = GDT_MAXID_FC - 1;
1419              else
1420                  cpi->max_target = GDT_MAXID - 1;
1421              cpi->max_lun = 7;
1422              cpi->unit_number = cam_sim_unit(sim);
1423              cpi->bus_id = bus;
1424              cpi->initiator_id =
1425                  (bus == gdt->sc_virt_bus ? 127 : gdt->sc_bus_id[bus]);
1426              cpi->base_transfer_speed = 3300;
1427              strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1428              if (gdt->sc_vendor == INTEL_VENDOR_ID)
1429                  strncpy(cpi->hba_vid, "Intel Corp.", HBA_IDLEN);
1430              else
1431                  strncpy(cpi->hba_vid, "ICP vortex ", HBA_IDLEN);
1432              strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1433              cpi->ccb_h.status = CAM_REQ_CMP;
1434              --gdt_stat.io_count_act;
1435              xpt_done(ccb);
1436              break;
1437          }
1438      default:
1439        GDT_DPRINTF(GDT_D_INVALID, ("gdt_next(%p) cmd 0x%x invalid\n",
1440                                    gdt, ccb->ccb_h.func_code));
1441        ccb->ccb_h.status = CAM_REQ_INVALID;
1442        --gdt_stat.io_count_act;
1443        xpt_done(ccb);
1444        break;
1445    }
1446}
1447
1448static void
1449iir_poll( struct cam_sim *sim )
1450{
1451    struct gdt_softc *gdt;
1452
1453    gdt = (struct gdt_softc *)cam_sim_softc( sim );
1454    GDT_DPRINTF(GDT_D_CMD, ("iir_poll sim %p gdt %p\n", sim, gdt));
1455    iir_intr(gdt);
1456}
1457
1458static void
1459iir_timeout(void *arg)
1460{
1461    GDT_DPRINTF(GDT_D_TIMEOUT, ("iir_timeout(%p)\n", gccb));
1462}
1463
1464static void
1465iir_watchdog(void *arg)
1466{
1467    struct gdt_softc *gdt;
1468
1469    gdt = (struct gdt_softc *)arg;
1470    GDT_DPRINTF(GDT_D_DEBUG, ("iir_watchdog(%p)\n", gdt));
1471
1472    {
1473        int ccbs = 0, ucmds = 0, frees = 0, pends = 0;
1474        struct gdt_ccb *p;
1475        struct ccb_hdr *h;
1476        struct gdt_ucmd *u;
1477
1478        for (h = TAILQ_FIRST(&gdt->sc_ccb_queue); h != NULL;
1479             h = TAILQ_NEXT(h, sim_links.tqe))
1480            ccbs++;
1481        for (u = TAILQ_FIRST(&gdt->sc_ucmd_queue); u != NULL;
1482             u = TAILQ_NEXT(u, links))
1483            ucmds++;
1484        for (p = SLIST_FIRST(&gdt->sc_free_gccb); p != NULL;
1485             p = SLIST_NEXT(p, sle))
1486            frees++;
1487        for (p = SLIST_FIRST(&gdt->sc_pending_gccb); p != NULL;
1488             p = SLIST_NEXT(p, sle))
1489            pends++;
1490
1491        GDT_DPRINTF(GDT_D_TIMEOUT, ("ccbs %d ucmds %d frees %d pends %d\n",
1492               ccbs, ucmds, frees, pends));
1493    }
1494
1495    timeout(iir_watchdog, (caddr_t)gdt, hz * 15);
1496}
1497
1498static void
1499iir_shutdown( void *arg, int howto )
1500{
1501    struct gdt_softc *gdt;
1502    struct gdt_ccb *gccb;
1503    gdt_ucmd_t *ucmd;
1504    int lock, i;
1505
1506    gdt = (struct gdt_softc *)arg;
1507    GDT_DPRINTF(GDT_D_CMD, ("iir_shutdown(%p, %d)\n", gdt, howto));
1508
1509    printf("iir%d: Flushing all Host Drives. Please wait ...  ",
1510           gdt->sc_hanum);
1511
1512    /* allocate ucmd buffer */
1513    ucmd = malloc(sizeof(gdt_ucmd_t), M_GDTBUF, M_NOWAIT);
1514    if (ucmd == NULL) {
1515        printf("iir%d: iir_shutdown(): Cannot allocate resource\n",
1516               gdt->sc_hanum);
1517        return;
1518    }
1519    bzero(ucmd, sizeof(gdt_ucmd_t));
1520
1521    /* wait for pending IOs */
1522    lock = splcam();
1523    gdt->sc_state = GDT_SHUTDOWN;
1524    splx(lock);
1525    if ((gccb = SLIST_FIRST(&gdt->sc_pending_gccb)) != NULL)
1526        (void) tsleep((void *)gccb, PCATCH | PRIBIO, "iirshw", 100 * hz);
1527
1528    /* flush */
1529    for (i = 0; i < GDT_MAX_HDRIVES; ++i) {
1530        if (gdt->sc_hdr[i].hd_present) {
1531            ucmd->service = GDT_CACHESERVICE;
1532            ucmd->OpCode = GDT_FLUSH;
1533            ucmd->u.cache.DeviceNo = i;
1534            lock = splcam();
1535            TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links);
1536            ucmd->complete_flag = FALSE;
1537            splx(lock);
1538            gdt_next(gdt);
1539            if (!ucmd->complete_flag)
1540                (void) tsleep((void *)ucmd, PCATCH|PRIBIO, "iirshw", 10*hz);
1541        }
1542    }
1543
1544    free(ucmd, M_DEVBUF);
1545    printf("Done.\n");
1546}
1547
1548void
1549iir_intr(void *arg)
1550{
1551    struct gdt_softc *gdt = arg;
1552    struct gdt_intr_ctx ctx;
1553    int lock = 0;
1554    struct gdt_ccb *gccb;
1555    gdt_ucmd_t *ucmd;
1556    u_int32_t cnt;
1557
1558    GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p)\n", gdt));
1559
1560    /* If polling and we were not called from gdt_wait, just return */
1561    if ((gdt->sc_state & GDT_POLLING) &&
1562        !(gdt->sc_state & GDT_POLL_WAIT))
1563        return;
1564
1565    if (!(gdt->sc_state & GDT_POLLING))
1566        lock = splcam();
1567    gdt_wait_index = 0;
1568
1569    ctx.istatus = gdt->sc_get_status(gdt);
1570    if (ctx.istatus == 0x00) {
1571        if (!(gdt->sc_state & GDT_POLLING))
1572            splx(lock);
1573        gdt->sc_status = GDT_S_NO_STATUS;
1574        return;
1575    }
1576
1577    gdt->sc_intr(gdt, &ctx);
1578
1579    gdt->sc_status = ctx.cmd_status;
1580    gdt->sc_service = ctx.service;
1581    gdt->sc_info = ctx.info;
1582    gdt->sc_info2 = ctx.info2;
1583
1584    if (gdt->sc_state & GDT_POLL_WAIT) {
1585        gdt_wait_gdt = gdt;
1586        gdt_wait_index = ctx.istatus;
1587    }
1588
1589    if (ctx.istatus == GDT_ASYNCINDEX) {
1590        gdt_async_event(gdt, ctx.service);
1591        if (!(gdt->sc_state & GDT_POLLING))
1592            splx(lock);
1593        return;
1594    }
1595    if (ctx.istatus == GDT_SPEZINDEX) {
1596        GDT_DPRINTF(GDT_D_INVALID,
1597                    ("iir%d: Service unknown or not initialized!\n",
1598                     gdt->sc_hanum));
1599        gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
1600        gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
1601        gdt_store_event(GDT_ES_DRIVER, 4, &gdt->sc_dvr);
1602        if (!(gdt->sc_state & GDT_POLLING))
1603            splx(lock);
1604        return;
1605    }
1606
1607    gccb = &gdt->sc_gccbs[ctx.istatus - 2];
1608    ctx.service = gccb->gc_service;
1609
1610    switch (gccb->gc_flags) {
1611      case GDT_GCF_UNUSED:
1612        GDT_DPRINTF(GDT_D_INVALID, ("iir%d: Index (%d) to unused command!\n",
1613                    gdt->sc_hanum, ctx.istatus));
1614        gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver);
1615        gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum;
1616        gdt->sc_dvr.eu.driver.index = ctx.istatus;
1617        gdt_store_event(GDT_ES_DRIVER, 1, &gdt->sc_dvr);
1618        gdt_free_ccb(gdt, gccb);
1619        /* fallthrough */
1620
1621      case GDT_GCF_INTERNAL:
1622        if (!(gdt->sc_state & GDT_POLLING))
1623            splx(lock);
1624        break;
1625
1626      case GDT_GCF_IOCTL:
1627        ucmd = gccb->gc_ucmd;
1628        if (gdt->sc_status == GDT_S_BSY) {
1629            GDT_DPRINTF(GDT_D_DEBUG, ("iir_intr(%p) ioctl: gccb %p busy\n",
1630                                      gdt, gccb));
1631            TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links);
1632            if (!(gdt->sc_state & GDT_POLLING))
1633                splx(lock);
1634        } else {
1635            ucmd->status = gdt->sc_status;
1636            ucmd->info = gdt->sc_info;
1637            ucmd->complete_flag = TRUE;
1638            if (ucmd->service == GDT_CACHESERVICE) {
1639                if (ucmd->OpCode == GDT_IOCTL) {
1640                    cnt = ucmd->u.ioctl.param_size;
1641                    if (cnt != 0)
1642                        bcopy(gccb->gc_scratch, ucmd->data, cnt);
1643                } else {
1644                    cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE;
1645                    if (cnt != 0)
1646                        bcopy(gccb->gc_scratch, ucmd->data, cnt);
1647                }
1648            } else {
1649                cnt = ucmd->u.raw.sdlen;
1650                if (cnt != 0)
1651                    bcopy(gccb->gc_scratch, ucmd->data, cnt);
1652                if (ucmd->u.raw.sense_len != 0)
1653                    bcopy(gccb->gc_scratch, ucmd->data, cnt);
1654            }
1655            gdt_free_ccb(gdt, gccb);
1656            if (!(gdt->sc_state & GDT_POLLING))
1657                splx(lock);
1658            /* wakeup */
1659            wakeup(ucmd);
1660        }
1661        gdt_next(gdt);
1662        break;
1663
1664      default:
1665        gdt_free_ccb(gdt, gccb);
1666        gdt_sync_event(gdt, ctx.service, ctx.istatus, gccb);
1667        if (!(gdt->sc_state & GDT_POLLING))
1668            splx(lock);
1669        gdt_next(gdt);
1670        break;
1671    }
1672}
1673
1674int
1675gdt_async_event(struct gdt_softc *gdt, int service)
1676{
1677    struct gdt_ccb *gccb;
1678
1679    GDT_DPRINTF(GDT_D_INTR, ("gdt_async_event(%p, %d)\n", gdt, service));
1680
1681    if (service == GDT_SCREENSERVICE) {
1682        if (gdt->sc_status == GDT_MSG_REQUEST) {
1683            while (gdt->sc_test_busy(gdt))
1684                DELAY(1);
1685            gccb = gdt_get_ccb(gdt);
1686            if (gccb == NULL) {
1687                printf("iir%d: No free command index found\n",
1688                       gdt->sc_hanum);
1689                return (1);
1690            }
1691            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1692            gccb->gc_service = service;
1693            gccb->gc_flags = GDT_GCF_SCREEN;
1694            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1695                      gccb->gc_cmd_index);
1696            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_READ);
1697            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1698                      GDT_MSG_INV_HANDLE);
1699            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1700                      gccb->gc_scratch_busbase);
1701            gdt->sc_set_sema0(gdt);
1702            gdt->sc_cmd_off = 0;
1703            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1704                                      sizeof(u_int32_t));
1705            gdt->sc_cmd_cnt = 0;
1706            gdt->sc_copy_cmd(gdt, gccb);
1707            printf("iir%d: [PCI %d/%d] ",
1708                gdt->sc_hanum,gdt->sc_bus,gdt->sc_slot);
1709            gdt->sc_release_event(gdt);
1710        }
1711
1712    } else {
1713        if ((gdt->sc_fw_vers & 0xff) >= 0x1a) {
1714            gdt->sc_dvr.size = 0;
1715            gdt->sc_dvr.eu.async.ionode = gdt->sc_hanum;
1716            gdt->sc_dvr.eu.async.status  = gdt->sc_status;
1717            /* severity and event_string already set! */
1718        } else {
1719            gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.async);
1720            gdt->sc_dvr.eu.async.ionode   = gdt->sc_hanum;
1721            gdt->sc_dvr.eu.async.service = service;
1722            gdt->sc_dvr.eu.async.status  = gdt->sc_status;
1723            gdt->sc_dvr.eu.async.info    = gdt->sc_info;
1724            *(u_int32_t *)gdt->sc_dvr.eu.async.scsi_coord  = gdt->sc_info2;
1725        }
1726        gdt_store_event(GDT_ES_ASYNC, service, &gdt->sc_dvr);
1727        printf("iir%d: %s\n", gdt->sc_hanum, gdt->sc_dvr.event_string);
1728    }
1729
1730    return (0);
1731}
1732
1733int
1734gdt_sync_event(struct gdt_softc *gdt, int service,
1735               u_int8_t index, struct gdt_ccb *gccb)
1736{
1737    union ccb *ccb;
1738
1739    GDT_DPRINTF(GDT_D_INTR,
1740                ("gdt_sync_event(%p, %d, %d, %p)\n", gdt,service,index,gccb));
1741
1742    ccb = gccb->gc_ccb;
1743
1744    if (service == GDT_SCREENSERVICE) {
1745        u_int32_t msg_len;
1746
1747        msg_len = gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_LEN);
1748        if (msg_len)
1749            if (!(gccb->gc_scratch[GDT_SCR_MSG_ANSWER] &&
1750                  gccb->gc_scratch[GDT_SCR_MSG_EXT])) {
1751                gccb->gc_scratch[GDT_SCR_MSG_TEXT + msg_len] = '\0';
1752                printf("%s",&gccb->gc_scratch[GDT_SCR_MSG_TEXT]);
1753            }
1754
1755        if (gccb->gc_scratch[GDT_SCR_MSG_EXT] &&
1756            !gccb->gc_scratch[GDT_SCR_MSG_ANSWER]) {
1757            while (gdt->sc_test_busy(gdt))
1758                DELAY(1);
1759            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1760            gccb = gdt_get_ccb(gdt);
1761            if (gccb == NULL) {
1762                printf("iir%d: No free command index found\n",
1763                       gdt->sc_hanum);
1764                return (1);
1765            }
1766            gccb->gc_service = service;
1767            gccb->gc_flags = GDT_GCF_SCREEN;
1768            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1769                      gccb->gc_cmd_index);
1770            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_READ);
1771            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1772                      gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
1773            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1774                      gccb->gc_scratch_busbase);
1775            gdt->sc_set_sema0(gdt);
1776            gdt->sc_cmd_off = 0;
1777            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1778                                      sizeof(u_int32_t));
1779            gdt->sc_cmd_cnt = 0;
1780            gdt->sc_copy_cmd(gdt, gccb);
1781            gdt->sc_release_event(gdt);
1782            return (0);
1783        }
1784
1785        if (gccb->gc_scratch[GDT_SCR_MSG_ANSWER] &&
1786            gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN)) {
1787            /* default answers (getchar() not possible) */
1788            if (gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) == 1) {
1789                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN, 0);
1790                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 1);
1791                gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 0;
1792            } else {
1793                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_ALEN,
1794                          gdt_dec32(gccb->gc_scratch + GDT_SCR_MSG_ALEN) - 2);
1795                gdt_enc32(gccb->gc_scratch + GDT_SCR_MSG_LEN, 2);
1796                gccb->gc_scratch[GDT_SCR_MSG_TEXT] = 1;
1797                gccb->gc_scratch[GDT_SCR_MSG_TEXT + 1] = 0;
1798            }
1799            gccb->gc_scratch[GDT_SCR_MSG_EXT] = 0;
1800            gccb->gc_scratch[GDT_SCR_MSG_ANSWER] = 0;
1801            while (gdt->sc_test_busy(gdt))
1802                DELAY(1);
1803            bzero(gccb->gc_cmd, GDT_CMD_SZ);
1804            gccb = gdt_get_ccb(gdt);
1805            if (gccb == NULL) {
1806                printf("iir%d: No free command index found\n",
1807                       gdt->sc_hanum);
1808                return (1);
1809            }
1810            gccb->gc_service = service;
1811            gccb->gc_flags = GDT_GCF_SCREEN;
1812            gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX,
1813                      gccb->gc_cmd_index);
1814            gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_WRITE);
1815            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_HANDLE,
1816                      gccb->gc_scratch[GDT_SCR_MSG_HANDLE]);
1817            gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_SCREEN_MSG_ADDR,
1818                      gccb->gc_scratch_busbase);
1819            gdt->sc_set_sema0(gdt);
1820            gdt->sc_cmd_off = 0;
1821            gccb->gc_cmd_len = roundup(GDT_CMD_UNION + GDT_SCREEN_SZ,
1822                                      sizeof(u_int32_t));
1823            gdt->sc_cmd_cnt = 0;
1824            gdt->sc_copy_cmd(gdt, gccb);
1825            gdt->sc_release_event(gdt);
1826            return (0);
1827        }
1828        printf("\n");
1829        return (0);
1830    } else {
1831        untimeout(iir_timeout, gccb, ccb->ccb_h.timeout_ch);
1832        if (gdt->sc_status == GDT_S_BSY) {
1833            GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n",
1834                                      gdt, gccb));
1835            TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe);
1836            ++gdt_stat.req_queue_act;
1837            if (gdt_stat.req_queue_act > gdt_stat.req_queue_max)
1838                gdt_stat.req_queue_max = gdt_stat.req_queue_act;
1839            return (2);
1840        }
1841
1842        bus_dmamap_sync(gdt->sc_buffer_dmat, gccb->gc_dmamap,
1843            (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN ?
1844            BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1845        bus_dmamap_unload(gdt->sc_buffer_dmat, gccb->gc_dmamap);
1846
1847        ccb->csio.resid = 0;
1848        if (gdt->sc_status == GDT_S_OK) {
1849            ccb->ccb_h.status |= CAM_REQ_CMP;
1850            ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1851        } else {
1852            /* error */
1853            if (gccb->gc_service == GDT_CACHESERVICE) {
1854                ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1855                ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1856                ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1857                bzero(&ccb->csio.sense_data, ccb->csio.sense_len);
1858                ccb->csio.sense_data.error_code =
1859                    SSD_CURRENT_ERROR | SSD_ERRCODE_VALID;
1860                ccb->csio.sense_data.flags = SSD_KEY_NOT_READY;
1861
1862                gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.sync);
1863                gdt->sc_dvr.eu.sync.ionode  = gdt->sc_hanum;
1864                gdt->sc_dvr.eu.sync.service = service;
1865                gdt->sc_dvr.eu.sync.status  = gdt->sc_status;
1866                gdt->sc_dvr.eu.sync.info    = gdt->sc_info;
1867                gdt->sc_dvr.eu.sync.hostdrive = ccb->ccb_h.target_id;
1868                if (gdt->sc_status >= 0x8000)
1869                    gdt_store_event(GDT_ES_SYNC, 0, &gdt->sc_dvr);
1870                else
1871                    gdt_store_event(GDT_ES_SYNC, service, &gdt->sc_dvr);
1872            } else {
1873                /* raw service */
1874                if (gdt->sc_status != GDT_S_RAW_SCSI || gdt->sc_info >= 0x100) {
1875                    ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1876                } else {
1877                    ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID;
1878                    ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1879                    ccb->csio.scsi_status = gdt->sc_info;
1880                    bcopy(gccb->gc_scratch, &ccb->csio.sense_data,
1881                          ccb->csio.sense_len);
1882                }
1883            }
1884        }
1885        --gdt_stat.io_count_act;
1886        xpt_done(ccb);
1887    }
1888    return (0);
1889}
1890
1891/* Controller event handling functions */
1892gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx,
1893                             gdt_evt_data *evt)
1894{
1895    gdt_evt_str *e;
1896    struct timeval tv;
1897
1898    GDT_DPRINTF(GDT_D_MISC, ("gdt_store_event(%d, %d)\n", source, idx));
1899    if (source == 0)                        /* no source -> no event */
1900        return 0;
1901
1902    if (ebuffer[elastidx].event_source == source &&
1903        ebuffer[elastidx].event_idx == idx &&
1904        ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 &&
1905          !memcmp((char *)&ebuffer[elastidx].event_data.eu,
1906                  (char *)&evt->eu, evt->size)) ||
1907         (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 &&
1908          !strcmp((char *)&ebuffer[elastidx].event_data.event_string,
1909                  (char *)&evt->event_string)))) {
1910        e = &ebuffer[elastidx];
1911        getmicrotime(&tv);
1912        e->last_stamp = tv.tv_sec;
1913        ++e->same_count;
1914    } else {
1915        if (ebuffer[elastidx].event_source != 0) {  /* entry not free ? */
1916            ++elastidx;
1917            if (elastidx == GDT_MAX_EVENTS)
1918                elastidx = 0;
1919            if (elastidx == eoldidx) {              /* reached mark ? */
1920                ++eoldidx;
1921                if (eoldidx == GDT_MAX_EVENTS)
1922                    eoldidx = 0;
1923            }
1924        }
1925        e = &ebuffer[elastidx];
1926        e->event_source = source;
1927        e->event_idx = idx;
1928        getmicrotime(&tv);
1929        e->first_stamp = e->last_stamp = tv.tv_sec;
1930        e->same_count = 1;
1931        e->event_data = *evt;
1932        e->application = 0;
1933    }
1934    return e;
1935}
1936
1937int gdt_read_event(int handle, gdt_evt_str *estr)
1938{
1939    gdt_evt_str *e;
1940    int eindex, lock;
1941
1942    GDT_DPRINTF(GDT_D_MISC, ("gdt_read_event(%d)\n", handle));
1943    lock = splcam();
1944    if (handle == -1)
1945        eindex = eoldidx;
1946    else
1947        eindex = handle;
1948    estr->event_source = 0;
1949
1950    if (eindex >= GDT_MAX_EVENTS) {
1951        splx(lock);
1952        return eindex;
1953    }
1954    e = &ebuffer[eindex];
1955    if (e->event_source != 0) {
1956        if (eindex != elastidx) {
1957            if (++eindex == GDT_MAX_EVENTS)
1958                eindex = 0;
1959        } else {
1960            eindex = -1;
1961        }
1962        memcpy(estr, e, sizeof(gdt_evt_str));
1963    }
1964    splx(lock);
1965    return eindex;
1966}
1967
1968void gdt_readapp_event(u_int8_t application, gdt_evt_str *estr)
1969{
1970    gdt_evt_str *e;
1971    int found = FALSE;
1972    int eindex, lock;
1973
1974    GDT_DPRINTF(GDT_D_MISC, ("gdt_readapp_event(%d)\n", application));
1975    lock = splcam();
1976    eindex = eoldidx;
1977    for (;;) {
1978        e = &ebuffer[eindex];
1979        if (e->event_source == 0)
1980            break;
1981        if ((e->application & application) == 0) {
1982            e->application |= application;
1983            found = TRUE;
1984            break;
1985        }
1986        if (eindex == elastidx)
1987            break;
1988        if (++eindex == GDT_MAX_EVENTS)
1989            eindex = 0;
1990    }
1991    if (found)
1992        memcpy(estr, e, sizeof(gdt_evt_str));
1993    else
1994        estr->event_source = 0;
1995    splx(lock);
1996}
1997
1998void gdt_clear_events()
1999{
2000    GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events\n"));
2001
2002    eoldidx = elastidx = 0;
2003    ebuffer[0].event_source = 0;
2004}
2005