Correct a typo in a comment.
authorPeter Avalos <pavalos@dragonflybsd.org>
Wed, 4 Jul 2007 23:52:04 +0000 (23:52 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Wed, 4 Jul 2007 23:52:04 +0000 (23:52 +0000)
Add a comment in ahd_clear_critical_sections() about
our need to leave ENBUSFREE set in SIMODE1 while single
stepping.

Re-arrange some delay loops so that we always perform
a read after any register write and before the delay.
This should make the delay loop more accurate.

When completing message processing for a packetized
commention, return the controller to a state where
invalid non-packetized phases will still cause protocol
violations.  These are the same operations as those
performed in the clear_target_state routine in the
firmware.

Now that we have a chip with working ABORTPENDING
support (the 7901B), comment out the automatic use
of this feature until we can adequately test it.
The previous checkin updated the bug mask for the
7901B so this code was exercised.

When resetting the bus, perform an ahd_flush_device_writes()
call so that our reset assertion delay is acurately
timed from when the reset bit is written to the controller.

Obtained-from: FreeBSD

sys/dev/disk/aic7xxx/aic79xx.c

index b42069a..3b3a07a 100644 (file)
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#199 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#200 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.c,v 1.21 2003/06/23 22:06:34 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.c,v 1.14 2007/07/03 21:13:35 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.c,v 1.22 2003/06/28 04:42:11 gibbs Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.c,v 1.15 2007/07/04 23:52:04 pavalos Exp $
  */
 
 #include "aic79xx_osm.h"
@@ -584,7 +584,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
                        /*
                         * Somehow need to know if this
                         * is from a selection or reselection.
-                        * From that, we can termine target
+                        * From that, we can determine target
                         * ID so we at least have an I_T nexus.
                         */
                } else {
@@ -2193,8 +2193,14 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
                        ahd_outb(ahd, LQOMODE0, 0);
                        ahd_outb(ahd, LQOMODE1, 0);
                        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
-                       simode1 = ahd_inb(ahd, SIMODE1);
-                       ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
+                       simode1 = ahd_inb(ahd, SIMODE1);
+                       /*
+                        * We don't clear ENBUSFREE.  Unfortunately
+                        * we cannot re-enable busfree detection within
+                        * the current connection, so we must leave it
+                        * on while single stepping.
+                        */
+                       ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
                        ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
                        stepping = TRUE;
                }
@@ -2202,9 +2208,8 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
                ahd_outb(ahd, CLRINT, CLRSCSIINT);
                ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
                ahd_outb(ahd, HCNTRL, ahd->unpause);
-               do {
+               while (!ahd_is_paused(ahd))
                        ahd_delay(200);
-               } while (!ahd_is_paused(ahd));
                ahd_update_modes(ahd);
        }
        if (stepping) {
@@ -3730,8 +3735,13 @@ reswitch:
                if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
                        kprintf("%s: Returning to Idle Loop\n",
                               ahd_name(ahd));
-                       ahd_outb(ahd, LASTPHASE, P_BUSFREE);
                        ahd_clear_msg_state(ahd);
+
+                       /*
+                        * Perform the equivalent of a clear_target_state.
+                        */
+                       ahd_outb(ahd, LASTPHASE, P_BUSFREE);
+                       ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
                        ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
                } else {
                        ahd_clear_msg_state(ahd);
@@ -4555,9 +4565,8 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
         */
        ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
        wait = 1000;
-       do {
+       while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
                ahd_delay(100);
-       } while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE));
        if (wait == 0) {
                ahd_print_path(ahd, scb);
                kprintf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
@@ -6201,6 +6210,7 @@ ahd_chip_init(struct ahd_softc *ahd)
        ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
        ahd_outb(ahd, CLRINT, CLRSCSIINT);
 
+#if NEEDS_MORE_TESTING
        /*
         * Always enable abort on incoming L_Qs if this feature is
         * supported.  We use this to catch invalid SCB references.
@@ -6208,6 +6218,7 @@ ahd_chip_init(struct ahd_softc *ahd)
        if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
                ahd_outb(ahd, LQCTL1, ABORTPENDING);
        else
+#endif
                ahd_outb(ahd, LQCTL1, 0);
 
        /* All of our queues are empty */
@@ -7348,9 +7359,12 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
        ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
        scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
        ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
+       ahd_flush_device_writes(ahd);
        ahd_delay(AHD_BUSRESET_DELAY);
        /* Turn off the bus reset */
        ahd_outb(ahd, SCSISEQ0, scsiseq);
+       ahd_flush_device_writes(ahd);
+       ahd_delay(AHD_BUSRESET_DELAY);
        if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
                /*
                 * 2A Razor #474
@@ -7358,7 +7372,6 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
                 * SCSI bus resets that we initiate, so
                 * we must reset the chip.
                 */
-               ahd_delay(AHD_BUSRESET_DELAY);
                ahd_reset(ahd, /*reinit*/TRUE);
                ahd_intr_enable(ahd, /*enable*/TRUE);
                AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);