xref: /linux/drivers/s390/net/qeth_core_sys.c (revision c145211d1f9e2ef19e7b4c2b943f68366daa97af)
1 /*
2  *  drivers/s390/net/qeth_core_sys.c
3  *
4  *    Copyright IBM Corp. 2007
5  *    Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6  *		 Frank Pavlic <fpavlic@de.ibm.com>,
7  *		 Thomas Spatzier <tspat@de.ibm.com>,
8  *		 Frank Blaschka <frank.blaschka@de.ibm.com>
9  */
10 
11 #define KMSG_COMPONENT "qeth"
12 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 
14 #include <linux/list.h>
15 #include <linux/rwsem.h>
16 #include <asm/ebcdic.h>
17 
18 #include "qeth_core.h"
19 
20 static ssize_t qeth_dev_state_show(struct device *dev,
21 				struct device_attribute *attr, char *buf)
22 {
23 	struct qeth_card *card = dev_get_drvdata(dev);
24 	if (!card)
25 		return -EINVAL;
26 
27 	switch (card->state) {
28 	case CARD_STATE_DOWN:
29 		return sprintf(buf, "DOWN\n");
30 	case CARD_STATE_HARDSETUP:
31 		return sprintf(buf, "HARDSETUP\n");
32 	case CARD_STATE_SOFTSETUP:
33 		return sprintf(buf, "SOFTSETUP\n");
34 	case CARD_STATE_UP:
35 		if (card->lan_online)
36 		return sprintf(buf, "UP (LAN ONLINE)\n");
37 		else
38 			return sprintf(buf, "UP (LAN OFFLINE)\n");
39 	case CARD_STATE_RECOVER:
40 		return sprintf(buf, "RECOVER\n");
41 	default:
42 		return sprintf(buf, "UNKNOWN\n");
43 	}
44 }
45 
46 static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
47 
48 static ssize_t qeth_dev_chpid_show(struct device *dev,
49 				struct device_attribute *attr, char *buf)
50 {
51 	struct qeth_card *card = dev_get_drvdata(dev);
52 	if (!card)
53 		return -EINVAL;
54 
55 	return sprintf(buf, "%02X\n", card->info.chpid);
56 }
57 
58 static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
59 
60 static ssize_t qeth_dev_if_name_show(struct device *dev,
61 				struct device_attribute *attr, char *buf)
62 {
63 	struct qeth_card *card = dev_get_drvdata(dev);
64 	if (!card)
65 		return -EINVAL;
66 	return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
67 }
68 
69 static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
70 
71 static ssize_t qeth_dev_card_type_show(struct device *dev,
72 				struct device_attribute *attr, char *buf)
73 {
74 	struct qeth_card *card = dev_get_drvdata(dev);
75 	if (!card)
76 		return -EINVAL;
77 
78 	return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
79 }
80 
81 static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
82 
83 static inline const char *qeth_get_bufsize_str(struct qeth_card *card)
84 {
85 	if (card->qdio.in_buf_size == 16384)
86 		return "16k";
87 	else if (card->qdio.in_buf_size == 24576)
88 		return "24k";
89 	else if (card->qdio.in_buf_size == 32768)
90 		return "32k";
91 	else if (card->qdio.in_buf_size == 40960)
92 		return "40k";
93 	else
94 		return "64k";
95 }
96 
97 static ssize_t qeth_dev_inbuf_size_show(struct device *dev,
98 				struct device_attribute *attr, char *buf)
99 {
100 	struct qeth_card *card = dev_get_drvdata(dev);
101 	if (!card)
102 		return -EINVAL;
103 
104 	return sprintf(buf, "%s\n", qeth_get_bufsize_str(card));
105 }
106 
107 static DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL);
108 
109 static ssize_t qeth_dev_portno_show(struct device *dev,
110 			struct device_attribute *attr, char *buf)
111 {
112 	struct qeth_card *card = dev_get_drvdata(dev);
113 	if (!card)
114 		return -EINVAL;
115 
116 	return sprintf(buf, "%i\n", card->info.portno);
117 }
118 
119 static ssize_t qeth_dev_portno_store(struct device *dev,
120 		struct device_attribute *attr, const char *buf, size_t count)
121 {
122 	struct qeth_card *card = dev_get_drvdata(dev);
123 	char *tmp;
124 	unsigned int portno, limit;
125 
126 	if (!card)
127 		return -EINVAL;
128 
129 	if ((card->state != CARD_STATE_DOWN) &&
130 	    (card->state != CARD_STATE_RECOVER))
131 		return -EPERM;
132 
133 	portno = simple_strtoul(buf, &tmp, 16);
134 	if (portno > QETH_MAX_PORTNO)
135 		return -EINVAL;
136 	limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
137 	if (portno > limit)
138 		return -EINVAL;
139 
140 	card->info.portno = portno;
141 	return count;
142 }
143 
144 static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
145 
146 static ssize_t qeth_dev_portname_show(struct device *dev,
147 				struct device_attribute *attr, char *buf)
148 {
149 	struct qeth_card *card = dev_get_drvdata(dev);
150 	char portname[9] = {0, };
151 
152 	if (!card)
153 		return -EINVAL;
154 
155 	if (card->info.portname_required) {
156 		memcpy(portname, card->info.portname + 1, 8);
157 		EBCASC(portname, 8);
158 		return sprintf(buf, "%s\n", portname);
159 	} else
160 		return sprintf(buf, "no portname required\n");
161 }
162 
163 static ssize_t qeth_dev_portname_store(struct device *dev,
164 		struct device_attribute *attr, const char *buf, size_t count)
165 {
166 	struct qeth_card *card = dev_get_drvdata(dev);
167 	char *tmp;
168 	int i;
169 
170 	if (!card)
171 		return -EINVAL;
172 
173 	if ((card->state != CARD_STATE_DOWN) &&
174 	    (card->state != CARD_STATE_RECOVER))
175 		return -EPERM;
176 
177 	tmp = strsep((char **) &buf, "\n");
178 	if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
179 		return -EINVAL;
180 
181 	card->info.portname[0] = strlen(tmp);
182 	/* for beauty reasons */
183 	for (i = 1; i < 9; i++)
184 		card->info.portname[i] = ' ';
185 	strcpy(card->info.portname + 1, tmp);
186 	ASCEBC(card->info.portname + 1, 8);
187 
188 	return count;
189 }
190 
191 static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
192 		qeth_dev_portname_store);
193 
194 static ssize_t qeth_dev_prioqing_show(struct device *dev,
195 				struct device_attribute *attr, char *buf)
196 {
197 	struct qeth_card *card = dev_get_drvdata(dev);
198 
199 	if (!card)
200 		return -EINVAL;
201 
202 	switch (card->qdio.do_prio_queueing) {
203 	case QETH_PRIO_Q_ING_PREC:
204 		return sprintf(buf, "%s\n", "by precedence");
205 	case QETH_PRIO_Q_ING_TOS:
206 		return sprintf(buf, "%s\n", "by type of service");
207 	default:
208 		return sprintf(buf, "always queue %i\n",
209 			       card->qdio.default_out_queue);
210 	}
211 }
212 
213 static ssize_t qeth_dev_prioqing_store(struct device *dev,
214 		struct device_attribute *attr, const char *buf, size_t count)
215 {
216 	struct qeth_card *card = dev_get_drvdata(dev);
217 	char *tmp;
218 
219 	if (!card)
220 		return -EINVAL;
221 
222 	if ((card->state != CARD_STATE_DOWN) &&
223 	    (card->state != CARD_STATE_RECOVER))
224 		return -EPERM;
225 
226 	/* check if 1920 devices are supported ,
227 	 * if though we have to permit priority queueing
228 	 */
229 	if (card->qdio.no_out_queues == 1) {
230 		card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
231 		return -EPERM;
232 	}
233 
234 	tmp = strsep((char **) &buf, "\n");
235 	if (!strcmp(tmp, "prio_queueing_prec"))
236 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
237 	else if (!strcmp(tmp, "prio_queueing_tos"))
238 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
239 	else if (!strcmp(tmp, "no_prio_queueing:0")) {
240 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
241 		card->qdio.default_out_queue = 0;
242 	} else if (!strcmp(tmp, "no_prio_queueing:1")) {
243 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
244 		card->qdio.default_out_queue = 1;
245 	} else if (!strcmp(tmp, "no_prio_queueing:2")) {
246 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
247 		card->qdio.default_out_queue = 2;
248 	} else if (!strcmp(tmp, "no_prio_queueing:3")) {
249 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
250 		card->qdio.default_out_queue = 3;
251 	} else if (!strcmp(tmp, "no_prio_queueing")) {
252 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
253 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
254 	} else {
255 		return -EINVAL;
256 	}
257 	return count;
258 }
259 
260 static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
261 		qeth_dev_prioqing_store);
262 
263 static ssize_t qeth_dev_bufcnt_show(struct device *dev,
264 				struct device_attribute *attr, char *buf)
265 {
266 	struct qeth_card *card = dev_get_drvdata(dev);
267 
268 	if (!card)
269 		return -EINVAL;
270 
271 	return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
272 }
273 
274 static ssize_t qeth_dev_bufcnt_store(struct device *dev,
275 		struct device_attribute *attr, const char *buf, size_t count)
276 {
277 	struct qeth_card *card = dev_get_drvdata(dev);
278 	char *tmp;
279 	int cnt, old_cnt;
280 	int rc;
281 
282 	if (!card)
283 		return -EINVAL;
284 
285 	if ((card->state != CARD_STATE_DOWN) &&
286 	    (card->state != CARD_STATE_RECOVER))
287 		return -EPERM;
288 
289 	old_cnt = card->qdio.in_buf_pool.buf_count;
290 	cnt = simple_strtoul(buf, &tmp, 10);
291 	cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
292 		((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
293 	if (old_cnt != cnt) {
294 		rc = qeth_realloc_buffer_pool(card, cnt);
295 	}
296 	return count;
297 }
298 
299 static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
300 		qeth_dev_bufcnt_store);
301 
302 static ssize_t qeth_dev_recover_store(struct device *dev,
303 		struct device_attribute *attr, const char *buf, size_t count)
304 {
305 	struct qeth_card *card = dev_get_drvdata(dev);
306 	char *tmp;
307 	int i;
308 
309 	if (!card)
310 		return -EINVAL;
311 
312 	if (card->state != CARD_STATE_UP)
313 		return -EPERM;
314 
315 	i = simple_strtoul(buf, &tmp, 16);
316 	if (i == 1)
317 		qeth_schedule_recovery(card);
318 
319 	return count;
320 }
321 
322 static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
323 
324 static ssize_t qeth_dev_performance_stats_show(struct device *dev,
325 				struct device_attribute *attr, char *buf)
326 {
327 	struct qeth_card *card = dev_get_drvdata(dev);
328 
329 	if (!card)
330 		return -EINVAL;
331 
332 	return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
333 }
334 
335 static ssize_t qeth_dev_performance_stats_store(struct device *dev,
336 		struct device_attribute *attr, const char *buf, size_t count)
337 {
338 	struct qeth_card *card = dev_get_drvdata(dev);
339 	char *tmp;
340 	int i;
341 
342 	if (!card)
343 		return -EINVAL;
344 
345 	i = simple_strtoul(buf, &tmp, 16);
346 	if ((i == 0) || (i == 1)) {
347 		if (i == card->options.performance_stats)
348 			return count;
349 		card->options.performance_stats = i;
350 		if (i == 0)
351 			memset(&card->perf_stats, 0,
352 				sizeof(struct qeth_perf_stats));
353 		card->perf_stats.initial_rx_packets = card->stats.rx_packets;
354 		card->perf_stats.initial_tx_packets = card->stats.tx_packets;
355 	} else {
356 		return -EINVAL;
357 	}
358 	return count;
359 }
360 
361 static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
362 		   qeth_dev_performance_stats_store);
363 
364 static ssize_t qeth_dev_layer2_show(struct device *dev,
365 		struct device_attribute *attr, char *buf)
366 {
367 	struct qeth_card *card = dev_get_drvdata(dev);
368 
369 	if (!card)
370 		return -EINVAL;
371 
372 	return sprintf(buf, "%i\n", card->options.layer2);
373 }
374 
375 static ssize_t qeth_dev_layer2_store(struct device *dev,
376 		struct device_attribute *attr, const char *buf, size_t count)
377 {
378 	struct qeth_card *card = dev_get_drvdata(dev);
379 	char *tmp;
380 	int i, rc;
381 	enum qeth_discipline_id newdis;
382 
383 	if (!card)
384 		return -EINVAL;
385 
386 	if (((card->state != CARD_STATE_DOWN) &&
387 	     (card->state != CARD_STATE_RECOVER)))
388 		return -EPERM;
389 
390 	i = simple_strtoul(buf, &tmp, 16);
391 	switch (i) {
392 	case 0:
393 		newdis = QETH_DISCIPLINE_LAYER3;
394 		break;
395 	case 1:
396 		newdis = QETH_DISCIPLINE_LAYER2;
397 		break;
398 	default:
399 		return -EINVAL;
400 	}
401 
402 	if (card->options.layer2 == newdis) {
403 		return count;
404 	} else {
405 		if (card->discipline.ccwgdriver) {
406 			card->discipline.ccwgdriver->remove(card->gdev);
407 			qeth_core_free_discipline(card);
408 		}
409 	}
410 
411 	rc = qeth_core_load_discipline(card, newdis);
412 	if (rc)
413 		return rc;
414 
415 	rc = card->discipline.ccwgdriver->probe(card->gdev);
416 	if (rc)
417 		return rc;
418 	return count;
419 }
420 
421 static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
422 		   qeth_dev_layer2_store);
423 
424 #define ATTR_QETH_ISOLATION_NONE	("none")
425 #define ATTR_QETH_ISOLATION_FWD		("forward")
426 #define ATTR_QETH_ISOLATION_DROP	("drop")
427 
428 static ssize_t qeth_dev_isolation_show(struct device *dev,
429 				struct device_attribute *attr, char *buf)
430 {
431 	struct qeth_card *card = dev_get_drvdata(dev);
432 
433 	if (!card)
434 		return -EINVAL;
435 
436 	switch (card->options.isolation) {
437 	case ISOLATION_MODE_NONE:
438 		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
439 	case ISOLATION_MODE_FWD:
440 		return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
441 	case ISOLATION_MODE_DROP:
442 		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
443 	default:
444 		return snprintf(buf, 5, "%s\n", "N/A");
445 	}
446 }
447 
448 static ssize_t qeth_dev_isolation_store(struct device *dev,
449 		struct device_attribute *attr, const char *buf, size_t count)
450 {
451 	struct qeth_card *card = dev_get_drvdata(dev);
452 	enum qeth_ipa_isolation_modes isolation;
453 	int rc = 0;
454 	char *tmp, *curtoken;
455 	curtoken = (char *) buf;
456 
457 	if (!card) {
458 		rc = -EINVAL;
459 		goto out;
460 	}
461 
462 	/* check for unknown, too, in case we do not yet know who we are */
463 	if (card->info.type != QETH_CARD_TYPE_OSAE &&
464 	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
465 		rc = -EOPNOTSUPP;
466 		dev_err(&card->gdev->dev, "Adapter does not "
467 			"support QDIO data connection isolation\n");
468 		goto out;
469 	}
470 
471 	/* parse input into isolation mode */
472 	tmp = strsep(&curtoken, "\n");
473 	if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
474 		isolation = ISOLATION_MODE_NONE;
475 	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
476 		isolation = ISOLATION_MODE_FWD;
477 	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
478 		isolation = ISOLATION_MODE_DROP;
479 	} else {
480 		rc = -EINVAL;
481 		goto out;
482 	}
483 	rc = count;
484 
485 	/* defer IP assist if device is offline (until discipline->set_online)*/
486 	card->options.isolation = isolation;
487 	if (card->state == CARD_STATE_SOFTSETUP ||
488 	    card->state == CARD_STATE_UP) {
489 		int ipa_rc = qeth_set_access_ctrl_online(card);
490 		if (ipa_rc != 0)
491 			rc = ipa_rc;
492 	}
493 out:
494 	return rc;
495 }
496 
497 static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
498 		   qeth_dev_isolation_store);
499 
500 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
501 {
502 
503 	if (!card)
504 		return -EINVAL;
505 
506 	return sprintf(buf, "%i\n", value);
507 }
508 
509 static ssize_t qeth_dev_blkt_store(struct qeth_card *card,
510 		const char *buf, size_t count, int *value, int max_value)
511 {
512 	char *tmp;
513 	int i;
514 
515 	if (!card)
516 		return -EINVAL;
517 
518 	if ((card->state != CARD_STATE_DOWN) &&
519 	    (card->state != CARD_STATE_RECOVER))
520 		return -EPERM;
521 
522 	i = simple_strtoul(buf, &tmp, 10);
523 	if (i <= max_value) {
524 		*value = i;
525 	} else {
526 		return -EINVAL;
527 	}
528 	return count;
529 }
530 
531 static ssize_t qeth_dev_blkt_total_show(struct device *dev,
532 				struct device_attribute *attr, char *buf)
533 {
534 	struct qeth_card *card = dev_get_drvdata(dev);
535 
536 	return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
537 }
538 
539 static ssize_t qeth_dev_blkt_total_store(struct device *dev,
540 		struct device_attribute *attr, const char *buf, size_t count)
541 {
542 	struct qeth_card *card = dev_get_drvdata(dev);
543 
544 	return qeth_dev_blkt_store(card, buf, count,
545 				   &card->info.blkt.time_total, 5000);
546 }
547 
548 
549 
550 static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
551 		   qeth_dev_blkt_total_store);
552 
553 static ssize_t qeth_dev_blkt_inter_show(struct device *dev,
554 				struct device_attribute *attr, char *buf)
555 {
556 	struct qeth_card *card = dev_get_drvdata(dev);
557 
558 	return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
559 }
560 
561 static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
562 		struct device_attribute *attr, const char *buf, size_t count)
563 {
564 	struct qeth_card *card = dev_get_drvdata(dev);
565 
566 	return qeth_dev_blkt_store(card, buf, count,
567 				   &card->info.blkt.inter_packet, 1000);
568 }
569 
570 static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
571 		   qeth_dev_blkt_inter_store);
572 
573 static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,
574 				struct device_attribute *attr, char *buf)
575 {
576 	struct qeth_card *card = dev_get_drvdata(dev);
577 
578 	return qeth_dev_blkt_show(buf, card,
579 				  card->info.blkt.inter_packet_jumbo);
580 }
581 
582 static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
583 		struct device_attribute *attr, const char *buf, size_t count)
584 {
585 	struct qeth_card *card = dev_get_drvdata(dev);
586 
587 	return qeth_dev_blkt_store(card, buf, count,
588 				   &card->info.blkt.inter_packet_jumbo, 1000);
589 }
590 
591 static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
592 		   qeth_dev_blkt_inter_jumbo_store);
593 
594 static struct attribute *qeth_blkt_device_attrs[] = {
595 	&dev_attr_total.attr,
596 	&dev_attr_inter.attr,
597 	&dev_attr_inter_jumbo.attr,
598 	NULL,
599 };
600 
601 static struct attribute_group qeth_device_blkt_group = {
602 	.name = "blkt",
603 	.attrs = qeth_blkt_device_attrs,
604 };
605 
606 static struct attribute *qeth_device_attrs[] = {
607 	&dev_attr_state.attr,
608 	&dev_attr_chpid.attr,
609 	&dev_attr_if_name.attr,
610 	&dev_attr_card_type.attr,
611 	&dev_attr_inbuf_size.attr,
612 	&dev_attr_portno.attr,
613 	&dev_attr_portname.attr,
614 	&dev_attr_priority_queueing.attr,
615 	&dev_attr_buffer_count.attr,
616 	&dev_attr_recover.attr,
617 	&dev_attr_performance_stats.attr,
618 	&dev_attr_layer2.attr,
619 	&dev_attr_isolation.attr,
620 	NULL,
621 };
622 
623 static struct attribute_group qeth_device_attr_group = {
624 	.attrs = qeth_device_attrs,
625 };
626 
627 static struct attribute *qeth_osn_device_attrs[] = {
628 	&dev_attr_state.attr,
629 	&dev_attr_chpid.attr,
630 	&dev_attr_if_name.attr,
631 	&dev_attr_card_type.attr,
632 	&dev_attr_buffer_count.attr,
633 	&dev_attr_recover.attr,
634 	NULL,
635 };
636 
637 static struct attribute_group qeth_osn_device_attr_group = {
638 	.attrs = qeth_osn_device_attrs,
639 };
640 
641 int qeth_core_create_device_attributes(struct device *dev)
642 {
643 	int ret;
644 	ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group);
645 	if (ret)
646 		return ret;
647 	ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group);
648 	if (ret)
649 		sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
650 
651 	return 0;
652 }
653 
654 void qeth_core_remove_device_attributes(struct device *dev)
655 {
656 	sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
657 	sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
658 }
659 
660 int qeth_core_create_osn_attributes(struct device *dev)
661 {
662 	return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group);
663 }
664 
665 void qeth_core_remove_osn_attributes(struct device *dev)
666 {
667 	sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
668 	return;
669 }
670