aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.h
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2008-12-25 07:38:47 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-12-25 07:38:59 -0500
commit50f769df1c4bea766c4eb927eae35728fb93e305 (patch)
treec86228e6965de0ea84bddc2104d7dfa339e2a187 /drivers/s390/cio/qdio.h
parent22f9934767f49012ffbae753b28b8055bd28348f (diff)
[S390] qdio: improve inbound buffer acknowledgement
- Use automatic acknowledgement of incoming buffers in QEBSM mode - Move ACK for non-QEBSM mode always to the newest buffer to prevent a race with qdio_stop_polling - Remove the polling spinlock, the upper layer drivers return new buffers in the same code path and could not run in parallel - Don't flood the error log in case of no-target-buffer-empty - In handle_inbound we check if we would overwrite an ACK'ed buffer, if so advance the pointer to the oldest ACK'ed buffer so we don't overwrite an empty buffer in qdio_stop_polling Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r--drivers/s390/cio/qdio.h19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 7b50882577d5..c60f2566d28c 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -112,12 +112,12 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue,
112} 112}
113 113
114static inline int do_eqbs(u64 token, unsigned char *state, int queue, 114static inline int do_eqbs(u64 token, unsigned char *state, int queue,
115 int *start, int *count) 115 int *start, int *count, int ack)
116{ 116{
117 register unsigned long _ccq asm ("0") = *count; 117 register unsigned long _ccq asm ("0") = *count;
118 register unsigned long _token asm ("1") = token; 118 register unsigned long _token asm ("1") = token;
119 unsigned long _queuestart = ((unsigned long)queue << 32) | *start; 119 unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
120 unsigned long _state = 0; 120 unsigned long _state = (unsigned long)ack << 63;
121 121
122 asm volatile( 122 asm volatile(
123 " .insn rrf,0xB99c0000,%1,%2,0,0" 123 " .insn rrf,0xB99c0000,%1,%2,0,0"
@@ -134,7 +134,7 @@ static inline int do_eqbs(u64 token, unsigned char *state, int queue,
134static inline int do_sqbs(u64 token, unsigned char state, int queue, 134static inline int do_sqbs(u64 token, unsigned char state, int queue,
135 int *start, int *count) { return 0; } 135 int *start, int *count) { return 0; }
136static inline int do_eqbs(u64 token, unsigned char *state, int queue, 136static inline int do_eqbs(u64 token, unsigned char *state, int queue,
137 int *start, int *count) { return 0; } 137 int *start, int *count, int ack) { return 0; }
138#endif /* CONFIG_64BIT */ 138#endif /* CONFIG_64BIT */
139 139
140struct qdio_irq; 140struct qdio_irq;
@@ -187,11 +187,11 @@ struct qdio_input_q {
187 /* input buffer acknowledgement flag */ 187 /* input buffer acknowledgement flag */
188 int polling; 188 int polling;
189 189
190 /* how much sbals are acknowledged with qebsm */
191 int ack_count;
192
190 /* last time of noticing incoming data */ 193 /* last time of noticing incoming data */
191 u64 timestamp; 194 u64 timestamp;
192
193 /* lock for clearing the acknowledgement */
194 spinlock_t lock;
195}; 195};
196 196
197struct qdio_output_q { 197struct qdio_output_q {
@@ -351,10 +351,13 @@ static inline unsigned long long get_usecs(void)
351 ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK) 351 ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK)
352#define add_buf(bufnr, inc) \ 352#define add_buf(bufnr, inc) \
353 ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK) 353 ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK)
354#define sub_buf(bufnr, dec) \
355 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
354 356
355/* prototypes for thin interrupt */ 357/* prototypes for thin interrupt */
356void qdio_sync_after_thinint(struct qdio_q *q); 358void qdio_sync_after_thinint(struct qdio_q *q);
357int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state); 359int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
360 int auto_ack);
358void qdio_check_outbound_after_thinint(struct qdio_q *q); 361void qdio_check_outbound_after_thinint(struct qdio_q *q);
359int qdio_inbound_q_moved(struct qdio_q *q); 362int qdio_inbound_q_moved(struct qdio_q *q);
360void qdio_kick_inbound_handler(struct qdio_q *q); 363void qdio_kick_inbound_handler(struct qdio_q *q);
@@ -388,6 +391,8 @@ int qdio_setup_irq(struct qdio_initialize *init_data);
388void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, 391void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
389 struct ccw_device *cdev); 392 struct ccw_device *cdev);
390void qdio_release_memory(struct qdio_irq *irq_ptr); 393void qdio_release_memory(struct qdio_irq *irq_ptr);
394int qdio_setup_create_sysfs(struct ccw_device *cdev);
395void qdio_setup_destroy_sysfs(struct ccw_device *cdev);
391int qdio_setup_init(void); 396int qdio_setup_init(void);
392void qdio_setup_exit(void); 397void qdio_setup_exit(void);
393 398