aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBenjamin Li <benjamin.li@qlogic.com>2007-02-26 14:06:40 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-27 04:21:44 -0500
commit0f8ab89e825f8c9f1c84c558ad7e2e4006aee0d3 (patch)
tree1e10a407c48ab982032084b5fc72bb62a0d95173 /drivers
parent3e71f6dd47e7e64461328adcdc3fbad1465b4c2f (diff)
qla3xxx: Check return code from pci_map_single() in ql_release_to_lrg_buf_free_list(), ql_populate_free_queue(), ql_alloc_large_buffers(), and ql3xxx_send()
pci_map_single() could fail. We need to properly check the return code from pci_map_single(). If we can not properly map this address, then we should cleanup and return the proper return code. Signed-off-by: Benjamin Li <benjamin.li@qlogic.com> Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rwxr-xr-xdrivers/net/qla3xxx.c114
1 files changed, 107 insertions, 7 deletions
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 4e9b25f475d0..7a2f01a22cbf 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -276,7 +276,8 @@ static void ql_enable_interrupts(struct ql3_adapter *qdev)
276static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, 276static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev,
277 struct ql_rcv_buf_cb *lrg_buf_cb) 277 struct ql_rcv_buf_cb *lrg_buf_cb)
278{ 278{
279 u64 map; 279 dma_addr_t map;
280 int err;
280 lrg_buf_cb->next = NULL; 281 lrg_buf_cb->next = NULL;
281 282
282 if (qdev->lrg_buf_free_tail == NULL) { /* The list is empty */ 283 if (qdev->lrg_buf_free_tail == NULL) { /* The list is empty */
@@ -304,6 +305,17 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev,
304 qdev->lrg_buffer_len - 305 qdev->lrg_buffer_len -
305 QL_HEADER_SPACE, 306 QL_HEADER_SPACE,
306 PCI_DMA_FROMDEVICE); 307 PCI_DMA_FROMDEVICE);
308 err = pci_dma_mapping_error(map);
309 if(err) {
310 printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
311 qdev->ndev->name, err);
312 dev_kfree_skb(lrg_buf_cb->skb);
313 lrg_buf_cb->skb = NULL;
314
315 qdev->lrg_buf_skb_check++;
316 return;
317 }
318
307 lrg_buf_cb->buf_phy_addr_low = 319 lrg_buf_cb->buf_phy_addr_low =
308 cpu_to_le32(LS_64BITS(map)); 320 cpu_to_le32(LS_64BITS(map));
309 lrg_buf_cb->buf_phy_addr_high = 321 lrg_buf_cb->buf_phy_addr_high =
@@ -1624,7 +1636,8 @@ static const struct ethtool_ops ql3xxx_ethtool_ops = {
1624static int ql_populate_free_queue(struct ql3_adapter *qdev) 1636static int ql_populate_free_queue(struct ql3_adapter *qdev)
1625{ 1637{
1626 struct ql_rcv_buf_cb *lrg_buf_cb = qdev->lrg_buf_free_head; 1638 struct ql_rcv_buf_cb *lrg_buf_cb = qdev->lrg_buf_free_head;
1627 u64 map; 1639 dma_addr_t map;
1640 int err;
1628 1641
1629 while (lrg_buf_cb) { 1642 while (lrg_buf_cb) {
1630 if (!lrg_buf_cb->skb) { 1643 if (!lrg_buf_cb->skb) {
@@ -1646,6 +1659,17 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
1646 qdev->lrg_buffer_len - 1659 qdev->lrg_buffer_len -
1647 QL_HEADER_SPACE, 1660 QL_HEADER_SPACE,
1648 PCI_DMA_FROMDEVICE); 1661 PCI_DMA_FROMDEVICE);
1662
1663 err = pci_dma_mapping_error(map);
1664 if(err) {
1665 printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
1666 qdev->ndev->name, err);
1667 dev_kfree_skb(lrg_buf_cb->skb);
1668 lrg_buf_cb->skb = NULL;
1669 break;
1670 }
1671
1672
1649 lrg_buf_cb->buf_phy_addr_low = 1673 lrg_buf_cb->buf_phy_addr_low =
1650 cpu_to_le32(LS_64BITS(map)); 1674 cpu_to_le32(LS_64BITS(map));
1651 lrg_buf_cb->buf_phy_addr_high = 1675 lrg_buf_cb->buf_phy_addr_high =
@@ -2147,7 +2171,9 @@ static int ql_send_map(struct ql3_adapter *qdev,
2147 struct oal *oal; 2171 struct oal *oal;
2148 struct oal_entry *oal_entry; 2172 struct oal_entry *oal_entry;
2149 int len = skb_headlen(skb); 2173 int len = skb_headlen(skb);
2150 u64 map; 2174 dma_addr_t map;
2175 int err;
2176 int completed_segs, i;
2151 int seg_cnt, seg = 0; 2177 int seg_cnt, seg = 0;
2152 int frag_cnt = (int)skb_shinfo(skb)->nr_frags; 2178 int frag_cnt = (int)skb_shinfo(skb)->nr_frags;
2153 2179
@@ -2160,6 +2186,15 @@ static int ql_send_map(struct ql3_adapter *qdev,
2160 * Map the skb buffer first. 2186 * Map the skb buffer first.
2161 */ 2187 */
2162 map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); 2188 map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE);
2189
2190 err = pci_dma_mapping_error(map);
2191 if(err) {
2192 printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
2193 qdev->ndev->name, err);
2194
2195 return NETDEV_TX_BUSY;
2196 }
2197
2163 oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low; 2198 oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low;
2164 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); 2199 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map));
2165 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); 2200 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map));
@@ -2173,10 +2208,9 @@ static int ql_send_map(struct ql3_adapter *qdev,
2173 oal_entry->len = 2208 oal_entry->len =
2174 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); 2209 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY);
2175 } else { 2210 } else {
2176 int i;
2177 oal = tx_cb->oal; 2211 oal = tx_cb->oal;
2178 for (i=0; i<frag_cnt; i++,seg++) { 2212 for (completed_segs=0; completed_segs<frag_cnt; completed_segs++,seg++) {
2179 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 2213 skb_frag_t *frag = &skb_shinfo(skb)->frags[completed_segs];
2180 oal_entry++; 2214 oal_entry++;
2181 if ((seg == 2 && seg_cnt > 3) || /* Check for continuation */ 2215 if ((seg == 2 && seg_cnt > 3) || /* Check for continuation */
2182 (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */ 2216 (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */
@@ -2186,6 +2220,15 @@ static int ql_send_map(struct ql3_adapter *qdev,
2186 map = pci_map_single(qdev->pdev, oal, 2220 map = pci_map_single(qdev->pdev, oal,
2187 sizeof(struct oal), 2221 sizeof(struct oal),
2188 PCI_DMA_TODEVICE); 2222 PCI_DMA_TODEVICE);
2223
2224 err = pci_dma_mapping_error(map);
2225 if(err) {
2226
2227 printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n",
2228 qdev->ndev->name, err);
2229 goto map_error;
2230 }
2231
2189 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); 2232 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map));
2190 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); 2233 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map));
2191 oal_entry->len = 2234 oal_entry->len =
@@ -2204,6 +2247,14 @@ static int ql_send_map(struct ql3_adapter *qdev,
2204 pci_map_page(qdev->pdev, frag->page, 2247 pci_map_page(qdev->pdev, frag->page,
2205 frag->page_offset, frag->size, 2248 frag->page_offset, frag->size,
2206 PCI_DMA_TODEVICE); 2249 PCI_DMA_TODEVICE);
2250
2251 err = pci_dma_mapping_error(map);
2252 if(err) {
2253 printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n",
2254 qdev->ndev->name, err);
2255 goto map_error;
2256 }
2257
2207 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); 2258 oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map));
2208 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); 2259 oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map));
2209 oal_entry->len = cpu_to_le32(frag->size); 2260 oal_entry->len = cpu_to_le32(frag->size);
@@ -2215,7 +2266,46 @@ static int ql_send_map(struct ql3_adapter *qdev,
2215 oal_entry->len = 2266 oal_entry->len =
2216 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); 2267 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY);
2217 } 2268 }
2269
2218 return NETDEV_TX_OK; 2270 return NETDEV_TX_OK;
2271
2272map_error:
2273 /* A PCI mapping failed and now we will need to back out
2274 * We need to traverse through the oal's and associated pages which
2275 * have been mapped and now we must unmap them to clean up properly
2276 */
2277
2278 seg = 1;
2279 oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low;
2280 oal = tx_cb->oal;
2281 for (i=0; i<completed_segs; i++,seg++) {
2282 oal_entry++;
2283
2284 if((seg == 2 && seg_cnt > 3) || /* Check for continuation */
2285 (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */
2286 (seg == 12 && seg_cnt > 13) || /* but necessary. */
2287 (seg == 17 && seg_cnt > 18)) {
2288 pci_unmap_single(qdev->pdev,
2289 pci_unmap_addr(&tx_cb->map[seg], mapaddr),
2290 pci_unmap_len(&tx_cb->map[seg], maplen),
2291 PCI_DMA_TODEVICE);
2292 oal++;
2293 seg++;
2294 }
2295
2296 pci_unmap_page(qdev->pdev,
2297 pci_unmap_addr(&tx_cb->map[seg], mapaddr),
2298 pci_unmap_len(&tx_cb->map[seg], maplen),
2299 PCI_DMA_TODEVICE);
2300 }
2301
2302 pci_unmap_single(qdev->pdev,
2303 pci_unmap_addr(&tx_cb->map[0], mapaddr),
2304 pci_unmap_addr(&tx_cb->map[0], maplen),
2305 PCI_DMA_TODEVICE);
2306
2307 return NETDEV_TX_BUSY;
2308
2219} 2309}
2220 2310
2221/* 2311/*
@@ -2528,7 +2618,8 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
2528 int i; 2618 int i;
2529 struct ql_rcv_buf_cb *lrg_buf_cb; 2619 struct ql_rcv_buf_cb *lrg_buf_cb;
2530 struct sk_buff *skb; 2620 struct sk_buff *skb;
2531 u64 map; 2621 dma_addr_t map;
2622 int err;
2532 2623
2533 for (i = 0; i < qdev->num_large_buffers; i++) { 2624 for (i = 0; i < qdev->num_large_buffers; i++) {
2534 skb = netdev_alloc_skb(qdev->ndev, 2625 skb = netdev_alloc_skb(qdev->ndev,
@@ -2558,6 +2649,15 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
2558 qdev->lrg_buffer_len - 2649 qdev->lrg_buffer_len -
2559 QL_HEADER_SPACE, 2650 QL_HEADER_SPACE,
2560 PCI_DMA_FROMDEVICE); 2651 PCI_DMA_FROMDEVICE);
2652
2653 err = pci_dma_mapping_error(map);
2654 if(err) {
2655 printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
2656 qdev->ndev->name, err);
2657 ql_free_large_buffers(qdev);
2658 return -ENOMEM;
2659 }
2660
2561 pci_unmap_addr_set(lrg_buf_cb, mapaddr, map); 2661 pci_unmap_addr_set(lrg_buf_cb, mapaddr, map);
2562 pci_unmap_len_set(lrg_buf_cb, maplen, 2662 pci_unmap_len_set(lrg_buf_cb, maplen,
2563 qdev->lrg_buffer_len - 2663 qdev->lrg_buffer_len -