linux/drivers/s390/cio/ioasm.c
<<
>>
Prefs
   1/*
   2 * Channel subsystem I/O instructions.
   3 */
   4
   5#include <linux/export.h>
   6
   7#include <asm/chpid.h>
   8#include <asm/schid.h>
   9#include <asm/crw.h>
  10
  11#include "ioasm.h"
  12#include "orb.h"
  13#include "cio.h"
  14
  15static inline int __stsch(struct subchannel_id schid, struct schib *addr)
  16{
  17        register struct subchannel_id reg1 asm ("1") = schid;
  18        int ccode = -EIO;
  19
  20        asm volatile(
  21                "       stsch   0(%3)\n"
  22                "0:     ipm     %0\n"
  23                "       srl     %0,28\n"
  24                "1:\n"
  25                EX_TABLE(0b, 1b)
  26                : "+d" (ccode), "=m" (*addr)
  27                : "d" (reg1), "a" (addr)
  28                : "cc");
  29        return ccode;
  30}
  31
  32int stsch(struct subchannel_id schid, struct schib *addr)
  33{
  34        int ccode;
  35
  36        ccode = __stsch(schid, addr);
  37        trace_s390_cio_stsch(schid, addr, ccode);
  38
  39        return ccode;
  40}
  41EXPORT_SYMBOL(stsch);
  42
  43static inline int __msch(struct subchannel_id schid, struct schib *addr)
  44{
  45        register struct subchannel_id reg1 asm ("1") = schid;
  46        int ccode = -EIO;
  47
  48        asm volatile(
  49                "       msch    0(%2)\n"
  50                "0:     ipm     %0\n"
  51                "       srl     %0,28\n"
  52                "1:\n"
  53                EX_TABLE(0b, 1b)
  54                : "+d" (ccode)
  55                : "d" (reg1), "a" (addr), "m" (*addr)
  56                : "cc");
  57        return ccode;
  58}
  59
  60int msch(struct subchannel_id schid, struct schib *addr)
  61{
  62        int ccode;
  63
  64        ccode = __msch(schid, addr);
  65        trace_s390_cio_msch(schid, addr, ccode);
  66
  67        return ccode;
  68}
  69
  70static inline int __tsch(struct subchannel_id schid, struct irb *addr)
  71{
  72        register struct subchannel_id reg1 asm ("1") = schid;
  73        int ccode;
  74
  75        asm volatile(
  76                "       tsch    0(%3)\n"
  77                "       ipm     %0\n"
  78                "       srl     %0,28"
  79                : "=d" (ccode), "=m" (*addr)
  80                : "d" (reg1), "a" (addr)
  81                : "cc");
  82        return ccode;
  83}
  84
  85int tsch(struct subchannel_id schid, struct irb *addr)
  86{
  87        int ccode;
  88
  89        ccode = __tsch(schid, addr);
  90        trace_s390_cio_tsch(schid, addr, ccode);
  91
  92        return ccode;
  93}
  94
  95static inline int __ssch(struct subchannel_id schid, union orb *addr)
  96{
  97        register struct subchannel_id reg1 asm("1") = schid;
  98        int ccode = -EIO;
  99
 100        asm volatile(
 101                "       ssch    0(%2)\n"
 102                "0:     ipm     %0\n"
 103                "       srl     %0,28\n"
 104                "1:\n"
 105                EX_TABLE(0b, 1b)
 106                : "+d" (ccode)
 107                : "d" (reg1), "a" (addr), "m" (*addr)
 108                : "cc", "memory");
 109        return ccode;
 110}
 111
 112int ssch(struct subchannel_id schid, union orb *addr)
 113{
 114        int ccode;
 115
 116        ccode = __ssch(schid, addr);
 117        trace_s390_cio_ssch(schid, addr, ccode);
 118
 119        return ccode;
 120}
 121EXPORT_SYMBOL(ssch);
 122
 123static inline int __csch(struct subchannel_id schid)
 124{
 125        register struct subchannel_id reg1 asm("1") = schid;
 126        int ccode;
 127
 128        asm volatile(
 129                "       csch\n"
 130                "       ipm     %0\n"
 131                "       srl     %0,28"
 132                : "=d" (ccode)
 133                : "d" (reg1)
 134                : "cc");
 135        return ccode;
 136}
 137
 138int csch(struct subchannel_id schid)
 139{
 140        int ccode;
 141
 142        ccode = __csch(schid);
 143        trace_s390_cio_csch(schid, ccode);
 144
 145        return ccode;
 146}
 147EXPORT_SYMBOL(csch);
 148
 149int tpi(struct tpi_info *addr)
 150{
 151        int ccode;
 152
 153        asm volatile(
 154                "       tpi     0(%2)\n"
 155                "       ipm     %0\n"
 156                "       srl     %0,28"
 157                : "=d" (ccode), "=m" (*addr)
 158                : "a" (addr)
 159                : "cc");
 160        trace_s390_cio_tpi(addr, ccode);
 161
 162        return ccode;
 163}
 164
 165int chsc(void *chsc_area)
 166{
 167        typedef struct { char _[4096]; } addr_type;
 168        int cc = -EIO;
 169
 170        asm volatile(
 171                "       .insn   rre,0xb25f0000,%2,0\n"
 172                "0:     ipm     %0\n"
 173                "       srl     %0,28\n"
 174                "1:\n"
 175                EX_TABLE(0b, 1b)
 176                : "+d" (cc), "=m" (*(addr_type *) chsc_area)
 177                : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
 178                : "cc");
 179        trace_s390_cio_chsc(chsc_area, cc);
 180
 181        return cc;
 182}
 183EXPORT_SYMBOL(chsc);
 184
 185static inline int __rchp(struct chp_id chpid)
 186{
 187        register struct chp_id reg1 asm ("1") = chpid;
 188        int ccode;
 189
 190        asm volatile(
 191                "       lr      1,%1\n"
 192                "       rchp\n"
 193                "       ipm     %0\n"
 194                "       srl     %0,28"
 195                : "=d" (ccode) : "d" (reg1) : "cc");
 196        return ccode;
 197}
 198
 199int rchp(struct chp_id chpid)
 200{
 201        int ccode;
 202
 203        ccode = __rchp(chpid);
 204        trace_s390_cio_rchp(chpid, ccode);
 205
 206        return ccode;
 207}
 208
 209static inline int __rsch(struct subchannel_id schid)
 210{
 211        register struct subchannel_id reg1 asm("1") = schid;
 212        int ccode;
 213
 214        asm volatile(
 215                "       rsch\n"
 216                "       ipm     %0\n"
 217                "       srl     %0,28"
 218                : "=d" (ccode)
 219                : "d" (reg1)
 220                : "cc", "memory");
 221
 222        return ccode;
 223}
 224
 225int rsch(struct subchannel_id schid)
 226{
 227        int ccode;
 228
 229        ccode = __rsch(schid);
 230        trace_s390_cio_rsch(schid, ccode);
 231
 232        return ccode;
 233}
 234
 235static inline int __hsch(struct subchannel_id schid)
 236{
 237        register struct subchannel_id reg1 asm("1") = schid;
 238        int ccode;
 239
 240        asm volatile(
 241                "       hsch\n"
 242                "       ipm     %0\n"
 243                "       srl     %0,28"
 244                : "=d" (ccode)
 245                : "d" (reg1)
 246                : "cc");
 247        return ccode;
 248}
 249
 250int hsch(struct subchannel_id schid)
 251{
 252        int ccode;
 253
 254        ccode = __hsch(schid);
 255        trace_s390_cio_hsch(schid, ccode);
 256
 257        return ccode;
 258}
 259
 260static inline int __xsch(struct subchannel_id schid)
 261{
 262        register struct subchannel_id reg1 asm("1") = schid;
 263        int ccode;
 264
 265        asm volatile(
 266                "       xsch\n"
 267                "       ipm     %0\n"
 268                "       srl     %0,28"
 269                : "=d" (ccode)
 270                : "d" (reg1)
 271                : "cc");
 272        return ccode;
 273}
 274
 275int xsch(struct subchannel_id schid)
 276{
 277        int ccode;
 278
 279        ccode = __xsch(schid);
 280        trace_s390_cio_xsch(schid, ccode);
 281
 282        return ccode;
 283}
 284
 285int stcrw(struct crw *crw)
 286{
 287        int ccode;
 288
 289        asm volatile(
 290                "       stcrw   0(%2)\n"
 291                "       ipm     %0\n"
 292                "       srl     %0,28\n"
 293                : "=d" (ccode), "=m" (*crw)
 294                : "a" (crw)
 295                : "cc");
 296        trace_s390_cio_stcrw(crw, ccode);
 297
 298        return ccode;
 299}
 300