Commit cec8546638dc634824b629e33968d6c68f8b07d6

Authored by Sebastian Ott
Committed by Martin Schwidefsky
1 parent aa92b33c6b

s390/css: stop stsch loop after cc 3

Receiving cc=3 from store subchannel means 2 things:
* the subchannel is not provided
* there are no further subchannels in this subchannel set

With this patch we abort the store subchannel loop after cc=3 (or an
exception) and clear the subsequent bits in the subchannel id set.

Reported-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Acked-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Showing 3 changed files with 16 additions and 2 deletions Side-by-side Diff

drivers/s390/cio/css.c
... ... @@ -377,7 +377,11 @@
377 377 /* Will be done on the slow path. */
378 378 return -EAGAIN;
379 379 }
380   - if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) {
  380 + if (stsch_err(schid, &schib)) {
  381 + /* Subchannel is not provided. */
  382 + return -ENXIO;
  383 + }
  384 + if (!css_sch_is_valid(&schib)) {
381 385 /* Unusable - ignore. */
382 386 return 0;
383 387 }
... ... @@ -536,6 +540,7 @@
536 540 case -ENOMEM:
537 541 case -EIO:
538 542 /* These should abort looping */
  543 + idset_sch_del_subseq(slow_subchannel_set, schid);
539 544 break;
540 545 default:
541 546 rc = 0;
drivers/s390/cio/idset.c
... ... @@ -90,6 +90,14 @@
90 90 idset_del(set, schid.ssid, schid.sch_no);
91 91 }
92 92  
  93 +/* Clear ids starting from @schid up to end of subchannel set. */
  94 +void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid)
  95 +{
  96 + int pos = schid.ssid * set->num_id + schid.sch_no;
  97 +
  98 + bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no);
  99 +}
  100 +
93 101 int idset_sch_contains(struct idset *set, struct subchannel_id schid)
94 102 {
95 103 return idset_contains(set, schid.ssid, schid.sch_no);
drivers/s390/cio/idset.h
1 1 /*
2   - * Copyright IBM Corp. 2007
  2 + * Copyright IBM Corp. 2007, 2012
3 3 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
4 4 */
5 5  
... ... @@ -17,6 +17,7 @@
17 17 struct idset *idset_sch_new(void);
18 18 void idset_sch_add(struct idset *set, struct subchannel_id id);
19 19 void idset_sch_del(struct idset *set, struct subchannel_id id);
  20 +void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid);
20 21 int idset_sch_contains(struct idset *set, struct subchannel_id id);
21 22 int idset_sch_get_first(struct idset *set, struct subchannel_id *id);
22 23 int idset_is_empty(struct idset *set);