]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/scsi/hpsa.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platf...
[mv-sheeva.git] / drivers / scsi / hpsa.c
index 42295c49682fcc09a6f89cccf9137bc9863cf2aa..03697ba942510243de25b4f4d093605ac3c16366 100644 (file)
@@ -52,7 +52,7 @@
 #include "hpsa.h"
 
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "1.0.0"
+#define HPSA_DRIVER_VERSION "2.0.1-3"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
@@ -675,6 +675,24 @@ lun_assigned:
        return 0;
 }
 
+/* Replace an entry from h->dev[] array. */
+static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
+       int entry, struct hpsa_scsi_dev_t *new_entry,
+       struct hpsa_scsi_dev_t *added[], int *nadded,
+       struct hpsa_scsi_dev_t *removed[], int *nremoved)
+{
+       /* assumes h->devlock is held */
+       BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
+       removed[*nremoved] = h->dev[entry];
+       (*nremoved)++;
+       h->dev[entry] = new_entry;
+       added[*nadded] = new_entry;
+       (*nadded)++;
+       dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d changed.\n",
+               scsi_device_type(new_entry->devtype), hostno, new_entry->bus,
+                       new_entry->target, new_entry->lun);
+}
+
 /* Remove an entry from h->dev[] array. */
 static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
        struct hpsa_scsi_dev_t *removed[], int *nremoved)
@@ -776,6 +794,8 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 #define DEVICE_CHANGED 1
 #define DEVICE_SAME 2
        for (i = 0; i < haystack_size; i++) {
+               if (haystack[i] == NULL) /* previously removed. */
+                       continue;
                if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
                        *index = i;
                        if (device_is_the_same(needle, haystack[i]))
@@ -833,12 +853,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
                        continue; /* remove ^^^, hence i not incremented */
                } else if (device_change == DEVICE_CHANGED) {
                        changes++;
-                       hpsa_scsi_remove_entry(h, hostno, i,
-                               removed, &nremoved);
-                       (void) hpsa_scsi_add_entry(h, hostno, sd[entry],
-                               added, &nadded);
-                       /* add can't fail, we just removed one. */
-
+                       hpsa_scsi_replace_entry(h, hostno, i, sd[entry],
+                               added, &nadded, removed, &nremoved);
                        /* Set it to NULL to prevent it from being freed
                         * at the bottom of hpsa_update_scsi_devices()
                         */
@@ -2271,50 +2287,6 @@ static void cmd_special_free(struct ctlr_info *h, struct CommandList *c)
 
 #ifdef CONFIG_COMPAT
 
-static int do_ioctl(struct scsi_device *dev, int cmd, void *arg)
-{
-       int ret;
-
-       lock_kernel();
-       ret = hpsa_ioctl(dev, cmd, arg);
-       unlock_kernel();
-       return ret;
-}
-
-static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg);
-static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
-       int cmd, void *arg);
-
-static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg)
-{
-       switch (cmd) {
-       case CCISS_GETPCIINFO:
-       case CCISS_GETINTINFO:
-       case CCISS_SETINTINFO:
-       case CCISS_GETNODENAME:
-       case CCISS_SETNODENAME:
-       case CCISS_GETHEARTBEAT:
-       case CCISS_GETBUSTYPES:
-       case CCISS_GETFIRMVER:
-       case CCISS_GETDRIVVER:
-       case CCISS_REVALIDVOLS:
-       case CCISS_DEREGDISK:
-       case CCISS_REGNEWDISK:
-       case CCISS_REGNEWD:
-       case CCISS_RESCANDISK:
-       case CCISS_GETLUNINFO:
-               return do_ioctl(dev, cmd, arg);
-
-       case CCISS_PASSTHRU32:
-               return hpsa_ioctl32_passthru(dev, cmd, arg);
-       case CCISS_BIG_PASSTHRU32:
-               return hpsa_ioctl32_big_passthru(dev, cmd, arg);
-
-       default:
-               return -ENOIOCTLCMD;
-       }
-}
-
 static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg)
 {
        IOCTL32_Command_struct __user *arg32 =
@@ -2339,7 +2311,7 @@ static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg)
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(dev, CCISS_PASSTHRU, (void *)p);
+       err = hpsa_ioctl(dev, CCISS_PASSTHRU, (void *)p);
        if (err)
                return err;
        err |= copy_in_user(&arg32->error_info, &p->error_info,
@@ -2376,7 +2348,7 @@ static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p);
+       err = hpsa_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p);
        if (err)
                return err;
        err |= copy_in_user(&arg32->error_info, &p->error_info,
@@ -2385,6 +2357,36 @@ static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
                return -EFAULT;
        return err;
 }
+
+static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg)
+{
+       switch (cmd) {
+       case CCISS_GETPCIINFO:
+       case CCISS_GETINTINFO:
+       case CCISS_SETINTINFO:
+       case CCISS_GETNODENAME:
+       case CCISS_SETNODENAME:
+       case CCISS_GETHEARTBEAT:
+       case CCISS_GETBUSTYPES:
+       case CCISS_GETFIRMVER:
+       case CCISS_GETDRIVVER:
+       case CCISS_REVALIDVOLS:
+       case CCISS_DEREGDISK:
+       case CCISS_REGNEWDISK:
+       case CCISS_REGNEWD:
+       case CCISS_RESCANDISK:
+       case CCISS_GETLUNINFO:
+               return hpsa_ioctl(dev, cmd, arg);
+
+       case CCISS_PASSTHRU32:
+               return hpsa_ioctl32_passthru(dev, cmd, arg);
+       case CCISS_BIG_PASSTHRU32:
+               return hpsa_ioctl32_big_passthru(dev, cmd, arg);
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
 #endif
 
 static int hpsa_getpciinfo_ioctl(struct ctlr_info *h, void __user *argp)