1*916bdfa5Spgoyette /* $NetBSD: aacvar.h,v 1.15 2016/09/27 03:33:32 pgoyette Exp $ */ 277e08f05Sad 377e08f05Sad /*- 477e08f05Sad * Copyright (c) 2002 The NetBSD Foundation, Inc. 577e08f05Sad * All rights reserved. 677e08f05Sad * 777e08f05Sad * This code is derived from software contributed to The NetBSD Foundation 877e08f05Sad * by Andrew Doran. 977e08f05Sad * 1077e08f05Sad * Redistribution and use in source and binary forms, with or without 1177e08f05Sad * modification, are permitted provided that the following conditions 1277e08f05Sad * are met: 1377e08f05Sad * 1. Redistributions of source code must retain the above copyright 1477e08f05Sad * notice, this list of conditions and the following disclaimer. 1577e08f05Sad * 2. Redistributions in binary form must reproduce the above copyright 1677e08f05Sad * notice, this list of conditions and the following disclaimer in the 1777e08f05Sad * documentation and/or other materials provided with the distribution. 1877e08f05Sad * 1977e08f05Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2077e08f05Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2177e08f05Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2277e08f05Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2377e08f05Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2477e08f05Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2577e08f05Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2677e08f05Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2777e08f05Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2877e08f05Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2977e08f05Sad * POSSIBILITY OF SUCH DAMAGE. 3077e08f05Sad */ 3177e08f05Sad 3277e08f05Sad /*- 3377e08f05Sad * Copyright (c) 2000 Michael Smith 3477e08f05Sad * Copyright (c) 2000 BSDi 3577e08f05Sad * Copyright (c) 2000 Niklas Hallqvist 3677e08f05Sad * All rights reserved. 3777e08f05Sad * 3877e08f05Sad * Redistribution and use in source and binary forms, with or without 3977e08f05Sad * modification, are permitted provided that the following conditions 4077e08f05Sad * are met: 4177e08f05Sad * 1. Redistributions of source code must retain the above copyright 4277e08f05Sad * notice, this list of conditions and the following disclaimer. 4377e08f05Sad * 2. Redistributions in binary form must reproduce the above copyright 4477e08f05Sad * notice, this list of conditions and the following disclaimer in the 4577e08f05Sad * documentation and/or other materials provided with the distribution. 4677e08f05Sad * 4777e08f05Sad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4877e08f05Sad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4977e08f05Sad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5077e08f05Sad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 5177e08f05Sad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5277e08f05Sad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5377e08f05Sad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5477e08f05Sad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5577e08f05Sad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5677e08f05Sad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5777e08f05Sad * SUCH DAMAGE. 5877e08f05Sad * 5977e08f05Sad * from FreeBSD: aacvar.h,v 1.1 2000/09/13 03:20:34 msmith Exp 6077e08f05Sad * via OpenBSD: aacvar.h,v 1.2 2002/03/14 01:26:53 millert Exp 6177e08f05Sad */ 6277e08f05Sad 6377e08f05Sad #ifndef _PCI_AACVAR_H_ 6477e08f05Sad #define _PCI_AACVAR_H_ 6577e08f05Sad 6677e08f05Sad /* Debugging */ 6777e08f05Sad #ifdef AAC_DEBUG 6877e08f05Sad #define AAC_DPRINTF(mask, args) if ((aac_debug & (mask)) != 0) printf args 6977e08f05Sad #define AAC_D_INTR 0x01 7077e08f05Sad #define AAC_D_MISC 0x02 7177e08f05Sad #define AAC_D_CMD 0x04 7277e08f05Sad #define AAC_D_QUEUE 0x08 7377e08f05Sad #define AAC_D_IO 0x10 7477e08f05Sad extern int aac_debug; 7577e08f05Sad 769b2b412cSperry #define AAC_PRINT_FIB(sc, fib) aac_print_fib((sc), (fib), __func__) 7777e08f05Sad #else 7877e08f05Sad #define AAC_DPRINTF(mask, args) 7977e08f05Sad #define AAC_PRINT_FIB(sc, fib) 8077e08f05Sad #endif 8177e08f05Sad 8277e08f05Sad struct aac_code_lookup { 83f381db60Schristos const char *string; 8477e08f05Sad u_int32_t code; 8577e08f05Sad }; 8677e08f05Sad 8777e08f05Sad extern const struct aac_code_lookup aac_command_status_table[]; 8877e08f05Sad extern const struct aac_code_lookup aac_container_types[]; 8977e08f05Sad 9077e08f05Sad struct aac_softc; 9177e08f05Sad 9277e08f05Sad /* 9377e08f05Sad * We allocate a small set of FIBs for the adapter to use to send us messages. 9477e08f05Sad */ 9577e08f05Sad #define AAC_ADAPTER_FIBS 8 9677e08f05Sad 9777e08f05Sad /* 98f82d990bSbriggs * FIBs are allocated in page-size chunks and can grow up to the 512 99f82d990bSbriggs * limit imposed by the hardware. 1001687b85aSbriggs * XXX -- There should be some way to allocate these as-needed without 1011687b85aSbriggs * allocating them at interrupt time. For now, though, allocate 1021687b85aSbriggs * all that we'll ever need up-front. 103f82d990bSbriggs */ 1041687b85aSbriggs #define AAC_PREALLOCATE_FIBS(sc) ((sc)->sc_max_fibs) 105f82d990bSbriggs 106f82d990bSbriggs /* 10777e08f05Sad * Firmware messages are passed in the printf buffer. 10877e08f05Sad */ 10977e08f05Sad #define AAC_PRINTF_BUFSIZE 256 11077e08f05Sad 11177e08f05Sad /* 11277e08f05Sad * We wait this many seconds for the adapter to come ready if it is still 11377e08f05Sad * booting. 11477e08f05Sad */ 11577e08f05Sad #define AAC_BOOT_TIMEOUT (3 * 60) 11677e08f05Sad 11777e08f05Sad /* 11877e08f05Sad * Wait this long for a lost interrupt to get detected. 11977e08f05Sad */ 12077e08f05Sad #define AAC_WATCH_TIMEOUT 10000 /* 10000 * 1ms = 10s */ 12177e08f05Sad 12277e08f05Sad /* 12377e08f05Sad * Timeout for immediate commands. 12477e08f05Sad */ 12577e08f05Sad #define AAC_IMMEDIATE_TIMEOUT 30 12677e08f05Sad 12777e08f05Sad /* 12877e08f05Sad * Delay 20ms after the qnotify in sync operations. Experimentally deduced. 12977e08f05Sad */ 13077e08f05Sad #define AAC_SYNC_DELAY 20000 13177e08f05Sad 13277e08f05Sad /* 133f82d990bSbriggs * sc->sc_max_sgs is the number of scatter-gather elements we can fit 134f82d990bSbriggs * in one block I/O request (64-bit or 32-bit, depending) FIB, or the 135f82d990bSbriggs * maximum number that the firmware will accept. We subtract one to 136f82d990bSbriggs * deal with requests that do not start on an even page boundary. 13777e08f05Sad */ 138f82d990bSbriggs #define AAC_MAX_XFER(sc) (((sc)->sc_max_sgs - 1) * PAGE_SIZE) 13977e08f05Sad 14077e08f05Sad /* 14177e08f05Sad * Fixed sector size. 14277e08f05Sad */ 14377e08f05Sad #define AAC_SECTOR_SIZE 512 14477e08f05Sad 14577e08f05Sad /* 146f82d990bSbriggs * Number of CCBs to reserve for control operations. 14777e08f05Sad */ 148f82d990bSbriggs #define AAC_NCCBS_RESERVE 8 14977e08f05Sad 15077e08f05Sad /* 15177e08f05Sad * Quirk listings. 15277e08f05Sad */ 15380240054Sbriggs #define AAC_QUIRK_PERC2QC (1 << 0) /* Dell PERC 2QC */ 15480240054Sbriggs #define AAC_QUIRK_SG_64BIT (1 << 4) /* Use 64-bit S/G addresses */ 15580240054Sbriggs #define AAC_QUIRK_4GB_WINDOW (1 << 5) /* Device can access host mem 15680240054Sbriggs * in 2GB-4GB range */ 15780240054Sbriggs #define AAC_QUIRK_NO4GB (1 << 6) /* Can't access host mem >2GB */ 15880240054Sbriggs #define AAC_QUIRK_256FIBS (1 << 7) /* Can only handle 256 cmds */ 15980240054Sbriggs #define AAC_QUIRK_BROKEN_MMAP (1 << 8) /* Broken HostPhysMemPages */ 160f82d990bSbriggs #define AAC_QUIRK_NEW_COMM (1 << 11) /* New comm. i/f supported */ 161f82d990bSbriggs #define AAC_QUIRK_RAW_IO (1 << 12) /* Raw I/O interface */ 162f82d990bSbriggs #define AAC_QUIRK_ARRAY_64BIT (1 << 13) /* 64-bit array size */ 16385b692fbSsborrill #define AAC_QUIRK_LBA_64BIT (1 << 14) /* 64-bit LBA support */ 16480240054Sbriggs 16577e08f05Sad 16677e08f05Sad /* 16777e08f05Sad * We gather a number of adapter-visible items into a single structure. 16877e08f05Sad * 169c5670263Swiz * The ordering of this structure may be important; we copy the Linux driver: 17077e08f05Sad * 17177e08f05Sad * Adapter FIBs 17277e08f05Sad * Init struct 17377e08f05Sad * Queue headers (Comm Area) 17477e08f05Sad * Printf buffer 17577e08f05Sad * 17677e08f05Sad * In addition, we add: 17777e08f05Sad * Sync Fib 17877e08f05Sad */ 17977e08f05Sad struct aac_common { 18077e08f05Sad /* fibs for the controller to send us messages */ 18177e08f05Sad struct aac_fib ac_fibs[AAC_ADAPTER_FIBS]; 18277e08f05Sad 18377e08f05Sad /* the init structure */ 18477e08f05Sad struct aac_adapter_init ac_init; 18577e08f05Sad 18677e08f05Sad /* arena within which the queue structures are kept */ 18777e08f05Sad u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN]; 18877e08f05Sad 18977e08f05Sad /* buffer for text messages from the controller */ 19077e08f05Sad char ac_printf[AAC_PRINTF_BUFSIZE]; 19177e08f05Sad 19277e08f05Sad /* fib for synchronous commands */ 19377e08f05Sad struct aac_fib ac_sync_fib; 19477e08f05Sad }; 19577e08f05Sad 196f82d990bSbriggs struct aac_ccb; 197f82d990bSbriggs 19877e08f05Sad /* 19977e08f05Sad * Interface operations 20077e08f05Sad */ 20177e08f05Sad struct aac_interface { 20277e08f05Sad int (*aif_get_fwstatus)(struct aac_softc *); 20377e08f05Sad void (*aif_qnotify)(struct aac_softc *, int); 20477e08f05Sad int (*aif_get_istatus)(struct aac_softc *); 20577e08f05Sad void (*aif_set_istatus)(struct aac_softc *, int); 20677e08f05Sad void (*aif_set_mailbox)(struct aac_softc *, u_int32_t, 20777e08f05Sad u_int32_t, u_int32_t, u_int32_t, u_int32_t); 20880240054Sbriggs uint32_t (*aif_get_mailbox)(struct aac_softc *, int); 20977e08f05Sad void (*aif_set_interrupts)(struct aac_softc *, int); 210f82d990bSbriggs int (*aif_send_command)(struct aac_softc *, struct aac_ccb *); 211f82d990bSbriggs int (*aif_get_outb_queue)(struct aac_softc *); 212f82d990bSbriggs void (*aif_set_outb_queue)(struct aac_softc *, int); 21377e08f05Sad }; 21477e08f05Sad 21577e08f05Sad #define AAC_GET_FWSTATUS(sc) ((sc)->sc_if.aif_get_fwstatus(sc)) 21677e08f05Sad #define AAC_QNOTIFY(sc, qbit) \ 21777e08f05Sad ((sc)->sc_if.aif_qnotify((sc), (qbit))) 21877e08f05Sad #define AAC_GET_ISTATUS(sc) ((sc)->sc_if.aif_get_istatus(sc)) 21977e08f05Sad #define AAC_CLEAR_ISTATUS(sc, mask) \ 22077e08f05Sad ((sc)->sc_if.aif_set_istatus((sc), (mask))) 22177e08f05Sad #define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \ 22277e08f05Sad do { \ 22377e08f05Sad ((sc)->sc_if.aif_set_mailbox((sc), (command), (arg0), \ 22477e08f05Sad (arg1), (arg2), (arg3))); \ 22577e08f05Sad } while(0) 22680240054Sbriggs #define AAC_GET_MAILBOX(sc, mb) ((sc)->sc_if.aif_get_mailbox(sc, mb)) 22780240054Sbriggs #define AAC_GET_MAILBOXSTATUS(sc) (AAC_GET_MAILBOX(sc, 0)) 22877e08f05Sad #define AAC_MASK_INTERRUPTS(sc) \ 22977e08f05Sad ((sc)->sc_if.aif_set_interrupts((sc), 0)) 23077e08f05Sad #define AAC_UNMASK_INTERRUPTS(sc) \ 23177e08f05Sad ((sc)->sc_if.aif_set_interrupts((sc), 1)) 232f82d990bSbriggs #define AAC_SEND_COMMAND(sc, cm) \ 233f82d990bSbriggs ((sc)->sc_if.aif_send_command((sc), cm)) 234f82d990bSbriggs #define AAC_GET_OUTB_QUEUE(sc) \ 235f82d990bSbriggs ((sc)->sc_if.aif_get_outb_queue((sc))) 236f82d990bSbriggs #define AAC_SET_OUTB_QUEUE(sc, idx) \ 237f82d990bSbriggs ((sc)->sc_if.aif_set_outb_queue((sc), (idx))) 23877e08f05Sad 23977e08f05Sad #define AAC_SETREG4(sc, reg, val) \ 24077e08f05Sad bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (reg), (val)) 24177e08f05Sad #define AAC_GETREG4(sc, reg) \ 24277e08f05Sad bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (reg)) 24377e08f05Sad #define AAC_SETREG2(sc, reg, val) \ 24477e08f05Sad bus_space_write_2((sc)->sc_memt, (sc)->sc_memh, (reg), (val)) 24577e08f05Sad #define AAC_GETREG2(sc, reg) \ 24677e08f05Sad bus_space_read_2((sc)->sc_memt, (sc)->sc_memh, (reg)) 24777e08f05Sad #define AAC_SETREG1(sc, reg, val) \ 24877e08f05Sad bus_space_write_1((sc)->sc_memt, (sc)->sc_memh, (reg), (val)) 24977e08f05Sad #define AAC_GETREG1(sc, reg) \ 25077e08f05Sad bus_space_read_1((sc)->sc_memt, (sc)->sc_memh, (reg)) 25177e08f05Sad 252f82d990bSbriggs struct aac_fibmap { 253f82d990bSbriggs TAILQ_ENTRY(aac_fibmap) fm_link; 254f82d990bSbriggs struct aac_fib *fm_fibs; 255f82d990bSbriggs bus_dma_segment_t fm_fibseg; 256f82d990bSbriggs bus_dmamap_t fm_fibmap; 257f82d990bSbriggs struct aac_ccb *fm_ccbs; 258f82d990bSbriggs }; 25977e08f05Sad 26077e08f05Sad /* 261f82d990bSbriggs * A command control block, one for each corresponding command index 262f82d990bSbriggs * of the controller. 26377e08f05Sad */ 26477e08f05Sad struct aac_ccb { 26577e08f05Sad SIMPLEQ_ENTRY(aac_ccb) ac_chain; 26677e08f05Sad 26777e08f05Sad struct aac_fib *ac_fib; 268f82d990bSbriggs struct aac_fibmap *ac_fibmap; 26977e08f05Sad bus_addr_t ac_fibphys; 27077e08f05Sad bus_dmamap_t ac_dmamap_xfer; 27177e08f05Sad 27277e08f05Sad void *ac_data; 27377e08f05Sad size_t ac_datalen; 27477e08f05Sad u_int ac_flags; 27577e08f05Sad 27677e08f05Sad void (*ac_intr)(struct aac_ccb *); 277cbab9cadSchs device_t ac_device; 27877e08f05Sad void *ac_context; 27977e08f05Sad }; 28077e08f05Sad #define AAC_CCB_MAPPED 0x01 28177e08f05Sad #define AAC_CCB_COMPLETED 0x02 28277e08f05Sad #define AAC_CCB_DATA_IN 0x04 28377e08f05Sad #define AAC_CCB_DATA_OUT 0x08 28477e08f05Sad 28577e08f05Sad struct aac_drive { 28677e08f05Sad u_int hd_present; 28777e08f05Sad u_int hd_devtype; 28885b692fbSsborrill u_int64_t hd_size; 28977e08f05Sad }; 29077e08f05Sad 29177e08f05Sad /* 29277e08f05Sad * Per-controller structure. 29377e08f05Sad */ 29477e08f05Sad struct aac_softc { 295cbab9cadSchs device_t sc_dv; 29677e08f05Sad void *sc_ih; 29777e08f05Sad bus_space_tag_t sc_memt; 29877e08f05Sad bus_space_handle_t sc_memh; 29977e08f05Sad bus_dma_tag_t sc_dmat; 300f82d990bSbriggs bus_size_t sc_regsize; 30177e08f05Sad 30277e08f05Sad struct FsaRevision sc_revision; 30377e08f05Sad int sc_hwif; 30477e08f05Sad int sc_quirks; 30577e08f05Sad struct aac_interface sc_if; 30677e08f05Sad 307f82d990bSbriggs u_int32_t sc_max_fibs; 308f82d990bSbriggs u_int32_t sc_max_fibs_alloc; 309f82d990bSbriggs u_int32_t sc_max_sectors; 310f82d990bSbriggs u_int32_t sc_max_fib_size; 311f82d990bSbriggs u_int32_t sc_max_sgs; 312f82d990bSbriggs 313f82d990bSbriggs u_int32_t sc_total_fibs; 314f82d990bSbriggs TAILQ_HEAD(,aac_fibmap) sc_fibmap_tqh; 315f82d990bSbriggs 31677e08f05Sad struct aac_common *sc_common; 31777e08f05Sad bus_dma_segment_t sc_common_seg; 31877e08f05Sad bus_dmamap_t sc_common_dmamap; 319f82d990bSbriggs struct aac_fib *sc_aif_fib; 32077e08f05Sad 32177e08f05Sad struct aac_ccb *sc_ccbs; 32277e08f05Sad SIMPLEQ_HEAD(, aac_ccb) sc_ccb_free; 32377e08f05Sad SIMPLEQ_HEAD(, aac_ccb) sc_ccb_queue; 32477e08f05Sad SIMPLEQ_HEAD(, aac_ccb) sc_ccb_complete; 32577e08f05Sad 32677e08f05Sad struct aac_queue_table *sc_queues; 32777e08f05Sad struct aac_queue_entry *sc_qentries[AAC_QUEUE_COUNT]; 32877e08f05Sad struct aac_drive sc_hdr[AAC_MAX_CONTAINERS]; 32977e08f05Sad int sc_nunits; 33077e08f05Sad int sc_flags; 33180240054Sbriggs uint32_t sc_supported_options; 332f82d990bSbriggs 333f82d990bSbriggs /* Set by parent */ 334f82d990bSbriggs int (*sc_intr_set)(struct aac_softc *, 335f82d990bSbriggs int (*)(void *), void *); 33677e08f05Sad }; 33777e08f05Sad #define AAC_HWIF_I960RX 0 33877e08f05Sad #define AAC_HWIF_STRONGARM 1 339f82d990bSbriggs #define AAC_HWIF_FALCON 2 340f82d990bSbriggs #define AAC_HWIF_RKT 3 341f82d990bSbriggs #define AAC_HWIF_UNKNOWN -1 34277e08f05Sad 34377e08f05Sad #define AAC_ONLINE 2 34477e08f05Sad 34577e08f05Sad struct aac_attach_args { 34677e08f05Sad int aaca_unit; 34777e08f05Sad }; 34877e08f05Sad 34977e08f05Sad int aac_attach(struct aac_softc *); 350*916bdfa5Spgoyette int aac_devscan(struct aac_softc *); 35177e08f05Sad void aac_ccb_enqueue(struct aac_softc *, struct aac_ccb *); 35277e08f05Sad void aac_ccb_free(struct aac_softc *, struct aac_ccb *); 35377e08f05Sad struct aac_ccb *aac_ccb_alloc(struct aac_softc *, int); 35477e08f05Sad int aac_ccb_map(struct aac_softc *, struct aac_ccb *); 35577e08f05Sad int aac_ccb_poll(struct aac_softc *, struct aac_ccb *, int); 35677e08f05Sad int aac_ccb_submit(struct aac_softc *, struct aac_ccb *); 35777e08f05Sad void aac_ccb_unmap(struct aac_softc *, struct aac_ccb *); 35877e08f05Sad const char *aac_describe_code(const struct aac_code_lookup *, u_int32_t); 35977e08f05Sad int aac_intr(void *); 36077e08f05Sad 36177e08f05Sad #endif /* !_PCI_AACVAR_H_ */ 362