Index: sys/dev/ichiic/ig4_iic.c =================================================================== --- sys/dev/ichiic/ig4_iic.c +++ sys/dev/ichiic/ig4_iic.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +116,7 @@ error = 0; break; } - mtx_sleep(sc, &sc->mutex, 0, "i2cslv", 1); + mtx_sleep(sc, &sc->ig4_io_lock, 0, "i2cslv", 1); } return (error); } @@ -179,7 +180,7 @@ * work, otherwise poll with the lock held. */ if (status & IG4_STATUS_RX_NOTEMPTY) { - mtx_sleep(sc, &sc->mutex, PZERO, "i2cwait", + mtx_sleep(sc, &sc->ig4_io_lock, PZERO, "i2cwait", (hz + 99) / 100); /* sleep up to 10ms */ count_us += 10000; } else { @@ -551,12 +552,12 @@ */ reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | IG4_INTR_RX_FULL); - mtx_lock(&sc->mutex); + mtx_lock(&sc->ig4_io_lock); if (set_controller(sc, 0)) device_printf(sc->dev, "controller error during attach-1\n"); if (set_controller(sc, IG4_I2C_ENABLE)) device_printf(sc->dev, "controller error during attach-2\n"); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, ig4iic_intr, sc, &sc->intr_handle); if (error) { @@ -615,7 +616,8 @@ if (sc->intr_handle) bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); sc->smb = NULL; sc->intr_handle = NULL; @@ -623,7 +625,8 @@ reg_read(sc, IG4_REG_CLR_INTR); set_controller(sc, 0); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (0); } @@ -633,7 +636,8 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); switch (index) { case SMB_REQUEST_BUS: @@ -647,8 +651,8 @@ break; } - mtx_unlock(&sc->mutex); - + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -663,7 +667,8 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); switch (how) { case SMB_QREAD: @@ -676,8 +681,9 @@ error = SMB_ENOTSUPP; break; } - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -695,7 +701,8 @@ uint32_t cmd; int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); cmd = byte; @@ -706,7 +713,8 @@ error = SMB_ETIMEOUT; } - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -721,7 +729,8 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD); @@ -733,7 +742,8 @@ error = SMB_ETIMEOUT; } - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -746,13 +756,15 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, &byte, 1, NULL, 0, NULL); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -766,7 +778,8 @@ char buf[2]; int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); buf[0] = word & 0xFF; @@ -774,7 +787,8 @@ error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, buf, 2, NULL, 0, NULL); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -787,13 +801,15 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, NULL, 0, byte, 1, NULL); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -807,7 +823,8 @@ char buf[2]; int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, @@ -815,7 +832,8 @@ *word = (u_char)buf[0] | ((u_char)buf[1] << 8); } - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -831,7 +849,8 @@ char wbuf[2]; int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); wbuf[0] = sdata & 0xFF; @@ -841,7 +860,8 @@ *rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8); } - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -852,13 +872,15 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); error = smb_transaction(sc, cmd, 0, buf, wcount, NULL, 0, NULL); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -870,14 +892,16 @@ int rcount = *countp_char; int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, 0); error = smb_transaction(sc, cmd, 0, NULL, 0, buf, rcount, &rcount); *countp_char = rcount; - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -889,13 +913,15 @@ ig4iic_softc_t *sc = device_get_softc(dev); int error; - mtx_lock(&sc->mutex); + sx_xlock(&sc->ig4_call_lock); + mtx_lock(&sc->ig4_io_lock); set_slave_addr(sc, slave, op); error = smb_transaction(sc, cmd, op, wbuf, wcount, rbuf, rcount, actualp); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); + sx_xunlock(&sc->ig4_call_lock); return (error); } @@ -908,7 +934,7 @@ ig4iic_softc_t *sc = cookie; uint32_t status; - mtx_lock(&sc->mutex); + mtx_lock(&sc->ig4_io_lock); /* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ status = reg_read(sc, IG4_REG_I2C_STA); while (status & IG4_STATUS_RX_NOTEMPTY) { @@ -919,7 +945,7 @@ } reg_read(sc, IG4_REG_CLR_INTR); wakeup(sc); - mtx_unlock(&sc->mutex); + mtx_unlock(&sc->ig4_io_lock); } #define REGDUMP(sc, reg) \ Index: sys/dev/ichiic/ig4_pci.c =================================================================== --- sys/dev/ichiic/ig4_pci.c +++ sys/dev/ichiic/ig4_pci.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,8 @@ bzero(sc, sizeof(*sc)); - mtx_init(&sc->mutex, device_get_nameunit(dev), "ig4iic", MTX_DEF); + mtx_init(&sc->ig4_io_lock, "IG4 I/O lock", NULL, MTX_DEF); + sx_init(&sc->ig4_call_lock, "IG4 call lock"); sc->dev = dev; sc->regs_rid = PCIR_BAR(0); @@ -150,7 +152,10 @@ sc->regs_rid, sc->regs_res); sc->regs_res = NULL; } - mtx_destroy(&sc->mutex); + if (mtx_initialized(&sc->ig4_io_lock)) { + mtx_destroy(&sc->ig4_io_lock); + sx_destroy(&sc->ig4_call_lock); + } return (0); } @@ -179,9 +184,9 @@ }; static driver_t ig4iic_pci_driver = { - "ig4iic", - ig4iic_pci_methods, - sizeof(struct ig4iic_softc) + "ig4iic", + ig4iic_pci_methods, + sizeof(struct ig4iic_softc) }; static devclass_t ig4iic_pci_devclass; Index: sys/dev/ichiic/ig4_var.h =================================================================== --- sys/dev/ichiic/ig4_var.h +++ sys/dev/ichiic/ig4_var.h @@ -70,7 +70,8 @@ int slave_valid : 1; int read_started : 1; int write_started : 1; - struct mtx mutex; + struct mtx ig4_io_lock; + struct sx ig4_call_lock; }; typedef struct ig4iic_softc ig4iic_softc_t;