lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 17 Feb 2009 08:25:07 -0700
From:	"Yang, Bo" <Bo.Yang@....com>
To:	"Yang, Bo" <Bo.Yang@....com>,
	James Bottomley <James.Bottomley@...senPartnership.com>,
	"linux-scsi@...r.kernel.org" <linux-scsi@...r.kernel.org>,
	"akpm@...l.org" <akpm@...l.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
CC:	"Austria, Winston" <Winston.Austria@....com>
Subject: [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid
 sas driver - I

Add Poll_wait mechanism to Gen-2 MegaRAID SAS Linux driver.  In the aen handler, driver needs to wakeup poll handler similar to the way it raises SIGIO.  Driver needs to reregister for AEN with the FW when it receives AEN.

Signed-off-by Bo Yang<bo.yang@....com>

---
drivers/scsi/megaraid/megaraid_sas.c |  133 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |   15 +++
 2 files changed, 147 insertions(+), 1 deletion(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:36:36.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:39:26.000000000 -0500
@@ -40,6 +40,7 @@
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/poll.h>

 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -89,6 +90,11 @@ static struct megasas_mgmt_info megasas_
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);

+static int megasas_poll_wait_aen;
+static DECLARE_WAIT_QUEUE_HEAD (megasas_poll_wait);
+extern void
+poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *token);
+
 static u32 megasas_dbg_lvl;

 static void
@@ -1277,6 +1283,8 @@ megasas_bios_param(struct scsi_device *s
        return 0;
 }

+static void megasas_aen_polling(void *arg);
+
 /**
  * megasas_service_aen -       Processes an event notification
  * @instance:                  Adapter soft state
@@ -1295,8 +1303,20 @@ megasas_service_aen(struct megasas_insta
        /*
         * Don't signal app if it is just an aborted previously registered aen
         */
-       if (!cmd->abort_aen)
+       if ((!cmd->abort_aen) && (instance->unload == 0)) {
+               struct megasas_aen_event *ev;
+               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+               if (!ev) {
+                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+               } else {
+                       ev->instance = instance;
+                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
+                       schedule_delayed_work(&ev->hotplug_work, 0);
+               }
+               megasas_poll_wait_aen = 1;
+               wake_up(&megasas_poll_wait);
                kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+       }
        else
                cmd->abort_aen = 0;

@@ -2621,6 +2641,7 @@ megasas_probe_one(struct pci_dev *pdev,

        megasas_dbg_lvl = 0;
        instance->flag = 0;
+       instance->unload = 0;
        instance->last_time = 0;

        /*
@@ -2924,6 +2945,7 @@ static void __devexit megasas_detach_one
        struct megasas_instance *instance;

        instance = pci_get_drvdata(pdev);
+       instance->unload = 1;
        host = instance->host;

        if (poll_mode_io)
@@ -3027,6 +3049,21 @@ static int megasas_mgmt_fasync(int fd, s
 }

 /**
+ * megasas_mgmt_poll -  char node "poll" entry point
+ * */
+static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
+{
+       unsigned int mask = 0;
+       poll_wait(file, &megasas_poll_wait, wait);
+
+       if (megasas_poll_wait_aen) {
+               mask |=   (POLLIN | POLLRDNORM);
+               megasas_poll_wait_aen = 0;
+       }
+       return mask;
+}
+
+/**
  * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
  * @instance:                  Adapter soft state
  * @argp:                      User's ioctl packet
@@ -3348,6 +3385,7 @@ static const struct file_operations mega
        .open = megasas_mgmt_open,
        .fasync = megasas_mgmt_fasync,
        .unlocked_ioctl = megasas_mgmt_ioctl,
+       .poll = megasas_mgmt_poll,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = megasas_mgmt_compat_ioctl,
 #endif
@@ -3462,6 +3500,99 @@ out:
        return retval;
 }

+
+static void
+megasas_aen_polling(struct work_struct *work)
+{
+       struct megasas_aen_event *ev =
+               container_of(work, struct megasas_aen_event, hotplug_work);
+       struct megasas_instance *instance = ev->instance;
+       struct megasas_evt_log_info eli;
+       union megasas_evt_class_locale class_locale;
+       int doscan = 0;
+       u32 seq_num;
+       int error;
+
+       if (!instance) {
+               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
+               kfree(ev);
+               return;
+       }
+
+       if (instance->evt_detail) {
+               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,
+                       instance->host->host_no, instance->evt_detail->code);
+
+               switch (instance->evt_detail->code) {
+
+               case MR_EVT_LD_CREATED:
+               case MR_EVT_PD_INSERTED:
+               case MR_EVT_LD_DELETED:
+               case MR_EVT_LD_OFFLINE:
+               case MR_EVT_CFG_CLEARED:
+               case MR_EVT_PD_REMOVED:
+               case MR_EVT_FOREIGN_CFG_IMPORTED:
+               case MR_EVT_LD_STATE_CHANGE:
+                       doscan = 1;
+                       break;
+               default:
+                       doscan = 0;
+                       break;
+               }
+       } else {
+               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
+                       __FUNCTION__, instance->host->host_no);
+               kfree(ev);
+               return;
+       }
+
+       if (doscan) {
+               printk(KERN_INFO "%s[%d]: scanning ...\n",
+                       __FUNCTION__, instance->host->host_no);
+               scsi_scan_host(instance->host);
+               msleep(1000);
+       }
+
+       kfree(ev);
+       /**
+       * Get the latest sequence number from FW
+       **/
+
+       memset(&eli, 0, sizeof(eli));
+
+       if (megasas_get_seq_num(instance, &eli)) {
+               printk(KERN_ERR "%s[%d]: failed to get seq_num\n",
+                       __FUNCTION__, instance->host->host_no);
+               return;
+       }
+
+       seq_num = instance->evt_detail->seq_num + 1;
+
+       /**
+       * Register AEN with FW for latest sequence number plus 1
+       **/
+
+       class_locale.members.reserved = 0;
+       class_locale.members.locale = MR_EVT_LOCALE_ALL;
+       class_locale.members.class = MR_EVT_CLASS_DEBUG;
+
+       down(&instance->aen_mutex);
+
+       error = megasas_register_aen(instance, seq_num,
+                               class_locale.word);
+
+       up(&instance->aen_mutex);
+
+       if (error)
+               printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
+                        __FUNCTION__, instance->host->host_no, error);
+       else
+               printk(KERN_INFO "%s[%d]: aen registered\n",
+                       __FUNCTION__, instance->host->host_no);
+
+}
+
+
 static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
                megasas_sysfs_show_poll_mode_io,
                megasas_sysfs_set_poll_mode_io);
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 15:36:37.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -132,6 +132,16 @@
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200

+#define MR_EVT_CFG_CLEARED                     0x0004
+
+#define MR_EVT_LD_STATE_CHANGE                 0x0051
+#define MR_EVT_PD_INSERTED                     0x005b
+#define MR_EVT_PD_REMOVED                      0x0070
+#define MR_EVT_LD_CREATED                      0x008a
+#define MR_EVT_LD_DELETED                      0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED            0x00db
+#define MR_EVT_LD_OFFLINE                      0x00fc
+
 /*
  * MFI command completion codes
  */
@@ -1072,6 +1082,11 @@ struct megasas_evt_detail {
        u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
  };

+struct megasas_aen_event {
+       struct work_struct hotplug_work;
+       struct megasas_instance *instance;
+};
+
 struct megasas_instance {

        u32 *producer;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ