2005-04-16 15:20:36 -07:00
/*
2006-10-03 23:01:26 +02:00
* linux / include / asm - s390 / qdio . h
2005-04-16 15:20:36 -07:00
*
2008-07-17 17:16:48 +02:00
* Copyright 2000 , 2008 IBM Corp .
2005-04-16 15:20:36 -07:00
* Author ( s ) : Utz Bacher < utz . bacher @ de . ibm . com >
2008-07-17 17:16:48 +02:00
* Jan Glauber < jang @ linux . vnet . ibm . com >
2005-04-16 15:20:36 -07:00
*
*/
# ifndef __QDIO_H__
# define __QDIO_H__
# include <linux/interrupt.h>
# include <asm/cio.h>
# include <asm/ccwdev.h>
2010-02-26 22:37:37 +01:00
/* only use 4 queues to save some cachelines */
# define QDIO_MAX_QUEUES_PER_IRQ 4
2008-07-17 17:16:48 +02:00
# define QDIO_MAX_BUFFERS_PER_Q 128
# define QDIO_MAX_BUFFERS_MASK (QDIO_MAX_BUFFERS_PER_Q - 1)
# define QDIO_MAX_ELEMENTS_PER_BUFFER 16
# define QDIO_SBAL_SIZE 256
# define QDIO_QETH_QFMT 0
# define QDIO_ZFCP_QFMT 1
# define QDIO_IQDIO_QFMT 2
/**
* struct qdesfmt0 - queue descriptor , format 0
* @ sliba : storage list information block address
* @ sla : storage list address
* @ slsba : storage list state block address
* @ akey : access key for DLIB
* @ bkey : access key for SL
* @ ckey : access key for SBALs
* @ dkey : access key for SLSB
*/
2005-04-16 15:20:36 -07:00
struct qdesfmt0 {
2008-07-17 17:16:48 +02:00
u64 sliba ;
u64 sla ;
u64 slsba ;
u32 : 32 ;
u32 akey : 4 ;
u32 bkey : 4 ;
u32 ckey : 4 ;
u32 dkey : 4 ;
u32 : 16 ;
2005-04-16 15:20:36 -07:00
} __attribute__ ( ( packed ) ) ;
2011-08-15 14:40:31 +02:00
# define QDR_AC_MULTI_BUFFER_ENABLE 0x01
2008-07-17 17:16:48 +02:00
/**
* struct qdr - queue description record ( QDR )
* @ qfmt : queue format
* @ pfmt : implementation dependent parameter format
* @ ac : adapter characteristics
* @ iqdcnt : input queue descriptor count
* @ oqdcnt : output queue descriptor count
* @ iqdsz : inpout queue descriptor size
* @ oqdsz : output queue descriptor size
* @ qiba : queue information block address
* @ qkey : queue information block key
* @ qdf0 : queue descriptions
2005-04-16 15:20:36 -07:00
*/
struct qdr {
2008-07-17 17:16:48 +02:00
u32 qfmt : 8 ;
u32 pfmt : 8 ;
u32 : 8 ;
u32 ac : 8 ;
u32 : 8 ;
u32 iqdcnt : 8 ;
u32 : 8 ;
u32 oqdcnt : 8 ;
u32 : 8 ;
u32 iqdsz : 8 ;
u32 : 8 ;
u32 oqdsz : 8 ;
/* private: */
u32 res [ 9 ] ;
/* public: */
u64 qiba ;
u32 : 32 ;
u32 qkey : 4 ;
u32 : 28 ;
struct qdesfmt0 qdf0 [ 126 ] ;
} __attribute__ ( ( packed , aligned ( 4096 ) ) ) ;
# define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
2006-01-06 00:19:20 -08:00
# define QIB_RFLAGS_ENABLE_QEBSM 0x80
2010-07-16 15:37:41 +02:00
# define QIB_RFLAGS_ENABLE_DATA_DIV 0x02
2006-01-06 00:19:20 -08:00
2008-07-17 17:16:48 +02:00
/**
* struct qib - queue information block ( QIB )
* @ qfmt : queue format
* @ pfmt : implementation dependent parameter format
* @ rflags : QEBSM
* @ ac : adapter characteristics
* @ isliba : absolute address of first input SLIB
* @ osliba : absolute address of first output SLIB
* @ ebcnam : adapter identifier in EBCDIC
* @ parm : implementation dependent parameters
*/
2005-04-16 15:20:36 -07:00
struct qib {
2008-07-17 17:16:48 +02:00
u32 qfmt : 8 ;
u32 pfmt : 8 ;
u32 rflags : 8 ;
u32 ac : 8 ;
u32 : 32 ;
u64 isliba ;
u64 osliba ;
u32 : 32 ;
u32 : 32 ;
u8 ebcnam [ 8 ] ;
/* private: */
u8 res [ 88 ] ;
/* public: */
u8 parm [ QDIO_MAX_BUFFERS_PER_Q ] ;
} __attribute__ ( ( packed , aligned ( 256 ) ) ) ;
/**
* struct slibe - storage list information block element ( SLIBE )
* @ parms : implementation dependent parameters
2005-04-16 15:20:36 -07:00
*/
struct slibe {
2008-07-17 17:16:48 +02:00
u64 parms ;
2005-04-16 15:20:36 -07:00
} ;
2011-08-08 01:33:55 +00:00
/**
* struct qaob - queue asynchronous operation block
* @ res0 : reserved parameters
* @ res1 : reserved parameter
* @ res2 : reserved parameter
* @ res3 : reserved parameter
* @ aorc : asynchronous operation return code
* @ flags : internal flags
* @ cbtbs : control block type
* @ sb_count : number of storage blocks
* @ sba : storage block element addresses
* @ dcount : size of storage block elements
* @ user0 : user defineable value
* @ res4 : reserved paramater
* @ user1 : user defineable value
* @ user2 : user defineable value
*/
struct qaob {
u64 res0 [ 6 ] ;
u8 res1 ;
u8 res2 ;
u8 res3 ;
u8 aorc ;
u8 flags ;
u16 cbtbs ;
u8 sb_count ;
u64 sba [ QDIO_MAX_ELEMENTS_PER_BUFFER ] ;
u16 dcount [ QDIO_MAX_ELEMENTS_PER_BUFFER ] ;
u64 user0 ;
u64 res4 [ 2 ] ;
u64 user1 ;
u64 user2 ;
} __attribute__ ( ( packed , aligned ( 256 ) ) ) ;
2008-07-17 17:16:48 +02:00
/**
* struct slib - storage list information block ( SLIB )
* @ nsliba : next SLIB address ( if any )
* @ sla : SL address
* @ slsba : SLSB address
* @ slibe : SLIB elements
2005-04-16 15:20:36 -07:00
*/
struct slib {
2008-07-17 17:16:48 +02:00
u64 nsliba ;
u64 sla ;
u64 slsba ;
/* private: */
u8 res [ 1000 ] ;
/* public: */
struct slibe slibe [ QDIO_MAX_BUFFERS_PER_Q ] ;
} __attribute__ ( ( packed , aligned ( 2048 ) ) ) ;
2011-06-06 14:14:40 +02:00
# define SBAL_EFLAGS_LAST_ENTRY 0x40
# define SBAL_EFLAGS_CONTIGUOUS 0x20
# define SBAL_EFLAGS_FIRST_FRAG 0x04
# define SBAL_EFLAGS_MIDDLE_FRAG 0x08
# define SBAL_EFLAGS_LAST_FRAG 0x0c
# define SBAL_EFLAGS_MASK 0x6f
2005-04-16 15:20:36 -07:00
2011-06-06 14:14:40 +02:00
# define SBAL_SFLAGS0_PCI_REQ 0x40
# define SBAL_SFLAGS0_DATA_CONTINUATION 0x20
2005-04-16 15:20:36 -07:00
/* Awesome OpenFCP extensions */
2011-06-06 14:14:40 +02:00
# define SBAL_SFLAGS0_TYPE_STATUS 0x00
# define SBAL_SFLAGS0_TYPE_WRITE 0x08
# define SBAL_SFLAGS0_TYPE_READ 0x10
# define SBAL_SFLAGS0_TYPE_WRITE_READ 0x18
# define SBAL_SFLAGS0_MORE_SBALS 0x04
# define SBAL_SFLAGS0_COMMAND 0x02
# define SBAL_SFLAGS0_LAST_SBAL 0x00
# define SBAL_SFLAGS0_ONLY_SBAL SBAL_SFLAGS0_COMMAND
# define SBAL_SFLAGS0_MIDDLE_SBAL SBAL_SFLAGS0_MORE_SBALS
# define SBAL_SFLAGS0_FIRST_SBAL (SBAL_SFLAGS0_MORE_SBALS | SBAL_SFLAGS0_COMMAND)
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/**
* struct qdio_buffer_element - SBAL entry
2011-06-06 14:14:40 +02:00
* @ eflags : SBAL entry flags
* @ scount : SBAL count
* @ sflags : whole SBAL flags
2008-07-17 17:16:48 +02:00
* @ length : length
* @ addr : address
*/
struct qdio_buffer_element {
2011-06-06 14:14:40 +02:00
u8 eflags ;
/* private: */
u8 res1 ;
/* public: */
u8 scount ;
u8 sflags ;
2008-07-17 17:16:48 +02:00
u32 length ;
# ifdef CONFIG_32BIT
/* private: */
2011-06-06 14:14:40 +02:00
void * res2 ;
2008-07-17 17:16:48 +02:00
/* public: */
# endif
void * addr ;
} __attribute__ ( ( packed , aligned ( 16 ) ) ) ;
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/**
* struct qdio_buffer - storage block address list ( SBAL )
* @ element : SBAL entries
2005-04-16 15:20:36 -07:00
*/
2008-07-17 17:16:48 +02:00
struct qdio_buffer {
struct qdio_buffer_element element [ QDIO_MAX_ELEMENTS_PER_BUFFER ] ;
} __attribute__ ( ( packed , aligned ( 256 ) ) ) ;
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/**
* struct sl_element - storage list entry
* @ sbal : absolute SBAL address
2005-04-16 15:20:36 -07:00
*/
struct sl_element {
2008-07-17 17:16:48 +02:00
# ifdef CONFIG_32BIT
/* private: */
unsigned long reserved ;
/* public: */
# endif
unsigned long sbal ;
2005-04-16 15:20:36 -07:00
} __attribute__ ( ( packed ) ) ;
2008-07-17 17:16:48 +02:00
/**
* struct sl - storage list ( SL )
* @ element : SL entries
*/
2005-04-16 15:20:36 -07:00
struct sl {
struct sl_element element [ QDIO_MAX_BUFFERS_PER_Q ] ;
2008-07-17 17:16:48 +02:00
} __attribute__ ( ( packed , aligned ( 1024 ) ) ) ;
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/**
* struct slsb - storage list state block ( SLSB )
* @ val : state per buffer
2005-04-16 15:20:36 -07:00
*/
2008-07-17 17:16:48 +02:00
struct slsb {
u8 val [ QDIO_MAX_BUFFERS_PER_Q ] ;
} __attribute__ ( ( packed , aligned ( 256 ) ) ) ;
2011-08-15 14:40:31 +02:00
# define CHSC_AC2_MULTI_BUFFER_AVAILABLE 0x0080
# define CHSC_AC2_MULTI_BUFFER_ENABLED 0x0040
2010-07-16 15:37:41 +02:00
# define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010
# define CHSC_AC2_DATA_DIV_ENABLED 0x0002
2011-08-08 01:33:55 +00:00
/**
* struct qdio_outbuf_state - SBAL related asynchronous operation information
* ( for communication with upper layer programs )
* ( only required for use with completion queues )
* @ flags : flags indicating state of buffer
* @ aob : pointer to QAOB used for the particular SBAL
* @ user : pointer to upper layer program ' s state information related to SBAL
* ( stored in user1 data of QAOB )
*/
struct qdio_outbuf_state {
u8 flags ;
struct qaob * aob ;
void * user ;
} ;
# define QDIO_OUTBUF_STATE_FLAG_NONE 0x00
# define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
# define CHSC_AC1_INITIATE_INPUTQ 0x80
2011-08-08 01:33:56 +00:00
/* 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 */
2011-08-08 01:33:55 +00:00
# define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010
# define CHSC_AC2_DATA_DIV_ENABLED 0x0002
# define CHSC_AC3_FORMAT2_CQ_AVAILABLE 0x8000
2008-07-17 17:16:48 +02:00
struct qdio_ssqd_desc {
u8 flags ;
u8 : 8 ;
u16 sch ;
u8 qfmt ;
u8 parm ;
u8 qdioac1 ;
u8 sch_class ;
u8 pcnt ;
u8 icnt ;
u8 : 8 ;
u8 ocnt ;
u8 : 8 ;
u8 mbccnt ;
u16 qdioac2 ;
u64 sch_token ;
2008-10-10 21:33:18 +02:00
u8 mro ;
u8 mri ;
2011-08-08 01:33:55 +00:00
u16 qdioac3 ;
2008-10-10 21:33:18 +02:00
u16 : 16 ;
u8 : 8 ;
u8 mmwc ;
2005-04-16 15:20:36 -07:00
} __attribute__ ( ( packed ) ) ;
2008-07-17 17:16:48 +02:00
/* params are: ccw_device, qdio_error, queue_number,
first element processed , number of elements processed , int_parm */
typedef void qdio_handler_t ( struct ccw_device * , unsigned int , int ,
int , int , unsigned long ) ;
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/* qdio errors reported to the upper-layer program */
2009-03-26 15:24:31 +01:00
# define QDIO_ERROR_SIGA_TARGET 0x02
2008-07-17 17:16:48 +02:00
# define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10
# define QDIO_ERROR_SIGA_BUSY 0x20
# define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
# define QDIO_ERROR_SLSB_STATE 0x80
2005-04-16 15:20:36 -07:00
2008-07-17 17:16:48 +02:00
/* for qdio_cleanup */
# define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
# define QDIO_FLAG_CLEANUP_USING_HALT 0x02
/**
* struct qdio_initialize - qdio initalization data
* @ cdev : associated ccw device
* @ q_format : queue format
* @ adapter_name : name for the adapter
* @ qib_param_field_format : format for qib_parm_field
* @ qib_param_field : pointer to 128 bytes or NULL , if no param field
2010-07-16 15:37:41 +02:00
* @ qib_rflags : rflags to set
2008-07-17 17:16:48 +02:00
* @ input_slib_elements : pointer to no_input_qs * 128 words of data or NULL
* @ output_slib_elements : pointer to no_output_qs * 128 words of data or NULL
* @ no_input_qs : number of input queues
* @ 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
2011-12-27 11:27:26 +01:00
* @ queue_start_poll_array : polling handlers ( one per input queue or NULL )
2008-07-17 17:16:48 +02:00
* @ int_parm : interruption parameter
* @ input_sbal_addr_array : address of no_input_qs * 128 pointers
* @ output_sbal_addr_array : address of no_output_qs * 128 pointers
2011-08-08 01:33:55 +00:00
* @ output_sbal_state_array : no_output_qs * 128 state info ( for CQ or NULL )
2005-04-16 15:20:36 -07:00
*/
2008-07-17 17:16:48 +02:00
struct qdio_initialize {
struct ccw_device * cdev ;
unsigned char q_format ;
2011-08-15 14:40:31 +02:00
unsigned char qdr_ac ;
2008-07-17 17:16:48 +02:00
unsigned char adapter_name [ 8 ] ;
unsigned int qib_param_field_format ;
unsigned char * qib_param_field ;
2010-07-16 15:37:41 +02:00
unsigned char qib_rflags ;
2008-07-17 17:16:48 +02:00
unsigned long * input_slib_elements ;
unsigned long * output_slib_elements ;
unsigned int no_input_qs ;
unsigned int no_output_qs ;
qdio_handler_t * input_handler ;
qdio_handler_t * output_handler ;
2011-12-27 11:27:26 +01:00
void ( * * queue_start_poll_array ) ( struct ccw_device * , int ,
unsigned long ) ;
2011-01-05 12:47:50 +01:00
int scan_threshold ;
2008-07-17 17:16:48 +02:00
unsigned long int_parm ;
void * * input_sbal_addr_array ;
void * * output_sbal_addr_array ;
2011-08-08 01:33:55 +00:00
struct qdio_outbuf_state * output_sbal_state_array ;
2008-07-17 17:16:48 +02:00
} ;
# define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */
# define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */
# define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */
# define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */
# define QDIO_FLAG_SYNC_INPUT 0x01
# define QDIO_FLAG_SYNC_OUTPUT 0x02
# define QDIO_FLAG_PCI_OUT 0x10
2008-12-25 13:38:43 +01:00
extern int qdio_allocate ( struct qdio_initialize * ) ;
extern int qdio_establish ( struct qdio_initialize * ) ;
2008-07-17 17:16:48 +02:00
extern int qdio_activate ( struct ccw_device * ) ;
2011-08-08 01:33:55 +00:00
extern void qdio_release_aob ( struct qaob * ) ;
2010-09-07 21:14:39 +00:00
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_get_next_buffers ( struct ccw_device * , int , int * , int * ) ;
extern int qdio_shutdown ( struct ccw_device * , int ) ;
2008-07-17 17:16:48 +02:00
extern int qdio_free ( struct ccw_device * ) ;
2010-09-07 21:14:39 +00:00
extern int qdio_get_ssqd_desc ( struct ccw_device * , struct qdio_ssqd_desc * ) ;
2005-04-16 15:20:36 -07:00
# endif /* __QDIO_H__ */