From 602b20f2bf335d0d5fce11cb2ade22aa74e7ba25 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Sat, 26 Jan 2008 14:10:39 +0100 Subject: [S390] cio: css_driver: Use consistent parameters. Make all callbacks in css_driver take a struct subchannel (and not a struct device). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/s390/cio/chsc.c') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 597c0c76a2a..44a2ea40806 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -132,7 +132,7 @@ static void terminate_internal_io(struct subchannel *sch) device_set_intretry(sch); /* Call handler. */ if (sch->driver && sch->driver->termination) - sch->driver->termination(&sch->dev); + sch->driver->termination(sch); } static int @@ -172,12 +172,12 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) terminate_internal_io(sch); /* Re-start path verification. */ if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); } } else { /* trigger path verification. */ if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); else if (sch->lpm == mask) goto out_unreg; } @@ -279,7 +279,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) if (!old_lpm && sch->lpm) device_trigger_reprobe(sch); else if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); out: spin_unlock_irq(sch->lock); put_device(&sch->dev); @@ -549,7 +549,7 @@ __chp_add(struct subchannel_id schid, void *data) | mask) & sch->opm; if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); spin_unlock_irq(sch->lock); put_device(&sch->dev); @@ -589,7 +589,7 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, if (!old_lpm) device_trigger_reprobe(sch); else if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); break; } sch->opm &= ~mask; @@ -603,13 +603,13 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, terminate_internal_io(sch); /* Re-start path verification. */ if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); } } else if (!sch->lpm) { if (device_trigger_verify(sch) != 0) css_schedule_eval(sch->schid); } else if (sch->driver && sch->driver->verify) - sch->driver->verify(&sch->dev); + sch->driver->verify(sch); break; } spin_unlock_irqrestore(sch->lock, flags); -- cgit v1.2.3 From b279a4f56d5476a0b9b0a97397f7a7bbe00b9b2f Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Sat, 26 Jan 2008 14:10:45 +0100 Subject: [S390] cio: I/O subchannel specific fields. Some fields may be !0 only for I/O subchannels. Add some checks where required. Also adapt cio_enable_subchannel() to make the caller specify the intparm, which makes it more generic. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/s390/cio/chsc.c') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 44a2ea40806..12a344c66b4 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -89,7 +89,8 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) /* Copy data */ ret = 0; memset(ssd, 0, sizeof(struct chsc_ssd_info)); - if ((ssd_area->st != 0) && (ssd_area->st != 2)) + if ((ssd_area->st != SUBCHANNEL_TYPE_IO) && + (ssd_area->st != SUBCHANNEL_TYPE_MSG)) goto out_free; ssd->path_mask = ssd_area->path_mask; ssd->fla_valid_mask = ssd_area->fla_valid_mask; @@ -158,7 +159,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) spin_lock_irq(sch->lock); stsch(sch->schid, &schib); - if (!schib.pmcw.dnv) + if (!css_sch_is_valid(&schib)) goto out_unreg; memcpy(&sch->schib, &schib, sizeof(struct schib)); /* Check for single path devices. */ -- cgit v1.2.3 From e82a1567e4b22eb035da2499d20ddd573c9acf75 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Sat, 26 Jan 2008 14:10:48 +0100 Subject: [S390] cio: reduce cpu utilization during device scan Minimize calls to cpu intensive function get_subchannel_by_schid() by introducing function for_each_subchannel_staged() which temporarily caches the information about registered subchannels in a bitmap. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 98 ++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 66 deletions(-) (limited to 'drivers/s390/cio/chsc.c') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 12a344c66b4..93e6f74187e 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -136,17 +136,13 @@ static void terminate_internal_io(struct subchannel *sch) sch->driver->termination(sch); } -static int -s390_subchannel_remove_chpid(struct device *dev, void *data) +static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) { int j; int mask; - struct subchannel *sch; - struct chp_id *chpid; + struct chp_id *chpid = data; struct schib schib; - sch = to_subchannel(dev); - chpid = data; for (j = 0; j < 8; j++) { mask = 0x80 >> j; if ((sch->schib.pmcw.pim & mask) && @@ -202,12 +198,10 @@ void chsc_chp_offline(struct chp_id chpid) if (chp_get_status(chpid) <= 0) return; - bus_for_each_dev(&css_bus_type, NULL, &chpid, - s390_subchannel_remove_chpid); + for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); } -static int -s390_process_res_acc_new_sch(struct subchannel_id schid) +static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) { struct schib schib; /* @@ -253,18 +247,10 @@ static int get_res_chpid_mask(struct chsc_ssd_info *ssd, return 0; } -static int -__s390_process_res_acc(struct subchannel_id schid, void *data) +static int __s390_process_res_acc(struct subchannel *sch, void *data) { int chp_mask, old_lpm; - struct res_acc_data *res_data; - struct subchannel *sch; - - res_data = data; - sch = get_subchannel_by_schid(schid); - if (!sch) - /* Check if a subchannel is newly available. */ - return s390_process_res_acc_new_sch(schid); + struct res_acc_data *res_data = data; spin_lock_irq(sch->lock); chp_mask = get_res_chpid_mask(&sch->ssd_info, res_data); @@ -283,7 +269,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) sch->driver->verify(sch); out: spin_unlock_irq(sch->lock); - put_device(&sch->dev); + return 0; } @@ -306,7 +292,8 @@ static void s390_process_res_acc (struct res_acc_data *res_data) * The more information we have (info), the less scanning * will we have to do. */ - for_each_subchannel(__s390_process_res_acc, res_data); + for_each_subchannel_staged(__s390_process_res_acc, + s390_process_res_acc_new_sch, res_data); } static int @@ -500,8 +487,7 @@ void chsc_process_crw(void) } while (sei_area->flags & 0x80); } -static int -__chp_add_new_sch(struct subchannel_id schid) +static int __chp_add_new_sch(struct subchannel_id schid, void *data) { struct schib schib; @@ -515,35 +501,27 @@ __chp_add_new_sch(struct subchannel_id schid) } -static int -__chp_add(struct subchannel_id schid, void *data) +static int __chp_add(struct subchannel *sch, void *data) { int i, mask; - struct chp_id *chpid; - struct subchannel *sch; - - chpid = data; - sch = get_subchannel_by_schid(schid); - if (!sch) - /* Check if the subchannel is now available. */ - return __chp_add_new_sch(schid); + struct chp_id *chpid = data; + spin_lock_irq(sch->lock); for (i=0; i<8; i++) { mask = 0x80 >> i; if ((sch->schib.pmcw.pim & mask) && - (sch->schib.pmcw.chpid[i] == chpid->id)) { - if (stsch(sch->schid, &sch->schib) != 0) { - /* Endgame. */ - spin_unlock_irq(sch->lock); - return -ENXIO; - } + (sch->schib.pmcw.chpid[i] == chpid->id)) break; - } } if (i==8) { spin_unlock_irq(sch->lock); return 0; } + if (stsch(sch->schid, &sch->schib)) { + spin_unlock_irq(sch->lock); + css_schedule_eval(sch->schid); + return 0; + } sch->lpm = ((sch->schib.pmcw.pim & sch->schib.pmcw.pam & sch->schib.pmcw.pom) @@ -553,7 +531,7 @@ __chp_add(struct subchannel_id schid, void *data) sch->driver->verify(sch); spin_unlock_irq(sch->lock); - put_device(&sch->dev); + return 0; } @@ -565,7 +543,8 @@ void chsc_chp_online(struct chp_id chpid) CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) != 0) - for_each_subchannel(__chp_add, &chpid); + for_each_subchannel_staged(__chp_add, __chp_add_new_sch, + &chpid); } static void __s390_subchannel_vary_chpid(struct subchannel *sch, @@ -616,25 +595,17 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, spin_unlock_irqrestore(sch->lock, flags); } -static int s390_subchannel_vary_chpid_off(struct device *dev, void *data) +static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data) { - struct subchannel *sch; - struct chp_id *chpid; - - sch = to_subchannel(dev); - chpid = data; + struct chp_id *chpid = data; __s390_subchannel_vary_chpid(sch, *chpid, 0); return 0; } -static int s390_subchannel_vary_chpid_on(struct device *dev, void *data) +static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data) { - struct subchannel *sch; - struct chp_id *chpid; - - sch = to_subchannel(dev); - chpid = data; + struct chp_id *chpid = data; __s390_subchannel_vary_chpid(sch, *chpid, 1); return 0; @@ -644,13 +615,7 @@ static int __s390_vary_chpid_on(struct subchannel_id schid, void *data) { struct schib schib; - struct subchannel *sch; - sch = get_subchannel_by_schid(schid); - if (sch) { - put_device(&sch->dev); - return 0; - } if (stsch_err(schid, &schib)) /* We're through */ return -ENXIO; @@ -670,12 +635,13 @@ int chsc_chp_vary(struct chp_id chpid, int on) * Redo PathVerification on the devices the chpid connects to */ - bus_for_each_dev(&css_bus_type, NULL, &chpid, on ? - s390_subchannel_vary_chpid_on : - s390_subchannel_vary_chpid_off); if (on) - /* Scan for new devices on varied on path. */ - for_each_subchannel(__s390_vary_chpid_on, NULL); + for_each_subchannel_staged(s390_subchannel_vary_chpid_on, + __s390_vary_chpid_on, &chpid); + else + for_each_subchannel_staged(s390_subchannel_vary_chpid_off, + NULL, &chpid); + return 0; } -- cgit v1.2.3 From ceb3dfbae1d3faacaedfc64c913fd18cd3624f72 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 26 Jan 2008 14:11:10 +0100 Subject: [S390] drivers/s390: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390/cio/chsc.c') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 93e6f74187e..e7ba16a74ef 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -1042,7 +1042,7 @@ chsc_determine_css_characteristics(void) scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!scsc_area) { - CIO_MSG_EVENT(0, "Was not able to determine available" + CIO_MSG_EVENT(0, "Was not able to determine available " "CHSCs due to no memory.\n"); return -ENOMEM; } -- cgit v1.2.3