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 --- |