aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio.c')
-rw-r--r--drivers/s390/cio/qdio.c322
1 files changed, 174 insertions, 148 deletions
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 8d5fa1b4d11f..d726cd5777de 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -46,6 +46,7 @@
46#include <asm/timex.h> 46#include <asm/timex.h>
47 47
48#include <asm/debug.h> 48#include <asm/debug.h>
49#include <asm/s390_rdev.h>
49#include <asm/qdio.h> 50#include <asm/qdio.h>
50 51
51#include "cio.h" 52#include "cio.h"
@@ -66,11 +67,10 @@ MODULE_LICENSE("GPL");
66 67
67static const char version[] = "QDIO base support version 2"; 68static const char version[] = "QDIO base support version 2";
68 69
69#ifdef QDIO_PERFORMANCE_STATS 70static int qdio_performance_stats = 0;
70static int proc_perf_file_registration; 71static int proc_perf_file_registration;
71static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; 72static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc;
72static struct qdio_perf_stats perf_stats; 73static struct qdio_perf_stats perf_stats;
73#endif /* QDIO_PERFORMANCE_STATS */
74 74
75static int hydra_thinints; 75static int hydra_thinints;
76static int is_passthrough = 0; 76static int is_passthrough = 0;
@@ -137,7 +137,7 @@ qdio_release_q(struct qdio_q *q)
137} 137}
138 138
139/*check ccq */ 139/*check ccq */
140static inline int 140static int
141qdio_check_ccq(struct qdio_q *q, unsigned int ccq) 141qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
142{ 142{
143 char dbf_text[15]; 143 char dbf_text[15];
@@ -152,7 +152,7 @@ qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
152 return -EIO; 152 return -EIO;
153} 153}
154/* EQBS: extract buffer states */ 154/* EQBS: extract buffer states */
155static inline int 155static int
156qdio_do_eqbs(struct qdio_q *q, unsigned char *state, 156qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
157 unsigned int *start, unsigned int *cnt) 157 unsigned int *start, unsigned int *cnt)
158{ 158{
@@ -187,7 +187,7 @@ again:
187} 187}
188 188
189/* SQBS: set buffer states */ 189/* SQBS: set buffer states */
190static inline int 190static int
191qdio_do_sqbs(struct qdio_q *q, unsigned char state, 191qdio_do_sqbs(struct qdio_q *q, unsigned char state,
192 unsigned int *start, unsigned int *cnt) 192 unsigned int *start, unsigned int *cnt)
193{ 193{
@@ -275,9 +275,8 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2,
275 QDIO_DBF_TEXT4(0,trace,"sigasync"); 275 QDIO_DBF_TEXT4(0,trace,"sigasync");
276 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 276 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
277 277
278#ifdef QDIO_PERFORMANCE_STATS 278 if (qdio_performance_stats)
279 perf_stats.siga_syncs++; 279 perf_stats.siga_syncs++;
280#endif /* QDIO_PERFORMANCE_STATS */
281 280
282 cc = do_siga_sync(q->schid, gpr2, gpr3); 281 cc = do_siga_sync(q->schid, gpr2, gpr3);
283 if (cc) 282 if (cc)
@@ -315,16 +314,15 @@ __do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
315 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns 314 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
316 * an access exception 315 * an access exception
317 */ 316 */
318static inline int 317static int
319qdio_siga_output(struct qdio_q *q) 318qdio_siga_output(struct qdio_q *q)
320{ 319{
321 int cc; 320 int cc;
322 __u32 busy_bit; 321 __u32 busy_bit;
323 __u64 start_time=0; 322 __u64 start_time=0;
324 323
325#ifdef QDIO_PERFORMANCE_STATS 324 if (qdio_performance_stats)
326 perf_stats.siga_outs++; 325 perf_stats.siga_outs++;
327#endif /* QDIO_PERFORMANCE_STATS */
328 326
329 QDIO_DBF_TEXT4(0,trace,"sigaout"); 327 QDIO_DBF_TEXT4(0,trace,"sigaout");
330 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 328 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
@@ -350,7 +348,7 @@ qdio_siga_output(struct qdio_q *q)
350 return cc; 348 return cc;
351} 349}
352 350
353static inline int 351static int
354qdio_siga_input(struct qdio_q *q) 352qdio_siga_input(struct qdio_q *q)
355{ 353{
356 int cc; 354 int cc;
@@ -358,9 +356,8 @@ qdio_siga_input(struct qdio_q *q)
358 QDIO_DBF_TEXT4(0,trace,"sigain"); 356 QDIO_DBF_TEXT4(0,trace,"sigain");
359 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 357 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
360 358
361#ifdef QDIO_PERFORMANCE_STATS 359 if (qdio_performance_stats)
362 perf_stats.siga_ins++; 360 perf_stats.siga_ins++;
363#endif /* QDIO_PERFORMANCE_STATS */
364 361
365 cc = do_siga_input(q->schid, q->mask); 362 cc = do_siga_input(q->schid, q->mask);
366 363
@@ -423,7 +420,7 @@ tiqdio_sched_tl(void)
423 tasklet_hi_schedule(&tiqdio_tasklet); 420 tasklet_hi_schedule(&tiqdio_tasklet);
424} 421}
425 422
426static inline void 423static void
427qdio_mark_tiq(struct qdio_q *q) 424qdio_mark_tiq(struct qdio_q *q)
428{ 425{
429 unsigned long flags; 426 unsigned long flags;
@@ -473,7 +470,7 @@ qdio_mark_q(struct qdio_q *q)
473 tasklet_schedule(&q->tasklet); 470 tasklet_schedule(&q->tasklet);
474} 471}
475 472
476static inline int 473static int
477qdio_stop_polling(struct qdio_q *q) 474qdio_stop_polling(struct qdio_q *q)
478{ 475{
479#ifdef QDIO_USE_PROCESSING_STATE 476#ifdef QDIO_USE_PROCESSING_STATE
@@ -527,7 +524,7 @@ qdio_stop_polling(struct qdio_q *q)
527 * sophisticated locking outside of unmark_q, so that we don't need to 524 * sophisticated locking outside of unmark_q, so that we don't need to
528 * disable the interrupts :-) 525 * disable the interrupts :-)
529*/ 526*/
530static inline void 527static void
531qdio_unmark_q(struct qdio_q *q) 528qdio_unmark_q(struct qdio_q *q)
532{ 529{
533 unsigned long flags; 530 unsigned long flags;
@@ -693,7 +690,7 @@ qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q)
693 return q->first_to_check; 690 return q->first_to_check;
694} 691}
695 692
696static inline int 693static int
697qdio_get_outbound_buffer_frontier(struct qdio_q *q) 694qdio_get_outbound_buffer_frontier(struct qdio_q *q)
698{ 695{
699 struct qdio_irq *irq; 696 struct qdio_irq *irq;
@@ -776,7 +773,7 @@ out:
776} 773}
777 774
778/* all buffers are processed */ 775/* all buffers are processed */
779static inline int 776static int
780qdio_is_outbound_q_done(struct qdio_q *q) 777qdio_is_outbound_q_done(struct qdio_q *q)
781{ 778{
782 int no_used; 779 int no_used;
@@ -798,7 +795,7 @@ qdio_is_outbound_q_done(struct qdio_q *q)
798 return (no_used==0); 795 return (no_used==0);
799} 796}
800 797
801static inline int 798static int
802qdio_has_outbound_q_moved(struct qdio_q *q) 799qdio_has_outbound_q_moved(struct qdio_q *q)
803{ 800{
804 int i; 801 int i;
@@ -818,7 +815,7 @@ qdio_has_outbound_q_moved(struct qdio_q *q)
818 } 815 }
819} 816}
820 817
821static inline void 818static void
822qdio_kick_outbound_q(struct qdio_q *q) 819qdio_kick_outbound_q(struct qdio_q *q)
823{ 820{
824 int result; 821 int result;
@@ -907,7 +904,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
907 } 904 }
908} 905}
909 906
910static inline void 907static void
911qdio_kick_outbound_handler(struct qdio_q *q) 908qdio_kick_outbound_handler(struct qdio_q *q)
912{ 909{
913 int start, end, real_end, count; 910 int start, end, real_end, count;
@@ -944,7 +941,7 @@ qdio_kick_outbound_handler(struct qdio_q *q)
944 q->error_status_flags=0; 941 q->error_status_flags=0;
945} 942}
946 943
947static inline void 944static void
948__qdio_outbound_processing(struct qdio_q *q) 945__qdio_outbound_processing(struct qdio_q *q)
949{ 946{
950 int siga_attempts; 947 int siga_attempts;
@@ -954,9 +951,8 @@ __qdio_outbound_processing(struct qdio_q *q)
954 951
955 if (unlikely(qdio_reserve_q(q))) { 952 if (unlikely(qdio_reserve_q(q))) {
956 qdio_release_q(q); 953 qdio_release_q(q);
957#ifdef QDIO_PERFORMANCE_STATS 954 if (qdio_performance_stats)
958 o_p_c++; 955 o_p_c++;
959#endif /* QDIO_PERFORMANCE_STATS */
960 /* as we're sissies, we'll check next time */ 956 /* as we're sissies, we'll check next time */
961 if (likely(!atomic_read(&q->is_in_shutdown))) { 957 if (likely(!atomic_read(&q->is_in_shutdown))) {
962 qdio_mark_q(q); 958 qdio_mark_q(q);
@@ -964,10 +960,10 @@ __qdio_outbound_processing(struct qdio_q *q)
964 } 960 }
965 return; 961 return;
966 } 962 }
967#ifdef QDIO_PERFORMANCE_STATS 963 if (qdio_performance_stats) {
968 o_p_nc++; 964 o_p_nc++;
969 perf_stats.tl_runs++; 965 perf_stats.tl_runs++;
970#endif /* QDIO_PERFORMANCE_STATS */ 966 }
971 967
972 /* see comment in qdio_kick_outbound_q */ 968 /* see comment in qdio_kick_outbound_q */
973 siga_attempts=atomic_read(&q->busy_siga_counter); 969 siga_attempts=atomic_read(&q->busy_siga_counter);
@@ -982,12 +978,11 @@ __qdio_outbound_processing(struct qdio_q *q)
982 978
983 if (q->is_iqdio_q) { 979 if (q->is_iqdio_q) {
984 /* 980 /*
985 * for asynchronous queues, we better check, if the fill 981 * for asynchronous queues, we better check, if the sent
986 * level is too high. for synchronous queues, the fill 982 * buffer is already switched from PRIMED to EMPTY.
987 * level will never be that high.
988 */ 983 */
989 if (atomic_read(&q->number_of_buffers_used)> 984 if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) &&
990 IQDIO_FILL_LEVEL_TO_POLL) 985 !qdio_is_outbound_q_done(q))
991 qdio_mark_q(q); 986 qdio_mark_q(q);
992 987
993 } else if (!q->hydra_gives_outbound_pcis) 988 } else if (!q->hydra_gives_outbound_pcis)
@@ -1006,7 +1001,7 @@ qdio_outbound_processing(struct qdio_q *q)
1006/************************* INBOUND ROUTINES *******************************/ 1001/************************* INBOUND ROUTINES *******************************/
1007 1002
1008 1003
1009static inline int 1004static int
1010qdio_get_inbound_buffer_frontier(struct qdio_q *q) 1005qdio_get_inbound_buffer_frontier(struct qdio_q *q)
1011{ 1006{
1012 struct qdio_irq *irq; 1007 struct qdio_irq *irq;
@@ -1137,20 +1132,21 @@ out:
1137 return q->first_to_check; 1132 return q->first_to_check;
1138} 1133}
1139 1134
1140static inline int 1135static int
1141qdio_has_inbound_q_moved(struct qdio_q *q) 1136qdio_has_inbound_q_moved(struct qdio_q *q)
1142{ 1137{
1143 int i; 1138 int i;
1144 1139
1145#ifdef QDIO_PERFORMANCE_STATS
1146 static int old_pcis=0; 1140 static int old_pcis=0;
1147 static int old_thinints=0; 1141 static int old_thinints=0;
1148 1142
1149 if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) 1143 if (qdio_performance_stats) {
1150 perf_stats.start_time_inbound=NOW; 1144 if ((old_pcis==perf_stats.pcis)&&
1151 else 1145 (old_thinints==perf_stats.thinints))
1152 old_pcis=perf_stats.pcis; 1146 perf_stats.start_time_inbound=NOW;
1153#endif /* QDIO_PERFORMANCE_STATS */ 1147 else
1148 old_pcis=perf_stats.pcis;
1149 }
1154 1150
1155 i=qdio_get_inbound_buffer_frontier(q); 1151 i=qdio_get_inbound_buffer_frontier(q);
1156 if ( (i!=GET_SAVED_FRONTIER(q)) || 1152 if ( (i!=GET_SAVED_FRONTIER(q)) ||
@@ -1170,7 +1166,7 @@ qdio_has_inbound_q_moved(struct qdio_q *q)
1170} 1166}
1171 1167
1172/* means, no more buffers to be filled */ 1168/* means, no more buffers to be filled */
1173static inline int 1169static int
1174tiqdio_is_inbound_q_done(struct qdio_q *q) 1170tiqdio_is_inbound_q_done(struct qdio_q *q)
1175{ 1171{
1176 int no_used; 1172 int no_used;
@@ -1231,7 +1227,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
1231 return 0; 1227 return 0;
1232} 1228}
1233 1229
1234static inline int 1230static int
1235qdio_is_inbound_q_done(struct qdio_q *q) 1231qdio_is_inbound_q_done(struct qdio_q *q)
1236{ 1232{
1237 int no_used; 1233 int no_used;
@@ -1299,7 +1295,7 @@ qdio_is_inbound_q_done(struct qdio_q *q)
1299 } 1295 }
1300} 1296}
1301 1297
1302static inline void 1298static void
1303qdio_kick_inbound_handler(struct qdio_q *q) 1299qdio_kick_inbound_handler(struct qdio_q *q)
1304{ 1300{
1305 int count, start, end, real_end, i; 1301 int count, start, end, real_end, i;
@@ -1340,13 +1336,13 @@ qdio_kick_inbound_handler(struct qdio_q *q)
1340 q->siga_error=0; 1336 q->siga_error=0;
1341 q->error_status_flags=0; 1337 q->error_status_flags=0;
1342 1338
1343#ifdef QDIO_PERFORMANCE_STATS 1339 if (qdio_performance_stats) {
1344 perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; 1340 perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound;
1345 perf_stats.inbound_cnt++; 1341 perf_stats.inbound_cnt++;
1346#endif /* QDIO_PERFORMANCE_STATS */ 1342 }
1347} 1343}
1348 1344
1349static inline void 1345static void
1350__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) 1346__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
1351{ 1347{
1352 struct qdio_irq *irq_ptr; 1348 struct qdio_irq *irq_ptr;
@@ -1363,9 +1359,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
1363 */ 1359 */
1364 if (unlikely(qdio_reserve_q(q))) { 1360 if (unlikely(qdio_reserve_q(q))) {
1365 qdio_release_q(q); 1361 qdio_release_q(q);
1366#ifdef QDIO_PERFORMANCE_STATS 1362 if (qdio_performance_stats)
1367 ii_p_c++; 1363 ii_p_c++;
1368#endif /* QDIO_PERFORMANCE_STATS */
1369 /* 1364 /*
1370 * as we might just be about to stop polling, we make 1365 * as we might just be about to stop polling, we make
1371 * sure that we check again at least once more 1366 * sure that we check again at least once more
@@ -1373,9 +1368,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
1373 tiqdio_sched_tl(); 1368 tiqdio_sched_tl();
1374 return; 1369 return;
1375 } 1370 }
1376#ifdef QDIO_PERFORMANCE_STATS 1371 if (qdio_performance_stats)
1377 ii_p_nc++; 1372 ii_p_nc++;
1378#endif /* QDIO_PERFORMANCE_STATS */
1379 if (unlikely(atomic_read(&q->is_in_shutdown))) { 1373 if (unlikely(atomic_read(&q->is_in_shutdown))) {
1380 qdio_unmark_q(q); 1374 qdio_unmark_q(q);
1381 goto out; 1375 goto out;
@@ -1416,11 +1410,11 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
1416 irq_ptr = (struct qdio_irq*)q->irq_ptr; 1410 irq_ptr = (struct qdio_irq*)q->irq_ptr;
1417 for (i=0;i<irq_ptr->no_output_qs;i++) { 1411 for (i=0;i<irq_ptr->no_output_qs;i++) {
1418 oq = irq_ptr->output_qs[i]; 1412 oq = irq_ptr->output_qs[i];
1419#ifdef QDIO_PERFORMANCE_STATS 1413 if (!qdio_is_outbound_q_done(oq)) {
1420 perf_stats.tl_runs--; 1414 if (qdio_performance_stats)
1421#endif /* QDIO_PERFORMANCE_STATS */ 1415 perf_stats.tl_runs--;
1422 if (!qdio_is_outbound_q_done(oq))
1423 __qdio_outbound_processing(oq); 1416 __qdio_outbound_processing(oq);
1417 }
1424 } 1418 }
1425 } 1419 }
1426 1420
@@ -1447,7 +1441,7 @@ tiqdio_inbound_processing(struct qdio_q *q)
1447 __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount)); 1441 __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount));
1448} 1442}
1449 1443
1450static inline void 1444static void
1451__qdio_inbound_processing(struct qdio_q *q) 1445__qdio_inbound_processing(struct qdio_q *q)
1452{ 1446{
1453 int q_laps=0; 1447 int q_laps=0;
@@ -1457,9 +1451,8 @@ __qdio_inbound_processing(struct qdio_q *q)
1457 1451
1458 if (unlikely(qdio_reserve_q(q))) { 1452 if (unlikely(qdio_reserve_q(q))) {
1459 qdio_release_q(q); 1453 qdio_release_q(q);
1460#ifdef QDIO_PERFORMANCE_STATS 1454 if (qdio_performance_stats)
1461 i_p_c++; 1455 i_p_c++;
1462#endif /* QDIO_PERFORMANCE_STATS */
1463 /* as we're sissies, we'll check next time */ 1456 /* as we're sissies, we'll check next time */
1464 if (likely(!atomic_read(&q->is_in_shutdown))) { 1457 if (likely(!atomic_read(&q->is_in_shutdown))) {
1465 qdio_mark_q(q); 1458 qdio_mark_q(q);
@@ -1467,10 +1460,10 @@ __qdio_inbound_processing(struct qdio_q *q)
1467 } 1460 }
1468 return; 1461 return;
1469 } 1462 }
1470#ifdef QDIO_PERFORMANCE_STATS 1463 if (qdio_performance_stats) {
1471 i_p_nc++; 1464 i_p_nc++;
1472 perf_stats.tl_runs++; 1465 perf_stats.tl_runs++;
1473#endif /* QDIO_PERFORMANCE_STATS */ 1466 }
1474 1467
1475again: 1468again:
1476 if (qdio_has_inbound_q_moved(q)) { 1469 if (qdio_has_inbound_q_moved(q)) {
@@ -1499,7 +1492,7 @@ qdio_inbound_processing(struct qdio_q *q)
1499/************************* MAIN ROUTINES *******************************/ 1492/************************* MAIN ROUTINES *******************************/
1500 1493
1501#ifdef QDIO_USE_PROCESSING_STATE 1494#ifdef QDIO_USE_PROCESSING_STATE
1502static inline int 1495static int
1503tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) 1496tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
1504{ 1497{
1505 if (!q) { 1498 if (!q) {
@@ -1516,9 +1509,8 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
1516 1509
1517 if (unlikely(qdio_reserve_q(q))) { 1510 if (unlikely(qdio_reserve_q(q))) {
1518 qdio_release_q(q); 1511 qdio_release_q(q);
1519#ifdef QDIO_PERFORMANCE_STATS 1512 if (qdio_performance_stats)
1520 ii_p_c++; 1513 ii_p_c++;
1521#endif /* QDIO_PERFORMANCE_STATS */
1522 /* 1514 /*
1523 * as we might just be about to stop polling, we make 1515 * as we might just be about to stop polling, we make
1524 * sure that we check again at least once more 1516 * sure that we check again at least once more
@@ -1552,7 +1544,7 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
1552} 1544}
1553#endif /* QDIO_USE_PROCESSING_STATE */ 1545#endif /* QDIO_USE_PROCESSING_STATE */
1554 1546
1555static inline void 1547static void
1556tiqdio_inbound_checks(void) 1548tiqdio_inbound_checks(void)
1557{ 1549{
1558 struct qdio_q *q; 1550 struct qdio_q *q;
@@ -1609,9 +1601,8 @@ tiqdio_tl(unsigned long data)
1609{ 1601{
1610 QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); 1602 QDIO_DBF_TEXT4(0,trace,"iqdio_tl");
1611 1603
1612#ifdef QDIO_PERFORMANCE_STATS 1604 if (qdio_performance_stats)
1613 perf_stats.tl_runs++; 1605 perf_stats.tl_runs++;
1614#endif /* QDIO_PERFORMANCE_STATS */
1615 1606
1616 tiqdio_inbound_checks(); 1607 tiqdio_inbound_checks();
1617} 1608}
@@ -1832,6 +1823,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1832 q->sbal[j]=*(outbound_sbals_array++); 1823 q->sbal[j]=*(outbound_sbals_array++);
1833 1824
1834 q->queue_type=q_format; 1825 q->queue_type=q_format;
1826 if ((q->queue_type == QDIO_IQDIO_QFMT) &&
1827 (no_output_qs > 1) &&
1828 (i == no_output_qs-1))
1829 q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
1835 q->int_parm=int_parm; 1830 q->int_parm=int_parm;
1836 q->is_input_q=0; 1831 q->is_input_q=0;
1837 q->schid = irq_ptr->schid; 1832 q->schid = irq_ptr->schid;
@@ -1918,10 +1913,10 @@ tiqdio_thinint_handler(void)
1918{ 1913{
1919 QDIO_DBF_TEXT4(0,trace,"thin_int"); 1914 QDIO_DBF_TEXT4(0,trace,"thin_int");
1920 1915
1921#ifdef QDIO_PERFORMANCE_STATS 1916 if (qdio_performance_stats) {
1922 perf_stats.thinints++; 1917 perf_stats.thinints++;
1923 perf_stats.start_time_inbound=NOW; 1918 perf_stats.start_time_inbound=NOW;
1924#endif /* QDIO_PERFORMANCE_STATS */ 1919 }
1925 1920
1926 /* SVS only when needed: 1921 /* SVS only when needed:
1927 * issue SVS to benefit from iqdio interrupt avoidance 1922 * issue SVS to benefit from iqdio interrupt avoidance
@@ -1953,7 +1948,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state)
1953 mb(); 1948 mb();
1954} 1949}
1955 1950
1956static inline void 1951static void
1957qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) 1952qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1958{ 1953{
1959 char dbf_text[15]; 1954 char dbf_text[15];
@@ -1970,24 +1965,23 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1970 1965
1971} 1966}
1972 1967
1973static inline void 1968static void
1974qdio_handle_pci(struct qdio_irq *irq_ptr) 1969qdio_handle_pci(struct qdio_irq *irq_ptr)
1975{ 1970{
1976 int i; 1971 int i;
1977 struct qdio_q *q; 1972 struct qdio_q *q;
1978 1973
1979#ifdef QDIO_PERFORMANCE_STATS 1974 if (qdio_performance_stats) {
1980 perf_stats.pcis++; 1975 perf_stats.pcis++;
1981 perf_stats.start_time_inbound=NOW; 1976 perf_stats.start_time_inbound=NOW;
1982#endif /* QDIO_PERFORMANCE_STATS */ 1977 }
1983 for (i=0;i<irq_ptr->no_input_qs;i++) { 1978 for (i=0;i<irq_ptr->no_input_qs;i++) {
1984 q=irq_ptr->input_qs[i]; 1979 q=irq_ptr->input_qs[i];
1985 if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) 1980 if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT)
1986 qdio_mark_q(q); 1981 qdio_mark_q(q);
1987 else { 1982 else {
1988#ifdef QDIO_PERFORMANCE_STATS 1983 if (qdio_performance_stats)
1989 perf_stats.tl_runs--; 1984 perf_stats.tl_runs--;
1990#endif /* QDIO_PERFORMANCE_STATS */
1991 __qdio_inbound_processing(q); 1985 __qdio_inbound_processing(q);
1992 } 1986 }
1993 } 1987 }
@@ -1995,11 +1989,10 @@ qdio_handle_pci(struct qdio_irq *irq_ptr)
1995 return; 1989 return;
1996 for (i=0;i<irq_ptr->no_output_qs;i++) { 1990 for (i=0;i<irq_ptr->no_output_qs;i++) {
1997 q=irq_ptr->output_qs[i]; 1991 q=irq_ptr->output_qs[i];
1998#ifdef QDIO_PERFORMANCE_STATS
1999 perf_stats.tl_runs--;
2000#endif /* QDIO_PERFORMANCE_STATS */
2001 if (qdio_is_outbound_q_done(q)) 1992 if (qdio_is_outbound_q_done(q))
2002 continue; 1993 continue;
1994 if (qdio_performance_stats)
1995 perf_stats.tl_runs--;
2003 if (!irq_ptr->sync_done_on_outb_pcis) 1996 if (!irq_ptr->sync_done_on_outb_pcis)
2004 SYNC_MEMORY; 1997 SYNC_MEMORY;
2005 __qdio_outbound_processing(q); 1998 __qdio_outbound_processing(q);
@@ -2008,7 +2001,7 @@ qdio_handle_pci(struct qdio_irq *irq_ptr)
2008 2001
2009static void qdio_establish_handle_irq(struct ccw_device*, int, int); 2002static void qdio_establish_handle_irq(struct ccw_device*, int, int);
2010 2003
2011static inline void 2004static void
2012qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, 2005qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm,
2013 int cstat, int dstat) 2006 int cstat, int dstat)
2014{ 2007{
@@ -2045,11 +2038,13 @@ omit_handler_call:
2045} 2038}
2046 2039
2047static void 2040static void
2048qdio_call_shutdown(void *data) 2041qdio_call_shutdown(struct work_struct *work)
2049{ 2042{
2043 struct ccw_device_private *priv;
2050 struct ccw_device *cdev; 2044 struct ccw_device *cdev;
2051 2045
2052 cdev = (struct ccw_device *)data; 2046 priv = container_of(work, struct ccw_device_private, kick_work);
2047 cdev = priv->cdev;
2053 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); 2048 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
2054 put_device(&cdev->dev); 2049 put_device(&cdev->dev);
2055} 2050}
@@ -2091,7 +2086,7 @@ qdio_timeout_handler(struct ccw_device *cdev)
2091 if (get_device(&cdev->dev)) { 2086 if (get_device(&cdev->dev)) {
2092 /* Can't call shutdown from interrupt context. */ 2087 /* Can't call shutdown from interrupt context. */
2093 PREPARE_WORK(&cdev->private->kick_work, 2088 PREPARE_WORK(&cdev->private->kick_work,
2094 qdio_call_shutdown, (void *)cdev); 2089 qdio_call_shutdown);
2095 queue_work(ccw_device_work, &cdev->private->kick_work); 2090 queue_work(ccw_device_work, &cdev->private->kick_work);
2096 } 2091 }
2097 break; 2092 break;
@@ -2233,7 +2228,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
2233 return cc; 2228 return cc;
2234} 2229}
2235 2230
2236static inline void 2231static void
2237qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac, 2232qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac,
2238 unsigned long token) 2233 unsigned long token)
2239{ 2234{
@@ -2744,7 +2739,7 @@ qdio_free(struct ccw_device *cdev)
2744 return 0; 2739 return 0;
2745} 2740}
2746 2741
2747static inline void 2742static void
2748qdio_allocate_do_dbf(struct qdio_initialize *init_data) 2743qdio_allocate_do_dbf(struct qdio_initialize *init_data)
2749{ 2744{
2750 char dbf_text[20]; /* if a printf printed out more than 8 chars */ 2745 char dbf_text[20]; /* if a printf printed out more than 8 chars */
@@ -2777,7 +2772,7 @@ qdio_allocate_do_dbf(struct qdio_initialize *init_data)
2777 QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); 2772 QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
2778} 2773}
2779 2774
2780static inline void 2775static void
2781qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) 2776qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
2782{ 2777{
2783 irq_ptr->input_qs[i]->is_iqdio_q = iqfmt; 2778 irq_ptr->input_qs[i]->is_iqdio_q = iqfmt;
@@ -2796,7 +2791,7 @@ qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
2796 irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY; 2791 irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY;
2797} 2792}
2798 2793
2799static inline void 2794static void
2800qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, 2795qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
2801 int j, int iqfmt) 2796 int j, int iqfmt)
2802{ 2797{
@@ -2817,7 +2812,7 @@ qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
2817} 2812}
2818 2813
2819 2814
2820static inline void 2815static void
2821qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) 2816qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
2822{ 2817{
2823 int i; 2818 int i;
@@ -2843,7 +2838,7 @@ qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
2843 } 2838 }
2844} 2839}
2845 2840
2846static inline void 2841static void
2847qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) 2842qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
2848{ 2843{
2849 int i; 2844 int i;
@@ -2869,7 +2864,7 @@ qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
2869 } 2864 }
2870} 2865}
2871 2866
2872static inline int 2867static int
2873qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, 2868qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
2874 int dstat) 2869 int dstat)
2875{ 2870{
@@ -3018,7 +3013,7 @@ qdio_allocate(struct qdio_initialize *init_data)
3018 return 0; 3013 return 0;
3019} 3014}
3020 3015
3021int qdio_fill_irq(struct qdio_initialize *init_data) 3016static int qdio_fill_irq(struct qdio_initialize *init_data)
3022{ 3017{
3023 int i; 3018 int i;
3024 char dbf_text[15]; 3019 char dbf_text[15];
@@ -3371,7 +3366,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
3371} 3366}
3372 3367
3373/* buffers filled forwards again to make Rick happy */ 3368/* buffers filled forwards again to make Rick happy */
3374static inline void 3369static void
3375qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, 3370qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
3376 unsigned int count, struct qdio_buffer *buffers) 3371 unsigned int count, struct qdio_buffer *buffers)
3377{ 3372{
@@ -3390,7 +3385,7 @@ qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
3390 } 3385 }
3391} 3386}
3392 3387
3393static inline void 3388static void
3394qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, 3389qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
3395 unsigned int count, struct qdio_buffer *buffers) 3390 unsigned int count, struct qdio_buffer *buffers)
3396{ 3391{
@@ -3411,7 +3406,7 @@ qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
3411 } 3406 }
3412} 3407}
3413 3408
3414static inline void 3409static void
3415do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, 3410do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3416 unsigned int qidx, unsigned int count, 3411 unsigned int qidx, unsigned int count,
3417 struct qdio_buffer *buffers) 3412 struct qdio_buffer *buffers)
@@ -3447,7 +3442,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3447 qdio_mark_q(q); 3442 qdio_mark_q(q);
3448} 3443}
3449 3444
3450static inline void 3445static void
3451do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, 3446do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3452 unsigned int qidx, unsigned int count, 3447 unsigned int qidx, unsigned int count,
3453 struct qdio_buffer *buffers) 3448 struct qdio_buffer *buffers)
@@ -3458,19 +3453,18 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3458 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; 3453 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
3459 3454
3460 /* This is the outbound handling of queues */ 3455 /* This is the outbound handling of queues */
3461#ifdef QDIO_PERFORMANCE_STATS 3456 if (qdio_performance_stats)
3462 perf_stats.start_time_outbound=NOW; 3457 perf_stats.start_time_outbound=NOW;
3463#endif /* QDIO_PERFORMANCE_STATS */
3464 3458
3465 qdio_do_qdio_fill_output(q,qidx,count,buffers); 3459 qdio_do_qdio_fill_output(q,qidx,count,buffers);
3466 3460
3467 used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; 3461 used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count;
3468 3462
3469 if (callflags&QDIO_FLAG_DONT_SIGA) { 3463 if (callflags&QDIO_FLAG_DONT_SIGA) {
3470#ifdef QDIO_PERFORMANCE_STATS 3464 if (qdio_performance_stats) {
3471 perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3465 perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
3472 perf_stats.outbound_cnt++; 3466 perf_stats.outbound_cnt++;
3473#endif /* QDIO_PERFORMANCE_STATS */ 3467 }
3474 return; 3468 return;
3475 } 3469 }
3476 if (q->is_iqdio_q) { 3470 if (q->is_iqdio_q) {
@@ -3500,9 +3494,8 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3500 qdio_kick_outbound_q(q); 3494 qdio_kick_outbound_q(q);
3501 } else { 3495 } else {
3502 QDIO_DBF_TEXT3(0,trace, "fast-req"); 3496 QDIO_DBF_TEXT3(0,trace, "fast-req");
3503#ifdef QDIO_PERFORMANCE_STATS 3497 if (qdio_performance_stats)
3504 perf_stats.fast_reqs++; 3498 perf_stats.fast_reqs++;
3505#endif /* QDIO_PERFORMANCE_STATS */
3506 } 3499 }
3507 } 3500 }
3508 /* 3501 /*
@@ -3513,10 +3506,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3513 __qdio_outbound_processing(q); 3506 __qdio_outbound_processing(q);
3514 } 3507 }
3515 3508
3516#ifdef QDIO_PERFORMANCE_STATS 3509 if (qdio_performance_stats) {
3517 perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3510 perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
3518 perf_stats.outbound_cnt++; 3511 perf_stats.outbound_cnt++;
3519#endif /* QDIO_PERFORMANCE_STATS */ 3512 }
3520} 3513}
3521 3514
3522/* count must be 1 in iqdio */ 3515/* count must be 1 in iqdio */
@@ -3574,7 +3567,6 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags,
3574 return 0; 3567 return 0;
3575} 3568}
3576 3569
3577#ifdef QDIO_PERFORMANCE_STATS
3578static int 3570static int
3579qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, 3571qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset,
3580 int buffer_length, int *eof, void *data) 3572 int buffer_length, int *eof, void *data)
@@ -3590,29 +3582,29 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset,
3590 _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); 3582 _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c);
3591 _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); 3583 _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c);
3592 _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); 3584 _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c);
3593 _OUTP_IT("Number of tasklet runs (total) : %u\n", 3585 _OUTP_IT("Number of tasklet runs (total) : %lu\n",
3594 perf_stats.tl_runs); 3586 perf_stats.tl_runs);
3595 _OUTP_IT("\n"); 3587 _OUTP_IT("\n");
3596 _OUTP_IT("Number of SIGA sync's issued : %u\n", 3588 _OUTP_IT("Number of SIGA sync's issued : %lu\n",
3597 perf_stats.siga_syncs); 3589 perf_stats.siga_syncs);
3598 _OUTP_IT("Number of SIGA in's issued : %u\n", 3590 _OUTP_IT("Number of SIGA in's issued : %lu\n",
3599 perf_stats.siga_ins); 3591 perf_stats.siga_ins);
3600 _OUTP_IT("Number of SIGA out's issued : %u\n", 3592 _OUTP_IT("Number of SIGA out's issued : %lu\n",
3601 perf_stats.siga_outs); 3593 perf_stats.siga_outs);
3602 _OUTP_IT("Number of PCIs caught : %u\n", 3594 _OUTP_IT("Number of PCIs caught : %lu\n",
3603 perf_stats.pcis); 3595 perf_stats.pcis);
3604 _OUTP_IT("Number of adapter interrupts caught : %u\n", 3596 _OUTP_IT("Number of adapter interrupts caught : %lu\n",
3605 perf_stats.thinints); 3597 perf_stats.thinints);
3606 _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", 3598 _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n",
3607 perf_stats.fast_reqs); 3599 perf_stats.fast_reqs);
3608 _OUTP_IT("\n"); 3600 _OUTP_IT("\n");
3609 _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", 3601 _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n",
3610 perf_stats.inbound_time); 3602 perf_stats.inbound_time);
3611 _OUTP_IT("Number of inbound transfers : %u\n", 3603 _OUTP_IT("Number of inbound transfers : %lu\n",
3612 perf_stats.inbound_cnt); 3604 perf_stats.inbound_cnt);
3613 _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", 3605 _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n",
3614 perf_stats.outbound_time); 3606 perf_stats.outbound_time);
3615 _OUTP_IT("Number of do_QDIOs outbound : %u\n", 3607 _OUTP_IT("Number of do_QDIOs outbound : %lu\n",
3616 perf_stats.outbound_cnt); 3608 perf_stats.outbound_cnt);
3617 _OUTP_IT("\n"); 3609 _OUTP_IT("\n");
3618 3610
@@ -3620,12 +3612,10 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset,
3620} 3612}
3621 3613
3622static struct proc_dir_entry *qdio_perf_proc_file; 3614static struct proc_dir_entry *qdio_perf_proc_file;
3623#endif /* QDIO_PERFORMANCE_STATS */
3624 3615
3625static void 3616static void
3626qdio_add_procfs_entry(void) 3617qdio_add_procfs_entry(void)
3627{ 3618{
3628#ifdef QDIO_PERFORMANCE_STATS
3629 proc_perf_file_registration=0; 3619 proc_perf_file_registration=0;
3630 qdio_perf_proc_file=create_proc_entry(QDIO_PERF, 3620 qdio_perf_proc_file=create_proc_entry(QDIO_PERF,
3631 S_IFREG|0444,&proc_root); 3621 S_IFREG|0444,&proc_root);
@@ -3637,20 +3627,58 @@ qdio_add_procfs_entry(void)
3637 QDIO_PRINT_WARN("was not able to register perf. " \ 3627 QDIO_PRINT_WARN("was not able to register perf. " \
3638 "proc-file (%i).\n", 3628 "proc-file (%i).\n",
3639 proc_perf_file_registration); 3629 proc_perf_file_registration);
3640#endif /* QDIO_PERFORMANCE_STATS */
3641} 3630}
3642 3631
3643static void 3632static void
3644qdio_remove_procfs_entry(void) 3633qdio_remove_procfs_entry(void)
3645{ 3634{
3646#ifdef QDIO_PERFORMANCE_STATS
3647 perf_stats.tl_runs=0; 3635 perf_stats.tl_runs=0;
3648 3636
3649 if (!proc_perf_file_registration) /* means if it went ok earlier */ 3637 if (!proc_perf_file_registration) /* means if it went ok earlier */
3650 remove_proc_entry(QDIO_PERF,&proc_root); 3638 remove_proc_entry(QDIO_PERF,&proc_root);
3651#endif /* QDIO_PERFORMANCE_STATS */
3652} 3639}
3653 3640
3641/**
3642 * attributes in sysfs
3643 *****************************************************************************/
3644
3645static ssize_t
3646qdio_performance_stats_show(struct bus_type *bus, char *buf)
3647{
3648 return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0);
3649}
3650
3651static ssize_t
3652qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count)
3653{
3654 char *tmp;
3655 int i;
3656
3657 i = simple_strtoul(buf, &tmp, 16);
3658 if ((i == 0) || (i == 1)) {
3659 if (i == qdio_performance_stats)
3660 return count;
3661 qdio_performance_stats = i;
3662 if (i==0) {
3663 /* reset perf. stat. info */
3664 i_p_nc = 0;
3665 i_p_c = 0;
3666 ii_p_nc = 0;
3667 ii_p_c = 0;
3668 o_p_nc = 0;
3669 o_p_c = 0;
3670 memset(&perf_stats, 0, sizeof(struct qdio_perf_stats));
3671 }
3672 } else {
3673 QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n");
3674 return -EINVAL;
3675 }
3676 return count;
3677}
3678
3679static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show,
3680 qdio_performance_stats_store);
3681
3654static void 3682static void
3655tiqdio_register_thinints(void) 3683tiqdio_register_thinints(void)
3656{ 3684{
@@ -3695,6 +3723,7 @@ qdio_release_qdio_memory(void)
3695 kfree(indicators); 3723 kfree(indicators);
3696} 3724}
3697 3725
3726
3698static void 3727static void
3699qdio_unregister_dbf_views(void) 3728qdio_unregister_dbf_views(void)
3700{ 3729{
@@ -3796,9 +3825,7 @@ static int __init
3796init_QDIO(void) 3825init_QDIO(void)
3797{ 3826{
3798 int res; 3827 int res;
3799#ifdef QDIO_PERFORMANCE_STATS
3800 void *ptr; 3828 void *ptr;
3801#endif /* QDIO_PERFORMANCE_STATS */
3802 3829
3803 printk("qdio: loading %s\n",version); 3830 printk("qdio: loading %s\n",version);
3804 3831
@@ -3811,13 +3838,12 @@ init_QDIO(void)
3811 return res; 3838 return res;
3812 3839
3813 QDIO_DBF_TEXT0(0,setup,"initQDIO"); 3840 QDIO_DBF_TEXT0(0,setup,"initQDIO");
3841 res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
3814 3842
3815#ifdef QDIO_PERFORMANCE_STATS 3843 memset((void*)&perf_stats,0,sizeof(perf_stats));
3816 memset((void*)&perf_stats,0,sizeof(perf_stats));
3817 QDIO_DBF_TEXT0(0,setup,"perfstat"); 3844 QDIO_DBF_TEXT0(0,setup,"perfstat");
3818 ptr=&perf_stats; 3845 ptr=&perf_stats;
3819 QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); 3846 QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
3820#endif /* QDIO_PERFORMANCE_STATS */
3821 3847
3822 qdio_add_procfs_entry(); 3848 qdio_add_procfs_entry();
3823 3849
@@ -3841,7 +3867,7 @@ cleanup_QDIO(void)
3841 qdio_release_qdio_memory(); 3867 qdio_release_qdio_memory();
3842 qdio_unregister_dbf_views(); 3868 qdio_unregister_dbf_views();
3843 mempool_destroy(qdio_mempool_scssc); 3869 mempool_destroy(qdio_mempool_scssc);
3844 3870 bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
3845 printk("qdio: %s: module removed\n",version); 3871 printk("qdio: %s: module removed\n",version);
3846} 3872}
3847 3873