xref: /openbmc/linux/drivers/nvme/host/nvme.h (revision 7fd8930f)
157dacad5SJay Sternberg /*
257dacad5SJay Sternberg  * Copyright (c) 2011-2014, Intel Corporation.
357dacad5SJay Sternberg  *
457dacad5SJay Sternberg  * This program is free software; you can redistribute it and/or modify it
557dacad5SJay Sternberg  * under the terms and conditions of the GNU General Public License,
657dacad5SJay Sternberg  * version 2, as published by the Free Software Foundation.
757dacad5SJay Sternberg  *
857dacad5SJay Sternberg  * This program is distributed in the hope it will be useful, but WITHOUT
957dacad5SJay Sternberg  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1057dacad5SJay Sternberg  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1157dacad5SJay Sternberg  * more details.
1257dacad5SJay Sternberg  */
1357dacad5SJay Sternberg 
1457dacad5SJay Sternberg #ifndef _NVME_H
1557dacad5SJay Sternberg #define _NVME_H
1657dacad5SJay Sternberg 
1757dacad5SJay Sternberg #include <linux/nvme.h>
1857dacad5SJay Sternberg #include <linux/pci.h>
1957dacad5SJay Sternberg #include <linux/kref.h>
2057dacad5SJay Sternberg #include <linux/blk-mq.h>
2157dacad5SJay Sternberg 
221673f1f0SChristoph Hellwig struct nvme_passthru_cmd;
231673f1f0SChristoph Hellwig 
2457dacad5SJay Sternberg extern unsigned char nvme_io_timeout;
2557dacad5SJay Sternberg #define NVME_IO_TIMEOUT	(nvme_io_timeout * HZ)
2657dacad5SJay Sternberg 
2721d34711SChristoph Hellwig extern unsigned char admin_timeout;
2821d34711SChristoph Hellwig #define ADMIN_TIMEOUT	(admin_timeout * HZ)
2921d34711SChristoph Hellwig 
305fd4ce1bSChristoph Hellwig extern unsigned char shutdown_timeout;
315fd4ce1bSChristoph Hellwig #define SHUTDOWN_TIMEOUT	(shutdown_timeout * HZ)
325fd4ce1bSChristoph Hellwig 
33ca064085SMatias Bjørling enum {
34ca064085SMatias Bjørling 	NVME_NS_LBA		= 0,
35ca064085SMatias Bjørling 	NVME_NS_LIGHTNVM	= 1,
36ca064085SMatias Bjørling };
37ca064085SMatias Bjørling 
38106198edSChristoph Hellwig /*
39106198edSChristoph Hellwig  * List of workarounds for devices that required behavior not specified in
40106198edSChristoph Hellwig  * the standard.
41106198edSChristoph Hellwig  */
42106198edSChristoph Hellwig enum nvme_quirks {
43106198edSChristoph Hellwig 	/*
44106198edSChristoph Hellwig 	 * Prefers I/O aligned to a stripe size specified in a vendor
45106198edSChristoph Hellwig 	 * specific Identify field.
46106198edSChristoph Hellwig 	 */
47106198edSChristoph Hellwig 	NVME_QUIRK_STRIPE_SIZE			= (1 << 0),
48106198edSChristoph Hellwig };
49106198edSChristoph Hellwig 
501c63dc66SChristoph Hellwig struct nvme_ctrl {
511c63dc66SChristoph Hellwig 	const struct nvme_ctrl_ops *ops;
5257dacad5SJay Sternberg 	struct request_queue *admin_q;
5357dacad5SJay Sternberg 	struct device *dev;
541673f1f0SChristoph Hellwig 	struct kref kref;
5557dacad5SJay Sternberg 	int instance;
561c63dc66SChristoph Hellwig 
5757dacad5SJay Sternberg 	char name[12];
5857dacad5SJay Sternberg 	char serial[20];
5957dacad5SJay Sternberg 	char model[40];
6057dacad5SJay Sternberg 	char firmware_rev[8];
615fd4ce1bSChristoph Hellwig 
625fd4ce1bSChristoph Hellwig 	u32 ctrl_config;
635fd4ce1bSChristoph Hellwig 
645fd4ce1bSChristoph Hellwig 	u32 page_size;
657fd8930fSChristoph Hellwig 	u32 max_hw_sectors;
667fd8930fSChristoph Hellwig 	u32 stripe_size;
6757dacad5SJay Sternberg 	u16 oncs;
6857dacad5SJay Sternberg 	u16 abort_limit;
6957dacad5SJay Sternberg 	u8 event_limit;
7057dacad5SJay Sternberg 	u8 vwc;
71106198edSChristoph Hellwig 	unsigned long quirks;
7257dacad5SJay Sternberg };
7357dacad5SJay Sternberg 
7457dacad5SJay Sternberg /*
7557dacad5SJay Sternberg  * An NVM Express namespace is equivalent to a SCSI LUN
7657dacad5SJay Sternberg  */
7757dacad5SJay Sternberg struct nvme_ns {
7857dacad5SJay Sternberg 	struct list_head list;
7957dacad5SJay Sternberg 
801c63dc66SChristoph Hellwig 	struct nvme_ctrl *ctrl;
8157dacad5SJay Sternberg 	struct request_queue *queue;
8257dacad5SJay Sternberg 	struct gendisk *disk;
8357dacad5SJay Sternberg 	struct kref kref;
8457dacad5SJay Sternberg 
8557dacad5SJay Sternberg 	unsigned ns_id;
8657dacad5SJay Sternberg 	int lba_shift;
8757dacad5SJay Sternberg 	u16 ms;
8857dacad5SJay Sternberg 	bool ext;
8957dacad5SJay Sternberg 	u8 pi_type;
90ca064085SMatias Bjørling 	int type;
9157dacad5SJay Sternberg 	u64 mode_select_num_blocks;
9257dacad5SJay Sternberg 	u32 mode_select_block_len;
9357dacad5SJay Sternberg };
9457dacad5SJay Sternberg 
951c63dc66SChristoph Hellwig struct nvme_ctrl_ops {
961c63dc66SChristoph Hellwig 	int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
975fd4ce1bSChristoph Hellwig 	int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
987fd8930fSChristoph Hellwig 	int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
991673f1f0SChristoph Hellwig 	void (*free_ctrl)(struct nvme_ctrl *ctrl);
1001c63dc66SChristoph Hellwig };
1011c63dc66SChristoph Hellwig 
1021c63dc66SChristoph Hellwig static inline bool nvme_ctrl_ready(struct nvme_ctrl *ctrl)
1031c63dc66SChristoph Hellwig {
1041c63dc66SChristoph Hellwig 	u32 val = 0;
1051c63dc66SChristoph Hellwig 
1061c63dc66SChristoph Hellwig 	if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
1071c63dc66SChristoph Hellwig 		return false;
1081c63dc66SChristoph Hellwig 	return val & NVME_CSTS_RDY;
1091c63dc66SChristoph Hellwig }
1101c63dc66SChristoph Hellwig 
11157dacad5SJay Sternberg static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector)
11257dacad5SJay Sternberg {
11357dacad5SJay Sternberg 	return (sector >> (ns->lba_shift - 9));
11457dacad5SJay Sternberg }
11557dacad5SJay Sternberg 
11622944e99SChristoph Hellwig static inline void nvme_setup_flush(struct nvme_ns *ns,
11722944e99SChristoph Hellwig 		struct nvme_command *cmnd)
11822944e99SChristoph Hellwig {
11922944e99SChristoph Hellwig 	memset(cmnd, 0, sizeof(*cmnd));
12022944e99SChristoph Hellwig 	cmnd->common.opcode = nvme_cmd_flush;
12122944e99SChristoph Hellwig 	cmnd->common.nsid = cpu_to_le32(ns->ns_id);
12222944e99SChristoph Hellwig }
12322944e99SChristoph Hellwig 
12422944e99SChristoph Hellwig static inline void nvme_setup_rw(struct nvme_ns *ns, struct request *req,
12522944e99SChristoph Hellwig 		struct nvme_command *cmnd)
12622944e99SChristoph Hellwig {
12722944e99SChristoph Hellwig 	u16 control = 0;
12822944e99SChristoph Hellwig 	u32 dsmgmt = 0;
12922944e99SChristoph Hellwig 
13022944e99SChristoph Hellwig 	if (req->cmd_flags & REQ_FUA)
13122944e99SChristoph Hellwig 		control |= NVME_RW_FUA;
13222944e99SChristoph Hellwig 	if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
13322944e99SChristoph Hellwig 		control |= NVME_RW_LR;
13422944e99SChristoph Hellwig 
13522944e99SChristoph Hellwig 	if (req->cmd_flags & REQ_RAHEAD)
13622944e99SChristoph Hellwig 		dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
13722944e99SChristoph Hellwig 
13822944e99SChristoph Hellwig 	memset(cmnd, 0, sizeof(*cmnd));
13922944e99SChristoph Hellwig 	cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
14022944e99SChristoph Hellwig 	cmnd->rw.command_id = req->tag;
14122944e99SChristoph Hellwig 	cmnd->rw.nsid = cpu_to_le32(ns->ns_id);
14222944e99SChristoph Hellwig 	cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
14322944e99SChristoph Hellwig 	cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
14422944e99SChristoph Hellwig 
14522944e99SChristoph Hellwig 	if (ns->ms) {
14622944e99SChristoph Hellwig 		switch (ns->pi_type) {
14722944e99SChristoph Hellwig 		case NVME_NS_DPS_PI_TYPE3:
14822944e99SChristoph Hellwig 			control |= NVME_RW_PRINFO_PRCHK_GUARD;
14922944e99SChristoph Hellwig 			break;
15022944e99SChristoph Hellwig 		case NVME_NS_DPS_PI_TYPE1:
15122944e99SChristoph Hellwig 		case NVME_NS_DPS_PI_TYPE2:
15222944e99SChristoph Hellwig 			control |= NVME_RW_PRINFO_PRCHK_GUARD |
15322944e99SChristoph Hellwig 					NVME_RW_PRINFO_PRCHK_REF;
15422944e99SChristoph Hellwig 			cmnd->rw.reftag = cpu_to_le32(
15522944e99SChristoph Hellwig 					nvme_block_nr(ns, blk_rq_pos(req)));
15622944e99SChristoph Hellwig 			break;
15722944e99SChristoph Hellwig 		}
15822944e99SChristoph Hellwig 		if (!blk_integrity_rq(req))
15922944e99SChristoph Hellwig 			control |= NVME_RW_PRINFO_PRACT;
16022944e99SChristoph Hellwig 	}
16122944e99SChristoph Hellwig 
16222944e99SChristoph Hellwig 	cmnd->rw.control = cpu_to_le16(control);
16322944e99SChristoph Hellwig 	cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
16422944e99SChristoph Hellwig }
16522944e99SChristoph Hellwig 
16622944e99SChristoph Hellwig 
16715a190f7SChristoph Hellwig static inline int nvme_error_status(u16 status)
16815a190f7SChristoph Hellwig {
16915a190f7SChristoph Hellwig 	switch (status & 0x7ff) {
17015a190f7SChristoph Hellwig 	case NVME_SC_SUCCESS:
17115a190f7SChristoph Hellwig 		return 0;
17215a190f7SChristoph Hellwig 	case NVME_SC_CAP_EXCEEDED:
17315a190f7SChristoph Hellwig 		return -ENOSPC;
17415a190f7SChristoph Hellwig 	default:
17515a190f7SChristoph Hellwig 		return -EIO;
17615a190f7SChristoph Hellwig 	}
17715a190f7SChristoph Hellwig }
17815a190f7SChristoph Hellwig 
1795fd4ce1bSChristoph Hellwig int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
1805fd4ce1bSChristoph Hellwig int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
1815fd4ce1bSChristoph Hellwig int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
1821673f1f0SChristoph Hellwig void nvme_put_ctrl(struct nvme_ctrl *ctrl);
1837fd8930fSChristoph Hellwig int nvme_init_identify(struct nvme_ctrl *ctrl);
1841673f1f0SChristoph Hellwig void nvme_put_ns(struct nvme_ns *ns);
1851673f1f0SChristoph Hellwig 
1864160982eSChristoph Hellwig struct request *nvme_alloc_request(struct request_queue *q,
1874160982eSChristoph Hellwig 		struct nvme_command *cmd, unsigned int flags);
18857dacad5SJay Sternberg int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
18957dacad5SJay Sternberg 		void *buf, unsigned bufflen);
19057dacad5SJay Sternberg int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
1914160982eSChristoph Hellwig 		void *buffer, unsigned bufflen,  u32 *result, unsigned timeout);
1924160982eSChristoph Hellwig int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
1934160982eSChristoph Hellwig 		void __user *ubuffer, unsigned bufflen, u32 *result,
1944160982eSChristoph Hellwig 		unsigned timeout);
1950b7f1f26SKeith Busch int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
1960b7f1f26SKeith Busch 		void __user *ubuffer, unsigned bufflen,
1970b7f1f26SKeith Busch 		void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
1980b7f1f26SKeith Busch 		u32 *result, unsigned timeout);
1991c63dc66SChristoph Hellwig int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id);
2001c63dc66SChristoph Hellwig int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
20157dacad5SJay Sternberg 		struct nvme_id_ns **id);
2021c63dc66SChristoph Hellwig int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log);
2031c63dc66SChristoph Hellwig int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
20457dacad5SJay Sternberg 			dma_addr_t dma_addr, u32 *result);
2051c63dc66SChristoph Hellwig int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
20657dacad5SJay Sternberg 			dma_addr_t dma_addr, u32 *result);
20757dacad5SJay Sternberg 
2081673f1f0SChristoph Hellwig extern const struct block_device_operations nvme_fops;
2091673f1f0SChristoph Hellwig extern spinlock_t dev_list_lock;
2101673f1f0SChristoph Hellwig 
2111673f1f0SChristoph Hellwig int nvme_revalidate_disk(struct gendisk *disk);
2121673f1f0SChristoph Hellwig int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
2131673f1f0SChristoph Hellwig 			struct nvme_passthru_cmd __user *ucmd);
2141673f1f0SChristoph Hellwig 
21557dacad5SJay Sternberg struct sg_io_hdr;
21657dacad5SJay Sternberg 
21757dacad5SJay Sternberg int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr);
21857dacad5SJay Sternberg int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg);
21957dacad5SJay Sternberg int nvme_sg_get_version_num(int __user *ip);
22057dacad5SJay Sternberg 
221ca064085SMatias Bjørling int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id);
222ca064085SMatias Bjørling int nvme_nvm_register(struct request_queue *q, char *disk_name);
223ca064085SMatias Bjørling void nvme_nvm_unregister(struct request_queue *q, char *disk_name);
224ca064085SMatias Bjørling 
22557dacad5SJay Sternberg #endif /* _NVME_H */
226