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