diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-04 09:37:39 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-04 09:37:39 -0800 |
commit | 2254c2e0184c603f92fc9b81016ff4bb53da622d (patch) | |
tree | c1410c58f07f82e5203d46b52a705d321d1cba97 /drivers | |
parent | a3aaabd6b402d8b0ede5aa4a040e9fdbbfdf9116 (diff) | |
parent | 7af0d6f753f5adf773f99470666b50490d3379f1 (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] Make sure the restore psw masks are initialized.
[S390] Fix compile error on 31bit without preemption
[S390] dcssblk: prevent early access without own make_request function
[S390] cio: add missing reprobe loop end statement
[S390] cio: Issue SenseID per path.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dcssblk.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device_id.c | 37 |
3 files changed, 31 insertions, 11 deletions
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 5e083d1f57e..15a5789b773 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -472,11 +472,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char if (rc) goto unregister_dev; - add_disk(dev_info->gd); - blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request); blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096); + add_disk(dev_info->gd); + switch (dev_info->segment_type) { case SEG_TYPE_SR: case SEG_TYPE_ER: diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 6db31089d2d..c3df2cd009a 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -451,6 +451,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) break; case -ENXIO: case -ENOMEM: + case -EIO: /* These should abort looping */ break; default: diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 2f6bf462425..156f3f9786b 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -113,6 +113,7 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) { struct subchannel *sch; struct ccw1 *ccw; + int ret; sch = to_subchannel(cdev->dev.parent); /* Setup sense channel program. */ @@ -124,9 +125,25 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) /* Reset device status. */ memset(&cdev->private->irb, 0, sizeof(struct irb)); - cdev->private->flags.intretry = 0; - return cio_start(sch, ccw, LPM_ANYPATH); + /* Try on every path. */ + ret = -ENODEV; + while (cdev->private->imask != 0) { + if ((sch->opm & cdev->private->imask) != 0 && + cdev->private->iretry > 0) { + cdev->private->iretry--; + /* Reset internal retry indication. */ + cdev->private->flags.intretry = 0; + ret = cio_start (sch, cdev->private->iccws, + cdev->private->imask); + /* ret is 0, -EBUSY, -EACCES or -ENODEV */ + if (ret != -EACCES) + return ret; + } + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + } + return ret; } void @@ -136,7 +153,8 @@ ccw_device_sense_id_start(struct ccw_device *cdev) memset (&cdev->private->senseid, 0, sizeof (struct senseid)); cdev->private->senseid.cu_type = 0xFFFF; - cdev->private->iretry = 3; + cdev->private->imask = 0x80; + cdev->private->iretry = 5; ret = __ccw_device_sense_id_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_id_done(cdev, ret); @@ -252,13 +270,14 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) ccw_device_sense_id_done(cdev, ret); break; case -EACCES: /* channel is not operational. */ + sch->lpm &= ~cdev->private->imask; + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + /* fall through. */ case -EAGAIN: /* try again. */ - cdev->private->iretry--; - if (cdev->private->iretry > 0) { - ret = __ccw_device_sense_id_start(cdev); - if (ret == 0 || ret == -EBUSY) - break; - } + ret = __ccw_device_sense_id_start(cdev); + if (ret == 0 || ret == -EBUSY) + break; /* fall through. */ default: /* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM) { |