Skip to content

Commit 9d9d377

Browse files
anobliAlex Elder
authored andcommitted
greybus: es2: Add a new bulk in endpoint for APBridgeA RPC
Add a new bulk in endpoint in order to get RPC status from APbridgeA without to have to poll on control endpoint. So the new endpoint layout is: EP0: control EP EP1 and EP2: muxed endpoints (bulk in and out) EP3 to EP14: direct muxed endpoints (bulk in and out) EP15: ARPC bulk in endpoint Note: This patch is allocating ARPC URBs but does nothing with them. The following patch will use them. Testing Done: Tested with an APBridgeA enumerating 16 endpoints. Kernel doesn't print Not enough endpoints found in device, aborting! Signed-off-by: Alexandre Bailon <[email protected]> Reviewed-by: Johan Hovold <[email protected]> Signed-off-by: Alex Elder <[email protected]>
1 parent 576bffb commit 9d9d377

File tree

1 file changed

+136
-4
lines changed
  • drivers/staging/greybus

1 file changed

+136
-4
lines changed

drivers/staging/greybus/es2.c

Lines changed: 136 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
/* Memory sizes for the buffers sent to/from the ES2 controller */
2626
#define ES2_GBUF_MSG_SIZE_MAX 2048
2727

28+
/* Memory sizes for the ARPC buffers */
29+
#define ARPC_IN_SIZE_MAX 128
30+
2831
static const struct usb_device_id id_table[] = {
2932
{ USB_DEVICE(0x18d1, 0x1eaf) },
3033
{ },
@@ -36,6 +39,12 @@ MODULE_DEVICE_TABLE(usb, id_table);
3639
/* Number of bulk in and bulk out couple */
3740
#define NUM_BULKS 7
3841

42+
/* Expected number of bulk out endpoints */
43+
#define NUM_BULKS_OUT NUM_BULKS
44+
45+
/* Expected number of bulk in endpoints (including ARPC endpoint) */
46+
#define NUM_BULKS_IN (NUM_BULKS + 1)
47+
3948
/*
4049
* Number of CPort IN urbs in flight at any point in time.
4150
* Adjust if we are having stalls in the USB buffer due to not enough urbs in
@@ -48,6 +57,11 @@ MODULE_DEVICE_TABLE(usb, id_table);
4857
*/
4958
#define NUM_CPORT_OUT_URB (8 * NUM_BULKS)
5059

60+
/*
61+
* Number of ARPC in urbs in flight at any point in time.
62+
*/
63+
#define NUM_ARPC_IN_URB 2
64+
5165
/*
5266
* @endpoint: bulk in endpoint for CPort data
5367
* @urb: array of urbs for the CPort in messages
@@ -85,6 +99,9 @@ struct es2_cport_out {
8599
* @apb_log_dentry: file system entry for the log file interface
86100
* @apb_log_enable_dentry: file system entry for enabling logging
87101
* @apb_log_fifo: kernel FIFO to carry logged data
102+
* @arpc_urb: array of urbs for the ARPC in messages
103+
* @arpc_buffer: array of buffers for the @arpc_urb urbs
104+
* @arpc_endpoint_in: bulk in endpoint for APBridgeA RPC
88105
*/
89106
struct es2_ap_dev {
90107
struct usb_device *usb_dev;
@@ -106,6 +123,10 @@ struct es2_ap_dev {
106123
struct dentry *apb_log_dentry;
107124
struct dentry *apb_log_enable_dentry;
108125
DECLARE_KFIFO(apb_log_fifo, char, APB1_LOG_SIZE);
126+
127+
__u8 arpc_endpoint_in;
128+
struct urb *arpc_urb[NUM_ARPC_IN_URB];
129+
u8 *arpc_buffer[NUM_ARPC_IN_URB];
109130
};
110131

111132
/**
@@ -344,6 +365,45 @@ static void es2_cport_in_disable(struct es2_ap_dev *es2,
344365
}
345366
}
346367

368+
static int es2_arpc_in_enable(struct es2_ap_dev *es2)
369+
{
370+
struct urb *urb;
371+
int ret;
372+
int i;
373+
374+
for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
375+
urb = es2->arpc_urb[i];
376+
377+
ret = usb_submit_urb(urb, GFP_KERNEL);
378+
if (ret) {
379+
dev_err(&es2->usb_dev->dev,
380+
"failed to submit arpc in-urb: %d\n", ret);
381+
goto err_kill_urbs;
382+
}
383+
}
384+
385+
return 0;
386+
387+
err_kill_urbs:
388+
for (--i; i >= 0; --i) {
389+
urb = es2->arpc_urb[i];
390+
usb_kill_urb(urb);
391+
}
392+
393+
return ret;
394+
}
395+
396+
static void es2_arpc_in_disable(struct es2_ap_dev *es2)
397+
{
398+
struct urb *urb;
399+
int i;
400+
401+
for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
402+
urb = es2->arpc_urb[i];
403+
usb_kill_urb(urb);
404+
}
405+
}
406+
347407
static struct urb *next_free_urb(struct es2_ap_dev *es2, gfp_t gfp_mask)
348408
{
349409
struct urb *urb = NULL;
@@ -899,6 +959,16 @@ static void es2_destroy(struct es2_ap_dev *es2)
899959
es2->cport_out_urb_busy[i] = false; /* just to be anal */
900960
}
901961

962+
for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
963+
struct urb *urb = es2->arpc_urb[i];
964+
965+
if (!urb)
966+
break;
967+
usb_free_urb(urb);
968+
kfree(es2->arpc_buffer[i]);
969+
es2->arpc_buffer[i] = NULL;
970+
}
971+
902972
for (bulk_in = 0; bulk_in < NUM_BULKS; bulk_in++) {
903973
struct es2_cport_in *cport_in = &es2->cport_in[bulk_in];
904974

@@ -991,6 +1061,31 @@ static void cport_out_callback(struct urb *urb)
9911061
free_urb(es2, urb);
9921062
}
9931063

1064+
static void arpc_in_callback(struct urb *urb)
1065+
{
1066+
struct device *dev = &urb->dev->dev;
1067+
int status = check_urb_status(urb);
1068+
int retval;
1069+
1070+
if (status) {
1071+
if ((status == -EAGAIN) || (status == -EPROTO))
1072+
goto exit;
1073+
1074+
/* The urb is being unlinked */
1075+
if (status == -ENOENT || status == -ESHUTDOWN)
1076+
return;
1077+
1078+
dev_err(dev, "arpc in-urb error %d (dropped)\n", status);
1079+
return;
1080+
}
1081+
1082+
exit:
1083+
/* put our urb back in the request pool */
1084+
retval = usb_submit_urb(urb, GFP_ATOMIC);
1085+
if (retval)
1086+
dev_err(dev, "failed to resubmit arpc in-urb: %d\n", retval);
1087+
}
1088+
9941089
#define APB1_LOG_MSG_SIZE 64
9951090
static void apb_log_get(struct es2_ap_dev *es2, char *buf)
9961091
{
@@ -1225,8 +1320,13 @@ static int ap_probe(struct usb_interface *interface,
12251320
endpoint = &iface_desc->endpoint[i].desc;
12261321

12271322
if (usb_endpoint_is_bulk_in(endpoint)) {
1228-
es2->cport_in[bulk_in++].endpoint =
1229-
endpoint->bEndpointAddress;
1323+
if (bulk_in < NUM_BULKS)
1324+
es2->cport_in[bulk_in].endpoint =
1325+
endpoint->bEndpointAddress;
1326+
else
1327+
es2->arpc_endpoint_in =
1328+
endpoint->bEndpointAddress;
1329+
bulk_in++;
12301330
} else if (usb_endpoint_is_bulk_out(endpoint)) {
12311331
es2->cport_out[bulk_out++].endpoint =
12321332
endpoint->bEndpointAddress;
@@ -1236,7 +1336,7 @@ static int ap_probe(struct usb_interface *interface,
12361336
endpoint->bEndpointAddress);
12371337
}
12381338
}
1239-
if (bulk_in != NUM_BULKS || bulk_out != NUM_BULKS) {
1339+
if (bulk_in != NUM_BULKS_IN || bulk_out != NUM_BULKS_OUT) {
12401340
dev_err(&udev->dev, "Not enough endpoints found in device, aborting!\n");
12411341
retval = -ENODEV;
12421342
goto error;
@@ -1271,6 +1371,32 @@ static int ap_probe(struct usb_interface *interface,
12711371
}
12721372
}
12731373

1374+
/* Allocate buffers for ARPC in messages */
1375+
for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
1376+
struct urb *urb;
1377+
u8 *buffer;
1378+
1379+
urb = usb_alloc_urb(0, GFP_KERNEL);
1380+
if (!urb) {
1381+
retval = -ENOMEM;
1382+
goto error;
1383+
}
1384+
buffer = kmalloc(ARPC_IN_SIZE_MAX, GFP_KERNEL);
1385+
if (!buffer) {
1386+
retval = -ENOMEM;
1387+
goto error;
1388+
}
1389+
1390+
usb_fill_bulk_urb(urb, udev,
1391+
usb_rcvbulkpipe(udev,
1392+
es2->arpc_endpoint_in),
1393+
buffer, ARPC_IN_SIZE_MAX,
1394+
arpc_in_callback, es2);
1395+
1396+
es2->arpc_urb[i] = urb;
1397+
es2->arpc_buffer[i] = buffer;
1398+
}
1399+
12741400
/* Allocate urbs for our CPort OUT messages */
12751401
for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
12761402
struct urb *urb;
@@ -1291,9 +1417,12 @@ static int ap_probe(struct usb_interface *interface,
12911417
gb_debugfs_get(), es2,
12921418
&apb_log_enable_fops);
12931419

1420+
if (es2_arpc_in_enable(es2))
1421+
goto error;
1422+
12941423
retval = gb_hd_add(hd);
12951424
if (retval)
1296-
goto error;
1425+
goto err_disable_arpc_in;
12971426

12981427
for (i = 0; i < NUM_BULKS; ++i) {
12991428
retval = es2_cport_in_enable(es2, &es2->cport_in[i]);
@@ -1307,6 +1436,8 @@ static int ap_probe(struct usb_interface *interface,
13071436
for (--i; i >= 0; --i)
13081437
es2_cport_in_disable(es2, &es2->cport_in[i]);
13091438
gb_hd_del(hd);
1439+
err_disable_arpc_in:
1440+
es2_arpc_in_disable(es2);
13101441
error:
13111442
es2_destroy(es2);
13121443

@@ -1322,6 +1453,7 @@ static void ap_disconnect(struct usb_interface *interface)
13221453

13231454
for (i = 0; i < NUM_BULKS; ++i)
13241455
es2_cport_in_disable(es2, &es2->cport_in[i]);
1456+
es2_arpc_in_disable(es2);
13251457

13261458
es2_destroy(es2);
13271459
}

0 commit comments

Comments
 (0)