This adds CAM pass(4) support for NVMe IO's. Applications indicate
the IO type (Admin or NVM) using XPT op-codes XPT_NVME_ADMIN or XPT_NVME_IO. Submitted by: Chuck Tuffli <chuck@tuffli.net> Differential Revision: https://reviews.freebsd.org/D10247
This commit is contained in:
parent
5cead59181
commit
df4245150a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320984
@ -207,7 +207,7 @@ typedef enum {
|
||||
/* Serial Management Protocol */
|
||||
|
||||
XPT_NVME_IO = 0x1c | XPT_FC_DEV_QUEUED,
|
||||
/* Execiute the requestred NVMe I/O operation */
|
||||
/* Execute the requested NVMe I/O operation */
|
||||
|
||||
XPT_MMC_IO = 0x1d | XPT_FC_DEV_QUEUED,
|
||||
/* Placeholder for MMC / SD / SDIO I/O stuff */
|
||||
@ -216,6 +216,9 @@ typedef enum {
|
||||
| XPT_FC_XPT_ONLY,
|
||||
/* Scan Target */
|
||||
|
||||
XPT_NVME_ADMIN = 0x1f | XPT_FC_DEV_QUEUED,
|
||||
/* Execute the requested NVMe Admin operation */
|
||||
|
||||
/* HBA engine commands 0x20->0x2F */
|
||||
XPT_ENG_INQ = 0x20 | XPT_FC_XPT_ONLY,
|
||||
/* HBA engine feature inquiry */
|
||||
@ -819,7 +822,7 @@ struct ccb_relsim {
|
||||
};
|
||||
|
||||
/*
|
||||
* NVMe I/O Request CCB used for the XPT_NVME_IO function code.
|
||||
* NVMe I/O Request CCB used for the XPT_NVME_IO and XPT_NVME_ADMIN function codes.
|
||||
*/
|
||||
struct ccb_nvmeio {
|
||||
struct ccb_hdr ccb_h;
|
||||
@ -1515,6 +1518,21 @@ cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t retries,
|
||||
nvmeio->data_ptr = data_ptr;
|
||||
nvmeio->dxfer_len = dxfer_len;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cam_fill_nvmeadmin(struct ccb_nvmeio *nvmeio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||
u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
|
||||
u_int32_t timeout)
|
||||
{
|
||||
nvmeio->ccb_h.func_code = XPT_NVME_ADMIN;
|
||||
nvmeio->ccb_h.flags = flags;
|
||||
nvmeio->ccb_h.retry_count = retries;
|
||||
nvmeio->ccb_h.cbfcnp = cbfcnp;
|
||||
nvmeio->ccb_h.timeout = timeout;
|
||||
nvmeio->data_ptr = data_ptr;
|
||||
nvmeio->dxfer_len = dxfer_len;
|
||||
}
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _CAM_CAM_CCB_H */
|
||||
|
@ -848,6 +848,17 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo,
|
||||
dirs[1] = CAM_DIR_IN;
|
||||
numbufs = 2;
|
||||
break;
|
||||
case XPT_NVME_IO:
|
||||
case XPT_NVME_ADMIN:
|
||||
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
|
||||
return (0);
|
||||
if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR)
|
||||
return (EINVAL);
|
||||
data_ptrs[0] = &ccb->nvmeio.data_ptr;
|
||||
lengths[0] = ccb->nvmeio.dxfer_len;
|
||||
dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
|
||||
numbufs = 1;
|
||||
break;
|
||||
case XPT_DEV_ADVINFO:
|
||||
if (ccb->cdai.bufsiz == 0)
|
||||
return (0);
|
||||
@ -1014,6 +1025,11 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
|
||||
numbufs = min(mapinfo->num_bufs_used, 1);
|
||||
data_ptrs[0] = (uint8_t **)&ccb->cdai.buf;
|
||||
break;
|
||||
case XPT_NVME_IO:
|
||||
case XPT_NVME_ADMIN:
|
||||
data_ptrs[0] = &ccb->nvmeio.data_ptr;
|
||||
numbufs = min(mapinfo->num_bufs_used, 1);
|
||||
break;
|
||||
default:
|
||||
/* allow ourselves to be swapped once again */
|
||||
PRELE(curproc);
|
||||
|
@ -2689,8 +2689,8 @@ xpt_action_default(union ccb *start_ccb)
|
||||
start_ccb->ataio.resid = 0;
|
||||
/* FALLTHROUGH */
|
||||
case XPT_NVME_IO:
|
||||
if (start_ccb->ccb_h.func_code == XPT_NVME_IO)
|
||||
start_ccb->nvmeio.resid = 0;
|
||||
/* FALLTHROUGH */
|
||||
case XPT_NVME_ADMIN:
|
||||
/* FALLTHROUGH */
|
||||
case XPT_MMC_IO:
|
||||
/* XXX just like nmve_io? */
|
||||
@ -5548,6 +5548,7 @@ static struct kv map[] = {
|
||||
{ XPT_MMC_IO, "XPT_MMC_IO" },
|
||||
{ XPT_SMP_IO, "XPT_SMP_IO" },
|
||||
{ XPT_SCAN_TGT, "XPT_SCAN_TGT" },
|
||||
{ XPT_NVME_ADMIN, "XPT_NVME_ADMIN" },
|
||||
{ XPT_ENG_INQ, "XPT_ENG_INQ" },
|
||||
{ XPT_ENG_EXEC, "XPT_ENG_EXEC" },
|
||||
{ XPT_EN_LUN, "XPT_EN_LUN" },
|
||||
|
@ -1146,6 +1146,11 @@ passiocleanup(struct pass_softc *softc, struct pass_io_req *io_req)
|
||||
numbufs = min(io_req->num_bufs, 1);
|
||||
data_ptrs[0] = (uint8_t **)&ccb->cdai.buf;
|
||||
break;
|
||||
case XPT_NVME_IO:
|
||||
case XPT_NVME_ADMIN:
|
||||
data_ptrs[0] = &ccb->nvmeio.data_ptr;
|
||||
numbufs = min(io_req->num_bufs, 1);
|
||||
break;
|
||||
default:
|
||||
/* allow ourselves to be swapped once again */
|
||||
return;
|
||||
@ -1384,6 +1389,25 @@ passmemsetup(struct cam_periph *periph, struct pass_io_req *io_req)
|
||||
dirs[0] = CAM_DIR_IN;
|
||||
numbufs = 1;
|
||||
break;
|
||||
case XPT_NVME_ADMIN:
|
||||
case XPT_NVME_IO:
|
||||
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
|
||||
return (0);
|
||||
|
||||
io_req->data_flags = ccb->ccb_h.flags & CAM_DATA_MASK;
|
||||
|
||||
/*
|
||||
* We only support a single virtual address for NVMe
|
||||
*/
|
||||
if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR)
|
||||
return (EINVAL);
|
||||
|
||||
data_ptrs[0] = &ccb->nvmeio.data_ptr;
|
||||
lengths[0] = ccb->nvmeio.dxfer_len;
|
||||
dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
|
||||
numbufs = 1;
|
||||
maxmap = softc->maxio;
|
||||
break;
|
||||
default:
|
||||
return(EINVAL);
|
||||
break; /* NOTREACHED */
|
||||
@ -1957,7 +1981,8 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread
|
||||
*/
|
||||
if ((fc == XPT_SCSI_IO) || (fc == XPT_ATA_IO)
|
||||
|| (fc == XPT_SMP_IO) || (fc == XPT_DEV_MATCH)
|
||||
|| (fc == XPT_DEV_ADVINFO)) {
|
||||
|| (fc == XPT_DEV_ADVINFO)
|
||||
|| (fc == XPT_NVME_ADMIN) || (fc == XPT_NVME_IO)) {
|
||||
error = passmemsetup(periph, io_req);
|
||||
if (error != 0)
|
||||
goto camioqueue_error;
|
||||
|
@ -110,7 +110,10 @@ nvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb)
|
||||
|
||||
memcpy(&req->cmd, &ccb->nvmeio.cmd, sizeof(ccb->nvmeio.cmd));
|
||||
|
||||
nvme_ctrlr_submit_io_request(ctrlr, req);
|
||||
if (ccb->ccb_h.func_code == XPT_NVME_IO)
|
||||
nvme_ctrlr_submit_io_request(ctrlr, req);
|
||||
else
|
||||
nvme_ctrlr_submit_admin_request(ctrlr, req);
|
||||
|
||||
ccb->ccb_h.status |= CAM_SIM_QUEUED;
|
||||
}
|
||||
@ -225,6 +228,7 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
case XPT_NVME_IO: /* Execute the requested I/O operation */
|
||||
case XPT_NVME_ADMIN: /* or Admin operation */
|
||||
nvme_sim_nvmeio(sim, ccb);
|
||||
return; /* no done */
|
||||
default:
|
||||
|
@ -218,6 +218,16 @@ _bus_dmamap_load_ccb(bus_dma_tag_t dmat, bus_dmamap_t map, union ccb *ccb,
|
||||
sglist_cnt = 0;
|
||||
break;
|
||||
}
|
||||
case XPT_NVME_IO:
|
||||
case XPT_NVME_ADMIN: {
|
||||
struct ccb_nvmeio *nvmeio;
|
||||
|
||||
nvmeio = &ccb->nvmeio;
|
||||
data_ptr = nvmeio->data_ptr;
|
||||
dxfer_len = nvmeio->dxfer_len;
|
||||
sglist_cnt = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
panic("_bus_dmamap_load_ccb: Unsupported func code %d",
|
||||
ccb_h->func_code);
|
||||
|
Loading…
Reference in New Issue
Block a user