diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-07 14:56:50 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:37 +0200 |
commit | c37f9fba70085fedc8eede7559489d2321393005 (patch) | |
tree | 042455ebf1fa89a277a825f72e1ed805d0b4d296 /freebsd/sys/dev/mmc/mmcsd.c | |
parent | Update to FreeBSD head 2017-06-01 (diff) | |
download | rtems-libbsd-c37f9fba70085fedc8eede7559489d2321393005.tar.bz2 |
Update to FreeBSD head 2017-08-01
Git mirror commit f5002f5e5f78cae9f0269d812dc0aedb0339312c.
Update #3472.
Diffstat (limited to '')
-rw-r--r-- | freebsd/sys/dev/mmc/mmcsd.c | 298 |
1 files changed, 208 insertions, 90 deletions
diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c index 5066e250..195feae2 100644 --- a/freebsd/sys/dev/mmc/mmcsd.c +++ b/freebsd/sys/dev/mmc/mmcsd.c @@ -108,7 +108,8 @@ __FBSDID("$FreeBSD$"); struct mmcsd_softc; struct mmcsd_part { - struct mtx part_mtx; + struct mtx disk_mtx; + struct mtx ioctl_mtx; struct mmcsd_softc *sc; #ifndef __rtems__ struct disk *disk; @@ -120,6 +121,7 @@ struct mmcsd_part { u_int type; int running; int suspend; + int ioctl; bool ro; char name[MMCSD_PART_NAMELEN]; }; @@ -129,6 +131,9 @@ struct mmcsd_softc { device_t mmcbr; struct mmcsd_part *part[MMC_PART_MAX]; enum mmc_card_mode mode; + u_int max_data; /* Maximum data size [blocks] */ + u_int erase_sector; /* Device native erase sector size [blocks] */ + uint8_t high_cap; /* High Capacity device (block addressed) */ uint8_t part_curr; /* Partition currently switched to */ uint8_t ext_csd[MMC_EXTCSD_SIZE]; uint16_t rca; @@ -199,15 +204,25 @@ static int mmcsd_slicer(device_t dev, const char *provider, static int mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part); -#define MMCSD_PART_LOCK(_part) mtx_lock(&(_part)->part_mtx) -#define MMCSD_PART_UNLOCK(_part) mtx_unlock(&(_part)->part_mtx) -#define MMCSD_PART_LOCK_INIT(_part) \ - mtx_init(&(_part)->part_mtx, (_part)->name, "mmcsd part", MTX_DEF) -#define MMCSD_PART_LOCK_DESTROY(_part) mtx_destroy(&(_part)->part_mtx); -#define MMCSD_PART_ASSERT_LOCKED(_part) \ - mtx_assert(&(_part)->part_mtx, MA_OWNED); -#define MMCSD_PART_ASSERT_UNLOCKED(_part) \ - mtx_assert(&(_part)->part_mtx, MA_NOTOWNED); +#define MMCSD_DISK_LOCK(_part) mtx_lock(&(_part)->disk_mtx) +#define MMCSD_DISK_UNLOCK(_part) mtx_unlock(&(_part)->disk_mtx) +#define MMCSD_DISK_LOCK_INIT(_part) \ + mtx_init(&(_part)->disk_mtx, (_part)->name, "mmcsd disk", MTX_DEF) +#define MMCSD_DISK_LOCK_DESTROY(_part) mtx_destroy(&(_part)->disk_mtx); +#define MMCSD_DISK_ASSERT_LOCKED(_part) \ + mtx_assert(&(_part)->disk_mtx, MA_OWNED); +#define MMCSD_DISK_ASSERT_UNLOCKED(_part) \ + mtx_assert(&(_part)->disk_mtx, MA_NOTOWNED); + +#define MMCSD_IOCTL_LOCK(_part) mtx_lock(&(_part)->ioctl_mtx) +#define MMCSD_IOCTL_UNLOCK(_part) mtx_unlock(&(_part)->ioctl_mtx) +#define MMCSD_IOCTL_LOCK_INIT(_part) \ + mtx_init(&(_part)->ioctl_mtx, (_part)->name, "mmcsd IOCTL", MTX_DEF) +#define MMCSD_IOCTL_LOCK_DESTROY(_part) mtx_destroy(&(_part)->ioctl_mtx); +#define MMCSD_IOCTL_ASSERT_LOCKED(_part) \ + mtx_assert(&(_part)->ioctl_mtx, MA_OWNED); +#define MMCSD_IOCLT_ASSERT_UNLOCKED(_part) \ + mtx_assert(&(_part)->ioctl_mtx, MA_NOTOWNED); static int mmcsd_probe(device_t dev) @@ -277,7 +292,7 @@ rtems_bsd_mmcsd_disk_read_write(struct mmcsd_part *part, rtems_blkdev_request *b data_flags = MMC_DATA_READ; } - MMCSD_PART_LOCK(part); + MMCSD_DISK_LOCK(part); for (i = 0; i < buffer_count; ++i) { rtems_blkdev_sg_buffer *sg = &blkreq->bufs [i]; @@ -354,7 +369,7 @@ rtems_bsd_mmcsd_disk_read_write(struct mmcsd_part *part, rtems_blkdev_request *b error: - MMCSD_PART_UNLOCK(part); + MMCSD_DISK_UNLOCK(part); rtems_blkdev_request_done(blkreq, status_code); @@ -439,6 +454,18 @@ mmcsd_attach(device_t dev) sc->dev = dev; sc->mmcbr = mmcbr = device_get_parent(dev); sc->mode = mmcbr_get_mode(mmcbr); + /* + * Note that in principle with an SDHCI-like re-tuning implementation, + * the maximum data size can change at runtime due to a device removal/ + * insertion that results in switches to/from a transfer mode involving + * re-tuning, iff there are multiple devices on a given bus. Until now + * mmc(4) lacks support for rescanning already attached buses, however, + * and sdhci(4) to date has no support for shared buses in the first + * place either. + */ + sc->max_data = mmc_get_max_data(dev); + sc->erase_sector = mmc_get_erase_sector(dev); + sc->high_cap = mmc_get_high_cap(dev); sc->rca = mmc_get_rca(dev); /* Only MMC >= 4.x devices support EXT_CSD. */ @@ -492,7 +519,7 @@ mmcsd_attach(device_t dev) (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) + (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) + (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24)) * - (mmc_get_high_cap(dev) ? MMC_SECTOR_SIZE : 1); + (sc->high_cap != 0 ? MMC_SECTOR_SIZE : 1); } else if (bootverbose) device_printf(dev, "enhanced user data area spans entire device\n"); @@ -505,7 +532,7 @@ mmcsd_attach(device_t dev) ro = mmc_get_read_only(dev); mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_DEFAULT, "mmcsd", device_get_unit(dev), mmc_get_media_size(dev) * sector_size, - mmc_get_erase_sector(dev) * sector_size, ro); + sc->erase_sector * sector_size, ro); if (mmc_get_spec_vers(dev) < 3) return (0); @@ -644,7 +671,16 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt, part->ro = ro; snprintf(part->name, sizeof(part->name), name, device_get_unit(dev)); - /* For the RPMB partition, allow IOCTL access only. */ + MMCSD_IOCTL_LOCK_INIT(part); + + /* + * For the RPMB partition, allow IOCTL access only. + * NB: If ever attaching RPMB partitions to disk(9), the re-tuning + * implementation and especially its pausing need to be revisited, + * because then re-tuning requests may be issued by the IOCTL half + * of this driver while re-tuning is already paused by the disk(9) + * one and vice versa. + */ if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) { make_dev_args_init(&args); args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; @@ -659,7 +695,7 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt, return; } } else { - MMCSD_PART_LOCK_INIT(part); + MMCSD_DISK_LOCK_INIT(part); #ifndef __rtems__ d = part->disk = disk_alloc(); @@ -672,7 +708,7 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt, d->d_name = part->name; d->d_drv1 = part; d->d_sectorsize = mmc_get_sector_size(dev); - d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize; + d->d_maxsize = sc->max_data * d->d_sectorsize; d->d_mediasize = media_size; d->d_stripesize = erase_size; d->d_unit = cnt; @@ -704,7 +740,7 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt, part->name, cnt, bytes, unit, mmc_get_card_id_string(dev), ro ? " (read-only)" : "", device_get_nameunit(mmcbr), speed / 1000000, (speed / 100000) % 10, - mmcsd_bus_bit_width(dev), mmc_get_max_data(dev)); + mmcsd_bus_bit_width(dev), sc->max_data); } else if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) { printf("%s: %ju%sB partion %d%s at %s\n", part->name, bytes, unit, type, ro ? " (read-only)" : "", @@ -795,19 +831,27 @@ mmcsd_detach(device_t dev) for (i = 0; i < MMC_PART_MAX; i++) { part = sc->part[i]; - if (part != NULL && part->disk != NULL) { - MMCSD_PART_LOCK(part); - part->suspend = 0; - if (part->running > 0) { - /* kill thread */ - part->running = 0; - wakeup(part); - /* wait for thread to finish. */ - while (part->running != -1) - msleep(part, &part->part_mtx, 0, - "detach", 0); + if (part != NULL) { + if (part->disk != NULL) { + MMCSD_DISK_LOCK(part); + part->suspend = 0; + if (part->running > 0) { + /* kill thread */ + part->running = 0; + wakeup(part); + /* wait for thread to finish. */ + while (part->running != -1) + msleep(part, &part->disk_mtx, 0, + "mmcsd disk detach", 0); + } + MMCSD_DISK_UNLOCK(part); } - MMCSD_PART_UNLOCK(part); + MMCSD_IOCTL_LOCK(part); + while (part->ioctl > 0) + msleep(part, &part->ioctl_mtx, 0, + "mmcsd IOCTL detach", 0); + part->ioctl = -1; + MMCSD_IOCTL_UNLOCK(part); } } @@ -823,8 +867,9 @@ mmcsd_detach(device_t dev) /* kill disk */ disk_destroy(part->disk); - MMCSD_PART_LOCK_DESTROY(part); + MMCSD_DISK_LOCK_DESTROY(part); } + MMCSD_IOCTL_LOCK_DESTROY(part); free(part, M_DEVBUF); } } @@ -844,19 +889,27 @@ mmcsd_suspend(device_t dev) for (i = 0; i < MMC_PART_MAX; i++) { part = sc->part[i]; - if (part != NULL && part->disk != NULL) { - MMCSD_PART_LOCK(part); - part->suspend = 1; - if (part->running > 0) { - /* kill thread */ - part->running = 0; - wakeup(part); - /* wait for thread to finish. */ - while (part->running != -1) - msleep(part, &part->part_mtx, 0, - "detach", 0); + if (part != NULL) { + if (part->disk != NULL) { + MMCSD_DISK_LOCK(part); + part->suspend = 1; + if (part->running > 0) { + /* kill thread */ + part->running = 0; + wakeup(part); + /* wait for thread to finish. */ + while (part->running != -1) + msleep(part, &part->disk_mtx, 0, + "mmcsd disk suspension", 0); + } + MMCSD_DISK_UNLOCK(part); } - MMCSD_PART_UNLOCK(part); + MMCSD_IOCTL_LOCK(part); + while (part->ioctl > 0) + msleep(part, &part->ioctl_mtx, 0, + "mmcsd IOCTL suspension", 0); + part->ioctl = -1; + MMCSD_IOCTL_UNLOCK(part); } } #else /* __rtems__ */ @@ -875,16 +928,22 @@ mmcsd_resume(device_t dev) for (i = 0; i < MMC_PART_MAX; i++) { part = sc->part[i]; - if (part != NULL && part->disk != NULL) { - MMCSD_PART_LOCK(part); - part->suspend = 0; - if (part->running <= 0) { - part->running = 1; - kproc_create(&mmcsd_task, part, &part->p, 0, 0, - "%s%d: mmc/sd card", part->name, part->cnt); - MMCSD_PART_UNLOCK(part); - } else - MMCSD_PART_UNLOCK(part); + if (part != NULL) { + if (part->disk != NULL) { + MMCSD_DISK_LOCK(part); + part->suspend = 0; + if (part->running <= 0) { + part->running = 1; + MMCSD_DISK_UNLOCK(part); + kproc_create(&mmcsd_task, part, + &part->p, 0, 0, "%s%d: mmc/sd card", + part->name, part->cnt); + } else + MMCSD_DISK_UNLOCK(part); + } + MMCSD_IOCTL_LOCK(part); + part->ioctl = 0; + MMCSD_IOCTL_UNLOCK(part); } } #else /* __rtems__ */ @@ -916,13 +975,13 @@ mmcsd_strategy(struct bio *bp) part = bp->bio_disk->d_drv1; sc = part->sc; - MMCSD_PART_LOCK(part); + MMCSD_DISK_LOCK(part); if (part->running > 0 || part->suspend > 0) { bioq_disksort(&part->bio_queue, bp); - MMCSD_PART_UNLOCK(part); + MMCSD_DISK_UNLOCK(part); wakeup(part); } else { - MMCSD_PART_UNLOCK(part); + MMCSD_DISK_UNLOCK(part); biofinish(bp, NULL, ENXIO); } } @@ -961,9 +1020,9 @@ mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data, int fflag) switch (cmd) { case MMC_IOC_CMD: mic = data; - err = mmcsd_ioctl_cmd(part, data, fflag); + err = mmcsd_ioctl_cmd(part, mic, fflag); break; - case MMC_IOC_CMD_MULTI: + case MMC_IOC_MULTI_CMD: mimc = data; if (mimc->num_of_cmds == 0) break; @@ -973,12 +1032,12 @@ mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data, int fflag) size = sizeof(*mic) * cnt; mic = malloc(size, M_TEMP, M_WAITOK); err = copyin((const void *)mimc->cmds, mic, size); - if (err != 0) - break; - for (i = 0; i < cnt; i++) { - err = mmcsd_ioctl_cmd(part, &mic[i], fflag); - if (err != 0) - break; + if (err == 0) { + for (i = 0; i < cnt; i++) { + err = mmcsd_ioctl_cmd(part, &mic[i], fflag); + if (err != 0) + break; + } } free(mic, M_TEMP); break; @@ -1007,11 +1066,31 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) if (part->ro == TRUE && mic->write_flag != 0) return (EROFS); + /* + * We don't need to explicitly lock against the disk(9) half of this + * driver as MMCBUS_ACQUIRE_BUS() will serialize us. However, it's + * necessary to protect against races with detachment and suspension, + * especially since it's required to switch away from RPMB partitions + * again after an access (see mmcsd_switch_part()). + */ + MMCSD_IOCTL_LOCK(part); + while (part->ioctl != 0) { + if (part->ioctl < 0) { + MMCSD_IOCTL_UNLOCK(part); + return (ENXIO); + } + msleep(part, &part->ioctl_mtx, 0, "mmcsd IOCTL", 0); + } + part->ioctl = 1; + MMCSD_IOCTL_UNLOCK(part); + err = 0; dp = NULL; len = mic->blksz * mic->blocks; - if (len > MMC_IOC_MAX_BYTES) - return (EOVERFLOW); + if (len > MMC_IOC_MAX_BYTES) { + err = EOVERFLOW; + goto out; + } if (len != 0) { dp = malloc(len, M_TEMP, M_WAITOK); err = copyin((void *)(uintptr_t)mic->data_ptr, dp, len); @@ -1066,7 +1145,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) err = mmcsd_set_blockcount(sc, mic->blocks, mic->write_flag & (1 << 31)); if (err != MMC_ERR_NONE) - goto release; + goto switch_back; } if (mic->is_acmd != 0) (void)mmc_wait_for_app_cmd(mmcbr, dev, rca, &cmd, 0); @@ -1088,6 +1167,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) DELAY(1000); } while (retries-- > 0); +switch_back: /* ... and always switch back to the default partition. */ err = mmcsd_switch_part(mmcbr, dev, rca, EXT_CSD_PART_CONFIG_ACC_DEFAULT); @@ -1138,6 +1218,10 @@ release: err = EIO; out: + MMCSD_IOCTL_LOCK(part); + part->ioctl = 0; + MMCSD_IOCTL_UNLOCK(part); + wakeup(part); if (dp != NULL) free(dp, M_TEMP); return (err); @@ -1191,10 +1275,23 @@ mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part) sc = device_get_softc(dev); - if (sc->part_curr == part) + if (sc->mode == mode_sd) return (MMC_ERR_NONE); - if (sc->mode == mode_sd) + /* + * According to section "6.2.2 Command restrictions" of the eMMC + * specification v5.1, CMD19/CMD21 aren't allowed to be used with + * RPMB partitions. So we pause re-tuning along with triggering + * it up-front to decrease the likelihood of re-tuning becoming + * necessary while accessing an RPMB partition. Consequently, an + * RPMB partition should immediately be switched away from again + * after an access in order to allow for re-tuning to take place + * anew. + */ + if (part == EXT_CSD_PART_CONFIG_ACC_RPMB) + MMCBUS_RETUNE_PAUSE(sc->mmcbr, sc->dev, true); + + if (sc->part_curr == part) return (MMC_ERR_NONE); value = (sc->ext_csd[EXT_CSD_PART_CONFIG] & @@ -1202,10 +1299,15 @@ mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part) /* Jump! */ err = mmc_switch(bus, dev, rca, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, value, sc->part_time, true); - if (err != MMC_ERR_NONE) + if (err != MMC_ERR_NONE) { + if (part == EXT_CSD_PART_CONFIG_ACC_RPMB) + MMCBUS_RETUNE_UNPAUSE(sc->mmcbr, sc->dev); return (err); + } sc->ext_csd[EXT_CSD_PART_CONFIG] = value; + if (sc->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB) + MMCBUS_RETUNE_UNPAUSE(sc->mmcbr, sc->dev); sc->part_curr = part; return (MMC_ERR_NONE); } @@ -1217,7 +1319,7 @@ mmcsd_errmsg(int e) if (e < 0 || e > MMC_ERR_MAX) return "Bad error code"; - return errmsg[e]; + return (errmsg[e]); } static daddr_t @@ -1230,7 +1332,7 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp) struct mmc_data data; struct mmcsd_softc *sc; device_t dev, mmcbr; - int numblocks, sz; + u_int numblocks, sz; char *vaddr; sc = part->sc; @@ -1242,7 +1344,7 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp) end = bp->bio_pblkno + (bp->bio_bcount / sz); while (block < end) { vaddr = bp->bio_data + (block - bp->bio_pblkno) * sz; - numblocks = min(end - block, mmc_get_max_data(dev)); + numblocks = min(end - block, sc->max_data); memset(&req, 0, sizeof(req)); memset(&cmd, 0, sizeof(cmd)); memset(&stop, 0, sizeof(stop)); @@ -1262,7 +1364,7 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp) cmd.opcode = MMC_WRITE_BLOCK; } cmd.arg = block; - if (!mmc_get_high_cap(dev)) + if (sc->high_cap == 0) cmd.arg <<= 9; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; data.data = vaddr; @@ -1302,7 +1404,7 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) struct mmc_request req; struct mmcsd_softc *sc; device_t dev, mmcbr; - int erase_sector, sz; + u_int erase_sector, sz; sc = part->sc; dev = sc->dev; @@ -1317,7 +1419,7 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) if (end >= part->eblock && end < part->eend) end = part->eend; /* Safe round to the erase sector boundaries. */ - erase_sector = mmc_get_erase_sector(dev); + erase_sector = sc->erase_sector; start = block + erase_sector - 1; /* Round up. */ start -= start % erase_sector; stop = end; /* Round down. */ @@ -1329,6 +1431,12 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) return (end); } + /* + * Pause re-tuning so it won't interfere with the order of erase + * commands. Note that these latter don't use the data lines, so + * re-tuning shouldn't actually become necessary during erase. + */ + MMCBUS_RETUNE_PAUSE(mmcbr, dev, false); /* Set erase start position. */ memset(&req, 0, sizeof(req)); memset(&cmd, 0, sizeof(cmd)); @@ -1339,13 +1447,15 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) else cmd.opcode = MMC_ERASE_GROUP_START; cmd.arg = start; - if (!mmc_get_high_cap(dev)) + if (sc->high_cap == 0) cmd.arg <<= 9; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { - printf("erase err1: %d\n", req.cmd->error); - return (block); + device_printf(dev, "Setting erase start position failed %d\n", + req.cmd->error); + block = bp->bio_pblkno; + goto unpause; } /* Set erase stop position. */ memset(&req, 0, sizeof(req)); @@ -1356,14 +1466,16 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) else cmd.opcode = MMC_ERASE_GROUP_END; cmd.arg = stop; - if (!mmc_get_high_cap(dev)) + if (sc->high_cap == 0) cmd.arg <<= 9; cmd.arg--; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { - printf("erase err2: %d\n", req.cmd->error); - return (block); + device_printf(dev, "Setting erase stop position failed %d\n", + req.cmd->error); + block = bp->bio_pblkno; + goto unpause; } /* Erase range. */ memset(&req, 0, sizeof(req)); @@ -1374,8 +1486,11 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { - printf("erase err3 %d\n", req.cmd->error); - return (block); + device_printf(dev, "erase err3: %d\n", req.cmd->error); + device_printf(dev, "Issuing erase command failed %d\n", + req.cmd->error); + block = bp->bio_pblkno; + goto unpause; } /* Store one of remaining parts for the next call. */ if (bp->bio_pblkno >= part->eblock || block == start) { @@ -1385,7 +1500,10 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) part->eblock = block; /* Predict next backward. */ part->eend = start; } - return (end); + block = end; +unpause: + MMCBUS_RETUNE_UNPAUSE(mmcbr, dev); + return (block); } static int @@ -1446,16 +1564,16 @@ mmcsd_task(void *arg) mmcbr = sc->mmcbr; while (1) { - MMCSD_PART_LOCK(part); + MMCSD_DISK_LOCK(part); do { if (part->running == 0) goto out; bp = bioq_takefirst(&part->bio_queue); if (bp == NULL) - msleep(part, &part->part_mtx, PRIBIO, - "jobqueue", 0); + msleep(part, &part->disk_mtx, PRIBIO, + "mmcsd disk jobqueue", 0); } while (bp == NULL); - MMCSD_PART_UNLOCK(part); + MMCSD_DISK_UNLOCK(part); if (bp->bio_cmd != BIO_READ && part->ro) { bp->bio_error = EROFS; bp->bio_resid = bp->bio_bcount; @@ -1496,7 +1614,7 @@ release: out: /* tell parent we're done */ part->running = -1; - MMCSD_PART_UNLOCK(part); + MMCSD_DISK_UNLOCK(part); wakeup(part); kproc_exit(0); |