blob: 79b9c194623270845e7ad7d31bd07510334f72b9 [file] [log] [blame]
/* Copyright 2014 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* USB endpoints/interfaces callbacks declaration
*/
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "usb_hw.h"
#include <stddef.h>
#include <stdint.h>
typedef void (*xfer_func)(void);
typedef void (*evt_func)(enum usb_ep_event evt);
#if defined(CHIP_FAMILY_STM32F4)
#define iface_arguments struct usb_setup_packet *req
#else
#define iface_arguments usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx
#endif
typedef int (*iface_func)(iface_arguments);
#ifndef PASS
#define PASS 1
#endif
#if PASS == 1
void ep_undefined(void)
{
return;
}
void ep_evt_undefined(enum usb_ep_event evt)
{
return;
}
/* Undefined interface callbacks fail by returning non-zero*/
int iface_undefined(iface_arguments)
{
return 1;
}
#define table(type, name, x) x
#define endpoint_tx(number) \
extern void __attribute__(( \
used, weak, alias("ep_undefined"))) ep_##number##_tx(void);
#define endpoint_rx(number) \
extern void __attribute__(( \
used, weak, alias("ep_undefined"))) ep_##number##_rx(void);
#define endpoint_evt(number) \
extern void __attribute__((used, weak, alias("ep_evt_undefined"))) \
ep_##number##_evt(enum usb_ep_event evt);
#define interface(number) \
extern int __attribute__((used, weak, alias("iface_undefined"))) \
iface_##number##_request(iface_arguments);
#define null
#endif /* PASS 1 */
#if PASS == 2
#undef table
#undef endpoint_tx
#undef endpoint_rx
#undef endpoint_evt
#undef interface
#undef null
/* Disable warning that "initializer overrides prior initialization of this
* subobject", since we are explicitly doing this to handle the unused
* endpoints.
*/
DISABLE_CLANG_WARNING("-Winitializer-overrides")
/* align function pointers on a 32-bit boundary */
#define table(type, name, x) \
type name[] __attribute__((aligned(4), section(".rodata.usb_ep." #name \
",\"a\" @"))) = { x };
#define null (void *)0
#define ep_(num, suf) CONCAT3(ep_, num, suf)
#define ep(num, suf) ep_(num, suf)
#define endpoint_tx(number) \
[number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_##number##_tx,
#define endpoint_rx(number) \
[number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_##number##_rx,
#define endpoint_evt(number) \
[number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_##number##_evt,
#define interface(number) \
[number < USB_IFACE_COUNT ? number : USB_IFACE_COUNT - 1] = \
iface_##number##_request,
#endif /* PASS 2 */
/*
* The initializers are listed backwards, but that's so that the items beyond
* the chip's limit are first assigned to the last field, then overwritten by
* its actual value due to the designated initializers in the macros above.
* It all sorts out nicely
*/
table(xfer_func, usb_ep_tx,
endpoint_tx(15) endpoint_tx(14) endpoint_tx(13) endpoint_tx(12)
endpoint_tx(11) endpoint_tx(10) endpoint_tx(9) endpoint_tx(8)
endpoint_tx(7) endpoint_tx(6) endpoint_tx(5)
endpoint_tx(4) endpoint_tx(3) endpoint_tx(2)
endpoint_tx(1) endpoint_tx(0))
table(xfer_func, usb_ep_rx,
endpoint_rx(15) endpoint_rx(14) endpoint_rx(13) endpoint_rx(12)
endpoint_rx(11) endpoint_rx(10) endpoint_rx(9)
endpoint_rx(8) endpoint_rx(7) endpoint_rx(6)
endpoint_rx(5) endpoint_rx(4)
endpoint_rx(3) endpoint_rx(2)
endpoint_rx(1)
endpoint_rx(0))
table(evt_func, usb_ep_event,
endpoint_evt(15) endpoint_evt(14) endpoint_evt(
13) endpoint_evt(12) endpoint_evt(11)
endpoint_evt(10) endpoint_evt(9) endpoint_evt(
8) endpoint_evt(7) endpoint_evt(6)
endpoint_evt(5) endpoint_evt(4)
endpoint_evt(3) endpoint_evt(2)
endpoint_evt(1)
endpoint_evt(0))
#if USB_IFACE_COUNT > 0
table(iface_func, usb_iface_request,
interface(7) interface(6) interface(5)
interface(4) interface(3) interface(2)
interface(1) interface(0))
#endif
#if PASS == 2
ENABLE_CLANG_WARNING("-Winitializer-overrides")
#endif
#if PASS == 1
#undef PASS
#define PASS 2
#include "usb_endpoints.c"
#endif