Commit 6b979de3 authored by Christian Borntraeger's avatar Christian Borntraeger Committed by Linus Torvalds
Browse files

[PATCH] s390: add vmcp interface



Add interface to issue VM control program commands.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 77fa2245
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -245,6 +245,7 @@ CONFIG_S390_TAPE_BLOCK=y
#
CONFIG_S390_TAPE_34XX=m
# CONFIG_VMLOGRDR is not set
# CONFIG_VMCP is not set
# CONFIG_MONREADER is not set
# CONFIG_DCSS_SHM is not set

+65 −44
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *  arch/s390/kernel/cpcmd.c
 *
 *  S390 version
 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
 *               Christian Borntraeger (cborntra@de.ibm.com),
 */
@@ -18,93 +18,114 @@
#include <asm/system.h>

static DEFINE_SPINLOCK(cpcmd_lock);
static char cpcmd_buf[240];
static char cpcmd_buf[241];

/*
 * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
 */
void __cpcmd(char *cmd, char *response, int rlen)
int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
{
	const int mask = 0x40000000L;
	unsigned long flags;
	int return_code;
	int return_len;
	int cmdlen;

	spin_lock_irqsave(&cpcmd_lock, flags);
	cmdlen = strlen(cmd);
	BUG_ON(cmdlen > 240);
	strcpy(cpcmd_buf, cmd);
	memcpy(cpcmd_buf, cmd, cmdlen);
	ASCEBC(cpcmd_buf, cmdlen);

	if (response != NULL && rlen > 0) {
		memset(response, 0, rlen);
#ifndef CONFIG_ARCH_S390X
		asm volatile ("LRA   2,0(%0)\n\t"
                              "LR    4,%1\n\t"
                              "O     4,%4\n\t"
                              "LRA   3,0(%2)\n\t"
                              "LR    5,%3\n\t"
                              ".long 0x83240008 # Diagnose X'08'\n\t"
                              : /* no output */
		asm volatile (	"lra	2,0(%2)\n"
				"lr	4,%3\n"
				"o	4,%6\n"
				"lra	3,0(%4)\n"
				"lr	5,%5\n"
				"diag	2,4,0x8\n"
				"brc	8, .Litfits\n"
				"ar	5, %5\n"
				".Litfits: \n"
				"lr	%0,4\n"
				"lr	%1,5\n"
				: "=d" (return_code), "=d" (return_len)
				: "a" (cpcmd_buf), "d" (cmdlen),
				"a" (response), "d" (rlen), "m" (mask)
				: "cc", "2", "3", "4", "5" );
#else /* CONFIG_ARCH_S390X */
                asm volatile ("   lrag  2,0(%0)\n"
                              "   lgr   4,%1\n"
                              "   o     4,%4\n"
                              "   lrag  3,0(%2)\n"
                              "   lgr   5,%3\n"
                asm volatile (	"lrag	2,0(%2)\n"
				"lgr	4,%3\n"
				"o	4,%6\n"
				"lrag	3,0(%4)\n"
				"lgr	5,%5\n"
				"sam31\n"
                              "   .long 0x83240008 # Diagnose X'08'\n"
                              "   sam64"
                              : /* no output */
				"diag	2,4,0x8\n"
				"sam64\n"
				"brc	8, .Litfits\n"
				"agr	5, %5\n"
				".Litfits: \n"
				"lgr	%0,4\n"
				"lgr	%1,5\n"
				: "=d" (return_code), "=d" (return_len)
				: "a" (cpcmd_buf), "d" (cmdlen),
				"a" (response), "d" (rlen), "m" (mask)
				: "cc", "2", "3", "4", "5" );
#endif /* CONFIG_ARCH_S390X */
                EBCASC(response, rlen);
        } else {
		return_len = 0;
#ifndef CONFIG_ARCH_S390X
                asm volatile ("LRA   2,0(%0)\n\t"
                              "LR    3,%1\n\t"
                              ".long 0x83230008 # Diagnose X'08'\n\t"
                              : /* no output */
                asm volatile (	"lra	2,0(%1)\n"
				"lr	3,%2\n"
				"diag	2,3,0x8\n"
				"lr	%0,3\n"
				: "=d" (return_code)
				: "a" (cpcmd_buf), "d" (cmdlen)
				: "2", "3"  );
#else /* CONFIG_ARCH_S390X */
                asm volatile ("   lrag  2,0(%0)\n"
                              "   lgr   3,%1\n"
                asm volatile (	"lrag	2,0(%1)\n"
				"lgr	3,%2\n"
				"sam31\n"
                              "   .long 0x83230008 # Diagnose X'08'\n"
                              "   sam64"
                              : /* no output */
				"diag	2,3,0x8\n"
				"sam64\n"
				"lgr	%0,3\n"
				: "=d" (return_code)
				: "a" (cpcmd_buf), "d" (cmdlen)
				: "2", "3" );
#endif /* CONFIG_ARCH_S390X */
        }
	spin_unlock_irqrestore(&cpcmd_lock, flags);
	if (response_code != NULL)
		*response_code = return_code;
	return return_len;
}

EXPORT_SYMBOL(__cpcmd);

#ifdef CONFIG_ARCH_S390X
void cpcmd(char *cmd, char *response, int rlen)
int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
{
	char *lowbuf;
	int len;

	if ((rlen == 0) || (response == NULL)
	    || !((unsigned long)response >> 31))
		__cpcmd(cmd, response, rlen);
		len = __cpcmd(cmd, response, rlen, response_code);
	else {
		lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
		if (!lowbuf) {
			printk(KERN_WARNING
				"cpcmd: could not allocate response buffer\n");
			return;
			return -ENOMEM;
		}
		__cpcmd(cmd, lowbuf, rlen);
		len = __cpcmd(cmd, lowbuf, rlen, response_code);
		memcpy(response, lowbuf, rlen);
		kfree(lowbuf);
	}
	return len;
}

EXPORT_SYMBOL(cpcmd);
+3 −3
Original line number Diff line number Diff line
@@ -198,11 +198,11 @@ static void __init conmode_default(void)
	char *ptr;

        if (MACHINE_IS_VM) {
		__cpcmd("QUERY CONSOLE", query_buffer, 1024);
		__cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL);
		console_devno = simple_strtoul(query_buffer + 5, NULL, 16);
		ptr = strstr(query_buffer, "SUBCHANNEL =");
		console_irq = simple_strtoul(ptr + 13, NULL, 16);
		__cpcmd("QUERY TERM", query_buffer, 1024);
		__cpcmd("QUERY TERM", query_buffer, 1024, NULL);
		ptr = strstr(query_buffer, "CONMODE");
		/*
		 * Set the conmode to 3215 so that the device recognition 
@@ -211,7 +211,7 @@ static void __init conmode_default(void)
		 * 3215 and the 3270 driver will try to access the console
		 * device (3215 as console and 3270 as normal tty).
		 */
		__cpcmd("TERM CONMODE 3215", NULL, 0);
		__cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
		if (ptr == NULL) {
#if defined(CONFIG_SCLP_CONSOLE)
			SET_CONSOLE_SCLP;
+3 −3
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ static void do_machine_restart(void * __unused)
	 * locks are always held disabled).
	 */
	if (MACHINE_IS_VM)
		cpcmd ("IPL", NULL, 0);
		cpcmd ("IPL", NULL, 0, NULL);
	else
		reipl (0x10000 | S390_lowcore.ipl_device);
}
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unused)
	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
		smp_send_stop();
		if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
			cpcmd(vmhalt_cmd, NULL, 0);
			cpcmd(vmhalt_cmd, NULL, 0, NULL);
		signal_processor(smp_processor_id(),
				 sigp_stop_and_store_status);
	}
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * __unused)
	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
		smp_send_stop();
		if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
			cpcmd(vmpoff_cmd, NULL, 0);
			cpcmd(vmpoff_cmd, NULL, 0, NULL);
		signal_processor(smp_processor_id(),
				 sigp_stop_and_store_status);
	}
+1 −1
Original line number Diff line number Diff line
@@ -735,7 +735,7 @@ void __init trap_init(void)
						    &ext_int_pfault);
#endif
#ifndef CONFIG_ARCH_S390X
		cpcmd("SET PAGEX ON", NULL, 0);
		cpcmd("SET PAGEX ON", NULL, 0, NULL);
#endif
	}
}
Loading