qdio: extend API to allow polling
Extend the qdio API to allow polling in the upper-layer driver. This is needed by qeth to use NAPI. To use the new interface the upper-layer driver must specify the queue_start_poll(). This callback is used to signal the upper-layer driver that is has initiative and must process the inbound queue by calling qdio_get_next_buffers(). If the upper-layer driver wants to stop polling it calls qdio_start_irq(). Since adapter interrupts are not completely stoppable qdio implements a software bit QDIO_QUEUE_IRQS_DISABLED to safely disable interrupts for an input queue. The old interface is preserved and will be used as is by zfcp. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
e508be174a
commit
d36deae750
@@ -208,6 +208,7 @@ struct qdio_dev_perf_stat {
|
||||
unsigned int eqbs_partial;
|
||||
unsigned int sqbs;
|
||||
unsigned int sqbs_partial;
|
||||
unsigned int int_discarded;
|
||||
} ____cacheline_aligned;
|
||||
|
||||
struct qdio_queue_perf_stat {
|
||||
@@ -222,6 +223,10 @@ struct qdio_queue_perf_stat {
|
||||
unsigned int nr_sbal_total;
|
||||
};
|
||||
|
||||
enum qdio_queue_irq_states {
|
||||
QDIO_QUEUE_IRQS_DISABLED,
|
||||
};
|
||||
|
||||
struct qdio_input_q {
|
||||
/* input buffer acknowledgement flag */
|
||||
int polling;
|
||||
@@ -231,6 +236,10 @@ 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 {
|
||||
@@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q)
|
||||
#define sub_buf(bufnr, dec) \
|
||||
((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
|
||||
|
||||
#define queue_irqs_enabled(q) \
|
||||
(test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0)
|
||||
#define queue_irqs_disabled(q) \
|
||||
(test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0)
|
||||
|
||||
#define TIQDIO_SHARED_IND 63
|
||||
|
||||
/* device state change indicators */
|
||||
struct indicator_t {
|
||||
u32 ind; /* u32 because of compare-and-swap performance */
|
||||
atomic_t count; /* use count, 0 or 1 for non-shared indicators */
|
||||
};
|
||||
|
||||
extern struct indicator_t *q_indicators;
|
||||
|
||||
static inline int shared_ind(struct qdio_irq *irq_ptr)
|
||||
{
|
||||
return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
|
||||
}
|
||||
|
||||
/* prototypes for thin interrupt */
|
||||
void qdio_setup_thinint(struct qdio_irq *irq_ptr);
|
||||
int qdio_establish_thinint(struct qdio_irq *irq_ptr);
|
||||
|
Reference in New Issue
Block a user