mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge branch 'for-3.20' of git://git.infradead.org/users/kbusch/linux-nvme into for-linus
Merge 3.20 NVMe changes from Keith.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -779,10 +779,8 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
struct nvme_dev *dev = ns->dev;
|
||||
dma_addr_t dma_addr;
|
||||
void *mem;
|
||||
struct nvme_id_ctrl *id_ctrl;
|
||||
int res = SNTI_TRANSLATION_SUCCESS;
|
||||
int nvme_sc;
|
||||
u8 ieee[4];
|
||||
int xfer_len;
|
||||
__be32 tmp_id = cpu_to_be32(ns->ns_id);
|
||||
|
||||
@@ -793,46 +791,60 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
goto out_dma;
|
||||
}
|
||||
|
||||
/* nvme controller identify */
|
||||
nvme_sc = nvme_identify(dev, 0, 1, dma_addr);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
goto out_free;
|
||||
if (nvme_sc) {
|
||||
res = nvme_sc;
|
||||
goto out_free;
|
||||
}
|
||||
id_ctrl = mem;
|
||||
|
||||
/* Since SCSI tried to save 4 bits... [SPC-4(r34) Table 591] */
|
||||
ieee[0] = id_ctrl->ieee[0] << 4;
|
||||
ieee[1] = id_ctrl->ieee[0] >> 4 | id_ctrl->ieee[1] << 4;
|
||||
ieee[2] = id_ctrl->ieee[1] >> 4 | id_ctrl->ieee[2] << 4;
|
||||
ieee[3] = id_ctrl->ieee[2] >> 4;
|
||||
|
||||
memset(inq_response, 0, STANDARD_INQUIRY_LENGTH);
|
||||
memset(inq_response, 0, alloc_len);
|
||||
inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */
|
||||
inq_response[3] = 20; /* Page Length */
|
||||
/* Designation Descriptor start */
|
||||
inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
|
||||
inq_response[5] = 0x03; /* PIV=0b | Asso=00b | Designator Type=3h */
|
||||
inq_response[6] = 0x00; /* Rsvd */
|
||||
inq_response[7] = 16; /* Designator Length */
|
||||
/* Designator start */
|
||||
inq_response[8] = 0x60 | ieee[3]; /* NAA=6h | IEEE ID MSB, High nibble*/
|
||||
inq_response[9] = ieee[2]; /* IEEE ID */
|
||||
inq_response[10] = ieee[1]; /* IEEE ID */
|
||||
inq_response[11] = ieee[0]; /* IEEE ID| Vendor Specific ID... */
|
||||
inq_response[12] = (dev->pci_dev->vendor & 0xFF00) >> 8;
|
||||
inq_response[13] = (dev->pci_dev->vendor & 0x00FF);
|
||||
inq_response[14] = dev->serial[0];
|
||||
inq_response[15] = dev->serial[1];
|
||||
inq_response[16] = dev->model[0];
|
||||
inq_response[17] = dev->model[1];
|
||||
memcpy(&inq_response[18], &tmp_id, sizeof(u32));
|
||||
/* Last 2 bytes are zero */
|
||||
if (readl(&dev->bar->vs) >= NVME_VS(1, 1)) {
|
||||
struct nvme_id_ns *id_ns = mem;
|
||||
void *eui = id_ns->eui64;
|
||||
int len = sizeof(id_ns->eui64);
|
||||
|
||||
xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
|
||||
nvme_sc = nvme_identify(dev, ns->ns_id, 0, dma_addr);
|
||||
res = nvme_trans_status_code(hdr, nvme_sc);
|
||||
if (res)
|
||||
goto out_free;
|
||||
if (nvme_sc) {
|
||||
res = nvme_sc;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
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))
|
||||
goto scsi_string;
|
||||
|
||||
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);
|
||||
} else {
|
||||
scsi_string:
|
||||
if (alloc_len < 72) {
|
||||
res = nvme_trans_completion(hdr,
|
||||
SAM_STAT_CHECK_CONDITION,
|
||||
ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
|
||||
SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
goto out_free;
|
||||
}
|
||||
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", dev->pci_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));
|
||||
}
|
||||
xfer_len = alloc_len;
|
||||
res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
|
||||
|
||||
out_free:
|
||||
@@ -1600,7 +1612,7 @@ static inline void nvme_trans_modesel_get_bd_len(u8 *parm_list, u8 cdb10,
|
||||
/* 10 Byte CDB */
|
||||
*bd_len = (parm_list[MODE_SELECT_10_BD_OFFSET] << 8) +
|
||||
parm_list[MODE_SELECT_10_BD_OFFSET + 1];
|
||||
*llbaa = parm_list[MODE_SELECT_10_LLBAA_OFFSET] &&
|
||||
*llbaa = parm_list[MODE_SELECT_10_LLBAA_OFFSET] &
|
||||
MODE_SELECT_10_LLBAA_MASK;
|
||||
} else {
|
||||
/* 6 Byte CDB */
|
||||
@@ -2222,7 +2234,7 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
page_code = GET_INQ_PAGE_CODE(cmd);
|
||||
alloc_len = GET_INQ_ALLOC_LENGTH(cmd);
|
||||
|
||||
inq_response = kmalloc(STANDARD_INQUIRY_LENGTH, GFP_KERNEL);
|
||||
inq_response = kmalloc(alloc_len, GFP_KERNEL);
|
||||
if (inq_response == NULL) {
|
||||
res = -ENOMEM;
|
||||
goto out_mem;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <uapi/linux/nvme.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/blk-mq.h>
|
||||
|
||||
@@ -62,8 +61,6 @@ enum {
|
||||
NVME_CSTS_SHST_MASK = 3 << 2,
|
||||
};
|
||||
|
||||
#define NVME_VS(major, minor) (major << 16 | minor)
|
||||
|
||||
extern unsigned char nvme_io_timeout;
|
||||
#define NVME_IO_TIMEOUT (nvme_io_timeout * HZ)
|
||||
|
||||
@@ -91,9 +88,10 @@ struct nvme_dev {
|
||||
struct nvme_bar __iomem *bar;
|
||||
struct list_head namespaces;
|
||||
struct kref kref;
|
||||
struct miscdevice miscdev;
|
||||
struct device *device;
|
||||
work_func_t reset_workfn;
|
||||
struct work_struct reset_work;
|
||||
struct work_struct probe_work;
|
||||
char name[12];
|
||||
char serial[20];
|
||||
char model[40];
|
||||
@@ -105,7 +103,6 @@ struct nvme_dev {
|
||||
u16 abort_limit;
|
||||
u8 event_limit;
|
||||
u8 vwc;
|
||||
u8 initialized;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -121,6 +118,7 @@ struct nvme_ns {
|
||||
unsigned ns_id;
|
||||
int lba_shift;
|
||||
int ms;
|
||||
int pi_type;
|
||||
u64 mode_select_num_blocks;
|
||||
u32 mode_select_block_len;
|
||||
};
|
||||
@@ -138,6 +136,7 @@ struct nvme_iod {
|
||||
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];
|
||||
};
|
||||
|
||||
|
||||
@@ -115,7 +115,13 @@ struct nvme_id_ns {
|
||||
__le16 nawun;
|
||||
__le16 nawupf;
|
||||
__le16 nacwu;
|
||||
__u8 rsvd40[80];
|
||||
__le16 nabsn;
|
||||
__le16 nabo;
|
||||
__le16 nabspf;
|
||||
__u16 rsvd46;
|
||||
__le64 nvmcap[2];
|
||||
__u8 rsvd64[40];
|
||||
__u8 nguid[16];
|
||||
__u8 eui64[8];
|
||||
struct nvme_lbaf lbaf[16];
|
||||
__u8 rsvd192[192];
|
||||
@@ -124,10 +130,22 @@ struct nvme_id_ns {
|
||||
|
||||
enum {
|
||||
NVME_NS_FEAT_THIN = 1 << 0,
|
||||
NVME_NS_FLBAS_LBA_MASK = 0xf,
|
||||
NVME_NS_FLBAS_META_EXT = 0x10,
|
||||
NVME_LBAF_RP_BEST = 0,
|
||||
NVME_LBAF_RP_BETTER = 1,
|
||||
NVME_LBAF_RP_GOOD = 2,
|
||||
NVME_LBAF_RP_DEGRADED = 3,
|
||||
NVME_NS_DPC_PI_LAST = 1 << 4,
|
||||
NVME_NS_DPC_PI_FIRST = 1 << 3,
|
||||
NVME_NS_DPC_PI_TYPE3 = 1 << 2,
|
||||
NVME_NS_DPC_PI_TYPE2 = 1 << 1,
|
||||
NVME_NS_DPC_PI_TYPE1 = 1 << 0,
|
||||
NVME_NS_DPS_PI_FIRST = 1 << 3,
|
||||
NVME_NS_DPS_PI_MASK = 0x7,
|
||||
NVME_NS_DPS_PI_TYPE1 = 1,
|
||||
NVME_NS_DPS_PI_TYPE2 = 2,
|
||||
NVME_NS_DPS_PI_TYPE3 = 3,
|
||||
};
|
||||
|
||||
struct nvme_smart_log {
|
||||
@@ -261,6 +279,10 @@ enum {
|
||||
NVME_RW_DSM_LATENCY_LOW = 3 << 4,
|
||||
NVME_RW_DSM_SEQ_REQ = 1 << 6,
|
||||
NVME_RW_DSM_COMPRESSED = 1 << 7,
|
||||
NVME_RW_PRINFO_PRCHK_REF = 1 << 10,
|
||||
NVME_RW_PRINFO_PRCHK_APP = 1 << 11,
|
||||
NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12,
|
||||
NVME_RW_PRINFO_PRACT = 1 << 13,
|
||||
};
|
||||
|
||||
struct nvme_dsm_cmd {
|
||||
@@ -549,6 +571,8 @@ struct nvme_passthru_cmd {
|
||||
__u32 result;
|
||||
};
|
||||
|
||||
#define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8))
|
||||
|
||||
#define nvme_admin_cmd nvme_passthru_cmd
|
||||
|
||||
#define NVME_IOCTL_ID _IO('N', 0x40)
|
||||
|
||||
Reference in New Issue
Block a user