diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index e4c43ea4e..d025e0a4b 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -179,6 +179,7 @@ void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev *dev, struct spdk_scsi_t enum spdk_scsi_task_func func); void spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task); int spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name); +int spdk_scsi_dev_delete_port(struct spdk_scsi_dev *dev, uint64_t id); struct spdk_scsi_port *spdk_scsi_dev_find_port_by_id(struct spdk_scsi_dev *dev, uint64_t id); void spdk_scsi_dev_print(struct spdk_scsi_dev *dev); int spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev); diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index 32748a337..08331f20e 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -220,6 +220,20 @@ spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, } } +static struct spdk_scsi_port * +spdk_scsi_dev_find_free_port(struct spdk_scsi_dev *dev) +{ + int i; + + for (i = 0; i < SPDK_SCSI_DEV_MAX_PORTS; i++) { + if (!dev->port[i].is_used) { + return &dev->port[i]; + } + } + + return NULL; +} + int spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name) { @@ -231,7 +245,17 @@ spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name) return -1; } - port = &dev->port[dev->num_ports]; + port = spdk_scsi_dev_find_port_by_id(dev, id); + if (port != NULL) { + SPDK_ERRLOG("device already has port(%" PRIu64 ")\n", id); + return -1; + } + + port = spdk_scsi_dev_find_free_port(dev); + if (port == NULL) { + assert(false); + return -1; + } rc = spdk_scsi_port_construct(port, id, dev->num_ports, name); if (rc != 0) { @@ -242,12 +266,33 @@ spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name) return 0; } +int +spdk_scsi_dev_delete_port(struct spdk_scsi_dev *dev, uint64_t id) +{ + struct spdk_scsi_port *port; + + port = spdk_scsi_dev_find_port_by_id(dev, id); + if (port == NULL) { + SPDK_ERRLOG("device does not have specified port(%" PRIu64 ")\n", id); + return -1; + } + + spdk_scsi_port_destruct(port); + + dev->num_ports--; + + return 0; +} + struct spdk_scsi_port * spdk_scsi_dev_find_port_by_id(struct spdk_scsi_dev *dev, uint64_t id) { int i; - for (i = 0; i < dev->num_ports; i++) { + for (i = 0; i < SPDK_SCSI_DEV_MAX_PORTS; i++) { + if (!dev->port[i].is_used) { + continue; + } if (dev->port[i].id == id) { return &dev->port[i]; } diff --git a/lib/scsi/port.c b/lib/scsi/port.c index fcee92d8b..70d720049 100644 --- a/lib/scsi/port.c +++ b/lib/scsi/port.c @@ -76,12 +76,19 @@ spdk_scsi_port_construct(struct spdk_scsi_port *port, uint64_t id, uint16_t inde return -1; } + port->is_used = 1; port->id = id; port->index = index; snprintf(port->name, sizeof(port->name), "%s", name); return 0; } +void +spdk_scsi_port_destruct(struct spdk_scsi_port *port) +{ + memset(port, 0, sizeof(struct spdk_scsi_port)); +} + const char * spdk_scsi_port_get_name(const struct spdk_scsi_port *port) { diff --git a/lib/scsi/scsi_bdev.c b/lib/scsi/scsi_bdev.c index bce5ab09b..a2617c7aa 100644 --- a/lib/scsi/scsi_bdev.c +++ b/lib/scsi/scsi_bdev.c @@ -452,10 +452,14 @@ spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task, hlen = 4; /* Identification descriptor list */ - for (i = 0; i < dev->num_ports; i++) { + for (i = 0; i < SPDK_SCSI_DEV_MAX_PORTS; i++) { struct spdk_scsi_port_desc *sdesc; struct spdk_scsi_tgt_port_desc *pdesc; + if (!dev->port[i].is_used) { + continue; + } + /* Identification descriptor N */ sdesc = (struct spdk_scsi_port_desc *)&vpage->params[len]; diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index 2da98dac3..0f39573d4 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -51,7 +51,7 @@ enum { }; struct spdk_scsi_port { - struct spdk_scsi_dev *dev; + uint8_t is_used; uint64_t id; uint16_t index; char name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; @@ -159,6 +159,7 @@ struct spdk_scsi_dev *spdk_scsi_dev_get_list(void); int spdk_scsi_port_construct(struct spdk_scsi_port *port, uint64_t id, uint16_t index, const char *name); +void spdk_scsi_port_destruct(struct spdk_scsi_port *port); int spdk_bdev_scsi_execute(struct spdk_bdev *bdev, struct spdk_scsi_task *task); int spdk_bdev_scsi_reset(struct spdk_bdev *bdev, struct spdk_scsi_task *task);