Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F166306463
D12141.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D12141.diff
View Options
Index: usr.sbin/camdd/camdd.c
===================================================================
--- usr.sbin/camdd/camdd.c
+++ usr.sbin/camdd/camdd.c
@@ -81,6 +81,7 @@
#include <cam/scsi/scsi_pass.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/smp_all.h>
+#include <cam/nvme/nvme_all.h>
#include <camlib.h>
#include <mtlib.h>
#include <zlib.h>
@@ -481,6 +482,9 @@
int camdd_probe_pass_scsi(struct cam_device *cam_dev, union ccb *ccb,
camdd_argmask arglist, int probe_retry_count,
int probe_timeout, uint64_t *maxsector, uint32_t *block_len);
+int camdd_probe_pass_nvme(struct cam_device *cam_dev, union ccb *ccb,
+ camdd_argmask arglist, int probe_retry_count,
+ int probe_timeout, uint64_t *maxsector, uint32_t *block_len);
struct camdd_dev *camdd_probe_file(int fd, struct camdd_io_opts *io_opts,
int retry_count, int timeout);
struct camdd_dev *camdd_probe_pass(struct cam_device *cam_dev,
@@ -488,6 +492,11 @@
camdd_argmask arglist, int probe_retry_count,
int probe_timeout, int io_retry_count,
int io_timeout);
+void nvme_read_write(struct ccb_nvmeio *nvmeio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint32_t nsid, int readop, uint64_t lba,
+ uint32_t block_count, uint8_t *data_ptr, uint32_t dxfer_len,
+ uint32_t timeout);
void *camdd_file_worker(void *arg);
camdd_buf_status camdd_ccb_status(union ccb *ccb, int protocol);
int camdd_get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
@@ -1401,6 +1410,68 @@
return retval;
}
+int
+camdd_probe_pass_nvme(struct cam_device *cam_dev, union ccb *ccb,
+ camdd_argmask arglist, int probe_retry_count,
+ int probe_timeout, uint64_t *maxsector, uint32_t *block_len)
+{
+ struct nvme_command *nc = NULL;
+ struct nvme_namespace_data nsdata;
+ uint32_t nsid = cam_dev->target_lun & UINT32_MAX;
+ int retval = -1;
+
+ if (ccb == NULL) {
+ warnx("%s: error passed ccb is NULL", __func__);
+ goto bailout;
+ }
+
+ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->nvmeio);
+
+ /* Send Identify Namespace to get block size and capacity */
+ nc = &ccb->nvmeio.cmd;
+ nc->opc = NVME_OPC_IDENTIFY;
+
+ nc->nsid = nsid;
+ nc->cdw10 = 0; /* Identify Namespace is CNS = 0 */
+
+ cam_fill_nvmeadmin(&ccb->nvmeio,
+ /*retries*/ probe_retry_count,
+ /*cbfcnp*/ NULL,
+ CAM_DIR_IN,
+ (uint8_t *)&nsdata,
+ sizeof(nsdata),
+ probe_timeout);
+
+ /* Disable freezing the device queue */
+ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
+
+ if (arglist & CAMDD_ARG_ERR_RECOVER)
+ ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
+
+ if (cam_send_ccb(cam_dev, ccb) < 0) {
+ warn("error sending Identify Namespace command");
+
+ cam_error_print(cam_dev, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+
+ goto bailout;
+ }
+
+ if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ cam_error_print(cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
+ goto bailout;
+ }
+
+ *maxsector = nsdata.nsze;
+ /* The LBA Data Size (LBADS) is reported as a power of 2 */
+ *block_len = 1 << nsdata.lbaf[nsdata.flbas.format].lbads;
+
+ retval = 0;
+
+bailout:
+ return retval;
+}
+
/*
* Need to implement this. Do a basic probe:
* - Check the inquiry data, make sure we're talking to a device that we
@@ -1464,6 +1535,13 @@
goto bailout;
}
break;
+ case PROTO_NVME:
+ if ((retval = camdd_probe_pass_nvme(cam_dev, ccb, probe_retry_count,
+ arglist, probe_timeout, &maxsector,
+ &block_len))) {
+ goto bailout;
+ }
+ break;
default:
errx(1, "Unsupported PROTO type %d", cgd.protocol);
break; /*NOTREACHED*/
@@ -1598,6 +1676,34 @@
return (NULL);
}
+void
+nvme_read_write(struct ccb_nvmeio *nvmeio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint32_t nsid, int readop, uint64_t lba,
+ uint32_t block_count, uint8_t *data_ptr, uint32_t dxfer_len,
+ uint32_t timeout)
+{
+ struct nvme_command *nc = &nvmeio->cmd;
+
+ nc->opc = readop ? NVME_OPC_READ : NVME_OPC_WRITE;
+
+ nc->nsid = nsid;
+
+ nc->cdw10 = lba & UINT32_MAX;
+ nc->cdw11 = lba >> 32;
+
+ /* NLB (bits 15:0) is a zero based value */
+ nc->cdw12 = (block_count - 1) & UINT16_MAX;
+
+ cam_fill_nvmeio(nvmeio,
+ retries,
+ cbfcnp,
+ readop ? CAM_DIR_IN : CAM_DIR_OUT,
+ data_ptr,
+ dxfer_len,
+ timeout);
+}
+
void *
camdd_worker(void *arg)
{
@@ -1853,6 +1959,16 @@
break;
}
break;
+ case PROTO_NVME:
+ switch (ccb_status) {
+ case CAM_REQ_CMP:
+ status = CAMDD_STATUS_OK;
+ break;
+ default:
+ status = CAMDD_STATUS_ERROR;
+ break;
+ }
+ break;
default:
status = CAMDD_STATUS_ERROR;
break;
@@ -2255,6 +2371,10 @@
data->resid = ccb.csio.resid;
dev->bytes_transferred += (ccb.csio.dxfer_len - ccb.csio.resid);
break;
+ case PROTO_NVME:
+ data->resid = 0;
+ dev->bytes_transferred += ccb.nvmeio.dxfer_len;
+ break;
default:
return -1;
break;
@@ -2577,6 +2697,23 @@
ccb->csio.sglist_cnt = data->sg_count;
}
break;
+ case PROTO_NVME:
+ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->nvmeio);
+
+ nvme_read_write(&ccb->nvmeio,
+ /*retries*/ dev->retry_count,
+ /*cbfcnp*/ NULL,
+ /*nsid*/ pass_dev->dev->target_lun & UINT32_MAX,
+ /*readop*/ dev->write_dev == 0,
+ /*lba*/ buf->lba,
+ /*block_count*/ num_blocks,
+ /*data_ptr*/ (data->sg_count != 0) ?
+ (uint8_t *)data->segs : data->buf,
+ /*dxfer_len*/ (num_blocks * pass_dev->block_len),
+ /*timeout*/ dev->io_timeout);
+
+ ccb->nvmeio.sglist_cnt = data->sg_count;
+ break;
default:
retval = -1;
goto bailout;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Aug 13, 7:23 PM (7 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36675559
Default Alt Text
D12141.diff (5 KB)
Attached To
Mode
D12141: Add NVMe support to camdd
Attached
Detach File
Event Timeline
Log In to Comment