aacvar.h revision 74374
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 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 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/sys/dev/aac/aacvar.h 74374 2001-03-17 00:12:15Z gibbs $ 28 */ 29 30/******************************************************************************** 31 ******************************************************************************** 32 Driver Parameter Definitions 33 ******************************************************************************** 34 ********************************************************************************/ 35 36/* 37 * The firmware interface allows for a 16-bit s/g list length. We limit 38 * ourselves to a reasonable maximum and ensure alignment. 39 */ 40#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */ 41 42/* 43 * We allocate a small set of FIBs for the adapter to use to send us messages. 44 */ 45#define AAC_ADAPTER_FIBS 8 46 47/* 48 * FIBs are allocated up-front, and the pool isn't grown. We should allocate 49 * enough here to let us keep the adapter busy without wasting large amounts 50 * of kernel memory. The current interface implementation limits us to 512 51 * FIBs queued for the adapter at any one time. 52 */ 53#define AAC_FIB_COUNT 128 54 55/* 56 * The controller reports status events in AIFs. We hang on to a number of these 57 * in order to pass them out to user-space management tools. 58 */ 59#define AAC_AIFQ_LENGTH 64 60 61/* 62 * Firmware messages are passed in the printf buffer. 63 */ 64#define AAC_PRINTF_BUFSIZE 256 65 66/* 67 * We wait this many seconds for the adapter to come ready if it is still booting 68 */ 69#define AAC_BOOT_TIMEOUT (3 * 60) 70 71/* 72 * Timeout for immediate commands. 73 */ 74#define AAC_IMMEDIATE_TIMEOUT 30 /* seconds */ 75 76/* 77 * Timeout for normal commands 78 */ 79#define AAC_CMD_TIMEOUT 30 /* seconds */ 80 81/* 82 * Rate at which we periodically check for timed out commands and kick the 83 * controller. 84 */ 85#define AAC_PERIODIC_INTERVAL 10 /* seconds */ 86 87/* 88 * Character device major numbers. 89 */ 90#define AAC_DISK_MAJOR 200 91 92/******************************************************************************** 93 ******************************************************************************** 94 Driver Variable Definitions 95 ******************************************************************************** 96 ********************************************************************************/ 97 98#include "opt_aac.h" 99 100#if __FreeBSD_version >= 500005 101# include <sys/taskqueue.h> 102#endif 103 104/* 105 * Per-container data structure 106 */ 107struct aac_container 108{ 109 struct aac_mntobj co_mntobj; 110 device_t co_disk; 111}; 112 113/* 114 * Per-disk structure 115 */ 116struct aac_disk 117{ 118 device_t ad_dev; 119 dev_t ad_dev_t; 120 struct aac_softc *ad_controller; 121 struct aac_container *ad_container; 122 struct disk ad_disk; 123 struct devstat ad_stats; 124 struct disklabel ad_label; 125 int ad_flags; 126#define AAC_DISK_OPEN (1<<0) 127 int ad_cylinders; 128 int ad_heads; 129 int ad_sectors; 130 u_int32_t ad_size; 131}; 132 133/* 134 * Per-command control structure. 135 */ 136struct aac_command 137{ 138 TAILQ_ENTRY(aac_command) cm_link; /* list linkage */ 139 140 struct aac_softc *cm_sc; /* controller that owns us */ 141 142 struct aac_fib *cm_fib; /* FIB associated with this command */ 143 u_int32_t cm_fibphys; /* bus address of the FIB */ 144 struct bio *cm_data; /* pointer to data in kernel space */ 145 u_int32_t cm_datalen; /* data length */ 146 bus_dmamap_t cm_datamap; /* DMA map for bio data */ 147 struct aac_sg_table *cm_sgtable; /* pointer to s/g table in command */ 148 149 int cm_flags; 150#define AAC_CMD_MAPPED (1<<0) /* command has had its data mapped */ 151#define AAC_CMD_DATAIN (1<<1) /* command involves data moving from controller to host */ 152#define AAC_CMD_DATAOUT (1<<2) /* command involves data moving from host to controller */ 153#define AAC_CMD_COMPLETED (1<<3) /* command has been completed */ 154#define AAC_CMD_TIMEDOUT (1<<4) /* command taken too long */ 155 156 void (* cm_complete)(struct aac_command *cm); 157 void *cm_private; 158 time_t cm_timestamp; /* command creation time */ 159}; 160 161/* 162 * We gather a number of adapter-visible items into a single structure. 163 * 164 * The ordering of this strucure may be important; we copy the Linux driver: 165 * 166 * Adapter FIBs 167 * Init struct 168 * Queue headers (Comm Area) 169 * Printf buffer 170 * 171 * In addition, we add: 172 * Sync Fib 173 */ 174struct aac_common { 175 /* fibs for the controller to send us messages */ 176 struct aac_fib ac_fibs[AAC_ADAPTER_FIBS]; 177 178 /* the init structure */ 179 struct aac_adapter_init ac_init; 180 181 /* arena within which the queue structures are kept */ 182 u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN]; 183 184 /* buffer for text messages from the controller */ 185 char ac_printf[AAC_PRINTF_BUFSIZE]; 186 187 /* fib for synchronous commands */ 188 struct aac_fib ac_sync_fib; 189}; 190 191/* 192 * Interface operations 193 */ 194struct aac_interface 195{ 196 int (* aif_get_fwstatus)(struct aac_softc *sc); 197 void (* aif_qnotify)(struct aac_softc *sc, int qbit); 198 int (* aif_get_istatus)(struct aac_softc *sc); 199 void (* aif_set_istatus)(struct aac_softc *sc, int mask); 200 void (* aif_set_mailbox)(struct aac_softc *sc, u_int32_t command, 201 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3); 202 int (* aif_get_mailboxstatus)(struct aac_softc *sc); 203 void (* aif_set_interrupts)(struct aac_softc *sc, int enable); 204}; 205extern struct aac_interface aac_rx_interface; 206extern struct aac_interface aac_sa_interface; 207 208#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc))) 209#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit))) 210#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc))) 211#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_set_istatus((sc), (mask))) 212#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \ 213 ((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), (arg3))) 214#define AAC_GET_MAILBOXSTATUS(sc) ((sc)->aac_if.aif_get_mailboxstatus((sc))) 215#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), 0)) 216#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), 1)) 217 218#define AAC_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val) 219#define AAC_GETREG4(sc, reg) bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg) 220#define AAC_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val) 221#define AAC_GETREG2(sc, reg) bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg) 222#define AAC_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val) 223#define AAC_GETREG1(sc, reg) bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg) 224 225/* 226 * Per-controller structure. 227 */ 228struct aac_softc 229{ 230 /* bus connections */ 231 device_t aac_dev; 232 struct resource *aac_regs_resource; /* register interface window */ 233 int aac_regs_rid; /* resource ID */ 234 bus_space_handle_t aac_bhandle; /* bus space handle */ 235 bus_space_tag_t aac_btag; /* bus space tag */ 236 bus_dma_tag_t aac_parent_dmat; /* parent DMA tag */ 237 bus_dma_tag_t aac_buffer_dmat; /* data buffer/command DMA tag */ 238 struct resource *aac_irq; /* interrupt */ 239 int aac_irq_rid; 240 void *aac_intr; /* interrupt handle */ 241 242 /* controller features, limits and status */ 243 int aac_state; 244#define AAC_STATE_SUSPEND (1<<0) 245#define AAC_STATE_OPEN (1<<1) 246#define AAC_STATE_INTERRUPTS_ON (1<<2) 247#define AAC_STATE_AIF_SLEEPER (1<<3) 248 struct FsaRevision aac_revision; 249 250 /* controller hardware interface */ 251 int aac_hwif; 252#define AAC_HWIF_I960RX 0 253#define AAC_HWIF_STRONGARM 1 254#define AAC_HWIF_UNKNOWN -1 255 bus_dma_tag_t aac_common_dmat; /* common structure DMA tag */ 256 bus_dmamap_t aac_common_dmamap; /* common structure DMA map */ 257 struct aac_common *aac_common; 258 u_int32_t aac_common_busaddr; 259 struct aac_interface aac_if; 260 261 /* command/fib resources */ 262 bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocating FIBs */ 263 struct aac_fib *aac_fibs; 264 bus_dmamap_t aac_fibmap; 265 u_int32_t aac_fibphys; 266 struct aac_command aac_command[AAC_FIB_COUNT]; 267 268 /* command management */ 269 TAILQ_HEAD(,aac_command) aac_free; /* command structures available for reuse */ 270 TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for controller resources */ 271 TAILQ_HEAD(,aac_command) aac_busy; 272 TAILQ_HEAD(,aac_command) aac_complete; /* commands which have been returned by the controller */ 273 struct bio_queue_head aac_bioq; 274 struct aac_queue_table *aac_queues; 275 struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT]; 276 277 struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */ 278 279 /* connected containters */ 280 struct aac_container aac_container[AAC_MAX_CONTAINERS]; 281 282 /* delayed activity infrastructure */ 283#if __FreeBSD_version >= 500005 284 struct task aac_task_complete; /* deferred-completion task */ 285#endif 286 struct intr_config_hook aac_ich; 287 288 /* management interface */ 289 dev_t aac_dev_t; 290 struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH]; 291 int aac_aifq_head; 292 int aac_aifq_tail; 293}; 294 295 296/* 297 * Public functions 298 */ 299extern void aac_free(struct aac_softc *sc); 300extern int aac_attach(struct aac_softc *sc); 301extern int aac_detach(device_t dev); 302extern int aac_shutdown(device_t dev); 303extern int aac_suspend(device_t dev); 304extern int aac_resume(device_t dev); 305extern void aac_intr(void *arg); 306extern devclass_t aac_devclass; 307extern void aac_submit_bio(struct bio *bp); 308extern void aac_biodone(struct bio *bp); 309 310/* 311 * Debugging levels: 312 * 0 - quiet, only emit warnings 313 * 1 - noisy, emit major function points and things done 314 * 2 - extremely noisy, emit trace items in loops, etc. 315 */ 316#ifdef AAC_DEBUG 317# define debug(level, fmt, args...) \ 318 do { \ 319 if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args); \ 320 } while(0) 321# define debug_called(level) \ 322 do { \ 323 if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n"); \ 324 } while(0) 325 326extern void aac_print_queues(struct aac_softc *sc); 327extern void aac_panic(struct aac_softc *sc, char *reason); 328extern void aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller); 329extern void aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif); 330 331# define AAC_PRINT_FIB(sc, fib) aac_print_fib(sc, fib, __FUNCTION__) 332 333#else 334# define debug(level, fmt, args...) 335# define debug_called(level) 336 337# define aac_print_queues(sc) 338# define aac_panic(sc, reason) 339# define aac_print_aif(sc, aif) 340 341# define AAC_PRINT_FIB(sc, fib) 342#endif 343 344struct aac_code_lookup { 345 char *string; 346 u_int32_t code; 347}; 348 349/******************************************************************************** 350 * Queue primitives for driver queues. 351 */ 352#define AACQ_ADD(sc, qname) \ 353 do { \ 354 struct aac_qstat *qs = &(sc)->aac_qstat[qname]; \ 355 \ 356 qs->q_length++; \ 357 if (qs->q_length > qs->q_max) \ 358 qs->q_max = qs->q_length; \ 359 } while(0) 360 361#define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length-- 362#define AACQ_INIT(sc, qname) \ 363 do { \ 364 sc->aac_qstat[qname].q_length = 0; \ 365 sc->aac_qstat[qname].q_max = 0; \ 366 } while(0) 367 368 369#define AACQ_COMMAND_QUEUE(name, index) \ 370static __inline void \ 371aac_initq_ ## name (struct aac_softc *sc) \ 372{ \ 373 TAILQ_INIT(&sc->aac_ ## name); \ 374 AACQ_INIT(sc, index); \ 375} \ 376static __inline void \ 377aac_enqueue_ ## name (struct aac_command *cm) \ 378{ \ 379 int s; \ 380 \ 381 s = splbio(); \ 382 TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 383 AACQ_ADD(cm->cm_sc, index); \ 384 splx(s); \ 385} \ 386static __inline void \ 387aac_requeue_ ## name (struct aac_command *cm) \ 388{ \ 389 int s; \ 390 \ 391 s = splbio(); \ 392 TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 393 AACQ_ADD(cm->cm_sc, index); \ 394 splx(s); \ 395} \ 396static __inline struct aac_command * \ 397aac_dequeue_ ## name (struct aac_softc *sc) \ 398{ \ 399 struct aac_command *cm; \ 400 int s; \ 401 \ 402 s = splbio(); \ 403 if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \ 404 TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \ 405 AACQ_REMOVE(sc, index); \ 406 } \ 407 splx(s); \ 408 return(cm); \ 409} \ 410static __inline void \ 411aac_remove_ ## name (struct aac_command *cm) \ 412{ \ 413 int s; \ 414 \ 415 s = splbio(); \ 416 TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 417 AACQ_REMOVE(cm->cm_sc, index); \ 418 splx(s); \ 419} \ 420struct hack 421 422AACQ_COMMAND_QUEUE(free, AACQ_FREE); 423AACQ_COMMAND_QUEUE(ready, AACQ_READY); 424AACQ_COMMAND_QUEUE(busy, AACQ_BUSY); 425AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE); 426 427/* 428 * outstanding bio queue 429 */ 430static __inline void 431aac_initq_bio(struct aac_softc *sc) 432{ 433 bioq_init(&sc->aac_bioq); 434 AACQ_INIT(sc, AACQ_BIO); 435} 436 437static __inline void 438aac_enqueue_bio(struct aac_softc *sc, struct bio *bp) 439{ 440 int s; 441 442 s = splbio(); 443 bioq_insert_tail(&sc->aac_bioq, bp); 444 AACQ_ADD(sc, AACQ_BIO); 445 splx(s); 446} 447 448static __inline struct bio * 449aac_dequeue_bio(struct aac_softc *sc) 450{ 451 int s; 452 struct bio *bp; 453 454 s = splbio(); 455 if ((bp = bioq_first(&sc->aac_bioq)) != NULL) { 456 bioq_remove(&sc->aac_bioq, bp); 457 AACQ_REMOVE(sc, AACQ_BIO); 458 } 459 splx(s); 460 return(bp); 461} 462