2005-04-17 02:20:36 +04:00
# ifndef S390_CIO_IOASM_H
# define S390_CIO_IOASM_H
2007-04-27 18:01:31 +04:00
# include <asm/chpid.h>
2008-07-14 11:59:05 +04:00
# include <asm/schid.h>
2011-03-15 19:08:24 +03:00
# include "orb.h"
# include "cio.h"
2006-01-06 11:19:21 +03:00
2005-04-17 02:20:36 +04:00
/*
* TPI info structure
*/
struct tpi_info {
2006-01-06 11:19:21 +03:00
struct subchannel_id schid ;
2005-04-17 02:20:36 +04:00
__u32 intparm ; /* interruption parameter */
__u32 adapter_IO : 1 ;
__u32 reserved2 : 1 ;
__u32 isc : 3 ;
__u32 reserved3 : 12 ;
__u32 int_type : 3 ;
__u32 reserved4 : 12 ;
} __attribute__ ( ( packed ) ) ;
/*
* Some S390 specific IO instructions as inline
*/
2008-10-10 23:33:15 +04:00
static inline int stsch_err ( struct subchannel_id schid , struct schib * addr )
2006-01-06 11:19:25 +03:00
{
2006-09-28 18:56:43 +04:00
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode = - EIO ;
2006-01-06 11:19:25 +03:00
2006-09-28 18:56:43 +04:00
asm volatile (
2008-10-10 23:33:15 +04:00
" stsch 0(%3) \n "
2006-09-28 18:56:43 +04:00
" 0: ipm %0 \n "
" srl %0,28 \n "
2006-01-06 11:19:25 +03:00
" 1: \n "
2006-09-28 18:56:43 +04:00
EX_TABLE ( 0 b , 1 b )
2008-10-10 23:33:15 +04:00
: " +d " ( ccode ) , " =m " ( * addr )
: " d " ( reg1 ) , " a " ( addr )
: " cc " ) ;
2006-01-06 11:19:25 +03:00
return ccode ;
}
2008-10-10 23:33:15 +04:00
static inline int msch ( struct subchannel_id schid , struct schib * addr )
2005-04-17 02:20:36 +04:00
{
2006-09-28 18:56:43 +04:00
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
2005-04-17 02:20:36 +04:00
int ccode ;
2006-09-28 18:56:43 +04:00
asm volatile (
" msch 0(%2) \n "
" ipm %0 \n "
" srl %0,28 "
2008-10-10 23:33:15 +04:00
: " =d " ( ccode )
: " d " ( reg1 ) , " a " ( addr ) , " m " ( * addr )
: " cc " ) ;
2005-04-17 02:20:36 +04:00
return ccode ;
}
2008-10-10 23:33:15 +04:00
static inline int msch_err ( struct subchannel_id schid , struct schib * addr )
2005-04-17 02:20:36 +04:00
{
2006-09-28 18:56:43 +04:00
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode = - EIO ;
2005-04-17 02:20:36 +04:00
2006-09-28 18:56:43 +04:00
asm volatile (
" msch 0(%2) \n "
" 0: ipm %0 \n "
" srl %0,28 \n "
2005-04-17 02:20:36 +04:00
" 1: \n "
2006-09-28 18:56:43 +04:00
EX_TABLE ( 0 b , 1 b )
2008-10-10 23:33:15 +04:00
: " +d " ( ccode )
: " d " ( reg1 ) , " a " ( addr ) , " m " ( * addr )
: " cc " ) ;
2005-04-17 02:20:36 +04:00
return ccode ;
}
2008-10-10 23:33:15 +04:00
static inline int tsch ( struct subchannel_id schid , struct irb * addr )
2005-04-17 02:20:36 +04:00
{
2006-09-28 18:56:43 +04:00
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
2005-04-17 02:20:36 +04:00
int ccode ;
2006-09-28 18:56:43 +04:00
asm volatile (
2008-10-10 23:33:15 +04:00
" tsch 0(%3) \n "
2006-09-28 18:56:43 +04:00
" ipm %0 \n "
" srl %0,28 "
2008-10-10 23:33:15 +04:00
: " =d " ( ccode ) , " =m " ( * addr )
: " d " ( reg1 ) , " a " ( addr )
: " cc " ) ;
2005-04-17 02:20:36 +04:00
return ccode ;
}
2011-03-15 19:08:24 +03:00
static inline int ssch ( struct subchannel_id schid , union orb * addr )
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode = - EIO ;
asm volatile (
" ssch 0(%2) \n "
" 0: ipm %0 \n "
" srl %0,28 \n "
" 1: \n "
EX_TABLE ( 0 b , 1 b )
: " +d " ( ccode )
: " d " ( reg1 ) , " a " ( addr ) , " m " ( * addr )
: " cc " , " memory " ) ;
return ccode ;
}
static inline int csch ( struct subchannel_id schid )
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode ;
asm volatile (
" csch \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode )
: " d " ( reg1 )
: " cc " ) ;
return ccode ;
}
2008-10-10 23:33:15 +04:00
static inline int tpi ( struct tpi_info * addr )
2005-04-17 02:20:36 +04:00
{
int ccode ;
2006-09-28 18:56:43 +04:00
asm volatile (
2008-10-10 23:33:15 +04:00
" tpi 0(%2) \n "
2006-09-28 18:56:43 +04:00
" ipm %0 \n "
" srl %0,28 "
2008-10-10 23:33:15 +04:00
: " =d " ( ccode ) , " =m " ( * addr )
: " a " ( addr )
: " cc " ) ;
2005-04-17 02:20:36 +04:00
return ccode ;
}
2005-09-04 02:58:01 +04:00
static inline int chsc ( void * chsc_area )
2005-04-17 02:20:36 +04:00
{
2006-01-06 11:19:21 +03:00
typedef struct { char _ [ 4096 ] ; } addr_type ;
2005-04-17 02:20:36 +04:00
int cc ;
2006-09-28 18:56:43 +04:00
asm volatile (
" .insn rre,0xb25f0000,%2,0 \n "
" ipm %0 \n "
" srl %0,28 \n "
2006-01-06 11:19:21 +03:00
: " =d " ( cc ) , " =m " ( * ( addr_type * ) chsc_area )
: " d " ( chsc_area ) , " m " ( * ( addr_type * ) chsc_area )
2006-09-28 18:56:43 +04:00
: " cc " ) ;
2005-04-17 02:20:36 +04:00
return cc ;
}
2007-04-27 18:01:26 +04:00
static inline int rchp ( struct chp_id chpid )
2005-04-17 02:20:36 +04:00
{
2007-04-27 18:01:26 +04:00
register struct chp_id reg1 asm ( " 1 " ) = chpid ;
2005-04-17 02:20:36 +04:00
int ccode ;
2006-09-28 18:56:43 +04:00
asm volatile (
" lr 1,%1 \n "
" rchp \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode ) : " d " ( reg1 ) : " cc " ) ;
2005-04-17 02:20:36 +04:00
return ccode ;
}
# endif