diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2007-03-06 05:41:52 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-06 06:10:02 -0500 |
commit | 4dc68f3de5e36d72663bb51b94662d2d5db84125 (patch) | |
tree | f5dd7ac3fce58e5f4e760a1c7b212230321eeeb5 /drivers/net/tulip | |
parent | f67ba792fa10e3a65226d53dccc1232908d86c20 (diff) |
dmfe: fix two bugs
Fix a oops on module removal due to deallocating memory before unregistring
driver Fix a NULL pointer dereference when dev_alloc_skb fails
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Cc: Valerie Henson <val_henson@linux.intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/tulip')
-rw-r--r-- | drivers/net/tulip/dmfe.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index fc4a2125b501..afd5e527032b 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -501,14 +501,17 @@ static void __devexit dmfe_remove_one (struct pci_dev *pdev) | |||
501 | DMFE_DBUG(0, "dmfe_remove_one()", 0); | 501 | DMFE_DBUG(0, "dmfe_remove_one()", 0); |
502 | 502 | ||
503 | if (dev) { | 503 | if (dev) { |
504 | |||
505 | unregister_netdev(dev); | ||
506 | |||
504 | pci_free_consistent(db->pdev, sizeof(struct tx_desc) * | 507 | pci_free_consistent(db->pdev, sizeof(struct tx_desc) * |
505 | DESC_ALL_CNT + 0x20, db->desc_pool_ptr, | 508 | DESC_ALL_CNT + 0x20, db->desc_pool_ptr, |
506 | db->desc_pool_dma_ptr); | 509 | db->desc_pool_dma_ptr); |
507 | pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, | 510 | pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, |
508 | db->buf_pool_ptr, db->buf_pool_dma_ptr); | 511 | db->buf_pool_ptr, db->buf_pool_dma_ptr); |
509 | unregister_netdev(dev); | ||
510 | pci_release_regions(pdev); | 512 | pci_release_regions(pdev); |
511 | free_netdev(dev); /* free board information */ | 513 | free_netdev(dev); /* free board information */ |
514 | |||
512 | pci_set_drvdata(pdev, NULL); | 515 | pci_set_drvdata(pdev, NULL); |
513 | } | 516 | } |
514 | 517 | ||
@@ -927,7 +930,7 @@ static inline u32 cal_CRC(unsigned char * Data, unsigned int Len, u8 flag) | |||
927 | static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) | 930 | static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) |
928 | { | 931 | { |
929 | struct rx_desc *rxptr; | 932 | struct rx_desc *rxptr; |
930 | struct sk_buff *skb; | 933 | struct sk_buff *skb, *newskb; |
931 | int rxlen; | 934 | int rxlen; |
932 | u32 rdes0; | 935 | u32 rdes0; |
933 | 936 | ||
@@ -980,9 +983,11 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) | |||
980 | } else { | 983 | } else { |
981 | /* Good packet, send to upper layer */ | 984 | /* Good packet, send to upper layer */ |
982 | /* Shorst packet used new SKB */ | 985 | /* Shorst packet used new SKB */ |
983 | if ( (rxlen < RX_COPY_SIZE) && | 986 | if ((rxlen < RX_COPY_SIZE) && |
984 | ( (skb = dev_alloc_skb(rxlen + 2) ) | 987 | ((newskb = dev_alloc_skb(rxlen + 2)) |
985 | != NULL) ) { | 988 | != NULL)) { |
989 | |||
990 | skb = newskb; | ||
986 | /* size less than COPY_SIZE, allocate a rxlen SKB */ | 991 | /* size less than COPY_SIZE, allocate a rxlen SKB */ |
987 | skb->dev = dev; | 992 | skb->dev = dev; |
988 | skb_reserve(skb, 2); /* 16byte align */ | 993 | skb_reserve(skb, 2); /* 16byte align */ |