reservation.c revision 90ff96f22426a9d1a06df97dead0a9098facb567
1/* 2 * WUSB cluster reservation management 3 * 4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18#include <linux/kernel.h> 19#include <linux/uwb.h> 20 21#include "wusbhc.h" 22 23/* 24 * WUSB cluster reservations are multicast reservations with the 25 * broadcast cluster ID (BCID) as the target DevAddr. 26 * 27 * FIXME: consider adjusting the reservation depending on what devices 28 * are attached. 29 */ 30 31static int wusbhc_bwa_set(struct wusbhc *wusbhc, u8 stream, 32 const struct uwb_mas_bm *mas) 33{ 34 if (mas == NULL) 35 mas = &uwb_mas_bm_zero; 36 return wusbhc->bwa_set(wusbhc, stream, mas); 37} 38 39/** 40 * wusbhc_rsv_complete_cb - WUSB HC reservation complete callback 41 * @rsv: the reservation 42 * 43 * Either set or clear the HC's view of the reservation. 44 * 45 * FIXME: when a reservation is denied the HC should be stopped. 46 */ 47static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) 48{ 49 struct wusbhc *wusbhc = rsv->pal_priv; 50 struct device *dev = wusbhc->dev; 51 char buf[72]; 52 53 switch (rsv->state) { 54 case UWB_RSV_STATE_O_ESTABLISHED: 55 bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS); 56 dev_dbg(dev, "established reservation: %s\n", buf); 57 wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas); 58 break; 59 case UWB_RSV_STATE_NONE: 60 dev_dbg(dev, "removed reservation\n"); 61 wusbhc_bwa_set(wusbhc, 0, NULL); 62 wusbhc->rsv = NULL; 63 break; 64 default: 65 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); 66 break; 67 } 68} 69 70 71/** 72 * wusbhc_rsv_establish - establish a reservation for the cluster 73 * @wusbhc: the WUSB HC requesting a bandwith reservation 74 */ 75int wusbhc_rsv_establish(struct wusbhc *wusbhc) 76{ 77 struct uwb_rc *rc = wusbhc->uwb_rc; 78 struct uwb_rsv *rsv; 79 struct uwb_dev_addr bcid; 80 int ret; 81 82 rsv = uwb_rsv_create(rc, wusbhc_rsv_complete_cb, wusbhc); 83 if (rsv == NULL) 84 return -ENOMEM; 85 86 bcid.data[0] = wusbhc->cluster_id; 87 bcid.data[1] = 0; 88 89 rsv->owner = &rc->uwb_dev; 90 rsv->target.type = UWB_RSV_TARGET_DEVADDR; 91 rsv->target.devaddr = bcid; 92 rsv->type = UWB_DRP_TYPE_PRIVATE; 93 rsv->max_mas = 256; 94 rsv->min_mas = 16; /* one MAS per zone? */ 95 rsv->sparsity = 16; /* at least one MAS in each zone? */ 96 rsv->is_multicast = true; 97 98 ret = uwb_rsv_establish(rsv); 99 if (ret == 0) 100 wusbhc->rsv = rsv; 101 else 102 uwb_rsv_destroy(rsv); 103 return ret; 104} 105 106 107/** 108 * wusbhc_rsv_terminate - terminate any cluster reservation 109 * @wusbhc: the WUSB host whose reservation is to be terminated 110 */ 111void wusbhc_rsv_terminate(struct wusbhc *wusbhc) 112{ 113 if (wusbhc->rsv) 114 uwb_rsv_terminate(wusbhc->rsv); 115} 116