aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2006-10-06 10:38:29 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-10-06 10:38:29 -0400
commit7e8ae7bfe8354b1f1b98c5cd29db8965ca1e6391 (patch)
tree3300b92f642fd69f77466a7f27e40afd2c2aa189
parent2d103d5a80846e96e1cb1ba5e635e8c37d30ada8 (diff)
[S390] cio: 0 is a valid chpid.
In order to determine chpid validity, we need to check whether the corresponding path is specified in the pim. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/cio/chsc.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 3bb4e472d73d..07c7f19339d2 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -200,11 +200,13 @@ css_get_ssd_info(struct subchannel *sch)
200 spin_unlock_irq(&sch->lock); 200 spin_unlock_irq(&sch->lock);
201 free_page((unsigned long)page); 201 free_page((unsigned long)page);
202 if (!ret) { 202 if (!ret) {
203 int j, chpid; 203 int j, chpid, mask;
204 /* Allocate channel path structures, if needed. */ 204 /* Allocate channel path structures, if needed. */
205 for (j = 0; j < 8; j++) { 205 for (j = 0; j < 8; j++) {
206 mask = 0x80 >> j;
206 chpid = sch->ssd_info.chpid[j]; 207 chpid = sch->ssd_info.chpid[j];
207 if (chpid && (get_chp_status(chpid) < 0)) 208 if ((sch->schib.pmcw.pim & mask) &&
209 (get_chp_status(chpid) < 0))
208 new_channel_path(chpid); 210 new_channel_path(chpid);
209 } 211 }
210 } 212 }
@@ -222,13 +224,15 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
222 224
223 sch = to_subchannel(dev); 225 sch = to_subchannel(dev);
224 chpid = data; 226 chpid = data;
225 for (j = 0; j < 8; j++) 227 for (j = 0; j < 8; j++) {
226 if (sch->schib.pmcw.chpid[j] == chpid->id) 228 mask = 0x80 >> j;
229 if ((sch->schib.pmcw.pim & mask) &&
230 (sch->schib.pmcw.chpid[j] == chpid->id))
227 break; 231 break;
232 }
228 if (j >= 8) 233 if (j >= 8)
229 return 0; 234 return 0;
230 235
231 mask = 0x80 >> j;
232 spin_lock_irq(&sch->lock); 236 spin_lock_irq(&sch->lock);
233 237
234 stsch(sch->schid, &schib); 238 stsch(sch->schid, &schib);
@@ -620,7 +624,7 @@ __chp_add_new_sch(struct subchannel_id schid)
620static int 624static int
621__chp_add(struct subchannel_id schid, void *data) 625__chp_add(struct subchannel_id schid, void *data)
622{ 626{
623 int i; 627 int i, mask;
624 struct channel_path *chp; 628 struct channel_path *chp;
625 struct subchannel *sch; 629 struct subchannel *sch;
626 630
@@ -630,8 +634,10 @@ __chp_add(struct subchannel_id schid, void *data)
630 /* Check if the subchannel is now available. */ 634 /* Check if the subchannel is now available. */
631 return __chp_add_new_sch(schid); 635 return __chp_add_new_sch(schid);
632 spin_lock_irq(&sch->lock); 636 spin_lock_irq(&sch->lock);
633 for (i=0; i<8; i++) 637 for (i=0; i<8; i++) {
634 if (sch->schib.pmcw.chpid[i] == chp->id) { 638 mask = 0x80 >> i;
639 if ((sch->schib.pmcw.pim & mask) &&
640 (sch->schib.pmcw.chpid[i] == chp->id)) {
635 if (stsch(sch->schid, &sch->schib) != 0) { 641 if (stsch(sch->schid, &sch->schib) != 0) {
636 /* Endgame. */ 642 /* Endgame. */
637 spin_unlock_irq(&sch->lock); 643 spin_unlock_irq(&sch->lock);
@@ -639,6 +645,7 @@ __chp_add(struct subchannel_id schid, void *data)
639 } 645 }
640 break; 646 break;
641 } 647 }
648 }
642 if (i==8) { 649 if (i==8) {
643 spin_unlock_irq(&sch->lock); 650 spin_unlock_irq(&sch->lock);
644 return 0; 651 return 0;
@@ -646,7 +653,7 @@ __chp_add(struct subchannel_id schid, void *data)
646 sch->lpm = ((sch->schib.pmcw.pim & 653 sch->lpm = ((sch->schib.pmcw.pim &
647 sch->schib.pmcw.pam & 654 sch->schib.pmcw.pam &
648 sch->schib.pmcw.pom) 655 sch->schib.pmcw.pom)
649 | 0x80 >> i) & sch->opm; 656 | mask) & sch->opm;
650 657
651 if (sch->driver && sch->driver->verify) 658 if (sch->driver && sch->driver->verify)
652 sch->driver->verify(&sch->dev); 659 sch->driver->verify(&sch->dev);