Lines Matching +full:default +full:- +full:trim

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