[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) | static int sas_get_port_device(struct asd_sas_port *port) | ||||||
| { | { | ||||||
| 	unsigned long flags; |  | ||||||
| 	struct asd_sas_phy *phy; | 	struct asd_sas_phy *phy; | ||||||
| 	struct sas_rphy *rphy; | 	struct sas_rphy *rphy; | ||||||
| 	struct domain_device *dev; | 	struct domain_device *dev; | ||||||
|  | @ -78,9 +77,9 @@ static int sas_get_port_device(struct asd_sas_port *port) | ||||||
| 	if (!dev) | 	if (!dev) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	spin_lock_irqsave(&port->phy_list_lock, flags); | 	spin_lock_irq(&port->phy_list_lock); | ||||||
| 	if (list_empty(&port->phy_list)) { | 	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); | 		sas_put_device(dev); | ||||||
| 		return -ENODEV; | 		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), | 	memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd), | ||||||
| 					     (size_t)phy->frame_rcvd_size)); | 					     (size_t)phy->frame_rcvd_size)); | ||||||
| 	spin_unlock(&phy->frame_rcvd_lock); | 	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) { | 	if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) { | ||||||
| 		struct dev_to_host_fis *fis = | 		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); | 		sas_put_device(dev); | ||||||
| 		return -ENODEV; | 		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; | 	rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; | ||||||
| 	memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); | 	memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); | ||||||
| 	sas_fill_in_rphy(dev, rphy); | 	sas_fill_in_rphy(dev, rphy); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ | ||||||
| #include <scsi/scsi_host.h> | #include <scsi/scsi_host.h> | ||||||
| #include <scsi/scsi_transport_sas.h> | #include <scsi/scsi_transport_sas.h> | ||||||
| #include <scsi/libsas.h> | #include <scsi/libsas.h> | ||||||
|  | #include <scsi/sas_ata.h> | ||||||
| 
 | 
 | ||||||
| #define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__) | #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) | static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) | ||||||
| { | { | ||||||
| 	struct expander_device *ex = &dev->ex_dev; | 	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 */ | 	/* add the phy to the port */ | ||||||
| 	list_add_tail(&phy->port_phy_el, &port->phy_list); | 	list_add_tail(&phy->port_phy_el, &port->phy_list); | ||||||
|  | 	sas_phy_set_target(phy, port->port_dev); | ||||||
| 	phy->port = port; | 	phy->port = port; | ||||||
| 	port->num_phys++; | 	port->num_phys++; | ||||||
| 	port->phy_mask |= (1U << phy->id); | 	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); | 	spin_lock(&port->phy_list_lock); | ||||||
| 
 | 
 | ||||||
| 	list_del_init(&phy->port_phy_el); | 	list_del_init(&phy->port_phy_el); | ||||||
|  | 	sas_phy_set_target(phy, NULL); | ||||||
| 	phy->port = NULL; | 	phy->port = NULL; | ||||||
| 	port->num_phys--; | 	port->num_phys--; | ||||||
| 	port->phy_mask &= ~(1U << phy->id); | 	port->phy_mask &= ~(1U << phy->id); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Williams
				Dan Williams