pre-2.3.4..
[davej-history.git] / drivers / isdn / isdn_budget.c
blob985c97ba89ebb465563049d3e76a6bb018e4f944
1 /* $Id: isdn_budget.c,v 1.3 1998/10/23 10:18:39 paul Exp $
3 * Linux ISDN subsystem, budget-accounting for network interfaces.
5 * Copyright 1997 by Christian Lademann <cal@zls.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * $Log: isdn_budget.c,v $
22 * Revision 1.3 1998/10/23 10:18:39 paul
23 * Implementation of "dialmode" (successor of "status")
24 * You also need current isdnctrl for this!
26 * Revision 1.2 1998/03/07 23:17:30 fritz
27 * Added RCS keywords
28 * Bugfix: Did not compile without isdn_dumppkt beeing enabled.
33 30.06.97:cal:angelegt
34 04.11.97:cal:budget.period: int --> time_t
37 #include <linux/config.h>
38 #define __NO_VERSION__
39 #include <linux/module.h>
40 #include <linux/isdn.h>
41 #include "isdn_common.h"
42 #include "isdn_net.h"
44 #ifdef CONFIG_ISDN_BUDGET
46 #define VERBOSE_PRINTK(v, l, p...) { \
47 if(dev->net_verbose >= (v)) { \
48 printk(l ## p); \
49 } else { ; } \
53 int
54 isdn_net_budget(int type, struct device *ndev) {
55 isdn_net_local *lp = (isdn_net_local *)ndev->priv;
56 int i, ret = 0;
58 switch(type) {
59 case ISDN_BUDGET_INIT:
60 for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
61 lp->budget [i] .amount = -1;
62 lp->budget [i] .used = 0;
63 lp->budget [i] .period = (time_t)0;
64 lp->budget [i] .period_started = (time_t)0;
65 lp->budget [i] .last_check = CURRENT_TIME;
66 lp->budget [i] .notified = 0;
69 return(0);
70 break;
72 case ISDN_BUDGET_CHECK_DIAL:
73 case ISDN_BUDGET_CHECK_CHARGE:
74 case ISDN_BUDGET_CHECK_ONLINE:
75 ret = 0;
77 for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
78 if(lp->budget [i] .amount < 0)
79 continue;
81 if(lp->budget [i] .period_started + lp->budget [i] .period < CURRENT_TIME) {
82 lp->budget [i] .used = 0;
83 lp->budget [i] .period_started = CURRENT_TIME;
84 lp->budget [i] .notified = 0;
87 if(lp->budget [i] .used >= lp->budget [i] .amount)
88 ret |= (1 << i);
91 switch(type) {
92 case ISDN_BUDGET_CHECK_DIAL:
93 if(! ret) {
94 lp->budget [ISDN_BUDGET_DIAL] .used++;
95 lp->budget [ISDN_BUDGET_DIAL] .last_check = CURRENT_TIME;
97 break;
99 case ISDN_BUDGET_CHECK_CHARGE:
100 lp->budget [ISDN_BUDGET_CHARGE] .used++;
101 lp->budget [ISDN_BUDGET_CHARGE] .last_check = CURRENT_TIME;
102 break;
104 case ISDN_BUDGET_CHECK_ONLINE:
105 if(lp->budget [ISDN_BUDGET_ONLINE] .last_check) {
106 lp->budget [ISDN_BUDGET_ONLINE] .used += (CURRENT_TIME - lp->budget [ISDN_BUDGET_ONLINE] .last_check);
109 lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME;
110 break;
114 if(ret)
115 lp->flags |= ISDN_NET_DM_OFF;
117 for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
118 if(ret & (1 << i) && ! lp->budget [i] .notified) {
119 switch(i) {
120 case ISDN_BUDGET_DIAL:
121 printk(KERN_WARNING "isdn_budget: dial budget used up.\n");
122 break;
124 case ISDN_BUDGET_CHARGE:
125 printk(KERN_WARNING "isdn_budget: charge budget used up.\n");
126 break;
128 case ISDN_BUDGET_ONLINE:
129 printk(KERN_WARNING "isdn_budget: online budget used up.\n");
130 break;
132 default:
133 printk(KERN_WARNING "isdn_budget: budget #%d used up.\n", i);
134 break;
137 lp->budget [i] .notified = 1;
141 return(ret);
142 break;
144 case ISDN_BUDGET_START_ONLINE:
145 lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME;
146 return(0);
148 break;
151 return(-1);
156 isdn_budget_ioctl(isdn_ioctl_budget *iocmd) {
157 isdn_net_dev *p = isdn_net_findif(iocmd->name);
159 if(p) {
160 switch(iocmd->command) {
161 case ISDN_BUDGET_SET_BUDGET:
162 if(! suser())
163 return(-EPERM);
165 if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET)
166 return(-EINVAL);
168 if(iocmd->amount < 0)
169 iocmd->amount = -1;
171 p->local->budget [iocmd->budget] .amount = iocmd->amount;
172 p->local->budget [iocmd->budget] .period = iocmd->period;
174 if(iocmd->used <= 0)
175 p->local->budget [iocmd->budget] .used = 0;
176 else
177 p->local->budget [iocmd->budget] .used = iocmd->used;
179 if(iocmd->period_started == (time_t)0)
180 p->local->budget [iocmd->budget] .period_started = CURRENT_TIME;
181 else
182 p->local->budget [iocmd->budget] .period_started = iocmd->period_started;
184 return(0);
185 break;
187 case ISDN_BUDGET_GET_BUDGET:
188 if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET)
189 return(-EINVAL);
191 iocmd->amount = p->local->budget [iocmd->budget] .amount;
192 iocmd->used = p->local->budget [iocmd->budget] .used;
193 iocmd->period = p->local->budget [iocmd->budget] .period;
194 iocmd->period_started = p->local->budget [iocmd->budget] .period_started;
196 return(0);
197 break;
199 default:
200 return(-EINVAL);
201 break;
204 return(-ENODEV);
206 #endif