Lines Matching +full:cam +full:- +full:if

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2023-2024 Chelsio Communications, Inc.
13 #include <cam/cam.h>
14 #include <cam/cam_ccb.h>
15 #include <cam/cam_sim.h>
16 #include <cam/cam_xpt_sim.h>
17 #include <cam/cam_debug.h>
22 * The I/O completion may trigger after the received CQE if the I/O
23 * used a zero-copy mbuf that isn't harvested until after the NIC
31 return ((u_int *)&ccb->ccb_h.spriv_field0); in ccb_refs()
39 if (!refcount_release(ccb_refs(ccb))) in nvmf_ccb_done()
42 if (nvmf_cqe_aborted(&ccb->nvmeio.cpl)) { in nvmf_ccb_done()
43 struct cam_sim *sim = xpt_path_sim(ccb->ccb_h.path); in nvmf_ccb_done()
46 if (nvmf_fail_disconnect || sc->sim_shutdown) in nvmf_ccb_done()
47 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in nvmf_ccb_done()
49 ccb->ccb_h.status = CAM_REQUEUE_REQ; in nvmf_ccb_done()
51 } else if (ccb->nvmeio.cpl.status != 0) { in nvmf_ccb_done()
52 ccb->ccb_h.status = CAM_NVME_STATUS_ERROR; in nvmf_ccb_done()
54 } else if (ccb->ccb_h.spriv_ioerror != 0) { in nvmf_ccb_done()
55 KASSERT(ccb->ccb_h.spriv_ioerror != EJUSTRETURN, in nvmf_ccb_done()
57 ccb->ccb_h.status = CAM_REQ_CMP_ERR; in nvmf_ccb_done()
60 ccb->ccb_h.status = CAM_REQ_CMP; in nvmf_ccb_done()
76 ccb->ccb_h.spriv_ioerror = error; in nvmf_ccb_io_complete()
77 if (error == 0) { in nvmf_ccb_io_complete()
78 if (xfered == 0) { in nvmf_ccb_io_complete()
81 * If the request fails with an error in the CQE in nvmf_ccb_io_complete()
85 ccb->ccb_h.spriv_ioerror = EJUSTRETURN; in nvmf_ccb_io_complete()
88 KASSERT(xfered == ccb->nvmeio.dxfer_len, in nvmf_ccb_io_complete()
100 ccb->nvmeio.cpl = *cqe; in nvmf_ccb_complete()
107 struct ccb_nvmeio *nvmeio = &ccb->nvmeio; in nvmf_sim_io()
112 mtx_lock(&sc->sim_mtx); in nvmf_sim_io()
113 if (sc->sim_disconnected) { in nvmf_sim_io()
114 mtx_unlock(&sc->sim_mtx); in nvmf_sim_io()
115 if (nvmf_fail_disconnect || sc->sim_shutdown) in nvmf_sim_io()
116 nvmeio->ccb_h.status = CAM_DEV_NOT_THERE; in nvmf_sim_io()
118 nvmeio->ccb_h.status = CAM_REQUEUE_REQ; in nvmf_sim_io()
122 if (nvmeio->ccb_h.func_code == XPT_NVME_IO) in nvmf_sim_io()
125 qp = sc->admin; in nvmf_sim_io()
126 req = nvmf_allocate_request(qp, &nvmeio->cmd, nvmf_ccb_complete, in nvmf_sim_io()
128 mtx_unlock(&sc->sim_mtx); in nvmf_sim_io()
129 if (req == NULL) { in nvmf_sim_io()
130 nvmeio->ccb_h.status = CAM_RESRC_UNAVAIL; in nvmf_sim_io()
135 if (nvmeio->dxfer_len != 0) { in nvmf_sim_io()
138 nvmf_capsule_append_data(req->nc, &mem, nvmeio->dxfer_len, in nvmf_sim_io()
139 (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT, in nvmf_sim_io()
145 * Clear spriv_ioerror as it can hold an earlier error if this in nvmf_sim_io()
148 ccb->ccb_h.spriv_ioerror = 0; in nvmf_sim_io()
149 KASSERT(ccb->ccb_h.status == CAM_REQ_INPROG, in nvmf_sim_io()
150 ("%s: incoming CCB is not in-progress", __func__)); in nvmf_sim_io()
151 ccb->ccb_h.status |= CAM_SIM_QUEUED; in nvmf_sim_io()
160 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, in nvmf_sim_action()
162 ccb->ccb_h.func_code)); in nvmf_sim_action()
164 switch (ccb->ccb_h.func_code) { in nvmf_sim_action()
167 struct ccb_pathinq *cpi = &ccb->cpi; in nvmf_sim_action()
169 cpi->version_num = 1; in nvmf_sim_action()
170 cpi->hba_inquiry = 0; in nvmf_sim_action()
171 cpi->target_sprt = 0; in nvmf_sim_action()
172 cpi->hba_misc = PIM_UNMAPPED | PIM_NOSCAN; in nvmf_sim_action()
173 cpi->hba_eng_cnt = 0; in nvmf_sim_action()
174 cpi->max_target = 0; in nvmf_sim_action()
175 cpi->max_lun = sc->cdata->nn; in nvmf_sim_action()
176 cpi->async_flags = 0; in nvmf_sim_action()
177 cpi->hpath_id = 0; in nvmf_sim_action()
178 cpi->initiator_id = 0; in nvmf_sim_action()
179 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); in nvmf_sim_action()
180 strlcpy(cpi->hba_vid, "NVMeoF", HBA_IDLEN); in nvmf_sim_action()
181 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); in nvmf_sim_action()
182 cpi->unit_number = cam_sim_unit(sim); in nvmf_sim_action()
183 cpi->bus_id = 0; in nvmf_sim_action()
186 cpi->base_transfer_speed = 150000; in nvmf_sim_action()
187 cpi->protocol = PROTO_NVME; in nvmf_sim_action()
188 cpi->protocol_version = sc->vs; in nvmf_sim_action()
189 cpi->transport = XPORT_NVMF; in nvmf_sim_action()
190 cpi->transport_version = sc->vs; in nvmf_sim_action()
191 cpi->xport_specific.nvmf.nsid = in nvmf_sim_action()
192 xpt_path_lun_id(ccb->ccb_h.path); in nvmf_sim_action()
193 cpi->xport_specific.nvmf.trtype = sc->trtype; in nvmf_sim_action()
194 strlcpy(cpi->xport_specific.nvmf.dev_name, in nvmf_sim_action()
195 device_get_nameunit(sc->dev), in nvmf_sim_action()
196 sizeof(cpi->xport_specific.nvmf.dev_name)); in nvmf_sim_action()
197 cpi->maxio = sc->max_xfer_size; in nvmf_sim_action()
198 cpi->hba_vendor = 0; in nvmf_sim_action()
199 cpi->hba_device = 0; in nvmf_sim_action()
200 cpi->hba_subvendor = 0; in nvmf_sim_action()
201 cpi->hba_subdevice = 0; in nvmf_sim_action()
202 cpi->ccb_h.status = CAM_REQ_CMP; in nvmf_sim_action()
207 struct ccb_trans_settings *cts = &ccb->cts; in nvmf_sim_action()
211 cts->protocol = PROTO_NVME; in nvmf_sim_action()
212 cts->protocol_version = sc->vs; in nvmf_sim_action()
213 cts->transport = XPORT_NVMF; in nvmf_sim_action()
214 cts->transport_version = sc->vs; in nvmf_sim_action()
216 nvme = &cts->proto_specific.nvme; in nvmf_sim_action()
217 nvme->valid = CTS_NVME_VALID_SPEC; in nvmf_sim_action()
218 nvme->spec = sc->vs; in nvmf_sim_action()
220 nvmf = &cts->xport_specific.nvmf; in nvmf_sim_action()
221 nvmf->valid = CTS_NVMF_VALID_TRTYPE; in nvmf_sim_action()
222 nvmf->trtype = sc->trtype; in nvmf_sim_action()
223 cts->ccb_h.status = CAM_REQ_CMP; in nvmf_sim_action()
231 ccb->ccb_h.status = CAM_REQ_CMP; in nvmf_sim_action()
239 device_printf(sc->dev, "unhandled sim function %#x\n", in nvmf_sim_action()
240 ccb->ccb_h.func_code); in nvmf_sim_action()
241 ccb->ccb_h.status = CAM_REQ_INVALID; in nvmf_sim_action()
253 max_trans = sc->max_pending_io * 3 / 4; in nvmf_init_sim()
255 if (devq == NULL) { in nvmf_init_sim()
256 device_printf(sc->dev, "Failed to allocate CAM simq\n"); in nvmf_init_sim()
260 mtx_init(&sc->sim_mtx, "nvmf sim", NULL, MTX_DEF); in nvmf_init_sim()
261 sc->sim = cam_sim_alloc(nvmf_sim_action, NULL, "nvme", sc, in nvmf_init_sim()
262 device_get_unit(sc->dev), NULL, max_trans, max_trans, devq); in nvmf_init_sim()
263 if (sc->sim == NULL) { in nvmf_init_sim()
264 device_printf(sc->dev, "Failed to allocate CAM sim\n"); in nvmf_init_sim()
266 mtx_destroy(&sc->sim_mtx); in nvmf_init_sim()
269 if (xpt_bus_register(sc->sim, sc->dev, 0) != CAM_SUCCESS) { in nvmf_init_sim()
270 device_printf(sc->dev, "Failed to create CAM bus\n"); in nvmf_init_sim()
271 cam_sim_free(sc->sim, TRUE); in nvmf_init_sim()
272 mtx_destroy(&sc->sim_mtx); in nvmf_init_sim()
275 if (xpt_create_path(&sc->path, NULL, cam_sim_path(sc->sim), in nvmf_init_sim()
277 device_printf(sc->dev, "Failed to create CAM path\n"); in nvmf_init_sim()
278 xpt_bus_deregister(cam_sim_path(sc->sim)); in nvmf_init_sim()
279 cam_sim_free(sc->sim, TRUE); in nvmf_init_sim()
280 mtx_destroy(&sc->sim_mtx); in nvmf_init_sim()
292 if (ccb == NULL) { in nvmf_sim_rescan_ns()
293 device_printf(sc->dev, in nvmf_sim_rescan_ns()
299 * As with nvme_sim, map NVMe namespace IDs onto CAM unit in nvmf_sim_rescan_ns()
302 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), 0, in nvmf_sim_rescan_ns()
304 device_printf(sc->dev, in nvmf_sim_rescan_ns()
315 mtx_lock(&sc->sim_mtx); in nvmf_disconnect_sim()
316 sc->sim_disconnected = true; in nvmf_disconnect_sim()
317 xpt_freeze_simq(sc->sim, 1); in nvmf_disconnect_sim()
318 mtx_unlock(&sc->sim_mtx); in nvmf_disconnect_sim()
324 mtx_lock(&sc->sim_mtx); in nvmf_reconnect_sim()
325 sc->sim_disconnected = false; in nvmf_reconnect_sim()
326 mtx_unlock(&sc->sim_mtx); in nvmf_reconnect_sim()
327 xpt_release_simq(sc->sim, 1); in nvmf_reconnect_sim()
333 mtx_lock(&sc->sim_mtx); in nvmf_shutdown_sim()
334 sc->sim_shutdown = true; in nvmf_shutdown_sim()
335 mtx_unlock(&sc->sim_mtx); in nvmf_shutdown_sim()
336 xpt_release_simq(sc->sim, 1); in nvmf_shutdown_sim()
342 xpt_async(AC_LOST_DEVICE, sc->path, NULL); in nvmf_destroy_sim()
343 if (sc->sim_disconnected) in nvmf_destroy_sim()
344 xpt_release_simq(sc->sim, 1); in nvmf_destroy_sim()
345 xpt_free_path(sc->path); in nvmf_destroy_sim()
346 xpt_bus_deregister(cam_sim_path(sc->sim)); in nvmf_destroy_sim()
347 cam_sim_free(sc->sim, TRUE); in nvmf_destroy_sim()
348 mtx_destroy(&sc->sim_mtx); in nvmf_destroy_sim()