Lines Matching defs:ctrlr
28 nvmft_printf(struct nvmft_controller *ctrlr, const char *fmt, ...)
38 sbuf_printf(&sb, "nvmft%u: ", ctrlr->cntlid);
54 struct nvmft_controller *ctrlr;
56 ctrlr = malloc(sizeof(*ctrlr), M_NVMFT, M_WAITOK | M_ZERO);
57 ctrlr->cntlid = cntlid;
59 TAILQ_INSERT_TAIL(&np->controllers, ctrlr, link);
60 ctrlr->np = np;
61 mtx_init(&ctrlr->lock, "nvmft controller", NULL, MTX_DEF);
62 callout_init(&ctrlr->ka_timer, 1);
63 TASK_INIT(&ctrlr->shutdown_task, 0, nvmft_controller_shutdown, ctrlr);
64 TIMEOUT_TASK_INIT(taskqueue_thread, &ctrlr->terminate_task, 0,
65 nvmft_controller_terminate, ctrlr);
67 ctrlr->cdata = np->cdata;
68 ctrlr->cdata.ctrlr_id = htole16(cntlid);
69 memcpy(ctrlr->hostid, data->hostid, sizeof(ctrlr->hostid));
70 memcpy(ctrlr->hostnqn, data->hostnqn, sizeof(ctrlr->hostnqn));
71 ctrlr->hip.power_cycles[0] = 1;
72 ctrlr->create_time = sbinuptime();
74 ctrlr->changed_ns = malloc(sizeof(*ctrlr->changed_ns), M_NVMFT,
77 return (ctrlr);
81 nvmft_controller_free(struct nvmft_controller *ctrlr)
83 mtx_destroy(&ctrlr->lock);
84 MPASS(ctrlr->io_qpairs == NULL);
85 free(ctrlr->changed_ns, M_NVMFT);
86 free(ctrlr, M_NVMFT);
92 struct nvmft_controller *ctrlr = arg;
95 if (ctrlr->shutdown)
98 traffic = atomic_readandclear_int(&ctrlr->ka_active_traffic);
100 nvmft_printf(ctrlr,
102 nvmft_controller_error(ctrlr, NULL, ETIMEDOUT);
106 callout_schedule_sbt(&ctrlr->ka_timer, ctrlr->ka_sbt, 0, C_HARDCLOCK);
114 struct nvmft_controller *ctrlr;
142 TAILQ_FOREACH(ctrlr, &np->controllers, link) {
143 KASSERT(ctrlr->cntlid != cntlid,
148 ctrlr = nvmft_controller_alloc(np, cntlid, data);
149 nvmft_printf(ctrlr, "associated with %.*s\n",
151 ctrlr->admin = qp;
152 ctrlr->trtype = trtype;
164 ctrlr->ka_sbt = mstosbt(roundup(kato, 1000));
165 callout_reset_sbt(&ctrlr->ka_timer, ctrlr->ka_sbt, 0,
166 nvmft_keep_alive_timer, ctrlr, C_HARDCLOCK);
169 nvmft_finish_accept(qp, cmd, ctrlr);
180 struct nvmft_controller *ctrlr;
199 TAILQ_FOREACH(ctrlr, &np->controllers, link) {
200 if (ctrlr->cntlid == cntlid)
203 if (ctrlr == NULL) {
206 ctrlr->cntlid, qid, (int)sizeof(data->hostnqn),
214 if (memcmp(ctrlr->hostid, data->hostid, sizeof(ctrlr->hostid)) != 0) {
216 nvmft_printf(ctrlr,
224 if (memcmp(ctrlr->hostnqn, data->hostnqn, sizeof(ctrlr->hostnqn)) != 0) {
226 nvmft_printf(ctrlr,
235 /* XXX: Require trtype == ctrlr->trtype? */
237 mtx_lock(&ctrlr->lock);
238 if (ctrlr->shutdown) {
239 mtx_unlock(&ctrlr->lock);
241 nvmft_printf(ctrlr,
249 if (ctrlr->num_io_queues == 0) {
250 mtx_unlock(&ctrlr->lock);
252 nvmft_printf(ctrlr,
260 if (cmd->qid > ctrlr->num_io_queues) {
261 mtx_unlock(&ctrlr->lock);
263 nvmft_printf(ctrlr,
271 if (ctrlr->io_qpairs[qid - 1].qp != NULL) {
272 mtx_unlock(&ctrlr->lock);
274 nvmft_printf(ctrlr,
283 ctrlr->io_qpairs[qid - 1].qp = qp;
284 mtx_unlock(&ctrlr->lock);
285 nvmft_finish_accept(qp, cmd, ctrlr);
294 struct nvmft_controller *ctrlr = arg;
302 mtx_lock(&ctrlr->lock);
303 for (u_int i = 0; i < ctrlr->num_io_queues; i++) {
304 if (ctrlr->io_qpairs[i].qp != NULL) {
305 ctrlr->io_qpairs[i].shutdown = true;
306 mtx_unlock(&ctrlr->lock);
307 nvmft_qpair_shutdown(ctrlr->io_qpairs[i].qp);
308 mtx_lock(&ctrlr->lock);
311 mtx_unlock(&ctrlr->lock);
314 nvmft_terminate_commands(ctrlr);
317 mtx_lock(&ctrlr->lock);
318 while (ctrlr->pending_commands != 0)
319 mtx_sleep(&ctrlr->pending_commands, &ctrlr->lock, 0, "nvmftsh",
321 mtx_unlock(&ctrlr->lock);
324 for (u_int i = 0; i < ctrlr->num_io_queues; i++) {
325 if (ctrlr->io_qpairs[i].qp != NULL)
326 nvmft_qpair_destroy(ctrlr->io_qpairs[i].qp);
328 free(ctrlr->io_qpairs, M_NVMFT);
329 ctrlr->io_qpairs = NULL;
331 mtx_lock(&ctrlr->lock);
332 ctrlr->num_io_queues = 0;
335 if (NVMEV(NVME_CSTS_REG_SHST, ctrlr->csts) == NVME_SHST_OCCURRING) {
336 ctrlr->csts &= ~NVMEM(NVME_CSTS_REG_SHST);
337 ctrlr->csts |= NVMEF(NVME_CSTS_REG_SHST, NVME_SHST_COMPLETE);
340 if (NVMEV(NVME_CSTS_REG_CFS, ctrlr->csts) == 0) {
341 ctrlr->csts &= ~NVMEM(NVME_CSTS_REG_RDY);
342 ctrlr->shutdown = false;
344 mtx_unlock(&ctrlr->lock);
352 if (ctrlr->admin_closed || NVMEV(NVME_CSTS_REG_CFS, ctrlr->csts) != 0)
353 nvmft_controller_terminate(ctrlr, 0);
356 &ctrlr->terminate_task, hz * 60 * 2);
362 struct nvmft_controller *ctrlr = arg;
367 mtx_lock(&ctrlr->lock);
368 if (NVMEV(NVME_CC_REG_EN, ctrlr->cc) != 0) {
369 mtx_unlock(&ctrlr->lock);
371 if (ctrlr->ka_sbt != 0)
372 callout_schedule_sbt(&ctrlr->ka_timer, ctrlr->ka_sbt, 0,
378 ctrlr->shutdown = true;
379 mtx_unlock(&ctrlr->lock);
381 nvmft_qpair_destroy(ctrlr->admin);
384 np = ctrlr->np;
386 TAILQ_REMOVE(&np->controllers, ctrlr, link);
387 free_unr(np->ids, ctrlr->cntlid);
393 callout_drain(&ctrlr->ka_timer);
395 nvmft_printf(ctrlr, "association terminated\n");
396 nvmft_controller_free(ctrlr);
401 nvmft_controller_error(struct nvmft_controller *ctrlr, struct nvmft_qpair *qp,
415 if (qp != ctrlr->admin)
418 mtx_lock(&ctrlr->lock);
419 if (ctrlr->shutdown) {
420 ctrlr->admin_closed = true;
421 mtx_unlock(&ctrlr->lock);
425 if (NVMEV(NVME_CC_REG_EN, ctrlr->cc) == 0) {
426 MPASS(ctrlr->num_io_queues == 0);
427 mtx_unlock(&ctrlr->lock);
430 * Ok to drop lock here since ctrlr->cc can't
445 &ctrlr->terminate_task, NULL) == 0)
447 &ctrlr->terminate_task, 0);
456 ctrlr->admin_closed = true;
458 mtx_lock(&ctrlr->lock);
461 if (ctrlr->shutdown) {
462 mtx_unlock(&ctrlr->lock);
466 ctrlr->csts |= NVMEF(NVME_CSTS_REG_CFS, 1);
467 ctrlr->cc &= ~NVMEM(NVME_CC_REG_EN);
468 ctrlr->shutdown = true;
469 mtx_unlock(&ctrlr->lock);
471 callout_stop(&ctrlr->ka_timer);
472 taskqueue_enqueue(taskqueue_thread, &ctrlr->shutdown_task);
526 handle_get_log_page(struct nvmft_controller *ctrlr,
571 mtx_lock(&ctrlr->lock);
572 hip = ctrlr->hip;
574 sbintime_getsec(ctrlr->busy_total) / 60;
576 sbintime_getsec(sbinuptime() - ctrlr->create_time) / 3600;
577 mtx_unlock(&ctrlr->lock);
588 if (offset >= sizeof(ctrlr->np->fp)) {
592 todo = sizeof(ctrlr->np->fp) - offset;
597 m_copyback(m, 0, todo, (char *)&ctrlr->np->fp + offset);
604 if (offset >= sizeof(*ctrlr->changed_ns)) {
608 todo = sizeof(*ctrlr->changed_ns) - offset;
613 mtx_lock(&ctrlr->lock);
614 m_copyback(m, 0, todo, (char *)ctrlr->changed_ns + offset);
615 if (offset == 0 && len == sizeof(*ctrlr->changed_ns))
616 memset(ctrlr->changed_ns, 0,
617 sizeof(*ctrlr->changed_ns));
619 ctrlr->changed_ns_reported = false;
620 mtx_unlock(&ctrlr->lock);
627 nvmft_printf(ctrlr, "Unsupported page %#x for GET_LOG_PAGE\n",
635 nvmft_command_completed(ctrlr->admin, nc);
637 nvmft_send_generic_error(ctrlr->admin, nc, status);
648 handle_identify_command(struct nvmft_controller *ctrlr,
658 if (data_len != sizeof(ctrlr->cdata)) {
659 nvmft_printf(ctrlr,
662 nvmft_send_generic_error(ctrlr->admin, nc,
671 nvmft_dispatch_command(ctrlr->admin, nc, true);
675 m = m_getml(sizeof(ctrlr->cdata), M_WAITOK);
676 m_copyback(m, 0, sizeof(ctrlr->cdata), (void *)&ctrlr->cdata);
678 sizeof(ctrlr->cdata));
694 nvmft_populate_active_nslist(ctrlr->np, nsid, nslist);
704 nvmft_printf(ctrlr, "Unsupported CNS %#x for IDENTIFY\n", cns);
710 nvmft_command_completed(ctrlr->admin, nc);
712 nvmft_send_generic_error(ctrlr->admin, nc, status);
717 handle_set_features(struct nvmft_controller *ctrlr,
746 mtx_lock(&ctrlr->lock);
747 if (ctrlr->num_io_queues != 0) {
748 mtx_unlock(&ctrlr->lock);
750 nvmft_send_generic_error(ctrlr->admin, nc,
756 ctrlr->num_io_queues = num_queues;
757 ctrlr->io_qpairs = io_qpairs;
758 mtx_unlock(&ctrlr->lock);
762 nvmft_send_response(ctrlr->admin, &cqe);
776 mtx_lock(&ctrlr->lock);
777 ctrlr->aer_mask = aer_mask;
778 mtx_unlock(&ctrlr->lock);
779 nvmft_send_success(ctrlr->admin, nc);
783 nvmft_printf(ctrlr,
789 nvmft_send_generic_error(ctrlr->admin, nc, NVME_SC_INVALID_FIELD);
794 update_cc(struct nvmft_controller *ctrlr, uint32_t new_cc, bool *need_shutdown)
796 struct nvmft_port *np = ctrlr->np;
801 mtx_lock(&ctrlr->lock);
804 if (ctrlr->shutdown) {
805 mtx_unlock(&ctrlr->lock);
809 if (!_nvmf_validate_cc(np->max_io_qsize, np->cap, ctrlr->cc, new_cc)) {
810 mtx_unlock(&ctrlr->lock);
814 changes = ctrlr->cc ^ new_cc;
815 ctrlr->cc = new_cc;
820 ctrlr->csts &= ~NVMEM(NVME_CSTS_REG_SHST);
821 ctrlr->csts |= NVMEF(NVME_CSTS_REG_SHST, NVME_SHST_OCCURRING);
822 ctrlr->cc &= ~NVMEM(NVME_CC_REG_EN);
823 ctrlr->shutdown = true;
825 nvmft_printf(ctrlr, "shutdown requested\n");
831 nvmft_printf(ctrlr, "reset requested\n");
832 ctrlr->shutdown = true;
835 ctrlr->csts |= NVMEF(NVME_CSTS_REG_RDY, 1);
837 mtx_unlock(&ctrlr->lock);
843 handle_property_get(struct nvmft_controller *ctrlr, struct nvmf_capsule *nc,
854 rsp.value.u64 = htole64(ctrlr->np->cap);
859 rsp.value.u32.low = ctrlr->cdata.ver;
864 rsp.value.u32.low = htole32(ctrlr->cc);
869 rsp.value.u32.low = htole32(ctrlr->csts);
875 nvmft_send_response(ctrlr->admin, &rsp);
878 nvmft_send_generic_error(ctrlr->admin, nc, NVME_SC_INVALID_FIELD);
882 handle_property_set(struct nvmft_controller *ctrlr, struct nvmf_capsule *nc,
892 if (!update_cc(ctrlr, le32toh(pset->value.u32.low),
900 nvmft_send_success(ctrlr->admin, nc);
902 callout_stop(&ctrlr->ka_timer);
903 taskqueue_enqueue(taskqueue_thread, &ctrlr->shutdown_task);
907 nvmft_send_generic_error(ctrlr->admin, nc, NVME_SC_INVALID_FIELD);
911 handle_admin_fabrics_command(struct nvmft_controller *ctrlr,
916 handle_property_get(ctrlr, nc,
920 handle_property_set(ctrlr, nc,
924 nvmft_printf(ctrlr,
926 nvmft_send_generic_error(ctrlr->admin, nc,
930 nvmft_printf(ctrlr, "DISCONNECT command on admin queue\n");
931 nvmft_send_error(ctrlr->admin, nc, NVME_SCT_COMMAND_SPECIFIC,
935 nvmft_printf(ctrlr, "Unsupported fabrics command %#x\n",
937 nvmft_send_generic_error(ctrlr->admin, nc,
945 nvmft_handle_admin_command(struct nvmft_controller *ctrlr,
951 if (NVMEV(NVME_CC_REG_EN, ctrlr->cc) == 0 &&
953 nvmft_printf(ctrlr,
955 nvmft_send_generic_error(ctrlr->admin, nc,
961 atomic_store_int(&ctrlr->ka_active_traffic, 1);
965 handle_get_log_page(ctrlr, nc, cmd);
968 handle_identify_command(ctrlr, nc, cmd);
971 handle_set_features(ctrlr, nc, cmd);
974 mtx_lock(&ctrlr->lock);
975 if (ctrlr->aer_pending == NVMFT_NUM_AER) {
976 mtx_unlock(&ctrlr->lock);
977 nvmft_send_error(ctrlr->admin, nc,
982 ctrlr->aer_cids[ctrlr->aer_pidx] = cmd->cid;
983 ctrlr->aer_pending++;
984 ctrlr->aer_pidx = (ctrlr->aer_pidx + 1) % NVMFT_NUM_AER;
985 mtx_unlock(&ctrlr->lock);
990 nvmft_send_success(ctrlr->admin, nc);
994 handle_admin_fabrics_command(ctrlr, nc,
998 nvmft_printf(ctrlr, "Unsupported admin opcode %#x\n", cmd->opc);
999 nvmft_send_generic_error(ctrlr->admin, nc,
1010 struct nvmft_controller *ctrlr = nvmft_qpair_ctrlr(qp);
1013 atomic_store_int(&ctrlr->ka_active_traffic, 1);
1034 nvmft_printf(ctrlr, "Unsupported I/O opcode %#x\n", cmd->opc);
1043 nvmft_report_aer(struct nvmft_controller *ctrlr, uint32_t aer_mask,
1051 mtx_lock(&ctrlr->lock);
1052 if ((ctrlr->aer_mask & aer_mask) == 0) {
1053 mtx_unlock(&ctrlr->lock);
1061 if (ctrlr->aer_pending == 0) {
1062 mtx_unlock(&ctrlr->lock);
1063 nvmft_printf(ctrlr,
1070 cpl.cid = ctrlr->aer_cids[ctrlr->aer_cidx];
1071 ctrlr->aer_pending--;
1072 ctrlr->aer_cidx = (ctrlr->aer_cidx + 1) % NVMFT_NUM_AER;
1073 mtx_unlock(&ctrlr->lock);
1079 nvmft_send_response(ctrlr->admin, &cpl);
1083 nvmft_controller_lun_changed(struct nvmft_controller *ctrlr, int lun_id)
1091 mtx_lock(&ctrlr->lock);
1092 nslist = ctrlr->changed_ns;
1101 mtx_unlock(&ctrlr->lock);
1111 memset(ctrlr->changed_ns, 0,
1112 sizeof(*ctrlr->changed_ns));
1113 ctrlr->changed_ns->ns[0] = 0xffffffff;
1128 if (ctrlr->changed_ns_reported) {
1129 mtx_unlock(&ctrlr->lock);
1132 ctrlr->changed_ns_reported = true;
1133 mtx_unlock(&ctrlr->lock);
1135 nvmft_report_aer(ctrlr, NVME_ASYNC_EVENT_NS_ATTRIBUTE, 0x2, 0x0,