diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-01-28 20:24:40 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-29 16:40:33 -0500 |
commit | 899fcf40f3177697ccfb029d0484cb8ec09a51ca (patch) | |
tree | 2983a14444ca62958e50e2fdbd4dc945d7a38849 | |
parent | 9a10b33caf78f897356ac006c455e6060a40af15 (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>
-rw-r--r-- | drivers/scsi/libsas/sas_discover.c | 12 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_internal.h | 17 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_port.c | 2 |
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 | */ |
70 | static int sas_get_port_device(struct asd_sas_port *port) | 70 | static 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 | ||
151 | static 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 | |||
150 | static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) | 167 | static 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); |