1/* 2 * arch/s390/kernel/cpcmd.c 3 * 4 * S390 version 5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 7 */ 8 9#include <linux/string.h> 10#include <linux/spinlock.h> 11#include <asm/cpcmd.h> 12#include <asm/ebcdic.h> 13#include <asm/system.h> 14 15static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED; 16static char cpcmd_buf[128]; 17 18void cpcmd(char *cmd, char *response, int rlen) 19{ 20 const int mask = 0x40000000L; 21 unsigned long flags; 22 int cmdlen; 23 24 spin_lock_irqsave(&cpcmd_lock, flags); 25 cmdlen = strlen(cmd); 26 strcpy(cpcmd_buf, cmd); 27 ASCEBC(cpcmd_buf, cmdlen); 28 29 if (response != NULL && rlen > 0) { 30 asm volatile (" lrag 2,0(%0)\n" 31 " lgr 4,%1\n" 32 " o 4,%4\n" 33 " lrag 3,0(%2)\n" 34 " lgr 5,%3\n" 35 " sam31\n" 36 " .long 0x83240008 # Diagnose 83\n" 37 " sam64" 38 : /* no output */ 39 : "a" (cpcmd_buf), "d" (cmdlen), 40 "a" (response), "d" (rlen), "m" (mask) 41 : "2", "3", "4", "5" ); 42 EBCASC(response, rlen); 43 } else { 44 asm volatile (" lrag 2,0(%0)\n" 45 " lgr 3,%1\n" 46 " sam31\n" 47 " .long 0x83230008 # Diagnose 83\n" 48 " sam64" 49 : /* no output */ 50 : "a" (cpcmd_buf), "d" (cmdlen) 51 : "2", "3" ); 52 } 53 spin_unlock_irqrestore(&cpcmd_lock, flags); 54} 55 56