Commit 6efca894 authored by David S. Miller's avatar David S. Miller

Merge branch 's390-qeth-next'

Julian Wiedmann says:

====================
s390/qeth: updates 2020-01-25

please apply the following patch series for qeth to your net-next tree.

This brings a number of cleanups for the init/teardown code paths.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 14a1d246 17d9723e
...@@ -558,7 +558,6 @@ enum qeth_channel_states { ...@@ -558,7 +558,6 @@ enum qeth_channel_states {
*/ */
enum qeth_card_states { enum qeth_card_states {
CARD_STATE_DOWN, CARD_STATE_DOWN,
CARD_STATE_HARDSETUP,
CARD_STATE_SOFTSETUP, CARD_STATE_SOFTSETUP,
}; };
...@@ -608,6 +607,8 @@ struct qeth_cmd_buffer { ...@@ -608,6 +607,8 @@ struct qeth_cmd_buffer {
long timeout; long timeout;
unsigned char *data; unsigned char *data;
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob); void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
bool (*match)(struct qeth_cmd_buffer *iob,
struct qeth_cmd_buffer *reply);
void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob, void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
unsigned int data_length); unsigned int data_length);
int rc; int rc;
...@@ -618,6 +619,14 @@ static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob) ...@@ -618,6 +619,14 @@ static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
refcount_inc(&iob->ref_count); refcount_inc(&iob->ref_count);
} }
static inline struct qeth_ipa_cmd *__ipa_reply(struct qeth_cmd_buffer *iob)
{
if (!IS_IPA(iob->data))
return NULL;
return (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
}
static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob) static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
{ {
return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
...@@ -727,11 +736,10 @@ struct qeth_osn_info { ...@@ -727,11 +736,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,14 +995,11 @@ struct net_device *qeth_clone_netdev(struct net_device *orig); ...@@ -987,14 +995,11 @@ 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_init_qdio_queues(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 *,
int (*reply_cb) int (*reply_cb)
(struct qeth_card *, struct qeth_reply *, unsigned long), (struct qeth_card *, struct qeth_reply *, unsigned long),
...@@ -1027,7 +1032,9 @@ void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable); ...@@ -1027,7 +1032,9 @@ void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable);
int qeth_setadpparms_change_macaddr(struct qeth_card *); int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *, unsigned int txqueue); void qeth_tx_timeout(struct net_device *, unsigned int txqueue);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
u16 cmd_length); u16 cmd_length,
bool (*match)(struct qeth_cmd_buffer *iob,
struct qeth_cmd_buffer *reply));
int qeth_query_switch_attributes(struct qeth_card *card, int qeth_query_switch_attributes(struct qeth_card *card,
struct qeth_switch_info *sw_info); struct qeth_switch_info *sw_info);
int qeth_query_card_info(struct qeth_card *card, int qeth_query_card_info(struct qeth_card *card,
......
This diff is collapsed.
...@@ -24,8 +24,6 @@ static ssize_t qeth_dev_state_show(struct device *dev, ...@@ -24,8 +24,6 @@ static ssize_t qeth_dev_state_show(struct device *dev,
switch (card->state) { switch (card->state) {
case CARD_STATE_DOWN: case CARD_STATE_DOWN:
return sprintf(buf, "DOWN\n"); return sprintf(buf, "DOWN\n");
case CARD_STATE_HARDSETUP:
return sprintf(buf, "HARDSETUP\n");
case CARD_STATE_SOFTSETUP: case CARD_STATE_SOFTSETUP:
if (card->dev->flags & IFF_UP) if (card->dev->flags & IFF_UP)
return sprintf(buf, "UP (LAN %s)\n", return sprintf(buf, "UP (LAN %s)\n",
......
...@@ -13,7 +13,6 @@ extern const struct attribute_group *qeth_l2_attr_groups[]; ...@@ -13,7 +13,6 @@ extern const struct attribute_group *qeth_l2_attr_groups[];
int qeth_l2_create_device_attributes(struct device *); int qeth_l2_create_device_attributes(struct device *);
void qeth_l2_remove_device_attributes(struct device *); void qeth_l2_remove_device_attributes(struct device *);
void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card);
int qeth_bridgeport_query_ports(struct qeth_card *card, int qeth_bridgeport_query_ports(struct qeth_card *card,
enum qeth_sbp_roles *role, enum qeth_sbp_roles *role,
enum qeth_sbp_states *state); enum qeth_sbp_states *state);
......
...@@ -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);
...@@ -284,15 +283,12 @@ static void qeth_l2_stop_card(struct qeth_card *card) ...@@ -284,15 +283,12 @@ static void qeth_l2_stop_card(struct qeth_card *card)
if (card->state == CARD_STATE_SOFTSETUP) { if (card->state == CARD_STATE_SOFTSETUP) {
qeth_clear_ipacmd_list(card); qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
}
if (card->state == CARD_STATE_HARDSETUP) {
qeth_drain_output_queues(card); qeth_drain_output_queues(card);
qeth_clear_working_pool_list(card);
card->state = CARD_STATE_DOWN; card->state = CARD_STATE_DOWN;
} }
qeth_qdio_clear_card(card, 0); qeth_qdio_clear_card(card, 0);
qeth_clear_working_pool_list(card);
flush_workqueue(card->event_wq); flush_workqueue(card->event_wq);
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
card->info.promisc_mode = 0; card->info.promisc_mode = 0;
...@@ -610,7 +606,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) ...@@ -610,7 +606,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))
...@@ -728,17 +724,31 @@ static void qeth_l2_trace_features(struct qeth_card *card) ...@@ -728,17 +724,31 @@ static void qeth_l2_trace_features(struct qeth_card *card)
sizeof(card->options.vnicc.sup_chars)); sizeof(card->options.vnicc.sup_chars));
} }
static int qeth_l2_set_online(struct ccwgroup_device *gdev) static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); if (!card->options.sbp.reflect_promisc &&
card->options.sbp.role != QETH_SBP_ROLE_NONE) {
/* Conditional to avoid spurious error messages */
qeth_bridgeport_setrole(card, card->options.sbp.role);
/* Let the callback function refresh the stored role value. */
qeth_bridgeport_query_ports(card, &card->options.sbp.role,
NULL);
}
if (card->options.sbp.hostnotification) {
if (qeth_bridgeport_an_set(card, 1))
card->options.sbp.hostnotification = 0;
} else {
qeth_bridgeport_an_set(card, 0);
}
}
static int qeth_l2_set_online(struct qeth_card *card)
{
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);
...@@ -748,9 +758,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -748,9 +758,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
mutex_lock(&card->sbp_lock); mutex_lock(&card->sbp_lock);
qeth_bridgeport_query_support(card); qeth_bridgeport_query_support(card);
if (card->options.sbp.supported_funcs) if (card->options.sbp.supported_funcs) {
qeth_l2_setup_bridgeport_attrs(card);
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"The device represents a Bridge Capable Port\n"); "The device represents a Bridge Capable Port\n");
}
mutex_unlock(&card->sbp_lock); mutex_unlock(&card->sbp_lock);
qeth_l2_register_dev_addr(card); qeth_l2_register_dev_addr(card);
...@@ -761,20 +773,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -761,20 +773,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
qeth_trace_features(card); qeth_trace_features(card);
qeth_l2_trace_features(card); qeth_l2_trace_features(card);
qeth_l2_setup_bridgeport_attrs(card);
card->state = CARD_STATE_HARDSETUP;
qeth_print_status_message(card); qeth_print_status_message(card);
/* softsetup */ /* softsetup */
QETH_CARD_TEXT(card, 2, "softsetp"); QETH_CARD_TEXT(card, 2, "softsetp");
rc = qeth_init_qdio_queues(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "6err%d", rc);
rc = -ENODEV;
goto out_remove;
}
card->state = CARD_STATE_SOFTSETUP; card->state = CARD_STATE_SOFTSETUP;
qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_set_allowed_threads(card, 0xffffffff, 0);
...@@ -801,8 +804,6 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -801,8 +804,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:
...@@ -811,81 +812,12 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) ...@@ -811,81 +812,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)
...@@ -922,7 +854,6 @@ static int qeth_l2_control_event(struct qeth_card *card, ...@@ -922,7 +854,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,
...@@ -961,7 +892,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) ...@@ -961,7 +892,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
if (!iob) if (!iob)
return -ENOMEM; return -ENOMEM;
qeth_prepare_ipa_cmd(card, iob, (u16) data_len); qeth_prepare_ipa_cmd(card, iob, (u16) data_len, NULL);
memcpy(__ipa_cmd(iob), data, data_len); memcpy(__ipa_cmd(iob), data, data_len);
iob->callback = qeth_osn_assist_cb; iob->callback = qeth_osn_assist_cb;
return qeth_send_ipa_cmd(card, iob, NULL, NULL); return qeth_send_ipa_cmd(card, iob, NULL, NULL);
......
...@@ -246,40 +246,6 @@ static struct attribute_group qeth_l2_bridgeport_attr_group = { ...@@ -246,40 +246,6 @@ static struct attribute_group qeth_l2_bridgeport_attr_group = {
.attrs = qeth_l2_bridgeport_attrs, .attrs = qeth_l2_bridgeport_attrs,
}; };
/**
* qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
* @card: qeth_card structure pointer
*
* Note: this function is called with conf_mutex held by the caller
*/
void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
{
int rc;
if (!card)
return;
if (!card->options.sbp.supported_funcs)
return;
mutex_lock(&card->sbp_lock);
if (!card->options.sbp.reflect_promisc &&
card->options.sbp.role != QETH_SBP_ROLE_NONE) {
/* Conditional to avoid spurious error messages */
qeth_bridgeport_setrole(card, card->options.sbp.role);
/* Let the callback function refresh the stored role value. */
qeth_bridgeport_query_ports(card,
&card->options.sbp.role, NULL);
}
if (card->options.sbp.hostnotification) {
rc = qeth_bridgeport_an_set(card, 1);
if (rc)
card->options.sbp.hostnotification = 0;
} else {
qeth_bridgeport_an_set(card, 0);
}
mutex_unlock(&card->sbp_lock);
}
/* VNIC CHARS support */ /* VNIC CHARS support */
/* convert sysfs attr name to VNIC characteristic */ /* convert sysfs attr name to VNIC characteristic */
......
...@@ -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 *,
...@@ -903,7 +901,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) ...@@ -903,7 +901,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
return rc; return rc;
} }
static int qeth_l3_start_ipassists(struct qeth_card *card) static void qeth_l3_start_ipassists(struct qeth_card *card)
{ {
QETH_CARD_TEXT(card, 3, "strtipas"); QETH_CARD_TEXT(card, 3, "strtipas");
...@@ -913,7 +911,6 @@ static int qeth_l3_start_ipassists(struct qeth_card *card) ...@@ -913,7 +911,6 @@ static int qeth_l3_start_ipassists(struct qeth_card *card)
qeth_l3_start_ipa_multicast(card); /* go on*/ qeth_l3_start_ipa_multicast(card); /* go on*/
qeth_l3_start_ipa_ipv6(card); /* go on*/ qeth_l3_start_ipa_ipv6(card); /* go on*/
qeth_l3_start_ipa_broadcast(card); /* go on*/ qeth_l3_start_ipa_broadcast(card); /* go on*/
return 0;
} }
static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card,
...@@ -1180,15 +1177,12 @@ static void qeth_l3_stop_card(struct qeth_card *card) ...@@ -1180,15 +1177,12 @@ static void qeth_l3_stop_card(struct qeth_card *card)
if (card->state == CARD_STATE_SOFTSETUP) { if (card->state == CARD_STATE_SOFTSETUP) {
qeth_l3_clear_ip_htable(card, 1); qeth_l3_clear_ip_htable(card, 1);
qeth_clear_ipacmd_list(card); qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
}
if (card->state == CARD_STATE_HARDSETUP) {
qeth_drain_output_queues(card); qeth_drain_output_queues(card);
qeth_clear_working_pool_list(card);
card->state = CARD_STATE_DOWN; card->state = CARD_STATE_DOWN;
} }
qeth_qdio_clear_card(card, 0); qeth_qdio_clear_card(card, 0);
qeth_clear_working_pool_list(card);
flush_workqueue(card->event_wq); flush_workqueue(card->event_wq);
card->info.promisc_mode = 0; card->info.promisc_mode = 0;
} }
...@@ -2044,7 +2038,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) ...@@ -2044,7 +2038,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 +2050,13 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) ...@@ -2056,17 +2050,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);
...@@ -2074,7 +2064,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2074,7 +2064,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
goto out_remove; goto out_remove;
} }
card->state = CARD_STATE_HARDSETUP;
qeth_print_status_message(card); qeth_print_status_message(card);
/* softsetup */ /* softsetup */
...@@ -2084,11 +2073,8 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2084,11 +2073,8 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
if (rc) if (rc)
QETH_CARD_TEXT_(card, 2, "2err%04x", rc); QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
if (!card->options.sniffer) { if (!card->options.sniffer) {
rc = qeth_l3_start_ipassists(card); qeth_l3_start_ipassists(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "3err%d", rc);
goto out_remove;
}
rc = qeth_l3_setrouting_v4(card); rc = qeth_l3_setrouting_v4(card);
if (rc) if (rc)
QETH_CARD_TEXT_(card, 2, "4err%04x", rc); QETH_CARD_TEXT_(card, 2, "4err%04x", rc);
...@@ -2097,12 +2083,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2097,12 +2083,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
QETH_CARD_TEXT_(card, 2, "5err%04x", rc); QETH_CARD_TEXT_(card, 2, "5err%04x", rc);
} }
rc = qeth_init_qdio_queues(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "6err%d", rc);
rc = -ENODEV;
goto out_remove;
}
card->state = CARD_STATE_SOFTSETUP; card->state = CARD_STATE_SOFTSETUP;
qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_set_allowed_threads(card, 0xffffffff, 0);
...@@ -2131,8 +2111,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2131,8 +2111,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);
...@@ -2140,82 +2118,12 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) ...@@ -2140,82 +2118,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" */
...@@ -2227,7 +2135,6 @@ static int qeth_l3_control_event(struct qeth_card *card, ...@@ -2227,7 +2135,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