aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chsc.c
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@de.ibm.com>2006-01-06 03:19:23 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:51 -0500
commita28c69448154a0901e8815922030c5dcd2f8e388 (patch)
tree532ac1d4abc9cb9317bdfabc09b225ef616dd07b /drivers/s390/cio/chsc.c
parentf97a56fb768e5fe9cd07c56ca47870136bb5530c (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.c32
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
27static struct channel_path *chps[NR_CHPIDS];
28
29static void *sei_page; 27static void *sei_page;
30 28
31static int new_channel_path(int chpid); 29static int new_channel_path(int chpid);
@@ -33,13 +31,13 @@ static int new_channel_path(int chpid);
33static inline void 31static inline void
34set_chp_logically_online(int chp, int onoff) 32set_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
39static int 37static int
40get_chp_status(int chp) 38get_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
45void 43void
@@ -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
296s390_set_chpid_offline( __u8 chpid) 294s390_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
313struct res_acc_data { 313struct 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;
1043out_free: 1049out_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);