]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
aacraid: Fix character device re-initialization
authorRaghava Aditya Renukunta <raghavaaditya.renukunta@pmcs.com>
Wed, 3 Feb 2016 23:06:07 +0000 (15:06 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 24 Feb 2016 02:27:02 +0000 (21:27 -0500)
During EEH PCI hotplug activity kernel unloads and loads the driver,
causing character device to be unregistered(aac_remove_one).When the
driver is loaded back using aac_probe_one the character device needs
to be registered again for the AIF management tools to work.

Fixed by adding code to register character device in aac_probe_one if
it is unregistered in aac_remove_one.

Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@pmcs.com>
Reviewed-by: Shane Seymour <shane.seymour@hpe.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c

index 75bc65ecad37a84ba7a70ae7621b152bcad36450..9cdf4d2bdece86804b00b0edb85707eda4ad9798 100644 (file)
@@ -94,6 +94,13 @@ enum {
 #define aac_phys_to_logical(x)  ((x)+1)
 #define aac_logical_to_phys(x)  ((x)?(x)-1:0)
 
+/*
+ * These macros are for keeping track of
+ * character device state.
+ */
+#define AAC_CHARDEV_UNREGISTERED       (-1)
+#define AAC_CHARDEV_NEEDS_REINIT       (-2)
+
 /* #define AAC_DETAILED_STATUS_INFO */
 
 struct diskparm
index 334f2a602fca98bb4720ac57106e0dc28df903fb..21a67ed047e8741889ee2a254989f55d095ddbd8 100644 (file)
@@ -80,7 +80,7 @@ MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
 
 static DEFINE_MUTEX(aac_mutex);
 static LIST_HEAD(aac_devices);
-static int aac_cfg_major = -1;
+static int aac_cfg_major = AAC_CHARDEV_UNREGISTERED;
 char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
 
 /*
@@ -1118,6 +1118,13 @@ static void __aac_shutdown(struct aac_dev * aac)
        else if (aac->max_msix > 1)
                pci_disable_msix(aac->pdev);
 }
+static void aac_init_char(void)
+{
+       aac_cfg_major = register_chrdev(0, "aac", &aac_cfg_fops);
+       if (aac_cfg_major < 0) {
+               pr_err("aacraid: unable to register \"aac\" device.\n");
+       }
+}
 
 static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
@@ -1175,6 +1182,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        shost->max_cmd_len = 16;
        shost->use_cmd_list = 1;
 
+       if (aac_cfg_major == AAC_CHARDEV_NEEDS_REINIT)
+               aac_init_char();
+
        aac = (struct aac_dev *)shost->hostdata;
        aac->base_start = pci_resource_start(pdev, 0);
        aac->scsi_host_ptr = shost;
@@ -1514,7 +1524,7 @@ static void aac_remove_one(struct pci_dev *pdev)
        pci_disable_device(pdev);
        if (list_empty(&aac_devices)) {
                unregister_chrdev(aac_cfg_major, "aac");
-               aac_cfg_major = -1;
+               aac_cfg_major = AAC_CHARDEV_NEEDS_REINIT;
        }
 }
 
@@ -1674,11 +1684,8 @@ static int __init aac_init(void)
        if (error < 0)
                return error;
 
-       aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops);
-       if (aac_cfg_major < 0) {
-               printk(KERN_WARNING
-                       "aacraid: unable to register \"aac\" device.\n");
-       }
+       aac_init_char();
+
 
        return 0;
 }