Lines Matching +full:suspend +full:- +full:to +full:- +full:disk

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * Portions of this software may have been developed with reference to
31 * The following conditions apply to the release of the simplified
35 * Group. This Simplified Specification is provided on a non-confidential
36 * basis subject to the disclaimers below. Any implementation of the
38 * Association, SD Group, SD-3C LLC or other third parties.
44 * is provided "AS-IS" without any representations or warranties of any
45 * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD
47 * right of the SD Group, SD-3C LLC, the SD Card Association or any third
50 * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing
51 * herein shall be construed as an obligation by the SD Group, the SD-3C LLC
52 * or the SD Card Association to disclose or distribute any technical
53 * information, know-how or other confidential information to any third party.
102 struct disk *disk; member
109 int suspend; member
123 uint8_t part_curr; /* Partition currently switched to */
166 /* disk routines */
167 static int mmcsd_close(struct disk *dp);
170 static int mmcsd_ioctl_disk(struct disk *disk, u_long cmd, void *data,
197 #define MMCSD_DISK_LOCK(_part) mtx_lock(&(_part)->disk_mtx)
198 #define MMCSD_DISK_UNLOCK(_part) mtx_unlock(&(_part)->disk_mtx)
200 mtx_init(&(_part)->disk_mtx, (_part)->name, "mmcsd disk", MTX_DEF)
201 #define MMCSD_DISK_LOCK_DESTROY(_part) mtx_destroy(&(_part)->disk_mtx);
203 mtx_assert(&(_part)->disk_mtx, MA_OWNED);
205 mtx_assert(&(_part)->disk_mtx, MA_NOTOWNED);
207 #define MMCSD_IOCTL_LOCK(_part) mtx_lock(&(_part)->ioctl_mtx)
208 #define MMCSD_IOCTL_UNLOCK(_part) mtx_unlock(&(_part)->ioctl_mtx)
210 mtx_init(&(_part)->ioctl_mtx, (_part)->name, "mmcsd IOCTL", MTX_DEF)
211 #define MMCSD_IOCTL_LOCK_DESTROY(_part) mtx_destroy(&(_part)->ioctl_mtx);
213 mtx_assert(&(_part)->ioctl_mtx, MA_OWNED);
215 mtx_assert(&(_part)->ioctl_mtx, MA_NOTOWNED);
241 sc->dev = dev; in mmcsd_attach()
242 sc->mmcbus = mmcbus = device_get_parent(dev); in mmcsd_attach()
243 sc->mode = mmc_get_card_type(dev); in mmcsd_attach()
245 * Note that in principle with an SDHCI-like re-tuning implementation, in mmcsd_attach()
246 * the maximum data size can change at runtime due to a device removal/ in mmcsd_attach()
247 * insertion that results in switches to/from a transfer mode involving in mmcsd_attach()
248 * re-tuning, iff there are multiple devices on a given bus. Until now in mmcsd_attach()
250 * and sdhci(4) to date has no support for shared buses in the first in mmcsd_attach()
253 sc->max_data = mmc_get_max_data(dev); in mmcsd_attach()
254 sc->high_cap = mmc_get_high_cap(dev); in mmcsd_attach()
255 sc->rca = mmc_get_rca(dev); in mmcsd_attach()
256 sc->cmd6_time = mmc_get_cmd6_timeout(dev); in mmcsd_attach()
262 err = mmc_send_ext_csd(mmcbus, dev, sc->ext_csd); in mmcsd_attach()
270 ext_csd = sc->ext_csd; in mmcsd_attach()
278 sc->flags |= MMCSD_INAND_CMD38; in mmcsd_attach()
290 sc->flags |= MMCSD_USE_TRIM; in mmcsd_attach()
291 sc->erase_sector = 1; in mmcsd_attach()
293 sc->erase_sector = mmc_get_erase_sector(dev); in mmcsd_attach()
313 err = mmc_switch(mmcbus, dev, sc->rca, in mmcsd_attach()
315 EXT_CSD_CACHE_CTRL_CACHE_EN, sc->cmd6_time, true); in mmcsd_attach()
318 device_printf(dev, "failed to enable cache\n"); in mmcsd_attach()
320 sc->flags |= MMCSD_FLUSH_CACHE; in mmcsd_attach()
325 * Ignore user-creatable enhanced user data area and general purpose in mmcsd_attach()
336 * NB: The slicer and its slices need to be registered before adding in mmcsd_attach()
337 * the disk for the corresponding user data area as re-tasting is in mmcsd_attach()
353 sc->enh_size = size; in mmcsd_attach()
354 sc->enh_base = in mmcsd_attach()
356 (sc->high_cap == 0 ? MMC_SECTOR_SIZE : 1); in mmcsd_attach()
374 if (sc->enh_size != 0) { in mmcsd_attach()
378 MMCSD_LABEL_ENH, bytes, unit, (uintmax_t)sc->enh_base, in mmcsd_attach()
386 sc->part_time = max(ext_csd[EXT_CSD_PART_SWITCH_TO] * 10 * 1000, in mmcsd_attach()
441 * SD standard goes to 2 GiB due to its reliance on FAT, but the data in mmcsd_pretty_size()
442 * format supports up to 4 GiB and some card makers push it up to this in mmcsd_pretty_size()
443 * limit. The SDHC standard only goes to 32 GiB due to FAT32, but the in mmcsd_pretty_size()
444 * data format supports up to 2 TiB however. 2048 GB isn't too ugly, in mmcsd_pretty_size()
445 * so we note it in passing here and don't add the code to print TB). in mmcsd_pretty_size()
447 * report them like that. We also round to the nearest unit, since in mmcsd_pretty_size()
453 bytes = (bytes + 1000 / 2 - 1) / 1000; in mmcsd_pretty_size()
486 struct disk *d; in mmcsd_add_part()
494 dev = sc->dev; in mmcsd_add_part()
495 mmcbus = sc->mmcbus; in mmcsd_add_part()
496 part = sc->part[type] = malloc(sizeof(*part), M_DEVBUF, in mmcsd_add_part()
498 part->sc = sc; in mmcsd_add_part()
499 part->cnt = cnt; in mmcsd_add_part()
500 part->type = type; in mmcsd_add_part()
501 part->ro = ro; in mmcsd_add_part()
502 snprintf(part->name, sizeof(part->name), name, device_get_unit(dev)); in mmcsd_add_part()
508 * NB: If ever attaching RPMB partitions to disk(9), the re-tuning in mmcsd_add_part()
509 * implementation and especially its pausing need to be revisited, in mmcsd_add_part()
510 * because then re-tuning requests may be issued by the IOCTL half in mmcsd_add_part()
511 * of this driver while re-tuning is already paused by the disk(9) in mmcsd_add_part()
522 if (make_dev_s(&args, &sc->rpmb_dev, "%s", part->name) != 0) { in mmcsd_add_part()
523 device_printf(dev, "Failed to make RPMB device\n"); in mmcsd_add_part()
530 d = part->disk = disk_alloc(); in mmcsd_add_part()
531 d->d_close = mmcsd_close; in mmcsd_add_part()
532 d->d_strategy = mmcsd_strategy; in mmcsd_add_part()
533 d->d_ioctl = mmcsd_ioctl_disk; in mmcsd_add_part()
534 d->d_dump = mmcsd_dump; in mmcsd_add_part()
535 d->d_getattr = mmcsd_getattr; in mmcsd_add_part()
536 d->d_name = part->name; in mmcsd_add_part()
537 d->d_drv1 = part; in mmcsd_add_part()
538 d->d_sectorsize = mmc_get_sector_size(dev); in mmcsd_add_part()
539 d->d_maxsize = sc->max_data * d->d_sectorsize; in mmcsd_add_part()
540 d->d_mediasize = media_size; in mmcsd_add_part()
541 d->d_stripesize = sc->erase_sector * d->d_sectorsize; in mmcsd_add_part()
542 d->d_unit = cnt; in mmcsd_add_part()
543 d->d_flags = DISKFLAG_CANDELETE; in mmcsd_add_part()
544 if ((sc->flags & MMCSD_FLUSH_CACHE) != 0) in mmcsd_add_part()
545 d->d_flags |= DISKFLAG_CANFLUSHCACHE; in mmcsd_add_part()
546 d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize; in mmcsd_add_part()
547 strlcpy(d->d_ident, mmc_get_card_sn_string(dev), in mmcsd_add_part()
548 sizeof(d->d_ident)); in mmcsd_add_part()
549 strlcpy(d->d_descr, mmc_get_card_id_string(dev), in mmcsd_add_part()
550 sizeof(d->d_descr)); in mmcsd_add_part()
551 d->d_rotation_rate = DISK_RR_NON_ROTATING; in mmcsd_add_part()
554 bioq_init(&part->bio_queue); in mmcsd_add_part()
556 part->running = 1; in mmcsd_add_part()
557 kproc_create(&mmcsd_task, part, &part->p, 0, 0, in mmcsd_add_part()
558 "%s%d: mmc/sd card", part->name, cnt); in mmcsd_add_part()
564 printf("%s%d: %ju%sB <%s>%s at %s %d.%01dMHz/%dbit/%d-block\n", in mmcsd_add_part()
565 part->name, cnt, bytes, unit, mmc_get_card_id_string(dev), in mmcsd_add_part()
566 ro ? " (read-only)" : "", device_get_nameunit(mmcbus), in mmcsd_add_part()
568 mmcsd_bus_bit_width(dev), sc->max_data); in mmcsd_add_part()
570 printf("%s: %ju%sB partition %d%s at %s\n", part->name, bytes, in mmcsd_add_part()
571 unit, type, ro ? " (read-only)" : "", in mmcsd_add_part()
579 ext_csd = sc->ext_csd; in mmcsd_add_part()
580 gp = type - EXT_CSD_PART_CONFIG_ACC_GP0; in mmcsd_add_part()
597 ext = "non-persistent"; in mmcsd_add_part()
607 part->name, cnt, bytes, unit, type, enh ? in mmcsd_add_part()
608 " enhanced" : "", ro ? " (read-only)" : "", in mmcsd_add_part()
612 "(%s)%s at %s\n", part->name, cnt, bytes, unit, in mmcsd_add_part()
613 type, extattr, ext, ro ? " (read-only)" : "", in mmcsd_add_part()
631 if (sc->enh_size == 0) in mmcsd_slicer()
634 part = sc->part[EXT_CSD_PART_CONFIG_ACC_DEFAULT]; in mmcsd_slicer()
635 snprintf(name, sizeof(name), "%s%d", part->disk->d_name, in mmcsd_slicer()
636 part->disk->d_unit); in mmcsd_slicer()
641 slices[0].base = sc->enh_base; in mmcsd_slicer()
642 slices[0].size = sc->enh_size; in mmcsd_slicer()
655 part = sc->part[i]; in mmcsd_detach()
657 if (part->disk != NULL) { in mmcsd_detach()
659 part->suspend = 0; in mmcsd_detach()
660 if (part->running > 0) { in mmcsd_detach()
662 part->running = 0; in mmcsd_detach()
664 /* wait for thread to finish. */ in mmcsd_detach()
665 while (part->running != -1) in mmcsd_detach()
666 msleep(part, &part->disk_mtx, 0, in mmcsd_detach()
667 "mmcsd disk detach", 0); in mmcsd_detach()
672 while (part->ioctl > 0) in mmcsd_detach()
673 msleep(part, &part->ioctl_mtx, 0, in mmcsd_detach()
675 part->ioctl = -1; in mmcsd_detach()
680 if (sc->rpmb_dev != NULL) in mmcsd_detach()
681 destroy_dev(sc->rpmb_dev); in mmcsd_detach()
684 part = sc->part[i]; in mmcsd_detach()
686 if (part->disk != NULL) { in mmcsd_detach()
688 bioq_flush(&part->bio_queue, NULL, ENXIO); in mmcsd_detach()
689 /* kill disk */ in mmcsd_detach()
690 disk_destroy(part->disk); in mmcsd_detach()
699 device_printf(dev, "failed to flush cache\n"); in mmcsd_detach()
709 device_printf(dev, "failed to flush cache\n"); in mmcsd_shutdown()
721 part = sc->part[i]; in mmcsd_suspend()
723 if (part->disk != NULL) { in mmcsd_suspend()
725 part->suspend = 1; in mmcsd_suspend()
726 if (part->running > 0) { in mmcsd_suspend()
728 part->running = 0; in mmcsd_suspend()
730 /* wait for thread to finish. */ in mmcsd_suspend()
731 while (part->running != -1) in mmcsd_suspend()
732 msleep(part, &part->disk_mtx, 0, in mmcsd_suspend()
733 "mmcsd disk suspension", 0); in mmcsd_suspend()
738 while (part->ioctl > 0) in mmcsd_suspend()
739 msleep(part, &part->ioctl_mtx, 0, in mmcsd_suspend()
741 part->ioctl = -1; in mmcsd_suspend()
746 device_printf(dev, "failed to flush cache\n"); in mmcsd_suspend()
758 part = sc->part[i]; in mmcsd_resume()
760 if (part->disk != NULL) { in mmcsd_resume()
762 part->suspend = 0; in mmcsd_resume()
763 if (part->running <= 0) { in mmcsd_resume()
764 part->running = 1; in mmcsd_resume()
767 &part->p, 0, 0, "%s%d: mmc/sd card", in mmcsd_resume()
768 part->name, part->cnt); in mmcsd_resume()
773 part->ioctl = 0; in mmcsd_resume()
781 mmcsd_close(struct disk *dp) in mmcsd_close()
785 if ((dp->d_flags & DISKFLAG_OPEN) != 0) { in mmcsd_close()
786 sc = ((struct mmcsd_part *)dp->d_drv1)->sc; in mmcsd_close()
788 device_printf(sc->dev, "failed to flush cache\n"); in mmcsd_close()
798 part = bp->bio_disk->d_drv1; in mmcsd_strategy()
800 if (part->running > 0 || part->suspend > 0) { in mmcsd_strategy()
801 bioq_disksort(&part->bio_queue, bp); in mmcsd_strategy()
815 return (mmcsd_ioctl(dev->si_drv1, cmd, data, fflag, td)); in mmcsd_ioctl_rpmb()
819 mmcsd_ioctl_disk(struct disk *disk, u_long cmd, void *data, int fflag, in mmcsd_ioctl_disk() argument
823 return (mmcsd_ioctl(disk->d_drv1, cmd, data, fflag, td)); in mmcsd_ioctl_disk()
850 if (mimc->num_of_cmds == 0) in mmcsd_ioctl()
852 if (mimc->num_of_cmds > MMC_IOC_MAX_CMDS) in mmcsd_ioctl()
854 cnt = mimc->num_of_cmds; in mmcsd_ioctl()
857 err = copyin((const void *)mimc->cmds, mic, size); in mmcsd_ioctl()
886 if ((fflag & FWRITE) == 0 && mic->write_flag != 0) in mmcsd_ioctl_cmd()
889 if (part->ro == TRUE && mic->write_flag != 0) in mmcsd_ioctl_cmd()
893 * We don't need to explicitly lock against the disk(9) half of this in mmcsd_ioctl_cmd()
895 * necessary to protect against races with detachment and suspension, in mmcsd_ioctl_cmd()
896 * especially since it's required to switch away from RPMB partitions in mmcsd_ioctl_cmd()
900 while (part->ioctl != 0) { in mmcsd_ioctl_cmd()
901 if (part->ioctl < 0) { in mmcsd_ioctl_cmd()
905 msleep(part, &part->ioctl_mtx, 0, "mmcsd IOCTL", 0); in mmcsd_ioctl_cmd()
907 part->ioctl = 1; in mmcsd_ioctl_cmd()
912 len = mic->blksz * mic->blocks; in mmcsd_ioctl_cmd()
919 err = copyin((void *)(uintptr_t)mic->data_ptr, dp, len); in mmcsd_ioctl_cmd()
925 cmd.opcode = mic->opcode; in mmcsd_ioctl_cmd()
926 cmd.arg = mic->arg; in mmcsd_ioctl_cmd()
927 cmd.flags = mic->flags; in mmcsd_ioctl_cmd()
931 data.flags = mic->write_flag != 0 ? MMC_DATA_WRITE : in mmcsd_ioctl_cmd()
935 sc = part->sc; in mmcsd_ioctl_cmd()
936 rca = sc->rca; in mmcsd_ioctl_cmd()
937 if (mic->is_acmd == 0) { in mmcsd_ioctl_cmd()
938 /* Enforce/patch/restrict RCA-based commands */ in mmcsd_ioctl_cmd()
962 * to recover from that, especially if things go wrong. in mmcsd_ioctl_cmd()
966 EXT_CSD_PART_CONFIG_ACC_MASK) != part->type) { in mmcsd_ioctl_cmd()
971 dev = sc->dev; in mmcsd_ioctl_cmd()
972 mmcbus = sc->mmcbus; in mmcsd_ioctl_cmd()
974 err = mmcsd_switch_part(mmcbus, dev, rca, part->type); in mmcsd_ioctl_cmd()
977 if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) { in mmcsd_ioctl_cmd()
978 err = mmcsd_set_blockcount(sc, mic->blocks, in mmcsd_ioctl_cmd()
979 mic->write_flag & (1 << 31)); in mmcsd_ioctl_cmd()
983 if (mic->write_flag != 0) in mmcsd_ioctl_cmd()
984 sc->flags |= MMCSD_DIRTY; in mmcsd_ioctl_cmd()
985 if (mic->is_acmd != 0) in mmcsd_ioctl_cmd()
989 if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) { in mmcsd_ioctl_cmd()
991 * If the request went to the RPMB partition, try to ensure in mmcsd_ioctl_cmd()
1003 } while (retries-- > 0); in mmcsd_ioctl_cmd()
1011 err = mmc_send_ext_csd(mmcbus, dev, sc->ext_csd); in mmcsd_ioctl_cmd()
1016 if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) { in mmcsd_ioctl_cmd()
1018 * If the request went to the RPMB partition, always switch in mmcsd_ioctl_cmd()
1019 * back to the default partition (see mmcsd_switch_part()). in mmcsd_ioctl_cmd()
1047 memcpy(mic->response, cmd.resp, 4 * sizeof(uint32_t)); in mmcsd_ioctl_cmd()
1048 if (mic->write_flag == 0 && len != 0) { in mmcsd_ioctl_cmd()
1049 err = copyout(dp, (void *)(uintptr_t)mic->data_ptr, len); in mmcsd_ioctl_cmd()
1061 part->ioctl = 0; in mmcsd_ioctl_cmd()
1075 if (strcmp(bp->bio_attribute, "MMC::device") == 0) { in mmcsd_getattr()
1076 if (bp->bio_length != sizeof(dev)) in mmcsd_getattr()
1078 part = bp->bio_disk->d_drv1; in mmcsd_getattr()
1079 dev = part->sc->dev; in mmcsd_getattr()
1080 bcopy(&dev, bp->bio_data, sizeof(dev)); in mmcsd_getattr()
1081 bp->bio_completed = bp->bio_length; in mmcsd_getattr()
1084 return (-1); in mmcsd_getattr()
1102 MMCBUS_WAIT_FOR_REQUEST(sc->mmcbus, sc->dev, &req); in mmcsd_set_blockcount()
1115 if (sc->mode == mode_sd) in mmcsd_switch_part()
1119 * According to section "6.2.2 Command restrictions" of the eMMC in mmcsd_switch_part()
1120 * specification v5.1, CMD19/CMD21 aren't allowed to be used with in mmcsd_switch_part()
1121 * RPMB partitions. So we pause re-tuning along with triggering in mmcsd_switch_part()
1122 * it up-front to decrease the likelihood of re-tuning becoming in mmcsd_switch_part()
1125 * after an access in order to allow for re-tuning to take place in mmcsd_switch_part()
1129 MMCBUS_RETUNE_PAUSE(sc->mmcbus, sc->dev, true); in mmcsd_switch_part()
1131 if (sc->part_curr == part) in mmcsd_switch_part()
1134 value = (sc->ext_csd[EXT_CSD_PART_CONFIG] & in mmcsd_switch_part()
1138 EXT_CSD_PART_CONFIG, value, sc->part_time, true); in mmcsd_switch_part()
1141 MMCBUS_RETUNE_UNPAUSE(sc->mmcbus, sc->dev); in mmcsd_switch_part()
1145 sc->ext_csd[EXT_CSD_PART_CONFIG] = value; in mmcsd_switch_part()
1146 if (sc->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB) in mmcsd_switch_part()
1147 MMCBUS_RETUNE_UNPAUSE(sc->mmcbus, sc->dev); in mmcsd_switch_part()
1148 sc->part_curr = part; in mmcsd_switch_part()
1174 sc = part->sc; in mmcsd_rw()
1175 dev = sc->dev; in mmcsd_rw()
1176 mmcbus = sc->mmcbus; in mmcsd_rw()
1178 block = bp->bio_pblkno; in mmcsd_rw()
1179 sz = part->disk->d_sectorsize; in mmcsd_rw()
1180 end = bp->bio_pblkno + (bp->bio_bcount / sz); in mmcsd_rw()
1182 vaddr = bp->bio_data + (block - bp->bio_pblkno) * sz; in mmcsd_rw()
1183 numblocks = min(end - block, sc->max_data); in mmcsd_rw()
1191 if (bp->bio_cmd == BIO_READ) { in mmcsd_rw()
1197 sc->flags |= MMCSD_DIRTY; in mmcsd_rw()
1204 if (sc->high_cap == 0) in mmcsd_rw()
1209 if (bp->bio_cmd == BIO_READ) in mmcsd_rw()
1223 if (req.cmd->error != MMC_ERR_NONE) { in mmcsd_rw()
1224 if (ppsratecheck(&sc->log_time, &sc->log_count, in mmcsd_rw()
1227 req.cmd->error, in mmcsd_rw()
1228 mmcsd_errmsg(req.cmd->error)); in mmcsd_rw()
1248 sc = part->sc; in mmcsd_delete()
1249 dev = sc->dev; in mmcsd_delete()
1250 mmcbus = sc->mmcbus; in mmcsd_delete()
1252 block = bp->bio_pblkno; in mmcsd_delete()
1253 sz = part->disk->d_sectorsize; in mmcsd_delete()
1254 end = bp->bio_pblkno + (bp->bio_bcount / sz); in mmcsd_delete()
1255 use_trim = sc->flags & MMCSD_USE_TRIM; in mmcsd_delete()
1261 if (block > part->eblock && block <= part->eend) in mmcsd_delete()
1262 block = part->eblock; in mmcsd_delete()
1263 if (end >= part->eblock && end < part->eend) in mmcsd_delete()
1264 end = part->eend; in mmcsd_delete()
1265 /* Safely round to the erase sector boundaries. */ in mmcsd_delete()
1266 erase_sector = sc->erase_sector; in mmcsd_delete()
1267 start = block + erase_sector - 1; /* Round up. */ in mmcsd_delete()
1268 start -= start % erase_sector; in mmcsd_delete()
1270 stop -= end % erase_sector; in mmcsd_delete()
1276 part->eblock = block; in mmcsd_delete()
1277 part->eend = end; in mmcsd_delete()
1282 if ((sc->flags & MMCSD_INAND_CMD38) != 0) { in mmcsd_delete()
1283 err = mmc_switch(mmcbus, dev, sc->rca, EXT_CSD_CMD_SET_NORMAL, in mmcsd_delete()
1286 sc->cmd6_time, true); in mmcsd_delete()
1296 * Pause re-tuning so it won't interfere with the order of erase in mmcsd_delete()
1298 * re-tuning shouldn't actually become necessary during erase. in mmcsd_delete()
1306 if (sc->mode == mode_sd) in mmcsd_delete()
1311 if (sc->high_cap == 0) in mmcsd_delete()
1315 if (req.cmd->error != MMC_ERR_NONE) { in mmcsd_delete()
1317 mmcsd_errmsg(req.cmd->error)); in mmcsd_delete()
1318 block = bp->bio_pblkno; in mmcsd_delete()
1325 if (sc->mode == mode_sd) in mmcsd_delete()
1330 if (sc->high_cap == 0) in mmcsd_delete()
1332 cmd.arg--; in mmcsd_delete()
1335 if (req.cmd->error != MMC_ERR_NONE) { in mmcsd_delete()
1337 mmcsd_errmsg(req.cmd->error)); in mmcsd_delete()
1338 block = bp->bio_pblkno; in mmcsd_delete()
1349 if (req.cmd->error != MMC_ERR_NONE) { in mmcsd_delete()
1351 mmcsd_errmsg(req.cmd->error)); in mmcsd_delete()
1352 block = bp->bio_pblkno; in mmcsd_delete()
1357 if (bp->bio_pblkno >= part->eblock || block == start) { in mmcsd_delete()
1358 part->eblock = stop; /* Predict next forward. */ in mmcsd_delete()
1359 part->eend = end; in mmcsd_delete()
1361 part->eblock = block; /* Predict next backward. */ in mmcsd_delete()
1362 part->eend = start; in mmcsd_delete()
1376 struct disk *disk; in mmcsd_dump() local
1382 disk = arg; in mmcsd_dump()
1383 part = disk->d_drv1; in mmcsd_dump()
1384 sc = part->sc; in mmcsd_dump()
1386 /* length zero is special and really means flush buffers to media */ in mmcsd_dump()
1394 dev = sc->dev; in mmcsd_dump()
1395 mmcbus = sc->mmcbus; in mmcsd_dump()
1398 bp.bio_disk = disk; in mmcsd_dump()
1399 bp.bio_pblkno = offset / disk->d_sectorsize; in mmcsd_dump()
1403 end = bp.bio_pblkno + bp.bio_bcount / disk->d_sectorsize; in mmcsd_dump()
1405 err = mmcsd_switch_part(mmcbus, dev, sc->rca, part->type); in mmcsd_dump()
1407 if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) in mmcsd_dump()
1428 sc = part->sc; in mmcsd_task()
1429 dev = sc->dev; in mmcsd_task()
1430 mmcbus = sc->mmcbus; in mmcsd_task()
1436 if (part->running == 0) in mmcsd_task()
1438 bp = bioq_takefirst(&part->bio_queue); in mmcsd_task()
1440 msleep(part, &part->disk_mtx, PRIBIO, in mmcsd_task()
1441 "mmcsd disk jobqueue", 0); in mmcsd_task()
1444 if (__predict_false(bp->bio_cmd == BIO_FLUSH)) { in mmcsd_task()
1446 bp->bio_error = EIO; in mmcsd_task()
1447 bp->bio_flags |= BIO_ERROR; in mmcsd_task()
1452 if (bp->bio_cmd != BIO_READ && part->ro) { in mmcsd_task()
1453 bp->bio_error = EROFS; in mmcsd_task()
1454 bp->bio_resid = bp->bio_bcount; in mmcsd_task()
1455 bp->bio_flags |= BIO_ERROR; in mmcsd_task()
1460 sz = part->disk->d_sectorsize; in mmcsd_task()
1461 block = bp->bio_pblkno; in mmcsd_task()
1462 end = bp->bio_pblkno + (bp->bio_bcount / sz); in mmcsd_task()
1463 err = mmcsd_switch_part(mmcbus, dev, sc->rca, part->type); in mmcsd_task()
1465 if (ppsratecheck(&sc->log_time, &sc->log_count, in mmcsd_task()
1470 if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { in mmcsd_task()
1471 /* Access to the remaining erase block obsoletes it. */ in mmcsd_task()
1472 if (block < part->eend && end > part->eblock) in mmcsd_task()
1473 part->eblock = part->eend = 0; in mmcsd_task()
1475 } else if (bp->bio_cmd == BIO_DELETE) in mmcsd_task()
1482 bp->bio_error = (bio_error == 0) ? EIO : bio_error; in mmcsd_task()
1483 bp->bio_resid = (end - block) * sz; in mmcsd_task()
1484 bp->bio_flags |= BIO_ERROR; in mmcsd_task()
1486 bp->bio_resid = 0; in mmcsd_task()
1491 part->running = -1; in mmcsd_task()
1515 if ((sc->flags & MMCSD_FLUSH_CACHE) == 0) in mmcsd_flush_cache()
1518 dev = sc->dev; in mmcsd_flush_cache()
1519 mmcbus = sc->mmcbus; in mmcsd_flush_cache()
1521 if ((sc->flags & MMCSD_DIRTY) == 0) { in mmcsd_flush_cache()
1525 err = mmc_switch(mmcbus, dev, sc->rca, EXT_CSD_CMD_SET_NORMAL, in mmcsd_flush_cache()
1528 sc->flags &= ~MMCSD_DIRTY; in mmcsd_flush_cache()