Commit 9b028b69 authored by Christian Bornträger's avatar Christian Bornträger Committed by Linus Torvalds

[PATCH] s390: cpcmd interface

- Diagnose 8 needs a response buffer below 2GB real storage.
  As the caller cannot always allocate the buffer with GFP_DMA the best
  solution is to rewrite cpcmd to use a bounce buffer if necessary.
  The old function was renamed to __cpcmd and can be called if appropriate.
  The early boot code does not provide kmalloc but need cpcmd functionality.
  These places have been converted to use __cpcmd, as the init code and data
  are below 2GB.
- In case of an 31 bit system, cpcmd is defined as __cpcmd.
- EXPORT_SYMBOL(cpcmd) moved into cpcmd.c
- some whitespace fixes in cpcmd.[c/h]
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 1fb75b8f
......@@ -4,34 +4,41 @@
* S390 version
* Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Christian Borntraeger (cborntra@de.ibm.com),
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <asm/ebcdic.h>
#include <linux/spinlock.h>
#include <asm/cpcmd.h>
#include <asm/system.h>
static DEFINE_SPINLOCK(cpcmd_lock);
static char cpcmd_buf[240];
void cpcmd(char *cmd, char *response, int rlen)
/*
* the caller of __cpcmd has to ensure that the response buffer is below 2 GB
*/
void __cpcmd(char *cmd, char *response, int rlen)
{
const int mask = 0x40000000L;
const int mask = 0x40000000L;
unsigned long flags;
int cmdlen;
int cmdlen;
spin_lock_irqsave(&cpcmd_lock, flags);
cmdlen = strlen(cmd);
BUG_ON(cmdlen>240);
BUG_ON(cmdlen > 240);
strcpy(cpcmd_buf, cmd);
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"
asm volatile ("LRA 2,0(%0)\n\t"
"LR 4,%1\n\t"
"O 4,%4\n\t"
"LRA 3,0(%2)\n\t"
......@@ -78,3 +85,27 @@ void cpcmd(char *cmd, char *response, int rlen)
spin_unlock_irqrestore(&cpcmd_lock, flags);
}
EXPORT_SYMBOL(__cpcmd);
#ifdef CONFIG_ARCH_S390X
void cpcmd(char *cmd, char *response, int rlen)
{
char *lowbuf;
if ((rlen == 0) || (response == NULL)
|| !((unsigned long)response >> 31))
__cpcmd(cmd, response, rlen);
else {
lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
if (!lowbuf) {
printk(KERN_WARNING
"cpcmd: could not allocate response buffer\n");
return;
}
__cpcmd(cmd, lowbuf, rlen);
memcpy(response, lowbuf, rlen);
kfree(lowbuf);
}
}
EXPORT_SYMBOL(cpcmd);
#endif /* CONFIG_ARCH_S390X */
......@@ -63,4 +63,3 @@ EXPORT_SYMBOL(console_mode);
EXPORT_SYMBOL(console_devno);
EXPORT_SYMBOL(console_irq);
EXPORT_SYMBOL(sys_wait4);
EXPORT_SYMBOL(cpcmd);
......@@ -191,11 +191,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);
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);
ptr = strstr(query_buffer, "CONMODE");
/*
* Set the conmode to 3215 so that the device recognition
......@@ -204,7 +204,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);
if (ptr == NULL) {
#if defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
......
......@@ -576,8 +576,8 @@ segment_save(char *name)
segtype_string[seg->range[i].start & 0xff]);
}
sprintf(cmd2, "SAVESEG %s", name);
cpcmd(cmd1, NULL, 80);
cpcmd(cmd2, NULL, 80);
cpcmd(cmd1, NULL, 0);
cpcmd(cmd2, NULL, 0);
spin_unlock(&dcss_lock);
}
......
......@@ -4,11 +4,21 @@
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Christian Borntraeger (cborntra@de.ibm.com),
*/
#ifndef __CPCMD__
#define __CPCMD__
/*
* the caller of __cpcmd has to ensure that the response buffer is below 2 GB
*/
extern void __cpcmd(char *cmd, char *response, int rlen);
#ifndef __s390x__
#define cpcmd __cpcmd
#else
extern void cpcmd(char *cmd, char *response, int rlen);
#endif /*__s390x__*/
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment