Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / s390 / cio / device_id.c
index aae28c3..438db48 100644 (file)
@@ -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 <linux/module.h>
-#include <linux/config.h>
 #include <linux/init.h>
 
 #include <asm/ccwdev.h>
@@ -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. */