diff options
author | Scott Teel <scott.teel@hp.com> | 2012-01-19 15:01:30 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:08:57 -0500 |
commit | bd9244f7b9508a5945dcbd015db334110a9cdecf (patch) | |
tree | 595b66138bf997b5d7d9d8326ffdda212ade0b9b /drivers/scsi/hpsa.c | |
parent | 4f4eb9f1d8f8eb91d0dd486deafd4800b425f289 (diff) |
[SCSI] hpsa: update device attributes when they change
Certain types of changes to devices should not be interpreted as a device
change that would cause the device to be removed and re-added. These include
RAID level and Firmware revision changes. However, these attribute changes DO
need to be reflected in the controller info structure's dev structure list, so
that sysfs and /proc info files for the devices will reflect the new values.
Signed-off-by: Scott Teel <scott.stacy.teel@hp.com>
Acked-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 74326b3b5341..13195072b234 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -677,6 +677,20 @@ lun_assigned: | |||
677 | return 0; | 677 | return 0; |
678 | } | 678 | } |
679 | 679 | ||
680 | /* Update an entry in h->dev[] array. */ | ||
681 | static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno, | ||
682 | int entry, struct hpsa_scsi_dev_t *new_entry) | ||
683 | { | ||
684 | /* assumes h->devlock is held */ | ||
685 | BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES); | ||
686 | |||
687 | /* Raid level changed. */ | ||
688 | h->dev[entry]->raid_level = new_entry->raid_level; | ||
689 | dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d updated.\n", | ||
690 | scsi_device_type(new_entry->devtype), hostno, new_entry->bus, | ||
691 | new_entry->target, new_entry->lun); | ||
692 | } | ||
693 | |||
680 | /* Replace an entry from h->dev[] array. */ | 694 | /* Replace an entry from h->dev[] array. */ |
681 | static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, | 695 | static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, |
682 | int entry, struct hpsa_scsi_dev_t *new_entry, | 696 | int entry, struct hpsa_scsi_dev_t *new_entry, |
@@ -783,10 +797,25 @@ static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1, | |||
783 | return 1; | 797 | return 1; |
784 | } | 798 | } |
785 | 799 | ||
800 | static inline int device_updated(struct hpsa_scsi_dev_t *dev1, | ||
801 | struct hpsa_scsi_dev_t *dev2) | ||
802 | { | ||
803 | /* Device attributes that can change, but don't mean | ||
804 | * that the device is a different device, nor that the OS | ||
805 | * needs to be told anything about the change. | ||
806 | */ | ||
807 | if (dev1->raid_level != dev2->raid_level) | ||
808 | return 1; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
786 | /* Find needle in haystack. If exact match found, return DEVICE_SAME, | 812 | /* Find needle in haystack. If exact match found, return DEVICE_SAME, |
787 | * and return needle location in *index. If scsi3addr matches, but not | 813 | * and return needle location in *index. If scsi3addr matches, but not |
788 | * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle | 814 | * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle |
789 | * location in *index. If needle not found, return DEVICE_NOT_FOUND. | 815 | * location in *index. |
816 | * In the case of a minor device attribute change, such as RAID level, just | ||
817 | * return DEVICE_UPDATED, along with the updated device's location in index. | ||
818 | * If needle not found, return DEVICE_NOT_FOUND. | ||
790 | */ | 819 | */ |
791 | static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle, | 820 | static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle, |
792 | struct hpsa_scsi_dev_t *haystack[], int haystack_size, | 821 | struct hpsa_scsi_dev_t *haystack[], int haystack_size, |
@@ -796,15 +825,19 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle, | |||
796 | #define DEVICE_NOT_FOUND 0 | 825 | #define DEVICE_NOT_FOUND 0 |
797 | #define DEVICE_CHANGED 1 | 826 | #define DEVICE_CHANGED 1 |
798 | #define DEVICE_SAME 2 | 827 | #define DEVICE_SAME 2 |
828 | #define DEVICE_UPDATED 3 | ||
799 | for (i = 0; i < haystack_size; i++) { | 829 | for (i = 0; i < haystack_size; i++) { |
800 | if (haystack[i] == NULL) /* previously removed. */ | 830 | if (haystack[i] == NULL) /* previously removed. */ |
801 | continue; | 831 | continue; |
802 | if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) { | 832 | if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) { |
803 | *index = i; | 833 | *index = i; |
804 | if (device_is_the_same(needle, haystack[i])) | 834 | if (device_is_the_same(needle, haystack[i])) { |
835 | if (device_updated(needle, haystack[i])) | ||
836 | return DEVICE_UPDATED; | ||
805 | return DEVICE_SAME; | 837 | return DEVICE_SAME; |
806 | else | 838 | } else { |
807 | return DEVICE_CHANGED; | 839 | return DEVICE_CHANGED; |
840 | } | ||
808 | } | 841 | } |
809 | } | 842 | } |
810 | *index = -1; | 843 | *index = -1; |
@@ -840,6 +873,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno, | |||
840 | * sd[] and remove them from h->dev[], and for any | 873 | * sd[] and remove them from h->dev[], and for any |
841 | * devices which have changed, remove the old device | 874 | * devices which have changed, remove the old device |
842 | * info and add the new device info. | 875 | * info and add the new device info. |
876 | * If minor device attributes change, just update | ||
877 | * the existing device structure. | ||
843 | */ | 878 | */ |
844 | i = 0; | 879 | i = 0; |
845 | nremoved = 0; | 880 | nremoved = 0; |
@@ -860,6 +895,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno, | |||
860 | * at the bottom of hpsa_update_scsi_devices() | 895 | * at the bottom of hpsa_update_scsi_devices() |
861 | */ | 896 | */ |
862 | sd[entry] = NULL; | 897 | sd[entry] = NULL; |
898 | } else if (device_change == DEVICE_UPDATED) { | ||
899 | hpsa_scsi_update_entry(h, hostno, i, sd[entry]); | ||
863 | } | 900 | } |
864 | i++; | 901 | i++; |
865 | } | 902 | } |