コード例 #1
0
ファイル: usb-v1.c プロジェクト: swetland/m3dev
void usb_handle_irq(void) {
	unsigned n;

	USB_IRQ_COUNT++;

//	P("usb %x\n", USB_IRQ_COUNT);

	n = readl(USB_INT_STATUS);
	//writel(n & (USB_INT_EP0 | USB_INT_EP1), USB_INT_CLEAR);
	writel(n, USB_INT_CLEAR);
	if (n & USB_INT_FRAME)
		msec_counter++;
	if (n & USB_INT_EP0)
		usb_ep0_rx();
	if (n & USB_INT_EP1)
		usb_ep0_tx();

	/* ignore masked interrupts */
	n &= readl(USB_INT_ENABLE);

	if (n & ~(USB_INT_FRAME)) {
//		P("usb n 0x%x\n", n);
	}

	if ((n & USB_INT_EP2) && usb_ep1_rx_full_cb)
		usb_ep1_rx_full_cb();
	if ((n & USB_INT_EP3) && usb_ep1_tx_empty_cb)
		usb_ep1_tx_empty_cb();
#if CONFIG_USB_2ND_IFC
	if ((n & USB_INT_EP4) && usb_ep2_rx_full_cb)
		usb_ep2_rx_full_cb();
	if ((n & USB_INT_EP5) && usb_ep2_tx_empty_cb)
		usb_ep2_tx_empty_cb();
#endif
}
コード例 #2
0
ファイル: usb.c プロジェクト: koson/mchck-os
static int
usb_tx_config_desc(int idx, int reqlen)
{
	const struct usb_desc_config_t *d = usb.identity->configs[idx]->desc;

	usb_ep0_tx(d, d->wTotalLength, reqlen, NULL, NULL);
	return (0);
}
コード例 #3
0
ファイル: hid.c プロジェクト: AM7000000/mchck
void
hid_update_data(struct hid_ctx *ctx, uint8_t report_id, const void *data, size_t len)
{
    if (ctx->get_report_outstanding_length != 0) {
        usb_ep0_tx(data, len, ctx->get_report_outstanding_length, NULL, NULL);
        ctx->get_report_outstanding_length = 0;
        usb_handle_control_status(0);
    } else if (ctx->hidf->report_max_size > 0)  {
        usb_tx(ctx->tx_pipe, data, len, ctx->hidf->report_max_size, NULL, NULL);
    }
}
コード例 #4
0
ファイル: wcid.c プロジェクト: corecode/mchck-os
int
wcid_handle_control(const struct usbd_global *f, struct usb_ctrl_req_t *req)
{
        const struct wcid_function *wcid = (const void *)f;

        if (req->bRequest != WCID_REQ_ID)
                return (0);

        size_t pos, len;
        const struct wcid_generic_header *desc;

        switch (req->wIndex) {
        case WCID_DESC_COMPAT_OS:
                desc = wcid->compat_id;
                break;

        case WCID_DESC_EXTENDED_PROP: {
                static const struct wcid_extended_prop_header ex_prop = {
                        .dwLength = sizeof(ex_prop),
                        .bcdVersion = { .raw = 0x0100 },
                        .wIndex = WCID_DESC_EXTENDED_PROP,
                        .wCount = 0,
                };

                desc = &ex_prop;
                break;
        }

        default:
                return (0);
        }

        pos = (req->wValue & 0xff00) << 8;
        len = req->wLength;
        if (pos > desc->dwLength)
                return (0);
        if (pos + len > desc->dwLength)
                len = desc->dwLength - pos;
        usb_ep0_tx((uint8_t *)desc + pos, len, req->wLength, NULL, NULL);
        usb_handle_control_status(0);
        return (1);
}
コード例 #5
0
ファイル: usb.c プロジェクト: koson/mchck-os
static int
usb_tx_string_desc(int idx, int reqlen)
{
	const struct usbd_string_entry *d;

	for (d = usb.identity->string_descs; d->string != NULL; ++d)
		if (d->index == idx)
			break;
	if (!d->string)
		return (-1);

	switch ((uintptr_t)d->string) {
	case (uintptr_t)NULL:
		return (-1);
	case (uintptr_t)USB_DESC_STRING_SERIALNO:
		return (usb_tx_serialno(reqlen));
	default:
		usb_ep0_tx(d->string, d->string->bLength, reqlen, NULL, NULL);
		return (0);
	}
}
コード例 #6
0
ファイル: usb.c プロジェクト: koson/mchck-os
static void
usb_handle_control(void *data, ssize_t len, void *cbdata)
{
	struct usb_ctrl_req_t *req = data;
	uint16_t zero16 = 0;
	int fail = 1;

	usb.ctrl_dir = req->in;

	/**
	 * Pass control to our handlers for non standard
	 * or non device (interface/class/other) requests.
	 */
	if (req->type != USB_CTRL_REQ_STD || req->recp != USB_CTRL_REQ_DEV) {
		if (usb_handle_control_nonstddev(req) != 0)
			return;
	}

	/* Only STD requests here */
	switch (req->bRequest) {
	case USB_CTRL_REQ_GET_STATUS:
		/**
		 * Because we don't support remote wakeup or
		 * self-powered operation, and we are specialized to
		 * only EP 0 so far, all GET_STATUS replies are just
		 * empty.
		 */
		usb_ep0_tx_cp(&zero16, sizeof(zero16), req->wLength, NULL, NULL);
		break;

	case USB_CTRL_REQ_CLEAR_FEATURE:
	case USB_CTRL_REQ_SET_FEATURE:
		/**
		 * Nothing to do.  Maybe return STALLs on illegal
		 * accesses?
		 */
		break;

	case USB_CTRL_REQ_SET_ADDRESS:
		/**
		 * We must keep our previous address until the end of
		 * the status stage;  therefore we can't set the
		 * address right now.  Since this is a special case,
		 * the EP 0 handler will take care of this later on.
		 */
		usb.address = req->wValue & 0x7f;
		usb.state = USBD_STATE_SETTING_ADDRESS;
		break;

	case USB_CTRL_REQ_GET_DESCRIPTOR:
		switch (req->wValue >> 8) {
		case USB_DESC_DEV:
			usb_ep0_tx(usb.identity->dev_desc, usb.identity->dev_desc->bLength,
				      req->wLength, NULL, NULL);
			fail = 0;
			break;
		case USB_DESC_CONFIG:
			fail = usb_tx_config_desc(req->wValue & 0xff, req->wLength);
			break;
		case USB_DESC_STRING:
			fail = usb_tx_string_desc(req->wValue & 0xff, req->wLength);
			break;
		default:
			fail = -1;
			break;
		}
		/* we set fail already, so we can go directly to `err' */
		goto err;

	case USB_CTRL_REQ_GET_CONFIGURATION:
		usb_ep0_tx(&usb.config, 1, req->wLength, NULL, NULL); /* XXX implicit LE */
		break;

	case USB_CTRL_REQ_SET_CONFIGURATION:
		if (usb_set_config(req->wValue) < 0)
			goto err;
		break;

	default:
		goto err;
	}

	fail = 0;

err:
	usb_handle_control_status(fail);
}