aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2013-07-31 05:21:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-31 17:49:13 -0400
commit31787f5398c3c5aced755e8abd5ae00a2c371cd4 (patch)
tree3ab1264fefcfd31691e5787a924a680e403054d7 /drivers/net/usb
parent543ae7f9c4e69816043ac3b526310353b413b325 (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.c60
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;
344static 344static
345int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) 345int 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
352static 364static
353int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) 365int 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
360static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, 384static 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)
685static inline void set_ethernet_addr(struct r8152 *tp) 709static 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
705static int rtl8152_set_mac_address(struct net_device *netdev, void *p) 722static 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)
882static void _rtl8152_set_rx_mode(struct net_device *netdev) 899static 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
931static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, 941static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,