2015-12-18 12:59:40 +01:00
/*
* Channel subsystem I / O instructions .
*/
# include <linux/export.h>
# include <asm/chpid.h>
# include <asm/schid.h>
# include <asm/crw.h>
# include "ioasm.h"
# include "orb.h"
# include "cio.h"
2016-06-20 14:03:52 +02:00
static inline int __stsch ( struct subchannel_id schid , struct schib * addr )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode = - EIO ;
asm volatile (
" stsch 0(%3) \n "
" 0: ipm %0 \n "
" srl %0,28 \n "
" 1: \n "
EX_TABLE ( 0 b , 1 b )
: " +d " ( ccode ) , " =m " ( * addr )
: " d " ( reg1 ) , " a " ( addr )
: " cc " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int stsch ( struct subchannel_id schid , struct schib * addr )
{
int ccode ;
ccode = __stsch ( schid , addr ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_stsch ( schid , addr , ccode ) ;
return ccode ;
}
EXPORT_SYMBOL ( stsch ) ;
2016-06-20 14:03:52 +02:00
static inline int __msch ( struct subchannel_id schid , struct schib * addr )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode = - EIO ;
asm volatile (
" msch 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 " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int msch ( struct subchannel_id schid , struct schib * addr )
{
int ccode ;
ccode = __msch ( schid , addr ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_msch ( schid , addr , ccode ) ;
return ccode ;
}
2016-06-20 14:03:52 +02:00
static inline int __tsch ( struct subchannel_id schid , struct irb * addr )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode ;
asm volatile (
" tsch 0(%3) \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode ) , " =m " ( * addr )
: " d " ( reg1 ) , " a " ( addr )
: " cc " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int tsch ( struct subchannel_id schid , struct irb * addr )
{
int ccode ;
ccode = __tsch ( schid , addr ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_tsch ( schid , addr , ccode ) ;
return ccode ;
}
2016-06-20 14:03:52 +02:00
static inline int __ssch ( struct subchannel_id schid , union orb * addr )
2015-12-18 12:59:40 +01:00
{
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 " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int ssch ( struct subchannel_id schid , union orb * addr )
{
int ccode ;
ccode = __ssch ( schid , addr ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_ssch ( schid , addr , ccode ) ;
return ccode ;
}
EXPORT_SYMBOL ( ssch ) ;
2016-06-20 14:03:52 +02:00
static inline int __csch ( struct subchannel_id schid )
2015-12-18 12:59:40 +01:00
{
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 " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int csch ( struct subchannel_id schid )
{
int ccode ;
ccode = __csch ( schid ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_csch ( schid , ccode ) ;
return ccode ;
}
EXPORT_SYMBOL ( csch ) ;
int tpi ( struct tpi_info * addr )
{
int ccode ;
asm volatile (
" tpi 0(%2) \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode ) , " =m " ( * addr )
: " a " ( addr )
: " cc " ) ;
trace_s390_cio_tpi ( addr , ccode ) ;
return ccode ;
}
int chsc ( void * chsc_area )
{
typedef struct { char _ [ 4096 ] ; } addr_type ;
2017-02-20 14:52:58 +01:00
int cc = - EIO ;
2015-12-18 12:59:40 +01:00
asm volatile (
" .insn rre,0xb25f0000,%2,0 \n "
2017-02-20 14:52:58 +01:00
" 0: ipm %0 \n "
2015-12-18 12:59:40 +01:00
" srl %0,28 \n "
2017-02-20 14:52:58 +01:00
" 1: \n "
EX_TABLE ( 0 b , 1 b )
: " +d " ( cc ) , " =m " ( * ( addr_type * ) chsc_area )
2015-12-18 12:59:40 +01:00
: " d " ( chsc_area ) , " m " ( * ( addr_type * ) chsc_area )
: " cc " ) ;
trace_s390_cio_chsc ( chsc_area , cc ) ;
return cc ;
}
EXPORT_SYMBOL ( chsc ) ;
2016-06-20 14:03:52 +02:00
static inline int __rchp ( struct chp_id chpid )
2015-12-18 12:59:40 +01:00
{
register struct chp_id reg1 asm ( " 1 " ) = chpid ;
int ccode ;
asm volatile (
" lr 1,%1 \n "
" rchp \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode ) : " d " ( reg1 ) : " cc " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int rchp ( struct chp_id chpid )
{
int ccode ;
ccode = __rchp ( chpid ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_rchp ( chpid , ccode ) ;
return ccode ;
}
2016-06-20 14:03:52 +02:00
static inline int __rsch ( struct subchannel_id schid )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode ;
asm volatile (
" rsch \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode )
: " d " ( reg1 )
: " cc " , " memory " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int rsch ( struct subchannel_id schid )
{
int ccode ;
ccode = __rsch ( schid ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_rsch ( schid , ccode ) ;
return ccode ;
}
2016-06-20 14:03:52 +02:00
static inline int __hsch ( struct subchannel_id schid )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode ;
asm volatile (
" hsch \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode )
: " d " ( reg1 )
: " cc " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int hsch ( struct subchannel_id schid )
{
int ccode ;
ccode = __hsch ( schid ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_hsch ( schid , ccode ) ;
return ccode ;
}
2016-06-20 14:03:52 +02:00
static inline int __xsch ( struct subchannel_id schid )
2015-12-18 12:59:40 +01:00
{
register struct subchannel_id reg1 asm ( " 1 " ) = schid ;
int ccode ;
asm volatile (
" xsch \n "
" ipm %0 \n "
" srl %0,28 "
: " =d " ( ccode )
: " d " ( reg1 )
: " cc " ) ;
2016-06-20 14:03:52 +02:00
return ccode ;
}
int xsch ( struct subchannel_id schid )
{
int ccode ;
ccode = __xsch ( schid ) ;
2015-12-18 12:59:40 +01:00
trace_s390_cio_xsch ( schid , ccode ) ;
return ccode ;
}
int stcrw ( struct crw * crw )
{
int ccode ;
asm volatile (
" stcrw 0(%2) \n "
" ipm %0 \n "
" srl %0,28 \n "
: " =d " ( ccode ) , " =m " ( * crw )
: " a " ( crw )
: " cc " ) ;
trace_s390_cio_stcrw ( crw , ccode ) ;
return ccode ;
}