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

[SCSI] libsas: set attached device type and target protocols for local phys

Before:
$ cat /sys/class/sas_phy/phy-6\:3/device_type
none
$ cat /sys/class/sas_phy/phy-6\:3/target_port_protocols
none

After:
$ cat /sys/class/sas_phy/phy-6\:3/device_type
end device
$ cat /sys/class/sas_phy/phy-6\:3/target_port_protocols
sata

Also downgrade the phy_list_lock to _irq instead of _irqsave since
libsas will never call sas_get_port_device with interrupts disbled.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Dan Williams and committed by
James Bottomley
899fcf40 9a10b33c

+27 -4
+8 -4
drivers/scsi/libsas/sas_discover.c
··· 69 69 */ 70 70 static int sas_get_port_device(struct asd_sas_port *port) 71 71 { 72 - unsigned long flags; 73 72 struct asd_sas_phy *phy; 74 73 struct sas_rphy *rphy; 75 74 struct domain_device *dev; ··· 77 78 if (!dev) 78 79 return -ENOMEM; 79 80 80 - spin_lock_irqsave(&port->phy_list_lock, flags); 81 + spin_lock_irq(&port->phy_list_lock); 81 82 if (list_empty(&port->phy_list)) { 82 - spin_unlock_irqrestore(&port->phy_list_lock, flags); 83 + spin_unlock_irq(&port->phy_list_lock); 83 84 sas_put_device(dev); 84 85 return -ENODEV; 85 86 } ··· 88 89 memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd), 89 90 (size_t)phy->frame_rcvd_size)); 90 91 spin_unlock(&phy->frame_rcvd_lock); 91 - spin_unlock_irqrestore(&port->phy_list_lock, flags); 92 + spin_unlock_irq(&port->phy_list_lock); 92 93 93 94 if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) { 94 95 struct dev_to_host_fis *fis = ··· 133 134 sas_put_device(dev); 134 135 return -ENODEV; 135 136 } 137 + 138 + spin_lock_irq(&port->phy_list_lock); 139 + list_for_each_entry(phy, &port->phy_list, port_phy_el) 140 + sas_phy_set_target(phy, dev); 141 + spin_unlock_irq(&port->phy_list_lock); 136 142 rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; 137 143 memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); 138 144 sas_fill_in_rphy(dev, rphy);
+17
drivers/scsi/libsas/sas_internal.h
··· 30 30 #include <scsi/scsi_host.h> 31 31 #include <scsi/scsi_transport_sas.h> 32 32 #include <scsi/libsas.h> 33 + #include <scsi/sas_ata.h> 33 34 34 35 #define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__) 35 36 ··· 145 144 default: 146 145 rphy->identify.device_type = SAS_PHY_UNUSED; 147 146 break; 147 + } 148 + } 149 + 150 + static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_device *dev) 151 + { 152 + struct sas_phy *phy = p->phy; 153 + 154 + if (dev) { 155 + if (dev_is_sata(dev)) 156 + phy->identify.device_type = SAS_END_DEVICE; 157 + else 158 + phy->identify.device_type = dev->dev_type; 159 + phy->identify.target_port_protocols = dev->tproto; 160 + } else { 161 + phy->identify.device_type = SAS_PHY_UNUSED; 162 + phy->identify.target_port_protocols = 0; 148 163 } 149 164 } 150 165
+2
drivers/scsi/libsas/sas_port.c
··· 104 104 105 105 /* add the phy to the port */ 106 106 list_add_tail(&phy->port_phy_el, &port->phy_list); 107 + sas_phy_set_target(phy, port->port_dev); 107 108 phy->port = port; 108 109 port->num_phys++; 109 110 port->phy_mask |= (1U << phy->id); ··· 183 182 spin_lock(&port->phy_list_lock); 184 183 185 184 list_del_init(&phy->port_phy_el); 185 + sas_phy_set_target(phy, NULL); 186 186 phy->port = NULL; 187 187 port->num_phys--; 188 188 port->phy_mask &= ~(1U << phy->id);