diag.c 1.5 KB

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