1 /* $FreeBSD: src/sys/dev/iir/iir.c,v 1.2.2.3 2002/05/05 08:18:12 asmodai Exp $ */
2 /* $DragonFly: src/sys/dev/raid/iir/iir.c,v 1.21 2008/05/18 20:30:23 pavalos Exp $ */
4 * Copyright (c) 2000-01 Intel Corporation
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
33 * iir.c: SCSI dependant code for the Intel Integrated RAID Controller driver
35 * Written by: Achim Leubner <achim.leubner@intel.com>
36 * Fixes/Additions: Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>
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.
45 #ident "$Id: iir.c 1.2 2001/06/21 20:28:32 achim Exp $"
49 /* #include "opt_iir.h" */
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/types.h>
53 #include <sys/eventhandler.h>
54 #include <sys/malloc.h>
55 #include <sys/kernel.h>
57 #include <sys/thread2.h>
59 #include <machine/clock.h>
60 #include <machine/stdarg.h>
62 #include <bus/cam/cam.h>
63 #include <bus/cam/cam_ccb.h>
64 #include <bus/cam/cam_sim.h>
65 #include <bus/cam/cam_xpt_sim.h>
66 #include <bus/cam/cam_debug.h>
67 #include <bus/cam/scsi/scsi_all.h>
68 #include <bus/cam/scsi/scsi_message.h>
75 struct gdt_softc
*gdt_wait_gdt
;
79 int gdt_debug
= GDT_DEBUG
;
81 #define MAX_SERBUF 160
82 static void ser_init(void);
83 static void ser_puts(char *str
);
84 static void ser_putc(int c
);
85 static char strbuf
[MAX_SERBUF
+1];
87 #define COM_BASE 0x2f8
89 #define COM_BASE 0x3f8
91 static void ser_init()
93 unsigned port
=COM_BASE
;
97 /* 19200 Baud, if 9600: outb(12,port) */
103 static void ser_puts(char *str
)
108 for (ptr
=str
;*ptr
;++ptr
)
109 ser_putc((int)(*ptr
));
112 static void ser_putc(int c
)
114 unsigned port
=COM_BASE
;
116 while ((inb(port
+5) & 0x20)==0);
120 while ((inb(port
+5) & 0x20)==0);
126 ser_kprintf(const char *fmt
, ...)
131 __va_start(args
,fmt
);
132 i
= kvsprintf(strbuf
,fmt
,args
);
140 /* The linked list of softc structures */
141 struct gdt_softc_list gdt_softcs
= TAILQ_HEAD_INITIALIZER(gdt_softcs
);
142 /* controller cnt. */
145 static gdt_evt_str ebuffer
[GDT_MAX_EVENTS
];
146 static int elastidx
, eoldidx
;
148 gdt_statist_t gdt_stat
;
150 /* Definitions for our use of the SIM private CCB area */
151 #define ccb_sim_ptr spriv_ptr0
152 #define ccb_priority spriv_field1
154 static void iir_action(struct cam_sim
*sim
, union ccb
*ccb
);
155 static void iir_poll(struct cam_sim
*sim
);
156 static void iir_shutdown(void *arg
, int howto
);
157 static void iir_timeout(void *arg
);
158 static void iir_watchdog(void *arg
);
160 static void gdt_eval_mapping(u_int32_t size
, int *cyls
, int *heads
,
162 static int gdt_internal_cmd(struct gdt_softc
*gdt
, struct gdt_ccb
*gccb
,
163 u_int8_t service
, u_int16_t opcode
,
164 u_int32_t arg1
, u_int32_t arg2
, u_int32_t arg3
);
165 static int gdt_wait(struct gdt_softc
*gdt
, struct gdt_ccb
*ccb
,
168 static struct gdt_ccb
*gdt_get_ccb(struct gdt_softc
*gdt
);
169 static u_int32_t
gdt_ccb_vtop(struct gdt_softc
*gdt
,
170 struct gdt_ccb
*gccb
);
172 static int gdt_sync_event(struct gdt_softc
*gdt
, int service
,
173 u_int8_t index
, struct gdt_ccb
*gccb
);
174 static int gdt_async_event(struct gdt_softc
*gdt
, int service
);
175 static struct gdt_ccb
*gdt_raw_cmd(struct gdt_softc
*gdt
, union ccb
*ccb
);
176 static struct gdt_ccb
*gdt_cache_cmd(struct gdt_softc
*gdt
, union ccb
*ccb
);
177 static struct gdt_ccb
*gdt_ioctl_cmd(struct gdt_softc
*gdt
, gdt_ucmd_t
*ucmd
);
178 static void gdt_internal_cache_cmd(struct gdt_softc
*gdt
,union ccb
*ccb
);
180 static void gdtmapmem(void *arg
, bus_dma_segment_t
*dm_segs
,
181 int nseg
, int error
);
182 static void gdtexecuteccb(void *arg
, bus_dma_segment_t
*dm_segs
,
183 int nseg
, int error
);
186 iir_init(struct gdt_softc
*gdt
)
189 int i
, id
, drv_cyls
, drv_hds
, drv_secs
;
190 struct gdt_ccb
*gccb
;
192 GDT_DPRINTF(GDT_D_DEBUG
, ("iir_init()\n"));
194 gdt
->sc_state
= GDT_POLLING
;
196 bzero(&gdt_stat
, sizeof(gdt_statist_t
));
198 SLIST_INIT(&gdt
->sc_free_gccb
);
199 SLIST_INIT(&gdt
->sc_pending_gccb
);
200 TAILQ_INIT(&gdt
->sc_ccb_queue
);
201 TAILQ_INIT(&gdt
->sc_ucmd_queue
);
202 TAILQ_INSERT_TAIL(&gdt_softcs
, gdt
, links
);
204 /* DMA tag for mapping buffers into device visible space. */
205 if (bus_dma_tag_create(gdt
->sc_parent_dmat
, /*alignment*/1, /*boundary*/0,
206 /*lowaddr*/BUS_SPACE_MAXADDR
,
207 /*highaddr*/BUS_SPACE_MAXADDR
,
208 /*filter*/NULL
, /*filterarg*/NULL
,
209 /*maxsize*/MAXBSIZE
, /*nsegments*/GDT_MAXSG
,
210 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT
,
211 /*flags*/BUS_DMA_ALLOCNOW
,
212 &gdt
->sc_buffer_dmat
) != 0) {
213 kprintf("iir%d: bus_dma_tag_create(...,gdt->sc_buffer_dmat) failed\n",
217 gdt
->sc_init_level
++;
219 /* DMA tag for our ccb structures */
220 if (bus_dma_tag_create(gdt
->sc_parent_dmat
, /*alignment*/1, /*boundary*/0,
221 /*lowaddr*/BUS_SPACE_MAXADDR
,
222 /*highaddr*/BUS_SPACE_MAXADDR
,
223 /*filter*/NULL
, /*filterarg*/NULL
,
224 GDT_MAXCMDS
* sizeof(struct gdt_ccb
),
226 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT
,
227 /*flags*/0, &gdt
->sc_gccb_dmat
) != 0) {
228 kprintf("iir%d: bus_dma_tag_create(...,gdt->sc_gccb_dmat) failed\n",
232 gdt
->sc_init_level
++;
234 /* Allocation for our ccbs */
235 if (bus_dmamem_alloc(gdt
->sc_gccb_dmat
, (void **)&gdt
->sc_gccbs
,
236 BUS_DMA_NOWAIT
, &gdt
->sc_gccb_dmamap
) != 0) {
237 kprintf("iir%d: bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n",
241 gdt
->sc_init_level
++;
243 /* And permanently map them */
244 bus_dmamap_load(gdt
->sc_gccb_dmat
, gdt
->sc_gccb_dmamap
,
245 gdt
->sc_gccbs
, GDT_MAXCMDS
* sizeof(struct gdt_ccb
),
246 gdtmapmem
, &gdt
->sc_gccb_busbase
, /*flags*/0);
247 gdt
->sc_init_level
++;
249 /* Clear them out. */
250 bzero(gdt
->sc_gccbs
, GDT_MAXCMDS
* sizeof(struct gdt_ccb
));
252 /* Initialize the ccbs */
253 for (i
= GDT_MAXCMDS
-1; i
>= 0; i
--) {
254 gdt
->sc_gccbs
[i
].gc_cmd_index
= i
+ 2;
255 gdt
->sc_gccbs
[i
].gc_flags
= GDT_GCF_UNUSED
;
256 gdt
->sc_gccbs
[i
].gc_map_flag
= FALSE
;
257 if (bus_dmamap_create(gdt
->sc_buffer_dmat
, /*flags*/0,
258 &gdt
->sc_gccbs
[i
].gc_dmamap
) != 0)
260 gdt
->sc_gccbs
[i
].gc_map_flag
= TRUE
;
261 SLIST_INSERT_HEAD(&gdt
->sc_free_gccb
, &gdt
->sc_gccbs
[i
], sle
);
263 gdt
->sc_init_level
++;
265 /* create the control device */
266 gdt
->sc_dev
= gdt_make_dev(gdt
->sc_hanum
);
268 /* allocate ccb for gdt_internal_cmd() */
269 gccb
= gdt_get_ccb(gdt
);
271 kprintf("iir%d: No free command index found\n",
276 if (!gdt_internal_cmd(gdt
, gccb
, GDT_SCREENSERVICE
, GDT_INIT
,
278 kprintf("iir%d: Screen service initialization error %d\n",
279 gdt
->sc_hanum
, gdt
->sc_status
);
280 gdt_free_ccb(gdt
, gccb
);
284 if (!gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_INIT
,
285 GDT_LINUX_OS
, 0, 0)) {
286 kprintf("iir%d: Cache service initialization error %d\n",
287 gdt
->sc_hanum
, gdt
->sc_status
);
288 gdt_free_ccb(gdt
, gccb
);
291 gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_UNFREEZE_IO
,
294 if (!gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_MOUNT
,
296 kprintf("iir%d: Cache service mount error %d\n",
297 gdt
->sc_hanum
, gdt
->sc_status
);
298 gdt_free_ccb(gdt
, gccb
);
302 if (!gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_INIT
,
303 GDT_LINUX_OS
, 0, 0)) {
304 kprintf("iir%d: Cache service post-mount initialization error %d\n",
305 gdt
->sc_hanum
, gdt
->sc_status
);
306 gdt_free_ccb(gdt
, gccb
);
309 cdev_cnt
= (u_int16_t
)gdt
->sc_info
;
310 gdt
->sc_fw_vers
= gdt
->sc_service
;
312 /* Detect number of buses */
313 gdt_enc32(gccb
->gc_scratch
+ GDT_IOC_VERSION
, GDT_IOC_NEWEST
);
314 gccb
->gc_scratch
[GDT_IOC_LIST_ENTRIES
] = GDT_MAXBUS
;
315 gccb
->gc_scratch
[GDT_IOC_FIRST_CHAN
] = 0;
316 gccb
->gc_scratch
[GDT_IOC_LAST_CHAN
] = GDT_MAXBUS
- 1;
317 gdt_enc32(gccb
->gc_scratch
+ GDT_IOC_LIST_OFFSET
, GDT_IOC_HDR_SZ
);
318 if (gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_IOCTL
,
319 GDT_IOCHAN_RAW_DESC
, GDT_INVALID_CHANNEL
,
320 GDT_IOC_HDR_SZ
+ GDT_MAXBUS
* GDT_RAWIOC_SZ
)) {
321 gdt
->sc_bus_cnt
= gccb
->gc_scratch
[GDT_IOC_CHAN_COUNT
];
322 for (i
= 0; i
< gdt
->sc_bus_cnt
; i
++) {
323 id
= gccb
->gc_scratch
[GDT_IOC_HDR_SZ
+
324 i
* GDT_RAWIOC_SZ
+ GDT_RAWIOC_PROC_ID
];
325 gdt
->sc_bus_id
[i
] = id
< GDT_MAXID_FC
? id
: 0xff;
328 /* New method failed, use fallback. */
329 for (i
= 0; i
< GDT_MAXBUS
; i
++) {
330 gdt_enc32(gccb
->gc_scratch
+ GDT_GETCH_CHANNEL_NO
, i
);
331 if (!gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_IOCTL
,
332 GDT_SCSI_CHAN_CNT
| GDT_L_CTRL_PATTERN
,
333 GDT_IO_CHANNEL
| GDT_INVALID_CHANNEL
,
336 kprintf("iir%d: Cannot get channel count, "
337 "error %d\n", gdt
->sc_hanum
, gdt
->sc_status
);
338 gdt_free_ccb(gdt
, gccb
);
344 (gccb
->gc_scratch
[GDT_GETCH_SIOP_ID
] < GDT_MAXID_FC
) ?
345 gccb
->gc_scratch
[GDT_GETCH_SIOP_ID
] : 0xff;
349 /* add one "virtual" channel for the host drives */
350 gdt
->sc_virt_bus
= gdt
->sc_bus_cnt
;
353 if (!gdt_internal_cmd(gdt
, gccb
, GDT_SCSIRAWSERVICE
, GDT_INIT
,
355 kprintf("iir%d: Raw service initialization error %d\n",
356 gdt
->sc_hanum
, gdt
->sc_status
);
357 gdt_free_ccb(gdt
, gccb
);
361 /* Set/get features raw service (scatter/gather) */
362 gdt
->sc_raw_feat
= 0;
363 if (gdt_internal_cmd(gdt
, gccb
, GDT_SCSIRAWSERVICE
, GDT_SET_FEAT
,
364 GDT_SCATTER_GATHER
, 0, 0)) {
365 if (gdt_internal_cmd(gdt
, gccb
, GDT_SCSIRAWSERVICE
, GDT_GET_FEAT
,
367 gdt
->sc_raw_feat
= gdt
->sc_info
;
368 if (!(gdt
->sc_info
& GDT_SCATTER_GATHER
)) {
369 panic("iir%d: Scatter/Gather Raw Service "
370 "required but not supported!\n", gdt
->sc_hanum
);
371 gdt_free_ccb(gdt
, gccb
);
377 /* Set/get features cache service (scatter/gather) */
378 gdt
->sc_cache_feat
= 0;
379 if (gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_SET_FEAT
,
380 0, GDT_SCATTER_GATHER
, 0)) {
381 if (gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_GET_FEAT
,
383 gdt
->sc_cache_feat
= gdt
->sc_info
;
384 if (!(gdt
->sc_info
& GDT_SCATTER_GATHER
)) {
385 panic("iir%d: Scatter/Gather Cache Service "
386 "required but not supported!\n", gdt
->sc_hanum
);
387 gdt_free_ccb(gdt
, gccb
);
393 /* Scan for cache devices */
394 for (i
= 0; i
< cdev_cnt
&& i
< GDT_MAX_HDRIVES
; i
++) {
395 if (gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
, GDT_INFO
,
397 gdt
->sc_hdr
[i
].hd_present
= 1;
398 gdt
->sc_hdr
[i
].hd_size
= gdt
->sc_info
;
401 * Evaluate mapping (sectors per head, heads per cyl)
403 gdt
->sc_hdr
[i
].hd_size
&= ~GDT_SECS32
;
404 if (gdt
->sc_info2
== 0)
405 gdt_eval_mapping(gdt
->sc_hdr
[i
].hd_size
,
406 &drv_cyls
, &drv_hds
, &drv_secs
);
408 drv_hds
= gdt
->sc_info2
& 0xff;
409 drv_secs
= (gdt
->sc_info2
>> 8) & 0xff;
410 drv_cyls
= gdt
->sc_hdr
[i
].hd_size
/ drv_hds
/
413 gdt
->sc_hdr
[i
].hd_heads
= drv_hds
;
414 gdt
->sc_hdr
[i
].hd_secs
= drv_secs
;
416 gdt
->sc_hdr
[i
].hd_size
= drv_cyls
* drv_hds
* drv_secs
;
418 if (gdt_internal_cmd(gdt
, gccb
, GDT_CACHESERVICE
,
419 GDT_DEVTYPE
, i
, 0, 0))
420 gdt
->sc_hdr
[i
].hd_devtype
= gdt
->sc_info
;
424 GDT_DPRINTF(GDT_D_INIT
, ("dpmem %x %d-bus %d cache device%s\n",
426 gdt
->sc_bus_cnt
, cdev_cnt
,
427 cdev_cnt
== 1 ? "" : "s"));
428 gdt_free_ccb(gdt
, gccb
);
435 iir_free(struct gdt_softc
*gdt
)
439 GDT_DPRINTF(GDT_D_INIT
, ("iir_free()\n"));
441 switch (gdt
->sc_init_level
) {
443 gdt_destroy_dev(gdt
->sc_dev
);
445 for (i
= GDT_MAXCMDS
-1; i
>= 0; i
--)
446 if (gdt
->sc_gccbs
[i
].gc_map_flag
)
447 bus_dmamap_destroy(gdt
->sc_buffer_dmat
,
448 gdt
->sc_gccbs
[i
].gc_dmamap
);
449 bus_dmamap_unload(gdt
->sc_gccb_dmat
, gdt
->sc_gccb_dmamap
);
451 bus_dmamem_free(gdt
->sc_gccb_dmat
, gdt
->sc_gccbs
, gdt
->sc_gccb_dmamap
);
453 bus_dma_tag_destroy(gdt
->sc_gccb_dmat
);
455 bus_dma_tag_destroy(gdt
->sc_buffer_dmat
);
457 bus_dma_tag_destroy(gdt
->sc_parent_dmat
);
461 TAILQ_REMOVE(&gdt_softcs
, gdt
, links
);
465 iir_attach(struct gdt_softc
*gdt
)
467 struct cam_devq
*devq
;
470 GDT_DPRINTF(GDT_D_INIT
, ("iir_attach()\n"));
472 callout_init(&gdt
->watchdog_timer
);
474 * Create the device queue for our SIM.
476 devq
= cam_simq_alloc(GDT_MAXCMDS
);
480 for (i
= 0; i
< gdt
->sc_bus_cnt
; i
++) {
482 * Construct our SIM entry
484 gdt
->sims
[i
] = cam_sim_alloc(iir_action
, iir_poll
, "iir",
485 gdt
, gdt
->sc_hanum
, &sim_mplock
,
487 /*tagged*/GDT_MAXCMDS
, devq
);
488 if (xpt_bus_register(gdt
->sims
[i
], i
) != CAM_SUCCESS
) {
489 cam_sim_free(gdt
->sims
[i
]);
493 if (xpt_create_path(&gdt
->paths
[i
], /*periph*/NULL
,
494 cam_sim_path(gdt
->sims
[i
]),
496 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
497 xpt_bus_deregister(cam_sim_path(gdt
->sims
[i
]));
498 cam_sim_free(gdt
->sims
[i
]);
502 cam_simq_release(devq
);
504 EVENTHANDLER_REGISTER(shutdown_post_sync
, iir_shutdown
,
505 gdt
, SHUTDOWN_PRI_DRIVER
);
506 /* iir_watchdog(gdt); */
507 gdt
->sc_state
= GDT_NORMAL
;
511 gdt_eval_mapping(u_int32_t size
, int *cyls
, int *heads
, int *secs
)
513 *cyls
= size
/ GDT_HEADS
/ GDT_SECS
;
514 if (*cyls
< GDT_MAXCYLS
) {
518 /* Too high for 64 * 32 */
519 *cyls
= size
/ GDT_MEDHEADS
/ GDT_MEDSECS
;
520 if (*cyls
< GDT_MAXCYLS
) {
521 *heads
= GDT_MEDHEADS
;
524 /* Too high for 127 * 63 */
525 *cyls
= size
/ GDT_BIGHEADS
/ GDT_BIGSECS
;
526 *heads
= GDT_BIGHEADS
;
533 gdt_wait(struct gdt_softc
*gdt
, struct gdt_ccb
*gccb
,
538 GDT_DPRINTF(GDT_D_INIT
,
539 ("gdt_wait(%p, %p, %d)\n", gdt
, gccb
, timeout
));
541 gdt
->sc_state
|= GDT_POLL_WAIT
;
544 if (gdt
== gdt_wait_gdt
&&
545 gccb
->gc_cmd_index
== gdt_wait_index
) {
551 gdt
->sc_state
&= ~GDT_POLL_WAIT
;
553 while (gdt
->sc_test_busy(gdt
))
554 DELAY(1); /* XXX correct? */
560 gdt_internal_cmd(struct gdt_softc
*gdt
, struct gdt_ccb
*gccb
,
561 u_int8_t service
, u_int16_t opcode
,
562 u_int32_t arg1
, u_int32_t arg2
, u_int32_t arg3
)
566 GDT_DPRINTF(GDT_D_CMD
, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d)\n",
567 gdt
, service
, opcode
, arg1
, arg2
, arg3
));
569 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
571 for (retries
= GDT_RETRIES
; ; ) {
572 gccb
->gc_service
= service
;
573 gccb
->gc_flags
= GDT_GCF_INTERNAL
;
575 gdt
->sc_set_sema0(gdt
);
576 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
578 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, opcode
);
581 case GDT_CACHESERVICE
:
582 if (opcode
== GDT_IOCTL
) {
583 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+
584 GDT_IOCTL_SUBFUNC
, arg1
);
585 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+
586 GDT_IOCTL_CHANNEL
, arg2
);
587 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_UNION
+
588 GDT_IOCTL_PARAM_SIZE
, (u_int16_t
)arg3
);
589 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_IOCTL_P_PARAM
,
590 gdt_ccb_vtop(gdt
, gccb
) +
591 offsetof(struct gdt_ccb
, gc_scratch
[0]));
593 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_UNION
+
594 GDT_CACHE_DEVICENO
, (u_int16_t
)arg1
);
595 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+
596 GDT_CACHE_BLOCKNO
, arg2
);
600 case GDT_SCSIRAWSERVICE
:
601 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+
602 GDT_RAW_DIRECTION
, arg1
);
603 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_BUS
] =
605 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_TARGET
] =
607 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_LUN
] =
608 (u_int8_t
)(arg3
>> 8);
611 gdt
->sc_cmd_len
= GDT_CMD_SZ
;
614 gdt
->sc_copy_cmd(gdt
, gccb
);
615 gdt
->sc_release_event(gdt
);
617 if (!gdt_wait(gdt
, gccb
, GDT_POLL_TIMEOUT
))
619 if (gdt
->sc_status
!= GDT_S_BSY
|| --retries
== 0)
623 return (gdt
->sc_status
== GDT_S_OK
);
626 static struct gdt_ccb
*
627 gdt_get_ccb(struct gdt_softc
*gdt
)
629 struct gdt_ccb
*gccb
;
631 GDT_DPRINTF(GDT_D_QUEUE
, ("gdt_get_ccb(%p)\n", gdt
));
634 gccb
= SLIST_FIRST(&gdt
->sc_free_gccb
);
636 SLIST_REMOVE_HEAD(&gdt
->sc_free_gccb
, sle
);
637 SLIST_INSERT_HEAD(&gdt
->sc_pending_gccb
, gccb
, sle
);
638 ++gdt_stat
.cmd_index_act
;
639 if (gdt_stat
.cmd_index_act
> gdt_stat
.cmd_index_max
)
640 gdt_stat
.cmd_index_max
= gdt_stat
.cmd_index_act
;
647 gdt_free_ccb(struct gdt_softc
*gdt
, struct gdt_ccb
*gccb
)
649 GDT_DPRINTF(GDT_D_QUEUE
, ("gdt_free_ccb(%p, %p)\n", gdt
, gccb
));
652 gccb
->gc_flags
= GDT_GCF_UNUSED
;
653 SLIST_REMOVE(&gdt
->sc_pending_gccb
, gccb
, gdt_ccb
, sle
);
654 SLIST_INSERT_HEAD(&gdt
->sc_free_gccb
, gccb
, sle
);
655 --gdt_stat
.cmd_index_act
;
657 if (gdt
->sc_state
& GDT_SHUTDOWN
)
662 gdt_ccb_vtop(struct gdt_softc
*gdt
, struct gdt_ccb
*gccb
)
664 return (gdt
->sc_gccb_busbase
665 + (u_int32_t
)((caddr_t
)gccb
- (caddr_t
)gdt
->sc_gccbs
));
669 gdt_next(struct gdt_softc
*gdt
)
674 int bus
, target
, lun
;
677 struct ccb_scsiio
*csio
;
678 struct ccb_hdr
*ccbh
;
679 struct gdt_ccb
*gccb
= NULL
;
682 GDT_DPRINTF(GDT_D_QUEUE
, ("gdt_next(%p)\n", gdt
));
685 if (gdt
->sc_test_busy(gdt
)) {
686 if (!(gdt
->sc_state
& GDT_POLLING
)) {
690 while (gdt
->sc_test_busy(gdt
))
694 gdt
->sc_cmd_cnt
= gdt
->sc_cmd_off
= 0;
697 /* I/Os in queue? controller ready? */
698 if (!TAILQ_FIRST(&gdt
->sc_ucmd_queue
) &&
699 !TAILQ_FIRST(&gdt
->sc_ccb_queue
))
702 /* 1.: I/Os without ccb (IOCTLs) */
703 ucmd
= TAILQ_FIRST(&gdt
->sc_ucmd_queue
);
705 TAILQ_REMOVE(&gdt
->sc_ucmd_queue
, ucmd
, links
);
706 if ((gccb
= gdt_ioctl_cmd(gdt
, ucmd
)) == NULL
) {
707 TAILQ_INSERT_HEAD(&gdt
->sc_ucmd_queue
, ucmd
, links
);
711 /* wenn mehrere Kdos. zulassen: if (!gdt_polling) continue; */
714 /* 2.: I/Os with ccb */
715 ccb
= (union ccb
*)TAILQ_FIRST(&gdt
->sc_ccb_queue
);
716 /* ist dann immer != NULL, da oben getestet */
717 sim
= (struct cam_sim
*)ccb
->ccb_h
.ccb_sim_ptr
;
718 bus
= cam_sim_bus(sim
);
719 target
= ccb
->ccb_h
.target_id
;
720 lun
= ccb
->ccb_h
.target_lun
;
722 TAILQ_REMOVE(&gdt
->sc_ccb_queue
, &ccb
->ccb_h
, sim_links
.tqe
);
723 --gdt_stat
.req_queue_act
;
724 /* ccb->ccb_h.func_code is XPT_SCSI_IO */
725 GDT_DPRINTF(GDT_D_QUEUE
, ("XPT_SCSI_IO flags 0x%x)\n",
729 cmd
= csio
->cdb_io
.cdb_bytes
[0];
730 /* Max CDB length is 12 bytes */
731 if (csio
->cdb_len
> 12) {
732 ccbh
->status
= CAM_REQ_INVALID
;
733 --gdt_stat
.io_count_act
;
735 } else if (bus
!= gdt
->sc_virt_bus
) {
736 /* raw service command */
737 if ((gccb
= gdt_raw_cmd(gdt
, ccb
)) == NULL
) {
738 TAILQ_INSERT_HEAD(&gdt
->sc_ccb_queue
, &ccb
->ccb_h
,
740 ++gdt_stat
.req_queue_act
;
741 if (gdt_stat
.req_queue_act
> gdt_stat
.req_queue_max
)
742 gdt_stat
.req_queue_max
= gdt_stat
.req_queue_act
;
745 } else if (target
>= GDT_MAX_HDRIVES
||
746 !gdt
->sc_hdr
[target
].hd_present
|| lun
!= 0) {
747 ccbh
->status
= CAM_SEL_TIMEOUT
;
748 --gdt_stat
.io_count_act
;
751 /* cache service command */
752 if (cmd
== READ_6
|| cmd
== WRITE_6
||
753 cmd
== READ_10
|| cmd
== WRITE_10
) {
754 if ((gccb
= gdt_cache_cmd(gdt
, ccb
)) == NULL
) {
755 TAILQ_INSERT_HEAD(&gdt
->sc_ccb_queue
, &ccb
->ccb_h
,
757 ++gdt_stat
.req_queue_act
;
758 if (gdt_stat
.req_queue_act
> gdt_stat
.req_queue_max
)
759 gdt_stat
.req_queue_max
= gdt_stat
.req_queue_act
;
764 gdt_internal_cache_cmd(gdt
, ccb
);
768 if ((gdt
->sc_state
& GDT_POLLING
) || !next_cmd
)
771 if (gdt
->sc_cmd_cnt
> 0)
772 gdt
->sc_release_event(gdt
);
776 if ((gdt
->sc_state
& GDT_POLLING
) && gdt
->sc_cmd_cnt
> 0) {
777 gdt_wait(gdt
, gccb
, GDT_POLL_TIMEOUT
);
781 static struct gdt_ccb
*
782 gdt_raw_cmd(struct gdt_softc
*gdt
, union ccb
*ccb
)
784 struct gdt_ccb
*gccb
;
787 GDT_DPRINTF(GDT_D_CMD
, ("gdt_raw_cmd(%p, %p)\n", gdt
, ccb
));
789 if (roundup(GDT_CMD_UNION
+ GDT_RAW_SZ
, sizeof(u_int32_t
)) +
790 gdt
->sc_cmd_off
+ GDT_DPMEM_COMMAND_OFFSET
>
791 gdt
->sc_ic_all_size
) {
792 GDT_DPRINTF(GDT_D_INVALID
, ("iir%d: gdt_raw_cmd(): DPMEM overflow\n",
797 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
799 gccb
= gdt_get_ccb(gdt
);
801 GDT_DPRINTF(GDT_D_INVALID
, ("iir%d: No free command index found\n",
805 sim
= (struct cam_sim
*)ccb
->ccb_h
.ccb_sim_ptr
;
807 gccb
->gc_service
= GDT_SCSIRAWSERVICE
;
808 gccb
->gc_flags
= GDT_GCF_SCSI
;
810 if (gdt
->sc_cmd_cnt
== 0)
811 gdt
->sc_set_sema0(gdt
);
813 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
815 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, GDT_WRITE
);
817 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_DIRECTION
,
818 (ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
?
819 GDT_DATA_IN
: GDT_DATA_OUT
);
820 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SDLEN
,
821 ccb
->csio
.dxfer_len
);
822 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_CLEN
,
824 bcopy(ccb
->csio
.cdb_io
.cdb_bytes
, gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_CMD
,
826 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_TARGET
] =
827 ccb
->ccb_h
.target_id
;
828 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_LUN
] =
829 ccb
->ccb_h
.target_lun
;
830 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_BUS
] =
832 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SENSE_LEN
,
833 sizeof(struct scsi_sense_data
));
834 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SENSE_DATA
,
835 gdt_ccb_vtop(gdt
, gccb
) +
836 offsetof(struct gdt_ccb
, gc_scratch
[0]));
839 * If we have any data to send with this command,
840 * map it into bus space.
842 /* Only use S/G if there is a transfer */
843 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
844 if ((ccb
->ccb_h
.flags
& CAM_SCATTER_VALID
) == 0) {
845 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) == 0) {
848 /* vorher unlock von splcam() ??? */
851 bus_dmamap_load(gdt
->sc_buffer_dmat
,
857 if (error
== EINPROGRESS
) {
858 xpt_freeze_simq(sim
, 1);
859 gccb
->gc_state
|= CAM_RELEASE_SIMQ
;
863 struct bus_dma_segment seg
;
865 /* Pointer to physical buffer */
867 (bus_addr_t
)ccb
->csio
.data_ptr
;
868 seg
.ds_len
= ccb
->csio
.dxfer_len
;
869 gdtexecuteccb(gccb
, &seg
, 1, 0);
872 struct bus_dma_segment
*segs
;
874 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) != 0)
875 panic("iir%d: iir_action - Physical "
876 "segment pointers unsupported", gdt
->sc_hanum
);
878 if ((ccb
->ccb_h
.flags
& CAM_SG_LIST_PHYS
)==0)
879 panic("iir%d: iir_action - Virtual "
880 "segment addresses unsupported", gdt
->sc_hanum
);
882 /* Just use the segments provided */
883 segs
= (struct bus_dma_segment
*)ccb
->csio
.data_ptr
;
884 gdtexecuteccb(gccb
, segs
, ccb
->csio
.sglist_cnt
, 0);
887 gdtexecuteccb(gccb
, NULL
, 0, 0);
894 static struct gdt_ccb
*
895 gdt_cache_cmd(struct gdt_softc
*gdt
, union ccb
*ccb
)
897 struct gdt_ccb
*gccb
;
901 u_int32_t blockno
, blockcnt
;
903 GDT_DPRINTF(GDT_D_CMD
, ("gdt_cache_cmd(%p, %p)\n", gdt
, ccb
));
905 if (roundup(GDT_CMD_UNION
+ GDT_CACHE_SZ
, sizeof(u_int32_t
)) +
906 gdt
->sc_cmd_off
+ GDT_DPMEM_COMMAND_OFFSET
>
907 gdt
->sc_ic_all_size
) {
908 GDT_DPRINTF(GDT_D_INVALID
, ("iir%d: gdt_cache_cmd(): DPMEM overflow\n",
913 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
915 gccb
= gdt_get_ccb(gdt
);
917 GDT_DPRINTF(GDT_D_DEBUG
, ("iir%d: No free command index found\n",
921 sim
= (struct cam_sim
*)ccb
->ccb_h
.ccb_sim_ptr
;
923 gccb
->gc_service
= GDT_CACHESERVICE
;
924 gccb
->gc_flags
= GDT_GCF_SCSI
;
926 if (gdt
->sc_cmd_cnt
== 0)
927 gdt
->sc_set_sema0(gdt
);
929 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
931 cmdp
= ccb
->csio
.cdb_io
.cdb_bytes
;
932 opcode
= (*cmdp
== WRITE_6
|| *cmdp
== WRITE_10
) ? GDT_WRITE
: GDT_READ
;
933 if ((gdt
->sc_state
& GDT_SHUTDOWN
) && opcode
== GDT_WRITE
)
934 opcode
= GDT_WRITE_THR
;
935 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, opcode
);
937 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_DEVICENO
,
938 ccb
->ccb_h
.target_id
);
939 if (ccb
->csio
.cdb_len
== 6) {
940 struct scsi_rw_6
*rw
= (struct scsi_rw_6
*)cmdp
;
941 blockno
= scsi_3btoul(rw
->addr
) & ((SRW_TOPADDR
<<16) | 0xffff);
942 blockcnt
= rw
->length
? rw
->length
: 0x100;
944 struct scsi_rw_10
*rw
= (struct scsi_rw_10
*)cmdp
;
945 blockno
= scsi_4btoul(rw
->addr
);
946 blockcnt
= scsi_2btoul(rw
->length
);
948 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_BLOCKNO
,
950 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_BLOCKCNT
,
954 * If we have any data to send with this command,
955 * map it into bus space.
957 /* Only use S/G if there is a transfer */
958 if ((ccb
->ccb_h
.flags
& CAM_SCATTER_VALID
) == 0) {
959 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) == 0) {
962 /* vorher unlock von splcam() ??? */
965 bus_dmamap_load(gdt
->sc_buffer_dmat
,
971 if (error
== EINPROGRESS
) {
972 xpt_freeze_simq(sim
, 1);
973 gccb
->gc_state
|= CAM_RELEASE_SIMQ
;
977 struct bus_dma_segment seg
;
979 /* Pointer to physical buffer */
981 (bus_addr_t
)ccb
->csio
.data_ptr
;
982 seg
.ds_len
= ccb
->csio
.dxfer_len
;
983 gdtexecuteccb(gccb
, &seg
, 1, 0);
986 struct bus_dma_segment
*segs
;
988 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) != 0)
989 panic("iir%d: iir_action - Physical "
990 "segment pointers unsupported", gdt
->sc_hanum
);
992 if ((ccb
->ccb_h
.flags
& CAM_SG_LIST_PHYS
)==0)
993 panic("iir%d: iir_action - Virtual "
994 "segment addresses unsupported", gdt
->sc_hanum
);
996 /* Just use the segments provided */
997 segs
= (struct bus_dma_segment
*)ccb
->csio
.data_ptr
;
998 gdtexecuteccb(gccb
, segs
, ccb
->csio
.sglist_cnt
, 0);
1005 static struct gdt_ccb
*
1006 gdt_ioctl_cmd(struct gdt_softc
*gdt
, gdt_ucmd_t
*ucmd
)
1008 struct gdt_ccb
*gccb
;
1011 GDT_DPRINTF(GDT_D_DEBUG
, ("gdt_ioctl_cmd(%p, %p)\n", gdt
, ucmd
));
1013 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
1015 gccb
= gdt_get_ccb(gdt
);
1017 GDT_DPRINTF(GDT_D_DEBUG
, ("iir%d: No free command index found\n",
1021 gccb
->gc_ucmd
= ucmd
;
1022 gccb
->gc_service
= ucmd
->service
;
1023 gccb
->gc_flags
= GDT_GCF_IOCTL
;
1025 /* check DPMEM space, copy data buffer from user space */
1026 if (ucmd
->service
== GDT_CACHESERVICE
) {
1027 if (ucmd
->OpCode
== GDT_IOCTL
) {
1028 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_IOCTL_SZ
,
1030 cnt
= ucmd
->u
.ioctl
.param_size
;
1031 if (cnt
> GDT_SCRATCH_SZ
) {
1032 kprintf("iir%d: Scratch buffer too small (%d/%d)\n",
1033 gdt
->sc_hanum
, GDT_SCRATCH_SZ
, cnt
);
1034 gdt_free_ccb(gdt
, gccb
);
1038 gdt
->sc_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 kprintf("iir%d: Scratch buffer too small (%d/%d)\n",
1043 gdt
->sc_hanum
, GDT_SCRATCH_SZ
, cnt
);
1044 gdt_free_ccb(gdt
, gccb
);
1049 gdt
->sc_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 kprintf("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
);
1060 bcopy(ucmd
->data
, gccb
->gc_scratch
, cnt
);
1062 if (gdt
->sc_cmd_off
+ gdt
->sc_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",
1066 gdt_free_ccb(gdt
, gccb
);
1070 if (gdt
->sc_cmd_cnt
== 0)
1071 gdt
->sc_set_sema0(gdt
);
1074 /* fill cmd structure */
1075 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
1076 gccb
->gc_cmd_index
);
1077 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
,
1080 if (ucmd
->service
== GDT_CACHESERVICE
) {
1081 if (ucmd
->OpCode
== GDT_IOCTL
) {
1083 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_IOCTL_PARAM_SIZE
,
1084 ucmd
->u
.ioctl
.param_size
);
1085 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_IOCTL_SUBFUNC
,
1086 ucmd
->u
.ioctl
.subfunc
);
1087 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_IOCTL_CHANNEL
,
1088 ucmd
->u
.ioctl
.channel
);
1089 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_IOCTL_P_PARAM
,
1090 gdt_ccb_vtop(gdt
, gccb
) +
1091 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1093 /* cache service command */
1094 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_DEVICENO
,
1095 ucmd
->u
.cache
.DeviceNo
);
1096 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_BLOCKNO
,
1097 ucmd
->u
.cache
.BlockNo
);
1098 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_BLOCKCNT
,
1099 ucmd
->u
.cache
.BlockCnt
);
1100 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_DESTADDR
,
1102 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_CANZ
,
1104 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_LST
+
1105 GDT_SG_PTR
, gdt_ccb_vtop(gdt
, gccb
) +
1106 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1107 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_LST
+
1108 GDT_SG_LEN
, ucmd
->u
.cache
.BlockCnt
* GDT_SECTOR_SIZE
);
1111 /* raw service command */
1112 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_DIRECTION
,
1113 ucmd
->u
.raw
.direction
);
1114 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SDATA
,
1116 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SDLEN
,
1118 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_CLEN
,
1120 bcopy(ucmd
->u
.raw
.cmd
, gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_CMD
,
1122 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_TARGET
] =
1124 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_LUN
] =
1126 gdt
->sc_cmd
[GDT_CMD_UNION
+ GDT_RAW_BUS
] =
1128 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SENSE_LEN
,
1129 ucmd
->u
.raw
.sense_len
);
1130 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SENSE_DATA
,
1131 gdt_ccb_vtop(gdt
, gccb
) +
1132 offsetof(struct gdt_ccb
, gc_scratch
[ucmd
->u
.raw
.sdlen
]));
1133 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_RANZ
,
1135 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_LST
+
1136 GDT_SG_PTR
, gdt_ccb_vtop(gdt
, gccb
) +
1137 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1138 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_LST
+
1139 GDT_SG_LEN
, ucmd
->u
.raw
.sdlen
);
1143 gdt_stat
.sg_count_act
= 1;
1144 gdt
->sc_copy_cmd(gdt
, gccb
);
1149 gdt_internal_cache_cmd(struct gdt_softc
*gdt
,union ccb
*ccb
)
1153 t
= ccb
->ccb_h
.target_id
;
1154 GDT_DPRINTF(GDT_D_CMD
, ("gdt_internal_cache_cmd(%p, %p, 0x%x, %d)\n",
1155 gdt
, ccb
, ccb
->csio
.cdb_io
.cdb_bytes
[0], t
));
1157 switch (ccb
->csio
.cdb_io
.cdb_bytes
[0]) {
1158 case TEST_UNIT_READY
:
1162 GDT_DPRINTF(GDT_D_MISC
, ("REQUEST_SENSE\n"));
1166 struct scsi_inquiry_data
*inq
;
1168 inq
= (struct scsi_inquiry_data
*)ccb
->csio
.data_ptr
;
1169 bzero(inq
, sizeof(struct scsi_inquiry_data
));
1170 inq
->device
= (gdt
->sc_hdr
[t
].hd_devtype
& 4) ?
1172 inq
->dev_qual2
= (gdt
->sc_hdr
[t
].hd_devtype
& 1) ? 0x80 : 0;
1173 inq
->version
= SCSI_REV_2
;
1174 inq
->response_format
= 2;
1175 inq
->additional_length
= 32;
1176 inq
->flags
= SID_CmdQue
| SID_Sync
;
1177 strcpy(inq
->vendor
, "IIR ");
1178 ksprintf(inq
->product
, "Host Drive #%02d", t
);
1179 strcpy(inq
->revision
, " ");
1185 struct scsi_mode_hdr_6 hd
;
1186 struct scsi_mode_block_descr bd
;
1187 struct scsi_control_page cp
;
1191 mpd
= (struct mpd_data
*)ccb
->csio
.data_ptr
;
1192 bzero(mpd
, sizeof(struct mpd_data
));
1193 mpd
->hd
.datalen
= sizeof(struct scsi_mode_hdr_6
) +
1194 sizeof(struct scsi_mode_block_descr
);
1195 mpd
->hd
.dev_specific
= (gdt
->sc_hdr
[t
].hd_devtype
& 2) ? 0x80 : 0;
1196 mpd
->hd
.block_descr_len
= sizeof(struct scsi_mode_block_descr
);
1197 mpd
->bd
.block_len
[0] = (GDT_SECTOR_SIZE
& 0x00ff0000) >> 16;
1198 mpd
->bd
.block_len
[1] = (GDT_SECTOR_SIZE
& 0x0000ff00) >> 8;
1199 mpd
->bd
.block_len
[2] = (GDT_SECTOR_SIZE
& 0x000000ff);
1200 page
=((struct scsi_mode_sense_6
*)ccb
->csio
.cdb_io
.cdb_bytes
)->page
;
1203 GDT_DPRINTF(GDT_D_MISC
, ("MODE_SENSE_6: page 0x%x\n", page
));
1210 struct scsi_read_capacity_data
*rcd
;
1212 rcd
= (struct scsi_read_capacity_data
*)ccb
->csio
.data_ptr
;
1213 bzero(rcd
, sizeof(struct scsi_read_capacity_data
));
1214 scsi_ulto4b(gdt
->sc_hdr
[t
].hd_size
- 1, rcd
->addr
);
1215 scsi_ulto4b(GDT_SECTOR_SIZE
, rcd
->length
);
1219 GDT_DPRINTF(GDT_D_MISC
, ("gdt_internal_cache_cmd(%d) unknown\n",
1220 ccb
->csio
.cdb_io
.cdb_bytes
[0]));
1223 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1224 --gdt_stat
.io_count_act
;
1229 gdtmapmem(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
1231 bus_addr_t
*busaddrp
;
1233 busaddrp
= (bus_addr_t
*)arg
;
1234 *busaddrp
= dm_segs
->ds_addr
;
1238 gdtexecuteccb(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
1240 struct gdt_ccb
*gccb
;
1242 struct gdt_softc
*gdt
;
1247 gccb
= (struct gdt_ccb
*)arg
;
1249 gdt
= cam_sim_softc((struct cam_sim
*)ccb
->ccb_h
.ccb_sim_ptr
);
1251 GDT_DPRINTF(GDT_D_CMD
, ("gdtexecuteccb(%p, %p, %p, %d, %d)\n",
1252 gdt
, gccb
, dm_segs
, nseg
, error
));
1253 gdt_stat
.sg_count_act
= nseg
;
1254 if (nseg
> gdt_stat
.sg_count_max
)
1255 gdt_stat
.sg_count_max
= nseg
;
1257 /* Copy the segments into our SG list */
1258 if (gccb
->gc_service
== GDT_CACHESERVICE
) {
1259 for (i
= 0; i
< nseg
; ++i
) {
1260 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_LST
+
1261 i
* GDT_SG_SZ
+ GDT_SG_PTR
, dm_segs
->ds_addr
);
1262 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_LST
+
1263 i
* GDT_SG_SZ
+ GDT_SG_LEN
, dm_segs
->ds_len
);
1266 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_SG_CANZ
,
1268 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_CACHE_DESTADDR
,
1271 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_CACHE_SG_LST
+
1272 nseg
* GDT_SG_SZ
, sizeof(u_int32_t
));
1274 for (i
= 0; i
< nseg
; ++i
) {
1275 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_LST
+
1276 i
* GDT_SG_SZ
+ GDT_SG_PTR
, dm_segs
->ds_addr
);
1277 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_LST
+
1278 i
* GDT_SG_SZ
+ GDT_SG_LEN
, dm_segs
->ds_len
);
1281 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SG_RANZ
,
1283 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_RAW_SDATA
,
1286 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_RAW_SG_LST
+
1287 nseg
* GDT_SG_SZ
, sizeof(u_int32_t
));
1291 bus_dmasync_op_t op
;
1293 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1294 op
= BUS_DMASYNC_PREREAD
;
1296 op
= BUS_DMASYNC_PREWRITE
;
1297 bus_dmamap_sync(gdt
->sc_buffer_dmat
, gccb
->gc_dmamap
, op
);
1300 /* We must NOT abort the command here if CAM_REQ_INPROG is not set,
1301 * because command semaphore is already set!
1304 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
1305 /* timeout handling */
1306 callout_reset(&ccb
->ccb_h
.timeout_ch
, (ccb
->ccb_h
.timeout
* hz
) / 1000,
1309 gdt
->sc_copy_cmd(gdt
, gccb
);
1315 iir_action( struct cam_sim
*sim
, union ccb
*ccb
)
1317 struct gdt_softc
*gdt
;
1318 int bus
, target
, lun
;
1320 gdt
= (struct gdt_softc
*)cam_sim_softc( sim
);
1321 ccb
->ccb_h
.ccb_sim_ptr
= sim
;
1322 bus
= cam_sim_bus(sim
);
1323 target
= ccb
->ccb_h
.target_id
;
1324 lun
= ccb
->ccb_h
.target_lun
;
1325 GDT_DPRINTF(GDT_D_CMD
,
1326 ("iir_action(%p) func 0x%x cmd 0x%x bus %d target %d lun %d\n",
1327 gdt
, ccb
->ccb_h
.func_code
, ccb
->csio
.cdb_io
.cdb_bytes
[0],
1329 ++gdt_stat
.io_count_act
;
1330 if (gdt_stat
.io_count_act
> gdt_stat
.io_count_max
)
1331 gdt_stat
.io_count_max
= gdt_stat
.io_count_act
;
1333 switch (ccb
->ccb_h
.func_code
) {
1336 TAILQ_INSERT_TAIL(&gdt
->sc_ccb_queue
, &ccb
->ccb_h
, sim_links
.tqe
);
1337 ++gdt_stat
.req_queue_act
;
1338 if (gdt_stat
.req_queue_act
> gdt_stat
.req_queue_max
)
1339 gdt_stat
.req_queue_max
= gdt_stat
.req_queue_act
;
1343 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
1344 case XPT_ABORT
: /* Abort the specified CCB */
1346 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1347 --gdt_stat
.io_count_act
;
1350 case XPT_SET_TRAN_SETTINGS
:
1351 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1352 --gdt_stat
.io_count_act
;
1355 case XPT_GET_TRAN_SETTINGS
:
1356 /* Get default/user set transfer settings for the target */
1358 struct ccb_trans_settings
*cts
= &ccb
->cts
;
1359 struct ccb_trans_settings_scsi
*scsi
= &cts
->proto_specific
.scsi
;
1360 struct ccb_trans_settings_spi
*spi
= &cts
->xport_specific
.spi
;
1362 cts
->protocol
= PROTO_SCSI
;
1363 cts
->protocol_version
= SCSI_REV_2
;
1364 cts
->transport
= XPORT_SPI
;
1365 cts
->transport_version
= 2;
1367 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
1368 spi
->flags
= CTS_SPI_FLAGS_DISC_ENB
;
1369 scsi
->flags
= CTS_SCSI_FLAGS_TAG_ENB
;
1370 spi
->bus_width
= MSG_EXT_WDTR_BUS_16_BIT
;
1371 spi
->sync_period
= 25; /* 10MHz */
1372 if (spi
->sync_period
!= 0)
1373 spi
->sync_offset
= 15;
1375 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
1376 | CTS_SPI_VALID_SYNC_OFFSET
1377 | CTS_SPI_VALID_BUS_WIDTH
1378 | CTS_SPI_VALID_DISC
;
1379 scsi
->valid
= CTS_SCSI_VALID_TQ
;
1380 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1382 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1384 --gdt_stat
.io_count_act
;
1388 case XPT_CALC_GEOMETRY
:
1390 struct ccb_calc_geometry
*ccg
;
1391 u_int32_t secs_per_cylinder
;
1394 ccg
->heads
= gdt
->sc_hdr
[target
].hd_heads
;
1395 ccg
->secs_per_track
= gdt
->sc_hdr
[target
].hd_secs
;
1396 secs_per_cylinder
= ccg
->heads
* ccg
->secs_per_track
;
1397 ccg
->cylinders
= ccg
->volume_size
/ secs_per_cylinder
;
1398 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1399 --gdt_stat
.io_count_act
;
1403 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
1406 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1407 --gdt_stat
.io_count_act
;
1411 case XPT_TERM_IO
: /* Terminate the I/O process */
1413 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1414 --gdt_stat
.io_count_act
;
1417 case XPT_PATH_INQ
: /* Path routing inquiry */
1419 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
1421 cpi
->version_num
= 1;
1422 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
1423 cpi
->hba_inquiry
|= PI_WIDE_16
;
1424 cpi
->target_sprt
= 1;
1426 cpi
->hba_eng_cnt
= 0;
1427 if (bus
== gdt
->sc_virt_bus
)
1428 cpi
->max_target
= GDT_MAX_HDRIVES
- 1;
1429 else if (gdt
->sc_class
& GDT_FC
)
1430 cpi
->max_target
= GDT_MAXID_FC
- 1;
1432 cpi
->max_target
= GDT_MAXID
- 1;
1434 cpi
->unit_number
= cam_sim_unit(sim
);
1437 (bus
== gdt
->sc_virt_bus
? 127 : gdt
->sc_bus_id
[bus
]);
1438 cpi
->base_transfer_speed
= 3300;
1439 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
1440 strncpy(cpi
->hba_vid
, "Intel Corp.", HBA_IDLEN
);
1441 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
1442 cpi
->transport
= XPORT_SPI
;
1443 cpi
->transport_version
= 2;
1444 cpi
->protocol
= PROTO_SCSI
;
1445 cpi
->protocol_version
= SCSI_REV_2
;
1446 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
1447 --gdt_stat
.io_count_act
;
1452 GDT_DPRINTF(GDT_D_INVALID
, ("gdt_next(%p) cmd 0x%x invalid\n",
1453 gdt
, ccb
->ccb_h
.func_code
));
1454 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1455 --gdt_stat
.io_count_act
;
1462 iir_poll( struct cam_sim
*sim
)
1464 struct gdt_softc
*gdt
;
1466 gdt
= (struct gdt_softc
*)cam_sim_softc( sim
);
1467 GDT_DPRINTF(GDT_D_CMD
, ("iir_poll sim %p gdt %p\n", sim
, gdt
));
1472 iir_timeout(void *arg
)
1474 GDT_DPRINTF(GDT_D_TIMEOUT
, ("iir_timeout(%p)\n", arg
));
1478 iir_watchdog(void *arg
)
1480 struct gdt_softc
*gdt
;
1482 gdt
= (struct gdt_softc
*)arg
;
1483 GDT_DPRINTF(GDT_D_DEBUG
, ("iir_watchdog(%p)\n", gdt
));
1486 int ccbs
= 0, ucmds
= 0, frees
= 0, pends
= 0;
1491 for (h
= TAILQ_FIRST(&gdt
->sc_ccb_queue
); h
!= NULL
;
1492 h
= TAILQ_NEXT(h
, sim_links
.tqe
))
1494 for (u
= TAILQ_FIRST(&gdt
->sc_ucmd_queue
); u
!= NULL
;
1495 u
= TAILQ_NEXT(u
, links
))
1497 for (p
= SLIST_FIRST(&gdt
->sc_free_gccb
); p
!= NULL
;
1498 p
= SLIST_NEXT(p
, sle
))
1500 for (p
= SLIST_FIRST(&gdt
->sc_pending_gccb
); p
!= NULL
;
1501 p
= SLIST_NEXT(p
, sle
))
1504 GDT_DPRINTF(GDT_D_TIMEOUT
, ("ccbs %d ucmds %d frees %d pends %d\n",
1505 ccbs
, ucmds
, frees
, pends
));
1508 callout_reset(&gdt
->watchdog_timer
, hz
* 15, iir_watchdog
, gdt
);
1512 iir_shutdown( void *arg
, int howto
)
1514 struct gdt_softc
*gdt
;
1515 struct gdt_ccb
*gccb
;
1519 gdt
= (struct gdt_softc
*)arg
;
1520 GDT_DPRINTF(GDT_D_CMD
, ("iir_shutdown(%p, %d)\n", gdt
, howto
));
1522 kprintf("iir%d: Flushing all Host Drives. Please wait ... ",
1525 /* allocate ucmd buffer */
1526 ucmd
= kmalloc(sizeof(gdt_ucmd_t
), M_DEVBUF
, M_INTWAIT
| M_ZERO
);
1528 /* wait for pending IOs */
1530 gdt
->sc_state
= GDT_SHUTDOWN
;
1532 if ((gccb
= SLIST_FIRST(&gdt
->sc_pending_gccb
)) != NULL
)
1533 (void) tsleep((void *)gccb
, PCATCH
, "iirshw", 100 * hz
);
1536 for (i
= 0; i
< GDT_MAX_HDRIVES
; ++i
) {
1537 if (gdt
->sc_hdr
[i
].hd_present
) {
1538 ucmd
->service
= GDT_CACHESERVICE
;
1539 ucmd
->OpCode
= GDT_FLUSH
;
1540 ucmd
->u
.cache
.DeviceNo
= i
;
1542 TAILQ_INSERT_TAIL(&gdt
->sc_ucmd_queue
, ucmd
, links
);
1543 ucmd
->complete_flag
= FALSE
;
1546 if (!ucmd
->complete_flag
)
1547 (void) tsleep((void *)ucmd
, PCATCH
, "iirshw", 10*hz
);
1551 kfree(ucmd
, M_DEVBUF
);
1558 struct gdt_softc
*gdt
= arg
;
1559 struct gdt_intr_ctx ctx
;
1560 struct gdt_ccb
*gccb
;
1564 GDT_DPRINTF(GDT_D_INTR
, ("gdt_intr(%p)\n", gdt
));
1566 /* If polling and we were not called from gdt_wait, just return */
1567 if ((gdt
->sc_state
& GDT_POLLING
) &&
1568 !(gdt
->sc_state
& GDT_POLL_WAIT
))
1571 if (!(gdt
->sc_state
& GDT_POLLING
))
1575 ctx
.istatus
= gdt
->sc_get_status(gdt
);
1577 if (!(gdt
->sc_state
& GDT_POLLING
))
1579 gdt
->sc_status
= GDT_S_NO_STATUS
;
1583 gdt
->sc_intr(gdt
, &ctx
);
1585 gdt
->sc_status
= ctx
.cmd_status
;
1586 gdt
->sc_service
= ctx
.service
;
1587 gdt
->sc_info
= ctx
.info
;
1588 gdt
->sc_info2
= ctx
.info2
;
1590 if (gdt
->sc_state
& GDT_POLL_WAIT
) {
1592 gdt_wait_index
= ctx
.istatus
;
1595 if (ctx
.istatus
== GDT_ASYNCINDEX
) {
1596 gdt_async_event(gdt
, ctx
.service
);
1597 if (!(gdt
->sc_state
& GDT_POLLING
))
1601 if (ctx
.istatus
== GDT_SPEZINDEX
) {
1602 GDT_DPRINTF(GDT_D_INVALID
,
1603 ("iir%d: Service unknown or not initialized!\n",
1605 gdt
->sc_dvr
.size
= sizeof(gdt
->sc_dvr
.eu
.driver
);
1606 gdt
->sc_dvr
.eu
.driver
.ionode
= gdt
->sc_hanum
;
1607 gdt_store_event(GDT_ES_DRIVER
, 4, &gdt
->sc_dvr
);
1608 if (!(gdt
->sc_state
& GDT_POLLING
))
1613 gccb
= &gdt
->sc_gccbs
[ctx
.istatus
- 2];
1614 ctx
.service
= gccb
->gc_service
;
1616 switch (gccb
->gc_flags
) {
1617 case GDT_GCF_UNUSED
:
1618 GDT_DPRINTF(GDT_D_INVALID
, ("iir%d: Index (%d) to unused command!\n",
1619 gdt
->sc_hanum
, ctx
.istatus
));
1620 gdt
->sc_dvr
.size
= sizeof(gdt
->sc_dvr
.eu
.driver
);
1621 gdt
->sc_dvr
.eu
.driver
.ionode
= gdt
->sc_hanum
;
1622 gdt
->sc_dvr
.eu
.driver
.index
= ctx
.istatus
;
1623 gdt_store_event(GDT_ES_DRIVER
, 1, &gdt
->sc_dvr
);
1624 gdt_free_ccb(gdt
, gccb
);
1627 case GDT_GCF_INTERNAL
:
1628 if (!(gdt
->sc_state
& GDT_POLLING
))
1633 ucmd
= gccb
->gc_ucmd
;
1634 if (gdt
->sc_status
== GDT_S_BSY
) {
1635 GDT_DPRINTF(GDT_D_DEBUG
, ("iir_intr(%p) ioctl: gccb %p busy\n",
1637 TAILQ_INSERT_HEAD(&gdt
->sc_ucmd_queue
, ucmd
, links
);
1638 if (!(gdt
->sc_state
& GDT_POLLING
))
1641 ucmd
->status
= gdt
->sc_status
;
1642 ucmd
->info
= gdt
->sc_info
;
1643 ucmd
->complete_flag
= TRUE
;
1644 if (ucmd
->service
== GDT_CACHESERVICE
) {
1645 if (ucmd
->OpCode
== GDT_IOCTL
) {
1646 cnt
= ucmd
->u
.ioctl
.param_size
;
1648 bcopy(gccb
->gc_scratch
, ucmd
->data
, cnt
);
1650 cnt
= ucmd
->u
.cache
.BlockCnt
* GDT_SECTOR_SIZE
;
1652 bcopy(gccb
->gc_scratch
, ucmd
->data
, cnt
);
1655 cnt
= ucmd
->u
.raw
.sdlen
;
1657 bcopy(gccb
->gc_scratch
, ucmd
->data
, cnt
);
1658 if (ucmd
->u
.raw
.sense_len
!= 0)
1659 bcopy(gccb
->gc_scratch
, ucmd
->data
, cnt
);
1661 gdt_free_ccb(gdt
, gccb
);
1662 if (!(gdt
->sc_state
& GDT_POLLING
))
1671 gdt_free_ccb(gdt
, gccb
);
1672 gdt_sync_event(gdt
, ctx
.service
, ctx
.istatus
, gccb
);
1673 if (!(gdt
->sc_state
& GDT_POLLING
))
1681 gdt_async_event(struct gdt_softc
*gdt
, int service
)
1683 struct gdt_ccb
*gccb
;
1685 GDT_DPRINTF(GDT_D_INTR
, ("gdt_async_event(%p, %d)\n", gdt
, service
));
1687 if (service
== GDT_SCREENSERVICE
) {
1688 if (gdt
->sc_status
== GDT_MSG_REQUEST
) {
1689 while (gdt
->sc_test_busy(gdt
))
1691 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
1692 gccb
= gdt_get_ccb(gdt
);
1694 kprintf("iir%d: No free command index found\n",
1698 gccb
->gc_service
= service
;
1699 gccb
->gc_flags
= GDT_GCF_SCREEN
;
1700 gdt
->sc_set_sema0(gdt
);
1701 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
1702 gccb
->gc_cmd_index
);
1703 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, GDT_READ
);
1704 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_HANDLE
,
1705 GDT_MSG_INV_HANDLE
);
1706 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_ADDR
,
1707 gdt_ccb_vtop(gdt
, gccb
) +
1708 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1709 gdt
->sc_cmd_off
= 0;
1710 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_SCREEN_SZ
,
1712 gdt
->sc_cmd_cnt
= 0;
1713 gdt
->sc_copy_cmd(gdt
, gccb
);
1714 kprintf("iir%d: [PCI %d/%d] ",
1715 gdt
->sc_hanum
,gdt
->sc_bus
,gdt
->sc_slot
);
1716 gdt
->sc_release_event(gdt
);
1720 if ((gdt
->sc_fw_vers
& 0xff) >= 0x1a) {
1721 gdt
->sc_dvr
.size
= 0;
1722 gdt
->sc_dvr
.eu
.async
.ionode
= gdt
->sc_hanum
;
1723 gdt
->sc_dvr
.eu
.async
.status
= gdt
->sc_status
;
1724 /* severity and event_string already set! */
1726 gdt
->sc_dvr
.size
= sizeof(gdt
->sc_dvr
.eu
.async
);
1727 gdt
->sc_dvr
.eu
.async
.ionode
= gdt
->sc_hanum
;
1728 gdt
->sc_dvr
.eu
.async
.service
= service
;
1729 gdt
->sc_dvr
.eu
.async
.status
= gdt
->sc_status
;
1730 gdt
->sc_dvr
.eu
.async
.info
= gdt
->sc_info
;
1731 *(u_int32_t
*)gdt
->sc_dvr
.eu
.async
.scsi_coord
= gdt
->sc_info2
;
1733 gdt_store_event(GDT_ES_ASYNC
, service
, &gdt
->sc_dvr
);
1734 kprintf("iir%d: %s\n", gdt
->sc_hanum
, gdt
->sc_dvr
.event_string
);
1741 gdt_sync_event(struct gdt_softc
*gdt
, int service
,
1742 u_int8_t index
, struct gdt_ccb
*gccb
)
1745 bus_dmasync_op_t op
;
1747 GDT_DPRINTF(GDT_D_INTR
,
1748 ("gdt_sync_event(%p, %d, %d, %p)\n", gdt
,service
,index
,gccb
));
1752 if (service
== GDT_SCREENSERVICE
) {
1755 msg_len
= gdt_dec32(gccb
->gc_scratch
+ GDT_SCR_MSG_LEN
);
1757 if (!(gccb
->gc_scratch
[GDT_SCR_MSG_ANSWER
] &&
1758 gccb
->gc_scratch
[GDT_SCR_MSG_EXT
])) {
1759 gccb
->gc_scratch
[GDT_SCR_MSG_TEXT
+ msg_len
] = '\0';
1760 kprintf("%s",&gccb
->gc_scratch
[GDT_SCR_MSG_TEXT
]);
1763 if (gccb
->gc_scratch
[GDT_SCR_MSG_EXT
] &&
1764 !gccb
->gc_scratch
[GDT_SCR_MSG_ANSWER
]) {
1765 while (gdt
->sc_test_busy(gdt
))
1767 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
1768 gccb
= gdt_get_ccb(gdt
);
1770 kprintf("iir%d: No free command index found\n",
1774 gccb
->gc_service
= service
;
1775 gccb
->gc_flags
= GDT_GCF_SCREEN
;
1776 gdt
->sc_set_sema0(gdt
);
1777 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
1778 gccb
->gc_cmd_index
);
1779 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, GDT_READ
);
1780 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_HANDLE
,
1781 gccb
->gc_scratch
[GDT_SCR_MSG_HANDLE
]);
1782 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_ADDR
,
1783 gdt_ccb_vtop(gdt
, gccb
) +
1784 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1785 gdt
->sc_cmd_off
= 0;
1786 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_SCREEN_SZ
,
1788 gdt
->sc_cmd_cnt
= 0;
1789 gdt
->sc_copy_cmd(gdt
, gccb
);
1790 gdt
->sc_release_event(gdt
);
1794 if (gccb
->gc_scratch
[GDT_SCR_MSG_ANSWER
] &&
1795 gdt_dec32(gccb
->gc_scratch
+ GDT_SCR_MSG_ALEN
)) {
1796 /* default answers (getchar() not possible) */
1797 if (gdt_dec32(gccb
->gc_scratch
+ GDT_SCR_MSG_ALEN
) == 1) {
1798 gdt_enc32(gccb
->gc_scratch
+ GDT_SCR_MSG_ALEN
, 0);
1799 gdt_enc32(gccb
->gc_scratch
+ GDT_SCR_MSG_LEN
, 1);
1800 gccb
->gc_scratch
[GDT_SCR_MSG_TEXT
] = 0;
1802 gdt_enc32(gccb
->gc_scratch
+ GDT_SCR_MSG_ALEN
,
1803 gdt_dec32(gccb
->gc_scratch
+ GDT_SCR_MSG_ALEN
) - 2);
1804 gdt_enc32(gccb
->gc_scratch
+ GDT_SCR_MSG_LEN
, 2);
1805 gccb
->gc_scratch
[GDT_SCR_MSG_TEXT
] = 1;
1806 gccb
->gc_scratch
[GDT_SCR_MSG_TEXT
+ 1] = 0;
1808 gccb
->gc_scratch
[GDT_SCR_MSG_EXT
] = 0;
1809 gccb
->gc_scratch
[GDT_SCR_MSG_ANSWER
] = 0;
1810 while (gdt
->sc_test_busy(gdt
))
1812 bzero(gdt
->sc_cmd
, GDT_CMD_SZ
);
1813 gccb
= gdt_get_ccb(gdt
);
1815 kprintf("iir%d: No free command index found\n",
1819 gccb
->gc_service
= service
;
1820 gccb
->gc_flags
= GDT_GCF_SCREEN
;
1821 gdt
->sc_set_sema0(gdt
);
1822 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_COMMANDINDEX
,
1823 gccb
->gc_cmd_index
);
1824 gdt_enc16(gdt
->sc_cmd
+ GDT_CMD_OPCODE
, GDT_WRITE
);
1825 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_HANDLE
,
1826 gccb
->gc_scratch
[GDT_SCR_MSG_HANDLE
]);
1827 gdt_enc32(gdt
->sc_cmd
+ GDT_CMD_UNION
+ GDT_SCREEN_MSG_ADDR
,
1828 gdt_ccb_vtop(gdt
, gccb
) +
1829 offsetof(struct gdt_ccb
, gc_scratch
[0]));
1830 gdt
->sc_cmd_off
= 0;
1831 gdt
->sc_cmd_len
= roundup(GDT_CMD_UNION
+ GDT_SCREEN_SZ
,
1833 gdt
->sc_cmd_cnt
= 0;
1834 gdt
->sc_copy_cmd(gdt
, gccb
);
1835 gdt
->sc_release_event(gdt
);
1841 callout_stop(&ccb
->ccb_h
.timeout_ch
);
1842 if (gdt
->sc_status
== GDT_S_BSY
) {
1843 GDT_DPRINTF(GDT_D_DEBUG
, ("gdt_sync_event(%p) gccb %p busy\n",
1845 TAILQ_INSERT_HEAD(&gdt
->sc_ccb_queue
, &ccb
->ccb_h
, sim_links
.tqe
);
1846 ++gdt_stat
.req_queue_act
;
1847 if (gdt_stat
.req_queue_act
> gdt_stat
.req_queue_max
)
1848 gdt_stat
.req_queue_max
= gdt_stat
.req_queue_act
;
1852 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1853 op
= BUS_DMASYNC_POSTREAD
;
1855 op
= BUS_DMASYNC_POSTWRITE
;
1856 bus_dmamap_sync(gdt
->sc_buffer_dmat
, gccb
->gc_dmamap
, op
);
1858 ccb
->csio
.resid
= 0;
1859 if (gdt
->sc_status
== GDT_S_OK
) {
1860 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1863 if (gccb
->gc_service
== GDT_CACHESERVICE
) {
1864 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
| CAM_AUTOSNS_VALID
;
1865 ccb
->csio
.scsi_status
= SCSI_STATUS_CHECK_COND
;
1866 bzero(&ccb
->csio
.sense_data
, ccb
->csio
.sense_len
);
1867 ccb
->csio
.sense_data
.error_code
=
1868 SSD_CURRENT_ERROR
| SSD_ERRCODE_VALID
;
1869 ccb
->csio
.sense_data
.flags
= SSD_KEY_NOT_READY
;
1871 gdt
->sc_dvr
.size
= sizeof(gdt
->sc_dvr
.eu
.sync
);
1872 gdt
->sc_dvr
.eu
.sync
.ionode
= gdt
->sc_hanum
;
1873 gdt
->sc_dvr
.eu
.sync
.service
= service
;
1874 gdt
->sc_dvr
.eu
.sync
.status
= gdt
->sc_status
;
1875 gdt
->sc_dvr
.eu
.sync
.info
= gdt
->sc_info
;
1876 gdt
->sc_dvr
.eu
.sync
.hostdrive
= ccb
->ccb_h
.target_id
;
1877 if (gdt
->sc_status
>= 0x8000)
1878 gdt_store_event(GDT_ES_SYNC
, 0, &gdt
->sc_dvr
);
1880 gdt_store_event(GDT_ES_SYNC
, service
, &gdt
->sc_dvr
);
1883 if (gdt
->sc_status
!= GDT_S_RAW_SCSI
|| gdt
->sc_info
>= 0x100) {
1884 ccb
->ccb_h
.status
= CAM_SEL_TIMEOUT
;
1886 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
|CAM_AUTOSNS_VALID
;
1887 ccb
->csio
.scsi_status
= gdt
->sc_info
;
1888 bcopy(gccb
->gc_scratch
, &ccb
->csio
.sense_data
,
1889 ccb
->csio
.sense_len
);
1893 --gdt_stat
.io_count_act
;
1899 /* Controller event handling functions */
1901 gdt_store_event(u_int16_t source
, u_int16_t idx
, gdt_evt_data
*evt
)
1906 GDT_DPRINTF(GDT_D_MISC
, ("gdt_store_event(%d, %d)\n", source
, idx
));
1907 if (source
== 0) /* no source -> no event */
1910 if (ebuffer
[elastidx
].event_source
== source
&&
1911 ebuffer
[elastidx
].event_idx
== idx
&&
1912 ((evt
->size
!= 0 && ebuffer
[elastidx
].event_data
.size
!= 0 &&
1913 !memcmp((char *)&ebuffer
[elastidx
].event_data
.eu
,
1914 (char *)&evt
->eu
, evt
->size
)) ||
1915 (evt
->size
== 0 && ebuffer
[elastidx
].event_data
.size
== 0 &&
1916 !strcmp((char *)&ebuffer
[elastidx
].event_data
.event_string
,
1917 (char *)&evt
->event_string
)))) {
1918 e
= &ebuffer
[elastidx
];
1920 e
->last_stamp
= tv
.tv_sec
;
1923 if (ebuffer
[elastidx
].event_source
!= 0) { /* entry not free ? */
1925 if (elastidx
== GDT_MAX_EVENTS
)
1927 if (elastidx
== eoldidx
) { /* reached mark ? */
1929 if (eoldidx
== GDT_MAX_EVENTS
)
1933 e
= &ebuffer
[elastidx
];
1934 e
->event_source
= source
;
1937 e
->first_stamp
= e
->last_stamp
= tv
.tv_sec
;
1939 e
->event_data
= *evt
;
1946 gdt_read_event(int handle
, gdt_evt_str
*estr
)
1951 GDT_DPRINTF(GDT_D_MISC
, ("gdt_read_event(%d)\n", handle
));
1957 estr
->event_source
= 0;
1959 if (eindex
>= GDT_MAX_EVENTS
) {
1963 e
= &ebuffer
[eindex
];
1964 if (e
->event_source
!= 0) {
1965 if (eindex
!= elastidx
) {
1966 if (++eindex
== GDT_MAX_EVENTS
)
1971 memcpy(estr
, e
, sizeof(gdt_evt_str
));
1978 gdt_readapp_event(u_int8_t application
, gdt_evt_str
*estr
)
1984 GDT_DPRINTF(GDT_D_MISC
, ("gdt_readapp_event(%d)\n", application
));
1988 e
= &ebuffer
[eindex
];
1989 if (e
->event_source
== 0)
1991 if ((e
->application
& application
) == 0) {
1992 e
->application
|= application
;
1996 if (eindex
== elastidx
)
1998 if (++eindex
== GDT_MAX_EVENTS
)
2002 memcpy(estr
, e
, sizeof(gdt_evt_str
));
2004 estr
->event_source
= 0;
2009 gdt_clear_events(void)
2011 GDT_DPRINTF(GDT_D_MISC
, ("gdt_clear_events\n"));
2013 eoldidx
= elastidx
= 0;
2014 ebuffer
[0].event_source
= 0;