Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] scsi_transport_sas: add unindexed ports

Some SAS HBAs don't want to go to the trouble of tracking port numbers,
so they'd simply like to say "add this port and give it a number".
This is especially beneficial from the hotplug point of view, since
tracking ports and the available number space can be a real pain.

The current implementation uses an incrementing number per expander to
add the port on. However, since there can never be more ports than
there are phys, a later implementation will try to be more intelligent
about this.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

James Bottomley and committed by
James Bottomley
c9fefeb2 24f6d2fd

+38 -2
+35 -1
drivers/scsi/scsi_transport_sas.c
··· 41 41 struct mutex lock; 42 42 u32 next_target_id; 43 43 u32 next_expander_id; 44 + int next_port_id; 44 45 }; 45 46 #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) 46 47 ··· 147 146 mutex_init(&sas_host->lock); 148 147 sas_host->next_target_id = 0; 149 148 sas_host->next_expander_id = 0; 149 + sas_host->next_port_id = 0; 150 150 return 0; 151 151 } 152 152 ··· 329 327 sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", 330 328 unsigned long long); 331 329 sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); 332 - //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); 330 + //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int); 333 331 sas_phy_linkspeed_attr(negotiated_linkrate); 334 332 sas_phy_linkspeed_attr(minimum_linkrate_hw); 335 333 sas_phy_linkspeed_attr(minimum_linkrate); ··· 591 589 return port; 592 590 } 593 591 EXPORT_SYMBOL(sas_port_alloc); 592 + 593 + /** sas_port_alloc_num - allocate and initialize a SAS port structure 594 + * 595 + * @parent: parent device 596 + * 597 + * Allocates a SAS port structure and a number to go with it. This 598 + * interface is really for adapters where the port number has no 599 + * meansing, so the sas class should manage them. It will be added to 600 + * the device tree below the device specified by @parent which must be 601 + * either a Scsi_Host or a sas_expander_device. 602 + * 603 + * Returns %NULL on error 604 + */ 605 + struct sas_port *sas_port_alloc_num(struct device *parent) 606 + { 607 + int index; 608 + struct Scsi_Host *shost = dev_to_shost(parent); 609 + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 610 + 611 + /* FIXME: use idr for this eventually */ 612 + mutex_lock(&sas_host->lock); 613 + if (scsi_is_sas_expander_device(parent)) { 614 + struct sas_rphy *rphy = dev_to_rphy(parent); 615 + struct sas_expander_device *exp = rphy_to_expander_device(rphy); 616 + 617 + index = exp->next_port_id++; 618 + } else 619 + index = sas_host->next_port_id++; 620 + mutex_unlock(&sas_host->lock); 621 + return sas_port_alloc(parent, index); 622 + } 623 + EXPORT_SYMBOL(sas_port_alloc_num); 594 624 595 625 /** 596 626 * sas_port_add - add a SAS port to the device hierarchy
+3 -1
include/scsi/scsi_transport_sas.h
··· 106 106 107 107 struct sas_expander_device { 108 108 int level; 109 + int next_port_id; 109 110 110 111 #define SAS_EXPANDER_VENDOR_ID_LEN 8 111 112 char vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1]; ··· 128 127 struct sas_port { 129 128 struct device dev; 130 129 131 - u8 port_identifier; 130 + int port_identifier; 132 131 int num_phys; 133 132 134 133 /* the other end of the link */ ··· 169 168 extern int scsi_is_sas_rphy(const struct device *); 170 169 171 170 struct sas_port *sas_port_alloc(struct device *, int); 171 + struct sas_port *sas_port_alloc_num(struct device *); 172 172 int sas_port_add(struct sas_port *); 173 173 void sas_port_free(struct sas_port *); 174 174 void sas_port_delete(struct sas_port *);