*/
static struct oz_cdev g_cdev;
static struct class *g_oz_class;
+
/*------------------------------------------------------------------------------
* Context: process and softirq
*/
spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
return ctx;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
kfree(ctx);
}
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
filp->private_data = dev;
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
{
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_pd_put(pd);
return count;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_pd_put(pd);
return count;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
poll_wait(filp, &dev->rdq, wait);
return ret;
}
+
/*------------------------------------------------------------------------------
*/
static const struct file_operations oz_fops = {
.unlocked_ioctl = oz_cdev_ioctl,
.poll = oz_cdev_poll
};
+
/*------------------------------------------------------------------------------
* Context: process
*/
unregister_chrdev_region(g_cdev.devnum, 1);
return err;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_app_enable(OZ_APPID_SERIAL, 1);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
{
oz_app_enable(OZ_APPID_SERIAL, 0);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_dbg(ON, "Serial service started\n");
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
}
oz_dbg(ON, "Serial service stopped\n");
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
spin_lock_init(&buf->lock);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
}
buf->free_elts = 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
}
return ei;
}
+
/*------------------------------------------------------------------------------
* Precondition: oz_elt_buf.lock must be held.
* Context: softirq or process
}
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
spin_unlock_bh(&buf->lock);
}
+
/*------------------------------------------------------------------------------
*/
int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count)
spin_unlock_bh(&buf->lock);
return 0;
}
+
/*------------------------------------------------------------------------------
*/
int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id)
oz_elt_stream_put(st);
return 0;
}
+
/*------------------------------------------------------------------------------
*/
void oz_elt_stream_get(struct oz_elt_stream *st)
{
atomic_inc(&st->ref_count);
}
+
/*------------------------------------------------------------------------------
*/
void oz_elt_stream_put(struct oz_elt_stream *st)
kfree(st);
}
}
+
/*------------------------------------------------------------------------------
* Precondition: Element buffer lock must be held.
* If this function fails the caller is responsible for deallocating the elt
&buf->isoc_list : &buf->order_list);
return 0;
}
+
/*------------------------------------------------------------------------------
*/
int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
spin_unlock_bh(&buf->lock);
return count;
}
+
/*------------------------------------------------------------------------------
*/
int oz_are_elts_available(struct oz_elt_buf *buf)
{
return buf->order_list.next != &buf->order_list;
}
+
/*------------------------------------------------------------------------------
*/
void oz_trim_elt_pool(struct oz_elt_buf *buf)
#include "ozusbif.h"
#include "ozurbparanoia.h"
#include "ozhcd.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"
+
/* Maximum number of free urb links that can be kept in the pool.
*/
#define OZ_MAX_LINK_POOL_SIZE 16
+
/* 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.
unsigned flags;
int start_frame;
};
+
/* Bits in the flags field. */
#define OZ_F_EP_BUFFERING 0x1
#define OZ_F_EP_HAVE_STREAM 0x2
struct list_head isoc_out_ep;
struct list_head isoc_in_ep;
};
+
#define OZ_PORT_F_PRESENT 0x1
#define OZ_PORT_F_CHANGED 0x2
#define OZ_PORT_F_DYING 0x4
uint flags;
struct usb_hcd *hcd;
};
+
/* Bits in flags field.
*/
#define OZ_HDC_F_SUSPENDED 0x1
static struct oz_urb_link *oz_remove_urb(struct oz_endpoint *ep,
struct urb *urb);
static void oz_hcd_clear_orphanage(struct oz_hcd *ozhcd, int status);
+
/*------------------------------------------------------------------------------
* Static external variables.
*/
.owner = THIS_MODULE,
},
};
+
/*------------------------------------------------------------------------------
* Gets our private context area (which is of type struct oz_hcd) from the
* usb_hcd structure.
{
return (struct oz_hcd *)hcd->hcd_priv;
}
+
/*------------------------------------------------------------------------------
* Searches list of ports to find the index of the one with a specified USB
* bus address. If none of the ports has the bus address then the connection
}
return ozhcd->conn_port;
}
+
/*------------------------------------------------------------------------------
* Allocates an urb link, first trying the pool but going to heap if empty.
* Context: any
urbl = kmalloc(sizeof(struct oz_urb_link), GFP_ATOMIC);
return urbl;
}
+
/*------------------------------------------------------------------------------
* Frees an urb link by putting it in the pool if there is enough space or
* deallocating it to heap otherwise.
kfree(urbl);
}
}
+
/*------------------------------------------------------------------------------
* Deallocates all the urb links in the pool.
* Context: unknown
kfree(urbl);
}
}
+
/*------------------------------------------------------------------------------
* Allocates endpoint structure and optionally a buffer. If a buffer is
* allocated it immediately follows the endpoint structure.
}
return ep;
}
+
/*------------------------------------------------------------------------------
* Pre-condition: Must be called with g_tasklet_lock held and interrupts
* disabled.
}
return NULL;
}
+
/*------------------------------------------------------------------------------
* This is called when we have finished processing an urb. It unlinks it from
* the ep and returns it to the core.
if (cancel_urbl)
oz_free_urb_link(cancel_urbl);
}
+
/*------------------------------------------------------------------------------
* Deallocates an endpoint including deallocating any associated stream and
* returning any queued urbs to the core.
oz_dbg(ON, "Freeing endpoint memory\n");
kfree(ep);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_free_urb_link(urbl);
return err;
}
+
/*------------------------------------------------------------------------------
* Removes an urb from the queue in the endpoint.
* Returns 0 if it is found and -EIDRM otherwise.
oz_free_urb_link(urbl);
return urbl ? 0 : -EIDRM;
}
+
/*------------------------------------------------------------------------------
* Finds an urb given its request id.
* Context: softirq
oz_free_urb_link(urbl);
return urb;
}
+
/*------------------------------------------------------------------------------
* Pre-condition: Port lock must be held.
* Context: softirq
oz_usb_get(hpd);
port->hpd = hpd;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
spin_unlock_bh(&g_hcdlock);
return ozhcd;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
if (ozhcd)
usb_put_hcd(ozhcd->hcd);
}
+
/*------------------------------------------------------------------------------
* This is called by the protocol handler to notify that a PD has arrived.
* We allocate a port to associate with the PD and create a structure for
oz_hcd_put(ozhcd);
return hport;
}
+
/*------------------------------------------------------------------------------
* This is called by the protocol handler to notify that the PD has gone away.
* We need to deallocate all resources and then request that the root hub is
usb_hcd_poll_rh_status(ozhcd->hcd);
oz_usb_put(hpd);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_clean_endpoints_for_config(ozhcd->hcd, port);
usb_hcd_poll_rh_status(ozhcd->hcd);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
urb->actual_length = total_size;
oz_complete_urb(port->ozhcd->hcd, urb, 0);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
oz_complete_urb(hcd, urb, rc);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
oz_complete_urb(hcd, urb, rc);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_complete_urb(hcd, urb, 0);
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
ep->buffered_units++;
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
done:
spin_unlock_bh(&ozhcd->hcd_lock);
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
{
return atomic_inc_return(&g_usb_frame_number);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_ep_free(port, ep);
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_clean_endpoints_for_config(hcd, port);
return -1;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
port->num_iface = 0;
spin_unlock_bh(&ozhcd->hcd_lock);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
spin_unlock_bh(&ozhcd->hcd_lock);
return hpd;
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
oz_usb_request_heartbeat(port->hpd);
}
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
oz_hcd_put(ozhcd);
}
+
/*------------------------------------------------------------------------------
* This function searches for the urb in any of the lists it could be in.
* If it is found it is removed from the list and completed. If the urb is
oz_complete_urb(ozhcd->hcd, urb, -EPIPE);
}
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
spin_unlock_irqrestore(&g_tasklet_lock, irq_state);
oz_hcd_put(ozhcd);
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
}
}
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
hcd->uses_new_polling = 1;
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
static void oz_hcd_stop(struct usb_hcd *hcd)
{
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
static void oz_hcd_shutdown(struct usb_hcd *hcd)
{
}
+
/*------------------------------------------------------------------------------
* Called to queue an urb for the device.
* This function should return a non-zero error code if it fails the urb but
atomic_inc(&g_pending_urbs);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
}
return NULL;
}
+
/*------------------------------------------------------------------------------
* Called to dequeue a previously submitted urb for the device.
* Context: any
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
struct usb_host_endpoint *ep)
{
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
struct usb_host_endpoint *ep)
{
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
oz_dbg(ON, "oz_hcd_get_frame_number\n");
return oz_usb_get_frame_number();
}
+
/*------------------------------------------------------------------------------
* Context: softirq
* This is called as a consquence of us calling usb_hcd_poll_rh_status() and we
else
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
__constant_cpu_to_le16(0x0001);
desc->bNbrPorts = OZ_NB_PORTS;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_dbg(HUB, "Port[%d] status = 0x%x\n", port_id, port->status);
return err;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
port_id, ozhcd->ports[port_id-1].status);
return err;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_dbg(HUB, "Port[%d] status = %x\n", windex, status);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
return err;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
spin_unlock_bh(&ozhcd->hcd_lock);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
spin_unlock_bh(&ozhcd->hcd_lock);
return 0;
}
+
/*------------------------------------------------------------------------------
*/
static void oz_plat_shutdown(struct platform_device *dev)
spin_unlock_bh(&g_hcdlock);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: unknown
*/
oz_dbg(ON, "oz_hcd_init() failed %d\n", err);
return err;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
* netcards. Bindings can be added later using an IOCTL.
*/
static char *g_net_dev = "";
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_apps_init();
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_apps_term();
oz_cdev_deregister();
}
+
/*------------------------------------------------------------------------------
*/
module_param(g_net_dev, charp, S_IRUGO);
/*------------------------------------------------------------------------------
*/
#define OZ_MAX_TX_POOL_SIZE 6
+
/*------------------------------------------------------------------------------
*/
static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd);
static int oz_def_app_start(struct oz_pd *pd, int resume);
static void oz_def_app_stop(struct oz_pd *pd, int pause);
static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt);
+
/*------------------------------------------------------------------------------
* Counts the uncompleted isoc frames submitted to netcard.
*/
static atomic_t g_submitted_isoc = ATOMIC_INIT(0);
+
/* Application handler functions.
*/
static const struct oz_app_if g_app_if[OZ_APPID_MAX] = {
NULL,
OZ_APPID_SERIAL},
};
+
/*------------------------------------------------------------------------------
* Context: process
*/
{
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
static void oz_def_app_term(void)
{
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
{
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
static void oz_def_app_stop(struct oz_pd *pd, int pause)
{
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt)
{
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
break;
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
{
atomic_inc(&pd->ref_count);
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
if (atomic_dec_and_test(&pd->ref_count))
oz_pd_destroy(pd);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
return pd;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
dev_put(pd->net_dev);
kfree(pd);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
}
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
;
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
oz_dbg(ON, "pd ref count = %d\n", atomic_read(&pd->ref_count));
oz_pd_put(pd);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return do_stop;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return f;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
oz_dbg(TX_FRAMES, "Releasing ISOC Frame isoc_nb= %d\n",
pd->nb_queued_isoc_frames);
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
spin_unlock_bh(&pd->tx_frame_lock);
kfree(f);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_hdr->control |= OZ_F_MORE_DATA;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_hdr->last_pkt_num = pd->trigger_pkt_num & OZ_LAST_PN_MASK;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
spin_unlock(&pd->tx_frame_lock);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
kfree_skb(skb);
return NULL;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
if (pd->elt_buff.free_elts > pd->elt_buff.max_free_elts)
oz_trim_elt_pool(&pd->elt_buff);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
out: oz_prepare_frame(pd, 1);
oz_send_next_queued_frame(pd, 0);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_elt_info_free_chain(&pd->elt_buff, &list);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_retire_frame(pd, f);
}
}
+
/*------------------------------------------------------------------------------
* Precondition: stream_lock must be held.
* Context: softirq
}
return NULL;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
kfree(st);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
kfree_skb(st->skb);
kfree(st);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_isoc_stream_free(st);
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: any
*/
{
atomic_dec(&g_submitted_isoc);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
if (g_app_if[i].init)
g_app_if[i].init();
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
if (g_app_if[i].term)
g_app_if[i].term();
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
ai = &g_app_if[app_id-1];
ai->rx(pd, elt);
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
#include <asm/unaligned.h>
#include <linux/uaccess.h>
#include <net/psnap.h>
+
/*------------------------------------------------------------------------------
*/
#define OZ_CF_CONN_SUCCESS 1
static u8 g_session_id;
static u16 g_apps = 0x1;
static int g_processing_rx;
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
return g_session_id;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
dev_queue_xmit(skb);
return;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
oz_dbg(ON, "Keepalive = %lu mSec\n", pd->keep_alive);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
oz_dbg(ON, "Presleep time = %lu mSec\n", pd->presleep);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_pd_destroy(free_pd);
return pd;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
if (found)
kfree(f2);
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
oz_pd_put(pd);
consume_skb(skb);
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
spin_unlock_bh(&g_polling_lock);
oz_dbg(ON, "Protocol stopped\n");
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_pd_heartbeat(pd, apps);
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
break;
}
}
+
/*------------------------------------------------------------------------------
* Context: Interrupt
*/
tasklet_schedule(&pd->heartbeat_tasklet);
return HRTIMER_RESTART;
}
+
/*------------------------------------------------------------------------------
* Context: Interrupt
*/
tasklet_schedule(&pd->timeout_tasklet);
return HRTIMER_NORESTART;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
}
spin_unlock_bh(&g_polling_lock);
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
oz_timer_add(pd, OZ_TIMER_HEARTBEAT, pd->pulse_period > 0 ?
pd->pulse_period : OZ_QUANTUM);
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
spin_unlock_bh(&g_polling_lock);
return NULL;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
spin_unlock_bh(&g_polling_lock);
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
}
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
oz_pd_put(pd);
}
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
kfree(binding);
}
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
*dname = 0;
return s;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: process
*/
spin_unlock_bh(&g_polling_lock);
return count;
}
+
/*------------------------------------------------------------------------------
*/
void oz_polling_lock_bh(void)
{
spin_lock_bh(&g_polling_lock);
}
+
/*------------------------------------------------------------------------------
*/
void oz_polling_unlock_bh(void)
struct urb *g_urb_memory[OZ_MAX_URBS];
int g_nb_urbs;
DEFINE_SPINLOCK(g_urb_mem_lock);
+
/*-----------------------------------------------------------------------------
*/
void oz_remember_urb(struct urb *urb)
}
spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
}
+
/*------------------------------------------------------------------------------
*/
int oz_forget_urb(struct urb *urb)
{
return oz_hcd_init();
}
+
/*------------------------------------------------------------------------------
* This is called once when the driver is unloaded to terminate the USB service.
* Context: process
{
oz_hcd_term();
}
+
/*------------------------------------------------------------------------------
* This is called when the USB service is started or resumed for a PD.
* Context: softirq
oz_usb_put(usb_ctx);
return rc;
}
+
/*------------------------------------------------------------------------------
* This is called when the USB service is stopped or paused for a PD.
* Context: softirq or process
oz_usb_put(usb_ctx);
}
}
+
/*------------------------------------------------------------------------------
* This increments the reference count of the context area for a specific PD.
* This ensures this context area does not disappear while still in use.
atomic_inc(&usb_ctx->ref_count);
}
+
/*------------------------------------------------------------------------------
* This decrements the reference count of the context area for a specific PD
* and destroys the context area if the reference count becomes zero.
kfree(usb_ctx);
}
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
oz_usb_put(usb_ctx);
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq or process
*/
#include "ozusbif.h"
#include "ozhcd.h"
#include "ozusbsvc.h"
+
/*------------------------------------------------------------------------------
*/
#define MAX_ISOC_FIXED_DATA (253-sizeof(struct oz_isoc_fixed))
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
spin_unlock_bh(&eb->lock);
return ret;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
body->index = index;
return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
body->index = index;
return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
body->alternative = alt;
return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
put_unaligned(feature, &body->feature);
return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
memcpy(body->data, data, data_len);
return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
+
/*------------------------------------------------------------------------------
* Context: tasklet
*/
}
return rc;
}
+
/*------------------------------------------------------------------------------
* Context: softirq
*/
}
return 0;
}
+
/*------------------------------------------------------------------------------
* Context: softirq-serialized
*/
}
}
+
/*------------------------------------------------------------------------------
* This is called when the PD has received a USB element. The type of element
* is determined and is then passed to an appropriate handler function.
done:
oz_usb_put(usb_ctx);
}
+
/*------------------------------------------------------------------------------
* Context: softirq, process
*/