diff options
author | hayeswang <hayeswang@realtek.com> | 2013-07-31 05:21:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-31 17:49:13 -0400 |
commit | 31787f5398c3c5aced755e8abd5ae00a2c371cd4 (patch) | |
tree | 3ab1264fefcfd31691e5787a924a680e403054d7 /drivers/net/usb | |
parent | 543ae7f9c4e69816043ac3b526310353b413b325 (diff) |
net/usb/r8152: make sure the USB buffer is DMA-able
Allocate the required memory before calling usb_control_msg. And
the additional memory copy is necessary.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/r8152.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ee13f9eb740c..ef033ab80e7f 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -344,17 +344,41 @@ static const int multicast_filter_limit = 32; | |||
344 | static | 344 | static |
345 | int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | 345 | int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) |
346 | { | 346 | { |
347 | return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), | 347 | int ret; |
348 | void *tmp; | ||
349 | |||
350 | tmp = kmalloc(size, GFP_KERNEL); | ||
351 | if (!tmp) | ||
352 | return -ENOMEM; | ||
353 | |||
354 | ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), | ||
348 | RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, | 355 | RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, |
349 | value, index, data, size, 500); | 356 | value, index, tmp, size, 500); |
357 | |||
358 | memcpy(data, tmp, size); | ||
359 | kfree(tmp); | ||
360 | |||
361 | return ret; | ||
350 | } | 362 | } |
351 | 363 | ||
352 | static | 364 | static |
353 | int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | 365 | int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) |
354 | { | 366 | { |
355 | return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), | 367 | int ret; |
368 | void *tmp; | ||
369 | |||
370 | tmp = kmalloc(size, GFP_KERNEL); | ||
371 | if (!tmp) | ||
372 | return -ENOMEM; | ||
373 | |||
374 | memcpy(tmp, data, size); | ||
375 | |||
376 | ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), | ||
356 | RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, | 377 | RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, |
357 | value, index, data, size, 500); | 378 | value, index, tmp, size, 500); |
379 | |||
380 | kfree(tmp); | ||
381 | return ret; | ||
358 | } | 382 | } |
359 | 383 | ||
360 | static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, | 384 | static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, |
@@ -685,21 +709,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) | |||
685 | static inline void set_ethernet_addr(struct r8152 *tp) | 709 | static inline void set_ethernet_addr(struct r8152 *tp) |
686 | { | 710 | { |
687 | struct net_device *dev = tp->netdev; | 711 | struct net_device *dev = tp->netdev; |
688 | u8 *node_id; | 712 | u8 node_id[8] = {0}; |
689 | 713 | ||
690 | node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); | 714 | if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) |
691 | if (!node_id) { | ||
692 | netif_err(tp, probe, dev, "out of memory"); | ||
693 | return; | ||
694 | } | ||
695 | |||
696 | if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) | ||
697 | netif_notice(tp, probe, dev, "inet addr fail\n"); | 715 | netif_notice(tp, probe, dev, "inet addr fail\n"); |
698 | else { | 716 | else { |
699 | memcpy(dev->dev_addr, node_id, dev->addr_len); | 717 | memcpy(dev->dev_addr, node_id, dev->addr_len); |
700 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 718 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
701 | } | 719 | } |
702 | kfree(node_id); | ||
703 | } | 720 | } |
704 | 721 | ||
705 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) | 722 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) |
@@ -882,15 +899,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) | |||
882 | static void _rtl8152_set_rx_mode(struct net_device *netdev) | 899 | static void _rtl8152_set_rx_mode(struct net_device *netdev) |
883 | { | 900 | { |
884 | struct r8152 *tp = netdev_priv(netdev); | 901 | struct r8152 *tp = netdev_priv(netdev); |
885 | u32 tmp, *mc_filter; /* Multicast hash filter */ | 902 | u32 mc_filter[2]; /* Multicast hash filter */ |
903 | __le32 tmp[2]; | ||
886 | u32 ocp_data; | 904 | u32 ocp_data; |
887 | 905 | ||
888 | mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); | ||
889 | if (!mc_filter) { | ||
890 | netif_err(tp, link, netdev, "out of memory"); | ||
891 | return; | ||
892 | } | ||
893 | |||
894 | clear_bit(RTL8152_SET_RX_MODE, &tp->flags); | 906 | clear_bit(RTL8152_SET_RX_MODE, &tp->flags); |
895 | netif_stop_queue(netdev); | 907 | netif_stop_queue(netdev); |
896 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | 908 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); |
@@ -918,14 +930,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) | |||
918 | } | 930 | } |
919 | } | 931 | } |
920 | 932 | ||
921 | tmp = mc_filter[0]; | 933 | tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); |
922 | mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); | 934 | tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); |
923 | mc_filter[1] = __cpu_to_le32(swab32(tmp)); | ||
924 | 935 | ||
925 | pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); | 936 | pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); |
926 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | 937 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); |
927 | netif_wake_queue(netdev); | 938 | netif_wake_queue(netdev); |
928 | kfree(mc_filter); | ||
929 | } | 939 | } |
930 | 940 | ||
931 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, | 941 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, |