Commit 2bfedd1d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull followup block layer updates from Jens Axboe:
 "Two things in this pull request:

   - A block throttle oops fix (marked for stable) from Thadeu.

   - The NVMe fixes/features queued up for 3.20, but merged later in the
     process.  From Keith.  We should have gotten this merged earlier,
     we're ironing out the kinks in the process.  Will be ready for the
     initial pull next series"

* 'for-linus' of git://git.kernel.dk/linux-block:
  blk-throttle: check stats_cpu before reading it from sysfs
  NVMe: Fix potential corruption on sync commands
  NVMe: Remove unused variables
  NVMe: Fix scsi mode select llbaa setting
  NVMe: Fix potential corruption during shutdown
  NVMe: Asynchronous controller probe
  NVMe: Register management handle under nvme class
  NVMe: Update SCSI Inquiry VPD 83h translation
  NVMe: Metadata format support
parents a911dcdb decf6d79
...@@ -1292,6 +1292,9 @@ static u64 tg_prfill_cpu_rwstat(struct seq_file *sf, ...@@ -1292,6 +1292,9 @@ static u64 tg_prfill_cpu_rwstat(struct seq_file *sf,
struct blkg_rwstat rwstat = { }, tmp; struct blkg_rwstat rwstat = { }, tmp;
int i, cpu; int i, cpu;
if (tg->stats_cpu == NULL)
return 0;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct tg_stats_cpu *sc = per_cpu_ptr(tg->stats_cpu, cpu); struct tg_stats_cpu *sc = per_cpu_ptr(tg->stats_cpu, cpu);
......
This diff is collapsed.
...@@ -779,10 +779,8 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, ...@@ -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; struct nvme_dev *dev = ns->dev;
dma_addr_t dma_addr; dma_addr_t dma_addr;
void *mem; void *mem;
struct nvme_id_ctrl *id_ctrl;
int res = SNTI_TRANSLATION_SUCCESS; int res = SNTI_TRANSLATION_SUCCESS;
int nvme_sc; int nvme_sc;
u8 ieee[4];
int xfer_len; int xfer_len;
__be32 tmp_id = cpu_to_be32(ns->ns_id); __be32 tmp_id = cpu_to_be32(ns->ns_id);
...@@ -793,8 +791,14 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, ...@@ -793,8 +791,14 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
goto out_dma; goto out_dma;
} }
/* nvme controller identify */ memset(inq_response, 0, alloc_len);
nvme_sc = nvme_identify(dev, 0, 1, dma_addr); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */
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);
nvme_sc = nvme_identify(dev, ns->ns_id, 0, dma_addr);
res = nvme_trans_status_code(hdr, nvme_sc); res = nvme_trans_status_code(hdr, nvme_sc);
if (res) if (res)
goto out_free; goto out_free;
...@@ -802,37 +806,45 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, ...@@ -802,37 +806,45 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
res = nvme_sc; res = nvme_sc;
goto out_free; goto out_free;
} }
id_ctrl = mem;
/* Since SCSI tried to save 4 bits... [SPC-4(r34) Table 591] */ if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) {
ieee[0] = id_ctrl->ieee[0] << 4; if (bitmap_empty(eui, len * 8)) {
ieee[1] = id_ctrl->ieee[0] >> 4 | id_ctrl->ieee[1] << 4; eui = id_ns->nguid;
ieee[2] = id_ctrl->ieee[1] >> 4 | id_ctrl->ieee[2] << 4; len = sizeof(id_ns->nguid);
ieee[3] = id_ctrl->ieee[2] >> 4; }
}
if (bitmap_empty(eui, len * 8))
goto scsi_string;
memset(inq_response, 0, STANDARD_INQUIRY_LENGTH); inq_response[3] = 4 + len; /* Page Length */
inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */
inq_response[3] = 20; /* Page Length */
/* Designation Descriptor start */ /* Designation Descriptor start */
inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
inq_response[5] = 0x03; /* PIV=0b | Asso=00b | Designator Type=3h */ inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */
inq_response[6] = 0x00; /* Rsvd */ inq_response[6] = 0x00; /* Rsvd */
inq_response[7] = 16; /* Designator Length */ inq_response[7] = len; /* Designator Length */
/* Designator start */ memcpy(&inq_response[8], eui, len);
inq_response[8] = 0x60 | ieee[3]; /* NAA=6h | IEEE ID MSB, High nibble*/ } else {
inq_response[9] = ieee[2]; /* IEEE ID */ scsi_string:
inq_response[10] = ieee[1]; /* IEEE ID */ if (alloc_len < 72) {
inq_response[11] = ieee[0]; /* IEEE ID| Vendor Specific ID... */ res = nvme_trans_completion(hdr,
inq_response[12] = (dev->pci_dev->vendor & 0xFF00) >> 8; SAM_STAT_CHECK_CONDITION,
inq_response[13] = (dev->pci_dev->vendor & 0x00FF); ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
inq_response[14] = dev->serial[0]; SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
inq_response[15] = dev->serial[1]; goto out_free;
inq_response[16] = dev->model[0]; }
inq_response[17] = dev->model[1]; inq_response[3] = 0x48; /* Page Length */
memcpy(&inq_response[18], &tmp_id, sizeof(u32)); /* Designation Descriptor start */
/* Last 2 bytes are zero */ 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 */
xfer_len = min(alloc_len, STANDARD_INQUIRY_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); res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
out_free: out_free:
...@@ -1600,7 +1612,7 @@ static inline void nvme_trans_modesel_get_bd_len(u8 *parm_list, u8 cdb10, ...@@ -1600,7 +1612,7 @@ static inline void nvme_trans_modesel_get_bd_len(u8 *parm_list, u8 cdb10,
/* 10 Byte CDB */ /* 10 Byte CDB */
*bd_len = (parm_list[MODE_SELECT_10_BD_OFFSET] << 8) + *bd_len = (parm_list[MODE_SELECT_10_BD_OFFSET] << 8) +
parm_list[MODE_SELECT_10_BD_OFFSET + 1]; 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; MODE_SELECT_10_LLBAA_MASK;
} else { } else {
/* 6 Byte CDB */ /* 6 Byte CDB */
...@@ -2222,7 +2234,7 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr, ...@@ -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); page_code = GET_INQ_PAGE_CODE(cmd);
alloc_len = GET_INQ_ALLOC_LENGTH(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) { if (inq_response == NULL) {
res = -ENOMEM; res = -ENOMEM;
goto out_mem; goto out_mem;
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <uapi/linux/nvme.h> #include <uapi/linux/nvme.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/miscdevice.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/blk-mq.h> #include <linux/blk-mq.h>
...@@ -62,8 +61,6 @@ enum { ...@@ -62,8 +61,6 @@ enum {
NVME_CSTS_SHST_MASK = 3 << 2, NVME_CSTS_SHST_MASK = 3 << 2,
}; };
#define NVME_VS(major, minor) (major << 16 | minor)
extern unsigned char nvme_io_timeout; extern unsigned char nvme_io_timeout;
#define NVME_IO_TIMEOUT (nvme_io_timeout * HZ) #define NVME_IO_TIMEOUT (nvme_io_timeout * HZ)
...@@ -91,9 +88,10 @@ struct nvme_dev { ...@@ -91,9 +88,10 @@ struct nvme_dev {
struct nvme_bar __iomem *bar; struct nvme_bar __iomem *bar;
struct list_head namespaces; struct list_head namespaces;
struct kref kref; struct kref kref;
struct miscdevice miscdev; struct device *device;
work_func_t reset_workfn; work_func_t reset_workfn;
struct work_struct reset_work; struct work_struct reset_work;
struct work_struct probe_work;
char name[12]; char name[12];
char serial[20]; char serial[20];
char model[40]; char model[40];
...@@ -105,7 +103,6 @@ struct nvme_dev { ...@@ -105,7 +103,6 @@ struct nvme_dev {
u16 abort_limit; u16 abort_limit;
u8 event_limit; u8 event_limit;
u8 vwc; u8 vwc;
u8 initialized;
}; };
/* /*
...@@ -121,6 +118,7 @@ struct nvme_ns { ...@@ -121,6 +118,7 @@ struct nvme_ns {
unsigned ns_id; unsigned ns_id;
int lba_shift; int lba_shift;
int ms; int ms;
int pi_type;
u64 mode_select_num_blocks; u64 mode_select_num_blocks;
u32 mode_select_block_len; u32 mode_select_block_len;
}; };
...@@ -138,6 +136,7 @@ struct nvme_iod { ...@@ -138,6 +136,7 @@ struct nvme_iod {
int nents; /* Used in scatterlist */ int nents; /* Used in scatterlist */
int length; /* Of data, in bytes */ int length; /* Of data, in bytes */
dma_addr_t first_dma; dma_addr_t first_dma;
struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */
struct scatterlist sg[0]; struct scatterlist sg[0];
}; };
......
...@@ -115,7 +115,13 @@ struct nvme_id_ns { ...@@ -115,7 +115,13 @@ struct nvme_id_ns {
__le16 nawun; __le16 nawun;
__le16 nawupf; __le16 nawupf;
__le16 nacwu; __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]; __u8 eui64[8];
struct nvme_lbaf lbaf[16]; struct nvme_lbaf lbaf[16];
__u8 rsvd192[192]; __u8 rsvd192[192];
...@@ -124,10 +130,22 @@ struct nvme_id_ns { ...@@ -124,10 +130,22 @@ struct nvme_id_ns {
enum { enum {
NVME_NS_FEAT_THIN = 1 << 0, 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_BEST = 0,
NVME_LBAF_RP_BETTER = 1, NVME_LBAF_RP_BETTER = 1,
NVME_LBAF_RP_GOOD = 2, NVME_LBAF_RP_GOOD = 2,
NVME_LBAF_RP_DEGRADED = 3, 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 { struct nvme_smart_log {
...@@ -261,6 +279,10 @@ enum { ...@@ -261,6 +279,10 @@ enum {
NVME_RW_DSM_LATENCY_LOW = 3 << 4, NVME_RW_DSM_LATENCY_LOW = 3 << 4,
NVME_RW_DSM_SEQ_REQ = 1 << 6, NVME_RW_DSM_SEQ_REQ = 1 << 6,
NVME_RW_DSM_COMPRESSED = 1 << 7, 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 { struct nvme_dsm_cmd {
...@@ -549,6 +571,8 @@ struct nvme_passthru_cmd { ...@@ -549,6 +571,8 @@ struct nvme_passthru_cmd {
__u32 result; __u32 result;
}; };
#define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8))
#define nvme_admin_cmd nvme_passthru_cmd #define nvme_admin_cmd nvme_passthru_cmd
#define NVME_IOCTL_ID _IO('N', 0x40) #define NVME_IOCTL_ID _IO('N', 0x40)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment