Commit 59579da3 authored by Klaus D. Wacker's avatar Klaus D. Wacker Committed by David S. Miller

lcs: Channel errors drive lcs_recovery which leads to kernel panic.

When the lcs irq routine detects channel failures it drives device recovery.
After this event the device is no longer usable for shutdown requests,
because the lcs_irq routine may get wrong channel status information.
In such a case the lcs_irq routine marks the channel in 'error' state.
The channel state comes back to 'running' after restarting the channels.
Signed-off-by: default avatarKlaus D. Wacker <kdwacker@de.ibm.com>
Signed-off-by: default avatarUrsula Braun <braunu@de.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d8fae9c2
...@@ -1400,11 +1400,14 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -1400,11 +1400,14 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n", PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
cdev->dev.bus_id, dstat, cstat); cdev->dev.bus_id, dstat, cstat);
if (rc) { if (rc) {
channel->state = LCS_CH_STATE_ERROR;
}
}
if (channel->state == LCS_CH_STATE_ERROR) {
lcs_schedule_recovery(card); lcs_schedule_recovery(card);
wake_up(&card->wait_q); wake_up(&card->wait_q);
return; return;
} }
}
/* How far in the ccw chain have we processed? */ /* How far in the ccw chain have we processed? */
if ((channel->state != LCS_CH_STATE_INIT) && if ((channel->state != LCS_CH_STATE_INIT) &&
(irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
...@@ -1708,6 +1711,8 @@ lcs_stopcard(struct lcs_card *card) ...@@ -1708,6 +1711,8 @@ lcs_stopcard(struct lcs_card *card)
if (card->read.state != LCS_CH_STATE_STOPPED && if (card->read.state != LCS_CH_STATE_STOPPED &&
card->write.state != LCS_CH_STATE_STOPPED && card->write.state != LCS_CH_STATE_STOPPED &&
card->read.state != LCS_CH_STATE_ERROR &&
card->write.state != LCS_CH_STATE_ERROR &&
card->state == DEV_STATE_UP) { card->state == DEV_STATE_UP) {
lcs_clear_multicast_list(card); lcs_clear_multicast_list(card);
rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP); rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP);
......
...@@ -138,6 +138,7 @@ enum lcs_channel_states { ...@@ -138,6 +138,7 @@ enum lcs_channel_states {
LCS_CH_STATE_RUNNING, LCS_CH_STATE_RUNNING,
LCS_CH_STATE_SUSPENDED, LCS_CH_STATE_SUSPENDED,
LCS_CH_STATE_CLEARED, LCS_CH_STATE_CLEARED,
LCS_CH_STATE_ERROR,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment