aacvar.h revision 70393
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 70393 2000-12-27 13:14:56Z msmith $ 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#if __FreeBSD_version >= 500005 99# include <sys/taskqueue.h> 100#endif 101 102/* 103 * Per-container data structure 104 */ 105struct aac_container 106{ 107 struct aac_mntobj co_mntobj; 108 device_t co_disk; 109}; 110 111/* 112 * Per-disk structure 113 */ 114struct aac_disk 115{ 116 device_t ad_dev; 117 dev_t ad_dev_t; 118 struct aac_softc *ad_controller; 119 struct aac_container *ad_container; 120 struct disk ad_disk; 121 struct devstat ad_stats; 122 struct disklabel ad_label; 123 int ad_flags; 124#define AAC_DISK_OPEN (1<<0) 125 int ad_cylinders; 126 int ad_heads; 127 int ad_sectors; 128 u_int32_t ad_size; 129}; 130 131/* 132 * Per-command control structure. 133 */ 134struct aac_command 135{ 136 TAILQ_ENTRY(aac_command) cm_link; /* list linkage */ 137 138 struct aac_softc *cm_sc; /* controller that owns us */ 139 140 struct aac_fib *cm_fib; /* FIB associated with this command */ 141 u_int32_t cm_fibphys; /* bus address of the FIB */ 142 struct bio *cm_data; /* pointer to data in kernel space */ 143 u_int32_t cm_datalen; /* data length */ 144 bus_dmamap_t cm_datamap; /* DMA map for bio data */ 145 struct aac_sg_table *cm_sgtable; /* pointer to s/g table in command */ 146 147 int cm_flags; 148#define AAC_CMD_MAPPED (1<<0) /* command has had its data mapped */ 149#define AAC_CMD_DATAIN (1<<1) /* command involves data moving from controller to host */ 150#define AAC_CMD_DATAOUT (1<<2) /* command involves data moving from host to controller */ 151#define AAC_CMD_COMPLETED (1<<3) /* command has been completed */ 152#define AAC_CMD_TIMEDOUT (1<<4) /* command taken too long */ 153 154 void (* cm_complete)(struct aac_command *cm); 155 void *cm_private; 156 time_t cm_timestamp; /* command creation time */ 157}; 158 159/* 160 * We gather a number of adapter-visible items into a single structure. 161 * 162 * The ordering of this strucure may be important; we copy the Linux driver: 163 * 164 * Adapter FIBs 165 * Init struct 166 * Queue headers (Comm Area) 167 * Printf buffer 168 * 169 * In addition, we add: 170 * Sync Fib 171 */ 172struct aac_common { 173 /* fibs for the controller to send us messages */ 174 struct aac_fib ac_fibs[AAC_ADAPTER_FIBS]; 175 176 /* the init structure */ 177 struct aac_adapter_init ac_init; 178 179 /* arena within which the queue structures are kept */ 180 u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN]; 181 182 /* buffer for text messages from the controller */ 183 char ac_printf[AAC_PRINTF_BUFSIZE]; 184 185 /* fib for synchronous commands */ 186 struct aac_fib ac_sync_fib; 187}; 188 189/* 190 * Interface operations 191 */ 192struct aac_interface 193{ 194 int (* aif_get_fwstatus)(struct aac_softc *sc); 195 void (* aif_qnotify)(struct aac_softc *sc, int qbit); 196 int (* aif_get_istatus)(struct aac_softc *sc); 197 void (* aif_set_istatus)(struct aac_softc *sc, int mask); 198 void (* aif_set_mailbox)(struct aac_softc *sc, u_int32_t command, 199 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3); 200 int (* aif_get_mailboxstatus)(struct aac_softc *sc); 201 void (* aif_set_interrupts)(struct aac_softc *sc, int enable); 202}; 203extern struct aac_interface aac_rx_interface; 204extern struct aac_interface aac_sa_interface; 205 206#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc))) 207#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit))) 208#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc))) 209#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_set_istatus((sc), (mask))) 210#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \ 211 ((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), (arg3))) 212#define AAC_GET_MAILBOXSTATUS(sc) ((sc)->aac_if.aif_get_mailboxstatus((sc))) 213#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), 0)) 214#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), 1)) 215 216#define AAC_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val) 217#define AAC_GETREG4(sc, reg) bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg) 218#define AAC_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val) 219#define AAC_GETREG2(sc, reg) bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg) 220#define AAC_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val) 221#define AAC_GETREG1(sc, reg) bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg) 222 223/* 224 * Per-controller structure. 225 */ 226struct aac_softc 227{ 228 /* bus connections */ 229 device_t aac_dev; 230 struct resource *aac_regs_resource; /* register interface window */ 231 int aac_regs_rid; /* resource ID */ 232 bus_space_handle_t aac_bhandle; /* bus space handle */ 233 bus_space_tag_t aac_btag; /* bus space tag */ 234 bus_dma_tag_t aac_parent_dmat; /* parent DMA tag */ 235 bus_dma_tag_t aac_buffer_dmat; /* data buffer/command DMA tag */ 236 struct resource *aac_irq; /* interrupt */ 237 int aac_irq_rid; 238 void *aac_intr; /* interrupt handle */ 239 240 /* controller features, limits and status */ 241 int aac_state; 242#define AAC_STATE_SUSPEND (1<<0) 243#define AAC_STATE_OPEN (1<<1) 244#define AAC_STATE_INTERRUPTS_ON (1<<2) 245#define AAC_STATE_AIF_SLEEPER (1<<3) 246 struct FsaRevision aac_revision; 247 248 /* controller hardware interface */ 249 int aac_hwif; 250#define AAC_HWIF_I960RX 0 251#define AAC_HWIF_STRONGARM 1 252#define AAC_HWIF_UNKNOWN -1 253 bus_dma_tag_t aac_common_dmat; /* common structure DMA tag */ 254 bus_dmamap_t aac_common_dmamap; /* common structure DMA map */ 255 struct aac_common *aac_common; 256 u_int32_t aac_common_busaddr; 257 struct aac_interface aac_if; 258 259 /* command/fib resources */ 260 bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocating FIBs */ 261 struct aac_fib *aac_fibs; 262 bus_dmamap_t aac_fibmap; 263 u_int32_t aac_fibphys; 264 struct aac_command aac_command[AAC_FIB_COUNT]; 265 266 /* command management */ 267 TAILQ_HEAD(,aac_command) aac_free; /* command structures available for reuse */ 268 TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for controller resources */ 269 TAILQ_HEAD(,aac_command) aac_busy; 270 TAILQ_HEAD(,aac_command) aac_complete; /* commands which have been returned by the controller */ 271 struct bio_queue_head aac_bioq; 272 struct aac_queue_table *aac_queues; 273 struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT]; 274 275 struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */ 276 277 /* connected containters */ 278 struct aac_container aac_container[AAC_MAX_CONTAINERS]; 279 280 /* delayed activity infrastructure */ 281#if __FreeBSD_version >= 500005 282 struct task aac_task_complete; /* deferred-completion task */ 283#endif 284 struct intr_config_hook aac_ich; 285 286 /* management interface */ 287 dev_t aac_dev_t; 288 struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH]; 289 int aac_aifq_head; 290 int aac_aifq_tail; 291}; 292 293 294/* 295 * Public functions 296 */ 297extern void aac_free(struct aac_softc *sc); 298extern int aac_attach(struct aac_softc *sc); 299extern int aac_detach(device_t dev); 300extern int aac_shutdown(device_t dev); 301extern int aac_suspend(device_t dev); 302extern int aac_resume(device_t dev); 303extern void aac_intr(void *arg); 304extern devclass_t aac_devclass; 305extern void aac_submit_bio(struct bio *bp); 306extern void aac_biodone(struct bio *bp); 307 308/* 309 * Debugging levels: 310 * 0 - quiet, only emit warnings 311 * 1 - noisy, emit major function points and things done 312 * 2 - extremely noisy, emit trace items in loops, etc. 313 */ 314#ifdef AAC_DEBUG 315# define debug(level, fmt, args...) \ 316 do { \ 317 if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args); \ 318 } while(0) 319# define debug_called(level) \ 320 do { \ 321 if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n"); \ 322 } while(0) 323 324extern void aac_print_queues(struct aac_softc *sc); 325extern void aac_panic(struct aac_softc *sc, char *reason); 326extern void aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller); 327extern void aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif); 328 329# define AAC_PRINT_FIB(sc, fib) aac_print_fib(sc, fib, __FUNCTION__) 330 331#else 332# define debug(level, fmt, args...) 333# define debug_called(level) 334 335# define aac_print_queues(sc) 336# define aac_panic(sc, reason) 337# define aac_print_aif(sc, aif) 338 339# define AAC_PRINT_FIB(sc, fib) 340#endif 341 342struct aac_code_lookup { 343 char *string; 344 u_int32_t code; 345}; 346 347/******************************************************************************** 348 * Queue primitives for driver queues. 349 */ 350#define AACQ_ADD(sc, qname) \ 351 do { \ 352 struct aac_qstat *qs = &(sc)->aac_qstat[qname]; \ 353 \ 354 qs->q_length++; \ 355 if (qs->q_length > qs->q_max) \ 356 qs->q_max = qs->q_length; \ 357 } while(0) 358 359#define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length-- 360#define AACQ_INIT(sc, qname) \ 361 do { \ 362 sc->aac_qstat[qname].q_length = 0; \ 363 sc->aac_qstat[qname].q_max = 0; \ 364 } while(0) 365 366 367#define AACQ_COMMAND_QUEUE(name, index) \ 368static __inline void \ 369aac_initq_ ## name (struct aac_softc *sc) \ 370{ \ 371 TAILQ_INIT(&sc->aac_ ## name); \ 372 AACQ_INIT(sc, index); \ 373} \ 374static __inline void \ 375aac_enqueue_ ## name (struct aac_command *cm) \ 376{ \ 377 int s; \ 378 \ 379 s = splbio(); \ 380 TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 381 AACQ_ADD(cm->cm_sc, index); \ 382 splx(s); \ 383} \ 384static __inline void \ 385aac_requeue_ ## name (struct aac_command *cm) \ 386{ \ 387 int s; \ 388 \ 389 s = splbio(); \ 390 TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 391 AACQ_ADD(cm->cm_sc, index); \ 392 splx(s); \ 393} \ 394static __inline struct aac_command * \ 395aac_dequeue_ ## name (struct aac_softc *sc) \ 396{ \ 397 struct aac_command *cm; \ 398 int s; \ 399 \ 400 s = splbio(); \ 401 if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \ 402 TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \ 403 AACQ_REMOVE(sc, index); \ 404 } \ 405 splx(s); \ 406 return(cm); \ 407} \ 408static __inline void \ 409aac_remove_ ## name (struct aac_command *cm) \ 410{ \ 411 int s; \ 412 \ 413 s = splbio(); \ 414 TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 415 AACQ_REMOVE(cm->cm_sc, index); \ 416 splx(s); \ 417} \ 418struct hack 419 420AACQ_COMMAND_QUEUE(free, AACQ_FREE); 421AACQ_COMMAND_QUEUE(ready, AACQ_READY); 422AACQ_COMMAND_QUEUE(busy, AACQ_BUSY); 423AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE); 424 425/* 426 * outstanding bio queue 427 */ 428static __inline void 429aac_initq_bio(struct aac_softc *sc) 430{ 431 bioq_init(&sc->aac_bioq); 432 AACQ_INIT(sc, AACQ_BIO); 433} 434 435static __inline void 436aac_enqueue_bio(struct aac_softc *sc, struct bio *bp) 437{ 438 int s; 439 440 s = splbio(); 441 bioq_insert_tail(&sc->aac_bioq, bp); 442 AACQ_ADD(sc, AACQ_BIO); 443 splx(s); 444} 445 446static __inline struct bio * 447aac_dequeue_bio(struct aac_softc *sc) 448{ 449 int s; 450 struct bio *bp; 451 452 s = splbio(); 453 if ((bp = bioq_first(&sc->aac_bioq)) != NULL) { 454 bioq_remove(&sc->aac_bioq, bp); 455 AACQ_REMOVE(sc, AACQ_BIO); 456 } 457 splx(s); 458 return(bp); 459} 460