]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.arch/s390-12-05-cio_introduce_ccw_device_boxed_notify.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-12-05-cio_introduce_ccw_device_boxed_notify.patch
diff --git a/src/patches/suse-2.6.27.31/patches.arch/s390-12-05-cio_introduce_ccw_device_boxed_notify.patch b/src/patches/suse-2.6.27.31/patches.arch/s390-12-05-cio_introduce_ccw_device_boxed_notify.patch
new file mode 100644 (file)
index 0000000..a56ff68
--- /dev/null
@@ -0,0 +1,219 @@
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: cio: notify ccw driver for boxed devices
+References: bnc#487755,LTC#52560
+
+Symptom:     Dasd driver keeps trying to start io on not accessible device.
+Problem:     Missing notification for ccw device drivers.
+Solution:    Add proper notification if a device goes into boxed state.
+
+Acked-by: John Jolly <jjolly@suse.de>
+---
+ Documentation/kmsg/s390/zfcp  |   15 +++++++++++++++
+ arch/s390/include/asm/cio.h   |    2 ++
+ drivers/s390/block/dasd.c     |    1 +
+ drivers/s390/cio/device.c     |   26 +++++++++++++++++---------
+ drivers/s390/cio/device.h     |    1 +
+ drivers/s390/cio/device_fsm.c |   29 ++++++++++++++++++-----------
+ drivers/s390/scsi/zfcp_ccw.c  |    5 +++++
+ 7 files changed, 59 insertions(+), 20 deletions(-)
+
+--- a/Documentation/kmsg/s390/zfcp
++++ b/Documentation/kmsg/s390/zfcp
+@@ -100,6 +100,21 @@
+  */
+ /*?
++ * Text: "%s: The FCP device did not respond within the specified time\n"
++ * Severity: Warning
++ * Parameter:
++ *   @1: bus ID of the zfcp device
++ * Description:
++ * The common I/O layer waited for a response from the FCP adapter but
++ * no response was received within the specified time limit. This might
++ * indicate a hardware problem.
++ * User action:
++ * Consult your hardware administrator. If this problem persists,
++ * gather Linux debug data, collect the FCP adapter hardware logs, and
++ * report the problem to your support organization.
++ */
++
++/*?
+  * Text: "%s: Registering the FCP device with the SCSI stack failed\n"
+  * Severity: Error
+  * Parameter:
+--- a/arch/s390/include/asm/cio.h
++++ b/arch/s390/include/asm/cio.h
+@@ -456,6 +456,8 @@ struct ciw {
+ #define CIO_OPER       0x0004
+ /* Sick revalidation of device. */
+ #define CIO_REVALIDATE 0x0008
++/* Device did not respond in time. */
++#define CIO_BOXED      0x0010
+ /**
+  * struct ccw_dev_id - unique identifier for ccw devices
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -2359,6 +2359,7 @@ int dasd_generic_notify(struct ccw_devic
+       ret = 0;
+       switch (event) {
+       case CIO_GONE:
++      case CIO_BOXED:
+       case CIO_NO_PATH:
+               /* First of all call extended error reporting. */
+               dasd_eer_write(device, NULL, DASD_EER_NOPATH);
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -479,11 +479,15 @@ static int online_store_recog_and_online
+               }
+               wait_event(cdev->private->wait_q,
+                          cdev->private->flags.recog_done);
++              if (cdev->private->state != DEV_STATE_OFFLINE)
++                      /* recognition failed */
++                      return -EAGAIN;
+       }
+       if (cdev->drv && cdev->drv->set_online)
+               ccw_device_set_online(cdev);
+       return 0;
+ }
++
+ static int online_store_handle_online(struct ccw_device *cdev, int force)
+ {
+       int ret;
+@@ -497,7 +501,9 @@ static int online_store_handle_online(st
+                       return ret;
+               if (cdev->id.cu_type == 0)
+                       cdev->private->state = DEV_STATE_NOT_OPER;
+-              online_store_recog_and_online(cdev);
++              ret = online_store_recog_and_online(cdev);
++              if (ret)
++                      return ret;
+       }
+       return 0;
+ }
+@@ -1017,33 +1023,35 @@ static void ccw_device_call_sch_unregist
+       put_device(&sch->dev);
+ }
++void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
++{
++      PREPARE_WORK(&cdev->private->kick_work,
++                   ccw_device_call_sch_unregister);
++      queue_work(slow_path_wq, &cdev->private->kick_work);
++}
++
+ /*
+  * subchannel recognition done. Called from the state machine.
+  */
+ void
+ io_subchannel_recog_done(struct ccw_device *cdev)
+ {
+-      struct subchannel *sch;
+-
+       if (css_init_done == 0) {
+               cdev->private->flags.recog_done = 1;
+               return;
+       }
+       switch (cdev->private->state) {
++      case DEV_STATE_BOXED:
++              /* Device did not respond in time. */
+       case DEV_STATE_NOT_OPER:
+               cdev->private->flags.recog_done = 1;
+               /* Remove device found not operational. */
+               if (!get_device(&cdev->dev))
+                       break;
+-              sch = to_subchannel(cdev->dev.parent);
+-              PREPARE_WORK(&cdev->private->kick_work,
+-                           ccw_device_call_sch_unregister);
+-              queue_work(slow_path_wq, &cdev->private->kick_work);
++              ccw_device_schedule_sch_unregister(cdev);
+               if (atomic_dec_and_test(&ccw_device_init_count))
+                       wake_up(&ccw_device_init_wq);
+               break;
+-      case DEV_STATE_BOXED:
+-              /* Device did not respond in time. */
+       case DEV_STATE_OFFLINE:
+               /* 
+                * We can't register the device in interrupt context so
+--- a/drivers/s390/cio/device.h
++++ b/drivers/s390/cio/device.h
+@@ -86,6 +86,7 @@ int ccw_device_is_orphan(struct ccw_devi
+ int ccw_device_recognition(struct ccw_device *);
+ int ccw_device_online(struct ccw_device *);
+ int ccw_device_offline(struct ccw_device *);
++void ccw_device_schedule_sch_unregister(struct ccw_device *);
+ /* Function prototypes for device status and basic sense stuff. */
+ void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
+--- a/drivers/s390/cio/device_fsm.c
++++ b/drivers/s390/cio/device_fsm.c
+@@ -253,13 +253,12 @@ ccw_device_recog_done(struct ccw_device
+               old_lpm = 0;
+       if (sch->lpm != old_lpm)
+               __recover_lost_chpids(sch, old_lpm);
+-      if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
+-              if (state == DEV_STATE_NOT_OPER) {
+-                      cdev->private->flags.recog_done = 1;
+-                      cdev->private->state = DEV_STATE_DISCONNECTED;
+-                      return;
+-              }
+-              /* Boxed devices don't need extra treatment. */
++      if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
++          (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
++              cdev->private->flags.recog_done = 1;
++              cdev->private->state = DEV_STATE_DISCONNECTED;
++              wake_up(&cdev->private->wait_q);
++              return;
+       }
+       notify = 0;
+       same_dev = 0; /* Keep the compiler quiet... */
+@@ -304,12 +303,17 @@ ccw_device_recog_done(struct ccw_device
+                             " subchannel 0.%x.%04x\n",
+                             cdev->private->dev_id.devno,
+                             sch->schid.ssid, sch->schid.sch_no);
++              if (cdev->id.cu_type != 0) { /* device was recognized before */
++                      cdev->private->flags.recog_done = 1;
++                      cdev->private->state = DEV_STATE_BOXED;
++                      wake_up(&cdev->private->wait_q);
++                      return;
++              }
+               break;
+       }
+       cdev->private->state = state;
+       io_subchannel_recog_done(cdev);
+-      if (state != DEV_STATE_NOT_OPER)
+-              wake_up(&cdev->private->wait_q);
++      wake_up(&cdev->private->wait_q);
+ }
+ /*
+@@ -387,10 +391,13 @@ ccw_device_done(struct ccw_device *cdev,
+       cdev->private->state = state;
+-
+-      if (state == DEV_STATE_BOXED)
++      if (state == DEV_STATE_BOXED) {
+               CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
+                             cdev->private->dev_id.devno, sch->schid.sch_no);
++              if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
++                      ccw_device_schedule_sch_unregister(cdev);
++              cdev->private->flags.donotify = 0;
++      }
+       if (cdev->private->flags.donotify) {
+               cdev->private->flags.donotify = 0;
+--- a/drivers/s390/scsi/zfcp_ccw.c
++++ b/drivers/s390/scsi/zfcp_ccw.c
+@@ -181,6 +181,11 @@ static int zfcp_ccw_notify(struct ccw_de
+               zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+                                       89, NULL);
+               break;
++      case CIO_BOXED:
++              dev_warn(&adapter->ccw_device->dev, "The FCP device "
++                       "did not respond within the specified time\n");
++              zfcp_erp_adapter_shutdown(adapter, 0, 91, NULL);
++              break;
+       }
+       return 1;
+ }