aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r--drivers/s390/cio/qdio_main.c222
1 files changed, 99 insertions, 123 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 10cb0f8726e5..9e8a2914259b 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdio_q *q)
380 380
381 /* show the card that we are not polling anymore */ 381 /* show the card that we are not polling anymore */
382 if (is_qebsm(q)) { 382 if (is_qebsm(q)) {
383 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT, 383 set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
384 q->u.in.ack_count); 384 q->u.in.ack_count);
385 q->u.in.ack_count = 0; 385 q->u.in.ack_count = 0;
386 } else 386 } else
387 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); 387 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
388} 388}
389 389
390static void announce_buffer_error(struct qdio_q *q, int count) 390static void announce_buffer_error(struct qdio_q *q, int count)
@@ -419,15 +419,15 @@ static inline void inbound_primed(struct qdio_q *q, int count)
419 if (!q->u.in.polling) { 419 if (!q->u.in.polling) {
420 q->u.in.polling = 1; 420 q->u.in.polling = 1;
421 q->u.in.ack_count = count; 421 q->u.in.ack_count = count;
422 q->last_move_ftc = q->first_to_check; 422 q->u.in.ack_start = q->first_to_check;
423 return; 423 return;
424 } 424 }
425 425
426 /* delete the previous ACK's */ 426 /* delete the previous ACK's */
427 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT, 427 set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
428 q->u.in.ack_count); 428 q->u.in.ack_count);
429 q->u.in.ack_count = count; 429 q->u.in.ack_count = count;
430 q->last_move_ftc = q->first_to_check; 430 q->u.in.ack_start = q->first_to_check;
431 return; 431 return;
432 } 432 }
433 433
@@ -439,14 +439,13 @@ static inline void inbound_primed(struct qdio_q *q, int count)
439 if (q->u.in.polling) { 439 if (q->u.in.polling) {
440 /* reset the previous ACK but first set the new one */ 440 /* reset the previous ACK but first set the new one */
441 set_buf_state(q, new, SLSB_P_INPUT_ACK); 441 set_buf_state(q, new, SLSB_P_INPUT_ACK);
442 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); 442 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
443 } 443 } else {
444 else {
445 q->u.in.polling = 1; 444 q->u.in.polling = 1;
446 set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK); 445 set_buf_state(q, new, SLSB_P_INPUT_ACK);
447 } 446 }
448 447
449 q->last_move_ftc = new; 448 q->u.in.ack_start = new;
450 count--; 449 count--;
451 if (!count) 450 if (!count)
452 return; 451 return;
@@ -455,7 +454,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
455 * Need to change all PRIMED buffers to NOT_INIT, otherwise 454 * Need to change all PRIMED buffers to NOT_INIT, otherwise
456 * we're loosing initiative in the thinint code. 455 * we're loosing initiative in the thinint code.
457 */ 456 */
458 set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT, 457 set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
459 count); 458 count);
460} 459}
461 460
@@ -523,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *q)
523 522
524 bufnr = get_inbound_buffer_frontier(q); 523 bufnr = get_inbound_buffer_frontier(q);
525 524
526 if ((bufnr != q->last_move_ftc) || q->qdio_error) { 525 if ((bufnr != q->last_move) || q->qdio_error) {
526 q->last_move = bufnr;
527 if (!need_siga_sync(q) && !pci_out_supported(q)) 527 if (!need_siga_sync(q) && !pci_out_supported(q))
528 q->u.in.timestamp = get_usecs(); 528 q->u.in.timestamp = get_usecs();
529 529
@@ -570,29 +570,30 @@ static int qdio_inbound_q_done(struct qdio_q *q)
570 } 570 }
571} 571}
572 572
573void qdio_kick_inbound_handler(struct qdio_q *q) 573void qdio_kick_handler(struct qdio_q *q)
574{ 574{
575 int count, start, end; 575 int start = q->first_to_kick;
576 576 int end = q->first_to_check;
577 qdio_perf_stat_inc(&perf_stats.inbound_handler); 577 int count;
578
579 start = q->first_to_kick;
580 end = q->first_to_check;
581 if (end >= start)
582 count = end - start;
583 else
584 count = end + QDIO_MAX_BUFFERS_PER_Q - start;
585
586 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
587 578
588 if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) 579 if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
589 return; 580 return;
590 581
591 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, 582 count = sub_buf(end, start);
592 start, count, q->irq_ptr->int_parm); 583
584 if (q->is_input_q) {
585 qdio_perf_stat_inc(&perf_stats.inbound_handler);
586 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
587 } else {
588 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: nr:%1d", q->nr);
589 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
590 }
591
592 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
593 q->irq_ptr->int_parm);
593 594
594 /* for the next time */ 595 /* for the next time */
595 q->first_to_kick = q->first_to_check; 596 q->first_to_kick = end;
596 q->qdio_error = 0; 597 q->qdio_error = 0;
597} 598}
598 599
@@ -603,7 +604,7 @@ again:
603 if (!qdio_inbound_q_moved(q)) 604 if (!qdio_inbound_q_moved(q))
604 return; 605 return;
605 606
606 qdio_kick_inbound_handler(q); 607 qdio_kick_handler(q);
607 608
608 if (!qdio_inbound_q_done(q)) 609 if (!qdio_inbound_q_done(q))
609 /* means poll time is not yet over */ 610 /* means poll time is not yet over */
@@ -698,21 +699,21 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
698 699
699 bufnr = get_outbound_buffer_frontier(q); 700 bufnr = get_outbound_buffer_frontier(q);
700 701
701 if ((bufnr != q->last_move_ftc) || q->qdio_error) { 702 if ((bufnr != q->last_move) || q->qdio_error) {
702 q->last_move_ftc = bufnr; 703 q->last_move = bufnr;
703 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); 704 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
704 return 1; 705 return 1;
705 } else 706 } else
706 return 0; 707 return 0;
707} 708}
708 709
709static void qdio_kick_outbound_q(struct qdio_q *q) 710static int qdio_kick_outbound_q(struct qdio_q *q)
710{ 711{
711 unsigned int busy_bit; 712 unsigned int busy_bit;
712 int cc; 713 int cc;
713 714
714 if (!need_siga_out(q)) 715 if (!need_siga_out(q))
715 return; 716 return 0;
716 717
717 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); 718 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
718 qdio_perf_stat_inc(&perf_stats.siga_out); 719 qdio_perf_stat_inc(&perf_stats.siga_out);
@@ -724,75 +725,37 @@ static void qdio_kick_outbound_q(struct qdio_q *q)
724 case 2: 725 case 2:
725 if (busy_bit) { 726 if (busy_bit) {
726 DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr); 727 DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr);
727 q->qdio_error = cc | QDIO_ERROR_SIGA_BUSY; 728 cc |= QDIO_ERROR_SIGA_BUSY;
728 } else { 729 } else
729 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", 730 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
730 q->nr);
731 q->qdio_error = cc;
732 }
733 break; 731 break;
734 case 1: 732 case 1:
735 case 3: 733 case 3:
736 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); 734 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
737 q->qdio_error = cc;
738 break; 735 break;
739 } 736 }
740} 737 return cc;
741
742static void qdio_kick_outbound_handler(struct qdio_q *q)
743{
744 int start, end, count;
745
746 start = q->first_to_kick;
747 end = q->last_move_ftc;
748 if (end >= start)
749 count = end - start;
750 else
751 count = end + QDIO_MAX_BUFFERS_PER_Q - start;
752
753 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kickouth: %1d", q->nr);
754 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
755
756 if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
757 return;
758
759 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
760 q->irq_ptr->int_parm);
761
762 /* for the next time: */
763 q->first_to_kick = q->last_move_ftc;
764 q->qdio_error = 0;
765} 738}
766 739
767static void __qdio_outbound_processing(struct qdio_q *q) 740static void __qdio_outbound_processing(struct qdio_q *q)
768{ 741{
769 unsigned long flags;
770
771 qdio_perf_stat_inc(&perf_stats.tasklet_outbound); 742 qdio_perf_stat_inc(&perf_stats.tasklet_outbound);
772 spin_lock_irqsave(&q->lock, flags);
773
774 BUG_ON(atomic_read(&q->nr_buf_used) < 0); 743 BUG_ON(atomic_read(&q->nr_buf_used) < 0);
775 744
776 if (qdio_outbound_q_moved(q)) 745 if (qdio_outbound_q_moved(q))
777 qdio_kick_outbound_handler(q); 746 qdio_kick_handler(q);
778
779 spin_unlock_irqrestore(&q->lock, flags);
780 747
781 if (queue_type(q) == QDIO_ZFCP_QFMT) { 748 if (queue_type(q) == QDIO_ZFCP_QFMT)
782 if (!pci_out_supported(q) && !qdio_outbound_q_done(q)) 749 if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
783 tasklet_schedule(&q->tasklet); 750 goto sched;
784 return;
785 }
786 751
787 /* bail out for HiperSockets unicast queues */ 752 /* bail out for HiperSockets unicast queues */
788 if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) 753 if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
789 return; 754 return;
790 755
791 if ((queue_type(q) == QDIO_IQDIO_QFMT) && 756 if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
792 (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) { 757 (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
793 tasklet_schedule(&q->tasklet); 758 goto sched;
794 return;
795 }
796 759
797 if (q->u.out.pci_out_enabled) 760 if (q->u.out.pci_out_enabled)
798 return; 761 return;
@@ -810,6 +773,12 @@ static void __qdio_outbound_processing(struct qdio_q *q)
810 qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer); 773 qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
811 } 774 }
812 } 775 }
776 return;
777
778sched:
779 if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
780 return;
781 tasklet_schedule(&q->tasklet);
813} 782}
814 783
815/* outbound tasklet */ 784/* outbound tasklet */
@@ -822,6 +791,9 @@ void qdio_outbound_processing(unsigned long data)
822void qdio_outbound_timer(unsigned long data) 791void qdio_outbound_timer(unsigned long data)
823{ 792{
824 struct qdio_q *q = (struct qdio_q *)data; 793 struct qdio_q *q = (struct qdio_q *)data;
794
795 if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
796 return;
825 tasklet_schedule(&q->tasklet); 797 tasklet_schedule(&q->tasklet);
826} 798}
827 799
@@ -863,6 +835,9 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
863 int i; 835 int i;
864 struct qdio_q *q; 836 struct qdio_q *q;
865 837
838 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
839 return;
840
866 qdio_perf_stat_inc(&perf_stats.pci_int); 841 qdio_perf_stat_inc(&perf_stats.pci_int);
867 842
868 for_each_input_queue(irq_ptr, q, i) 843 for_each_input_queue(irq_ptr, q, i)
@@ -1065,8 +1040,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
1065 * @cdev: associated ccw device 1040 * @cdev: associated ccw device
1066 * @how: use halt or clear to shutdown 1041 * @how: use halt or clear to shutdown
1067 * 1042 *
1068 * This function calls qdio_shutdown() for @cdev with method @how 1043 * This function calls qdio_shutdown() for @cdev with method @how.
1069 * and on success qdio_free() for @cdev. 1044 * and qdio_free(). The qdio_free() return value is ignored since
1045 * !irq_ptr is already checked.
1070 */ 1046 */
1071int qdio_cleanup(struct ccw_device *cdev, int how) 1047int qdio_cleanup(struct ccw_device *cdev, int how)
1072{ 1048{
@@ -1077,8 +1053,8 @@ int qdio_cleanup(struct ccw_device *cdev, int how)
1077 return -ENODEV; 1053 return -ENODEV;
1078 1054
1079 rc = qdio_shutdown(cdev, how); 1055 rc = qdio_shutdown(cdev, how);
1080 if (rc == 0) 1056
1081 rc = qdio_free(cdev); 1057 qdio_free(cdev);
1082 return rc; 1058 return rc;
1083} 1059}
1084EXPORT_SYMBOL_GPL(qdio_cleanup); 1060EXPORT_SYMBOL_GPL(qdio_cleanup);
@@ -1090,11 +1066,11 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
1090 int i; 1066 int i;
1091 1067
1092 for_each_input_queue(irq_ptr, q, i) 1068 for_each_input_queue(irq_ptr, q, i)
1093 tasklet_disable(&q->tasklet); 1069 tasklet_kill(&q->tasklet);
1094 1070
1095 for_each_output_queue(irq_ptr, q, i) { 1071 for_each_output_queue(irq_ptr, q, i) {
1096 tasklet_disable(&q->tasklet);
1097 del_timer(&q->u.out.timer); 1072 del_timer(&q->u.out.timer);
1073 tasklet_kill(&q->tasklet);
1098 } 1074 }
1099} 1075}
1100 1076
@@ -1112,6 +1088,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1112 if (!irq_ptr) 1088 if (!irq_ptr)
1113 return -ENODEV; 1089 return -ENODEV;
1114 1090
1091 BUG_ON(irqs_disabled());
1115 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no); 1092 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
1116 1093
1117 mutex_lock(&irq_ptr->setup_mutex); 1094 mutex_lock(&irq_ptr->setup_mutex);
@@ -1124,6 +1101,12 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1124 return 0; 1101 return 0;
1125 } 1102 }
1126 1103
1104 /*
1105 * Indicate that the device is going down. Scheduling the queue
1106 * tasklets is forbidden from here on.
1107 */
1108 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
1109
1127 tiqdio_remove_input_queues(irq_ptr); 1110 tiqdio_remove_input_queues(irq_ptr);
1128 qdio_shutdown_queues(cdev); 1111 qdio_shutdown_queues(cdev);
1129 qdio_shutdown_debug_entries(irq_ptr, cdev); 1112 qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1403,9 +1386,8 @@ int qdio_activate(struct ccw_device *cdev)
1403 switch (irq_ptr->state) { 1386 switch (irq_ptr->state) {
1404 case QDIO_IRQ_STATE_STOPPED: 1387 case QDIO_IRQ_STATE_STOPPED:
1405 case QDIO_IRQ_STATE_ERR: 1388 case QDIO_IRQ_STATE_ERR:
1406 mutex_unlock(&irq_ptr->setup_mutex); 1389 rc = -EIO;
1407 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); 1390 break;
1408 return -EIO;
1409 default: 1391 default:
1410 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE); 1392 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
1411 rc = 0; 1393 rc = 0;
@@ -1442,10 +1424,10 @@ static inline int buf_in_between(int bufnr, int start, int count)
1442 * @bufnr: first buffer to process 1424 * @bufnr: first buffer to process
1443 * @count: how many buffers are emptied 1425 * @count: how many buffers are emptied
1444 */ 1426 */
1445static void handle_inbound(struct qdio_q *q, unsigned int callflags, 1427static int handle_inbound(struct qdio_q *q, unsigned int callflags,
1446 int bufnr, int count) 1428 int bufnr, int count)
1447{ 1429{
1448 int used, cc, diff; 1430 int used, diff;
1449 1431
1450 if (!q->u.in.polling) 1432 if (!q->u.in.polling)
1451 goto set; 1433 goto set;
@@ -1456,19 +1438,18 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
1456 q->u.in.polling = 0; 1438 q->u.in.polling = 0;
1457 q->u.in.ack_count = 0; 1439 q->u.in.ack_count = 0;
1458 goto set; 1440 goto set;
1459 } else if (buf_in_between(q->last_move_ftc, bufnr, count)) { 1441 } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
1460 if (is_qebsm(q)) { 1442 if (is_qebsm(q)) {
1461 /* partial overwrite, just update last_move_ftc */ 1443 /* partial overwrite, just update ack_start */
1462 diff = add_buf(bufnr, count); 1444 diff = add_buf(bufnr, count);
1463 diff = sub_buf(diff, q->last_move_ftc); 1445 diff = sub_buf(diff, q->u.in.ack_start);
1464 q->u.in.ack_count -= diff; 1446 q->u.in.ack_count -= diff;
1465 if (q->u.in.ack_count <= 0) { 1447 if (q->u.in.ack_count <= 0) {
1466 q->u.in.polling = 0; 1448 q->u.in.polling = 0;
1467 q->u.in.ack_count = 0; 1449 q->u.in.ack_count = 0;
1468 /* TODO: must we set last_move_ftc to something meaningful? */
1469 goto set; 1450 goto set;
1470 } 1451 }
1471 q->last_move_ftc = add_buf(q->last_move_ftc, diff); 1452 q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
1472 } 1453 }
1473 else 1454 else
1474 /* the only ACK will be deleted, so stop polling */ 1455 /* the only ACK will be deleted, so stop polling */
@@ -1483,13 +1464,11 @@ set:
1483 1464
1484 /* no need to signal as long as the adapter had free buffers */ 1465 /* no need to signal as long as the adapter had free buffers */
1485 if (used) 1466 if (used)
1486 return; 1467 return 0;
1487 1468
1488 if (need_siga_in(q)) { 1469 if (need_siga_in(q))
1489 cc = qdio_siga_input(q); 1470 return qdio_siga_input(q);
1490 if (cc) 1471 return 0;
1491 q->qdio_error = cc;
1492 }
1493} 1472}
1494 1473
1495/** 1474/**
@@ -1499,11 +1478,11 @@ set:
1499 * @bufnr: first buffer to process 1478 * @bufnr: first buffer to process
1500 * @count: how many buffers are filled 1479 * @count: how many buffers are filled
1501 */ 1480 */
1502static void handle_outbound(struct qdio_q *q, unsigned int callflags, 1481static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1503 int bufnr, int count) 1482 int bufnr, int count)
1504{ 1483{
1505 unsigned char state; 1484 unsigned char state;
1506 int used; 1485 int used, rc = 0;
1507 1486
1508 qdio_perf_stat_inc(&perf_stats.outbound_handler); 1487 qdio_perf_stat_inc(&perf_stats.outbound_handler);
1509 1488
@@ -1518,27 +1497,26 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
1518 1497
1519 if (queue_type(q) == QDIO_IQDIO_QFMT) { 1498 if (queue_type(q) == QDIO_IQDIO_QFMT) {
1520 if (multicast_outbound(q)) 1499 if (multicast_outbound(q))
1521 qdio_kick_outbound_q(q); 1500 rc = qdio_kick_outbound_q(q);
1522 else 1501 else
1523 if ((q->irq_ptr->ssqd_desc.mmwc > 1) && 1502 if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
1524 (count > 1) && 1503 (count > 1) &&
1525 (count <= q->irq_ptr->ssqd_desc.mmwc)) { 1504 (count <= q->irq_ptr->ssqd_desc.mmwc)) {
1526 /* exploit enhanced SIGA */ 1505 /* exploit enhanced SIGA */
1527 q->u.out.use_enh_siga = 1; 1506 q->u.out.use_enh_siga = 1;
1528 qdio_kick_outbound_q(q); 1507 rc = qdio_kick_outbound_q(q);
1529 } else { 1508 } else {
1530 /* 1509 /*
1531 * One siga-w per buffer required for unicast 1510 * One siga-w per buffer required for unicast
1532 * HiperSockets. 1511 * HiperSockets.
1533 */ 1512 */
1534 q->u.out.use_enh_siga = 0; 1513 q->u.out.use_enh_siga = 0;
1535 while (count--) 1514 while (count--) {
1536 qdio_kick_outbound_q(q); 1515 rc = qdio_kick_outbound_q(q);
1516 if (rc)
1517 goto out;
1518 }
1537 } 1519 }
1538
1539 /* report CC=2 conditions synchronously */
1540 if (q->qdio_error)
1541 __qdio_outbound_processing(q);
1542 goto out; 1520 goto out;
1543 } 1521 }
1544 1522
@@ -1550,14 +1528,14 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
1550 /* try to fast requeue buffers */ 1528 /* try to fast requeue buffers */
1551 get_buf_state(q, prev_buf(bufnr), &state, 0); 1529 get_buf_state(q, prev_buf(bufnr), &state, 0);
1552 if (state != SLSB_CU_OUTPUT_PRIMED) 1530 if (state != SLSB_CU_OUTPUT_PRIMED)
1553 qdio_kick_outbound_q(q); 1531 rc = qdio_kick_outbound_q(q);
1554 else { 1532 else {
1555 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req"); 1533 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req");
1556 qdio_perf_stat_inc(&perf_stats.fast_requeue); 1534 qdio_perf_stat_inc(&perf_stats.fast_requeue);
1557 } 1535 }
1558out: 1536out:
1559 /* Fixme: could wait forever if called from process context */
1560 tasklet_schedule(&q->tasklet); 1537 tasklet_schedule(&q->tasklet);
1538 return rc;
1561} 1539}
1562 1540
1563/** 1541/**
@@ -1596,14 +1574,12 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1596 return -EBUSY; 1574 return -EBUSY;
1597 1575
1598 if (callflags & QDIO_FLAG_SYNC_INPUT) 1576 if (callflags & QDIO_FLAG_SYNC_INPUT)
1599 handle_inbound(irq_ptr->input_qs[q_nr], callflags, bufnr, 1577 return handle_inbound(irq_ptr->input_qs[q_nr],
1600 count); 1578 callflags, bufnr, count);
1601 else if (callflags & QDIO_FLAG_SYNC_OUTPUT) 1579 else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
1602 handle_outbound(irq_ptr->output_qs[q_nr], callflags, bufnr, 1580 return handle_outbound(irq_ptr->output_qs[q_nr],
1603 count); 1581 callflags, bufnr, count);
1604 else 1582 return -EINVAL;
1605 return -EINVAL;
1606 return 0;
1607} 1583}
1608EXPORT_SYMBOL_GPL(do_QDIO); 1584EXPORT_SYMBOL_GPL(do_QDIO);
1609 1585