diff options
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_hwi.c')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_hwi.c | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 46a37657307f..512aed3ae4f1 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c | |||
@@ -1966,26 +1966,29 @@ static void bnx2fc_free_hash_table(struct bnx2fc_hba *hba) | |||
1966 | { | 1966 | { |
1967 | int i; | 1967 | int i; |
1968 | int segment_count; | 1968 | int segment_count; |
1969 | int hash_table_size; | ||
1970 | u32 *pbl; | 1969 | u32 *pbl; |
1971 | 1970 | ||
1972 | segment_count = hba->hash_tbl_segment_count; | 1971 | if (hba->hash_tbl_segments) { |
1973 | hash_table_size = BNX2FC_NUM_MAX_SESS * BNX2FC_MAX_ROWS_IN_HASH_TBL * | ||
1974 | sizeof(struct fcoe_hash_table_entry); | ||
1975 | 1972 | ||
1976 | pbl = hba->hash_tbl_pbl; | 1973 | pbl = hba->hash_tbl_pbl; |
1977 | for (i = 0; i < segment_count; ++i) { | 1974 | if (pbl) { |
1978 | dma_addr_t dma_address; | 1975 | segment_count = hba->hash_tbl_segment_count; |
1976 | for (i = 0; i < segment_count; ++i) { | ||
1977 | dma_addr_t dma_address; | ||
1979 | 1978 | ||
1980 | dma_address = le32_to_cpu(*pbl); | 1979 | dma_address = le32_to_cpu(*pbl); |
1981 | ++pbl; | 1980 | ++pbl; |
1982 | dma_address += ((u64)le32_to_cpu(*pbl)) << 32; | 1981 | dma_address += ((u64)le32_to_cpu(*pbl)) << 32; |
1983 | ++pbl; | 1982 | ++pbl; |
1984 | dma_free_coherent(&hba->pcidev->dev, | 1983 | dma_free_coherent(&hba->pcidev->dev, |
1985 | BNX2FC_HASH_TBL_CHUNK_SIZE, | 1984 | BNX2FC_HASH_TBL_CHUNK_SIZE, |
1986 | hba->hash_tbl_segments[i], | 1985 | hba->hash_tbl_segments[i], |
1987 | dma_address); | 1986 | dma_address); |
1987 | } | ||
1988 | } | ||
1988 | 1989 | ||
1990 | kfree(hba->hash_tbl_segments); | ||
1991 | hba->hash_tbl_segments = NULL; | ||
1989 | } | 1992 | } |
1990 | 1993 | ||
1991 | if (hba->hash_tbl_pbl) { | 1994 | if (hba->hash_tbl_pbl) { |
@@ -2023,7 +2026,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) | |||
2023 | dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL); | 2026 | dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL); |
2024 | if (!dma_segment_array) { | 2027 | if (!dma_segment_array) { |
2025 | printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n"); | 2028 | printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n"); |
2026 | return -ENOMEM; | 2029 | goto cleanup_ht; |
2027 | } | 2030 | } |
2028 | 2031 | ||
2029 | for (i = 0; i < segment_count; ++i) { | 2032 | for (i = 0; i < segment_count; ++i) { |
@@ -2034,15 +2037,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) | |||
2034 | GFP_KERNEL); | 2037 | GFP_KERNEL); |
2035 | if (!hba->hash_tbl_segments[i]) { | 2038 | if (!hba->hash_tbl_segments[i]) { |
2036 | printk(KERN_ERR PFX "hash segment alloc failed\n"); | 2039 | printk(KERN_ERR PFX "hash segment alloc failed\n"); |
2037 | while (--i >= 0) { | 2040 | goto cleanup_dma; |
2038 | dma_free_coherent(&hba->pcidev->dev, | ||
2039 | BNX2FC_HASH_TBL_CHUNK_SIZE, | ||
2040 | hba->hash_tbl_segments[i], | ||
2041 | dma_segment_array[i]); | ||
2042 | hba->hash_tbl_segments[i] = NULL; | ||
2043 | } | ||
2044 | kfree(dma_segment_array); | ||
2045 | return -ENOMEM; | ||
2046 | } | 2041 | } |
2047 | memset(hba->hash_tbl_segments[i], 0, | 2042 | memset(hba->hash_tbl_segments[i], 0, |
2048 | BNX2FC_HASH_TBL_CHUNK_SIZE); | 2043 | BNX2FC_HASH_TBL_CHUNK_SIZE); |
@@ -2054,8 +2049,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) | |||
2054 | GFP_KERNEL); | 2049 | GFP_KERNEL); |
2055 | if (!hba->hash_tbl_pbl) { | 2050 | if (!hba->hash_tbl_pbl) { |
2056 | printk(KERN_ERR PFX "hash table pbl alloc failed\n"); | 2051 | printk(KERN_ERR PFX "hash table pbl alloc failed\n"); |
2057 | kfree(dma_segment_array); | 2052 | goto cleanup_dma; |
2058 | return -ENOMEM; | ||
2059 | } | 2053 | } |
2060 | memset(hba->hash_tbl_pbl, 0, PAGE_SIZE); | 2054 | memset(hba->hash_tbl_pbl, 0, PAGE_SIZE); |
2061 | 2055 | ||
@@ -2080,6 +2074,22 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) | |||
2080 | } | 2074 | } |
2081 | kfree(dma_segment_array); | 2075 | kfree(dma_segment_array); |
2082 | return 0; | 2076 | return 0; |
2077 | |||
2078 | cleanup_dma: | ||
2079 | for (i = 0; i < segment_count; ++i) { | ||
2080 | if (hba->hash_tbl_segments[i]) | ||
2081 | dma_free_coherent(&hba->pcidev->dev, | ||
2082 | BNX2FC_HASH_TBL_CHUNK_SIZE, | ||
2083 | hba->hash_tbl_segments[i], | ||
2084 | dma_segment_array[i]); | ||
2085 | } | ||
2086 | |||
2087 | kfree(dma_segment_array); | ||
2088 | |||
2089 | cleanup_ht: | ||
2090 | kfree(hba->hash_tbl_segments); | ||
2091 | hba->hash_tbl_segments = NULL; | ||
2092 | return -ENOMEM; | ||
2083 | } | 2093 | } |
2084 | 2094 | ||
2085 | /** | 2095 | /** |