aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Raspl <raspl@linux.vnet.ibm.com>2013-01-20 21:30:22 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-21 13:51:15 -0500
commit819dc537fd7fcd799c5f7f85693d29e2635a84f9 (patch)
tree7b1a745bb135b02ebd64c2fb3718abb0b89fe82b /drivers
parent26e4b3340e5ac423497ee1a59d42b4ef81af4272 (diff)
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: 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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/net/qeth_core_main.c90
1 files changed, 78 insertions, 12 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 1cccbad69cd4..3535b134bd31 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -5122,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = {
5122 .groups = qeth_osn_attr_groups, 5122 .groups = qeth_osn_attr_groups,
5123}; 5123};
5124 5124
5125#define DBF_NAME_LEN 20
5126
5127struct qeth_dbf_entry {
5128 char dbf_name[DBF_NAME_LEN];
5129 debug_info_t *dbf_info;
5130 struct list_head dbf_list;
5131};
5132
5133static LIST_HEAD(qeth_dbf_list);
5134static DEFINE_MUTEX(qeth_dbf_list_mutex);
5135
5136static debug_info_t *qeth_get_dbf_entry(char *name)
5137{
5138 struct qeth_dbf_entry *entry;
5139 debug_info_t *rc = NULL;
5140
5141 mutex_lock(&qeth_dbf_list_mutex);
5142 list_for_each_entry(entry, &qeth_dbf_list, dbf_list) {
5143 if (strcmp(entry->dbf_name, name) == 0) {
5144 rc = entry->dbf_info;
5145 break;
5146 }
5147 }
5148 mutex_unlock(&qeth_dbf_list_mutex);
5149 return rc;
5150}
5151
5152static int qeth_add_dbf_entry(struct qeth_card *card, char *name)
5153{
5154 struct qeth_dbf_entry *new_entry;
5155
5156 card->debug = debug_register(name, 2, 1, 8);
5157 if (!card->debug) {
5158 QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf");
5159 goto err;
5160 }
5161 if (debug_register_view(card->debug, &debug_hex_ascii_view))
5162 goto err_dbg;
5163 new_entry = kzalloc(sizeof(struct qeth_dbf_entry), GFP_KERNEL);
5164 if (!new_entry)
5165 goto err_dbg;
5166 strncpy(new_entry->dbf_name, name, DBF_NAME_LEN);
5167 new_entry->dbf_info = card->debug;
5168 mutex_lock(&qeth_dbf_list_mutex);
5169 list_add(&new_entry->dbf_list, &qeth_dbf_list);
5170 mutex_unlock(&qeth_dbf_list_mutex);
5171
5172 return 0;
5173
5174err_dbg:
5175 debug_unregister(card->debug);
5176err:
5177 return -ENOMEM;
5178}
5179
5180static void qeth_clear_dbf_list(void)
5181{
5182 struct qeth_dbf_entry *entry, *tmp;
5183
5184 mutex_lock(&qeth_dbf_list_mutex);
5185 list_for_each_entry_safe(entry, tmp, &qeth_dbf_list, dbf_list) {
5186 list_del(&entry->dbf_list);
5187 debug_unregister(entry->dbf_info);
5188 kfree(entry);
5189 }
5190 mutex_unlock(&qeth_dbf_list_mutex);
5191}
5192
5125static int qeth_core_probe_device(struct ccwgroup_device *gdev) 5193static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5126{ 5194{
5127 struct qeth_card *card; 5195 struct qeth_card *card;
5128 struct device *dev; 5196 struct device *dev;
5129 int rc; 5197 int rc;
5130 unsigned long flags; 5198 unsigned long flags;
5131 char dbf_name[20]; 5199 char dbf_name[DBF_NAME_LEN];
5132 5200
5133 QETH_DBF_TEXT(SETUP, 2, "probedev"); 5201 QETH_DBF_TEXT(SETUP, 2, "probedev");
5134 5202
@@ -5147,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5147 5215
5148 snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s", 5216 snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s",
5149 dev_name(&gdev->dev)); 5217 dev_name(&gdev->dev));
5150 card->debug = debug_register(dbf_name, 2, 1, 8); 5218 card->debug = qeth_get_dbf_entry(dbf_name);
5151 if (!card->debug) { 5219 if (!card->debug) {
5152 QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf"); 5220 rc = qeth_add_dbf_entry(card, dbf_name);
5153 rc = -ENOMEM; 5221 if (rc)
5154 goto err_card; 5222 goto err_card;
5155 } 5223 }
5156 debug_register_view(card->debug, &debug_hex_ascii_view);
5157 5224
5158 card->read.ccwdev = gdev->cdev[0]; 5225 card->read.ccwdev = gdev->cdev[0];
5159 card->write.ccwdev = gdev->cdev[1]; 5226 card->write.ccwdev = gdev->cdev[1];
@@ -5167,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5167 rc = qeth_determine_card_type(card); 5234 rc = qeth_determine_card_type(card);
5168 if (rc) { 5235 if (rc) {
5169 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 5236 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
5170 goto err_dbf; 5237 goto err_card;
5171 } 5238 }
5172 rc = qeth_setup_card(card); 5239 rc = qeth_setup_card(card);
5173 if (rc) { 5240 if (rc) {
5174 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 5241 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
5175 goto err_dbf; 5242 goto err_card;
5176 } 5243 }
5177 5244
5178 if (card->info.type == QETH_CARD_TYPE_OSN) 5245 if (card->info.type == QETH_CARD_TYPE_OSN)
@@ -5185,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5185 case QETH_CARD_TYPE_OSM: 5252 case QETH_CARD_TYPE_OSM:
5186 rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); 5253 rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
5187 if (rc) 5254 if (rc)
5188 goto err_dbf; 5255 goto err_card;
5189 rc = card->discipline->setup(card->gdev); 5256 rc = card->discipline->setup(card->gdev);
5190 if (rc) 5257 if (rc)
5191 goto err_disc; 5258 goto err_disc;
@@ -5204,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5204 5271
5205err_disc: 5272err_disc:
5206 qeth_core_free_discipline(card); 5273 qeth_core_free_discipline(card);
5207err_dbf:
5208 debug_unregister(card->debug);
5209err_card: 5274err_card:
5210 qeth_core_free_card(card); 5275 qeth_core_free_card(card);
5211err_dev: 5276err_dev:
@@ -5225,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
5225 qeth_core_free_discipline(card); 5290 qeth_core_free_discipline(card);
5226 } 5291 }
5227 5292
5228 debug_unregister(card->debug);
5229 write_lock_irqsave(&qeth_core_card_list.rwlock, flags); 5293 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
5230 list_del(&card->list); 5294 list_del(&card->list);
5231 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); 5295 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
@@ -5579,6 +5643,7 @@ static int __init qeth_core_init(void)
5579 5643
5580 pr_info("loading core functions\n"); 5644 pr_info("loading core functions\n");
5581 INIT_LIST_HEAD(&qeth_core_card_list.list); 5645 INIT_LIST_HEAD(&qeth_core_card_list.list);
5646 INIT_LIST_HEAD(&qeth_dbf_list);
5582 rwlock_init(&qeth_core_card_list.rwlock); 5647 rwlock_init(&qeth_core_card_list.rwlock);
5583 mutex_init(&qeth_mod_mutex); 5648 mutex_init(&qeth_mod_mutex);
5584 5649
@@ -5630,6 +5695,7 @@ out_err:
5630 5695
5631static void __exit qeth_core_exit(void) 5696static void __exit qeth_core_exit(void)
5632{ 5697{
5698 qeth_clear_dbf_list();
5633 destroy_workqueue(qeth_wq); 5699 destroy_workqueue(qeth_wq);
5634 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); 5700 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
5635 ccw_driver_unregister(&qeth_ccw_driver); 5701 ccw_driver_unregister(&qeth_ccw_driver);