1b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/* ----------------------------------------------------------------------------- 2b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Copyright (c) 2011 Ozmo Inc 3b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Released under the GNU General Public License Version 2 (GPLv2). 4b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * 5b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This file provides protocol independent part of the implementation of the USB 6b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * service for a PD. 7b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * The implementation of this service is split into two parts the first of which 8b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * is protocol independent and the second contains protocol specific details. 9b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This split is to allow alternative protocols to be defined. 10b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * The implemenation of this service uses ozhcd.c to implement a USB HCD. 11b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * ----------------------------------------------------------------------------- 12b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 13b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/init.h> 14b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/module.h> 15b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/timer.h> 16b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/sched.h> 17b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/netdevice.h> 18b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/errno.h> 19b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <linux/input.h> 20b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include <asm/unaligned.h> 21b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozconfig.h" 22b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozprotocol.h" 23b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozeltbuf.h" 24b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozpd.h" 25b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozproto.h" 26b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozusbif.h" 27b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozhcd.h" 28b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "oztrace.h" 29b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozusbsvc.h" 30b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly#include "ozevent.h" 31b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 32b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This is called once when the driver is loaded to initialise the USB service. 33b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: process 34b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 35b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyint oz_usb_init(void) 36b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 37b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_event_log(OZ_EVT_SERVICE, 1, OZ_APPID_USB, 0, 0); 38b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return oz_hcd_init(); 39b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 40b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 41b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This is called once when the driver is unloaded to terminate the USB service. 42b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: process 43b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 44b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyvoid oz_usb_term(void) 45b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 46b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_event_log(OZ_EVT_SERVICE, 2, OZ_APPID_USB, 0, 0); 47b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_hcd_term(); 48b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 49b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 50b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This is called when the USB service is started or resumed for a PD. 51b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq 52b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 53b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyint oz_usb_start(struct oz_pd *pd, int resume) 54b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 55b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly int rc = 0; 56b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx; 57b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *old_ctx = 0; 58b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_event_log(OZ_EVT_SERVICE, 3, OZ_APPID_USB, 0, resume); 59b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (resume) { 60b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB service resumed.\n"); 61b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return 0; 62b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 63b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB service started.\n"); 64b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* Create a USB context in case we need one. If we find the PD already 65b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * has a USB context then we will destroy it. 66b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 671ec41a31fb695682cab7fc7c1f6ced84d188b6f9Greg Kroah-Hartman usb_ctx = kzalloc(sizeof(struct oz_usb_ctx), GFP_ATOMIC); 68b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx == 0) 691ec41a31fb695682cab7fc7c1f6ced84d188b6f9Greg Kroah-Hartman return -ENOMEM; 70b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly atomic_set(&usb_ctx->ref_count, 1); 71b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx->pd = pd; 72b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx->stopped = 0; 73b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* Install the USB context if the PD doesn't already have one. 74b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * If it does already have one then destroy the one we have just 75b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * created. 76b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 77b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); 78b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly old_ctx = pd->app_ctx[OZ_APPID_USB-1]; 79b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (old_ctx == 0) 80b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly pd->app_ctx[OZ_APPID_USB-1] = usb_ctx; 81b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_get(pd->app_ctx[OZ_APPID_USB-1]); 82b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); 83b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (old_ctx) { 84b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("Already have USB context.\n"); 851ec41a31fb695682cab7fc7c1f6ced84d188b6f9Greg Kroah-Hartman kfree(usb_ctx); 86b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx = old_ctx; 87b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } else if (usb_ctx) { 88b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* Take a reference to the PD. This will be released when 89b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * the USB context is destroyed. 90b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 91b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_get(pd); 92b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 93b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* If we already had a USB context and had obtained a port from 94b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * the USB HCD then just reset the port. If we didn't have a port 95b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * then report the arrival to the USB HCD so we get one. 96b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 97b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx->hport) { 98b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_hcd_pd_reset(usb_ctx, usb_ctx->hport); 99b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } else { 100b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx->hport = oz_hcd_pd_arrived(usb_ctx); 101b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx->hport == 0) { 102b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB hub returned null port.\n"); 103b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); 104b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly pd->app_ctx[OZ_APPID_USB-1] = 0; 105b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); 106b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_put(usb_ctx); 107b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly rc = -1; 108b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 109b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 110b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_put(usb_ctx); 111b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return rc; 112b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 113b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 114b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This is called when the USB service is stopped or paused for a PD. 115b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq or process 116b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 117b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyvoid oz_usb_stop(struct oz_pd *pd, int pause) 118b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 119b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx; 120b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_event_log(OZ_EVT_SERVICE, 4, OZ_APPID_USB, 0, pause); 121b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (pause) { 122b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB service paused.\n"); 123b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return; 124b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 125b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); 126b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; 127b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly pd->app_ctx[OZ_APPID_USB-1] = 0; 128b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); 129b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx) { 130b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly unsigned long tout = jiffies + HZ; 131b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB service stopping...\n"); 132b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx->stopped = 1; 133b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* At this point the reference count on the usb context should 134b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * be 2 - one from when we created it and one from the hcd 135b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * which claims a reference. Since stopped = 1 no one else 136b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * should get in but someone may already be in. So wait 137b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * until they leave but timeout after 1 second. 138b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 139b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly while ((atomic_read(&usb_ctx->ref_count) > 2) && 140b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly time_before(jiffies, tout)) 141b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly ; 142b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("USB service stopped.\n"); 143b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_hcd_pd_departed(usb_ctx->hport); 144b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly /* Release the reference taken in oz_usb_start. 145b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 146b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_put(usb_ctx); 147b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 148b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 149b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 150b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This increments the reference count of the context area for a specific PD. 151b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This ensures this context area does not disappear while still in use. 152b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq 153b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 154b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyvoid oz_usb_get(void *hpd) 155b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 156b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; 157b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly atomic_inc(&usb_ctx->ref_count); 158b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 159b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 160b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * This decrements the reference count of the context area for a specific PD 161b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * and destroys the context area if the reference count becomes zero. 162b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq or process 163b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 164b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyvoid oz_usb_put(void *hpd) 165b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 166b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; 167b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (atomic_dec_and_test(&usb_ctx->ref_count)) { 168b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("Dealloc USB context.\n"); 169b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_put(usb_ctx->pd); 1701ec41a31fb695682cab7fc7c1f6ced84d188b6f9Greg Kroah-Hartman kfree(usb_ctx); 171b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 172b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 173b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 174b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq 175b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 176b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyint oz_usb_heartbeat(struct oz_pd *pd) 177b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 178b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx; 179b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly int rc = 0; 180b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); 181b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; 182b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx) 183b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_get(usb_ctx); 184b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); 185b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx == 0) 186b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return rc; 187b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx->stopped) 188b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly goto done; 189b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx->hport) 190b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (oz_hcd_heartbeat(usb_ctx->hport)) 191b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly rc = 1; 192b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellydone: 193b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_usb_put(usb_ctx); 194b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return rc; 195b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 196b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 197b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq 198b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 199b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyint oz_usb_stream_create(void *hpd, u8 ep_num) 200b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 201b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; 202b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_pd *pd = usb_ctx->pd; 203b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("oz_usb_stream_create(0x%x)\n", ep_num); 204b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (pd->mode & OZ_F_ISOC_NO_ELTS) { 205b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_isoc_stream_create(pd, ep_num); 206b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } else { 207b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_get(pd); 208b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (oz_elt_stream_create(&pd->elt_buff, ep_num, 209b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly 4*pd->max_tx_size)) { 210b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_put(pd); 211b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return -1; 212b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 213b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 214b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return 0; 215b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 216b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 217b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq 218b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 219b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyint oz_usb_stream_delete(void *hpd, u8 ep_num) 220b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 221b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; 222b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx) { 223b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_pd *pd = usb_ctx->pd; 224b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (pd) { 225b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_trace("oz_usb_stream_delete(0x%x)\n", ep_num); 226b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (pd->mode & OZ_F_ISOC_NO_ELTS) { 227b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_isoc_stream_delete(pd, ep_num); 228b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } else { 229b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (oz_elt_stream_delete(&pd->elt_buff, ep_num)) 230b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return -1; 231b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_put(pd); 232b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 233b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 234b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly } 235b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly return 0; 236b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 237b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly/*------------------------------------------------------------------------------ 238b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly * Context: softirq or process 239b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly */ 240b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kellyvoid oz_usb_request_heartbeat(void *hpd) 241b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly{ 242b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; 243b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly if (usb_ctx && usb_ctx->pd) 244b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly oz_pd_request_heartbeat(usb_ctx->pd); 245b3147863b523912633bfd4876d242cd5ae7d8e7aChris Kelly} 246