summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Kwak <kkwak@nvidia.com>2014-06-24 21:43:08 -0700
committerPeter Kim <pekim@nvidia.com>2014-06-25 19:17:29 -0700
commitf97258264752500ce7a49ad0bca1f8b1afafa9f1 (patch)
treed4322e9fd54e0abe017acb8cee28a81601cc334c
parent2bffd2846cb042ba0b04e2dca82d09d2238a0a93 (diff)
Revert "staging:ozwpan: Merge from main"
DO NOT INTEGRATE Bug 1466757 This reverts commit 5303a5b7be5e1973152f9899c3b240f4118aa0ca. Change-Id: I6274a3ae3699ac78a6facd4d57b72681b85511a5 Signed-off-by: Kenneth Kwak <kkwak@nvidia.com> Reviewed-on: http://git-master/r/428085 Reviewed-by: Peter Kim <pekim@nvidia.com> Tested-by: Peter Kim <pekim@nvidia.com>
-rw-r--r--drivers/staging/ozwpan/Kbuild2
-rw-r--r--drivers/staging/ozwpan/Makefile25
-rw-r--r--drivers/staging/ozwpan/ozappif.h20
-rw-r--r--drivers/staging/ozwpan/ozcdev.c374
-rw-r--r--drivers/staging/ozwpan/ozcdev.h3
-rw-r--r--drivers/staging/ozwpan/ozconfig.h27
-rw-r--r--drivers/staging/ozwpan/ozeltbuf.c39
-rw-r--r--drivers/staging/ozwpan/ozeltbuf.h5
-rw-r--r--drivers/staging/ozwpan/ozevent.c116
-rw-r--r--drivers/staging/ozwpan/ozevent.h31
-rw-r--r--drivers/staging/ozwpan/ozeventdef.h47
-rw-r--r--drivers/staging/ozwpan/ozeventtrace.h219
-rw-r--r--drivers/staging/ozwpan/ozhcd.c829
-rw-r--r--drivers/staging/ozwpan/ozkobject.c304
-rw-r--r--drivers/staging/ozwpan/ozkobject.h17
-rw-r--r--drivers/staging/ozwpan/ozmain.c10
-rw-r--r--drivers/staging/ozwpan/ozpd.c394
-rw-r--r--drivers/staging/ozwpan/ozpd.h31
-rw-r--r--drivers/staging/ozwpan/ozproto.c540
-rw-r--r--drivers/staging/ozwpan/ozproto.h39
-rw-r--r--drivers/staging/ozwpan/ozprotocol.h55
-rw-r--r--drivers/staging/ozwpan/oztrace.c179
-rw-r--r--drivers/staging/ozwpan/oztrace.h114
-rw-r--r--drivers/staging/ozwpan/ozurbparanoia.c7
-rw-r--r--drivers/staging/ozwpan/ozusbif.h18
-rw-r--r--drivers/staging/ozwpan/ozusbsvc.c57
-rw-r--r--drivers/staging/ozwpan/ozusbsvc1.c59
27 files changed, 1321 insertions, 2240 deletions
diff --git a/drivers/staging/ozwpan/Kbuild b/drivers/staging/ozwpan/Kbuild
index 08bc7938692d..6cc84cb3f0a6 100644
--- a/drivers/staging/ozwpan/Kbuild
+++ b/drivers/staging/ozwpan/Kbuild
@@ -14,6 +14,6 @@ ozwpan-y := \
ozcdev.o \
ozurbparanoia.o \
oztrace.o \
- ozkobject.o
+ ozevent.o
diff --git a/drivers/staging/ozwpan/Makefile b/drivers/staging/ozwpan/Makefile
deleted file mode 100644
index d2fdf8a1b5cf..000000000000
--- a/drivers/staging/ozwpan/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright .o) 2011 Ozmo I.o
-# Released under the GNU General Publ.o L.oense Version 2 (GPLv2).
-# -----------------------------------------------------------------------------
-ifneq ($(KERNELRELEASE),)
-# If invoked from kbuild.
-obj-m := ozwpan.o
-ozwpan-y := ozusbsvc.o ozusbsvc1.o ozurbparanoia.o oztrace.o ozproto.o ozpd.o ozmain.o ozkobject.o ozhcd.o ozeltbuf.o ozcdev.o
-
-else
-# If invoked dir.otly.
-KDIR := /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-
-default:
- $(MAKE) -C $(KDIR) M=$(PWD) modules EXTRA_CFLAGS="-I$(PWD)"
-
-debug: OZ_CFLAGS=-DWANT_TRACE_DATA_FLOW
-debug:
- $(MAKE) -C $(KDIR) M=$(PWD) modules EXTRA_CFLAGS="$(OZ_CFLAGS) -I$(PWD)"
-less_debug:
- $(MAKE) -C $(KDIR) M=$(PWD) modules EXTRA_CFLAGS="-DDEBUG -I$(PWD)"
-
-endif
-
diff --git a/drivers/staging/ozwpan/ozappif.h b/drivers/staging/ozwpan/ozappif.h
index ea1b271fdcda..af0273293872 100644
--- a/drivers/staging/ozwpan/ozappif.h
+++ b/drivers/staging/ozwpan/ozappif.h
@@ -6,16 +6,18 @@
#ifndef _OZAPPIF_H
#define _OZAPPIF_H
+#include "ozeventdef.h"
+
#define OZ_IOCTL_MAGIC 0xf4
struct oz_mac_addr {
- __u8 a[6];
+ unsigned char a[6];
};
#define OZ_MAX_PDS 8
struct oz_pd_list {
- __u32 count;
+ int count;
struct oz_mac_addr addr[OZ_MAX_PDS];
};
@@ -25,12 +27,20 @@ struct oz_binding_info {
char name[OZ_MAX_BINDING_LEN];
};
+struct oz_test {
+ int action;
+};
+
#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
+#define OZ_IOCTL_CLEAR_EVENTS _IO(OZ_IOCTL_MAGIC, 3)
+#define OZ_IOCTL_GET_EVENTS _IOR(OZ_IOCTL_MAGIC, 4, struct oz_evtlist)
+#define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 5, struct oz_binding_info)
+#define OZ_IOCTL_TEST _IOWR(OZ_IOCTL_MAGIC, 6, struct oz_test)
+#define OZ_IOCTL_SET_EVENT_MASK _IOW(OZ_IOCTL_MAGIC, 7, unsigned long)
+#define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 8, struct oz_binding_info)
+#define OZ_IOCTL_MAX 9
#endif /* _OZAPPIF_H */
diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c
index 9785eaa86b94..1c380d687963 100644
--- a/drivers/staging/ozwpan/ozcdev.c
+++ b/drivers/staging/ozwpan/ozcdev.c
@@ -8,23 +8,19 @@
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
#include <linux/poll.h>
#include <linux/sched.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "oztrace.h"
#include "ozappif.h"
#include "ozeltbuf.h"
#include "ozpd.h"
#include "ozproto.h"
-#include "ozcdev.h"
-#include "ozkobject.h"
+#include "ozevent.h"
/*------------------------------------------------------------------------------
*/
#define OZ_RD_BUF_SZ 256
-#define OZ_MODE_TFTP 0x1
-#define OZ_MODE_SERIAL 0x0
-
struct oz_cdev {
dev_t devnum;
struct cdev cdev;
@@ -32,8 +28,6 @@ struct oz_cdev {
spinlock_t lock;
u8 active_addr[ETH_ALEN];
struct oz_pd *active_pd;
- atomic_t ref_count;
- u8 mode;
};
/* Per PD context for the serial service stored in the PD. */
@@ -41,34 +35,16 @@ struct oz_serial_ctx {
atomic_t ref_count;
u8 tx_seq_num;
u8 rx_seq_num;
- u8 tx_done_seq_num;
- u8 padding;
u8 rd_buf[OZ_RD_BUF_SZ];
int rd_in;
int rd_out;
- spinlock_t rd_lock;
- int dg_len[OZ_RD_BUF_SZ/4];
- int dg_in;
- int dg_out;
};
/*------------------------------------------------------------------------------
*/
-static struct oz_cdev g_cdev;
-struct class *g_oz_class;
-struct device *g_oz_wpan_dev;
+int g_taction;
/*------------------------------------------------------------------------------
- * Context: softirq
*/
-
-static void oz_cdev_elt_completion_callback(struct oz_pd *pd, long context)
-{
- struct oz_serial_ctx *ctx;
- spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
- ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1];
- if (ctx)
- ctx->tx_done_seq_num = (u8)context;
- spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
-}
+static struct oz_cdev g_cdev;
/*------------------------------------------------------------------------------
* Context: process and softirq
*/
@@ -87,7 +63,7 @@ static struct oz_serial_ctx *oz_cdev_claim_ctx(struct oz_pd *pd)
*/
static void oz_cdev_release_ctx(struct oz_serial_ctx *ctx)
{
- if (ctx && atomic_dec_and_test(&ctx->ref_count)) {
+ if (atomic_dec_and_test(&ctx->ref_count)) {
oz_trace("Dealloc serial context.\n");
kfree(ctx);
}
@@ -98,10 +74,8 @@ static void oz_cdev_release_ctx(struct oz_serial_ctx *ctx)
int oz_cdev_open(struct inode *inode, struct file *filp)
{
struct oz_cdev *dev;
-
- if (!atomic_add_unless(&g_cdev.ref_count, 1, 1))
- return -EBUSY;
-
+ oz_trace("oz_cdev_open()\n");
+ oz_trace("major = %d minor = %d\n", imajor(inode), iminor(inode));
dev = container_of(inode->i_cdev, struct oz_cdev, cdev);
filp->private_data = dev;
return 0;
@@ -111,7 +85,7 @@ int oz_cdev_open(struct inode *inode, struct file *filp)
*/
int oz_cdev_release(struct inode *inode, struct file *filp)
{
- atomic_dec(&g_cdev.ref_count);
+ oz_trace("oz_cdev_release()\n");
return 0;
}
/*------------------------------------------------------------------------------
@@ -122,101 +96,44 @@ ssize_t oz_cdev_read(struct file *filp, char __user *buf, size_t count,
{
int n;
int ix;
- int is_tftp;
+
struct oz_pd *pd;
- struct oz_serial_ctx *ctx;
+ struct oz_serial_ctx *ctx = 0;
spin_lock_bh(&g_cdev.lock);
pd = g_cdev.active_pd;
if (pd)
oz_pd_get(pd);
- is_tftp = (g_cdev.mode & OZ_MODE_TFTP) ? 1 : 0;
spin_unlock_bh(&g_cdev.lock);
- if (pd == NULL)
+ if (pd == 0)
return -1;
ctx = oz_cdev_claim_ctx(pd);
- if (ctx == NULL)
+ if (ctx == 0)
goto out2;
-
- spin_lock_bh(&ctx->rd_lock);
-
- if (is_tftp) {
- /* if n is non zero we have a datagram */
- n = ctx->dg_len[ctx->dg_out];
-
- if (n == 0) {
- count = 0;
- spin_unlock_bh(&ctx->rd_lock);
- goto out1;
- }
-
- ix = ctx->rd_out;
- spin_unlock_bh(&ctx->rd_lock);
-
- /* copy n bytes of datagram to user bufer */
- if ((ix + n) < OZ_RD_BUF_SZ) {
- if (copy_to_user(buf, &ctx->rd_buf[ix], n)) {
- count = 0;
- goto out1;
- }
- spin_lock_bh(&ctx->rd_lock);
- ctx->rd_out += n;
- } else {
- int b = (OZ_RD_BUF_SZ - ix);
- /* datagram maybe split in between the end and start of
- * the buffer */
- if (copy_to_user(buf, &ctx->rd_buf[ix], b)) {
- count = 0;
- goto out1;
- }
- if (copy_to_user(&buf[b], ctx->rd_buf, n - b)) {
- count = 0;
- goto out1;
- }
- spin_lock_bh(&ctx->rd_lock);
- ctx->rd_out = n - (OZ_RD_BUF_SZ - ix);
- }
-
+ n = ctx->rd_in - ctx->rd_out;
+ if (n < 0)
+ n += OZ_RD_BUF_SZ;
+ if (count > n)
count = n;
-
- ctx->dg_len[ctx->dg_out] = 0;
- ctx->dg_out++;
- if ((OZ_RD_BUF_SZ/4) == ctx->dg_out)
- ctx->dg_out = 0;
- spin_unlock_bh(&ctx->rd_lock);
- } else {
- n = ctx->rd_in - ctx->rd_out;
- if (n < 0)
- n += OZ_RD_BUF_SZ;
- if (count > n)
- count = n;
-
- ix = ctx->rd_out;
- spin_unlock_bh(&ctx->rd_lock);
- n = OZ_RD_BUF_SZ - ix;
- if (n > count)
- n = count;
-
- if (copy_to_user(buf, &ctx->rd_buf[ix], n)) {
+ ix = ctx->rd_out;
+ n = OZ_RD_BUF_SZ - ix;
+ if (n > count)
+ n = count;
+ if (copy_to_user(buf, &ctx->rd_buf[ix], n)) {
+ count = 0;
+ goto out1;
+ }
+ ix += n;
+ if (ix == OZ_RD_BUF_SZ)
+ ix = 0;
+ if (n < count) {
+ if (copy_to_user(&buf[n], ctx->rd_buf, count-n)) {
count = 0;
goto out1;
}
-
- ix += n;
- if (ix == OZ_RD_BUF_SZ)
- ix = 0;
- if (n < count) {
- if (copy_to_user(&buf[n], ctx->rd_buf, count-n)) {
- count = 0;
- goto out1;
- }
- ix = count-n;
- }
-
- spin_lock_bh(&ctx->rd_lock);
- ctx->rd_out = ix;
- spin_unlock_bh(&ctx->rd_lock);
+ ix = count-n;
}
+ ctx->rd_out = ix;
out1:
oz_cdev_release_ctx(ctx);
out2:
@@ -231,68 +148,45 @@ ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count,
{
struct oz_pd *pd;
struct oz_elt_buf *eb;
- struct oz_elt_info *ei;
+ struct oz_elt_info *ei = 0;
struct oz_elt *elt;
- struct oz_ext_elt *ext_elt;
struct oz_app_hdr *app_hdr;
struct oz_serial_ctx *ctx;
- if (count > sizeof(ei->data) - sizeof(*elt) - sizeof(*app_hdr))
- return -EINVAL;
-
spin_lock_bh(&g_cdev.lock);
pd = g_cdev.active_pd;
if (pd)
oz_pd_get(pd);
spin_unlock_bh(&g_cdev.lock);
- if (pd == NULL)
+ if (pd == 0)
return -1;
- if (!(pd->state & OZ_PD_S_CONNECTED))
- return -ENXIO;
eb = &pd->elt_buff;
ei = oz_elt_info_alloc(eb);
- if (ei == NULL) {
+ if (ei == 0) {
count = 0;
goto out;
}
- spin_lock_bh(&g_cdev.lock);
- if (g_cdev.mode & OZ_MODE_TFTP) {
- spin_unlock_bh(&g_cdev.lock);
- ei->app_id = OZ_APPID_SERIAL;
- ei->flags |= OZ_EI_F_EXT_ELM;
- ext_elt = (struct oz_ext_elt *)ei->data;
- app_hdr = (struct oz_app_hdr *)(ext_elt+1);
- app_hdr->app_id = OZ_APPID_TFTP;
- ext_elt->length = sizeof(struct oz_app_hdr) + count;
- ext_elt->type = OZ_ELT_APP_DATA_EX;
- ei->length = ext_elt->length + sizeof(struct oz_ext_elt);
- ext_elt->length = cpu_to_le16(ext_elt->length);
- } else {
- spin_unlock_bh(&g_cdev.lock);
- ei->app_id = OZ_APPID_SERIAL;
- elt = (struct oz_elt *)ei->data;
- app_hdr = (struct oz_app_hdr *)(elt+1);
- app_hdr->app_id = OZ_APPID_SERIAL;
- elt->length = sizeof(struct oz_app_hdr) + count;
- elt->type = OZ_ELT_APP_DATA;
- ei->length = elt->length + sizeof(struct oz_elt);
- }
+ elt = (struct oz_elt *)ei->data;
+ app_hdr = (struct oz_app_hdr *)(elt+1);
+ elt->length = sizeof(struct oz_app_hdr) + count;
+ elt->type = OZ_ELT_APP_DATA;
+ ei->app_id = OZ_APPID_SERIAL;
+ ei->length = elt->length + sizeof(struct oz_elt);
+ app_hdr->app_id = OZ_APPID_SERIAL;
if (copy_from_user(app_hdr+1, buf, count))
goto out;
- spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
+ spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1];
if (ctx) {
app_hdr->elt_seq_num = ctx->tx_seq_num++;
if (ctx->tx_seq_num == 0)
ctx->tx_seq_num = 1;
- ei->callback = oz_cdev_elt_completion_callback;
- ei->context = ctx->tx_seq_num;
spin_lock(&eb->lock);
if (oz_queue_elt_info(eb, 0, 0, ei) == 0)
- ei = NULL;
+ ei = 0;
spin_unlock(&eb->lock);
}
- spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
+ spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
out:
if (ei) {
count = 0;
@@ -306,43 +200,25 @@ out:
/*------------------------------------------------------------------------------
* Context: process
*/
-int oz_set_active_pd(const u8 *addr)
+static int oz_set_active_pd(u8 *addr)
{
int rc = 0;
struct oz_pd *pd;
struct oz_pd *old_pd;
- struct oz_serial_ctx *ctx;
pd = oz_pd_find(addr);
if (pd) {
spin_lock_bh(&g_cdev.lock);
- if (memcmp(g_cdev.active_addr, addr, ETH_ALEN) == 0) {
- spin_unlock_bh(&g_cdev.lock);
- return rc;
- }
memcpy(g_cdev.active_addr, addr, ETH_ALEN);
old_pd = g_cdev.active_pd;
g_cdev.active_pd = pd;
spin_unlock_bh(&g_cdev.lock);
-
- /*Reset buffer pointers if new device is selected*/
- ctx = oz_cdev_claim_ctx(pd);
- if (ctx != NULL) {
- spin_lock_bh(&ctx->rd_lock);
- ctx->dg_in = 0;
- ctx->dg_out = 0;
- ctx->dg_len[0] = 0;
- ctx->rd_out = 0;
- ctx->rd_in = 0;
- spin_unlock_bh(&ctx->rd_lock);
- }
-
if (old_pd)
oz_pd_put(old_pd);
} else {
- if (is_zero_ether_addr(addr)) {
+ if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) {
spin_lock_bh(&g_cdev.lock);
pd = g_cdev.active_pd;
- g_cdev.active_pd = NULL;
+ g_cdev.active_pd = 0;
memset(g_cdev.active_addr, 0,
sizeof(g_cdev.active_addr));
spin_unlock_bh(&g_cdev.lock);
@@ -357,52 +233,6 @@ int oz_set_active_pd(const u8 *addr)
/*------------------------------------------------------------------------------
* Context: process
*/
-void oz_get_active_pd(u8 *addr)
-{
- spin_lock_bh(&g_cdev.lock);
- memcpy(addr, g_cdev.active_addr, ETH_ALEN);
- spin_unlock_bh(&g_cdev.lock);
-
-}
-/*------------------------------------------------------------------------------
- * Context: process
- */
-u8 oz_get_serial_mode(void)
-{
- u8 serial_mode;
-
- spin_lock_bh(&g_cdev.lock);
- serial_mode = g_cdev.mode;
- spin_unlock_bh(&g_cdev.lock);
- return serial_mode;
-}
-/*------------------------------------------------------------------------------
- * Context: process
- */
-void oz_set_serial_mode(u8 mode)
-{
- u8 addr[ETH_ALEN];
- struct oz_pd *pd;
- struct oz_serial_ctx *ctx;
-
- oz_get_active_pd(addr);
- pd = oz_pd_find(addr);
- if (!pd)
- return;
- ctx = oz_cdev_claim_ctx(pd);
- if (!ctx) {
- oz_pd_put(pd);
- return;
- }
- spin_lock_bh(&g_cdev.lock);
- g_cdev.mode = mode;
- spin_unlock_bh(&g_cdev.lock);
- oz_cdev_release_ctx(ctx);
- oz_pd_put(pd);
-}
-/*------------------------------------------------------------------------------
- * Context: process
- */
long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int rc = 0;
@@ -421,7 +251,7 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
switch (cmd) {
case OZ_IOCTL_GET_PD_LIST: {
struct oz_pd_list list;
- memset(&list, 0, sizeof(list));
+ oz_trace("OZ_IOCTL_GET_PD_LIST\n");
list.count = oz_get_pd_list(list.addr, OZ_MAX_PDS);
if (copy_to_user((void __user *)arg, &list,
sizeof(list)))
@@ -430,6 +260,7 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
case OZ_IOCTL_SET_ACTIVE_PD: {
u8 addr[ETH_ALEN];
+ oz_trace("OZ_IOCTL_SET_ACTIVE_PD\n");
if (copy_from_user(addr, (void __user *)arg, ETH_ALEN))
return -EFAULT;
rc = oz_set_active_pd(addr);
@@ -437,6 +268,7 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
case OZ_IOCTL_GET_ACTIVE_PD: {
u8 addr[ETH_ALEN];
+ oz_trace("OZ_IOCTL_GET_ACTIVE_PD\n");
spin_lock_bh(&g_cdev.lock);
memcpy(addr, g_cdev.active_addr, ETH_ALEN);
spin_unlock_bh(&g_cdev.lock);
@@ -444,6 +276,20 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return -EFAULT;
}
break;
+#ifdef WANT_EVENT_TRACE
+ case OZ_IOCTL_CLEAR_EVENTS:
+ oz_events_clear();
+ break;
+ case OZ_IOCTL_GET_EVENTS:
+ rc = oz_events_copy((void __user *)arg);
+ break;
+ case OZ_IOCTL_SET_EVENT_MASK:
+ if (copy_from_user(&g_evt_mask, (void __user *)arg,
+ sizeof(unsigned long))) {
+ return -EFAULT;
+ }
+ break;
+#endif /* WANT_EVENT_TRACE */
case OZ_IOCTL_ADD_BINDING:
case OZ_IOCTL_REMOVE_BINDING: {
struct oz_binding_info b;
@@ -469,23 +315,17 @@ unsigned int oz_cdev_poll(struct file *filp, poll_table *wait)
{
unsigned int ret = 0;
struct oz_cdev *dev = filp->private_data;
+ oz_trace("Poll called wait = %p\n", wait);
spin_lock_bh(&dev->lock);
if (dev->active_pd) {
struct oz_serial_ctx *ctx = oz_cdev_claim_ctx(dev->active_pd);
- spin_unlock_bh(&dev->lock);
if (ctx) {
- spin_lock_bh(&ctx->rd_lock);
if (ctx->rd_in != ctx->rd_out)
ret |= POLLIN | POLLRDNORM;
-
- if (ctx->tx_seq_num == ctx->tx_done_seq_num)
- ret |= POLLOUT;
- spin_unlock_bh(&ctx->rd_lock);
oz_cdev_release_ctx(ctx);
}
- } else
- spin_unlock_bh(&dev->lock);
-
+ }
+ spin_unlock_bh(&dev->lock);
if (wait)
poll_wait(filp, &dev->rdq, wait);
return ret;
@@ -510,38 +350,16 @@ int oz_cdev_register(void)
memset(&g_cdev, 0, sizeof(g_cdev));
err = alloc_chrdev_region(&g_cdev.devnum, 0, 1, "ozwpan");
if (err < 0)
- goto out3;
+ return err;
+ oz_trace("Alloc dev number %d:%d\n", MAJOR(g_cdev.devnum),
+ MINOR(g_cdev.devnum));
cdev_init(&g_cdev.cdev, &oz_fops);
g_cdev.cdev.owner = THIS_MODULE;
g_cdev.cdev.ops = &oz_fops;
spin_lock_init(&g_cdev.lock);
init_waitqueue_head(&g_cdev.rdq);
err = cdev_add(&g_cdev.cdev, g_cdev.devnum, 1);
- if (err < 0) {
- oz_trace("Failed to add cdev\n");
- goto out2;
- }
- g_oz_class = class_create(THIS_MODULE, "ozmo_wpan");
- if (IS_ERR(g_oz_class)) {
- oz_trace("Failed to register ozmo_wpan class\n");
- err = PTR_ERR(g_oz_class);
- goto out1;
- }
- g_oz_wpan_dev = device_create(g_oz_class, NULL, g_cdev.devnum, NULL,
- "ozwpan");
- if (IS_ERR(g_oz_wpan_dev)) {
- oz_trace("Failed to create sysfs entry for cdev\n");
- err = PTR_ERR(g_oz_wpan_dev);
- goto out1;
- }
- oz_create_sys_entry();
return 0;
-out1:
- cdev_del(&g_cdev.cdev);
-out2:
- unregister_chrdev_region(g_cdev.devnum, 1);
-out3:
- return err;
}
/*------------------------------------------------------------------------------
* Context: process
@@ -550,11 +368,6 @@ int oz_cdev_deregister(void)
{
cdev_del(&g_cdev.cdev);
unregister_chrdev_region(g_cdev.devnum, 1);
- if (g_oz_class) {
- oz_destroy_sys_entry();
- device_destroy(g_oz_class, g_cdev.devnum);
- class_destroy(g_oz_class);
- }
return 0;
}
/*------------------------------------------------------------------------------
@@ -562,6 +375,7 @@ int oz_cdev_deregister(void)
*/
int oz_cdev_init(void)
{
+ oz_event_log(OZ_EVT_SERVICE, 1, OZ_APPID_SERIAL, 0, 0);
oz_app_enable(OZ_APPID_SERIAL, 1);
return 0;
}
@@ -570,6 +384,7 @@ int oz_cdev_init(void)
*/
void oz_cdev_term(void)
{
+ oz_event_log(OZ_EVT_SERVICE, 2, OZ_APPID_SERIAL, 0, 0);
oz_app_enable(OZ_APPID_SERIAL, 0);
}
/*------------------------------------------------------------------------------
@@ -578,17 +393,17 @@ void oz_cdev_term(void)
int oz_cdev_start(struct oz_pd *pd, int resume)
{
struct oz_serial_ctx *ctx;
- struct oz_serial_ctx *old_ctx;
+ struct oz_serial_ctx *old_ctx = 0;
+ oz_event_log(OZ_EVT_SERVICE, 3, OZ_APPID_SERIAL, 0, resume);
if (resume) {
oz_trace("Serial service resumed.\n");
return 0;
}
ctx = kzalloc(sizeof(struct oz_serial_ctx), GFP_ATOMIC);
- if (ctx == NULL)
+ if (ctx == 0)
return -ENOMEM;
atomic_set(&ctx->ref_count, 1);
ctx->tx_seq_num = 1;
- ctx->tx_done_seq_num = 1;
spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
old_ctx = pd->app_ctx[OZ_APPID_SERIAL-1];
if (old_ctx) {
@@ -599,10 +414,11 @@ int oz_cdev_start(struct oz_pd *pd, int resume)
spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
}
spin_lock(&g_cdev.lock);
- if ((g_cdev.active_pd == NULL) &&
+ if ((g_cdev.active_pd == 0) &&
(memcmp(pd->mac_addr, g_cdev.active_addr, ETH_ALEN) == 0)) {
oz_pd_get(pd);
g_cdev.active_pd = pd;
+ oz_trace("Active PD arrived.\n");
}
spin_unlock(&g_cdev.lock);
oz_trace("Serial service started.\n");
@@ -614,24 +430,26 @@ int oz_cdev_start(struct oz_pd *pd, int resume)
void oz_cdev_stop(struct oz_pd *pd, int pause)
{
struct oz_serial_ctx *ctx;
+ oz_event_log(OZ_EVT_SERVICE, 4, OZ_APPID_SERIAL, 0, pause);
if (pause) {
oz_trace("Serial service paused.\n");
return;
}
spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1];
- pd->app_ctx[OZ_APPID_SERIAL-1] = NULL;
+ pd->app_ctx[OZ_APPID_SERIAL-1] = 0;
spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
if (ctx)
oz_cdev_release_ctx(ctx);
spin_lock(&g_cdev.lock);
if (pd == g_cdev.active_pd)
- g_cdev.active_pd = NULL;
+ g_cdev.active_pd = 0;
else
- pd = NULL;
+ pd = 0;
spin_unlock(&g_cdev.lock);
if (pd) {
oz_pd_put(pd);
+ oz_trace("Active PD departed.\n");
}
oz_trace("Serial service stopped.\n");
}
@@ -647,19 +465,14 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt)
int space;
int copy_sz;
int ix;
- int is_tftp;
-
- spin_lock_bh(&g_cdev.lock);
- is_tftp = (g_cdev.mode & OZ_MODE_TFTP) ? 1 : 0;
- spin_unlock_bh(&g_cdev.lock);
ctx = oz_cdev_claim_ctx(pd);
- if (ctx == NULL) {
+ if (ctx == 0) {
oz_trace("Cannot claim serial context.\n");
return;
}
- app_hdr = (struct oz_app_hdr *)(oz_elt_data(elt));
+ app_hdr = (struct oz_app_hdr *)(elt+1);
/* If sequence number is non-zero then check it is not a duplicate.
*/
if (app_hdr->elt_seq_num != 0) {
@@ -671,11 +484,10 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt)
}
}
ctx->rx_seq_num = app_hdr->elt_seq_num;
- len = oz_elt_data_len(elt) - sizeof(struct oz_app_hdr);
- data = ((u8 *)(app_hdr + 1));
+ len = elt->length - sizeof(struct oz_app_hdr);
+ data = ((u8 *)(elt+1)) + sizeof(struct oz_app_hdr);
if (len <= 0)
goto out;
- spin_lock_bh(&ctx->rd_lock);
space = ctx->rd_out - ctx->rd_in - 1;
if (space < 0)
space += OZ_RD_BUF_SZ;
@@ -683,19 +495,6 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt)
oz_trace("Not enough space:%d %d\n", len, space);
len = space;
}
-
-
- if (is_tftp) {
- if (len != 0) {
- /* remember length of datagram */
- ctx->dg_len[ctx->dg_in] = len;
-
- ctx->dg_in++;
- if ((OZ_RD_BUF_SZ/4) == ctx->dg_in)
- ctx->dg_in = 0;
- }
- }
-
ix = ctx->rd_in;
copy_sz = OZ_RD_BUF_SZ - ix;
if (copy_sz > len)
@@ -710,7 +509,6 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt)
ix = len;
}
ctx->rd_in = ix;
- spin_unlock_bh(&ctx->rd_lock);
wake_up(&g_cdev.rdq);
out:
oz_cdev_release_ctx(ctx);
diff --git a/drivers/staging/ozwpan/ozcdev.h b/drivers/staging/ozwpan/ozcdev.h
index d0dc3dc5d5f1..698014bb8d72 100644
--- a/drivers/staging/ozwpan/ozcdev.h
+++ b/drivers/staging/ozwpan/ozcdev.h
@@ -6,7 +6,6 @@
#ifndef _OZCDEV_H
#define _OZCDEV_H
-extern struct device *g_oz_wpan_dev;
int oz_cdev_register(void);
int oz_cdev_deregister(void);
int oz_cdev_init(void);
@@ -15,7 +14,5 @@ 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);
void oz_cdev_heartbeat(struct oz_pd *pd);
-int oz_set_active_pd(const u8 *addr);
-void oz_get_active_pd(u8 *addr);
#endif /* _OZCDEV_H */
diff --git a/drivers/staging/ozwpan/ozconfig.h b/drivers/staging/ozwpan/ozconfig.h
new file mode 100644
index 000000000000..43e6373a009c
--- /dev/null
+++ b/drivers/staging/ozwpan/ozconfig.h
@@ -0,0 +1,27 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * ---------------------------------------------------------------------------*/
+#ifndef _OZCONFIG_H
+#define _OZCONFIG_H
+
+/* #define WANT_TRACE */
+#ifdef WANT_TRACE
+#define WANT_VERBOSE_TRACE
+#endif /* #ifdef WANT_TRACE */
+/* #define WANT_URB_PARANOIA */
+
+/* #define WANT_PRE_2_6_39 */
+#define WANT_EVENT_TRACE
+
+/* These defines determine what verbose trace is displayed. */
+#ifdef WANT_VERBOSE_TRACE
+/* #define WANT_TRACE_STREAM */
+/* #define WANT_TRACE_URB */
+/* #define WANT_TRACE_CTRL_DETAIL */
+#define WANT_TRACE_HUB
+/* #define WANT_TRACE_RX_FRAMES */
+/* #define WANT_TRACE_TX_FRAMES */
+#endif /* WANT_VERBOSE_TRACE */
+
+#endif /* _OZCONFIG_H */
diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c
index a52fecef85fb..988f522475d9 100644
--- a/drivers/staging/ozwpan/ozeltbuf.c
+++ b/drivers/staging/ozwpan/ozeltbuf.c
@@ -6,6 +6,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
@@ -63,7 +64,7 @@ void oz_elt_buf_term(struct oz_elt_buf *buf)
*/
struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf)
{
- struct oz_elt_info *ei = NULL;
+ struct oz_elt_info *ei = 0;
spin_lock_bh(&buf->lock);
if (buf->free_elts && buf->elt_pool) {
ei = container_of(buf->elt_pool, struct oz_elt_info, link);
@@ -81,9 +82,9 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf)
if (ei) {
ei->flags = 0;
ei->app_id = 0;
- ei->callback = NULL;
+ ei->callback = 0;
ei->context = 0;
- ei->stream = NULL;
+ ei->stream = 0;
ei->magic = OZ_ELT_INFO_MAGIC_USED;
INIT_LIST_HEAD(&ei->link);
INIT_LIST_HEAD(&ei->link_order);
@@ -131,8 +132,10 @@ int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count)
{
struct oz_elt_stream *st;
+ oz_trace("oz_elt_stream_create(0x%x)\n", id);
+
st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC | __GFP_ZERO);
- if (st == NULL)
+ if (st == 0)
return -ENOMEM;
atomic_set(&st->ref_count, 1);
st->id = id;
@@ -148,8 +151,8 @@ 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)
{
struct list_head *e;
- struct oz_elt_stream *st = NULL;
-
+ struct oz_elt_stream *st;
+ oz_trace("oz_elt_stream_delete(0x%x)\n", id);
spin_lock_bh(&buf->lock);
e = buf->stream_list.next;
while (e != &buf->stream_list) {
@@ -158,7 +161,7 @@ int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id)
list_del(e);
break;
}
- st = NULL;
+ st = 0;
}
if (!st) {
spin_unlock_bh(&buf->lock);
@@ -172,6 +175,9 @@ int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id)
list_del_init(&ei->link);
list_del_init(&ei->link_order);
st->buf_count -= ei->length;
+ oz_trace2(OZ_TRACE_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);
}
@@ -202,7 +208,7 @@ 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)
{
- struct oz_elt_stream *st = NULL;
+ struct oz_elt_stream *st = 0;
struct list_head *e;
if (id) {
list_for_each(e, &buf->stream_list) {
@@ -236,6 +242,8 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id,
st->buf_count += ei->length;
/* Add to list in stream. */
list_add_tail(&ei->link, &st->elt_list);
+ oz_trace2(OZ_TRACE_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.
*/
@@ -275,12 +283,8 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
ei = container_of(e, struct oz_elt_info, link_order);
e = e->next;
if ((*len + ei->length) <= max_len) {
- if (ei->flags & OZ_EI_F_EXT_ELM)
- app_hdr = (struct oz_app_hdr *)
- &ei->data[sizeof(struct oz_ext_elt)];
- else
- app_hdr = (struct oz_app_hdr *)
- &ei->data[sizeof(struct oz_elt)];
+ 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;
@@ -289,8 +293,11 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
list_del(&ei->link_order);
if (ei->stream) {
ei->stream->buf_count -= ei->length;
+ oz_trace2(OZ_TRACE_STREAM,
+ "Stream down: %d %d\n",
+ ei->stream->buf_count, ei->length);
oz_elt_stream_put(ei->stream);
- ei->stream = NULL;
+ ei->stream = 0;
}
INIT_LIST_HEAD(&ei->link_order);
list_add_tail(&ei->link, list);
@@ -312,7 +319,7 @@ int oz_are_elts_available(struct oz_elt_buf *buf)
*/
void oz_trim_elt_pool(struct oz_elt_buf *buf)
{
- struct list_head *free = NULL;
+ struct list_head *free = 0;
struct list_head *e;
spin_lock_bh(&buf->lock);
while (buf->free_elts > buf->max_free_elts) {
diff --git a/drivers/staging/ozwpan/ozeltbuf.h b/drivers/staging/ozwpan/ozeltbuf.h
index 2c184be4adab..03c12f57b9bb 100644
--- a/drivers/staging/ozwpan/ozeltbuf.h
+++ b/drivers/staging/ozwpan/ozeltbuf.h
@@ -23,7 +23,7 @@ struct oz_elt_stream {
u8 id;
};
-#define OZ_MAX_ELT_PAYLOAD 1024
+#define OZ_MAX_ELT_PAYLOAD 255
struct oz_elt_info {
struct list_head link;
struct list_head link_order;
@@ -32,13 +32,12 @@ struct oz_elt_info {
oz_elt_callback_t callback;
long context;
struct oz_elt_stream *stream;
- u8 data[sizeof(struct oz_ext_elt) + OZ_MAX_ELT_PAYLOAD];
+ u8 data[sizeof(struct oz_elt) + OZ_MAX_ELT_PAYLOAD];
int length;
unsigned magic;
};
/* Flags values */
#define OZ_EI_F_MARKED 0x1
-#define OZ_EI_F_EXT_ELM 0x2
struct oz_elt_buf {
spinlock_t lock;
diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c
new file mode 100644
index 000000000000..73703d3e96bd
--- /dev/null
+++ b/drivers/staging/ozwpan/ozevent.c
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#include "ozconfig.h"
+#ifdef WANT_EVENT_TRACE
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+#include "oztrace.h"
+#include "ozevent.h"
+/*------------------------------------------------------------------------------
+ */
+unsigned long g_evt_mask = 0xffffffff;
+/*------------------------------------------------------------------------------
+ */
+#define OZ_MAX_EVTS 2048 /* Must be power of 2 */
+DEFINE_SPINLOCK(g_eventlock);
+static int g_evt_in;
+static int g_evt_out;
+static int g_missed_events;
+static struct oz_event g_events[OZ_MAX_EVTS];
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+void oz_event_init(void)
+{
+ oz_trace("Event tracing initialized\n");
+ g_evt_in = g_evt_out = 0;
+ g_missed_events = 0;
+}
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+void oz_event_term(void)
+{
+ oz_trace("Event tracing terminated\n");
+}
+/*------------------------------------------------------------------------------
+ * Context: any
+ */
+void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4)
+{
+ unsigned long irqstate;
+ int ix;
+ spin_lock_irqsave(&g_eventlock, irqstate);
+ ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1);
+ if (ix != g_evt_out) {
+ struct oz_event *e = &g_events[g_evt_in];
+ e->jiffies = jiffies;
+ e->evt = evt;
+ e->ctx1 = ctx1;
+ e->ctx2 = ctx2;
+ e->ctx3 = ctx3;
+ e->ctx4 = ctx4;
+ g_evt_in = ix;
+ } else {
+ g_missed_events++;
+ }
+ spin_unlock_irqrestore(&g_eventlock, irqstate);
+}
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+int oz_events_copy(struct oz_evtlist __user *lst)
+{
+ int first;
+ int ix;
+ struct hdr {
+ int count;
+ int missed;
+ } hdr;
+ ix = g_evt_out;
+ hdr.count = g_evt_in - ix;
+ if (hdr.count < 0)
+ hdr.count += OZ_MAX_EVTS;
+ if (hdr.count > OZ_EVT_LIST_SZ)
+ hdr.count = OZ_EVT_LIST_SZ;
+ hdr.missed = g_missed_events;
+ g_missed_events = 0;
+ if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr)))
+ return -EFAULT;
+ first = OZ_MAX_EVTS - ix;
+ if (first > hdr.count)
+ first = hdr.count;
+ if (first) {
+ int sz = first*sizeof(struct oz_event);
+ void __user *p = (void __user *)lst->evts;
+ if (copy_to_user(p, &g_events[ix], sz))
+ return -EFAULT;
+ if (hdr.count > first) {
+ p = (void __user *)&lst->evts[first];
+ sz = (hdr.count-first)*sizeof(struct oz_event);
+ if (copy_to_user(p, g_events, sz))
+ return -EFAULT;
+ }
+ }
+ ix += hdr.count;
+ if (ix >= OZ_MAX_EVTS)
+ ix -= OZ_MAX_EVTS;
+ g_evt_out = ix;
+ return 0;
+}
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+void oz_events_clear(void)
+{
+ unsigned long irqstate;
+ spin_lock_irqsave(&g_eventlock, irqstate);
+ g_evt_in = g_evt_out = 0;
+ g_missed_events = 0;
+ spin_unlock_irqrestore(&g_eventlock, irqstate);
+}
+#endif /* WANT_EVENT_TRACE */
+
diff --git a/drivers/staging/ozwpan/ozevent.h b/drivers/staging/ozwpan/ozevent.h
new file mode 100644
index 000000000000..f033d014c6f3
--- /dev/null
+++ b/drivers/staging/ozwpan/ozevent.h
@@ -0,0 +1,31 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZEVENT_H
+#define _OZEVENT_H
+#include "ozconfig.h"
+#include "ozeventdef.h"
+
+#ifdef WANT_EVENT_TRACE
+extern unsigned long g_evt_mask;
+void oz_event_init(void);
+void oz_event_term(void);
+void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4);
+#define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) \
+ do { \
+ if ((1<<(__evt)) & g_evt_mask) \
+ oz_event_log2(__evt, __ctx1, __ctx2, __ctx3, __ctx4); \
+ } while (0)
+int oz_events_copy(struct oz_evtlist __user *lst);
+void oz_events_clear(void);
+#else
+#define oz_event_init()
+#define oz_event_term()
+#define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4)
+#define oz_events_copy(__lst)
+#define oz_events_clear()
+#endif /* WANT_EVENT_TRACE */
+
+#endif /* _OZEVENT_H */
diff --git a/drivers/staging/ozwpan/ozeventdef.h b/drivers/staging/ozwpan/ozeventdef.h
new file mode 100644
index 000000000000..a880288bab11
--- /dev/null
+++ b/drivers/staging/ozwpan/ozeventdef.h
@@ -0,0 +1,47 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZEVENTDEF_H
+#define _OZEVENTDEF_H
+
+#define OZ_EVT_RX_FRAME 0
+#define OZ_EVT_RX_PROCESS 1
+#define OZ_EVT_TX_FRAME 2
+#define OZ_EVT_TX_ISOC 3
+#define OZ_EVT_URB_SUBMIT 4
+#define OZ_EVT_URB_DONE 5
+#define OZ_EVT_URB_CANCEL 6
+#define OZ_EVT_CTRL_REQ 7
+#define OZ_EVT_CTRL_CNF 8
+#define OZ_EVT_CTRL_LOCAL 9
+#define OZ_EVT_CONNECT_REQ 10
+#define OZ_EVT_CONNECT_RSP 11
+#define OZ_EVT_EP_CREDIT 12
+#define OZ_EVT_EP_BUFFERING 13
+#define OZ_EVT_TX_ISOC_DONE 14
+#define OZ_EVT_TX_ISOC_DROP 15
+#define OZ_EVT_TIMER_CTRL 16
+#define OZ_EVT_TIMER 17
+#define OZ_EVT_PD_STATE 18
+#define OZ_EVT_SERVICE 19
+#define OZ_EVT_DEBUG 20
+
+struct oz_event {
+ unsigned long jiffies;
+ unsigned char evt;
+ unsigned char ctx1;
+ unsigned short ctx2;
+ void *ctx3;
+ unsigned ctx4;
+};
+
+#define OZ_EVT_LIST_SZ 64
+struct oz_evtlist {
+ int count;
+ int missed;
+ struct oz_event evts[OZ_EVT_LIST_SZ];
+};
+
+#endif /* _OZEVENTDEF_H */
diff --git a/drivers/staging/ozwpan/ozeventtrace.h b/drivers/staging/ozwpan/ozeventtrace.h
deleted file mode 100644
index def0878b3fc1..000000000000
--- a/drivers/staging/ozwpan/ozeventtrace.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -----------------------------------------------------------------------------
- * Copyright (c) 2011 Ozmo Inc
- * Released under the GNU General Public License Version 2 (GPLv2).
- * -----------------------------------------------------------------------------
- */
-
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM ozwpan
-
-#if !defined(_OZEVENTTRACE_H) || defined(TRACE_HEADER_MULTI_READ)
-
-#define _OZEVENTTRACE_H
-
-#include <linux/tracepoint.h>
-#include <linux/usb.h>
-
-#define MAX_URB_LEN 16
-#define MAX_FRAME_LEN 32
-#define MAX_MSG_LEN 128
-
-TRACE_EVENT(urb_in,
-
- TP_PROTO(struct urb *oz_urb),
-
- TP_ARGS(oz_urb),
-
- TP_STRUCT__entry(
- __field(uintptr_t, urb)
- __field(u32, endpoint)
- __field(u32, buffer_length)
- __field(u32, inc_length)
- __array(u8, buffer, MAX_URB_LEN)
- ),
-
- TP_fast_assign(
- __entry->urb = (uintptr_t)oz_urb;
- __entry->endpoint = usb_pipeendpoint(oz_urb->pipe);
- if (usb_pipein(oz_urb->pipe))
- __entry->endpoint |= 0x80;
- __entry->buffer_length = oz_urb->transfer_buffer_length;
- __entry->inc_length = oz_urb->transfer_buffer_length
- <= MAX_URB_LEN ? oz_urb->transfer_buffer_length : MAX_URB_LEN;
- if ((__entry->endpoint == 0x00) ||
- (__entry->endpoint == 0x80)) {
- __entry->buffer_length = 8;
- __entry->inc_length = 8;
- memcpy(__entry->buffer, oz_urb->setup_packet, 8);
- } else {
- memcpy(__entry->buffer, oz_urb->transfer_buffer,
- __entry->inc_length);
- }
- ),
-
- TP_printk("%08x,%02x,%03x,%03x,"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- (u32)__entry->urb, __entry->endpoint, __entry->buffer_length,
- __entry->inc_length, __entry->buffer[0], __entry->buffer[1],
- __entry->buffer[2], __entry->buffer[3], __entry->buffer[4],
- __entry->buffer[5], __entry->buffer[6], __entry->buffer[7],
- __entry->buffer[8], __entry->buffer[9], __entry->buffer[10],
- __entry->buffer[11], __entry->buffer[12], __entry->buffer[13],
- __entry->buffer[14], __entry->buffer[15])
-);
-
-TRACE_EVENT(urb_out,
-
- TP_PROTO(struct urb *oz_urb, int status),
-
- TP_ARGS(oz_urb, status),
-
- TP_STRUCT__entry(
- __field(uintptr_t, urb)
- __field(u32, endpoint)
- __field(u32, status)
- __field(u32, actual_length)
- __field(u32, inc_length)
- __array(u8, buffer, MAX_URB_LEN)
- ),
-
- TP_fast_assign(
- __entry->urb = (uintptr_t)oz_urb;
- __entry->endpoint = usb_pipeendpoint(oz_urb->pipe);
- __entry->status = status;
- if (usb_pipein(oz_urb->pipe))
- __entry->endpoint |= 0x80;
- __entry->actual_length = oz_urb->actual_length;
- __entry->inc_length = oz_urb->actual_length
- <= MAX_URB_LEN ? oz_urb->actual_length : MAX_URB_LEN;
- if (usb_pipein(oz_urb->pipe))
- memcpy(__entry->buffer, oz_urb->transfer_buffer,
- __entry->inc_length);
- ),
-
- TP_printk("%08x,%08x,%02x,%03x,%03x,"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- (u32)__entry->urb, __entry->status, __entry->endpoint,
- __entry->actual_length, __entry->inc_length, __entry->buffer[0],
- __entry->buffer[1], __entry->buffer[2], __entry->buffer[3],
- __entry->buffer[4], __entry->buffer[5], __entry->buffer[6],
- __entry->buffer[7], __entry->buffer[8], __entry->buffer[9],
- __entry->buffer[10], __entry->buffer[11], __entry->buffer[12],
- __entry->buffer[13], __entry->buffer[14], __entry->buffer[15])
-);
-
-TRACE_EVENT(rx_frame,
-
- TP_PROTO(struct sk_buff *skb),
-
- TP_ARGS(skb),
-
- TP_STRUCT__entry(
- __field(u32, inc_len)
- __field(u32, orig_len)
- __array(u8, data, MAX_FRAME_LEN)
- ),
-
- TP_fast_assign(
- __entry->orig_len = skb->len;
- __entry->inc_len = skb->len < MAX_FRAME_LEN ?
- skb->len : MAX_FRAME_LEN;
- memcpy(__entry->data, (u8 *)skb_network_header(skb),
- __entry->inc_len);
- ),
-
- TP_printk("%03x,%03x,%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x", __entry->orig_len,
- __entry->inc_len, __entry->data[0], __entry->data[1],
- __entry->data[2], __entry->data[3], __entry->data[4],
- __entry->data[5], __entry->data[6], __entry->data[7],
- __entry->data[8], __entry->data[9], __entry->data[10],
- __entry->data[11], __entry->data[12], __entry->data[13],
- __entry->data[14], __entry->data[15], __entry->data[16],
- __entry->data[17], __entry->data[18], __entry->data[19],
- __entry->data[20], __entry->data[21], __entry->data[22],
- __entry->data[23], __entry->data[24], __entry->data[25],
- __entry->data[26], __entry->data[27], __entry->data[28],
- __entry->data[29], __entry->data[30], __entry->data[31])
-);
-
-TRACE_EVENT(tx_frame,
-
- TP_PROTO(struct sk_buff *skb),
-
- TP_ARGS(skb),
-
- TP_STRUCT__entry(
- __field(u32, inc_len)
- __field(u32, orig_len)
- __array(u8, data, MAX_FRAME_LEN)
- ),
-
- TP_fast_assign(
- __entry->orig_len = skb->len - 14;
- __entry->inc_len = __entry->orig_len
- < MAX_FRAME_LEN ?
- __entry->orig_len
- : MAX_FRAME_LEN;
- memcpy(__entry->data, (u8 *)skb_network_header(skb),
- __entry->inc_len);
- ),
-
- TP_printk("%03x,%03x,%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x", __entry->orig_len,
- __entry->inc_len, __entry->data[0], __entry->data[1],
- __entry->data[2], __entry->data[3], __entry->data[4],
- __entry->data[5], __entry->data[6], __entry->data[7],
- __entry->data[8], __entry->data[9], __entry->data[10],
- __entry->data[11], __entry->data[12], __entry->data[13],
- __entry->data[14], __entry->data[15], __entry->data[16],
- __entry->data[17], __entry->data[18], __entry->data[19],
- __entry->data[20], __entry->data[21], __entry->data[22],
- __entry->data[23], __entry->data[24], __entry->data[25],
- __entry->data[26], __entry->data[27], __entry->data[28],
- __entry->data[29], __entry->data[30], __entry->data[31])
-);
-
-DECLARE_EVENT_CLASS(debug_msg,
-
- TP_PROTO(char *fmt, va_list arg),
-
- TP_ARGS(fmt, arg),
-
- TP_STRUCT__entry(
- __array(char, msg, MAX_MSG_LEN)
- ),
-
- TP_fast_assign(
- snprintf(__entry->msg, MAX_MSG_LEN, fmt, arg);
- ),
-
- TP_printk("%s", __entry->msg)
-);
-
-DEFINE_EVENT(debug_msg, hcd_msg_evt,
- TP_PROTO(char *fmt, va_list arg),
- TP_ARGS(fmt, arg)
-);
-
-DEFINE_EVENT(debug_msg, isoc_msg_evt,
- TP_PROTO(char *fmt, va_list arg),
- TP_ARGS(fmt, arg)
-);
-
-DEFINE_EVENT(debug_msg, info_msg_evt,
- TP_PROTO(char *fmt, va_list arg),
- TP_ARGS(fmt, arg)
-);
-
-
-#endif /*_OZEVENTTRACE_H*/
-
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_FILE ozeventtrace
-#include <trace/define_trace.h>
diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c
index 42c8a0880740..750b14eb505e 100644
--- a/drivers/staging/ozwpan/ozhcd.c
+++ b/drivers/staging/ozwpan/ozhcd.c
@@ -26,17 +26,21 @@
*/
#include <linux/platform_device.h>
#include <linux/usb.h>
+#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/export.h>
#include "linux/usb/hcd.h"
#include <asm/unaligned.h>
+#include "ozconfig.h"
#include "ozusbif.h"
#include "oztrace.h"
#include "ozurbparanoia.h"
-#include "ozhcd.h"
-
-#define OZ_HUB_DEBOUNCE_TIMEOUT 1500
-
+#include "ozevent.h"
+/*------------------------------------------------------------------------------
+ * Number of units of buffering to capture for an isochronous IN endpoint before
+ * allowing data to be indicated up.
+ */
+#define OZ_IN_BUFFERING_UNITS 50
/* Name of our platform device.
*/
#define OZ_PLAT_DEV_NAME "ozwpan"
@@ -46,9 +50,6 @@
/* Get endpoint object from the containing link.
*/
#define ep_from_link(__e) container_of((__e), struct oz_endpoint, link)
-/*EP0 timeout before ep0 request is again added to TX queue. (13*8 = 98mSec)
- */
-#define EP0_TIMEOUT_COUNTER 13
/*------------------------------------------------------------------------------
* Used to link urbs together and also store some status information for each
* urb.
@@ -60,7 +61,7 @@ struct oz_urb_link {
struct oz_port *port;
u8 req_id;
u8 ep_num;
- unsigned submit_counter;
+ unsigned long submit_jiffies;
};
/* Holds state information about a USB endpoint.
@@ -69,8 +70,7 @@ struct oz_endpoint {
struct list_head urb_list; /* List of oz_urb_link items. */
struct list_head link; /* For isoc ep, links in to isoc
lists of oz_port. */
- struct timespec timestamp;
- int credit2;
+ unsigned long last_jiffies;
int credit;
int credit_ceiling;
u8 ep_num;
@@ -80,7 +80,6 @@ struct oz_endpoint {
int in_ix;
int out_ix;
int buffered_units;
- u8 max_buffer_units;
unsigned flags;
int start_frame;
};
@@ -88,13 +87,6 @@ struct oz_endpoint {
#define OZ_F_EP_BUFFERING 0x1
#define OZ_F_EP_HAVE_STREAM 0x2
-
-/* Buffer_size.
-Total size of buffer (in bytes) for the endpoint buffer for isochronous data,
-and for stashing BULK or INT data if a URB is not available.
-*/
-#define OZ_EP_BUFFER_SIZE_ISOC (1024*24)
-#define OZ_EP_BUFFER_SIZE_INT (512)
/* Holds state information about a USB interface.
*/
struct oz_interface {
@@ -196,7 +188,6 @@ static DEFINE_SPINLOCK(g_tasklet_lock);
static struct tasklet_struct g_urb_process_tasklet;
static struct tasklet_struct g_urb_cancel_tasklet;
static atomic_t g_pending_urbs = ATOMIC_INIT(0);
-static atomic_t g_usb_frame_number = ATOMIC_INIT(0);
static const struct hc_driver g_oz_hc_drv = {
.description = g_hcd_name,
.product_desc = "Ozmo Devices WPAN",
@@ -245,14 +236,9 @@ static inline struct oz_hcd *oz_hcd_private(struct usb_hcd *hcd)
static int oz_get_port_from_addr(struct oz_hcd *ozhcd, u8 bus_addr)
{
int i;
-
- if (0 != bus_addr) {
- for (i = 0; i < OZ_NB_PORTS; i++) {
- if (ozhcd->ports[i].bus_addr == bus_addr)
- return i;
- }
-
- return -1;
+ for (i = 0; i < OZ_NB_PORTS; i++) {
+ if (ozhcd->ports[i].bus_addr == bus_addr)
+ return i;
}
return ozhcd->conn_port;
}
@@ -262,7 +248,7 @@ static int oz_get_port_from_addr(struct oz_hcd *ozhcd, u8 bus_addr)
*/
static struct oz_urb_link *oz_alloc_urb_link(void)
{
- struct oz_urb_link *urbl = NULL;
+ struct oz_urb_link *urbl = 0;
unsigned long irq_state;
spin_lock_irqsave(&g_link_lock, irq_state);
if (g_link_pool) {
@@ -271,7 +257,7 @@ static struct oz_urb_link *oz_alloc_urb_link(void)
--g_link_pool_size;
}
spin_unlock_irqrestore(&g_link_lock, irq_state);
- if (urbl == NULL)
+ if (urbl == 0)
urbl = kmalloc(sizeof(struct oz_urb_link), GFP_ATOMIC);
return urbl;
}
@@ -288,7 +274,7 @@ static void oz_free_urb_link(struct oz_urb_link *urbl)
if (g_link_pool_size < OZ_MAX_LINK_POOL_SIZE) {
urbl->link.next = g_link_pool;
g_link_pool = &urbl->link;
- urbl = NULL;
+ urbl = 0;
g_link_pool_size++;
}
spin_unlock_irqrestore(&g_link_lock, irq_state);
@@ -306,7 +292,7 @@ static void oz_empty_link_pool(void)
unsigned long irq_state;
spin_lock_irqsave(&g_link_lock, irq_state);
e = g_link_pool;
- g_link_pool = NULL;
+ g_link_pool = 0;
g_link_pool_size = 0;
spin_unlock_irqrestore(&g_link_lock, irq_state);
while (e) {
@@ -352,7 +338,7 @@ struct oz_urb_link *oz_uncancel_urb(struct oz_hcd *ozhcd, struct urb *urb)
return urbl;
}
}
- return NULL;
+ return 0;
}
/*------------------------------------------------------------------------------
* This is called when we have finished processing an urb. It unlinks it from
@@ -360,32 +346,17 @@ struct oz_urb_link *oz_uncancel_urb(struct oz_hcd *ozhcd, struct urb *urb)
* Context: softirq or process
*/
static void oz_complete_urb(struct usb_hcd *hcd, struct urb *urb,
- int status)
+ int status, unsigned long submit_jiffies)
{
struct oz_hcd *ozhcd = oz_hcd_private(hcd);
unsigned long irq_state;
- struct oz_urb_link *cancel_urbl = NULL;
+ struct oz_urb_link *cancel_urbl = 0;
spin_lock_irqsave(&g_tasklet_lock, irq_state);
-
- if (usb_pipeisoc(urb->pipe)) {
- if (status < 0) {
- int i;
- urb->transfer_buffer_length = 0;
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc[i].actual_length = 0;
- urb->iso_frame_desc[i].status = status;
- }
- } else {
- /* ISOC checks transfer_buffer_length */
- urb->transfer_buffer_length = urb->actual_length;
- }
- }
- oz_trace_urb_out(urb, status);
usb_hcd_unlink_urb_from_ep(hcd, urb);
/* Clear hcpriv which will prevent it being put in the cancel list
* in the event that an attempt is made to cancel it.
*/
- urb->hcpriv = NULL;
+ urb->hcpriv = 0;
/* Walk the cancel list in case the urb is already sitting there.
* Since we process the cancel list in a tasklet rather than in
* the dequeue function this could happen.
@@ -403,7 +374,14 @@ static void oz_complete_urb(struct usb_hcd *hcd, struct urb *urb,
if (oz_forget_urb(urb)) {
oz_trace("OZWPAN: ERROR Unknown URB %p\n", urb);
} else {
+ static unsigned long last_time;
atomic_dec(&g_pending_urbs);
+ oz_trace2(OZ_TRACE_URB,
+ "%lu: giveback_urb(%p,%x) %lu %lu pending:%d\n",
+ jiffies, urb, status, jiffies-submit_jiffies,
+ jiffies-last_time, atomic_read(&g_pending_urbs));
+ last_time = jiffies;
+ oz_event_log(OZ_EVT_URB_DONE, 0, 0, urb, status);
usb_hcd_giveback_urb(hcd, urb, status);
}
spin_lock(&g_tasklet_lock);
@@ -418,6 +396,7 @@ static void oz_complete_urb(struct usb_hcd *hcd, struct urb *urb,
*/
static void oz_ep_free(struct oz_port *port, struct oz_endpoint *ep)
{
+ oz_trace("oz_ep_free()\n");
if (port) {
struct list_head list;
struct oz_hcd *ozhcd = port->ozhcd;
@@ -432,47 +411,12 @@ static void oz_ep_free(struct oz_port *port, struct oz_endpoint *ep)
list_splice_tail(&list, &ozhcd->orphanage);
spin_unlock_bh(&ozhcd->hcd_lock);
}
+ oz_trace("Freeing endpoint memory\n");
kfree(ep);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
-void oz_complete_buffered_urb(struct oz_port *port, struct oz_endpoint *ep,
- struct urb *urb)
-{
- int data_len, available_space, copy_len;
-
- data_len = ep->buffer[ep->out_ix];
- if (data_len <= urb->transfer_buffer_length)
- available_space = data_len;
- else
- available_space = urb->transfer_buffer_length;
-
- if (++ep->out_ix == ep->buffer_size)
- ep->out_ix = 0;
- copy_len = ep->buffer_size - ep->out_ix;
- if (copy_len >= available_space)
- copy_len = available_space;
- memcpy(urb->transfer_buffer, &ep->buffer[ep->out_ix], copy_len);
-
- if (copy_len < available_space) {
- memcpy((urb->transfer_buffer + copy_len), ep->buffer,
- (available_space - copy_len));
- ep->out_ix = available_space - copy_len;
- } else {
- ep->out_ix += copy_len;
- }
- urb->actual_length = available_space;
- if (ep->out_ix == ep->buffer_size)
- ep->out_ix = 0;
-
- ep->buffered_units--;
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
-}
-
-/*------------------------------------------------------------------------------
- * Context: softirq
- */
static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir,
struct urb *urb, u8 req_id)
{
@@ -486,7 +430,7 @@ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir,
urbl = oz_alloc_urb_link();
if (!urbl)
return -ENOMEM;
- urbl->submit_counter = 0;
+ urbl->submit_jiffies = jiffies;
urbl->urb = urb;
urbl->req_id = req_id;
urbl->ep_num = ep_addr;
@@ -500,47 +444,25 @@ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir,
if (urb->unlinked) {
spin_unlock_bh(&port->ozhcd->hcd_lock);
oz_trace("urb %p unlinked so complete immediately\n", urb);
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
+ oz_complete_urb(port->ozhcd->hcd, urb, 0, 0);
oz_free_urb_link(urbl);
return 0;
}
- if (in_dir) {
- if (port->in_ep[ep_addr]) {
- ep = port->in_ep[ep_addr];
- } else {
- err = -EINVAL;
- goto out;
- }
- } else {
- if (port->out_ep[ep_addr]) {
- ep = port->out_ep[ep_addr];
- } else {
- err = -EINVAL;
- goto out;
- }
- }
-
- /*For interrupt endpoint check for buffered data
- * & complete urb
- */
- if (((ep->attrib & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
- && ep->buffered_units > 0) {
- oz_free_urb_link(urbl);
- spin_unlock_bh(&port->ozhcd->hcd_lock);
- oz_complete_buffered_urb(port, ep, urb);
- return 0;
- }
-
+ if (in_dir)
+ ep = port->in_ep[ep_addr];
+ else
+ ep = port->out_ep[ep_addr];
if (ep && port->hpd) {
list_add_tail(&urbl->link, &ep->urb_list);
if (!in_dir && ep_addr && (ep->credit < 0)) {
- getrawmonotonic(&ep->timestamp);
+ ep->last_jiffies = jiffies;
ep->credit = 0;
+ oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num,
+ 0, 0, ep->credit);
}
} else {
err = -EPIPE;
}
-out:
spin_unlock_bh(&port->ozhcd->hcd_lock);
if (err)
oz_free_urb_link(urbl);
@@ -554,7 +476,7 @@ out:
static int oz_dequeue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir,
struct urb *urb)
{
- struct oz_urb_link *urbl = NULL;
+ struct oz_urb_link *urbl = 0;
struct oz_endpoint *ep;
spin_lock_bh(&port->ozhcd->hcd_lock);
if (in_dir)
@@ -569,7 +491,7 @@ static int oz_dequeue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir,
list_del_init(e);
break;
}
- urbl = NULL;
+ urbl = 0;
}
}
spin_unlock_bh(&port->ozhcd->hcd_lock);
@@ -585,8 +507,8 @@ static struct urb *oz_find_urb_by_id(struct oz_port *port, int ep_ix,
u8 req_id)
{
struct oz_hcd *ozhcd = port->ozhcd;
- struct urb *urb = NULL;
- struct oz_urb_link *urbl = NULL;
+ struct urb *urb = 0;
+ struct oz_urb_link *urbl = 0;
struct oz_endpoint *ep;
spin_lock_bh(&ozhcd->hcd_lock);
@@ -610,35 +532,6 @@ static struct urb *oz_find_urb_by_id(struct oz_port *port, int ep_ix,
return urb;
}
/*------------------------------------------------------------------------------
- * Finds an urbl given request it, then set submit_count to 1, thus heartbeat
- * count this value up to EP0_TIMEOUT.
- */
-void oz_hcd_mark_urb_submitted(void *hport, int ep_ix, u8 req_id)
-{
- struct oz_port *port = (struct oz_port *)hport;
- struct oz_hcd *ozhcd = port->ozhcd;
- struct oz_urb_link *urbl = 0;
- struct oz_endpoint *ep;
- unsigned long irq_state;
- unsigned found = 0;
- spin_lock_bh(&ozhcd->hcd_lock);
- spin_lock_irqsave(&g_tasklet_lock, irq_state);
- ep = port->out_ep[ep_ix];
- if (ep) {
- struct list_head *e;
- list_for_each(e, &ep->urb_list) {
- urbl = container_of(e, struct oz_urb_link, link);
- if (urbl->req_id == req_id) {
- urbl->submit_counter = 1;
- found = 1;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
- spin_unlock_bh(&ozhcd->hcd_lock);
-}
-/*------------------------------------------------------------------------------
* Pre-condition: Port lock must be held.
* Context: softirq
*/
@@ -688,14 +581,13 @@ static inline void oz_hcd_put(struct oz_hcd *ozhcd)
void *oz_hcd_pd_arrived(void *hpd)
{
int i;
- void *hport = NULL;
- struct oz_hcd *ozhcd = NULL;
+ void *hport = 0;
+ struct oz_hcd *ozhcd = 0;
struct oz_endpoint *ep;
- static int n = OZ_NB_PORTS;
- int j;
+ oz_trace("oz_hcd_pd_arrived()\n");
ozhcd = oz_hcd_claim();
- if (ozhcd == NULL)
- return NULL;
+ if (ozhcd == 0)
+ return 0;
/* Allocate an endpoint object in advance (before holding hcd lock) to
* use for out endpoint 0.
*/
@@ -703,45 +595,39 @@ void *oz_hcd_pd_arrived(void *hpd)
spin_lock_bh(&ozhcd->hcd_lock);
if (ozhcd->conn_port >= 0) {
spin_unlock_bh(&ozhcd->hcd_lock);
+ oz_trace("conn_port >= 0\n");
goto out;
}
- j = n;
for (i = 0; i < OZ_NB_PORTS; i++) {
- struct oz_port *port;
- if (++j >= OZ_NB_PORTS)
- j = 0;
- port = &ozhcd->ports[j];
+ struct oz_port *port = &ozhcd->ports[i];
spin_lock(&port->port_lock);
if ((port->flags & OZ_PORT_F_PRESENT) == 0) {
oz_acquire_port(port, hpd);
- port->bus_addr = 0;
- port->config_num = 0;
spin_unlock(&port->port_lock);
break;
}
spin_unlock(&port->port_lock);
}
if (i < OZ_NB_PORTS) {
- ozhcd->conn_port = j;
+ oz_trace("Setting conn_port = %d\n", i);
+ ozhcd->conn_port = i;
/* Attach out endpoint 0.
*/
- ozhcd->ports[j].out_ep[0] = ep;
- ep = NULL;
- hport = &ozhcd->ports[j];
+ ozhcd->ports[i].out_ep[0] = ep;
+ ep = 0;
+ hport = &ozhcd->ports[i];
spin_unlock_bh(&ozhcd->hcd_lock);
if (ozhcd->flags & OZ_HDC_F_SUSPENDED) {
- oz_trace_msg(H, "usb_hcd_resume_root_hub()\n");
+ oz_trace("Resuming root hub\n");
usb_hcd_resume_root_hub(ozhcd->hcd);
}
- n = j;
- oz_trace_msg(H, "usb_hcd_poll_rh()\n");
usb_hcd_poll_rh_status(ozhcd->hcd);
} else {
spin_unlock_bh(&ozhcd->hcd_lock);
}
out:
if (ep) /* ep is non-null if not used. */
- oz_ep_free(NULL, ep);
+ oz_ep_free(0, ep);
oz_hcd_put(ozhcd);
return hport;
}
@@ -756,21 +642,22 @@ void oz_hcd_pd_departed(void *hport)
struct oz_port *port = (struct oz_port *)hport;
struct oz_hcd *ozhcd;
void *hpd;
- struct oz_endpoint *ep = NULL;
+ struct oz_endpoint *ep = 0;
- oz_trace("%s:\n", __func__);
- if (port == NULL) {
- oz_trace("%s: port = 0\n", __func__);
+ oz_trace("oz_hcd_pd_departed()\n");
+ if (port == 0) {
+ oz_trace("oz_hcd_pd_departed() port = 0\n");
return;
}
ozhcd = port->ozhcd;
- if (ozhcd == NULL)
+ if (ozhcd == 0)
return;
/* Check if this is the connection port - if so clear it.
*/
spin_lock_bh(&ozhcd->hcd_lock);
if ((ozhcd->conn_port >= 0) &&
(port == &ozhcd->ports[ozhcd->conn_port])) {
+ oz_trace("Clearing conn_port\n");
ozhcd->conn_port = -1;
}
spin_lock(&port->port_lock);
@@ -781,24 +668,22 @@ void oz_hcd_pd_departed(void *hport)
oz_clean_endpoints_for_config(ozhcd->hcd, port);
spin_lock_bh(&port->port_lock);
hpd = port->hpd;
- port->hpd = NULL;
+ port->hpd = 0;
port->bus_addr = 0xff;
- port->config_num = 0;
port->flags &= ~(OZ_PORT_F_PRESENT | OZ_PORT_F_DYING);
port->flags |= OZ_PORT_F_CHANGED;
- port->status &= ~(USB_PORT_STAT_CONNECTION|USB_PORT_STAT_ENABLE);
+ port->status &= ~USB_PORT_STAT_CONNECTION;
port->status |= (USB_PORT_STAT_C_CONNECTION << 16);
/* If there is an endpont 0 then clear the pointer while we hold
* the spinlock be we deallocate it after releasing the lock.
*/
if (port->out_ep[0]) {
ep = port->out_ep[0];
- port->out_ep[0] = NULL;
+ port->out_ep[0] = 0;
}
spin_unlock_bh(&port->port_lock);
if (ep)
oz_ep_free(port, ep);
- oz_trace_msg(H, "usb_hcd_poll_rh_status()\n");
usb_hcd_poll_rh_status(ozhcd->hcd);
oz_usb_put(hpd);
}
@@ -823,13 +708,16 @@ void oz_hcd_pd_reset(void *hpd, void *hport)
/*------------------------------------------------------------------------------
* Context: softirq
*/
-void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc,
+void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, u8 *desc,
int length, int offset, int total_size)
{
struct oz_port *port = (struct oz_port *)hport;
struct urb *urb;
int err = 0;
+ oz_event_log(OZ_EVT_CTRL_CNF, 0, req_id, 0, status);
+ oz_trace("oz_hcd_get_desc_cnf length = %d offs = %d tot_size = %d\n",
+ length, offset, total_size);
urb = oz_find_urb_by_id(port, 0, req_id);
if (!urb)
return;
@@ -861,11 +749,56 @@ void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc,
}
}
urb->actual_length = total_size;
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
+ oz_complete_urb(port->ozhcd->hcd, urb, 0, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
+#ifdef WANT_TRACE
+static void oz_display_conf_type(u8 t)
+{
+ switch (t) {
+ case USB_REQ_GET_STATUS:
+ oz_trace("USB_REQ_GET_STATUS - cnf\n");
+ break;
+ case USB_REQ_CLEAR_FEATURE:
+ oz_trace("USB_REQ_CLEAR_FEATURE - cnf\n");
+ break;
+ case USB_REQ_SET_FEATURE:
+ oz_trace("USB_REQ_SET_FEATURE - cnf\n");
+ break;
+ case USB_REQ_SET_ADDRESS:
+ oz_trace("USB_REQ_SET_ADDRESS - cnf\n");
+ break;
+ case USB_REQ_GET_DESCRIPTOR:
+ oz_trace("USB_REQ_GET_DESCRIPTOR - cnf\n");
+ break;
+ case USB_REQ_SET_DESCRIPTOR:
+ oz_trace("USB_REQ_SET_DESCRIPTOR - cnf\n");
+ break;
+ case USB_REQ_GET_CONFIGURATION:
+ oz_trace("USB_REQ_GET_CONFIGURATION - cnf\n");
+ break;
+ case USB_REQ_SET_CONFIGURATION:
+ oz_trace("USB_REQ_SET_CONFIGURATION - cnf\n");
+ break;
+ case USB_REQ_GET_INTERFACE:
+ oz_trace("USB_REQ_GET_INTERFACE - cnf\n");
+ break;
+ case USB_REQ_SET_INTERFACE:
+ oz_trace("USB_REQ_SET_INTERFACE - cnf\n");
+ break;
+ case USB_REQ_SYNCH_FRAME:
+ oz_trace("USB_REQ_SYNCH_FRAME - cnf\n");
+ break;
+ }
+}
+#else
+#define oz_display_conf_type(__x)
+#endif /* WANT_TRACE */
+/*------------------------------------------------------------------------------
+ * Context: softirq
+ */
static void oz_hcd_complete_set_config(struct oz_port *port, struct urb *urb,
u8 rcode, u8 config_num)
{
@@ -881,7 +814,7 @@ static void oz_hcd_complete_set_config(struct oz_port *port, struct urb *urb,
} else {
rc = -ENOMEM;
}
- oz_complete_urb(hcd, urb, rc);
+ oz_complete_urb(hcd, urb, rc, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq
@@ -892,29 +825,26 @@ static void oz_hcd_complete_set_interface(struct oz_port *port, struct urb *urb,
struct usb_hcd *hcd = port->ozhcd->hcd;
int rc = 0;
if (rcode == 0) {
- if (port->config_num > 0) {
- struct usb_host_config *config;
- struct usb_host_interface *intf;
-
- oz_clean_endpoints_for_interface(hcd, port, if_num);
- config = &urb->dev->config[port->config_num-1];
- intf = &config->intf_cache[if_num]->altsetting[alt];
- if (oz_build_endpoints_for_interface(hcd, port, intf,
- GFP_ATOMIC))
- rc = -ENOMEM;
- else
- port->iface[if_num].alt = alt;
- } else
+ struct usb_host_config *config;
+ struct usb_host_interface *intf;
+ oz_trace("Set interface %d alt %d\n", if_num, alt);
+ oz_clean_endpoints_for_interface(hcd, port, if_num);
+ config = &urb->dev->config[port->config_num-1];
+ intf = &config->intf_cache[if_num]->altsetting[alt];
+ if (oz_build_endpoints_for_interface(hcd, port, intf,
+ GFP_ATOMIC))
rc = -ENOMEM;
+ else
+ port->iface[if_num].alt = alt;
} else {
rc = -ENOMEM;
}
- oz_complete_urb(hcd, urb, rc);
+ oz_complete_urb(hcd, urb, rc, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
-void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data,
+void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, u8 *data,
int data_len)
{
struct oz_port *port = (struct oz_port *)hport;
@@ -924,9 +854,11 @@ void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data,
unsigned windex;
unsigned wvalue;
+ oz_event_log(OZ_EVT_CTRL_CNF, 0, req_id, 0, rcode);
+ oz_trace("oz_hcd_control_cnf rcode=%u len=%d\n", rcode, data_len);
urb = oz_find_urb_by_id(port, 0, req_id);
if (!urb) {
- oz_trace("URB not found: %p\n", urb);
+ oz_trace("URB not found\n");
return;
}
setup = (struct usb_ctrlrequest *)urb->setup_packet;
@@ -934,6 +866,7 @@ void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data,
wvalue = le16_to_cpu(setup->wValue);
if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
/* Standard requests */
+ oz_display_conf_type(setup->bRequest);
switch (setup->bRequest) {
case USB_REQ_SET_CONFIGURATION:
oz_hcd_complete_set_config(port, urb, rcode,
@@ -944,27 +877,26 @@ void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data,
(u8)windex, (u8)wvalue);
break;
default:
- oz_complete_urb(hcd, urb, 0);
+ oz_complete_urb(hcd, urb, 0, 0);
}
} else {
int copy_len;
- if (data_len) {
- if (data_len <= urb->transfer_buffer_length)
- copy_len = data_len;
- else
- copy_len = urb->transfer_buffer_length;
+ oz_trace("VENDOR-CLASS - cnf\n");
+ if (data_len <= urb->transfer_buffer_length)
+ copy_len = data_len;
+ else
+ copy_len = urb->transfer_buffer_length;
+ if (copy_len)
memcpy(urb->transfer_buffer, data, copy_len);
- urb->actual_length = copy_len;
- }
- oz_complete_urb(hcd, urb, 0);
+ urb->actual_length = copy_len;
+ oz_complete_urb(hcd, urb, 0, 0);
}
}
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
-static int oz_hcd_buffer_data(struct oz_endpoint *ep, const u8 *data,
- int data_len)
+static int oz_hcd_buffer_data(struct oz_endpoint *ep, u8 *data, int data_len)
{
int space;
int copy_len;
@@ -974,10 +906,7 @@ static int oz_hcd_buffer_data(struct oz_endpoint *ep, const u8 *data,
if (space < 0)
space += ep->buffer_size;
if (space < (data_len+1)) {
- oz_trace_msg(I, "EP:%02X u:%d FULL len:%d spc:%d\n",
- ep->ep_num | USB_DIR_IN,
- ep->buffered_units,
- data_len, space);
+ oz_trace("Buffer full\n");
return -1;
}
ep->buffer[ep->in_ix] = (u8)data_len;
@@ -1002,14 +931,14 @@ static int oz_hcd_buffer_data(struct oz_endpoint *ep, const u8 *data,
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
-void oz_hcd_data_ind(void *hport, u8 endpoint, const u8 *data, int data_len)
+void oz_hcd_data_ind(void *hport, u8 endpoint, u8 *data, int data_len)
{
struct oz_port *port = (struct oz_port *)hport;
struct oz_endpoint *ep;
struct oz_hcd *ozhcd = port->ozhcd;
spin_lock_bh(&ozhcd->hcd_lock);
ep = port->in_ep[endpoint & USB_ENDPOINT_NUMBER_MASK];
- if (ep == NULL)
+ if (ep == 0)
goto done;
switch (ep->attrib & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_INT:
@@ -1030,35 +959,12 @@ void oz_hcd_data_ind(void *hport, u8 endpoint, const u8 *data, int data_len)
copy_len = urb->transfer_buffer_length;
memcpy(urb->transfer_buffer, data, copy_len);
urb->actual_length = copy_len;
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
+ oz_complete_urb(port->ozhcd->hcd, urb, 0, 0);
return;
- } else {
- oz_hcd_buffer_data(ep, data, data_len);
}
break;
case USB_ENDPOINT_XFER_ISOC:
- if (oz_hcd_buffer_data(ep, data, data_len) != 0) {
- int len;
- int copy_len;
- while (ep->buffered_units > ep->max_buffer_units) {
- len = ep->buffer[ep->out_ix];
- if (++ep->out_ix == ep->buffer_size)
- ep->out_ix = 0;
- copy_len = ep->buffer_size - ep->out_ix;
- if (copy_len > len)
- copy_len = len;
- if (copy_len < len)
- ep->out_ix = len - copy_len;
- else
- ep->out_ix += copy_len;
-
- if (ep->out_ix == ep->buffer_size)
- ep->out_ix = 0;
-
- ep->buffered_units--;
- }
- ep->flags |= OZ_F_EP_BUFFERING;
- }
+ oz_hcd_buffer_data(ep, data, data_len);
break;
}
done:
@@ -1069,7 +975,7 @@ done:
*/
static inline int oz_usb_get_frame_number(void)
{
- return atomic_inc_return(&g_usb_frame_number);
+ return jiffies_to_msecs(get_jiffies_64());
}
/*------------------------------------------------------------------------------
* Context: softirq
@@ -1085,8 +991,7 @@ int oz_hcd_heartbeat(void *hport)
struct list_head *n;
struct urb *urb;
struct oz_endpoint *ep;
- struct timespec ts, delta;
- getrawmonotonic(&ts);
+ unsigned long now = jiffies;
INIT_LIST_HEAD(&xfr_list);
/* Check the OUT isoc endpoints to see if any URB data can be sent.
*/
@@ -1095,55 +1000,62 @@ int oz_hcd_heartbeat(void *hport)
ep = ep_from_link(e);
if (ep->credit < 0)
continue;
- delta = timespec_sub(ts, ep->timestamp);
- ep->credit += div64_u64(timespec_to_ns(&delta), NSEC_PER_MSEC);
+ ep->credit += (now - ep->last_jiffies);
if (ep->credit > ep->credit_ceiling)
ep->credit = ep->credit_ceiling;
- ep->timestamp = ts;
+ oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, ep->credit);
+ ep->last_jiffies = now;
while (ep->credit && !list_empty(&ep->urb_list)) {
urbl = list_first_entry(&ep->urb_list,
struct oz_urb_link, link);
urb = urbl->urb;
- if ((ep->credit + 1) < urb->number_of_packets)
+ if (ep->credit < urb->number_of_packets)
break;
ep->credit -= urb->number_of_packets;
- if (ep->credit < 0)
- ep->credit = 0;
- list_move_tail(&urbl->link, &xfr_list);
+ oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0,
+ ep->credit);
+ list_del(&urbl->link);
+ list_add_tail(&urbl->link, &xfr_list);
}
}
spin_unlock_bh(&ozhcd->hcd_lock);
/* Send to PD and complete URBs.
*/
list_for_each_safe(e, n, &xfr_list) {
+ unsigned long t;
urbl = container_of(e, struct oz_urb_link, link);
urb = urbl->urb;
+ t = urbl->submit_jiffies;
list_del_init(e);
urb->error_count = 0;
urb->start_frame = oz_usb_get_frame_number();
oz_usb_send_isoc(port->hpd, urbl->ep_num, urb);
oz_free_urb_link(urbl);
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
+ oz_complete_urb(port->ozhcd->hcd, urb, 0, t);
}
/* Check the IN isoc endpoints to see if any URBs can be completed.
*/
spin_lock_bh(&ozhcd->hcd_lock);
list_for_each(e, &port->isoc_in_ep) {
struct oz_endpoint *ep = ep_from_link(e);
-
if (ep->flags & OZ_F_EP_BUFFERING) {
- if (ep->buffered_units >= ep->max_buffer_units) {
+ if (ep->buffered_units * OZ_IN_BUFFERING_UNITS) {
ep->flags &= ~OZ_F_EP_BUFFERING;
ep->credit = 0;
- ep->credit2 = 0;
- ep->timestamp = ts;
+ oz_event_log(OZ_EVT_EP_CREDIT,
+ ep->ep_num | USB_DIR_IN,
+ 0, 0, ep->credit);
+ ep->last_jiffies = now;
ep->start_frame = 0;
+ oz_event_log(OZ_EVT_EP_BUFFERING,
+ ep->ep_num | USB_DIR_IN, 0, 0, 0);
}
continue;
}
- delta = timespec_sub(ts, ep->timestamp);
- ep->credit += div64_u64(timespec_to_ns(&delta)+5000, NSEC_PER_MSEC);
- ep->timestamp = ts;
+ ep->credit += (now - ep->last_jiffies);
+ oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN,
+ 0, 0, ep->credit);
+ ep->last_jiffies = now;
while (!list_empty(&ep->urb_list)) {
struct oz_urb_link *urbl =
list_first_entry(&ep->urb_list,
@@ -1152,6 +1064,8 @@ int oz_hcd_heartbeat(void *hport)
int len = 0;
int copy_len;
int i;
+ if (ep->credit < urb->number_of_packets)
+ break;
if (ep->buffered_units < urb->number_of_packets)
break;
urb->actual_length = 0;
@@ -1182,31 +1096,11 @@ int oz_hcd_heartbeat(void *hport)
urb->error_count = 0;
urb->start_frame = ep->start_frame;
ep->start_frame += urb->number_of_packets;
- list_move_tail(&urbl->link, &xfr_list);
+ list_del(&urbl->link);
+ list_add_tail(&urbl->link, &xfr_list);
ep->credit -= urb->number_of_packets;
- ep->credit2 += urb->number_of_packets;
- }
- if (ep->buffered_units == 0) {
- oz_trace_msg(I, "EP:%02X Buffer under run\n",
- ep->ep_num | USB_DIR_IN);
- ep->flags |= OZ_F_EP_BUFFERING;
- continue;
- }
- if (ep->credit2 >= 1000)
- {
- static int buffered_units=-1;
- static int max_buffer_units=-1;
- {
- int diff = ep->buffered_units - buffered_units;
- oz_trace_msg(I, "u:%d o:%04d b:%d\n",
- ep->credit2,
- ep->credit2 + diff,
- ep->buffered_units);
-
- buffered_units = ep->buffered_units;
- max_buffer_units = ep->max_buffer_units;
- }
- ep->credit2 = 0;
+ oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN,
+ 0, 0, ep->credit);
}
}
if (!list_empty(&port->isoc_out_ep) || !list_empty(&port->isoc_in_ep))
@@ -1219,7 +1113,7 @@ int oz_hcd_heartbeat(void *hport)
urb = urbl->urb;
list_del_init(e);
oz_free_urb_link(urbl);
- oz_complete_urb(port->ozhcd->hcd, urb, 0);
+ oz_complete_urb(port->ozhcd->hcd, urb, 0, 0);
}
/* Check if there are any ep0 requests that have timed out.
* If so resent to PD.
@@ -1231,14 +1125,12 @@ int oz_hcd_heartbeat(void *hport)
spin_lock_bh(&ozhcd->hcd_lock);
list_for_each_safe(e, n, &ep->urb_list) {
urbl = container_of(e, struct oz_urb_link, link);
- if (urbl->submit_counter > EP0_TIMEOUT_COUNTER) {
- oz_trace_msg(M, "URB:%08X timeout %02X\n",
- (unsigned int)((uintptr_t)urbl->urb),
- urbl->req_id);
- list_move_tail(e, &xfr_list);
- urbl->submit_counter = 0;
- } else if (urbl->submit_counter) {
- urbl->submit_counter++;
+ if (time_after(now, urbl->submit_jiffies+HZ/2)) {
+ oz_trace("%ld: Request 0x%p timeout\n",
+ now, urbl->urb);
+ urbl->submit_jiffies = now;
+ list_del(e);
+ list_add_tail(e, &xfr_list);
}
}
if (!list_empty(&ep->urb_list))
@@ -1248,7 +1140,7 @@ int oz_hcd_heartbeat(void *hport)
while (e != &xfr_list) {
urbl = container_of(e, struct oz_urb_link, link);
e = e->next;
- oz_trace_msg(M, "Resending request to PD.\n");
+ oz_trace("Resending request to PD.\n");
oz_process_ep0_urb(ozhcd, urbl->urb, GFP_ATOMIC);
oz_free_urb_link(urbl);
}
@@ -1264,17 +1156,9 @@ static int oz_build_endpoints_for_interface(struct usb_hcd *hcd,
{
struct oz_hcd *ozhcd = port->ozhcd;
int i;
- int if_ix;
+ int if_ix = intf->desc.bInterfaceNumber;
int request_heartbeat = 0;
-
- if (intf == NULL)
- return -ENOMEM;
-
- if_ix = intf->desc.bInterfaceNumber;
oz_trace("interface[%d] = %p\n", if_ix, intf);
- if (if_ix >= port->num_iface || port->iface == NULL)
- return -ENOMEM;
-
for (i = 0; i < intf->desc.bNumEndpoints; i++) {
struct usb_host_endpoint *hep = &intf->endpoint[i];
u8 ep_addr = hep->desc.bEndpointAddress;
@@ -1282,16 +1166,11 @@ static int oz_build_endpoints_for_interface(struct usb_hcd *hcd,
struct oz_endpoint *ep;
int buffer_size = 0;
- if (ep_addr & USB_ENDPOINT_DIR_MASK) {
- switch (hep->desc.bmAttributes &
- USB_ENDPOINT_XFERTYPE_MASK) {
- case USB_ENDPOINT_XFER_ISOC:
- buffer_size = OZ_EP_BUFFER_SIZE_ISOC;
- break;
- case USB_ENDPOINT_XFER_INT:
- buffer_size = OZ_EP_BUFFER_SIZE_INT;
- break;
- }
+ oz_trace("%d bEndpointAddress = %x\n", i, ep_addr);
+ if ((ep_addr & USB_ENDPOINT_DIR_MASK) &&
+ ((hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_ISOC)) {
+ buffer_size = 24*1024;
}
ep = oz_ep_alloc(mem_flags, buffer_size);
@@ -1303,11 +1182,13 @@ static int oz_build_endpoints_for_interface(struct usb_hcd *hcd,
ep->ep_num = ep_num;
if ((ep->attrib & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_ISOC) {
+ oz_trace("wMaxPacketSize = %d\n",
+ hep->desc.wMaxPacketSize);
ep->credit_ceiling = 200;
if (ep_addr & USB_ENDPOINT_DIR_MASK) {
- ep->max_buffer_units =
- oz_get_up_max_buffer_units(port->hpd);
ep->flags |= OZ_F_EP_BUFFERING;
+ oz_event_log(OZ_EVT_EP_BUFFERING,
+ ep->ep_num | USB_DIR_IN, 1, 0, 0);
} else {
ep->flags |= OZ_F_EP_HAVE_STREAM;
if (oz_usb_stream_create(port->hpd, ep_num))
@@ -1363,17 +1244,19 @@ static void oz_clean_endpoints_for_interface(struct usb_hcd *hcd,
*/
if ((mask & (1<<i)) && port->out_ep[i]) {
e = &port->out_ep[i]->link;
- port->out_ep[i] = NULL;
+ port->out_ep[i] = 0;
/* Remove from isoc list if present.
*/
- list_move_tail(e, &ep_list);
+ list_del(e);
+ list_add_tail(e, &ep_list);
}
/* Gather IN endpoints.
*/
if ((mask & (1<<(i+OZ_NB_ENDPOINTS))) && port->in_ep[i]) {
e = &port->in_ep[i]->link;
- port->in_ep[i] = NULL;
- list_move_tail(e, &ep_list);
+ port->in_ep[i] = 0;
+ list_del(e);
+ list_add_tail(e, &ep_list);
}
}
spin_unlock_bh(&ozhcd->hcd_lock);
@@ -1431,8 +1314,9 @@ static void oz_clean_endpoints_for_config(struct usb_hcd *hcd,
oz_clean_endpoints_for_interface(hcd, port, i);
spin_lock_bh(&ozhcd->hcd_lock);
if (port->iface) {
+ oz_trace("Freeing interfaces object.\n");
kfree(port->iface);
- port->iface = NULL;
+ port->iface = 0;
}
port->num_iface = 0;
spin_unlock_bh(&ozhcd->hcd_lock);
@@ -1442,7 +1326,7 @@ static void oz_clean_endpoints_for_config(struct usb_hcd *hcd,
*/
static void *oz_claim_hpd(struct oz_port *port)
{
- void *hpd = NULL;
+ void *hpd = 0;
struct oz_hcd *ozhcd = port->ozhcd;
spin_lock_bh(&ozhcd->hcd_lock);
hpd = port->hpd;
@@ -1461,15 +1345,16 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
unsigned windex;
unsigned wvalue;
unsigned wlength;
- void *hpd = NULL;
+ void *hpd = 0;
u8 req_id;
int rc = 0;
unsigned complete = 0;
int port_ix = -1;
- struct oz_port *port = NULL;
+ struct oz_port *port = 0;
- port_ix = oz_get_port_from_addr(ozhcd, (usb_pipedevice(urb->pipe)));
+ oz_trace2(OZ_TRACE_URB, "%lu: oz_process_ep0_urb(%p)\n", jiffies, urb);
+ port_ix = oz_get_port_from_addr(ozhcd, urb->dev->devnum);
if (port_ix < 0) {
rc = -EPIPE;
goto out;
@@ -1489,10 +1374,17 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
windex = le16_to_cpu(setup->wIndex);
wvalue = le16_to_cpu(setup->wValue);
wlength = le16_to_cpu(setup->wLength);
+ oz_trace2(OZ_TRACE_CTRL_DETAIL, "bRequestType = %x\n",
+ setup->bRequestType);
+ oz_trace2(OZ_TRACE_CTRL_DETAIL, "bRequest = %x\n", setup->bRequest);
+ oz_trace2(OZ_TRACE_CTRL_DETAIL, "wValue = %x\n", wvalue);
+ oz_trace2(OZ_TRACE_CTRL_DETAIL, "wIndex = %x\n", windex);
+ oz_trace2(OZ_TRACE_CTRL_DETAIL, "wLength = %x\n", wlength);
req_id = port->next_req_id++;
hpd = oz_claim_hpd(port);
- if (hpd == NULL) {
+ if (hpd == 0) {
+ oz_trace("Cannot claim port\n");
rc = -EPIPE;
goto out;
}
@@ -1502,23 +1394,34 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
*/
switch (setup->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
+ oz_trace("USB_REQ_GET_DESCRIPTOR - req\n");
break;
case USB_REQ_SET_ADDRESS:
+ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest,
+ 0, 0, setup->bRequestType);
+ oz_trace("USB_REQ_SET_ADDRESS - req\n");
+ oz_trace("Port %d address is 0x%x\n", ozhcd->conn_port,
+ (u8)le16_to_cpu(setup->wValue));
spin_lock_bh(&ozhcd->hcd_lock);
if (ozhcd->conn_port >= 0) {
ozhcd->ports[ozhcd->conn_port].bus_addr =
(u8)le16_to_cpu(setup->wValue);
+ oz_trace("Clearing conn_port\n");
ozhcd->conn_port = -1;
}
spin_unlock_bh(&ozhcd->hcd_lock);
complete = 1;
break;
case USB_REQ_SET_CONFIGURATION:
+ oz_trace("USB_REQ_SET_CONFIGURATION - req\n");
break;
case USB_REQ_GET_CONFIGURATION:
- /* We short circuit this case and reply directly since
+ /* We short curcuit this case and reply directly since
* we have the selected configuration number cached.
*/
+ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0,
+ setup->bRequestType);
+ oz_trace("USB_REQ_GET_CONFIGURATION - reply now\n");
if (urb->transfer_buffer_length >= 1) {
urb->actual_length = 1;
*((u8 *)urb->transfer_buffer) =
@@ -1529,19 +1432,25 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
}
break;
case USB_REQ_GET_INTERFACE:
- /* We short circuit this case and reply directly since
+ /* We short curcuit this case and reply directly since
* we have the selected interface alternative cached.
*/
+ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0,
+ setup->bRequestType);
+ oz_trace("USB_REQ_GET_INTERFACE - reply now\n");
if (urb->transfer_buffer_length >= 1) {
urb->actual_length = 1;
*((u8 *)urb->transfer_buffer) =
port->iface[(u8)windex].alt;
+ oz_trace("interface = %d alt = %d\n",
+ windex, port->iface[(u8)windex].alt);
complete = 1;
} else {
rc = -EPIPE;
}
break;
case USB_REQ_SET_INTERFACE:
+ oz_trace("USB_REQ_SET_INTERFACE - req\n");
break;
}
}
@@ -1549,13 +1458,12 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
int data_len = 0;
if ((setup->bRequestType & USB_DIR_IN) == 0)
data_len = wlength;
- urb->actual_length = data_len;
if (oz_usb_control_req(port->hpd, req_id, setup,
urb->transfer_buffer, data_len)) {
rc = -ENOMEM;
} else {
/* Note: we are queuing the request after we have
- * submitted it to be transmitted. If the request were
+ * submitted it to be tranmitted. If the request were
* to complete before we queued it then it would not
* be found in the queue. It seems impossible for
* this to happen but if it did the request would
@@ -1572,7 +1480,8 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb,
oz_usb_put(hpd);
out:
if (rc || complete) {
- oz_complete_urb(ozhcd->hcd, urb, rc);
+ oz_trace("Completing request locally\n");
+ oz_complete_urb(ozhcd->hcd, urb, rc, 0);
} else {
oz_usb_request_heartbeat(port->hpd);
}
@@ -1597,14 +1506,14 @@ static int oz_urb_process(struct oz_hcd *ozhcd, struct urb *urb)
/* Check if there is a device at the port - refuse if not.
*/
if ((port->flags & OZ_PORT_F_PRESENT) == 0)
- return -ENODEV;
+ return -EPIPE;
ep_addr = usb_pipeendpoint(urb->pipe);
if (ep_addr) {
/* If the request is not for EP0 then queue it.
*/
if (oz_enqueue_ep_urb(port, ep_addr, usb_pipein(urb->pipe),
urb, 0))
- rc = -ENOENT;
+ rc = -EPIPE;
} else {
oz_process_ep0_urb(ozhcd, urb, GFP_ATOMIC);
}
@@ -1619,7 +1528,7 @@ static void oz_urb_process_tasklet(unsigned long unused)
struct urb *urb;
struct oz_hcd *ozhcd = oz_hcd_claim();
int rc = 0;
- if (ozhcd == NULL)
+ if (ozhcd == 0)
return;
/* This is called from a tasklet so is in softirq context but the urb
* list is filled from any context so we need to lock
@@ -1636,7 +1545,7 @@ static void oz_urb_process_tasklet(unsigned long unused)
oz_free_urb_link(urbl);
rc = oz_urb_process(ozhcd, urb);
if (rc)
- oz_complete_urb(ozhcd->hcd, urb, rc);
+ oz_complete_urb(ozhcd->hcd, urb, rc, 0);
spin_lock_irqsave(&g_tasklet_lock, irq_state);
}
spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
@@ -1653,18 +1562,18 @@ static void oz_urb_process_tasklet(unsigned long unused)
*/
static void oz_urb_cancel(struct oz_port *port, u8 ep_num, struct urb *urb)
{
- struct oz_urb_link *urbl = NULL;
+ struct oz_urb_link *urbl = 0;
struct list_head *e;
struct oz_hcd *ozhcd;
unsigned long irq_state;
u8 ix;
- if (port == NULL) {
- oz_trace("%s: urb=%p port is null\n", __func__, urb);
+ if (port == 0) {
+ oz_trace("ERRORERROR: oz_urb_cancel(%p) port is null\n", urb);
return;
}
ozhcd = port->ozhcd;
- if (ozhcd == NULL) {
- oz_trace("%s: urb=%p ozhcd is null\n", __func__, urb);
+ if (ozhcd == 0) {
+ oz_trace("ERRORERROR: oz_urb_cancel(%p) ozhcd is null\n", urb);
return;
}
@@ -1680,7 +1589,7 @@ static void oz_urb_cancel(struct oz_port *port, u8 ep_num, struct urb *urb)
}
}
spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
- urbl = NULL;
+ urbl = 0;
/* Look in the orphanage.
*/
@@ -1689,12 +1598,12 @@ static void oz_urb_cancel(struct oz_port *port, u8 ep_num, struct urb *urb)
urbl = container_of(e, struct oz_urb_link, link);
if (urbl->urb == urb) {
list_del(e);
- oz_trace("Found urb in orphanage urb=%p\n", urb);
+ oz_trace("Found urb in orphanage\n");
goto out;
}
}
ix = (ep_num & 0xf);
- urbl = NULL;
+ urbl = 0;
if ((ep_num & USB_DIR_IN) && ix)
urbl = oz_remove_urb(port->in_ep[ix], urb);
else
@@ -1705,7 +1614,7 @@ out2:
if (urbl) {
urb->actual_length = 0;
oz_free_urb_link(urbl);
- oz_complete_urb(ozhcd->hcd, urb, -ENOENT);
+ oz_complete_urb(ozhcd->hcd, urb, -EPIPE, 0);
}
}
/*------------------------------------------------------------------------------
@@ -1716,7 +1625,7 @@ static void oz_urb_cancel_tasklet(unsigned long unused)
unsigned long irq_state;
struct urb *urb;
struct oz_hcd *ozhcd = oz_hcd_claim();
- if (ozhcd == NULL)
+ if (ozhcd == 0)
return;
spin_lock_irqsave(&g_tasklet_lock, irq_state);
while (!list_empty(&ozhcd->urb_cancel_list)) {
@@ -1745,7 +1654,7 @@ static void oz_hcd_clear_orphanage(struct oz_hcd *ozhcd, int status)
urbl = list_first_entry(&ozhcd->orphanage,
struct oz_urb_link, link);
list_del(&urbl->link);
- oz_complete_urb(ozhcd->hcd, urbl->urb, status);
+ oz_complete_urb(ozhcd->hcd, urbl->urb, status, 0);
oz_free_urb_link(urbl);
}
}
@@ -1755,6 +1664,7 @@ static void oz_hcd_clear_orphanage(struct oz_hcd *ozhcd, int status)
*/
static int oz_hcd_start(struct usb_hcd *hcd)
{
+ oz_trace("oz_hcd_start()\n");
hcd->power_budget = 200;
hcd->state = HC_STATE_RUNNING;
hcd->uses_new_polling = 1;
@@ -1765,16 +1675,30 @@ static int oz_hcd_start(struct usb_hcd *hcd)
*/
static void oz_hcd_stop(struct usb_hcd *hcd)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_hcd_stop()\n");
}
/*------------------------------------------------------------------------------
* Context: unknown
*/
static void oz_hcd_shutdown(struct usb_hcd *hcd)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_hcd_shutdown()\n");
}
/*------------------------------------------------------------------------------
+ * Context: any
+ */
+#ifdef WANT_EVENT_TRACE
+static u8 oz_get_irq_ctx(void)
+{
+ u8 irq_info = 0;
+ if (in_interrupt())
+ irq_info |= 1;
+ if (in_irq())
+ irq_info |= 2;
+ return irq_info;
+}
+#endif /* WANT_EVENT_TRACE */
+/*------------------------------------------------------------------------------
* Called to queue an urb for the device.
* This function should return a non-zero error code if it fails the urb but
* should not call usb_hcd_giveback_urb().
@@ -1789,34 +1713,39 @@ static int oz_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
struct oz_port *port;
unsigned long irq_state;
struct oz_urb_link *urbl;
- if (unlikely(ozhcd == NULL)) {
- oz_trace("Refused urb(%p) not ozhcd.\n", urb);
- return -ENODEV;
+ oz_trace2(OZ_TRACE_URB, "%lu: oz_hcd_urb_enqueue(%p)\n",
+ jiffies, urb);
+ oz_event_log(OZ_EVT_URB_SUBMIT, oz_get_irq_ctx(),
+ (u16)urb->number_of_packets, urb, urb->pipe);
+ if (unlikely(ozhcd == 0)) {
+ oz_trace2(OZ_TRACE_URB, "%lu: Refused urb(%p) not ozhcd.\n",
+ jiffies, urb);
+ return -EPIPE;
}
if (unlikely(hcd->state != HC_STATE_RUNNING)) {
- oz_trace("Refused urb(%p) not running.\n", urb);
- return -ENODEV;
+ oz_trace2(OZ_TRACE_URB, "%lu: Refused urb(%p) not running.\n",
+ jiffies, urb);
+ return -EPIPE;
}
- port_ix = oz_get_port_from_addr(ozhcd, (usb_pipedevice(urb->pipe)));
+ port_ix = oz_get_port_from_addr(ozhcd, urb->dev->devnum);
if (port_ix < 0)
- return -ENODEV;
+ return -EPIPE;
port = &ozhcd->ports[port_ix];
- if (port == NULL)
- return -ENODEV;
+ if (port == 0)
+ return -EPIPE;
if ((port->flags & OZ_PORT_F_PRESENT) == 0) {
oz_trace("Refusing URB port_ix = %d devnum = %d\n",
port_ix, urb->dev->devnum);
- return -ENODEV;
+ return -EPIPE;
}
urb->hcpriv = port;
/* Put request in queue for processing by tasklet.
*/
urbl = oz_alloc_urb_link();
- if (unlikely(urbl == NULL))
+ if (unlikely(urbl == 0))
return -ENOMEM;
urbl->urb = urb;
spin_lock_irqsave(&g_tasklet_lock, irq_state);
- oz_trace_urb_in(urb);
rc = usb_hcd_link_urb_to_ep(hcd, urb);
if (unlikely(rc)) {
spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
@@ -1835,19 +1764,22 @@ static int oz_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
static struct oz_urb_link *oz_remove_urb(struct oz_endpoint *ep,
struct urb *urb)
{
- struct oz_urb_link *urbl = NULL;
+ struct oz_urb_link *urbl = 0;
struct list_head *e;
- if (unlikely(ep == NULL))
+ if (unlikely(ep == 0))
return 0;
list_for_each(e, &ep->urb_list) {
urbl = container_of(e, struct oz_urb_link, link);
if (urbl->urb == urb) {
list_del_init(e);
if (usb_pipeisoc(urb->pipe)) {
- oz_trace_msg(M, "oz_remove_urb:%p\n", urb);
ep->credit -= urb->number_of_packets;
if (ep->credit < 0)
ep->credit = 0;
+ oz_event_log(OZ_EVT_EP_CREDIT,
+ usb_pipein(urb->pipe) ?
+ (ep->ep_num | USB_DIR_IN) : ep->ep_num,
+ 0, 0, ep->credit);
}
return urbl;
}
@@ -1861,12 +1793,12 @@ static struct oz_urb_link *oz_remove_urb(struct oz_endpoint *ep,
static int oz_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
{
struct oz_hcd *ozhcd = oz_hcd_private(hcd);
- struct oz_urb_link *urbl = NULL;
+ struct oz_urb_link *urbl = 0;
int rc;
unsigned long irq_state;
-
+ oz_trace2(OZ_TRACE_URB, "%lu: oz_hcd_urb_dequeue(%p)\n", jiffies, urb);
urbl = oz_alloc_urb_link();
- if (unlikely(urbl == NULL))
+ if (unlikely(urbl == 0))
return -ENOMEM;
spin_lock_irqsave(&g_tasklet_lock, irq_state);
/* The following function checks the urb is still in the queue
@@ -1900,7 +1832,7 @@ static int oz_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
static void oz_hcd_endpoint_disable(struct usb_hcd *hcd,
struct usb_host_endpoint *ep)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_hcd_endpoint_disable\n");
}
/*------------------------------------------------------------------------------
* Context: unknown
@@ -1908,13 +1840,14 @@ static void oz_hcd_endpoint_disable(struct usb_hcd *hcd,
static void oz_hcd_endpoint_reset(struct usb_hcd *hcd,
struct usb_host_endpoint *ep)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_hcd_endpoint_reset\n");
}
/*------------------------------------------------------------------------------
* Context: unknown
*/
static int oz_hcd_get_frame_number(struct usb_hcd *hcd)
{
+ oz_trace("oz_hcd_get_frame_number\n");
return oz_usb_get_frame_number();
}
/*------------------------------------------------------------------------------
@@ -1927,24 +1860,19 @@ static int oz_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
struct oz_hcd *ozhcd = oz_hcd_private(hcd);
int i;
+ oz_trace2(OZ_TRACE_HUB, "oz_hcd_hub_status_data()\n");
buf[0] = 0;
- buf[1] = 0;
+
spin_lock_bh(&ozhcd->hcd_lock);
for (i = 0; i < OZ_NB_PORTS; i++) {
if (ozhcd->ports[i].flags & OZ_PORT_F_CHANGED) {
- if (i < 7)
- buf[0] |= 1<<(i+1);
- else
- buf[1] |= 1<<(i-7);
+ oz_trace2(OZ_TRACE_HUB, "Port %d changed\n", i);
+ ozhcd->ports[i].flags &= ~OZ_PORT_F_CHANGED;
+ buf[0] |= 1<<(i+1);
}
}
- oz_trace_msg(H, "HUBSTS : %02X%02X\n",
- (unsigned char)(buf[1]), (unsigned char)(buf[0]));
spin_unlock_bh(&ozhcd->hcd_lock);
- if (buf[1] != 0 || buf[0] != 0)
- return 2;
- else
- return 0;
+ return buf[0] ? 1 : 0;
}
/*------------------------------------------------------------------------------
* Context: process
@@ -1952,6 +1880,7 @@ static int oz_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
static void oz_get_hub_descriptor(struct usb_hcd *hcd,
struct usb_hub_descriptor *desc)
{
+ oz_trace2(OZ_TRACE_HUB, "GetHubDescriptor\n");
memset(desc, 0, sizeof(*desc));
desc->bDescriptorType = 0x29;
desc->bDescLength = 9;
@@ -1970,65 +1899,59 @@ static int oz_set_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex)
struct oz_hcd *ozhcd = oz_hcd_private(hcd);
unsigned set_bits = 0;
unsigned clear_bits = 0;
- void *hpd;
-
+ oz_trace2(OZ_TRACE_HUB, "SetPortFeature\n");
if ((port_id < 1) || (port_id > OZ_NB_PORTS))
- return -ENODEV;
+ return -EPIPE;
port = &ozhcd->ports[port_id-1];
switch (wvalue) {
case USB_PORT_FEAT_CONNECTION:
- oz_trace("USB_PORT_FEAT_CONNECTION\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_CONNECTION\n");
break;
case USB_PORT_FEAT_ENABLE:
- oz_trace("USB_PORT_FEAT_ENABLE\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_ENABLE\n");
break;
case USB_PORT_FEAT_SUSPEND:
- oz_trace("USB_PORT_FEAT_SUSPEND\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_SUSPEND\n");
break;
case USB_PORT_FEAT_OVER_CURRENT:
- oz_trace("USB_PORT_FEAT_OVER_CURRENT\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_OVER_CURRENT\n");
break;
case USB_PORT_FEAT_RESET:
- oz_trace("USB_PORT_FEAT_RESET\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_RESET\n");
set_bits = USB_PORT_STAT_ENABLE | (USB_PORT_STAT_C_RESET<<16);
clear_bits = USB_PORT_STAT_RESET;
ozhcd->ports[port_id-1].bus_addr = 0;
- hpd = oz_claim_hpd(&ozhcd->ports[port_id-1]);
- if (hpd != NULL) {
- oz_usb_reset_device(hpd);
- oz_usb_put(hpd);
- }
break;
case USB_PORT_FEAT_POWER:
- oz_trace("USB_PORT_FEAT_POWER\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_POWER\n");
set_bits |= USB_PORT_STAT_POWER;
break;
case USB_PORT_FEAT_LOWSPEED:
- oz_trace("USB_PORT_FEAT_LOWSPEED\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_LOWSPEED\n");
break;
case USB_PORT_FEAT_C_CONNECTION:
- oz_trace("USB_PORT_FEAT_C_CONNECTION\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_CONNECTION\n");
break;
case USB_PORT_FEAT_C_ENABLE:
- oz_trace("USB_PORT_FEAT_C_ENABLE\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_ENABLE\n");
break;
case USB_PORT_FEAT_C_SUSPEND:
- oz_trace("USB_PORT_FEAT_C_SUSPEND\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_SUSPEND\n");
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
- oz_trace("USB_PORT_FEAT_C_OVER_CURRENT\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_OVER_CURRENT\n");
break;
case USB_PORT_FEAT_C_RESET:
- oz_trace("USB_PORT_FEAT_C_RESET\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_RESET\n");
break;
case USB_PORT_FEAT_TEST:
- oz_trace("USB_PORT_FEAT_TEST\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_TEST\n");
break;
case USB_PORT_FEAT_INDICATOR:
- oz_trace("USB_PORT_FEAT_INDICATOR\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_INDICATOR\n");
break;
default:
- oz_trace("Other %d\n", wvalue);
+ oz_trace2(OZ_TRACE_HUB, "Other %d\n", wvalue);
break;
}
if (set_bits || clear_bits) {
@@ -2037,9 +1960,8 @@ static int oz_set_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex)
port->status |= set_bits;
spin_unlock_bh(&port->port_lock);
}
-
- oz_trace_msg(H, "Port[%d]: %08X\n", port_id,
- ozhcd->ports[port_id-1].status);
+ oz_trace2(OZ_TRACE_HUB, "Port[%d] status = 0x%x\n", port_id,
+ port->status);
return err;
}
/*------------------------------------------------------------------------------
@@ -2052,60 +1974,60 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex)
u8 port_id = (u8)windex;
struct oz_hcd *ozhcd = oz_hcd_private(hcd);
unsigned clear_bits = 0;
-
+ oz_trace2(OZ_TRACE_HUB, "ClearPortFeature\n");
if ((port_id < 1) || (port_id > OZ_NB_PORTS))
- return -ENODEV;
+ return -EPIPE;
port = &ozhcd->ports[port_id-1];
switch (wvalue) {
case USB_PORT_FEAT_CONNECTION:
- oz_trace("USB_PORT_FEAT_CONNECTION\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_CONNECTION\n");
break;
case USB_PORT_FEAT_ENABLE:
- oz_trace("USB_PORT_FEAT_ENABLE\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_ENABLE\n");
clear_bits = USB_PORT_STAT_ENABLE;
break;
case USB_PORT_FEAT_SUSPEND:
- oz_trace("USB_PORT_FEAT_SUSPEND\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_SUSPEND\n");
break;
case USB_PORT_FEAT_OVER_CURRENT:
- oz_trace("USB_PORT_FEAT_OVER_CURRENT\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_OVER_CURRENT\n");
break;
case USB_PORT_FEAT_RESET:
- oz_trace("USB_PORT_FEAT_RESET\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_RESET\n");
break;
case USB_PORT_FEAT_POWER:
- oz_trace("USB_PORT_FEAT_POWER\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_POWER\n");
clear_bits |= USB_PORT_STAT_POWER;
break;
case USB_PORT_FEAT_LOWSPEED:
- oz_trace("USB_PORT_FEAT_LOWSPEED\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_LOWSPEED\n");
break;
case USB_PORT_FEAT_C_CONNECTION:
- oz_trace("USB_PORT_FEAT_C_CONNECTION\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_CONNECTION\n");
clear_bits = (USB_PORT_STAT_C_CONNECTION << 16);
break;
case USB_PORT_FEAT_C_ENABLE:
- oz_trace("USB_PORT_FEAT_C_ENABLE\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_ENABLE\n");
clear_bits = (USB_PORT_STAT_C_ENABLE << 16);
break;
case USB_PORT_FEAT_C_SUSPEND:
- oz_trace("USB_PORT_FEAT_C_SUSPEND\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_SUSPEND\n");
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
- oz_trace("USB_PORT_FEAT_C_OVER_CURRENT\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_OVER_CURRENT\n");
break;
case USB_PORT_FEAT_C_RESET:
- oz_trace("USB_PORT_FEAT_C_RESET\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_C_RESET\n");
clear_bits = (USB_PORT_FEAT_C_RESET << 16);
break;
case USB_PORT_FEAT_TEST:
- oz_trace("USB_PORT_FEAT_TEST\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_TEST\n");
break;
case USB_PORT_FEAT_INDICATOR:
- oz_trace("USB_PORT_FEAT_INDICATOR\n");
+ oz_trace2(OZ_TRACE_HUB, "USB_PORT_FEAT_INDICATOR\n");
break;
default:
- oz_trace("Other %d\n", wvalue);
+ oz_trace2(OZ_TRACE_HUB, "Other %d\n", wvalue);
break;
}
if (clear_bits) {
@@ -2113,8 +2035,7 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex)
port->status &= ~clear_bits;
spin_unlock_bh(&port->port_lock);
}
-
- oz_trace_msg(H, "Port[%d]: %08X\n", port_id,
+ oz_trace2(OZ_TRACE_HUB, "Port[%d] status = 0x%x\n", port_id,
ozhcd->ports[port_id-1].status);
return err;
}
@@ -2126,12 +2047,12 @@ static int oz_get_port_status(struct usb_hcd *hcd, u16 windex, char *buf)
struct oz_hcd *ozhcd;
u32 status = 0;
if ((windex < 1) || (windex > OZ_NB_PORTS))
- return -ENODEV;
+ return -EPIPE;
ozhcd = oz_hcd_private(hcd);
- ozhcd->ports[windex-1].flags &= ~OZ_PORT_F_CHANGED;
+ oz_trace2(OZ_TRACE_HUB, "GetPortStatus windex = %d\n", windex);
status = ozhcd->ports[windex-1].status;
put_unaligned(cpu_to_le32(status), (__le32 *)buf);
- oz_trace_msg(H, "Port[%d]: %08X\n", windex, status);
+ oz_trace2(OZ_TRACE_HUB, "Port[%d] status = %x\n", windex, status);
return 0;
}
/*------------------------------------------------------------------------------
@@ -2141,13 +2062,10 @@ static int oz_hcd_hub_control(struct usb_hcd *hcd, u16 req_type, u16 wvalue,
u16 windex, char *buf, u16 wlength)
{
int err = 0;
-
- oz_trace_msg(H, "HUBCTL: %04X %04X %04X %04X\n",
- req_type, wvalue, windex, wlength);
-
+ oz_trace2(OZ_TRACE_HUB, "oz_hcd_hub_control()\n");
switch (req_type) {
case ClearHubFeature:
- oz_trace("ClearHubFeature: %d\n", req_type);
+ oz_trace2(OZ_TRACE_HUB, "ClearHubFeature: %d\n", req_type);
break;
case ClearPortFeature:
err = oz_clear_port_feature(hcd, wvalue, windex);
@@ -2156,7 +2074,7 @@ static int oz_hcd_hub_control(struct usb_hcd *hcd, u16 req_type, u16 wvalue,
oz_get_hub_descriptor(hcd, (struct usb_hub_descriptor *)buf);
break;
case GetHubStatus:
- oz_trace("GetHubStatus: req_type = 0x%x\n",
+ oz_trace2(OZ_TRACE_HUB, "GetHubStatus: req_type = 0x%x\n",
req_type);
put_unaligned(__constant_cpu_to_le32(0), (__le32 *)buf);
break;
@@ -2164,13 +2082,13 @@ static int oz_hcd_hub_control(struct usb_hcd *hcd, u16 req_type, u16 wvalue,
err = oz_get_port_status(hcd, windex, buf);
break;
case SetHubFeature:
- oz_trace("SetHubFeature: %d\n", req_type);
+ oz_trace2(OZ_TRACE_HUB, "SetHubFeature: %d\n", req_type);
break;
case SetPortFeature:
err = oz_set_port_feature(hcd, wvalue, windex);
break;
default:
- oz_trace("Other: %d\n", req_type);
+ oz_trace2(OZ_TRACE_HUB, "Other: %d\n", req_type);
break;
}
return err;
@@ -2181,7 +2099,7 @@ static int oz_hcd_hub_control(struct usb_hcd *hcd, u16 req_type, u16 wvalue,
static int oz_hcd_bus_suspend(struct usb_hcd *hcd)
{
struct oz_hcd *ozhcd;
-
+ oz_trace2(OZ_TRACE_HUB, "oz_hcd_hub_suspend()\n");
ozhcd = oz_hcd_private(hcd);
spin_lock_bh(&ozhcd->hcd_lock);
hcd->state = HC_STATE_SUSPENDED;
@@ -2195,7 +2113,7 @@ static int oz_hcd_bus_suspend(struct usb_hcd *hcd)
static int oz_hcd_bus_resume(struct usb_hcd *hcd)
{
struct oz_hcd *ozhcd;
-
+ oz_trace2(OZ_TRACE_HUB, "oz_hcd_hub_resume()\n");
ozhcd = oz_hcd_private(hcd);
spin_lock_bh(&ozhcd->hcd_lock);
ozhcd->flags &= ~OZ_HDC_F_SUSPENDED;
@@ -2207,7 +2125,7 @@ static int oz_hcd_bus_resume(struct usb_hcd *hcd)
*/
static void oz_plat_shutdown(struct platform_device *dev)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_plat_shutdown()\n");
}
/*------------------------------------------------------------------------------
* Context: process
@@ -2218,10 +2136,10 @@ static int oz_plat_probe(struct platform_device *dev)
int err;
struct usb_hcd *hcd;
struct oz_hcd *ozhcd;
-
+ oz_trace("oz_plat_probe()\n");
hcd = usb_create_hcd(&g_oz_hc_drv, &dev->dev, dev_name(&dev->dev));
- if (hcd == NULL) {
- oz_trace("Failed to created hcd object\n");
+ if (hcd == 0) {
+ oz_trace("Failed to created hcd object OK\n");
return -ENOMEM;
}
ozhcd = oz_hcd_private(hcd);
@@ -2240,9 +2158,9 @@ static int oz_plat_probe(struct platform_device *dev)
port->bus_addr = 0xff;
spin_lock_init(&port->port_lock);
}
- err = usb_add_hcd(hcd, -1, 0);
+ err = usb_add_hcd(hcd, 0, 0);
if (err) {
- oz_trace("Failed to add hcd object\n");
+ oz_trace("Failed to add hcd object OK\n");
usb_put_hcd(hcd);
return -1;
}
@@ -2258,15 +2176,17 @@ static int oz_plat_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct oz_hcd *ozhcd;
-
- if (hcd == NULL)
+ oz_trace("oz_plat_remove()\n");
+ if (hcd == 0)
return -1;
ozhcd = oz_hcd_private(hcd);
spin_lock_bh(&g_hcdlock);
if (ozhcd == g_ozhcd)
- g_ozhcd = NULL;
+ g_ozhcd = 0;
spin_unlock_bh(&g_hcdlock);
- oz_hcd_clear_orphanage(ozhcd, -ENODEV);
+ oz_trace("Clearing orphanage\n");
+ oz_hcd_clear_orphanage(ozhcd, -EPIPE);
+ oz_trace("Removing hcd\n");
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
oz_empty_link_pool();
@@ -2277,7 +2197,7 @@ static int oz_plat_remove(struct platform_device *dev)
*/
static int oz_plat_suspend(struct platform_device *dev, pm_message_t msg)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_plat_suspend()\n");
return 0;
}
/*------------------------------------------------------------------------------
@@ -2285,7 +2205,7 @@ static int oz_plat_suspend(struct platform_device *dev, pm_message_t msg)
*/
static int oz_plat_resume(struct platform_device *dev)
{
- oz_trace("%s:\n", __func__);
+ oz_trace("oz_plat_resume()\n");
return 0;
}
/*------------------------------------------------------------------------------
@@ -2296,20 +2216,22 @@ int oz_hcd_init(void)
int err;
if (usb_disabled())
return -ENODEV;
-
tasklet_init(&g_urb_process_tasklet, oz_urb_process_tasklet, 0);
tasklet_init(&g_urb_cancel_tasklet, oz_urb_cancel_tasklet, 0);
err = platform_driver_register(&g_oz_plat_drv);
+ oz_trace("platform_driver_register() returned %d\n", err);
if (err)
goto error;
g_plat_dev = platform_device_alloc(OZ_PLAT_DEV_NAME, -1);
- if (g_plat_dev == NULL) {
+ if (g_plat_dev == 0) {
err = -ENOMEM;
goto error1;
}
+ oz_trace("platform_device_alloc() succeeded\n");
err = platform_device_add(g_plat_dev);
if (err)
goto error2;
+ oz_trace("platform_device_add() succeeded\n");
return 0;
error2:
platform_device_put(g_plat_dev);
@@ -2318,7 +2240,7 @@ error1:
error:
tasklet_disable(&g_urb_process_tasklet);
tasklet_disable(&g_urb_cancel_tasklet);
- oz_trace("HCD Init failed: %d\n", err);
+ oz_trace("oz_hcd_init() failed %d\n", err);
return err;
}
/*------------------------------------------------------------------------------
@@ -2326,9 +2248,8 @@ error:
*/
void oz_hcd_term(void)
{
- msleep(OZ_HUB_DEBOUNCE_TIMEOUT);
- tasklet_kill(&g_urb_process_tasklet);
- tasklet_kill(&g_urb_cancel_tasklet);
+ tasklet_disable(&g_urb_process_tasklet);
+ tasklet_disable(&g_urb_cancel_tasklet);
platform_device_unregister(g_plat_dev);
platform_driver_unregister(&g_oz_plat_drv);
oz_trace("Pending urbs:%d\n", atomic_read(&g_pending_urbs));
diff --git a/drivers/staging/ozwpan/ozkobject.c b/drivers/staging/ozwpan/ozkobject.c
deleted file mode 100644
index 9b85ef55da15..000000000000
--- a/drivers/staging/ozwpan/ozkobject.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/* -----------------------------------------------------------------------------
- * 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/netdevice.h>
-#include <linux/sysfs.h>
-#include <linux/version.h>
-#include "ozpd.h"
-#include "ozcdev.h"
-#include "ozproto.h"
-#include "oztrace.h"
-#include "ozkobject.h"
-#include "ozappif.h"
-
-static ssize_t devices_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- int i, count, s;
- unsigned state;
- int ret = 0;
- u8 devices[(ETH_ALEN + sizeof(unsigned)) * OZ_MAX_PDS];
-
- count = oz_get_pd_status_list(devices, OZ_MAX_PDS);
- s = sprintf(buf, "Total: %d\n", count);
- buf += s;
- ret += s;
- for (i = 0; i < count; i++) {
- ret += sprintf(buf, "%pm", (void *)&devices[i * (ETH_ALEN +
- sizeof(unsigned))]);
- buf += (ETH_ALEN * 2);
- ret += sprintf(buf++, "\t");
- memcpy(&state, &devices[(i * (ETH_ALEN + sizeof(unsigned))) +
- ETH_ALEN], sizeof(unsigned));
- switch (state) {
- case OZ_PD_S_IDLE:
- s = sprintf(buf, "IDLE\n");
- buf += s;
- ret += s;
- break;
- case OZ_PD_S_CONNECTED:
- s = sprintf(buf, "CONNECTED\n");
- buf += s;
- ret += s;
- break;
- case OZ_PD_S_STOPPED:
- s = sprintf(buf, "STOPPED\n");
- buf += s;
- ret += s;
- break;
- case OZ_PD_S_SLEEP:
- s = sprintf(buf, "SLEEP\n");
- buf += s;
- ret += s;
- break;
- }
-
- }
- return ret;
-}
-
-u8 oz_str_to_hex(const char *st)
-{
- u8 t1 = 0;
- char arr[3];
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- char **pt = NULL;
-#endif
-
- memcpy(arr, st, 2);
- arr[2] = '\0';
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- t1 = (u8) simple_strtoul(arr, pt, 16);
-#else
- if (kstrtou8(arr, 16, &t1))
- oz_trace("Invalid string received\n");
-#endif
- return t1;
-}
-
-static ssize_t stop_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
-{
- int i;
- u8 mac_addr[6];
- struct oz_pd *pd;
-
- if (count >= 12) {
- for (i = 0; i < 6; i++) {
- mac_addr[i] = oz_str_to_hex(buf);
- buf += 2;
- }
-
- pd = oz_pd_find(mac_addr);
- if (pd && (!(pd->state & OZ_PD_S_CONNECTED))) {
- oz_pd_stop(pd);
- oz_pd_put(pd);
- } else
- oz_pd_put(pd);
- }
-
- return count;
-}
-
-static ssize_t select_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- int i;
- int ret = 0;
- u8 mac_addr[6];
-
- oz_get_active_pd(mac_addr);
-
- for (i = 0; i < 6; i++) {
- ret += sprintf(buf, "%02x", mac_addr[i]);
- buf += 2;
- }
- ret += sprintf(buf, "\n");
- return ret;
-}
-
-static ssize_t select_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
-{
- int i;
- u8 mac_addr[6];
-
- if (count >= 12) {
- for (i = 0; i < 6; i++) {
- mac_addr[i] = oz_str_to_hex(buf);
- buf += 2;
- }
-
- oz_set_active_pd(mac_addr);
- }
- return count;
-}
-
-static ssize_t bind_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- char nw_list[OZ_MAX_NW_IF * OZ_MAX_BINDING_LEN] = {0};
- int count, i, s;
- int ret = 0;
-
- count = oz_get_binding_list(nw_list, OZ_MAX_NW_IF);
- for (i = 0; i < count; i++) {
- s = sprintf(buf, "%s\n", nw_list + (i * OZ_MAX_BINDING_LEN));
- ret += s;
- buf += s;
- }
- return ret;
-}
-
-static ssize_t bind_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
-{
- char name[OZ_MAX_BINDING_LEN];
- char *p = NULL;
-
- memcpy(name, buf + 2, count);
- p = strstr(name, "\n");
- if (p)
- *p = '\0';
-
- switch (*buf) {
- case 'a':
- oz_binding_add(name);
- break;
- case 'r':
- oz_binding_remove(name);
- break;
- }
- return count;
-}
-
-static ssize_t mode_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- u8 mode;
- int ret;
-
- mode = oz_get_serial_mode();
- ret = sprintf(buf, "0x%02x\n", mode);
- return ret;
-}
-
-static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
-{
- u8 new_mode;
- if (count >= 4) {
- new_mode = oz_str_to_hex(buf + 2);
- oz_set_serial_mode(new_mode);
- } else {
- printk(KERN_ERR "Invalid mode\n");
- }
- return count;
-}
-
-static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- int ret = 0;
- u32 debug = g_debug;
- int i;
-
- for (i = 0; i < 'Z'-'A'+1; i++) {
- if (debug & (1<<i))
- *(buf + ret++) = 'A' + i;
- }
-
- return ret;
-}
-
-static ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
-{
- u32 new_debug = 0;
- const char *t = buf;
-
- if (count > 1 && count < 33) {
- while (*t) {
- char symbol = *t;
- if ('A' <= symbol && symbol <= 'Z')
- new_debug |= 1<<(symbol - 'A');
- t++;
- }
-
- if (0 != new_debug) {
- g_debug = new_debug;
- }
- else
- printk(KERN_ERR "Invalid debug\n");
- } else {
- if (1 == count && *t == '\0')
- g_debug = 0;
- }
-
- return count;
-}
-
-static ssize_t fptr_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- int ret;
-
- ret = sprintf(buf, "p->oz_protocol_init = 0x%p\n", oz_protocol_init);
- return ret;
-
-}
-
-static struct kobj_attribute devices_attribute =
- __ATTR(devices, 0400, devices_show, NULL);
-
-static struct kobj_attribute stop_attribute =
- __ATTR(stop, 0200, NULL, stop_store);
-
-static struct kobj_attribute select_attribute =
- __ATTR(select, 0600, select_show, select_store);
-
-static struct kobj_attribute bind_attribute =
- __ATTR(bind, 0600, bind_show, bind_store);
-
-static struct kobj_attribute mode_attribute =
- __ATTR(mode, 0600, mode_show, mode_store);
-
-static struct kobj_attribute debug_attribute =
- __ATTR(debug, 0600, debug_show, debug_store);
-
-static struct kobj_attribute fptr_attribute =
- __ATTR(fptr, 0400, fptr_show, NULL);
-
-static struct attribute *attrs[] = {
- &devices_attribute.attr,
- &stop_attribute.attr,
- &select_attribute.attr,
- &bind_attribute.attr,
- &mode_attribute.attr,
- &debug_attribute.attr,
- &fptr_attribute.attr,
- NULL,
-};
-
-static struct attribute_group attr_group = {
- .attrs = attrs,
-};
-
-void oz_create_sys_entry(void)
-{
- int retval;
-
- retval = sysfs_create_group(&g_oz_wpan_dev->kobj, &attr_group);
- if (retval)
- oz_trace("Can not create attribute group\n");
-
-}
-
-void oz_destroy_sys_entry(void)
-{
- sysfs_remove_group(&g_oz_wpan_dev->kobj, &attr_group);
-}
diff --git a/drivers/staging/ozwpan/ozkobject.h b/drivers/staging/ozwpan/ozkobject.h
deleted file mode 100644
index 0557228001d4..000000000000
--- a/drivers/staging/ozwpan/ozkobject.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -----------------------------------------------------------------------------
- * Copyright (c) 2011 Ozmo Inc
- * Released under the GNU General Public License Version 2 (GPLv2).
- * -----------------------------------------------------------------------------
- */
-
-#ifndef _OZKOBJECT_H
-#define _OZKOBJECT_H
-
-#define OZ_MAX_NW_IF 6
-
-void oz_create_sys_entry(void);
-void oz_destroy_sys_entry(void);
-void oz_set_serial_mode(u8 mode);
-u8 oz_get_serial_mode(void);
-
-#endif /* _OZKOBJECT_H */
diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c
index 61b83f86ef63..aaf2ccc0bcfb 100644
--- a/drivers/staging/ozwpan/ozmain.c
+++ b/drivers/staging/ozwpan/ozmain.c
@@ -10,10 +10,12 @@
#include <linux/netdevice.h>
#include <linux/errno.h>
#include <linux/ieee80211.h>
+#include "ozconfig.h"
#include "ozpd.h"
#include "ozproto.h"
#include "ozcdev.h"
#include "oztrace.h"
+#include "ozevent.h"
/*------------------------------------------------------------------------------
* 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
@@ -26,12 +28,11 @@ char *g_net_dev = "";
*/
static int __init ozwpan_init(void)
{
- if (oz_protocol_init(g_net_dev))
- return -1;
+ oz_event_init();
oz_cdev_register();
+ oz_protocol_init(g_net_dev);
oz_app_enable(OZ_APPID_USB, 1);
oz_apps_init();
- printk(KERN_DEBUG "p->oz_protocol_init = 0x%p\n", oz_protocol_init);
return 0;
}
/*------------------------------------------------------------------------------
@@ -42,6 +43,7 @@ static void __exit ozwpan_exit(void)
oz_protocol_term();
oz_apps_term();
oz_cdev_deregister();
+ oz_event_term();
}
/*------------------------------------------------------------------------------
*/
@@ -51,6 +53,6 @@ module_exit(ozwpan_exit);
MODULE_AUTHOR("Chris Kelly");
MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver");
-MODULE_VERSION("1.2.3-rc9");
+MODULE_VERSION("1.0.8");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c
index e9a3de041b8c..04cd57f2a6da 100644
--- a/drivers/staging/ozwpan/ozpd.c
+++ b/drivers/staging/ozwpan/ozpd.c
@@ -9,11 +9,13 @@
#include <linux/sched.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
#include "ozproto.h"
#include "oztrace.h"
+#include "ozevent.h"
#include "ozcdev.h"
#include "ozusbsvc.h"
#include <asm/unaligned.h>
@@ -22,17 +24,18 @@
/*------------------------------------------------------------------------------
*/
#define OZ_MAX_TX_POOL_SIZE 6
-#define AC_VO 0x106
+/* Maximum number of uncompleted isoc frames that can be pending.
+ */
+#define OZ_MAX_SUBMITTED_ISOC 16
/*------------------------------------------------------------------------------
*/
static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd);
static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f);
-static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f);
static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f);
static int oz_send_isoc_frame(struct oz_pd *pd);
static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f);
static void oz_isoc_stream_free(struct oz_isoc_stream *st);
-static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data);
+static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data);
static void oz_isoc_destructor(struct sk_buff *skb);
static int oz_def_app_init(void);
static void oz_def_app_term(void);
@@ -45,7 +48,7 @@ static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt);
static atomic_t g_submitted_isoc = ATOMIC_INIT(0);
/* Application handler functions.
*/
-static const struct oz_app_if g_app_if[OZ_APPID_MAX] = {
+static struct oz_app_if g_app_if[OZ_APPID_MAX] = {
{oz_usb_init,
oz_usb_term,
oz_usb_start,
@@ -60,8 +63,8 @@ static const struct oz_app_if g_app_if[OZ_APPID_MAX] = {
oz_def_app_start,
oz_def_app_stop,
oz_def_app_rx,
- NULL,
- NULL,
+ 0,
+ 0,
OZ_APPID_UNUSED1},
{oz_def_app_init,
@@ -69,8 +72,8 @@ static const struct oz_app_if g_app_if[OZ_APPID_MAX] = {
oz_def_app_start,
oz_def_app_stop,
oz_def_app_rx,
- NULL,
- NULL,
+ 0,
+ 0,
OZ_APPID_UNUSED2},
{oz_cdev_init,
@@ -78,36 +81,9 @@ static const struct oz_app_if g_app_if[OZ_APPID_MAX] = {
oz_cdev_start,
oz_cdev_stop,
oz_cdev_rx,
- NULL,
- NULL,
+ 0,
+ 0,
OZ_APPID_SERIAL},
-
- {oz_def_app_init,
- oz_def_app_term,
- oz_def_app_start,
- oz_def_app_stop,
- oz_def_app_rx,
- NULL,
- NULL,
- OZ_APPID_UNUSED3},
-
- {oz_def_app_init,
- oz_def_app_term,
- oz_def_app_start,
- oz_def_app_stop,
- oz_def_app_rx,
- NULL,
- NULL,
- OZ_APPID_UNUSED4},
-
- {NULL,
- NULL,
- NULL,
- NULL,
- oz_cdev_rx,
- NULL,
- NULL,
- OZ_APPID_TFTP},
};
/*------------------------------------------------------------------------------
* Context: process
@@ -147,6 +123,23 @@ static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt)
void oz_pd_set_state(struct oz_pd *pd, unsigned state)
{
pd->state = state;
+ oz_event_log(OZ_EVT_PD_STATE, 0, 0, 0, state);
+#ifdef WANT_TRACE
+ switch (state) {
+ case OZ_PD_S_IDLE:
+ oz_trace("PD State: OZ_PD_S_IDLE\n");
+ break;
+ case OZ_PD_S_CONNECTED:
+ oz_trace("PD State: OZ_PD_S_CONNECTED\n");
+ break;
+ case OZ_PD_S_STOPPED:
+ oz_trace("PD State: OZ_PD_S_STOPPED\n");
+ break;
+ case OZ_PD_S_SLEEP:
+ oz_trace("PD State: OZ_PD_S_SLEEP\n");
+ break;
+ }
+#endif /* WANT_TRACE */
}
/*------------------------------------------------------------------------------
* Context: softirq or process
@@ -166,12 +159,11 @@ void oz_pd_put(struct oz_pd *pd)
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
-struct oz_pd *oz_pd_alloc(const u8 *mac_addr)
+struct oz_pd *oz_pd_alloc(u8 *mac_addr)
{
struct oz_pd *pd = kzalloc(sizeof(struct oz_pd), GFP_ATOMIC);
if (pd) {
int i;
-
atomic_set(&pd->ref_count, 2);
for (i = 0; i < OZ_APPID_MAX; i++)
spin_lock_init(&pd->app_lock[i]);
@@ -181,7 +173,7 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr)
memcpy(pd->mac_addr, mac_addr, ETH_ALEN);
if (0 != oz_elt_buf_init(&pd->elt_buff)) {
kfree(pd);
- pd = NULL;
+ pd = 0;
}
spin_lock_init(&pd->tx_frame_lock);
INIT_LIST_HEAD(&pd->tx_queue);
@@ -189,28 +181,19 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr)
pd->last_sent_frame = &pd->tx_queue;
spin_lock_init(&pd->stream_lock);
INIT_LIST_HEAD(&pd->stream_list);
- tasklet_init(&pd->heartbeat_tasklet, oz_pd_heartbeat_handler,
- (unsigned long)pd);
- tasklet_init(&pd->timeout_tasklet, oz_pd_timeout_handler,
- (unsigned long)pd);
- hrtimer_init(&pd->heartbeat, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hrtimer_init(&pd->timeout, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- pd->heartbeat.function = oz_pd_heartbeat_event;
- pd->timeout.function = oz_pd_timeout_event;
}
return pd;
}
-static void oz_pd_free(struct work_struct *work)
+/*------------------------------------------------------------------------------
+ * Context: softirq or process
+ */
+void oz_pd_destroy(struct oz_pd *pd)
{
- struct oz_pd *pd;
struct list_head *e;
struct oz_tx_frame *f;
struct oz_isoc_stream *st;
struct oz_farewell *fwell;
- pd = container_of(work, struct oz_pd, workitem);
oz_trace("Destroying PD\n");
- tasklet_kill(&pd->heartbeat_tasklet);
- tasklet_kill(&pd->timeout_tasklet);
/* Delete any streams.
*/
e = pd->stream_list.next;
@@ -225,8 +208,6 @@ static void oz_pd_free(struct work_struct *work)
while (e != &pd->tx_queue) {
f = container_of(e, struct oz_tx_frame, link);
e = e->next;
- if (f->skb != NULL)
- kfree_skb(f->skb);
oz_retire_frame(pd, f);
}
oz_elt_buf_term(&pd->elt_buff);
@@ -249,42 +230,20 @@ static void oz_pd_free(struct work_struct *work)
dev_put(pd->net_dev);
kfree(pd);
}
-
-
-/*------------------------------------------------------------------------------
- * Context: softirq or Process
- */
-void oz_pd_destroy(struct oz_pd *pd)
-{
- int ret;
-
- if (hrtimer_active(&pd->timeout))
- hrtimer_cancel(&pd->timeout);
- if (hrtimer_active(&pd->heartbeat))
- hrtimer_cancel(&pd->heartbeat);
-
- memset(&pd->workitem, 0, sizeof(pd->workitem));
- INIT_WORK(&pd->workitem, oz_pd_free);
- ret = schedule_work(&pd->workitem);
-
- if (ret)
- oz_trace("failed to schedule workitem\n");
-}
-
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
int oz_services_start(struct oz_pd *pd, u16 apps, int resume)
{
- const struct oz_app_if *ai;
+ struct oz_app_if *ai;
int rc = 0;
oz_trace("oz_services_start(0x%x) resume(%d)\n", apps, resume);
- if (apps & (1<<OZ_APPID_TFTP))
- apps |= 1<<OZ_APPID_SERIAL;
for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) {
if (apps & (1<<ai->app_id)) {
- if (ai->start && ai->start(pd, resume)) {
+ if (ai->start(pd, resume)) {
rc = -1;
+ oz_trace("Unabled to start service %d\n",
+ ai->app_id);
break;
}
oz_polling_lock_bh();
@@ -301,10 +260,8 @@ int oz_services_start(struct oz_pd *pd, u16 apps, int resume)
*/
void oz_services_stop(struct oz_pd *pd, u16 apps, int pause)
{
- const struct oz_app_if *ai;
+ struct oz_app_if *ai;
oz_trace("oz_stop_services(0x%x) pause(%d)\n", apps, pause);
- if (apps & (1<<OZ_APPID_TFTP))
- apps |= 1<<OZ_APPID_SERIAL;
for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) {
if (apps & (1<<ai->app_id)) {
oz_polling_lock_bh();
@@ -315,8 +272,7 @@ void oz_services_stop(struct oz_pd *pd, u16 apps, int pause)
pd->paused_apps &= ~(1<<ai->app_id);
}
oz_polling_unlock_bh();
- if (ai->stop)
- ai->stop(pd, pause);
+ ai->stop(pd, pause);
}
}
}
@@ -325,7 +281,7 @@ void oz_services_stop(struct oz_pd *pd, u16 apps, int pause)
*/
void oz_pd_heartbeat(struct oz_pd *pd, u16 apps)
{
- const struct oz_app_if *ai;
+ struct oz_app_if *ai;
int more = 0;
for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) {
if (ai->heartbeat && (apps & (1<<ai->app_id))) {
@@ -333,8 +289,8 @@ void oz_pd_heartbeat(struct oz_pd *pd, u16 apps)
more = 1;
}
}
- if ((!more) && (hrtimer_active(&pd->heartbeat)))
- hrtimer_cancel(&pd->heartbeat);
+ if (more)
+ oz_pd_request_heartbeat(pd);
if (pd->mode & OZ_F_ISOC_ANYTIME) {
int count = 8;
while (count-- && (oz_send_isoc_frame(pd) >= 0))
@@ -347,9 +303,9 @@ void oz_pd_heartbeat(struct oz_pd *pd, u16 apps)
void oz_pd_stop(struct oz_pd *pd)
{
u16 stop_apps = 0;
- oz_trace("%s: State = 0x%x\n", __func__, pd->state);
- oz_polling_lock_bh();
+ oz_trace("oz_pd_stop() State = 0x%x\n", pd->state);
oz_pd_indicate_farewells(pd);
+ oz_polling_lock_bh();
stop_apps = pd->total_apps;
pd->total_apps = 0;
pd->paused_apps = 0;
@@ -359,9 +315,9 @@ void oz_pd_stop(struct oz_pd *pd)
oz_pd_set_state(pd, OZ_PD_S_STOPPED);
/* Remove from PD list.*/
list_del(&pd->link);
-
-
oz_polling_unlock_bh();
+ oz_trace("pd ref count = %d\n", atomic_read(&pd->ref_count));
+ oz_timer_delete(pd, 0);
oz_pd_put(pd);
}
/*------------------------------------------------------------------------------
@@ -376,10 +332,11 @@ int oz_pd_sleep(struct oz_pd *pd)
oz_polling_unlock_bh();
return 0;
}
- if (pd->keep_alive && pd->session_id) {
- if (pd->keep_alive >= OZ_KALIVE_INFINITE)
- oz_pd_indicate_farewells(pd);
+ if (pd->keep_alive_j && pd->session_id) {
oz_pd_set_state(pd, OZ_PD_S_SLEEP);
+ pd->pulse_time_j = jiffies + pd->keep_alive_j;
+ oz_trace("Sleep Now %lu until %lu\n",
+ jiffies, pd->pulse_time_j);
} else {
do_stop = 1;
}
@@ -389,7 +346,7 @@ int oz_pd_sleep(struct oz_pd *pd)
oz_pd_stop(pd);
} else {
oz_services_stop(pd, stop_apps, 1);
- oz_timer_add(pd, OZ_TIMER_STOP, pd->keep_alive);
+ oz_timer_add(pd, OZ_TIMER_STOP, jiffies + pd->keep_alive_j, 1);
}
return do_stop;
}
@@ -398,7 +355,7 @@ int oz_pd_sleep(struct oz_pd *pd)
*/
static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd)
{
- struct oz_tx_frame *f = NULL;
+ struct oz_tx_frame *f = 0;
spin_lock_bh(&pd->tx_frame_lock);
if (pd->tx_pool) {
f = container_of(pd->tx_pool, struct oz_tx_frame, link);
@@ -406,7 +363,7 @@ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd)
pd->tx_pool_count--;
}
spin_unlock_bh(&pd->tx_frame_lock);
- if (f == NULL)
+ if (f == 0)
f = kmalloc(sizeof(struct oz_tx_frame), GFP_ATOMIC);
if (f) {
f->total_size = sizeof(struct oz_hdr);
@@ -418,21 +375,6 @@ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd)
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
-static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f)
-{
- pd->nb_queued_isoc_frames--;
- list_del_init(&f->link);
- if (pd->tx_pool_count < OZ_MAX_TX_POOL_SIZE) {
- f->link.next = pd->tx_pool;
- pd->tx_pool = &f->link;
- pd->tx_pool_count++;
- } else {
- kfree(f);
- }
-}
-/*------------------------------------------------------------------------------
- * Context: softirq or process
- */
static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f)
{
spin_lock_bh(&pd->tx_frame_lock);
@@ -440,29 +382,13 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f)
f->link.next = pd->tx_pool;
pd->tx_pool = &f->link;
pd->tx_pool_count++;
- f = NULL;
+ f = 0;
}
spin_unlock_bh(&pd->tx_frame_lock);
if (f)
kfree(f);
}
/*------------------------------------------------------------------------------
- * Context: softirq-serialized
- */
-void oz_set_more_bit(struct sk_buff *skb)
-{
- struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb);
- oz_hdr->control |= OZ_F_MORE_DATA;
-}
-/*------------------------------------------------------------------------------
- * Context: softirq-serialized
- */
-void oz_set_last_pkt_nb(struct oz_pd *pd, struct sk_buff *skb)
-{
- struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb);
- oz_hdr->last_pkt_num = pd->trigger_pkt_num & OZ_LAST_PN_MASK;
-}
-/*------------------------------------------------------------------------------
* Context: softirq
*/
int oz_prepare_frame(struct oz_pd *pd, int empty)
@@ -475,9 +401,8 @@ int oz_prepare_frame(struct oz_pd *pd, int empty)
if (!empty && !oz_are_elts_available(&pd->elt_buff))
return -1;
f = oz_tx_frame_alloc(pd);
- if (f == NULL)
+ if (f == 0)
return -1;
- f->skb = NULL;
f->hdr.control =
(OZ_PROTOCOL_VERSION<<OZ_VERSION_SHIFT) | OZ_F_ACK_REQUESTED;
++pd->last_tx_pkt_num;
@@ -497,7 +422,7 @@ int oz_prepare_frame(struct oz_pd *pd, int empty)
*/
static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = 0;
struct net_device *dev = pd->net_dev;
struct oz_hdr *oz_hdr;
struct oz_elt *elt;
@@ -506,15 +431,14 @@ static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f)
* as the space we need.
*/
skb = alloc_skb(f->total_size + OZ_ALLOCATED_SPACE(dev), GFP_ATOMIC);
- if (skb == NULL)
- return NULL;
+ if (skb == 0)
+ return 0;
/* Reserve the head room for lower layers.
*/
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb_reset_network_header(skb);
skb->dev = dev;
skb->protocol = htons(OZ_ETHERTYPE);
- skb->priority = AC_VO;
if (dev_hard_header(skb, dev, OZ_ETHERTYPE, pd->mac_addr,
dev->dev_addr, skb->len) < 0)
goto fail;
@@ -535,7 +459,7 @@ static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f)
return skb;
fail:
kfree_skb(skb);
- return NULL;
+ return 0;
}
/*------------------------------------------------------------------------------
* Context: softirq or process
@@ -562,51 +486,33 @@ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f)
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
-static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data)
+static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data)
{
struct sk_buff *skb;
struct oz_tx_frame *f;
struct list_head *e;
+ *more_data = 0;
spin_lock(&pd->tx_frame_lock);
e = pd->last_sent_frame->next;
if (e == &pd->tx_queue) {
spin_unlock(&pd->tx_frame_lock);
return -1;
}
- f = container_of(e, struct oz_tx_frame, link);
-
- if (f->skb != NULL) {
- skb = f->skb;
- oz_tx_isoc_free(pd, f);
- spin_unlock(&pd->tx_frame_lock);
- if (more_data)
- oz_set_more_bit(skb);
- oz_set_last_pkt_nb(pd, skb);
- if ((int)atomic_read(&g_submitted_isoc) <
- OZ_MAX_SUBMITTED_ISOC) {
- oz_trace_skb(skb, 'T');
- if (dev_queue_xmit(skb) < 0) {
- return -1;
- }
- atomic_inc(&g_submitted_isoc);
- return 0;
- } else {
- kfree_skb(skb);
- return -1;
- }
- }
-
pd->last_sent_frame = e;
+ if (e->next != &pd->tx_queue)
+ *more_data = 1;
+ f = container_of(e, struct oz_tx_frame, link);
skb = oz_build_frame(pd, f);
spin_unlock(&pd->tx_frame_lock);
- if (skb == 0)
- return -1;
-
- if (more_data)
- oz_set_more_bit(skb);
- oz_trace_skb(skb, 'T');
- if (dev_queue_xmit(skb) < 0)
- return -1;
+ oz_trace2(OZ_TRACE_TX_FRAMES, "TX frame PN=0x%x\n", f->hdr.pkt_num);
+ if (skb) {
+ oz_event_log(OZ_EVT_TX_FRAME,
+ 0,
+ (((u16)f->hdr.control)<<8)|f->hdr.last_pkt_num,
+ 0, f->hdr.pkt_num);
+ if (dev_queue_xmit(skb) < 0)
+ return -1;
+ }
return 0;
}
/*------------------------------------------------------------------------------
@@ -614,45 +520,28 @@ static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data)
*/
void oz_send_queued_frames(struct oz_pd *pd, int backlog)
{
- while (oz_prepare_frame(pd, 0) >= 0)
- backlog++;
-
- switch (pd->mode & (OZ_F_ISOC_NO_ELTS | OZ_F_ISOC_ANYTIME)) {
-
- case OZ_F_ISOC_NO_ELTS: {
- backlog += pd->nb_queued_isoc_frames;
- if (backlog <= 0)
- goto out;
- if (backlog > OZ_MAX_SUBMITTED_ISOC)
- backlog = OZ_MAX_SUBMITTED_ISOC;
- break;
- }
- case OZ_NO_ELTS_ANYTIME: {
- if ((backlog <= 0) && (pd->isoc_sent == 0))
- goto out;
- break;
- }
- default: {
- if (backlog <= 0)
- goto out;
- break;
+ int more;
+ if (backlog < OZ_MAX_QUEUED_FRAMES) {
+ if (oz_send_next_queued_frame(pd, &more) >= 0) {
+ while (more && oz_send_next_queued_frame(pd, &more))
+ ;
+ } else {
+ if (((pd->mode & OZ_F_ISOC_ANYTIME) == 0)
+ || (pd->isoc_sent == 0)) {
+ if (oz_prepare_frame(pd, 1) >= 0)
+ oz_send_next_queued_frame(pd, &more);
+ }
}
+ } else {
+ oz_send_next_queued_frame(pd, &more);
}
- while (backlog--) {
- if (oz_send_next_queued_frame(pd, backlog) < 0)
- break;
- }
- return;
-
-out: oz_prepare_frame(pd, 1);
- oz_send_next_queued_frame(pd, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
static int oz_send_isoc_frame(struct oz_pd *pd)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = 0;
struct net_device *dev = pd->net_dev;
struct oz_hdr *oz_hdr;
struct oz_elt *elt;
@@ -666,7 +555,8 @@ static int oz_send_isoc_frame(struct oz_pd *pd)
if (list.next == &list)
return 0;
skb = alloc_skb(total_size + OZ_ALLOCATED_SPACE(dev), GFP_ATOMIC);
- if (skb == NULL) {
+ if (skb == 0) {
+ oz_trace("Cannot alloc skb\n");
oz_elt_info_free_chain(&pd->elt_buff, &list);
return -1;
}
@@ -690,7 +580,7 @@ static int oz_send_isoc_frame(struct oz_pd *pd)
memcpy(elt, ei->data, ei->length);
elt = oz_next_elt(elt);
}
- oz_trace_skb(skb, 'T');
+ oz_event_log(OZ_EVT_TX_ISOC, 0, 0, 0, 0);
dev_queue_xmit(skb);
oz_elt_info_free_chain(&pd->elt_buff, &list);
return 0;
@@ -702,8 +592,8 @@ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn)
{
struct list_head *e;
struct oz_tx_frame *f;
- struct list_head *first = NULL;
- struct list_head *last = NULL;
+ struct list_head *first = 0;
+ struct list_head *last = 0;
u8 diff;
u32 pkt_num;
@@ -713,9 +603,9 @@ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn)
f = container_of(e, struct oz_tx_frame, link);
pkt_num = le32_to_cpu(get_unaligned(&f->hdr.pkt_num));
diff = (lpn - (pkt_num & OZ_LAST_PN_MASK)) & OZ_LAST_PN_MASK;
- if ((diff > OZ_LAST_PN_HALF_CYCLE) || (pkt_num == 0))
+ if (diff > OZ_LAST_PN_HALF_CYCLE)
break;
- if (first == NULL)
+ if (first == 0)
first = e;
last = e;
e = e->next;
@@ -724,7 +614,7 @@ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn)
if (first) {
last->next->prev = &pd->tx_queue;
pd->tx_queue.next = last->next;
- last->next = NULL;
+ last->next = 0;
}
pd->last_sent_frame = &pd->tx_queue;
spin_unlock(&pd->tx_frame_lock);
@@ -747,7 +637,7 @@ static struct oz_isoc_stream *pd_stream_find(struct oz_pd *pd, u8 ep_num)
if (st->ep_num == ep_num)
return st;
}
- return NULL;
+ return 0;
}
/*------------------------------------------------------------------------------
* Context: softirq
@@ -762,7 +652,7 @@ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num)
spin_lock_bh(&pd->stream_lock);
if (!pd_stream_find(pd, ep_num)) {
list_add(&st->link, &pd->stream_list);
- st = NULL;
+ st = 0;
}
spin_unlock_bh(&pd->stream_lock);
if (st)
@@ -799,23 +689,25 @@ int oz_isoc_stream_delete(struct oz_pd *pd, u8 ep_num)
static void oz_isoc_destructor(struct sk_buff *skb)
{
atomic_dec(&g_submitted_isoc);
+ oz_event_log(OZ_EVT_TX_ISOC_DONE, atomic_read(&g_submitted_isoc),
+ 0, skb, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
-int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, const u8 *data, int len)
+int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, u8 *data, int len)
{
struct net_device *dev = pd->net_dev;
struct oz_isoc_stream *st;
u8 nb_units = 0;
- struct sk_buff *skb = NULL;
- struct oz_hdr *oz_hdr = NULL;
+ struct sk_buff *skb = 0;
+ struct oz_hdr *oz_hdr = 0;
int size = 0;
spin_lock_bh(&pd->stream_lock);
st = pd_stream_find(pd, ep_num);
if (st) {
skb = st->skb;
- st->skb = NULL;
+ st->skb = 0;
nb_units = st->nb_units;
st->nb_units = 0;
oz_hdr = st->oz_hdr;
@@ -828,22 +720,19 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, const u8 *data, int len)
/* Allocate enough space for max size frame. */
skb = alloc_skb(pd->max_tx_size + OZ_ALLOCATED_SPACE(dev),
GFP_ATOMIC);
- if (skb == NULL)
+ if (skb == 0)
return 0;
/* Reserve the head room for lower layers. */
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb_reset_network_header(skb);
skb->dev = dev;
skb->protocol = htons(OZ_ETHERTYPE);
- /* For audio packet set priority to AC_VO */
- skb->priority = AC_VO;
size = sizeof(struct oz_hdr) + sizeof(struct oz_isoc_large);
oz_hdr = (struct oz_hdr *)skb_put(skb, size);
}
memcpy(skb_put(skb, len), data, len);
size += len;
- if ((++nb_units < pd->ms_per_isoc)
- && ((pd->max_tx_size - size) > len)) {
+ if (++nb_units < pd->ms_per_isoc) {
spin_lock_bh(&pd->stream_lock);
st->skb = skb;
st->nb_units = nb_units;
@@ -867,52 +756,21 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, const u8 *data, int len)
memcpy(oz_hdr, &oz, sizeof(oz));
memcpy(oz_hdr+1, &iso, sizeof(iso));
if (dev_hard_header(skb, dev, OZ_ETHERTYPE, pd->mac_addr,
- dev->dev_addr, skb->len) < 0)
- goto out;
-
- skb->destructor = oz_isoc_destructor;
- /*Queue for Xmit if mode is not ANYTIME*/
- if (!(pd->mode & OZ_F_ISOC_ANYTIME)) {
- struct oz_tx_frame *isoc_unit = NULL;
- int nb = pd->nb_queued_isoc_frames;
- struct list_head *e;
- struct oz_tx_frame *f;
- if (nb >= pd->isoc_latency) {
- spin_lock(&pd->tx_frame_lock);
- list_for_each(e, &pd->tx_queue) {
- f = container_of(e, struct oz_tx_frame,
- link);
- if (f->skb != NULL) {
- oz_tx_isoc_free(pd, f);
- break;
- }
- }
- spin_unlock(&pd->tx_frame_lock);
- }
- isoc_unit = oz_tx_frame_alloc(pd);
- if (isoc_unit == NULL)
- goto out;
- isoc_unit->hdr = oz;
- isoc_unit->skb = skb;
- spin_lock_bh(&pd->tx_frame_lock);
- list_add_tail(&isoc_unit->link, &pd->tx_queue);
- pd->nb_queued_isoc_frames++;
- spin_unlock_bh(&pd->tx_frame_lock);
- return 0;
+ dev->dev_addr, skb->len) < 0) {
+ kfree_skb(skb);
+ return -1;
}
- /*In ANYTIME mode Xmit unit immediately*/
if (atomic_read(&g_submitted_isoc) < OZ_MAX_SUBMITTED_ISOC) {
+ skb->destructor = oz_isoc_destructor;
atomic_inc(&g_submitted_isoc);
- oz_trace_skb(skb, 'T');
- if (dev_queue_xmit(skb) < 0) {
+ oz_event_log(OZ_EVT_TX_ISOC, nb_units, iso.frame_number,
+ skb, atomic_read(&g_submitted_isoc));
+ if (dev_queue_xmit(skb) < 0)
return -1;
- } else
- return 0;
+ } else {
+ oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0);
+ kfree_skb(skb);
}
-
-out: kfree_skb(skb);
- return -1;
-
}
return 0;
}
@@ -942,7 +800,7 @@ void oz_apps_term(void)
*/
void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt)
{
- const struct oz_app_if *ai;
+ struct oz_app_if *ai;
if (app_id == 0 || app_id > OZ_APPID_MAX)
return;
ai = &g_app_if[app_id-1];
@@ -954,9 +812,19 @@ void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt)
void oz_pd_indicate_farewells(struct oz_pd *pd)
{
struct oz_farewell *f;
- const struct oz_app_if *ai = &g_app_if[OZ_APPID_USB-1];
- list_for_each_entry(f, &pd->farewell_list, link) {
+ struct oz_app_if *ai = &g_app_if[OZ_APPID_USB-1];
+ while (1) {
+ oz_polling_lock_bh();
+ if (list_empty(&pd->farewell_list)) {
+ oz_polling_unlock_bh();
+ break;
+ }
+ f = list_first_entry(&pd->farewell_list,
+ struct oz_farewell, link);
+ list_del(&f->link);
+ oz_polling_unlock_bh();
if (ai->farewell)
ai->farewell(pd, f->ep_num, f->report, f->len);
+ kfree(f);
}
}
diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h
index d75f0afa20ed..afc77f0260f0 100644
--- a/drivers/staging/ozwpan/ozpd.h
+++ b/drivers/staging/ozwpan/ozpd.h
@@ -6,7 +6,6 @@
#ifndef _OZPD_H_
#define _OZPD_H_
-#include <linux/interrupt.h>
#include "ozeltbuf.h"
/* PD state
@@ -22,7 +21,6 @@
#define OZ_TIMER_HEARTBEAT 2
#define OZ_TIMER_STOP 3
-#define ETH_STRING_LEN 17
/* 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.
@@ -31,7 +29,6 @@ struct oz_tx_frame {
struct list_head link;
struct list_head elt_list;
struct oz_hdr hdr;
- struct sk_buff *skb;
int total_size;
};
@@ -49,7 +46,7 @@ struct oz_farewell {
struct list_head link;
u8 ep_num;
u8 index;
- u8 report[32];
+ u8 report[1];
u8 len;
};
@@ -70,22 +67,22 @@ struct oz_pd {
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;
- ktime_t pulse_period;
- unsigned long presleep;
- unsigned long keep_alive;
+ unsigned long pulse_time_j;
+ unsigned long timeout_time_j;
+ unsigned long pulse_period_j;
+ unsigned long presleep_j;
+ unsigned long keep_alive_j;
+ unsigned long last_rx_time_j;
struct oz_elt_buf elt_buff;
void *app_ctx[OZ_APPID_MAX];
spinlock_t app_lock[OZ_APPID_MAX];
int max_tx_size;
+ u8 heartbeat_requested;
u8 mode;
u8 ms_per_isoc;
- unsigned isoc_latency;
unsigned max_stream_buffering;
int nb_queued_frames;
- int nb_queued_isoc_frames;
struct list_head *tx_pool;
int tx_pool_count;
spinlock_t tx_frame_lock;
@@ -95,18 +92,11 @@ struct oz_pd {
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;
- u8 up_audio_buf;
};
#define OZ_MAX_QUEUED_FRAMES 4
-struct oz_pd *oz_pd_alloc(const u8 *mac_addr);
+struct oz_pd *oz_pd_alloc(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);
@@ -122,9 +112,10 @@ 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);
+int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, 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);
#endif /* Sentry */
+
diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c
index c116e5250f6b..ad857eeabbb7 100644
--- a/drivers/staging/ozwpan/ozproto.c
+++ b/drivers/staging/ozwpan/ozproto.c
@@ -10,6 +10,7 @@
#include <linux/netdevice.h>
#include <linux/errno.h>
#include <linux/ieee80211.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
@@ -17,6 +18,7 @@
#include "ozusbsvc.h"
#include "oztrace.h"
#include "ozappif.h"
+#include "ozevent.h"
#include <asm/unaligned.h>
#include <linux/uaccess.h>
#include <net/psnap.h>
@@ -28,32 +30,48 @@
#define OZ_DO_STOP 1
#define OZ_DO_SLEEP 2
-#define OZ_MAX_TIMER_POOL_SIZE 16
-/*------------------------------------------------------------------------------
- * Number of units of buffering to capture for an isochronous IN endpoint before
- * allowing data to be indicated up.
+/* States of the timer.
*/
-#define OZ_IN_BUFFERING_UNITS 100
+#define OZ_TIMER_IDLE 0
+#define OZ_TIMER_SET 1
+#define OZ_TIMER_IN_HANDLER 2
+
+#define OZ_MAX_TIMER_POOL_SIZE 16
/*------------------------------------------------------------------------------
*/
struct oz_binding {
struct packet_type ptype;
char name[OZ_MAX_BINDING_LEN];
- struct list_head link;
+ struct oz_binding *next;
};
+struct oz_timer {
+ struct list_head link;
+ struct oz_pd *pd;
+ unsigned long due_time;
+ int type;
+};
/*------------------------------------------------------------------------------
* Static external variables.
*/
static DEFINE_SPINLOCK(g_polling_lock);
static LIST_HEAD(g_pd_list);
-static LIST_HEAD(g_binding);
+static struct oz_binding *g_binding ;
static DEFINE_SPINLOCK(g_binding_lock);
static struct sk_buff_head g_rx_queue;
static u8 g_session_id;
static u16 g_apps = 0x1;
static int g_processing_rx;
+static struct timer_list g_timer;
+static struct oz_timer *g_cur_timer;
+static struct list_head *g_timer_pool;
+static int g_timer_pool_count;
+static int g_timer_state = OZ_TIMER_IDLE;
+static LIST_HEAD(g_timer_list);
+/*------------------------------------------------------------------------------
+ */
+static void oz_protocol_timer_start(void);
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
@@ -80,7 +98,7 @@ static void oz_send_conn_rsp(struct oz_pd *pd, u8 status)
int sz = sizeof(struct oz_hdr) + sizeof(struct oz_elt) +
sizeof(struct oz_elt_connect_rsp);
skb = alloc_skb(sz + OZ_ALLOCATED_SPACE(dev), GFP_ATOMIC);
- if (skb == NULL)
+ if (skb == 0)
return;
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb_reset_network_header(skb);
@@ -96,8 +114,9 @@ static void oz_send_conn_rsp(struct oz_pd *pd, u8 status)
return;
}
oz_hdr->control = (OZ_PROTOCOL_VERSION<<OZ_VERSION_SHIFT);
- oz_hdr->last_pkt_num = pd->trigger_pkt_num & OZ_LAST_PN_MASK;
+ oz_hdr->last_pkt_num = 0;
put_unaligned(0, &oz_hdr->pkt_num);
+ oz_event_log(OZ_EVT_CONNECT_RSP, 0, 0, 0, 0);
elt->type = OZ_ELT_CONNECT_RSP;
elt->length = sizeof(struct oz_elt_connect_rsp);
memset(body, 0, sizeof(struct oz_elt_connect_rsp));
@@ -107,7 +126,7 @@ static void oz_send_conn_rsp(struct oz_pd *pd, u8 status)
body->session_id = pd->session_id;
put_unaligned(cpu_to_le16(pd->total_apps), &body->apps);
}
- oz_trace_skb(skb, 'T');
+ oz_trace("TX: OZ_ELT_CONNECT_RSP %d", status);
dev_queue_xmit(skb);
return;
}
@@ -120,41 +139,39 @@ static void pd_set_keepalive(struct oz_pd *pd, u8 kalive)
switch (kalive & OZ_KALIVE_TYPE_MASK) {
case OZ_KALIVE_SPECIAL:
- pd->keep_alive = (keep_alive * OZ_KALIVE_INFINITE);
+ pd->keep_alive_j =
+ oz_ms_to_jiffies(keep_alive * 1000*60*60*24*20);
break;
case OZ_KALIVE_SECS:
- pd->keep_alive = (keep_alive*1000);
+ pd->keep_alive_j = oz_ms_to_jiffies(keep_alive*1000);
break;
case OZ_KALIVE_MINS:
- pd->keep_alive = (keep_alive*1000*60);
+ pd->keep_alive_j = oz_ms_to_jiffies(keep_alive*1000*60);
break;
case OZ_KALIVE_HOURS:
- pd->keep_alive = (keep_alive*1000*60*60);
+ pd->keep_alive_j = oz_ms_to_jiffies(keep_alive*1000*60*60);
break;
default:
- pd->keep_alive = 0;
+ pd->keep_alive_j = 0;
}
+ oz_trace("Keepalive = %lu jiffies\n", pd->keep_alive_j);
}
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
-static void pd_set_presleep(struct oz_pd *pd, u8 presleep, u8 start_timer)
+static void pd_set_presleep(struct oz_pd *pd, u8 presleep)
{
if (presleep)
- pd->presleep = presleep*100;
+ pd->presleep_j = oz_ms_to_jiffies(presleep*100);
else
- pd->presleep = OZ_PRESLEEP_TOUT;
- if (start_timer) {
- spin_unlock(&g_polling_lock);
- oz_timer_add(pd, OZ_TIMER_TOUT, pd->presleep);
- spin_lock(&g_polling_lock);
- }
+ pd->presleep_j = OZ_PRESLEEP_TOUT_J;
+ oz_trace("Presleep time = %lu jiffies\n", pd->presleep_j);
}
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt,
- const u8 *pd_addr, struct net_device *net_dev, u32 pkt_num)
+ u8 *pd_addr, struct net_device *net_dev)
{
struct oz_pd *pd;
struct oz_elt_connect_req *body =
@@ -162,18 +179,18 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt,
u8 rsp_status = OZ_STATUS_SUCCESS;
u8 stop_needed = 0;
u16 new_apps = g_apps;
- struct net_device *old_net_dev = NULL;
- struct oz_pd *free_pd = NULL;
+ struct net_device *old_net_dev = 0;
+ struct oz_pd *free_pd = 0;
if (cur_pd) {
pd = cur_pd;
spin_lock_bh(&g_polling_lock);
} else {
- struct oz_pd *pd2 = NULL;
+ struct oz_pd *pd2 = 0;
struct list_head *e;
pd = oz_pd_alloc(pd_addr);
- if (pd == NULL)
- return NULL;
- getnstimeofday(&pd->last_rx_timestamp);
+ if (pd == 0)
+ return 0;
+ pd->last_rx_time_j = jiffies;
spin_lock_bh(&g_polling_lock);
list_for_each(e, &g_pd_list) {
pd2 = container_of(e, struct oz_pd, link);
@@ -186,44 +203,33 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt,
if (pd != pd2)
list_add_tail(&pd->link, &g_pd_list);
}
- if (pd == NULL) {
+ if (pd == 0) {
spin_unlock_bh(&g_polling_lock);
- return NULL;
+ return 0;
}
if (pd->net_dev != net_dev) {
old_net_dev = pd->net_dev;
dev_hold(net_dev);
pd->net_dev = net_dev;
}
+ oz_trace("Host vendor: %d\n", body->host_vendor);
pd->max_tx_size = OZ_MAX_TX_SIZE;
pd->mode = body->mode;
pd->pd_info = body->pd_info;
- pd->up_audio_buf = body->up_audio_buf > 0 ? body->up_audio_buf :
- OZ_IN_BUFFERING_UNITS;
if (pd->mode & OZ_F_ISOC_NO_ELTS) {
+ pd->mode |= OZ_F_ISOC_ANYTIME;
pd->ms_per_isoc = body->ms_per_isoc;
if (!pd->ms_per_isoc)
pd->ms_per_isoc = 4;
-
- switch (body->ms_isoc_latency & OZ_LATENCY_MASK) {
- case OZ_ONE_MS_LATENCY:
- pd->isoc_latency = (body->ms_isoc_latency &
- ~OZ_LATENCY_MASK) / pd->ms_per_isoc;
- break;
- case OZ_TEN_MS_LATENCY:
- pd->isoc_latency = ((body->ms_isoc_latency &
- ~OZ_LATENCY_MASK) * 10) / pd->ms_per_isoc;
- break;
- default:
- pd->isoc_latency = OZ_MAX_TX_QUEUE_ISOC;
- }
}
if (body->max_len_div16)
pd->max_tx_size = ((u16)body->max_len_div16)<<4;
+ oz_trace("Max frame:%u Ms per isoc:%u\n",
+ pd->max_tx_size, pd->ms_per_isoc);
pd->max_stream_buffering = 3*1024;
- pd->pulse_period = ktime_set(OZ_QUANTUM / MSEC_PER_SEC, (OZ_QUANTUM %
- MSEC_PER_SEC) * NSEC_PER_MSEC);
- pd_set_presleep(pd, body->presleep, 0);
+ pd->timeout_time_j = jiffies + OZ_CONNECTION_TOUT_J;
+ pd->pulse_period_j = OZ_QUANTUM_J;
+ pd_set_presleep(pd, body->presleep);
pd_set_keepalive(pd, body->keep_alive);
new_apps &= le16_to_cpu(get_unaligned(&body->apps));
@@ -255,6 +261,9 @@ done:
u16 resume_apps = new_apps & pd->paused_apps & ~0x1;
spin_unlock_bh(&g_polling_lock);
oz_pd_set_state(pd, OZ_PD_S_CONNECTED);
+ oz_timer_delete(pd, OZ_TIMER_STOP);
+ oz_trace("new_apps=0x%x total_apps=0x%x paused_apps=0x%x\n",
+ new_apps, pd->total_apps, pd->paused_apps);
if (start_apps) {
if (oz_services_start(pd, start_apps, 0))
rsp_status = OZ_STATUS_TOO_MANY_PDS;
@@ -268,17 +277,12 @@ done:
} else {
spin_unlock_bh(&g_polling_lock);
}
-
- /* CONNECT_REQ was sent without AR bit,
- but firmware does check LPN field to identify correcponding
- CONNECT_RSP field. */
- pd->trigger_pkt_num = pkt_num;
oz_send_conn_rsp(pd, rsp_status);
if (rsp_status != OZ_STATUS_SUCCESS) {
if (stop_needed)
oz_pd_stop(pd);
oz_pd_put(pd);
- pd = NULL;
+ pd = 0;
}
if (old_net_dev)
dev_put(old_net_dev);
@@ -290,7 +294,7 @@ done:
* Context: softirq-serialized
*/
static void oz_add_farewell(struct oz_pd *pd, u8 ep_num, u8 index,
- const u8 *report, u8 len)
+ u8 *report, u8 len)
{
struct oz_farewell *f;
struct oz_farewell *f2;
@@ -300,7 +304,6 @@ static void oz_add_farewell(struct oz_pd *pd, u8 ep_num, u8 index,
return;
f->ep_num = ep_num;
f->index = index;
- f->len = len;
memcpy(f->report, report, len);
oz_trace("RX: Adding farewell report\n");
spin_lock(&g_polling_lock);
@@ -325,13 +328,17 @@ static void oz_rx_frame(struct sk_buff *skb)
u8 *src_addr;
struct oz_elt *elt;
int length;
- struct oz_pd *pd = NULL;
+ struct oz_pd *pd = 0;
struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb);
- struct timespec current_time;
int dup = 0;
u32 pkt_num;
- oz_trace_skb(skb, 'R');
+ oz_event_log(OZ_EVT_RX_PROCESS, 0,
+ (((u16)oz_hdr->control)<<8)|oz_hdr->last_pkt_num,
+ 0, oz_hdr->pkt_num);
+ oz_trace2(OZ_TRACE_RX_FRAMES,
+ "RX frame PN=0x%x LPN=0x%x control=0x%x\n",
+ oz_hdr->pkt_num, oz_hdr->last_pkt_num, oz_hdr->control);
mac_hdr = skb_mac_header(skb);
src_addr = &mac_hdr[ETH_ALEN] ;
length = skb->len;
@@ -343,23 +350,18 @@ static void oz_rx_frame(struct sk_buff *skb)
goto done;
}
-
pkt_num = le32_to_cpu(get_unaligned(&oz_hdr->pkt_num));
pd = oz_pd_find(src_addr);
if (pd) {
- if (!(pd->state & OZ_PD_S_CONNECTED))
- oz_pd_set_state(pd, OZ_PD_S_CONNECTED);
- getnstimeofday(&current_time);
- if ((current_time.tv_sec != pd->last_rx_timestamp.tv_sec) ||
- (pd->presleep < MSEC_PER_SEC)) {
- oz_timer_add(pd, OZ_TIMER_TOUT, pd->presleep);
- pd->last_rx_timestamp = current_time;
- }
+ pd->last_rx_time_j = jiffies;
+ oz_timer_add(pd, OZ_TIMER_TOUT,
+ pd->last_rx_time_j + pd->presleep_j, 1);
if (pkt_num != pd->last_rx_pkt_num) {
pd->last_rx_pkt_num = pkt_num;
} else {
dup = 1;
+ oz_trace("Duplicate frame\n");
}
}
@@ -374,6 +376,8 @@ static void oz_rx_frame(struct sk_buff *skb)
int backlog = pd->nb_queued_frames;
pd->trigger_pkt_num = pkt_num;
/* Send queued frames */
+ while (oz_prepare_frame(pd, 0) >= 0)
+ ;
oz_send_queued_frames(pd, backlog);
}
}
@@ -381,26 +385,29 @@ static void oz_rx_frame(struct sk_buff *skb)
length -= sizeof(struct oz_hdr);
elt = (struct oz_elt *)((u8 *)oz_hdr + sizeof(struct oz_hdr));
- while (length >= oz_elt_hdr_len(elt)) {
- length -= oz_elt_len(elt);
+ while (length >= sizeof(struct oz_elt)) {
+ length -= sizeof(struct oz_elt) + elt->length;
if (length < 0)
break;
switch (elt->type) {
case OZ_ELT_CONNECT_REQ:
- pd = oz_connect_req(pd, elt, src_addr, skb->dev,
- pkt_num);
+ oz_event_log(OZ_EVT_CONNECT_REQ, 0, 0, 0, 0);
+ oz_trace("RX: OZ_ELT_CONNECT_REQ\n");
+ pd = oz_connect_req(pd, elt, src_addr, skb->dev);
break;
case OZ_ELT_DISCONNECT:
+ oz_trace("RX: OZ_ELT_DISCONNECT\n");
if (pd)
oz_pd_sleep(pd);
break;
case OZ_ELT_UPDATE_PARAM_REQ: {
struct oz_elt_update_param *body =
(struct oz_elt_update_param *)(elt + 1);
+ oz_trace("RX: OZ_ELT_UPDATE_PARAM_REQ\n");
if (pd && (pd->state & OZ_PD_S_CONNECTED)) {
spin_lock(&g_polling_lock);
pd_set_keepalive(pd, body->keepalive);
- pd_set_presleep(pd, body->presleep, 1);
+ pd_set_presleep(pd, body->presleep);
spin_unlock(&g_polling_lock);
}
}
@@ -408,16 +415,16 @@ static void oz_rx_frame(struct sk_buff *skb)
case OZ_ELT_FAREWELL_REQ: {
struct oz_elt_farewell *body =
(struct oz_elt_farewell *)(elt + 1);
+ oz_trace("RX: OZ_ELT_FAREWELL_REQ\n");
oz_add_farewell(pd, body->ep_num,
body->index, body->report,
elt->length + 1 - sizeof(*body));
}
break;
case OZ_ELT_APP_DATA:
- case OZ_ELT_APP_DATA_EX:
if (pd && (pd->state & OZ_PD_S_CONNECTED)) {
struct oz_app_hdr *app_hdr =
- (struct oz_app_hdr *)(oz_elt_data(elt));
+ (struct oz_app_hdr *)(elt+1);
if (dup)
break;
oz_handle_app_elt(pd, app_hdr->app_id, elt);
@@ -438,13 +445,14 @@ done:
*/
void oz_protocol_term(void)
{
- struct oz_binding *b, *t;
-
+ struct list_head *chain = 0;
+ del_timer_sync(&g_timer);
/* Walk the list of bindings and remove each one.
*/
spin_lock_bh(&g_binding_lock);
- list_for_each_entry_safe(b, t, &g_binding, link) {
- list_del(&b->link);
+ while (g_binding) {
+ struct oz_binding *b = g_binding;
+ g_binding = b->next;
spin_unlock_bh(&g_binding_lock);
dev_remove_pack(&b->ptype);
if (b->ptype.dev)
@@ -467,115 +475,256 @@ void oz_protocol_term(void)
oz_pd_put(pd);
spin_lock_bh(&g_polling_lock);
}
+ chain = g_timer_pool;
+ g_timer_pool = 0;
spin_unlock_bh(&g_polling_lock);
+ while (chain) {
+ struct oz_timer *t = container_of(chain, struct oz_timer, link);
+ chain = chain->next;
+ kfree(t);
+ }
oz_trace("Protocol stopped\n");
}
/*------------------------------------------------------------------------------
* Context: softirq
*/
-void oz_pd_heartbeat_handler(unsigned long data)
-{
- struct oz_pd *pd = (struct oz_pd *)data;
- u16 apps = 0;
- spin_lock_bh(&g_polling_lock);
- if (pd->state & OZ_PD_S_CONNECTED)
- apps = pd->total_apps;
- spin_unlock_bh(&g_polling_lock);
- if (apps)
- oz_pd_heartbeat(pd, apps);
-
- oz_pd_put(pd);
-}
-/*------------------------------------------------------------------------------
- * Context: softirq
- */
-void oz_pd_timeout_handler(unsigned long data)
+static void oz_pd_handle_timer(struct oz_pd *pd, int type)
{
- int type;
- struct oz_pd *pd = (struct oz_pd *)data;
-
- spin_lock_bh(&g_polling_lock);
- type = pd->timeout_type;
- spin_unlock_bh(&g_polling_lock);
switch (type) {
case OZ_TIMER_TOUT:
- oz_trace_msg(M, "OZ_TIMER_TOUT:\n");
oz_pd_sleep(pd);
break;
case OZ_TIMER_STOP:
- oz_trace_msg(M, "OZ_TIMER_STOP:\n");
oz_pd_stop(pd);
break;
+ case OZ_TIMER_HEARTBEAT: {
+ u16 apps = 0;
+ spin_lock_bh(&g_polling_lock);
+ pd->heartbeat_requested = 0;
+ if (pd->state & OZ_PD_S_CONNECTED)
+ apps = pd->total_apps;
+ spin_unlock_bh(&g_polling_lock);
+ if (apps)
+ oz_pd_heartbeat(pd, apps);
+ }
+ break;
}
- oz_pd_put(pd);
}
/*------------------------------------------------------------------------------
- * Context: Interrupt
+ * Context: softirq
*/
-enum hrtimer_restart oz_pd_heartbeat_event(struct hrtimer *timer)
+static void oz_protocol_timer(unsigned long arg)
{
+ struct oz_timer *t;
+ struct oz_timer *t2;
struct oz_pd *pd;
-
- pd = container_of(timer, struct oz_pd, heartbeat);
- hrtimer_forward(timer,
- hrtimer_get_expires(timer), pd->pulse_period);
- oz_pd_get(pd);
- tasklet_schedule(&pd->heartbeat_tasklet);
- return HRTIMER_RESTART;
+ spin_lock_bh(&g_polling_lock);
+ if (!g_cur_timer) {
+ /* This happens if we remove the current timer but can't stop
+ * the timer from firing. In this case just get out.
+ */
+ oz_event_log(OZ_EVT_TIMER, 0, 0, 0, 0);
+ spin_unlock_bh(&g_polling_lock);
+ return;
+ }
+ g_timer_state = OZ_TIMER_IN_HANDLER;
+ t = g_cur_timer;
+ g_cur_timer = 0;
+ list_del(&t->link);
+ spin_unlock_bh(&g_polling_lock);
+ do {
+ pd = t->pd;
+ oz_event_log(OZ_EVT_TIMER, 0, t->type, 0, 0);
+ oz_pd_handle_timer(pd, t->type);
+ spin_lock_bh(&g_polling_lock);
+ if (g_timer_pool_count < OZ_MAX_TIMER_POOL_SIZE) {
+ t->link.next = g_timer_pool;
+ g_timer_pool = &t->link;
+ g_timer_pool_count++;
+ t = 0;
+ }
+ if (!list_empty(&g_timer_list)) {
+ t2 = container_of(g_timer_list.next,
+ struct oz_timer, link);
+ if (time_before_eq(t2->due_time, jiffies))
+ list_del(&t2->link);
+ else
+ t2 = 0;
+ } else {
+ t2 = 0;
+ }
+ spin_unlock_bh(&g_polling_lock);
+ oz_pd_put(pd);
+ if (t)
+ kfree(t);
+ t = t2;
+ } while (t);
+ g_timer_state = OZ_TIMER_IDLE;
+ oz_protocol_timer_start();
}
/*------------------------------------------------------------------------------
- * Context: Interrupt
+ * Context: softirq
*/
-enum hrtimer_restart oz_pd_timeout_event(struct hrtimer *timer)
+static void oz_protocol_timer_start(void)
{
- struct oz_pd *pd;
-
- pd = container_of(timer, struct oz_pd, timeout);
- oz_pd_get(pd);
- tasklet_schedule(&pd->timeout_tasklet);
- return HRTIMER_NORESTART;
+ spin_lock_bh(&g_polling_lock);
+ if (!list_empty(&g_timer_list)) {
+ g_cur_timer =
+ container_of(g_timer_list.next, struct oz_timer, link);
+ if (g_timer_state == OZ_TIMER_SET) {
+ oz_event_log(OZ_EVT_TIMER_CTRL, 3,
+ (u16)g_cur_timer->type, 0,
+ (unsigned)g_cur_timer->due_time);
+ mod_timer(&g_timer, g_cur_timer->due_time);
+ } else {
+ oz_event_log(OZ_EVT_TIMER_CTRL, 4,
+ (u16)g_cur_timer->type, 0,
+ (unsigned)g_cur_timer->due_time);
+ g_timer.expires = g_cur_timer->due_time;
+ g_timer.function = oz_protocol_timer;
+ g_timer.data = 0;
+ add_timer(&g_timer);
+ }
+ g_timer_state = OZ_TIMER_SET;
+ } else {
+ oz_trace("No queued timers\n");
+ }
+ spin_unlock_bh(&g_polling_lock);
}
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
-void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time)
+void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time,
+ int remove)
{
- spin_lock_bh(&g_polling_lock);
- switch (type) {
- case OZ_TIMER_TOUT:
- case OZ_TIMER_STOP:
- if (hrtimer_active(&pd->timeout)) {
- hrtimer_set_expires(&pd->timeout, ktime_set(due_time /
- MSEC_PER_SEC, (due_time % MSEC_PER_SEC) *
- NSEC_PER_MSEC));
- hrtimer_start_expires(&pd->timeout, HRTIMER_MODE_REL);
+ struct list_head *e;
+ struct oz_timer *t = 0;
+ int restart_needed = 0;
+ oz_event_log(OZ_EVT_TIMER_CTRL, 1, (u16)type, 0, (unsigned)due_time);
+ spin_lock(&g_polling_lock);
+ if (remove) {
+ list_for_each(e, &g_timer_list) {
+ t = container_of(e, struct oz_timer, link);
+ if ((t->pd == pd) && (t->type == type)) {
+ if (g_cur_timer == t) {
+ restart_needed = 1;
+ g_cur_timer = 0;
+ }
+ list_del(e);
+ break;
+ }
+ t = 0;
+ }
+ }
+ if (!t) {
+ if (g_timer_pool) {
+ t = container_of(g_timer_pool, struct oz_timer, link);
+ g_timer_pool = g_timer_pool->next;
+ g_timer_pool_count--;
} else {
- hrtimer_start(&pd->timeout, ktime_set(due_time /
- MSEC_PER_SEC, (due_time % MSEC_PER_SEC) *
- NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ t = kmalloc(sizeof(struct oz_timer), GFP_ATOMIC);
+ }
+ if (t) {
+ t->pd = pd;
+ t->type = type;
+ oz_pd_get(pd);
}
- pd->timeout_type = type;
- break;
- case OZ_TIMER_HEARTBEAT:
- if (!hrtimer_active(&pd->heartbeat))
- hrtimer_start(&pd->heartbeat, ktime_set(due_time /
- MSEC_PER_SEC, (due_time % MSEC_PER_SEC) *
- NSEC_PER_MSEC), HRTIMER_MODE_REL);
- break;
}
- spin_unlock_bh(&g_polling_lock);
+ if (t) {
+ struct oz_timer *t2;
+ t->due_time = due_time;
+ list_for_each(e, &g_timer_list) {
+ t2 = container_of(e, struct oz_timer, link);
+ if (time_before(due_time, t2->due_time)) {
+ if (t2 == g_cur_timer) {
+ g_cur_timer = 0;
+ restart_needed = 1;
+ }
+ break;
+ }
+ }
+ list_add_tail(&t->link, e);
+ }
+ if (g_timer_state == OZ_TIMER_IDLE)
+ restart_needed = 1;
+ else if (g_timer_state == OZ_TIMER_IN_HANDLER)
+ restart_needed = 0;
+ spin_unlock(&g_polling_lock);
+ if (restart_needed)
+ oz_protocol_timer_start();
+}
+/*------------------------------------------------------------------------------
+ * Context: softirq or process
+ */
+void oz_timer_delete(struct oz_pd *pd, int type)
+{
+ struct list_head *chain = 0;
+ struct oz_timer *t;
+ struct oz_timer *n;
+ int restart_needed = 0;
+ int release = 0;
+ oz_event_log(OZ_EVT_TIMER_CTRL, 2, (u16)type, 0, 0);
+ spin_lock(&g_polling_lock);
+ list_for_each_entry_safe(t, n, &g_timer_list, link) {
+ if ((t->pd == pd) && ((type == 0) || (t->type == type))) {
+ if (g_cur_timer == t) {
+ restart_needed = 1;
+ g_cur_timer = 0;
+ del_timer(&g_timer);
+ }
+ list_del(&t->link);
+ release++;
+ if (g_timer_pool_count < OZ_MAX_TIMER_POOL_SIZE) {
+ t->link.next = g_timer_pool;
+ g_timer_pool = &t->link;
+ g_timer_pool_count++;
+ } else {
+ t->link.next = chain;
+ chain = &t->link;
+ }
+ if (type)
+ break;
+ }
+ }
+ if (g_timer_state == OZ_TIMER_IN_HANDLER)
+ restart_needed = 0;
+ else if (restart_needed)
+ g_timer_state = OZ_TIMER_IDLE;
+ spin_unlock(&g_polling_lock);
+ if (restart_needed)
+ oz_protocol_timer_start();
+ while (release--)
+ oz_pd_put(pd);
+ while (chain) {
+ t = container_of(chain, struct oz_timer, link);
+ chain = chain->next;
+ kfree(t);
+ }
}
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
void oz_pd_request_heartbeat(struct oz_pd *pd)
{
- oz_timer_add(pd, OZ_TIMER_HEARTBEAT, OZ_QUANTUM);
+ unsigned long now = jiffies;
+ unsigned long t;
+ spin_lock(&g_polling_lock);
+ if (pd->heartbeat_requested) {
+ spin_unlock(&g_polling_lock);
+ return;
+ }
+ if (pd->pulse_period_j)
+ t = ((now / pd->pulse_period_j) + 1) * pd->pulse_period_j;
+ else
+ t = now + 1;
+ pd->heartbeat_requested = 1;
+ spin_unlock(&g_polling_lock);
+ oz_timer_add(pd, OZ_TIMER_HEARTBEAT, t, 0);
}
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
-struct oz_pd *oz_pd_find(const u8 *mac_addr)
+struct oz_pd *oz_pd_find(u8 *mac_addr)
{
struct oz_pd *pd;
struct list_head *e;
@@ -611,8 +760,9 @@ void oz_app_enable(int app_id, int enable)
static int oz_pkt_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
+ oz_event_log(OZ_EVT_RX_FRAME, 0, 0, 0, 0);
skb = skb_share_check(skb, GFP_ATOMIC);
- if (skb == NULL)
+ if (skb == 0)
return 0;
spin_lock_bh(&g_rx_queue.lock);
if (g_processing_rx) {
@@ -642,33 +792,33 @@ static int oz_pkt_recv(struct sk_buff *skb, struct net_device *dev,
/*------------------------------------------------------------------------------
* Context: process
*/
-void oz_binding_add(const char *net_dev)
+void oz_binding_add(char *net_dev)
{
struct oz_binding *binding;
- binding = kmalloc(sizeof(struct oz_binding), GFP_KERNEL);
+ binding = kmalloc(sizeof(struct oz_binding), GFP_ATOMIC);
if (binding) {
binding->ptype.type = __constant_htons(OZ_ETHERTYPE);
binding->ptype.func = oz_pkt_recv;
memcpy(binding->name, net_dev, OZ_MAX_BINDING_LEN);
if (net_dev && *net_dev) {
- oz_trace_msg(M, "Adding binding: '%s'\n", net_dev);
+ oz_trace("Adding binding: %s\n", net_dev);
binding->ptype.dev =
dev_get_by_name(&init_net, net_dev);
- if (binding->ptype.dev == NULL) {
- oz_trace_msg(M, "Netdev '%s' not found\n",
- net_dev);
+ if (binding->ptype.dev == 0) {
+ oz_trace("Netdev %s not found\n", net_dev);
kfree(binding);
- binding = NULL;
+ binding = 0;
}
} else {
- oz_trace_msg(M, "Binding to all netcards\n");
- binding->ptype.dev = NULL;
+ oz_trace("Binding to all netcards\n");
+ binding->ptype.dev = 0;
}
if (binding) {
dev_add_pack(&binding->ptype);
spin_lock_bh(&g_binding_lock);
- list_add_tail(&binding->link, &g_binding);
+ binding->next = g_binding;
+ g_binding = binding;
spin_unlock_bh(&g_binding_lock);
}
}
@@ -676,7 +826,7 @@ void oz_binding_add(const char *net_dev)
/*------------------------------------------------------------------------------
* Context: process
*/
-static int compare_binding_name(const char *s1, const char *s2)
+static int compare_binding_name(char *s1, char *s2)
{
int i;
for (i = 0; i < OZ_MAX_BINDING_LEN; i++) {
@@ -714,52 +864,37 @@ static void pd_stop_all_for_device(struct net_device *net_dev)
/*------------------------------------------------------------------------------
* Context: process
*/
-void oz_binding_remove(const char *net_dev)
+void oz_binding_remove(char *net_dev)
{
- struct oz_binding *binding;
- int found = 0;
-
- oz_trace_msg(M, "Removing binding: '%s'\n", net_dev);
+ struct oz_binding *binding = 0;
+ struct oz_binding **link;
+ oz_trace("Removing binding: %s\n", net_dev);
spin_lock_bh(&g_binding_lock);
- list_for_each_entry(binding, &g_binding, link) {
+ binding = g_binding;
+ link = &g_binding;
+ while (binding) {
if (compare_binding_name(binding->name, net_dev)) {
- oz_trace_msg(M, "Binding '%s' found\n", net_dev);
- found = 1;
+ oz_trace("Binding '%s' found\n", net_dev);
+ *link = binding->next;
break;
+ } else {
+ link = &binding;
+ binding = binding->next;
}
}
spin_unlock_bh(&g_binding_lock);
- if (found) {
+ if (binding) {
dev_remove_pack(&binding->ptype);
if (binding->ptype.dev) {
dev_put(binding->ptype.dev);
pd_stop_all_for_device(binding->ptype.dev);
}
- list_del(&binding->link);
kfree(binding);
}
}
/*------------------------------------------------------------------------------
* Context: process
*/
-int oz_get_binding_list(char *buf, int max_if)
-{
- struct oz_binding *binding = 0;
- int count = 0;
-
- spin_lock_bh(&g_binding_lock);
- list_for_each_entry(binding, &g_binding, link) {
- if (count++ > max_if)
- break;
- memcpy(buf, binding->name, OZ_MAX_BINDING_LEN);
- buf += OZ_MAX_BINDING_LEN;
- }
- spin_unlock_bh(&g_binding_lock);
- return count;
-}
-/*------------------------------------------------------------------------------
- * Context: process
- */
static char *oz_get_next_device_name(char *s, char *dname, int max_size)
{
while (*s == ',')
@@ -778,7 +913,7 @@ int oz_protocol_init(char *devs)
{
skb_queue_head_init(&g_rx_queue);
if (devs && (devs[0] == '*')) {
- return -1;
+ oz_binding_add(0);
} else {
char d[32];
while (*devs) {
@@ -787,6 +922,7 @@ int oz_protocol_init(char *devs)
oz_binding_add(d);
}
}
+ init_timer(&g_timer);
return 0;
}
/*------------------------------------------------------------------------------
@@ -808,32 +944,6 @@ int oz_get_pd_list(struct oz_mac_addr *addr, int max_count)
return count;
}
/*------------------------------------------------------------------------------
- * Context: process
- */
-int oz_get_pd_status_list(u8 *pd_list, int max_count)
-{
- struct oz_pd *pd;
- struct list_head *e;
- int count = 0;
-
- spin_lock_bh(&g_polling_lock);
- list_for_each(e, &g_pd_list) {
- if (count >= max_count)
- break;
- pd = container_of(e, struct oz_pd, link);
- if (pd_list) {
- memcpy(&pd_list[count * (ETH_ALEN + sizeof(pd->state))],
- pd->mac_addr, ETH_ALEN);
- memcpy(&pd_list[(count * (ETH_ALEN + sizeof(pd->state)))
- + ETH_ALEN],
- &pd->state, sizeof(pd->state));
- count++;
- }
- }
- spin_unlock_bh(&g_polling_lock);
- return count;
-}
-/*------------------------------------------------------------------------------
*/
void oz_polling_lock_bh(void)
{
diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h
index 64ac30c7fb54..89aea28bd8d5 100644
--- a/drivers/staging/ozwpan/ozproto.h
+++ b/drivers/staging/ozwpan/ozproto.h
@@ -7,25 +7,28 @@
#define _OZPROTO_H
#include <asm/byteorder.h>
+#include "ozconfig.h"
#include "ozappif.h"
#define OZ_ALLOCATED_SPACE(__x) (LL_RESERVED_SPACE(__x)+(__x)->needed_tailroom)
+/* Converts millisecs to jiffies.
+ */
+#define oz_ms_to_jiffies(__x) (((__x)*1000)/HZ)
-/* Quantum in MS */
-#define OZ_QUANTUM 8
+/* Quantum milliseconds.
+ */
+#define OZ_QUANTUM_MS 8
+/* Quantum jiffies
+ */
+#define OZ_QUANTUM_J (oz_ms_to_jiffies(OZ_QUANTUM_MS))
/* Default timeouts.
*/
-#define OZ_PRESLEEP_TOUT 11
+#define OZ_CONNECTION_TOUT_J (2*HZ)
+#define OZ_PRESLEEP_TOUT_J (11*HZ)
/* 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
+#define OZ_MAX_TX_SIZE 1514
/* Application handler functions.
*/
@@ -53,18 +56,14 @@ 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);
+struct oz_pd *oz_pd_find(u8 *mac_addr);
+void oz_binding_add(char *net_dev);
+void oz_binding_remove(char *net_dev);
+void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time,
+ int remove);
void oz_timer_delete(struct oz_pd *pd, int type);
void oz_pd_request_heartbeat(struct oz_pd *pd);
void oz_polling_lock_bh(void);
void oz_polling_unlock_bh(void);
-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(u8 *pd_list, int max_count);
-int oz_get_binding_list(char *buf, int max_if);
+
#endif /* _OZPROTO_H */
diff --git a/drivers/staging/ozwpan/ozprotocol.h b/drivers/staging/ozwpan/ozprotocol.h
index 5cb989c90a58..b3e7d77f3fff 100644
--- a/drivers/staging/ozwpan/ozprotocol.h
+++ b/drivers/staging/ozwpan/ozprotocol.h
@@ -27,51 +27,17 @@ struct oz_elt {
u8 length;
} PACKED;
-/* This is an extended element header.
- */
-struct oz_ext_elt {
- u8 type;
- u16 length;
-} PACKED;
-
-
-
-#define oz_is_ext_elt(__elt) \
- (((struct oz_elt *)(__elt))->type >= OZ_ELT_EXTENDED)
-
-#define oz_elt_hdr_len(__elt) \
- (int)(oz_is_ext_elt(__elt) ? \
- (sizeof(struct oz_ext_elt)) \
- : (sizeof(struct oz_elt)))
-
-#define oz_elt_data_len(__elt) \
- (int)(oz_is_ext_elt(__elt) ? \
- (le16_to_cpu((((struct oz_ext_elt *)(__elt))->length))) \
- : (__elt)->length)
-
-#define oz_elt_len(__elt) \
- (oz_elt_hdr_len(__elt) + oz_elt_data_len(__elt))
-
-#define oz_elt_data(__elt) \
- ((u8 *)(((u8 *)(__elt)) + oz_elt_hdr_len(__elt)))
-
-
-#define oz_next_elt(__elt) \
- (struct oz_elt *)((u8 *)(__elt) + oz_elt_len(__elt))
-
+#define oz_next_elt(__elt) \
+ (struct oz_elt *)((u8 *)((__elt) + 1) + (__elt)->length)
/* Protocol element IDs.
*/
-#define OZ_ELT_EXTENDED 0xC0
-#define OZ_ELT_ID_MASK 0x3F
#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
-#define OZ_ELT_APP_DATA_EX (OZ_ELT_EXTENDED|OZ_ELT_APP_DATA)
-
/* This is the Ozmo header which is the first Ozmo specific part
* of a frame and comes after the MAC header.
@@ -99,10 +65,6 @@ struct oz_hdr {
#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 {
@@ -111,14 +73,13 @@ struct oz_elt_connect_req {
u8 pd_info;
u8 session_id;
u8 presleep;
- u8 ms_isoc_latency;
+ u8 resv2;
u8 host_vendor;
u8 keep_alive;
u16 apps;
u8 max_len_div16;
u8 ms_per_isoc;
- u8 up_audio_buf;
- u8 ms_per_elt;
+ u8 resv3[2];
} PACKED;
/* mode field bits.
@@ -128,7 +89,6 @@ struct oz_elt_connect_req {
#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.
*/
@@ -139,8 +99,6 @@ struct oz_elt_connect_req {
#define OZ_KALIVE_MINS 0x80
#define OZ_KALIVE_HOURS 0xc0
-#define OZ_KALIVE_INFINITE (1000*60*60*24*20)
-
/* Connect response data structure.
*/
struct oz_elt_connect_rsp {
@@ -179,10 +137,7 @@ struct oz_app_hdr {
#define OZ_APPID_UNUSED1 0x2
#define OZ_APPID_UNUSED2 0x3
#define OZ_APPID_SERIAL 0x4
-#define OZ_APPID_UNUSED3 0x5
-#define OZ_APPID_UNUSED4 0x6
-#define OZ_APPID_TFTP 0x7
-#define OZ_APPID_MAX OZ_APPID_TFTP
+#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.
diff --git a/drivers/staging/ozwpan/oztrace.c b/drivers/staging/ozwpan/oztrace.c
index 4503c5dfa091..353ead24fd7d 100644
--- a/drivers/staging/ozwpan/oztrace.c
+++ b/drivers/staging/ozwpan/oztrace.c
@@ -3,157 +3,34 @@
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
+#include "ozconfig.h"
#include "oztrace.h"
-#define CREATE_TRACE_POINTS
-#include "ozeventtrace.h"
-#define OZ_TRACE_DUMP_SKB_LEN_MAX 32
-#define OZ_TRACE_DUMP_URB_LEN_MAX 16
+#ifdef WANT_VERBOSE_TRACE
+unsigned long trace_flags =
+ 0
+#ifdef WANT_TRACE_STREAM
+ | OZ_TRACE_STREAM
+#endif /* WANT_TRACE_STREAM */
+#ifdef WANT_TRACE_URB
+ | OZ_TRACE_URB
+#endif /* WANT_TRACE_URB */
+
+#ifdef WANT_TRACE_CTRL_DETAIL
+ | OZ_TRACE_CTRL_DETAIL
+#endif /* WANT_TRACE_CTRL_DETAIL */
+
+#ifdef WANT_TRACE_HUB
+ | OZ_TRACE_HUB
+#endif /* WANT_TRACE_HUB */
+
+#ifdef WANT_TRACE_RX_FRAMES
+ | OZ_TRACE_RX_FRAMES
+#endif /* WANT_TRACE_RX_FRAMES */
+
+#ifdef WANT_TRACE_TX_FRAMES
+ | OZ_TRACE_TX_FRAMES
+#endif /* WANT_TRACE_TX_FRAMES */
+ ;
+#endif /* WANT_VERBOSE_TRACE */
-u32 g_debug =
-#ifdef WANT_TRACE_DATA_FLOW
- TRC_FLG(M)|TRC_FLG(R)|TRC_FLG(T)|
- TRC_FLG(S)|TRC_FLG(E)|TRC_FLG(C);
-#else
- 0;
-#endif
-
-void (*func[]) (char *fmt, va_list arg) = {
- trace_hcd_msg_evt,
- trace_isoc_msg_evt,
- trace_info_msg_evt
-};
-
-void oz_dump_data(char *buf, unsigned char *data, int len, int lmt)
-{
- int i = 0;
- if (len > lmt)
- len = lmt;
- while (len--) {
- *buf = (*data>>4) + '0';
- if (*data > (0xA0-1))
- *buf += 'A' - '9' - 1;
- *++buf = (*data++&0xF) + '0';
- if (*buf > '9')
- *buf += 'A' - '9' - 1;
- if (buf++ && !(++i%4))
- *buf++ = ' ';
- }
- *buf++ = '\n';
- *buf = 0;
-}
-
-void oz_trace_f_urb_in(struct urb *urb)
-{
- int i = 0;
- char buf[128*2];
- int endpoint = usb_pipeendpoint(urb->pipe);
-
- if (usb_pipein(urb->pipe))
- endpoint |= 0x80;
-
- if (endpoint == 0x00 || endpoint == 0x80) {
- i += sprintf(&buf[i], "OZ S %08X %02X %02X ",
- (unsigned int)((uintptr_t)urb), endpoint,
- urb->transfer_buffer_length);
-
- oz_dump_data(&buf[i], urb->setup_packet, 8, 8);
-
- } else {
- i += sprintf(&buf[i], "OZ S %08X %02X %02X ",
- (unsigned int)((uintptr_t)urb), endpoint,
- urb->transfer_buffer_length);
- if (!usb_pipein(urb->pipe)) {
- oz_dump_data(&buf[i], (u8 *)(urb->transfer_buffer),
- urb->transfer_buffer_length,
- OZ_TRACE_DUMP_URB_LEN_MAX);
-
- } else {
- oz_dump_data(&buf[i], NULL, 0, 0);
- }
-
- }
- printk(buf);
-}
-
-void oz_trace_f_urb_out(struct urb *urb, int status)
-{
- int i = 0;
- char buf[128*2];
- int endpoint = usb_pipeendpoint(urb->pipe);
- int length = urb->actual_length;
-
- if (usb_pipeisoc(urb->pipe))
- length = urb->transfer_buffer_length;
-
- if (usb_pipein(urb->pipe))
- endpoint |= 0x80;
-
- if (status != 0) {
- printk("OZ E %08X %08X\n",
- (unsigned int)((uintptr_t)urb), status);
- } else {
- i += sprintf(&buf[i], "OZ C %08X %02X %02X ",
- (unsigned int)((uintptr_t)urb),
- endpoint, urb->actual_length);
-
- if (usb_pipein(urb->pipe)) {
- oz_dump_data(&buf[i],
- (u8 *)(urb->transfer_buffer),
- urb->actual_length,
- OZ_TRACE_DUMP_URB_LEN_MAX);
- } else {
- oz_dump_data(&buf[i], NULL, 0, 0);
- }
- printk(buf);
- }
-}
-
-void oz_trace_f_skb(struct sk_buff *skb, char dir)
-{
- int i = 0;
- char buf[128*2];
- int len = skb->len;
-
- if (dir == 'T')
- len -= 14;
-
- i += sprintf(&buf[i], "OZ %c %04X ", dir, len);
- oz_dump_data(&buf[i], (u8 *)skb_network_header(skb),
- len, OZ_TRACE_DUMP_SKB_LEN_MAX);
- printk(buf);
-}
-
-void oz_trace_f_dbg(void)
-{
-}
-
-void trace_dbg_msg(int c, char *fmt, ...)
-{
- va_list arg;
-
- va_start(arg, fmt);
- func[c](fmt, arg);
- va_end(arg);
-}
-
-void trace_debug_log(char log_type, ...)
-{
- va_list arg;
- char *fmt;
-
- va_start(arg, log_type);
- fmt = va_arg(arg, char *);
- switch (log_type) {
- case 'H':
- trace_hcd_msg_evt(fmt, arg);
- break;
- case 'I':
- trace_isoc_msg_evt(fmt, arg);
- break;
- default:
- trace_info_msg_evt(fmt, arg);
- break;
- }
- va_end(arg);
-}
diff --git a/drivers/staging/ozwpan/oztrace.h b/drivers/staging/ozwpan/oztrace.h
index ab1d5cb96c1c..8293b24c5a77 100644
--- a/drivers/staging/ozwpan/oztrace.h
+++ b/drivers/staging/ozwpan/oztrace.h
@@ -5,95 +5,31 @@
*/
#ifndef _OZTRACE_H_
#define _OZTRACE_H_
-#include <linux/usb.h>
-#include <linux/netdevice.h>
-#include "ozeventtrace.h"
-
-extern struct device *g_oz_wpan_dev;
-
-#define oz_trace(fmt, ...) \
- do { dev_dbg(g_oz_wpan_dev, fmt, ##__VA_ARGS__); } while (0)
-
-void oz_trace_f_urb_out(struct urb *urb, int status);
-void oz_trace_f_urb_in(struct urb *urb);
-void oz_trace_f_skb(struct sk_buff *skb, char dir);
-void oz_trace_f_dbg(void);
-void trace_dbg_msg(int c, char *fmt, ...);
-void trace_debug_log(char log_type, ...);
-
-extern u32 g_debug;
-
-#define TRC_A 'A'
-#define TRC_B 'B'
-#define TRC_C 'C' /* urb Completion */
-#define TRC_D 'D' /* Debug */
-#define TRC_E 'E' /* urb Error */
-#define TRC_F 'F'
-#define TRC_G 'G'
-#define TRC_H 'H' /* Hcd message */
-#define TRC_I 'I' /* Isoc buffer depth */
-#define TRC_J 'J'
-#define TRC_K 'K'
-#define TRC_L 'L'
-#define TRC_M 'M' /* Message */
-#define TRC_N 'N'
-#define TRC_O 'O'
-#define TRC_P 'P'
-#define TRC_Q 'Q'
-#define TRC_R 'R' /* Rx Ozmo frame */
-#define TRC_S 'S' /* urb Submission */
-#define TRC_T 'T' /* Tx ozmo frame */
-#define TRC_U 'U'
-#define TRC_V 'V'
-#define TRC_W 'W'
-#define TRC_X 'X'
-#define TRC_Y 'Y'
-#define TRC_Z 'Z'
-
-#define TRC_FLG(f) (1<<((TRC_##f)-'A'))
-
-#define oz_trace_urb_out(u, s) \
- do { if (!g_debug) \
- trace_urb_out(u, s); \
- else if ((g_debug & TRC_FLG(C)) ||\
- ((g_debug & TRC_FLG(E)) && (s != 0))) \
- oz_trace_f_urb_out(u, s); } while (0)
-
-#define oz_trace_urb_in(u) \
- do { if (!g_debug) \
- trace_urb_in(u); \
- else if (g_debug & TRC_FLG(S)) \
- oz_trace_f_urb_in(u); } while (0)
-
-#define oz_trace_skb(u, d) \
- do { if ((!g_debug) && ('T' == d)) \
- trace_tx_frame(u); \
- else if ((!g_debug) && ('R' == d)) \
- trace_rx_frame(u); \
- else if ((('T' == d) && (g_debug & TRC_FLG(T))) || \
- (('R' == d) && (g_debug & TRC_FLG(R)))) \
- oz_trace_f_skb(u, d); } while(0)
-
-#define oz_trace_msg(f, ...) \
- do { if (!g_debug) \
- trace_debug_log(TRC_##f, __VA_ARGS__); \
- else if (g_debug & TRC_FLG(f)) \
- printk("OZ " #f " " __VA_ARGS__); } while(0)
-
-enum {
- TRACE_HCD_MSG,
- TRACE_ISOC_MSG,
- TRACE_INFO_MSG
-};
-
-#define trace_hcd_msg(fmt, ...)\
- trace_dbg_msg(TRACE_HCD_MSG, fmt, ##__VA_ARGS__)
-
-#define trace_isoc_msg(fmt, ...)\
- trace_dbg_msg(TRACE_ISOC_MSG, fmt, ##__VA_ARGS__)
-
-#define trace_info_msg(fmt, ...)\
- trace_dbg_msg(TRACE_INFO_MSG, fmt, ##__VA_ARGS__)
+#include "ozconfig.h"
+
+#define TRACE_PREFIX KERN_ALERT "OZWPAN: "
+
+#ifdef WANT_TRACE
+#define oz_trace(...) printk(TRACE_PREFIX __VA_ARGS__)
+#ifdef WANT_VERBOSE_TRACE
+extern unsigned long trace_flags;
+#define oz_trace2(_flag, ...) \
+ do { if (trace_flags & _flag) printk(TRACE_PREFIX __VA_ARGS__); \
+ } while (0)
+#else
+#define oz_trace2(...)
+#endif /* #ifdef WANT_VERBOSE_TRACE */
+#else
+#define oz_trace(...)
+#define oz_trace2(...)
+#endif /* #ifdef WANT_TRACE */
+
+#define OZ_TRACE_STREAM 0x1
+#define OZ_TRACE_URB 0x2
+#define OZ_TRACE_CTRL_DETAIL 0x4
+#define OZ_TRACE_HUB 0x8
+#define OZ_TRACE_RX_FRAMES 0x10
+#define OZ_TRACE_TX_FRAMES 0x20
#endif /* Sentry */
diff --git a/drivers/staging/ozwpan/ozurbparanoia.c b/drivers/staging/ozwpan/ozurbparanoia.c
index b05519534444..55b9afbbe47b 100644
--- a/drivers/staging/ozwpan/ozurbparanoia.c
+++ b/drivers/staging/ozwpan/ozurbparanoia.c
@@ -4,6 +4,7 @@
* -----------------------------------------------------------------------------
*/
#include <linux/usb.h>
+#include "ozconfig.h"
#ifdef WANT_URB_PARANOIA
#include "ozurbparanoia.h"
#include "oztrace.h"
@@ -21,7 +22,7 @@ void oz_remember_urb(struct urb *urb)
spin_lock_irqsave(&g_urb_mem_lock, irq_state);
if (g_nb_urbs < OZ_MAX_URBS) {
g_urb_memory[g_nb_urbs++] = urb;
- oz_trace("urb up = %d %p\n", g_nb_urbs, urb);
+ oz_trace("%lu: urb up = %d %p\n", jiffies, g_nb_urbs, urb);
} else {
oz_trace("ERROR urb buffer full\n");
}
@@ -41,8 +42,8 @@ int oz_forget_urb(struct urb *urb)
if (--g_nb_urbs > i)
memcpy(&g_urb_memory[i], &g_urb_memory[i+1],
(g_nb_urbs - i) * sizeof(struct urb *));
- oz_trace("urb down = %d %p\n",
- g_nb_urbs, urb);
+ oz_trace("%lu: urb down = %d %p\n",
+ jiffies, g_nb_urbs, urb);
}
}
spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
diff --git a/drivers/staging/ozwpan/ozusbif.h b/drivers/staging/ozwpan/ozusbif.h
index b1d58e16992a..3acf5980d7cc 100644
--- a/drivers/staging/ozwpan/ozusbif.h
+++ b/drivers/staging/ozwpan/ozusbif.h
@@ -13,10 +13,6 @@
void oz_usb_get(void *hpd);
void oz_usb_put(void *hpd);
-/* Reset device.
-*/
-void oz_usb_reset_device(void *hpd);
-
/* Stream functions.
*/
int oz_usb_stream_create(void *hpd, u8 ep_num);
@@ -25,7 +21,7 @@ int oz_usb_stream_delete(void *hpd, u8 ep_num);
/* Request functions.
*/
int oz_usb_control_req(void *hpd, u8 req_id, struct usb_ctrlrequest *setup,
- const u8 *data, int data_len);
+ u8 *data, int data_len);
int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type,
u8 index, u16 windex, int offset, int len);
int oz_usb_send_isoc(void *hpd, u8 ep_num, struct urb *urb);
@@ -34,20 +30,14 @@ void oz_usb_request_heartbeat(void *hpd);
/* Confirmation functions.
*/
void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status,
- const u8 *desc, int length, int offset, int total_size);
+ u8 *desc, int length, int offset, int total_size);
void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode,
- const u8 *data, int data_len);
-
-void oz_hcd_mark_urb_submitted(void *hport, int ep_ix, u8 req_id);
+ u8 *data, int data_len);
/* Indication functions.
*/
-void oz_hcd_data_ind(void *hport, u8 endpoint, const u8 *data, int data_len);
+void oz_hcd_data_ind(void *hport, u8 endpoint, u8 *data, int data_len);
int oz_hcd_heartbeat(void *hport);
-/* Get information.
- */
-u8 oz_get_up_max_buffer_units(void *hpd);
-
#endif /* _OZUSBIF_H */
diff --git a/drivers/staging/ozwpan/ozusbsvc.c b/drivers/staging/ozwpan/ozusbsvc.c
index c763c089ebc9..9e74f9602384 100644
--- a/drivers/staging/ozwpan/ozusbsvc.c
+++ b/drivers/staging/ozwpan/ozusbsvc.c
@@ -7,7 +7,7 @@
* The implementation of this service is split into two parts the first of which
* is protocol independent and the second contains protocol specific details.
* This split is to allow alternative protocols to be defined.
- * The implementation of this service uses ozhcd.c to implement a USB HCD.
+ * The implemenation of this service uses ozhcd.c to implement a USB HCD.
* -----------------------------------------------------------------------------
*/
#include <linux/init.h>
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/input.h>
#include <asm/unaligned.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
@@ -26,12 +27,14 @@
#include "ozhcd.h"
#include "oztrace.h"
#include "ozusbsvc.h"
+#include "ozevent.h"
/*------------------------------------------------------------------------------
* This is called once when the driver is loaded to initialise the USB service.
* Context: process
*/
int oz_usb_init(void)
{
+ oz_event_log(OZ_EVT_SERVICE, 1, OZ_APPID_USB, 0, 0);
return oz_hcd_init();
}
/*------------------------------------------------------------------------------
@@ -40,25 +43,10 @@ int oz_usb_init(void)
*/
void oz_usb_term(void)
{
+ oz_event_log(OZ_EVT_SERVICE, 2, OZ_APPID_USB, 0, 0);
oz_hcd_term();
}
/*------------------------------------------------------------------------------
- * This is called when HCD received FEAT_RESET request from hub.
- * If PD is in sleep, it then removes PD as it is unable to respond any host
- * action.
- */
-void oz_usb_reset_device(void *hpd)
-{
- struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
- struct oz_pd *pd = usb_ctx->pd;
- oz_pd_get(pd);
- if (pd && (!(pd->state & OZ_PD_S_CONNECTED))) {
- oz_trace_msg(M, "Remove device\n");
- oz_pd_stop(pd);
- }
- oz_pd_put(pd);
-}
-/*------------------------------------------------------------------------------
* This is called when the USB service is started or resumed for a PD.
* Context: softirq
*/
@@ -66,7 +54,8 @@ int oz_usb_start(struct oz_pd *pd, int resume)
{
int rc = 0;
struct oz_usb_ctx *usb_ctx;
- struct oz_usb_ctx *old_ctx;
+ struct oz_usb_ctx *old_ctx = 0;
+ oz_event_log(OZ_EVT_SERVICE, 3, OZ_APPID_USB, 0, resume);
if (resume) {
oz_trace("USB service resumed.\n");
return 0;
@@ -76,7 +65,7 @@ int oz_usb_start(struct oz_pd *pd, int resume)
* has a USB context then we will destroy it.
*/
usb_ctx = kzalloc(sizeof(struct oz_usb_ctx), GFP_ATOMIC);
- if (usb_ctx == NULL)
+ if (usb_ctx == 0)
return -ENOMEM;
atomic_set(&usb_ctx->ref_count, 1);
usb_ctx->pd = pd;
@@ -87,11 +76,12 @@ int oz_usb_start(struct oz_pd *pd, int resume)
*/
spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
old_ctx = pd->app_ctx[OZ_APPID_USB-1];
- if (old_ctx == NULL)
+ if (old_ctx == 0)
pd->app_ctx[OZ_APPID_USB-1] = usb_ctx;
oz_usb_get(pd->app_ctx[OZ_APPID_USB-1]);
spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
if (old_ctx) {
+ oz_trace("Already have USB context.\n");
kfree(usb_ctx);
usb_ctx = old_ctx;
} else if (usb_ctx) {
@@ -108,9 +98,10 @@ int oz_usb_start(struct oz_pd *pd, int resume)
oz_hcd_pd_reset(usb_ctx, usb_ctx->hport);
} else {
usb_ctx->hport = oz_hcd_pd_arrived(usb_ctx);
- if (usb_ctx->hport == NULL) {
+ if (usb_ctx->hport == 0) {
+ oz_trace("USB hub returned null port.\n");
spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
- pd->app_ctx[OZ_APPID_USB-1] = NULL;
+ pd->app_ctx[OZ_APPID_USB-1] = 0;
spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
oz_usb_put(usb_ctx);
rc = -1;
@@ -126,17 +117,17 @@ int oz_usb_start(struct oz_pd *pd, int resume)
void oz_usb_stop(struct oz_pd *pd, int pause)
{
struct oz_usb_ctx *usb_ctx;
+ oz_event_log(OZ_EVT_SERVICE, 4, OZ_APPID_USB, 0, pause);
if (pause) {
oz_trace("USB service paused.\n");
return;
}
spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1];
- pd->app_ctx[OZ_APPID_USB-1] = NULL;
+ pd->app_ctx[OZ_APPID_USB-1] = 0;
spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
if (usb_ctx) {
- struct timespec ts, now;
- getnstimeofday(&ts);
+ unsigned long tout = jiffies + HZ;
oz_trace("USB service stopping...\n");
usb_ctx->stopped = 1;
/* At this point the reference count on the usb context should
@@ -145,13 +136,10 @@ void oz_usb_stop(struct oz_pd *pd, int pause)
* should get in but someone may already be in. So wait
* until they leave but timeout after 1 second.
*/
- while ((atomic_read(&usb_ctx->ref_count) > 2)) {
- getnstimeofday(&now);
- /*Approx 1 Sec. this is not perfect calculation*/
- if (now.tv_sec != ts.tv_sec)
- break;
- }
- oz_trace_msg(M, "USB service stopped.\n");
+ while ((atomic_read(&usb_ctx->ref_count) > 2) &&
+ time_before(jiffies, tout))
+ ;
+ oz_trace("USB service stopped.\n");
oz_hcd_pd_departed(usb_ctx->hport);
/* Release the reference taken in oz_usb_start.
*/
@@ -177,6 +165,7 @@ void oz_usb_put(void *hpd)
{
struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
if (atomic_dec_and_test(&usb_ctx->ref_count)) {
+ oz_trace("Dealloc USB context.\n");
oz_pd_put(usb_ctx->pd);
kfree(usb_ctx);
}
@@ -193,7 +182,7 @@ int oz_usb_heartbeat(struct oz_pd *pd)
if (usb_ctx)
oz_usb_get(usb_ctx);
spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
- if (usb_ctx == NULL)
+ if (usb_ctx == 0)
return rc;
if (usb_ctx->stopped)
goto done;
@@ -211,6 +200,7 @@ int oz_usb_stream_create(void *hpd, u8 ep_num)
{
struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
struct oz_pd *pd = usb_ctx->pd;
+ oz_trace("oz_usb_stream_create(0x%x)\n", ep_num);
if (pd->mode & OZ_F_ISOC_NO_ELTS) {
oz_isoc_stream_create(pd, ep_num);
} else {
@@ -232,6 +222,7 @@ int oz_usb_stream_delete(void *hpd, u8 ep_num)
if (usb_ctx) {
struct oz_pd *pd = usb_ctx->pd;
if (pd) {
+ oz_trace("oz_usb_stream_delete(0x%x)\n", ep_num);
if (pd->mode & OZ_F_ISOC_NO_ELTS) {
oz_isoc_stream_delete(pd, ep_num);
} else {
diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c
index 609d7119051a..66bd576bb5e9 100644
--- a/drivers/staging/ozwpan/ozusbsvc1.c
+++ b/drivers/staging/ozwpan/ozusbsvc1.c
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/input.h>
#include <asm/unaligned.h>
+#include "ozconfig.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
#include "ozpd.h"
@@ -21,24 +22,10 @@
#include "ozhcd.h"
#include "oztrace.h"
#include "ozusbsvc.h"
+#include "ozevent.h"
/*------------------------------------------------------------------------------
*/
#define MAX_ISOC_FIXED_DATA (253-sizeof(struct oz_isoc_fixed))
-
-/*------------------------------------------------------------------------------
- * Context: softirq
- */
-static void oz_usb_setup_elt_completion_callback(struct oz_pd *pd, long context)
-{
- struct oz_usb_ctx *ctx;
- spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
- ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1];
- if (ctx) {
- u8 req_id = (u8)context;
- oz_hcd_mark_urb_submitted(ctx->hport, 0, req_id);
- }
- spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
-}
/*------------------------------------------------------------------------------
* Context: softirq
*/
@@ -76,12 +63,16 @@ int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type,
struct oz_get_desc_req *body;
struct oz_elt_buf *eb = &pd->elt_buff;
struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
+ oz_trace(" req_type = 0x%x\n", req_type);
+ oz_trace(" desc_type = 0x%x\n", desc_type);
+ oz_trace(" index = 0x%x\n", index);
+ oz_trace(" windex = 0x%x\n", windex);
+ oz_trace(" offset = 0x%x\n", offset);
+ oz_trace(" len = 0x%x\n", len);
if (len > 200)
len = 200;
if (ei == 0)
return -1;
- ei->callback = oz_usb_setup_elt_completion_callback;
- ei->context = req_id;
elt = (struct oz_elt *)ei->data;
elt->length = sizeof(struct oz_get_desc_req);
body = (struct oz_get_desc_req *)(elt+1);
@@ -108,8 +99,6 @@ static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index)
struct oz_set_config_req *body;
if (ei == 0)
return -1;
- ei->callback = oz_usb_setup_elt_completion_callback;
- ei->context = req_id;
elt = (struct oz_elt *)ei->data;
elt->length = sizeof(struct oz_set_config_req);
body = (struct oz_set_config_req *)(elt+1);
@@ -131,8 +120,6 @@ static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt)
struct oz_set_interface_req *body;
if (ei == 0)
return -1;
- ei->callback = oz_usb_setup_elt_completion_callback;
- ei->context = req_id;
elt = (struct oz_elt *)ei->data;
elt->length = sizeof(struct oz_set_interface_req);
body = (struct oz_set_interface_req *)(elt+1);
@@ -157,8 +144,6 @@ static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type,
if (ei == 0)
return -1;
elt = (struct oz_elt *)ei->data;
- ei->callback = oz_usb_setup_elt_completion_callback;
- ei->context = req_id;
elt->length = sizeof(struct oz_feature_req);
body = (struct oz_feature_req *)(elt+1);
body->type = type;
@@ -172,7 +157,7 @@ static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type,
* Context: tasklet
*/
static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type,
- u8 request, __le16 value, __le16 index, const u8 *data, int data_len)
+ u8 request, __le16 value, __le16 index, u8 *data, int data_len)
{
struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
struct oz_pd *pd = usb_ctx->pd;
@@ -182,8 +167,6 @@ static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type,
struct oz_vendor_class_req *body;
if (ei == 0)
return -1;
- ei->callback = oz_usb_setup_elt_completion_callback;
- ei->context = req_id;
elt = (struct oz_elt *)ei->data;
elt->length = sizeof(struct oz_vendor_class_req) - 1 + data_len;
body = (struct oz_vendor_class_req *)(elt+1);
@@ -201,13 +184,16 @@ static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type,
* Context: tasklet
*/
int oz_usb_control_req(void *hpd, u8 req_id, struct usb_ctrlrequest *setup,
- const u8 *data, int data_len)
+ u8 *data, int data_len)
{
unsigned wvalue = le16_to_cpu(setup->wValue);
unsigned windex = le16_to_cpu(setup->wIndex);
unsigned wlength = le16_to_cpu(setup->wLength);
int rc = 0;
-
+ oz_event_log(OZ_EVT_CTRL_REQ, setup->bRequest, req_id,
+ (void *)(((unsigned long)(setup->wValue))<<16 |
+ ((unsigned long)setup->wIndex)),
+ setup->bRequestType);
if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
switch (setup->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
@@ -259,14 +245,10 @@ int oz_usb_send_isoc(void *hpd, u8 ep_num, struct urb *urb)
struct usb_iso_packet_descriptor *desc;
if (pd->mode & OZ_F_ISOC_NO_ELTS) {
- urb->actual_length = 0;
for (i = 0; i < urb->number_of_packets; i++) {
u8 *data;
desc = &urb->iso_frame_desc[i];
data = ((u8 *)urb->transfer_buffer)+desc->offset;
- desc->status = 0;
- desc->actual_length = desc->length;
- urb->actual_length += desc->length;
oz_send_isoc_unit(pd, ep_num, data, desc->length);
}
return 0;
@@ -387,9 +369,7 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt)
if (usb_hdr->elt_seq_num != 0) {
if (((usb_ctx->rx_seq_num - usb_hdr->elt_seq_num) & 0x80) == 0)
/* Reject duplicate element. */
- oz_trace_msg(M, "USB seq overlap %02X %02X\n",
- usb_ctx->rx_seq_num,
- usb_hdr->elt_seq_num);
+ goto done;
}
usb_ctx->rx_seq_num = usb_hdr->elt_seq_num;
switch (usb_hdr->type) {
@@ -401,6 +381,7 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt)
u16 offs = le16_to_cpu(get_unaligned(&body->offset));
u16 total_size =
le16_to_cpu(get_unaligned(&body->total_size));
+ oz_trace("USB_REQ_GET_DESCRIPTOR - cnf\n");
oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id,
body->rcode, body->data,
data_len, offs, total_size);
@@ -454,11 +435,3 @@ void oz_usb_farewell(struct oz_pd *pd, u8 ep_num, u8 *data, u8 len)
}
oz_usb_put(usb_ctx);
}
-/*------------------------------------------------------------------------------
- * Context: softirq or process
- */
-u8 oz_get_up_max_buffer_units(void *hpd)
-{
- struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
- return usb_ctx->pd->up_audio_buf;
-}