Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stefan Raspl and committed by
David S. Miller
819dc537 26e4b334

+78 -12
+78 -12
drivers/s390/net/qeth_core_main.c
··· 5122 5122 .groups = qeth_osn_attr_groups, 5123 5123 }; 5124 5124 5125 + #define DBF_NAME_LEN 20 5126 + 5127 + struct qeth_dbf_entry { 5128 + char dbf_name[DBF_NAME_LEN]; 5129 + debug_info_t *dbf_info; 5130 + struct list_head dbf_list; 5131 + }; 5132 + 5133 + static LIST_HEAD(qeth_dbf_list); 5134 + static DEFINE_MUTEX(qeth_dbf_list_mutex); 5135 + 5136 + static 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 + 5152 + static 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 + 5174 + err_dbg: 5175 + debug_unregister(card->debug); 5176 + err: 5177 + return -ENOMEM; 5178 + } 5179 + 5180 + static 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 + 5125 5193 static int qeth_core_probe_device(struct ccwgroup_device *gdev) 5126 5194 { 5127 5195 struct qeth_card *card; 5128 5196 struct device *dev; 5129 5197 int rc; 5130 5198 unsigned long flags; 5131 - char dbf_name[20]; 5199 + char dbf_name[DBF_NAME_LEN]; 5132 5200 5133 5201 QETH_DBF_TEXT(SETUP, 2, "probedev"); 5134 5202 ··· 5215 5147 5216 5148 snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s", 5217 5149 dev_name(&gdev->dev)); 5218 - card->debug = debug_register(dbf_name, 2, 1, 8); 5150 + card->debug = qeth_get_dbf_entry(dbf_name); 5219 5151 if (!card->debug) { 5220 - QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf"); 5221 - rc = -ENOMEM; 5222 - goto err_card; 5152 + rc = qeth_add_dbf_entry(card, dbf_name); 5153 + if (rc) 5154 + goto err_card; 5223 5155 } 5224 - debug_register_view(card->debug, &debug_hex_ascii_view); 5225 5156 5226 5157 card->read.ccwdev = gdev->cdev[0]; 5227 5158 card->write.ccwdev = gdev->cdev[1]; ··· 5234 5167 rc = qeth_determine_card_type(card); 5235 5168 if (rc) { 5236 5169 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 5237 - goto err_dbf; 5170 + goto err_card; 5238 5171 } 5239 5172 rc = qeth_setup_card(card); 5240 5173 if (rc) { 5241 5174 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 5242 - goto err_dbf; 5175 + goto err_card; 5243 5176 } 5244 5177 5245 5178 if (card->info.type == QETH_CARD_TYPE_OSN) ··· 5252 5185 case QETH_CARD_TYPE_OSM: 5253 5186 rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); 5254 5187 if (rc) 5255 - goto err_dbf; 5188 + goto err_card; 5256 5189 rc = card->discipline->setup(card->gdev); 5257 5190 if (rc) 5258 5191 goto err_disc; ··· 5271 5204 5272 5205 err_disc: 5273 5206 qeth_core_free_discipline(card); 5274 - err_dbf: 5275 - debug_unregister(card->debug); 5276 5207 err_card: 5277 5208 qeth_core_free_card(card); 5278 5209 err_dev: ··· 5290 5225 qeth_core_free_discipline(card); 5291 5226 } 5292 5227 5293 - debug_unregister(card->debug); 5294 5228 write_lock_irqsave(&qeth_core_card_list.rwlock, flags); 5295 5229 list_del(&card->list); 5296 5230 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); ··· 5643 5579 5644 5580 pr_info("loading core functions\n"); 5645 5581 INIT_LIST_HEAD(&qeth_core_card_list.list); 5582 + INIT_LIST_HEAD(&qeth_dbf_list); 5646 5583 rwlock_init(&qeth_core_card_list.rwlock); 5647 5584 mutex_init(&qeth_mod_mutex); 5648 5585 ··· 5695 5630 5696 5631 static void __exit qeth_core_exit(void) 5697 5632 { 5633 + qeth_clear_dbf_list(); 5698 5634 destroy_workqueue(qeth_wq); 5699 5635 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); 5700 5636 ccw_driver_unregister(&qeth_ccw_driver);