[PATCH 1/2] ibmvscsi: Add suspend/resume support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Adds support for resuming from suspend for IBM VSCSI devices. We may have
lost an interrupt over the suspend, so we just kick the interrupt handler
to process anything that is outstanding. We expect to find a transport event
indicating we need to reestablish our CRQ.

Signed-off-by: Brian King <brking@xxxxxxxxxxxxxxxxxx>
---

 drivers/scsi/ibmvscsi/ibmvscsi.c      |   19 +++++++++++++++++++
 drivers/scsi/ibmvscsi/ibmvscsi.h      |    1 +
 drivers/scsi/ibmvscsi/iseries_vscsi.c |    6 ++++++
 drivers/scsi/ibmvscsi/rpa_vscsi.c     |   13 +++++++++++++
 4 files changed, 39 insertions(+)

diff -puN drivers/scsi/ibmvscsi/ibmvscsi.c~ibmvscsi_suspend drivers/scsi/ibmvscsi/ibmvscsi.c
--- linux-2.6/drivers/scsi/ibmvscsi/ibmvscsi.c~ibmvscsi_suspend	2010-02-21 10:30:38.000000000 -0600
+++ linux-2.6-bjking1/drivers/scsi/ibmvscsi/ibmvscsi.c	2010-02-21 10:30:38.000000000 -0600
@@ -71,6 +71,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+#include <linux/pm.h>
 #include <asm/firmware.h>
 #include <asm/vio.h>
 #include <scsi/scsi.h>
@@ -1991,6 +1992,19 @@ static int ibmvscsi_remove(struct vio_de
 }
 
 /**
+ * ibmvscsi_resume: Resume from suspend
+ * @dev:	device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ */
+static int ibmvscsi_resume(struct device *dev)
+{
+	struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
+	return ibmvscsi_ops->resume(hostdata);
+}
+
+/**
  * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we 
  * support.
  */
@@ -2000,6 +2014,10 @@ static struct vio_device_id ibmvscsi_dev
 };
 MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
 
+static struct dev_pm_ops ibmvscsi_pm_ops = {
+	.resume = ibmvscsi_resume
+};
+
 static struct vio_driver ibmvscsi_driver = {
 	.id_table = ibmvscsi_device_table,
 	.probe = ibmvscsi_probe,
@@ -2008,6 +2026,7 @@ static struct vio_driver ibmvscsi_driver
 	.driver = {
 		.name = "ibmvscsi",
 		.owner = THIS_MODULE,
+		.pm = &ibmvscsi_pm_ops,
 	}
 };
 
diff -puN drivers/scsi/ibmvscsi/rpa_vscsi.c~ibmvscsi_suspend drivers/scsi/ibmvscsi/rpa_vscsi.c
--- linux-2.6/drivers/scsi/ibmvscsi/rpa_vscsi.c~ibmvscsi_suspend	2010-02-21 10:30:38.000000000 -0600
+++ linux-2.6-bjking1/drivers/scsi/ibmvscsi/rpa_vscsi.c	2010-02-21 10:30:38.000000000 -0600
@@ -334,10 +334,23 @@ static int rpavscsi_reenable_crq_queue(s
 	return rc;
 }
 
+/**
+ * rpavscsi_resume: - resume after suspend
+ * @hostdata:	ibmvscsi_host_data of host
+ *
+ */
+static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+	vio_disable_interrupts(to_vio_dev(hostdata->dev));
+	tasklet_schedule(&hostdata->srp_task);
+	return 0;
+}
+
 struct ibmvscsi_ops rpavscsi_ops = {
 	.init_crq_queue = rpavscsi_init_crq_queue,
 	.release_crq_queue = rpavscsi_release_crq_queue,
 	.reset_crq_queue = rpavscsi_reset_crq_queue,
 	.reenable_crq_queue = rpavscsi_reenable_crq_queue,
 	.send_crq = rpavscsi_send_crq,
+	.resume = rpavscsi_resume,
 };
diff -puN drivers/scsi/ibmvscsi/ibmvscsi.h~ibmvscsi_suspend drivers/scsi/ibmvscsi/ibmvscsi.h
--- linux-2.6/drivers/scsi/ibmvscsi/ibmvscsi.h~ibmvscsi_suspend	2010-02-21 10:30:38.000000000 -0600
+++ linux-2.6-bjking1/drivers/scsi/ibmvscsi/ibmvscsi.h	2010-02-21 10:30:38.000000000 -0600
@@ -120,6 +120,7 @@ struct ibmvscsi_ops {
 				  struct ibmvscsi_host_data *hostdata);
 	int (*send_crq)(struct ibmvscsi_host_data *hostdata,
 		       u64 word1, u64 word2);
+	int (*resume) (struct ibmvscsi_host_data *hostdata);
 };
 
 extern struct ibmvscsi_ops iseriesvscsi_ops;
diff -puN drivers/scsi/ibmvscsi/iseries_vscsi.c~ibmvscsi_suspend drivers/scsi/ibmvscsi/iseries_vscsi.c
--- linux-2.6/drivers/scsi/ibmvscsi/iseries_vscsi.c~ibmvscsi_suspend	2010-02-21 10:30:38.000000000 -0600
+++ linux-2.6-bjking1/drivers/scsi/ibmvscsi/iseries_vscsi.c	2010-02-21 10:30:38.000000000 -0600
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct
 					     0);
 }
 
+static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+	return 0;
+}
+
 struct ibmvscsi_ops iseriesvscsi_ops = {
 	.init_crq_queue = iseriesvscsi_init_crq_queue,
 	.release_crq_queue = iseriesvscsi_release_crq_queue,
 	.reset_crq_queue = iseriesvscsi_reset_crq_queue,
 	.reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
 	.send_crq = iseriesvscsi_send_crq,
+	.resume = iseriesvscsi_resume,
 };
_
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux