-/* $OpenBSD: ufshci.c,v 1.25 2024/05/19 20:24:02 mglocker Exp $ */
+/* $OpenBSD: ufshci.c,v 1.26 2024/05/20 12:42:45 mglocker Exp $ */
/*
* Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
}
DPRINTF(1, "Intr. aggr. counter threshold:\nIACTH=%d\n", sc->sc_iacth);
+ /*
+ * XXX:
+ * At the moment normal interrupts work better for us than interrupt
+ * aggregation, because:
+ *
+ * 1. With interrupt aggregation enabled, the I/O performance
+ * isn't better, but even slightly worse depending on the
+ * UFS controller and architecture.
+ * 2. With interrupt aggregation enabled we currently see
+ * intermittent SCSI command stalling. Probably there is a
+ * race condition where new SCSI commands are getting
+ * scheduled, while we miss to reset the interrupt aggregation
+ * counter/timer, which leaves us with no more interrupts
+ * triggered. This needs to be fixed, but I couldn't figure
+ * out yet how.
+ */
+#if 0
+ sc->sc_flags |= UFSHCI_FLAGS_AGGR_INTR; /* Enable intr. aggregation */
+#endif
ufshci_init(sc);
if (ufshci_ccb_alloc(sc, sc->sc_nutrs) != 0) {
*/
/* 7.1.1 Host Controller Initialization: 11) */
- UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
- UFSHCI_REG_UTRIACR_IAEN |
- UFSHCI_REG_UTRIACR_IAPWEN |
- UFSHCI_REG_UTRIACR_CTR |
- UFSHCI_REG_UTRIACR_IACTH(sc->sc_iacth) |
- UFSHCI_REG_UTRIACR_IATOVAL(UFSHCI_INTR_AGGR_TIMEOUT));
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR) {
+ UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
+ UFSHCI_REG_UTRIACR_IAEN |
+ UFSHCI_REG_UTRIACR_IAPWEN |
+ UFSHCI_REG_UTRIACR_CTR |
+ UFSHCI_REG_UTRIACR_IACTH(sc->sc_iacth) |
+ UFSHCI_REG_UTRIACR_IATOVAL(UFSHCI_INTR_AGGR_TIMEOUT));
+ } else {
+ UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR, 0);
+ }
/*
* 7.1.1 Host Controller Initialization: 12)
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_NO;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_T2I;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_T2I;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_T2I;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_T2I;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_I2T;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
utrd->dw0 |= UFSHCI_UTRD_DW0_DD_I2T;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2c) */
- utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR)
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_REG;
+ else
+ utrd->dw0 |= UFSHCI_UTRD_DW0_I_INT;
/* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
}
/* 7.2.3: Reset Interrupt Aggregation Counter and Timer 4) */
- UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
- UFSHCI_REG_UTRIACR_IAEN | UFSHCI_REG_UTRIACR_CTR);
+ if (sc->sc_flags & UFSHCI_FLAGS_AGGR_INTR) {
+ UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
+ UFSHCI_REG_UTRIACR_IAEN | UFSHCI_REG_UTRIACR_CTR);
+ }
mtx_leave(&sc->sc_cmd_mtx);