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