diff options
author | Cornelia Huck <cohuck@de.ibm.com> | 2006-01-06 03:19:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:51 -0500 |
commit | a28c69448154a0901e8815922030c5dcd2f8e388 (patch) | |
tree | 532ac1d4abc9cb9317bdfabc09b225ef616dd07b /drivers/s390/cio/chsc.c | |
parent | f97a56fb768e5fe9cd07c56ca47870136bb5530c (diff) |
[PATCH] s390: introduce struct channel_subsystem
struct channel_subsystem encapsulates several per channel subsystem
properties, like status of chpids or the global path group id.
Signed-off-by: Cornelia Huck <cohuck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r-- | drivers/s390/cio/chsc.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 78e082311f48..ebd924962df0 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -24,8 +24,6 @@ | |||
24 | #include "ioasm.h" | 24 | #include "ioasm.h" |
25 | #include "chsc.h" | 25 | #include "chsc.h" |
26 | 26 | ||
27 | static struct channel_path *chps[NR_CHPIDS]; | ||
28 | |||
29 | static void *sei_page; | 27 | static void *sei_page; |
30 | 28 | ||
31 | static int new_channel_path(int chpid); | 29 | static int new_channel_path(int chpid); |
@@ -33,13 +31,13 @@ static int new_channel_path(int chpid); | |||
33 | static inline void | 31 | static inline void |
34 | set_chp_logically_online(int chp, int onoff) | 32 | set_chp_logically_online(int chp, int onoff) |
35 | { | 33 | { |
36 | chps[chp]->state = onoff; | 34 | css[0]->chps[chp]->state = onoff; |
37 | } | 35 | } |
38 | 36 | ||
39 | static int | 37 | static int |
40 | get_chp_status(int chp) | 38 | get_chp_status(int chp) |
41 | { | 39 | { |
42 | return (chps[chp] ? chps[chp]->state : -ENODEV); | 40 | return (css[0]->chps[chp] ? css[0]->chps[chp]->state : -ENODEV); |
43 | } | 41 | } |
44 | 42 | ||
45 | void | 43 | void |
@@ -219,13 +217,13 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
219 | int j; | 217 | int j; |
220 | int mask; | 218 | int mask; |
221 | struct subchannel *sch; | 219 | struct subchannel *sch; |
222 | __u8 *chpid; | 220 | struct channel_path *chpid; |
223 | struct schib schib; | 221 | struct schib schib; |
224 | 222 | ||
225 | sch = to_subchannel(dev); | 223 | sch = to_subchannel(dev); |
226 | chpid = data; | 224 | chpid = data; |
227 | for (j = 0; j < 8; j++) | 225 | for (j = 0; j < 8; j++) |
228 | if (sch->schib.pmcw.chpid[j] == *chpid) | 226 | if (sch->schib.pmcw.chpid[j] == chpid->id) |
229 | break; | 227 | break; |
230 | if (j >= 8) | 228 | if (j >= 8) |
231 | return 0; | 229 | return 0; |
@@ -296,18 +294,20 @@ static inline void | |||
296 | s390_set_chpid_offline( __u8 chpid) | 294 | s390_set_chpid_offline( __u8 chpid) |
297 | { | 295 | { |
298 | char dbf_txt[15]; | 296 | char dbf_txt[15]; |
297 | struct device *dev; | ||
299 | 298 | ||
300 | sprintf(dbf_txt, "chpr%x", chpid); | 299 | sprintf(dbf_txt, "chpr%x", chpid); |
301 | CIO_TRACE_EVENT(2, dbf_txt); | 300 | CIO_TRACE_EVENT(2, dbf_txt); |
302 | 301 | ||
303 | if (get_chp_status(chpid) <= 0) | 302 | if (get_chp_status(chpid) <= 0) |
304 | return; | 303 | return; |
305 | 304 | dev = get_device(&css[0]->chps[chpid]->dev); | |
306 | bus_for_each_dev(&css_bus_type, NULL, &chpid, | 305 | bus_for_each_dev(&css_bus_type, NULL, to_channelpath(dev), |
307 | s390_subchannel_remove_chpid); | 306 | s390_subchannel_remove_chpid); |
308 | 307 | ||
309 | if (need_rescan || css_slow_subchannels_exist()) | 308 | if (need_rescan || css_slow_subchannels_exist()) |
310 | queue_work(slow_path_wq, &slow_path_work); | 309 | queue_work(slow_path_wq, &slow_path_work); |
310 | put_device(dev); | ||
311 | } | 311 | } |
312 | 312 | ||
313 | struct res_acc_data { | 313 | struct res_acc_data { |
@@ -511,6 +511,7 @@ chsc_process_crw(void) | |||
511 | ret = 0; | 511 | ret = 0; |
512 | do { | 512 | do { |
513 | int ccode, status; | 513 | int ccode, status; |
514 | struct device *dev; | ||
514 | memset(sei_area, 0, sizeof(*sei_area)); | 515 | memset(sei_area, 0, sizeof(*sei_area)); |
515 | memset(&res_data, 0, sizeof(struct res_acc_data)); | 516 | memset(&res_data, 0, sizeof(struct res_acc_data)); |
516 | sei_area->request = (struct chsc_header) { | 517 | sei_area->request = (struct chsc_header) { |
@@ -586,7 +587,8 @@ chsc_process_crw(void) | |||
586 | new_channel_path(sei_area->rsid); | 587 | new_channel_path(sei_area->rsid); |
587 | else if (!status) | 588 | else if (!status) |
588 | break; | 589 | break; |
589 | res_data.chp = chps[sei_area->rsid]; | 590 | dev = get_device(&css[0]->chps[sei_area->rsid]->dev); |
591 | res_data.chp = to_channelpath(dev); | ||
590 | pr_debug("chpid: %x", sei_area->rsid); | 592 | pr_debug("chpid: %x", sei_area->rsid); |
591 | if ((sei_area->vf & 0xc0) != 0) { | 593 | if ((sei_area->vf & 0xc0) != 0) { |
592 | res_data.fla = sei_area->fla; | 594 | res_data.fla = sei_area->fla; |
@@ -602,6 +604,7 @@ chsc_process_crw(void) | |||
602 | } | 604 | } |
603 | ret = s390_process_res_acc(&res_data); | 605 | ret = s390_process_res_acc(&res_data); |
604 | pr_debug("\n\n"); | 606 | pr_debug("\n\n"); |
607 | put_device(dev); | ||
605 | break; | 608 | break; |
606 | 609 | ||
607 | default: /* other stuff */ | 610 | default: /* other stuff */ |
@@ -678,6 +681,7 @@ chp_add(int chpid) | |||
678 | { | 681 | { |
679 | int rc; | 682 | int rc; |
680 | char dbf_txt[15]; | 683 | char dbf_txt[15]; |
684 | struct device *dev; | ||
681 | 685 | ||
682 | if (!get_chp_status(chpid)) | 686 | if (!get_chp_status(chpid)) |
683 | return 0; /* no need to do the rest */ | 687 | return 0; /* no need to do the rest */ |
@@ -685,11 +689,13 @@ chp_add(int chpid) | |||
685 | sprintf(dbf_txt, "cadd%x", chpid); | 689 | sprintf(dbf_txt, "cadd%x", chpid); |
686 | CIO_TRACE_EVENT(2, dbf_txt); | 690 | CIO_TRACE_EVENT(2, dbf_txt); |
687 | 691 | ||
688 | rc = for_each_subchannel(__chp_add, chps[chpid]); | 692 | dev = get_device(&css[0]->chps[chpid]->dev); |
693 | rc = for_each_subchannel(__chp_add, to_channelpath(dev)); | ||
689 | if (css_slow_subchannels_exist()) | 694 | if (css_slow_subchannels_exist()) |
690 | rc = -EAGAIN; | 695 | rc = -EAGAIN; |
691 | if (rc != -EAGAIN) | 696 | if (rc != -EAGAIN) |
692 | rc = 0; | 697 | rc = 0; |
698 | put_device(dev); | ||
693 | return rc; | 699 | return rc; |
694 | } | 700 | } |
695 | 701 | ||
@@ -1016,7 +1022,7 @@ new_channel_path(int chpid) | |||
1016 | chp->id = chpid; | 1022 | chp->id = chpid; |
1017 | chp->state = 1; | 1023 | chp->state = 1; |
1018 | chp->dev = (struct device) { | 1024 | chp->dev = (struct device) { |
1019 | .parent = &css_bus_device, | 1025 | .parent = &css[0]->device, |
1020 | .release = chp_release, | 1026 | .release = chp_release, |
1021 | }; | 1027 | }; |
1022 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); | 1028 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); |
@@ -1038,7 +1044,7 @@ new_channel_path(int chpid) | |||
1038 | device_unregister(&chp->dev); | 1044 | device_unregister(&chp->dev); |
1039 | goto out_free; | 1045 | goto out_free; |
1040 | } else | 1046 | } else |
1041 | chps[chpid] = chp; | 1047 | css[0]->chps[chpid] = chp; |
1042 | return ret; | 1048 | return ret; |
1043 | out_free: | 1049 | out_free: |
1044 | kfree(chp); | 1050 | kfree(chp); |
@@ -1051,7 +1057,7 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no) | |||
1051 | struct channel_path *chp; | 1057 | struct channel_path *chp; |
1052 | struct channel_path_desc *desc; | 1058 | struct channel_path_desc *desc; |
1053 | 1059 | ||
1054 | chp = chps[sch->schib.pmcw.chpid[chp_no]]; | 1060 | chp = css[0]->chps[sch->schib.pmcw.chpid[chp_no]]; |
1055 | if (!chp) | 1061 | if (!chp) |
1056 | return NULL; | 1062 | return NULL; |
1057 | desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); | 1063 | desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); |