diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
| -rw-r--r-- | drivers/scsi/hpsa.c | 754 |
1 files changed, 512 insertions, 242 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index c016426b31b2..4f5551b5fe53 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
| @@ -86,10 +86,17 @@ static const struct pci_device_id hpsa_pci_device_id[] = { | |||
| 86 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324a}, | 86 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324a}, |
| 87 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324b}, | 87 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324b}, |
| 88 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3233}, | 88 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3233}, |
| 89 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3250}, | ||
| 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3251}, | ||
| 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, | ||
| 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, | ||
| 93 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, | ||
| 89 | #define PCI_DEVICE_ID_HP_CISSF 0x333f | 94 | #define PCI_DEVICE_ID_HP_CISSF 0x333f |
| 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, | 95 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, |
| 91 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 96 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 92 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 97 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
| 98 | {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 99 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
| 93 | {0,} | 100 | {0,} |
| 94 | }; | 101 | }; |
| 95 | 102 | ||
| @@ -109,12 +116,18 @@ static struct board_type products[] = { | |||
| 109 | {0x324b103C, "Smart Array P711m", &SA5_access}, | 116 | {0x324b103C, "Smart Array P711m", &SA5_access}, |
| 110 | {0x3233103C, "StorageWorks P1210m", &SA5_access}, | 117 | {0x3233103C, "StorageWorks P1210m", &SA5_access}, |
| 111 | {0x333F103C, "StorageWorks P1210m", &SA5_access}, | 118 | {0x333F103C, "StorageWorks P1210m", &SA5_access}, |
| 119 | {0x3250103C, "Smart Array", &SA5_access}, | ||
| 120 | {0x3250113C, "Smart Array", &SA5_access}, | ||
| 121 | {0x3250123C, "Smart Array", &SA5_access}, | ||
| 122 | {0x3250133C, "Smart Array", &SA5_access}, | ||
| 123 | {0x3250143C, "Smart Array", &SA5_access}, | ||
| 112 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, | 124 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, |
| 113 | }; | 125 | }; |
| 114 | 126 | ||
| 115 | static int number_of_controllers; | 127 | static int number_of_controllers; |
| 116 | 128 | ||
| 117 | static irqreturn_t do_hpsa_intr(int irq, void *dev_id); | 129 | static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id); |
| 130 | static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id); | ||
| 118 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); | 131 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); |
| 119 | static void start_io(struct ctlr_info *h); | 132 | static void start_io(struct ctlr_info *h); |
| 120 | 133 | ||
| @@ -148,6 +161,8 @@ static ssize_t lunid_show(struct device *dev, | |||
| 148 | struct device_attribute *attr, char *buf); | 161 | struct device_attribute *attr, char *buf); |
| 149 | static ssize_t unique_id_show(struct device *dev, | 162 | static ssize_t unique_id_show(struct device *dev, |
| 150 | struct device_attribute *attr, char *buf); | 163 | struct device_attribute *attr, char *buf); |
| 164 | static ssize_t host_show_firmware_revision(struct device *dev, | ||
| 165 | struct device_attribute *attr, char *buf); | ||
| 151 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno); | 166 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno); |
| 152 | static ssize_t host_store_rescan(struct device *dev, | 167 | static ssize_t host_store_rescan(struct device *dev, |
| 153 | struct device_attribute *attr, const char *buf, size_t count); | 168 | struct device_attribute *attr, const char *buf, size_t count); |
| @@ -158,13 +173,21 @@ static void check_ioctl_unit_attention(struct ctlr_info *h, | |||
| 158 | /* performant mode helper functions */ | 173 | /* performant mode helper functions */ |
| 159 | static void calc_bucket_map(int *bucket, int num_buckets, | 174 | static void calc_bucket_map(int *bucket, int num_buckets, |
| 160 | int nsgs, int *bucket_map); | 175 | int nsgs, int *bucket_map); |
| 161 | static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h); | 176 | static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h); |
| 162 | static inline u32 next_command(struct ctlr_info *h); | 177 | static inline u32 next_command(struct ctlr_info *h); |
| 178 | static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev, | ||
| 179 | void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, | ||
| 180 | u64 *cfg_offset); | ||
| 181 | static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, | ||
| 182 | unsigned long *memory_bar); | ||
| 183 | static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); | ||
| 163 | 184 | ||
| 164 | static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); | 185 | static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); |
| 165 | static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); | 186 | static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); |
| 166 | static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL); | 187 | static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL); |
| 167 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); | 188 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); |
| 189 | static DEVICE_ATTR(firmware_revision, S_IRUGO, | ||
| 190 | host_show_firmware_revision, NULL); | ||
| 168 | 191 | ||
| 169 | static struct device_attribute *hpsa_sdev_attrs[] = { | 192 | static struct device_attribute *hpsa_sdev_attrs[] = { |
| 170 | &dev_attr_raid_level, | 193 | &dev_attr_raid_level, |
| @@ -175,6 +198,7 @@ static struct device_attribute *hpsa_sdev_attrs[] = { | |||
| 175 | 198 | ||
| 176 | static struct device_attribute *hpsa_shost_attrs[] = { | 199 | static struct device_attribute *hpsa_shost_attrs[] = { |
| 177 | &dev_attr_rescan, | 200 | &dev_attr_rescan, |
| 201 | &dev_attr_firmware_revision, | ||
| 178 | NULL, | 202 | NULL, |
| 179 | }; | 203 | }; |
| 180 | 204 | ||
| @@ -260,6 +284,21 @@ static ssize_t host_store_rescan(struct device *dev, | |||
| 260 | return count; | 284 | return count; |
| 261 | } | 285 | } |
| 262 | 286 | ||
| 287 | static ssize_t host_show_firmware_revision(struct device *dev, | ||
| 288 | struct device_attribute *attr, char *buf) | ||
| 289 | { | ||
| 290 | struct ctlr_info *h; | ||
| 291 | struct Scsi_Host *shost = class_to_shost(dev); | ||
| 292 | unsigned char *fwrev; | ||
| 293 | |||
| 294 | h = shost_to_hba(shost); | ||
| 295 | if (!h->hba_inquiry_data) | ||
| 296 | return 0; | ||
| 297 | fwrev = &h->hba_inquiry_data[32]; | ||
| 298 | return snprintf(buf, 20, "%c%c%c%c\n", | ||
| 299 | fwrev[0], fwrev[1], fwrev[2], fwrev[3]); | ||
| 300 | } | ||
| 301 | |||
| 263 | /* Enqueuing and dequeuing functions for cmdlists. */ | 302 | /* Enqueuing and dequeuing functions for cmdlists. */ |
| 264 | static inline void addQ(struct hlist_head *list, struct CommandList *c) | 303 | static inline void addQ(struct hlist_head *list, struct CommandList *c) |
| 265 | { | 304 | { |
| @@ -1440,12 +1479,6 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
| 1440 | goto bail_out; | 1479 | goto bail_out; |
| 1441 | } | 1480 | } |
| 1442 | 1481 | ||
| 1443 | /* As a side effect, record the firmware version number | ||
| 1444 | * if we happen to be talking to the RAID controller. | ||
| 1445 | */ | ||
| 1446 | if (is_hba_lunid(scsi3addr)) | ||
| 1447 | memcpy(h->firm_ver, &inq_buff[32], 4); | ||
| 1448 | |||
| 1449 | this_device->devtype = (inq_buff[0] & 0x1f); | 1482 | this_device->devtype = (inq_buff[0] & 0x1f); |
| 1450 | memcpy(this_device->scsi3addr, scsi3addr, 8); | 1483 | memcpy(this_device->scsi3addr, scsi3addr, 8); |
| 1451 | memcpy(this_device->vendor, &inq_buff[8], | 1484 | memcpy(this_device->vendor, &inq_buff[8], |
| @@ -2826,9 +2859,8 @@ static inline bool interrupt_pending(struct ctlr_info *h) | |||
| 2826 | 2859 | ||
| 2827 | static inline long interrupt_not_for_us(struct ctlr_info *h) | 2860 | static inline long interrupt_not_for_us(struct ctlr_info *h) |
| 2828 | { | 2861 | { |
| 2829 | return !(h->msi_vector || h->msix_vector) && | 2862 | return (h->access.intr_pending(h) == 0) || |
| 2830 | ((h->access.intr_pending(h) == 0) || | 2863 | (h->interrupts_enabled == 0); |
| 2831 | (h->interrupts_enabled == 0)); | ||
| 2832 | } | 2864 | } |
| 2833 | 2865 | ||
| 2834 | static inline int bad_tag(struct ctlr_info *h, u32 tag_index, | 2866 | static inline int bad_tag(struct ctlr_info *h, u32 tag_index, |
| @@ -2902,7 +2934,7 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h, | |||
| 2902 | return next_command(h); | 2934 | return next_command(h); |
| 2903 | } | 2935 | } |
| 2904 | 2936 | ||
| 2905 | static irqreturn_t do_hpsa_intr(int irq, void *dev_id) | 2937 | static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id) |
| 2906 | { | 2938 | { |
| 2907 | struct ctlr_info *h = dev_id; | 2939 | struct ctlr_info *h = dev_id; |
| 2908 | unsigned long flags; | 2940 | unsigned long flags; |
| @@ -2911,6 +2943,26 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id) | |||
| 2911 | if (interrupt_not_for_us(h)) | 2943 | if (interrupt_not_for_us(h)) |
| 2912 | return IRQ_NONE; | 2944 | return IRQ_NONE; |
| 2913 | spin_lock_irqsave(&h->lock, flags); | 2945 | spin_lock_irqsave(&h->lock, flags); |
| 2946 | while (interrupt_pending(h)) { | ||
| 2947 | raw_tag = get_next_completion(h); | ||
| 2948 | while (raw_tag != FIFO_EMPTY) { | ||
| 2949 | if (hpsa_tag_contains_index(raw_tag)) | ||
| 2950 | raw_tag = process_indexed_cmd(h, raw_tag); | ||
| 2951 | else | ||
| 2952 | raw_tag = process_nonindexed_cmd(h, raw_tag); | ||
| 2953 | } | ||
| 2954 | } | ||
| 2955 | spin_unlock_irqrestore(&h->lock, flags); | ||
| 2956 | return IRQ_HANDLED; | ||
| 2957 | } | ||
| 2958 | |||
| 2959 | static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id) | ||
| 2960 | { | ||
| 2961 | struct ctlr_info *h = dev_id; | ||
| 2962 | unsigned long flags; | ||
| 2963 | u32 raw_tag; | ||
| 2964 | |||
| 2965 | spin_lock_irqsave(&h->lock, flags); | ||
| 2914 | raw_tag = get_next_completion(h); | 2966 | raw_tag = get_next_completion(h); |
| 2915 | while (raw_tag != FIFO_EMPTY) { | 2967 | while (raw_tag != FIFO_EMPTY) { |
| 2916 | if (hpsa_tag_contains_index(raw_tag)) | 2968 | if (hpsa_tag_contains_index(raw_tag)) |
| @@ -3052,17 +3104,75 @@ static __devinit int hpsa_reset_msi(struct pci_dev *pdev) | |||
| 3052 | return 0; | 3104 | return 0; |
| 3053 | } | 3105 | } |
| 3054 | 3106 | ||
| 3055 | /* This does a hard reset of the controller using PCI power management | 3107 | static int hpsa_controller_hard_reset(struct pci_dev *pdev, |
| 3056 | * states. | 3108 | void * __iomem vaddr, bool use_doorbell) |
| 3057 | */ | ||
| 3058 | static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) | ||
| 3059 | { | 3109 | { |
| 3060 | u16 pmcsr, saved_config_space[32]; | 3110 | u16 pmcsr; |
| 3061 | int i, pos; | 3111 | int pos; |
| 3062 | 3112 | ||
| 3063 | dev_info(&pdev->dev, "using PCI PM to reset controller\n"); | 3113 | if (use_doorbell) { |
| 3114 | /* For everything after the P600, the PCI power state method | ||
| 3115 | * of resetting the controller doesn't work, so we have this | ||
| 3116 | * other way using the doorbell register. | ||
| 3117 | */ | ||
| 3118 | dev_info(&pdev->dev, "using doorbell to reset controller\n"); | ||
| 3119 | writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL); | ||
| 3120 | msleep(1000); | ||
| 3121 | } else { /* Try to do it the PCI power state way */ | ||
| 3122 | |||
| 3123 | /* Quoting from the Open CISS Specification: "The Power | ||
| 3124 | * Management Control/Status Register (CSR) controls the power | ||
| 3125 | * state of the device. The normal operating state is D0, | ||
| 3126 | * CSR=00h. The software off state is D3, CSR=03h. To reset | ||
| 3127 | * the controller, place the interface device in D3 then to D0, | ||
| 3128 | * this causes a secondary PCI reset which will reset the | ||
| 3129 | * controller." */ | ||
| 3130 | |||
| 3131 | pos = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
| 3132 | if (pos == 0) { | ||
| 3133 | dev_err(&pdev->dev, | ||
| 3134 | "hpsa_reset_controller: " | ||
| 3135 | "PCI PM not supported\n"); | ||
| 3136 | return -ENODEV; | ||
| 3137 | } | ||
| 3138 | dev_info(&pdev->dev, "using PCI PM to reset controller\n"); | ||
| 3139 | /* enter the D3hot power management state */ | ||
| 3140 | pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); | ||
| 3141 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | ||
| 3142 | pmcsr |= PCI_D3hot; | ||
| 3143 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | ||
| 3064 | 3144 | ||
| 3065 | /* This is very nearly the same thing as | 3145 | msleep(500); |
| 3146 | |||
| 3147 | /* enter the D0 power management state */ | ||
| 3148 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | ||
| 3149 | pmcsr |= PCI_D0; | ||
| 3150 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | ||
| 3151 | |||
| 3152 | msleep(500); | ||
| 3153 | } | ||
| 3154 | return 0; | ||
| 3155 | } | ||
| 3156 | |||
| 3157 | /* This does a hard reset of the controller using PCI power management | ||
| 3158 | * states or the using the doorbell register. | ||
| 3159 | */ | ||
| 3160 | static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) | ||
| 3161 | { | ||
| 3162 | u16 saved_config_space[32]; | ||
| 3163 | u64 cfg_offset; | ||
| 3164 | u32 cfg_base_addr; | ||
| 3165 | u64 cfg_base_addr_index; | ||
| 3166 | void __iomem *vaddr; | ||
| 3167 | unsigned long paddr; | ||
| 3168 | u32 misc_fw_support, active_transport; | ||
| 3169 | int rc, i; | ||
| 3170 | struct CfgTable __iomem *cfgtable; | ||
| 3171 | bool use_doorbell; | ||
| 3172 | u32 board_id; | ||
| 3173 | |||
| 3174 | /* For controllers as old as the P600, this is very nearly | ||
| 3175 | * the same thing as | ||
| 3066 | * | 3176 | * |
| 3067 | * pci_save_state(pci_dev); | 3177 | * pci_save_state(pci_dev); |
| 3068 | * pci_set_power_state(pci_dev, PCI_D3hot); | 3178 | * pci_set_power_state(pci_dev, PCI_D3hot); |
| @@ -3076,41 +3186,54 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) | |||
| 3076 | * violate the ordering requirements for restoring the | 3186 | * violate the ordering requirements for restoring the |
| 3077 | * configuration space from the CCISS document (see the | 3187 | * configuration space from the CCISS document (see the |
| 3078 | * comment below). So we roll our own .... | 3188 | * comment below). So we roll our own .... |
| 3189 | * | ||
| 3190 | * For controllers newer than the P600, the pci power state | ||
| 3191 | * method of resetting doesn't work so we have another way | ||
| 3192 | * using the doorbell register. | ||
| 3079 | */ | 3193 | */ |
| 3080 | 3194 | ||
| 3195 | /* Exclude 640x boards. These are two pci devices in one slot | ||
| 3196 | * which share a battery backed cache module. One controls the | ||
| 3197 | * cache, the other accesses the cache through the one that controls | ||
| 3198 | * it. If we reset the one controlling the cache, the other will | ||
| 3199 | * likely not be happy. Just forbid resetting this conjoined mess. | ||
| 3200 | * The 640x isn't really supported by hpsa anyway. | ||
| 3201 | */ | ||
| 3202 | hpsa_lookup_board_id(pdev, &board_id); | ||
| 3203 | if (board_id == 0x409C0E11 || board_id == 0x409D0E11) | ||
| 3204 | return -ENOTSUPP; | ||
| 3205 | |||
| 3081 | for (i = 0; i < 32; i++) | 3206 | for (i = 0; i < 32; i++) |
| 3082 | pci_read_config_word(pdev, 2*i, &saved_config_space[i]); | 3207 | pci_read_config_word(pdev, 2*i, &saved_config_space[i]); |
| 3083 | 3208 | ||
| 3084 | pos = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
| 3085 | if (pos == 0) { | ||
| 3086 | dev_err(&pdev->dev, | ||
| 3087 | "hpsa_reset_controller: PCI PM not supported\n"); | ||
| 3088 | return -ENODEV; | ||
| 3089 | } | ||
| 3090 | |||
| 3091 | /* Quoting from the Open CISS Specification: "The Power | ||
| 3092 | * Management Control/Status Register (CSR) controls the power | ||
| 3093 | * state of the device. The normal operating state is D0, | ||
| 3094 | * CSR=00h. The software off state is D3, CSR=03h. To reset | ||
| 3095 | * the controller, place the interface device in D3 then to | ||
| 3096 | * D0, this causes a secondary PCI reset which will reset the | ||
| 3097 | * controller." | ||
| 3098 | */ | ||
| 3099 | 3209 | ||
| 3100 | /* enter the D3hot power management state */ | 3210 | /* find the first memory BAR, so we can find the cfg table */ |
| 3101 | pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); | 3211 | rc = hpsa_pci_find_memory_BAR(pdev, &paddr); |
| 3102 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | 3212 | if (rc) |
| 3103 | pmcsr |= PCI_D3hot; | 3213 | return rc; |
| 3104 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | 3214 | vaddr = remap_pci_mem(paddr, 0x250); |
| 3215 | if (!vaddr) | ||
| 3216 | return -ENOMEM; | ||
| 3105 | 3217 | ||
| 3106 | msleep(500); | 3218 | /* find cfgtable in order to check if reset via doorbell is supported */ |
| 3219 | rc = hpsa_find_cfg_addrs(pdev, vaddr, &cfg_base_addr, | ||
| 3220 | &cfg_base_addr_index, &cfg_offset); | ||
| 3221 | if (rc) | ||
| 3222 | goto unmap_vaddr; | ||
| 3223 | cfgtable = remap_pci_mem(pci_resource_start(pdev, | ||
| 3224 | cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable)); | ||
| 3225 | if (!cfgtable) { | ||
| 3226 | rc = -ENOMEM; | ||
| 3227 | goto unmap_vaddr; | ||
| 3228 | } | ||
| 3107 | 3229 | ||
| 3108 | /* enter the D0 power management state */ | 3230 | /* If reset via doorbell register is supported, use that. */ |
| 3109 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | 3231 | misc_fw_support = readl(&cfgtable->misc_fw_support); |
| 3110 | pmcsr |= PCI_D0; | 3232 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; |
| 3111 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | ||
| 3112 | 3233 | ||
| 3113 | msleep(500); | 3234 | rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); |
| 3235 | if (rc) | ||
| 3236 | goto unmap_cfgtable; | ||
| 3114 | 3237 | ||
| 3115 | /* Restore the PCI configuration space. The Open CISS | 3238 | /* Restore the PCI configuration space. The Open CISS |
| 3116 | * Specification says, "Restore the PCI Configuration | 3239 | * Specification says, "Restore the PCI Configuration |
| @@ -3127,7 +3250,29 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) | |||
| 3127 | wmb(); | 3250 | wmb(); |
| 3128 | pci_write_config_word(pdev, 4, saved_config_space[2]); | 3251 | pci_write_config_word(pdev, 4, saved_config_space[2]); |
| 3129 | 3252 | ||
| 3130 | return 0; | 3253 | /* Some devices (notably the HP Smart Array 5i Controller) |
| 3254 | need a little pause here */ | ||
| 3255 | msleep(HPSA_POST_RESET_PAUSE_MSECS); | ||
| 3256 | |||
| 3257 | /* Controller should be in simple mode at this point. If it's not, | ||
| 3258 | * It means we're on one of those controllers which doesn't support | ||
| 3259 | * the doorbell reset method and on which the PCI power management reset | ||
| 3260 | * method doesn't work (P800, for example.) | ||
| 3261 | * In those cases, pretend the reset worked and hope for the best. | ||
| 3262 | */ | ||
| 3263 | active_transport = readl(&cfgtable->TransportActive); | ||
| 3264 | if (active_transport & PERFORMANT_MODE) { | ||
| 3265 | dev_warn(&pdev->dev, "Unable to successfully reset controller," | ||
| 3266 | " proceeding anyway.\n"); | ||
| 3267 | rc = -ENOTSUPP; | ||
| 3268 | } | ||
| 3269 | |||
| 3270 | unmap_cfgtable: | ||
| 3271 | iounmap(cfgtable); | ||
| 3272 | |||
| 3273 | unmap_vaddr: | ||
| 3274 | iounmap(vaddr); | ||
| 3275 | return rc; | ||
| 3131 | } | 3276 | } |
| 3132 | 3277 | ||
| 3133 | /* | 3278 | /* |
| @@ -3135,9 +3280,9 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) | |||
| 3135 | * the io functions. | 3280 | * the io functions. |
| 3136 | * This is for debug only. | 3281 | * This is for debug only. |
| 3137 | */ | 3282 | */ |
| 3138 | #ifdef HPSA_DEBUG | ||
| 3139 | static void print_cfg_table(struct device *dev, struct CfgTable *tb) | 3283 | static void print_cfg_table(struct device *dev, struct CfgTable *tb) |
| 3140 | { | 3284 | { |
| 3285 | #ifdef HPSA_DEBUG | ||
| 3141 | int i; | 3286 | int i; |
| 3142 | char temp_name[17]; | 3287 | char temp_name[17]; |
| 3143 | 3288 | ||
| @@ -3167,8 +3312,8 @@ static void print_cfg_table(struct device *dev, struct CfgTable *tb) | |||
| 3167 | dev_info(dev, " Server Name = %s\n", temp_name); | 3312 | dev_info(dev, " Server Name = %s\n", temp_name); |
| 3168 | dev_info(dev, " Heartbeat Counter = 0x%x\n\n\n", | 3313 | dev_info(dev, " Heartbeat Counter = 0x%x\n\n\n", |
| 3169 | readl(&(tb->HeartBeat))); | 3314 | readl(&(tb->HeartBeat))); |
| 3170 | } | ||
| 3171 | #endif /* HPSA_DEBUG */ | 3315 | #endif /* HPSA_DEBUG */ |
| 3316 | } | ||
| 3172 | 3317 | ||
| 3173 | static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) | 3318 | static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) |
| 3174 | { | 3319 | { |
| @@ -3209,8 +3354,7 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) | |||
| 3209 | * controllers that are capable. If not, we use IO-APIC mode. | 3354 | * controllers that are capable. If not, we use IO-APIC mode. |
| 3210 | */ | 3355 | */ |
| 3211 | 3356 | ||
| 3212 | static void __devinit hpsa_interrupt_mode(struct ctlr_info *h, | 3357 | static void __devinit hpsa_interrupt_mode(struct ctlr_info *h) |
| 3213 | struct pci_dev *pdev, u32 board_id) | ||
| 3214 | { | 3358 | { |
| 3215 | #ifdef CONFIG_PCI_MSI | 3359 | #ifdef CONFIG_PCI_MSI |
| 3216 | int err; | 3360 | int err; |
| @@ -3219,13 +3363,12 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h, | |||
| 3219 | }; | 3363 | }; |
| 3220 | 3364 | ||
| 3221 | /* Some boards advertise MSI but don't really support it */ | 3365 | /* Some boards advertise MSI but don't really support it */ |
| 3222 | if ((board_id == 0x40700E11) || | 3366 | if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || |
| 3223 | (board_id == 0x40800E11) || | 3367 | (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11)) |
| 3224 | (board_id == 0x40820E11) || (board_id == 0x40830E11)) | ||
| 3225 | goto default_int_mode; | 3368 | goto default_int_mode; |
| 3226 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | 3369 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { |
| 3227 | dev_info(&pdev->dev, "MSIX\n"); | 3370 | dev_info(&h->pdev->dev, "MSIX\n"); |
| 3228 | err = pci_enable_msix(pdev, hpsa_msix_entries, 4); | 3371 | err = pci_enable_msix(h->pdev, hpsa_msix_entries, 4); |
| 3229 | if (!err) { | 3372 | if (!err) { |
| 3230 | h->intr[0] = hpsa_msix_entries[0].vector; | 3373 | h->intr[0] = hpsa_msix_entries[0].vector; |
| 3231 | h->intr[1] = hpsa_msix_entries[1].vector; | 3374 | h->intr[1] = hpsa_msix_entries[1].vector; |
| @@ -3235,144 +3378,158 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h, | |||
| 3235 | return; | 3378 | return; |
| 3236 | } | 3379 | } |
| 3237 | if (err > 0) { | 3380 | if (err > 0) { |
| 3238 | dev_warn(&pdev->dev, "only %d MSI-X vectors " | 3381 | dev_warn(&h->pdev->dev, "only %d MSI-X vectors " |
| 3239 | "available\n", err); | 3382 | "available\n", err); |
| 3240 | goto default_int_mode; | 3383 | goto default_int_mode; |
| 3241 | } else { | 3384 | } else { |
| 3242 | dev_warn(&pdev->dev, "MSI-X init failed %d\n", | 3385 | dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", |
| 3243 | err); | 3386 | err); |
| 3244 | goto default_int_mode; | 3387 | goto default_int_mode; |
| 3245 | } | 3388 | } |
| 3246 | } | 3389 | } |
| 3247 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { | 3390 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { |
| 3248 | dev_info(&pdev->dev, "MSI\n"); | 3391 | dev_info(&h->pdev->dev, "MSI\n"); |
| 3249 | if (!pci_enable_msi(pdev)) | 3392 | if (!pci_enable_msi(h->pdev)) |
| 3250 | h->msi_vector = 1; | 3393 | h->msi_vector = 1; |
| 3251 | else | 3394 | else |
| 3252 | dev_warn(&pdev->dev, "MSI init failed\n"); | 3395 | dev_warn(&h->pdev->dev, "MSI init failed\n"); |
| 3253 | } | 3396 | } |
| 3254 | default_int_mode: | 3397 | default_int_mode: |
| 3255 | #endif /* CONFIG_PCI_MSI */ | 3398 | #endif /* CONFIG_PCI_MSI */ |
| 3256 | /* if we get here we're going to use the default interrupt mode */ | 3399 | /* if we get here we're going to use the default interrupt mode */ |
| 3257 | h->intr[PERF_MODE_INT] = pdev->irq; | 3400 | h->intr[PERF_MODE_INT] = h->pdev->irq; |
| 3258 | } | 3401 | } |
| 3259 | 3402 | ||
| 3260 | static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) | 3403 | static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id) |
| 3261 | { | 3404 | { |
| 3262 | ushort subsystem_vendor_id, subsystem_device_id, command; | 3405 | int i; |
| 3263 | u32 board_id, scratchpad = 0; | 3406 | u32 subsystem_vendor_id, subsystem_device_id; |
| 3264 | u64 cfg_offset; | ||
| 3265 | u32 cfg_base_addr; | ||
| 3266 | u64 cfg_base_addr_index; | ||
| 3267 | u32 trans_offset; | ||
| 3268 | int i, prod_index, err; | ||
| 3269 | 3407 | ||
| 3270 | subsystem_vendor_id = pdev->subsystem_vendor; | 3408 | subsystem_vendor_id = pdev->subsystem_vendor; |
| 3271 | subsystem_device_id = pdev->subsystem_device; | 3409 | subsystem_device_id = pdev->subsystem_device; |
| 3272 | board_id = (((u32) (subsystem_device_id << 16) & 0xffff0000) | | 3410 | *board_id = ((subsystem_device_id << 16) & 0xffff0000) | |
| 3273 | subsystem_vendor_id); | 3411 | subsystem_vendor_id; |
| 3274 | 3412 | ||
| 3275 | for (i = 0; i < ARRAY_SIZE(products); i++) | 3413 | for (i = 0; i < ARRAY_SIZE(products); i++) |
| 3276 | if (board_id == products[i].board_id) | 3414 | if (*board_id == products[i].board_id) |
| 3277 | break; | 3415 | return i; |
| 3278 | 3416 | ||
| 3279 | prod_index = i; | 3417 | if ((subsystem_vendor_id != PCI_VENDOR_ID_HP && |
| 3280 | 3418 | subsystem_vendor_id != PCI_VENDOR_ID_COMPAQ) || | |
| 3281 | if (prod_index == ARRAY_SIZE(products)) { | 3419 | !hpsa_allow_any) { |
| 3282 | prod_index--; | 3420 | dev_warn(&pdev->dev, "unrecognized board ID: " |
| 3283 | if (subsystem_vendor_id != PCI_VENDOR_ID_HP || | 3421 | "0x%08x, ignoring.\n", *board_id); |
| 3284 | !hpsa_allow_any) { | ||
| 3285 | dev_warn(&pdev->dev, "unrecognized board ID:" | ||
| 3286 | " 0x%08lx, ignoring.\n", | ||
| 3287 | (unsigned long) board_id); | ||
| 3288 | return -ENODEV; | 3422 | return -ENODEV; |
| 3289 | } | ||
| 3290 | } | ||
| 3291 | /* check to see if controller has been disabled | ||
| 3292 | * BEFORE trying to enable it | ||
| 3293 | */ | ||
| 3294 | (void)pci_read_config_word(pdev, PCI_COMMAND, &command); | ||
| 3295 | if (!(command & 0x02)) { | ||
| 3296 | dev_warn(&pdev->dev, "controller appears to be disabled\n"); | ||
| 3297 | return -ENODEV; | ||
| 3298 | } | ||
| 3299 | |||
| 3300 | err = pci_enable_device(pdev); | ||
| 3301 | if (err) { | ||
| 3302 | dev_warn(&pdev->dev, "unable to enable PCI device\n"); | ||
| 3303 | return err; | ||
| 3304 | } | 3423 | } |
| 3424 | return ARRAY_SIZE(products) - 1; /* generic unknown smart array */ | ||
| 3425 | } | ||
| 3305 | 3426 | ||
| 3306 | err = pci_request_regions(pdev, "hpsa"); | 3427 | static inline bool hpsa_board_disabled(struct pci_dev *pdev) |
| 3307 | if (err) { | 3428 | { |
| 3308 | dev_err(&pdev->dev, "cannot obtain PCI resources, aborting\n"); | 3429 | u16 command; |
| 3309 | return err; | ||
| 3310 | } | ||
| 3311 | 3430 | ||
| 3312 | /* If the kernel supports MSI/MSI-X we will try to enable that, | 3431 | (void) pci_read_config_word(pdev, PCI_COMMAND, &command); |
| 3313 | * else we use the IO-APIC interrupt assigned to us by system ROM. | 3432 | return ((command & PCI_COMMAND_MEMORY) == 0); |
| 3314 | */ | 3433 | } |
| 3315 | hpsa_interrupt_mode(h, pdev, board_id); | ||
| 3316 | 3434 | ||
| 3317 | /* find the memory BAR */ | 3435 | static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, |
| 3318 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 3436 | unsigned long *memory_bar) |
| 3319 | if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) | 3437 | { |
| 3320 | break; | 3438 | int i; |
| 3321 | } | ||
| 3322 | if (i == DEVICE_COUNT_RESOURCE) { | ||
| 3323 | dev_warn(&pdev->dev, "no memory BAR found\n"); | ||
| 3324 | err = -ENODEV; | ||
| 3325 | goto err_out_free_res; | ||
| 3326 | } | ||
| 3327 | 3439 | ||
| 3328 | h->paddr = pci_resource_start(pdev, i); /* addressing mode bits | 3440 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) |
| 3329 | * already removed | 3441 | if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { |
| 3330 | */ | 3442 | /* addressing mode bits already removed */ |
| 3443 | *memory_bar = pci_resource_start(pdev, i); | ||
| 3444 | dev_dbg(&pdev->dev, "memory BAR = %lx\n", | ||
| 3445 | *memory_bar); | ||
| 3446 | return 0; | ||
| 3447 | } | ||
| 3448 | dev_warn(&pdev->dev, "no memory BAR found\n"); | ||
| 3449 | return -ENODEV; | ||
| 3450 | } | ||
| 3331 | 3451 | ||
| 3332 | h->vaddr = remap_pci_mem(h->paddr, 0x250); | 3452 | static int __devinit hpsa_wait_for_board_ready(struct ctlr_info *h) |
| 3453 | { | ||
| 3454 | int i; | ||
| 3455 | u32 scratchpad; | ||
| 3333 | 3456 | ||
| 3334 | /* Wait for the board to become ready. */ | ||
| 3335 | for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) { | 3457 | for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) { |
| 3336 | scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); | 3458 | scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); |
| 3337 | if (scratchpad == HPSA_FIRMWARE_READY) | 3459 | if (scratchpad == HPSA_FIRMWARE_READY) |
| 3338 | break; | 3460 | return 0; |
| 3339 | msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS); | 3461 | msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS); |
| 3340 | } | 3462 | } |
| 3341 | if (scratchpad != HPSA_FIRMWARE_READY) { | 3463 | dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); |
| 3342 | dev_warn(&pdev->dev, "board not ready, timed out.\n"); | 3464 | return -ENODEV; |
| 3343 | err = -ENODEV; | 3465 | } |
| 3344 | goto err_out_free_res; | ||
| 3345 | } | ||
| 3346 | 3466 | ||
| 3347 | /* get the address index number */ | 3467 | static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev, |
| 3348 | cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET); | 3468 | void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, |
| 3349 | cfg_base_addr &= (u32) 0x0000ffff; | 3469 | u64 *cfg_offset) |
| 3350 | cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); | 3470 | { |
| 3351 | if (cfg_base_addr_index == -1) { | 3471 | *cfg_base_addr = readl(vaddr + SA5_CTCFG_OFFSET); |
| 3472 | *cfg_offset = readl(vaddr + SA5_CTMEM_OFFSET); | ||
| 3473 | *cfg_base_addr &= (u32) 0x0000ffff; | ||
| 3474 | *cfg_base_addr_index = find_PCI_BAR_index(pdev, *cfg_base_addr); | ||
| 3475 | if (*cfg_base_addr_index == -1) { | ||
| 3352 | dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n"); | 3476 | dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n"); |
| 3353 | err = -ENODEV; | 3477 | return -ENODEV; |
| 3354 | goto err_out_free_res; | ||
| 3355 | } | 3478 | } |
| 3479 | return 0; | ||
| 3480 | } | ||
| 3356 | 3481 | ||
| 3357 | cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET); | 3482 | static int __devinit hpsa_find_cfgtables(struct ctlr_info *h) |
| 3358 | h->cfgtable = remap_pci_mem(pci_resource_start(pdev, | 3483 | { |
| 3359 | cfg_base_addr_index) + cfg_offset, | 3484 | u64 cfg_offset; |
| 3360 | sizeof(h->cfgtable)); | 3485 | u32 cfg_base_addr; |
| 3486 | u64 cfg_base_addr_index; | ||
| 3487 | u32 trans_offset; | ||
| 3488 | int rc; | ||
| 3489 | |||
| 3490 | rc = hpsa_find_cfg_addrs(h->pdev, h->vaddr, &cfg_base_addr, | ||
| 3491 | &cfg_base_addr_index, &cfg_offset); | ||
| 3492 | if (rc) | ||
| 3493 | return rc; | ||
| 3494 | h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev, | ||
| 3495 | cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable)); | ||
| 3496 | if (!h->cfgtable) | ||
| 3497 | return -ENOMEM; | ||
| 3361 | /* Find performant mode table. */ | 3498 | /* Find performant mode table. */ |
| 3362 | trans_offset = readl(&(h->cfgtable->TransMethodOffset)); | 3499 | trans_offset = readl(&h->cfgtable->TransMethodOffset); |
| 3363 | h->transtable = remap_pci_mem(pci_resource_start(pdev, | 3500 | h->transtable = remap_pci_mem(pci_resource_start(h->pdev, |
| 3364 | cfg_base_addr_index)+cfg_offset+trans_offset, | 3501 | cfg_base_addr_index)+cfg_offset+trans_offset, |
| 3365 | sizeof(*h->transtable)); | 3502 | sizeof(*h->transtable)); |
| 3503 | if (!h->transtable) | ||
| 3504 | return -ENOMEM; | ||
| 3505 | return 0; | ||
| 3506 | } | ||
| 3366 | 3507 | ||
| 3367 | h->board_id = board_id; | 3508 | static void __devinit hpsa_get_max_perf_mode_cmds(struct ctlr_info *h) |
| 3509 | { | ||
| 3368 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | 3510 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); |
| 3369 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); | 3511 | if (h->max_commands < 16) { |
| 3512 | dev_warn(&h->pdev->dev, "Controller reports " | ||
| 3513 | "max supported commands of %d, an obvious lie. " | ||
| 3514 | "Using 16. Ensure that firmware is up to date.\n", | ||
| 3515 | h->max_commands); | ||
| 3516 | h->max_commands = 16; | ||
| 3517 | } | ||
| 3518 | } | ||
| 3370 | 3519 | ||
| 3520 | /* Interrogate the hardware for some limits: | ||
| 3521 | * max commands, max SG elements without chaining, and with chaining, | ||
| 3522 | * SG chain block size, etc. | ||
| 3523 | */ | ||
| 3524 | static void __devinit hpsa_find_board_params(struct ctlr_info *h) | ||
| 3525 | { | ||
| 3526 | hpsa_get_max_perf_mode_cmds(h); | ||
| 3527 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ | ||
| 3528 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); | ||
| 3371 | /* | 3529 | /* |
| 3372 | * Limit in-command s/g elements to 32 save dma'able memory. | 3530 | * Limit in-command s/g elements to 32 save dma'able memory. |
| 3373 | * Howvever spec says if 0, use 31 | 3531 | * Howvever spec says if 0, use 31 |
| 3374 | */ | 3532 | */ |
| 3375 | |||
| 3376 | h->max_cmd_sg_entries = 31; | 3533 | h->max_cmd_sg_entries = 31; |
| 3377 | if (h->maxsgentries > 512) { | 3534 | if (h->maxsgentries > 512) { |
| 3378 | h->max_cmd_sg_entries = 32; | 3535 | h->max_cmd_sg_entries = 32; |
| @@ -3382,45 +3539,49 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) | |||
| 3382 | h->maxsgentries = 31; /* default to traditional values */ | 3539 | h->maxsgentries = 31; /* default to traditional values */ |
| 3383 | h->chainsize = 0; | 3540 | h->chainsize = 0; |
| 3384 | } | 3541 | } |
| 3542 | } | ||
| 3385 | 3543 | ||
| 3386 | h->product_name = products[prod_index].product_name; | 3544 | static inline bool hpsa_CISS_signature_present(struct ctlr_info *h) |
| 3387 | h->access = *(products[prod_index].access); | 3545 | { |
| 3388 | /* Allow room for some ioctls */ | ||
| 3389 | h->nr_cmds = h->max_commands - 4; | ||
| 3390 | |||
| 3391 | if ((readb(&h->cfgtable->Signature[0]) != 'C') || | 3546 | if ((readb(&h->cfgtable->Signature[0]) != 'C') || |
| 3392 | (readb(&h->cfgtable->Signature[1]) != 'I') || | 3547 | (readb(&h->cfgtable->Signature[1]) != 'I') || |
| 3393 | (readb(&h->cfgtable->Signature[2]) != 'S') || | 3548 | (readb(&h->cfgtable->Signature[2]) != 'S') || |
| 3394 | (readb(&h->cfgtable->Signature[3]) != 'S')) { | 3549 | (readb(&h->cfgtable->Signature[3]) != 'S')) { |
| 3395 | dev_warn(&pdev->dev, "not a valid CISS config table\n"); | 3550 | dev_warn(&h->pdev->dev, "not a valid CISS config table\n"); |
| 3396 | err = -ENODEV; | 3551 | return false; |
| 3397 | goto err_out_free_res; | ||
| 3398 | } | 3552 | } |
| 3553 | return true; | ||
| 3554 | } | ||
| 3555 | |||
| 3556 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | ||
| 3557 | static inline void hpsa_enable_scsi_prefetch(struct ctlr_info *h) | ||
| 3558 | { | ||
| 3399 | #ifdef CONFIG_X86 | 3559 | #ifdef CONFIG_X86 |
| 3400 | { | 3560 | u32 prefetch; |
| 3401 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | 3561 | |
| 3402 | u32 prefetch; | 3562 | prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); |
| 3403 | prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); | 3563 | prefetch |= 0x100; |
| 3404 | prefetch |= 0x100; | 3564 | writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); |
| 3405 | writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); | ||
| 3406 | } | ||
| 3407 | #endif | 3565 | #endif |
| 3566 | } | ||
| 3408 | 3567 | ||
| 3409 | /* Disabling DMA prefetch for the P600 | 3568 | /* Disable DMA prefetch for the P600. Otherwise an ASIC bug may result |
| 3410 | * An ASIC bug may result in a prefetch beyond | 3569 | * in a prefetch beyond physical memory. |
| 3411 | * physical memory. | 3570 | */ |
| 3412 | */ | 3571 | static inline void hpsa_p600_dma_prefetch_quirk(struct ctlr_info *h) |
| 3413 | if (board_id == 0x3225103C) { | 3572 | { |
| 3414 | u32 dma_prefetch; | 3573 | u32 dma_prefetch; |
| 3415 | dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); | ||
| 3416 | dma_prefetch |= 0x8000; | ||
| 3417 | writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); | ||
| 3418 | } | ||
| 3419 | 3574 | ||
| 3420 | h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); | 3575 | if (h->board_id != 0x3225103C) |
| 3421 | /* Update the field, and then ring the doorbell */ | 3576 | return; |
| 3422 | writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); | 3577 | dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); |
| 3423 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); | 3578 | dma_prefetch |= 0x8000; |
| 3579 | writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | static void __devinit hpsa_wait_for_mode_change_ack(struct ctlr_info *h) | ||
| 3583 | { | ||
| 3584 | int i; | ||
| 3424 | 3585 | ||
| 3425 | /* under certain very rare conditions, this can take awhile. | 3586 | /* under certain very rare conditions, this can take awhile. |
| 3426 | * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right | 3587 | * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right |
| @@ -3432,24 +3593,96 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) | |||
| 3432 | /* delay and try again */ | 3593 | /* delay and try again */ |
| 3433 | msleep(10); | 3594 | msleep(10); |
| 3434 | } | 3595 | } |
| 3596 | } | ||
| 3435 | 3597 | ||
| 3436 | #ifdef HPSA_DEBUG | 3598 | static int __devinit hpsa_enter_simple_mode(struct ctlr_info *h) |
| 3437 | print_cfg_table(&pdev->dev, h->cfgtable); | 3599 | { |
| 3438 | #endif /* HPSA_DEBUG */ | 3600 | u32 trans_support; |
| 3439 | 3601 | ||
| 3602 | trans_support = readl(&(h->cfgtable->TransportSupport)); | ||
| 3603 | if (!(trans_support & SIMPLE_MODE)) | ||
| 3604 | return -ENOTSUPP; | ||
| 3605 | |||
| 3606 | h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); | ||
| 3607 | /* Update the field, and then ring the doorbell */ | ||
| 3608 | writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); | ||
| 3609 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); | ||
| 3610 | hpsa_wait_for_mode_change_ack(h); | ||
| 3611 | print_cfg_table(&h->pdev->dev, h->cfgtable); | ||
| 3440 | if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { | 3612 | if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { |
| 3441 | dev_warn(&pdev->dev, "unable to get board into simple mode\n"); | 3613 | dev_warn(&h->pdev->dev, |
| 3614 | "unable to get board into simple mode\n"); | ||
| 3615 | return -ENODEV; | ||
| 3616 | } | ||
| 3617 | return 0; | ||
| 3618 | } | ||
| 3619 | |||
| 3620 | static int __devinit hpsa_pci_init(struct ctlr_info *h) | ||
| 3621 | { | ||
| 3622 | int prod_index, err; | ||
| 3623 | |||
| 3624 | prod_index = hpsa_lookup_board_id(h->pdev, &h->board_id); | ||
| 3625 | if (prod_index < 0) | ||
| 3626 | return -ENODEV; | ||
| 3627 | h->product_name = products[prod_index].product_name; | ||
| 3628 | h->access = *(products[prod_index].access); | ||
| 3629 | |||
| 3630 | if (hpsa_board_disabled(h->pdev)) { | ||
| 3631 | dev_warn(&h->pdev->dev, "controller appears to be disabled\n"); | ||
| 3632 | return -ENODEV; | ||
| 3633 | } | ||
| 3634 | err = pci_enable_device(h->pdev); | ||
| 3635 | if (err) { | ||
| 3636 | dev_warn(&h->pdev->dev, "unable to enable PCI device\n"); | ||
| 3637 | return err; | ||
| 3638 | } | ||
| 3639 | |||
| 3640 | err = pci_request_regions(h->pdev, "hpsa"); | ||
| 3641 | if (err) { | ||
| 3642 | dev_err(&h->pdev->dev, | ||
| 3643 | "cannot obtain PCI resources, aborting\n"); | ||
| 3644 | return err; | ||
| 3645 | } | ||
| 3646 | hpsa_interrupt_mode(h); | ||
| 3647 | err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); | ||
| 3648 | if (err) | ||
| 3649 | goto err_out_free_res; | ||
| 3650 | h->vaddr = remap_pci_mem(h->paddr, 0x250); | ||
| 3651 | if (!h->vaddr) { | ||
| 3652 | err = -ENOMEM; | ||
| 3653 | goto err_out_free_res; | ||
| 3654 | } | ||
| 3655 | err = hpsa_wait_for_board_ready(h); | ||
| 3656 | if (err) | ||
| 3657 | goto err_out_free_res; | ||
| 3658 | err = hpsa_find_cfgtables(h); | ||
| 3659 | if (err) | ||
| 3660 | goto err_out_free_res; | ||
| 3661 | hpsa_find_board_params(h); | ||
| 3662 | |||
| 3663 | if (!hpsa_CISS_signature_present(h)) { | ||
| 3442 | err = -ENODEV; | 3664 | err = -ENODEV; |
| 3443 | goto err_out_free_res; | 3665 | goto err_out_free_res; |
| 3444 | } | 3666 | } |
| 3667 | hpsa_enable_scsi_prefetch(h); | ||
| 3668 | hpsa_p600_dma_prefetch_quirk(h); | ||
| 3669 | err = hpsa_enter_simple_mode(h); | ||
| 3670 | if (err) | ||
| 3671 | goto err_out_free_res; | ||
| 3445 | return 0; | 3672 | return 0; |
| 3446 | 3673 | ||
| 3447 | err_out_free_res: | 3674 | err_out_free_res: |
| 3675 | if (h->transtable) | ||
| 3676 | iounmap(h->transtable); | ||
| 3677 | if (h->cfgtable) | ||
| 3678 | iounmap(h->cfgtable); | ||
| 3679 | if (h->vaddr) | ||
| 3680 | iounmap(h->vaddr); | ||
| 3448 | /* | 3681 | /* |
| 3449 | * Deliberately omit pci_disable_device(): it does something nasty to | 3682 | * Deliberately omit pci_disable_device(): it does something nasty to |
| 3450 | * Smart Array controllers that pci_enable_device does not undo | 3683 | * Smart Array controllers that pci_enable_device does not undo |
| 3451 | */ | 3684 | */ |
| 3452 | pci_release_regions(pdev); | 3685 | pci_release_regions(h->pdev); |
| 3453 | return err; | 3686 | return err; |
| 3454 | } | 3687 | } |
| 3455 | 3688 | ||
| @@ -3469,33 +3702,51 @@ static void __devinit hpsa_hba_inquiry(struct ctlr_info *h) | |||
| 3469 | } | 3702 | } |
| 3470 | } | 3703 | } |
| 3471 | 3704 | ||
| 3705 | static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev) | ||
| 3706 | { | ||
| 3707 | int rc, i; | ||
| 3708 | |||
| 3709 | if (!reset_devices) | ||
| 3710 | return 0; | ||
| 3711 | |||
| 3712 | /* Reset the controller with a PCI power-cycle or via doorbell */ | ||
| 3713 | rc = hpsa_kdump_hard_reset_controller(pdev); | ||
| 3714 | |||
| 3715 | /* -ENOTSUPP here means we cannot reset the controller | ||
| 3716 | * but it's already (and still) up and running in | ||
| 3717 | * "performant mode". Or, it might be 640x, which can't reset | ||
| 3718 | * due to concerns about shared bbwc between 6402/6404 pair. | ||
| 3719 | */ | ||
| 3720 | if (rc == -ENOTSUPP) | ||
| 3721 | return 0; /* just try to do the kdump anyhow. */ | ||
| 3722 | if (rc) | ||
| 3723 | return -ENODEV; | ||
| 3724 | if (hpsa_reset_msi(pdev)) | ||
| 3725 | return -ENODEV; | ||
| 3726 | |||
| 3727 | /* Now try to get the controller to respond to a no-op */ | ||
| 3728 | for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { | ||
| 3729 | if (hpsa_noop(pdev) == 0) | ||
| 3730 | break; | ||
| 3731 | else | ||
| 3732 | dev_warn(&pdev->dev, "no-op failed%s\n", | ||
| 3733 | (i < 11 ? "; re-trying" : "")); | ||
| 3734 | } | ||
| 3735 | return 0; | ||
| 3736 | } | ||
| 3737 | |||
| 3472 | static int __devinit hpsa_init_one(struct pci_dev *pdev, | 3738 | static int __devinit hpsa_init_one(struct pci_dev *pdev, |
| 3473 | const struct pci_device_id *ent) | 3739 | const struct pci_device_id *ent) |
| 3474 | { | 3740 | { |
| 3475 | int i, rc; | 3741 | int dac, rc; |
| 3476 | int dac; | ||
| 3477 | struct ctlr_info *h; | 3742 | struct ctlr_info *h; |
| 3478 | 3743 | ||
| 3479 | if (number_of_controllers == 0) | 3744 | if (number_of_controllers == 0) |
| 3480 | printk(KERN_INFO DRIVER_NAME "\n"); | 3745 | printk(KERN_INFO DRIVER_NAME "\n"); |
| 3481 | if (reset_devices) { | ||
| 3482 | /* Reset the controller with a PCI power-cycle */ | ||
| 3483 | if (hpsa_hard_reset_controller(pdev) || hpsa_reset_msi(pdev)) | ||
| 3484 | return -ENODEV; | ||
| 3485 | 3746 | ||
| 3486 | /* Some devices (notably the HP Smart Array 5i Controller) | 3747 | rc = hpsa_init_reset_devices(pdev); |
| 3487 | need a little pause here */ | 3748 | if (rc) |
| 3488 | msleep(HPSA_POST_RESET_PAUSE_MSECS); | 3749 | return rc; |
| 3489 | |||
| 3490 | /* Now try to get the controller to respond to a no-op */ | ||
| 3491 | for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { | ||
| 3492 | if (hpsa_noop(pdev) == 0) | ||
| 3493 | break; | ||
| 3494 | else | ||
| 3495 | dev_warn(&pdev->dev, "no-op failed%s\n", | ||
| 3496 | (i < 11 ? "; re-trying" : "")); | ||
| 3497 | } | ||
| 3498 | } | ||
| 3499 | 3750 | ||
| 3500 | /* Command structures must be aligned on a 32-byte boundary because | 3751 | /* Command structures must be aligned on a 32-byte boundary because |
| 3501 | * the 5 lower bits of the address are used by the hardware. and by | 3752 | * the 5 lower bits of the address are used by the hardware. and by |
| @@ -3507,17 +3758,17 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
| 3507 | if (!h) | 3758 | if (!h) |
| 3508 | return -ENOMEM; | 3759 | return -ENOMEM; |
| 3509 | 3760 | ||
| 3761 | h->pdev = pdev; | ||
| 3510 | h->busy_initializing = 1; | 3762 | h->busy_initializing = 1; |
| 3511 | INIT_HLIST_HEAD(&h->cmpQ); | 3763 | INIT_HLIST_HEAD(&h->cmpQ); |
| 3512 | INIT_HLIST_HEAD(&h->reqQ); | 3764 | INIT_HLIST_HEAD(&h->reqQ); |
| 3513 | rc = hpsa_pci_init(h, pdev); | 3765 | rc = hpsa_pci_init(h); |
| 3514 | if (rc != 0) | 3766 | if (rc != 0) |
| 3515 | goto clean1; | 3767 | goto clean1; |
| 3516 | 3768 | ||
| 3517 | sprintf(h->devname, "hpsa%d", number_of_controllers); | 3769 | sprintf(h->devname, "hpsa%d", number_of_controllers); |
| 3518 | h->ctlr = number_of_controllers; | 3770 | h->ctlr = number_of_controllers; |
| 3519 | number_of_controllers++; | 3771 | number_of_controllers++; |
| 3520 | h->pdev = pdev; | ||
| 3521 | 3772 | ||
| 3522 | /* configure PCI DMA stuff */ | 3773 | /* configure PCI DMA stuff */ |
| 3523 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | 3774 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); |
| @@ -3535,8 +3786,13 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
| 3535 | 3786 | ||
| 3536 | /* make sure the board interrupts are off */ | 3787 | /* make sure the board interrupts are off */ |
| 3537 | h->access.set_intr_mask(h, HPSA_INTR_OFF); | 3788 | h->access.set_intr_mask(h, HPSA_INTR_OFF); |
| 3538 | rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr, | 3789 | |
| 3539 | IRQF_DISABLED, h->devname, h); | 3790 | if (h->msix_vector || h->msi_vector) |
| 3791 | rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_msi, | ||
| 3792 | IRQF_DISABLED, h->devname, h); | ||
| 3793 | else | ||
| 3794 | rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_intx, | ||
| 3795 | IRQF_DISABLED, h->devname, h); | ||
| 3540 | if (rc) { | 3796 | if (rc) { |
| 3541 | dev_err(&pdev->dev, "unable to get irq %d for %s\n", | 3797 | dev_err(&pdev->dev, "unable to get irq %d for %s\n", |
| 3542 | h->intr[PERF_MODE_INT], h->devname); | 3798 | h->intr[PERF_MODE_INT], h->devname); |
| @@ -3663,6 +3919,8 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
| 3663 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ | 3919 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ |
| 3664 | hpsa_shutdown(pdev); | 3920 | hpsa_shutdown(pdev); |
| 3665 | iounmap(h->vaddr); | 3921 | iounmap(h->vaddr); |
| 3922 | iounmap(h->transtable); | ||
| 3923 | iounmap(h->cfgtable); | ||
| 3666 | hpsa_free_sg_chain_blocks(h); | 3924 | hpsa_free_sg_chain_blocks(h); |
| 3667 | pci_free_consistent(h->pdev, | 3925 | pci_free_consistent(h->pdev, |
| 3668 | h->nr_cmds * sizeof(struct CommandList), | 3926 | h->nr_cmds * sizeof(struct CommandList), |
| @@ -3742,38 +4000,35 @@ static void calc_bucket_map(int bucket[], int num_buckets, | |||
| 3742 | } | 4000 | } |
| 3743 | } | 4001 | } |
| 3744 | 4002 | ||
| 3745 | static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) | 4003 | static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h) |
| 3746 | { | 4004 | { |
| 3747 | u32 trans_support; | 4005 | int i; |
| 3748 | u64 trans_offset; | 4006 | unsigned long register_value; |
| 4007 | |||
| 4008 | /* This is a bit complicated. There are 8 registers on | ||
| 4009 | * the controller which we write to to tell it 8 different | ||
| 4010 | * sizes of commands which there may be. It's a way of | ||
| 4011 | * reducing the DMA done to fetch each command. Encoded into | ||
| 4012 | * each command's tag are 3 bits which communicate to the controller | ||
| 4013 | * which of the eight sizes that command fits within. The size of | ||
| 4014 | * each command depends on how many scatter gather entries there are. | ||
| 4015 | * Each SG entry requires 16 bytes. The eight registers are programmed | ||
| 4016 | * with the number of 16-byte blocks a command of that size requires. | ||
| 4017 | * The smallest command possible requires 5 such 16 byte blocks. | ||
| 4018 | * the largest command possible requires MAXSGENTRIES + 4 16-byte | ||
| 4019 | * blocks. Note, this only extends to the SG entries contained | ||
| 4020 | * within the command block, and does not extend to chained blocks | ||
| 4021 | * of SG elements. bft[] contains the eight values we write to | ||
| 4022 | * the registers. They are not evenly distributed, but have more | ||
| 4023 | * sizes for small commands, and fewer sizes for larger commands. | ||
| 4024 | */ | ||
| 4025 | int bft[8] = {5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4}; | ||
| 4026 | BUILD_BUG_ON(28 > MAXSGENTRIES + 4); | ||
| 3749 | /* 5 = 1 s/g entry or 4k | 4027 | /* 5 = 1 s/g entry or 4k |
| 3750 | * 6 = 2 s/g entry or 8k | 4028 | * 6 = 2 s/g entry or 8k |
| 3751 | * 8 = 4 s/g entry or 16k | 4029 | * 8 = 4 s/g entry or 16k |
| 3752 | * 10 = 6 s/g entry or 24k | 4030 | * 10 = 6 s/g entry or 24k |
| 3753 | */ | 4031 | */ |
| 3754 | int bft[8] = {5, 6, 8, 10, 12, 20, 28, 35}; /* for scatter/gathers */ | ||
| 3755 | int i = 0; | ||
| 3756 | int l = 0; | ||
| 3757 | unsigned long register_value; | ||
| 3758 | |||
| 3759 | trans_support = readl(&(h->cfgtable->TransportSupport)); | ||
| 3760 | if (!(trans_support & PERFORMANT_MODE)) | ||
| 3761 | return; | ||
| 3762 | |||
| 3763 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | ||
| 3764 | h->max_sg_entries = 32; | ||
| 3765 | /* Performant mode ring buffer and supporting data structures */ | ||
| 3766 | h->reply_pool_size = h->max_commands * sizeof(u64); | ||
| 3767 | h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size, | ||
| 3768 | &(h->reply_pool_dhandle)); | ||
| 3769 | |||
| 3770 | /* Need a block fetch table for performant mode */ | ||
| 3771 | h->blockFetchTable = kmalloc(((h->max_sg_entries+1) * | ||
| 3772 | sizeof(u32)), GFP_KERNEL); | ||
| 3773 | |||
| 3774 | if ((h->reply_pool == NULL) | ||
| 3775 | || (h->blockFetchTable == NULL)) | ||
| 3776 | goto clean_up; | ||
| 3777 | 4032 | ||
| 3778 | h->reply_pool_wraparound = 1; /* spec: init to 1 */ | 4033 | h->reply_pool_wraparound = 1; /* spec: init to 1 */ |
| 3779 | 4034 | ||
| @@ -3781,7 +4036,6 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) | |||
| 3781 | memset(h->reply_pool, 0, h->reply_pool_size); | 4036 | memset(h->reply_pool, 0, h->reply_pool_size); |
| 3782 | h->reply_pool_head = h->reply_pool; | 4037 | h->reply_pool_head = h->reply_pool; |
| 3783 | 4038 | ||
| 3784 | trans_offset = readl(&(h->cfgtable->TransMethodOffset)); | ||
| 3785 | bft[7] = h->max_sg_entries + 4; | 4039 | bft[7] = h->max_sg_entries + 4; |
| 3786 | calc_bucket_map(bft, ARRAY_SIZE(bft), 32, h->blockFetchTable); | 4040 | calc_bucket_map(bft, ARRAY_SIZE(bft), 32, h->blockFetchTable); |
| 3787 | for (i = 0; i < 8; i++) | 4041 | for (i = 0; i < 8; i++) |
| @@ -3797,23 +4051,39 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) | |||
| 3797 | writel(CFGTBL_Trans_Performant, | 4051 | writel(CFGTBL_Trans_Performant, |
| 3798 | &(h->cfgtable->HostWrite.TransportRequest)); | 4052 | &(h->cfgtable->HostWrite.TransportRequest)); |
| 3799 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); | 4053 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); |
| 3800 | /* under certain very rare conditions, this can take awhile. | 4054 | hpsa_wait_for_mode_change_ack(h); |
| 3801 | * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right | ||
| 3802 | * as we enter this code.) */ | ||
| 3803 | for (l = 0; l < MAX_CONFIG_WAIT; l++) { | ||
| 3804 | register_value = readl(h->vaddr + SA5_DOORBELL); | ||
| 3805 | if (!(register_value & CFGTBL_ChangeReq)) | ||
| 3806 | break; | ||
| 3807 | /* delay and try again */ | ||
| 3808 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 3809 | schedule_timeout(10); | ||
| 3810 | } | ||
| 3811 | register_value = readl(&(h->cfgtable->TransportActive)); | 4055 | register_value = readl(&(h->cfgtable->TransportActive)); |
| 3812 | if (!(register_value & CFGTBL_Trans_Performant)) { | 4056 | if (!(register_value & CFGTBL_Trans_Performant)) { |
| 3813 | dev_warn(&h->pdev->dev, "unable to get board into" | 4057 | dev_warn(&h->pdev->dev, "unable to get board into" |
| 3814 | " performant mode\n"); | 4058 | " performant mode\n"); |
| 3815 | return; | 4059 | return; |
| 3816 | } | 4060 | } |
| 4061 | } | ||
| 4062 | |||
| 4063 | static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) | ||
| 4064 | { | ||
| 4065 | u32 trans_support; | ||
| 4066 | |||
| 4067 | trans_support = readl(&(h->cfgtable->TransportSupport)); | ||
| 4068 | if (!(trans_support & PERFORMANT_MODE)) | ||
| 4069 | return; | ||
| 4070 | |||
| 4071 | hpsa_get_max_perf_mode_cmds(h); | ||
| 4072 | h->max_sg_entries = 32; | ||
| 4073 | /* Performant mode ring buffer and supporting data structures */ | ||
| 4074 | h->reply_pool_size = h->max_commands * sizeof(u64); | ||
| 4075 | h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size, | ||
| 4076 | &(h->reply_pool_dhandle)); | ||
| 4077 | |||
| 4078 | /* Need a block fetch table for performant mode */ | ||
| 4079 | h->blockFetchTable = kmalloc(((h->max_sg_entries+1) * | ||
| 4080 | sizeof(u32)), GFP_KERNEL); | ||
| 4081 | |||
| 4082 | if ((h->reply_pool == NULL) | ||
| 4083 | || (h->blockFetchTable == NULL)) | ||
| 4084 | goto clean_up; | ||
| 4085 | |||
| 4086 | hpsa_enter_performant_mode(h); | ||
| 3817 | 4087 | ||
| 3818 | /* Change the access methods to the performant access methods */ | 4088 | /* Change the access methods to the performant access methods */ |
| 3819 | h->access = SA5_performant_access; | 4089 | h->access = SA5_performant_access; |
