提交 819dc537 编写于 作者: S Stefan Raspl 提交者: David S. Miller

qeth: Make s390dbf card entries persistent

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: NStefan Raspl <raspl@linux.vnet.ibm.com>
Signed-off-by: NFrank Blaschka <frank.blaschka@de.ibm.com>
Reviewed-by: NUrsula Braun <ursula.braun@de.ibm.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 26e4b334
...@@ -5122,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = { ...@@ -5122,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = {
.groups = qeth_osn_attr_groups, .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) static int qeth_core_probe_device(struct ccwgroup_device *gdev)
{ {
struct qeth_card *card; struct qeth_card *card;
struct device *dev; struct device *dev;
int rc; int rc;
unsigned long flags; unsigned long flags;
char dbf_name[20]; char dbf_name[DBF_NAME_LEN];
QETH_DBF_TEXT(SETUP, 2, "probedev"); QETH_DBF_TEXT(SETUP, 2, "probedev");
...@@ -5147,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5147,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s", snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s",
dev_name(&gdev->dev)); dev_name(&gdev->dev));
card->debug = debug_register(dbf_name, 2, 1, 8); card->debug = qeth_get_dbf_entry(dbf_name);
if (!card->debug) { if (!card->debug) {
QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf"); rc = qeth_add_dbf_entry(card, dbf_name);
rc = -ENOMEM; if (rc)
goto err_card; goto err_card;
} }
debug_register_view(card->debug, &debug_hex_ascii_view);
card->read.ccwdev = gdev->cdev[0]; card->read.ccwdev = gdev->cdev[0];
card->write.ccwdev = gdev->cdev[1]; card->write.ccwdev = gdev->cdev[1];
...@@ -5167,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5167,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
rc = qeth_determine_card_type(card); rc = qeth_determine_card_type(card);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
goto err_dbf; goto err_card;
} }
rc = qeth_setup_card(card); rc = qeth_setup_card(card);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
goto err_dbf; goto err_card;
} }
if (card->info.type == QETH_CARD_TYPE_OSN) if (card->info.type == QETH_CARD_TYPE_OSN)
...@@ -5185,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5185,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
case QETH_CARD_TYPE_OSM: case QETH_CARD_TYPE_OSM:
rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
if (rc) if (rc)
goto err_dbf; goto err_card;
rc = card->discipline->setup(card->gdev); rc = card->discipline->setup(card->gdev);
if (rc) if (rc)
goto err_disc; goto err_disc;
...@@ -5204,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5204,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
err_disc: err_disc:
qeth_core_free_discipline(card); qeth_core_free_discipline(card);
err_dbf:
debug_unregister(card->debug);
err_card: err_card:
qeth_core_free_card(card); qeth_core_free_card(card);
err_dev: err_dev:
...@@ -5225,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) ...@@ -5225,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
qeth_core_free_discipline(card); qeth_core_free_discipline(card);
} }
debug_unregister(card->debug);
write_lock_irqsave(&qeth_core_card_list.rwlock, flags); write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
list_del(&card->list); list_del(&card->list);
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
...@@ -5579,6 +5643,7 @@ static int __init qeth_core_init(void) ...@@ -5579,6 +5643,7 @@ static int __init qeth_core_init(void)
pr_info("loading core functions\n"); pr_info("loading core functions\n");
INIT_LIST_HEAD(&qeth_core_card_list.list); INIT_LIST_HEAD(&qeth_core_card_list.list);
INIT_LIST_HEAD(&qeth_dbf_list);
rwlock_init(&qeth_core_card_list.rwlock); rwlock_init(&qeth_core_card_list.rwlock);
mutex_init(&qeth_mod_mutex); mutex_init(&qeth_mod_mutex);
...@@ -5630,6 +5695,7 @@ static int __init qeth_core_init(void) ...@@ -5630,6 +5695,7 @@ static int __init qeth_core_init(void)
static void __exit qeth_core_exit(void) static void __exit qeth_core_exit(void)
{ {
qeth_clear_dbf_list();
destroy_workqueue(qeth_wq); destroy_workqueue(qeth_wq);
ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
ccw_driver_unregister(&qeth_ccw_driver); ccw_driver_unregister(&qeth_ccw_driver);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册