s390/sclp: do not use static sccbs
The sccbs for init/read/sdias/early have to be located below 2 GB, and they are currently defined as a static buffer. With a relocatable kernel that could reside at any place in memory, this will no longer guarantee the location below 2 GB, so use a dynamic GFP_DMA allocation instead. The sclp_early_sccb buffer needs special handling, as it can be used very early, and by both the decompressor and also the decompressed kernel. Therefore, a fixed 4 KB buffer is introduced at 0x11000, the former PARMAREA_END. The new PARMAREA_END is now 0x12000, and it is renamed to HEAD_END, as it is rather the end of head.S and not the end of the parmarea. Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Reviewed-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
fd3d2742d5
commit
087c4d7423
|
@ -336,4 +336,7 @@ ENTRY(startup_kdump)
|
||||||
.byte "root=/dev/ram0 ro"
|
.byte "root=/dev/ram0 ro"
|
||||||
.byte 0
|
.byte 0
|
||||||
|
|
||||||
.org 0x11000
|
.org EARLY_SCCB_OFFSET
|
||||||
|
.fill 4096
|
||||||
|
|
||||||
|
.org HEAD_END
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
#define EP_OFFSET 0x10008
|
#define EP_OFFSET 0x10008
|
||||||
#define EP_STRING "S390EP"
|
#define EP_STRING "S390EP"
|
||||||
#define PARMAREA 0x10400
|
#define PARMAREA 0x10400
|
||||||
#define PARMAREA_END 0x11000
|
#define EARLY_SCCB_OFFSET 0x11000
|
||||||
|
#define HEAD_END 0x12000
|
||||||
|
|
||||||
|
#define EARLY_SCCB_SIZE PAGE_SIZE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Machine features detected in early.c
|
* Machine features detected in early.c
|
||||||
|
|
|
@ -337,10 +337,8 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
|
||||||
* load memory in head.S will be accessed, e.g. to register the next
|
* load memory in head.S will be accessed, e.g. to register the next
|
||||||
* command line. If the next kernel were smaller the current kernel
|
* command line. If the next kernel were smaller the current kernel
|
||||||
* will panic at load.
|
* will panic at load.
|
||||||
*
|
|
||||||
* 0x11000 = sizeof(head.S)
|
|
||||||
*/
|
*/
|
||||||
if (buf_len < 0x11000)
|
if (buf_len < HEAD_END)
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
|
|
||||||
return kexec_image_probe_default(image, buf, buf_len);
|
return kexec_image_probe_default(image, buf, buf_len);
|
||||||
|
|
|
@ -829,7 +829,7 @@ static void __init reserve_kernel(void)
|
||||||
{
|
{
|
||||||
unsigned long start_pfn = PFN_UP(__pa(_end));
|
unsigned long start_pfn = PFN_UP(__pa(_end));
|
||||||
|
|
||||||
memblock_reserve(0, PARMAREA_END);
|
memblock_reserve(0, HEAD_END);
|
||||||
memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn)
|
memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn)
|
||||||
- (unsigned long)_stext);
|
- (unsigned long)_stext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,8 @@ static struct list_head sclp_req_queue;
|
||||||
/* Data for read and and init requests. */
|
/* Data for read and and init requests. */
|
||||||
static struct sclp_req sclp_read_req;
|
static struct sclp_req sclp_read_req;
|
||||||
static struct sclp_req sclp_init_req;
|
static struct sclp_req sclp_init_req;
|
||||||
static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
|
static void *sclp_read_sccb;
|
||||||
static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
|
static struct init_sccb *sclp_init_sccb;
|
||||||
|
|
||||||
/* Suspend request */
|
/* Suspend request */
|
||||||
static DECLARE_COMPLETION(sclp_request_queue_flushed);
|
static DECLARE_COMPLETION(sclp_request_queue_flushed);
|
||||||
|
@ -753,9 +753,8 @@ EXPORT_SYMBOL(sclp_remove_processed);
|
||||||
static inline void
|
static inline void
|
||||||
__sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask)
|
__sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask)
|
||||||
{
|
{
|
||||||
struct init_sccb *sccb;
|
struct init_sccb *sccb = sclp_init_sccb;
|
||||||
|
|
||||||
sccb = (struct init_sccb *) sclp_init_sccb;
|
|
||||||
clear_page(sccb);
|
clear_page(sccb);
|
||||||
memset(&sclp_init_req, 0, sizeof(struct sclp_req));
|
memset(&sclp_init_req, 0, sizeof(struct sclp_req));
|
||||||
sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK;
|
sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK;
|
||||||
|
@ -782,7 +781,7 @@ static int
|
||||||
sclp_init_mask(int calculate)
|
sclp_init_mask(int calculate)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct init_sccb *sccb = (struct init_sccb *) sclp_init_sccb;
|
struct init_sccb *sccb = sclp_init_sccb;
|
||||||
sccb_mask_t receive_mask;
|
sccb_mask_t receive_mask;
|
||||||
sccb_mask_t send_mask;
|
sccb_mask_t send_mask;
|
||||||
int retry;
|
int retry;
|
||||||
|
@ -1175,6 +1174,9 @@ sclp_init(void)
|
||||||
if (sclp_init_state != sclp_init_state_uninitialized)
|
if (sclp_init_state != sclp_init_state_uninitialized)
|
||||||
goto fail_unlock;
|
goto fail_unlock;
|
||||||
sclp_init_state = sclp_init_state_initializing;
|
sclp_init_state = sclp_init_state_initializing;
|
||||||
|
sclp_read_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
|
||||||
|
sclp_init_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
|
||||||
|
BUG_ON(!sclp_read_sccb || !sclp_init_sccb);
|
||||||
/* Set up variables */
|
/* Set up variables */
|
||||||
INIT_LIST_HEAD(&sclp_req_queue);
|
INIT_LIST_HEAD(&sclp_req_queue);
|
||||||
INIT_LIST_HEAD(&sclp_reg_list);
|
INIT_LIST_HEAD(&sclp_reg_list);
|
||||||
|
@ -1207,6 +1209,8 @@ fail_unregister_reboot_notifier:
|
||||||
unregister_reboot_notifier(&sclp_reboot_notifier);
|
unregister_reboot_notifier(&sclp_reboot_notifier);
|
||||||
fail_init_state_uninitialized:
|
fail_init_state_uninitialized:
|
||||||
sclp_init_state = sclp_init_state_uninitialized;
|
sclp_init_state = sclp_init_state_uninitialized;
|
||||||
|
free_page((unsigned long) sclp_read_sccb);
|
||||||
|
free_page((unsigned long) sclp_init_sccb);
|
||||||
fail_unlock:
|
fail_unlock:
|
||||||
spin_unlock_irqrestore(&sclp_lock, flags);
|
spin_unlock_irqrestore(&sclp_lock, flags);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -321,7 +321,7 @@ extern int sclp_console_drop;
|
||||||
extern unsigned long sclp_console_full;
|
extern unsigned long sclp_console_full;
|
||||||
extern bool sclp_mask_compat_mode;
|
extern bool sclp_mask_compat_mode;
|
||||||
|
|
||||||
extern char sclp_early_sccb[PAGE_SIZE];
|
extern char *sclp_early_sccb;
|
||||||
|
|
||||||
void sclp_early_wait_irq(void);
|
void sclp_early_wait_irq(void);
|
||||||
int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
|
int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
|
||||||
|
|
|
@ -147,7 +147,7 @@ static void __init sclp_early_console_detect(struct init_sccb *sccb)
|
||||||
|
|
||||||
void __init sclp_early_detect(void)
|
void __init sclp_early_detect(void)
|
||||||
{
|
{
|
||||||
void *sccb = &sclp_early_sccb;
|
void *sccb = sclp_early_sccb;
|
||||||
|
|
||||||
sclp_early_facilities_detect(sccb);
|
sclp_early_facilities_detect(sccb);
|
||||||
sclp_early_init_core_info(sccb);
|
sclp_early_init_core_info(sccb);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
static struct read_info_sccb __bootdata(sclp_info_sccb);
|
static struct read_info_sccb __bootdata(sclp_info_sccb);
|
||||||
static int __bootdata(sclp_info_sccb_valid);
|
static int __bootdata(sclp_info_sccb_valid);
|
||||||
char sclp_early_sccb[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data);
|
char *sclp_early_sccb = (char *) EARLY_SCCB_OFFSET;
|
||||||
int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
|
int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
|
||||||
/*
|
/*
|
||||||
* Used to keep track of the size of the event masks. Qemu until version 2.11
|
* Used to keep track of the size of the event masks. Qemu until version 2.11
|
||||||
|
@ -91,8 +91,8 @@ static void sclp_early_print_lm(const char *str, unsigned int len)
|
||||||
struct mto *mto;
|
struct mto *mto;
|
||||||
struct go *go;
|
struct go *go;
|
||||||
|
|
||||||
sccb = (struct write_sccb *) &sclp_early_sccb;
|
sccb = (struct write_sccb *) sclp_early_sccb;
|
||||||
end = (unsigned char *) sccb + sizeof(sclp_early_sccb) - 1;
|
end = (unsigned char *) sccb + EARLY_SCCB_SIZE - 1;
|
||||||
memset(sccb, 0, sizeof(*sccb));
|
memset(sccb, 0, sizeof(*sccb));
|
||||||
ptr = (unsigned char *) &sccb->msg.mdb.mto;
|
ptr = (unsigned char *) &sccb->msg.mdb.mto;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
@ -139,9 +139,9 @@ static void sclp_early_print_vt220(const char *str, unsigned int len)
|
||||||
{
|
{
|
||||||
struct vt220_sccb *sccb;
|
struct vt220_sccb *sccb;
|
||||||
|
|
||||||
sccb = (struct vt220_sccb *) &sclp_early_sccb;
|
sccb = (struct vt220_sccb *) sclp_early_sccb;
|
||||||
if (sizeof(*sccb) + len >= sizeof(sclp_early_sccb))
|
if (sizeof(*sccb) + len >= EARLY_SCCB_SIZE)
|
||||||
len = sizeof(sclp_early_sccb) - sizeof(*sccb);
|
len = EARLY_SCCB_SIZE - sizeof(*sccb);
|
||||||
memset(sccb, 0, sizeof(*sccb));
|
memset(sccb, 0, sizeof(*sccb));
|
||||||
memcpy(&sccb->msg.data, str, len);
|
memcpy(&sccb->msg.data, str, len);
|
||||||
sccb->header.length = sizeof(*sccb) + len;
|
sccb->header.length = sizeof(*sccb) + len;
|
||||||
|
@ -199,7 +199,7 @@ static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220)
|
||||||
BUILD_BUG_ON(sizeof(struct init_sccb) > PAGE_SIZE);
|
BUILD_BUG_ON(sizeof(struct init_sccb) > PAGE_SIZE);
|
||||||
|
|
||||||
*have_linemode = *have_vt220 = 0;
|
*have_linemode = *have_vt220 = 0;
|
||||||
sccb = (struct init_sccb *) &sclp_early_sccb;
|
sccb = (struct init_sccb *) sclp_early_sccb;
|
||||||
receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
|
receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
|
||||||
send_mask = disable ? 0 : EVTYP_VT220MSG_MASK | EVTYP_MSG_MASK;
|
send_mask = disable ? 0 : EVTYP_VT220MSG_MASK | EVTYP_MSG_MASK;
|
||||||
rc = sclp_early_set_event_mask(sccb, receive_mask, send_mask);
|
rc = sclp_early_set_event_mask(sccb, receive_mask, send_mask);
|
||||||
|
@ -304,7 +304,7 @@ int __init sclp_early_get_hsa_size(unsigned long *hsa_size)
|
||||||
void __weak __init add_mem_detect_block(u64 start, u64 end) {}
|
void __weak __init add_mem_detect_block(u64 start, u64 end) {}
|
||||||
int __init sclp_early_read_storage_info(void)
|
int __init sclp_early_read_storage_info(void)
|
||||||
{
|
{
|
||||||
struct read_storage_sccb *sccb = (struct read_storage_sccb *)&sclp_early_sccb;
|
struct read_storage_sccb *sccb = (struct read_storage_sccb *)sclp_early_sccb;
|
||||||
int rc, id, max_id = 0;
|
int rc, id, max_id = 0;
|
||||||
unsigned long rn, rzm;
|
unsigned long rn, rzm;
|
||||||
sclp_cmdw_t command;
|
sclp_cmdw_t command;
|
||||||
|
@ -320,8 +320,8 @@ int __init sclp_early_read_storage_info(void)
|
||||||
rzm <<= 20;
|
rzm <<= 20;
|
||||||
|
|
||||||
for (id = 0; id <= max_id; id++) {
|
for (id = 0; id <= max_id; id++) {
|
||||||
memset(sclp_early_sccb, 0, sizeof(sclp_early_sccb));
|
memset(sclp_early_sccb, 0, EARLY_SCCB_SIZE);
|
||||||
sccb->header.length = sizeof(sclp_early_sccb);
|
sccb->header.length = EARLY_SCCB_SIZE;
|
||||||
command = SCLP_CMDW_READ_STORAGE_INFO | (id << 8);
|
command = SCLP_CMDW_READ_STORAGE_INFO | (id << 8);
|
||||||
rc = sclp_early_cmd(command, sccb);
|
rc = sclp_early_cmd(command, sccb);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
|
@ -29,7 +29,7 @@ static struct sclp_register sclp_sdias_register = {
|
||||||
.send_mask = EVTYP_SDIAS_MASK,
|
.send_mask = EVTYP_SDIAS_MASK,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sdias_sccb sccb __attribute__((aligned(4096)));
|
static struct sdias_sccb *sclp_sdias_sccb;
|
||||||
static struct sdias_evbuf sdias_evbuf;
|
static struct sdias_evbuf sdias_evbuf;
|
||||||
|
|
||||||
static DECLARE_COMPLETION(evbuf_accepted);
|
static DECLARE_COMPLETION(evbuf_accepted);
|
||||||
|
@ -58,6 +58,7 @@ static void sdias_callback(struct sclp_req *request, void *data)
|
||||||
|
|
||||||
static int sdias_sclp_send(struct sclp_req *req)
|
static int sdias_sclp_send(struct sclp_req *req)
|
||||||
{
|
{
|
||||||
|
struct sdias_sccb *sccb = sclp_sdias_sccb;
|
||||||
int retries;
|
int retries;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -78,16 +79,16 @@ static int sdias_sclp_send(struct sclp_req *req)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* if not accepted, retry */
|
/* if not accepted, retry */
|
||||||
if (!(sccb.evbuf.hdr.flags & 0x80)) {
|
if (!(sccb->evbuf.hdr.flags & 0x80)) {
|
||||||
TRACE("sclp request failed: flags=%x\n",
|
TRACE("sclp request failed: flags=%x\n",
|
||||||
sccb.evbuf.hdr.flags);
|
sccb->evbuf.hdr.flags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* for the sync interface the response is in the initial sccb
|
* for the sync interface the response is in the initial sccb
|
||||||
*/
|
*/
|
||||||
if (!sclp_sdias_register.receiver_fn) {
|
if (!sclp_sdias_register.receiver_fn) {
|
||||||
memcpy(&sdias_evbuf, &sccb.evbuf, sizeof(sdias_evbuf));
|
memcpy(&sdias_evbuf, &sccb->evbuf, sizeof(sdias_evbuf));
|
||||||
TRACE("sync request done\n");
|
TRACE("sync request done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,23 +105,24 @@ static int sdias_sclp_send(struct sclp_req *req)
|
||||||
*/
|
*/
|
||||||
int sclp_sdias_blk_count(void)
|
int sclp_sdias_blk_count(void)
|
||||||
{
|
{
|
||||||
|
struct sdias_sccb *sccb = sclp_sdias_sccb;
|
||||||
struct sclp_req request;
|
struct sclp_req request;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mutex_lock(&sdias_mutex);
|
mutex_lock(&sdias_mutex);
|
||||||
|
|
||||||
memset(&sccb, 0, sizeof(sccb));
|
memset(sccb, 0, sizeof(*sccb));
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
|
|
||||||
sccb.hdr.length = sizeof(sccb);
|
sccb->hdr.length = sizeof(*sccb);
|
||||||
sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf);
|
sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
|
||||||
sccb.evbuf.hdr.type = EVTYP_SDIAS;
|
sccb->evbuf.hdr.type = EVTYP_SDIAS;
|
||||||
sccb.evbuf.event_qual = SDIAS_EQ_SIZE;
|
sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
|
||||||
sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP;
|
sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
|
||||||
sccb.evbuf.event_id = 4712;
|
sccb->evbuf.event_id = 4712;
|
||||||
sccb.evbuf.dbs = 1;
|
sccb->evbuf.dbs = 1;
|
||||||
|
|
||||||
request.sccb = &sccb;
|
request.sccb = sccb;
|
||||||
request.command = SCLP_CMDW_WRITE_EVENT_DATA;
|
request.command = SCLP_CMDW_WRITE_EVENT_DATA;
|
||||||
request.status = SCLP_REQ_FILLED;
|
request.status = SCLP_REQ_FILLED;
|
||||||
request.callback = sdias_callback;
|
request.callback = sdias_callback;
|
||||||
|
@ -130,8 +132,8 @@ int sclp_sdias_blk_count(void)
|
||||||
pr_err("sclp_send failed for get_nr_blocks\n");
|
pr_err("sclp_send failed for get_nr_blocks\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (sccb.hdr.response_code != 0x0020) {
|
if (sccb->hdr.response_code != 0x0020) {
|
||||||
TRACE("send failed: %x\n", sccb.hdr.response_code);
|
TRACE("send failed: %x\n", sccb->hdr.response_code);
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -163,30 +165,31 @@ out:
|
||||||
*/
|
*/
|
||||||
int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
|
int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
|
||||||
{
|
{
|
||||||
|
struct sdias_sccb *sccb = sclp_sdias_sccb;
|
||||||
struct sclp_req request;
|
struct sclp_req request;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mutex_lock(&sdias_mutex);
|
mutex_lock(&sdias_mutex);
|
||||||
|
|
||||||
memset(&sccb, 0, sizeof(sccb));
|
memset(sccb, 0, sizeof(*sccb));
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
|
|
||||||
sccb.hdr.length = sizeof(sccb);
|
sccb->hdr.length = sizeof(*sccb);
|
||||||
sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf);
|
sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
|
||||||
sccb.evbuf.hdr.type = EVTYP_SDIAS;
|
sccb->evbuf.hdr.type = EVTYP_SDIAS;
|
||||||
sccb.evbuf.hdr.flags = 0;
|
sccb->evbuf.hdr.flags = 0;
|
||||||
sccb.evbuf.event_qual = SDIAS_EQ_STORE_DATA;
|
sccb->evbuf.event_qual = SDIAS_EQ_STORE_DATA;
|
||||||
sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP;
|
sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
|
||||||
sccb.evbuf.event_id = 4712;
|
sccb->evbuf.event_id = 4712;
|
||||||
sccb.evbuf.asa_size = SDIAS_ASA_SIZE_64;
|
sccb->evbuf.asa_size = SDIAS_ASA_SIZE_64;
|
||||||
sccb.evbuf.event_status = 0;
|
sccb->evbuf.event_status = 0;
|
||||||
sccb.evbuf.blk_cnt = nr_blks;
|
sccb->evbuf.blk_cnt = nr_blks;
|
||||||
sccb.evbuf.asa = (unsigned long)dest;
|
sccb->evbuf.asa = (unsigned long)dest;
|
||||||
sccb.evbuf.fbn = start_blk;
|
sccb->evbuf.fbn = start_blk;
|
||||||
sccb.evbuf.lbn = 0;
|
sccb->evbuf.lbn = 0;
|
||||||
sccb.evbuf.dbs = 1;
|
sccb->evbuf.dbs = 1;
|
||||||
|
|
||||||
request.sccb = &sccb;
|
request.sccb = sccb;
|
||||||
request.command = SCLP_CMDW_WRITE_EVENT_DATA;
|
request.command = SCLP_CMDW_WRITE_EVENT_DATA;
|
||||||
request.status = SCLP_REQ_FILLED;
|
request.status = SCLP_REQ_FILLED;
|
||||||
request.callback = sdias_callback;
|
request.callback = sdias_callback;
|
||||||
|
@ -196,8 +199,8 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
|
||||||
pr_err("sclp_send failed: %x\n", rc);
|
pr_err("sclp_send failed: %x\n", rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (sccb.hdr.response_code != 0x0020) {
|
if (sccb->hdr.response_code != 0x0020) {
|
||||||
TRACE("copy failed: %x\n", sccb.hdr.response_code);
|
TRACE("copy failed: %x\n", sccb->hdr.response_code);
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +259,8 @@ int __init sclp_sdias_init(void)
|
||||||
{
|
{
|
||||||
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
|
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
|
||||||
return 0;
|
return 0;
|
||||||
|
sclp_sdias_sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA);
|
||||||
|
BUG_ON(!sclp_sdias_sccb);
|
||||||
sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long));
|
sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long));
|
||||||
debug_register_view(sdias_dbf, &debug_sprintf_view);
|
debug_register_view(sdias_dbf, &debug_sprintf_view);
|
||||||
debug_set_level(sdias_dbf, 6);
|
debug_set_level(sdias_dbf, 6);
|
||||||
|
@ -264,6 +269,7 @@ int __init sclp_sdias_init(void)
|
||||||
if (sclp_sdias_init_async() == 0)
|
if (sclp_sdias_init_async() == 0)
|
||||||
goto out;
|
goto out;
|
||||||
TRACE("init failed\n");
|
TRACE("init failed\n");
|
||||||
|
free_page((unsigned long) sclp_sdias_sccb);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
out:
|
out:
|
||||||
TRACE("init done\n");
|
TRACE("init done\n");
|
||||||
|
|
Loading…
Reference in New Issue