diff options
Diffstat (limited to 'drivers/s390')
30 files changed, 732 insertions, 213 deletions
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig index 96413c2cd1ad..a86a650f3d6d 100644 --- a/drivers/s390/Kconfig +++ b/drivers/s390/Kconfig | |||
@@ -187,6 +187,13 @@ config VMLOGRDR | |||
187 | *SYMPTOM. | 187 | *SYMPTOM. |
188 | This driver depends on the IUCV support driver. | 188 | This driver depends on the IUCV support driver. |
189 | 189 | ||
190 | config VMCP | ||
191 | tristate "Support for the z/VM CP interface (VM only)" | ||
192 | help | ||
193 | Select this option if you want to be able to interact with the control | ||
194 | program on z/VM | ||
195 | |||
196 | |||
190 | config MONREADER | 197 | config MONREADER |
191 | tristate "API for reading z/VM monitor service records" | 198 | tristate "API for reading z/VM monitor service records" |
192 | depends on IUCV | 199 | depends on IUCV |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index ceeb3cf64a16..6527ff6f4706 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -176,7 +176,7 @@ dasd_state_known_to_basic(struct dasd_device * device) | |||
176 | return rc; | 176 | return rc; |
177 | 177 | ||
178 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ | 178 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ |
179 | device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2, | 179 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, |
180 | 8 * sizeof (long)); | 180 | 8 * sizeof (long)); |
181 | debug_register_view(device->debug_area, &debug_sprintf_view); | 181 | debug_register_view(device->debug_area, &debug_sprintf_view); |
182 | debug_set_level(device->debug_area, DBF_EMERG); | 182 | debug_set_level(device->debug_area, DBF_EMERG); |
@@ -1952,26 +1952,24 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1952 | * Automatically online either all dasd devices (dasd_autodetect) or | 1952 | * Automatically online either all dasd devices (dasd_autodetect) or |
1953 | * all devices specified with dasd= parameters. | 1953 | * all devices specified with dasd= parameters. |
1954 | */ | 1954 | */ |
1955 | static int | ||
1956 | __dasd_auto_online(struct device *dev, void *data) | ||
1957 | { | ||
1958 | struct ccw_device *cdev; | ||
1959 | |||
1960 | cdev = to_ccwdev(dev); | ||
1961 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
1962 | ccw_device_set_online(cdev); | ||
1963 | return 0; | ||
1964 | } | ||
1965 | |||
1955 | void | 1966 | void |
1956 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | 1967 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) |
1957 | { | 1968 | { |
1958 | struct device_driver *drv; | 1969 | struct device_driver *drv; |
1959 | struct device *d, *dev; | ||
1960 | struct ccw_device *cdev; | ||
1961 | 1970 | ||
1962 | drv = get_driver(&dasd_discipline_driver->driver); | 1971 | drv = get_driver(&dasd_discipline_driver->driver); |
1963 | down_read(&drv->bus->subsys.rwsem); | 1972 | driver_for_each_device(drv, NULL, NULL, __dasd_auto_online); |
1964 | dev = NULL; | ||
1965 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
1966 | dev = get_device(d); | ||
1967 | if (!dev) | ||
1968 | continue; | ||
1969 | cdev = to_ccwdev(dev); | ||
1970 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
1971 | ccw_device_set_online(cdev); | ||
1972 | put_device(dev); | ||
1973 | } | ||
1974 | up_read(&drv->bus->subsys.rwsem); | ||
1975 | put_driver(drv); | 1973 | put_driver(drv); |
1976 | } | 1974 | } |
1977 | 1975 | ||
@@ -1983,7 +1981,7 @@ dasd_init(void) | |||
1983 | init_waitqueue_head(&dasd_init_waitq); | 1981 | init_waitqueue_head(&dasd_init_waitq); |
1984 | 1982 | ||
1985 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ | 1983 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ |
1986 | dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long)); | 1984 | dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long)); |
1987 | if (dasd_debug_area == NULL) { | 1985 | if (dasd_debug_area == NULL) { |
1988 | rc = -ENOMEM; | 1986 | rc = -ENOMEM; |
1989 | goto failed; | 1987 | goto failed; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index d7f19745911f..43c34f8c5e68 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -9,13 +9,14 @@ | |||
9 | * | 9 | * |
10 | * /proc interface for the dasd driver. | 10 | * /proc interface for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.31 $ | 12 | * $Revision: 1.32 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/proc_fs.h> | ||
19 | 20 | ||
20 | #include <asm/debug.h> | 21 | #include <asm/debug.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 6bc27d52326f..4fde41188996 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -718,7 +718,7 @@ dcssblk_check_params(void) | |||
718 | buf[j-i] = dcssblk_segments[j]; | 718 | buf[j-i] = dcssblk_segments[j]; |
719 | } | 719 | } |
720 | buf[j-i] = '\0'; | 720 | buf[j-i] = '\0'; |
721 | rc = dcssblk_add_store(dcssblk_root_dev, buf, j-i); | 721 | rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i); |
722 | if ((rc >= 0) && (dcssblk_segments[j] == '(')) { | 722 | if ((rc >= 0) && (dcssblk_segments[j] == '(')) { |
723 | for (k = 0; buf[k] != '\0'; k++) | 723 | for (k = 0; buf[k] != '\0'; k++) |
724 | buf[k] = toupper(buf[k]); | 724 | buf[k] = toupper(buf[k]); |
@@ -728,7 +728,7 @@ dcssblk_check_params(void) | |||
728 | up_read(&dcssblk_devices_sem); | 728 | up_read(&dcssblk_devices_sem); |
729 | if (dev_info) | 729 | if (dev_info) |
730 | dcssblk_shared_store(&dev_info->dev, | 730 | dcssblk_shared_store(&dev_info->dev, |
731 | "0\n", 2); | 731 | NULL, "0\n", 2); |
732 | } | 732 | } |
733 | } | 733 | } |
734 | while ((dcssblk_segments[j] != ',') && | 734 | while ((dcssblk_segments[j] != ',') && |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 14e8cce9f862..6377a96735df 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o | |||
19 | 19 | ||
20 | obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o | 20 | obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o |
21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o | 21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o |
22 | obj-$(CONFIG_VMCP) += vmcp.o | ||
22 | 23 | ||
23 | tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o | 24 | tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o |
24 | tape-$(CONFIG_PROC_FS) += tape_proc.o | 25 | tape-$(CONFIG_PROC_FS) += tape_proc.o |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 022f17bff731..f11a67fda40e 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -860,8 +860,8 @@ con3215_init(void) | |||
860 | 860 | ||
861 | /* Set the console mode for VM */ | 861 | /* Set the console mode for VM */ |
862 | if (MACHINE_IS_VM) { | 862 | if (MACHINE_IS_VM) { |
863 | cpcmd("TERM CONMODE 3215", NULL, 0); | 863 | cpcmd("TERM CONMODE 3215", NULL, 0, NULL); |
864 | cpcmd("TERM AUTOCR OFF", NULL, 0); | 864 | cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); |
865 | } | 865 | } |
866 | 866 | ||
867 | /* allocate 3215 request structures */ | 867 | /* allocate 3215 request structures */ |
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index d52fb57a6b19..fc7a213e591f 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c | |||
@@ -591,8 +591,8 @@ con3270_init(void) | |||
591 | 591 | ||
592 | /* Set the console mode for VM */ | 592 | /* Set the console mode for VM */ |
593 | if (MACHINE_IS_VM) { | 593 | if (MACHINE_IS_VM) { |
594 | cpcmd("TERM CONMODE 3270", 0, 0); | 594 | cpcmd("TERM CONMODE 3270", NULL, 0, NULL); |
595 | cpcmd("TERM AUTOCR OFF", 0, 0); | 595 | cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); |
596 | } | 596 | } |
597 | 597 | ||
598 | cdev = ccw_device_probe_console(); | 598 | cdev = ccw_device_probe_console(); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 480ec87976fb..20be88e91fa1 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -1351,13 +1351,13 @@ tape_34xx_init (void) | |||
1351 | { | 1351 | { |
1352 | int rc; | 1352 | int rc; |
1353 | 1353 | ||
1354 | TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long)); | 1354 | TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long)); |
1355 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); | 1355 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); |
1356 | #ifdef DBF_LIKE_HELL | 1356 | #ifdef DBF_LIKE_HELL |
1357 | debug_set_level(TAPE_DBF_AREA, 6); | 1357 | debug_set_level(TAPE_DBF_AREA, 6); |
1358 | #endif | 1358 | #endif |
1359 | 1359 | ||
1360 | DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n"); | 1360 | DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n"); |
1361 | /* Register driver for 3480/3490 tapes. */ | 1361 | /* Register driver for 3480/3490 tapes. */ |
1362 | rc = ccw_driver_register(&tape_34xx_driver); | 1362 | rc = ccw_driver_register(&tape_34xx_driver); |
1363 | if (rc) | 1363 | if (rc) |
@@ -1378,7 +1378,7 @@ tape_34xx_exit(void) | |||
1378 | MODULE_DEVICE_TABLE(ccw, tape_34xx_ids); | 1378 | MODULE_DEVICE_TABLE(ccw, tape_34xx_ids); |
1379 | MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH"); | 1379 | MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH"); |
1380 | MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape " | 1380 | MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape " |
1381 | "device driver ($Revision: 1.21 $)"); | 1381 | "device driver ($Revision: 1.23 $)"); |
1382 | MODULE_LICENSE("GPL"); | 1382 | MODULE_LICENSE("GPL"); |
1383 | 1383 | ||
1384 | module_init(tape_34xx_init); | 1384 | module_init(tape_34xx_init); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index b4df4a515b12..0597aa0e27ee 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -1186,7 +1186,7 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count) | |||
1186 | static int | 1186 | static int |
1187 | tape_init (void) | 1187 | tape_init (void) |
1188 | { | 1188 | { |
1189 | TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long)); | 1189 | TAPE_DBF_AREA = debug_register ( "tape", 2, 2, 4*sizeof(long)); |
1190 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); | 1190 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); |
1191 | #ifdef DBF_LIKE_HELL | 1191 | #ifdef DBF_LIKE_HELL |
1192 | debug_set_level(TAPE_DBF_AREA, 6); | 1192 | debug_set_level(TAPE_DBF_AREA, 6); |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index 801d17cca34e..5fec0a10cc3d 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/vmalloc.h> | 16 | #include <linux/vmalloc.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/proc_fs.h> | ||
18 | 19 | ||
19 | #define TAPE_DBF_AREA tape_core_dbf | 20 | #define TAPE_DBF_AREA tape_core_dbf |
20 | 21 | ||
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c new file mode 100644 index 000000000000..7f11a608a633 --- /dev/null +++ b/drivers/s390/char/vmcp.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004,2005 IBM Corporation | ||
3 | * Interface implementation for communication with the v/VM control program | ||
4 | * Author(s): Christian Borntraeger <cborntra@de.ibm.com> | ||
5 | * | ||
6 | * | ||
7 | * z/VMs CP offers the possibility to issue commands via the diagnose code 8 | ||
8 | * this driver implements a character device that issues these commands and | ||
9 | * returns the answer of CP. | ||
10 | |||
11 | * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS | ||
12 | */ | ||
13 | |||
14 | #include <linux/fs.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/miscdevice.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <asm/cpcmd.h> | ||
20 | #include <asm/debug.h> | ||
21 | #include <asm/uaccess.h> | ||
22 | #include "vmcp.h" | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>"); | ||
26 | MODULE_DESCRIPTION("z/VM CP interface"); | ||
27 | |||
28 | static debug_info_t *vmcp_debug; | ||
29 | |||
30 | static int vmcp_open(struct inode *inode, struct file *file) | ||
31 | { | ||
32 | struct vmcp_session *session; | ||
33 | |||
34 | if (!capable(CAP_SYS_ADMIN)) | ||
35 | return -EPERM; | ||
36 | |||
37 | session = kmalloc(sizeof(*session), GFP_KERNEL); | ||
38 | if (!session) | ||
39 | return -ENOMEM; | ||
40 | session->bufsize = PAGE_SIZE; | ||
41 | session->response = NULL; | ||
42 | session->resp_size = 0; | ||
43 | init_MUTEX(&session->mutex); | ||
44 | file->private_data = session; | ||
45 | return nonseekable_open(inode, file); | ||
46 | } | ||
47 | |||
48 | static int vmcp_release(struct inode *inode, struct file *file) | ||
49 | { | ||
50 | struct vmcp_session *session; | ||
51 | |||
52 | session = (struct vmcp_session *)file->private_data; | ||
53 | file->private_data = NULL; | ||
54 | free_pages((unsigned long)session->response, get_order(session->bufsize)); | ||
55 | kfree(session); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static ssize_t | ||
60 | vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos) | ||
61 | { | ||
62 | size_t tocopy; | ||
63 | struct vmcp_session *session; | ||
64 | |||
65 | session = (struct vmcp_session *)file->private_data; | ||
66 | if (down_interruptible(&session->mutex)) | ||
67 | return -ERESTARTSYS; | ||
68 | if (!session->response) { | ||
69 | up(&session->mutex); | ||
70 | return 0; | ||
71 | } | ||
72 | if (*ppos > session->resp_size) { | ||
73 | up(&session->mutex); | ||
74 | return 0; | ||
75 | } | ||
76 | tocopy = min(session->resp_size - (size_t) (*ppos), count); | ||
77 | tocopy = min(tocopy,session->bufsize - (size_t) (*ppos)); | ||
78 | |||
79 | if (copy_to_user(buff, session->response + (*ppos), tocopy)) { | ||
80 | up(&session->mutex); | ||
81 | return -EFAULT; | ||
82 | } | ||
83 | up(&session->mutex); | ||
84 | *ppos += tocopy; | ||
85 | return tocopy; | ||
86 | } | ||
87 | |||
88 | static ssize_t | ||
89 | vmcp_write(struct file *file, const char __user * buff, size_t count, | ||
90 | loff_t * ppos) | ||
91 | { | ||
92 | char *cmd; | ||
93 | struct vmcp_session *session; | ||
94 | |||
95 | if (count > 240) | ||
96 | return -EINVAL; | ||
97 | cmd = kmalloc(count + 1, GFP_KERNEL); | ||
98 | if (!cmd) | ||
99 | return -ENOMEM; | ||
100 | if (copy_from_user(cmd, buff, count)) { | ||
101 | kfree(cmd); | ||
102 | return -EFAULT; | ||
103 | } | ||
104 | cmd[count] = '\0'; | ||
105 | session = (struct vmcp_session *)file->private_data; | ||
106 | if (down_interruptible(&session->mutex)) | ||
107 | return -ERESTARTSYS; | ||
108 | if (!session->response) | ||
109 | session->response = (char *)__get_free_pages(GFP_KERNEL | ||
110 | | __GFP_REPEAT | GFP_DMA, | ||
111 | get_order(session->bufsize)); | ||
112 | if (!session->response) { | ||
113 | up(&session->mutex); | ||
114 | kfree(cmd); | ||
115 | return -ENOMEM; | ||
116 | } | ||
117 | debug_text_event(vmcp_debug, 1, cmd); | ||
118 | session->resp_size = cpcmd(cmd, session->response, | ||
119 | session->bufsize, | ||
120 | &session->resp_code); | ||
121 | up(&session->mutex); | ||
122 | kfree(cmd); | ||
123 | *ppos = 0; /* reset the file pointer after a command */ | ||
124 | return count; | ||
125 | } | ||
126 | |||
127 | |||
128 | /* | ||
129 | * These ioctls are available, as the semantics of the diagnose 8 call | ||
130 | * does not fit very well into a Linux call. Diagnose X'08' is described in | ||
131 | * CP Programming Services SC24-6084-00 | ||
132 | * | ||
133 | * VMCP_GETCODE: gives the CP return code back to user space | ||
134 | * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8 | ||
135 | * expects adjacent pages in real storage and to make matters worse, we | ||
136 | * dont know the size of the response. Therefore we default to PAGESIZE and | ||
137 | * let userspace to change the response size, if userspace expects a bigger | ||
138 | * response | ||
139 | */ | ||
140 | static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
141 | { | ||
142 | struct vmcp_session *session; | ||
143 | int temp; | ||
144 | |||
145 | session = (struct vmcp_session *)file->private_data; | ||
146 | if (down_interruptible(&session->mutex)) | ||
147 | return -ERESTARTSYS; | ||
148 | switch (cmd) { | ||
149 | case VMCP_GETCODE: | ||
150 | temp = session->resp_code; | ||
151 | up(&session->mutex); | ||
152 | return put_user(temp, (int __user *)arg); | ||
153 | case VMCP_SETBUF: | ||
154 | free_pages((unsigned long)session->response, | ||
155 | get_order(session->bufsize)); | ||
156 | session->response=NULL; | ||
157 | temp = get_user(session->bufsize, (int __user *)arg); | ||
158 | if (get_order(session->bufsize) > 8) { | ||
159 | session->bufsize = PAGE_SIZE; | ||
160 | temp = -EINVAL; | ||
161 | } | ||
162 | up(&session->mutex); | ||
163 | return temp; | ||
164 | case VMCP_GETSIZE: | ||
165 | temp = session->resp_size; | ||
166 | up(&session->mutex); | ||
167 | return put_user(temp, (int __user *)arg); | ||
168 | default: | ||
169 | up(&session->mutex); | ||
170 | return -ENOIOCTLCMD; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static struct file_operations vmcp_fops = { | ||
175 | .owner = THIS_MODULE, | ||
176 | .open = &vmcp_open, | ||
177 | .release = &vmcp_release, | ||
178 | .read = &vmcp_read, | ||
179 | .llseek = &no_llseek, | ||
180 | .write = &vmcp_write, | ||
181 | .unlocked_ioctl = &vmcp_ioctl, | ||
182 | .compat_ioctl = &vmcp_ioctl | ||
183 | }; | ||
184 | |||
185 | static struct miscdevice vmcp_dev = { | ||
186 | .name = "vmcp", | ||
187 | .minor = MISC_DYNAMIC_MINOR, | ||
188 | .fops = &vmcp_fops, | ||
189 | }; | ||
190 | |||
191 | static int __init vmcp_init(void) | ||
192 | { | ||
193 | int ret; | ||
194 | |||
195 | if (!MACHINE_IS_VM) { | ||
196 | printk(KERN_WARNING | ||
197 | "z/VM CP interface is only available under z/VM\n"); | ||
198 | return -ENODEV; | ||
199 | } | ||
200 | ret = misc_register(&vmcp_dev); | ||
201 | if (!ret) | ||
202 | printk(KERN_INFO "z/VM CP interface loaded\n"); | ||
203 | else | ||
204 | printk(KERN_WARNING | ||
205 | "z/VM CP interface not loaded. Could not register misc device.\n"); | ||
206 | vmcp_debug = debug_register("vmcp", 1, 1, 240); | ||
207 | debug_register_view(vmcp_debug, &debug_hex_ascii_view); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static void __exit vmcp_exit(void) | ||
212 | { | ||
213 | WARN_ON(misc_deregister(&vmcp_dev) != 0); | ||
214 | debug_unregister(vmcp_debug); | ||
215 | printk(KERN_INFO "z/VM CP interface unloaded.\n"); | ||
216 | } | ||
217 | |||
218 | module_init(vmcp_init); | ||
219 | module_exit(vmcp_exit); | ||
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h new file mode 100644 index 000000000000..87389e730465 --- /dev/null +++ b/drivers/s390/char/vmcp.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2005 IBM Corporation | ||
3 | * Interface implementation for communication with the v/VM control program | ||
4 | * Version 1.0 | ||
5 | * Author(s): Christian Borntraeger <cborntra@de.ibm.com> | ||
6 | * | ||
7 | * | ||
8 | * z/VMs CP offers the possibility to issue commands via the diagnose code 8 | ||
9 | * this driver implements a character device that issues these commands and | ||
10 | * returns the answer of CP. | ||
11 | * | ||
12 | * The idea of this driver is based on cpint from Neale Ferguson | ||
13 | */ | ||
14 | |||
15 | #include <asm/semaphore.h> | ||
16 | #include <linux/ioctl.h> | ||
17 | |||
18 | #define VMCP_GETCODE _IOR(0x10, 1, int) | ||
19 | #define VMCP_SETBUF _IOW(0x10, 2, int) | ||
20 | #define VMCP_GETSIZE _IOR(0x10, 3, int) | ||
21 | |||
22 | struct vmcp_session { | ||
23 | unsigned int bufsize; | ||
24 | char *response; | ||
25 | int resp_size; | ||
26 | int resp_code; | ||
27 | /* As we use copy_from/to_user, which might * | ||
28 | * sleep and cannot use a spinlock */ | ||
29 | struct semaphore mutex; | ||
30 | }; | ||
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index f7717327d15e..491f00c032e8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -236,7 +236,7 @@ vmlogrdr_get_recording_class_AB(void) { | |||
236 | int len,i; | 236 | int len,i; |
237 | 237 | ||
238 | printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); | 238 | printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); |
239 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 239 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
240 | printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); | 240 | printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); |
241 | len = strnlen(cp_response,sizeof(cp_response)); | 241 | len = strnlen(cp_response,sizeof(cp_response)); |
242 | // now the parsing | 242 | // now the parsing |
@@ -288,7 +288,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { | |||
288 | 288 | ||
289 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", | 289 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", |
290 | cp_command); | 290 | cp_command); |
291 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 291 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
292 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 292 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
293 | cp_response); | 293 | cp_response); |
294 | } | 294 | } |
@@ -301,7 +301,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { | |||
301 | qid_string); | 301 | qid_string); |
302 | 302 | ||
303 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); | 303 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); |
304 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 304 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
305 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 305 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
306 | cp_response); | 306 | cp_response); |
307 | /* The recording command will usually answer with 'Command complete' | 307 | /* The recording command will usually answer with 'Command complete' |
@@ -607,7 +607,7 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c | |||
607 | priv->recording_name); | 607 | priv->recording_name); |
608 | 608 | ||
609 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); | 609 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); |
610 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 610 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
611 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 611 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
612 | cp_response); | 612 | cp_response); |
613 | 613 | ||
@@ -682,7 +682,7 @@ vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) { | |||
682 | char cp_command[] = "QUERY RECORDING "; | 682 | char cp_command[] = "QUERY RECORDING "; |
683 | int len; | 683 | int len; |
684 | 684 | ||
685 | cpcmd(cp_command, buf, 4096); | 685 | cpcmd(cp_command, buf, 4096, NULL); |
686 | len = strlen(buf); | 686 | len = strlen(buf); |
687 | return len; | 687 | return len; |
688 | } | 688 | } |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 306525acb9f8..91ea8e4777f3 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) | |||
403 | return driver_register(&cdriver->driver); | 403 | return driver_register(&cdriver->driver); |
404 | } | 404 | } |
405 | 405 | ||
406 | static inline struct device * | 406 | static int |
407 | __get_next_ccwgroup_device(struct device_driver *drv) | 407 | __ccwgroup_driver_unregister_device(struct device *dev, void *data) |
408 | { | 408 | { |
409 | struct device *dev, *d; | 409 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); |
410 | 410 | device_unregister(dev); | |
411 | down_read(&drv->bus->subsys.rwsem); | 411 | put_device(dev); |
412 | dev = NULL; | 412 | return 0; |
413 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
414 | dev = get_device(d); | ||
415 | if (dev) | ||
416 | break; | ||
417 | } | ||
418 | up_read(&drv->bus->subsys.rwsem); | ||
419 | return dev; | ||
420 | } | 413 | } |
421 | 414 | ||
422 | void | 415 | void |
423 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | 416 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) |
424 | { | 417 | { |
425 | struct device *dev; | ||
426 | |||
427 | /* We don't want ccwgroup devices to live longer than their driver. */ | 418 | /* We don't want ccwgroup devices to live longer than their driver. */ |
428 | get_driver(&cdriver->driver); | 419 | get_driver(&cdriver->driver); |
429 | while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) { | 420 | driver_for_each_device(&cdriver->driver, NULL, NULL, |
430 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | 421 | __ccwgroup_driver_unregister_device); |
431 | device_unregister(dev); | ||
432 | put_device(dev); | ||
433 | }; | ||
434 | put_driver(&cdriver->driver); | 422 | put_driver(&cdriver->driver); |
435 | driver_unregister(&cdriver->driver); | 423 | driver_unregister(&cdriver->driver); |
436 | } | 424 | } |
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) | |||
449 | if (cdev->dev.driver_data) { | 437 | if (cdev->dev.driver_data) { |
450 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; | 438 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; |
451 | if (get_device(&gdev->dev)) { | 439 | if (get_device(&gdev->dev)) { |
452 | if (!list_empty(&gdev->dev.node)) | 440 | if (klist_node_attached(&gdev->dev.knode_bus)) |
453 | return gdev; | 441 | return gdev; |
454 | put_device(&gdev->dev); | 442 | put_device(&gdev->dev); |
455 | } | 443 | } |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 1d9b3f18d8de..ea813bdce1d6 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/cio.c | 2 | * drivers/s390/cio/cio.c |
3 | * S/390 common I/O routines -- low level i/o calls | 3 | * S/390 common I/O routines -- low level i/o calls |
4 | * $Revision: 1.133 $ | 4 | * $Revision: 1.134 $ |
5 | * | 5 | * |
6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -63,17 +63,17 @@ __setup ("cio_msg=", cio_setup); | |||
63 | static int __init | 63 | static int __init |
64 | cio_debug_init (void) | 64 | cio_debug_init (void) |
65 | { | 65 | { |
66 | cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long)); | 66 | cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long)); |
67 | if (!cio_debug_msg_id) | 67 | if (!cio_debug_msg_id) |
68 | goto out_unregister; | 68 | goto out_unregister; |
69 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); | 69 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); |
70 | debug_set_level (cio_debug_msg_id, 2); | 70 | debug_set_level (cio_debug_msg_id, 2); |
71 | cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8); | 71 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8); |
72 | if (!cio_debug_trace_id) | 72 | if (!cio_debug_trace_id) |
73 | goto out_unregister; | 73 | goto out_unregister; |
74 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); | 74 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); |
75 | debug_set_level (cio_debug_trace_id, 2); | 75 | debug_set_level (cio_debug_trace_id, 2); |
76 | cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long)); | 76 | cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long)); |
77 | if (!cio_debug_crw_id) | 77 | if (!cio_debug_crw_id) |
78 | goto out_unregister; | 78 | goto out_unregister; |
79 | debug_register_view (cio_debug_crw_id, &debug_sprintf_view); | 79 | debug_register_view (cio_debug_crw_id, &debug_sprintf_view); |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 87bd70eeabed..555119cacc27 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -128,34 +128,28 @@ css_probe_device(int irq) | |||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int | ||
132 | check_subchannel(struct device * dev, void * data) | ||
133 | { | ||
134 | struct subchannel *sch; | ||
135 | int irq = (unsigned long)data; | ||
136 | |||
137 | sch = to_subchannel(dev); | ||
138 | return (sch->irq == irq); | ||
139 | } | ||
140 | |||
131 | struct subchannel * | 141 | struct subchannel * |
132 | get_subchannel_by_schid(int irq) | 142 | get_subchannel_by_schid(int irq) |
133 | { | 143 | { |
134 | struct subchannel *sch; | ||
135 | struct list_head *entry; | ||
136 | struct device *dev; | 144 | struct device *dev; |
137 | 145 | ||
138 | if (!get_bus(&css_bus_type)) | 146 | dev = bus_find_device(&css_bus_type, NULL, |
139 | return NULL; | 147 | (void *)(unsigned long)irq, check_subchannel); |
140 | down_read(&css_bus_type.subsys.rwsem); | ||
141 | sch = NULL; | ||
142 | list_for_each(entry, &css_bus_type.devices.list) { | ||
143 | dev = get_device(container_of(entry, | ||
144 | struct device, bus_list)); | ||
145 | if (!dev) | ||
146 | continue; | ||
147 | sch = to_subchannel(dev); | ||
148 | if (sch->irq == irq) | ||
149 | break; | ||
150 | put_device(dev); | ||
151 | sch = NULL; | ||
152 | } | ||
153 | up_read(&css_bus_type.subsys.rwsem); | ||
154 | put_bus(&css_bus_type); | ||
155 | 148 | ||
156 | return sch; | 149 | return dev ? to_subchannel(dev) : NULL; |
157 | } | 150 | } |
158 | 151 | ||
152 | |||
159 | static inline int | 153 | static inline int |
160 | css_get_subchannel_status(struct subchannel *sch, int schid) | 154 | css_get_subchannel_status(struct subchannel *sch, int schid) |
161 | { | 155 | { |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 809e1108a06e..14c76f5e4177 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev) | |||
514 | return ret; | 514 | return ret; |
515 | } | 515 | } |
516 | 516 | ||
517 | struct match_data { | ||
518 | unsigned int devno; | ||
519 | struct ccw_device * sibling; | ||
520 | }; | ||
521 | |||
522 | static int | ||
523 | match_devno(struct device * dev, void * data) | ||
524 | { | ||
525 | struct match_data * d = (struct match_data *)data; | ||
526 | struct ccw_device * cdev; | ||
527 | |||
528 | cdev = to_ccwdev(dev); | ||
529 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && | ||
530 | (cdev->private->devno == d->devno) && | ||
531 | (cdev != d->sibling)) { | ||
532 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
533 | return 1; | ||
534 | } | ||
535 | return 0; | ||
536 | } | ||
537 | |||
517 | static struct ccw_device * | 538 | static struct ccw_device * |
518 | get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) | 539 | get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) |
519 | { | 540 | { |
520 | struct ccw_device *cdev; | ||
521 | struct list_head *entry; | ||
522 | struct device *dev; | 541 | struct device *dev; |
542 | struct match_data data = { | ||
543 | .devno = devno, | ||
544 | .sibling = sibling, | ||
545 | }; | ||
523 | 546 | ||
524 | if (!get_bus(&ccw_bus_type)) | 547 | dev = bus_find_device(&css_bus_type, NULL, &data, match_devno); |
525 | return NULL; | ||
526 | down_read(&ccw_bus_type.subsys.rwsem); | ||
527 | cdev = NULL; | ||
528 | list_for_each(entry, &ccw_bus_type.devices.list) { | ||
529 | dev = get_device(container_of(entry, | ||
530 | struct device, bus_list)); | ||
531 | if (!dev) | ||
532 | continue; | ||
533 | cdev = to_ccwdev(dev); | ||
534 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && | ||
535 | (cdev->private->devno == devno) && | ||
536 | (cdev != sibling)) { | ||
537 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
538 | break; | ||
539 | } | ||
540 | put_device(dev); | ||
541 | cdev = NULL; | ||
542 | } | ||
543 | up_read(&ccw_bus_type.subsys.rwsem); | ||
544 | put_bus(&ccw_bus_type); | ||
545 | 548 | ||
546 | return cdev; | 549 | return dev ? to_ccwdev(dev) : NULL; |
547 | } | 550 | } |
548 | 551 | ||
549 | static void | 552 | static void |
@@ -647,7 +650,7 @@ io_subchannel_register(void *data) | |||
647 | cdev = (struct ccw_device *) data; | 650 | cdev = (struct ccw_device *) data; |
648 | sch = to_subchannel(cdev->dev.parent); | 651 | sch = to_subchannel(cdev->dev.parent); |
649 | 652 | ||
650 | if (!list_empty(&sch->dev.children)) { | 653 | if (klist_node_attached(&cdev->dev.knode_parent)) { |
651 | bus_rescan_devices(&ccw_bus_type); | 654 | bus_rescan_devices(&ccw_bus_type); |
652 | goto out; | 655 | goto out; |
653 | } | 656 | } |
@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void) | |||
1019 | /* | 1022 | /* |
1020 | * get ccw_device matching the busid, but only if owned by cdrv | 1023 | * get ccw_device matching the busid, but only if owned by cdrv |
1021 | */ | 1024 | */ |
1025 | static int | ||
1026 | __ccwdev_check_busid(struct device *dev, void *id) | ||
1027 | { | ||
1028 | char *bus_id; | ||
1029 | |||
1030 | bus_id = (char *)id; | ||
1031 | |||
1032 | return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); | ||
1033 | } | ||
1034 | |||
1035 | |||
1022 | struct ccw_device * | 1036 | struct ccw_device * |
1023 | get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) | 1037 | get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) |
1024 | { | 1038 | { |
1025 | struct device *d, *dev; | 1039 | struct device *dev; |
1026 | struct device_driver *drv; | 1040 | struct device_driver *drv; |
1027 | 1041 | ||
1028 | drv = get_driver(&cdrv->driver); | 1042 | drv = get_driver(&cdrv->driver); |
1029 | if (!drv) | 1043 | if (!drv) |
1030 | return 0; | 1044 | return NULL; |
1031 | |||
1032 | down_read(&drv->bus->subsys.rwsem); | ||
1033 | |||
1034 | dev = NULL; | ||
1035 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
1036 | dev = get_device(d); | ||
1037 | 1045 | ||
1038 | if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE)) | 1046 | dev = driver_find_device(drv, NULL, (void *)bus_id, |
1039 | break; | 1047 | __ccwdev_check_busid); |
1040 | else if (dev) { | ||
1041 | put_device(dev); | ||
1042 | dev = NULL; | ||
1043 | } | ||
1044 | } | ||
1045 | up_read(&drv->bus->subsys.rwsem); | ||
1046 | put_driver(drv); | 1048 | put_driver(drv); |
1047 | 1049 | ||
1048 | return dev ? to_ccwdev(dev) : 0; | 1050 | return dev ? to_ccwdev(dev) : 0; |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index bbe9f45d1438..82194c4eadfb 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include "ioasm.h" | 56 | #include "ioasm.h" |
57 | #include "chsc.h" | 57 | #include "chsc.h" |
58 | 58 | ||
59 | #define VERSION_QDIO_C "$Revision: 1.98 $" | 59 | #define VERSION_QDIO_C "$Revision: 1.101 $" |
60 | 60 | ||
61 | /****************** MODULE PARAMETER VARIABLES ********************/ | 61 | /****************** MODULE PARAMETER VARIABLES ********************/ |
62 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); | 62 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); |
@@ -3342,7 +3342,7 @@ static int | |||
3342 | qdio_register_dbf_views(void) | 3342 | qdio_register_dbf_views(void) |
3343 | { | 3343 | { |
3344 | qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME, | 3344 | qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME, |
3345 | QDIO_DBF_SETUP_INDEX, | 3345 | QDIO_DBF_SETUP_PAGES, |
3346 | QDIO_DBF_SETUP_NR_AREAS, | 3346 | QDIO_DBF_SETUP_NR_AREAS, |
3347 | QDIO_DBF_SETUP_LEN); | 3347 | QDIO_DBF_SETUP_LEN); |
3348 | if (!qdio_dbf_setup) | 3348 | if (!qdio_dbf_setup) |
@@ -3351,7 +3351,7 @@ qdio_register_dbf_views(void) | |||
3351 | debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL); | 3351 | debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL); |
3352 | 3352 | ||
3353 | qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME, | 3353 | qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME, |
3354 | QDIO_DBF_SBAL_INDEX, | 3354 | QDIO_DBF_SBAL_PAGES, |
3355 | QDIO_DBF_SBAL_NR_AREAS, | 3355 | QDIO_DBF_SBAL_NR_AREAS, |
3356 | QDIO_DBF_SBAL_LEN); | 3356 | QDIO_DBF_SBAL_LEN); |
3357 | if (!qdio_dbf_sbal) | 3357 | if (!qdio_dbf_sbal) |
@@ -3361,7 +3361,7 @@ qdio_register_dbf_views(void) | |||
3361 | debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL); | 3361 | debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL); |
3362 | 3362 | ||
3363 | qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME, | 3363 | qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME, |
3364 | QDIO_DBF_SENSE_INDEX, | 3364 | QDIO_DBF_SENSE_PAGES, |
3365 | QDIO_DBF_SENSE_NR_AREAS, | 3365 | QDIO_DBF_SENSE_NR_AREAS, |
3366 | QDIO_DBF_SENSE_LEN); | 3366 | QDIO_DBF_SENSE_LEN); |
3367 | if (!qdio_dbf_sense) | 3367 | if (!qdio_dbf_sense) |
@@ -3371,7 +3371,7 @@ qdio_register_dbf_views(void) | |||
3371 | debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL); | 3371 | debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL); |
3372 | 3372 | ||
3373 | qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME, | 3373 | qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME, |
3374 | QDIO_DBF_TRACE_INDEX, | 3374 | QDIO_DBF_TRACE_PAGES, |
3375 | QDIO_DBF_TRACE_NR_AREAS, | 3375 | QDIO_DBF_TRACE_NR_AREAS, |
3376 | QDIO_DBF_TRACE_LEN); | 3376 | QDIO_DBF_TRACE_LEN); |
3377 | if (!qdio_dbf_trace) | 3377 | if (!qdio_dbf_trace) |
@@ -3382,7 +3382,7 @@ qdio_register_dbf_views(void) | |||
3382 | 3382 | ||
3383 | #ifdef CONFIG_QDIO_DEBUG | 3383 | #ifdef CONFIG_QDIO_DEBUG |
3384 | qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME, | 3384 | qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME, |
3385 | QDIO_DBF_SLSB_OUT_INDEX, | 3385 | QDIO_DBF_SLSB_OUT_PAGES, |
3386 | QDIO_DBF_SLSB_OUT_NR_AREAS, | 3386 | QDIO_DBF_SLSB_OUT_NR_AREAS, |
3387 | QDIO_DBF_SLSB_OUT_LEN); | 3387 | QDIO_DBF_SLSB_OUT_LEN); |
3388 | if (!qdio_dbf_slsb_out) | 3388 | if (!qdio_dbf_slsb_out) |
@@ -3391,7 +3391,7 @@ qdio_register_dbf_views(void) | |||
3391 | debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL); | 3391 | debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL); |
3392 | 3392 | ||
3393 | qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME, | 3393 | qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME, |
3394 | QDIO_DBF_SLSB_IN_INDEX, | 3394 | QDIO_DBF_SLSB_IN_PAGES, |
3395 | QDIO_DBF_SLSB_IN_NR_AREAS, | 3395 | QDIO_DBF_SLSB_IN_NR_AREAS, |
3396 | QDIO_DBF_SLSB_IN_LEN); | 3396 | QDIO_DBF_SLSB_IN_LEN); |
3397 | if (!qdio_dbf_slsb_in) | 3397 | if (!qdio_dbf_slsb_in) |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index b6daadac4e8b..6b8aa6a852be 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | 5 | ||
6 | #define VERSION_CIO_QDIO_H "$Revision: 1.32 $" | 6 | #define VERSION_CIO_QDIO_H "$Revision: 1.33 $" |
7 | 7 | ||
8 | #ifdef CONFIG_QDIO_DEBUG | 8 | #ifdef CONFIG_QDIO_DEBUG |
9 | #define QDIO_VERBOSE_LEVEL 9 | 9 | #define QDIO_VERBOSE_LEVEL 9 |
@@ -132,7 +132,7 @@ enum qdio_irq_states { | |||
132 | 132 | ||
133 | #define QDIO_DBF_SETUP_NAME "qdio_setup" | 133 | #define QDIO_DBF_SETUP_NAME "qdio_setup" |
134 | #define QDIO_DBF_SETUP_LEN 8 | 134 | #define QDIO_DBF_SETUP_LEN 8 |
135 | #define QDIO_DBF_SETUP_INDEX 2 | 135 | #define QDIO_DBF_SETUP_PAGES 4 |
136 | #define QDIO_DBF_SETUP_NR_AREAS 1 | 136 | #define QDIO_DBF_SETUP_NR_AREAS 1 |
137 | #ifdef CONFIG_QDIO_DEBUG | 137 | #ifdef CONFIG_QDIO_DEBUG |
138 | #define QDIO_DBF_SETUP_LEVEL 6 | 138 | #define QDIO_DBF_SETUP_LEVEL 6 |
@@ -142,7 +142,7 @@ enum qdio_irq_states { | |||
142 | 142 | ||
143 | #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ | 143 | #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ |
144 | #define QDIO_DBF_SBAL_LEN 256 | 144 | #define QDIO_DBF_SBAL_LEN 256 |
145 | #define QDIO_DBF_SBAL_INDEX 2 | 145 | #define QDIO_DBF_SBAL_PAGES 4 |
146 | #define QDIO_DBF_SBAL_NR_AREAS 2 | 146 | #define QDIO_DBF_SBAL_NR_AREAS 2 |
147 | #ifdef CONFIG_QDIO_DEBUG | 147 | #ifdef CONFIG_QDIO_DEBUG |
148 | #define QDIO_DBF_SBAL_LEVEL 6 | 148 | #define QDIO_DBF_SBAL_LEVEL 6 |
@@ -154,16 +154,16 @@ enum qdio_irq_states { | |||
154 | #define QDIO_DBF_TRACE_LEN 8 | 154 | #define QDIO_DBF_TRACE_LEN 8 |
155 | #define QDIO_DBF_TRACE_NR_AREAS 2 | 155 | #define QDIO_DBF_TRACE_NR_AREAS 2 |
156 | #ifdef CONFIG_QDIO_DEBUG | 156 | #ifdef CONFIG_QDIO_DEBUG |
157 | #define QDIO_DBF_TRACE_INDEX 4 | 157 | #define QDIO_DBF_TRACE_PAGES 16 |
158 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ | 158 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ |
159 | #else /* CONFIG_QDIO_DEBUG */ | 159 | #else /* CONFIG_QDIO_DEBUG */ |
160 | #define QDIO_DBF_TRACE_INDEX 2 | 160 | #define QDIO_DBF_TRACE_PAGES 4 |
161 | #define QDIO_DBF_TRACE_LEVEL 2 | 161 | #define QDIO_DBF_TRACE_LEVEL 2 |
162 | #endif /* CONFIG_QDIO_DEBUG */ | 162 | #endif /* CONFIG_QDIO_DEBUG */ |
163 | 163 | ||
164 | #define QDIO_DBF_SENSE_NAME "qdio_sense" | 164 | #define QDIO_DBF_SENSE_NAME "qdio_sense" |
165 | #define QDIO_DBF_SENSE_LEN 64 | 165 | #define QDIO_DBF_SENSE_LEN 64 |
166 | #define QDIO_DBF_SENSE_INDEX 1 | 166 | #define QDIO_DBF_SENSE_PAGES 2 |
167 | #define QDIO_DBF_SENSE_NR_AREAS 1 | 167 | #define QDIO_DBF_SENSE_NR_AREAS 1 |
168 | #ifdef CONFIG_QDIO_DEBUG | 168 | #ifdef CONFIG_QDIO_DEBUG |
169 | #define QDIO_DBF_SENSE_LEVEL 6 | 169 | #define QDIO_DBF_SENSE_LEVEL 6 |
@@ -176,13 +176,13 @@ enum qdio_irq_states { | |||
176 | 176 | ||
177 | #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" | 177 | #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" |
178 | #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q | 178 | #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q |
179 | #define QDIO_DBF_SLSB_OUT_INDEX 8 | 179 | #define QDIO_DBF_SLSB_OUT_PAGES 256 |
180 | #define QDIO_DBF_SLSB_OUT_NR_AREAS 1 | 180 | #define QDIO_DBF_SLSB_OUT_NR_AREAS 1 |
181 | #define QDIO_DBF_SLSB_OUT_LEVEL 6 | 181 | #define QDIO_DBF_SLSB_OUT_LEVEL 6 |
182 | 182 | ||
183 | #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" | 183 | #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" |
184 | #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q | 184 | #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q |
185 | #define QDIO_DBF_SLSB_IN_INDEX 8 | 185 | #define QDIO_DBF_SLSB_IN_PAGES 256 |
186 | #define QDIO_DBF_SLSB_IN_NR_AREAS 1 | 186 | #define QDIO_DBF_SLSB_IN_NR_AREAS 1 |
187 | #define QDIO_DBF_SLSB_IN_LEVEL 6 | 187 | #define QDIO_DBF_SLSB_IN_LEVEL 6 |
188 | #endif /* CONFIG_QDIO_DEBUG */ | 188 | #endif /* CONFIG_QDIO_DEBUG */ |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index a99927d54ebb..60440dbe3a27 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -146,8 +146,8 @@ claw_unregister_debug_facility(void) | |||
146 | static int | 146 | static int |
147 | claw_register_debug_facility(void) | 147 | claw_register_debug_facility(void) |
148 | { | 148 | { |
149 | claw_dbf_setup = debug_register("claw_setup", 1, 1, 8); | 149 | claw_dbf_setup = debug_register("claw_setup", 2, 1, 8); |
150 | claw_dbf_trace = debug_register("claw_trace", 1, 2, 8); | 150 | claw_dbf_trace = debug_register("claw_trace", 2, 2, 8); |
151 | if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) { | 151 | if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) { |
152 | printk(KERN_WARNING "Not enough memory for debug facility.\n"); | 152 | printk(KERN_WARNING "Not enough memory for debug facility.\n"); |
153 | claw_unregister_debug_facility(); | 153 | claw_unregister_debug_facility(); |
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c index 2c86bfa11b2f..0e2a8bb93032 100644 --- a/drivers/s390/net/ctcdbug.c +++ b/drivers/s390/net/ctcdbug.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.4 $) | 3 | * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $) |
4 | * | 4 | * |
5 | * CTC / ESCON network driver - s390 dbf exploit. | 5 | * CTC / ESCON network driver - s390 dbf exploit. |
6 | * | 6 | * |
@@ -9,7 +9,7 @@ | |||
9 | * Author(s): Original Code written by | 9 | * Author(s): Original Code written by |
10 | * Peter Tiedemann (ptiedem@de.ibm.com) | 10 | * Peter Tiedemann (ptiedem@de.ibm.com) |
11 | * | 11 | * |
12 | * $Revision: 1.4 $ $Date: 2004/08/04 10:11:59 $ | 12 | * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $ |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -51,15 +51,15 @@ int | |||
51 | ctc_register_dbf_views(void) | 51 | ctc_register_dbf_views(void) |
52 | { | 52 | { |
53 | ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME, | 53 | ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME, |
54 | CTC_DBF_SETUP_INDEX, | 54 | CTC_DBF_SETUP_PAGES, |
55 | CTC_DBF_SETUP_NR_AREAS, | 55 | CTC_DBF_SETUP_NR_AREAS, |
56 | CTC_DBF_SETUP_LEN); | 56 | CTC_DBF_SETUP_LEN); |
57 | ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME, | 57 | ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME, |
58 | CTC_DBF_DATA_INDEX, | 58 | CTC_DBF_DATA_PAGES, |
59 | CTC_DBF_DATA_NR_AREAS, | 59 | CTC_DBF_DATA_NR_AREAS, |
60 | CTC_DBF_DATA_LEN); | 60 | CTC_DBF_DATA_LEN); |
61 | ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME, | 61 | ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME, |
62 | CTC_DBF_TRACE_INDEX, | 62 | CTC_DBF_TRACE_PAGES, |
63 | CTC_DBF_TRACE_NR_AREAS, | 63 | CTC_DBF_TRACE_NR_AREAS, |
64 | CTC_DBF_TRACE_LEN); | 64 | CTC_DBF_TRACE_LEN); |
65 | 65 | ||
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h index 7fe2ebd1792d..7d6afa1627c3 100644 --- a/drivers/s390/net/ctcdbug.h +++ b/drivers/s390/net/ctcdbug.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $) | 3 | * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $) |
4 | * | 4 | * |
5 | * CTC / ESCON network driver - s390 dbf exploit. | 5 | * CTC / ESCON network driver - s390 dbf exploit. |
6 | * | 6 | * |
@@ -9,7 +9,7 @@ | |||
9 | * Author(s): Original Code written by | 9 | * Author(s): Original Code written by |
10 | * Peter Tiedemann (ptiedem@de.ibm.com) | 10 | * Peter Tiedemann (ptiedem@de.ibm.com) |
11 | * | 11 | * |
12 | * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $ | 12 | * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $ |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -35,19 +35,19 @@ | |||
35 | */ | 35 | */ |
36 | #define CTC_DBF_SETUP_NAME "ctc_setup" | 36 | #define CTC_DBF_SETUP_NAME "ctc_setup" |
37 | #define CTC_DBF_SETUP_LEN 16 | 37 | #define CTC_DBF_SETUP_LEN 16 |
38 | #define CTC_DBF_SETUP_INDEX 3 | 38 | #define CTC_DBF_SETUP_PAGES 8 |
39 | #define CTC_DBF_SETUP_NR_AREAS 1 | 39 | #define CTC_DBF_SETUP_NR_AREAS 1 |
40 | #define CTC_DBF_SETUP_LEVEL 3 | 40 | #define CTC_DBF_SETUP_LEVEL 3 |
41 | 41 | ||
42 | #define CTC_DBF_DATA_NAME "ctc_data" | 42 | #define CTC_DBF_DATA_NAME "ctc_data" |
43 | #define CTC_DBF_DATA_LEN 128 | 43 | #define CTC_DBF_DATA_LEN 128 |
44 | #define CTC_DBF_DATA_INDEX 3 | 44 | #define CTC_DBF_DATA_PAGES 8 |
45 | #define CTC_DBF_DATA_NR_AREAS 1 | 45 | #define CTC_DBF_DATA_NR_AREAS 1 |
46 | #define CTC_DBF_DATA_LEVEL 3 | 46 | #define CTC_DBF_DATA_LEVEL 3 |
47 | 47 | ||
48 | #define CTC_DBF_TRACE_NAME "ctc_trace" | 48 | #define CTC_DBF_TRACE_NAME "ctc_trace" |
49 | #define CTC_DBF_TRACE_LEN 16 | 49 | #define CTC_DBF_TRACE_LEN 16 |
50 | #define CTC_DBF_TRACE_INDEX 2 | 50 | #define CTC_DBF_TRACE_PAGES 4 |
51 | #define CTC_DBF_TRACE_NR_AREAS 2 | 51 | #define CTC_DBF_TRACE_NR_AREAS 2 |
52 | #define CTC_DBF_TRACE_LEVEL 3 | 52 | #define CTC_DBF_TRACE_LEVEL 3 |
53 | 53 | ||
diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h index 198330217eff..0c4644d3d2f3 100644 --- a/drivers/s390/net/iucv.h +++ b/drivers/s390/net/iucv.h | |||
@@ -37,19 +37,19 @@ | |||
37 | */ | 37 | */ |
38 | #define IUCV_DBF_SETUP_NAME "iucv_setup" | 38 | #define IUCV_DBF_SETUP_NAME "iucv_setup" |
39 | #define IUCV_DBF_SETUP_LEN 32 | 39 | #define IUCV_DBF_SETUP_LEN 32 |
40 | #define IUCV_DBF_SETUP_INDEX 1 | 40 | #define IUCV_DBF_SETUP_PAGES 2 |
41 | #define IUCV_DBF_SETUP_NR_AREAS 1 | 41 | #define IUCV_DBF_SETUP_NR_AREAS 1 |
42 | #define IUCV_DBF_SETUP_LEVEL 3 | 42 | #define IUCV_DBF_SETUP_LEVEL 3 |
43 | 43 | ||
44 | #define IUCV_DBF_DATA_NAME "iucv_data" | 44 | #define IUCV_DBF_DATA_NAME "iucv_data" |
45 | #define IUCV_DBF_DATA_LEN 128 | 45 | #define IUCV_DBF_DATA_LEN 128 |
46 | #define IUCV_DBF_DATA_INDEX 1 | 46 | #define IUCV_DBF_DATA_PAGES 2 |
47 | #define IUCV_DBF_DATA_NR_AREAS 1 | 47 | #define IUCV_DBF_DATA_NR_AREAS 1 |
48 | #define IUCV_DBF_DATA_LEVEL 2 | 48 | #define IUCV_DBF_DATA_LEVEL 2 |
49 | 49 | ||
50 | #define IUCV_DBF_TRACE_NAME "iucv_trace" | 50 | #define IUCV_DBF_TRACE_NAME "iucv_trace" |
51 | #define IUCV_DBF_TRACE_LEN 16 | 51 | #define IUCV_DBF_TRACE_LEN 16 |
52 | #define IUCV_DBF_TRACE_INDEX 2 | 52 | #define IUCV_DBF_TRACE_PAGES 4 |
53 | #define IUCV_DBF_TRACE_NR_AREAS 1 | 53 | #define IUCV_DBF_TRACE_NR_AREAS 1 |
54 | #define IUCV_DBF_TRACE_LEVEL 3 | 54 | #define IUCV_DBF_TRACE_LEVEL 3 |
55 | 55 | ||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index ab086242d305..46f34ba93ac5 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Frank Pavlic (pavlic@de.ibm.com) and | 11 | * Frank Pavlic (pavlic@de.ibm.com) and |
12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
13 | * | 13 | * |
14 | * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $ | 14 | * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $ |
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -59,7 +59,7 @@ | |||
59 | /** | 59 | /** |
60 | * initialization string for output | 60 | * initialization string for output |
61 | */ | 61 | */ |
62 | #define VERSION_LCS_C "$Revision: 1.98 $" | 62 | #define VERSION_LCS_C "$Revision: 1.99 $" |
63 | 63 | ||
64 | static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; | 64 | static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; |
65 | static char debug_buffer[255]; | 65 | static char debug_buffer[255]; |
@@ -93,8 +93,8 @@ lcs_unregister_debug_facility(void) | |||
93 | static int | 93 | static int |
94 | lcs_register_debug_facility(void) | 94 | lcs_register_debug_facility(void) |
95 | { | 95 | { |
96 | lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8); | 96 | lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8); |
97 | lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8); | 97 | lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8); |
98 | if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) { | 98 | if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) { |
99 | PRINT_ERR("Not enough memory for debug facility.\n"); | 99 | PRINT_ERR("Not enough memory for debug facility.\n"); |
100 | lcs_unregister_debug_facility(); | 100 | lcs_unregister_debug_facility(); |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 3fd4fb754b2d..69425a7a6e98 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: netiucv.c,v 1.63 2004/07/27 13:36:05 mschwide Exp $ | 2 | * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $ |
3 | * | 3 | * |
4 | * IUCV network driver | 4 | * IUCV network driver |
5 | * | 5 | * |
@@ -30,7 +30,7 @@ | |||
30 | * along with this program; if not, write to the Free Software | 30 | * along with this program; if not, write to the Free Software |
31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
32 | * | 32 | * |
33 | * RELEASE-TAG: IUCV network driver $Revision: 1.63 $ | 33 | * RELEASE-TAG: IUCV network driver $Revision: 1.66 $ |
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
@@ -391,15 +391,15 @@ static int | |||
391 | iucv_register_dbf_views(void) | 391 | iucv_register_dbf_views(void) |
392 | { | 392 | { |
393 | iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, | 393 | iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, |
394 | IUCV_DBF_SETUP_INDEX, | 394 | IUCV_DBF_SETUP_PAGES, |
395 | IUCV_DBF_SETUP_NR_AREAS, | 395 | IUCV_DBF_SETUP_NR_AREAS, |
396 | IUCV_DBF_SETUP_LEN); | 396 | IUCV_DBF_SETUP_LEN); |
397 | iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME, | 397 | iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME, |
398 | IUCV_DBF_DATA_INDEX, | 398 | IUCV_DBF_DATA_PAGES, |
399 | IUCV_DBF_DATA_NR_AREAS, | 399 | IUCV_DBF_DATA_NR_AREAS, |
400 | IUCV_DBF_DATA_LEN); | 400 | IUCV_DBF_DATA_LEN); |
401 | iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME, | 401 | iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME, |
402 | IUCV_DBF_TRACE_INDEX, | 402 | IUCV_DBF_TRACE_PAGES, |
403 | IUCV_DBF_TRACE_NR_AREAS, | 403 | IUCV_DBF_TRACE_NR_AREAS, |
404 | IUCV_DBF_TRACE_LEN); | 404 | IUCV_DBF_TRACE_LEN); |
405 | 405 | ||
@@ -2076,7 +2076,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_write); | |||
2076 | static void | 2076 | static void |
2077 | netiucv_banner(void) | 2077 | netiucv_banner(void) |
2078 | { | 2078 | { |
2079 | char vbuf[] = "$Revision: 1.63 $"; | 2079 | char vbuf[] = "$Revision: 1.66 $"; |
2080 | char *version = vbuf; | 2080 | char *version = vbuf; |
2081 | 2081 | ||
2082 | if ((version = strchr(version, ':'))) { | 2082 | if ((version = strchr(version, ':'))) { |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index a755b57db46b..008e0a5d2eb3 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -42,44 +42,44 @@ | |||
42 | */ | 42 | */ |
43 | #define QETH_DBF_SETUP_NAME "qeth_setup" | 43 | #define QETH_DBF_SETUP_NAME "qeth_setup" |
44 | #define QETH_DBF_SETUP_LEN 8 | 44 | #define QETH_DBF_SETUP_LEN 8 |
45 | #define QETH_DBF_SETUP_INDEX 3 | 45 | #define QETH_DBF_SETUP_PAGES 8 |
46 | #define QETH_DBF_SETUP_NR_AREAS 1 | 46 | #define QETH_DBF_SETUP_NR_AREAS 1 |
47 | #define QETH_DBF_SETUP_LEVEL 5 | 47 | #define QETH_DBF_SETUP_LEVEL 5 |
48 | 48 | ||
49 | #define QETH_DBF_MISC_NAME "qeth_misc" | 49 | #define QETH_DBF_MISC_NAME "qeth_misc" |
50 | #define QETH_DBF_MISC_LEN 128 | 50 | #define QETH_DBF_MISC_LEN 128 |
51 | #define QETH_DBF_MISC_INDEX 1 | 51 | #define QETH_DBF_MISC_PAGES 2 |
52 | #define QETH_DBF_MISC_NR_AREAS 1 | 52 | #define QETH_DBF_MISC_NR_AREAS 1 |
53 | #define QETH_DBF_MISC_LEVEL 2 | 53 | #define QETH_DBF_MISC_LEVEL 2 |
54 | 54 | ||
55 | #define QETH_DBF_DATA_NAME "qeth_data" | 55 | #define QETH_DBF_DATA_NAME "qeth_data" |
56 | #define QETH_DBF_DATA_LEN 96 | 56 | #define QETH_DBF_DATA_LEN 96 |
57 | #define QETH_DBF_DATA_INDEX 3 | 57 | #define QETH_DBF_DATA_PAGES 8 |
58 | #define QETH_DBF_DATA_NR_AREAS 1 | 58 | #define QETH_DBF_DATA_NR_AREAS 1 |
59 | #define QETH_DBF_DATA_LEVEL 2 | 59 | #define QETH_DBF_DATA_LEVEL 2 |
60 | 60 | ||
61 | #define QETH_DBF_CONTROL_NAME "qeth_control" | 61 | #define QETH_DBF_CONTROL_NAME "qeth_control" |
62 | #define QETH_DBF_CONTROL_LEN 256 | 62 | #define QETH_DBF_CONTROL_LEN 256 |
63 | #define QETH_DBF_CONTROL_INDEX 3 | 63 | #define QETH_DBF_CONTROL_PAGES 8 |
64 | #define QETH_DBF_CONTROL_NR_AREAS 2 | 64 | #define QETH_DBF_CONTROL_NR_AREAS 2 |
65 | #define QETH_DBF_CONTROL_LEVEL 5 | 65 | #define QETH_DBF_CONTROL_LEVEL 5 |
66 | 66 | ||
67 | #define QETH_DBF_TRACE_NAME "qeth_trace" | 67 | #define QETH_DBF_TRACE_NAME "qeth_trace" |
68 | #define QETH_DBF_TRACE_LEN 8 | 68 | #define QETH_DBF_TRACE_LEN 8 |
69 | #define QETH_DBF_TRACE_INDEX 2 | 69 | #define QETH_DBF_TRACE_PAGES 4 |
70 | #define QETH_DBF_TRACE_NR_AREAS 2 | 70 | #define QETH_DBF_TRACE_NR_AREAS 2 |
71 | #define QETH_DBF_TRACE_LEVEL 3 | 71 | #define QETH_DBF_TRACE_LEVEL 3 |
72 | extern debug_info_t *qeth_dbf_trace; | 72 | extern debug_info_t *qeth_dbf_trace; |
73 | 73 | ||
74 | #define QETH_DBF_SENSE_NAME "qeth_sense" | 74 | #define QETH_DBF_SENSE_NAME "qeth_sense" |
75 | #define QETH_DBF_SENSE_LEN 64 | 75 | #define QETH_DBF_SENSE_LEN 64 |
76 | #define QETH_DBF_SENSE_INDEX 1 | 76 | #define QETH_DBF_SENSE_PAGES 2 |
77 | #define QETH_DBF_SENSE_NR_AREAS 1 | 77 | #define QETH_DBF_SENSE_NR_AREAS 1 |
78 | #define QETH_DBF_SENSE_LEVEL 2 | 78 | #define QETH_DBF_SENSE_LEVEL 2 |
79 | 79 | ||
80 | #define QETH_DBF_QERR_NAME "qeth_qerr" | 80 | #define QETH_DBF_QERR_NAME "qeth_qerr" |
81 | #define QETH_DBF_QERR_LEN 8 | 81 | #define QETH_DBF_QERR_LEN 8 |
82 | #define QETH_DBF_QERR_INDEX 1 | 82 | #define QETH_DBF_QERR_PAGES 2 |
83 | #define QETH_DBF_QERR_NR_AREAS 2 | 83 | #define QETH_DBF_QERR_NR_AREAS 2 |
84 | #define QETH_DBF_QERR_LEVEL 2 | 84 | #define QETH_DBF_QERR_LEVEL 2 |
85 | 85 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 208127a5033a..3cb88c770037 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -7639,31 +7639,31 @@ static int | |||
7639 | qeth_register_dbf_views(void) | 7639 | qeth_register_dbf_views(void) |
7640 | { | 7640 | { |
7641 | qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME, | 7641 | qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME, |
7642 | QETH_DBF_SETUP_INDEX, | 7642 | QETH_DBF_SETUP_PAGES, |
7643 | QETH_DBF_SETUP_NR_AREAS, | 7643 | QETH_DBF_SETUP_NR_AREAS, |
7644 | QETH_DBF_SETUP_LEN); | 7644 | QETH_DBF_SETUP_LEN); |
7645 | qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME, | 7645 | qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME, |
7646 | QETH_DBF_MISC_INDEX, | 7646 | QETH_DBF_MISC_PAGES, |
7647 | QETH_DBF_MISC_NR_AREAS, | 7647 | QETH_DBF_MISC_NR_AREAS, |
7648 | QETH_DBF_MISC_LEN); | 7648 | QETH_DBF_MISC_LEN); |
7649 | qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME, | 7649 | qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME, |
7650 | QETH_DBF_DATA_INDEX, | 7650 | QETH_DBF_DATA_PAGES, |
7651 | QETH_DBF_DATA_NR_AREAS, | 7651 | QETH_DBF_DATA_NR_AREAS, |
7652 | QETH_DBF_DATA_LEN); | 7652 | QETH_DBF_DATA_LEN); |
7653 | qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME, | 7653 | qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME, |
7654 | QETH_DBF_CONTROL_INDEX, | 7654 | QETH_DBF_CONTROL_PAGES, |
7655 | QETH_DBF_CONTROL_NR_AREAS, | 7655 | QETH_DBF_CONTROL_NR_AREAS, |
7656 | QETH_DBF_CONTROL_LEN); | 7656 | QETH_DBF_CONTROL_LEN); |
7657 | qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME, | 7657 | qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME, |
7658 | QETH_DBF_SENSE_INDEX, | 7658 | QETH_DBF_SENSE_PAGES, |
7659 | QETH_DBF_SENSE_NR_AREAS, | 7659 | QETH_DBF_SENSE_NR_AREAS, |
7660 | QETH_DBF_SENSE_LEN); | 7660 | QETH_DBF_SENSE_LEN); |
7661 | qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME, | 7661 | qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME, |
7662 | QETH_DBF_QERR_INDEX, | 7662 | QETH_DBF_QERR_PAGES, |
7663 | QETH_DBF_QERR_NR_AREAS, | 7663 | QETH_DBF_QERR_NR_AREAS, |
7664 | QETH_DBF_QERR_LEN); | 7664 | QETH_DBF_QERR_LEN); |
7665 | qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME, | 7665 | qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME, |
7666 | QETH_DBF_TRACE_INDEX, | 7666 | QETH_DBF_TRACE_PAGES, |
7667 | QETH_DBF_TRACE_NR_AREAS, | 7667 | QETH_DBF_TRACE_NR_AREAS, |
7668 | QETH_DBF_TRACE_LEN); | 7668 | QETH_DBF_TRACE_LEN); |
7669 | 7669 | ||
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 1e3f7f3c662f..d6469baa7e16 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -138,7 +138,7 @@ static void __exit | |||
138 | smsg_exit(void) | 138 | smsg_exit(void) |
139 | { | 139 | { |
140 | if (smsg_handle > 0) { | 140 | if (smsg_handle > 0) { |
141 | cpcmd("SET SMSG OFF", 0, 0); | 141 | cpcmd("SET SMSG OFF", NULL, 0, NULL); |
142 | iucv_sever(smsg_pathid, 0); | 142 | iucv_sever(smsg_pathid, 0); |
143 | iucv_unregister_program(smsg_handle); | 143 | iucv_unregister_program(smsg_handle); |
144 | driver_unregister(&smsg_driver); | 144 | driver_unregister(&smsg_driver); |
@@ -177,7 +177,7 @@ smsg_init(void) | |||
177 | smsg_handle = 0; | 177 | smsg_handle = 0; |
178 | return -EIO; | 178 | return -EIO; |
179 | } | 179 | } |
180 | cpcmd("SET SMSG IUCV", 0, 0); | 180 | cpcmd("SET SMSG IUCV", NULL, 0, NULL); |
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
183 | 183 | ||
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index ffa996c8a908..5bb255e02acc 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -31,14 +31,14 @@ extern void css_reiterate_subchannels(void); | |||
31 | extern struct workqueue_struct *slow_path_wq; | 31 | extern struct workqueue_struct *slow_path_wq; |
32 | extern struct work_struct slow_path_work; | 32 | extern struct work_struct slow_path_work; |
33 | 33 | ||
34 | static void | 34 | static NORET_TYPE void |
35 | s390_handle_damage(char *msg) | 35 | s390_handle_damage(char *msg) |
36 | { | 36 | { |
37 | printk(KERN_EMERG "%s\n", msg); | ||
38 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
39 | smp_send_stop(); | 38 | smp_send_stop(); |
40 | #endif | 39 | #endif |
41 | disabled_wait((unsigned long) __builtin_return_address(0)); | 40 | disabled_wait((unsigned long) __builtin_return_address(0)); |
41 | for(;;); | ||
42 | } | 42 | } |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -122,40 +122,39 @@ repeat: | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | struct mcck_struct { | ||
126 | int kill_task; | ||
127 | int channel_report; | ||
128 | int warning; | ||
129 | unsigned long long mcck_code; | ||
130 | }; | ||
131 | |||
132 | static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck); | ||
133 | |||
125 | /* | 134 | /* |
126 | * machine check handler. | 135 | * Main machine check handler function. Will be called with interrupts enabled |
136 | * or disabled and machine checks enabled or disabled. | ||
127 | */ | 137 | */ |
128 | void | 138 | void |
129 | s390_do_machine_check(void) | 139 | s390_handle_mcck(void) |
130 | { | 140 | { |
131 | struct mci *mci; | 141 | unsigned long flags; |
132 | 142 | struct mcck_struct mcck; | |
133 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | ||
134 | 143 | ||
135 | if (mci->sd) /* system damage */ | 144 | /* |
136 | s390_handle_damage("received system damage machine check\n"); | 145 | * Disable machine checks and get the current state of accumulated |
146 | * machine checks. Afterwards delete the old state and enable machine | ||
147 | * checks again. | ||
148 | */ | ||
149 | local_irq_save(flags); | ||
150 | local_mcck_disable(); | ||
151 | mcck = __get_cpu_var(cpu_mcck); | ||
152 | memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct)); | ||
153 | clear_thread_flag(TIF_MCCK_PENDING); | ||
154 | local_mcck_enable(); | ||
155 | local_irq_restore(flags); | ||
137 | 156 | ||
138 | if (mci->pd) /* instruction processing damage */ | 157 | if (mcck.channel_report) |
139 | s390_handle_damage("received instruction processing " | ||
140 | "damage machine check\n"); | ||
141 | |||
142 | if (mci->se) /* storage error uncorrected */ | ||
143 | s390_handle_damage("received storage error uncorrected " | ||
144 | "machine check\n"); | ||
145 | |||
146 | if (mci->sc) /* storage error corrected */ | ||
147 | printk(KERN_WARNING | ||
148 | "received storage error corrected machine check\n"); | ||
149 | |||
150 | if (mci->ke) /* storage key-error uncorrected */ | ||
151 | s390_handle_damage("received storage key-error uncorrected " | ||
152 | "machine check\n"); | ||
153 | |||
154 | if (mci->ds && mci->fa) /* storage degradation */ | ||
155 | s390_handle_damage("received storage degradation machine " | ||
156 | "check\n"); | ||
157 | |||
158 | if (mci->cp) /* channel report word pending */ | ||
159 | up(&m_sem); | 158 | up(&m_sem); |
160 | 159 | ||
161 | #ifdef CONFIG_MACHCHK_WARNING | 160 | #ifdef CONFIG_MACHCHK_WARNING |
@@ -168,7 +167,7 @@ s390_do_machine_check(void) | |||
168 | * On VM we only get one interrupt per virtally presented machinecheck. | 167 | * On VM we only get one interrupt per virtally presented machinecheck. |
169 | * Though one suffices, we may get one interrupt per (virtual) processor. | 168 | * Though one suffices, we may get one interrupt per (virtual) processor. |
170 | */ | 169 | */ |
171 | if (mci->w) { /* WARNING pending ? */ | 170 | if (mcck.warning) { /* WARNING pending ? */ |
172 | static int mchchk_wng_posted = 0; | 171 | static int mchchk_wng_posted = 0; |
173 | /* | 172 | /* |
174 | * Use single machine clear, as we cannot handle smp right now | 173 | * Use single machine clear, as we cannot handle smp right now |
@@ -178,6 +177,261 @@ s390_do_machine_check(void) | |||
178 | kill_proc(1, SIGPWR, 1); | 177 | kill_proc(1, SIGPWR, 1); |
179 | } | 178 | } |
180 | #endif | 179 | #endif |
180 | |||
181 | if (mcck.kill_task) { | ||
182 | local_irq_enable(); | ||
183 | printk(KERN_EMERG "mcck: Terminating task because of machine " | ||
184 | "malfunction (code 0x%016llx).\n", mcck.mcck_code); | ||
185 | printk(KERN_EMERG "mcck: task: %s, pid: %d.\n", | ||
186 | current->comm, current->pid); | ||
187 | do_exit(SIGSEGV); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * returns 0 if all registers could be validated | ||
193 | * returns 1 otherwise | ||
194 | */ | ||
195 | static int | ||
196 | s390_revalidate_registers(struct mci *mci) | ||
197 | { | ||
198 | int kill_task; | ||
199 | u64 tmpclock; | ||
200 | u64 zero; | ||
201 | void *fpt_save_area, *fpt_creg_save_area; | ||
202 | |||
203 | kill_task = 0; | ||
204 | zero = 0; | ||
205 | /* General purpose registers */ | ||
206 | if (!mci->gr) | ||
207 | /* | ||
208 | * General purpose registers couldn't be restored and have | ||
209 | * unknown contents. Process needs to be terminated. | ||
210 | */ | ||
211 | kill_task = 1; | ||
212 | |||
213 | /* Revalidate floating point registers */ | ||
214 | if (!mci->fp) | ||
215 | /* | ||
216 | * Floating point registers can't be restored and | ||
217 | * therefore the process needs to be terminated. | ||
218 | */ | ||
219 | kill_task = 1; | ||
220 | |||
221 | #ifndef __s390x__ | ||
222 | asm volatile("ld 0,0(%0)\n" | ||
223 | "ld 2,8(%0)\n" | ||
224 | "ld 4,16(%0)\n" | ||
225 | "ld 6,24(%0)" | ||
226 | : : "a" (&S390_lowcore.floating_pt_save_area)); | ||
227 | #endif | ||
228 | |||
229 | if (MACHINE_HAS_IEEE) { | ||
230 | #ifdef __s390x__ | ||
231 | fpt_save_area = &S390_lowcore.floating_pt_save_area; | ||
232 | fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area; | ||
233 | #else | ||
234 | fpt_save_area = (void *) S390_lowcore.extended_save_area_addr; | ||
235 | fpt_creg_save_area = fpt_save_area+128; | ||
236 | #endif | ||
237 | /* Floating point control register */ | ||
238 | if (!mci->fc) { | ||
239 | /* | ||
240 | * Floating point control register can't be restored. | ||
241 | * Task will be terminated. | ||
242 | */ | ||
243 | asm volatile ("lfpc 0(%0)" : : "a" (&zero)); | ||
244 | kill_task = 1; | ||
245 | |||
246 | } | ||
247 | else | ||
248 | asm volatile ( | ||
249 | "lfpc 0(%0)" | ||
250 | : : "a" (fpt_creg_save_area)); | ||
251 | |||
252 | asm volatile("ld 0,0(%0)\n" | ||
253 | "ld 1,8(%0)\n" | ||
254 | "ld 2,16(%0)\n" | ||
255 | "ld 3,24(%0)\n" | ||
256 | "ld 4,32(%0)\n" | ||
257 | "ld 5,40(%0)\n" | ||
258 | "ld 6,48(%0)\n" | ||
259 | "ld 7,56(%0)\n" | ||
260 | "ld 8,64(%0)\n" | ||
261 | "ld 9,72(%0)\n" | ||
262 | "ld 10,80(%0)\n" | ||
263 | "ld 11,88(%0)\n" | ||
264 | "ld 12,96(%0)\n" | ||
265 | "ld 13,104(%0)\n" | ||
266 | "ld 14,112(%0)\n" | ||
267 | "ld 15,120(%0)\n" | ||
268 | : : "a" (fpt_save_area)); | ||
269 | } | ||
270 | |||
271 | /* Revalidate access registers */ | ||
272 | asm volatile("lam 0,15,0(%0)" | ||
273 | : : "a" (&S390_lowcore.access_regs_save_area)); | ||
274 | if (!mci->ar) | ||
275 | /* | ||
276 | * Access registers have unknown contents. | ||
277 | * Terminating task. | ||
278 | */ | ||
279 | kill_task = 1; | ||
280 | |||
281 | /* Revalidate control registers */ | ||
282 | if (!mci->cr) | ||
283 | /* | ||
284 | * Control registers have unknown contents. | ||
285 | * Can't recover and therefore stopping machine. | ||
286 | */ | ||
287 | s390_handle_damage("invalid control registers."); | ||
288 | else | ||
289 | #ifdef __s390x__ | ||
290 | asm volatile("lctlg 0,15,0(%0)" | ||
291 | : : "a" (&S390_lowcore.cregs_save_area)); | ||
292 | #else | ||
293 | asm volatile("lctl 0,15,0(%0)" | ||
294 | : : "a" (&S390_lowcore.cregs_save_area)); | ||
295 | #endif | ||
296 | |||
297 | /* | ||
298 | * We don't even try to revalidate the TOD register, since we simply | ||
299 | * can't write something sensible into that register. | ||
300 | */ | ||
301 | |||
302 | #ifdef __s390x__ | ||
303 | /* | ||
304 | * See if we can revalidate the TOD programmable register with its | ||
305 | * old contents (should be zero) otherwise set it to zero. | ||
306 | */ | ||
307 | if (!mci->pr) | ||
308 | asm volatile("sr 0,0\n" | ||
309 | "sckpf" | ||
310 | : : : "0", "cc"); | ||
311 | else | ||
312 | asm volatile( | ||
313 | "l 0,0(%0)\n" | ||
314 | "sckpf" | ||
315 | : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc"); | ||
316 | #endif | ||
317 | |||
318 | /* Revalidate clock comparator register */ | ||
319 | asm volatile ("stck 0(%1)\n" | ||
320 | "sckc 0(%1)" | ||
321 | : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); | ||
322 | |||
323 | /* Check if old PSW is valid */ | ||
324 | if (!mci->wp) | ||
325 | /* | ||
326 | * Can't tell if we come from user or kernel mode | ||
327 | * -> stopping machine. | ||
328 | */ | ||
329 | s390_handle_damage("old psw invalid."); | ||
330 | |||
331 | if (!mci->ms || !mci->pm || !mci->ia) | ||
332 | kill_task = 1; | ||
333 | |||
334 | return kill_task; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * machine check handler. | ||
339 | */ | ||
340 | void | ||
341 | s390_do_machine_check(struct pt_regs *regs) | ||
342 | { | ||
343 | struct mci *mci; | ||
344 | struct mcck_struct *mcck; | ||
345 | int umode; | ||
346 | |||
347 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | ||
348 | mcck = &__get_cpu_var(cpu_mcck); | ||
349 | umode = user_mode(regs); | ||
350 | |||
351 | if (mci->sd) | ||
352 | /* System damage -> stopping machine */ | ||
353 | s390_handle_damage("received system damage machine check."); | ||
354 | |||
355 | if (mci->pd) { | ||
356 | if (mci->b) { | ||
357 | /* Processing backup -> verify if we can survive this */ | ||
358 | u64 z_mcic, o_mcic, t_mcic; | ||
359 | #ifdef __s390x__ | ||
360 | z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29); | ||
361 | o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 | | ||
362 | 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 | | ||
363 | 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 | | ||
364 | 1ULL<<16); | ||
365 | #else | ||
366 | z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 | | ||
367 | 1ULL<<29); | ||
368 | o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 | | ||
369 | 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 | | ||
370 | 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16); | ||
371 | #endif | ||
372 | t_mcic = *(u64 *)mci; | ||
373 | |||
374 | if (((t_mcic & z_mcic) != 0) || | ||
375 | ((t_mcic & o_mcic) != o_mcic)) { | ||
376 | s390_handle_damage("processing backup machine " | ||
377 | "check with damage."); | ||
378 | } | ||
379 | if (!umode) | ||
380 | s390_handle_damage("processing backup machine " | ||
381 | "check in kernel mode."); | ||
382 | mcck->kill_task = 1; | ||
383 | mcck->mcck_code = *(unsigned long long *) mci; | ||
384 | } | ||
385 | else { | ||
386 | /* Processing damage -> stopping machine */ | ||
387 | s390_handle_damage("received instruction processing " | ||
388 | "damage machine check."); | ||
389 | } | ||
390 | } | ||
391 | if (s390_revalidate_registers(mci)) { | ||
392 | if (umode) { | ||
393 | /* | ||
394 | * Couldn't restore all register contents while in | ||
395 | * user mode -> mark task for termination. | ||
396 | */ | ||
397 | mcck->kill_task = 1; | ||
398 | mcck->mcck_code = *(unsigned long long *) mci; | ||
399 | set_thread_flag(TIF_MCCK_PENDING); | ||
400 | } | ||
401 | else | ||
402 | /* | ||
403 | * Couldn't restore all register contents while in | ||
404 | * kernel mode -> stopping machine. | ||
405 | */ | ||
406 | s390_handle_damage("unable to revalidate registers."); | ||
407 | } | ||
408 | |||
409 | if (mci->se) | ||
410 | /* Storage error uncorrected */ | ||
411 | s390_handle_damage("received storage error uncorrected " | ||
412 | "machine check."); | ||
413 | |||
414 | if (mci->ke) | ||
415 | /* Storage key-error uncorrected */ | ||
416 | s390_handle_damage("received storage key-error uncorrected " | ||
417 | "machine check."); | ||
418 | |||
419 | if (mci->ds && mci->fa) | ||
420 | /* Storage degradation */ | ||
421 | s390_handle_damage("received storage degradation machine " | ||
422 | "check."); | ||
423 | |||
424 | if (mci->cp) { | ||
425 | /* Channel report word pending */ | ||
426 | mcck->channel_report = 1; | ||
427 | set_thread_flag(TIF_MCCK_PENDING); | ||
428 | } | ||
429 | |||
430 | if (mci->w) { | ||
431 | /* Warning pending */ | ||
432 | mcck->warning = 1; | ||
433 | set_thread_flag(TIF_MCCK_PENDING); | ||
434 | } | ||
181 | } | 435 | } |
182 | 436 | ||
183 | /* | 437 | /* |
@@ -189,9 +443,8 @@ static int | |||
189 | machine_check_init(void) | 443 | machine_check_init(void) |
190 | { | 444 | { |
191 | init_MUTEX_LOCKED(&m_sem); | 445 | init_MUTEX_LOCKED(&m_sem); |
192 | ctl_clear_bit(14, 25); /* disable damage MCH */ | 446 | ctl_clear_bit(14, 25); /* disable external damage MCH */ |
193 | ctl_set_bit(14, 26); /* enable degradation MCH */ | 447 | ctl_set_bit(14, 27); /* enable system recovery MCH */ |
194 | ctl_set_bit(14, 27); /* enable system recovery MCH */ | ||
195 | #ifdef CONFIG_MACHCHK_WARNING | 448 | #ifdef CONFIG_MACHCHK_WARNING |
196 | ctl_set_bit(14, 24); /* enable warning MCH */ | 449 | ctl_set_bit(14, 24); /* enable warning MCH */ |
197 | #endif | 450 | #endif |
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h index 7e26f0f1b0dc..4eaa70179182 100644 --- a/drivers/s390/s390mach.h +++ b/drivers/s390/s390mach.h | |||
@@ -16,20 +16,45 @@ struct mci { | |||
16 | __u32 sd : 1; /* 00 system damage */ | 16 | __u32 sd : 1; /* 00 system damage */ |
17 | __u32 pd : 1; /* 01 instruction-processing damage */ | 17 | __u32 pd : 1; /* 01 instruction-processing damage */ |
18 | __u32 sr : 1; /* 02 system recovery */ | 18 | __u32 sr : 1; /* 02 system recovery */ |
19 | __u32 to_be_defined_1 : 4; /* 03-06 */ | 19 | __u32 to_be_defined_1 : 1; /* 03 */ |
20 | __u32 cd : 1; /* 04 timing-facility damage */ | ||
21 | __u32 ed : 1; /* 05 external damage */ | ||
22 | __u32 to_be_defined_2 : 1; /* 06 */ | ||
20 | __u32 dg : 1; /* 07 degradation */ | 23 | __u32 dg : 1; /* 07 degradation */ |
21 | __u32 w : 1; /* 08 warning pending */ | 24 | __u32 w : 1; /* 08 warning pending */ |
22 | __u32 cp : 1; /* 09 channel-report pending */ | 25 | __u32 cp : 1; /* 09 channel-report pending */ |
23 | __u32 to_be_defined_2 : 6; /* 10-15 */ | 26 | __u32 sp : 1; /* 10 service-processor damage */ |
27 | __u32 ck : 1; /* 11 channel-subsystem damage */ | ||
28 | __u32 to_be_defined_3 : 2; /* 12-13 */ | ||
29 | __u32 b : 1; /* 14 backed up */ | ||
30 | __u32 to_be_defined_4 : 1; /* 15 */ | ||
24 | __u32 se : 1; /* 16 storage error uncorrected */ | 31 | __u32 se : 1; /* 16 storage error uncorrected */ |
25 | __u32 sc : 1; /* 17 storage error corrected */ | 32 | __u32 sc : 1; /* 17 storage error corrected */ |
26 | __u32 ke : 1; /* 18 storage-key error uncorrected */ | 33 | __u32 ke : 1; /* 18 storage-key error uncorrected */ |
27 | __u32 ds : 1; /* 19 storage degradation */ | 34 | __u32 ds : 1; /* 19 storage degradation */ |
28 | __u32 to_be_defined_3 : 4; /* 20-23 */ | 35 | __u32 wp : 1; /* 20 psw mwp validity */ |
36 | __u32 ms : 1; /* 21 psw mask and key validity */ | ||
37 | __u32 pm : 1; /* 22 psw program mask and cc validity */ | ||
38 | __u32 ia : 1; /* 23 psw instruction address validity */ | ||
29 | __u32 fa : 1; /* 24 failing storage address validity */ | 39 | __u32 fa : 1; /* 24 failing storage address validity */ |
30 | __u32 to_be_defined_4 : 7; /* 25-31 */ | 40 | __u32 to_be_defined_5 : 1; /* 25 */ |
41 | __u32 ec : 1; /* 26 external damage code validity */ | ||
42 | __u32 fp : 1; /* 27 floating point register validity */ | ||
43 | __u32 gr : 1; /* 28 general register validity */ | ||
44 | __u32 cr : 1; /* 29 control register validity */ | ||
45 | __u32 to_be_defined_6 : 1; /* 30 */ | ||
46 | __u32 st : 1; /* 31 storage logical validity */ | ||
31 | __u32 ie : 1; /* 32 indirect storage error */ | 47 | __u32 ie : 1; /* 32 indirect storage error */ |
32 | __u32 to_be_defined_5 : 31; /* 33-63 */ | 48 | __u32 ar : 1; /* 33 access register validity */ |
49 | __u32 da : 1; /* 34 delayed access exception */ | ||
50 | __u32 to_be_defined_7 : 7; /* 35-41 */ | ||
51 | __u32 pr : 1; /* 42 tod programmable register validity */ | ||
52 | __u32 fc : 1; /* 43 fp control register validity */ | ||
53 | __u32 ap : 1; /* 44 ancillary report */ | ||
54 | __u32 to_be_defined_8 : 1; /* 45 */ | ||
55 | __u32 ct : 1; /* 46 cpu timer validity */ | ||
56 | __u32 cc : 1; /* 47 clock comparator validity */ | ||
57 | __u32 to_be_defined_9 : 16; /* 47-63 */ | ||
33 | }; | 58 | }; |
34 | 59 | ||
35 | /* | 60 | /* |