linux/arch/s390/kernel/diag.c
<<
>>
Prefs
   1/*
   2 * Implementation of s390 diagnose codes
   3 *
   4 * Copyright IBM Corp. 2007
   5 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
   6 */
   7
   8#include <linux/module.h>
   9#include <asm/diag.h>
  10
  11/*
  12 * Diagnose 10: Release pages
  13 */
  14void diag10(unsigned long addr)
  15{
  16        if (addr >= 0x7ff00000)
  17                return;
  18        asm volatile(
  19#ifdef CONFIG_64BIT
  20                "       sam31\n"
  21                "       diag    %0,%0,0x10\n"
  22                "0:     sam64\n"
  23#else
  24                "       diag    %0,%0,0x10\n"
  25                "0:\n"
  26#endif
  27                EX_TABLE(0b, 0b)
  28                : : "a" (addr));
  29}
  30EXPORT_SYMBOL(diag10);
  31
  32/*
  33 * Diagnose 14: Input spool file manipulation
  34 */
  35int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
  36{
  37        register unsigned long _ry1 asm("2") = ry1;
  38        register unsigned long _ry2 asm("3") = subcode;
  39        int rc = 0;
  40
  41        asm volatile(
  42#ifdef CONFIG_64BIT
  43                "   sam31\n"
  44                "   diag    %2,2,0x14\n"
  45                "   sam64\n"
  46#else
  47                "   diag    %2,2,0x14\n"
  48#endif
  49                "   ipm     %0\n"
  50                "   srl     %0,28\n"
  51                : "=d" (rc), "+d" (_ry2)
  52                : "d" (rx), "d" (_ry1)
  53                : "cc");
  54
  55        return rc;
  56}
  57EXPORT_SYMBOL(diag14);
  58
  59/*
  60 * Diagnose 210: Get information about a virtual device
  61 */
  62int diag210(struct diag210 *addr)
  63{
  64        /*
  65         * diag 210 needs its data below the 2GB border, so we
  66         * use a static data area to be sure
  67         */
  68        static struct diag210 diag210_tmp;
  69        static DEFINE_SPINLOCK(diag210_lock);
  70        unsigned long flags;
  71        int ccode;
  72
  73        spin_lock_irqsave(&diag210_lock, flags);
  74        diag210_tmp = *addr;
  75
  76#ifdef CONFIG_64BIT
  77        asm volatile(
  78                "       lhi     %0,-1\n"
  79                "       sam31\n"
  80                "       diag    %1,0,0x210\n"
  81                "0:     ipm     %0\n"
  82                "       srl     %0,28\n"
  83                "1:     sam64\n"
  84                EX_TABLE(0b, 1b)
  85                : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
  86#else
  87        asm volatile(
  88                "       lhi     %0,-1\n"
  89                "       diag    %1,0,0x210\n"
  90                "0:     ipm     %0\n"
  91                "       srl     %0,28\n"
  92                "1:\n"
  93                EX_TABLE(0b, 1b)
  94                : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
  95#endif
  96
  97        *addr = diag210_tmp;
  98        spin_unlock_irqrestore(&diag210_lock, flags);
  99
 100        return ccode;
 101}
 102EXPORT_SYMBOL(diag210);
 103