Ejemplo n.º 1
0
void
read_logpage(int fd, uint8_t log_page, int nsid, void *payload, 
    uint32_t payload_size)
{
	struct nvme_pt_command	pt;

	memset(&pt, 0, sizeof(pt));
	pt.cmd.opc = NVME_OPC_GET_LOG_PAGE;
	pt.cmd.nsid = nsid;
	pt.cmd.cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16;
	pt.cmd.cdw10 |= log_page;
	pt.buf = payload;
	pt.len = payload_size;
	pt.is_read = 1;

	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
		printf("Get log page request failed. errno=%d (%s)\n",
		    errno, strerror(errno));
		exit(EX_IOERR);
	}

	if (nvme_completion_is_error(&pt.cpl)) {
		printf("Passthrough command returned error.\n");
		exit(EX_IOERR);
	}
}
Ejemplo n.º 2
0
static void
nvd_done(void *arg, const struct nvme_completion *cpl)
{
	struct bio *bp;
	struct nvd_disk *ndisk;

	bp = (struct bio *)arg;

	ndisk = bp->bio_disk->d_drv1;

	atomic_add_int(&ndisk->cur_depth, -1);

	/*
	 * TODO: add more extensive translation of NVMe status codes
	 *  to different bio error codes (i.e. EIO, EINVAL, etc.)
	 */
	if (nvme_completion_is_error(cpl)) {
		bp->bio_error = EIO;
		bp->bio_flags |= BIO_ERROR;
		bp->bio_resid = bp->bio_bcount;
	} else
		bp->bio_resid = 0;

	biodone(bp);
}
Ejemplo n.º 3
0
static void
reservation_ns_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	if (nvme_completion_is_error(cpl)) {
		reserve_command_result = -1;
	} else {
		reserve_command_result = 0;
	}

	outstanding_commands--;
}
Ejemplo n.º 4
0
static void
get_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	struct feature *feature = cb_arg;
	int fid = feature - features;
	if (nvme_completion_is_error(cpl)) {
		fprintf(stdout, "get_feature(0x%02X) failed\n", fid);
	} else {
		feature->result = cpl->cdw0;
		feature->valid = true;
	}
	outstanding_commands--;
}
Ejemplo n.º 5
0
static void
set_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	struct feature *feature = cb_arg;
	int fid = feature - features;
	if (nvme_completion_is_error(cpl)) {
		fprintf(stdout, "set_feature(0x%02X) failed\n", fid);
		set_feature_result = -1;
	} else {
		set_feature_result = 0;
	}
	outstanding_commands--;
}
Ejemplo n.º 6
0
Archivo: aer.c Proyecto: HengWang/spdk
static void set_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	struct dev *dev = cb_arg;

	if (nvme_completion_is_error(cpl)) {
		printf("%s: set feature (temp threshold) failed\n", dev->name);
		failed = 1;
		return;
	}

	/* Admin command completions are synchronized by the NVMe driver,
	 * so we don't need to do any special locking here. */
	temperature_done++;
}
Ejemplo n.º 7
0
Archivo: aer.c Proyecto: HengWang/spdk
static void
get_log_page_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	struct dev *dev = cb_arg;

	if (nvme_completion_is_error(cpl)) {
		printf("%s: get log page failed\n", dev->name);
		failed = 1;
		return;
	}

	print_health_page(dev, dev->health_page);
	aer_done++;
}
Ejemplo n.º 8
0
static void
nvme_sim_nvmeio_done(void *ccb_arg, const struct nvme_completion *cpl)
{
	union ccb *ccb = (union ccb *)ccb_arg;

	/*
	 * Let the periph know the completion, and let it sort out what
	 * it means. Make our best guess, though for the status code.
	 */
	memcpy(&ccb->nvmeio.cpl, cpl, sizeof(*cpl));
	if (nvme_completion_is_error(cpl))
		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
	else
		ccb->ccb_h.status = CAM_REQ_CMP;
	xpt_done(ccb);
}
Ejemplo n.º 9
0
Archivo: aer.c Proyecto: HengWang/spdk
static void
get_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
{
	struct dev *dev = cb_arg;

	if (nvme_completion_is_error(cpl)) {
		printf("%s: get feature (temp threshold) failed\n", dev->name);
		failed = 1;
		return;
	}

	dev->orig_temp_threshold = cpl->cdw0;
	printf("%s: original temperature threshold: %u Kelvin (%d Celsius)\n",
	       dev->name, dev->orig_temp_threshold, dev->orig_temp_threshold - 273);

	/* Set temperature threshold to a low value so the AER will trigger. */
	set_temp_threshold(dev, 200);
}
Ejemplo n.º 10
0
void
read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata)
{
	struct nvme_pt_command	pt;

	memset(&pt, 0, sizeof(pt));
	pt.cmd.opc = NVME_OPC_IDENTIFY;
	pt.cmd.nsid = nsid;
	pt.buf = nsdata;
	pt.len = sizeof(*nsdata);
	pt.is_read = 1;

	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
		err(1, "identify request failed");

	if (nvme_completion_is_error(&pt.cpl))
		errx(1, "identify request returned error");
}
Ejemplo n.º 11
0
void
read_logpage(int fd, uint8_t log_page, int nsid, void *payload,
    uint32_t payload_size)
{
	struct nvme_pt_command	pt;

	memset(&pt, 0, sizeof(pt));
	pt.cmd.opc = NVME_OPC_GET_LOG_PAGE;
	pt.cmd.nsid = nsid;
	pt.cmd.cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16;
	pt.cmd.cdw10 |= log_page;
	pt.buf = payload;
	pt.len = payload_size;
	pt.is_read = 1;

	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
		err(1, "get log page request failed");

	if (nvme_completion_is_error(&pt.cpl))
		errx(1, "get log page request returned error");
}
Ejemplo n.º 12
0
static int
activate_firmware(int fd, int slot, int activate_action)
{
	struct nvme_pt_command	pt;

	memset(&pt, 0, sizeof(pt));
	pt.cmd.opc = NVME_OPC_FIRMWARE_ACTIVATE;
	pt.cmd.cdw10 = (activate_action << 3) | slot;
	pt.is_read = 0;

	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
		err(1, "firmware activate request failed");

	if (pt.cpl.status.sct == NVME_SCT_COMMAND_SPECIFIC &&
	    pt.cpl.status.sc == NVME_SC_FIRMWARE_REQUIRES_RESET)
		return 1;

	if (nvme_completion_is_error(&pt.cpl))
		errx(1, "firmware activate request returned error");

	return 0;
}
Ejemplo n.º 13
0
static void
read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata)
{
	struct nvme_pt_command	pt;

	memset(&pt, 0, sizeof(pt));
	pt.cmd.opc = NVME_OPC_IDENTIFY;
	pt.cmd.nsid = nsid;
	pt.buf = nsdata;
	pt.len = sizeof(*nsdata);
	pt.is_read = 1;

	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
		printf("Identify request failed. errno=%d (%s)\n",
		    errno, strerror(errno));
		exit(EX_IOERR);
	}

	if (nvme_completion_is_error(&pt.cpl)) {
		printf("Passthrough command returned error.\n");
		exit(EX_IOERR);
	}
}
Ejemplo n.º 14
0
static void
nvme_ns_io_test_cb(void *arg, const struct nvme_completion *cpl)
{
	struct nvme_io_test_thread	*tth = arg;
	struct timeval			t;

	tth->io_completed++;

	if (nvme_completion_is_error(cpl)) {
		printf("%s: error occurred\n", __func__);
		wakeup_one(tth);
		return;
	}

	getmicrouptime(&t);
	timevalsub(&t, &tth->start);

	if (t.tv_sec >= tth->time) {
		wakeup_one(tth);
		return;
	}

	switch (tth->opc) {
	case NVME_OPC_WRITE:
		nvme_ns_cmd_write(tth->ns, tth->buf, tth->idx * 2048,
		    tth->size/nvme_ns_get_sector_size(tth->ns),
		    nvme_ns_io_test_cb, tth);
		break;
	case NVME_OPC_READ:
		nvme_ns_cmd_read(tth->ns, tth->buf, tth->idx * 2048,
		    tth->size/nvme_ns_get_sector_size(tth->ns),
		    nvme_ns_io_test_cb, tth);
		break;
	default:
		break;
	}
}
Ejemplo n.º 15
0
static void
update_firmware(int fd, uint8_t *payload, int32_t payload_size)
{
	struct nvme_pt_command	pt;
	int32_t			off, resid, size;
	void			*chunk;

	off = 0;
	resid = payload_size;

	if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
		errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);

	while (resid > 0) {
		size = (resid >= NVME_MAX_XFER_SIZE) ?
		    NVME_MAX_XFER_SIZE : resid;
		memcpy(chunk, payload + off, size);

		memset(&pt, 0, sizeof(pt));
		pt.cmd.opc = NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD;
		pt.cmd.cdw10 = (size / sizeof(uint32_t)) - 1;
		pt.cmd.cdw11 = (off / sizeof(uint32_t));
		pt.buf = chunk;
		pt.len = size;
		pt.is_read = 0;

		if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
			err(1, "firmware download request failed");

		if (nvme_completion_is_error(&pt.cpl))
			errx(1, "firmware download request returned error");

		resid -= size;
		off += size;
	}
}
Ejemplo n.º 16
0
void
expected_failure_callback(void *arg, const struct nvme_completion *cpl)
{
	CU_ASSERT(nvme_completion_is_error(cpl));
}
Ejemplo n.º 17
0
void
expected_success_callback(void *arg, const struct nvme_completion *cpl)
{
	CU_ASSERT(!nvme_completion_is_error(cpl));
}