[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>
This commit is contained in:
		
					parent
					
						
							
								9a10b33caf
							
						
					
				
			
			
				commit
				
					
						899fcf40f3
					
				
			
		
					 3 changed files with 27 additions and 4 deletions
				
			
		|  | @ -69,7 +69,6 @@ void sas_init_dev(struct domain_device *dev) | |||
|  */ | ||||
| static int sas_get_port_device(struct asd_sas_port *port) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	struct asd_sas_phy *phy; | ||||
| 	struct sas_rphy *rphy; | ||||
| 	struct domain_device *dev; | ||||
|  | @ -78,9 +77,9 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
| 	if (!dev) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&port->phy_list_lock, flags); | ||||
| 	spin_lock_irq(&port->phy_list_lock); | ||||
| 	if (list_empty(&port->phy_list)) { | ||||
| 		spin_unlock_irqrestore(&port->phy_list_lock, flags); | ||||
| 		spin_unlock_irq(&port->phy_list_lock); | ||||
| 		sas_put_device(dev); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
|  | @ -89,7 +88,7 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
| 	memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd), | ||||
| 					     (size_t)phy->frame_rcvd_size)); | ||||
| 	spin_unlock(&phy->frame_rcvd_lock); | ||||
| 	spin_unlock_irqrestore(&port->phy_list_lock, flags); | ||||
| 	spin_unlock_irq(&port->phy_list_lock); | ||||
| 
 | ||||
| 	if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) { | ||||
| 		struct dev_to_host_fis *fis = | ||||
|  | @ -134,6 +133,11 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
| 		sas_put_device(dev); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irq(&port->phy_list_lock); | ||||
| 	list_for_each_entry(phy, &port->phy_list, port_phy_el) | ||||
| 		sas_phy_set_target(phy, dev); | ||||
| 	spin_unlock_irq(&port->phy_list_lock); | ||||
| 	rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; | ||||
| 	memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); | ||||
| 	sas_fill_in_rphy(dev, rphy); | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ | |||
| #include <scsi/scsi_host.h> | ||||
| #include <scsi/scsi_transport_sas.h> | ||||
| #include <scsi/libsas.h> | ||||
| #include <scsi/sas_ata.h> | ||||
| 
 | ||||
| #define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__) | ||||
| 
 | ||||
|  | @ -147,6 +148,22 @@ static inline void sas_fill_in_rphy(struct domain_device *dev, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_device *dev) | ||||
| { | ||||
| 	struct sas_phy *phy = p->phy; | ||||
| 
 | ||||
| 	if (dev) { | ||||
| 		if (dev_is_sata(dev)) | ||||
| 			phy->identify.device_type = SAS_END_DEVICE; | ||||
| 		else | ||||
| 			phy->identify.device_type = dev->dev_type; | ||||
| 		phy->identify.target_port_protocols = dev->tproto; | ||||
| 	} else { | ||||
| 		phy->identify.device_type = SAS_PHY_UNUSED; | ||||
| 		phy->identify.target_port_protocols = 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) | ||||
| { | ||||
| 	struct expander_device *ex = &dev->ex_dev; | ||||
|  |  | |||
|  | @ -104,6 +104,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
| 
 | ||||
| 	/* add the phy to the port */ | ||||
| 	list_add_tail(&phy->port_phy_el, &port->phy_list); | ||||
| 	sas_phy_set_target(phy, port->port_dev); | ||||
| 	phy->port = port; | ||||
| 	port->num_phys++; | ||||
| 	port->phy_mask |= (1U << phy->id); | ||||
|  | @ -182,6 +183,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) | |||
| 	spin_lock(&port->phy_list_lock); | ||||
| 
 | ||||
| 	list_del_init(&phy->port_phy_el); | ||||
| 	sas_phy_set_target(phy, NULL); | ||||
| 	phy->port = NULL; | ||||
| 	port->num_phys--; | ||||
| 	port->phy_mask &= ~(1U << phy->id); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Williams
				Dan Williams