1 /* $OpenBSD: aic7xxx_inline.h,v 1.17 2016/08/17 01:17:54 krw Exp $ */ 2 /* $NetBSD: aic7xxx_inline.h,v 1.4 2003/11/02 11:07:44 wiz Exp $ */ 3 4 /* 5 * Inline routines shareable across OS platforms. 6 * 7 * Copyright (c) 1994-2001 Justin T. Gibbs. 8 * Copyright (c) 2000-2001 Adaptec Inc. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 * 43 * //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#39 $ 44 * 45 * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.20 2003/01/20 20:44:55 gibbs Exp $ 46 */ 47 /* 48 * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003 49 */ 50 51 #ifndef _AIC7XXX_INLINE_H_ 52 #define _AIC7XXX_INLINE_H_ 53 54 #ifdef SMALL_KERNEL 55 #define IO_INLINE 56 #else 57 #define IO_INLINE static __inline 58 #define IO_EXPAND 59 #endif 60 61 /************************* Sequencer Execution Control ************************/ 62 IO_INLINE void ahc_pause_bug_fix(struct ahc_softc *ahc); 63 IO_INLINE int ahc_is_paused(struct ahc_softc *ahc); 64 IO_INLINE void ahc_pause(struct ahc_softc *ahc); 65 IO_INLINE void ahc_unpause(struct ahc_softc *ahc); 66 67 #ifdef IO_EXPAND 68 /* 69 * Work around any chip bugs related to halting sequencer execution. 70 * On Ultra2 controllers, we must clear the CIOBUS stretch signal by 71 * reading a register that will set this signal and deassert it. 72 * Without this workaround, if the chip is paused, by an interrupt or 73 * manual pause while accessing scb ram, accesses to certain registers 74 * will hang the system (infinite pci retries). 75 */ 76 IO_INLINE void 77 ahc_pause_bug_fix(struct ahc_softc *ahc) 78 { 79 if ((ahc->features & AHC_ULTRA2) != 0) 80 (void)ahc_inb(ahc, CCSCBCTL); 81 } 82 83 /* 84 * Determine whether the sequencer has halted code execution. 85 * Returns non-zero status if the sequencer is stopped. 86 */ 87 IO_INLINE int 88 ahc_is_paused(struct ahc_softc *ahc) 89 { 90 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0); 91 } 92 93 /* 94 * Request that the sequencer stop and wait, indefinitely, for it 95 * to stop. The sequencer will only acknowledge that it is paused 96 * once it has reached an instruction boundary and PAUSEDIS is 97 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS 98 * for critical sections. 99 */ 100 IO_INLINE void 101 ahc_pause(struct ahc_softc *ahc) 102 { 103 ahc_outb(ahc, HCNTRL, ahc->pause); 104 105 /* 106 * Since the sequencer can disable pausing in a critical section, we 107 * must loop until it actually stops. 108 */ 109 while (ahc_is_paused(ahc) == 0) 110 ; 111 112 ahc_pause_bug_fix(ahc); 113 } 114 115 /* 116 * Allow the sequencer to continue program execution. 117 * We check here to ensure that no additional interrupt 118 * sources that would cause the sequencer to halt have been 119 * asserted. If, for example, a SCSI bus reset is detected 120 * while we are fielding a different, pausing, interrupt type, 121 * we don't want to release the sequencer before going back 122 * into our interrupt handler and dealing with this new 123 * condition. 124 */ 125 IO_INLINE void 126 ahc_unpause(struct ahc_softc *ahc) 127 { 128 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0) 129 ahc_outb(ahc, HCNTRL, ahc->unpause); 130 } 131 #endif /* IO_EXPAND */ 132 133 /*********************** Untagged Transaction Routines ************************/ 134 IO_INLINE void ahc_freeze_untagged_queues(struct ahc_softc *ahc); 135 IO_INLINE void ahc_release_untagged_queues(struct ahc_softc *ahc); 136 137 #ifdef IO_EXPAND 138 /* 139 * Block our completion routine from starting the next untagged 140 * transaction for this target or target lun. 141 */ 142 IO_INLINE void 143 ahc_freeze_untagged_queues(struct ahc_softc *ahc) 144 { 145 if ((ahc->flags & AHC_SCB_BTT) == 0) 146 ahc->untagged_queue_lock++; 147 } 148 149 /* 150 * Allow the next untagged transaction for this target or target lun 151 * to be executed. We use a counting semaphore to allow the lock 152 * to be acquired recursively. Once the count drops to zero, the 153 * transaction queues will be run. 154 */ 155 IO_INLINE void 156 ahc_release_untagged_queues(struct ahc_softc *ahc) 157 { 158 if ((ahc->flags & AHC_SCB_BTT) == 0) { 159 ahc->untagged_queue_lock--; 160 if (ahc->untagged_queue_lock == 0) 161 ahc_run_untagged_queues(ahc); 162 } 163 } 164 #endif /* IO_EXPAND */ 165 166 167 /************************** Memory mapping routines ***************************/ 168 IO_INLINE struct ahc_dma_seg * 169 ahc_sg_bus_to_virt(struct scb *scb, 170 uint32_t sg_busaddr); 171 IO_INLINE uint32_t 172 ahc_sg_virt_to_bus(struct scb *scb, 173 struct ahc_dma_seg *sg); 174 IO_INLINE uint32_t 175 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index); 176 IO_INLINE void ahc_sync_scb(struct ahc_softc *ahc, 177 struct scb *scb, int op); 178 #ifdef AHC_TARGET_MODE 179 IO_INLINE uint32_t 180 ahc_targetcmd_offset(struct ahc_softc *ahc, 181 u_int index); 182 #endif 183 184 #ifdef IO_EXPAND 185 186 IO_INLINE struct ahc_dma_seg * 187 ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr) 188 { 189 int sg_index; 190 191 sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg); 192 /* sg_list_phys points to entry 1, not 0 */ 193 sg_index++; 194 195 return (&scb->sg_list[sg_index]); 196 } 197 198 IO_INLINE uint32_t 199 ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg) 200 { 201 int sg_index; 202 203 /* sg_list_phys points to entry 1, not 0 */ 204 sg_index = sg - &scb->sg_list[1]; 205 206 return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list))); 207 } 208 209 IO_INLINE uint32_t 210 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index) 211 { 212 return (ahc->scb_data->hscb_busaddr 213 + (sizeof(struct hardware_scb) * index)); 214 } 215 216 IO_INLINE void 217 ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op) 218 { 219 ahc_dmamap_sync(ahc, ahc->parent_dmat, 220 ahc->scb_data->hscb_dmamap, 221 /*offset*/(scb->hscb - ahc->scb_data->hscbs) * sizeof(*scb->hscb), 222 /*len*/sizeof(*scb->hscb), op); 223 } 224 225 #ifdef AHC_TARGET_MODE 226 IO_INLINE uint32_t 227 ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index) 228 { 229 return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo); 230 } 231 #endif /* AHC_TARGET_MODE */ 232 #endif /* IO_EXPAND */ 233 234 /******************************** Debugging ***********************************/ 235 static __inline char *ahc_name(struct ahc_softc *ahc); 236 237 static __inline char * 238 ahc_name(struct ahc_softc *ahc) 239 { 240 return (ahc->name); 241 } 242 243 /*********************** Miscellaneous Support Functions ***********************/ 244 245 IO_INLINE void ahc_update_residual(struct ahc_softc *ahc, 246 struct scb *scb); 247 IO_INLINE struct ahc_initiator_tinfo * 248 ahc_fetch_transinfo(struct ahc_softc *ahc, 249 char channel, u_int our_id, 250 u_int remote_id, 251 struct ahc_tmode_tstate **tstate); 252 253 IO_INLINE uint16_t 254 ahc_inw(struct ahc_softc *ahc, u_int port); 255 IO_INLINE void ahc_outw(struct ahc_softc *ahc, u_int port, 256 u_int value); 257 IO_INLINE uint32_t 258 ahc_inl(struct ahc_softc *ahc, u_int port); 259 IO_INLINE void ahc_outl(struct ahc_softc *ahc, u_int port, 260 uint32_t value); 261 IO_INLINE struct scb *ahc_lookup_scb(struct ahc_softc *ahc, u_int tag); 262 IO_INLINE void ahc_swap_with_next_hscb(struct ahc_softc *ahc, 263 struct scb *scb); 264 IO_INLINE void ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb); 265 IO_INLINE struct scsi_sense_data * 266 ahc_get_sense_buf(struct ahc_softc *ahc, 267 struct scb *scb); 268 IO_INLINE uint32_t 269 ahc_get_sense_bufaddr(struct ahc_softc *ahc, 270 struct scb *scb); 271 272 #ifdef IO_EXPAND 273 274 /* 275 * Determine whether the sequencer reported a residual 276 * for this SCB/transaction. 277 */ 278 IO_INLINE void 279 ahc_update_residual(struct ahc_softc *ahc, struct scb *scb) 280 { 281 uint32_t sgptr; 282 283 sgptr = aic_le32toh(scb->hscb->sgptr); 284 if ((sgptr & SG_RESID_VALID) != 0) 285 ahc_calc_residual(ahc, scb); 286 } 287 288 /* 289 * Return pointers to the transfer negotiation information 290 * for the specified our_id/remote_id pair. 291 */ 292 IO_INLINE struct ahc_initiator_tinfo * 293 ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id, 294 u_int remote_id, struct ahc_tmode_tstate **tstate) 295 { 296 /* 297 * Transfer data structures are stored from the perspective 298 * of the target role. Since the parameters for a connection 299 * in the initiator role to a given target are the same as 300 * when the roles are reversed, we pretend we are the target. 301 */ 302 if (channel == 'B') 303 our_id += 8; 304 *tstate = ahc->enabled_targets[our_id]; 305 return (&(*tstate)->transinfo[remote_id]); 306 } 307 308 IO_INLINE uint16_t 309 ahc_inw(struct ahc_softc *ahc, u_int port) 310 { 311 return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port)); 312 } 313 314 IO_INLINE void 315 ahc_outw(struct ahc_softc *ahc, u_int port, u_int value) 316 { 317 ahc_outb(ahc, port, value & 0xFF); 318 ahc_outb(ahc, port+1, (value >> 8) & 0xFF); 319 } 320 321 IO_INLINE uint32_t 322 ahc_inl(struct ahc_softc *ahc, u_int port) 323 { 324 return ((ahc_inb(ahc, port)) 325 | (ahc_inb(ahc, port+1) << 8) 326 | (ahc_inb(ahc, port+2) << 16) 327 | (ahc_inb(ahc, port+3) << 24)); 328 } 329 330 IO_INLINE void 331 ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value) 332 { 333 ahc_outb(ahc, port, (value) & 0xFF); 334 ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF); 335 ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF); 336 ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF); 337 } 338 339 IO_INLINE struct scb * 340 ahc_lookup_scb(struct ahc_softc *ahc, u_int tag) 341 { 342 struct scb* scb; 343 344 scb = ahc->scb_data->scbindex[tag]; 345 if (scb != NULL) 346 ahc_sync_scb(ahc, scb, 347 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 348 return (scb); 349 } 350 351 352 IO_INLINE void 353 ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb) 354 { 355 struct hardware_scb *q_hscb; 356 u_int saved_tag; 357 358 /* 359 * Our queuing method is a bit tricky. The card 360 * knows in advance which HSCB to download, and we 361 * can't disappoint it. To achieve this, the next 362 * SCB to download is saved off in ahc->next_queued_scb. 363 * When we are called to queue "an arbitrary scb", 364 * we copy the contents of the incoming HSCB to the one 365 * the sequencer knows about, swap HSCB pointers and 366 * finally assign the SCB to the tag indexed location 367 * in the scb_array. This makes sure that we can still 368 * locate the correct SCB by SCB_TAG. 369 */ 370 q_hscb = ahc->next_queued_scb->hscb; 371 saved_tag = q_hscb->tag; 372 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); 373 if ((scb->flags & SCB_CDB32_PTR) != 0) { 374 q_hscb->shared_data.cdb_ptr = 375 aic_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag) 376 + offsetof(struct hardware_scb, cdb32)); 377 } 378 q_hscb->tag = saved_tag; 379 q_hscb->next = scb->hscb->tag; 380 381 /* Now swap HSCB pointers. */ 382 ahc->next_queued_scb->hscb = scb->hscb; 383 scb->hscb = q_hscb; 384 385 /* Now define the mapping from tag to SCB in the scbindex */ 386 ahc->scb_data->scbindex[scb->hscb->tag] = scb; 387 } 388 389 /* 390 * Tell the sequencer about a new transaction to execute. 391 */ 392 IO_INLINE void 393 ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb) 394 { 395 ahc_swap_with_next_hscb(ahc, scb); 396 397 if (scb->hscb->tag == SCB_LIST_NULL 398 || scb->hscb->next == SCB_LIST_NULL) 399 panic("Attempt to queue invalid SCB tag %x:%x", 400 scb->hscb->tag, scb->hscb->next); 401 402 /* 403 * Setup data "oddness". 404 */ 405 scb->hscb->lun &= LID; 406 if (ahc_get_transfer_length(scb) & 0x1) 407 scb->hscb->lun |= SCB_XFERLEN_ODD; 408 409 /* 410 * Keep a history of SCBs we've downloaded in the qinfifo. 411 */ 412 ahc->qinfifo[ahc->qinfifonext] = scb->hscb->tag; 413 ahc_dmamap_sync(ahc, ahc->parent_dmat, ahc->shared_data_dmamap, 414 /*offset*/ahc->qinfifonext+256, /*len*/1, 415 BUS_DMASYNC_PREWRITE); 416 ahc->qinfifonext++; 417 418 /* 419 * Make sure our data is consistent from the 420 * perspective of the adapter. 421 */ 422 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 423 424 /* Tell the adapter about the newly queued SCB */ 425 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 426 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext); 427 } else { 428 if ((ahc->features & AHC_AUTOPAUSE) == 0) 429 ahc_pause(ahc); 430 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext); 431 if ((ahc->features & AHC_AUTOPAUSE) == 0) 432 ahc_unpause(ahc); 433 } 434 } 435 436 437 IO_INLINE struct scsi_sense_data * 438 ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb) 439 { 440 int offset; 441 442 offset = scb - ahc->scb_data->scbarray; 443 return (&ahc->scb_data->sense[offset]); 444 } 445 446 IO_INLINE uint32_t 447 ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb) 448 { 449 int offset; 450 451 offset = scb - ahc->scb_data->scbarray; 452 return (ahc->scb_data->sense_busaddr 453 + (offset * sizeof(struct scsi_sense_data))); 454 } 455 #endif /* IO_EXPAND */ 456 457 /************************** Interrupt Processing ******************************/ 458 IO_INLINE void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op); 459 IO_INLINE void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op); 460 IO_INLINE u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc); 461 IO_INLINE int ahc_intr(struct ahc_softc *ahc); 462 463 #ifdef IO_EXPAND 464 IO_INLINE void 465 ahc_sync_qoutfifo(struct ahc_softc *ahc, int op) 466 { 467 ahc_dmamap_sync(ahc, ahc->parent_dmat, ahc->shared_data_dmamap, 468 /*offset*/0, /*len*/256, op); 469 } 470 471 IO_INLINE void 472 ahc_sync_tqinfifo(struct ahc_softc *ahc, int op) 473 { 474 #ifdef AHC_TARGET_MODE 475 if ((ahc->flags & AHC_TARGETROLE) != 0) { 476 ahc_dmamap_sync(ahc, ahc->parent_dmat /*shared_data_dmat*/, 477 ahc->shared_data_dmamap, 478 ahc_targetcmd_offset(ahc, 0), 479 sizeof(struct target_cmd) * AHC_TMODE_CMDS, 480 op); 481 } 482 #endif 483 } 484 485 /* 486 * See if the firmware has posted any completed commands 487 * into our in-core command complete fifos. 488 */ 489 #define AHC_RUN_QOUTFIFO 0x1 490 #define AHC_RUN_TQINFIFO 0x2 491 IO_INLINE u_int 492 ahc_check_cmdcmpltqueues(struct ahc_softc *ahc) 493 { 494 u_int retval; 495 496 retval = 0; 497 ahc_dmamap_sync(ahc, ahc->parent_dmat /*shared_data_dmat*/, ahc->shared_data_dmamap, 498 /*offset*/ahc->qoutfifonext, /*len*/1, 499 BUS_DMASYNC_POSTREAD); 500 if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) 501 retval |= AHC_RUN_QOUTFIFO; 502 #ifdef AHC_TARGET_MODE 503 if ((ahc->flags & AHC_TARGETROLE) != 0 504 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) { 505 ahc_dmamap_sync(ahc, ahc->parent_dmat /*shared_data_dmat*/, 506 ahc->shared_data_dmamap, 507 ahc_targetcmd_offset(ahc, ahc->tqinfifonext), 508 /*len*/sizeof(struct target_cmd), 509 BUS_DMASYNC_POSTREAD); 510 if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0) 511 retval |= AHC_RUN_TQINFIFO; 512 } 513 #endif 514 return (retval); 515 } 516 517 518 /* 519 * Catch an interrupt from the adapter 520 */ 521 IO_INLINE int 522 ahc_intr(struct ahc_softc *ahc) 523 { 524 u_int intstat; 525 526 if ((ahc->pause & INTEN) == 0) { 527 /* 528 * Our interrupt is not enabled on the chip 529 * and may be disabled for re-entrancy reasons, 530 * so just return. This is likely just a shared 531 * interrupt. 532 */ 533 return (0); 534 } 535 /* 536 * Instead of directly reading the interrupt status register, 537 * infer the cause of the interrupt by checking our in-core 538 * completion queues. This avoids a costly PCI bus read in 539 * most cases. 540 */ 541 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0 542 && (ahc_check_cmdcmpltqueues(ahc) != 0)) 543 intstat = CMDCMPLT; 544 else { 545 intstat = ahc_inb(ahc, INTSTAT); 546 } 547 548 if (intstat & CMDCMPLT) { 549 ahc_outb(ahc, CLRINT, CLRCMDINT); 550 551 /* 552 * Ensure that the chip sees that we've cleared 553 * this interrupt before we walk the output fifo. 554 * Otherwise, we may, due to posted bus writes, 555 * clear the interrupt after we finish the scan, 556 * and after the sequencer has added new entries 557 * and asserted the interrupt again. 558 */ 559 ahc_flush_device_writes(ahc); 560 ahc_run_qoutfifo(ahc); 561 #ifdef AHC_TARGET_MODE 562 if ((ahc->flags & AHC_TARGETROLE) != 0) 563 ahc_run_tqinfifo(ahc, /*paused*/FALSE); 564 #endif 565 } 566 567 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) 568 /* Hot eject */ 569 return 1; 570 571 if ((intstat & INT_PEND) == 0) { 572 #if AHC_PCI_CONFIG > 0 573 if (ahc->unsolicited_ints > 500) { 574 ahc->unsolicited_ints = 0; 575 if ((ahc->chip & AHC_PCI) != 0 576 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0) 577 ahc->bus_intr(ahc); 578 } 579 ahc->unsolicited_ints++; 580 #endif 581 return 0; 582 } 583 ahc->unsolicited_ints = 0; 584 585 if (intstat & BRKADRINT) { 586 ahc_handle_brkadrint(ahc); 587 /* Fatal error, no more interrupts to handle. */ 588 return 1; 589 } 590 591 if ((intstat & (SEQINT|SCSIINT)) != 0) 592 ahc_pause_bug_fix(ahc); 593 594 if ((intstat & SEQINT) != 0) 595 ahc_handle_seqint(ahc, intstat); 596 597 if ((intstat & SCSIINT) != 0) 598 ahc_handle_scsiint(ahc, intstat); 599 600 return (1); 601 } 602 603 #endif /* IO_EXPAND */ 604 605 #endif /* _AIC7XXX_INLINE_H_ */ 606