Loading drivers/nvme/host/core.c +5 −1 Original line number Diff line number Diff line Loading @@ -1995,6 +1995,9 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, int serial_len = sizeof(ctrl->serial); int model_len = sizeof(ctrl->model); if (!uuid_is_null(&ns->uuid)) return sprintf(buf, "uuid.%pU\n", &ns->uuid); if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) return sprintf(buf, "eui.%16phN\n", ns->nguid); Loading Loading @@ -2709,6 +2712,7 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl) mutex_lock(&ctrl->namespaces_mutex); /* Forcibly unquiesce queues to avoid blocking dispatch */ if (ctrl->admin_q) blk_mq_unquiesce_queue(ctrl->admin_q); list_for_each_entry(ns, &ctrl->namespaces, list) { Loading drivers/nvme/host/fc.c +64 −57 Original line number Diff line number Diff line Loading @@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, * the target device is present */ if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE) return BLK_STS_IOERR; goto busy; if (!nvme_fc_ctrl_get(ctrl)) return BLK_STS_IOERR; Loading Loading @@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, queue->lldd_handle, &op->fcp_req); if (ret) { if (op->rq) /* normal request */ if (!(op->flags & FCOP_FLAGS_AEN)) nvme_fc_unmap_data(ctrl, op->rq, op); /* else - aen. no cleanup needed */ nvme_fc_ctrl_put(ctrl); if (ret != -EBUSY) if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE && ret != -EBUSY) return BLK_STS_IOERR; if (op->rq) blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY); return BLK_STS_RESOURCE; goto busy; } return BLK_STS_OK; busy: if (!(op->flags & FCOP_FLAGS_AEN) && queue->hctx) blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY); return BLK_STS_RESOURCE; } static blk_status_t Loading Loading @@ -2802,66 +2805,70 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, return ERR_PTR(ret); } enum { FCT_TRADDR_ERR = 0, FCT_TRADDR_WWNN = 1 << 0, FCT_TRADDR_WWPN = 1 << 1, }; struct nvmet_fc_traddr { u64 nn; u64 pn; }; static const match_table_t traddr_opt_tokens = { { FCT_TRADDR_WWNN, "nn-%s" }, { FCT_TRADDR_WWPN, "pn-%s" }, { FCT_TRADDR_ERR, NULL } }; static int nvme_fc_parse_address(struct nvmet_fc_traddr *traddr, char *buf) __nvme_fc_parse_u64(substring_t *sstr, u64 *val) { substring_t args[MAX_OPT_ARGS]; char *options, *o, *p; int token, ret = 0; u64 token64; options = o = kstrdup(buf, GFP_KERNEL); if (!options) return -ENOMEM; while ((p = strsep(&o, ":\n")) != NULL) { if (!*p) continue; if (match_u64(sstr, &token64)) return -EINVAL; *val = token64; token = match_token(p, traddr_opt_tokens, args); switch (token) { case FCT_TRADDR_WWNN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->nn = token64; break; case FCT_TRADDR_WWPN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->pn = token64; break; default: pr_warn("unknown traddr token or missing value '%s'\n", p); ret = -EINVAL; goto out; } return 0; } out: kfree(options); return ret; /* * This routine validates and extracts the WWN's from the TRADDR string. * As kernel parsers need the 0x to determine number base, universally * build string to parse with 0x prefix before parsing name strings. */ static int nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen) { char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1]; substring_t wwn = { name, &name[sizeof(name)-1] }; int nnoffset, pnoffset; /* validate it string one of the 2 allowed formats */ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH && !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET], "pn-0x", NVME_FC_TRADDR_OXNNLEN)) { nnoffset = NVME_FC_TRADDR_OXNNLEN; pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET + NVME_FC_TRADDR_OXNNLEN; } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH && !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET], "pn-", NVME_FC_TRADDR_NNLEN))) { nnoffset = NVME_FC_TRADDR_NNLEN; pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN; } else goto out_einval; name[0] = '0'; name[1] = 'x'; name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0; memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->nn)) goto out_einval; memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->pn)) goto out_einval; return 0; out_einval: pr_warn("%s: bad traddr string\n", __func__); return -EINVAL; } static struct nvme_ctrl * Loading @@ -2875,11 +2882,11 @@ nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts) unsigned long flags; int ret; ret = nvme_fc_parse_address(&raddr, opts->traddr); ret = nvme_fc_parse_traddr(&raddr, opts->traddr, NVMF_TRADDR_SIZE); if (ret || !raddr.nn || !raddr.pn) return ERR_PTR(-EINVAL); ret = nvme_fc_parse_address(&laddr, opts->host_traddr); ret = nvme_fc_parse_traddr(&laddr, opts->host_traddr, NVMF_TRADDR_SIZE); if (ret || !laddr.nn || !laddr.pn) return ERR_PTR(-EINVAL); Loading drivers/nvme/host/pci.c +3 −3 Original line number Diff line number Diff line Loading @@ -1619,7 +1619,7 @@ static void nvme_free_host_mem(struct nvme_dev *dev) static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred) { struct nvme_host_mem_buf_desc *descs; u32 chunk_size, max_entries; u32 chunk_size, max_entries, len; int i = 0; void **bufs; u64 size = 0, tmp; Loading @@ -1638,10 +1638,10 @@ static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred) if (!bufs) goto out_free_descs; for (size = 0; size < preferred; size += chunk_size) { u32 len = min_t(u64, chunk_size, preferred - size); for (size = 0; size < preferred; size += len) { dma_addr_t dma_addr; len = min_t(u64, chunk_size, preferred - size); bufs[i] = dma_alloc_attrs(dev->dev, len, &dma_addr, GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_NO_WARN); if (!bufs[i]) Loading drivers/nvme/target/fc.c +53 −48 Original line number Diff line number Diff line Loading @@ -2293,66 +2293,70 @@ nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *target_port, } EXPORT_SYMBOL_GPL(nvmet_fc_rcv_fcp_abort); enum { FCT_TRADDR_ERR = 0, FCT_TRADDR_WWNN = 1 << 0, FCT_TRADDR_WWPN = 1 << 1, }; struct nvmet_fc_traddr { u64 nn; u64 pn; }; static const match_table_t traddr_opt_tokens = { { FCT_TRADDR_WWNN, "nn-%s" }, { FCT_TRADDR_WWPN, "pn-%s" }, { FCT_TRADDR_ERR, NULL } }; static int nvmet_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf) __nvme_fc_parse_u64(substring_t *sstr, u64 *val) { substring_t args[MAX_OPT_ARGS]; char *options, *o, *p; int token, ret = 0; u64 token64; options = o = kstrdup(buf, GFP_KERNEL); if (!options) return -ENOMEM; while ((p = strsep(&o, ":\n")) != NULL) { if (!*p) continue; if (match_u64(sstr, &token64)) return -EINVAL; *val = token64; token = match_token(p, traddr_opt_tokens, args); switch (token) { case FCT_TRADDR_WWNN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->nn = token64; break; case FCT_TRADDR_WWPN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->pn = token64; break; default: pr_warn("unknown traddr token or missing value '%s'\n", p); ret = -EINVAL; goto out; } return 0; } out: kfree(options); return ret; /* * This routine validates and extracts the WWN's from the TRADDR string. * As kernel parsers need the 0x to determine number base, universally * build string to parse with 0x prefix before parsing name strings. */ static int nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen) { char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1]; substring_t wwn = { name, &name[sizeof(name)-1] }; int nnoffset, pnoffset; /* validate it string one of the 2 allowed formats */ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH && !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET], "pn-0x", NVME_FC_TRADDR_OXNNLEN)) { nnoffset = NVME_FC_TRADDR_OXNNLEN; pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET + NVME_FC_TRADDR_OXNNLEN; } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH && !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET], "pn-", NVME_FC_TRADDR_NNLEN))) { nnoffset = NVME_FC_TRADDR_NNLEN; pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN; } else goto out_einval; name[0] = '0'; name[1] = 'x'; name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0; memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->nn)) goto out_einval; memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->pn)) goto out_einval; return 0; out_einval: pr_warn("%s: bad traddr string\n", __func__); return -EINVAL; } static int Loading @@ -2370,7 +2374,8 @@ nvmet_fc_add_port(struct nvmet_port *port) /* map the traddr address info to a target port */ ret = nvmet_fc_parse_traddr(&traddr, port->disc_addr.traddr); ret = nvme_fc_parse_traddr(&traddr, port->disc_addr.traddr, sizeof(port->disc_addr.traddr)); if (ret) return ret; Loading include/linux/nvme-fc.h +19 −0 Original line number Diff line number Diff line Loading @@ -334,5 +334,24 @@ struct fcnvme_ls_disconnect_acc { #define NVME_FC_LS_TIMEOUT_SEC 2 /* 2 seconds */ #define NVME_FC_TGTOP_TIMEOUT_SEC 2 /* 2 seconds */ /* * TRADDR string must be of form "nn-<16hexdigits>:pn-<16hexdigits>" * the string is allowed to be specified with or without a "0x" prefix * infront of the <16hexdigits>. Without is considered the "min" string * and with is considered the "max" string. The hexdigits may be upper * or lower case. */ #define NVME_FC_TRADDR_NNLEN 3 /* "?n-" */ #define NVME_FC_TRADDR_OXNNLEN 5 /* "?n-0x" */ #define NVME_FC_TRADDR_HEXNAMELEN 16 #define NVME_FC_TRADDR_MINLENGTH \ (2 * (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1) #define NVME_FC_TRADDR_MAXLENGTH \ (2 * (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1) #define NVME_FC_TRADDR_MIN_PN_OFFSET \ (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1) #define NVME_FC_TRADDR_MAX_PN_OFFSET \ (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1) #endif /* _NVME_FC_H */ Loading
drivers/nvme/host/core.c +5 −1 Original line number Diff line number Diff line Loading @@ -1995,6 +1995,9 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, int serial_len = sizeof(ctrl->serial); int model_len = sizeof(ctrl->model); if (!uuid_is_null(&ns->uuid)) return sprintf(buf, "uuid.%pU\n", &ns->uuid); if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) return sprintf(buf, "eui.%16phN\n", ns->nguid); Loading Loading @@ -2709,6 +2712,7 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl) mutex_lock(&ctrl->namespaces_mutex); /* Forcibly unquiesce queues to avoid blocking dispatch */ if (ctrl->admin_q) blk_mq_unquiesce_queue(ctrl->admin_q); list_for_each_entry(ns, &ctrl->namespaces, list) { Loading
drivers/nvme/host/fc.c +64 −57 Original line number Diff line number Diff line Loading @@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, * the target device is present */ if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE) return BLK_STS_IOERR; goto busy; if (!nvme_fc_ctrl_get(ctrl)) return BLK_STS_IOERR; Loading Loading @@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, queue->lldd_handle, &op->fcp_req); if (ret) { if (op->rq) /* normal request */ if (!(op->flags & FCOP_FLAGS_AEN)) nvme_fc_unmap_data(ctrl, op->rq, op); /* else - aen. no cleanup needed */ nvme_fc_ctrl_put(ctrl); if (ret != -EBUSY) if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE && ret != -EBUSY) return BLK_STS_IOERR; if (op->rq) blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY); return BLK_STS_RESOURCE; goto busy; } return BLK_STS_OK; busy: if (!(op->flags & FCOP_FLAGS_AEN) && queue->hctx) blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY); return BLK_STS_RESOURCE; } static blk_status_t Loading Loading @@ -2802,66 +2805,70 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, return ERR_PTR(ret); } enum { FCT_TRADDR_ERR = 0, FCT_TRADDR_WWNN = 1 << 0, FCT_TRADDR_WWPN = 1 << 1, }; struct nvmet_fc_traddr { u64 nn; u64 pn; }; static const match_table_t traddr_opt_tokens = { { FCT_TRADDR_WWNN, "nn-%s" }, { FCT_TRADDR_WWPN, "pn-%s" }, { FCT_TRADDR_ERR, NULL } }; static int nvme_fc_parse_address(struct nvmet_fc_traddr *traddr, char *buf) __nvme_fc_parse_u64(substring_t *sstr, u64 *val) { substring_t args[MAX_OPT_ARGS]; char *options, *o, *p; int token, ret = 0; u64 token64; options = o = kstrdup(buf, GFP_KERNEL); if (!options) return -ENOMEM; while ((p = strsep(&o, ":\n")) != NULL) { if (!*p) continue; if (match_u64(sstr, &token64)) return -EINVAL; *val = token64; token = match_token(p, traddr_opt_tokens, args); switch (token) { case FCT_TRADDR_WWNN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->nn = token64; break; case FCT_TRADDR_WWPN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->pn = token64; break; default: pr_warn("unknown traddr token or missing value '%s'\n", p); ret = -EINVAL; goto out; } return 0; } out: kfree(options); return ret; /* * This routine validates and extracts the WWN's from the TRADDR string. * As kernel parsers need the 0x to determine number base, universally * build string to parse with 0x prefix before parsing name strings. */ static int nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen) { char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1]; substring_t wwn = { name, &name[sizeof(name)-1] }; int nnoffset, pnoffset; /* validate it string one of the 2 allowed formats */ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH && !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET], "pn-0x", NVME_FC_TRADDR_OXNNLEN)) { nnoffset = NVME_FC_TRADDR_OXNNLEN; pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET + NVME_FC_TRADDR_OXNNLEN; } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH && !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET], "pn-", NVME_FC_TRADDR_NNLEN))) { nnoffset = NVME_FC_TRADDR_NNLEN; pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN; } else goto out_einval; name[0] = '0'; name[1] = 'x'; name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0; memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->nn)) goto out_einval; memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->pn)) goto out_einval; return 0; out_einval: pr_warn("%s: bad traddr string\n", __func__); return -EINVAL; } static struct nvme_ctrl * Loading @@ -2875,11 +2882,11 @@ nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts) unsigned long flags; int ret; ret = nvme_fc_parse_address(&raddr, opts->traddr); ret = nvme_fc_parse_traddr(&raddr, opts->traddr, NVMF_TRADDR_SIZE); if (ret || !raddr.nn || !raddr.pn) return ERR_PTR(-EINVAL); ret = nvme_fc_parse_address(&laddr, opts->host_traddr); ret = nvme_fc_parse_traddr(&laddr, opts->host_traddr, NVMF_TRADDR_SIZE); if (ret || !laddr.nn || !laddr.pn) return ERR_PTR(-EINVAL); Loading
drivers/nvme/host/pci.c +3 −3 Original line number Diff line number Diff line Loading @@ -1619,7 +1619,7 @@ static void nvme_free_host_mem(struct nvme_dev *dev) static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred) { struct nvme_host_mem_buf_desc *descs; u32 chunk_size, max_entries; u32 chunk_size, max_entries, len; int i = 0; void **bufs; u64 size = 0, tmp; Loading @@ -1638,10 +1638,10 @@ static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred) if (!bufs) goto out_free_descs; for (size = 0; size < preferred; size += chunk_size) { u32 len = min_t(u64, chunk_size, preferred - size); for (size = 0; size < preferred; size += len) { dma_addr_t dma_addr; len = min_t(u64, chunk_size, preferred - size); bufs[i] = dma_alloc_attrs(dev->dev, len, &dma_addr, GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_NO_WARN); if (!bufs[i]) Loading
drivers/nvme/target/fc.c +53 −48 Original line number Diff line number Diff line Loading @@ -2293,66 +2293,70 @@ nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *target_port, } EXPORT_SYMBOL_GPL(nvmet_fc_rcv_fcp_abort); enum { FCT_TRADDR_ERR = 0, FCT_TRADDR_WWNN = 1 << 0, FCT_TRADDR_WWPN = 1 << 1, }; struct nvmet_fc_traddr { u64 nn; u64 pn; }; static const match_table_t traddr_opt_tokens = { { FCT_TRADDR_WWNN, "nn-%s" }, { FCT_TRADDR_WWPN, "pn-%s" }, { FCT_TRADDR_ERR, NULL } }; static int nvmet_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf) __nvme_fc_parse_u64(substring_t *sstr, u64 *val) { substring_t args[MAX_OPT_ARGS]; char *options, *o, *p; int token, ret = 0; u64 token64; options = o = kstrdup(buf, GFP_KERNEL); if (!options) return -ENOMEM; while ((p = strsep(&o, ":\n")) != NULL) { if (!*p) continue; if (match_u64(sstr, &token64)) return -EINVAL; *val = token64; token = match_token(p, traddr_opt_tokens, args); switch (token) { case FCT_TRADDR_WWNN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->nn = token64; break; case FCT_TRADDR_WWPN: if (match_u64(args, &token64)) { ret = -EINVAL; goto out; } traddr->pn = token64; break; default: pr_warn("unknown traddr token or missing value '%s'\n", p); ret = -EINVAL; goto out; } return 0; } out: kfree(options); return ret; /* * This routine validates and extracts the WWN's from the TRADDR string. * As kernel parsers need the 0x to determine number base, universally * build string to parse with 0x prefix before parsing name strings. */ static int nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen) { char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1]; substring_t wwn = { name, &name[sizeof(name)-1] }; int nnoffset, pnoffset; /* validate it string one of the 2 allowed formats */ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH && !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET], "pn-0x", NVME_FC_TRADDR_OXNNLEN)) { nnoffset = NVME_FC_TRADDR_OXNNLEN; pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET + NVME_FC_TRADDR_OXNNLEN; } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH && !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) && !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET], "pn-", NVME_FC_TRADDR_NNLEN))) { nnoffset = NVME_FC_TRADDR_NNLEN; pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN; } else goto out_einval; name[0] = '0'; name[1] = 'x'; name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0; memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->nn)) goto out_einval; memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN); if (__nvme_fc_parse_u64(&wwn, &traddr->pn)) goto out_einval; return 0; out_einval: pr_warn("%s: bad traddr string\n", __func__); return -EINVAL; } static int Loading @@ -2370,7 +2374,8 @@ nvmet_fc_add_port(struct nvmet_port *port) /* map the traddr address info to a target port */ ret = nvmet_fc_parse_traddr(&traddr, port->disc_addr.traddr); ret = nvme_fc_parse_traddr(&traddr, port->disc_addr.traddr, sizeof(port->disc_addr.traddr)); if (ret) return ret; Loading
include/linux/nvme-fc.h +19 −0 Original line number Diff line number Diff line Loading @@ -334,5 +334,24 @@ struct fcnvme_ls_disconnect_acc { #define NVME_FC_LS_TIMEOUT_SEC 2 /* 2 seconds */ #define NVME_FC_TGTOP_TIMEOUT_SEC 2 /* 2 seconds */ /* * TRADDR string must be of form "nn-<16hexdigits>:pn-<16hexdigits>" * the string is allowed to be specified with or without a "0x" prefix * infront of the <16hexdigits>. Without is considered the "min" string * and with is considered the "max" string. The hexdigits may be upper * or lower case. */ #define NVME_FC_TRADDR_NNLEN 3 /* "?n-" */ #define NVME_FC_TRADDR_OXNNLEN 5 /* "?n-0x" */ #define NVME_FC_TRADDR_HEXNAMELEN 16 #define NVME_FC_TRADDR_MINLENGTH \ (2 * (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1) #define NVME_FC_TRADDR_MAXLENGTH \ (2 * (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1) #define NVME_FC_TRADDR_MIN_PN_OFFSET \ (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1) #define NVME_FC_TRADDR_MAX_PN_OFFSET \ (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1) #endif /* _NVME_FC_H */