summaryrefslogtreecommitdiff
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 11:08:24 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 11:08:24 -0700
commitc1101cbc7db316dcdc94d344727fd372622d0ce7 (patch)
treef1d8946a404bbf7508408a8a76f9c1b7fe672498 /drivers/s390/char/sclp.c
parent1873e50028ce87dd9014049c86d71a898fa02166 (diff)
parent5ea34a01423a27d4526f3551e8542f2f991bd4a0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "This is the bulk of the s390 patches for the 3.11 merge window. Notable enhancements are: the block timeout patches for dasd from Hannes, and more work on the PCI support front. In addition some cleanup and the usual bug fixing." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (42 commits) s390/dasd: Fail all requests when DASD_FLAG_ABORTIO is set s390/dasd: Add 'timeout' attribute block: check for timeout function in blk_rq_timed_out() block/dasd: detailed I/O errors s390/dasd: Reduce amount of messages for specific errors s390/dasd: Implement block timeout handling s390/dasd: process all requests in the device tasklet s390/dasd: make number of retries configurable s390/dasd: Clarify comment s390/hwsampler: Updated misleading member names in hws_data_entry s390/appldata_net_sum: do not use static data s390/appldata_mem: do not use static data s390/vmwatchdog: do not use static data s390/airq: simplify adapter interrupt code s390/pci: remove per device debug attribute s390/dma: remove gratuitous brackets s390/facility: decompose test_facility() s390/sclp: remove duplicated include from sclp_ctl.c s390/irq: store interrupt information in pt_regs s390/drivers: Cocci spatch "ptr_ret.spatch" ...
Diffstat (limited to 'drivers/s390/char/sclp.c')
-rw-r--r--drivers/s390/char/sclp.c86
1 files changed, 80 insertions, 6 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index bd6871bf545a..3e4fb4e858da 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -50,11 +50,42 @@ static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
/* Suspend request */
static DECLARE_COMPLETION(sclp_request_queue_flushed);
+/* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */
+int sclp_console_pages = SCLP_CONSOLE_PAGES;
+/* Flag to indicate if buffer pages are dropped on buffer full condition */
+int sclp_console_drop = 0;
+/* Number of times the console dropped buffer pages */
+unsigned long sclp_console_full;
+
static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
{
complete(&sclp_request_queue_flushed);
}
+static int __init sclp_setup_console_pages(char *str)
+{
+ int pages, rc;
+
+ rc = kstrtoint(str, 0, &pages);
+ if (!rc && pages >= SCLP_CONSOLE_PAGES)
+ sclp_console_pages = pages;
+ return 1;
+}
+
+__setup("sclp_con_pages=", sclp_setup_console_pages);
+
+static int __init sclp_setup_console_drop(char *str)
+{
+ int drop, rc;
+
+ rc = kstrtoint(str, 0, &drop);
+ if (!rc && drop)
+ sclp_console_drop = 1;
+ return 1;
+}
+
+__setup("sclp_con_drop=", sclp_setup_console_drop);
+
static struct sclp_req sclp_suspend_req;
/* Timer for request retries. */
@@ -117,14 +148,19 @@ static int sclp_init(void);
int
sclp_service_call(sclp_cmdw_t command, void *sccb)
{
- int cc;
+ int cc = 4; /* Initialize for program check handling */
asm volatile(
- " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
- " ipm %0\n"
- " srl %0,28"
- : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
+ "0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
+ "1: ipm %0\n"
+ " srl %0,28\n"
+ "2:\n"
+ EX_TABLE(0b, 2b)
+ EX_TABLE(1b, 2b)
+ : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
: "cc", "memory");
+ if (cc == 4)
+ return -EINVAL;
if (cc == 3)
return -EIO;
if (cc == 2)
@@ -1013,11 +1049,47 @@ static const struct dev_pm_ops sclp_pm_ops = {
.restore = sclp_restore,
};
+static ssize_t sclp_show_console_pages(struct device_driver *dev, char *buf)
+{
+ return sprintf(buf, "%i\n", sclp_console_pages);
+}
+
+static DRIVER_ATTR(con_pages, S_IRUSR, sclp_show_console_pages, NULL);
+
+static ssize_t sclp_show_con_drop(struct device_driver *dev, char *buf)
+{
+ return sprintf(buf, "%i\n", sclp_console_drop);
+}
+
+static DRIVER_ATTR(con_drop, S_IRUSR, sclp_show_con_drop, NULL);
+
+static ssize_t sclp_show_console_full(struct device_driver *dev, char *buf)
+{
+ return sprintf(buf, "%lu\n", sclp_console_full);
+}
+
+static DRIVER_ATTR(con_full, S_IRUSR, sclp_show_console_full, NULL);
+
+static struct attribute *sclp_drv_attrs[] = {
+ &driver_attr_con_pages.attr,
+ &driver_attr_con_drop.attr,
+ &driver_attr_con_full.attr,
+ NULL,
+};
+static struct attribute_group sclp_drv_attr_group = {
+ .attrs = sclp_drv_attrs,
+};
+static const struct attribute_group *sclp_drv_attr_groups[] = {
+ &sclp_drv_attr_group,
+ NULL,
+};
+
static struct platform_driver sclp_pdrv = {
.driver = {
.name = "sclp",
.owner = THIS_MODULE,
.pm = &sclp_pm_ops,
+ .groups = sclp_drv_attr_groups,
},
};
@@ -1096,10 +1168,12 @@ static __init int sclp_initcall(void)
rc = platform_driver_register(&sclp_pdrv);
if (rc)
return rc;
+
sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
- rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
+ rc = PTR_RET(sclp_pdev);
if (rc)
goto fail_platform_driver_unregister;
+
rc = atomic_notifier_chain_register(&panic_notifier_list,
&sclp_on_panic_nb);
if (rc)