mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'for-4.5/nvme' of git://git.kernel.dk/linux-block
Pull NVMe updates from Jens Axboe: "Last branch for this series is the nvme changes. It's in a separate branch to avoid splitting too much between core and NVMe changes, since NVMe is still helping drive some blk-mq changes. That said, not a huge amount of core changes in here. The grunt of the work is the continued split of the code" * 'for-4.5/nvme' of git://git.kernel.dk/linux-block: (67 commits) uapi: update install list after nvme.h rename NVMe: Export NVMe attributes to sysfs group NVMe: Shutdown controller only for power-off NVMe: IO queue deletion re-write NVMe: Remove queue freezing on resets NVMe: Use a retryable error code on reset NVMe: Fix admin queue ring wrap nvme: make SG_IO support optional nvme: fixes for NVME_IOCTL_IO_CMD on the char device nvme: synchronize access to ctrl->namespaces nvme: Move nvme_freeze/unfreeze_queues to nvme core PCI/AER: include header file NVMe: Export namespace attributes to sysfs NVMe: Add pci error handlers block: remove REQ_NO_TIMEOUT flag nvme: merge iod and cmd_info nvme: meta_sg doesn't have to be an array nvme: properly free resources for cancelled command nvme: simplify completion handling nvme: special case AEN requests ...
This commit is contained in:
commit
3e1e21c7bf
19 changed files with 2608 additions and 2209 deletions
|
|
@ -8,3 +8,14 @@ config BLK_DEV_NVME
|
|||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called nvme.
|
||||
|
||||
config BLK_DEV_NVME_SCSI
|
||||
bool "SCSI emulation for NVMe device nodes"
|
||||
depends on BLK_DEV_NVME
|
||||
---help---
|
||||
This adds support for the SG_IO ioctl on the NVMe character
|
||||
and block devices nodes, as well a a translation for a small
|
||||
number of selected SCSI commands to NVMe commands to the NVMe
|
||||
driver. If you don't know what this means you probably want
|
||||
to say N here, and if you know what it means you probably
|
||||
want to say N as well.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
obj-$(CONFIG_BLK_DEV_NVME) += nvme.o
|
||||
|
||||
lightnvm-$(CONFIG_NVM) := lightnvm.o
|
||||
nvme-y += pci.o scsi.o $(lightnvm-y)
|
||||
lightnvm-$(CONFIG_NVM) := lightnvm.o
|
||||
nvme-y += core.o pci.o $(lightnvm-y)
|
||||
nvme-$(CONFIG_BLK_DEV_NVME_SCSI) += scsi.o
|
||||
|
|
|
|||
1472
drivers/nvme/host/core.c
Normal file
1472
drivers/nvme/host/core.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -294,7 +294,6 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
|
|||
static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
|
||||
{
|
||||
struct nvme_ns *ns = nvmdev->q->queuedata;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_nvm_id *nvme_nvm_id;
|
||||
struct nvme_nvm_command c = {};
|
||||
int ret;
|
||||
|
|
@ -307,7 +306,7 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
|
|||
if (!nvme_nvm_id)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
|
||||
ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
|
||||
nvme_nvm_id, sizeof(struct nvme_nvm_id));
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
|
|
@ -332,9 +331,8 @@ static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
|
|||
nvm_l2p_update_fn *update_l2p, void *priv)
|
||||
{
|
||||
struct nvme_ns *ns = nvmdev->q->queuedata;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_nvm_command c = {};
|
||||
u32 len = queue_max_hw_sectors(dev->admin_q) << 9;
|
||||
u32 len = queue_max_hw_sectors(ns->ctrl->admin_q) << 9;
|
||||
u32 nlb_pr_rq = len / sizeof(u64);
|
||||
u64 cmd_slba = slba;
|
||||
void *entries;
|
||||
|
|
@ -352,10 +350,10 @@ static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
|
|||
c.l2p.slba = cpu_to_le64(cmd_slba);
|
||||
c.l2p.nlb = cpu_to_le32(cmd_nlb);
|
||||
|
||||
ret = nvme_submit_sync_cmd(dev->admin_q,
|
||||
ret = nvme_submit_sync_cmd(ns->ctrl->admin_q,
|
||||
(struct nvme_command *)&c, entries, len);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "L2P table transfer failed (%d)\n",
|
||||
dev_err(ns->ctrl->dev, "L2P table transfer failed (%d)\n",
|
||||
ret);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
|
|
@ -381,7 +379,7 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
|
|||
{
|
||||
struct request_queue *q = nvmdev->q;
|
||||
struct nvme_ns *ns = q->queuedata;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
struct nvme_nvm_command c = {};
|
||||
struct nvme_nvm_bb_tbl *bb_tbl;
|
||||
int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blocks;
|
||||
|
|
@ -395,30 +393,30 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
|
|||
if (!bb_tbl)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
|
||||
ret = nvme_submit_sync_cmd(ctrl->admin_q, (struct nvme_command *)&c,
|
||||
bb_tbl, tblsz);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "get bad block table failed (%d)\n", ret);
|
||||
dev_err(ctrl->dev, "get bad block table failed (%d)\n", ret);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bb_tbl->tblid[0] != 'B' || bb_tbl->tblid[1] != 'B' ||
|
||||
bb_tbl->tblid[2] != 'L' || bb_tbl->tblid[3] != 'T') {
|
||||
dev_err(dev->dev, "bbt format mismatch\n");
|
||||
dev_err(ctrl->dev, "bbt format mismatch\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(bb_tbl->verid) != 1) {
|
||||
ret = -EINVAL;
|
||||
dev_err(dev->dev, "bbt version not supported\n");
|
||||
dev_err(ctrl->dev, "bbt version not supported\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(bb_tbl->tblks) != nr_blocks) {
|
||||
ret = -EINVAL;
|
||||
dev_err(dev->dev, "bbt unsuspected blocks returned (%u!=%u)",
|
||||
dev_err(ctrl->dev, "bbt unsuspected blocks returned (%u!=%u)",
|
||||
le32_to_cpu(bb_tbl->tblks), nr_blocks);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -434,7 +432,6 @@ static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
|
|||
int type)
|
||||
{
|
||||
struct nvme_ns *ns = nvmdev->q->queuedata;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_nvm_command c = {};
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -444,10 +441,10 @@ static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
|
|||
c.set_bb.nlb = cpu_to_le16(rqd->nr_pages - 1);
|
||||
c.set_bb.value = type;
|
||||
|
||||
ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
|
||||
ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
|
||||
NULL, 0);
|
||||
if (ret)
|
||||
dev_err(dev->dev, "set bad block table failed (%d)\n", ret);
|
||||
dev_err(ns->ctrl->dev, "set bad block table failed (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -532,9 +529,8 @@ static int nvme_nvm_erase_block(struct nvm_dev *dev, struct nvm_rq *rqd)
|
|||
static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name)
|
||||
{
|
||||
struct nvme_ns *ns = nvmdev->q->queuedata;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
|
||||
return dma_pool_create(name, dev->dev, PAGE_SIZE, PAGE_SIZE, 0);
|
||||
return dma_pool_create(name, ns->ctrl->dev, PAGE_SIZE, PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
static void nvme_nvm_destroy_dma_pool(void *pool)
|
||||
|
|
@ -592,8 +588,9 @@ void nvme_nvm_unregister(struct request_queue *q, char *disk_name)
|
|||
|
||||
int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
|
||||
{
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
/* XXX: this is poking into PCI structures from generic code! */
|
||||
struct pci_dev *pdev = to_pci_dev(ctrl->dev);
|
||||
|
||||
/* QEMU NVMe simulator - PCI ID + Vendor specific bit */
|
||||
if (pdev->vendor == PCI_VENDOR_ID_CNEX &&
|
||||
|
|
|
|||
|
|
@ -19,58 +19,77 @@
|
|||
#include <linux/kref.h>
|
||||
#include <linux/blk-mq.h>
|
||||
|
||||
enum {
|
||||
/*
|
||||
* Driver internal status code for commands that were cancelled due
|
||||
* to timeouts or controller shutdown. The value is negative so
|
||||
* that it a) doesn't overlap with the unsigned hardware error codes,
|
||||
* and b) can easily be tested for.
|
||||
*/
|
||||
NVME_SC_CANCELLED = -EINTR,
|
||||
};
|
||||
|
||||
extern unsigned char nvme_io_timeout;
|
||||
#define NVME_IO_TIMEOUT (nvme_io_timeout * HZ)
|
||||
|
||||
extern unsigned char admin_timeout;
|
||||
#define ADMIN_TIMEOUT (admin_timeout * HZ)
|
||||
|
||||
extern unsigned char shutdown_timeout;
|
||||
#define SHUTDOWN_TIMEOUT (shutdown_timeout * HZ)
|
||||
|
||||
enum {
|
||||
NVME_NS_LBA = 0,
|
||||
NVME_NS_LIGHTNVM = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents an NVM Express device. Each nvme_dev is a PCI function.
|
||||
* List of workarounds for devices that required behavior not specified in
|
||||
* the standard.
|
||||
*/
|
||||
struct nvme_dev {
|
||||
struct list_head node;
|
||||
struct nvme_queue **queues;
|
||||
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),
|
||||
};
|
||||
|
||||
struct nvme_ctrl {
|
||||
const struct nvme_ctrl_ops *ops;
|
||||
struct request_queue *admin_q;
|
||||
struct blk_mq_tag_set tagset;
|
||||
struct blk_mq_tag_set admin_tagset;
|
||||
u32 __iomem *dbs;
|
||||
struct device *dev;
|
||||
struct dma_pool *prp_page_pool;
|
||||
struct dma_pool *prp_small_pool;
|
||||
int instance;
|
||||
unsigned queue_count;
|
||||
unsigned online_queues;
|
||||
unsigned max_qid;
|
||||
int q_depth;
|
||||
u32 db_stride;
|
||||
u32 ctrl_config;
|
||||
struct msix_entry *entry;
|
||||
struct nvme_bar __iomem *bar;
|
||||
struct list_head namespaces;
|
||||
struct kref kref;
|
||||
struct device *device;
|
||||
struct work_struct reset_work;
|
||||
struct work_struct probe_work;
|
||||
struct work_struct scan_work;
|
||||
int instance;
|
||||
struct blk_mq_tag_set *tagset;
|
||||
struct list_head namespaces;
|
||||
struct mutex namespaces_mutex;
|
||||
struct device *device; /* char device */
|
||||
struct list_head node;
|
||||
|
||||
char name[12];
|
||||
char serial[20];
|
||||
char model[40];
|
||||
char firmware_rev[8];
|
||||
bool subsystem;
|
||||
|
||||
u32 ctrl_config;
|
||||
|
||||
u32 page_size;
|
||||
u32 max_hw_sectors;
|
||||
u32 stripe_size;
|
||||
u32 page_size;
|
||||
void __iomem *cmb;
|
||||
dma_addr_t cmb_dma_addr;
|
||||
u64 cmb_size;
|
||||
u32 cmbsz;
|
||||
u16 oncs;
|
||||
u16 abort_limit;
|
||||
atomic_t abort_limit;
|
||||
u8 event_limit;
|
||||
u8 vwc;
|
||||
u32 vs;
|
||||
bool subsystem;
|
||||
unsigned long quirks;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -79,11 +98,14 @@ struct nvme_dev {
|
|||
struct nvme_ns {
|
||||
struct list_head list;
|
||||
|
||||
struct nvme_dev *dev;
|
||||
struct nvme_ctrl *ctrl;
|
||||
struct request_queue *queue;
|
||||
struct gendisk *disk;
|
||||
struct kref kref;
|
||||
|
||||
u8 eui[8];
|
||||
u8 uuid[16];
|
||||
|
||||
unsigned ns_id;
|
||||
int lba_shift;
|
||||
u16 ms;
|
||||
|
|
@ -94,41 +116,156 @@ struct nvme_ns {
|
|||
u32 mode_select_block_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* The nvme_iod describes the data in an I/O, including the list of PRP
|
||||
* entries. You can't see it in this data structure because C doesn't let
|
||||
* me express that. Use nvme_alloc_iod to ensure there's enough space
|
||||
* allocated to store the PRP list.
|
||||
*/
|
||||
struct nvme_iod {
|
||||
unsigned long private; /* For the use of the submitter of the I/O */
|
||||
int npages; /* In the PRP list. 0 means small pool in use */
|
||||
int offset; /* Of PRP list */
|
||||
int nents; /* Used in scatterlist */
|
||||
int length; /* Of data, in bytes */
|
||||
dma_addr_t first_dma;
|
||||
struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */
|
||||
struct scatterlist sg[0];
|
||||
struct nvme_ctrl_ops {
|
||||
int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
|
||||
int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
|
||||
int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
|
||||
bool (*io_incapable)(struct nvme_ctrl *ctrl);
|
||||
int (*reset_ctrl)(struct nvme_ctrl *ctrl);
|
||||
void (*free_ctrl)(struct nvme_ctrl *ctrl);
|
||||
};
|
||||
|
||||
static inline bool nvme_ctrl_ready(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
|
||||
return false;
|
||||
return val & NVME_CSTS_RDY;
|
||||
}
|
||||
|
||||
static inline bool nvme_io_incapable(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if (ctrl->ops->io_incapable(ctrl))
|
||||
return false;
|
||||
if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
|
||||
return false;
|
||||
return val & NVME_CSTS_CFS;
|
||||
}
|
||||
|
||||
static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
if (!ctrl->subsystem)
|
||||
return -ENOTTY;
|
||||
return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
|
||||
}
|
||||
|
||||
static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector)
|
||||
{
|
||||
return (sector >> (ns->lba_shift - 9));
|
||||
}
|
||||
|
||||
static inline void nvme_setup_flush(struct nvme_ns *ns,
|
||||
struct nvme_command *cmnd)
|
||||
{
|
||||
memset(cmnd, 0, sizeof(*cmnd));
|
||||
cmnd->common.opcode = nvme_cmd_flush;
|
||||
cmnd->common.nsid = cpu_to_le32(ns->ns_id);
|
||||
}
|
||||
|
||||
static inline void nvme_setup_rw(struct nvme_ns *ns, struct request *req,
|
||||
struct nvme_command *cmnd)
|
||||
{
|
||||
u16 control = 0;
|
||||
u32 dsmgmt = 0;
|
||||
|
||||
if (req->cmd_flags & REQ_FUA)
|
||||
control |= NVME_RW_FUA;
|
||||
if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
|
||||
control |= NVME_RW_LR;
|
||||
|
||||
if (req->cmd_flags & REQ_RAHEAD)
|
||||
dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
|
||||
|
||||
memset(cmnd, 0, sizeof(*cmnd));
|
||||
cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
|
||||
cmnd->rw.command_id = req->tag;
|
||||
cmnd->rw.nsid = cpu_to_le32(ns->ns_id);
|
||||
cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
|
||||
cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
|
||||
|
||||
if (ns->ms) {
|
||||
switch (ns->pi_type) {
|
||||
case NVME_NS_DPS_PI_TYPE3:
|
||||
control |= NVME_RW_PRINFO_PRCHK_GUARD;
|
||||
break;
|
||||
case NVME_NS_DPS_PI_TYPE1:
|
||||
case NVME_NS_DPS_PI_TYPE2:
|
||||
control |= NVME_RW_PRINFO_PRCHK_GUARD |
|
||||
NVME_RW_PRINFO_PRCHK_REF;
|
||||
cmnd->rw.reftag = cpu_to_le32(
|
||||
nvme_block_nr(ns, blk_rq_pos(req)));
|
||||
break;
|
||||
}
|
||||
if (!blk_integrity_rq(req))
|
||||
control |= NVME_RW_PRINFO_PRACT;
|
||||
}
|
||||
|
||||
cmnd->rw.control = cpu_to_le16(control);
|
||||
cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
|
||||
}
|
||||
|
||||
|
||||
static inline int nvme_error_status(u16 status)
|
||||
{
|
||||
switch (status & 0x7ff) {
|
||||
case NVME_SC_SUCCESS:
|
||||
return 0;
|
||||
case NVME_SC_CAP_EXCEEDED:
|
||||
return -ENOSPC;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool nvme_req_needs_retry(struct request *req, u16 status)
|
||||
{
|
||||
return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
|
||||
(jiffies - req->start_time) < req->timeout;
|
||||
}
|
||||
|
||||
int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
|
||||
int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
|
||||
int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
|
||||
int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
|
||||
const struct nvme_ctrl_ops *ops, unsigned long quirks);
|
||||
void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
|
||||
void nvme_put_ctrl(struct nvme_ctrl *ctrl);
|
||||
int nvme_init_identify(struct nvme_ctrl *ctrl);
|
||||
|
||||
void nvme_scan_namespaces(struct nvme_ctrl *ctrl);
|
||||
void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
|
||||
|
||||
void nvme_stop_queues(struct nvme_ctrl *ctrl);
|
||||
void nvme_start_queues(struct nvme_ctrl *ctrl);
|
||||
|
||||
struct request *nvme_alloc_request(struct request_queue *q,
|
||||
struct nvme_command *cmd, unsigned int flags);
|
||||
void nvme_requeue_req(struct request *req);
|
||||
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,
|
||||
void *buffer, void __user *ubuffer, unsigned bufflen,
|
||||
void *buffer, unsigned bufflen, u32 *result, unsigned timeout);
|
||||
int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
|
||||
void __user *ubuffer, unsigned bufflen, u32 *result,
|
||||
unsigned timeout);
|
||||
int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
|
||||
void __user *ubuffer, unsigned bufflen,
|
||||
void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
|
||||
u32 *result, unsigned timeout);
|
||||
int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id);
|
||||
int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
|
||||
int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id);
|
||||
int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
|
||||
struct nvme_id_ns **id);
|
||||
int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log);
|
||||
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
||||
int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log);
|
||||
int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
|
||||
dma_addr_t dma_addr, u32 *result);
|
||||
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
||||
int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
|
||||
dma_addr_t dma_addr, u32 *result);
|
||||
int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
|
||||
|
||||
extern spinlock_t dev_list_lock;
|
||||
|
||||
struct sg_io_hdr;
|
||||
|
||||
|
|
@ -154,4 +291,7 @@ static inline int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *i
|
|||
}
|
||||
#endif /* CONFIG_NVM */
|
||||
|
||||
int __init nvme_core_init(void);
|
||||
void nvme_core_exit(void);
|
||||
|
||||
#endif /* _NVME_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -524,7 +524,7 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
|
|||
struct sg_io_hdr *hdr, u8 *inq_response,
|
||||
int alloc_len)
|
||||
{
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
struct nvme_id_ns *id_ns;
|
||||
int res;
|
||||
int nvme_sc;
|
||||
|
|
@ -532,10 +532,10 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
|
|||
u8 resp_data_format = 0x02;
|
||||
u8 protect;
|
||||
u8 cmdque = 0x01 << 1;
|
||||
u8 fw_offset = sizeof(dev->firmware_rev);
|
||||
u8 fw_offset = sizeof(ctrl->firmware_rev);
|
||||
|
||||
/* nvme ns identify - use DPS value for PROTECT field */
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -553,12 +553,12 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
|
|||
inq_response[5] = protect; /* sccs=0 | acc=0 | tpgs=0 | pc3=0 */
|
||||
inq_response[7] = cmdque; /* wbus16=0 | sync=0 | vs=0 */
|
||||
strncpy(&inq_response[8], "NVMe ", 8);
|
||||
strncpy(&inq_response[16], dev->model, 16);
|
||||
strncpy(&inq_response[16], ctrl->model, 16);
|
||||
|
||||
while (dev->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
|
||||
while (ctrl->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
|
||||
fw_offset--;
|
||||
fw_offset -= 4;
|
||||
strncpy(&inq_response[32], dev->firmware_rev + fw_offset, 4);
|
||||
strncpy(&inq_response[32], ctrl->firmware_rev + fw_offset, 4);
|
||||
|
||||
xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
|
||||
return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
|
||||
|
|
@ -588,82 +588,113 @@ static int nvme_trans_unit_serial_page(struct nvme_ns *ns,
|
|||
struct sg_io_hdr *hdr, u8 *inq_response,
|
||||
int alloc_len)
|
||||
{
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
int xfer_len;
|
||||
|
||||
memset(inq_response, 0, STANDARD_INQUIRY_LENGTH);
|
||||
inq_response[1] = INQ_UNIT_SERIAL_NUMBER_PAGE; /* Page Code */
|
||||
inq_response[3] = INQ_SERIAL_NUMBER_LENGTH; /* Page Length */
|
||||
strncpy(&inq_response[4], dev->serial, INQ_SERIAL_NUMBER_LENGTH);
|
||||
strncpy(&inq_response[4], ns->ctrl->serial, INQ_SERIAL_NUMBER_LENGTH);
|
||||
|
||||
xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
|
||||
return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
|
||||
}
|
||||
|
||||
static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
u8 *inq_response, int alloc_len)
|
||||
static int nvme_fill_device_id_eui64(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
u8 *inq_response, int alloc_len)
|
||||
{
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
int res;
|
||||
int nvme_sc;
|
||||
int xfer_len;
|
||||
__be32 tmp_id = cpu_to_be32(ns->ns_id);
|
||||
struct nvme_id_ns *id_ns;
|
||||
int nvme_sc, res;
|
||||
size_t len;
|
||||
void *eui;
|
||||
|
||||
nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
eui = id_ns->eui64;
|
||||
len = sizeof(id_ns->eui64);
|
||||
|
||||
if (ns->ctrl->vs >= NVME_VS(1, 2)) {
|
||||
if (bitmap_empty(eui, len * 8)) {
|
||||
eui = id_ns->nguid;
|
||||
len = sizeof(id_ns->nguid);
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap_empty(eui, len * 8)) {
|
||||
res = -EOPNOTSUPP;
|
||||
goto out_free_id;
|
||||
}
|
||||
|
||||
memset(inq_response, 0, alloc_len);
|
||||
inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */
|
||||
if (readl(&dev->bar->vs) >= NVME_VS(1, 1)) {
|
||||
struct nvme_id_ns *id_ns;
|
||||
void *eui;
|
||||
int len;
|
||||
inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
|
||||
inq_response[3] = 4 + len; /* Page Length */
|
||||
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
/* Designation Descriptor start */
|
||||
inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
|
||||
inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */
|
||||
inq_response[6] = 0x00; /* Rsvd */
|
||||
inq_response[7] = len; /* Designator Length */
|
||||
memcpy(&inq_response[8], eui, len);
|
||||
|
||||
eui = id_ns->eui64;
|
||||
len = sizeof(id_ns->eui64);
|
||||
if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) {
|
||||
if (bitmap_empty(eui, len * 8)) {
|
||||
eui = id_ns->nguid;
|
||||
len = sizeof(id_ns->nguid);
|
||||
}
|
||||
}
|
||||
if (bitmap_empty(eui, len * 8)) {
|
||||
kfree(id_ns);
|
||||
goto scsi_string;
|
||||
}
|
||||
res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
|
||||
out_free_id:
|
||||
kfree(id_ns);
|
||||
return res;
|
||||
}
|
||||
|
||||
inq_response[3] = 4 + len; /* Page Length */
|
||||
/* Designation Descriptor start */
|
||||
inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
|
||||
inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */
|
||||
inq_response[6] = 0x00; /* Rsvd */
|
||||
inq_response[7] = len; /* Designator Length */
|
||||
memcpy(&inq_response[8], eui, len);
|
||||
kfree(id_ns);
|
||||
} else {
|
||||
scsi_string:
|
||||
if (alloc_len < 72) {
|
||||
return nvme_trans_completion(hdr,
|
||||
SAM_STAT_CHECK_CONDITION,
|
||||
ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
|
||||
SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
}
|
||||
inq_response[3] = 0x48; /* Page Length */
|
||||
/* Designation Descriptor start */
|
||||
inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */
|
||||
inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */
|
||||
inq_response[6] = 0x00; /* Rsvd */
|
||||
inq_response[7] = 0x44; /* Designator Length */
|
||||
static int nvme_fill_device_id_scsi_string(struct nvme_ns *ns,
|
||||
struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len)
|
||||
{
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
struct nvme_id_ctrl *id_ctrl;
|
||||
int nvme_sc, res;
|
||||
|
||||
sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor);
|
||||
memcpy(&inq_response[12], dev->model, sizeof(dev->model));
|
||||
sprintf(&inq_response[52], "%04x", tmp_id);
|
||||
memcpy(&inq_response[56], dev->serial, sizeof(dev->serial));
|
||||
if (alloc_len < 72) {
|
||||
return nvme_trans_completion(hdr,
|
||||
SAM_STAT_CHECK_CONDITION,
|
||||
ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
|
||||
SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
}
|
||||
xfer_len = alloc_len;
|
||||
return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
|
||||
|
||||
nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
memset(inq_response, 0, alloc_len);
|
||||
inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
|
||||
inq_response[3] = 0x48; /* Page Length */
|
||||
|
||||
/* Designation Descriptor start */
|
||||
inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */
|
||||
inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */
|
||||
inq_response[6] = 0x00; /* Rsvd */
|
||||
inq_response[7] = 0x44; /* Designator Length */
|
||||
|
||||
sprintf(&inq_response[8], "%04x", le16_to_cpu(id_ctrl->vid));
|
||||
memcpy(&inq_response[12], ctrl->model, sizeof(ctrl->model));
|
||||
sprintf(&inq_response[52], "%04x", cpu_to_be32(ns->ns_id));
|
||||
memcpy(&inq_response[56], ctrl->serial, sizeof(ctrl->serial));
|
||||
|
||||
res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
|
||||
kfree(id_ctrl);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
u8 *resp, int alloc_len)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (ns->ctrl->vs >= NVME_VS(1, 1)) {
|
||||
res = nvme_fill_device_id_eui64(ns, hdr, resp, alloc_len);
|
||||
if (res != -EOPNOTSUPP)
|
||||
return res;
|
||||
}
|
||||
|
||||
return nvme_fill_device_id_scsi_string(ns, hdr, resp, alloc_len);
|
||||
}
|
||||
|
||||
static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
|
|
@ -672,7 +703,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
u8 *inq_response;
|
||||
int res;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
struct nvme_id_ctrl *id_ctrl;
|
||||
struct nvme_id_ns *id_ns;
|
||||
int xfer_len;
|
||||
|
|
@ -688,7 +719,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
if (inq_response == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
goto out_free_inq;
|
||||
|
|
@ -704,7 +735,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
app_chk = protect << 1;
|
||||
ref_chk = protect;
|
||||
|
||||
nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
|
||||
nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
goto out_free_inq;
|
||||
|
|
@ -815,7 +846,6 @@ static int nvme_trans_log_info_exceptions(struct nvme_ns *ns,
|
|||
int res;
|
||||
int xfer_len;
|
||||
u8 *log_response;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_smart_log *smart_log;
|
||||
u8 temp_c;
|
||||
u16 temp_k;
|
||||
|
|
@ -824,7 +854,7 @@ static int nvme_trans_log_info_exceptions(struct nvme_ns *ns,
|
|||
if (log_response == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
res = nvme_get_log_page(dev, &smart_log);
|
||||
res = nvme_get_log_page(ns->ctrl, &smart_log);
|
||||
if (res < 0)
|
||||
goto out_free_response;
|
||||
|
||||
|
|
@ -862,7 +892,6 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
int res;
|
||||
int xfer_len;
|
||||
u8 *log_response;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_smart_log *smart_log;
|
||||
u32 feature_resp;
|
||||
u8 temp_c_cur, temp_c_thresh;
|
||||
|
|
@ -872,7 +901,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
if (log_response == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
res = nvme_get_log_page(dev, &smart_log);
|
||||
res = nvme_get_log_page(ns->ctrl, &smart_log);
|
||||
if (res < 0)
|
||||
goto out_free_response;
|
||||
|
||||
|
|
@ -886,7 +915,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
kfree(smart_log);
|
||||
|
||||
/* Get Features for Temp Threshold */
|
||||
res = nvme_get_features(dev, NVME_FEAT_TEMP_THRESH, 0, 0,
|
||||
res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, 0,
|
||||
&feature_resp);
|
||||
if (res != NVME_SC_SUCCESS)
|
||||
temp_c_thresh = LOG_TEMP_UNKNOWN;
|
||||
|
|
@ -948,7 +977,6 @@ static int nvme_trans_fill_blk_desc(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
{
|
||||
int res;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_id_ns *id_ns;
|
||||
u8 flbas;
|
||||
u32 lba_length;
|
||||
|
|
@ -958,7 +986,7 @@ static int nvme_trans_fill_blk_desc(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
else if (llbaa > 0 && len < MODE_PAGE_LLBAA_BLK_DES_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -1014,14 +1042,13 @@ static int nvme_trans_fill_caching_page(struct nvme_ns *ns,
|
|||
{
|
||||
int res = 0;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
u32 feature_resp;
|
||||
u8 vwc;
|
||||
|
||||
if (len < MODE_PAGE_CACHING_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
nvme_sc = nvme_get_features(dev, NVME_FEAT_VOLATILE_WC, 0, 0,
|
||||
nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, 0,
|
||||
&feature_resp);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
|
|
@ -1207,12 +1234,11 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
{
|
||||
int res;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_id_ctrl *id_ctrl;
|
||||
int lowest_pow_st; /* max npss = lowest power consumption */
|
||||
unsigned ps_desired = 0;
|
||||
|
||||
nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
|
||||
nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -1256,7 +1282,7 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
break;
|
||||
}
|
||||
nvme_sc = nvme_set_features(dev, NVME_FEAT_POWER_MGMT, ps_desired, 0,
|
||||
nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_POWER_MGMT, ps_desired, 0,
|
||||
NULL);
|
||||
return nvme_trans_status_code(hdr, nvme_sc);
|
||||
}
|
||||
|
|
@ -1280,7 +1306,6 @@ static int nvme_trans_send_download_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr
|
|||
u8 buffer_id)
|
||||
{
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_command c;
|
||||
|
||||
if (hdr->iovec_count > 0) {
|
||||
|
|
@ -1297,7 +1322,7 @@ static int nvme_trans_send_download_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr
|
|||
c.dlfw.numd = cpu_to_le32((tot_len/BYTES_TO_DWORDS) - 1);
|
||||
c.dlfw.offset = cpu_to_le32(offset/BYTES_TO_DWORDS);
|
||||
|
||||
nvme_sc = __nvme_submit_sync_cmd(dev->admin_q, &c, NULL,
|
||||
nvme_sc = nvme_submit_user_cmd(ns->ctrl->admin_q, &c,
|
||||
hdr->dxferp, tot_len, NULL, 0);
|
||||
return nvme_trans_status_code(hdr, nvme_sc);
|
||||
}
|
||||
|
|
@ -1364,14 +1389,13 @@ static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
{
|
||||
int res = 0;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
unsigned dword11;
|
||||
|
||||
switch (page_code) {
|
||||
case MODE_PAGE_CACHING:
|
||||
dword11 = ((mode_page[2] & CACHING_MODE_PAGE_WCE_MASK) ? 1 : 0);
|
||||
nvme_sc = nvme_set_features(dev, NVME_FEAT_VOLATILE_WC, dword11,
|
||||
0, NULL);
|
||||
nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_VOLATILE_WC,
|
||||
dword11, 0, NULL);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
break;
|
||||
case MODE_PAGE_CONTROL:
|
||||
|
|
@ -1473,7 +1497,6 @@ static int nvme_trans_fmt_set_blk_size_count(struct nvme_ns *ns,
|
|||
{
|
||||
int res = 0;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
u8 flbas;
|
||||
|
||||
/*
|
||||
|
|
@ -1486,7 +1509,7 @@ static int nvme_trans_fmt_set_blk_size_count(struct nvme_ns *ns,
|
|||
if (ns->mode_select_num_blocks == 0 || ns->mode_select_block_len == 0) {
|
||||
struct nvme_id_ns *id_ns;
|
||||
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -1570,7 +1593,6 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
{
|
||||
int res;
|
||||
int nvme_sc;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_id_ns *id_ns;
|
||||
u8 i;
|
||||
u8 flbas, nlbaf;
|
||||
|
|
@ -1579,7 +1601,7 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
struct nvme_command c;
|
||||
|
||||
/* Loop thru LBAF's in id_ns to match reqd lbaf, put in cdw10 */
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -1611,7 +1633,7 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
c.format.nsid = cpu_to_le32(ns->ns_id);
|
||||
c.format.cdw10 = cpu_to_le32(cdw10);
|
||||
|
||||
nvme_sc = nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
|
||||
nvme_sc = nvme_submit_sync_cmd(ns->ctrl->admin_q, &c, NULL, 0);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
|
||||
kfree(id_ns);
|
||||
|
|
@ -1704,7 +1726,7 @@ static int nvme_trans_do_nvme_io(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
nvme_sc = NVME_SC_LBA_RANGE;
|
||||
break;
|
||||
}
|
||||
nvme_sc = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
|
||||
nvme_sc = nvme_submit_user_cmd(ns->queue, &c,
|
||||
next_mapping_addr, unit_len, NULL, 0);
|
||||
if (nvme_sc)
|
||||
break;
|
||||
|
|
@ -2040,7 +2062,6 @@ static int nvme_trans_read_capacity(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
u32 alloc_len;
|
||||
u32 resp_size;
|
||||
u32 xfer_len;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_id_ns *id_ns;
|
||||
u8 *response;
|
||||
|
||||
|
|
@ -2052,7 +2073,7 @@ static int nvme_trans_read_capacity(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
resp_size = READ_CAP_10_RESP_SIZE;
|
||||
}
|
||||
|
||||
nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
|
||||
nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -2080,7 +2101,6 @@ static int nvme_trans_report_luns(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
int nvme_sc;
|
||||
u32 alloc_len, xfer_len, resp_size;
|
||||
u8 *response;
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
struct nvme_id_ctrl *id_ctrl;
|
||||
u32 ll_length, lun_id;
|
||||
u8 lun_id_offset = REPORT_LUNS_FIRST_LUN_OFFSET;
|
||||
|
|
@ -2094,7 +2114,7 @@ static int nvme_trans_report_luns(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
|||
case ALL_LUNS_RETURNED:
|
||||
case ALL_WELL_KNOWN_LUNS_RETURNED:
|
||||
case RESTRICTED_LUNS_RETURNED:
|
||||
nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
|
||||
nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
return res;
|
||||
|
|
@ -2295,9 +2315,7 @@ static int nvme_trans_test_unit_ready(struct nvme_ns *ns,
|
|||
struct sg_io_hdr *hdr,
|
||||
u8 *cmd)
|
||||
{
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
|
||||
if (!(readl(&dev->bar->csts) & NVME_CSTS_RDY))
|
||||
if (nvme_ctrl_ready(ns->ctrl))
|
||||
return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION,
|
||||
NOT_READY, SCSI_ASC_LUN_NOT_READY,
|
||||
SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
|
|
|
|||
Loading…
Reference in a new issue