diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-10-19 20:45:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-20 11:23:08 -0400 |
commit | 22d8aa93d7ea169a349fb2f9dee5babc68f6a683 (patch) | |
tree | e27ab3bc1a06c24831946d1319a64d292f55f7d5 /net/ncsi | |
parent | bbc7c01e95ceef4e23e343f8cbb6edca887121a5 (diff) |
net/ncsi: Improve HNCDSC AEN handler
This improves AEN handler for Host Network Controller Driver Status
Change (HNCDSC):
* The channel's lock should be hold when accessing its state.
* Do failover when host driver isn't ready.
* Configure channel when host driver becomes ready.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ncsi')
-rw-r--r-- | net/ncsi/ncsi-aen.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c index b41a6617d498..6898e7229285 100644 --- a/net/ncsi/ncsi-aen.c +++ b/net/ncsi/ncsi-aen.c | |||
@@ -141,23 +141,35 @@ static int ncsi_aen_handler_hncdsc(struct ncsi_dev_priv *ndp, | |||
141 | return -ENODEV; | 141 | return -ENODEV; |
142 | 142 | ||
143 | /* If the channel is active one, we need reconfigure it */ | 143 | /* If the channel is active one, we need reconfigure it */ |
144 | spin_lock_irqsave(&nc->lock, flags); | ||
144 | ncm = &nc->modes[NCSI_MODE_LINK]; | 145 | ncm = &nc->modes[NCSI_MODE_LINK]; |
145 | hncdsc = (struct ncsi_aen_hncdsc_pkt *)h; | 146 | hncdsc = (struct ncsi_aen_hncdsc_pkt *)h; |
146 | ncm->data[3] = ntohl(hncdsc->status); | 147 | ncm->data[3] = ntohl(hncdsc->status); |
147 | if (!list_empty(&nc->link) || | 148 | if (!list_empty(&nc->link) || |
148 | nc->state != NCSI_CHANNEL_ACTIVE || | 149 | nc->state != NCSI_CHANNEL_ACTIVE) { |
149 | (ncm->data[3] & 0x1)) | 150 | spin_unlock_irqrestore(&nc->lock, flags); |
150 | return 0; | 151 | return 0; |
152 | } | ||
151 | 153 | ||
152 | if (ndp->flags & NCSI_DEV_HWA) | 154 | spin_unlock_irqrestore(&nc->lock, flags); |
155 | if (!(ndp->flags & NCSI_DEV_HWA) && !(ncm->data[3] & 0x1)) | ||
153 | ndp->flags |= NCSI_DEV_RESHUFFLE; | 156 | ndp->flags |= NCSI_DEV_RESHUFFLE; |
154 | 157 | ||
155 | /* If this channel is the active one and the link doesn't | 158 | /* If this channel is the active one and the link doesn't |
156 | * work, we have to choose another channel to be active one. | 159 | * work, we have to choose another channel to be active one. |
157 | * The logic here is exactly similar to what we do when link | 160 | * The logic here is exactly similar to what we do when link |
158 | * is down on the active channel. | 161 | * is down on the active channel. |
162 | * | ||
163 | * On the other hand, we need configure it when host driver | ||
164 | * state on the active channel becomes ready. | ||
159 | */ | 165 | */ |
160 | ncsi_stop_channel_monitor(nc); | 166 | ncsi_stop_channel_monitor(nc); |
167 | |||
168 | spin_lock_irqsave(&nc->lock, flags); | ||
169 | nc->state = (ncm->data[3] & 0x1) ? NCSI_CHANNEL_INACTIVE : | ||
170 | NCSI_CHANNEL_ACTIVE; | ||
171 | spin_unlock_irqrestore(&nc->lock, flags); | ||
172 | |||
161 | spin_lock_irqsave(&ndp->lock, flags); | 173 | spin_lock_irqsave(&ndp->lock, flags); |
162 | list_add_tail_rcu(&nc->link, &ndp->channel_queue); | 174 | list_add_tail_rcu(&nc->link, &ndp->channel_queue); |
163 | spin_unlock_irqrestore(&ndp->lock, flags); | 175 | spin_unlock_irqrestore(&ndp->lock, flags); |