Merge read/write UFS commands in to one single function, since they are very
authormglocker <mglocker@openbsd.org>
Sat, 6 Jan 2024 13:04:03 +0000 (13:04 +0000)
committermglocker <mglocker@openbsd.org>
Sat, 6 Jan 2024 13:04:03 +0000 (13:04 +0000)
similar.

sys/dev/ic/ufshci.c

index 8724a93..64d9c2b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ufshci.c,v 1.6 2024/01/04 21:35:56 mglocker Exp $ */
+/*     $OpenBSD: ufshci.c,v 1.7 2024/01/06 13:04:03 mglocker Exp $ */
 
 /*
  * Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
@@ -75,12 +75,8 @@ int                   ufshci_utr_cmd_capacity16(struct ufshci_softc *,
                             struct ufshci_ccb *, int, int);
 int                     ufshci_utr_cmd_capacity(struct ufshci_softc *,
                             struct ufshci_ccb *, int, int);
-int                     ufshci_utr_cmd_read(struct ufshci_softc *,
-                            struct ufshci_ccb *, int, int,
-                            struct scsi_generic *);
-int                     ufshci_utr_cmd_write(struct ufshci_softc *,
-                            struct ufshci_ccb *, int, int,
-                            struct scsi_generic *);
+int                     ufshci_utr_cmd_io(struct ufshci_softc *,
+                            struct ufshci_ccb *, struct scsi_xfer *, int);
 int                     ufshci_utr_cmd_sync(struct ufshci_softc *,
                             struct ufshci_ccb *, int, uint32_t, uint16_t);
 int                     ufshci_xfer_complete(struct ufshci_softc *);
@@ -1061,8 +1057,8 @@ ufshci_utr_cmd_capacity(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
 }
 
 int
-ufshci_utr_cmd_read(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
-    int rsp_size, int flags, struct scsi_generic *scsi_cmd)
+ufshci_utr_cmd_io(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
+    struct scsi_xfer *xs, int dir)
 {
        int slot, off, len, i;
        uint64_t dva;
@@ -1080,115 +1076,10 @@ ufshci_utr_cmd_read(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        utrd->dw0 = UFSHCI_UTRD_DW0_CT_UFS;
 
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2b) */
-       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;
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2d) */
-       utrd->dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2e) */
-       ucd = UFSHCI_DMA_KVA(sc->sc_dmamem_ucd) + (sizeof(*ucd) * slot);
-       memset(ucd, 0, sizeof(*ucd));
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2f) */
-       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 = ufshci_get_taskid(sc);
-       ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
-       ucd->cmd.hdr.query = 0;
-       ucd->cmd.hdr.response = 0;
-       ucd->cmd.hdr.status = 0;
-       ucd->cmd.hdr.ehs_len = 0;
-       ucd->cmd.hdr.device_info = 0;
-       ucd->cmd.hdr.ds_len = 0;
-
-       ucd->cmd.expected_xfer_len = htobe32(rsp_size);
-
-       memcpy(ucd->cmd.cdb, scsi_cmd, sizeof(ucd->cmd.cdb));
-       //ucd->cmd.cdb[1] = (1 << 3); /* FUA: Force Unit Access */
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2g) */
-       /* Already done with above memset */
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 3) */
-       dva = UFSHCI_DMA_DVA(sc->sc_dmamem_ucd) + (sizeof(*ucd) * slot);
-       DPRINTF("%s: ucd dva=%llu\n", __func__, dva);
-       utrd->dw4 = (uint32_t)dva;
-       utrd->dw5 = (uint32_t)(dva >> 32);
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 4) */
-       off = sizeof(struct upiu_command) / 4; /* DWORD offset */
-       utrd->dw6 = UFSHCI_UTRD_DW6_RUO(off);
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 5) */
-       len = sizeof(struct upiu_response) / 4; /* DWORD length */
-       utrd->dw6 |= UFSHCI_UTRD_DW6_RUL(len);
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 6) */
-       off = (sizeof(struct upiu_command) + sizeof(struct upiu_response)) / 4;
-       utrd->dw7 = UFSHCI_UTRD_DW7_PRDTO(off);
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 7) */
-       utrd->dw7 |= UFSHCI_UTRD_DW7_PRDTL(dmap->dm_nsegs);
-
-       /* Build PRDT data segment. */
-       for (i = 0; i < dmap->dm_nsegs; i++) {
-               dva = dmap->dm_segs[i].ds_addr;
-               ucd->prdt[i].dw0 = (uint32_t)dva;
-               ucd->prdt[i].dw1 = (uint32_t)(dva >> 32);
-               ucd->prdt[i].dw2 = 0;
-               ucd->prdt[i].dw3 = dmap->dm_segs[i].ds_len - 1;
-       }
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 9) */
-       if (UFSHCI_READ_4(sc, UFSHCI_REG_UTRLRSR) != 1) {
-               printf("%s: %s: UTRLRSR not set\n",
-                   sc->sc_dev.dv_xname, __func__);
-               return -1;
-       }
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 10) */
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 11) */
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 12) */
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 13) */
-       if (!ISSET(flags, SCSI_POLL)) {
-               UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
-                   UFSHCI_REG_UTRIACR_IAEN |
-                   UFSHCI_REG_UTRIACR_IAPWEN |
-                   UFSHCI_REG_UTRIACR_IACTH(UFSHCI_INTR_AGGR_COUNT) |
-                   UFSHCI_REG_UTRIACR_IATOVAL(UFSHCI_INTR_AGGR_TIMEOUT));
-       }
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 14) */
-       ufshci_doorbell_set(sc, slot);
-
-       return slot;
-}
-
-int
-ufshci_utr_cmd_write(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
-    int rsp_size, int flags, struct scsi_generic *scsi_cmd)
-{
-       int slot, off, len, i;
-       uint64_t dva;
-       struct ufshci_utrd *utrd;
-       struct ufshci_ucd *ucd;
-       bus_dmamap_t dmap = ccb->ccb_dmamap;
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 1) */
-       slot = ufshci_doorbell_get_free(sc);
-       utrd = UFSHCI_DMA_KVA(sc->sc_dmamem_utrd) + (sizeof(*utrd) * slot);
-       memset(utrd, 0, sizeof(*utrd));
-       DPRINTF("%s: slot=%d\n", __func__, slot);
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2a) */
-       utrd->dw0 = UFSHCI_UTRD_DW0_CT_UFS;
-
-       /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2b) */
-       utrd->dw0 |= UFSHCI_UTRD_DW0_DD_I2T;
+       if (dir == SCSI_DATA_IN)
+               utrd->dw0 |= UFSHCI_UTRD_DW0_DD_T2I;
+       else
+               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;
@@ -1202,7 +1093,10 @@ ufshci_utr_cmd_write(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
 
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2f) */
        ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
-       ucd->cmd.hdr.flags = (1 << 5); /* Bit-5 = Write, Bit-6 = Read */
+       if (dir == SCSI_DATA_IN)
+               ucd->cmd.hdr.flags = (1 << 6); /* Bit-6 = Read */
+       else
+               ucd->cmd.hdr.flags = (1 << 5); /* Bit-5 = Write */
        ucd->cmd.hdr.lun = 0;
        ucd->cmd.hdr.taskid = ufshci_get_taskid(sc);
        ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */
@@ -1213,10 +1107,11 @@ ufshci_utr_cmd_write(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        ucd->cmd.hdr.device_info = 0;
        ucd->cmd.hdr.ds_len = 0;
 
-       ucd->cmd.expected_xfer_len = htobe32(rsp_size);
+       ucd->cmd.expected_xfer_len = htobe32(xs->datalen);
 
-       memcpy(ucd->cmd.cdb, scsi_cmd, sizeof(ucd->cmd.cdb));
-       ucd->cmd.cdb[1] = (1 << 3); /* FUA: Force Unit Access */
+       memcpy(ucd->cmd.cdb, &xs->cmd, sizeof(ucd->cmd.cdb));
+       if (dir == SCSI_DATA_OUT)
+               ucd->cmd.cdb[1] = (1 << 3); /* FUA: Force Unit Access */
 
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 2g) */
        /* Already done with above memset */
@@ -1262,7 +1157,7 @@ ufshci_utr_cmd_write(struct ufshci_softc *sc, struct ufshci_ccb *ccb,
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 11) */
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 12) */
        /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 13) */
-       if (!ISSET(flags, SCSI_POLL)) {
+       if (!ISSET(xs->flags, SCSI_POLL)) {
                UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRIACR,
                    UFSHCI_REG_UTRIACR_IAEN |
                    UFSHCI_REG_UTRIACR_IAPWEN |
@@ -1822,13 +1717,10 @@ ufshci_scsi_io(struct scsi_xfer *xs, int dir)
        ccb->ccb_cookie = xs;
        ccb->ccb_done = ufshci_scsi_io_done;
 
-       if (dir == SCSI_DATA_IN) {
-               ccb->ccb_slot = ufshci_utr_cmd_read(sc, ccb, xs->datalen,
-                   xs->flags, &xs->cmd);
-       } else {
-               ccb->ccb_slot = ufshci_utr_cmd_write(sc, ccb, xs->datalen,
-                   xs->flags, &xs->cmd);
-       }
+       if (dir == SCSI_DATA_IN)
+               ccb->ccb_slot = ufshci_utr_cmd_io(sc, ccb, xs, SCSI_DATA_IN);
+       else
+               ccb->ccb_slot = ufshci_utr_cmd_io(sc, ccb, xs, SCSI_DATA_OUT);
 
        if (ccb->ccb_slot == -1)
                goto error2;