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 */ 14 void 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 } 30 EXPORT_SYMBOL(diag10); 31 32 /* 33 * Diagnose 14: Input spool file manipulation 34 */ 35 int 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 } 57 EXPORT_SYMBOL(diag14); 58 59 /* 60 * Diagnose 210: Get information about a virtual device 61 */ 62 int 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 } 102 EXPORT_SYMBOL(diag210); 103