X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fcio%2Fdevice_id.c;h=438db483035d033a85013e184fcef818a75dcfd2;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=aae28c3bb74838ff7b57504d5953fae1b496487f;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index aae28c3bb..438db4830 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -3,14 +3,13 @@ * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation - * Author(s): Cornelia Huck(cohuck@de.ibm.com) + * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) * Martin Schwidefsky (schwidefsky@de.ibm.com) * * Sense ID functions. */ #include -#include #include #include @@ -27,7 +26,7 @@ /* * diag210 is used under VM to get information about a virtual device */ -#ifdef CONFIG_ARCH_S390X +#ifdef CONFIG_64BIT int diag210(struct diag210 * addr) { @@ -36,7 +35,7 @@ diag210(struct diag210 * addr) * use a static data area to be sure */ static struct diag210 diag210_tmp; - static spinlock_t diag210_lock = SPIN_LOCK_UNLOCKED; + static DEFINE_SPINLOCK(diag210_lock); unsigned long flags; int ccode; @@ -256,16 +255,17 @@ ccw_device_check_sense_id(struct ccw_device *cdev) * sense id information. So, for intervention required, * we use the "whack it until it talks" strategy... */ - CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel %04x " - "reports cmd reject\n", - cdev->private->devno, sch->irq); + CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " + "0.%x.%04x reports cmd reject\n", + cdev->private->devno, sch->schid.ssid, + sch->schid.sch_no); return -EOPNOTSUPP; } if (irb->esw.esw0.erw.cons) { - CIO_MSG_EVENT(2, "SenseID : UC on dev %04x, " + CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " "lpum %02X, cnt %02d, sns :" " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", - cdev->private->devno, + cdev->private->ssid, cdev->private->devno, irb->esw.esw0.sublog.lpum, irb->esw.esw0.erw.scnt, irb->ecw[0], irb->ecw[1], @@ -277,16 +277,17 @@ ccw_device_check_sense_id(struct ccw_device *cdev) if (irb->scsw.cc == 3) { if ((sch->orb.lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) - CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x on" - " subchannel %04x is 'not operational'\n", - sch->orb.lpm, cdev->private->devno, - sch->irq); + CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " + "on subchannel 0.%x.%04x is " + "'not operational'\n", sch->orb.lpm, + cdev->private->devno, sch->schid.ssid, + sch->schid.sch_no); return -EACCES; } /* Hmm, whatever happened, try again. */ CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " - "subchannel %04x returns status %02X%02X\n", - cdev->private->devno, sch->irq, + "subchannel 0.%x.%04x returns status %02X%02X\n", + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, irb->scsw.dstat, irb->scsw.cstat); return -EAGAIN; } @@ -303,20 +304,20 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); irb = (struct irb *) __LC_IRB; - /* - * Unsolicited interrupts may pertain to an earlier status pending or - * busy condition on the subchannel. Retry sense id. - */ + /* Retry sense id, if needed. */ if (irb->scsw.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - ret = __ccw_device_sense_id_start(cdev); - if (ret && ret != -EBUSY) - ccw_device_sense_id_done(cdev, ret); + if ((irb->scsw.cc == 1) || !irb->scsw.actl) { + ret = __ccw_device_sense_id_start(cdev); + if (ret && ret != -EBUSY) + ccw_device_sense_id_done(cdev, ret); + } return; } if (ccw_device_accumulate_and_sense(cdev, irb) != 0) return; ret = ccw_device_check_sense_id(cdev); + memset(&cdev->private->irb, 0, sizeof(struct irb)); switch (ret) { /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN or -EACCES */ case 0: /* Sense id succeeded. */