Lines Matching +full:write +full:- +full:1 +full:- +full:bps

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
9 * 1. Redistributions of source code must retain the above copyright
138 TAILQ_HEAD(, bio) bps;
165 #define NDA_DEFAULT_SEND_ORDERED 1
184 static int nda_enable_biospeedup = 1;
185 static int nda_nvd_compat = 1;
192 &nda_nvd_compat, 1, "Enable creation of nvd aliases.");
195 * All NVMe media is non-rotational, so all nvme device instances
227 nvme_ns_flush_cmd(&nvmeio->cmd, softc->nsid);
241 nvme_ns_trim_cmd(&nvmeio->cmd, softc->nsid, num_ranges);
255 nvme_ns_write_cmd(&nvmeio->cmd, softc->nsid, lba, count);
267 if (bp->bio_flags & BIO_UNMAPPED) {
271 payload = bp->bio_data;
274 lba = bp->bio_pblkno;
275 count = bp->bio_bcount / softc->disk->d_sectorsize;
282 bp->bio_bcount, /* dxfer_len */
284 nvme_ns_rw_cmd(&nvmeio->cmd, rwcmd, softc->nsid, lba, count);
294 periph = (struct cam_periph *)dp->d_drv1;
306 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
309 softc = (struct nda_softc *)periph->softc;
310 softc->flags |= NDA_FLAG_OPEN;
325 periph = (struct cam_periph *)dp->d_drv1;
326 softc = (struct nda_softc *)periph->softc;
329 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
332 if ((softc->flags & NDA_FLAG_DIRTY) != 0 &&
333 (periph->flags & CAM_PERIPH_INVALID) == 0 &&
336 nda_nvme_flush(softc, &ccb->nvmeio);
338 /*sense_flags*/0, softc->disk->d_devstat);
341 xpt_print(periph->path, "Synchronize cache failed\n");
343 softc->flags &= ~NDA_FLAG_DIRTY;
348 softc->flags &= ~NDA_FLAG_OPEN;
350 while (softc->refcount != 0)
351 cam_periph_sleep(periph, &softc->refcount, PRIBIO, "ndaclose", 1);
352 KASSERT(softc->outstanding_cmds == 0,
353 ("nda %d outstanding commands", softc->outstanding_cmds));
362 struct nda_softc *softc = (struct nda_softc *)periph->softc;
364 if (softc->state != NDA_STATE_NORMAL)
367 cam_iosched_schedule(softc->cam_iosched, periph);
376 periph = (struct cam_periph *)dp->d_drv1;
391 xpt_path_inq(&cpi, periph->path);
392 strncpy(gnsid->cdev, cpi.xport_specific.nvme.dev_name,
393 sizeof(gnsid->cdev));
394 gnsid->nsid = cpi.xport_specific.nvme.nsid;
402 u_int maxmap = dp->d_maxsize;
410 xpt_setup_ccb(&ccb->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
411 ccb->ccb_state = NDA_CCB_PASS;
412 cam_fill_nvmeio(&ccb->nvmeio,
415 (pt->is_read ? CAM_DIR_IN : CAM_DIR_OUT) | CAM_DATA_VADDR,
416 pt->buf,
417 pt->len,
419 memcpy(&ccb->nvmeio.cmd, &pt->cmd, sizeof(pt->cmd));
466 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
467 softc = (struct nda_softc *)periph->softc;
471 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ndastrategy(%p)\n", bp));
476 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
482 if (bp->bio_cmd == BIO_DELETE)
483 softc->deletes++;
488 cam_iosched_queue_work(softc->cam_iosched, bp);
512 periph = dp->d_drv1;
513 softc = (struct nda_softc *)periph->softc;
514 secsize = softc->disk->d_sectorsize;
518 if ((periph->flags & CAM_PERIPH_INVALID) != 0)
524 xpt_setup_ccb(&nvmeio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
536 xpt_setup_ccb(&nvmeio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
543 xpt_print(periph->path, "flush cmd failed\n");
581 periph = (struct cam_periph *)dp->d_drv1;
591 softc = (struct nda_softc *)periph->softc;
594 * De-register any async callbacks.
596 xpt_register_async(0, ndaasync, periph, periph->path);
598 softc->invalidations++;
607 cam_iosched_flush(softc->cam_iosched, NULL, ENXIO);
613 disk_gone(softc->disk);
621 softc = (struct nda_softc *)periph->softc;
625 cam_iosched_fini(softc->cam_iosched);
630 if ((softc->flags & NDA_FLAG_SCTX_INIT) != 0) {
632 if (sysctl_ctx_free(&softc->sysctl_stats_ctx) != 0)
633 xpt_print(periph->path,
636 if (sysctl_ctx_free(&softc->sysctl_ctx) != 0)
637 xpt_print(periph->path,
641 disk_destroy(softc->disk);
663 if (cgd->protocol != PROTO_NVME)
691 softc = periph->softc;
692 disk_attr_changed(softc->disk, "GEOM::physpath",
714 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
719 softc = (struct nda_softc *)periph->softc;
720 snprintf(tmpstr, sizeof(tmpstr), "CAM NDA unit %d", periph->unit_number);
721 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
723 sysctl_ctx_init(&softc->sysctl_ctx);
724 softc->flags |= NDA_FLAG_SCTX_INIT;
725 softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
728 if (softc->sysctl_tree == NULL) {
734 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
736 &softc->unmappedio, 0, "Unmapped I/O leaf");
738 SYSCTL_ADD_QUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
740 &softc->deletes, "Number of BIO_DELETE requests");
742 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
743 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
744 "trim_count", CTLFLAG_RD, &softc->trim_count,
746 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
747 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
748 "trim_ranges", CTLFLAG_RD, &softc->trim_ranges,
750 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
751 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
752 "trim_lbas", CTLFLAG_RD, &softc->trim_lbas,
755 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
756 OID_AUTO, "rotating", CTLFLAG_RD, &nda_rotating_media, 1,
759 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
765 softc->sysctl_stats_tree = SYSCTL_ADD_NODE(&softc->sysctl_stats_ctx,
766 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "stats",
768 if (softc->sysctl_stats_tree == NULL) {
773 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
774 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
776 &softc->timeouts, 0,
778 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
779 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
781 &softc->errors, 0,
783 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
784 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
786 &softc->invalidations, 0,
791 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
794 "Write 1 to invalidate the drive immediately");
797 cam_iosched_sysctl_init(softc->cam_iosched, &softc->sysctl_ctx,
798 softc->sysctl_tree);
811 if (softc->flags != 0)
812 sbuf_printf(&sbuf, "0x%b", (unsigned)softc->flags, NDA_FLAG_STRING);
830 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
832 ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
833 periph->path);
836 bp->bio_completed = bp->bio_length;
867 periph->softc = softc;
868 softc->quirks = NDA_Q_NONE;
869 xpt_path_inq(&cpi, periph->path);
870 TASK_INIT(&softc->sysctl_task, 0, ndasysctlinit, periph);
875 softc->nsid = (uint32_t)xpt_path_lun_id(periph->path);
883 "kern.cam.nda.%d.quirks", periph->unit_number);
884 quirks = softc->quirks;
886 softc->quirks = quirks;
887 softc->disk = disk = disk_alloc();
888 disk->d_rotation_rate = DISK_RR_NON_ROTATING;
889 disk->d_open = ndaopen;
890 disk->d_close = ndaclose;
891 disk->d_strategy = ndastrategy;
892 disk->d_ioctl = ndaioctl;
893 disk->d_getattr = ndagetattr;
894 if (cam_sim_pollable(periph->sim))
895 disk->d_dump = ndadump;
896 disk->d_gone = ndadiskgonecb;
897 disk->d_name = "nda";
898 disk->d_drv1 = periph;
899 disk->d_unit = periph->unit_number;
905 disk->d_maxsize = maxio;
906 flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd->flbas);
907 lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsd->lbaf[flbas_fmt]);
908 disk->d_sectorsize = 1 << lbads;
909 disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze);
910 disk->d_delmaxsize = disk->d_mediasize;
911 disk->d_flags = DISKFLAG_DIRECT_COMPLETION;
913 disk->d_flags |= DISKFLAG_CANDELETE;
914 vwc_present = NVMEV(NVME_CTRLR_DATA_VWC_PRESENT, cd->vwc);
916 disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
918 disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
919 softc->unmappedio = 1;
925 cam_strvis_flag(disk->d_descr, cd->mn, NVME_MODEL_NUMBER_LENGTH,
926 sizeof(disk->d_descr), CAM_STRVIS_FLAG_NONASCII_SPC);
928 cam_strvis_flag(disk->d_ident, cd->sn, NVME_SERIAL_NUMBER_LENGTH,
929 sizeof(disk->d_ident), CAM_STRVIS_FLAG_NONASCII_SPC);
931 disk->d_hba_vendor = cpi.hba_vendor;
932 disk->d_hba_device = cpi.hba_device;
933 disk->d_hba_subvendor = cpi.hba_subvendor;
934 disk->d_hba_subdevice = cpi.hba_subdevice;
935 snprintf(disk->d_attachment, sizeof(disk->d_attachment),
937 if (NVMEV(NVME_NS_DATA_NSFEAT_NPVALID, nsd->nsfeat) != 0 &&
938 nsd->npwg != 0)
939 disk->d_stripesize = ((nsd->npwg + 1) * disk->d_sectorsize);
941 disk->d_stripesize = nsd->noiob * disk->d_sectorsize;
942 disk->d_stripeoffset = 0;
943 disk->d_devstat = devstat_new_entry(periph->periph_name,
944 periph->unit_number, disk->d_sectorsize,
949 if (cam_iosched_init(&softc->cam_iosched, periph, disk,
956 cam_iosched_set_sort_queue(softc->cam_iosched, 0);
968 (uintmax_t)((uintmax_t)disk->d_mediasize / (1024*1024)),
969 (uintmax_t)disk->d_mediasize / disk->d_sectorsize,
970 disk->d_sectorsize);
972 xpt_announce_quirks(periph, softc->quirks, NDA_Q_BIT_STRING);
979 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
986 ndaasync, periph, periph->path);
988 softc->state = NDA_STATE_NORMAL;
995 disk_create(softc->disk, DISK_VERSION);
1004 struct nda_softc *softc = (struct nda_softc *)periph->softc;
1005 struct ccb_nvmeio *nvmeio = &start_ccb->nvmeio;
1007 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ndastart\n"));
1009 switch (softc->state) {
1014 bp = cam_iosched_next_bio(softc->cam_iosched);
1015 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ndastart: bio %p\n", bp));
1021 switch (bp->bio_cmd) {
1023 softc->flags |= NDA_FLAG_DIRTY;
1033 * if a write and pending write errors, then fail this
1039 if (bp->bio_cmd == BIO_READ) {
1040 if (softc->force_read_error) {
1041 softc->force_read_error--;
1042 fail = 1;
1044 if (softc->periodic_read_error > 0) {
1045 if (++softc->periodic_read_count >=
1046 softc->periodic_read_error) {
1047 softc->periodic_read_count = 0;
1048 fail = 1;
1052 if (softc->force_write_error) {
1053 softc->force_write_error--;
1054 fail = 1;
1064 KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
1065 round_page(bp->bio_bcount + bp->bio_ma_offset) /
1066 PAGE_SIZE == bp->bio_ma_n,
1068 nda_nvme_rw_bio(softc, &start_ccb->nvmeio, bp, bp->bio_cmd == BIO_READ ?
1097 TAILQ_INIT(&trim->bps);
1099 ents = min(nitems(trim->dsm), nda_max_trim_entries);
1100 ents = max(ents, 1);
1101 dsm_range = trim->dsm;
1104 TAILQ_INSERT_TAIL(&trim->bps, bp1, bio_queue);
1105 dsm_range->length =
1106 htole32(bp1->bio_bcount / softc->disk->d_sectorsize);
1107 dsm_range->starting_lba =
1108 htole64(bp1->bio_offset / softc->disk->d_sectorsize);
1110 totalcount += dsm_range->length;
1114 bp1 = cam_iosched_next_trim(softc->cam_iosched);
1115 /* XXX -- Could collapse adjacent ranges, but we don't for now */
1116 /* XXX -- Could limit based on total payload size */
1118 start_ccb->ccb_trim = trim;
1119 nda_nvme_trim(softc, &start_ccb->nvmeio, trim->dsm,
1120 dsm_range - trim->dsm);
1121 start_ccb->ccb_state = NDA_CCB_TRIM;
1122 softc->trim_count++;
1123 softc->trim_ranges += ranges;
1124 softc->trim_lbas += totalcount;
1127 * cam_iosched_submit_trim(softc->cam_iosched);
1142 start_ccb->ccb_state = NDA_CCB_BUFFER_IO;
1143 start_ccb->ccb_bp = bp;
1145 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
1146 softc->outstanding_cmds++;
1147 softc->refcount++; /* For submission only */
1151 softc->refcount--; /* Submission done */
1164 struct ccb_nvmeio *nvmeio = &done_ccb->nvmeio;
1168 softc = (struct nda_softc *)periph->softc;
1169 path = done_ccb->ccb_h.path;
1173 state = nvmeio->ccb_state & NDA_CCB_TYPE_MASK;
1181 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1188 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1195 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1202 bp = (struct bio *)done_ccb->ccb_bp;
1203 bp->bio_error = error;
1205 bp->bio_resid = bp->bio_bcount;
1206 bp->bio_flags |= BIO_ERROR;
1208 bp->bio_resid = 0;
1210 softc->outstanding_cmds--;
1218 cam_iosched_bio_complete(softc->cam_iosched, bp, done_ccb);
1228 trim = nvmeio->ccb_trim;
1230 TAILQ_CONCAT(&queue, &trim->bps, bio_queue);
1236 * cam_iosched_trim_done(softc->cam_iosched);
1245 cam_iosched_bio_complete(softc->cam_iosched, bp1, done_ccb);
1247 softc->outstanding_cmds--;
1252 bp2->bio_error = error;
1254 bp2->bio_flags |= BIO_ERROR;
1255 bp2->bio_resid = bp1->bio_bcount;
1257 bp2->bio_resid = 0;
1259 cam_iosched_bio_complete(softc->cam_iosched, bp2, NULL);
1266 /* No-op. We're polling */
1284 periph = xpt_path_periph(ccb->ccb_h.path);
1285 softc = (struct nda_softc *)periph->softc;
1288 switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
1291 softc->timeouts++;
1297 softc->errors++;
1320 softc = (struct nda_softc *)periph->softc;
1330 (softc->flags & NDA_FLAG_OPEN)) {
1331 ndadump(softc->disk, NULL, 0, 0);
1340 if ((softc->flags & NDA_FLAG_OPEN) == 0) {
1346 nda_nvme_flush(softc, &ccb->nvmeio);
1349 softc->disk->d_devstat);
1351 xpt_print(periph->path, "Synchronize cache failed\n");