diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-02-05 21:18:37 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-02-05 21:18:37 +0100 |
commit | ab14de6c37fae22911ba99f4171613e6d758050b (patch) | |
tree | 7545169fe9d64a82616ae37f2b6c1a420c77f30f /drivers | |
parent | 31ee4b2f40994e8b21691f85cdd4052551a789b7 (diff) | |
download | linux-ab14de6c37fae22911ba99f4171613e6d758050b.tar.gz linux-ab14de6c37fae22911ba99f4171613e6d758050b.tar.bz2 linux-ab14de6c37fae22911ba99f4171613e6d758050b.zip |
[S390] Convert memory detection into C code.
Hopefully this will make it more maintainable and less error prone.
Code makes use of search_exception_tables(). Since it calls this
function before the kernel exeception table is sorted, there is an
early call to sort_main_extable().
This way it's easy to use the already present infrastructure of fixup
sections. Also this would allows to easily convert the rest of
head[31|64].S into C code.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/Kconfig | 8 | ||||
-rw-r--r-- | drivers/s390/char/Makefile | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 18 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cpi.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_info.c | 57 | ||||
-rw-r--r-- | drivers/s390/char/sclp_rw.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 10 |
9 files changed, 80 insertions, 35 deletions
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig index ae89b9b88743..165af398fdea 100644 --- a/drivers/s390/Kconfig +++ b/drivers/s390/Kconfig @@ -103,14 +103,8 @@ config CCW_CONSOLE depends on TN3215_CONSOLE || TN3270_CONSOLE default y -config SCLP - bool "Support for SCLP" - help - Include support for the SCLP interface to the service element. - config SCLP_TTY bool "Support for SCLP line mode terminal" - depends on SCLP help Include support for IBM SCLP line-mode terminals. @@ -123,7 +117,6 @@ config SCLP_CONSOLE config SCLP_VT220_TTY bool "Support for SCLP VT220-compatible terminal" - depends on SCLP help Include support for an IBM SCLP VT220-compatible terminal. @@ -136,7 +129,6 @@ config SCLP_VT220_CONSOLE config SCLP_CPI tristate "Control-Program Identification" - depends on SCLP help This option enables the hardware console interface for system identification. This is commonly used for workload management and diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index c3e97b4fc186..293e667b50f2 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -2,7 +2,8 @@ # S/390 character devices # -obj-y += ctrlchar.o keyboard.o defkeymap.o +obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ + sclp_info.o obj-$(CONFIG_TN3270) += raw3270.o obj-$(CONFIG_TN3270_CONSOLE) += con3270.o @@ -11,7 +12,6 @@ obj-$(CONFIG_TN3270_FS) += fs3270.o obj-$(CONFIG_TN3215) += con3215.o -obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o sclp_quiesce.o obj-$(CONFIG_SCLP_TTY) += sclp_tty.o obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index c1dd19bb7bf8..6a83e2d722a8 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -96,8 +96,8 @@ static int sclp_init_mask(int calculate); static int sclp_init(void); /* Perform service call. Return 0 on success, non-zero otherwise. */ -static int -service_call(sclp_cmdw_t command, void *sccb) +int +sclp_service_call(sclp_cmdw_t command, void *sccb) { int cc; @@ -173,7 +173,7 @@ __sclp_start_request(struct sclp_req *req) if (sclp_running_state != sclp_running_state_idle) return 0; del_timer(&sclp_request_timer); - rc = service_call(req->command, req->sccb); + rc = sclp_service_call(req->command, req->sccb); req->start_count++; if (rc == 0) { @@ -325,7 +325,7 @@ __sclp_make_read_req(void) sccb = (struct sccb_header *) sclp_read_sccb; clear_page(sccb); memset(&sclp_read_req, 0, sizeof(struct sclp_req)); - sclp_read_req.command = SCLP_CMDW_READDATA; + sclp_read_req.command = SCLP_CMDW_READ_EVENT_DATA; sclp_read_req.status = SCLP_REQ_QUEUED; sclp_read_req.start_count = 0; sclp_read_req.callback = sclp_read_cb; @@ -628,7 +628,7 @@ __sclp_make_init_req(u32 receive_mask, u32 send_mask) sccb = (struct init_sccb *) sclp_init_sccb; clear_page(sccb); memset(&sclp_init_req, 0, sizeof(struct sclp_req)); - sclp_init_req.command = SCLP_CMDW_WRITEMASK; + sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK; sclp_init_req.status = SCLP_REQ_FILLED; sclp_init_req.start_count = 0; sclp_init_req.callback = NULL; @@ -831,7 +831,7 @@ sclp_check_interface(void) for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) { __sclp_make_init_req(0, 0); sccb = (struct init_sccb *) sclp_init_req.sccb; - rc = service_call(sclp_init_req.command, sccb); + rc = sclp_service_call(sclp_init_req.command, sccb); if (rc == -EIO) break; sclp_init_req.status = SCLP_REQ_RUNNING; diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 2c71d6ee7b5b..7d29ab45a6ed 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -12,7 +12,7 @@ #include <linux/types.h> #include <linux/list.h> - +#include <asm/sclp.h> #include <asm/ebcdic.h> /* maximum number of pages concerning our own memory management */ @@ -49,9 +49,11 @@ typedef unsigned int sclp_cmdw_t; -#define SCLP_CMDW_READDATA 0x00770005 -#define SCLP_CMDW_WRITEDATA 0x00760005 -#define SCLP_CMDW_WRITEMASK 0x00780005 +#define SCLP_CMDW_READ_EVENT_DATA 0x00770005 +#define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005 +#define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005 +#define SCLP_CMDW_READ_SCP_INFO 0x00020001 +#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 #define GDS_ID_MDSMU 0x1310 #define GDS_ID_MDSRouteInfo 0x1311 @@ -66,13 +68,6 @@ typedef unsigned int sclp_cmdw_t; typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ -struct sccb_header { - u16 length; - u8 function_code; - u8 control_mask[3]; - u16 response_code; -} __attribute__((packed)); - struct gds_subvector { u8 length; u8 key; @@ -131,6 +126,7 @@ void sclp_unregister(struct sclp_register *reg); int sclp_remove_processed(struct sccb_header *sccb); int sclp_deactivate(void); int sclp_reactivate(void); +int sclp_service_call(sclp_cmdw_t command, void *sccb); /* useful inlines */ diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c index 4f873ae148b7..65aa2c85737f 100644 --- a/drivers/s390/char/sclp_cpi.c +++ b/drivers/s390/char/sclp_cpi.c @@ -169,7 +169,7 @@ cpi_prepare_req(void) } /* prepare request data structure presented to SCLP driver */ - req->command = SCLP_CMDW_WRITEDATA; + req->command = SCLP_CMDW_WRITE_EVENT_DATA; req->sccb = sccb; req->status = SCLP_REQ_FILLED; req->callback = cpi_callback; diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c new file mode 100644 index 000000000000..7bcbe643b087 --- /dev/null +++ b/drivers/s390/char/sclp_info.c @@ -0,0 +1,57 @@ +/* + * drivers/s390/char/sclp_info.c + * + * Copyright IBM Corp. 2007 + * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> + */ + +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <asm/sclp.h> +#include "sclp.h" + +struct sclp_readinfo_sccb s390_readinfo_sccb; + +void __init sclp_readinfo_early(void) +{ + sclp_cmdw_t command; + struct sccb_header *sccb; + int ret; + + __ctl_set_bit(0, 9); /* enable service signal subclass mask */ + + sccb = &s390_readinfo_sccb.header; + command = SCLP_CMDW_READ_SCP_INFO_FORCED; + while (1) { + u16 response; + + memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); + sccb->length = sizeof(s390_readinfo_sccb); + sccb->control_mask[2] = 0x80; + + ret = sclp_service_call(command, &s390_readinfo_sccb); + + if (ret == -EIO) + goto out; + if (ret == -EBUSY) + continue; + + __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | + PSW_MASK_WAIT | PSW_DEFAULT_KEY); + local_irq_disable(); + barrier(); + + response = sccb->response_code; + + if (response == 0x10) + break; + + if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) + break; + + command = SCLP_CMDW_READ_SCP_INFO; + } +out: + __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ +} diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index 0c92d3909cca..2486783ea58e 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -460,7 +460,7 @@ sclp_emit_buffer(struct sclp_buffer *buffer, sccb->msg_buf.header.type = EvTyp_PMsgCmd; else return -ENOSYS; - buffer->request.command = SCLP_CMDW_WRITEDATA; + buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA; buffer->request.status = SCLP_REQ_FILLED; buffer->request.callback = sclp_writedata_callback; buffer->request.callback_data = buffer; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index d8135cd4d7ab..544f137d70d7 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -207,7 +207,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request) request->sclp_req.status = SCLP_REQ_FAILED; return -EIO; } - request->sclp_req.command = SCLP_CMDW_WRITEDATA; + request->sclp_req.command = SCLP_CMDW_WRITE_EVENT_DATA; request->sclp_req.status = SCLP_REQ_FILLED; request->sclp_req.callback = sclp_vt220_callback; request->sclp_req.callback_data = (void *) request; diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index ad2b37929848..23e71a76cdab 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -895,11 +895,11 @@ static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr) int rc; pgm_check_occured = 0; - s390_reset_pgm_handler = cio_reset_pgm_check_handler; + s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; rc = stsch(schid, addr); - s390_reset_pgm_handler = NULL; + s390_base_pgm_handler_fn = NULL; - /* The program check handler could have changed pgm_check_occured */ + /* The program check handler could have changed pgm_check_occured. */ barrier(); if (pgm_check_occured) @@ -957,7 +957,7 @@ static void css_reset(void) /* Reset subchannels. */ for_each_subchannel(__shutdown_subchannel_easy, NULL); /* Reset channel paths. */ - s390_reset_mcck_handler = s390_reset_chpids_mcck_handler; + s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler; /* Enable channel report machine checks. */ __ctl_set_bit(14, 28); /* Temporarily reenable machine checks. */ @@ -982,7 +982,7 @@ static void css_reset(void) local_mcck_disable(); /* Disable channel report machine checks. */ __ctl_clear_bit(14, 28); - s390_reset_mcck_handler = NULL; + s390_base_mcck_handler_fn = NULL; } static struct reset_call css_reset_call = { |