since atascsi screws it up...

Index: ahci.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/ahci.c,v
retrieving revision 1.174
diff -u -p -r1.174 ahci.c
--- ahci.c      7 Apr 2011 15:30:16 -0000       1.174
+++ ahci.c      18 Apr 2011 01:39:19 -0000
@@ -373,6 +373,7 @@ struct ahci_port {
        TAILQ_HEAD(, ahci_ccb)  ap_ccb_free;
        TAILQ_HEAD(, ahci_ccb)  ap_ccb_pending;
        struct mutex            ap_ccb_mtx;
+       struct ahci_ccb         *ap_ccb_err;
 
        u_int32_t               ap_state;
 #define AP_S_NORMAL                    0
@@ -863,8 +864,7 @@ noccc:
        aaa.aaa_methods = &ahci_atascsi_methods;
        aaa.aaa_minphys = NULL;
        aaa.aaa_nports = AHCI_MAX_PORTS;
-       aaa.aaa_ncmds = sc->sc_ncmds;
-       aaa.aaa_capability = ASAA_CAP_NEEDS_RESERVED;
+       aaa.aaa_ncmds = sc->sc_ncmds - 1;
        if (!(sc->sc_flags & AHCI_F_NO_NCQ) &&
            (sc->sc_cap & AHCI_REG_CAP_SNCQ)) {
                aaa.aaa_capability |= ASAA_CAP_NCQ | ASAA_CAP_PMP_NCQ;
@@ -1292,6 +1292,10 @@ nomem:
 
        ahci_enable_interrupts(ap);
 
+       /* grab a ccb for use during error recovery */
+       ap->ap_ccb_err = &ap->ap_ccbs[sc->sc_ncmds - 1];
+       TAILQ_REMOVE(&ap->ap_ccb_free, ap->ap_ccb_err, ccb_entry);
+
 freeport:
        if (rc != 0)
                ahci_port_free(sc, port);
@@ -1313,6 +1317,9 @@ ahci_port_free(struct ahci_softc *sc, u_
                ahci_write(sc, AHCI_REG_IS, 1 << port);
        }
 
+       if (ap->ap_ccb_err)
+               ahci_put_ccb(ap->ap_ccb_err);
+
        if (ap->ap_ccbs) {
                while ((ccb = ahci_get_ccb(ap)) != NULL)
                        bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
@@ -3012,12 +3019,11 @@ ahci_get_err_ccb(struct ahci_port *ap)
         * Grab a CCB to use for error recovery.  This should never fail, as
         * we ask atascsi to reserve one for us at init time.
         */
-       err_ccb = ahci_get_ccb(ap);
-       KASSERT(err_ccb != NULL);
+       err_ccb = ap->ap_ccb_err;
        err_ccb->ccb_xa.flags = 0;
        err_ccb->ccb_done = ahci_empty_done;
 
-       return err_ccb;
+       return (err_ccb);
 }
 
 void
@@ -3037,8 +3043,10 @@ ahci_put_err_ccb(struct ahci_ccb *ccb)
                printf("ahci_port_err_ccb_restore but SACT %08x != 0?\n", sact);
        KASSERT(ahci_pread(ap, AHCI_PREG_CI) == 0);
 
+#ifdef DIAGNOSTIC
        /* Done with the CCB */
-       ahci_put_ccb(ccb);
+       KASSERT(ccb == ap->ap_ccb_err);
+#endif
 
        /* Restore outstanding command state */
        ap->ap_sactive = ap->ap_err_saved_sactive;

Reply via email to