From 38304948bc8dd0374538547578a2ff359db2835f Mon Sep 17 00:00:00 2001 From: mglocker Date: Wed, 15 May 2024 20:10:27 +0000 Subject: [PATCH] Fix multi-slot support. We also add an timeout while waiting for command completion. --- sys/dev/ic/ufshci.c | 28 ++++++++++++++-------------- sys/dev/ic/ufshcireg.h | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/sys/dev/ic/ufshci.c b/sys/dev/ic/ufshci.c index f0c6505b811..ae69dfa55f8 100644 --- a/sys/dev/ic/ufshci.c +++ b/sys/dev/ic/ufshci.c @@ -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 @@ -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]; diff --git a/sys/dev/ic/ufshcireg.h b/sys/dev/ic/ufshcireg.h index 688d6696223..682a855c578 100644 --- a/sys/dev/ic/ufshcireg.h +++ b/sys/dev/ic/ufshcireg.h @@ -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 @@ -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; -- 2.20.1