@@ -276,7 +276,8 @@ static void ql_enable_interrupts(struct ql3_adapter *qdev)
276276static void ql_release_to_lrg_buf_free_list (struct ql3_adapter * qdev ,
277277 struct ql_rcv_buf_cb * lrg_buf_cb )
278278{
279- u64 map ;
279+ dma_addr_t map ;
280+ int err ;
280281 lrg_buf_cb -> next = NULL ;
281282
282283 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,
304305 qdev -> lrg_buffer_len -
305306 QL_HEADER_SPACE ,
306307 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+
307319 lrg_buf_cb -> buf_phy_addr_low =
308320 cpu_to_le32 (LS_64BITS (map ));
309321 lrg_buf_cb -> buf_phy_addr_high =
@@ -1624,7 +1636,8 @@ static const struct ethtool_ops ql3xxx_ethtool_ops = {
16241636static int ql_populate_free_queue (struct ql3_adapter * qdev )
16251637{
16261638 struct ql_rcv_buf_cb * lrg_buf_cb = qdev -> lrg_buf_free_head ;
1627- u64 map ;
1639+ dma_addr_t map ;
1640+ int err ;
16281641
16291642 while (lrg_buf_cb ) {
16301643 if (!lrg_buf_cb -> skb ) {
@@ -1646,6 +1659,17 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
16461659 qdev -> lrg_buffer_len -
16471660 QL_HEADER_SPACE ,
16481661 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+
16491673 lrg_buf_cb -> buf_phy_addr_low =
16501674 cpu_to_le32 (LS_64BITS (map ));
16511675 lrg_buf_cb -> buf_phy_addr_high =
@@ -2147,7 +2171,9 @@ static int ql_send_map(struct ql3_adapter *qdev,
21472171 struct oal * oal ;
21482172 struct oal_entry * oal_entry ;
21492173 int len = skb_headlen (skb );
2150- u64 map ;
2174+ dma_addr_t map ;
2175+ int err ;
2176+ int completed_segs , i ;
21512177 int seg_cnt , seg = 0 ;
21522178 int frag_cnt = (int )skb_shinfo (skb )-> nr_frags ;
21532179
@@ -2160,6 +2186,15 @@ static int ql_send_map(struct ql3_adapter *qdev,
21602186 * Map the skb buffer first.
21612187 */
21622188 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+
21632198 oal_entry = (struct oal_entry * )& mac_iocb_ptr -> buf_addr0_low ;
21642199 oal_entry -> dma_lo = cpu_to_le32 (LS_64BITS (map ));
21652200 oal_entry -> dma_hi = cpu_to_le32 (MS_64BITS (map ));
@@ -2173,10 +2208,9 @@ static int ql_send_map(struct ql3_adapter *qdev,
21732208 oal_entry -> len =
21742209 cpu_to_le32 (le32_to_cpu (oal_entry -> len ) | OAL_LAST_ENTRY );
21752210 } else {
2176- int i ;
21772211 oal = tx_cb -> oal ;
2178- for (i = 0 ; i < frag_cnt ; i ++ ,seg ++ ) {
2179- skb_frag_t * frag = & skb_shinfo (skb )-> frags [i ];
2212+ for (completed_segs = 0 ; completed_segs < frag_cnt ; completed_segs ++ ,seg ++ ) {
2213+ skb_frag_t * frag = & skb_shinfo (skb )-> frags [completed_segs ];
21802214 oal_entry ++ ;
21812215 if ((seg == 2 && seg_cnt > 3 ) || /* Check for continuation */
21822216 (seg == 7 && seg_cnt > 8 ) || /* requirements. It's strange */
@@ -2186,6 +2220,15 @@ static int ql_send_map(struct ql3_adapter *qdev,
21862220 map = pci_map_single (qdev -> pdev , oal ,
21872221 sizeof (struct oal ),
21882222 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+
21892232 oal_entry -> dma_lo = cpu_to_le32 (LS_64BITS (map ));
21902233 oal_entry -> dma_hi = cpu_to_le32 (MS_64BITS (map ));
21912234 oal_entry -> len =
@@ -2204,6 +2247,14 @@ static int ql_send_map(struct ql3_adapter *qdev,
22042247 pci_map_page (qdev -> pdev , frag -> page ,
22052248 frag -> page_offset , frag -> size ,
22062249 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+
22072258 oal_entry -> dma_lo = cpu_to_le32 (LS_64BITS (map ));
22082259 oal_entry -> dma_hi = cpu_to_le32 (MS_64BITS (map ));
22092260 oal_entry -> len = cpu_to_le32 (frag -> size );
@@ -2215,7 +2266,46 @@ static int ql_send_map(struct ql3_adapter *qdev,
22152266 oal_entry -> len =
22162267 cpu_to_le32 (le32_to_cpu (oal_entry -> len ) | OAL_LAST_ENTRY );
22172268 }
2269+
22182270 return NETDEV_TX_OK ;
2271+
2272+ map_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+
22192309}
22202310
22212311/*
@@ -2528,7 +2618,8 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
25282618 int i ;
25292619 struct ql_rcv_buf_cb * lrg_buf_cb ;
25302620 struct sk_buff * skb ;
2531- u64 map ;
2621+ dma_addr_t map ;
2622+ int err ;
25322623
25332624 for (i = 0 ; i < qdev -> num_large_buffers ; i ++ ) {
25342625 skb = netdev_alloc_skb (qdev -> ndev ,
@@ -2558,6 +2649,15 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
25582649 qdev -> lrg_buffer_len -
25592650 QL_HEADER_SPACE ,
25602651 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+
25612661 pci_unmap_addr_set (lrg_buf_cb , mapaddr , map );
25622662 pci_unmap_len_set (lrg_buf_cb , maplen ,
25632663 qdev -> lrg_buffer_len -
0 commit comments