summaryrefslogtreecommitdiffstats
path: root/usb/endpt0.c
diff options
context:
space:
mode:
Diffstat (limited to 'usb/endpt0.c')
-rw-r--r--usb/endpt0.c82
1 files changed, 15 insertions, 67 deletions
diff --git a/usb/endpt0.c b/usb/endpt0.c
index 57c994e..b3e195b 100644
--- a/usb/endpt0.c
+++ b/usb/endpt0.c
@@ -28,18 +28,16 @@
#include "bdt.h"
#include "endpt0.h"
#include "endpt1.h"
+#include "txhandler.h"
#include "descriptors.h"
#define MAX_PACKET 64
static unsigned char buf[2][MAX_PACKET];
-static bool tx_odd;
-static bool tx_data01;
static volatile unsigned int nextaddr;
-static void *tx_data;
-static size_t tx_size;
+static struct tx_ctx tx;
struct tok_setup {
uint8_t reqtyp;
@@ -61,56 +59,6 @@ static void read_setup(struct tok_setup *setup, const void *_data)
setup->length = le16toh(&data[6]);
}
-/* TODO: Make this a shared thing across all USB endpoints */
-
-/* puttx: place data in the current buffer descriptor */
-static bool puttx(void *data, size_t size)
-{
- if (GET_BIT(usb_bdt[0][BDT_TX][tx_odd].desc, BD_OWN))
- return false;
-
- /* TODO: Just stop bothering with const */
- usb_bdt[0][BDT_TX][tx_odd].addr = data;
- usb_bdt[0][BDT_TX][tx_odd].desc = USB0_BD_INIT(size, tx_data01);
- tx_odd = !tx_odd;
- tx_data01 = !tx_data01;
-
- return true;
-}
-
-/* pushtx: attempt to push rest of the current transmission into a BD */
-static bool pushtx(void)
-{
- size_t size = tx_size;
-
- if (tx_data == NULL)
- return false;
-
- if (size > MAX_PACKET)
- size = MAX_PACKET;
-
- if (!puttx(tx_data, size))
- return false;
-
- tx_data = (char *)tx_data + size;
- tx_size -= size;
-
- if (tx_size == 0 && size < MAX_PACKET)
- tx_data = NULL;
-
- return true;
-}
-
-/* quetx: enqueue a transmission */
-static void quetx(void *data, size_t size)
-{
- tx_data = data;
- tx_size = size;
-
- while (pushtx())
- ;
-}
-
/* usb_endpt0_disable: Disable endpoint 0 (not valid) */
void usb_endpt0_disable(void)
{
@@ -133,9 +81,7 @@ void usb_endpt0_enable(void)
USB0_ENDPT(0) = BV(ENDPT_EPRXEN) | BV(ENDPT_EPTXEN) | BV(ENDPT_EPHSHK);
nextaddr = 0;
- tx_data = NULL;
- tx_odd = 0;
- tx_data01 = 0;
+ tx = TX_CTX(usb_bdt[0][BDT_TX], MAX_PACKET);
}
/* trunc: truncate size_t to a limit TODO: MOVE THIS */
@@ -152,32 +98,32 @@ static void tok_setup(struct tok_setup *setup)
switch (setup->reqtyp << 8 | setup->req) {
case 0x0005: /* SET ADDRESS */
nextaddr = setup->value;
- puttx(NULL, 0);
+ tx_que(&tx, NULL, 0);
break;
case 0x0009: /* SET CONFIGURATION */
usb_endpt1_enable();
- puttx(NULL, 0);
+ tx_que(&tx, NULL, 0);
break;
case 0x210a: /* SET IDLE */
- puttx(NULL, 0);
+ tx_que(&tx, NULL, 0);
break;
case 0x8106: /* GET INTERFACE */
case 0x8006: /* GET DESCRIPTOR */
switch (setup->value) {
case 0x0100: /* DEVICE */
- quetx(ds_dev, trunc(ARRLEN(ds_dev), setup->length));
+ tx_que(&tx, ds_dev, trunc(ARRLEN(ds_dev), setup->length));
return;
case 0x0200: /* CONFIGURATION */
- quetx(ds_conf, trunc(ARRLEN(ds_conf), setup->length));
+ tx_que(&tx, ds_conf, trunc(ARRLEN(ds_conf), setup->length));
return;
case 0x0300: /* STRING 0 */
- quetx(ds_lang, trunc(ARRLEN(ds_lang), setup->length));
+ tx_que(&tx, ds_lang, trunc(ARRLEN(ds_lang), setup->length));
return;
case 0x0301: /* STRING 1 */
- quetx(ds_str1, trunc(ARRLEN(ds_str1), setup->length));
+ tx_que(&tx, ds_str1, trunc(ARRLEN(ds_str1), setup->length));
return;
case 0x2200:
- quetx(ds_hidrep, trunc(ARRLEN(ds_hidrep), setup->length));
+ tx_que(&tx, ds_hidrep, trunc(ARRLEN(ds_hidrep), setup->length));
return;
}
/* fall through */
@@ -200,6 +146,7 @@ void usb_endpt0_token(uint8_t state)
bd->desc = USB0_BD_INIT(sizeof buf[0], 1);
break;
case BD_TOK_PID_IN:
+ tx_push(&tx);
if (nextaddr) {
USB0_ADDR = nextaddr;
nextaddr = 0;
@@ -209,11 +156,12 @@ void usb_endpt0_token(uint8_t state)
read_setup(&setup, bd->addr);
bd->desc = USB0_BD_INIT(sizeof buf[0], 1);
+ /* This is a bit of a dodgy thing to do */
usb_bdt[0][BDT_TX][BDT_EVEN].desc = 0;
usb_bdt[0][BDT_TX][BDT_ODD].desc = 0;
- tx_data = NULL;
+ tx.data = NULL;
- tx_data01 = 1;
+ tx.data01 = 1;
tok_setup(&setup);