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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6efca894e9
|
@ -558,7 +558,6 @@ enum qeth_channel_states {
|
|||
*/
|
||||
enum qeth_card_states {
|
||||
CARD_STATE_DOWN,
|
||||
CARD_STATE_HARDSETUP,
|
||||
CARD_STATE_SOFTSETUP,
|
||||
};
|
||||
|
||||
|
@ -608,6 +607,8 @@ struct qeth_cmd_buffer {
|
|||
long timeout;
|
||||
unsigned char *data;
|
||||
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,
|
||||
unsigned int data_length);
|
||||
int rc;
|
||||
|
@ -618,6 +619,14 @@ static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
|
|||
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)
|
||||
{
|
||||
return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
|
||||
|
@ -727,11 +736,10 @@ struct qeth_osn_info {
|
|||
|
||||
struct qeth_discipline {
|
||||
const struct device_type *devtype;
|
||||
int (*recover)(void *ptr);
|
||||
int (*setup) (struct ccwgroup_device *);
|
||||
void (*remove) (struct ccwgroup_device *);
|
||||
int (*set_online) (struct ccwgroup_device *);
|
||||
int (*set_offline) (struct ccwgroup_device *);
|
||||
int (*set_online)(struct qeth_card *card);
|
||||
void (*set_offline)(struct qeth_card *card);
|
||||
int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
int (*control_event_handler)(struct qeth_card *card,
|
||||
struct qeth_ipa_cmd *cmd);
|
||||
|
@ -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);
|
||||
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
|
||||
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_stop_channel(struct qeth_channel *channel);
|
||||
int qeth_set_offline(struct qeth_card *card, bool resetting);
|
||||
|
||||
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 (*reply_cb)
|
||||
(struct qeth_card *, struct qeth_reply *, unsigned long),
|
||||
|
@ -1027,7 +1032,9 @@ void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable);
|
|||
int qeth_setadpparms_change_macaddr(struct qeth_card *);
|
||||
void qeth_tx_timeout(struct net_device *, unsigned int txqueue);
|
||||
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,
|
||||
struct qeth_switch_info *sw_info);
|
||||
int qeth_query_card_info(struct qeth_card *card,
|
||||
|
|
|
@ -247,9 +247,6 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
|
|||
{
|
||||
QETH_CARD_TEXT(card, 2, "realcbp");
|
||||
|
||||
if (card->state != CARD_STATE_DOWN)
|
||||
return -EPERM;
|
||||
|
||||
/* TODO: steel/add buffers from/to a running card's buffer pool (?) */
|
||||
qeth_clear_working_pool_list(card);
|
||||
qeth_free_buffer_pool(card);
|
||||
|
@ -748,8 +745,8 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (IS_IPA(iob->data)) {
|
||||
cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
|
||||
cmd = __ipa_reply(iob);
|
||||
if (cmd) {
|
||||
cmd = qeth_check_ipa_data(card, cmd);
|
||||
if (!cmd)
|
||||
goto out;
|
||||
|
@ -758,17 +755,12 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
|
|||
card->osn_info.assist_cb(card->dev, cmd);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* non-IPA commands should only flow during initialization */
|
||||
if (card->state != CARD_STATE_DOWN)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* match against pending cmd requests */
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
|
||||
if (!IS_IPA(tmp->data) ||
|
||||
__ipa_cmd(tmp)->hdr.seqno == cmd->hdr.seqno) {
|
||||
if (tmp->match && tmp->match(tmp, iob)) {
|
||||
request = tmp;
|
||||
/* take the object outside the lock */
|
||||
qeth_get_cmd(request);
|
||||
|
@ -823,7 +815,8 @@ static int qeth_set_thread_start_bit(struct qeth_card *card,
|
|||
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;
|
||||
|
||||
|
@ -832,9 +825,9 @@ void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
|
|||
spin_unlock_irqrestore(&card->thread_mask_lock, flags);
|
||||
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;
|
||||
|
||||
|
@ -843,7 +836,6 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
|
|||
spin_unlock_irqrestore(&card->thread_mask_lock, flags);
|
||||
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)
|
||||
{
|
||||
|
@ -864,7 +856,7 @@ static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
|
|||
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;
|
||||
|
||||
|
@ -872,7 +864,6 @@ int qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
|
|||
(rc = __qeth_do_run_thread(card, thread)) >= 0);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_do_run_thread);
|
||||
|
||||
void qeth_schedule_recovery(struct qeth_card *card)
|
||||
{
|
||||
|
@ -880,7 +871,6 @@ void qeth_schedule_recovery(struct qeth_card *card)
|
|||
if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
|
||||
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,
|
||||
struct irb *irb)
|
||||
|
@ -1287,6 +1277,7 @@ static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_do_reset(void *data);
|
||||
static void qeth_start_kernel_thread(struct work_struct *work)
|
||||
{
|
||||
struct task_struct *ts;
|
||||
|
@ -1298,8 +1289,7 @@ static void qeth_start_kernel_thread(struct work_struct *work)
|
|||
card->write.state != CH_STATE_UP)
|
||||
return;
|
||||
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
|
||||
ts = kthread_run(card->discipline->recover, (void *)card,
|
||||
"qeth_recover");
|
||||
ts = kthread_run(qeth_do_reset, card, "qeth_recover");
|
||||
if (IS_ERR(ts)) {
|
||||
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
|
||||
qeth_clear_thread_running_bit(card,
|
||||
|
@ -1690,6 +1680,13 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card,
|
|||
iob->callback = qeth_release_buffer_cb;
|
||||
}
|
||||
|
||||
static bool qeth_mpc_match_reply(struct qeth_cmd_buffer *iob,
|
||||
struct qeth_cmd_buffer *reply)
|
||||
{
|
||||
/* MPC cmds are issued strictly in sequence. */
|
||||
return !IS_IPA(reply->data);
|
||||
}
|
||||
|
||||
static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
|
||||
void *data,
|
||||
unsigned int data_length)
|
||||
|
@ -1704,6 +1701,7 @@ static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
|
|||
qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, data_length,
|
||||
iob->data);
|
||||
iob->finalize = qeth_mpc_finalize_cmd;
|
||||
iob->match = qeth_mpc_match_reply;
|
||||
return iob;
|
||||
}
|
||||
|
||||
|
@ -2665,7 +2663,7 @@ static unsigned int qeth_tx_select_bulk_max(struct qeth_card *card,
|
|||
return card->ssqd.mmwc ? card->ssqd.mmwc : 1;
|
||||
}
|
||||
|
||||
int qeth_init_qdio_queues(struct qeth_card *card)
|
||||
static int qeth_init_qdio_queues(struct qeth_card *card)
|
||||
{
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
@ -2713,7 +2711,6 @@ int qeth_init_qdio_queues(struct qeth_card *card)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_init_qdio_queues);
|
||||
|
||||
static void qeth_ipa_finalize_cmd(struct qeth_card *card,
|
||||
struct qeth_cmd_buffer *iob)
|
||||
|
@ -2725,7 +2722,9 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card,
|
|||
}
|
||||
|
||||
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))
|
||||
{
|
||||
u8 prot_type = qeth_mpc_select_prot_type(card);
|
||||
u16 total_length = iob->length;
|
||||
|
@ -2733,6 +2732,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
|
|||
qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length,
|
||||
iob->data);
|
||||
iob->finalize = qeth_ipa_finalize_cmd;
|
||||
iob->match = match;
|
||||
|
||||
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
|
||||
memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2);
|
||||
|
@ -2745,6 +2745,14 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
|
||||
|
||||
static bool qeth_ipa_match_reply(struct qeth_cmd_buffer *iob,
|
||||
struct qeth_cmd_buffer *reply)
|
||||
{
|
||||
struct qeth_ipa_cmd *ipa_reply = __ipa_reply(reply);
|
||||
|
||||
return ipa_reply && (__ipa_cmd(iob)->hdr.seqno == ipa_reply->hdr.seqno);
|
||||
}
|
||||
|
||||
struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
|
||||
enum qeth_ipa_cmds cmd_code,
|
||||
enum qeth_prot_versions prot,
|
||||
|
@ -2760,7 +2768,7 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
|
|||
if (!iob)
|
||||
return NULL;
|
||||
|
||||
qeth_prepare_ipa_cmd(card, iob, data_length);
|
||||
qeth_prepare_ipa_cmd(card, iob, data_length, qeth_ipa_match_reply);
|
||||
|
||||
hdr = &__ipa_cmd(iob)->hdr;
|
||||
hdr->command = cmd_code;
|
||||
|
@ -3096,7 +3104,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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_hw_trap);
|
||||
|
||||
static int qeth_check_qdio_errors(struct qeth_card *card,
|
||||
struct qdio_buffer *buf,
|
||||
|
@ -5026,6 +5033,12 @@ retriable:
|
|||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = qeth_init_qdio_queues(card);
|
||||
if (rc) {
|
||||
QETH_CARD_TEXT_(card, 2, "9err%d", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
|
||||
|
@ -5036,6 +5049,89 @@ out:
|
|||
}
|
||||
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)
|
||||
static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr *hdr)
|
||||
|
@ -5972,7 +6068,8 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
rc = card->discipline->set_online(gdev);
|
||||
|
||||
rc = qeth_set_online(card);
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
@ -5980,7 +6077,8 @@ err:
|
|||
static int qeth_core_set_offline(struct ccwgroup_device *gdev)
|
||||
{
|
||||
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)
|
||||
|
@ -6003,7 +6101,7 @@ static int qeth_suspend(struct ccwgroup_device *gdev)
|
|||
if (gdev->state == CCWGROUP_OFFLINE)
|
||||
return 0;
|
||||
|
||||
card->discipline->set_offline(gdev);
|
||||
qeth_set_offline(card, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6012,7 +6110,7 @@ static int qeth_resume(struct ccwgroup_device *gdev)
|
|||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
int rc;
|
||||
|
||||
rc = card->discipline->set_online(gdev);
|
||||
rc = qeth_set_online(card);
|
||||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
if (rc)
|
||||
|
|
|
@ -24,8 +24,6 @@ static ssize_t qeth_dev_state_show(struct device *dev,
|
|||
switch (card->state) {
|
||||
case CARD_STATE_DOWN:
|
||||
return sprintf(buf, "DOWN\n");
|
||||
case CARD_STATE_HARDSETUP:
|
||||
return sprintf(buf, "HARDSETUP\n");
|
||||
case CARD_STATE_SOFTSETUP:
|
||||
if (card->dev->flags & IFF_UP)
|
||||
return sprintf(buf, "UP (LAN %s)\n",
|
||||
|
|
|
@ -13,7 +13,6 @@ extern const struct attribute_group *qeth_l2_attr_groups[];
|
|||
|
||||
int qeth_l2_create_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,
|
||||
enum qeth_sbp_roles *role,
|
||||
enum qeth_sbp_states *state);
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "qeth_core.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_bridge_state_change(struct qeth_card *card,
|
||||
struct qeth_ipa_cmd *cmd);
|
||||
|
@ -284,15 +283,12 @@ static void qeth_l2_stop_card(struct qeth_card *card)
|
|||
|
||||
if (card->state == CARD_STATE_SOFTSETUP) {
|
||||
qeth_clear_ipacmd_list(card);
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
}
|
||||
if (card->state == CARD_STATE_HARDSETUP) {
|
||||
qeth_drain_output_queues(card);
|
||||
qeth_clear_working_pool_list(card);
|
||||
card->state = CARD_STATE_DOWN;
|
||||
}
|
||||
|
||||
qeth_qdio_clear_card(card, 0);
|
||||
qeth_clear_working_pool_list(card);
|
||||
flush_workqueue(card->event_wq);
|
||||
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
|
||||
card->info.promisc_mode = 0;
|
||||
|
@ -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);
|
||||
|
||||
if (cgdev->state == CCWGROUP_ONLINE)
|
||||
qeth_l2_set_offline(cgdev);
|
||||
qeth_set_offline(card, false);
|
||||
|
||||
cancel_work_sync(&card->close_dev_work);
|
||||
if (qeth_netdev_is_registered(card->dev))
|
||||
|
@ -728,17 +724,31 @@ static void qeth_l2_trace_features(struct qeth_card *card)
|
|||
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;
|
||||
int rc = 0;
|
||||
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);
|
||||
if (rc) {
|
||||
QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
|
||||
|
@ -748,9 +758,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
|
|||
|
||||
mutex_lock(&card->sbp_lock);
|
||||
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,
|
||||
"The device represents a Bridge Capable Port\n");
|
||||
}
|
||||
mutex_unlock(&card->sbp_lock);
|
||||
|
||||
qeth_l2_register_dev_addr(card);
|
||||
|
@ -761,20 +773,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
|
|||
qeth_trace_features(card);
|
||||
qeth_l2_trace_features(card);
|
||||
|
||||
qeth_l2_setup_bridgeport_attrs(card);
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
qeth_print_status_message(card);
|
||||
|
||||
/* softsetup */
|
||||
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;
|
||||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
|
@ -801,8 +804,6 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
|
|||
}
|
||||
/* let user_space know that device is online */
|
||||
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
mutex_unlock(&card->discipline_mutex);
|
||||
return 0;
|
||||
|
||||
out_remove:
|
||||
|
@ -811,81 +812,12 @@ out_remove:
|
|||
qeth_stop_channel(&card->write);
|
||||
qeth_stop_channel(&card->read);
|
||||
qdio_free(CARD_DDEV(card));
|
||||
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
mutex_unlock(&card->discipline_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
|
||||
int recovery_mode)
|
||||
static void qeth_l2_set_offline(struct qeth_card *card)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
|
@ -922,7 +854,6 @@ static int qeth_l2_control_event(struct qeth_card *card,
|
|||
|
||||
struct qeth_discipline qeth_l2_discipline = {
|
||||
.devtype = &qeth_l2_devtype,
|
||||
.recover = qeth_l2_recover,
|
||||
.setup = qeth_l2_probe_device,
|
||||
.remove = qeth_l2_remove_device,
|
||||
.set_online = qeth_l2_set_online,
|
||||
|
@ -961,7 +892,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
|
|||
if (!iob)
|
||||
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);
|
||||
iob->callback = qeth_osn_assist_cb;
|
||||
return qeth_send_ipa_cmd(card, iob, NULL, NULL);
|
||||
|
|
|
@ -246,40 +246,6 @@ static struct attribute_group qeth_l2_bridgeport_attr_group = {
|
|||
.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 */
|
||||
|
||||
/* convert sysfs attr name to VNIC characteristic */
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
|
||||
#include "qeth_l3.h"
|
||||
|
||||
|
||||
static int qeth_l3_set_offline(struct ccwgroup_device *);
|
||||
static int qeth_l3_register_addr_entry(struct qeth_card *,
|
||||
struct qeth_ipaddr *);
|
||||
static int qeth_l3_deregister_addr_entry(struct qeth_card *,
|
||||
|
@ -903,7 +901,7 @@ out:
|
|||
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");
|
||||
|
||||
|
@ -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_ipv6(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,
|
||||
|
@ -1180,15 +1177,12 @@ static void qeth_l3_stop_card(struct qeth_card *card)
|
|||
if (card->state == CARD_STATE_SOFTSETUP) {
|
||||
qeth_l3_clear_ip_htable(card, 1);
|
||||
qeth_clear_ipacmd_list(card);
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
}
|
||||
if (card->state == CARD_STATE_HARDSETUP) {
|
||||
qeth_drain_output_queues(card);
|
||||
qeth_clear_working_pool_list(card);
|
||||
card->state = CARD_STATE_DOWN;
|
||||
}
|
||||
|
||||
qeth_qdio_clear_card(card, 0);
|
||||
qeth_clear_working_pool_list(card);
|
||||
flush_workqueue(card->event_wq);
|
||||
card->info.promisc_mode = 0;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
if (cgdev->state == CCWGROUP_ONLINE)
|
||||
qeth_l3_set_offline(cgdev);
|
||||
qeth_set_offline(card, false);
|
||||
|
||||
cancel_work_sync(&card->close_dev_work);
|
||||
if (qeth_netdev_is_registered(card->dev))
|
||||
|
@ -2056,17 +2050,13 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
|
|||
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;
|
||||
int rc = 0;
|
||||
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);
|
||||
if (rc) {
|
||||
QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
|
||||
|
@ -2074,7 +2064,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
|
|||
goto out_remove;
|
||||
}
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
qeth_print_status_message(card);
|
||||
|
||||
/* softsetup */
|
||||
|
@ -2084,11 +2073,8 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
|
|||
if (rc)
|
||||
QETH_CARD_TEXT_(card, 2, "2err%04x", rc);
|
||||
if (!card->options.sniffer) {
|
||||
rc = qeth_l3_start_ipassists(card);
|
||||
if (rc) {
|
||||
QETH_CARD_TEXT_(card, 2, "3err%d", rc);
|
||||
goto out_remove;
|
||||
}
|
||||
qeth_l3_start_ipassists(card);
|
||||
|
||||
rc = qeth_l3_setrouting_v4(card);
|
||||
if (rc)
|
||||
QETH_CARD_TEXT_(card, 2, "4err%04x", rc);
|
||||
|
@ -2097,12 +2083,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
|
|||
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;
|
||||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
|
@ -2131,8 +2111,6 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
|
|||
qeth_trace_features(card);
|
||||
/* let user_space know that device is online */
|
||||
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
mutex_unlock(&card->discipline_mutex);
|
||||
return 0;
|
||||
out_remove:
|
||||
qeth_l3_stop_card(card);
|
||||
|
@ -2140,82 +2118,12 @@ out_remove:
|
|||
qeth_stop_channel(&card->write);
|
||||
qeth_stop_channel(&card->read);
|
||||
qdio_free(CARD_DDEV(card));
|
||||
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
mutex_unlock(&card->discipline_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
|
||||
int recovery_mode)
|
||||
static void qeth_l3_set_offline(struct qeth_card *card)
|
||||
{
|
||||
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);
|
||||
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" */
|
||||
|
@ -2227,7 +2135,6 @@ static int qeth_l3_control_event(struct qeth_card *card,
|
|||
|
||||
struct qeth_discipline qeth_l3_discipline = {
|
||||
.devtype = &qeth_l3_devtype,
|
||||
.recover = qeth_l3_recover,
|
||||
.setup = qeth_l3_probe_device,
|
||||
.remove = qeth_l3_remove_device,
|
||||
.set_online = qeth_l3_set_online,
|
||||
|
|
Loading…
Reference in New Issue