Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5da273fe authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NVMe driver update from Matthew Wilcox:
 "These patches have mostly been baking for a few months; sorry I didn't
  get them in during the merge window.  They're all bug fixes, except
  for the addition of the SMART log and the addition to MAINTAINERS."

* git://git.infradead.org/users/willy/linux-nvme:
  NVMe: Add namespaces with no LBA range feature
  MAINTAINERS: Add entry for the NVMe driver
  NVMe: Initialize iod nents to 0
  NVMe: Define SMART log
  NVMe: Add result to nvme_get_features
  NVMe: Set result from user admin command
  NVMe: End queued bio requests when freeing queue
  NVMe: Free cmdid on nvme_submit_bio error
parents 14629ed3 12209036
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -5641,6 +5641,14 @@ S: Maintained
F:	drivers/video/riva/
F:	drivers/video/riva/
F:	drivers/video/nvidia/
F:	drivers/video/nvidia/


NVM EXPRESS DRIVER
M:	Matthew Wilcox <willy@linux.intel.com>
L:	linux-nvme@lists.infradead.org
T:	git git://git.infradead.org/users/willy/linux-nvme.git
S:	Supported
F:	drivers/block/nvme.c
F:	include/linux/nvme.h

OMAP SUPPORT
OMAP SUPPORT
M:	Tony Lindgren <tony@atomide.com>
M:	Tony Lindgren <tony@atomide.com>
L:	linux-omap@vger.kernel.org
L:	linux-omap@vger.kernel.org
+24 −9
Original line number Original line Diff line number Diff line
@@ -135,6 +135,7 @@ static inline void _nvme_check_size(void)
	BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096);
	BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096);
	BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096);
	BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096);
	BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
	BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
	BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
}
}


typedef void (*nvme_completion_fn)(struct nvme_dev *, void *,
typedef void (*nvme_completion_fn)(struct nvme_dev *, void *,
@@ -237,6 +238,7 @@ static void *free_cmdid(struct nvme_queue *nvmeq, int cmdid,
		*fn = special_completion;
		*fn = special_completion;
		return CMD_CTX_INVALID;
		return CMD_CTX_INVALID;
	}
	}
	if (fn)
		*fn = info[cmdid].fn;
		*fn = info[cmdid].fn;
	ctx = info[cmdid].ctx;
	ctx = info[cmdid].ctx;
	info[cmdid].fn = special_completion;
	info[cmdid].fn = special_completion;
@@ -335,6 +337,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp)
		iod->offset = offsetof(struct nvme_iod, sg[nseg]);
		iod->offset = offsetof(struct nvme_iod, sg[nseg]);
		iod->npages = -1;
		iod->npages = -1;
		iod->length = nbytes;
		iod->length = nbytes;
		iod->nents = 0;
	}
	}


	return iod;
	return iod;
@@ -375,6 +378,7 @@ static void bio_completion(struct nvme_dev *dev, void *ctx,
	struct bio *bio = iod->private;
	struct bio *bio = iod->private;
	u16 status = le16_to_cpup(&cqe->status) >> 1;
	u16 status = le16_to_cpup(&cqe->status) >> 1;


	if (iod->nents)
		dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
		dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
			bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
			bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
	nvme_free_iod(dev, iod);
	nvme_free_iod(dev, iod);
@@ -589,7 +593,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,


	result = nvme_map_bio(nvmeq->q_dmadev, iod, bio, dma_dir, psegs);
	result = nvme_map_bio(nvmeq->q_dmadev, iod, bio, dma_dir, psegs);
	if (result < 0)
	if (result < 0)
		goto free_iod;
		goto free_cmdid;
	length = result;
	length = result;


	cmnd->rw.command_id = cmdid;
	cmnd->rw.command_id = cmdid;
@@ -609,6 +613,8 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,


	return 0;
	return 0;


 free_cmdid:
	free_cmdid(nvmeq, cmdid, NULL);
 free_iod:
 free_iod:
	nvme_free_iod(nvmeq->dev, iod);
	nvme_free_iod(nvmeq->dev, iod);
 nomem:
 nomem:
@@ -835,8 +841,8 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns,
	return nvme_submit_admin_cmd(dev, &c, NULL);
	return nvme_submit_admin_cmd(dev, &c, NULL);
}
}


static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
static int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
				unsigned nsid, dma_addr_t dma_addr)
					dma_addr_t dma_addr, u32 *result)
{
{
	struct nvme_command c;
	struct nvme_command c;


@@ -846,7 +852,7 @@ static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
	c.features.prp1 = cpu_to_le64(dma_addr);
	c.features.prp1 = cpu_to_le64(dma_addr);
	c.features.fid = cpu_to_le32(fid);
	c.features.fid = cpu_to_le32(fid);


	return nvme_submit_admin_cmd(dev, &c, NULL);
	return nvme_submit_admin_cmd(dev, &c, result);
}
}


static int nvme_set_features(struct nvme_dev *dev, unsigned fid,
static int nvme_set_features(struct nvme_dev *dev, unsigned fid,
@@ -906,6 +912,10 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid)


	spin_lock_irq(&nvmeq->q_lock);
	spin_lock_irq(&nvmeq->q_lock);
	nvme_cancel_ios(nvmeq, false);
	nvme_cancel_ios(nvmeq, false);
	while (bio_list_peek(&nvmeq->sq_cong)) {
		struct bio *bio = bio_list_pop(&nvmeq->sq_cong);
		bio_endio(bio, -EIO);
	}
	spin_unlock_irq(&nvmeq->q_lock);
	spin_unlock_irq(&nvmeq->q_lock);


	irq_set_affinity_hint(vector, NULL);
	irq_set_affinity_hint(vector, NULL);
@@ -1230,12 +1240,17 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev,
	if (length != cmd.data_len)
	if (length != cmd.data_len)
		status = -ENOMEM;
		status = -ENOMEM;
	else
	else
		status = nvme_submit_admin_cmd(dev, &c, NULL);
		status = nvme_submit_admin_cmd(dev, &c, &cmd.result);


	if (cmd.data_len) {
	if (cmd.data_len) {
		nvme_unmap_user_pages(dev, cmd.opcode & 1, iod);
		nvme_unmap_user_pages(dev, cmd.opcode & 1, iod);
		nvme_free_iod(dev, iod);
		nvme_free_iod(dev, iod);
	}
	}

	if (!status && copy_to_user(&ucmd->result, &cmd.result,
							sizeof(cmd.result)))
		status = -EFAULT;

	return status;
	return status;
}
}


@@ -1523,9 +1538,9 @@ static int nvme_dev_add(struct nvme_dev *dev)
			continue;
			continue;


		res = nvme_get_features(dev, NVME_FEAT_LBA_RANGE, i,
		res = nvme_get_features(dev, NVME_FEAT_LBA_RANGE, i,
							dma_addr + 4096);
							dma_addr + 4096, NULL);
		if (res)
		if (res)
			continue;
			memset(mem + 4096, 0, 4096);


		ns = nvme_alloc_ns(dev, i, mem, mem + 4096);
		ns = nvme_alloc_ns(dev, i, mem, mem + 4096);
		if (ns)
		if (ns)
+28 −0
Original line number Original line Diff line number Diff line
@@ -137,6 +137,34 @@ enum {
	NVME_LBAF_RP_DEGRADED	= 3,
	NVME_LBAF_RP_DEGRADED	= 3,
};
};


struct nvme_smart_log {
	__u8			critical_warning;
	__u8			temperature[2];
	__u8			avail_spare;
	__u8			spare_thresh;
	__u8			percent_used;
	__u8			rsvd6[26];
	__u8			data_units_read[16];
	__u8			data_units_written[16];
	__u8			host_reads[16];
	__u8			host_writes[16];
	__u8			ctrl_busy_time[16];
	__u8			power_cycles[16];
	__u8			power_on_hours[16];
	__u8			unsafe_shutdowns[16];
	__u8			media_errors[16];
	__u8			num_err_log_entries[16];
	__u8			rsvd192[320];
};

enum {
	NVME_SMART_CRIT_SPARE		= 1 << 0,
	NVME_SMART_CRIT_TEMPERATURE	= 1 << 1,
	NVME_SMART_CRIT_RELIABILITY	= 1 << 2,
	NVME_SMART_CRIT_MEDIA		= 1 << 3,
	NVME_SMART_CRIT_VOLATILE_MEMORY	= 1 << 4,
};

struct nvme_lba_range_type {
struct nvme_lba_range_type {
	__u8			type;
	__u8			type;
	__u8			attributes;
	__u8			attributes;