Annotation of sys/dev/ic/aacvar.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: aacvar.h,v 1.7 2006/05/07 20:12:41 tedu Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 2000 Michael Smith
! 5: * Copyright (c) 2000 BSDi
! 6: * Copyright (c) 2000 Niklas Hallqvist
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 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
! 22: * FOR 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: * $FreeBSD: /c/ncvs/src/sys/dev/aac/aacvar.h,v 1.1 2000/09/13 03:20:34 msmith Exp $
! 31: */
! 32:
! 33: /*
! 34: * This driver would not have rewritten for OpenBSD if it was not for the
! 35: * hardware donation from Nocom. I want to thank them for their support.
! 36: * Of course, credit should go to Mike Smith for the original work he did
! 37: * in the FreeBSD driver where I found lots of inspiration.
! 38: * - Niklas Hallqvist
! 39: */
! 40:
! 41: /* compatability */
! 42: #define time_second (mono_time.tv_sec)
! 43:
! 44: /* Debugging */
! 45: // #define AAC_DEBUG 0x0
! 46:
! 47: #ifdef AAC_DEBUG
! 48: #define AAC_DPRINTF(mask, args) if (aac_debug & (mask)) printf args
! 49: #define AAC_D_INTR 0x001
! 50: #define AAC_D_MISC 0x002
! 51: #define AAC_D_CMD 0x004
! 52: #define AAC_D_QUEUE 0x008
! 53: #define AAC_D_IO 0x010
! 54: #define AAC_D_IOCTL 0x020
! 55: #define AAC_D_LOCK 0x040
! 56: #define AAC_D_THREAD 0x080
! 57: #define AAC_D_FIB 0x100
! 58: extern int aac_debug;
! 59:
! 60: #define AAC_PRINT_FIB(sc, fib) do { \
! 61: if (aac_debug & AAC_D_FIB) \
! 62: aac_print_fib((sc), (fib), __func__); \
! 63: } while (0)
! 64: #else
! 65: #define AAC_DPRINTF(mask, args)
! 66: #define AAC_PRINT_FIB(sc, fib)
! 67: #endif
! 68:
! 69: struct aac_code_lookup {
! 70: char *string;
! 71: u_int32_t code;
! 72: };
! 73:
! 74: struct aac_softc;
! 75:
! 76: /*
! 77: * We allocate a small set of FIBs for the adapter to use to send us messages.
! 78: */
! 79: #define AAC_ADAPTER_FIBS 8
! 80:
! 81: /*
! 82: * FIBs are allocated in page-size chunks and can grow up to the 512
! 83: * limit imposed by the hardware.
! 84: */
! 85: #define AAC_FIB_COUNT (PAGE_SIZE/sizeof(struct aac_fib))
! 86: #define AAC_MAX_FIBS 512
! 87: #define AAC_FIBMAP_SIZE (PAGE_SIZE)
! 88:
! 89: /*
! 90: * The controller reports status events in AIFs. We hang on to a number of
! 91: * these in order to pass them out to user-space management tools.
! 92: */
! 93: #define AAC_AIFQ_LENGTH 64
! 94:
! 95: /*
! 96: * Firmware messages are passed in the printf buffer.
! 97: */
! 98: #define AAC_PRINTF_BUFSIZE 256
! 99:
! 100: /*
! 101: * We wait this many seconds for the adapter to come ready if it is still
! 102: * booting.
! 103: */
! 104: #define AAC_BOOT_TIMEOUT (3 * 60)
! 105:
! 106: /*
! 107: * Timeout for immediate commands.
! 108: */
! 109: #define AAC_IMMEDIATE_TIMEOUT 30
! 110:
! 111: /*
! 112: * Timeout for normal commands
! 113: */
! 114: #define AAC_CMD_TIMEOUT 30 /* seconds */
! 115:
! 116: /*
! 117: * Rate at which we periodically check for timed out commands and kick the
! 118: * controller.
! 119: */
! 120: #define AAC_PERIODIC_INTERVAL 20 /* seconds */
! 121:
! 122: /*
! 123: * Wait this long for a lost interrupt to get detected.
! 124: */
! 125: #define AAC_WATCH_TIMEOUT 10000 /* 10000 * 1ms = 10s */
! 126:
! 127: /*
! 128: * Delay 20ms after the qnotify in sync operations. Experimentally deduced.
! 129: */
! 130: #define AAC_SYNC_DELAY 20000
! 131:
! 132: /*
! 133: * The firmware interface allows for a 16-bit s/g list length. We limit
! 134: * ourselves to a reasonable maximum and ensure alignment.
! 135: */
! 136: #define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
! 137:
! 138: /*
! 139: * We gather a number of adapter-visible items into a single structure.
! 140: *
! 141: * The ordering of this structure may be important; we copy the Linux driver:
! 142: *
! 143: * Adapter FIBs
! 144: * Init struct
! 145: * Queue headers (Comm Area)
! 146: * Printf buffer
! 147: *
! 148: * In addition, we add:
! 149: * Sync Fib
! 150: */
! 151: struct aac_common {
! 152: /* fibs for the controller to send us messages */
! 153: struct aac_fib ac_fibs[AAC_ADAPTER_FIBS];
! 154:
! 155: /* the init structure */
! 156: struct aac_adapter_init ac_init;
! 157:
! 158: /* arena within which the queue structures are kept */
! 159: u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
! 160:
! 161: /* buffer for text messages from the controller */
! 162: char ac_printf[AAC_PRINTF_BUFSIZE];
! 163:
! 164: /* fib for synchronous commands */
! 165: struct aac_fib ac_sync_fib;
! 166: };
! 167: #define AAC_COMMON_ALLOCSIZE (8192 + sizeof(struct aac_common))
! 168:
! 169: /*
! 170: * Interface operations
! 171: */
! 172: struct aac_interface {
! 173: int (*aif_get_fwstatus)(struct aac_softc *);
! 174: void (*aif_qnotify)(struct aac_softc *, int);
! 175: int (*aif_get_istatus)(struct aac_softc *);
! 176: void (*aif_set_istatus)(struct aac_softc *, int);
! 177: void (*aif_set_mailbox)(struct aac_softc *, u_int32_t,
! 178: u_int32_t, u_int32_t, u_int32_t, u_int32_t);
! 179: int (*aif_get_mailbox)(struct aac_softc *, int mb);
! 180: void (*aif_set_interrupts)(struct aac_softc *, int);
! 181: };
! 182: extern struct aac_interface aac_fa_interface;
! 183: extern struct aac_interface aac_sa_interface;
! 184: extern struct aac_interface aac_rx_interface;
! 185: extern struct aac_interface aac_rkt_interface;
! 186:
! 187: #define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus(sc))
! 188: #define AAC_QNOTIFY(sc, qbit) \
! 189: ((sc)->aac_if.aif_qnotify((sc), (qbit)))
! 190: #define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus(sc))
! 191: #define AAC_CLEAR_ISTATUS(sc, mask) \
! 192: ((sc)->aac_if.aif_set_istatus((sc), (mask)))
! 193: #define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
! 194: do { \
! 195: ((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), \
! 196: (arg1), (arg2), (arg3))); \
! 197: } while(0)
! 198: #define AAC_GET_MAILBOX(sc, mb) \
! 199: ((sc)->aac_if.aif_get_mailbox(sc, (mb)))
! 200: #define AAC_MASK_INTERRUPTS(sc) \
! 201: ((sc)->aac_if.aif_set_interrupts((sc), 0))
! 202: #define AAC_UNMASK_INTERRUPTS(sc) \
! 203: ((sc)->aac_if.aif_set_interrupts((sc), 1))
! 204:
! 205: #define AAC_SETREG4(sc, reg, val) \
! 206: bus_space_write_4((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
! 207: #define AAC_GETREG4(sc, reg) \
! 208: bus_space_read_4((sc)->aac_memt, (sc)->aac_memh, (reg))
! 209: #define AAC_SETREG2(sc, reg, val) \
! 210: bus_space_write_2((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
! 211: #define AAC_GETREG2(sc, reg) \
! 212: bus_space_read_2((sc)->aac_memt, (sc)->aac_memh, (reg))
! 213: #define AAC_SETREG1(sc, reg, val) \
! 214: bus_space_write_1((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
! 215: #define AAC_GETREG1(sc, reg) \
! 216: bus_space_read_1((sc)->aac_memt, (sc)->aac_memh, (reg))
! 217:
! 218: /* Define the OS version specific locks */
! 219: typedef struct rwlock aac_lock_t;
! 220: #define AAC_LOCK_INIT(l, s) do { \
! 221: rw_init((l), "aaclock"); \
! 222: AAC_DPRINTF(AAC_D_LOCK, ("%s: init lock @%s: %d\n", \
! 223: sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
! 224: } while (0)
! 225:
! 226: #define AAC_LOCK_ACQUIRE(l) do { \
! 227: AAC_DPRINTF(AAC_D_LOCK, ("%s: lock @%s: %d\n", \
! 228: sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
! 229: rw_enter_write((l)); \
! 230: } while (0)
! 231:
! 232: #define AAC_LOCK_RELEASE(l) do { \
! 233: rw_exit_write((l)); \
! 234: AAC_DPRINTF(AAC_D_LOCK, ("%s: unlock @%s: %d\n", \
! 235: sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
! 236: } while (0)
! 237:
! 238: /*
! 239: * Per-container data structure
! 240: */
! 241: struct aac_container
! 242: {
! 243: struct aac_mntobj co_mntobj;
! 244: int co_found;
! 245: TAILQ_ENTRY(aac_container) co_link;
! 246: };
! 247:
! 248: /*
! 249: * A command contol block, one for each corresponding command index of the
! 250: * controller.
! 251: */
! 252: struct aac_command
! 253: {
! 254: TAILQ_ENTRY(aac_command) cm_link; /* list linkage */
! 255:
! 256: struct aac_softc *cm_sc; /* controller that owns us */
! 257:
! 258: struct aac_fib *cm_fib; /* FIB for this command */
! 259: bus_addr_t cm_fibphys; /* bus address of the FIB */
! 260: void *cm_data;
! 261: size_t cm_datalen;
! 262: bus_dmamap_t cm_datamap;
! 263: struct aac_sg_table *cm_sgtable; /* pointer to s/g table */
! 264:
! 265: u_int cm_flags;
! 266: #define AAC_CMD_MAPPED (1<<0) /* command has had its data mapped */
! 267: #define AAC_CMD_DATAIN (1<<1) /* command involves data moving
! 268: * from controller to host */
! 269: #define AAC_CMD_DATAOUT (1<<2) /* command involves data moving
! 270: * from host to controller */
! 271: #define AAC_CMD_COMPLETED (1<<3) /* command has been completed */
! 272: #define AAC_CMD_TIMEDOUT (1<<4) /* command taken too long */
! 273: #define AAC_ON_AACQ_FREE (1<<5)
! 274: #define AAC_ON_AACQ_READY (1<<6)
! 275: #define AAC_ON_AACQ_BUSY (1<<7)
! 276: #define AAC_ON_AACQ_BIO (1<<8)
! 277: #define AAC_ON_AACQ_MASK ((1<<5)|(1<<6)|(1<<7)|(1<<8))
! 278: #define AAC_QUEUE_FRZN (1<<9) /* Freeze the processing of
! 279: * commands on the queue. */
! 280: #define AAC_ACF_WATCHDOG (1<<10)
! 281:
! 282: void (*cm_complete)(struct aac_command *);
! 283: void *cm_private;
! 284: u_int32_t cm_blkno;
! 285: u_int32_t cm_bcount;
! 286: time_t cm_timestamp; /* command creation time */
! 287: int cm_queue;
! 288: int cm_index;
! 289: };
! 290:
! 291: struct aac_fibmap {
! 292: TAILQ_ENTRY(aac_fibmap) fm_link; /* list linkage */
! 293: struct aac_fib *aac_fibs;
! 294: bus_dmamap_t aac_fibmap;
! 295: bus_dma_segment_t aac_seg;
! 296: int aac_nsegs;
! 297: struct aac_command *aac_commands;
! 298: };
! 299:
! 300: /*
! 301: * Command queue statistics
! 302: */
! 303: #define AACQ_FREE 0
! 304: #define AACQ_BIO 1
! 305: #define AACQ_READY 2
! 306: #define AACQ_BUSY 3
! 307: #define AACQ_COUNT 4 /* total number of queues */
! 308:
! 309: struct aac_qstat {
! 310: u_int32_t q_length;
! 311: u_int32_t q_max;
! 312: };
! 313:
! 314: /*
! 315: * Per-controller structure.
! 316: */
! 317: struct aac_softc
! 318: {
! 319: struct device aac_dev;
! 320: void *aac_ih;
! 321: struct scsi_link aac_link; /* Virtual SCSI bus for cache devs */
! 322:
! 323: bus_space_tag_t aac_memt;
! 324: bus_space_handle_t aac_memh;
! 325: bus_dma_tag_t aac_dmat; /* parent DMA tag */
! 326:
! 327: /* controller features, limits and status */
! 328: int aac_state;
! 329: #define AAC_STATE_SUSPEND (1<<0)
! 330: #define AAC_STATE_OPEN (1<<1)
! 331: #define AAC_STATE_INTERRUPTS_ON (1<<2)
! 332: #define AAC_STATE_AIF_SLEEPER (1<<3)
! 333: struct FsaRevision aac_revision;
! 334:
! 335: int aac_hwif; /* controller hardware interface */
! 336: #define AAC_HWIF_I960RX 0
! 337: #define AAC_HWIF_STRONGARM 1
! 338: #define AAC_HWIF_FALCON 2
! 339: #define AAC_HWIF_RKT 3
! 340: #define AAC_HWIF_UNKNOWN -1
! 341:
! 342: struct aac_common *aac_common;
! 343: bus_dmamap_t aac_common_map;
! 344: u_int32_t aac_common_busaddr;
! 345: struct aac_interface aac_if;
! 346:
! 347: /* command/fib resources */
! 348: TAILQ_HEAD(,aac_fibmap) aac_fibmap_tqh;
! 349: u_int total_fibs;
! 350: struct aac_command *aac_commands;
! 351:
! 352: /* command management */
! 353: TAILQ_HEAD(,aac_command) aac_free; /* command structures
! 354: * available for reuse */
! 355: TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for
! 356: * controller resources */
! 357: TAILQ_HEAD(,aac_command) aac_busy;
! 358: TAILQ_HEAD(,aac_command) aac_bio;
! 359:
! 360: /* command management */
! 361: struct aac_queue_table *aac_queues;
! 362: struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT];
! 363:
! 364: struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */
! 365:
! 366: /* connected containters */
! 367: TAILQ_HEAD(,aac_container) aac_container_tqh;
! 368: aac_lock_t aac_container_lock;
! 369:
! 370: /* Protect the sync fib */
! 371: #define AAC_SYNC_LOCK_FORCE (1 << 0)
! 372: aac_lock_t aac_sync_lock;
! 373:
! 374: aac_lock_t aac_io_lock;
! 375:
! 376: struct {
! 377: u_int8_t hd_present;
! 378: u_int8_t hd_is_logdrv;
! 379: u_int8_t hd_is_arraydrv;
! 380: u_int8_t hd_is_master;
! 381: u_int8_t hd_is_parity;
! 382: u_int8_t hd_is_hotfix;
! 383: u_int8_t hd_master_no;
! 384: u_int8_t hd_lock;
! 385: u_int8_t hd_heads;
! 386: u_int8_t hd_secs;
! 387: u_int16_t hd_devtype;
! 388: u_int32_t hd_size;
! 389: u_int8_t hd_ldr_no;
! 390: u_int8_t hd_rw_attribs;
! 391: u_int32_t hd_start_sec;
! 392: } aac_hdr[AAC_MAX_CONTAINERS];
! 393: int aac_container_count;
! 394:
! 395: /* management interface */
! 396: aac_lock_t aac_aifq_lock;
! 397: struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH];
! 398: int aac_aifq_head;
! 399: int aac_aifq_tail;
! 400: struct selinfo aac_select;
! 401: struct proc *aifthread;
! 402: int aifflags;
! 403: #define AAC_AIFFLAGS_RUNNING (1 << 0)
! 404: #define AAC_AIFFLAGS_AIF (1 << 1)
! 405: #define AAC_AIFFLAGS_EXIT (1 << 2)
! 406: #define AAC_AIFFLAGS_EXITED (1 << 3)
! 407: #define AAC_AIFFLAGS_COMPLETE (1 << 4)
! 408: #define AAC_AIFFLAGS_PRINTF (1 << 5)
! 409: #define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_COMPLETE | \
! 410: AAC_AIFFLAGS_PRINTF)
! 411:
! 412: u_int32_t flags;
! 413: #define AAC_FLAGS_PERC2QC (1 << 0)
! 414: #define AAC_FLAGS_ENABLE_CAM (1 << 1) /* No SCSI passthrough */
! 415: #define AAC_FLAGS_CAM_NORESET (1 << 2) /* Fake SCSI resets */
! 416: #define AAC_FLAGS_CAM_PASSONLY (1 << 3) /* Only create pass devices */
! 417: #define AAC_FLAGS_SG_64BIT (1 << 4) /* Use 64-bit S/G addresses */
! 418: #define AAC_FLAGS_4GB_WINDOW (1 << 5) /* Device can access host mem
! 419: * 2GB-4GB range */
! 420: #define AAC_FLAGS_NO4GB (1 << 6) /* Can't access host mem >2GB*/
! 421: #define AAC_FLAGS_256FIBS (1 << 7) /* Can only do 256 commands */
! 422: #define AAC_FLAGS_BROKEN_MEMMAP (1 << 8) /* Broken HostPhysMemPages */
! 423:
! 424: u_int32_t supported_options;
! 425: int aac_max_fibs;
! 426: void *aac_sdh;
! 427: };
! 428:
! 429: /*
! 430: * Public functions
! 431: */
! 432: extern int aac_wait_command(struct aac_command *, int);
! 433: extern int aac_alloc_command(struct aac_softc *, struct aac_command **);
! 434: extern void aac_release_command(struct aac_command *);
! 435: extern int aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int);
! 436: extern void aac_release_sync_fib(struct aac_softc *);
! 437: extern int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t,
! 438: struct aac_fib *, u_int16_t);
! 439:
! 440: void aacminphys(struct buf *);
! 441: int aac_attach(struct aac_softc *);
! 442: int aac_intr(void *);
! 443:
! 444: /* These all require correctly aligned buffers */
! 445: static __inline__ void aac_enc16(u_int8_t *, u_int16_t);
! 446: static __inline__ void aac_enc32(u_int8_t *, u_int32_t);
! 447: static __inline__ u_int16_t aac_dec16(u_int8_t *);
! 448: static __inline__ u_int32_t aac_dec32(u_int8_t *);
! 449:
! 450: static __inline__ void
! 451: aac_enc16(addr, value)
! 452: u_int8_t *addr;
! 453: u_int16_t value;
! 454: {
! 455: *(u_int16_t *)addr = htole16(value);
! 456: }
! 457:
! 458: static __inline__ void
! 459: aac_enc32(addr, value)
! 460: u_int8_t *addr;
! 461: u_int32_t value;
! 462: {
! 463: *(u_int32_t *)addr = htole32(value);
! 464: }
! 465:
! 466: static __inline__ u_int16_t
! 467: aac_dec16(addr)
! 468: u_int8_t *addr;
! 469: {
! 470: return letoh16(*(u_int16_t *)addr);
! 471: }
! 472:
! 473: static __inline__ u_int32_t
! 474: aac_dec32(addr)
! 475: u_int8_t *addr;
! 476: {
! 477: return letoh32(*(u_int32_t *)addr);
! 478: }
! 479:
! 480: /* Declarations copied from aac.c */
! 481: #ifdef AAC_DEBUG
! 482: void aac_print_fib(struct aac_softc *, struct aac_fib *, const char *);
! 483: void aac_print_aif(struct aac_softc *, struct aac_aif_command *);
! 484: #endif
! 485: void aac_handle_aif(struct aac_softc *, struct aac_fib *);
! 486:
! 487:
! 488:
! 489:
! 490:
! 491: /*
! 492: * Queue primitives for driver queues.
! 493: */
! 494: #define AACQ_ADD(sc, qname) \
! 495: do { \
! 496: struct aac_qstat *qs; \
! 497: \
! 498: qs = &(sc)->aac_qstat[qname]; \
! 499: \
! 500: qs->q_length++; \
! 501: if (qs->q_length > qs->q_max) \
! 502: qs->q_max = qs->q_length; \
! 503: } while (0)
! 504:
! 505: #define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length--
! 506: #define AACQ_INIT(sc, qname) \
! 507: do { \
! 508: sc->aac_qstat[qname].q_length = 0; \
! 509: sc->aac_qstat[qname].q_max = 0; \
! 510: } while (0)
! 511:
! 512:
! 513: #define AACQ_COMMAND_QUEUE(name, index) \
! 514: static __inline void \
! 515: aac_initq_ ## name (struct aac_softc *sc) \
! 516: { \
! 517: TAILQ_INIT(&sc->aac_ ## name); \
! 518: AACQ_INIT(sc, index); \
! 519: } \
! 520: static __inline void \
! 521: aac_enqueue_ ## name (struct aac_command *cm) \
! 522: { \
! 523: AAC_DPRINTF(AAC_D_CMD, (": enqueue " #name)); \
! 524: if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
! 525: printf("command %p is on another queue, flags = %#x\n", \
! 526: cm, cm->cm_flags); \
! 527: panic("command is on another queue"); \
! 528: } \
! 529: TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \
! 530: cm->cm_flags |= AAC_ON_ ## index; \
! 531: AACQ_ADD(cm->cm_sc, index); \
! 532: } \
! 533: static __inline void \
! 534: aac_requeue_ ## name (struct aac_command *cm) \
! 535: { \
! 536: AAC_DPRINTF(AAC_D_CMD, (": requeue " #name)); \
! 537: if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
! 538: printf("command %p is on another queue, flags = %#x\n", \
! 539: cm, cm->cm_flags); \
! 540: panic("command is on another queue"); \
! 541: } \
! 542: TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \
! 543: cm->cm_flags |= AAC_ON_ ## index; \
! 544: AACQ_ADD(cm->cm_sc, index); \
! 545: } \
! 546: static __inline struct aac_command * \
! 547: aac_dequeue_ ## name (struct aac_softc *sc) \
! 548: { \
! 549: struct aac_command *cm; \
! 550: \
! 551: if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \
! 552: AAC_DPRINTF(AAC_D_CMD, (": dequeue " #name)); \
! 553: if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
! 554: printf("dequeue - command %p not in queue, flags = %#x, " \
! 555: "bit = %#x\n", cm, cm->cm_flags, \
! 556: AAC_ON_ ## index); \
! 557: panic("command not in queue"); \
! 558: } \
! 559: TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \
! 560: cm->cm_flags &= ~AAC_ON_ ## index; \
! 561: AACQ_REMOVE(sc, index); \
! 562: } \
! 563: return(cm); \
! 564: } \
! 565: static __inline void \
! 566: aac_remove_ ## name (struct aac_command *cm) \
! 567: { \
! 568: AAC_DPRINTF(AAC_D_CMD, (": remove " #name)); \
! 569: if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
! 570: printf("remove - command %p not in queue, flags = %#x, " \
! 571: "bit = %#x\n", cm, cm->cm_flags, \
! 572: AAC_ON_ ## index); \
! 573: panic("command not in queue"); \
! 574: } \
! 575: TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \
! 576: cm->cm_flags &= ~AAC_ON_ ## index; \
! 577: AACQ_REMOVE(cm->cm_sc, index); \
! 578: } \
! 579: struct hack
! 580:
! 581: AACQ_COMMAND_QUEUE(free, AACQ_FREE);
! 582: AACQ_COMMAND_QUEUE(ready, AACQ_READY);
! 583: AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
! 584: AACQ_COMMAND_QUEUE(bio, AACQ_BIO);
! 585:
! 586: static __inline void
! 587: aac_print_printf(struct aac_softc *sc)
! 588: {
! 589: /*
! 590: * XXX We have the ability to read the length of the printf string
! 591: * from out of the mailboxes.
! 592: */
! 593: printf("** %s: %.*s", sc->aac_dev.dv_xname, AAC_PRINTF_BUFSIZE,
! 594: sc->aac_common->ac_printf);
! 595: sc->aac_common->ac_printf[0] = 0;
! 596: AAC_QNOTIFY(sc, AAC_DB_PRINTF);
! 597: }
CVSweb