diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/con3215.c | 8 | ||||
-rw-r--r-- | drivers/s390/char/con3270.c | 13 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 26 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/sclp_early.c | 31 |
5 files changed, 68 insertions, 13 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index eb5d22795c47..5af7f0bd6125 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -922,7 +922,7 @@ static int __init con3215_init(void) raw3215_freelist = req; } - cdev = ccw_device_probe_console(); + cdev = ccw_device_create_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; @@ -932,6 +932,12 @@ static int __init con3215_init(void) cdev->handler = raw3215_irq; raw->flags |= RAW3215_FIXED; + if (ccw_device_enable_console(cdev)) { + ccw_device_destroy_console(cdev); + raw3215_free_info(raw); + raw3215[0] = NULL; + return -ENODEV; + } /* Request the console irq */ if (raw3215_startup(raw) != 0) { diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 699fd3e363df..75ffe9980c3e 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -7,6 +7,7 @@ * Copyright IBM Corp. 2003, 2009 */ +#include <linux/module.h> #include <linux/console.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -30,6 +31,9 @@ static struct raw3270_fn con3270_fn; +static bool auto_update = 1; +module_param(auto_update, bool, 0); + /* * Main 3270 console view data structure. */ @@ -204,6 +208,8 @@ con3270_update(struct con3270 *cp) struct string *s, *n; int rc; + if (!auto_update && !raw3270_view_active(&cp->view)) + return; if (cp->view.dev) raw3270_activate_view(&cp->view); @@ -529,6 +535,7 @@ con3270_flush(void) if (!cp->view.dev) return; raw3270_pm_unfreeze(&cp->view); + raw3270_activate_view(&cp->view); spin_lock_irqsave(&cp->view.lock, flags); con3270_wait_write(cp); cp->nr_up = 0; @@ -576,7 +583,6 @@ static struct console con3270 = { static int __init con3270_init(void) { - struct ccw_device *cdev; struct raw3270 *rp; void *cbuf; int i; @@ -591,10 +597,7 @@ con3270_init(void) cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } - cdev = ccw_device_probe_console(); - if (IS_ERR(cdev)) - return -ENODEV; - rp = raw3270_setup_console(cdev); + rp = raw3270_setup_console(); if (IS_ERR(rp)) return PTR_ERR(rp); diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 2cdec21e8924..9f849df4381e 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -276,6 +276,15 @@ __raw3270_start(struct raw3270 *rp, struct raw3270_view *view, } int +raw3270_view_active(struct raw3270_view *view) +{ + struct raw3270 *rp = view->dev; + + return rp && rp->view == view && + !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags); +} + +int raw3270_start(struct raw3270_view *view, struct raw3270_request *rq) { unsigned long flags; @@ -776,22 +785,37 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) } #ifdef CONFIG_TN3270_CONSOLE +/* Tentative definition - see below for actual definition. */ +static struct ccw_driver raw3270_ccw_driver; + /* * Setup 3270 device configured as console. */ -struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) +struct raw3270 __init *raw3270_setup_console(void) { + struct ccw_device *cdev; unsigned long flags; struct raw3270 *rp; char *ascebc; int rc; + cdev = ccw_device_create_console(&raw3270_ccw_driver); + if (IS_ERR(cdev)) + return ERR_CAST(cdev); + rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); ascebc = kzalloc(256, GFP_KERNEL); rc = raw3270_setup_device(cdev, rp, ascebc); if (rc) return ERR_PTR(rc); set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags); + + rc = ccw_device_enable_console(cdev); + if (rc) { + ccw_device_destroy_console(cdev); + return ERR_PTR(rc); + } + spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); do { __raw3270_reset_device(rp); diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h index 7b73ff8c1bd7..e1e41c2861fb 100644 --- a/drivers/s390/char/raw3270.h +++ b/drivers/s390/char/raw3270.h @@ -173,6 +173,7 @@ int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *); int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *); int raw3270_reset(struct raw3270_view *); struct raw3270_view *raw3270_view(struct raw3270_view *); +int raw3270_view_active(struct raw3270_view *); /* Reference count inliner for view structures. */ static inline void @@ -190,7 +191,7 @@ raw3270_put_view(struct raw3270_view *view) wake_up(&raw3270_wait_queue); } -struct raw3270 *raw3270_setup_console(struct ccw_device *cdev); +struct raw3270 *raw3270_setup_console(void); void raw3270_wait_cons_dev(struct raw3270 *); /* Notifier for device addition/removal */ diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 82f2c389b4d1..14196ea0fdf3 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -20,7 +20,9 @@ struct read_info_sccb { struct sccb_header header; /* 0-7 */ u16 rnmax; /* 8-9 */ u8 rnsize; /* 10 */ - u8 _reserved0[24 - 11]; /* 11-15 */ + u8 _reserved0[16 - 11]; /* 11-15 */ + u16 ncpurl; /* 16-17 */ + u8 _reserved7[24 - 18]; /* 18-23 */ u8 loadparm[8]; /* 24-31 */ u8 _reserved1[48 - 32]; /* 32-47 */ u64 facilities; /* 48-55 */ @@ -32,13 +34,16 @@ struct read_info_sccb { u8 _reserved4[100 - 92]; /* 92-99 */ u32 rnsize2; /* 100-103 */ u64 rnmax2; /* 104-111 */ - u8 _reserved5[4096 - 112]; /* 112-4095 */ + u8 _reserved5[120 - 112]; /* 112-119 */ + u16 hcpua; /* 120-121 */ + u8 _reserved6[4096 - 122]; /* 122-4095 */ } __packed __aligned(PAGE_SIZE); static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; static unsigned int sclp_con_has_vt220 __initdata; static unsigned int sclp_con_has_linemode __initdata; static unsigned long sclp_hsa_size; +static unsigned int sclp_max_cpu; static struct sclp_ipl_info sclp_ipl_info; u64 sclp_facilities; @@ -102,6 +107,15 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp_rzm <<= 20; + if (!sccb->hcpua) { + if (MACHINE_IS_VM) + sclp_max_cpu = 64; + else + sclp_max_cpu = sccb->ncpurl; + } else { + sclp_max_cpu = sccb->hcpua + 1; + } + /* Save IPL information */ sclp_ipl_info.is_valid = 1; if (sccb->flags & 0x2) @@ -129,6 +143,11 @@ unsigned long long sclp_get_rzm(void) return sclp_rzm; } +unsigned int sclp_get_max_cpu(void) +{ + return sclp_max_cpu; +} + /* * This function will be called after sclp_facilities_detect(), which gets * called from early.c code. The sclp_facilities_detect() function retrieves @@ -184,9 +203,9 @@ static long __init sclp_hsa_size_init(struct sdias_sccb *sccb) sccb_init_eq_size(sccb); if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb)) return -EIO; - if (sccb->evbuf.blk_cnt != 0) - return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; - return 0; + if (sccb->evbuf.blk_cnt == 0) + return 0; + return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; } static long __init sclp_hsa_copy_wait(struct sccb_header *sccb) @@ -195,6 +214,8 @@ static long __init sclp_hsa_copy_wait(struct sccb_header *sccb) sccb->length = PAGE_SIZE; if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb)) return -EIO; + if (((struct sdias_sccb *) sccb)->evbuf.blk_cnt == 0) + return 0; return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE; } |