diff options
author | stephen hemminger <stephen@networkplumber.org> | 2017-07-28 11:59:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-07-29 18:25:43 -0400 |
commit | 867047c4512aa65fb4cf66b253b51b830c7fa172 (patch) | |
tree | 61fe0635f7c2eaae5d6591d5df61f05c18a3ff11 /drivers/net/hyperv | |
parent | d6aac1f218873f2266de23280bffb909b4a98fbf (diff) |
netvsc: fix warnings reported by lockdep
This includes a bunch of fixups for issues reported by
lockdep.
* ethtool routines can assume RTNL
* send is done with RCU lock (and BH disable)
* avoid refetching internal device struct (netvsc)
instead pass it as a parameter.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 3 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 2 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 15 | ||||
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 84 |
4 files changed, 54 insertions, 50 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 4e7ff348327e..fb62ea632914 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -217,7 +217,8 @@ int rndis_filter_receive(struct net_device *ndev, | |||
217 | struct vmbus_channel *channel, | 217 | struct vmbus_channel *channel, |
218 | void *data, u32 buflen); | 218 | void *data, u32 buflen); |
219 | 219 | ||
220 | int rndis_filter_set_device_mac(struct net_device *ndev, char *mac); | 220 | int rndis_filter_set_device_mac(struct netvsc_device *ndev, |
221 | const char *mac); | ||
221 | 222 | ||
222 | void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); | 223 | void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); |
223 | 224 | ||
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 06f39a99da7c..94c00acac58a 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -832,7 +832,7 @@ int netvsc_send(struct net_device_context *ndev_ctx, | |||
832 | struct sk_buff *skb) | 832 | struct sk_buff *skb) |
833 | { | 833 | { |
834 | struct netvsc_device *net_device | 834 | struct netvsc_device *net_device |
835 | = rcu_dereference_rtnl(ndev_ctx->nvdev); | 835 | = rcu_dereference_bh(ndev_ctx->nvdev); |
836 | struct hv_device *device = ndev_ctx->device_ctx; | 836 | struct hv_device *device = ndev_ctx->device_ctx; |
837 | int ret = 0; | 837 | int ret = 0; |
838 | struct netvsc_channel *nvchan; | 838 | struct netvsc_channel *nvchan; |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index f1eaf675d2e9..a04f2efbbc25 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -923,6 +923,8 @@ static void netvsc_get_stats64(struct net_device *net, | |||
923 | 923 | ||
924 | static int netvsc_set_mac_addr(struct net_device *ndev, void *p) | 924 | static int netvsc_set_mac_addr(struct net_device *ndev, void *p) |
925 | { | 925 | { |
926 | struct net_device_context *ndc = netdev_priv(ndev); | ||
927 | struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev); | ||
926 | struct sockaddr *addr = p; | 928 | struct sockaddr *addr = p; |
927 | char save_adr[ETH_ALEN]; | 929 | char save_adr[ETH_ALEN]; |
928 | unsigned char save_aatype; | 930 | unsigned char save_aatype; |
@@ -935,7 +937,10 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p) | |||
935 | if (err != 0) | 937 | if (err != 0) |
936 | return err; | 938 | return err; |
937 | 939 | ||
938 | err = rndis_filter_set_device_mac(ndev, addr->sa_data); | 940 | if (!nvdev) |
941 | return -ENODEV; | ||
942 | |||
943 | err = rndis_filter_set_device_mac(nvdev, addr->sa_data); | ||
939 | if (err != 0) { | 944 | if (err != 0) { |
940 | /* roll back to saved MAC */ | 945 | /* roll back to saved MAC */ |
941 | memcpy(ndev->dev_addr, save_adr, ETH_ALEN); | 946 | memcpy(ndev->dev_addr, save_adr, ETH_ALEN); |
@@ -981,7 +986,7 @@ static void netvsc_get_ethtool_stats(struct net_device *dev, | |||
981 | struct ethtool_stats *stats, u64 *data) | 986 | struct ethtool_stats *stats, u64 *data) |
982 | { | 987 | { |
983 | struct net_device_context *ndc = netdev_priv(dev); | 988 | struct net_device_context *ndc = netdev_priv(dev); |
984 | struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); | 989 | struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev); |
985 | const void *nds = &ndc->eth_stats; | 990 | const void *nds = &ndc->eth_stats; |
986 | const struct netvsc_stats *qstats; | 991 | const struct netvsc_stats *qstats; |
987 | unsigned int start; | 992 | unsigned int start; |
@@ -1019,7 +1024,7 @@ static void netvsc_get_ethtool_stats(struct net_device *dev, | |||
1019 | static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data) | 1024 | static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
1020 | { | 1025 | { |
1021 | struct net_device_context *ndc = netdev_priv(dev); | 1026 | struct net_device_context *ndc = netdev_priv(dev); |
1022 | struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); | 1027 | struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev); |
1023 | u8 *p = data; | 1028 | u8 *p = data; |
1024 | int i; | 1029 | int i; |
1025 | 1030 | ||
@@ -1077,7 +1082,7 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, | |||
1077 | u32 *rules) | 1082 | u32 *rules) |
1078 | { | 1083 | { |
1079 | struct net_device_context *ndc = netdev_priv(dev); | 1084 | struct net_device_context *ndc = netdev_priv(dev); |
1080 | struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); | 1085 | struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev); |
1081 | 1086 | ||
1082 | if (!nvdev) | 1087 | if (!nvdev) |
1083 | return -ENODEV; | 1088 | return -ENODEV; |
@@ -1127,7 +1132,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, | |||
1127 | u8 *hfunc) | 1132 | u8 *hfunc) |
1128 | { | 1133 | { |
1129 | struct net_device_context *ndc = netdev_priv(dev); | 1134 | struct net_device_context *ndc = netdev_priv(dev); |
1130 | struct netvsc_device *ndev = rcu_dereference(ndc->nvdev); | 1135 | struct netvsc_device *ndev = rtnl_dereference(ndc->nvdev); |
1131 | struct rndis_device *rndis_dev; | 1136 | struct rndis_device *rndis_dev; |
1132 | int i; | 1137 | int i; |
1133 | 1138 | ||
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index eaa3f0d5682a..bf21ea92c743 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -85,14 +85,6 @@ static struct rndis_device *get_rndis_device(void) | |||
85 | return device; | 85 | return device; |
86 | } | 86 | } |
87 | 87 | ||
88 | static struct netvsc_device * | ||
89 | net_device_to_netvsc_device(struct net_device *ndev) | ||
90 | { | ||
91 | struct net_device_context *net_device_ctx = netdev_priv(ndev); | ||
92 | |||
93 | return rtnl_dereference(net_device_ctx->nvdev); | ||
94 | } | ||
95 | |||
96 | static struct rndis_request *get_rndis_request(struct rndis_device *dev, | 88 | static struct rndis_request *get_rndis_request(struct rndis_device *dev, |
97 | u32 msg_type, | 89 | u32 msg_type, |
98 | u32 msg_len) | 90 | u32 msg_len) |
@@ -252,7 +244,10 @@ static int rndis_filter_send_request(struct rndis_device *dev, | |||
252 | pb[0].len; | 244 | pb[0].len; |
253 | } | 245 | } |
254 | 246 | ||
247 | rcu_read_lock_bh(); | ||
255 | ret = netvsc_send(net_device_ctx, packet, NULL, &pb, NULL); | 248 | ret = netvsc_send(net_device_ctx, packet, NULL, &pb, NULL); |
249 | rcu_read_unlock_bh(); | ||
250 | |||
256 | return ret; | 251 | return ret; |
257 | } | 252 | } |
258 | 253 | ||
@@ -452,8 +447,9 @@ int rndis_filter_receive(struct net_device *ndev, | |||
452 | return 0; | 447 | return 0; |
453 | } | 448 | } |
454 | 449 | ||
455 | static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, | 450 | static int rndis_filter_query_device(struct rndis_device *dev, |
456 | void *result, u32 *result_size) | 451 | struct netvsc_device *nvdev, |
452 | u32 oid, void *result, u32 *result_size) | ||
457 | { | 453 | { |
458 | struct rndis_request *request; | 454 | struct rndis_request *request; |
459 | u32 inresult_size = *result_size; | 455 | u32 inresult_size = *result_size; |
@@ -480,8 +476,6 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, | |||
480 | query->dev_vc_handle = 0; | 476 | query->dev_vc_handle = 0; |
481 | 477 | ||
482 | if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) { | 478 | if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) { |
483 | struct net_device_context *ndevctx = netdev_priv(dev->ndev); | ||
484 | struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); | ||
485 | struct ndis_offload *hwcaps; | 479 | struct ndis_offload *hwcaps; |
486 | u32 nvsp_version = nvdev->nvsp_version; | 480 | u32 nvsp_version = nvdev->nvsp_version; |
487 | u8 ndis_rev; | 481 | u8 ndis_rev; |
@@ -550,14 +544,15 @@ cleanup: | |||
550 | 544 | ||
551 | /* Get the hardware offload capabilities */ | 545 | /* Get the hardware offload capabilities */ |
552 | static int | 546 | static int |
553 | rndis_query_hwcaps(struct rndis_device *dev, struct ndis_offload *caps) | 547 | rndis_query_hwcaps(struct rndis_device *dev, struct netvsc_device *net_device, |
548 | struct ndis_offload *caps) | ||
554 | { | 549 | { |
555 | u32 caps_len = sizeof(*caps); | 550 | u32 caps_len = sizeof(*caps); |
556 | int ret; | 551 | int ret; |
557 | 552 | ||
558 | memset(caps, 0, sizeof(*caps)); | 553 | memset(caps, 0, sizeof(*caps)); |
559 | 554 | ||
560 | ret = rndis_filter_query_device(dev, | 555 | ret = rndis_filter_query_device(dev, net_device, |
561 | OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, | 556 | OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, |
562 | caps, &caps_len); | 557 | caps, &caps_len); |
563 | if (ret) | 558 | if (ret) |
@@ -586,11 +581,12 @@ rndis_query_hwcaps(struct rndis_device *dev, struct ndis_offload *caps) | |||
586 | return 0; | 581 | return 0; |
587 | } | 582 | } |
588 | 583 | ||
589 | static int rndis_filter_query_device_mac(struct rndis_device *dev) | 584 | static int rndis_filter_query_device_mac(struct rndis_device *dev, |
585 | struct netvsc_device *net_device) | ||
590 | { | 586 | { |
591 | u32 size = ETH_ALEN; | 587 | u32 size = ETH_ALEN; |
592 | 588 | ||
593 | return rndis_filter_query_device(dev, | 589 | return rndis_filter_query_device(dev, net_device, |
594 | RNDIS_OID_802_3_PERMANENT_ADDRESS, | 590 | RNDIS_OID_802_3_PERMANENT_ADDRESS, |
595 | dev->hw_mac_adr, &size); | 591 | dev->hw_mac_adr, &size); |
596 | } | 592 | } |
@@ -598,9 +594,9 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev) | |||
598 | #define NWADR_STR "NetworkAddress" | 594 | #define NWADR_STR "NetworkAddress" |
599 | #define NWADR_STRLEN 14 | 595 | #define NWADR_STRLEN 14 |
600 | 596 | ||
601 | int rndis_filter_set_device_mac(struct net_device *ndev, char *mac) | 597 | int rndis_filter_set_device_mac(struct netvsc_device *nvdev, |
598 | const char *mac) | ||
602 | { | 599 | { |
603 | struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev); | ||
604 | struct rndis_device *rdev = nvdev->extension; | 600 | struct rndis_device *rdev = nvdev->extension; |
605 | struct rndis_request *request; | 601 | struct rndis_request *request; |
606 | struct rndis_set_request *set; | 602 | struct rndis_set_request *set; |
@@ -654,11 +650,8 @@ int rndis_filter_set_device_mac(struct net_device *ndev, char *mac) | |||
654 | wait_for_completion(&request->wait_event); | 650 | wait_for_completion(&request->wait_event); |
655 | 651 | ||
656 | set_complete = &request->response_msg.msg.set_complete; | 652 | set_complete = &request->response_msg.msg.set_complete; |
657 | if (set_complete->status != RNDIS_STATUS_SUCCESS) { | 653 | if (set_complete->status != RNDIS_STATUS_SUCCESS) |
658 | netdev_err(ndev, "Fail to set MAC on host side:0x%x\n", | 654 | ret = -EIO; |
659 | set_complete->status); | ||
660 | ret = -EINVAL; | ||
661 | } | ||
662 | 655 | ||
663 | cleanup: | 656 | cleanup: |
664 | put_rndis_request(rdev, request); | 657 | put_rndis_request(rdev, request); |
@@ -791,27 +784,27 @@ cleanup: | |||
791 | return ret; | 784 | return ret; |
792 | } | 785 | } |
793 | 786 | ||
794 | static int rndis_filter_query_device_link_status(struct rndis_device *dev) | 787 | static int rndis_filter_query_device_link_status(struct rndis_device *dev, |
788 | struct netvsc_device *net_device) | ||
795 | { | 789 | { |
796 | u32 size = sizeof(u32); | 790 | u32 size = sizeof(u32); |
797 | u32 link_status; | 791 | u32 link_status; |
798 | int ret; | ||
799 | 792 | ||
800 | ret = rndis_filter_query_device(dev, | 793 | return rndis_filter_query_device(dev, net_device, |
801 | RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, | 794 | RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, |
802 | &link_status, &size); | 795 | &link_status, &size); |
803 | |||
804 | return ret; | ||
805 | } | 796 | } |
806 | 797 | ||
807 | static int rndis_filter_query_link_speed(struct rndis_device *dev) | 798 | static int rndis_filter_query_link_speed(struct rndis_device *dev, |
799 | struct netvsc_device *net_device) | ||
808 | { | 800 | { |
809 | u32 size = sizeof(u32); | 801 | u32 size = sizeof(u32); |
810 | u32 link_speed; | 802 | u32 link_speed; |
811 | struct net_device_context *ndc; | 803 | struct net_device_context *ndc; |
812 | int ret; | 804 | int ret; |
813 | 805 | ||
814 | ret = rndis_filter_query_device(dev, RNDIS_OID_GEN_LINK_SPEED, | 806 | ret = rndis_filter_query_device(dev, net_device, |
807 | RNDIS_OID_GEN_LINK_SPEED, | ||
815 | &link_speed, &size); | 808 | &link_speed, &size); |
816 | 809 | ||
817 | if (!ret) { | 810 | if (!ret) { |
@@ -880,14 +873,14 @@ void rndis_filter_update(struct netvsc_device *nvdev) | |||
880 | schedule_work(&rdev->mcast_work); | 873 | schedule_work(&rdev->mcast_work); |
881 | } | 874 | } |
882 | 875 | ||
883 | static int rndis_filter_init_device(struct rndis_device *dev) | 876 | static int rndis_filter_init_device(struct rndis_device *dev, |
877 | struct netvsc_device *nvdev) | ||
884 | { | 878 | { |
885 | struct rndis_request *request; | 879 | struct rndis_request *request; |
886 | struct rndis_initialize_request *init; | 880 | struct rndis_initialize_request *init; |
887 | struct rndis_initialize_complete *init_complete; | 881 | struct rndis_initialize_complete *init_complete; |
888 | u32 status; | 882 | u32 status; |
889 | int ret; | 883 | int ret; |
890 | struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev); | ||
891 | 884 | ||
892 | request = get_rndis_request(dev, RNDIS_MSG_INIT, | 885 | request = get_rndis_request(dev, RNDIS_MSG_INIT, |
893 | RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); | 886 | RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); |
@@ -1024,12 +1017,17 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc) | |||
1024 | { | 1017 | { |
1025 | struct net_device *ndev = | 1018 | struct net_device *ndev = |
1026 | hv_get_drvdata(new_sc->primary_channel->device_obj); | 1019 | hv_get_drvdata(new_sc->primary_channel->device_obj); |
1027 | struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev); | 1020 | struct net_device_context *ndev_ctx = netdev_priv(ndev); |
1021 | struct netvsc_device *nvscdev; | ||
1028 | u16 chn_index = new_sc->offermsg.offer.sub_channel_index; | 1022 | u16 chn_index = new_sc->offermsg.offer.sub_channel_index; |
1029 | struct netvsc_channel *nvchan; | 1023 | struct netvsc_channel *nvchan; |
1030 | int ret; | 1024 | int ret; |
1031 | 1025 | ||
1032 | if (chn_index >= nvscdev->num_chn) | 1026 | /* This is safe because this callback only happens when |
1027 | * new device is being setup and waiting on the channel_init_wait. | ||
1028 | */ | ||
1029 | nvscdev = rcu_dereference_raw(ndev_ctx->nvdev); | ||
1030 | if (!nvscdev || chn_index >= nvscdev->num_chn) | ||
1033 | return; | 1031 | return; |
1034 | 1032 | ||
1035 | nvchan = nvscdev->chan_table + chn_index; | 1033 | nvchan = nvscdev->chan_table + chn_index; |
@@ -1104,27 +1102,27 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, | |||
1104 | rndis_device->ndev = net; | 1102 | rndis_device->ndev = net; |
1105 | 1103 | ||
1106 | /* Send the rndis initialization message */ | 1104 | /* Send the rndis initialization message */ |
1107 | ret = rndis_filter_init_device(rndis_device); | 1105 | ret = rndis_filter_init_device(rndis_device, net_device); |
1108 | if (ret != 0) | 1106 | if (ret != 0) |
1109 | goto err_dev_remv; | 1107 | goto err_dev_remv; |
1110 | 1108 | ||
1111 | /* Get the MTU from the host */ | 1109 | /* Get the MTU from the host */ |
1112 | size = sizeof(u32); | 1110 | size = sizeof(u32); |
1113 | ret = rndis_filter_query_device(rndis_device, | 1111 | ret = rndis_filter_query_device(rndis_device, net_device, |
1114 | RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, | 1112 | RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, |
1115 | &mtu, &size); | 1113 | &mtu, &size); |
1116 | if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) | 1114 | if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) |
1117 | net->mtu = mtu; | 1115 | net->mtu = mtu; |
1118 | 1116 | ||
1119 | /* Get the mac address */ | 1117 | /* Get the mac address */ |
1120 | ret = rndis_filter_query_device_mac(rndis_device); | 1118 | ret = rndis_filter_query_device_mac(rndis_device, net_device); |
1121 | if (ret != 0) | 1119 | if (ret != 0) |
1122 | goto err_dev_remv; | 1120 | goto err_dev_remv; |
1123 | 1121 | ||
1124 | memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN); | 1122 | memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN); |
1125 | 1123 | ||
1126 | /* Find HW offload capabilities */ | 1124 | /* Find HW offload capabilities */ |
1127 | ret = rndis_query_hwcaps(rndis_device, &hwcaps); | 1125 | ret = rndis_query_hwcaps(rndis_device, net_device, &hwcaps); |
1128 | if (ret != 0) | 1126 | if (ret != 0) |
1129 | goto err_dev_remv; | 1127 | goto err_dev_remv; |
1130 | 1128 | ||
@@ -1185,7 +1183,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, | |||
1185 | if (ret) | 1183 | if (ret) |
1186 | goto err_dev_remv; | 1184 | goto err_dev_remv; |
1187 | 1185 | ||
1188 | rndis_filter_query_device_link_status(rndis_device); | 1186 | rndis_filter_query_device_link_status(rndis_device, net_device); |
1189 | 1187 | ||
1190 | netdev_dbg(net, "Device MAC %pM link state %s\n", | 1188 | netdev_dbg(net, "Device MAC %pM link state %s\n", |
1191 | rndis_device->hw_mac_adr, | 1189 | rndis_device->hw_mac_adr, |
@@ -1194,11 +1192,11 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, | |||
1194 | if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) | 1192 | if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) |
1195 | return net_device; | 1193 | return net_device; |
1196 | 1194 | ||
1197 | rndis_filter_query_link_speed(rndis_device); | 1195 | rndis_filter_query_link_speed(rndis_device, net_device); |
1198 | 1196 | ||
1199 | /* vRSS setup */ | 1197 | /* vRSS setup */ |
1200 | memset(&rsscap, 0, rsscap_size); | 1198 | memset(&rsscap, 0, rsscap_size); |
1201 | ret = rndis_filter_query_device(rndis_device, | 1199 | ret = rndis_filter_query_device(rndis_device, net_device, |
1202 | OID_GEN_RECEIVE_SCALE_CAPABILITIES, | 1200 | OID_GEN_RECEIVE_SCALE_CAPABILITIES, |
1203 | &rsscap, &rsscap_size); | 1201 | &rsscap, &rsscap_size); |
1204 | if (ret || rsscap.num_recv_que < 2) | 1202 | if (ret || rsscap.num_recv_que < 2) |