aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-28 20:24:40 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:40:33 -0500
commit899fcf40f3177697ccfb029d0484cb8ec09a51ca (patch)
tree2983a14444ca62958e50e2fdbd4dc945d7a38849 /drivers/scsi
parent9a10b33caf78f897356ac006c455e6060a40af15 (diff)
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libsas/sas_discover.c12
-rw-r--r--drivers/scsi/libsas/sas_internal.h17
-rw-r--r--drivers/scsi/libsas/sas_port.c2
3 files changed, 27 insertions, 4 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 0d58a8beaa3d..364679675602 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -69,7 +69,6 @@ void sas_init_dev(struct domain_device *dev)
69 */ 69 */
70static int sas_get_port_device(struct asd_sas_port *port) 70static int sas_get_port_device(struct asd_sas_port *port)
71{ 71{
72 unsigned long flags;
73 struct asd_sas_phy *phy; 72 struct asd_sas_phy *phy;
74 struct sas_rphy *rphy; 73 struct sas_rphy *rphy;
75 struct domain_device *dev; 74 struct domain_device *dev;
@@ -78,9 +77,9 @@ static int sas_get_port_device(struct asd_sas_port *port)
78 if (!dev) 77 if (!dev)
79 return -ENOMEM; 78 return -ENOMEM;
80 79
81 spin_lock_irqsave(&port->phy_list_lock, flags); 80 spin_lock_irq(&port->phy_list_lock);
82 if (list_empty(&port->phy_list)) { 81 if (list_empty(&port->phy_list)) {
83 spin_unlock_irqrestore(&port->phy_list_lock, flags); 82 spin_unlock_irq(&port->phy_list_lock);
84 sas_put_device(dev); 83 sas_put_device(dev);
85 return -ENODEV; 84 return -ENODEV;
86 } 85 }
@@ -89,7 +88,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
89 memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd), 88 memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd),
90 (size_t)phy->frame_rcvd_size)); 89 (size_t)phy->frame_rcvd_size));
91 spin_unlock(&phy->frame_rcvd_lock); 90 spin_unlock(&phy->frame_rcvd_lock);
92 spin_unlock_irqrestore(&port->phy_list_lock, flags); 91 spin_unlock_irq(&port->phy_list_lock);
93 92
94 if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) { 93 if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) {
95 struct dev_to_host_fis *fis = 94 struct dev_to_host_fis *fis =
@@ -134,6 +133,11 @@ static int sas_get_port_device(struct asd_sas_port *port)
134 sas_put_device(dev); 133 sas_put_device(dev);
135 return -ENODEV; 134 return -ENODEV;
136 } 135 }
136
137 spin_lock_irq(&port->phy_list_lock);
138 list_for_each_entry(phy, &port->phy_list, port_phy_el)
139 sas_phy_set_target(phy, dev);
140 spin_unlock_irq(&port->phy_list_lock);
137 rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; 141 rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
138 memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); 142 memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
139 sas_fill_in_rphy(dev, rphy); 143 sas_fill_in_rphy(dev, rphy);
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index d0d9bf10f79c..f05c63879949 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -30,6 +30,7 @@
30#include <scsi/scsi_host.h> 30#include <scsi/scsi_host.h>
31#include <scsi/scsi_transport_sas.h> 31#include <scsi/scsi_transport_sas.h>
32#include <scsi/libsas.h> 32#include <scsi/libsas.h>
33#include <scsi/sas_ata.h>
33 34
34#define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__) 35#define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__)
35 36
@@ -147,6 +148,22 @@ static inline void sas_fill_in_rphy(struct domain_device *dev,
147 } 148 }
148} 149}
149 150
151static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_device *dev)
152{
153 struct sas_phy *phy = p->phy;
154
155 if (dev) {
156 if (dev_is_sata(dev))
157 phy->identify.device_type = SAS_END_DEVICE;
158 else
159 phy->identify.device_type = dev->dev_type;
160 phy->identify.target_port_protocols = dev->tproto;
161 } else {
162 phy->identify.device_type = SAS_PHY_UNUSED;
163 phy->identify.target_port_protocols = 0;
164 }
165}
166
150static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) 167static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
151{ 168{
152 struct expander_device *ex = &dev->ex_dev; 169 struct expander_device *ex = &dev->ex_dev;
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 29f8fd335523..eb19c016d500 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -104,6 +104,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
104 104
105 /* add the phy to the port */ 105 /* add the phy to the port */
106 list_add_tail(&phy->port_phy_el, &port->phy_list); 106 list_add_tail(&phy->port_phy_el, &port->phy_list);
107 sas_phy_set_target(phy, port->port_dev);
107 phy->port = port; 108 phy->port = port;
108 port->num_phys++; 109 port->num_phys++;
109 port->phy_mask |= (1U << phy->id); 110 port->phy_mask |= (1U << phy->id);
@@ -182,6 +183,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
182 spin_lock(&port->phy_list_lock); 183 spin_lock(&port->phy_list_lock);
183 184
184 list_del_init(&phy->port_phy_el); 185 list_del_init(&phy->port_phy_el);
186 sas_phy_set_target(phy, NULL);
185 phy->port = NULL; 187 phy->port = NULL;
186 port->num_phys--; 188 port->num_phys--;
187 port->phy_mask &= ~(1U << phy->id); 189 port->phy_mask &= ~(1U << phy->id);