diff options
Diffstat (limited to 'drivers/s390/cio/qdio.h')
| -rw-r--r-- | drivers/s390/cio/qdio.h | 131 | 
1 files changed, 45 insertions, 86 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 0f4ef8769a3..a563e4c0059 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -1,7 +1,5 @@  /* - * linux/drivers/s390/cio/qdio.h - * - * Copyright 2000,2009 IBM Corp. + * Copyright IBM Corp. 2000, 2009   * Author(s): Utz Bacher <utz.bacher@de.ibm.com>   *	      Jan Glauber <jang@linux.vnet.ibm.com>   */ @@ -14,16 +12,10 @@  #include "chsc.h"  #define QDIO_BUSY_BIT_PATIENCE		(100 << 12)	/* 100 microseconds */ +#define QDIO_BUSY_BIT_RETRY_DELAY	10		/* 10 milliseconds */ +#define QDIO_BUSY_BIT_RETRIES		1000		/* = 10s retry time */  #define QDIO_INPUT_THRESHOLD		(500 << 12)	/* 500 microseconds */ -/* - * if an asynchronous HiperSockets queue runs full, the 10 seconds timer wait - * till next initiative to give transmitted skbs back to the stack is too long. - * Therefore polling is started in case of multicast queue is filled more - * than 50 percent. - */ -#define QDIO_IQDIO_POLL_LVL		65	/* HS multicast queue */ -  enum qdio_irq_states {  	QDIO_IRQ_STATE_INACTIVE,  	QDIO_IRQ_STATE_ESTABLISHED, @@ -42,6 +34,7 @@ enum qdio_irq_states {  #define SLSB_STATE_NOT_INIT	0x0  #define SLSB_STATE_EMPTY	0x1  #define SLSB_STATE_PRIMED	0x2 +#define SLSB_STATE_PENDING	0x3  #define SLSB_STATE_HALTED	0xe  #define SLSB_STATE_ERROR	0xf  #define SLSB_TYPE_INPUT		0x0 @@ -65,6 +58,8 @@ enum qdio_irq_states {  	(SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */  #define SLSB_P_OUTPUT_EMPTY	\  	(SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY)	   /* 0xa1 */ +#define SLSB_P_OUTPUT_PENDING \ +	(SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_PENDING)  /* 0xa3 */  #define SLSB_CU_OUTPUT_PRIMED	\  	(SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED)	   /* 0x62 */  #define SLSB_P_OUTPUT_HALTED	\ @@ -82,14 +77,12 @@ enum qdio_irq_states {  #define CHSC_FLAG_QDIO_CAPABILITY	0x80  #define CHSC_FLAG_VALIDITY		0x40 -/* qdio adapter-characteristics-1 flag */ -#define AC1_SIGA_INPUT_NEEDED		0x40	/* process input queues */ -#define AC1_SIGA_OUTPUT_NEEDED		0x20	/* process output queues */ -#define AC1_SIGA_SYNC_NEEDED		0x10	/* ask hypervisor to sync */ -#define AC1_AUTOMATIC_SYNC_ON_THININT	0x08	/* set by hypervisor */ -#define AC1_AUTOMATIC_SYNC_ON_OUT_PCI	0x04	/* set by hypervisor */ -#define AC1_SC_QEBSM_AVAILABLE		0x02	/* available for subchannel */ -#define AC1_SC_QEBSM_ENABLED		0x01	/* enabled for subchannel */ +/* SIGA flags */ +#define QDIO_SIGA_WRITE		0x00 +#define QDIO_SIGA_READ		0x01 +#define QDIO_SIGA_SYNC		0x02 +#define QDIO_SIGA_WRITEQ	0x04 +#define QDIO_SIGA_QEBSM_FLAG	0x80  #ifdef CONFIG_64BIT  static inline int do_sqbs(u64 token, unsigned char state, int queue, @@ -142,44 +135,9 @@ struct siga_flag {  	u8 input:1;  	u8 output:1;  	u8 sync:1; -	u8 no_sync_ti:1; -	u8 no_sync_out_ti:1; -	u8 no_sync_out_pci:1; -	u8:2; -} __attribute__ ((packed)); - -struct chsc_ssqd_area { -	struct chsc_header request; -	u16:10; -	u8 ssid:2; -	u8 fmt:4; -	u16 first_sch; -	u16:16; -	u16 last_sch; -	u32:32; -	struct chsc_header response; -	u32:32; -	struct qdio_ssqd_desc qdio_ssqd; -} __attribute__ ((packed)); - -struct scssc_area { -	struct chsc_header request; -	u16 operation_code; -	u16:16; -	u32:32; -	u32:32; -	u64 summary_indicator_addr; -	u64 subchannel_indicator_addr; -	u32 ks:4; -	u32 kc:4; -	u32:21; -	u32 isc:3; -	u32 word_with_d_bit; -	u32:32; -	struct subchannel_id schid; -	u32 reserved[1004]; -	struct chsc_header response; -	u32:32; +	u8 sync_after_ai:1; +	u8 sync_out_after_pci:1; +	u8:3;  } __attribute__ ((packed));  struct qdio_dev_perf_stat { @@ -202,6 +160,7 @@ struct qdio_dev_perf_stat {  	unsigned int inbound_queue_full;  	unsigned int outbound_call;  	unsigned int outbound_handler; +	unsigned int outbound_queue_full;  	unsigned int fast_requeue;  	unsigned int target_full;  	unsigned int eqbs; @@ -245,10 +204,16 @@ struct qdio_input_q {  struct qdio_output_q {  	/* PCIs are enabled for the queue */  	int pci_out_enabled; -	/* IQDIO: output multiple buffers (enhanced SIGA) */ -	int use_enh_siga; +	/* cq: use asynchronous output buffers */ +	int use_cq; +	/* cq: aobs used for particual SBAL */ +	struct qaob **aobs; +	/* cq: sbal state related to asynchronous operation */ +	struct qdio_outbuf_state *sbal_state;  	/* timer to check for more outbound work */  	struct timer_list timer; +	/* used SBALs before tasklet schedule */ +	int scan_threshold;  };  /* @@ -281,6 +246,9 @@ struct qdio_q {  	/* error condition during a data transfer */  	unsigned int qdio_error; +	/* last scan of the queue */ +	u64 timestamp; +  	struct tasklet_struct tasklet;  	struct qdio_queue_perf_stat q_stats; @@ -383,21 +351,20 @@ static inline int multicast_outbound(struct qdio_q *q)  	(q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)  #define is_qebsm(q)			(q->irq_ptr->sch_token != 0) -#define need_siga_sync_thinint(q)	(!q->irq_ptr->siga_flag.no_sync_ti) -#define need_siga_sync_out_thinint(q)	(!q->irq_ptr->siga_flag.no_sync_out_ti)  #define need_siga_in(q)			(q->irq_ptr->siga_flag.input)  #define need_siga_out(q)		(q->irq_ptr->siga_flag.output) -#define need_siga_sync(q)		(q->irq_ptr->siga_flag.sync) -#define siga_syncs_out_pci(q)		(q->irq_ptr->siga_flag.no_sync_out_pci) - -#define for_each_input_queue(irq_ptr, q, i)	\ -	for (i = 0, q = irq_ptr->input_qs[0];	\ -		i < irq_ptr->nr_input_qs;	\ -		q = irq_ptr->input_qs[++i]) -#define for_each_output_queue(irq_ptr, q, i)	\ -	for (i = 0, q = irq_ptr->output_qs[0];	\ -		i < irq_ptr->nr_output_qs;	\ -		q = irq_ptr->output_qs[++i]) +#define need_siga_sync(q)		(unlikely(q->irq_ptr->siga_flag.sync)) +#define need_siga_sync_after_ai(q)	\ +	(unlikely(q->irq_ptr->siga_flag.sync_after_ai)) +#define need_siga_sync_out_after_pci(q)	\ +	(unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) + +#define for_each_input_queue(irq_ptr, q, i)		\ +	for (i = 0; i < irq_ptr->nr_input_qs &&		\ +		({ q = irq_ptr->input_qs[i]; 1; }); i++) +#define for_each_output_queue(irq_ptr, q, i)		\ +	for (i = 0; i < irq_ptr->nr_output_qs &&	\ +		({ q = irq_ptr->output_qs[i]; 1; }); i++)  #define prev_buf(bufnr)	\  	((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) @@ -413,20 +380,7 @@ static inline int multicast_outbound(struct qdio_q *q)  #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; -} +extern u64 last_ai_time;  /* prototypes for thin interrupt */  void qdio_setup_thinint(struct qdio_irq *irq_ptr); @@ -439,6 +393,8 @@ int tiqdio_allocate_memory(void);  void tiqdio_free_memory(void);  int tiqdio_register_thinints(void);  void tiqdio_unregister_thinints(void); +void clear_nonshared_ind(struct qdio_irq *); +int test_nonshared_ind(struct qdio_irq *);  /* prototypes for setup */  void qdio_inbound_processing(unsigned long data); @@ -460,6 +416,9 @@ int qdio_setup_create_sysfs(struct ccw_device *cdev);  void qdio_setup_destroy_sysfs(struct ccw_device *cdev);  int qdio_setup_init(void);  void qdio_setup_exit(void); +int qdio_enable_async_operation(struct qdio_output_q *q); +void qdio_disable_async_operation(struct qdio_output_q *q); +struct qaob *qdio_allocate_aob(void);  int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,  			unsigned char *state);  | 
