diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 496 |
1 files changed, 399 insertions, 97 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 415ad4fb50d..c6c0434d803 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -273,7 +273,7 @@ static ssize_t host_show_transport_mode(struct device *dev, "performant" : "simple"); } -/* List of controllers which cannot be reset on kexec with reset_devices */ +/* List of controllers which cannot be hard reset on kexec with reset_devices */ static u32 unresettable_controller[] = { 0x324a103C, /* Smart Array P712m */ 0x324b103C, /* SmartArray P711m */ @@ -291,16 +291,45 @@ static u32 unresettable_controller[] = { 0x409D0E11, /* Smart Array 6400 EM */ }; -static int ctlr_is_resettable(struct ctlr_info *h) +/* List of controllers which cannot even be soft reset */ +static u32 soft_unresettable_controller[] = { + /* Exclude 640x boards. These are two pci devices in one slot + * which share a battery backed cache module. One controls the + * cache, the other accesses the cache through the one that controls + * it. If we reset the one controlling the cache, the other will + * likely not be happy. Just forbid resetting this conjoined mess. + * The 640x isn't really supported by hpsa anyway. + */ + 0x409C0E11, /* Smart Array 6400 */ + 0x409D0E11, /* Smart Array 6400 EM */ +}; + +static int ctlr_is_hard_resettable(u32 board_id) { int i; for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++) - if (unresettable_controller[i] == h->board_id) + if (unresettable_controller[i] == board_id) + return 0; + return 1; +} + +static int ctlr_is_soft_resettable(u32 board_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++) + if (soft_unresettable_controller[i] == board_id) return 0; return 1; } +static int ctlr_is_resettable(u32 board_id) +{ + return ctlr_is_hard_resettable(board_id) || + ctlr_is_soft_resettable(board_id); +} + static ssize_t host_show_resettable(struct device *dev, struct device_attribute *attr, char *buf) { @@ -308,7 +337,7 @@ static ssize_t host_show_resettable(struct device *dev, struct Scsi_Host *shost = class_to_shost(dev); h = shost_to_hba(shost); - return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h)); + return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id)); } static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) @@ -929,13 +958,6 @@ static void hpsa_slave_destroy(struct scsi_device *sdev) /* nothing to do. */ } -static void hpsa_scsi_setup(struct ctlr_info *h) -{ - h->ndevices = 0; - h->scsi_host = NULL; - spin_lock_init(&h->devlock); -} - static void hpsa_free_sg_chain_blocks(struct ctlr_info *h) { int i; @@ -1006,8 +1028,7 @@ static void hpsa_unmap_sg_chain_block(struct ctlr_info *h, pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE); } -static void complete_scsi_command(struct CommandList *cp, - int timeout, u32 tag) +static void complete_scsi_command(struct CommandList *cp) { struct scsi_cmnd *cmd; struct ctlr_info *h; @@ -1308,7 +1329,7 @@ static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h, int retry_count = 0; do { - memset(c->err_info, 0, sizeof(c->err_info)); + memset(c->err_info, 0, sizeof(*c->err_info)); hpsa_scsi_do_simple_cmd_core(h, c); retry_count++; } while (check_for_unit_attention(h, c) && retry_count <= 3); @@ -1570,6 +1591,7 @@ static unsigned char *msa2xxx_model[] = { "MSA2024", "MSA2312", "MSA2324", + "P2000 G3 SAS", NULL, }; @@ -2751,6 +2773,26 @@ static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg) } } +static int __devinit hpsa_send_host_reset(struct ctlr_info *h, + unsigned char *scsi3addr, u8 reset_type) +{ + struct CommandList *c; + + c = cmd_alloc(h); + if (!c) + return -ENOMEM; + fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, + RAID_CTLR_LUNID, TYPE_MSG); + c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */ + c->waiting = NULL; + enqueue_cmd_and_start_io(h, c); + /* Don't wait for completion, the reset won't complete. Don't free + * the command either. This is the last command we will send before + * re-initializing everything, so it doesn't matter and won't leak. + */ + return 0; +} + static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, void *buff, size_t size, u8 page_code, unsigned char *scsi3addr, int cmd_type) @@ -2828,7 +2870,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_NONE; c->Request.Timeout = 0; /* Don't time out */ - c->Request.CDB[0] = 0x01; /* RESET_MSG is 0x01 */ + memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); + c->Request.CDB[0] = cmd; c->Request.CDB[1] = 0x03; /* Reset target above */ /* If bytes 4-7 are zero, it means reset the */ /* LunID device */ @@ -2936,7 +2979,7 @@ static inline void finish_cmd(struct CommandList *c, u32 raw_tag) { removeQ(c); if (likely(c->cmd_type == CMD_SCSI)) - complete_scsi_command(c, 0, raw_tag); + complete_scsi_command(c); else if (c->cmd_type == CMD_IOCTL_PEND) complete(c->waiting); } @@ -2994,6 +3037,63 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h, return next_command(h); } +/* Some controllers, like p400, will give us one interrupt + * after a soft reset, even if we turned interrupts off. + * Only need to check for this in the hpsa_xxx_discard_completions + * functions. + */ +static int ignore_bogus_interrupt(struct ctlr_info *h) +{ + if (likely(!reset_devices)) + return 0; + + if (likely(h->interrupts_enabled)) + return 0; + + dev_info(&h->pdev->dev, "Received interrupt while interrupts disabled " + "(known firmware bug.) Ignoring.\n"); + + return 1; +} + +static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id) +{ + struct ctlr_info *h = dev_id; + unsigned long flags; + u32 raw_tag; + + if (ignore_bogus_interrupt(h)) + return IRQ_NONE; + + if (interrupt_not_for_us(h)) + return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); + while (interrupt_pending(h)) { + raw_tag = get_next_completion(h); + while (raw_tag != FIFO_EMPTY) + raw_tag = next_command(h); + } + spin_unlock_irqrestore(&h->lock, flags); + return IRQ_HANDLED; +} + +static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id) +{ + struct ctlr_info *h = dev_id; + unsigned long flags; + u32 raw_tag; + + if (ignore_bogus_interrupt(h)) + return IRQ_NONE; + + spin_lock_irqsave(&h->lock, flags); + raw_tag = get_next_completion(h); + while (raw_tag != FIFO_EMPTY) + raw_tag = next_command(h); + spin_unlock_irqrestore(&h->lock, flags); + return IRQ_HANDLED; +} + static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id) { struct ctlr_info *h = dev_id; @@ -3132,11 +3232,10 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, return 0; } -#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0) #define hpsa_noop(p) hpsa_message(p, 3, 0) static int hpsa_controller_hard_reset(struct pci_dev *pdev, - void * __iomem vaddr, bool use_doorbell) + void * __iomem vaddr, u32 use_doorbell) { u16 pmcsr; int pos; @@ -3147,8 +3246,7 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev, * other way using the doorbell register. */ dev_info(&pdev->dev, "using doorbell to reset controller\n"); - writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL); - msleep(1000); + writel(use_doorbell, vaddr + SA5_DOORBELL); } else { /* Try to do it the PCI power state way */ /* Quoting from the Open CISS Specification: "The Power @@ -3179,12 +3277,63 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev, pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= PCI_D0; pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - - msleep(500); } return 0; } +static __devinit void init_driver_version(char *driver_version, int len) +{ + memset(driver_version, 0, len); + strncpy(driver_version, "hpsa " HPSA_DRIVER_VERSION, len - 1); +} + +static __devinit int write_driver_ver_to_cfgtable( + struct CfgTable __iomem *cfgtable) +{ + char *driver_version; + int i, size = sizeof(cfgtable->driver_version); + + driver_version = kmalloc(size, GFP_KERNEL); + if (!driver_version) + return -ENOMEM; + + init_driver_version(driver_version, size); + for (i = 0; i < size; i++) + writeb(driver_version[i], &cfgtable->driver_version[i]); + kfree(driver_version); + return 0; +} + +static __devinit void read_driver_ver_from_cfgtable( + struct CfgTable __iomem *cfgtable, unsigned char *driver_ver) +{ + int i; + + for (i = 0; i < sizeof(cfgtable->driver_version); i++) + driver_ver[i] = readb(&cfgtable->driver_version[i]); +} + +static __devinit int controller_reset_failed( + struct CfgTable __iomem *cfgtable) +{ + + char *driver_ver, *old_driver_ver; + int rc, size = sizeof(cfgtable->driver_version); + + old_driver_ver = kmalloc(2 * size, GFP_KERNEL); + if (!old_driver_ver) + return -ENOMEM; + driver_ver = old_driver_ver + size; + + /* After a reset, the 32 bytes of "driver version" in the cfgtable + * should have been changed, otherwise we know the reset failed. + */ + init_driver_version(old_driver_ver, size); + read_driver_ver_from_cfgtable(cfgtable, driver_ver); + rc = !memcmp(driver_ver, old_driver_ver, size); + kfree(old_driver_ver); + return rc; +} /* This does a hard reset of the controller using PCI power management * states or the using the doorbell register. */ @@ -3195,10 +3344,10 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) u64 cfg_base_addr_index; void __iomem *vaddr; unsigned long paddr; - u32 misc_fw_support, active_transport; + u32 misc_fw_support; int rc; struct CfgTable __iomem *cfgtable; - bool use_doorbell; + u32 use_doorbell; u32 board_id; u16 command_register; @@ -3215,20 +3364,15 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) * using the doorbell register. */ - /* Exclude 640x boards. These are two pci devices in one slot - * which share a battery backed cache module. One controls the - * cache, the other accesses the cache through the one that controls - * it. If we reset the one controlling the cache, the other will - * likely not be happy. Just forbid resetting this conjoined mess. - * The 640x isn't really supported by hpsa anyway. - */ rc = hpsa_lookup_board_id(pdev, &board_id); - if (rc < 0) { + if (rc < 0 || !ctlr_is_resettable(board_id)) { dev_warn(&pdev->dev, "Not resetting device.\n"); return -ENODEV; } - if (board_id == 0x409C0E11 || board_id == 0x409D0E11) - return -ENOTSUPP; + + /* if controller is soft- but not hard resettable... */ + if (!ctlr_is_hard_resettable(board_id)) + return -ENOTSUPP; /* try soft reset later. */ /* Save the PCI command register */ pci_read_config_word(pdev, 4, &command_register); @@ -3257,10 +3401,28 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) rc = -ENOMEM; goto unmap_vaddr; } + rc = write_driver_ver_to_cfgtable(cfgtable); + if (rc) + goto unmap_vaddr; - /* If reset via doorbell register is supported, use that. */ + /* If reset via doorbell register is supported, use that. + * There are two such methods. Favor the newest method. + */ misc_fw_support = readl(&cfgtable->misc_fw_support); - use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; + use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2; + if (use_doorbell) { + use_doorbell = DOORBELL_CTLR_RESET2; + } else { + use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; + if (use_doorbell) { + dev_warn(&pdev->dev, "Controller claims that " + "'Bit 2 doorbell reset' is " + "supported, but not 'bit 5 doorbell reset'. " + "Firmware update is recommended.\n"); + rc = -ENOTSUPP; /* try soft reset */ + goto unmap_cfgtable; + } + } rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); if (rc) @@ -3279,30 +3441,32 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) msleep(HPSA_POST_RESET_PAUSE_MSECS); /* Wait for board to become not ready, then ready. */ - dev_info(&pdev->dev, "Waiting for board to become ready.\n"); + dev_info(&pdev->dev, "Waiting for board to reset.\n"); rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY); - if (rc) + if (rc) { dev_warn(&pdev->dev, - "failed waiting for board to become not ready\n"); + "failed waiting for board to reset." + " Will try soft reset.\n"); + rc = -ENOTSUPP; /* Not expected, but try soft reset later */ + goto unmap_cfgtable; + } rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY); if (rc) { dev_warn(&pdev->dev, - "failed waiting for board to become ready\n"); + "failed waiting for board to become ready " + "after hard reset\n"); goto unmap_cfgtable; } - dev_info(&pdev->dev, "board ready.\n"); - /* Controller should be in simple mode at this point. If it's not, - * It means we're on one of those controllers which doesn't support - * the doorbell reset method and on which the PCI power management reset - * method doesn't work (P800, for example.) - * In those cases, don't try to proceed, as it generally doesn't work. - */ - active_transport = readl(&cfgtable->TransportActive); - if (active_transport & PERFORMANT_MODE) { - dev_warn(&pdev->dev, "Unable to successfully reset controller," - " Ignoring controller.\n"); - rc = -ENODEV; + rc = controller_reset_failed(vaddr); + if (rc < 0) + goto unmap_cfgtable; + if (rc) { + dev_warn(&pdev->dev, "Unable to successfully reset " + "controller. Will try soft reset.\n"); + rc = -ENOTSUPP; + } else { + dev_info(&pdev->dev, "board ready after hard reset.\n"); } unmap_cfgtable: @@ -3543,6 +3707,9 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h) cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable)); if (!h->cfgtable) return -ENOMEM; + rc = write_driver_ver_to_cfgtable(h->cfgtable); + if (rc) + return rc; /* Find performant mode table. */ trans_offset = readl(&h->cfgtable->TransMethodOffset); h->transtable = remap_pci_mem(pci_resource_start(h->pdev, @@ -3777,11 +3944,12 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev) * due to concerns about shared bbwc between 6402/6404 pair. */ if (rc == -ENOTSUPP) - return 0; /* just try to do the kdump anyhow. */ + return rc; /* just try to do the kdump anyhow. */ if (rc) return -ENODEV; /* Now try to get the controller to respond to a no-op */ + dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n"); for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { if (hpsa_noop(pdev) == 0) break; @@ -3792,18 +3960,133 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev) return 0; } +static __devinit int hpsa_allocate_cmd_pool(struct ctlr_info *h) +{ + h->cmd_pool_bits = kzalloc( + DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) * + sizeof(unsigned long), GFP_KERNEL); + h->cmd_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->cmd_pool), + &(h->cmd_pool_dhandle)); + h->errinfo_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->errinfo_pool), + &(h->errinfo_pool_dhandle)); + if ((h->cmd_pool_bits == NULL) + || (h->cmd_pool == NULL) + || (h->errinfo_pool == NULL)) { + dev_err(&h->pdev->dev, "out of memory in %s", __func__); + return -ENOMEM; + } + return 0; +} + +static void hpsa_free_cmd_pool(struct ctlr_info *h) +{ + kfree(h->cmd_pool_bits); + if (h->cmd_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct CommandList), + h->cmd_pool, h->cmd_pool_dhandle); + if (h->errinfo_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct ErrorInfo), + h->errinfo_pool, + h->errinfo_pool_dhandle); +} + +static int hpsa_request_irq(struct ctlr_info *h, + irqreturn_t (*msixhandler)(int, void *), + irqreturn_t (*intxhandler)(int, void *)) +{ + int rc; + + if (h->msix_vector || h->msi_vector) + rc = request_irq(h->intr[h->intr_mode], msixhandler, + IRQF_DISABLED, h->devname, h); + else + rc = request_irq(h->intr[h->intr_mode], intxhandler, + IRQF_DISABLED, h->devname, h); + if (rc) { + dev_err(&h->pdev->dev, "unable to get irq %d for %s\n", + h->intr[h->intr_mode], h->devname); + return -ENODEV; + } + return 0; +} + +static int __devinit hpsa_kdump_soft_reset(struct ctlr_info *h) +{ + if (hpsa_send_host_reset(h, RAID_CTLR_LUNID, + HPSA_RESET_TYPE_CONTROLLER)) { + dev_warn(&h->pdev->dev, "Resetting array controller failed.\n"); + return -EIO; + } + + dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n"); + if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY)) { + dev_warn(&h->pdev->dev, "Soft reset had no effect.\n"); + return -1; + } + + dev_info(&h->pdev->dev, "Board reset, awaiting READY status.\n"); + if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY)) { + dev_warn(&h->pdev->dev, "Board failed to become ready " + "after soft reset.\n"); + return -1; + } + + return 0; +} + +static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) +{ + free_irq(h->intr[h->intr_mode], h); +#ifdef CONFIG_PCI_MSI + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); +#endif /* CONFIG_PCI_MSI */ + hpsa_free_sg_chain_blocks(h); + hpsa_free_cmd_pool(h); + kfree(h->blockFetchTable); + pci_free_consistent(h->pdev, h->reply_pool_size, + h->reply_pool, h->reply_pool_dhandle); + if (h->vaddr) + iounmap(h->vaddr); + if (h->transtable) + iounmap(h->transtable); + if (h->cfgtable) + iounmap(h->cfgtable); + pci_release_regions(h->pdev); + kfree(h); +} + static int __devinit hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int dac, rc; struct ctlr_info *h; + int try_soft_reset = 0; + unsigned long flags; if (number_of_controllers == 0) printk(KERN_INFO DRIVER_NAME "\n"); rc = hpsa_init_reset_devices(pdev); - if (rc) - return rc; + if (rc) { + if (rc != -ENOTSUPP) + return rc; + /* If the reset fails in a particular way (it has no way to do + * a proper hard reset, so returns -ENOTSUPP) we can try to do + * a soft reset once we get the controller configured up to the + * point that it can accept a command. + */ + try_soft_reset = 1; + rc = 0; + } + +reinit_after_soft_reset: /* Command structures must be aligned on a 32-byte boundary because * the 5 lower bits of the address are used by the hardware. and by @@ -3847,54 +4130,82 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, /* make sure the board interrupts are off */ h->access.set_intr_mask(h, HPSA_INTR_OFF); - if (h->msix_vector || h->msi_vector) - rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_msi, - IRQF_DISABLED, h->devname, h); - else - rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_intx, - IRQF_DISABLED, h->devname, h); - if (rc) { - dev_err(&pdev->dev, "unable to get irq %d for %s\n", - h->intr[h->intr_mode], h->devname); + if (hpsa_request_irq(h, do_hpsa_intr_msi, do_hpsa_intr_intx)) goto clean2; - } - dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n", h->devname, pdev->device, h->intr[h->intr_mode], dac ? "" : " not"); - - h->cmd_pool_bits = - kmalloc(((h->nr_cmds + BITS_PER_LONG - - 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); - h->cmd_pool = pci_alloc_consistent(h->pdev, - h->nr_cmds * sizeof(*h->cmd_pool), - &(h->cmd_pool_dhandle)); - h->errinfo_pool = pci_alloc_consistent(h->pdev, - h->nr_cmds * sizeof(*h->errinfo_pool), - &(h->errinfo_pool_dhandle)); - if ((h->cmd_pool_bits == NULL) - || (h->cmd_pool == NULL) - || (h->errinfo_pool == NULL)) { - dev_err(&pdev->dev, "out of memory"); - rc = -ENOMEM; + if (hpsa_allocate_cmd_pool(h)) goto clean4; - } if (hpsa_allocate_sg_chain_blocks(h)) goto clean4; init_waitqueue_head(&h->scan_wait_queue); h->scan_finished = 1; /* no scan currently in progress */ pci_set_drvdata(pdev, h); - memset(h->cmd_pool_bits, 0, - ((h->nr_cmds + BITS_PER_LONG - - 1) / BITS_PER_LONG) * sizeof(unsigned long)); + h->ndevices = 0; + h->scsi_host = NULL; + spin_lock_init(&h->devlock); + hpsa_put_ctlr_into_performant_mode(h); + + /* At this point, the controller is ready to take commands. + * Now, if reset_devices and the hard reset didn't work, try + * the soft reset and see if that works. + */ + if (try_soft_reset) { + + /* This is kind of gross. We may or may not get a completion + * from the soft reset command, and if we do, then the value + * from the fifo may or may not be valid. So, we wait 10 secs + * after the reset throwing away any completions we get during + * that time. Unregister the interrupt handler and register + * fake ones to scoop up any residual completions. + */ + spin_lock_irqsave(&h->lock, flags); + h->access.set_intr_mask(h, HPSA_INTR_OFF); + spin_unlock_irqrestore(&h->lock, flags); + free_irq(h->intr[h->intr_mode], h); + rc = hpsa_request_irq(h, hpsa_msix_discard_completions, + hpsa_intx_discard_completions); + if (rc) { + dev_warn(&h->pdev->dev, "Failed to request_irq after " + "soft reset.\n"); + goto clean4; + } + + rc = hpsa_kdump_soft_reset(h); + if (rc) + /* Neither hard nor soft reset worked, we're hosed. */ + goto clean4; + + dev_info(&h->pdev->dev, "Board READY.\n"); + dev_info(&h->pdev->dev, + "Waiting for stale completions to drain.\n"); + h->access.set_intr_mask(h, HPSA_INTR_ON); + msleep(10000); + h->access.set_intr_mask(h, HPSA_INTR_OFF); + + rc = controller_reset_failed(h->cfgtable); + if (rc) + dev_info(&h->pdev->dev, + "Soft reset appears to have failed.\n"); + + /* since the controller's reset, we have to go back and re-init + * everything. Easiest to just forget what we've done and do it + * all over again. + */ + hpsa_undo_allocations_after_kdump_soft_reset(h); + try_soft_reset = 0; + if (rc) + /* don't go to clean4, we already unallocated */ + return -ENODEV; - hpsa_scsi_setup(h); + goto reinit_after_soft_reset; + } /* Turn the interrupts on so we can service requests */ h->access.set_intr_mask(h, HPSA_INTR_ON); - hpsa_put_ctlr_into_performant_mode(h); hpsa_hba_inquiry(h); hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ h->busy_initializing = 0; @@ -3902,16 +4213,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, clean4: hpsa_free_sg_chain_blocks(h); - kfree(h->cmd_pool_bits); - if (h->cmd_pool) - pci_free_consistent(h->pdev, - h->nr_cmds * sizeof(struct CommandList), - h->cmd_pool, h->cmd_pool_dhandle); - if (h->errinfo_pool) - pci_free_consistent(h->pdev, - h->nr_cmds * sizeof(struct ErrorInfo), - h->errinfo_pool, - h->errinfo_pool_dhandle); + hpsa_free_cmd_pool(h); free_irq(h->intr[h->intr_mode], h); clean2: clean1: |