diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2024-01-06 13:04:04 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2024-01-06 13:04:04 +0000 |
commit | db10ade1673a59c14afb9dba37aad19bb56e2acb (patch) | |
tree | 9629398e7c63657d138b9d5c700541b68466f1cd | |
parent | 8a3edbe0657f6d4edb98a6f3f982a65e6bda3e29 (diff) |
Merge read/write UFS commands in to one single function, since they are very
similar.
-rw-r--r-- | sys/dev/ic/ufshci.c | 152 |
1 files changed, 22 insertions, 130 deletions
diff --git a/sys/dev/ic/ufshci.c b/sys/dev/ic/ufshci.c index 8724a938148..64d9c2b6a91 100644 --- a/sys/dev/ic/ufshci.c +++ b/sys/dev/ic/ufshci.c @@ -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; |