2008-09-17 19:34:23 +04:00
/*
* WUSB cluster reservation management
*
* Copyright ( C ) 2007 Cambridge Silicon Radio Ltd .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/kernel.h>
# include <linux/uwb.h>
# include "wusbhc.h"
/*
* WUSB cluster reservations are multicast reservations with the
* broadcast cluster ID ( BCID ) as the target DevAddr .
*
* FIXME : consider adjusting the reservation depending on what devices
* are attached .
*/
static int wusbhc_bwa_set ( struct wusbhc * wusbhc , u8 stream ,
const struct uwb_mas_bm * mas )
{
if ( mas = = NULL )
mas = & uwb_mas_bm_zero ;
return wusbhc - > bwa_set ( wusbhc , stream , mas ) ;
}
/**
* wusbhc_rsv_complete_cb - WUSB HC reservation complete callback
* @ rsv : the reservation
*
* Either set or clear the HC ' s view of the reservation .
*
* FIXME : when a reservation is denied the HC should be stopped .
*/
static void wusbhc_rsv_complete_cb ( struct uwb_rsv * rsv )
{
struct wusbhc * wusbhc = rsv - > pal_priv ;
struct device * dev = wusbhc - > dev ;
2008-12-12 16:00:06 +03:00
struct uwb_mas_bm mas ;
2008-09-17 19:34:23 +04:00
char buf [ 72 ] ;
switch ( rsv - > state ) {
case UWB_RSV_STATE_O_ESTABLISHED :
2008-12-12 16:00:06 +03:00
uwb_rsv_get_usable_mas ( rsv , & mas ) ;
bitmap_scnprintf ( buf , sizeof ( buf ) , mas . bm , UWB_NUM_MAS ) ;
2008-09-17 19:34:23 +04:00
dev_dbg ( dev , " established reservation: %s \n " , buf ) ;
2008-12-12 16:00:06 +03:00
wusbhc_bwa_set ( wusbhc , rsv - > stream , & mas ) ;
2008-09-17 19:34:23 +04:00
break ;
case UWB_RSV_STATE_NONE :
dev_dbg ( dev , " removed reservation \n " ) ;
wusbhc_bwa_set ( wusbhc , 0 , NULL ) ;
break ;
default :
dev_dbg ( dev , " unexpected reservation state: %d \n " , rsv - > state ) ;
break ;
}
}
/**
* wusbhc_rsv_establish - establish a reservation for the cluster
2011-03-31 05:57:33 +04:00
* @ wusbhc : the WUSB HC requesting a bandwidth reservation
2008-09-17 19:34:23 +04:00
*/
int wusbhc_rsv_establish ( struct wusbhc * wusbhc )
{
struct uwb_rc * rc = wusbhc - > uwb_rc ;
struct uwb_rsv * rsv ;
struct uwb_dev_addr bcid ;
int ret ;
rsv = uwb_rsv_create ( rc , wusbhc_rsv_complete_cb , wusbhc ) ;
if ( rsv = = NULL )
return - ENOMEM ;
bcid . data [ 0 ] = wusbhc - > cluster_id ;
bcid . data [ 1 ] = 0 ;
rsv - > target . type = UWB_RSV_TARGET_DEVADDR ;
rsv - > target . devaddr = bcid ;
rsv - > type = UWB_DRP_TYPE_PRIVATE ;
2008-12-12 16:00:06 +03:00
rsv - > max_mas = 256 ; /* try to get as much as possible */
rsv - > min_mas = 15 ; /* one MAS per zone */
rsv - > max_interval = 1 ; /* max latency is one zone */
2008-09-17 19:34:23 +04:00
rsv - > is_multicast = true ;
ret = uwb_rsv_establish ( rsv ) ;
if ( ret = = 0 )
wusbhc - > rsv = rsv ;
else
uwb_rsv_destroy ( rsv ) ;
return ret ;
}
/**
2008-10-27 18:22:46 +03:00
* wusbhc_rsv_terminate - terminate the cluster reservation
2008-09-17 19:34:23 +04:00
* @ wusbhc : the WUSB host whose reservation is to be terminated
*/
void wusbhc_rsv_terminate ( struct wusbhc * wusbhc )
{
2008-12-12 16:25:21 +03:00
if ( wusbhc - > rsv ) {
uwb_rsv_terminate ( wusbhc - > rsv ) ;
uwb_rsv_destroy ( wusbhc - > rsv ) ;
wusbhc - > rsv = NULL ;
}
2008-09-17 19:34:23 +04:00
}