/* * Default to a 4K page size, with the intention to update this * path in the future to accommodate architectures with differing * kernel and IO page sizes.
*/ #define NVME_CTRL_PAGE_SHIFT 12 #define NVME_CTRL_PAGE_SIZE (1 << NVME_CTRL_PAGE_SHIFT)
/* * List of workarounds for devices that required behavior not specified in * the standard.
*/ enum nvme_quirks { /* * Prefers I/O aligned to a stripe size specified in a vendor * specific Identify field.
*/
NVME_QUIRK_STRIPE_SIZE = (1 << 0),
/* * The controller doesn't handle Identify value others than 0 or 1 * correctly.
*/
NVME_QUIRK_IDENTIFY_CNS = (1 << 1),
/* * The controller deterministically returns 0's on reads to * logical blocks that deallocate was called on.
*/
NVME_QUIRK_DEALLOCATE_ZEROES = (1 << 2),
/* * The controller needs a delay before starts checking the device * readiness, which is done by reading the NVME_CSTS_RDY bit.
*/
NVME_QUIRK_DELAY_BEFORE_CHK_RDY = (1 << 3),
/* * APST should not be used.
*/
NVME_QUIRK_NO_APST = (1 << 4),
/* * The deepest sleep state should not be used.
*/
NVME_QUIRK_NO_DEEPEST_PS = (1 << 5),
/* * Problems seen with concurrent commands
*/
NVME_QUIRK_QDEPTH_ONE = (1 << 6),
/* * Set MEDIUM priority on SQ creation
*/
NVME_QUIRK_MEDIUM_PRIO_SQ = (1 << 7),
/* * Prevent tag overlap between queues
*/
NVME_QUIRK_SHARED_TAGS = (1 << 13),
/* * Don't change the value of the temperature threshold feature
*/
NVME_QUIRK_NO_TEMP_THRESH_CHANGE = (1 << 14),
/* * The controller doesn't handle the Identify Namespace * Identification Descriptor list subcommand despite claiming * NVMe 1.3 compliance.
*/
NVME_QUIRK_NO_NS_DESC_LIST = (1 << 15),
/* * The controller does not properly handle DMA addresses over * 48 bits.
*/
NVME_QUIRK_DMA_ADDRESS_BITS_48 = (1 << 16),
/* * The controller requires the command_id value be limited, so skip * encoding the generation sequence number.
*/
NVME_QUIRK_SKIP_CID_GEN = (1 << 17),
/* * Reports garbage in the namespace identifiers (eui64, nguid, uuid).
*/
NVME_QUIRK_BOGUS_NID = (1 << 18),
/* * No temperature thresholds for channels other than 0 (Composite).
*/
NVME_QUIRK_NO_SECONDARY_TEMP_THRESH = (1 << 19),
/* * MSI (but not MSI-X) interrupts are broken and never fire.
*/
NVME_QUIRK_BROKEN_MSI = (1 << 21),
/* * Align dma pool segment size to 512 bytes
*/
NVME_QUIRK_DMAPOOL_ALIGN_512 = (1 << 22),
};
/* * Common request structure for NVMe passthrough. All drivers must have * this structure as the first member of their request-private data.
*/ struct nvme_request { struct nvme_command *cmd; union nvme_result result;
u8 genctr;
u8 retries;
u8 flags;
u16 status; #ifdef CONFIG_NVME_MULTIPATH unsignedlong start_time; #endif struct nvme_ctrl *ctrl;
};
/* * Mark a bio as coming in through the mpath node.
*/ #define REQ_NVME_MPATH REQ_DRV
staticinline u16 nvme_req_qid(struct request *req)
{ if (!req->q->queuedata) return 0;
return req->mq_hctx->queue_num + 1;
}
/* The below value is the specific amount of delay needed before checking * readiness in case of the PCI_DEVICE(0x1c58, 0x0003), which needs the * NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was * found empirically.
*/ #define NVME_QUIRK_DELAY_AMOUNT 2300
/* * enum nvme_ctrl_state: Controller state * * @NVME_CTRL_NEW: New controller just allocated, initial state * @NVME_CTRL_LIVE: Controller is connected and I/O capable * @NVME_CTRL_RESETTING: Controller is resetting (or scheduled reset) * @NVME_CTRL_CONNECTING: Controller is disconnected, now connecting the * transport * @NVME_CTRL_DELETING: Controller is deleting (or scheduled deletion) * @NVME_CTRL_DELETING_NOIO: Controller is deleting and I/O is not * disabled/failed immediately. This state comes * after all async event processing took place and * before ns removal and the controller deletion * progress * @NVME_CTRL_DEAD: Controller is non-present/unresponsive during * shutdown or removal. In this case we forcibly * kill all inflight I/O as they have no chance to * complete
*/ enum nvme_ctrl_state {
NVME_CTRL_NEW,
NVME_CTRL_LIVE,
NVME_CTRL_RESETTING,
NVME_CTRL_CONNECTING,
NVME_CTRL_DELETING,
NVME_CTRL_DELETING_NOIO,
NVME_CTRL_DEAD,
};
struct nvme_fault_inject { #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS struct fault_attr attr; struct dentry *parent; bool dont_retry; /* DNR, do not retry */
u16 status; /* status code */ #endif
};
/* * Anchor structure for namespaces. There is one for each namespace in a * NVMe subsystem that any of our controllers can see, and the namespace * structure for each controller is chained of it. For private namespaces * there is a 1:1 relation to our namespace structures, that is ->list * only ever has a single entry for private namespaces.
*/ struct nvme_ns_head { struct list_head list; struct srcu_struct srcu; struct nvme_subsystem *subsys; struct nvme_ns_ids ids;
u8 lba_shift;
u16 ms;
u16 pi_size;
u8 pi_type;
u8 guard_type; struct list_head entry; struct kref ref; bool shared; bool rotational; bool passthru_err_log_enabled; struct nvme_effects_log *effects;
u64 nuse; unsigned ns_id; int instance; #ifdef CONFIG_BLK_DEV_ZONED
u64 zsze; #endif unsignedlong features;
/* * Return the length of the string without the space padding
*/ staticinlineint nvme_strlen(char *s, int len)
{ while (s[len - 1] == ' ')
len--; return len;
}
staticinlinebool nvme_is_ana_error(u16 status)
{ switch (status & NVME_SCT_SC_MASK) { case NVME_SC_ANA_TRANSITION: case NVME_SC_ANA_INACCESSIBLE: case NVME_SC_ANA_PERSISTENT_LOSS: returntrue; default: returnfalse;
}
}
staticinlinebool nvme_is_path_error(u16 status)
{ /* check for a status code type of 'path related status' */ return (status & NVME_SCT_MASK) == NVME_SCT_PATH;
}
/* * Fill in the status and result information from the CQE, and then figure out * if blk-mq will need to use IPI magic to complete the request, and if yes do * so. If not let the caller complete the request without an indirect function * call.
*/ staticinlinebool nvme_try_complete_req(struct request *req, __le16 status, union nvme_result result)
{ struct nvme_request *rq = nvme_req(req); struct nvme_ctrl *ctrl = rq->ctrl;
if (!(ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN))
rq->genctr++;
rq->status = le16_to_cpu(status) >> 1;
rq->result = result; /* inject error when permitted by fault injection framework */
nvme_should_fail(req); if (unlikely(blk_should_fake_timeout(req->q))) returntrue; return blk_mq_complete_request_remote(req);
}
/* * Returns true for sink states that can't ever transition back to live.
*/ staticinlinebool nvme_state_terminal(struct nvme_ctrl *ctrl)
{ switch (nvme_ctrl_state(ctrl)) { case NVME_CTRL_NEW: case NVME_CTRL_LIVE: case NVME_CTRL_RESETTING: case NVME_CTRL_CONNECTING: returnfalse; case NVME_CTRL_DELETING: case NVME_CTRL_DELETING_NOIO: case NVME_CTRL_DEAD: returntrue; default:
WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state); returntrue;
}
}
if (likely(state == NVME_CTRL_LIVE)) returntrue; if (ctrl->ops->flags & NVME_F_FABRICS && state == NVME_CTRL_DELETING) return queue_live; return __nvme_check_ready(ctrl, rq, queue_live, state);
}
/* * NSID shall be unique for all shared namespaces, or if at least one of the * following conditions is met: * 1. Namespace Management is supported by the controller * 2. ANA is supported by the controller * 3. NVM Set are supported by the controller * * In other case, private namespace are not required to report a unique NSID.
*/ staticinlinebool nvme_is_unique_nsid(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
{ return head->shared ||
(ctrl->oacs & NVME_CTRL_OACS_NS_MNGT_SUPP) ||
(ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA) ||
(ctrl->ctratt & NVME_CTRL_CTRATT_NVM_SETS);
}
/* * Flags for __nvme_submit_sync_cmd()
*/ typedef __u32 __bitwise nvme_submit_flags_t;
enum { /* Insert request at the head of the queue */
NVME_SUBMIT_AT_HEAD = (__force nvme_submit_flags_t)(1 << 0), /* Set BLK_MQ_REQ_NOWAIT when allocating request */
NVME_SUBMIT_NOWAIT = (__force nvme_submit_flags_t)(1 << 1), /* Set BLK_MQ_REQ_RESERVED when allocating request */
NVME_SUBMIT_RESERVED = (__force nvme_submit_flags_t)(1 << 2), /* Retry command when NVME_STATUS_DNR is not set in the result */
NVME_SUBMIT_RETRY = (__force nvme_submit_flags_t)(1 << 3),
};
int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, void *buf, unsigned bufflen); int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, union nvme_result *result, void *buffer, unsigned bufflen, int qid, nvme_submit_flags_t flags); int nvme_set_features(struct nvme_ctrl *dev, unsignedint fid, unsignedint dword11, void *buffer, size_t buflen, void *result); int nvme_get_features(struct nvme_ctrl *dev, unsignedint fid, unsignedint dword11, void *buffer, size_t buflen, void *result); int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); void nvme_queue_scan(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, void *log, size_t size, u64 offset); bool nvme_tryget_ns_head(struct nvme_ns_head *head); void nvme_put_ns_head(struct nvme_ns_head *head); int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device, conststruct file_operations *fops, struct module *owner); void nvme_cdev_del(struct cdev *cdev, struct device *cdev_device); int nvme_ioctl(struct block_device *bdev, blk_mode_t mode, unsignedint cmd, unsignedlong arg); long nvme_ns_chr_ioctl(struct file *file, unsignedint cmd, unsignedlong arg); int nvme_ns_head_ioctl(struct block_device *bdev, blk_mode_t mode, unsignedint cmd, unsignedlong arg); long nvme_ns_head_chr_ioctl(struct file *file, unsignedint cmd, unsignedlong arg); long nvme_dev_ioctl(struct file *file, unsignedint cmd, unsignedlong arg); int nvme_ns_chr_uring_cmd_iopoll(struct io_uring_cmd *ioucmd, struct io_comp_batch *iob, unsignedint poll_flags); int nvme_ns_chr_uring_cmd(struct io_uring_cmd *ioucmd, unsignedint issue_flags); int nvme_ns_head_chr_uring_cmd(struct io_uring_cmd *ioucmd, unsignedint issue_flags); int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, struct nvme_id_ns **id); int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo); int nvme_dev_uring_cmd(struct io_uring_cmd *ioucmd, unsignedint issue_flags);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.