Fix multi-slot support.
authormglocker <mglocker@openbsd.org>
Wed, 15 May 2024 20:10:27 +0000 (20:10 +0000)
committermglocker <mglocker@openbsd.org>
Wed, 15 May 2024 20:10:27 +0000 (20:10 +0000)
We also add an timeout while waiting for command completion.

sys/dev/ic/ufshci.c
sys/dev/ic/ufshcireg.h

index f0c6505..ae69dfa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ufshci.c,v 1.22 2024/05/15 18:01:10 mglocker Exp $ */
+/*     $OpenBSD: ufshci.c,v 1.23 2024/05/15 20:10:27 mglocker Exp $ */
 
 /*
  * Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
@@ -186,9 +186,6 @@ ufshci_attach(struct ufshci_softc *sc)
        DPRINTF(1, " BI=0x%04x\n", UFSHCI_REG_HCMID_BI(sc->sc_hcmid));
        DPRINTF(1, " MIC=0x%04x\n", UFSHCI_REG_HCMID_MIC(sc->sc_hcmid));
 
-       /* XXX: Using more than one slot currently causes OCS errors */
-       sc->sc_nutrs = 1;
-
        if (sc->sc_nutrs > 32) {
                printf("%s: NUTRS can't be >32 (is %d)!\n",
                    sc->sc_dev.dv_xname, sc->sc_nutrs);
@@ -513,7 +510,7 @@ ufshci_utr_cmd_nop(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_NOP_OUT;
        ucd->cmd.hdr.flags = 0;
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -603,7 +600,7 @@ ufshci_utr_cmd_lun(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
        ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -710,7 +707,7 @@ ufshci_utr_cmd_inquiry(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
        ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -815,7 +812,7 @@ ufshci_utr_cmd_capacity16(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
        ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -924,7 +921,7 @@ ufshci_utr_cmd_capacity(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
        ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -1038,7 +1035,7 @@ ufshci_utr_cmd_io(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        else
                ucd->cmd.hdr.flags = (1 << 5); /* Bit-5 = Write */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -1140,7 +1137,7 @@ ufshci_utr_cmd_sync(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
        ucd->cmd.hdr.flags = 0; /* No data transfer */
        ucd->cmd.hdr.lun = 0;
-       ucd->cmd.hdr.taskid = 0;
+       ucd->cmd.hdr.task_tag = slot;
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
        ucd->cmd.hdr.query = 0;
        ucd->cmd.hdr.response = 0;
@@ -1207,16 +1204,19 @@ ufshci_xfer_complete(struct ufshci_softc *sc)
 {
        struct ufshci_ccb *ccb;
        uint32_t reg;
-       int i;
+       int i, timeout;
 
        mtx_enter(&sc->sc_cmd_mtx);
 
        /* Wait for all commands to complete. */
-       while ((reg = ufshci_doorbell_read(sc))) {
-               DPRINTF(3, "%s: doorbell reg=0x%x\n", __func__, reg);
+       for (timeout = 5000; timeout != 0; timeout--) {
+               reg = ufshci_doorbell_read(sc);
                if (reg == 0)
                        break;
+               delay(10);
        }
+       if (timeout == 0)
+               printf("%s: timeout (reg=0x%x)\n", __func__, reg);
 
        for (i = 0; i < sc->sc_nutrs; i++) {
                ccb = &sc->sc_ccbs[i];
index 688d669..682a855 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ufshcireg.h,v 1.7 2024/05/09 08:20:22 mglocker Exp $ */
+/*     $OpenBSD: ufshcireg.h,v 1.8 2024/05/15 20:10:27 mglocker Exp $ */
 
 /*
  * Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
@@ -21,7 +21,7 @@
  */
 #define UFSHCI_UCD_PRDT_MAX_SEGS       64
 #define UFSHCI_UCD_PRDT_MAX_XFER       (UFSHCI_UCD_PRDT_MAX_SEGS * PAGE_SIZE)
-#define UFSHCI_INTR_AGGR_TIMEOUT       0x64 /* 4ms */
+#define UFSHCI_INTR_AGGR_TIMEOUT       0x08 /* 320us (1 unit = 40us) */
 #define UFSHCI_MAX_UNITS               32
 
 /*
@@ -335,7 +335,7 @@ struct upiu_hdr {
        uint8_t tc;                     /* Transaction Code */
        uint8_t flags;
        uint8_t lun;
-       uint8_t taskid;
+       uint8_t task_tag;
        uint8_t cmd_set_type;
        uint8_t query;
        uint8_t response;