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