hpsa.c (1fb011fb05b6bac4fb8eabd324a6983116f7594d) hpsa.c (580ada3c1e2f23b4b0f3c254cae3eb278f92d494)
1/*
2 * Disk Array driver for HP Smart Array SAS controllers
3 * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *

--- 3170 unchanged lines hidden (view full) ---

3179 pmcsr |= PCI_D0;
3180 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3181
3182 msleep(500);
3183 }
3184 return 0;
3185}
3186
1/*
2 * Disk Array driver for HP Smart Array SAS controllers
3 * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *

--- 3170 unchanged lines hidden (view full) ---

3179 pmcsr |= PCI_D0;
3180 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3181
3182 msleep(500);
3183 }
3184 return 0;
3185}
3186
3187static __devinit void init_driver_version(char *driver_version, int len)
3188{
3189 memset(driver_version, 0, len);
3190 strncpy(driver_version, "hpsa " HPSA_DRIVER_VERSION, len - 1);
3191}
3192
3193static __devinit int write_driver_ver_to_cfgtable(
3194 struct CfgTable __iomem *cfgtable)
3195{
3196 char *driver_version;
3197 int i, size = sizeof(cfgtable->driver_version);
3198
3199 driver_version = kmalloc(size, GFP_KERNEL);
3200 if (!driver_version)
3201 return -ENOMEM;
3202
3203 init_driver_version(driver_version, size);
3204 for (i = 0; i < size; i++)
3205 writeb(driver_version[i], &cfgtable->driver_version[i]);
3206 kfree(driver_version);
3207 return 0;
3208}
3209
3210static __devinit void read_driver_ver_from_cfgtable(
3211 struct CfgTable __iomem *cfgtable, unsigned char *driver_ver)
3212{
3213 int i;
3214
3215 for (i = 0; i < sizeof(cfgtable->driver_version); i++)
3216 driver_ver[i] = readb(&cfgtable->driver_version[i]);
3217}
3218
3219static __devinit int controller_reset_failed(
3220 struct CfgTable __iomem *cfgtable)
3221{
3222
3223 char *driver_ver, *old_driver_ver;
3224 int rc, size = sizeof(cfgtable->driver_version);
3225
3226 old_driver_ver = kmalloc(2 * size, GFP_KERNEL);
3227 if (!old_driver_ver)
3228 return -ENOMEM;
3229 driver_ver = old_driver_ver + size;
3230
3231 /* After a reset, the 32 bytes of "driver version" in the cfgtable
3232 * should have been changed, otherwise we know the reset failed.
3233 */
3234 init_driver_version(old_driver_ver, size);
3235 read_driver_ver_from_cfgtable(cfgtable, driver_ver);
3236 rc = !memcmp(driver_ver, old_driver_ver, size);
3237 kfree(old_driver_ver);
3238 return rc;
3239}
3187/* This does a hard reset of the controller using PCI power management
3188 * states or the using the doorbell register.
3189 */
3190static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3191{
3192 u64 cfg_offset;
3193 u32 cfg_base_addr;
3194 u64 cfg_base_addr_index;
3195 void __iomem *vaddr;
3196 unsigned long paddr;
3240/* This does a hard reset of the controller using PCI power management
3241 * states or the using the doorbell register.
3242 */
3243static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3244{
3245 u64 cfg_offset;
3246 u32 cfg_base_addr;
3247 u64 cfg_base_addr_index;
3248 void __iomem *vaddr;
3249 unsigned long paddr;
3197 u32 misc_fw_support, active_transport;
3250 u32 misc_fw_support;
3198 int rc;
3199 struct CfgTable __iomem *cfgtable;
3200 bool use_doorbell;
3201 u32 board_id;
3202 u16 command_register;
3203
3204 /* For controllers as old as the P600, this is very nearly
3205 * the same thing as

--- 45 unchanged lines hidden (view full) ---

3251 if (rc)
3252 goto unmap_vaddr;
3253 cfgtable = remap_pci_mem(pci_resource_start(pdev,
3254 cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable));
3255 if (!cfgtable) {
3256 rc = -ENOMEM;
3257 goto unmap_vaddr;
3258 }
3251 int rc;
3252 struct CfgTable __iomem *cfgtable;
3253 bool use_doorbell;
3254 u32 board_id;
3255 u16 command_register;
3256
3257 /* For controllers as old as the P600, this is very nearly
3258 * the same thing as

--- 45 unchanged lines hidden (view full) ---

3304 if (rc)
3305 goto unmap_vaddr;
3306 cfgtable = remap_pci_mem(pci_resource_start(pdev,
3307 cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable));
3308 if (!cfgtable) {
3309 rc = -ENOMEM;
3310 goto unmap_vaddr;
3311 }
3312 rc = write_driver_ver_to_cfgtable(cfgtable);
3313 if (rc)
3314 goto unmap_vaddr;
3259
3260 /* If reset via doorbell register is supported, use that. */
3261 misc_fw_support = readl(&cfgtable->misc_fw_support);
3262 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
3263
3264 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
3265 if (rc)
3266 goto unmap_cfgtable;

--- 17 unchanged lines hidden (view full) ---

3284 dev_warn(&pdev->dev,
3285 "failed waiting for board to become not ready\n");
3286 rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
3287 if (rc) {
3288 dev_warn(&pdev->dev,
3289 "failed waiting for board to become ready\n");
3290 goto unmap_cfgtable;
3291 }
3315
3316 /* If reset via doorbell register is supported, use that. */
3317 misc_fw_support = readl(&cfgtable->misc_fw_support);
3318 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
3319
3320 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
3321 if (rc)
3322 goto unmap_cfgtable;

--- 17 unchanged lines hidden (view full) ---

3340 dev_warn(&pdev->dev,
3341 "failed waiting for board to become not ready\n");
3342 rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
3343 if (rc) {
3344 dev_warn(&pdev->dev,
3345 "failed waiting for board to become ready\n");
3346 goto unmap_cfgtable;
3347 }
3292 dev_info(&pdev->dev, "board ready.\n");
3293
3348
3294 /* Controller should be in simple mode at this point. If it's not,
3295 * It means we're on one of those controllers which doesn't support
3296 * the doorbell reset method and on which the PCI power management reset
3297 * method doesn't work (P800, for example.)
3298 * In those cases, don't try to proceed, as it generally doesn't work.
3299 */
3300 active_transport = readl(&cfgtable->TransportActive);
3301 if (active_transport & PERFORMANT_MODE) {
3349 rc = controller_reset_failed(vaddr);
3350 if (rc < 0)
3351 goto unmap_cfgtable;
3352 if (rc) {
3302 dev_warn(&pdev->dev, "Unable to successfully reset controller,"
3303 " Ignoring controller.\n");
3304 rc = -ENODEV;
3353 dev_warn(&pdev->dev, "Unable to successfully reset controller,"
3354 " Ignoring controller.\n");
3355 rc = -ENODEV;
3356 } else {
3357 dev_info(&pdev->dev, "board ready.\n");
3305 }
3306
3307unmap_cfgtable:
3308 iounmap(cfgtable);
3309
3310unmap_vaddr:
3311 iounmap(vaddr);
3312 return rc;

--- 224 unchanged lines hidden (view full) ---

3537 rc = hpsa_find_cfg_addrs(h->pdev, h->vaddr, &cfg_base_addr,
3538 &cfg_base_addr_index, &cfg_offset);
3539 if (rc)
3540 return rc;
3541 h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev,
3542 cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
3543 if (!h->cfgtable)
3544 return -ENOMEM;
3358 }
3359
3360unmap_cfgtable:
3361 iounmap(cfgtable);
3362
3363unmap_vaddr:
3364 iounmap(vaddr);
3365 return rc;

--- 224 unchanged lines hidden (view full) ---

3590 rc = hpsa_find_cfg_addrs(h->pdev, h->vaddr, &cfg_base_addr,
3591 &cfg_base_addr_index, &cfg_offset);
3592 if (rc)
3593 return rc;
3594 h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev,
3595 cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
3596 if (!h->cfgtable)
3597 return -ENOMEM;
3598 rc = write_driver_ver_to_cfgtable(h->cfgtable);
3599 if (rc)
3600 return rc;
3545 /* Find performant mode table. */
3546 trans_offset = readl(&h->cfgtable->TransMethodOffset);
3547 h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
3548 cfg_base_addr_index)+cfg_offset+trans_offset,
3549 sizeof(*h->transtable));
3550 if (!h->transtable)
3551 return -ENOMEM;
3552 return 0;

--- 625 unchanged lines hidden ---
3601 /* Find performant mode table. */
3602 trans_offset = readl(&h->cfgtable->TransMethodOffset);
3603 h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
3604 cfg_base_addr_index)+cfg_offset+trans_offset,
3605 sizeof(*h->transtable));
3606 if (!h->transtable)
3607 return -ENOMEM;
3608 return 0;

--- 625 unchanged lines hidden ---