You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2021/03/25 13:46:19 UTC
[incubator-nuttx] 03/03: Revert "USBDEV RNDIS: Fix occasional
disconnections due to race condition"
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch revert-3163-dev_rndis
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 77f040459a0fb46f0df3a953f18bf319c38b59d9
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Thu Mar 25 22:45:59 2021 +0900
Revert "USBDEV RNDIS: Fix occasional disconnections due to race condition"
This reverts commit 4f66624ea34b5107883d2c787bba6e5611373000.
---
drivers/usbdev/rndis.c | 93 +++++++++++++++++++-------------------------------
1 file changed, 35 insertions(+), 58 deletions(-)
diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c
index 53e031d..deb8165 100644
--- a/drivers/usbdev/rndis.c
+++ b/drivers/usbdev/rndis.c
@@ -97,8 +97,7 @@
#define RNDIS_MXDESCLEN (128)
#define RNDIS_MAXSTRLEN (RNDIS_MXDESCLEN-2)
-#define RNDIS_CTRLREQ_LEN (256)
-#define RNDIS_RESP_QUEUE_LEN (256)
+#define RNDIS_CTRLREQ_LEN (512)
#define RNDIS_BUFFER_SIZE CONFIG_NET_ETH_PKTSIZE
#define RNDIS_BUFFER_COUNT 4
@@ -168,14 +167,12 @@ struct rndis_dev_s
size_t current_rx_msglen; /* Length of the entire message to be received */
bool rdreq_submitted; /* Indicates if the read request is submitted */
bool rx_blocked; /* Indicates if we can receive packets on bulk in endpoint */
+ bool ctrlreq_has_encap_response; /* Indicates if ctrlreq buffer holds a response */
bool connected; /* Connection status indicator */
uint32_t rndis_packet_filter; /* RNDIS packet filter value */
uint32_t rndis_host_tx_count; /* TX packet counter */
uint32_t rndis_host_rx_count; /* RX packet counter */
uint8_t host_mac_address[6]; /* Host side MAC address */
-
- uint8_t response_queue[RNDIS_RESP_QUEUE_LEN];
- size_t response_queue_bytes; /* Count of bytes waiting in response_queue. */
};
/* The internal version of the class driver */
@@ -1350,28 +1347,26 @@ static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
* Input Parameters:
* priv: pointer to RNDIS device driver structure
*
- * Returns:
- * pointer to response buffer
- *
* Assumptions:
* Called from critical section
*
****************************************************************************/
-static FAR void*
+static bool
rndis_prepare_response(FAR struct rndis_dev_s *priv, size_t size,
FAR struct rndis_command_header *request_hdr)
{
- uint8_t *buf = priv->response_queue + priv->response_queue_bytes;
FAR struct rndis_response_header *hdr =
- (FAR struct rndis_response_header *)buf;
+ (FAR struct rndis_response_header *)priv->ctrlreq->buf;
hdr->msgtype = request_hdr->msgtype | RNDIS_MSG_COMPLETE;
hdr->msglen = size;
hdr->reqid = request_hdr->reqid;
hdr->status = RNDIS_STATUS_SUCCESS;
- return hdr;
+ priv->ctrlreq_has_encap_response = true;
+
+ return true;
}
/****************************************************************************
@@ -1389,16 +1384,11 @@ rndis_prepare_response(FAR struct rndis_dev_s *priv, size_t size,
*
****************************************************************************/
-static int rndis_send_encapsulated_response(FAR struct rndis_dev_s *priv, size_t size)
+static int rndis_send_encapsulated_response(FAR struct rndis_dev_s *priv)
{
FAR struct rndis_notification *notif =
(FAR struct rndis_notification *)priv->epintin_req->buf;
- /* Mark the response as available in the queue */
- priv->response_queue_bytes += size;
- DEBUGASSERT(priv->response_queue_bytes <= RNDIS_RESP_QUEUE_LEN);
-
- /* Send notification on IRQ endpoint, to tell host to read the data. */
notif->notification = RNDIS_NOTIFICATION_RESPONSE_AVAILABLE;
notif->reserved = 0;
priv->epintin_req->len = sizeof(struct rndis_notification);
@@ -1436,9 +1426,9 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
{
FAR struct rndis_initialize_cmplt *resp;
- resp = rndis_prepare_response(priv,
- sizeof(struct rndis_initialize_cmplt),
- cmd_hdr);
+ rndis_prepare_response(priv, sizeof(struct rndis_initialize_cmplt),
+ cmd_hdr);
+ resp = (FAR struct rndis_initialize_cmplt *)priv->ctrlreq->buf;
resp->major = RNDIS_MAJOR_VERSION;
resp->minor = RNDIS_MINOR_VERSION;
@@ -1448,7 +1438,7 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
resp->xfrsize = (4 + 44 + 22) + RNDIS_BUFFER_SIZE;
resp->pktalign = 2;
- rndis_send_encapsulated_response(priv, resp->hdr.msglen);
+ rndis_send_encapsulated_response(priv);
}
break;
@@ -1463,11 +1453,11 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
int i;
size_t max_reply_size = sizeof(struct rndis_query_cmplt) +
sizeof(g_rndis_supported_oids);
- FAR struct rndis_query_cmplt *resp;
+ rndis_prepare_response(priv, max_reply_size, cmd_hdr);
FAR struct rndis_query_msg *req =
(FAR struct rndis_query_msg *)dataout;
-
- resp = rndis_prepare_response(priv, max_reply_size, cmd_hdr);
+ FAR struct rndis_query_cmplt *resp =
+ (FAR struct rndis_query_cmplt *)priv->ctrlreq->buf;
resp->hdr.msglen = sizeof(struct rndis_query_cmplt);
resp->bufoffset = 0;
@@ -1542,7 +1532,7 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
resp->hdr.msglen += resp->buflen;
- rndis_send_encapsulated_response(priv, resp->hdr.msglen);
+ rndis_send_encapsulated_response(priv);
}
break;
@@ -1551,9 +1541,10 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
FAR struct rndis_set_msg *req;
FAR struct rndis_response_header *resp;
- resp = rndis_prepare_response(priv, sizeof(struct rndis_response_header),
- cmd_hdr);
+ rndis_prepare_response(priv, sizeof(struct rndis_response_header),
+ cmd_hdr);
req = (FAR struct rndis_set_msg *)dataout;
+ resp = (FAR struct rndis_response_header *)priv->ctrlreq->buf;
uinfo("RNDIS SET RID=%08x OID=%08x LEN=%d DAT=%08x",
(unsigned)req->hdr.reqid, (unsigned)req->objid,
@@ -1583,7 +1574,7 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
resp->status = RNDIS_STATUS_NOT_SUPPORTED;
}
- rndis_send_encapsulated_response(priv, resp->msglen);
+ rndis_send_encapsulated_response(priv);
}
break;
@@ -1591,11 +1582,12 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
{
FAR struct rndis_reset_cmplt *resp;
- resp = rndis_prepare_response(priv, sizeof(struct rndis_reset_cmplt),
- cmd_hdr);
+ rndis_prepare_response(priv, sizeof(struct rndis_reset_cmplt),
+ cmd_hdr);
+ resp = (FAR struct rndis_reset_cmplt *)priv->ctrlreq->buf;
resp->addreset = 0;
priv->connected = false;
- rndis_send_encapsulated_response(priv, resp->hdr.msglen);
+ rndis_send_encapsulated_response(priv);
}
break;
@@ -1603,7 +1595,7 @@ static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
{
rndis_prepare_response(priv, sizeof(struct rndis_response_header),
cmd_hdr);
- rndis_send_encapsulated_response(priv, sizeof(struct rndis_response_header));
+ rndis_send_encapsulated_response(priv);
}
break;
@@ -1746,27 +1738,15 @@ static void rndis_wrcomplete(FAR struct usbdev_ep_s *ep,
static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep,
FAR struct usbdev_req_s *req)
{
- struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)ep->priv;
if (req->result || req->xfrd != req->len)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_REQRESULT),
(uint16_t)-req->result);
}
- else if (req->len > 0 && req->priv == priv->response_queue)
+ else if (req->len > 0)
{
- /* This transfer was from the response queue, subtract remaining byte count. */
- req->priv = 0;
- if (req->len >= priv->response_queue_bytes)
- {
- /* Queue now empty */
- priv->response_queue_bytes = 0;
- }
- else
- {
- /* Copy the remaining responses to beginning of buffer. */
- priv->response_queue_bytes -= req->len;
- memcpy(priv->response_queue, priv->response_queue + req->len, priv->response_queue_bytes);
- }
+ struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)ep->priv;
+ priv->ctrlreq_has_encap_response = false;
}
}
@@ -2214,9 +2194,6 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
leave_critical_section(flags);
}
- /* Initialize response queue to empty */
- priv->response_queue_bytes = 0;
-
/* Report if we are selfpowered */
#ifndef CONFIG_RNDIS_COMPOSITE
@@ -2395,7 +2372,6 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
}
#endif
ctrlreq = priv->ctrlreq;
- ctrlreq->priv = 0;
/* Extract the little-endian 16-bit values to host order */
@@ -2498,19 +2474,20 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
}
else if (ctrl->req == RNDIS_GET_ENCAPSULATED_RESPONSE)
{
- if (priv->response_queue_bytes == 0)
+ if (!priv->ctrlreq_has_encap_response)
{
- /* No reply available is indicated with a single 0x00 byte. */
ret = 1;
ctrlreq->buf[0] = 0;
}
else
{
- /* Retrieve a single reply from the response queue to control request buffer. */
+ /* There is data prepared in the ctrlreq buffer.
+ * Just assign the length.
+ */
+
FAR struct rndis_response_header *hdr =
- (struct rndis_response_header *)priv->response_queue;
- memcpy(ctrlreq->buf, hdr, hdr->msglen);
- ctrlreq->priv = priv->response_queue;
+ (struct rndis_response_header *)ctrlreq->buf;
+
ret = hdr->msglen;
}
}