diff options
| author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2007-11-20 05:13:30 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-11-20 05:13:44 -0500 |
| commit | 3b8c88993e3709b4d44f7ca4e886044a49605394 (patch) | |
| tree | e34b883ce7fb53bbe9861fb3a9194530cebad336 /drivers/s390 | |
| parent | 2ffbb8377c7a0713baf6644e285adc27a5654582 (diff) | |
[S390] cio: change device sense procedure to work with pav aliases
Modify the sense id channel program to allow device sensing of pav
alias devices which belong to a base device with ungrouped paths.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
| -rw-r--r-- | drivers/s390/cio/device_id.c | 45 |
1 files changed, 9 insertions, 36 deletions
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index f232832f2b..2f6bf46242 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
| @@ -113,19 +113,10 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) | |||
| 113 | { | 113 | { |
| 114 | struct subchannel *sch; | 114 | struct subchannel *sch; |
| 115 | struct ccw1 *ccw; | 115 | struct ccw1 *ccw; |
| 116 | int ret; | ||
| 117 | 116 | ||
| 118 | sch = to_subchannel(cdev->dev.parent); | 117 | sch = to_subchannel(cdev->dev.parent); |
| 119 | /* Setup sense channel program. */ | 118 | /* Setup sense channel program. */ |
| 120 | ccw = cdev->private->iccws; | 119 | ccw = cdev->private->iccws; |
| 121 | if (sch->schib.pmcw.pim != 0x80) { | ||
| 122 | /* more than one path installed. */ | ||
| 123 | ccw->cmd_code = CCW_CMD_SUSPEND_RECONN; | ||
| 124 | ccw->cda = 0; | ||
| 125 | ccw->count = 0; | ||
| 126 | ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC; | ||
| 127 | ccw++; | ||
| 128 | } | ||
| 129 | ccw->cmd_code = CCW_CMD_SENSE_ID; | 120 | ccw->cmd_code = CCW_CMD_SENSE_ID; |
| 130 | ccw->cda = (__u32) __pa (&cdev->private->senseid); | 121 | ccw->cda = (__u32) __pa (&cdev->private->senseid); |
| 131 | ccw->count = sizeof (struct senseid); | 122 | ccw->count = sizeof (struct senseid); |
| @@ -133,25 +124,9 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) | |||
| 133 | 124 | ||
| 134 | /* Reset device status. */ | 125 | /* Reset device status. */ |
| 135 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 126 | memset(&cdev->private->irb, 0, sizeof(struct irb)); |
| 127 | cdev->private->flags.intretry = 0; | ||
| 136 | 128 | ||
| 137 | /* Try on every path. */ | 129 | return cio_start(sch, ccw, LPM_ANYPATH); |
| 138 | ret = -ENODEV; | ||
| 139 | while (cdev->private->imask != 0) { | ||
| 140 | if ((sch->opm & cdev->private->imask) != 0 && | ||
| 141 | cdev->private->iretry > 0) { | ||
| 142 | cdev->private->iretry--; | ||
| 143 | /* Reset internal retry indication. */ | ||
| 144 | cdev->private->flags.intretry = 0; | ||
| 145 | ret = cio_start (sch, cdev->private->iccws, | ||
| 146 | cdev->private->imask); | ||
| 147 | /* ret is 0, -EBUSY, -EACCES or -ENODEV */ | ||
| 148 | if (ret != -EACCES) | ||
| 149 | return ret; | ||
| 150 | } | ||
| 151 | cdev->private->imask >>= 1; | ||
| 152 | cdev->private->iretry = 5; | ||
| 153 | } | ||
| 154 | return ret; | ||
| 155 | } | 130 | } |
| 156 | 131 | ||
| 157 | void | 132 | void |
| @@ -161,8 +136,7 @@ ccw_device_sense_id_start(struct ccw_device *cdev) | |||
| 161 | 136 | ||
| 162 | memset (&cdev->private->senseid, 0, sizeof (struct senseid)); | 137 | memset (&cdev->private->senseid, 0, sizeof (struct senseid)); |
| 163 | cdev->private->senseid.cu_type = 0xFFFF; | 138 | cdev->private->senseid.cu_type = 0xFFFF; |
| 164 | cdev->private->imask = 0x80; | 139 | cdev->private->iretry = 3; |
| 165 | cdev->private->iretry = 5; | ||
| 166 | ret = __ccw_device_sense_id_start(cdev); | 140 | ret = __ccw_device_sense_id_start(cdev); |
| 167 | if (ret && ret != -EBUSY) | 141 | if (ret && ret != -EBUSY) |
| 168 | ccw_device_sense_id_done(cdev, ret); | 142 | ccw_device_sense_id_done(cdev, ret); |
| @@ -278,14 +252,13 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 278 | ccw_device_sense_id_done(cdev, ret); | 252 | ccw_device_sense_id_done(cdev, ret); |
| 279 | break; | 253 | break; |
| 280 | case -EACCES: /* channel is not operational. */ | 254 | case -EACCES: /* channel is not operational. */ |
| 281 | sch->lpm &= ~cdev->private->imask; | ||
| 282 | cdev->private->imask >>= 1; | ||
| 283 | cdev->private->iretry = 5; | ||
| 284 | /* fall through. */ | ||
| 285 | case -EAGAIN: /* try again. */ | 255 | case -EAGAIN: /* try again. */ |
| 286 | ret = __ccw_device_sense_id_start(cdev); | 256 | cdev->private->iretry--; |
| 287 | if (ret == 0 || ret == -EBUSY) | 257 | if (cdev->private->iretry > 0) { |
| 288 | break; | 258 | ret = __ccw_device_sense_id_start(cdev); |
| 259 | if (ret == 0 || ret == -EBUSY) | ||
| 260 | break; | ||
| 261 | } | ||
| 289 | /* fall through. */ | 262 | /* fall through. */ |
| 290 | default: /* Sense ID failed. Try asking VM. */ | 263 | default: /* Sense ID failed. Try asking VM. */ |
| 291 | if (MACHINE_IS_VM) { | 264 | if (MACHINE_IS_VM) { |
