0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "sas_internal.h"
0010
0011 #include <scsi/scsi_transport.h>
0012 #include <scsi/scsi_transport_sas.h>
0013 #include "scsi_sas_internal.h"
0014
0015 static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy *phy)
0016 {
0017 struct sas_ha_struct *sas_ha = phy->ha;
0018
0019 if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
0020 SAS_ADDR_SIZE) != 0 || (sas_ha->strict_wide_ports &&
0021 memcmp(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE) != 0))
0022 return false;
0023 return true;
0024 }
0025
0026 static void sas_resume_port(struct asd_sas_phy *phy)
0027 {
0028 struct domain_device *dev, *n;
0029 struct asd_sas_port *port = phy->port;
0030 struct sas_ha_struct *sas_ha = phy->ha;
0031 struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt);
0032
0033 if (si->dft->lldd_port_formed)
0034 si->dft->lldd_port_formed(phy);
0035
0036 if (port->suspended)
0037 port->suspended = 0;
0038 else {
0039
0040 return;
0041 }
0042
0043
0044
0045
0046
0047 list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) {
0048 int i, rc;
0049
0050 rc = sas_notify_lldd_dev_found(dev);
0051 if (rc) {
0052 sas_unregister_dev(port, dev);
0053 sas_destruct_devices(port);
0054 continue;
0055 }
0056
0057 if (dev_is_expander(dev->dev_type)) {
0058 dev->ex_dev.ex_change_count = -1;
0059 for (i = 0; i < dev->ex_dev.num_phys; i++) {
0060 struct ex_phy *phy = &dev->ex_dev.ex_phy[i];
0061
0062 phy->phy_change_count = -1;
0063 }
0064 }
0065 }
0066
0067 sas_discover_event(port, DISCE_RESUME);
0068 }
0069
0070 static void sas_form_port_add_phy(struct asd_sas_port *port,
0071 struct asd_sas_phy *phy, bool wideport)
0072 {
0073 list_add_tail(&phy->port_phy_el, &port->phy_list);
0074 sas_phy_set_target(phy, port->port_dev);
0075 phy->port = port;
0076 port->num_phys++;
0077 port->phy_mask |= (1U << phy->id);
0078
0079 if (wideport)
0080 pr_debug("phy%d matched wide port%d\n", phy->id,
0081 port->id);
0082 else
0083 memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE);
0084
0085 if (*(u64 *)port->attached_sas_addr == 0) {
0086 port->class = phy->class;
0087 memcpy(port->attached_sas_addr, phy->attached_sas_addr,
0088 SAS_ADDR_SIZE);
0089 port->iproto = phy->iproto;
0090 port->tproto = phy->tproto;
0091 port->oob_mode = phy->oob_mode;
0092 port->linkrate = phy->linkrate;
0093 } else {
0094 port->linkrate = max(port->linkrate, phy->linkrate);
0095 }
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105 static void sas_form_port(struct asd_sas_phy *phy)
0106 {
0107 int i;
0108 struct sas_ha_struct *sas_ha = phy->ha;
0109 struct asd_sas_port *port = phy->port;
0110 struct domain_device *port_dev = NULL;
0111 struct sas_internal *si =
0112 to_sas_internal(sas_ha->core.shost->transportt);
0113 unsigned long flags;
0114
0115 if (port) {
0116 if (!phy_is_wideport_member(port, phy))
0117 sas_deform_port(phy, 0);
0118 else if (phy->suspended) {
0119 phy->suspended = 0;
0120 sas_resume_port(phy);
0121
0122
0123 wake_up(&sas_ha->eh_wait_q);
0124 return;
0125 } else {
0126 pr_info("%s: phy%d belongs to port%d already(%d)!\n",
0127 __func__, phy->id, phy->port->id,
0128 phy->port->num_phys);
0129 return;
0130 }
0131 }
0132
0133
0134 spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
0135 for (i = 0; i < sas_ha->num_phys; i++) {
0136 port = sas_ha->sas_port[i];
0137 spin_lock(&port->phy_list_lock);
0138 if (*(u64 *) port->sas_addr &&
0139 phy_is_wideport_member(port, phy) && port->num_phys > 0) {
0140
0141 port_dev = port->port_dev;
0142 sas_form_port_add_phy(port, phy, true);
0143 spin_unlock(&port->phy_list_lock);
0144 break;
0145 }
0146 spin_unlock(&port->phy_list_lock);
0147 }
0148
0149 if (i == sas_ha->num_phys) {
0150 for (i = 0; i < sas_ha->num_phys; i++) {
0151 port = sas_ha->sas_port[i];
0152 spin_lock(&port->phy_list_lock);
0153 if (*(u64 *)port->sas_addr == 0
0154 && port->num_phys == 0) {
0155 port_dev = port->port_dev;
0156 sas_form_port_add_phy(port, phy, false);
0157 spin_unlock(&port->phy_list_lock);
0158 break;
0159 }
0160 spin_unlock(&port->phy_list_lock);
0161 }
0162
0163 if (i >= sas_ha->num_phys) {
0164 pr_err("%s: couldn't find a free port, bug?\n",
0165 __func__);
0166 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
0167 return;
0168 }
0169 }
0170 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
0171
0172 if (!port->port) {
0173 port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
0174 BUG_ON(!port->port);
0175 sas_port_add(port->port);
0176 }
0177 sas_port_add_phy(port->port, phy->phy);
0178
0179 pr_debug("%s added to %s, phy_mask:0x%x (%016llx)\n",
0180 dev_name(&phy->phy->dev), dev_name(&port->port->dev),
0181 port->phy_mask,
0182 SAS_ADDR(port->attached_sas_addr));
0183
0184 if (port_dev)
0185 port_dev->pathways = port->num_phys;
0186
0187
0188 if (si->dft->lldd_port_formed)
0189 si->dft->lldd_port_formed(phy);
0190
0191 sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN);
0192
0193 if (port_dev && dev_is_expander(port_dev->dev_type)) {
0194 struct expander_device *ex_dev = &port_dev->ex_dev;
0195
0196 ex_dev->ex_change_count = -1;
0197 sas_discover_event(port, DISCE_REVALIDATE_DOMAIN);
0198 }
0199 flush_workqueue(sas_ha->disco_q);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 void sas_deform_port(struct asd_sas_phy *phy, int gone)
0211 {
0212 struct sas_ha_struct *sas_ha = phy->ha;
0213 struct asd_sas_port *port = phy->port;
0214 struct sas_internal *si =
0215 to_sas_internal(sas_ha->core.shost->transportt);
0216 struct domain_device *dev;
0217 unsigned long flags;
0218
0219 if (!port)
0220 return;
0221
0222 dev = port->port_dev;
0223 if (dev)
0224 dev->pathways--;
0225
0226 if (port->num_phys == 1) {
0227 sas_unregister_domain_devices(port, gone);
0228 sas_destruct_devices(port);
0229 sas_port_delete(port->port);
0230 port->port = NULL;
0231 } else {
0232 sas_port_delete_phy(port->port, phy->phy);
0233 sas_device_set_phy(dev, port->port);
0234 }
0235
0236 if (si->dft->lldd_port_deformed)
0237 si->dft->lldd_port_deformed(phy);
0238
0239 spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
0240 spin_lock(&port->phy_list_lock);
0241
0242 list_del_init(&phy->port_phy_el);
0243 sas_phy_set_target(phy, NULL);
0244 phy->port = NULL;
0245 port->num_phys--;
0246 port->phy_mask &= ~(1U << phy->id);
0247
0248 if (port->num_phys == 0) {
0249 INIT_LIST_HEAD(&port->phy_list);
0250 memset(port->sas_addr, 0, SAS_ADDR_SIZE);
0251 memset(port->attached_sas_addr, 0, SAS_ADDR_SIZE);
0252 port->class = 0;
0253 port->iproto = 0;
0254 port->tproto = 0;
0255 port->oob_mode = 0;
0256 port->phy_mask = 0;
0257 }
0258 spin_unlock(&port->phy_list_lock);
0259 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
0260
0261
0262 if (port->port && dev && dev_is_expander(dev->dev_type)) {
0263 struct expander_device *ex_dev = &dev->ex_dev;
0264
0265 ex_dev->ex_change_count = -1;
0266 sas_discover_event(port, DISCE_REVALIDATE_DOMAIN);
0267 }
0268 flush_workqueue(sas_ha->disco_q);
0269
0270 return;
0271 }
0272
0273
0274
0275 void sas_porte_bytes_dmaed(struct work_struct *work)
0276 {
0277 struct asd_sas_event *ev = to_asd_sas_event(work);
0278 struct asd_sas_phy *phy = ev->phy;
0279
0280 sas_form_port(phy);
0281 }
0282
0283 void sas_porte_broadcast_rcvd(struct work_struct *work)
0284 {
0285 struct asd_sas_event *ev = to_asd_sas_event(work);
0286 struct asd_sas_phy *phy = ev->phy;
0287 unsigned long flags;
0288 u32 prim;
0289
0290 spin_lock_irqsave(&phy->sas_prim_lock, flags);
0291 prim = phy->sas_prim;
0292 spin_unlock_irqrestore(&phy->sas_prim_lock, flags);
0293
0294 pr_debug("broadcast received: %d\n", prim);
0295 sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN);
0296
0297 if (phy->port)
0298 flush_workqueue(phy->port->ha->disco_q);
0299 }
0300
0301 void sas_porte_link_reset_err(struct work_struct *work)
0302 {
0303 struct asd_sas_event *ev = to_asd_sas_event(work);
0304 struct asd_sas_phy *phy = ev->phy;
0305
0306 sas_deform_port(phy, 1);
0307 }
0308
0309 void sas_porte_timer_event(struct work_struct *work)
0310 {
0311 struct asd_sas_event *ev = to_asd_sas_event(work);
0312 struct asd_sas_phy *phy = ev->phy;
0313
0314 sas_deform_port(phy, 1);
0315 }
0316
0317 void sas_porte_hard_reset(struct work_struct *work)
0318 {
0319 struct asd_sas_event *ev = to_asd_sas_event(work);
0320 struct asd_sas_phy *phy = ev->phy;
0321
0322 sas_deform_port(phy, 1);
0323 }
0324
0325
0326
0327 static void sas_init_port(struct asd_sas_port *port,
0328 struct sas_ha_struct *sas_ha, int i)
0329 {
0330 memset(port, 0, sizeof(*port));
0331 port->id = i;
0332 INIT_LIST_HEAD(&port->dev_list);
0333 INIT_LIST_HEAD(&port->disco_list);
0334 INIT_LIST_HEAD(&port->destroy_list);
0335 INIT_LIST_HEAD(&port->sas_port_del_list);
0336 spin_lock_init(&port->phy_list_lock);
0337 INIT_LIST_HEAD(&port->phy_list);
0338 port->ha = sas_ha;
0339
0340 spin_lock_init(&port->dev_list_lock);
0341 }
0342
0343 int sas_register_ports(struct sas_ha_struct *sas_ha)
0344 {
0345 int i;
0346
0347
0348 for (i = 0; i < sas_ha->num_phys; i++) {
0349 struct asd_sas_port *port = sas_ha->sas_port[i];
0350
0351 sas_init_port(port, sas_ha, i);
0352 sas_init_disc(&port->disc, port);
0353 }
0354 return 0;
0355 }
0356
0357 void sas_unregister_ports(struct sas_ha_struct *sas_ha)
0358 {
0359 int i;
0360
0361 for (i = 0; i < sas_ha->num_phys; i++)
0362 if (sas_ha->sas_phy[i]->port)
0363 sas_deform_port(sas_ha->sas_phy[i], 0);
0364
0365 }
0366
0367 const work_func_t sas_port_event_fns[PORT_NUM_EVENTS] = {
0368 [PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed,
0369 [PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd,
0370 [PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err,
0371 [PORTE_TIMER_EVENT] = sas_porte_timer_event,
0372 [PORTE_HARD_RESET] = sas_porte_hard_reset,
0373 };