* @no_output_qs: number of output queues
  * @input_handler: handler to be called for input queues
  * @output_handler: handler to be called for output queues
- * @queue_start_poll_array: polling handlers (one per input queue or NULL)
+ * @irq_poll: Data IRQ polling handler (NULL when not supported)
  * @scan_threshold: # of in-use buffers that triggers scan on output queue
  * @int_parm: interruption parameter
  * @input_sbal_addr_array:  address of no_input_qs * 128 pointers
        unsigned int no_output_qs;
        qdio_handler_t *input_handler;
        qdio_handler_t *output_handler;
-       void (**queue_start_poll_array) (struct ccw_device *, int,
-                                         unsigned long);
+       void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
        unsigned int scan_threshold;
        unsigned long int_parm;
        struct qdio_buffer **input_sbal_addr_array;
 extern void qdio_release_aob(struct qaob *);
 extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
                   unsigned int);
-extern int qdio_start_irq(struct ccw_device *, int);
-extern int qdio_stop_irq(struct ccw_device *, int);
+extern int qdio_start_irq(struct ccw_device *cdev);
+extern int qdio_stop_irq(struct ccw_device *cdev);
 extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
 extern int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr,
                              bool is_input, unsigned int *bufnr,
 
        unsigned int nr_sbal_total;
 };
 
-enum qdio_queue_irq_states {
-       QDIO_QUEUE_IRQS_DISABLED,
+enum qdio_irq_poll_states {
+       QDIO_IRQ_DISABLED,
 };
 
 struct qdio_input_q {
        int ack_count;
        /* last time of noticing incoming data */
        u64 timestamp;
-       /* upper-layer polling flag */
-       unsigned long queue_irq_state;
-       /* callback to start upper-layer polling */
-       void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
 };
 
 struct qdio_output_q {
        struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
        struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
 
+       void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
+       unsigned long poll_state;
+
        debug_info_t *debug_area;
        struct mutex setup_mutex;
        struct qdio_dev_perf_stat perf_stat;
 
                           q->u.in.ack_start, q->u.in.ack_count);
                seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
                           *(u8 *)q->irq_ptr->dsci,
-                          test_bit(QDIO_QUEUE_IRQS_DISABLED,
-                          &q->u.in.queue_irq_state));
+                          test_bit(QDIO_IRQ_DISABLED,
+                                   &q->irq_ptr->poll_state));
        }
        seq_printf(m, "SBAL states:\n");
        seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
 
        if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
                return;
 
-       for_each_input_queue(irq_ptr, q, i) {
-               if (q->u.in.queue_start_poll) {
-                       /* skip if polling is enabled or already in work */
-                       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                                    &q->u.in.queue_irq_state)) {
-                               QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
-                               continue;
-                       }
-                       q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
-                                                q->irq_ptr->int_parm);
-               } else {
+       if (irq_ptr->irq_poll) {
+               if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
+                       irq_ptr->irq_poll(irq_ptr->cdev, irq_ptr->int_parm);
+               else
+                       QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
+       } else {
+               for_each_input_queue(irq_ptr, q, i)
                        tasklet_schedule(&q->tasklet);
-               }
        }
 
        if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold)
 /**
  * qdio_start_irq - process input buffers
  * @cdev: associated ccw_device for the qdio subchannel
- * @nr: input queue number
  *
  * Return codes
  *   0 - success
  *   1 - irqs not started since new data is available
  */
-int qdio_start_irq(struct ccw_device *cdev, int nr)
+int qdio_start_irq(struct ccw_device *cdev)
 {
        struct qdio_q *q;
        struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+       unsigned int i;
 
        if (!irq_ptr)
                return -ENODEV;
-       q = irq_ptr->input_qs[nr];
 
        clear_nonshared_ind(irq_ptr);
-       qdio_stop_polling(q);
-       clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
+
+       for_each_input_queue(irq_ptr, q, i)
+               qdio_stop_polling(q);
+
+       clear_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
 
        /*
         * We need to check again to not lose initiative after
         */
        if (test_nonshared_ind(irq_ptr))
                goto rescan;
-       if (!qdio_inbound_q_done(q, q->first_to_check))
-               goto rescan;
+
+       for_each_input_queue(irq_ptr, q, i) {
+               if (!qdio_inbound_q_done(q, q->first_to_check))
+                       goto rescan;
+       }
+
        return 0;
 
 rescan:
-       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                            &q->u.in.queue_irq_state))
+       if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
                return 0;
        else
                return 1;
 /**
  * qdio_stop_irq - disable interrupt processing for the device
  * @cdev: associated ccw_device for the qdio subchannel
- * @nr: input queue number
  *
  * Return codes
  *   0 - interrupts were already disabled
  *   1 - interrupts successfully disabled
  */
-int qdio_stop_irq(struct ccw_device *cdev, int nr)
+int qdio_stop_irq(struct ccw_device *cdev)
 {
-       struct qdio_q *q;
        struct qdio_irq *irq_ptr = cdev->private->qdio_data;
 
        if (!irq_ptr)
                return -ENODEV;
-       q = irq_ptr->input_qs[nr];
 
-       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                            &q->u.in.queue_irq_state))
+       if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
                return 0;
        else
                return 1;
 
                setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
 
                q->is_input_q = 1;
-               if (qdio_init->queue_start_poll_array &&
-                   qdio_init->queue_start_poll_array[i]) {
-                       q->u.in.queue_start_poll =
-                               qdio_init->queue_start_poll_array[i];
-                       set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                               &q->u.in.queue_irq_state);
-               } else {
-                       q->u.in.queue_start_poll = NULL;
-               }
 
                setup_storage_lists(q, irq_ptr, input_sbal_array, i);
                input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
        ccw_device_get_schid(irq_ptr->cdev, &irq_ptr->schid);
        setup_queues(irq_ptr, init_data);
 
+       if (init_data->irq_poll) {
+               irq_ptr->irq_poll = init_data->irq_poll;
+               set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
+       } else {
+               irq_ptr->irq_poll = NULL;
+       }
+
        setup_qib(irq_ptr, init_data);
        qdio_setup_thinint(irq_ptr);
        set_impl_params(irq_ptr, init_data->qib_param_field_format,
 
            has_multiple_inq_on_dsci(irq))
                xchg(irq->dsci, 0);
 
+       if (irq->irq_poll) {
+               if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq->poll_state))
+                       irq->irq_poll(irq->cdev, irq->int_parm);
+               else
+                       QDIO_PERF_STAT_INC(irq, int_discarded);
+
+               return;
+       }
+
        for_each_input_queue(irq, q, i) {
-               if (q->u.in.queue_start_poll) {
-                       /* skip if polling is enabled or already in work */
-                       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                                            &q->u.in.queue_irq_state)) {
-                               QDIO_PERF_STAT_INC(irq, int_discarded);
-                               continue;
-                       }
-
-                       /* avoid dsci clear here, done after processing */
-                       q->u.in.queue_start_poll(irq->cdev, q->nr,
-                                                irq->int_parm);
-               } else {
-                       if (!shared_ind(irq))
-                               xchg(irq->dsci, 0);
-
-                       /*
-                        * Call inbound processing but not directly
-                        * since that could starve other thinint queues.
-                        */
-                       tasklet_schedule(&q->tasklet);
-               }
+               if (!shared_ind(irq))
+                       xchg(irq->dsci, 0);
+
+               /*
+                * Call inbound processing but not directly
+                * since that could starve other thinint queues.
+                */
+               tasklet_schedule(&q->tasklet);
        }
 }
 
 
        qdio_release_aob(aob);
 }
 
-static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue)
-{
-       return card->options.cq == QETH_CQ_ENABLED &&
-           card->qdio.c_q != NULL &&
-           queue != 0 &&
-           queue == card->qdio.no_in_queues - 1;
-}
-
 static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len,
                           void *data)
 {
        }
 }
 
-static void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
-                                unsigned long card_ptr)
+static void qeth_qdio_poll(struct ccw_device *cdev, unsigned long card_ptr)
 {
        struct qeth_card *card = (struct qeth_card *)card_ptr;
 
        int i;
        int rc;
 
-       if (!qeth_is_cq(card, queue))
-               return;
-
        QETH_CARD_TEXT_(card, 5, "qcqhe%d", first_element);
        QETH_CARD_TEXT_(card, 5, "qcqhc%d", count);
        QETH_CARD_TEXT_(card, 5, "qcqherr%d", qdio_err);
        QETH_CARD_TEXT_(card, 2, "qihq%d", queue);
        QETH_CARD_TEXT_(card, 2, "qiec%d", qdio_err);
 
-       if (qeth_is_cq(card, queue))
-               qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
-       else if (qdio_err)
+       if (qdio_err)
                qeth_schedule_recovery(card);
 }
 
 }
 
 static void qeth_qdio_establish_cq(struct qeth_card *card,
-                                  struct qdio_buffer **in_sbal_ptrs,
-                                  void (**queue_start_poll)
-                                       (struct ccw_device *, int,
-                                        unsigned long))
+                                  struct qdio_buffer **in_sbal_ptrs)
 {
        int i;
 
                for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++)
                        in_sbal_ptrs[offset + i] =
                                card->qdio.c_q->bufs[i].buffer;
-
-               queue_start_poll[card->qdio.no_in_queues - 1] = NULL;
        }
 }
 
        struct qdio_initialize init_data;
        char *qib_param_field;
        struct qdio_buffer **in_sbal_ptrs;
-       void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
        struct qdio_buffer **out_sbal_ptrs;
        int i, j, k;
        int rc = 0;
        for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++)
                in_sbal_ptrs[i] = card->qdio.in_q->bufs[i].buffer;
 
-       queue_start_poll = kcalloc(card->qdio.no_in_queues, sizeof(void *),
-                                  GFP_KERNEL);
-       if (!queue_start_poll) {
-               rc = -ENOMEM;
-               goto out_free_in_sbals;
-       }
-       for (i = 0; i < card->qdio.no_in_queues; ++i)
-               queue_start_poll[i] = qeth_qdio_start_poll;
-
-       qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
+       qeth_qdio_establish_cq(card, in_sbal_ptrs);
 
        out_sbal_ptrs =
                kcalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q,
                        GFP_KERNEL);
        if (!out_sbal_ptrs) {
                rc = -ENOMEM;
-               goto out_free_queue_start_poll;
+               goto out_free_in_sbals;
        }
 
        for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
        init_data.no_output_qs           = card->qdio.no_out_queues;
        init_data.input_handler          = qeth_qdio_input_handler;
        init_data.output_handler         = qeth_qdio_output_handler;
-       init_data.queue_start_poll_array = queue_start_poll;
+       init_data.irq_poll               = qeth_qdio_poll;
        init_data.int_parm               = (unsigned long) card;
        init_data.input_sbal_addr_array  = in_sbal_ptrs;
        init_data.output_sbal_addr_array = out_sbal_ptrs;
        }
 out:
        kfree(out_sbal_ptrs);
-out_free_queue_start_poll:
-       kfree(queue_start_poll);
 out_free_in_sbals:
        kfree(in_sbal_ptrs);
 out_free_qib_param:
        return work_done;
 }
 
+static void qeth_cq_poll(struct qeth_card *card)
+{
+       unsigned int work_done = 0;
+
+       while (work_done < QDIO_MAX_BUFFERS_PER_Q) {
+               unsigned int start, error;
+               int completed;
+
+               completed = qdio_inspect_queue(CARD_DDEV(card), 1, true, &start,
+                                              &error);
+               if (completed <= 0)
+                       return;
+
+               qeth_qdio_cq_handler(card, error, 1, start, completed);
+               work_done += completed;
+       }
+}
+
 int qeth_poll(struct napi_struct *napi, int budget)
 {
        struct qeth_card *card = container_of(napi, struct qeth_card, napi);
 
        work_done = qeth_rx_poll(card, budget);
 
+       if (card->options.cq == QETH_CQ_ENABLED)
+               qeth_cq_poll(card);
+
        /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */
        if (budget && work_done >= budget)
                return work_done;
 
        if (napi_complete_done(napi, work_done) &&
-           qdio_start_irq(CARD_DDEV(card), 0))
+           qdio_start_irq(CARD_DDEV(card)))
                napi_schedule(napi);
 
        return work_done;
        }
 
        napi_disable(&card->napi);
-       qdio_stop_irq(CARD_DDEV(card), 0);
+       qdio_stop_irq(CARD_DDEV(card));
 
        return 0;
 }