Commit a73e99cb authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Greg Kroah-Hartman

staging: ozwpan: Remove from tree

Ozwpan is completely unmaintained and potentially a security problem. As
this is a staging driver, it should be removed, since it has been
abandoned.

Cc: Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f70d6318
......@@ -9734,11 +9734,6 @@ W: http://wiki.laptop.org/go/DCON
S: Maintained
F: drivers/staging/olpc_dcon/
STAGING - OZMO DEVICES USB OVER WIFI DRIVER
M: Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
S: Maintained
F: drivers/staging/ozwpan/
STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
M: Willy Tarreau <willy@meta-x.org>
S: Odd Fixes
......
......@@ -76,8 +76,6 @@ source "drivers/staging/android/Kconfig"
source "drivers/staging/board/Kconfig"
source "drivers/staging/ozwpan/Kconfig"
source "drivers/staging/gdm72xx/Kconfig"
source "drivers/staging/gdm724x/Kconfig"
......
......@@ -31,7 +31,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_STAGING_BOARD) += board/
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
obj-$(CONFIG_LTE_GDM724X) += gdm724x/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
......
config USB_WPAN_HCD
tristate "USB over WiFi Host Controller"
depends on USB && NET
help
A driver for USB Host Controllers that are compatible with
Ozmo Devices USB over WiFi technology.
To compile this driver a module, choose M here: the module
will be called "ozwpan".
# -----------------------------------------------------------------------------
# Copyright (c) 2011 Ozmo Inc
# Released under the GNU General Public License Version 2 (GPLv2).
# -----------------------------------------------------------------------------
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan.o
ozwpan-y := \
ozmain.o \
ozpd.o \
ozusbsvc.o \
ozusbsvc1.o \
ozhcd.o \
ozeltbuf.o \
ozproto.o \
ozcdev.o \
ozurbparanoia.o
OZWPAN USB Host Controller Driver
---------------------------------
This driver is a USB HCD driver that does not have an associated a physical
device but instead uses Wi-Fi to communicate with the wireless peripheral.
The USB requests are converted into a layer 2 network protocol and transmitted
on the network using an ethertype (0x892e) regestered to Ozmo Device Inc.
This driver is compatible with existing wireless devices that use Ozmo Devices
technology.
To operate the driver must be bound to a suitable network interface. This can
be done when the module is loaded (specifying the name of the network interface
as a parameter - e.g. 'insmod ozwpan g_net_dev=go0') or can be bound after
loading using an ioctl call. See the ozappif.h file and the ioctls
OZ_IOCTL_ADD_BINDING and OZ_IOCTL_REMOVE_BINDING.
The devices connect to the host use Wi-Fi Direct so a network card that supports
Wi-Fi direct is required. A recent version (0.8.x or later) version of the
wpa_supplicant can be used to setup the network interface to create a persistent
autonomous group (for older pre-WFD peripherals) or put in a listen state to
allow group negotiation to occur for more recent devices that support WFD.
The protocol used over the network does not directly mimic the USB bus
transactions as this would be rather busy and inefficient. Instead the chapter 9
requests are converted into a request/response pair of messages. (See
ozprotocol.h for data structures used in the protocol).
TODO:
- Convert event tracing code to in-kernel tracing infrastructure
- Check for remaining ioctl & check if that can be converted into
sysfs entries
- Convert debug prints to appropriate dev_debug or something better
- Modify Kconfig to add CONFIG option for enabling/disabling event
tracing.
- check USB HCD implementation is complete and correct.
- code review by USB developer community.
- testing with as many devices as possible.
Please send any patches for this driver to
Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
and Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZAPPIF_H
#define _OZAPPIF_H
#define OZ_IOCTL_MAGIC 0xf4
struct oz_mac_addr {
__u8 a[6];
};
#define OZ_MAX_PDS 8
struct oz_pd_list {
__u32 count;
struct oz_mac_addr addr[OZ_MAX_PDS];
};
#define OZ_MAX_BINDING_LEN 32
struct oz_binding_info {
char name[OZ_MAX_BINDING_LEN];
};
#define OZ_IOCTL_GET_PD_LIST _IOR(OZ_IOCTL_MAGIC, 0, struct oz_pd_list)
#define OZ_IOCTL_SET_ACTIVE_PD _IOW(OZ_IOCTL_MAGIC, 1, struct oz_mac_addr)
#define OZ_IOCTL_GET_ACTIVE_PD _IOR(OZ_IOCTL_MAGIC, 2, struct oz_mac_addr)
#define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 3, struct oz_binding_info)
#define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 4, struct oz_binding_info)
#define OZ_IOCTL_MAX 5
#endif /* _OZAPPIF_H */
This diff is collapsed.
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZCDEV_H
#define _OZCDEV_H
int oz_cdev_register(void);
int oz_cdev_deregister(void);
int oz_cdev_init(void);
void oz_cdev_term(void);
int oz_cdev_start(struct oz_pd *pd, int resume);
void oz_cdev_stop(struct oz_pd *pd, int pause);
void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt);
#endif /* _OZCDEV_H */
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* ---------------------------------------------------------------------------*/
#ifndef _OZDBG_H
#define _OZDBG_H
#define OZ_WANT_DBG 0
#define OZ_WANT_VERBOSE_DBG 1
#define OZ_DBG_ON 0x0
#define OZ_DBG_STREAM 0x1
#define OZ_DBG_URB 0x2
#define OZ_DBG_CTRL_DETAIL 0x4
#define OZ_DBG_HUB 0x8
#define OZ_DBG_RX_FRAMES 0x10
#define OZ_DBG_TX_FRAMES 0x20
#define OZ_DEFAULT_DBG_MASK \
( \
/* OZ_DBG_STREAM | */ \
/* OZ_DBG_URB | */ \
/* OZ_DBG_CTRL_DETAIL | */ \
OZ_DBG_HUB | \
/* OZ_DBG_RX_FRAMES | */ \
/* OZ_DBG_TX_FRAMES | */ \
0)
extern unsigned int oz_dbg_mask;
#define oz_want_dbg(mask) \
((OZ_WANT_DBG && (OZ_DBG_##mask == OZ_DBG_ON)) || \
(OZ_WANT_VERBOSE_DBG && (OZ_DBG_##mask & oz_dbg_mask)))
#define oz_dbg(mask, fmt, ...) \
do { \
if (oz_want_dbg(mask)) \
pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
#define oz_cdev_dbg(cdev, mask, fmt, ...) \
do { \
if (oz_want_dbg(mask)) \
netdev_dbg((cdev)->dev, fmt, ##__VA_ARGS__); \
} while (0)
#define oz_pd_dbg(pd, mask, fmt, ...) \
do { \
if (oz_want_dbg(mask)) \
pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
#endif /* _OZDBG_H */
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#include <linux/module.h>
#include <linux/netdevice.h>
#include "ozdbg.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
/*
* Context: softirq-serialized
*/
void oz_elt_buf_init(struct oz_elt_buf *buf)
{
memset(buf, 0, sizeof(struct oz_elt_buf));
INIT_LIST_HEAD(&buf->stream_list);
INIT_LIST_HEAD(&buf->order_list);
INIT_LIST_HEAD(&buf->isoc_list);
spin_lock_init(&buf->lock);
}
/*
* Context: softirq or process
*/
void oz_elt_buf_term(struct oz_elt_buf *buf)
{
struct oz_elt_info *ei, *n;
list_for_each_entry_safe(ei, n, &buf->isoc_list, link_order)
kfree(ei);
list_for_each_entry_safe(ei, n, &buf->order_list, link_order)
kfree(ei);
}
/*
* Context: softirq or process
*/
struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf)
{
struct oz_elt_info *ei;
ei = kmem_cache_zalloc(oz_elt_info_cache, GFP_ATOMIC);
if (ei) {
INIT_LIST_HEAD(&ei->link);
INIT_LIST_HEAD(&ei->link_order);
}
return ei;
}
/*
* Precondition: oz_elt_buf.lock must be held.
* Context: softirq or process
*/
void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei)
{
if (ei)
kmem_cache_free(oz_elt_info_cache, ei);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
void oz_elt_info_free_chain(struct oz_elt_buf *buf, struct list_head *list)
{
struct oz_elt_info *ei, *n;
spin_lock_bh(&buf->lock);
list_for_each_entry_safe(ei, n, list->next, link)
oz_elt_info_free(buf, ei);
spin_unlock_bh(&buf->lock);
}
int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count)
{
struct oz_elt_stream *st;
oz_dbg(ON, "%s: (0x%x)\n", __func__, id);
st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC);
if (st == NULL)
return -ENOMEM;
atomic_set(&st->ref_count, 1);
st->id = id;
st->max_buf_count = max_buf_count;
INIT_LIST_HEAD(&st->elt_list);
spin_lock_bh(&buf->lock);
list_add_tail(&st->link, &buf->stream_list);
spin_unlock_bh(&buf->lock);
return 0;
}
int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id)
{
struct list_head *e, *n;
struct oz_elt_stream *st = NULL;
oz_dbg(ON, "%s: (0x%x)\n", __func__, id);
spin_lock_bh(&buf->lock);
list_for_each(e, &buf->stream_list) {
st = list_entry(e, struct oz_elt_stream, link);
if (st->id == id) {
list_del(e);
break;
}
st = NULL;
}
if (!st) {
spin_unlock_bh(&buf->lock);
return -1;
}
list_for_each_safe(e, n, &st->elt_list) {
struct oz_elt_info *ei =
list_entry(e, struct oz_elt_info, link);
list_del_init(&ei->link);
list_del_init(&ei->link_order);
st->buf_count -= ei->length;
oz_dbg(STREAM, "Stream down: %d %d %d\n",
st->buf_count, ei->length, atomic_read(&st->ref_count));
oz_elt_stream_put(st);
oz_elt_info_free(buf, ei);
}
spin_unlock_bh(&buf->lock);
oz_elt_stream_put(st);
return 0;
}
void oz_elt_stream_get(struct oz_elt_stream *st)
{
atomic_inc(&st->ref_count);
}
void oz_elt_stream_put(struct oz_elt_stream *st)
{
if (atomic_dec_and_test(&st->ref_count)) {
oz_dbg(ON, "Stream destroyed\n");
kfree(st);
}
}
/*
* Precondition: Element buffer lock must be held.
* If this function fails the caller is responsible for deallocating the elt
* info structure.
*/
int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id,
struct oz_elt_info *ei)
{
struct oz_elt_stream *st = NULL;
struct list_head *e;
if (id) {
list_for_each(e, &buf->stream_list) {
st = list_entry(e, struct oz_elt_stream, link);
if (st->id == id)
break;
}
if (e == &buf->stream_list) {
/* Stream specified but stream not known so fail.
* Caller deallocates element info. */
return -1;
}
}
if (st) {
/* If this is an ISOC fixed element that needs a frame number
* then insert that now. Earlier we stored the unit count in
* this field.
*/
struct oz_isoc_fixed *body = (struct oz_isoc_fixed *)
&ei->data[sizeof(struct oz_elt)];
if ((body->app_id == OZ_APPID_USB) && (body->type
== OZ_USB_ENDPOINT_DATA) &&
(body->format == OZ_DATA_F_ISOC_FIXED)) {
u8 unit_count = body->frame_number;
body->frame_number = st->frame_number;
st->frame_number += unit_count;
}
/* Claim stream and update accounts */
oz_elt_stream_get(st);
ei->stream = st;
st->buf_count += ei->length;
/* Add to list in stream. */
list_add_tail(&ei->link, &st->elt_list);
oz_dbg(STREAM, "Stream up: %d %d\n", st->buf_count, ei->length);
/* Check if we have too much buffered for this stream. If so
* start dropping elements until we are back in bounds.
*/
while ((st->buf_count > st->max_buf_count) &&
!list_empty(&st->elt_list)) {
struct oz_elt_info *ei2 =
list_first_entry(&st->elt_list,
struct oz_elt_info, link);
list_del_init(&ei2->link);
list_del_init(&ei2->link_order);
st->buf_count -= ei2->length;
oz_elt_info_free(buf, ei2);
oz_elt_stream_put(st);
}
}
list_add_tail(&ei->link_order, isoc ?
&buf->isoc_list : &buf->order_list);
return 0;
}
int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
unsigned max_len, struct list_head *list)
{
int count = 0;
struct list_head *el;
struct oz_elt_info *ei, *n;
spin_lock_bh(&buf->lock);
if (isoc)
el = &buf->isoc_list;
else
el = &buf->order_list;
list_for_each_entry_safe(ei, n, el, link_order) {
if ((*len + ei->length) <= max_len) {
struct oz_app_hdr *app_hdr = (struct oz_app_hdr *)
&ei->data[sizeof(struct oz_elt)];
app_hdr->elt_seq_num = buf->tx_seq_num[ei->app_id]++;
if (buf->tx_seq_num[ei->app_id] == 0)
buf->tx_seq_num[ei->app_id] = 1;
*len += ei->length;
list_del(&ei->link);
list_del(&ei->link_order);
if (ei->stream) {
ei->stream->buf_count -= ei->length;
oz_dbg(STREAM, "Stream down: %d %d\n",
ei->stream->buf_count, ei->length);
oz_elt_stream_put(ei->stream);
ei->stream = NULL;
}
INIT_LIST_HEAD(&ei->link_order);
list_add_tail(&ei->link, list);
count++;
} else {
break;
}
}
spin_unlock_bh(&buf->lock);
return count;
}
int oz_are_elts_available(struct oz_elt_buf *buf)
{
return !list_empty(&buf->order_list);
}
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZELTBUF_H
#define _OZELTBUF_H
#include "ozprotocol.h"
/*-----------------------------------------------------------------------------
*/
struct oz_pd;
typedef void (*oz_elt_callback_t)(struct oz_pd *pd, long context);
struct oz_elt_stream {
struct list_head link;
struct list_head elt_list;
atomic_t ref_count;
unsigned buf_count;
unsigned max_buf_count;
u8 frame_number;
u8 id;
};
#define OZ_MAX_ELT_PAYLOAD 255
struct oz_elt_info {
struct list_head link;
struct list_head link_order;
u8 flags;
u8 app_id;
oz_elt_callback_t callback;
long context;
struct oz_elt_stream *stream;
u8 data[sizeof(struct oz_elt) + OZ_MAX_ELT_PAYLOAD];
int length;
};
/* Flags values */
#define OZ_EI_F_MARKED 0x1
struct oz_elt_buf {
spinlock_t lock;
struct list_head stream_list;
struct list_head order_list;
struct list_head isoc_list;
u8 tx_seq_num[OZ_NB_APPS];
};
void oz_elt_buf_init(struct oz_elt_buf *buf);
void oz_elt_buf_term(struct oz_elt_buf *buf);
struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf);
void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei);
void oz_elt_info_free_chain(struct oz_elt_buf *buf, struct list_head *list);
int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count);
int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id);
void oz_elt_stream_get(struct oz_elt_stream *st);
void oz_elt_stream_put(struct oz_elt_stream *st);
int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id,
struct oz_elt_info *ei);
int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
unsigned max_len, struct list_head *list);
int oz_are_elts_available(struct oz_elt_buf *buf);
#endif /* _OZELTBUF_H */
This diff is collapsed.
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* ---------------------------------------------------------------------------*/
#ifndef _OZHCD_H
#define _OZHCD_H
int oz_hcd_init(void);
void oz_hcd_term(void);
struct oz_port *oz_hcd_pd_arrived(void *ctx);
void oz_hcd_pd_departed(struct oz_port *hport);
void oz_hcd_pd_reset(void *hpd, void *hport);
#endif /* _OZHCD_H */
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
#include <linux/ieee80211.h>
#include "ozdbg.h"
#include "ozpd.h"
#include "ozproto.h"
#include "ozcdev.h"
unsigned int oz_dbg_mask = OZ_DEFAULT_DBG_MASK;
/*
* The name of the 802.11 mac device. Empty string is the default value but a
* value can be supplied as a parameter to the module. An empty string means
* bind to nothing. '*' means bind to all netcards - this includes non-802.11
* netcards. Bindings can be added later using an IOCTL.
*/
static char *g_net_dev = "";
module_param(g_net_dev, charp, S_IRUGO);
MODULE_PARM_DESC(g_net_dev, "The device(s) to bind to; "
"'*' means all, '' (empty string; default) means none.");
/*
* Context: process
*/
static int __init ozwpan_init(void)
{
int err;
err = oz_cdev_register();
if (err)
return err;
err = oz_protocol_init(g_net_dev);
if (err)
goto err_protocol;
oz_app_enable(OZ_APPID_USB, 1);
oz_apps_init();
return 0;
err_protocol:
oz_cdev_deregister();
return err;
}
/*
* Context: process
*/
static void __exit ozwpan_exit(void)
{
oz_protocol_term();
oz_apps_term();
oz_cdev_deregister();
}
module_init(ozwpan_init);
module_exit(ozwpan_exit);
MODULE_AUTHOR("Chris Kelly");
MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver");
MODULE_VERSION("1.0.13");
MODULE_LICENSE("GPL");
This diff is collapsed.
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZPD_H_
#define _OZPD_H_
#include <linux/interrupt.h>
#include "ozeltbuf.h"
/* PD state
*/
#define OZ_PD_S_IDLE 0x1
#define OZ_PD_S_CONNECTED 0x2
#define OZ_PD_S_SLEEP 0x4
#define OZ_PD_S_STOPPED 0x8
/* Timer event types.
*/
#define OZ_TIMER_TOUT 1
#define OZ_TIMER_HEARTBEAT 2
#define OZ_TIMER_STOP 3
/*
*External spinlock variable
*/
extern spinlock_t g_polling_lock;
/* Data structure that hold information on a frame for transmisson. This is
* built when the frame is first transmitted and is used to rebuild the frame
* if a re-transmission is required.
*/
struct oz_tx_frame {
struct list_head link;
struct list_head elt_list;
struct oz_hdr hdr;
struct sk_buff *skb;
int total_size;
};
struct oz_isoc_stream {
struct list_head link;
u8 ep_num;
u8 frame_num;
u8 nb_units;
int size;
struct sk_buff *skb;
struct oz_hdr *oz_hdr;
};
struct oz_farewell {
struct list_head link;
u8 ep_num;
u8 index;
u8 len;
u8 report[0];
};
/* Data structure that holds information on a specific peripheral device (PD).
*/
struct oz_pd {
struct list_head link;
atomic_t ref_count;
u8 mac_addr[ETH_ALEN];
unsigned state;
unsigned state_flags;
unsigned send_flags;
u16 total_apps;
u16 paused_apps;
u8 session_id;
u8 param_rsp_status;
u8 pd_info;
u8 isoc_sent;
u32 last_rx_pkt_num;
u32 last_tx_pkt_num;
struct timespec last_rx_timestamp;
u32 trigger_pkt_num;
unsigned long pulse_time;
unsigned long pulse_period;
unsigned long presleep;
unsigned long keep_alive;
struct oz_elt_buf elt_buff;
void *app_ctx[OZ_NB_APPS];
spinlock_t app_lock[OZ_NB_APPS];
int max_tx_size;
u8 mode;
u8 ms_per_isoc;
unsigned isoc_latency;
unsigned max_stream_buffering;
int nb_queued_frames;
int nb_queued_isoc_frames;
spinlock_t tx_frame_lock;
struct list_head *last_sent_frame;
struct list_head tx_queue;
struct list_head farewell_list;
spinlock_t stream_lock;
struct list_head stream_list;
struct net_device *net_dev;
struct hrtimer heartbeat;
struct hrtimer timeout;
u8 timeout_type;
struct tasklet_struct heartbeat_tasklet;
struct tasklet_struct timeout_tasklet;
struct work_struct workitem;
};
#define OZ_MAX_QUEUED_FRAMES 4
struct oz_pd *oz_pd_alloc(const u8 *mac_addr);
void oz_pd_destroy(struct oz_pd *pd);
void oz_pd_get(struct oz_pd *pd);
void oz_pd_put(struct oz_pd *pd);
void oz_pd_set_state(struct oz_pd *pd, unsigned state);
void oz_pd_indicate_farewells(struct oz_pd *pd);
int oz_pd_sleep(struct oz_pd *pd);
void oz_pd_stop(struct oz_pd *pd);
void oz_pd_heartbeat(struct oz_pd *pd, u16 apps);
int oz_services_start(struct oz_pd *pd, u16 apps, int resume);
void oz_services_stop(struct oz_pd *pd, u16 apps, int pause);
int oz_prepare_frame(struct oz_pd *pd, int empty);
void oz_send_queued_frames(struct oz_pd *pd, int backlog);
void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn);
int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num);
int oz_isoc_stream_delete(struct oz_pd *pd, u8 ep_num);
int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, const u8 *data, int len);
void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt);
void oz_apps_init(void);
void oz_apps_term(void);
extern struct kmem_cache *oz_elt_info_cache;
extern struct kmem_cache *oz_tx_frame_cache;
#endif /* Sentry */
This diff is collapsed.
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZPROTO_H
#define _OZPROTO_H
#include <asm/byteorder.h>
#include "ozdbg.h"
#include "ozappif.h"
#define OZ_ALLOCATED_SPACE(__x) (LL_RESERVED_SPACE(__x)+(__x)->needed_tailroom)
/* Quantum in MS */
#define OZ_QUANTUM 8
/* Default timeouts.
*/
#define OZ_PRESLEEP_TOUT 11
/* Maximun sizes of tx frames. */
#define OZ_MAX_TX_SIZE 760
/* Maximum number of uncompleted isoc frames that can be pending in network. */
#define OZ_MAX_SUBMITTED_ISOC 16
/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. */
#define OZ_MAX_TX_QUEUE_ISOC 32
/* Application handler functions.
*/
struct oz_app_if {
int (*init)(void);
void (*term)(void);
int (*start)(struct oz_pd *pd, int resume);
void (*stop)(struct oz_pd *pd, int pause);
void (*rx)(struct oz_pd *pd, struct oz_elt *elt);
int (*heartbeat)(struct oz_pd *pd);
void (*farewell)(struct oz_pd *pd, u8 ep_num, u8 *data, u8 len);
};
int oz_protocol_init(char *devs);
void oz_protocol_term(void);
int oz_get_pd_list(struct oz_mac_addr *addr, int max_count);
void oz_app_enable(int app_id, int enable);
struct oz_pd *oz_pd_find(const u8 *mac_addr);
void oz_binding_add(const char *net_dev);
void oz_binding_remove(const char *net_dev);
void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time);
void oz_timer_delete(struct oz_pd *pd, int type);
void oz_pd_request_heartbeat(struct oz_pd *pd);
void oz_pd_heartbeat_handler(unsigned long data);
void oz_pd_timeout_handler(unsigned long data);
enum hrtimer_restart oz_pd_heartbeat_event(struct hrtimer *timer);
enum hrtimer_restart oz_pd_timeout_event(struct hrtimer *timer);
int oz_get_pd_status_list(char *pd_list, int max_count);
int oz_get_binding_list(char *buf, int max_if);
extern struct kmem_cache *oz_elt_info_cache;
extern struct kmem_cache *oz_tx_frame_cache;
#endif /* _OZPROTO_H */
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZPROTOCOL_H
#define _OZPROTOCOL_H
#define PACKED __packed
#define OZ_ETHERTYPE 0x892e
/* Status codes
*/
#define OZ_STATUS_SUCCESS 0
#define OZ_STATUS_INVALID_PARAM 1
#define OZ_STATUS_TOO_MANY_PDS 2
#define OZ_STATUS_NOT_ALLOWED 4
#define OZ_STATUS_SESSION_MISMATCH 5
#define OZ_STATUS_SESSION_TEARDOWN 6
/* This is the generic element header.
Every element starts with this.
*/
struct oz_elt {
u8 type;
u8 length;
} PACKED;
#define oz_next_elt(__elt) \
(struct oz_elt *)((u8 *)((__elt) + 1) + (__elt)->length)
/* Protocol element IDs.
*/
#define OZ_ELT_CONNECT_REQ 0x06
#define OZ_ELT_CONNECT_RSP 0x07
#define OZ_ELT_DISCONNECT 0x08
#define OZ_ELT_UPDATE_PARAM_REQ 0x11
#define OZ_ELT_FAREWELL_REQ 0x12
#define OZ_ELT_APP_DATA 0x31
/* This is the Ozmo header which is the first Ozmo specific part
* of a frame and comes after the MAC header.
*/
struct oz_hdr {
u8 control;
u8 last_pkt_num;
u32 pkt_num;
} PACKED;
#define OZ_PROTOCOL_VERSION 0x1
/* Bits in the control field. */
#define OZ_VERSION_MASK 0xc
#define OZ_VERSION_SHIFT 2
#define OZ_F_ACK 0x10
#define OZ_F_ISOC 0x20
#define OZ_F_MORE_DATA 0x40
#define OZ_F_ACK_REQUESTED 0x80
#define oz_get_prot_ver(__x) (((__x) & OZ_VERSION_MASK) >> OZ_VERSION_SHIFT)
/* Used to select the bits of packet number to put in the last_pkt_num.
*/
#define OZ_LAST_PN_MASK 0x00ff
#define OZ_LAST_PN_HALF_CYCLE 127
#define OZ_LATENCY_MASK 0xc0
#define OZ_ONE_MS_LATENCY 0x40
#define OZ_TEN_MS_LATENCY 0x80
/* Connect request data structure.
*/
struct oz_elt_connect_req {
u8 mode;
u8 resv1[16];
u8 pd_info;
u8 session_id;
u8 presleep;
u8 ms_isoc_latency;
u8 host_vendor;
u8 keep_alive;
u16 apps;
u8 max_len_div16;
u8 ms_per_isoc;
u8 resv3[2];
} PACKED;
/* mode field bits.
*/
#define OZ_MODE_POLLED 0x0
#define OZ_MODE_TRIGGERED 0x1
#define OZ_MODE_MASK 0xf
#define OZ_F_ISOC_NO_ELTS 0x40
#define OZ_F_ISOC_ANYTIME 0x80
#define OZ_NO_ELTS_ANYTIME 0xc0
/* Keep alive field.
*/
#define OZ_KALIVE_TYPE_MASK 0xc0
#define OZ_KALIVE_VALUE_MASK 0x3f
#define OZ_KALIVE_SPECIAL 0x00
#define OZ_KALIVE_SECS 0x40
#define OZ_KALIVE_MINS 0x80
#define OZ_KALIVE_HOURS 0xc0
/* Connect response data structure.
*/
struct oz_elt_connect_rsp {
u8 mode;
u8 status;
u8 resv1[3];
u8 session_id;
u16 apps;
u32 resv2;
} PACKED;
struct oz_elt_farewell {
u8 ep_num;
u8 index;
u8 report[1];
} PACKED;
struct oz_elt_update_param {
u8 resv1[16];
u8 presleep;
u8 resv2;
u8 host_vendor;
u8 keepalive;
} PACKED;
/* Header common to all application elements.
*/
struct oz_app_hdr {
u8 app_id;
u8 elt_seq_num;
} PACKED;
/* Values for app_id.
*/
#define OZ_APPID_USB 0x1
#define OZ_APPID_SERIAL 0x4
#define OZ_APPID_MAX OZ_APPID_SERIAL
#define OZ_NB_APPS (OZ_APPID_MAX+1)
/* USB header common to all elements for the USB application.
* This header extends the oz_app_hdr and comes directly after
* the element header in a USB application.
*/
struct oz_usb_hdr {
u8 app_id;
u8 elt_seq_num;
u8 type;
} PACKED;
/* USB requests element subtypes (type field of hs_usb_hdr).
*/
#define OZ_GET_DESC_REQ 1
#define OZ_GET_DESC_RSP 2
#define OZ_SET_CONFIG_REQ 3
#define OZ_SET_CONFIG_RSP 4
#define OZ_SET_INTERFACE_REQ 5
#define OZ_SET_INTERFACE_RSP 6
#define OZ_VENDOR_CLASS_REQ 7
#define OZ_VENDOR_CLASS_RSP 8
#define OZ_GET_STATUS_REQ 9
#define OZ_GET_STATUS_RSP 10
#define OZ_CLEAR_FEATURE_REQ 11
#define OZ_CLEAR_FEATURE_RSP 12
#define OZ_SET_FEATURE_REQ 13
#define OZ_SET_FEATURE_RSP 14
#define OZ_GET_CONFIGURATION_REQ 15
#define OZ_GET_CONFIGURATION_RSP 16
#define OZ_GET_INTERFACE_REQ 17
#define OZ_GET_INTERFACE_RSP 18
#define OZ_SYNCH_FRAME_REQ 19
#define OZ_SYNCH_FRAME_RSP 20
#define OZ_USB_ENDPOINT_DATA 23
#define OZ_REQD_D2H 0x80
struct oz_get_desc_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u16 offset;
u16 size;
u8 req_type;
u8 desc_type;
__le16 w_index;
u8 index;
} PACKED;
/* Values for desc_type field.
*/
#define OZ_DESC_DEVICE 0x01
#define OZ_DESC_CONFIG 0x02
#define OZ_DESC_STRING 0x03
/* Values for req_type field.
*/
#define OZ_RECP_MASK 0x1F
#define OZ_RECP_DEVICE 0x00
#define OZ_RECP_INTERFACE 0x01
#define OZ_RECP_ENDPOINT 0x02
#define OZ_REQT_MASK 0x60
#define OZ_REQT_STD 0x00
#define OZ_REQT_CLASS 0x20
#define OZ_REQT_VENDOR 0x40
struct oz_get_desc_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
__le16 offset;
__le16 total_size;
u8 rcode;
u8 data[1];
} PACKED;
struct oz_feature_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 recipient;
u8 index;
u16 feature;
} PACKED;
struct oz_feature_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 rcode;
} PACKED;
struct oz_set_config_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 index;
} PACKED;
struct oz_set_config_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 rcode;
} PACKED;
struct oz_set_interface_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 index;
u8 alternative;
} PACKED;
struct oz_set_interface_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 rcode;
} PACKED;
struct oz_get_interface_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 index;
} PACKED;
struct oz_get_interface_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 rcode;
u8 alternative;
} PACKED;
struct oz_vendor_class_req {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 req_type;
u8 request;
u16 value;
u16 index;
u8 data[1];
} PACKED;
struct oz_vendor_class_rsp {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 req_id;
u8 rcode;
u8 data[1];
} PACKED;
struct oz_data {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 endpoint;
u8 format;
} PACKED;
struct oz_isoc_fixed {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 endpoint;
u8 format;
u8 unit_size;
u8 frame_number;
u8 data[1];
} PACKED;
struct oz_multiple_fixed {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 endpoint;
u8 format;
u8 unit_size;
u8 data[1];
} PACKED;
struct oz_fragmented {
u8 app_id;
u8 elt_seq_num;
u8 type;
u8 endpoint;
u8 format;
u16 total_size;
u16 offset;
u8 data[1];
} PACKED;
/* Note: the following does not get packaged in an element in the same way
* that other data formats are packaged. Instead the data is put in a frame
* directly after the oz_header and is the only permitted data in such a
* frame. The length of the data is directly determined from the frame size.
*/
struct oz_isoc_large {
u8 endpoint;
u8 format;
u8 ms_data;
u8 frame_number;
} PACKED;
#define OZ_DATA_F_TYPE_MASK 0xF
#define OZ_DATA_F_MULTIPLE_FIXED 0x1
#define OZ_DATA_F_MULTIPLE_VAR 0x2
#define OZ_DATA_F_ISOC_FIXED 0x3
#define OZ_DATA_F_ISOC_VAR 0x4
#define OZ_DATA_F_FRAGMENTED 0x5
#define OZ_DATA_F_ISOC_LARGE 0x7
#endif /* _OZPROTOCOL_H */
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#include <linux/usb.h>
#include "ozdbg.h"
#ifdef WANT_URB_PARANOIA
#include "ozurbparanoia.h"
#define OZ_MAX_URBS 1000
struct urb *g_urb_memory[OZ_MAX_URBS];
int g_nb_urbs;
DEFINE_SPINLOCK(g_urb_mem_lock);
void oz_remember_urb(struct urb *urb)
{
unsigned long irq_state;
spin_lock_irqsave(&g_urb_mem_lock, irq_state);
if (g_nb_urbs < OZ_MAX_URBS) {
g_urb_memory[g_nb_urbs++] = urb;
oz_dbg(ON, "urb up = %d %p\n", g_nb_urbs, urb);
} else {
oz_dbg(ON, "ERROR urb buffer full\n");
}
spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
}
/*
*/
int oz_forget_urb(struct urb *urb)
{
unsigned long irq_state;
int i;
int rc = -1;
spin_lock_irqsave(&g_urb_mem_lock, irq_state);
for (i = 0; i < g_nb_urbs; i++) {
if (g_urb_memory[i] == urb) {
rc = 0;
if (--g_nb_urbs > i)
memcpy(&g_urb_memory[i], &g_urb_memory[i+1],
(g_nb_urbs - i) * sizeof(struct urb *));
oz_dbg(ON, "urb down = %d %p\n", g_nb_urbs, urb);
}
}
spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
return rc;
}
#endif /* #ifdef WANT_URB_PARANOIA */
#ifndef _OZURBPARANOIA_H
#define _OZURBPARANOIA_H
/* -----------------------------------------------------------------------------
* Released under the GNU General Public License Version 2 (GPLv2).
* Copyright (c) 2011 Ozmo Inc
* -----------------------------------------------------------------------------
*/
#ifdef WANT_URB_PARANOIA
void oz_remember_urb(struct urb *urb);
int oz_forget_urb(struct urb *urb);
#else
static inline void oz_remember_urb(struct urb *urb) {}
static inline int oz_forget_urb(struct urb *urb) { return 0; }
#endif /* WANT_URB_PARANOIA */
#endif /* _OZURBPARANOIA_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment