Commit 91003f35 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

s390/qeth: consolidate online/offline code

Large parts of the online/offline code are identical now, and cleaning
up the remaining stuff is easier with a shared core.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aa3ad392
...@@ -727,11 +727,10 @@ struct qeth_osn_info { ...@@ -727,11 +727,10 @@ struct qeth_osn_info {
struct qeth_discipline { struct qeth_discipline {
const struct device_type *devtype; const struct device_type *devtype;
int (*recover)(void *ptr);
int (*setup) (struct ccwgroup_device *); int (*setup) (struct ccwgroup_device *);
void (*remove) (struct ccwgroup_device *); void (*remove) (struct ccwgroup_device *);
int (*set_online) (struct ccwgroup_device *); int (*set_online)(struct qeth_card *card);
int (*set_offline) (struct ccwgroup_device *); void (*set_offline)(struct qeth_card *card);
int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd); int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd);
int (*control_event_handler)(struct qeth_card *card, int (*control_event_handler)(struct qeth_card *card,
struct qeth_ipa_cmd *cmd); struct qeth_ipa_cmd *cmd);
...@@ -987,11 +986,9 @@ struct net_device *qeth_clone_netdev(struct net_device *orig); ...@@ -987,11 +986,9 @@ struct net_device *qeth_clone_netdev(struct net_device *orig);
struct qeth_card *qeth_get_card_by_busid(char *bus_id); struct qeth_card *qeth_get_card_by_busid(char *bus_id);
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int); void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
int qeth_threads_running(struct qeth_card *, unsigned long); int qeth_threads_running(struct qeth_card *, unsigned long);
int qeth_do_run_thread(struct qeth_card *, unsigned long);
void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok); int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok);
int qeth_stop_channel(struct qeth_channel *channel); int qeth_stop_channel(struct qeth_channel *channel);
int qeth_set_offline(struct qeth_card *card, bool resetting);
void qeth_print_status_message(struct qeth_card *); void qeth_print_status_message(struct qeth_card *);
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
......
...@@ -823,7 +823,8 @@ static int qeth_set_thread_start_bit(struct qeth_card *card, ...@@ -823,7 +823,8 @@ static int qeth_set_thread_start_bit(struct qeth_card *card,
return 0; return 0;
} }
void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread) static void qeth_clear_thread_start_bit(struct qeth_card *card,
unsigned long thread)
{ {
unsigned long flags; unsigned long flags;
...@@ -832,9 +833,9 @@ void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread) ...@@ -832,9 +833,9 @@ void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
spin_unlock_irqrestore(&card->thread_mask_lock, flags); spin_unlock_irqrestore(&card->thread_mask_lock, flags);
wake_up(&card->wait_q); wake_up(&card->wait_q);
} }
EXPORT_SYMBOL_GPL(qeth_clear_thread_start_bit);
void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread) static void qeth_clear_thread_running_bit(struct qeth_card *card,
unsigned long thread)
{ {
unsigned long flags; unsigned long flags;
...@@ -843,7 +844,6 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread) ...@@ -843,7 +844,6 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
spin_unlock_irqrestore(&card->thread_mask_lock, flags); spin_unlock_irqrestore(&card->thread_mask_lock, flags);
wake_up_all(&card->wait_q); wake_up_all(&card->wait_q);
} }
EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread) static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{ {
...@@ -864,7 +864,7 @@ static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread) ...@@ -864,7 +864,7 @@ static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
return rc; return rc;
} }
int qeth_do_run_thread(struct qeth_card *card, unsigned long thread) static int qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{ {
int rc = 0; int rc = 0;
...@@ -872,7 +872,6 @@ int qeth_do_run_thread(struct qeth_card *card, unsigned long thread) ...@@ -872,7 +872,6 @@ int qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
(rc = __qeth_do_run_thread(card, thread)) >= 0); (rc = __qeth_do_run_thread(card, thread)) >= 0);
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(qeth_do_run_thread);
void qeth_schedule_recovery(struct qeth_card *card) void qeth_schedule_recovery(struct qeth_card *card)
{ {
...@@ -880,7 +879,6 @@ void qeth_schedule_recovery(struct qeth_card *card) ...@@ -880,7 +879,6 @@ void qeth_schedule_recovery(struct qeth_card *card)
if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
schedule_work(&card->kernel_thread_starter); schedule_work(&card->kernel_thread_starter);
} }
EXPORT_SYMBOL_GPL(qeth_schedule_recovery);
static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev, static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev,
struct irb *irb) struct irb *irb)
...@@ -1287,6 +1285,7 @@ static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread) ...@@ -1287,6 +1285,7 @@ static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
return rc; return rc;
} }
static int qeth_do_reset(void *data);
static void qeth_start_kernel_thread(struct work_struct *work) static void qeth_start_kernel_thread(struct work_struct *work)
{ {
struct task_struct *ts; struct task_struct *ts;
...@@ -1298,8 +1297,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) ...@@ -1298,8 +1297,7 @@ static void qeth_start_kernel_thread(struct work_struct *work)
card->write.state != CH_STATE_UP) card->write.state != CH_STATE_UP)
return; return;
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
ts = kthread_run(card->discipline->recover, (void *)card, ts = kthread_run(qeth_do_reset, card, "qeth_recover");
"qeth_recover");
if (IS_ERR(ts)) { if (IS_ERR(ts)) {
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, qeth_clear_thread_running_bit(card,
...@@ -3095,7 +3093,6 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) ...@@ -3095,7 +3093,6 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
} }
return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL); return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
} }
EXPORT_SYMBOL_GPL(qeth_hw_trap);
static int qeth_check_qdio_errors(struct qeth_card *card, static int qeth_check_qdio_errors(struct qeth_card *card,
struct qdio_buffer *buf, struct qdio_buffer *buf,
...@@ -5041,6 +5038,89 @@ int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok) ...@@ -5041,6 +5038,89 @@ int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
} }
EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card); EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);
static int qeth_set_online(struct qeth_card *card)
{
int rc;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 2, "setonlin");
rc = card->discipline->set_online(card);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return rc;
}
int qeth_set_offline(struct qeth_card *card, bool resetting)
{
int rc, rc2, rc3;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 3, "setoffl");
if ((!resetting && card->info.hwtrap) || card->info.hwtrap == 2) {
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
card->info.hwtrap = 1;
}
rtnl_lock();
card->info.open_when_online = card->dev->flags & IFF_UP;
dev_close(card->dev);
netif_device_detach(card->dev);
netif_carrier_off(card->dev);
rtnl_unlock();
card->discipline->set_offline(card);
rc = qeth_stop_channel(&card->data);
rc2 = qeth_stop_channel(&card->write);
rc3 = qeth_stop_channel(&card->read);
if (!rc)
rc = (rc2) ? rc2 : rc3;
if (rc)
QETH_CARD_TEXT_(card, 2, "1err%d", rc);
qdio_free(CARD_DDEV(card));
/* let user_space know that device is offline */
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(qeth_set_offline);
static int qeth_do_reset(void *data)
{
struct qeth_card *card = data;
int rc;
QETH_CARD_TEXT(card, 2, "recover1");
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
return 0;
QETH_CARD_TEXT(card, 2, "recover2");
dev_warn(&card->gdev->dev,
"A recovery process has been started for the device\n");
qeth_set_offline(card, true);
rc = qeth_set_online(card);
if (!rc) {
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
} else {
ccwgroup_set_offline(card->gdev);
dev_warn(&card->gdev->dev,
"The qeth device driver failed to recover an error on the device\n");
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
}
#if IS_ENABLED(CONFIG_QETH_L3) #if IS_ENABLED(CONFIG_QETH_L3)
static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr) struct qeth_hdr *hdr)
...@@ -5977,7 +6057,8 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) ...@@ -5977,7 +6057,8 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
goto err; goto err;
} }
} }
rc = card->discipline->set_online(gdev);
rc = qeth_set_online(card);
err: err:
return rc; return rc;
} }
...@@ -5985,7 +6066,8 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) ...@@ -5985,7 +6066,8 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
static int qeth_core_set_offline(struct ccwgroup_device *gdev) static int qeth_core_set_offline(struct ccwgroup_device *gdev)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
return card->discipline->set_offline(gdev);
return qeth_set_offline(card, false);
} }
static void qeth_core_shutdown(struct ccwgroup_device *gdev) static void qeth_core_shutdown(struct ccwgroup_device *gdev)
...@@ -6008,7 +6090,7 @@ static int qeth_suspend(struct ccwgroup_device *gdev) ...@@ -6008,7 +6090,7 @@ static int qeth_suspend(struct ccwgroup_device *gdev)
if (gdev->state == CCWGROUP_OFFLINE) if (gdev->state == CCWGROUP_OFFLINE)
return 0; return 0;
card->discipline->set_offline(gdev); qeth_set_offline(card, false);
return 0; return 0;
} }
...@@ -6017,7 +6099,7 @@ static int qeth_resume(struct ccwgroup_device *gdev) ...@@ -6017,7 +6099,7 @@ static int qeth_resume(struct ccwgroup_device *gdev)
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc; int rc;
rc = card->discipline->set_online(gdev); rc = qeth_set_online(card);
qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_set_allowed_threads(card, 0xffffffff, 0);
if (rc) if (rc)
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "qeth_core.h" #include "qeth_core.h"
#include "qeth_l2.h" #include "qeth_l2.h"
static int qeth_l2_set_offline(struct ccwgroup_device *);
static void qeth_bridgeport_query_support(struct qeth_card *card); static void qeth_bridgeport_query_support(struct qeth_card *card);
static void qeth_bridge_state_change(struct qeth_card *card, static void qeth_bridge_state_change(struct qeth_card *card,
struct qeth_ipa_cmd *cmd); struct qeth_ipa_cmd *cmd);
...@@ -610,7 +609,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) ...@@ -610,7 +609,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
if (cgdev->state == CCWGROUP_ONLINE) if (cgdev->state == CCWGROUP_ONLINE)
qeth_l2_set_offline(cgdev); qeth_set_offline(card, false);
cancel_work_sync(&card->close_dev_work); cancel_work_sync(&card->close_dev_work);
if (qeth_netdev_is_registered(card->dev)) if (qeth_netdev_is_registered(card->dev))
...@@ -746,17 +745,13 @@ static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) ...@@ -746,17 +745,13 @@ static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
} }
} }
static int qeth_l2_set_online(struct ccwgroup_device *gdev) static int qeth_l2_set_online(struct qeth_card *card)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct ccwgroup_device *gdev = card->gdev;
struct net_device *dev = card->dev; struct net_device *dev = card->dev;
int rc = 0; int rc = 0;
bool carrier_ok; bool carrier_ok;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 2, "setonlin");
rc = qeth_core_hardsetup_card(card, &carrier_ok); rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) { if (rc) {
QETH_CARD_TEXT_(card, 2, "2err%04x", rc); QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
...@@ -813,8 +808,6 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -813,8 +808,6 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
} }
/* let user_space know that device is online */ /* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0; return 0;
out_remove: out_remove:
...@@ -823,81 +816,12 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -823,81 +816,12 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
qeth_stop_channel(&card->write); qeth_stop_channel(&card->write);
qeth_stop_channel(&card->read); qeth_stop_channel(&card->read);
qdio_free(CARD_DDEV(card)); qdio_free(CARD_DDEV(card));
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return rc; return rc;
} }
static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, static void qeth_l2_set_offline(struct qeth_card *card)
int recovery_mode)
{ {
struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
int rc = 0, rc2 = 0, rc3 = 0;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 3, "setoffl");
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
card->info.hwtrap = 1;
}
rtnl_lock();
card->info.open_when_online = card->dev->flags & IFF_UP;
dev_close(card->dev);
netif_device_detach(card->dev);
netif_carrier_off(card->dev);
rtnl_unlock();
qeth_l2_stop_card(card); qeth_l2_stop_card(card);
rc = qeth_stop_channel(&card->data);
rc2 = qeth_stop_channel(&card->write);
rc3 = qeth_stop_channel(&card->read);
if (!rc)
rc = (rc2) ? rc2 : rc3;
if (rc)
QETH_CARD_TEXT_(card, 2, "1err%d", rc);
qdio_free(CARD_DDEV(card));
/* let user_space know that device is offline */
kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
}
static int qeth_l2_set_offline(struct ccwgroup_device *cgdev)
{
return __qeth_l2_set_offline(cgdev, 0);
}
static int qeth_l2_recover(void *ptr)
{
struct qeth_card *card;
int rc = 0;
card = (struct qeth_card *) ptr;
QETH_CARD_TEXT(card, 2, "recover1");
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
return 0;
QETH_CARD_TEXT(card, 2, "recover2");
dev_warn(&card->gdev->dev,
"A recovery process has been started for the device\n");
__qeth_l2_set_offline(card->gdev, 1);
rc = qeth_l2_set_online(card->gdev);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
ccwgroup_set_offline(card->gdev);
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
} }
static int __init qeth_l2_init(void) static int __init qeth_l2_init(void)
...@@ -934,7 +858,6 @@ static int qeth_l2_control_event(struct qeth_card *card, ...@@ -934,7 +858,6 @@ static int qeth_l2_control_event(struct qeth_card *card,
struct qeth_discipline qeth_l2_discipline = { struct qeth_discipline qeth_l2_discipline = {
.devtype = &qeth_l2_devtype, .devtype = &qeth_l2_devtype,
.recover = qeth_l2_recover,
.setup = qeth_l2_probe_device, .setup = qeth_l2_probe_device,
.remove = qeth_l2_remove_device, .remove = qeth_l2_remove_device,
.set_online = qeth_l2_set_online, .set_online = qeth_l2_set_online,
......
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
#include "qeth_l3.h" #include "qeth_l3.h"
static int qeth_l3_set_offline(struct ccwgroup_device *);
static int qeth_l3_register_addr_entry(struct qeth_card *, static int qeth_l3_register_addr_entry(struct qeth_card *,
struct qeth_ipaddr *); struct qeth_ipaddr *);
static int qeth_l3_deregister_addr_entry(struct qeth_card *, static int qeth_l3_deregister_addr_entry(struct qeth_card *,
...@@ -2044,7 +2042,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) ...@@ -2044,7 +2042,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
if (cgdev->state == CCWGROUP_ONLINE) if (cgdev->state == CCWGROUP_ONLINE)
qeth_l3_set_offline(cgdev); qeth_set_offline(card, false);
cancel_work_sync(&card->close_dev_work); cancel_work_sync(&card->close_dev_work);
if (qeth_netdev_is_registered(card->dev)) if (qeth_netdev_is_registered(card->dev))
...@@ -2056,17 +2054,13 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) ...@@ -2056,17 +2054,13 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
qeth_l3_clear_ipato_list(card); qeth_l3_clear_ipato_list(card);
} }
static int qeth_l3_set_online(struct ccwgroup_device *gdev) static int qeth_l3_set_online(struct qeth_card *card)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct ccwgroup_device *gdev = card->gdev;
struct net_device *dev = card->dev; struct net_device *dev = card->dev;
int rc = 0; int rc = 0;
bool carrier_ok; bool carrier_ok;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 2, "setonlin");
rc = qeth_core_hardsetup_card(card, &carrier_ok); rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) { if (rc) {
QETH_CARD_TEXT_(card, 2, "2err%04x", rc); QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
...@@ -2125,8 +2119,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2125,8 +2119,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
qeth_trace_features(card); qeth_trace_features(card);
/* let user_space know that device is online */ /* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0; return 0;
out_remove: out_remove:
qeth_l3_stop_card(card); qeth_l3_stop_card(card);
...@@ -2134,82 +2126,12 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2134,82 +2126,12 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
qeth_stop_channel(&card->write); qeth_stop_channel(&card->write);
qeth_stop_channel(&card->read); qeth_stop_channel(&card->read);
qdio_free(CARD_DDEV(card)); qdio_free(CARD_DDEV(card));
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return rc; return rc;
} }
static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, static void qeth_l3_set_offline(struct qeth_card *card)
int recovery_mode)
{ {
struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
int rc = 0, rc2 = 0, rc3 = 0;
mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 3, "setoffl");
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
card->info.hwtrap = 1;
}
rtnl_lock();
card->info.open_when_online = card->dev->flags & IFF_UP;
dev_close(card->dev);
netif_device_detach(card->dev);
netif_carrier_off(card->dev);
rtnl_unlock();
qeth_l3_stop_card(card); qeth_l3_stop_card(card);
rc = qeth_stop_channel(&card->data);
rc2 = qeth_stop_channel(&card->write);
rc3 = qeth_stop_channel(&card->read);
if (!rc)
rc = (rc2) ? rc2 : rc3;
if (rc)
QETH_CARD_TEXT_(card, 2, "1err%d", rc);
qdio_free(CARD_DDEV(card));
/* let user_space know that device is offline */
kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
}
static int qeth_l3_set_offline(struct ccwgroup_device *cgdev)
{
return __qeth_l3_set_offline(cgdev, 0);
}
static int qeth_l3_recover(void *ptr)
{
struct qeth_card *card;
int rc = 0;
card = (struct qeth_card *) ptr;
QETH_CARD_TEXT(card, 2, "recover1");
QETH_CARD_HEX(card, 2, &card, sizeof(void *));
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
return 0;
QETH_CARD_TEXT(card, 2, "recover2");
dev_warn(&card->gdev->dev,
"A recovery process has been started for the device\n");
__qeth_l3_set_offline(card->gdev, 1);
rc = qeth_l3_set_online(card->gdev);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
ccwgroup_set_offline(card->gdev);
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
} }
/* Returns zero if the command is successfully "consumed" */ /* Returns zero if the command is successfully "consumed" */
...@@ -2221,7 +2143,6 @@ static int qeth_l3_control_event(struct qeth_card *card, ...@@ -2221,7 +2143,6 @@ static int qeth_l3_control_event(struct qeth_card *card,
struct qeth_discipline qeth_l3_discipline = { struct qeth_discipline qeth_l3_discipline = {
.devtype = &qeth_l3_devtype, .devtype = &qeth_l3_devtype,
.recover = qeth_l3_recover,
.setup = qeth_l3_probe_device, .setup = qeth_l3_probe_device,
.remove = qeth_l3_remove_device, .remove = qeth_l3_remove_device,
.set_online = qeth_l3_set_online, .set_online = qeth_l3_set_online,
......
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