aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chsc.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2008-07-14 03:59:02 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-07-14 04:02:11 -0400
commit99611f87176b2a908d8c66ab19a5fc550a3cd13a (patch)
tree2c9898f347d00aeab5ffcbf74c90469efb86043e /drivers/s390/cio/chsc.c
parent6ef556ccc8fd256259745c4f0d0ab65aaf703824 (diff)
[S390] cio: Repair chpid event handling.
Passing the affected chpid in chp_event() worked only by chance since chpid is the first element in res_acc_data. Make it work properly by generalizing res_acc_data as chp_link and always passing around a properly filled out chp_link structure in chp_event(). Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r--drivers/s390/cio/chsc.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 62b0b16fe3d3..e23c3806972a 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -146,15 +146,18 @@ out_unreg:
146void chsc_chp_offline(struct chp_id chpid) 146void chsc_chp_offline(struct chp_id chpid)
147{ 147{
148 char dbf_txt[15]; 148 char dbf_txt[15];
149 struct chp_link link;
149 150
150 sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); 151 sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id);
151 CIO_TRACE_EVENT(2, dbf_txt); 152 CIO_TRACE_EVENT(2, dbf_txt);
152 153
153 if (chp_get_status(chpid) <= 0) 154 if (chp_get_status(chpid) <= 0)
154 return; 155 return;
156 memset(&link, 0, sizeof(struct chp_link));
157 link.chpid = chpid;
155 /* Wait until previous actions have settled. */ 158 /* Wait until previous actions have settled. */
156 css_wait_for_slow_path(); 159 css_wait_for_slow_path();
157 for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); 160 for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
158} 161}
159 162
160static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) 163static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data)
@@ -187,15 +190,15 @@ static int __s390_process_res_acc(struct subchannel *sch, void *data)
187 return 0; 190 return 0;
188} 191}
189 192
190static void s390_process_res_acc (struct res_acc_data *res_data) 193static void s390_process_res_acc(struct chp_link *link)
191{ 194{
192 char dbf_txt[15]; 195 char dbf_txt[15];
193 196
194 sprintf(dbf_txt, "accpr%x.%02x", res_data->chpid.cssid, 197 sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid,
195 res_data->chpid.id); 198 link->chpid.id);
196 CIO_TRACE_EVENT( 2, dbf_txt); 199 CIO_TRACE_EVENT( 2, dbf_txt);
197 if (res_data->fla != 0) { 200 if (link->fla != 0) {
198 sprintf(dbf_txt, "fla%x", res_data->fla); 201 sprintf(dbf_txt, "fla%x", link->fla);
199 CIO_TRACE_EVENT( 2, dbf_txt); 202 CIO_TRACE_EVENT( 2, dbf_txt);
200 } 203 }
201 /* Wait until previous actions have settled. */ 204 /* Wait until previous actions have settled. */
@@ -208,7 +211,7 @@ static void s390_process_res_acc (struct res_acc_data *res_data)
208 * will we have to do. 211 * will we have to do.
209 */ 212 */
210 for_each_subchannel_staged(__s390_process_res_acc, 213 for_each_subchannel_staged(__s390_process_res_acc,
211 s390_process_res_acc_new_sch, res_data); 214 s390_process_res_acc_new_sch, link);
212} 215}
213 216
214static int 217static int
@@ -281,7 +284,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
281 284
282static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) 285static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
283{ 286{
284 struct res_acc_data res_data; 287 struct chp_link link;
285 struct chp_id chpid; 288 struct chp_id chpid;
286 int status; 289 int status;
287 290
@@ -297,18 +300,18 @@ static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
297 chp_new(chpid); 300 chp_new(chpid);
298 else if (!status) 301 else if (!status)
299 return; 302 return;
300 memset(&res_data, 0, sizeof(struct res_acc_data)); 303 memset(&link, 0, sizeof(struct chp_link));
301 res_data.chpid = chpid; 304 link.chpid = chpid;
302 if ((sei_area->vf & 0xc0) != 0) { 305 if ((sei_area->vf & 0xc0) != 0) {
303 res_data.fla = sei_area->fla; 306 link.fla = sei_area->fla;
304 if ((sei_area->vf & 0xc0) == 0xc0) 307 if ((sei_area->vf & 0xc0) == 0xc0)
305 /* full link address */ 308 /* full link address */
306 res_data.fla_mask = 0xffff; 309 link.fla_mask = 0xffff;
307 else 310 else
308 /* link address */ 311 /* link address */
309 res_data.fla_mask = 0xff00; 312 link.fla_mask = 0xff00;
310 } 313 }
311 s390_process_res_acc(&res_data); 314 s390_process_res_acc(&link);
312} 315}
313 316
314struct chp_config_data { 317struct chp_config_data {
@@ -413,18 +416,18 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
413void chsc_chp_online(struct chp_id chpid) 416void chsc_chp_online(struct chp_id chpid)
414{ 417{
415 char dbf_txt[15]; 418 char dbf_txt[15];
416 struct res_acc_data res_data; 419 struct chp_link link;
417 420
418 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); 421 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id);
419 CIO_TRACE_EVENT(2, dbf_txt); 422 CIO_TRACE_EVENT(2, dbf_txt);
420 423
421 if (chp_get_status(chpid) != 0) { 424 if (chp_get_status(chpid) != 0) {
422 memset(&res_data, 0, sizeof(struct res_acc_data)); 425 memset(&link, 0, sizeof(struct chp_link));
423 res_data.chpid = chpid; 426 link.chpid = chpid;
424 /* Wait until previous actions have settled. */ 427 /* Wait until previous actions have settled. */
425 css_wait_for_slow_path(); 428 css_wait_for_slow_path();
426 for_each_subchannel_staged(__s390_process_res_acc, NULL, 429 for_each_subchannel_staged(__s390_process_res_acc, NULL,
427 &res_data); 430 &link);
428 } 431 }
429} 432}
430 433
@@ -432,13 +435,13 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch,
432 struct chp_id chpid, int on) 435 struct chp_id chpid, int on)
433{ 436{
434 unsigned long flags; 437 unsigned long flags;
435 struct res_acc_data res_data; 438 struct chp_link link;
436 439
437 memset(&res_data, 0, sizeof(struct res_acc_data)); 440 memset(&link, 0, sizeof(struct chp_link));
438 res_data.chpid = chpid; 441 link.chpid = chpid;
439 spin_lock_irqsave(sch->lock, flags); 442 spin_lock_irqsave(sch->lock, flags);
440 if (sch->driver && sch->driver->chp_event) 443 if (sch->driver && sch->driver->chp_event)
441 sch->driver->chp_event(sch, &res_data, 444 sch->driver->chp_event(sch, &link,
442 on ? CHP_VARY_ON : CHP_VARY_OFF); 445 on ? CHP_VARY_ON : CHP_VARY_OFF);
443 spin_unlock_irqrestore(sch->lock, flags); 446 spin_unlock_irqrestore(sch->lock, flags);
444} 447}
@@ -479,6 +482,10 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
479 */ 482 */
480int chsc_chp_vary(struct chp_id chpid, int on) 483int chsc_chp_vary(struct chp_id chpid, int on)
481{ 484{
485 struct chp_link link;
486
487 memset(&link, 0, sizeof(struct chp_link));
488 link.chpid = chpid;
482 /* Wait until previous actions have settled. */ 489 /* Wait until previous actions have settled. */
483 css_wait_for_slow_path(); 490 css_wait_for_slow_path();
484 /* 491 /*
@@ -487,10 +494,10 @@ int chsc_chp_vary(struct chp_id chpid, int on)
487 494
488 if (on) 495 if (on)
489 for_each_subchannel_staged(s390_subchannel_vary_chpid_on, 496 for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
490 __s390_vary_chpid_on, &chpid); 497 __s390_vary_chpid_on, &link);
491 else 498 else
492 for_each_subchannel_staged(s390_subchannel_vary_chpid_off, 499 for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
493 NULL, &chpid); 500 NULL, &link);
494 501
495 return 0; 502 return 0;
496} 503}