aacvar.h revision 110604
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2001 Scott Long 4 * Copyright (c) 2000 BSDi 5 * Copyright (c) 2001 Adaptec, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: head/sys/dev/aac/aacvar.h 110604 2003-02-10 00:34:24Z scottl $ 30 */ 31 32/* 33 * Driver Parameter Definitions 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 in page-size chunks and can grow up to the 512 49 * limit imposed by the hardware. 50 */ 51#define AAC_FIB_COUNT 8 52#define AAC_MAX_FIBS 512 53 54/* 55 * The controller reports status events in AIFs. We hang on to a number of 56 * these in order to pass them out to user-space management tools. 57 */ 58#define AAC_AIFQ_LENGTH 64 59 60/* 61 * Firmware messages are passed in the printf buffer. 62 */ 63#define AAC_PRINTF_BUFSIZE 256 64 65/* 66 * We wait this many seconds for the adapter to come ready if it is still 67 * 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 20 /* seconds */ 86 87/* 88 * Character device major numbers. 89 */ 90#define AAC_DISK_MAJOR 200 91 92/* 93 * Driver Variable Definitions 94 */ 95 96#if __FreeBSD_version >= 500005 97# include <sys/taskqueue.h> 98#endif 99 100/* 101 * Per-container data structure 102 */ 103struct aac_container 104{ 105 struct aac_mntobj co_mntobj; 106 device_t co_disk; 107 int co_found; 108 TAILQ_ENTRY(aac_container) co_link; 109}; 110 111/* 112 * Per-SIM data structure 113 */ 114struct aac_sim 115{ 116 device_t sim_dev; 117 int TargetsPerBus; 118 int BusNumber; 119 int InitiatorBusId; 120 struct aac_softc *aac_sc; 121 TAILQ_ENTRY(aac_sim) sim_link; 122}; 123 124/* 125 * Per-disk structure 126 */ 127struct aac_disk 128{ 129 device_t ad_dev; 130 dev_t ad_dev_t; 131 struct aac_softc *ad_controller; 132 struct aac_container *ad_container; 133 struct disk ad_disk; 134 struct devstat ad_stats; 135 int ad_flags; 136#define AAC_DISK_OPEN (1<<0) 137 int ad_cylinders; 138 int ad_heads; 139 int ad_sectors; 140 u_int32_t ad_size; 141 int unit; 142}; 143 144/* 145 * Per-command control structure. 146 */ 147struct aac_command 148{ 149 TAILQ_ENTRY(aac_command) cm_link; /* list linkage */ 150 151 struct aac_softc *cm_sc; /* controller that owns us */ 152 153 struct aac_fib *cm_fib; /* FIB associated with this 154 * command */ 155 u_int32_t cm_fibphys; /* bus address of the FIB */ 156 struct bio *cm_data; /* pointer to data in kernel 157 * space */ 158 u_int32_t cm_datalen; /* data length */ 159 bus_dmamap_t cm_datamap; /* DMA map for bio data */ 160 struct aac_sg_table *cm_sgtable; /* pointer to s/g table in 161 * command */ 162 int cm_flags; 163#define AAC_CMD_MAPPED (1<<0) /* command has had its data 164 * mapped */ 165#define AAC_CMD_DATAIN (1<<1) /* command involves data moving 166 * from controller to host */ 167#define AAC_CMD_DATAOUT (1<<2) /* command involves data moving 168 * from host to controller */ 169#define AAC_CMD_COMPLETED (1<<3) /* command has been completed */ 170#define AAC_CMD_TIMEDOUT (1<<4) /* command taken too long */ 171#define AAC_ON_AACQ_FREE (1<<5) 172#define AAC_ON_AACQ_READY (1<<6) 173#define AAC_ON_AACQ_BUSY (1<<7) 174#define AAC_ON_AACQ_COMPLETE (1<<8) 175#define AAC_ON_AACQ_MASK ((1<<5)|(1<<6)|(1<<7)|(1<<8)) 176 177 void (* cm_complete)(struct aac_command *cm); 178 void *cm_private; 179 time_t cm_timestamp; /* command creation time */ 180 int cm_queue; 181}; 182 183struct aac_fibmap { 184 TAILQ_ENTRY(aac_fibmap) fm_link; /* list linkage */ 185 struct aac_fib *aac_fibs; 186 bus_dmamap_t aac_fibmap; 187 struct aac_command *aac_commands; 188}; 189 190/* 191 * We gather a number of adapter-visible items into a single structure. 192 * 193 * The ordering of this strucure may be important; we copy the Linux driver: 194 * 195 * Adapter FIBs 196 * Init struct 197 * Queue headers (Comm Area) 198 * Printf buffer 199 * 200 * In addition, we add: 201 * Sync Fib 202 */ 203struct aac_common { 204 /* fibs for the controller to send us messages */ 205 struct aac_fib ac_fibs[AAC_ADAPTER_FIBS]; 206 207 /* the init structure */ 208 struct aac_adapter_init ac_init; 209 210 /* arena within which the queue structures are kept */ 211 u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + 212 AAC_QUEUE_ALIGN]; 213 214 /* buffer for text messages from the controller */ 215 char ac_printf[AAC_PRINTF_BUFSIZE]; 216 217 /* fib for synchronous commands */ 218 struct aac_fib ac_sync_fib; 219}; 220 221/* 222 * Interface operations 223 */ 224struct aac_interface 225{ 226 int (*aif_get_fwstatus)(struct aac_softc *sc); 227 void (*aif_qnotify)(struct aac_softc *sc, int qbit); 228 int (*aif_get_istatus)(struct aac_softc *sc); 229 void (*aif_clr_istatus)(struct aac_softc *sc, int mask); 230 void (*aif_set_mailbox)(struct aac_softc *sc, u_int32_t command, 231 u_int32_t arg0, u_int32_t arg1, 232 u_int32_t arg2, u_int32_t arg3); 233 int (*aif_get_mailboxstatus)(struct aac_softc *sc); 234 void (*aif_set_interrupts)(struct aac_softc *sc, int enable); 235}; 236extern struct aac_interface aac_rx_interface; 237extern struct aac_interface aac_sa_interface; 238extern struct aac_interface aac_fa_interface; 239 240#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc))) 241#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit))) 242#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc))) 243#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_clr_istatus((sc), \ 244 (mask))) 245#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \ 246 ((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), \ 247 (arg3))) 248#define AAC_GET_MAILBOXSTATUS(sc) ((sc)->aac_if.aif_get_mailboxstatus( \ 249 (sc))) 250#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \ 251 0)) 252#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \ 253 1)) 254 255#define AAC_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag, \ 256 sc->aac_bhandle, reg, val) 257#define AAC_GETREG4(sc, reg) bus_space_read_4 (sc->aac_btag, \ 258 sc->aac_bhandle, reg) 259#define AAC_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag, \ 260 sc->aac_bhandle, reg, val) 261#define AAC_GETREG2(sc, reg) bus_space_read_2 (sc->aac_btag, \ 262 sc->aac_bhandle, reg) 263#define AAC_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag, \ 264 sc->aac_bhandle, reg, val) 265#define AAC_GETREG1(sc, reg) bus_space_read_1 (sc->aac_btag, \ 266 sc->aac_bhandle, reg) 267 268/* Define the OS version specific locks */ 269#if __FreeBSD_version >= 500005 270#include <sys/lock.h> 271#include <sys/mutex.h> 272typedef struct mtx aac_lock_t; 273#define AAC_LOCK_INIT(l, s) mtx_init(l, s, NULL, MTX_DEF) 274#define AAC_LOCK_ACQUIRE(l) mtx_lock(l) 275#define AAC_LOCK_RELEASE(l) mtx_unlock(l) 276#else 277typedef struct simplelock aac_lock_t; 278#define AAC_LOCK_INIT(l, s) simple_lock_init(l) 279#define AAC_LOCK_ACQUIRE(l) simple_lock(l) 280#define AAC_LOCK_RELEASE(l) simple_unlock(l) 281#endif 282 283#if __FreeBSD_version >= 500005 284#include <sys/selinfo.h> 285#else 286#include <sys/select.h> 287#endif 288 289/* 290 * Per-controller structure. 291 */ 292struct aac_softc 293{ 294 /* bus connections */ 295 device_t aac_dev; 296 struct resource *aac_regs_resource; /* register interface 297 * window */ 298 int aac_regs_rid; /* resource ID */ 299 bus_space_handle_t aac_bhandle; /* bus space handle */ 300 bus_space_tag_t aac_btag; /* bus space tag */ 301 bus_dma_tag_t aac_parent_dmat; /* parent DMA tag */ 302 bus_dma_tag_t aac_buffer_dmat; /* data buffer/command 303 * DMA tag */ 304 struct resource *aac_irq; /* interrupt */ 305 int aac_irq_rid; 306 void *aac_intr; /* interrupt handle */ 307 eventhandler_tag eh; 308 309 /* controller features, limits and status */ 310 int aac_state; 311#define AAC_STATE_SUSPEND (1<<0) 312#define AAC_STATE_OPEN (1<<1) 313#define AAC_STATE_INTERRUPTS_ON (1<<2) 314#define AAC_STATE_AIF_SLEEPER (1<<3) 315 struct FsaRevision aac_revision; 316 317 /* controller hardware interface */ 318 int aac_hwif; 319#define AAC_HWIF_I960RX 0 320#define AAC_HWIF_STRONGARM 1 321#define AAC_HWIF_FALCON 2 322#define AAC_HWIF_UNKNOWN -1 323 bus_dma_tag_t aac_common_dmat; /* common structure 324 * DMA tag */ 325 bus_dmamap_t aac_common_dmamap; /* common structure 326 * DMA map */ 327 struct aac_common *aac_common; 328 u_int32_t aac_common_busaddr; 329 struct aac_interface aac_if; 330 331 /* command/fib resources */ 332 bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocing FIBs */ 333 TAILQ_HEAD(,aac_fibmap) aac_fibmap_tqh; 334 uint total_fibs; 335 struct aac_command *aac_commands; 336 337 /* command management */ 338 TAILQ_HEAD(,aac_command) aac_free; /* command structures 339 * available for reuse */ 340 TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for 341 * controller resources */ 342 TAILQ_HEAD(,aac_command) aac_busy; 343 TAILQ_HEAD(,aac_command) aac_complete; /* commands which have been 344 * returned by the controller */ 345 struct bio_queue_head aac_bioq; 346 struct aac_queue_table *aac_queues; 347 struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT]; 348 349 struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */ 350 351 /* connected containters */ 352 TAILQ_HEAD(,aac_container) aac_container_tqh; 353 aac_lock_t aac_container_lock; 354 355 /* Protect the sync fib */ 356#define AAC_SYNC_LOCK_FORCE (1 << 0) 357 aac_lock_t aac_sync_lock; 358 359 /* delayed activity infrastructure */ 360#if __FreeBSD_version >= 500005 361 struct task aac_task_complete; /* deferred-completion 362 * task */ 363#endif 364 struct intr_config_hook aac_ich; 365 366 /* management interface */ 367 dev_t aac_dev_t; 368 aac_lock_t aac_aifq_lock; 369 struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH]; 370 int aac_aifq_head; 371 int aac_aifq_tail; 372 struct selinfo rcv_select; 373 struct proc *aifthread; 374 int aifflags; 375#define AAC_AIFFLAGS_RUNNING (1 << 0) 376#define AAC_AIFFLAGS_AIF (1 << 1) 377#define AAC_AIFFLAGS_EXIT (1 << 2) 378#define AAC_AIFFLAGS_EXITED (1 << 3) 379#define AAC_AIFFLAGS_PRINTF (1 << 4) 380#define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_PRINTF) 381 u_int32_t quirks; 382#define AAC_QUIRK_PERC2QC (1 << 0) 383#define AAC_QUIRK_NOCAM (1 << 1) /* No SCSI passthrough */ 384#define AAC_QUIRK_CAM_NORESET (1 << 2) /* Fake SCSI resets */ 385#define AAC_QUIRK_CAM_PASSONLY (1 << 3) /* Only create pass devices */ 386 387 u_int32_t scsi_method_id; 388 TAILQ_HEAD(,aac_sim) aac_sim_tqh; 389}; 390 391 392/* 393 * Public functions 394 */ 395extern void aac_free(struct aac_softc *sc); 396extern int aac_attach(struct aac_softc *sc); 397extern int aac_detach(device_t dev); 398extern int aac_shutdown(device_t dev); 399extern int aac_suspend(device_t dev); 400extern int aac_resume(device_t dev); 401extern void aac_intr(void *arg); 402extern void aac_submit_bio(struct bio *bp); 403extern void aac_biodone(struct bio *bp); 404extern void aac_startio(struct aac_softc *sc); 405extern int aac_alloc_command(struct aac_softc *sc, 406 struct aac_command **cmp); 407extern void aac_release_command(struct aac_command *cm); 408extern int aac_alloc_sync_fib(struct aac_softc *sc, 409 struct aac_fib **fib, int flags); 410extern void aac_release_sync_fib(struct aac_softc *sc); 411extern int aac_sync_fib(struct aac_softc *sc, u_int32_t command, 412 u_int32_t xferstate, struct aac_fib *fib, 413 u_int16_t datasize); 414 415/* 416 * Debugging levels: 417 * 0 - quiet, only emit warnings 418 * 1 - noisy, emit major function points and things done 419 * 2 - extremely noisy, emit trace items in loops, etc. 420 */ 421#ifdef AAC_DEBUG 422# define debug(level, fmt, args...) \ 423 do { \ 424 if (level <=AAC_DEBUG) printf("%s: " fmt "\n", __func__ , ##args); \ 425 } while (0) 426# define debug_called(level) \ 427 do { \ 428 if (level <= AAC_DEBUG) printf("%s: called\n", __func__); \ 429 } while (0) 430 431extern void aac_print_queues(struct aac_softc *sc); 432extern void aac_panic(struct aac_softc *sc, char *reason); 433extern void aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, 434 const char *caller); 435extern void aac_print_aif(struct aac_softc *sc, 436 struct aac_aif_command *aif); 437 438#define AAC_PRINT_FIB(sc, fib) aac_print_fib(sc, fib, __func__) 439 440#else 441# define debug(level, fmt, args...) 442# define debug_called(level) 443 444# define aac_print_queues(sc) 445# define aac_panic(sc, reason) 446 447# define AAC_PRINT_FIB(sc, fib) 448# define aac_print_aif(sc, aac_aif_command) 449#endif 450 451struct aac_code_lookup { 452 char *string; 453 u_int32_t code; 454}; 455 456/* 457 * Queue primitives for driver queues. 458 */ 459#define AACQ_ADD(sc, qname) \ 460 do { \ 461 struct aac_qstat *qs; \ 462 \ 463 qs = &(sc)->aac_qstat[qname]; \ 464 \ 465 qs->q_length++; \ 466 if (qs->q_length > qs->q_max) \ 467 qs->q_max = qs->q_length; \ 468 } while (0) 469 470#define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length-- 471#define AACQ_INIT(sc, qname) \ 472 do { \ 473 sc->aac_qstat[qname].q_length = 0; \ 474 sc->aac_qstat[qname].q_max = 0; \ 475 } while (0) 476 477 478#define AACQ_COMMAND_QUEUE(name, index) \ 479static __inline void \ 480aac_initq_ ## name (struct aac_softc *sc) \ 481{ \ 482 TAILQ_INIT(&sc->aac_ ## name); \ 483 AACQ_INIT(sc, index); \ 484} \ 485static __inline void \ 486aac_enqueue_ ## name (struct aac_command *cm) \ 487{ \ 488 int s; \ 489 \ 490 s = splbio(); \ 491 if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \ 492 printf("command %p is on another queue, flags = %#x\n", \ 493 cm, cm->cm_flags); \ 494 panic("command is on another queue"); \ 495 } \ 496 TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 497 cm->cm_flags |= AAC_ON_ ## index; \ 498 AACQ_ADD(cm->cm_sc, index); \ 499 splx(s); \ 500} \ 501static __inline void \ 502aac_requeue_ ## name (struct aac_command *cm) \ 503{ \ 504 int s; \ 505 \ 506 s = splbio(); \ 507 if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \ 508 printf("command %p is on another queue, flags = %#x\n", \ 509 cm, cm->cm_flags); \ 510 panic("command is on another queue"); \ 511 } \ 512 TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 513 cm->cm_flags |= AAC_ON_ ## index; \ 514 AACQ_ADD(cm->cm_sc, index); \ 515 splx(s); \ 516} \ 517static __inline struct aac_command * \ 518aac_dequeue_ ## name (struct aac_softc *sc) \ 519{ \ 520 struct aac_command *cm; \ 521 int s; \ 522 \ 523 s = splbio(); \ 524 if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \ 525 if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \ 526 printf("command %p not in queue, flags = %#x, " \ 527 "bit = %#x\n", cm, cm->cm_flags, \ 528 AAC_ON_ ## index); \ 529 panic("command not in queue"); \ 530 } \ 531 TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \ 532 cm->cm_flags &= ~AAC_ON_ ## index; \ 533 AACQ_REMOVE(sc, index); \ 534 } \ 535 splx(s); \ 536 return(cm); \ 537} \ 538static __inline void \ 539aac_remove_ ## name (struct aac_command *cm) \ 540{ \ 541 int s; \ 542 \ 543 s = splbio(); \ 544 if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \ 545 printf("command %p not in queue, flags = %#x, " \ 546 "bit = %#x\n", cm, cm->cm_flags, \ 547 AAC_ON_ ## index); \ 548 panic("command not in queue"); \ 549 } \ 550 TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \ 551 cm->cm_flags &= ~AAC_ON_ ## index; \ 552 AACQ_REMOVE(cm->cm_sc, index); \ 553 splx(s); \ 554} \ 555struct hack 556 557AACQ_COMMAND_QUEUE(free, AACQ_FREE); 558AACQ_COMMAND_QUEUE(ready, AACQ_READY); 559AACQ_COMMAND_QUEUE(busy, AACQ_BUSY); 560AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE); 561 562/* 563 * outstanding bio queue 564 */ 565static __inline void 566aac_initq_bio(struct aac_softc *sc) 567{ 568 bioq_init(&sc->aac_bioq); 569 AACQ_INIT(sc, AACQ_BIO); 570} 571 572static __inline void 573aac_enqueue_bio(struct aac_softc *sc, struct bio *bp) 574{ 575 int s; 576 577 s = splbio(); 578 bioq_insert_tail(&sc->aac_bioq, bp); 579 AACQ_ADD(sc, AACQ_BIO); 580 splx(s); 581} 582 583static __inline struct bio * 584aac_dequeue_bio(struct aac_softc *sc) 585{ 586 int s; 587 struct bio *bp; 588 589 s = splbio(); 590 if ((bp = bioq_first(&sc->aac_bioq)) != NULL) { 591 bioq_remove(&sc->aac_bioq, bp); 592 AACQ_REMOVE(sc, AACQ_BIO); 593 } 594 splx(s); 595 return(bp); 596} 597 598static __inline void 599aac_print_printf(struct aac_softc *sc) 600{ 601 /* 602 * XXX We have the ability to read the length of the printf string 603 * from out of the mailboxes. 604 */ 605 device_printf(sc->aac_dev, "**Monitor** %.*s", AAC_PRINTF_BUFSIZE, 606 sc->aac_common->ac_printf); 607 AAC_QNOTIFY(sc, AAC_DB_PRINTF); 608} 609