aic7xxx_inline.h (72811) | aic7xxx_inline.h (74094) |
---|---|
1/* 2 * Inline routines shareable across OS platforms. 3 * 4 * Copyright (c) 1994-2001 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 14 unchanged lines hidden (view full) --- 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * | 1/* 2 * Inline routines shareable across OS platforms. 3 * 4 * Copyright (c) 1994-2001 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 14 unchanged lines hidden (view full) --- 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * |
31 * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#15 $ | 31 * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#17 $ |
32 * | 32 * |
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx_inline.h 72811 2001-02-21 20:50:36Z gibbs $ | 33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx_inline.h 74094 2001-03-11 06:34:17Z gibbs $ |
34 */ 35 36#ifndef _AIC7XXX_INLINE_H_ 37#define _AIC7XXX_INLINE_H_ 38 39/************************* Sequencer Execution Control ************************/ | 34 */ 35 36#ifndef _AIC7XXX_INLINE_H_ 37#define _AIC7XXX_INLINE_H_ 38 39/************************* Sequencer Execution Control ************************/ |
40static __inline int sequencer_paused(struct ahc_softc *ahc); | 40static __inline int ahc_is_paused(struct ahc_softc *ahc); |
41static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc); | 41static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc); |
42static __inline void pause_sequencer(struct ahc_softc *ahc); 43static __inline void unpause_sequencer(struct ahc_softc *ahc); | 42static __inline void ahc_pause(struct ahc_softc *ahc); 43static __inline void ahc_unpause(struct ahc_softc *ahc); |
44 45/* 46 * Work around any chip bugs related to halting sequencer execution. 47 * On Ultra2 controllers, we must clear the CIOBUS stretch signal by 48 * reading a register that will set this signal and deassert it. 49 * Without this workaround, if the chip is paused, by an interrupt or 50 * manual pause while accessing scb ram, accesses to certain registers 51 * will hang the system (infinite pci retries). --- 5 unchanged lines hidden (view full) --- 57 (void)ahc_inb(ahc, CCSCBCTL); 58} 59 60/* 61 * Determine whether the sequencer has halted code execution. 62 * Returns non-zero status if the sequencer is stopped. 63 */ 64static __inline int | 44 45/* 46 * Work around any chip bugs related to halting sequencer execution. 47 * On Ultra2 controllers, we must clear the CIOBUS stretch signal by 48 * reading a register that will set this signal and deassert it. 49 * Without this workaround, if the chip is paused, by an interrupt or 50 * manual pause while accessing scb ram, accesses to certain registers 51 * will hang the system (infinite pci retries). --- 5 unchanged lines hidden (view full) --- 57 (void)ahc_inb(ahc, CCSCBCTL); 58} 59 60/* 61 * Determine whether the sequencer has halted code execution. 62 * Returns non-zero status if the sequencer is stopped. 63 */ 64static __inline int |
65sequencer_paused(struct ahc_softc *ahc) | 65ahc_is_paused(struct ahc_softc *ahc) |
66{ 67 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0); 68} 69 70/* 71 * Request that the sequencer stop and wait, indefinitely, for it 72 * to stop. The sequencer will only acknowledge that it is paused 73 * once it has reached an instruction boundary and PAUSEDIS is 74 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS 75 * for critical sections. 76 */ 77static __inline void | 66{ 67 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0); 68} 69 70/* 71 * Request that the sequencer stop and wait, indefinitely, for it 72 * to stop. The sequencer will only acknowledge that it is paused 73 * once it has reached an instruction boundary and PAUSEDIS is 74 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS 75 * for critical sections. 76 */ 77static __inline void |
78pause_sequencer(struct ahc_softc *ahc) | 78ahc_pause(struct ahc_softc *ahc) |
79{ 80 ahc_outb(ahc, HCNTRL, ahc->pause); 81 82 /* 83 * Since the sequencer can disable pausing in a critical section, we 84 * must loop until it actually stops. 85 */ | 79{ 80 ahc_outb(ahc, HCNTRL, ahc->pause); 81 82 /* 83 * Since the sequencer can disable pausing in a critical section, we 84 * must loop until it actually stops. 85 */ |
86 while (sequencer_paused(ahc) == 0) | 86 while (ahc_is_paused(ahc) == 0) |
87 ; 88 89 ahc_pause_bug_fix(ahc); 90} 91 92/* 93 * Allow the sequencer to continue program execution. 94 * We check here to ensure that no additional interrupt 95 * sources that would cause the sequencer to halt have been 96 * asserted. If, for example, a SCSI bus reset is detected 97 * while we are fielding a different, pausing, interrupt type, 98 * we don't want to release the sequencer before going back 99 * into our interrupt handler and dealing with this new 100 * condition. 101 */ 102static __inline void | 87 ; 88 89 ahc_pause_bug_fix(ahc); 90} 91 92/* 93 * Allow the sequencer to continue program execution. 94 * We check here to ensure that no additional interrupt 95 * sources that would cause the sequencer to halt have been 96 * asserted. If, for example, a SCSI bus reset is detected 97 * while we are fielding a different, pausing, interrupt type, 98 * we don't want to release the sequencer before going back 99 * into our interrupt handler and dealing with this new 100 * condition. 101 */ 102static __inline void |
103unpause_sequencer(struct ahc_softc *ahc) | 103ahc_unpause(struct ahc_softc *ahc) |
104{ 105 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0) 106 ahc_outb(ahc, HCNTRL, ahc->unpause); 107} 108 109/*********************** Untagged Transaction Routines ************************/ 110static __inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc); 111static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc); --- 228 unchanged lines hidden (view full) --- 340 /* 341 * Keep a history of SCBs we've downloaded in the qinfifo. 342 */ 343 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag; 344 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 345 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext); 346 } else { 347 if ((ahc->features & AHC_AUTOPAUSE) == 0) | 104{ 105 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0) 106 ahc_outb(ahc, HCNTRL, ahc->unpause); 107} 108 109/*********************** Untagged Transaction Routines ************************/ 110static __inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc); 111static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc); --- 228 unchanged lines hidden (view full) --- 340 /* 341 * Keep a history of SCBs we've downloaded in the qinfifo. 342 */ 343 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag; 344 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 345 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext); 346 } else { 347 if ((ahc->features & AHC_AUTOPAUSE) == 0) |
348 pause_sequencer(ahc); | 348 ahc_pause(ahc); |
349 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext); 350 if ((ahc->features & AHC_AUTOPAUSE) == 0) | 349 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext); 350 if ((ahc->features & AHC_AUTOPAUSE) == 0) |
351 unpause_sequencer(ahc); | 351 ahc_unpause(ahc); |
352 } 353} 354 355static __inline struct scsi_sense_data * 356ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb) 357{ 358 int offset; 359 --- 47 unchanged lines hidden (view full) --- 407 u_int queuestat; 408 409 /* 410 * Instead of directly reading the interrupt status register, 411 * infer the cause of the interrupt by checking our in-core 412 * completion queues. This avoids a costly PCI bus read in 413 * most cases. 414 */ | 352 } 353} 354 355static __inline struct scsi_sense_data * 356ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb) 357{ 358 int offset; 359 --- 47 unchanged lines hidden (view full) --- 407 u_int queuestat; 408 409 /* 410 * Instead of directly reading the interrupt status register, 411 * infer the cause of the interrupt by checking our in-core 412 * completion queues. This avoids a costly PCI bus read in 413 * most cases. 414 */ |
415 intstat = 0; 416 if ((queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0) | 415 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0 416 && (queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0) |
417 intstat = CMDCMPLT; | 417 intstat = CMDCMPLT; |
418 419 if ((intstat & INT_PEND) == 0 420 || (ahc->flags & AHC_ALL_INTERRUPTS) != 0) { 421 | 418 else { |
422 intstat = ahc_inb(ahc, INTSTAT); | 419 intstat = ahc_inb(ahc, INTSTAT); |
420 /* 421 * We can't generate queuestat once above 422 * or we are exposed to a race when our 423 * interrupt is shared with another device. 424 * if instat showed a command complete interrupt, 425 * but our first generation of queue stat 426 * "just missed" the delivery of this transaction, 427 * we would clear the command complete interrupt 428 * below without ever servicing the completed 429 * command. 430 */ 431 queuestat = ahc_check_cmdcmpltqueues(ahc); |
|
423#if AHC_PCI_CONFIG > 0 424 if (ahc->unsolicited_ints > 500 425 && (ahc->chip & AHC_PCI) != 0 426 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0) 427 ahc_pci_intr(ahc); 428#endif 429 } 430 --- 48 unchanged lines hidden --- | 432#if AHC_PCI_CONFIG > 0 433 if (ahc->unsolicited_ints > 500 434 && (ahc->chip & AHC_PCI) != 0 435 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0) 436 ahc_pci_intr(ahc); 437#endif 438 } 439 --- 48 unchanged lines hidden --- |