aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2fc/bnx2fc_hwi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_hwi.c')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_hwi.c64
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
2078cleanup_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
2089cleanup_ht:
2090 kfree(hba->hash_tbl_segments);
2091 hba->hash_tbl_segments = NULL;
2092 return -ENOMEM;
2083} 2093}
2084 2094
2085/** 2095/**