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