From: mglocker Date: Thu, 9 May 2024 08:04:48 +0000 (+0000) Subject: Prevent that scheduling of new commands is interfering with processing X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e58b468b3b79be838e2f53b9009f1c07ee492b80;p=openbsd Prevent that scheduling of new commands is interfering with processing of completed commands with a command mutex. --- diff --git a/sys/dev/ic/ufshci.c b/sys/dev/ic/ufshci.c index 99cec7b23bb..5c38cd4c85d 100644 --- a/sys/dev/ic/ufshci.c +++ b/sys/dev/ic/ufshci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufshci.c,v 1.10 2024/05/09 08:02:59 mglocker Exp $ */ +/* $OpenBSD: ufshci.c,v 1.11 2024/05/09 08:04:48 mglocker Exp $ */ /* * Copyright (c) 2022 Marcus Glocker @@ -152,6 +152,7 @@ ufshci_attach(struct ufshci_softc *sc) { struct scsibus_attach_args saa; + mtx_init(&sc->sc_cmd_mtx, IPL_BIO); mtx_init(&sc->sc_ccb_mtx, IPL_BIO); SIMPLEQ_INIT(&sc->sc_ccb_list); scsi_iopool_init(&sc->sc_iopool, sc, ufshci_ccb_get, ufshci_ccb_put); @@ -1267,6 +1268,8 @@ ufshci_xfer_complete(struct ufshci_softc *sc) uint32_t reg; int i; + mtx_enter(&sc->sc_cmd_mtx); + /* Wait for all commands to complete. */ while ((reg = ufshci_doorbell_read(sc))) { DPRINTF("%s: doorbell reg=0x%x\n", __func__, reg); @@ -1292,6 +1295,7 @@ ufshci_xfer_complete(struct ufshci_softc *sc) DPRINTF("slot %d completed\n", i); } + mtx_leave(&sc->sc_cmd_mtx); /* * Complete the CCB, which will re-schedule new transfers if any are @@ -1400,6 +1404,8 @@ ufshci_scsi_cmd(struct scsi_xfer *xs) struct scsi_link *link = xs->sc_link; struct ufshci_softc *sc = link->bus->sb_adapter_softc; + mtx_enter(&sc->sc_cmd_mtx); + DPRINTF("%s: cmd=0x%x\n", __func__, xs->cmd.opcode); if (!cold && !sc->sc_intraggr_enabled) { @@ -1420,44 +1426,45 @@ ufshci_scsi_cmd(struct scsi_xfer *xs) case READ_12: case READ_16: ufshci_scsi_io(xs, SCSI_DATA_IN); - return; + break; case WRITE_COMMAND: case WRITE_10: case WRITE_12: case WRITE_16: ufshci_scsi_io(xs, SCSI_DATA_OUT); - return; + break; case SYNCHRONIZE_CACHE: ufshci_scsi_sync(xs); - return; + break; case INQUIRY: ufshci_scsi_inquiry(xs); - return; + break; case READ_CAPACITY_16: ufshci_scsi_capacity16(xs); - return; + break; case READ_CAPACITY: ufshci_scsi_capacity(xs); - return; + break; case TEST_UNIT_READY: case PREVENT_ALLOW: case START_STOP: xs->error = XS_NOERROR; scsi_done(xs); - return; + break; default: DPRINTF("%s: unhandled scsi command 0x%02x\n", __func__, xs->cmd.opcode); + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); break; } - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); + mtx_leave(&sc->sc_cmd_mtx); } void diff --git a/sys/dev/ic/ufshcivar.h b/sys/dev/ic/ufshcivar.h index 8441ab788a7..689c256f898 100644 --- a/sys/dev/ic/ufshcivar.h +++ b/sys/dev/ic/ufshcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ufshcivar.h,v 1.2 2024/05/09 08:02:59 mglocker Exp $ */ +/* $OpenBSD: ufshcivar.h,v 1.3 2024/05/09 08:04:48 mglocker Exp $ */ /* * Copyright (c) 2022 Marcus Glocker @@ -58,6 +58,7 @@ struct ufshci_softc { bus_dma_tag_t sc_dmat; uint8_t sc_intraggr_enabled; + struct mutex sc_cmd_mtx; uint32_t sc_ver; uint32_t sc_cap;