diff options
author | Ewan D. Milne <emilne@redhat.com> | 2016-02-23 09:00:12 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-02-23 21:27:02 -0500 |
commit | e8c61ecc1b1658f887e74a5be2cb9f9b79baa325 (patch) | |
tree | ce3df6a7074e952abd7fb874628c4fa2700d4dfe | |
parent | f50abb9b63b1d8773e1ce32115701c06416e6f91 (diff) |
mptbase: fixup error handling paths in mpt_attach()
mpt_attach() was not checking for the failure to create fw_event_q.
Also, iounmap() was not being called in all error cases after ioremap()
had been called by mpt_mapresources().
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
Reported-by: Insu Yun <wuninsu@gmail.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/message/fusion/mptbase.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 207370d68c17..5537f8df8512 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -1801,8 +1801,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1801 | 1801 | ||
1802 | ioc->pcidev = pdev; | 1802 | ioc->pcidev = pdev; |
1803 | if (mpt_mapresources(ioc)) { | 1803 | if (mpt_mapresources(ioc)) { |
1804 | kfree(ioc); | 1804 | goto out_free_ioc; |
1805 | return r; | ||
1806 | } | 1805 | } |
1807 | 1806 | ||
1808 | /* | 1807 | /* |
@@ -1871,9 +1870,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1871 | if (!ioc->reset_work_q) { | 1870 | if (!ioc->reset_work_q) { |
1872 | printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", | 1871 | printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", |
1873 | ioc->name); | 1872 | ioc->name); |
1874 | pci_release_selected_regions(pdev, ioc->bars); | 1873 | r = -ENOMEM; |
1875 | kfree(ioc); | 1874 | goto out_unmap_resources; |
1876 | return -ENOMEM; | ||
1877 | } | 1875 | } |
1878 | 1876 | ||
1879 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", | 1877 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", |
@@ -1995,16 +1993,27 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1995 | spin_lock_init(&ioc->fw_event_lock); | 1993 | spin_lock_init(&ioc->fw_event_lock); |
1996 | snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id); | 1994 | snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id); |
1997 | ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name); | 1995 | ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name); |
1996 | if (!ioc->fw_event_q) { | ||
1997 | printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", | ||
1998 | ioc->name); | ||
1999 | r = -ENOMEM; | ||
2000 | goto out_remove_ioc; | ||
2001 | } | ||
1998 | 2002 | ||
1999 | if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, | 2003 | if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, |
2000 | CAN_SLEEP)) != 0){ | 2004 | CAN_SLEEP)) != 0){ |
2001 | printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", | 2005 | printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", |
2002 | ioc->name, r); | 2006 | ioc->name, r); |
2003 | 2007 | ||
2008 | destroy_workqueue(ioc->fw_event_q); | ||
2009 | ioc->fw_event_q = NULL; | ||
2010 | |||
2004 | list_del(&ioc->list); | 2011 | list_del(&ioc->list); |
2005 | if (ioc->alt_ioc) | 2012 | if (ioc->alt_ioc) |
2006 | ioc->alt_ioc->alt_ioc = NULL; | 2013 | ioc->alt_ioc->alt_ioc = NULL; |
2007 | iounmap(ioc->memmap); | 2014 | iounmap(ioc->memmap); |
2015 | if (pci_is_enabled(pdev)) | ||
2016 | pci_disable_device(pdev); | ||
2008 | if (r != -5) | 2017 | if (r != -5) |
2009 | pci_release_selected_regions(pdev, ioc->bars); | 2018 | pci_release_selected_regions(pdev, ioc->bars); |
2010 | 2019 | ||
@@ -2012,7 +2021,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2012 | ioc->reset_work_q = NULL; | 2021 | ioc->reset_work_q = NULL; |
2013 | 2022 | ||
2014 | kfree(ioc); | 2023 | kfree(ioc); |
2015 | pci_set_drvdata(pdev, NULL); | ||
2016 | return r; | 2024 | return r; |
2017 | } | 2025 | } |
2018 | 2026 | ||
@@ -2040,6 +2048,24 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2040 | msecs_to_jiffies(MPT_POLLING_INTERVAL)); | 2048 | msecs_to_jiffies(MPT_POLLING_INTERVAL)); |
2041 | 2049 | ||
2042 | return 0; | 2050 | return 0; |
2051 | |||
2052 | out_remove_ioc: | ||
2053 | list_del(&ioc->list); | ||
2054 | if (ioc->alt_ioc) | ||
2055 | ioc->alt_ioc->alt_ioc = NULL; | ||
2056 | |||
2057 | destroy_workqueue(ioc->reset_work_q); | ||
2058 | ioc->reset_work_q = NULL; | ||
2059 | |||
2060 | out_unmap_resources: | ||
2061 | iounmap(ioc->memmap); | ||
2062 | pci_disable_device(pdev); | ||
2063 | pci_release_selected_regions(pdev, ioc->bars); | ||
2064 | |||
2065 | out_free_ioc: | ||
2066 | kfree(ioc); | ||
2067 | |||
2068 | return r; | ||
2043 | } | 2069 | } |
2044 | 2070 | ||
2045 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2071 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -6229,7 +6255,7 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc) | |||
6229 | memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); | 6255 | memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); |
6230 | memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); | 6256 | memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); |
6231 | 6257 | ||
6232 | out: | 6258 | out: |
6233 | 6259 | ||
6234 | if (pbuf) | 6260 | if (pbuf) |
6235 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); | 6261 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); |