aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/monreader.c1
-rw-r--r--drivers/s390/char/sclp_async.c47
-rw-r--r--drivers/s390/char/sclp_quiesce.c48
-rw-r--r--drivers/s390/net/smsgiucv.c7
-rw-r--r--drivers/s390/scsi/zfcp_aux.c11
-rw-r--r--drivers/s390/scsi/zfcp_erp.c22
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fc.c11
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c13
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c1
10 files changed, 102 insertions, 60 deletions
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 89ece1c235aa..66e21dd23154 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -357,6 +357,7 @@ static int mon_close(struct inode *inode, struct file *filp)
357 atomic_set(&monpriv->msglim_count, 0); 357 atomic_set(&monpriv->msglim_count, 0);
358 monpriv->write_index = 0; 358 monpriv->write_index = 0;
359 monpriv->read_index = 0; 359 monpriv->read_index = 0;
360 dev_set_drvdata(monreader_device, NULL);
360 361
361 for (i = 0; i < MON_MSGLIM; i++) 362 for (i = 0; i < MON_MSGLIM; i++)
362 kfree(monpriv->msg_array[i]); 363 kfree(monpriv->msg_array[i]);
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index a4f68e5b9c96..b44462a6c6d3 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -26,7 +26,6 @@ static struct sclp_async_sccb *sccb;
26static int sclp_async_send_wait(char *message); 26static int sclp_async_send_wait(char *message);
27static struct ctl_table_header *callhome_sysctl_header; 27static struct ctl_table_header *callhome_sysctl_header;
28static DEFINE_SPINLOCK(sclp_async_lock); 28static DEFINE_SPINLOCK(sclp_async_lock);
29static char nodename[64];
30#define SCLP_NORMAL_WRITE 0x00 29#define SCLP_NORMAL_WRITE 0x00
31 30
32struct async_evbuf { 31struct async_evbuf {
@@ -52,9 +51,10 @@ static struct sclp_register sclp_async_register = {
52static int call_home_on_panic(struct notifier_block *self, 51static int call_home_on_panic(struct notifier_block *self,
53 unsigned long event, void *data) 52 unsigned long event, void *data)
54{ 53{
55 strncat(data, nodename, strlen(nodename)); 54 strncat(data, init_utsname()->nodename,
56 sclp_async_send_wait(data); 55 sizeof(init_utsname()->nodename));
57 return NOTIFY_DONE; 56 sclp_async_send_wait(data);
57 return NOTIFY_DONE;
58} 58}
59 59
60static struct notifier_block call_home_panic_nb = { 60static struct notifier_block call_home_panic_nb = {
@@ -68,15 +68,14 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
68{ 68{
69 unsigned long val; 69 unsigned long val;
70 int len, rc; 70 int len, rc;
71 char buf[2]; 71 char buf[3];
72 72
73 if (!*count | (*ppos && !write)) { 73 if (!*count || (*ppos && !write)) {
74 *count = 0; 74 *count = 0;
75 return 0; 75 return 0;
76 } 76 }
77 if (!write) { 77 if (!write) {
78 len = sprintf(buf, "%d\n", callhome_enabled); 78 len = snprintf(buf, sizeof(buf), "%d\n", callhome_enabled);
79 buf[len] = '\0';
80 rc = copy_to_user(buffer, buf, sizeof(buf)); 79 rc = copy_to_user(buffer, buf, sizeof(buf));
81 if (rc != 0) 80 if (rc != 0)
82 return -EFAULT; 81 return -EFAULT;
@@ -171,39 +170,29 @@ static int __init sclp_async_init(void)
171 rc = sclp_register(&sclp_async_register); 170 rc = sclp_register(&sclp_async_register);
172 if (rc) 171 if (rc)
173 return rc; 172 return rc;
174 callhome_sysctl_header = register_sysctl_table(kern_dir_table); 173 rc = -EOPNOTSUPP;
175 if (!callhome_sysctl_header) { 174 if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK))
176 rc = -ENOMEM;
177 goto out_sclp;
178 }
179 if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) {
180 rc = -EOPNOTSUPP;
181 goto out_sclp; 175 goto out_sclp;
182 }
183 rc = -ENOMEM; 176 rc = -ENOMEM;
177 callhome_sysctl_header = register_sysctl_table(kern_dir_table);
178 if (!callhome_sysctl_header)
179 goto out_sclp;
184 request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); 180 request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL);
185 if (!request)
186 goto out_sys;
187 sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 181 sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
188 if (!sccb) 182 if (!request || !sccb)
189 goto out_mem; 183 goto out_mem;
190 rc = atomic_notifier_chain_register(&panic_notifier_list, 184 rc = atomic_notifier_chain_register(&panic_notifier_list,
191 &call_home_panic_nb); 185 &call_home_panic_nb);
192 if (rc) 186 if (!rc)
193 goto out_mem; 187 goto out;
194
195 strncpy(nodename, init_utsname()->nodename, 64);
196 return 0;
197
198out_mem: 188out_mem:
199 kfree(request); 189 kfree(request);
200 free_page((unsigned long) sccb); 190 free_page((unsigned long) sccb);
201out_sys:
202 unregister_sysctl_table(callhome_sysctl_header); 191 unregister_sysctl_table(callhome_sysctl_header);
203out_sclp: 192out_sclp:
204 sclp_unregister(&sclp_async_register); 193 sclp_unregister(&sclp_async_register);
194out:
205 return rc; 195 return rc;
206
207} 196}
208module_init(sclp_async_init); 197module_init(sclp_async_init);
209 198
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 84c191c1cd62..05909a7df8b3 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -20,9 +20,12 @@
20 20
21#include "sclp.h" 21#include "sclp.h"
22 22
23static void (*old_machine_restart)(char *);
24static void (*old_machine_halt)(void);
25static void (*old_machine_power_off)(void);
26
23/* Shutdown handler. Signal completion of shutdown by loading special PSW. */ 27/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
24static void 28static void do_machine_quiesce(void)
25do_machine_quiesce(void)
26{ 29{
27 psw_t quiesce_psw; 30 psw_t quiesce_psw;
28 31
@@ -33,23 +36,48 @@ do_machine_quiesce(void)
33} 36}
34 37
35/* Handler for quiesce event. Start shutdown procedure. */ 38/* Handler for quiesce event. Start shutdown procedure. */
36static void 39static void sclp_quiesce_handler(struct evbuf_header *evbuf)
37sclp_quiesce_handler(struct evbuf_header *evbuf)
38{ 40{
39 _machine_restart = (void *) do_machine_quiesce; 41 if (_machine_restart != (void *) do_machine_quiesce) {
40 _machine_halt = do_machine_quiesce; 42 old_machine_restart = _machine_restart;
41 _machine_power_off = do_machine_quiesce; 43 old_machine_halt = _machine_halt;
44 old_machine_power_off = _machine_power_off;
45 _machine_restart = (void *) do_machine_quiesce;
46 _machine_halt = do_machine_quiesce;
47 _machine_power_off = do_machine_quiesce;
48 }
42 ctrl_alt_del(); 49 ctrl_alt_del();
43} 50}
44 51
52/* Undo machine restart/halt/power_off modification on resume */
53static void sclp_quiesce_pm_event(struct sclp_register *reg,
54 enum sclp_pm_event sclp_pm_event)
55{
56 switch (sclp_pm_event) {
57 case SCLP_PM_EVENT_RESTORE:
58 if (old_machine_restart) {
59 _machine_restart = old_machine_restart;
60 _machine_halt = old_machine_halt;
61 _machine_power_off = old_machine_power_off;
62 old_machine_restart = NULL;
63 old_machine_halt = NULL;
64 old_machine_power_off = NULL;
65 }
66 break;
67 case SCLP_PM_EVENT_FREEZE:
68 case SCLP_PM_EVENT_THAW:
69 break;
70 }
71}
72
45static struct sclp_register sclp_quiesce_event = { 73static struct sclp_register sclp_quiesce_event = {
46 .receive_mask = EVTYP_SIGQUIESCE_MASK, 74 .receive_mask = EVTYP_SIGQUIESCE_MASK,
47 .receiver_fn = sclp_quiesce_handler 75 .receiver_fn = sclp_quiesce_handler,
76 .pm_event_fn = sclp_quiesce_pm_event
48}; 77};
49 78
50/* Initialize quiesce driver. */ 79/* Initialize quiesce driver. */
51static int __init 80static int __init sclp_quiesce_init(void)
52sclp_quiesce_init(void)
53{ 81{
54 return sclp_register(&sclp_quiesce_event); 82 return sclp_register(&sclp_quiesce_event);
55} 83}
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 102000d1af6f..3012355f8304 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -158,7 +158,12 @@ static int smsg_pm_restore_thaw(struct device *dev)
158 smsg_path->flags = 0; 158 smsg_path->flags = 0;
159 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", 159 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
160 NULL, NULL, NULL); 160 NULL, NULL, NULL);
161 printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc); 161#ifdef CONFIG_PM_DEBUG
162 if (rc)
163 printk(KERN_ERR
164 "iucv_path_connect returned with rc %i\n", rc);
165#endif
166 cpcmd("SET SMSG IUCV", NULL, 0, NULL);
162 } 167 }
163 return 0; 168 return 0;
164} 169}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 0f79f3af4f54..2889e5f2dfd3 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -128,12 +128,13 @@ out_ccwdev:
128static void __init zfcp_init_device_setup(char *devstr) 128static void __init zfcp_init_device_setup(char *devstr)
129{ 129{
130 char *token; 130 char *token;
131 char *str; 131 char *str, *str_saved;
132 char busid[ZFCP_BUS_ID_SIZE]; 132 char busid[ZFCP_BUS_ID_SIZE];
133 u64 wwpn, lun; 133 u64 wwpn, lun;
134 134
135 /* duplicate devstr and keep the original for sysfs presentation*/ 135 /* duplicate devstr and keep the original for sysfs presentation*/
136 str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); 136 str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
137 str = str_saved;
137 if (!str) 138 if (!str)
138 return; 139 return;
139 140
@@ -152,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr)
152 if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) 153 if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun))
153 goto err_out; 154 goto err_out;
154 155
155 kfree(str); 156 kfree(str_saved);
156 zfcp_init_device_configure(busid, wwpn, lun); 157 zfcp_init_device_configure(busid, wwpn, lun);
157 return; 158 return;
158 159
159 err_out: 160err_out:
160 kfree(str); 161 kfree(str_saved);
161 pr_err("%s is not a valid SCSI device\n", devstr); 162 pr_err("%s is not a valid SCSI device\n", devstr);
162} 163}
163 164
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 73d366ba31e5..f73e2180f333 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
858 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) 858 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
859 return zfcp_erp_open_ptp_port(act); 859 return zfcp_erp_open_ptp_port(act);
860 if (!port->d_id) { 860 if (!port->d_id) {
861 zfcp_port_get(port); 861 zfcp_fc_trigger_did_lookup(port);
862 if (!queue_work(adapter->work_queue,
863 &port->gid_pn_work))
864 zfcp_port_put(port);
865 return ZFCP_ERP_EXIT; 862 return ZFCP_ERP_EXIT;
866 } 863 }
867 return zfcp_erp_port_strategy_open_port(act); 864 return zfcp_erp_port_strategy_open_port(act);
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
869 case ZFCP_ERP_STEP_PORT_OPENING: 866 case ZFCP_ERP_STEP_PORT_OPENING:
870 /* D_ID might have changed during open */ 867 /* D_ID might have changed during open */
871 if (p_status & ZFCP_STATUS_COMMON_OPEN) { 868 if (p_status & ZFCP_STATUS_COMMON_OPEN) {
872 if (port->d_id) 869 if (!port->d_id) {
873 return ZFCP_ERP_SUCCEEDED; 870 zfcp_fc_trigger_did_lookup(port);
874 else { 871 return ZFCP_ERP_EXIT;
875 act->step = ZFCP_ERP_STEP_PORT_CLOSING;
876 return ZFCP_ERP_CONTINUES;
877 } 872 }
873 return ZFCP_ERP_SUCCEEDED;
878 } 874 }
879 if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { 875 if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) {
880 port->d_id = 0; 876 port->d_id = 0;
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
889static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) 885static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
890{ 886{
891 struct zfcp_port *port = erp_action->port; 887 struct zfcp_port *port = erp_action->port;
888 int p_status = atomic_read(&port->status);
892 889
893 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) 890 if ((p_status & ZFCP_STATUS_COMMON_NOESC) &&
891 !(p_status & ZFCP_STATUS_COMMON_OPEN))
894 goto close_init_done; 892 goto close_init_done;
895 893
896 switch (erp_action->step) { 894 switch (erp_action->step) {
897 case ZFCP_ERP_STEP_UNINITIALIZED: 895 case ZFCP_ERP_STEP_UNINITIALIZED:
898 zfcp_erp_port_strategy_clearstati(port); 896 zfcp_erp_port_strategy_clearstati(port);
899 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) 897 if (p_status & ZFCP_STATUS_COMMON_OPEN)
900 return zfcp_erp_port_strategy_close(erp_action); 898 return zfcp_erp_port_strategy_close(erp_action);
901 break; 899 break;
902 900
903 case ZFCP_ERP_STEP_PORT_CLOSING: 901 case ZFCP_ERP_STEP_PORT_CLOSING:
904 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) 902 if (p_status & ZFCP_STATUS_COMMON_OPEN)
905 return ZFCP_ERP_FAILED; 903 return ZFCP_ERP_FAILED;
906 break; 904 break;
907 } 905 }
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 629edec70405..b3f28deb4505 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
96extern void _zfcp_fc_scan_ports_later(struct work_struct *); 96extern void _zfcp_fc_scan_ports_later(struct work_struct *);
97extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); 97extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
98extern void zfcp_fc_port_did_lookup(struct work_struct *); 98extern void zfcp_fc_port_did_lookup(struct work_struct *);
99extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
99extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); 100extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
100extern void zfcp_fc_test_link(struct zfcp_port *); 101extern void zfcp_fc_test_link(struct zfcp_port *);
101extern void zfcp_fc_link_test_work(struct work_struct *); 102extern void zfcp_fc_link_test_work(struct work_struct *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 722f22de8753..df23bcead23d 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -361,6 +361,17 @@ out:
361} 361}
362 362
363/** 363/**
364 * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request
365 * @port: The zfcp_port to lookup the d_id for.
366 */
367void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
368{
369 zfcp_port_get(port);
370 if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
371 zfcp_port_put(port);
372}
373
374/**
364 * zfcp_fc_plogi_evaluate - evaluate PLOGI playload 375 * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
365 * @port: zfcp_port structure 376 * @port: zfcp_port structure
366 * @plogi: plogi payload 377 * @plogi: plogi payload
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 38a7e4a6b639..4e41baa0c141 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1079,7 +1079,7 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
1079 /* common settings for ct/gs and els requests */ 1079 /* common settings for ct/gs and els requests */
1080 req->qtcb->bottom.support.service_class = FSF_CLASS_3; 1080 req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1081 req->qtcb->bottom.support.timeout = 2 * R_A_TOV; 1081 req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
1082 zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); 1082 zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);
1083 1083
1084 return 0; 1084 return 0;
1085} 1085}
@@ -1475,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1475 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1475 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
1476 if (req->qtcb->bottom.support.els1_length >= 1476 if (req->qtcb->bottom.support.els1_length >=
1477 FSF_PLOGI_MIN_LEN) { 1477 FSF_PLOGI_MIN_LEN) {
1478 if (plogi->serv_param.wwpn != port->wwpn) 1478 if (plogi->serv_param.wwpn != port->wwpn) {
1479 port->d_id = 0; 1479 port->d_id = 0;
1480 else { 1480 dev_warn(&port->adapter->ccw_device->dev,
1481 "A port opened with WWPN 0x%016Lx "
1482 "returned data that identifies it as "
1483 "WWPN 0x%016Lx\n",
1484 (unsigned long long) port->wwpn,
1485 (unsigned long long)
1486 plogi->serv_param.wwpn);
1487 } else {
1481 port->wwnn = plogi->serv_param.wwnn; 1488 port->wwnn = plogi->serv_param.wwnn;
1482 zfcp_fc_plogi_evaluate(port, plogi); 1489 zfcp_fc_plogi_evaluate(port, plogi);
1483 } 1490 }
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 079a8cf518a3..d31000886ca8 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -224,6 +224,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
224 224
225 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); 225 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
226 zfcp_erp_wait(unit->port->adapter); 226 zfcp_erp_wait(unit->port->adapter);
227 flush_work(&unit->scsi_work);
227 zfcp_unit_put(unit); 228 zfcp_unit_put(unit);
228out: 229out:
229 mutex_unlock(&zfcp_data.config_mutex); 230 mutex_unlock(&zfcp_data.config_mutex);