Skip to content

Commit

Permalink
qeth: Make s390dbf card entries persistent
Browse files Browse the repository at this point in the history
As of now, s390dbf entries for the cards are discarded as soon as the
device is removed. However, this will also bar us of all chances of
getting valuable debug information after a device has been removed.
This patch will keep the s390dbf entries around until the qeth module
is removed.

Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stefan Raspl authored and David S. Miller committed Jan 21, 2013
1 parent 26e4b33 commit 819dc53
Showing 1 changed file with 78 additions and 12 deletions.
90 changes: 78 additions & 12 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5122,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = {
.groups = qeth_osn_attr_groups,
};

#define DBF_NAME_LEN 20

struct qeth_dbf_entry {
char dbf_name[DBF_NAME_LEN];
debug_info_t *dbf_info;
struct list_head dbf_list;
};

static LIST_HEAD(qeth_dbf_list);
static DEFINE_MUTEX(qeth_dbf_list_mutex);

static debug_info_t *qeth_get_dbf_entry(char *name)
{
struct qeth_dbf_entry *entry;
debug_info_t *rc = NULL;

mutex_lock(&qeth_dbf_list_mutex);
list_for_each_entry(entry, &qeth_dbf_list, dbf_list) {
if (strcmp(entry->dbf_name, name) == 0) {
rc = entry->dbf_info;
break;
}
}
mutex_unlock(&qeth_dbf_list_mutex);
return rc;
}

static int qeth_add_dbf_entry(struct qeth_card *card, char *name)
{
struct qeth_dbf_entry *new_entry;

card->debug = debug_register(name, 2, 1, 8);
if (!card->debug) {
QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf");
goto err;
}
if (debug_register_view(card->debug, &debug_hex_ascii_view))
goto err_dbg;
new_entry = kzalloc(sizeof(struct qeth_dbf_entry), GFP_KERNEL);
if (!new_entry)
goto err_dbg;
strncpy(new_entry->dbf_name, name, DBF_NAME_LEN);
new_entry->dbf_info = card->debug;
mutex_lock(&qeth_dbf_list_mutex);
list_add(&new_entry->dbf_list, &qeth_dbf_list);
mutex_unlock(&qeth_dbf_list_mutex);

return 0;

err_dbg:
debug_unregister(card->debug);
err:
return -ENOMEM;
}

static void qeth_clear_dbf_list(void)
{
struct qeth_dbf_entry *entry, *tmp;

mutex_lock(&qeth_dbf_list_mutex);
list_for_each_entry_safe(entry, tmp, &qeth_dbf_list, dbf_list) {
list_del(&entry->dbf_list);
debug_unregister(entry->dbf_info);
kfree(entry);
}
mutex_unlock(&qeth_dbf_list_mutex);
}

static int qeth_core_probe_device(struct ccwgroup_device *gdev)
{
struct qeth_card *card;
struct device *dev;
int rc;
unsigned long flags;
char dbf_name[20];
char dbf_name[DBF_NAME_LEN];

QETH_DBF_TEXT(SETUP, 2, "probedev");

Expand All @@ -5147,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)

snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s",
dev_name(&gdev->dev));
card->debug = debug_register(dbf_name, 2, 1, 8);
card->debug = qeth_get_dbf_entry(dbf_name);
if (!card->debug) {
QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf");
rc = -ENOMEM;
goto err_card;
rc = qeth_add_dbf_entry(card, dbf_name);
if (rc)
goto err_card;
}
debug_register_view(card->debug, &debug_hex_ascii_view);

card->read.ccwdev = gdev->cdev[0];
card->write.ccwdev = gdev->cdev[1];
Expand All @@ -5167,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
rc = qeth_determine_card_type(card);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
goto err_dbf;
goto err_card;
}
rc = qeth_setup_card(card);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
goto err_dbf;
goto err_card;
}

if (card->info.type == QETH_CARD_TYPE_OSN)
Expand All @@ -5185,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
case QETH_CARD_TYPE_OSM:
rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
if (rc)
goto err_dbf;
goto err_card;
rc = card->discipline->setup(card->gdev);
if (rc)
goto err_disc;
Expand All @@ -5204,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)

err_disc:
qeth_core_free_discipline(card);
err_dbf:
debug_unregister(card->debug);
err_card:
qeth_core_free_card(card);
err_dev:
Expand All @@ -5225,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
qeth_core_free_discipline(card);
}

debug_unregister(card->debug);
write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
list_del(&card->list);
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
Expand Down Expand Up @@ -5579,6 +5643,7 @@ static int __init qeth_core_init(void)

pr_info("loading core functions\n");
INIT_LIST_HEAD(&qeth_core_card_list.list);
INIT_LIST_HEAD(&qeth_dbf_list);
rwlock_init(&qeth_core_card_list.rwlock);
mutex_init(&qeth_mod_mutex);

Expand Down Expand Up @@ -5630,6 +5695,7 @@ static int __init qeth_core_init(void)

static void __exit qeth_core_exit(void)
{
qeth_clear_dbf_list();
destroy_workqueue(qeth_wq);
ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
ccw_driver_unregister(&qeth_ccw_driver);
Expand Down

0 comments on commit 819dc53

Please sign in to comment.