Commit f31153ad authored by Chas Williams's avatar Chas Williams Committed by David S. Miller

[ATM]: Eliminate atm_find_ci().

parent a88930cc
...@@ -1064,7 +1064,8 @@ static unsigned int make_rate (unsigned int rate, rounding r, ...@@ -1064,7 +1064,8 @@ static unsigned int make_rate (unsigned int rate, rounding r,
/********** Open a VC **********/ /********** Open a VC **********/
static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { static int amb_open (struct atm_vcc * atm_vcc)
{
int error; int error;
struct atm_qos * qos; struct atm_qos * qos;
...@@ -1077,6 +1078,8 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -1077,6 +1078,8 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
amb_dev * dev = AMB_DEV(atm_vcc->dev); amb_dev * dev = AMB_DEV(atm_vcc->dev);
amb_vcc * vcc; amb_vcc * vcc;
unsigned char pool = -1; // hush gcc unsigned char pool = -1; // hush gcc
short vpi = atm_vcc->vpi;
int vci = atm_vcc->vci;
PRINTD (DBG_FLOW|DBG_VCC, "amb_open %x %x", vpi, vci); PRINTD (DBG_FLOW|DBG_VCC, "amb_open %x %x", vpi, vci);
...@@ -1088,14 +1091,6 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -1088,14 +1091,6 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
} }
#endif #endif
// deal with possibly wildcarded VCs
error = atm_find_ci (atm_vcc, &vpi, &vci);
if (error) {
PRINTD (DBG_WARN|DBG_VCC, "atm_find_ci failed!");
return error;
}
PRINTD (DBG_VCC, "atm_find_ci gives %x %x", vpi, vci);
if (!(0 <= vpi && vpi < (1<<NUM_VPI_BITS) && if (!(0 <= vpi && vpi < (1<<NUM_VPI_BITS) &&
0 <= vci && vci < (1<<NUM_VCI_BITS))) { 0 <= vci && vci < (1<<NUM_VCI_BITS))) {
PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci); PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci);
...@@ -1274,10 +1269,6 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -1274,10 +1269,6 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
up (&dev->vcc_sf); up (&dev->vcc_sf);
} }
// set elements of vcc
atm_vcc->vpi = vpi; // 0
atm_vcc->vci = vci;
// indicate readiness // indicate readiness
set_bit(ATM_VF_READY,&atm_vcc->flags); set_bit(ATM_VF_READY,&atm_vcc->flags);
......
...@@ -115,10 +115,12 @@ static void atmtcp_v_dev_close(struct atm_dev *dev) ...@@ -115,10 +115,12 @@ static void atmtcp_v_dev_close(struct atm_dev *dev)
} }
static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci) static int atmtcp_v_open(struct atm_vcc *vcc)
{ {
struct atmtcp_control msg; struct atmtcp_control msg;
int error; int error;
short vpi = vcc->vpi;
int vci = vcc->vci;
memset(&msg,0,sizeof(msg)); memset(&msg,0,sizeof(msg));
msg.addr.sap_family = AF_ATMPVC; msg.addr.sap_family = AF_ATMPVC;
...@@ -126,8 +128,6 @@ static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci) ...@@ -126,8 +128,6 @@ static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci)
msg.addr.sap_addr.vpi = vpi; msg.addr.sap_addr.vpi = vpi;
msg.hdr.vci = htons(vci); msg.hdr.vci = htons(vci);
msg.addr.sap_addr.vci = vci; msg.addr.sap_addr.vci = vci;
error = atm_find_ci(vcc,&msg.addr.sap_addr.vpi,&msg.addr.sap_addr.vci);
if (error) return error;
if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0; if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
msg.type = ATMTCP_CTRL_OPEN; msg.type = ATMTCP_CTRL_OPEN;
msg.qos = vcc->qos; msg.qos = vcc->qos;
......
...@@ -1881,80 +1881,18 @@ static void eni_close(struct atm_vcc *vcc) ...@@ -1881,80 +1881,18 @@ static void eni_close(struct atm_vcc *vcc)
} }
static int get_ci(struct atm_vcc *vcc,short *vpi,int *vci) static int eni_open(struct atm_vcc *vcc)
{
struct sock *s;
struct hlist_node *node;
struct atm_vcc *walk;
read_lock(&vcc_sklist_lock);
if (*vpi == ATM_VPI_ANY) *vpi = 0;
if (*vci == ATM_VCI_ANY) {
for (*vci = ATM_NOT_RSV_VCI; *vci < NR_VCI; (*vci)++) {
if (vcc->qos.rxtp.traffic_class != ATM_NONE &&
ENI_DEV(vcc->dev)->rx_map[*vci])
continue;
if (vcc->qos.txtp.traffic_class != ATM_NONE) {
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if (test_bit(ATM_VF_ADDR,&walk->flags)
&& walk->vci == *vci &&
walk->qos.txtp.traffic_class !=
ATM_NONE)
break;
}
if (node)
continue;
}
break;
}
read_unlock(&vcc_sklist_lock);
return *vci == NR_VCI ? -EADDRINUSE : 0;
}
if (*vci == ATM_VCI_UNSPEC) {
read_unlock(&vcc_sklist_lock);
return 0;
}
if (vcc->qos.rxtp.traffic_class != ATM_NONE &&
ENI_DEV(vcc->dev)->rx_map[*vci]) {
read_unlock(&vcc_sklist_lock);
return -EADDRINUSE;
}
if (vcc->qos.txtp.traffic_class == ATM_NONE) {
read_unlock(&vcc_sklist_lock);
return 0;
}
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vci == *vci &&
walk->qos.txtp.traffic_class != ATM_NONE) {
read_unlock(&vcc_sklist_lock);
return -EADDRINUSE;
}
}
read_unlock(&vcc_sklist_lock);
return 0;
}
static int eni_open(struct atm_vcc *vcc,short vpi,int vci)
{ {
struct eni_dev *eni_dev; struct eni_dev *eni_dev;
struct eni_vcc *eni_vcc; struct eni_vcc *eni_vcc;
int error; int error;
short vpi = vcc->vpi;
int vci = vcc->vci;
DPRINTK(">eni_open\n"); DPRINTK(">eni_open\n");
EVENT("eni_open\n",0,0); EVENT("eni_open\n",0,0);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) ENI_VCC(vcc) = NULL; if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) ENI_VCC(vcc) = NULL;
eni_dev = ENI_DEV(vcc->dev); eni_dev = ENI_DEV(vcc->dev);
error = get_ci(vcc,&vpi,&vci);
if (error) return error;
vcc->vpi = vpi;
vcc->vci = vci;
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags); set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5) if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
......
...@@ -854,7 +854,7 @@ static void process_incoming (struct fs_dev *dev, struct queue *q) ...@@ -854,7 +854,7 @@ static void process_incoming (struct fs_dev *dev, struct queue *q)
#define DO_DIRECTION(tp) ((tp)->traffic_class != ATM_NONE) #define DO_DIRECTION(tp) ((tp)->traffic_class != ATM_NONE)
static int fs_open(struct atm_vcc *atm_vcc, short vpi, int vci) static int fs_open(struct atm_vcc *atm_vcc)
{ {
struct fs_dev *dev; struct fs_dev *dev;
struct fs_vcc *vcc; struct fs_vcc *vcc;
...@@ -867,6 +867,8 @@ static int fs_open(struct atm_vcc *atm_vcc, short vpi, int vci) ...@@ -867,6 +867,8 @@ static int fs_open(struct atm_vcc *atm_vcc, short vpi, int vci)
int bfp; int bfp;
int to; int to;
unsigned short tmc0; unsigned short tmc0;
short vpi = atm_vcc->vpi;
int vci = atm_vcc->vci;
func_enter (); func_enter ();
...@@ -874,14 +876,6 @@ static int fs_open(struct atm_vcc *atm_vcc, short vpi, int vci) ...@@ -874,14 +876,6 @@ static int fs_open(struct atm_vcc *atm_vcc, short vpi, int vci)
fs_dprintk (FS_DEBUG_OPEN, "fs: open on dev: %p, vcc at %p\n", fs_dprintk (FS_DEBUG_OPEN, "fs: open on dev: %p, vcc at %p\n",
dev, atm_vcc); dev, atm_vcc);
error = atm_find_ci(atm_vcc, &vpi, &vci);
if (error) {
fs_dprintk (FS_DEBUG_OPEN, "fs: find_ci failed.\n");
return error;
}
atm_vcc->vpi = vpi;
atm_vcc->vci = vci;
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR, &atm_vcc->flags); set_bit(ATM_VF_ADDR, &atm_vcc->flags);
......
...@@ -1351,56 +1351,6 @@ fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* ...@@ -1351,56 +1351,6 @@ fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc*
} }
static int
fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci)
{
struct atm_vcc* walk;
struct sock *s;
struct hlist_node *node;
/* find a free VPI */
read_lock(&vcc_sklist_lock);
if (*vpi == ATM_VPI_ANY) {
*vpi = 0;
restart_vpi_search:
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if ((walk->vci == *vci) && (walk->vpi == *vpi)) {
(*vpi)++;
goto restart_vpi_search;
}
}
}
/* find a free VCI */
if (*vci == ATM_VCI_ANY) {
*vci = ATM_NOT_RSV_VCI;
restart_vci_search:
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if ((walk->vpi = *vpi) && (walk->vci == *vci)) {
*vci = walk->vci + 1;
goto restart_vci_search;
}
}
}
read_unlock(&vcc_sklist_lock);
return 0;
}
#define FORE200E_MAX_BACK2BACK_CELLS 255 /* XXX depends on CDVT */ #define FORE200E_MAX_BACK2BACK_CELLS 255 /* XXX depends on CDVT */
static void static void
...@@ -1420,16 +1370,12 @@ fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate) ...@@ -1420,16 +1370,12 @@ fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
static int static int
fore200e_open(struct atm_vcc *vcc, short vpi, int vci) fore200e_open(struct atm_vcc *vcc)
{ {
struct fore200e* fore200e = FORE200E_DEV(vcc->dev); struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
struct fore200e_vcc* fore200e_vcc; struct fore200e_vcc* fore200e_vcc;
short vpi = vcc->vpi;
/* find a free VPI/VCI */ int vci = vcc->vci;
fore200e_walk_vccs(vcc, &vpi, &vci);
vcc->vpi = vpi;
vcc->vci = vci;
/* ressource checking only? */ /* ressource checking only? */
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
......
...@@ -135,7 +135,7 @@ static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $"; ...@@ -135,7 +135,7 @@ static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $";
/* declarations */ /* declarations */
static int he_open(struct atm_vcc *vcc, short vpi, int vci); static int he_open(struct atm_vcc *vcc);
static void he_close(struct atm_vcc *vcc); static void he_close(struct atm_vcc *vcc);
static int he_send(struct atm_vcc *vcc, struct sk_buff *skb); static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg); static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
...@@ -2333,23 +2333,18 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid) ...@@ -2333,23 +2333,18 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
} }
static int static int
he_open(struct atm_vcc *vcc, short vpi, int vci) he_open(struct atm_vcc *vcc)
{ {
unsigned long flags; unsigned long flags;
struct he_dev *he_dev = HE_DEV(vcc->dev); struct he_dev *he_dev = HE_DEV(vcc->dev);
struct he_vcc *he_vcc; struct he_vcc *he_vcc;
int err = 0; int err = 0;
unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock; unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock;
short vpi = vcc->vpi;
int vci = vcc->vci;
if ((err = atm_find_ci(vcc, &vpi, &vci))) {
HPRINTK("atm_find_ci err = %d\n", err);
return err;
}
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
return 0; return 0;
vcc->vpi = vpi;
vcc->vci = vci;
HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci); HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci);
......
...@@ -2174,7 +2174,8 @@ static int atm_pcr_check (struct atm_trafprm * tp, unsigned int pcr) { ...@@ -2174,7 +2174,8 @@ static int atm_pcr_check (struct atm_trafprm * tp, unsigned int pcr) {
/********** open VC **********/ /********** open VC **********/
static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { static int hrz_open (struct atm_vcc *atm_vcc)
{
int error; int error;
u16 channel; u16 channel;
...@@ -2185,6 +2186,8 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -2185,6 +2186,8 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
hrz_dev * dev = HRZ_DEV(atm_vcc->dev); hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
hrz_vcc vcc; hrz_vcc vcc;
hrz_vcc * vccp; // allocated late hrz_vcc * vccp; // allocated late
short vpi = atm_vcc->vpi;
int vci = atm_vcc->vci;
PRINTD (DBG_FLOW|DBG_VCC, "hrz_open %x %x", vpi, vci); PRINTD (DBG_FLOW|DBG_VCC, "hrz_open %x %x", vpi, vci);
#ifdef ATM_VPI_UNSPEC #ifdef ATM_VPI_UNSPEC
...@@ -2195,14 +2198,6 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -2195,14 +2198,6 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
} }
#endif #endif
// deal with possibly wildcarded VCs
error = atm_find_ci (atm_vcc, &vpi, &vci);
if (error) {
PRINTD (DBG_WARN|DBG_VCC, "atm_find_ci failed!");
return error;
}
PRINTD (DBG_VCC, "atm_find_ci gives %x %x", vpi, vci);
error = vpivci_to_channel (&channel, vpi, vci); error = vpivci_to_channel (&channel, vpi, vci);
if (error) { if (error) {
PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci); PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci);
...@@ -2557,8 +2552,6 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { ...@@ -2557,8 +2552,6 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) {
} }
// success, set elements of atm_vcc // success, set elements of atm_vcc
atm_vcc->vpi = vpi;
atm_vcc->vci = vci;
atm_vcc->dev_data = (void *) vccp; atm_vcc->dev_data = (void *) vccp;
// indicate readiness // indicate readiness
......
...@@ -122,7 +122,7 @@ static void idt77252_tx(struct idt77252_dev *); ...@@ -122,7 +122,7 @@ static void idt77252_tx(struct idt77252_dev *);
* ATM Interface. * ATM Interface.
*/ */
static void idt77252_dev_close(struct atm_dev *dev); static void idt77252_dev_close(struct atm_dev *dev);
static int idt77252_open(struct atm_vcc *vcc, short vpi, int vci); static int idt77252_open(struct atm_vcc *vcc);
static void idt77252_close(struct atm_vcc *vcc); static void idt77252_close(struct atm_vcc *vcc);
static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb); static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int idt77252_send_oam(struct atm_vcc *vcc, void *cell, static int idt77252_send_oam(struct atm_vcc *vcc, void *cell,
...@@ -2402,50 +2402,7 @@ idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc, ...@@ -2402,50 +2402,7 @@ idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc,
} }
static int static int
idt77252_find_vcc(struct atm_vcc *vcc, short *vpi, int *vci) idt77252_open(struct atm_vcc *vcc)
{
struct sock *s;
struct atm_vcc *walk;
read_lock(&vcc_sklist_lock);
if (*vpi == ATM_VPI_ANY) {
*vpi = 0;
s = sk_head(&vcc_sklist);
while (s) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if ((walk->vci == *vci) && (walk->vpi == *vpi)) {
(*vpi)++;
s = sk_head(&vcc_sklist);
continue;
}
s = sk_next(s);
}
}
if (*vci == ATM_VCI_ANY) {
*vci = ATM_NOT_RSV_VCI;
s = sk_head(&vcc_sklist);
while (s) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if ((walk->vci == *vci) && (walk->vpi == *vpi)) {
(*vci)++;
s = sk_head(&vcc_sklist);
continue;
}
s = sk_next(s);
}
}
read_unlock(&vcc_sklist_lock);
return 0;
}
static int
idt77252_open(struct atm_vcc *vcc, short vpi, int vci)
{ {
struct atm_dev *dev = vcc->dev; struct atm_dev *dev = vcc->dev;
struct idt77252_dev *card = dev->dev_data; struct idt77252_dev *card = dev->dev_data;
...@@ -2453,8 +2410,8 @@ idt77252_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2453,8 +2410,8 @@ idt77252_open(struct atm_vcc *vcc, short vpi, int vci)
unsigned int index; unsigned int index;
unsigned int inuse; unsigned int inuse;
int error; int error;
int vci = vcc->vci;
idt77252_find_vcc(vcc, &vpi, &vci); short vpi = vcc->vpi;
if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
return 0; return 0;
...@@ -2469,8 +2426,6 @@ idt77252_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2469,8 +2426,6 @@ idt77252_open(struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL; return -EINVAL;
} }
vcc->vpi = vpi;
vcc->vci = vci;
set_bit(ATM_VF_ADDR, &vcc->flags); set_bit(ATM_VF_ADDR, &vcc->flags);
down(&card->mutex); down(&card->mutex);
......
...@@ -2676,7 +2676,7 @@ static void ia_close(struct atm_vcc *vcc) ...@@ -2676,7 +2676,7 @@ static void ia_close(struct atm_vcc *vcc)
return; return;
} }
static int ia_open(struct atm_vcc *vcc, short vpi, int vci) static int ia_open(struct atm_vcc *vcc)
{ {
IADEV *iadev; IADEV *iadev;
struct ia_vcc *ia_vcc; struct ia_vcc *ia_vcc;
...@@ -2687,15 +2687,7 @@ static int ia_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2687,15 +2687,7 @@ static int ia_open(struct atm_vcc *vcc, short vpi, int vci)
INPH_IA_VCC(vcc) = NULL; INPH_IA_VCC(vcc) = NULL;
} }
iadev = INPH_IA_DEV(vcc->dev); iadev = INPH_IA_DEV(vcc->dev);
error = atm_find_ci(vcc, &vpi, &vci); if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)
if (error)
{
printk("iadev: atm_find_ci returned error %d\n", error);
return error;
}
vcc->vpi = vpi;
vcc->vci = vci;
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
{ {
IF_EVENT(printk("iphase open: unspec part\n");) IF_EVENT(printk("iphase open: unspec part\n");)
set_bit(ATM_VF_ADDR,&vcc->flags); set_bit(ATM_VF_ADDR,&vcc->flags);
......
...@@ -2350,11 +2350,13 @@ static void lanai_close(struct atm_vcc *atmvcc) ...@@ -2350,11 +2350,13 @@ static void lanai_close(struct atm_vcc *atmvcc)
} }
/* open a vcc on the card to vpi/vci */ /* open a vcc on the card to vpi/vci */
static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci) static int lanai_open(struct atm_vcc *atmvcc)
{ {
struct lanai_dev *lanai; struct lanai_dev *lanai;
struct lanai_vcc *lvcc; struct lanai_vcc *lvcc;
int result = 0; int result = 0;
int vci = atmvcc->vci;
short vpi = atmvcc->vpi;
/* we don't support partial open - it's not really useful anyway */ /* we don't support partial open - it's not really useful anyway */
if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) || if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) ||
(vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC)) (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC))
...@@ -2363,8 +2365,6 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci) ...@@ -2363,8 +2365,6 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci); result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci);
if (unlikely(result != 0)) if (unlikely(result != 0))
goto out; goto out;
atmvcc->vpi = vpi;
atmvcc->vci = vci;
set_bit(ATM_VF_ADDR, &atmvcc->flags); set_bit(ATM_VF_ADDR, &atmvcc->flags);
if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5) if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)
return -EINVAL; return -EINVAL;
......
...@@ -221,7 +221,7 @@ static void free_scq(scq_info *scq, struct atm_vcc *vcc); ...@@ -221,7 +221,7 @@ static void free_scq(scq_info *scq, struct atm_vcc *vcc);
static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1, static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
u32 handle2, u32 addr2); u32 handle2, u32 addr2);
static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
static int ns_open(struct atm_vcc *vcc, short vpi, int vci); static int ns_open(struct atm_vcc *vcc);
static void ns_close(struct atm_vcc *vcc); static void ns_close(struct atm_vcc *vcc);
static void fill_tst(ns_dev *card, int n, vc_map *vc); static void fill_tst(ns_dev *card, int n, vc_map *vc);
static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb); static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);
...@@ -1371,11 +1371,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1371,11 +1371,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
static int ns_open(struct atm_vcc *vcc, short vpi, int vci) static int ns_open(struct atm_vcc *vcc)
{ {
ns_dev *card; ns_dev *card;
vc_map *vc; vc_map *vc;
int error;
unsigned long tmpl, modl; unsigned long tmpl, modl;
int tcr, tcra; /* target cell rate, and absolute value */ int tcr, tcra; /* target cell rate, and absolute value */
int n = 0; /* Number of entries in the TST. Initialized to remove int n = 0; /* Number of entries in the TST. Initialized to remove
...@@ -1386,6 +1385,8 @@ static int ns_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -1386,6 +1385,8 @@ static int ns_open(struct atm_vcc *vcc, short vpi, int vci)
tell which variables can truly be used tell which variables can truly be used
uninitialized... */ uninitialized... */
int inuse; /* tx or rx vc already in use by another vcc */ int inuse; /* tx or rx vc already in use by another vcc */
short vpi = vcc->vpi;
int vci = vcc->vci;
card = (ns_dev *) vcc->dev->dev_data; card = (ns_dev *) vcc->dev->dev_data;
PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int) vpi, vci); PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int) vpi, vci);
...@@ -1395,14 +1396,7 @@ static int ns_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -1395,14 +1396,7 @@ static int ns_open(struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL; return -EINVAL;
} }
if ((error = atm_find_ci(vcc, &vpi, &vci)))
{
PRINTK("nicstar%d: error in atm_find_ci().\n", card->index);
return error;
}
vc = &(card->vcmap[vpi << card->vcibits | vci]); vc = &(card->vcmap[vpi << card->vcibits | vci]);
vcc->vpi = vpi;
vcc->vci = vci;
vcc->dev_data = vc; vcc->dev_data = vc;
inuse = 0; inuse = 0;
......
...@@ -1373,19 +1373,17 @@ static void zatm_close(struct atm_vcc *vcc) ...@@ -1373,19 +1373,17 @@ static void zatm_close(struct atm_vcc *vcc)
} }
static int zatm_open(struct atm_vcc *vcc,short vpi,int vci) static int zatm_open(struct atm_vcc *vcc)
{ {
struct zatm_dev *zatm_dev; struct zatm_dev *zatm_dev;
struct zatm_vcc *zatm_vcc; struct zatm_vcc *zatm_vcc;
short vpi = vcc->vpi;
int vci = vcc->vci;
int error; int error;
DPRINTK(">zatm_open\n"); DPRINTK(">zatm_open\n");
zatm_dev = ZATM_DEV(vcc->dev); zatm_dev = ZATM_DEV(vcc->dev);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) ZATM_VCC(vcc) = NULL; if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) ZATM_VCC(vcc) = NULL;
error = atm_find_ci(vcc,&vpi,&vci);
if (error) return error;
vcc->vpi = vpi;
vcc->vci = vci;
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags); set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL5) return -EINVAL; /* @@@ AAL0 */ if (vcc->qos.aal != ATM_AAL5) return -EINVAL; /* @@@ AAL0 */
......
...@@ -263,7 +263,7 @@ struct udsl_instance_data { ...@@ -263,7 +263,7 @@ struct udsl_instance_data {
/* ATM */ /* ATM */
static void udsl_atm_dev_close (struct atm_dev *dev); static void udsl_atm_dev_close (struct atm_dev *dev);
static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci); static int udsl_atm_open (struct atm_vcc *vcc);
static void udsl_atm_close (struct atm_vcc *vcc); static void udsl_atm_close (struct atm_vcc *vcc);
static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb); static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
...@@ -863,11 +863,13 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page) ...@@ -863,11 +863,13 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
return 0; return 0;
} }
static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) static int udsl_atm_open (struct atm_vcc *vcc)
{ {
struct udsl_instance_data *instance = vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *new; struct udsl_vcc_data *new;
unsigned int max_pdu; unsigned int max_pdu;
int vci = vcc->vci;
short vpi = vcc->vpi;
dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci); dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
...@@ -876,9 +878,6 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -876,9 +878,6 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -ENODEV; return -ENODEV;
} }
if ((vpi == ATM_VPI_ANY) || (vci == ATM_VCI_ANY))
return -EINVAL;
/* only support AAL5 */ /* only support AAL5 */
if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) { if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal); dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
...@@ -919,8 +918,6 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -919,8 +918,6 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
} }
vcc->dev_data = new; vcc->dev_data = new;
vcc->vpi = vpi;
vcc->vci = vci;
tasklet_disable (&instance->receive_tasklet); tasklet_disable (&instance->receive_tasklet);
list_add (&new->list, &instance->vcc_list); list_add (&new->list, &instance->vcc_list);
......
...@@ -351,7 +351,7 @@ struct atm_dev { ...@@ -351,7 +351,7 @@ struct atm_dev {
struct atmdev_ops { /* only send is required */ struct atmdev_ops { /* only send is required */
void (*dev_close)(struct atm_dev *dev); void (*dev_close)(struct atm_dev *dev);
int (*open)(struct atm_vcc *vcc,short vpi,int vci); int (*open)(struct atm_vcc *vcc);
void (*close)(struct atm_vcc *vcc); void (*close)(struct atm_vcc *vcc);
int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg); int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg);
int (*getsockopt)(struct atm_vcc *vcc,int level,int optname, int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
...@@ -443,7 +443,6 @@ static inline void atm_dev_put(struct atm_dev *dev) ...@@ -443,7 +443,6 @@ static inline void atm_dev_put(struct atm_dev *dev)
int atm_charge(struct atm_vcc *vcc,int truesize); int atm_charge(struct atm_vcc *vcc,int truesize);
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
int gfp_flags); int gfp_flags);
int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci);
int atm_pcr_goal(struct atm_trafprm *tp); int atm_pcr_goal(struct atm_trafprm *tp);
void vcc_release_async(struct atm_vcc *vcc, int reply); void vcc_release_async(struct atm_vcc *vcc, int reply);
......
...@@ -45,76 +45,6 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, ...@@ -45,76 +45,6 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
} }
static int check_ci(struct atm_vcc *vcc,short vpi,int vci)
{
struct hlist_node *node;
struct sock *s;
struct atm_vcc *walk;
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vpi == vpi &&
walk->vci == vci && ((walk->qos.txtp.traffic_class !=
ATM_NONE && vcc->qos.txtp.traffic_class != ATM_NONE) ||
(walk->qos.rxtp.traffic_class != ATM_NONE &&
vcc->qos.rxtp.traffic_class != ATM_NONE)))
return -EADDRINUSE;
}
/* allow VCCs with same VPI/VCI iff they don't collide on
TX/RX (but we may refuse such sharing for other reasons,
e.g. if protocol requires to have both channels) */
return 0;
}
int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci)
{
static short p; /* poor man's per-device cache */
static int c;
short old_p;
int old_c;
int err;
read_lock(&vcc_sklist_lock);
if (*vpi != ATM_VPI_ANY && *vci != ATM_VCI_ANY) {
err = check_ci(vcc,*vpi,*vci);
read_unlock(&vcc_sklist_lock);
return err;
}
/* last scan may have left values out of bounds for current device */
if (*vpi != ATM_VPI_ANY) p = *vpi;
else if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0;
if (*vci != ATM_VCI_ANY) c = *vci;
else if (c < ATM_NOT_RSV_VCI || c >= 1 << vcc->dev->ci_range.vci_bits)
c = ATM_NOT_RSV_VCI;
old_p = p;
old_c = c;
do {
if (!check_ci(vcc,p,c)) {
*vpi = p;
*vci = c;
read_unlock(&vcc_sklist_lock);
return 0;
}
if (*vci == ATM_VCI_ANY) {
c++;
if (c >= 1 << vcc->dev->ci_range.vci_bits)
c = ATM_NOT_RSV_VCI;
}
if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) &&
*vpi == ATM_VPI_ANY) {
p++;
if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0;
}
}
while (old_p != p || old_c != c);
read_unlock(&vcc_sklist_lock);
return -EADDRINUSE;
}
/* /*
* atm_pcr_goal returns the positive PCR if it should be rounded up, the * atm_pcr_goal returns the positive PCR if it should be rounded up, the
* negative PCR if it should be rounded down, and zero if the maximum available * negative PCR if it should be rounded down, and zero if the maximum available
...@@ -170,7 +100,6 @@ void sonet_subtract_stats(struct k_sonet_stats *from,struct sonet_stats *to) ...@@ -170,7 +100,6 @@ void sonet_subtract_stats(struct k_sonet_stats *from,struct sonet_stats *to)
EXPORT_SYMBOL(atm_charge); EXPORT_SYMBOL(atm_charge);
EXPORT_SYMBOL(atm_alloc_charge); EXPORT_SYMBOL(atm_alloc_charge);
EXPORT_SYMBOL(atm_find_ci);
EXPORT_SYMBOL(atm_pcr_goal); EXPORT_SYMBOL(atm_pcr_goal);
EXPORT_SYMBOL(sonet_copy_stats); EXPORT_SYMBOL(sonet_copy_stats);
EXPORT_SYMBOL(sonet_subtract_stats); EXPORT_SYMBOL(sonet_subtract_stats);
...@@ -248,7 +248,78 @@ static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) ...@@ -248,7 +248,78 @@ static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
} }
static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi, static int check_ci(struct atm_vcc *vcc, short vpi, int vci)
{
struct hlist_node *node;
struct sock *s;
struct atm_vcc *walk;
sk_for_each(s, node, &vcc_sklist) {
walk = atm_sk(s);
if (walk->dev != vcc->dev)
continue;
if (test_bit(ATM_VF_ADDR, &walk->flags) && walk->vpi == vpi &&
walk->vci == vci && ((walk->qos.txtp.traffic_class !=
ATM_NONE && vcc->qos.txtp.traffic_class != ATM_NONE) ||
(walk->qos.rxtp.traffic_class != ATM_NONE &&
vcc->qos.rxtp.traffic_class != ATM_NONE)))
return -EADDRINUSE;
}
/* allow VCCs with same VPI/VCI iff they don't collide on
TX/RX (but we may refuse such sharing for other reasons,
e.g. if protocol requires to have both channels) */
return 0;
}
static int find_ci(struct atm_vcc *vcc, short *vpi, int *vci)
{
static short p; /* poor man's per-device cache */
static int c;
short old_p;
int old_c;
int err;
if (*vpi != ATM_VPI_ANY && *vci != ATM_VCI_ANY) {
err = check_ci(vcc, *vpi, *vci);
return err;
}
/* last scan may have left values out of bounds for current device */
if (*vpi != ATM_VPI_ANY)
p = *vpi;
else if (p >= 1 << vcc->dev->ci_range.vpi_bits)
p = 0;
if (*vci != ATM_VCI_ANY)
c = *vci;
else if (c < ATM_NOT_RSV_VCI || c >= 1 << vcc->dev->ci_range.vci_bits)
c = ATM_NOT_RSV_VCI;
old_p = p;
old_c = c;
do {
if (!check_ci(vcc, p, c)) {
*vpi = p;
*vci = c;
return 0;
}
if (*vci == ATM_VCI_ANY) {
c++;
if (c >= 1 << vcc->dev->ci_range.vci_bits)
c = ATM_NOT_RSV_VCI;
}
if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) &&
*vpi == ATM_VPI_ANY) {
p++;
if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0;
}
}
while (old_p != p || old_c != c);
return -EADDRINUSE;
}
static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
int vci) int vci)
{ {
int error; int error;
...@@ -260,8 +331,18 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi, ...@@ -260,8 +331,18 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
return -EPERM; return -EPERM;
error = 0; error = 0;
if (!try_module_get(dev->ops->owner))
return -ENODEV;
vcc->dev = dev; vcc->dev = dev;
vcc_insert_socket(vcc->sk); write_lock_irq(&vcc_sklist_lock);
if ((error = find_ci(vcc, &vpi, &vci))) {
write_unlock_irq(&vcc_sklist_lock);
goto fail_module_put;
}
vcc->vpi = vpi;
vcc->vci = vci;
__vcc_insert_socket(vcc->sk);
write_unlock_irq(&vcc_sklist_lock);
switch (vcc->qos.aal) { switch (vcc->qos.aal) {
case ATM_AAL0: case ATM_AAL0:
error = atm_init_aal0(vcc); error = atm_init_aal0(vcc);
...@@ -291,21 +372,17 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi, ...@@ -291,21 +372,17 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu); vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
DPRINTK(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class, DPRINTK(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu); vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
if (!try_module_get(dev->ops->owner)) {
error = -ENODEV;
goto fail;
}
if (dev->ops->open) { if (dev->ops->open) {
if ((error = dev->ops->open(vcc,vpi,vci))) if ((error = dev->ops->open(vcc)))
goto put_module_fail; goto fail;
} }
return 0; return 0;
put_module_fail:
module_put(dev->ops->owner);
fail: fail:
vcc_remove_socket(vcc->sk); vcc_remove_socket(vcc->sk);
fail_module_put:
module_put(dev->ops->owner);
/* ensure we get dev module ref count correct */ /* ensure we get dev module ref count correct */
vcc->dev = NULL; vcc->dev = NULL;
return error; return error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment