From: Karl H. <ka...@hi...> - 2010-07-02 18:17:11
|
In userspace it's helpfull to know if a network device has a carrier signal. Often it is monitored via netlink. This patchset allows a way for the struct atm_dev drivers to pass carrier on/off to the netdevice. For DSL, carrier is on when the line has reached showtime state. Currently this patchset only propagates the changes to br2684 vccs, as this is the only type of hardware I have to test. If you prefer git you can pull from: git://github.com/karlhiramoto/linux-2.6.git linux-atm Signed-off-by: Karl Hiramoto <ka...@hi...> Karl Hiramoto (6): atm: add hooks to propagate signal changes to netdevice atm br2684: add callback for carrier signal changes. atm/idt77105.c: call atm_dev_signal_change() when signal changes. atm/solos-pci: call atm_dev_signal_change() when signal changes. atm/suni.c: call atm_dev_signal_change() when signal changes. atm/adummy: add syfs DEVICE_ATTR to change signal drivers/atm/adummy.c | 39 +++++++++++++++++++++++++++++++++++++++ drivers/atm/idt77105.c | 11 ++++++----- drivers/atm/solos-pci.c | 6 +++--- drivers/atm/suni.c | 5 +++-- include/linux/atmdev.h | 5 +++++ net/atm/br2684.c | 13 +++++++++++++ net/atm/common.c | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 102 insertions(+), 10 deletions(-) |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:23
|
Propagate changes to upper atm layer, so userspace netmontor knows when DSL showtime reached. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/solos-pci.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index ded76c4..6174965 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -383,7 +383,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb /* Anything but 'Showtime' is down */ if (strcmp(state_str, "Showtime")) { - card->atmdev[port]->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); release_vccs(card->atmdev[port]); dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); return 0; @@ -401,7 +401,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn); card->atmdev[port]->link_rate = rate_down / 424; - card->atmdev[port]->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_FOUND); return 0; } @@ -1246,7 +1246,7 @@ static int atm_init(struct solos_card *card) card->atmdev[i]->ci_range.vci_bits = 16; card->atmdev[i]->dev_data = card; card->atmdev[i]->phy_data = (void *)(unsigned long)i; - card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:22
|
Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/adummy.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-) diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 6d44f07..46b9476 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -40,6 +40,42 @@ struct adummy_dev { static LIST_HEAD(adummy_devs); +static ssize_t __set_signal(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); + int signal; + + if (sscanf(buf, "%d", &signal) == 1) { + + if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND) + signal = ATM_PHY_SIG_UNKNOWN; + + atm_dev_signal_change(atm_dev, signal); + return 1; + } + return -EINVAL; +} + +static ssize_t __show_signal(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); + return sprintf(buf, "%d\n", atm_dev->signal); +} +static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal); + +static struct attribute *adummy_attrs[] = { + &dev_attr_signal.attr, + NULL +}; + +static struct attribute_group adummy_group_attrs = { + .name = NULL, /* We want them in dev's root folder */ + .attrs = adummy_attrs +}; + static int __init adummy_start(struct atm_dev *dev) { @@ -128,6 +164,9 @@ static int __init adummy_init(void) adummy_dev->atm_dev = atm_dev; atm_dev->dev_data = adummy_dev; + if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs)) + dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n"); + if (adummy_start(atm_dev)) { printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n"); err = -ENODEV; -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:24
|
When a signal change event occurs call netif_carrier_on/off. Signed-off-by: Karl Hiramoto <ka...@hi...> --- net/atm/br2684.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 6719af6..e0136ec 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -448,6 +448,17 @@ free_skb: dev_kfree_skb(skb); } +static void br2684_signal_change(struct atm_vcc *atmvcc) +{ + struct br2684_vcc *brvcc = BR2684_VCC(atmvcc); + struct net_device *net_dev = brvcc->device; + + if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) + netif_carrier_off(net_dev); + else + netif_carrier_on(net_dev); +} + /* * Assign a vcc to a dev * Note: we do not have explicit unassign, but look at _push() @@ -514,6 +525,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) barrier(); atmvcc->push = br2684_push; atmvcc->pop = br2684_pop; + atmvcc->signal_change = br2684_signal_change; __skb_queue_head_init(&queue); rq = &sk_atm(atmvcc)->sk_receive_queue; @@ -530,6 +542,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) br2684_push(atmvcc, skb); } + br2684_signal_change(atmvcc); /* initialize netdev carrier state */ __module_get(THIS_MODULE); return 0; -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:27
|
Propagate changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/suni.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index da4b91f..41c56ea 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c @@ -291,8 +291,9 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) static void poll_los(struct atm_dev *dev) { - dev->signal = GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? ATM_PHY_SIG_LOST : - ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, + GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? + ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND); } -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:27
|
Propagate changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/idt77105.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index dab5cf5..bca9cb8 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -126,7 +126,7 @@ static void idt77105_restart_timer_func(unsigned long dummy) istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ if (istat & IDT77105_ISTAT_GOODSIG) { /* Found signal again */ - dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); printk(KERN_NOTICE "%s(itf %d): signal detected again\n", dev->type,dev->number); /* flush the receive FIFO */ @@ -222,7 +222,7 @@ static void idt77105_int(struct atm_dev *dev) /* Rx Signal Condition Change - line went up or down */ if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */ /* This should not happen (restart timer does it) but JIC */ - dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); } else { /* signal lost */ /* * Disable interrupts and stop all transmission and @@ -235,7 +235,7 @@ static void idt77105_int(struct atm_dev *dev) IDT77105_MCR_DRIC| IDT77105_MCR_HALTTX ) & ~IDT77105_MCR_EIP, MCR); - dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(dev, ATM_PHY_SIG_LOST); printk(KERN_NOTICE "%s(itf %d): signal lost\n", dev->type,dev->number); } @@ -272,8 +272,9 @@ static int idt77105_start(struct atm_dev *dev) memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); /* initialise dev->signal from Good Signal Bit */ - dev->signal = GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? ATM_PHY_SIG_FOUND : - ATM_PHY_SIG_LOST; + atm_dev_signal_change(dev, + GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? + ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST); if (dev->signal == ATM_PHY_SIG_LOST) printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, dev->number); -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-02 18:17:43
|
On DSL and ATM devices it's usefull to have a know if you have a carrier signal. netdevice LOWER_UP changes can be propagated to userspace via netlink monitor. Signed-off-by: Karl Hiramoto <ka...@hi...> --- include/linux/atmdev.h | 5 +++++ net/atm/common.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 817b237..c6958ec 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -311,6 +311,7 @@ struct atm_vcc { void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */ int (*push_oam)(struct atm_vcc *vcc,void *cell); int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); + void (*signal_change)(struct atm_vcc *vcc); /* optional. to propagate LOWER_UP */ void *dev_data; /* per-device data */ void *proto_data; /* per-protocol data */ struct k_atm_aal_stats *stats; /* pointer to AAL stats group */ @@ -431,6 +432,10 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, int number,unsigned long *flags); /* number == -1: pick first available */ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); +/** +* Propagate lower layer signal change in atm_dev->signal to netdevice. +*/ +void atm_dev_signal_change(struct atm_dev *dev, char signal); void vcc_insert_socket(struct sock *sk); diff --git a/net/atm/common.c b/net/atm/common.c index b43feb1..ccf09f2 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -212,6 +212,39 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) } EXPORT_SYMBOL(vcc_release_async); +void atm_dev_signal_change(struct atm_dev *dev, char signal) +{ + int i; + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", + __func__, signal, dev, dev->number, dev->signal); + + if (dev->signal == signal) + return; /* no change */ + + dev->signal = signal; + + read_lock_irq(&vcc_sklist_lock); + for (i = 0; i < VCC_HTABLE_SIZE; i++) { + struct hlist_head *head = &vcc_hash[i]; + struct hlist_node *node, *tmp; + struct sock *s; + struct atm_vcc *vcc; + sk_for_each_safe(s, node, tmp, head) { + vcc = atm_sk(s); + pr_debug("%s signal=%d vcc=%p dev=%p vcc->dev=%p %d.%d itf=%d meta=%d\n", + __func__, signal, vcc, dev, vcc->dev, + vcc->vpi, vcc->vci, vcc->itf, test_bit(ATM_VF_META, &vcc->flags)); + /* if there is a signal change callback and dev matches, + or if this is a meta dev (clip atm_dev is arpd) */ + if (vcc->signal_change && (vcc->dev == dev + || test_bit(ATM_VF_META, &vcc->flags))) { + vcc->signal_change(vcc); + } + } + } + read_unlock_irq(&vcc_sklist_lock); +} +EXPORT_SYMBOL(atm_dev_signal_change); void atm_dev_release_vccs(struct atm_dev *dev) { -- 1.7.1 |
From: chas w. - C. <ch...@cm...> - 2010-07-03 20:09:56
|
thanks for writing this. this is something that has been missing for some time in the atm stack. however, i was hoping it could take a different approach. i would prefer this mechanism to be more generic instead of being only suitable for signalling carrier changes. take a look at the notifier/register_netdevice_notifier scheme. clients (like br2684) who wish to get these notifications, would need to call register_atmdevice_notifier(). and yes, instead of handling setting the signal flag yourself, everyone (including the drivers in usb/atm) should be using the atm_dev_signal_change(). i am not fond of the idea of adding to the vcc struct something that is really per device, not per vcc. On Fri, 2 Jul 2010 19:47:04 +0200 Karl Hiramoto <ka...@hi...> wrote: > In userspace it's helpfull to know if a network device has a carrier > signal. Often it is monitored via netlink. This patchset allows a > way for the struct atm_dev drivers to pass carrier on/off to the > netdevice. > > For DSL, carrier is on when the line has reached showtime state. > > Currently this patchset only propagates the changes to br2684 vccs, > as this is the only type of hardware I have to test. > > If you prefer git you can pull from: > git://github.com/karlhiramoto/linux-2.6.git linux-atm > > Signed-off-by: Karl Hiramoto <ka...@hi...> > > Karl Hiramoto (6): > atm: add hooks to propagate signal changes to netdevice > atm br2684: add callback for carrier signal changes. > atm/idt77105.c: call atm_dev_signal_change() when signal changes. > atm/solos-pci: call atm_dev_signal_change() when signal changes. > atm/suni.c: call atm_dev_signal_change() when signal changes. > atm/adummy: add syfs DEVICE_ATTR to change signal > > drivers/atm/adummy.c | 39 > +++++++++++++++++++++++++++++++++++++++ drivers/atm/idt77105.c | > 11 ++++++----- drivers/atm/solos-pci.c | 6 +++--- > drivers/atm/suni.c | 5 +++-- > include/linux/atmdev.h | 5 +++++ > net/atm/br2684.c | 13 +++++++++++++ > net/atm/common.c | 33 +++++++++++++++++++++++++++++++++ > 7 files changed, 102 insertions(+), 10 deletions(-) > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Sprint > What will you do first with EVO, the first 4G phone? > Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first > _______________________________________________ > Linux-atm-general mailing list > Lin...@li... > https://lists.sourceforge.net/lists/listinfo/linux-atm-general > |
From: MIke W. <we...@cs...> - 2010-07-05 01:53:18
|
> > i am not fond of the idea of adding to the vcc struct something that > is really per device, not per vcc. I concur 100% with Chas on this one. mike chas williams - CONTRACTOR wrote: > thanks for writing this. this is something that has been missing for > some time in the atm stack. however, i was hoping it could take a > different approach. i would prefer this mechanism to be more generic > instead of being only suitable for signalling carrier changes. take a > look at the notifier/register_netdevice_notifier scheme. > > clients (like br2684) who wish to get these notifications, would need > to call register_atmdevice_notifier(). and yes, instead of handling > setting the signal flag yourself, everyone (including the drivers in > usb/atm) should be using the atm_dev_signal_change(). > > i am not fond of the idea of adding to the vcc struct something that > is really per device, not per vcc. > > On Fri, 2 Jul 2010 19:47:04 +0200 > Karl Hiramoto <ka...@hi...> wrote: > > >> In userspace it's helpfull to know if a network device has a carrier >> signal. Often it is monitored via netlink. This patchset allows a >> way for the struct atm_dev drivers to pass carrier on/off to the >> netdevice. >> >> For DSL, carrier is on when the line has reached showtime state. >> >> Currently this patchset only propagates the changes to br2684 vccs, >> as this is the only type of hardware I have to test. >> >> If you prefer git you can pull from: >> git://github.com/karlhiramoto/linux-2.6.git linux-atm >> >> Signed-off-by: Karl Hiramoto <ka...@hi...> >> >> Karl Hiramoto (6): >> atm: add hooks to propagate signal changes to netdevice >> atm br2684: add callback for carrier signal changes. >> atm/idt77105.c: call atm_dev_signal_change() when signal changes. >> atm/solos-pci: call atm_dev_signal_change() when signal changes. >> atm/suni.c: call atm_dev_signal_change() when signal changes. >> atm/adummy: add syfs DEVICE_ATTR to change signal >> >> drivers/atm/adummy.c | 39 >> +++++++++++++++++++++++++++++++++++++++ drivers/atm/idt77105.c | >> 11 ++++++----- drivers/atm/solos-pci.c | 6 +++--- >> drivers/atm/suni.c | 5 +++-- >> include/linux/atmdev.h | 5 +++++ >> net/atm/br2684.c | 13 +++++++++++++ >> net/atm/common.c | 33 +++++++++++++++++++++++++++++++++ >> 7 files changed, 102 insertions(+), 10 deletions(-) >> >> >> ------------------------------------------------------------------------------ >> This SF.net email is sponsored by Sprint >> What will you do first with EVO, the first 4G phone? >> Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first >> _______________________________________________ >> Linux-atm-general mailing list >> Lin...@li... >> https://lists.sourceforge.net/lists/listinfo/linux-atm-general >> >> > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Sprint > What will you do first with EVO, the first 4G phone? > Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first > _______________________________________________ > Linux-atm-general mailing list > Lin...@li... > https://lists.sourceforge.net/lists/listinfo/linux-atm-general > > > |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:27
|
Changes from v1: Use atm_dev notifier chain instead of callback function pointer in struct vcc. In drivers/usb/atm call atm_dev_signal_change(). In userspace it's helpfull to know if a network device has a carrier signal. Often it is monitored via netlink. This patchset allows a way for the struct atm_dev drivers to pass carrier on/off to the netdevice. For DSL, carrier is on when the line has reached showtime state. Currently this patchset only propagates the changes to br2684 vccs, as this is the only type of hardware I have to test. If you prefer git you can pull from: git://github.com/karlhiramoto/linux-2.6.git atm-v2 Karl Hiramoto (9): atm: propagate signal changes via notifier atm/br2684: register notifier event for carrier signal changes. atm/adummy: add syfs DEVICE_ATTR to change signal atm/idt77105.c: call atm_dev_signal_change() when signal changes. atm/solos-pci: call atm_dev_signal_change() when signal changes. atm/suni.c: call atm_dev_signal_change() when signal changes. usb/atm/cxacru.c: call atm_dev_signal_change() when signal changes. usb/atm/speedtch.c: call atm_dev_signal_change() when signal changes. usb/atm/ueagle-atm.c: call atm_dev_signal_change() when signal changes. drivers/atm/adummy.c | 39 ++++++++++++++++++++++++ drivers/atm/idt77105.c | 11 ++++--- drivers/atm/solos-pci.c | 6 ++-- drivers/atm/suni.c | 5 ++- drivers/usb/atm/cxacru.c | 18 ++++++------ drivers/usb/atm/speedtch.c | 10 +++--- drivers/usb/atm/ueagle-atm.c | 13 ++++++-- include/linux/atmdev.h | 12 +++++++ net/atm/br2684.c | 66 ++++++++++++++++++++++++++++++++++++++++- net/atm/common.c | 31 +++++++++++++++++++ 10 files changed, 182 insertions(+), 29 deletions(-) |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:34
|
Add notifier chain for changes in atm_dev. Clients like br2684 will call register_atmdevice_notifier() to be notified of changes. Drivers will call atm_dev_signal_change() to notify clients like br2684 of the change. On DSL and ATM devices it's usefull to have a know if you have a carrier signal. netdevice LOWER_UP changes can be propagated to userspace via netlink monitor. Signed-off-by: Karl Hiramoto <ka...@hi...> --- include/linux/atmdev.h | 12 ++++++++++++ net/atm/common.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 817b237..30890bc 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -431,6 +431,10 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, int number,unsigned long *flags); /* number == -1: pick first available */ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); +/** +* Propagate lower layer signal change in atm_dev->signal to netdevice. +*/ +void atm_dev_signal_change(struct atm_dev *dev, char signal); void vcc_insert_socket(struct sock *sk); @@ -510,6 +514,14 @@ void register_atm_ioctl(struct atm_ioctl *); */ void deregister_atm_ioctl(struct atm_ioctl *); + +/** +* register_atmdevice_notifier - register atm_dev notify events +* Currently we notify of signal found/lost +*/ +int register_atmdevice_notifier(struct notifier_block *nb); +void unregister_atmdevice_notifier(struct notifier_block *nb); + #endif /* __KERNEL__ */ #endif diff --git a/net/atm/common.c b/net/atm/common.c index b43feb1..cfa342e 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -37,6 +37,8 @@ EXPORT_SYMBOL(vcc_hash); DEFINE_RWLOCK(vcc_sklist_lock); EXPORT_SYMBOL(vcc_sklist_lock); +static BLOCKING_NOTIFIER_HEAD(atm_dev_notify_chain); + static void __vcc_insert_socket(struct sock *sk) { struct atm_vcc *vcc = atm_sk(sk); @@ -212,6 +214,23 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) } EXPORT_SYMBOL(vcc_release_async); +void atm_dev_signal_change(struct atm_dev *dev, char signal) +{ + int i; + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", + __func__, signal, dev, dev->number, dev->signal); + + /* atm driver sending invalid signal */ + WARN_ON(signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND); + + if (dev->signal == signal) + return; /* no change */ + + dev->signal = signal; + + blocking_notifier_call_chain(&atm_dev_notify_chain, signal, dev); +} +EXPORT_SYMBOL(atm_dev_signal_change); void atm_dev_release_vccs(struct atm_dev *dev) { @@ -781,6 +800,18 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len); } +int register_atmdevice_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&atm_dev_notify_chain, nb); +} +EXPORT_SYMBOL_GPL(register_atmdevice_notifier); + +void unregister_atmdevice_notifier(struct notifier_block *nb) +{ + blocking_notifier_chain_unregister(&atm_dev_notify_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_atmdevice_notifier); + static int __init atm_init(void) { int error; -- 1.7.1 |
From: chas w. - C. <ch...@cm...> - 2010-07-06 19:30:26
|
On Mon, 5 Jul 2010 10:45:53 +0200 Karl Hiramoto <ka...@hi...> wrote: > +void atm_dev_signal_change(struct atm_dev *dev, char signal) > +{ > + int i; > + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", > + __func__, signal, dev, dev->number, dev->signal); > + > + /* atm driver sending invalid signal */ > + WARN_ON(signal < ATM_PHY_SIG_LOST || signal > > ATM_PHY_SIG_FOUND); + > + if (dev->signal == signal) > + return; /* no change */ > + > + dev->signal = signal; > + > + blocking_notifier_call_chain(&atm_dev_notify_chain, signal, > dev); +} > +EXPORT_SYMBOL(atm_dev_signal_change); net/atm/common.c: In function 'atm_dev_signal_change': net/atm/common.c:213: warning: unused variable 'i' please remove i unless you need it |
From: chas w. - C. <ch...@cm...> - 2010-07-06 19:33:50
|
On Mon, 5 Jul 2010 10:45:53 +0200 Karl Hiramoto <ka...@hi...> wrote: > +/** > +* register_atmdevice_notifier - register atm_dev notify events > +* Currently we notify of signal found/lost > +*/ per Documentation/CodingStyle, the preferred style for multiline comments would look like: /* * This is the preferred style for multi-line * comments in the Linux kernel source code. * Please use it consistently. * * Description: A column of asterisks on the left side, * with beginning and ending almost-blank lines. */ please update all your comments to reflect this style. |
From: chas w. - C. <ch...@cm...> - 2010-07-06 19:42:34
|
On Mon, 5 Jul 2010 10:45:53 +0200 Karl Hiramoto <ka...@hi...> wrote: > +void atm_dev_signal_change(struct atm_dev *dev, char signal) > +{ > + int i; > + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", > + __func__, signal, dev, dev->number, dev->signal); > + > + /* atm driver sending invalid signal */ > + WARN_ON(signal < ATM_PHY_SIG_LOST || signal > > ATM_PHY_SIG_FOUND); + > + if (dev->signal == signal) > + return; /* no change */ > + > + dev->signal = signal; > + > + &atm_dev_notify_chain, signal, > dev); +} i am not sure that you can use blocking_notifier_call_chain() here. atm_dev_signal_change() might be called from an interrupt context in some of the drivers. this implies that the notifier functions themselves must also not block. so in br2684 you probably want to use read_lock_irq() instead of just read_lock() |
From: Karl H. <ka...@hi...> - 2010-07-07 07:40:58
|
On 07/06/2010 09:41 PM, chas williams - CONTRACTOR wrote: > On Mon, 5 Jul 2010 10:45:53 +0200 > Karl Hiramoto<ka...@hi...> wrote: > >> +void atm_dev_signal_change(struct atm_dev *dev, char signal) >> +{ >> + int i; >> + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", >> + __func__, signal, dev, dev->number, dev->signal); >> + >> + /* atm driver sending invalid signal */ >> + WARN_ON(signal< ATM_PHY_SIG_LOST || signal> >> ATM_PHY_SIG_FOUND); + >> + if (dev->signal == signal) >> + return; /* no change */ >> + >> + dev->signal = signal; >> + >> + &atm_dev_notify_chain, signal, >> dev); +} > i am not sure that you can use blocking_notifier_call_chain() here. > atm_dev_signal_change() might be called from an interrupt context in > some of the drivers. > > this implies that the notifier functions themselves must also not block. > so in br2684 you probably want to use read_lock_irq() instead of just > read_lock() Chas, I'll change to an atomic notifier, fix these issues, your other comments and send a new version of the patchset. Thanks. -- Karl |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:35
|
When a signal change event occurs call netif_carrier_on/off. Signed-off-by: Karl Hiramoto <ka...@hi...> --- net/atm/br2684.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 64 insertions(+), 2 deletions(-) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 6719af6..5afa512 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -139,6 +139,42 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s) return NULL; } +static int atm_dev_event(struct notifier_block *this, unsigned long event, + void *arg) +{ + struct atm_dev *atm_dev = arg; + struct list_head *lh; + struct net_device *net_dev; + struct br2684_vcc *brvcc; + struct atm_vcc *atm_vcc; + + pr_debug("event=%ld dev=%p\n", event, atm_dev); + + read_lock(&devs_lock); + list_for_each(lh, &br2684_devs) { + net_dev = list_entry_brdev(lh); + + list_for_each_entry(brvcc, &BRPRIV(net_dev)->brvccs, brvccs) { + atm_vcc = brvcc->atmvcc; + if (atm_vcc && brvcc->atmvcc->dev == atm_dev) { + + if (atm_vcc->dev->signal == ATM_PHY_SIG_LOST) + netif_carrier_off(net_dev); + else + netif_carrier_on(net_dev); + + } + } + } + read_unlock(&devs_lock); + + return NOTIFY_DONE; +} + +static struct notifier_block atm_dev_notifier = { + .notifier_call = atm_dev_event, +}; + /* chained vcc->pop function. Check if we should wake the netif_queue */ static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb) { @@ -362,6 +398,12 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) unregister_netdev(net_dev); free_netdev(net_dev); } + read_lock_irq(&devs_lock); + if (list_empty(&br2684_devs)) { + /* last br2684 device */ + unregister_atmdevice_notifier(&atm_dev_notifier); + } + read_unlock_irq(&devs_lock); return; } @@ -530,6 +572,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) br2684_push(atmvcc, skb); } + + /* initialize netdev carrier state */ + if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) + netif_carrier_off(net_dev); + else + netif_carrier_on(net_dev); + __module_get(THIS_MODULE); return 0; @@ -620,9 +669,16 @@ static int br2684_create(void __user *arg) } write_lock_irq(&devs_lock); + brdev->payload = payload; - brdev->number = list_empty(&br2684_devs) ? 1 : - BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; + + if (list_empty(&br2684_devs)) { + /* 1st br2684 device */ + register_atmdevice_notifier(&atm_dev_notifier); + brdev->number = 1; + } else + brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; + list_add_tail(&brdev->br2684_devs, &br2684_devs); write_unlock_irq(&devs_lock); return 0; @@ -758,6 +814,7 @@ static int __init br2684_init(void) return -ENOMEM; #endif register_atm_ioctl(&br2684_ioctl_ops); + return 0; } @@ -772,6 +829,11 @@ static void __exit br2684_exit(void) remove_proc_entry("br2684", atm_proc_root); #endif + + /* if not already empty */ + if (!list_empty(&br2684_devs)) + unregister_atmdevice_notifier(&atm_dev_notifier); + while (!list_empty(&br2684_devs)) { net_dev = list_entry_brdev(br2684_devs.next); brdev = BRPRIV(net_dev); -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:40
|
Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/adummy.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-) diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 6d44f07..46b9476 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -40,6 +40,42 @@ struct adummy_dev { static LIST_HEAD(adummy_devs); +static ssize_t __set_signal(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); + int signal; + + if (sscanf(buf, "%d", &signal) == 1) { + + if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND) + signal = ATM_PHY_SIG_UNKNOWN; + + atm_dev_signal_change(atm_dev, signal); + return 1; + } + return -EINVAL; +} + +static ssize_t __show_signal(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); + return sprintf(buf, "%d\n", atm_dev->signal); +} +static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal); + +static struct attribute *adummy_attrs[] = { + &dev_attr_signal.attr, + NULL +}; + +static struct attribute_group adummy_group_attrs = { + .name = NULL, /* We want them in dev's root folder */ + .attrs = adummy_attrs +}; + static int __init adummy_start(struct atm_dev *dev) { @@ -128,6 +164,9 @@ static int __init adummy_init(void) adummy_dev->atm_dev = atm_dev; atm_dev->dev_data = adummy_dev; + if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs)) + dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n"); + if (adummy_start(atm_dev)) { printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n"); err = -ENODEV; -- 1.7.1 |
[Linux-ATM-General] [PATCH v2 4/9] atm/idt77105.c: call
atm_dev_signal_change() when signal changes.
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:48
|
Propagate changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/idt77105.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index dab5cf5..bca9cb8 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -126,7 +126,7 @@ static void idt77105_restart_timer_func(unsigned long dummy) istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ if (istat & IDT77105_ISTAT_GOODSIG) { /* Found signal again */ - dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); printk(KERN_NOTICE "%s(itf %d): signal detected again\n", dev->type,dev->number); /* flush the receive FIFO */ @@ -222,7 +222,7 @@ static void idt77105_int(struct atm_dev *dev) /* Rx Signal Condition Change - line went up or down */ if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */ /* This should not happen (restart timer does it) but JIC */ - dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); } else { /* signal lost */ /* * Disable interrupts and stop all transmission and @@ -235,7 +235,7 @@ static void idt77105_int(struct atm_dev *dev) IDT77105_MCR_DRIC| IDT77105_MCR_HALTTX ) & ~IDT77105_MCR_EIP, MCR); - dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(dev, ATM_PHY_SIG_LOST); printk(KERN_NOTICE "%s(itf %d): signal lost\n", dev->type,dev->number); } @@ -272,8 +272,9 @@ static int idt77105_start(struct atm_dev *dev) memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); /* initialise dev->signal from Good Signal Bit */ - dev->signal = GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? ATM_PHY_SIG_FOUND : - ATM_PHY_SIG_LOST; + atm_dev_signal_change(dev, + GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? + ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST); if (dev->signal == ATM_PHY_SIG_LOST) printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, dev->number); -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:51
|
Propagate changes to upper atm layer, so userspace netmontor knows when DSL showtime reached. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/solos-pci.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index ded76c4..6174965 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -383,7 +383,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb /* Anything but 'Showtime' is down */ if (strcmp(state_str, "Showtime")) { - card->atmdev[port]->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); release_vccs(card->atmdev[port]); dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); return 0; @@ -401,7 +401,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn); card->atmdev[port]->link_rate = rate_down / 424; - card->atmdev[port]->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_FOUND); return 0; } @@ -1246,7 +1246,7 @@ static int atm_init(struct solos_card *card) card->atmdev[i]->ci_range.vci_bits = 16; card->atmdev[i]->dev_data = card; card->atmdev[i]->phy_data = (void *)(unsigned long)i; - card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:54
|
Propagate changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/atm/suni.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index da4b91f..41c56ea 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c @@ -291,8 +291,9 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) static void poll_los(struct atm_dev *dev) { - dev->signal = GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? ATM_PHY_SIG_LOST : - ATM_PHY_SIG_FOUND; + atm_dev_signal_change(dev, + GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? + ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND); } -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:46:58
|
Propagate signal changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/usb/atm/cxacru.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index c89990f..101ffc9 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -866,50 +866,50 @@ static void cxacru_poll_status(struct work_struct *work) instance->line_status = buf[CXINF_LINE_STATUS]; switch (instance->line_status) { case 0: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: down\n"); break; case 1: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: attempting to activate\n"); break; case 2: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: training\n"); break; case 3: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: channel analysis\n"); break; case 4: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: exchange\n"); break; case 5: atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; - atm_dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_FOUND); atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n", buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); break; case 6: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: waiting\n"); break; case 7: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: initializing\n"); break; default: - atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN); atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); break; } -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:47:04
|
Propagate signal changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/usb/atm/speedtch.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 1335456..80f9617 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -525,7 +525,7 @@ static void speedtch_check_status(struct work_struct *work) switch (status) { case 0: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); if (instance->last_status) atm_info(usbatm, "ADSL line is down\n"); /* It may never resync again unless we ask it to... */ @@ -533,12 +533,12 @@ static void speedtch_check_status(struct work_struct *work) break; case 0x08: - atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN); atm_info(usbatm, "ADSL line is blocked?\n"); break; case 0x10: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line is synchronising\n"); break; @@ -554,7 +554,7 @@ static void speedtch_check_status(struct work_struct *work) } atm_dev->link_rate = down_speed * 1000 / 424; - atm_dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_FOUND); atm_info(usbatm, "ADSL line is up (%d kb/s down | %d kb/s up)\n", @@ -562,7 +562,7 @@ static void speedtch_check_status(struct work_struct *work) break; default: - atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN); atm_info(usbatm, "unknown line state %02x\n", status); break; } -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-05 08:47:08
|
Propagate signal changes to upper atm layer. Signed-off-by: Karl Hiramoto <ka...@hi...> --- drivers/usb/atm/ueagle-atm.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index e213d3f..ebae944 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -575,6 +575,13 @@ MODULE_PARM_DESC(annex, sc->usbatm->atm_dev->type = val; \ } while (0) +#define UPDATE_ATM_SIGNAL(val) \ + do { \ + if (sc->usbatm->atm_dev) \ + atm_dev_signal_change(sc->usbatm->atm_dev, val); \ + } while (0) + + /* Firmware loading */ #define LOAD_INTERNAL 0xA0 #define F8051_USBCS 0x7f92 @@ -1359,7 +1366,7 @@ static int uea_stat_e1(struct uea_softc *sc) /* always update it as atm layer could not be init when we switch to * operational state */ - UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); + UPDATE_ATM_SIGNAL(ATM_PHY_SIG_FOUND); /* wake up processes waiting for synchronization */ wake_up(&sc->sync_q); @@ -1498,7 +1505,7 @@ static int uea_stat_e4(struct uea_softc *sc) /* always update it as atm layer could not be init when we switch to * operational state */ - UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); + UPDATE_ATM_SIGNAL(ATM_PHY_SIG_FOUND); /* wake up processes waiting for synchronization */ wake_up(&sc->sync_q); @@ -1825,7 +1832,7 @@ static int uea_start_reset(struct uea_softc *sc) * So we will failed to wait Ready CMV. */ sc->cmv_ack = 0; - UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); + UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST); /* reset statistics */ memset(&sc->stats, 0, sizeof(struct uea_stats)); -- 1.7.1 |
From: Karl H. <ka...@hi...> - 2010-07-07 08:50:53
|
Changes from v2: * use atomic instead of blocking notifier * use read_lock_irq() instead of read_lock() in atm/br2684 * clean up comments * remove unused variable. I feel really bad about missing that last time. Changes from v1: Use atm_dev notifier chain instead of callback function pointer in struct vcc. In drivers/usb/atm call atm_dev_signal_change(). In userspace it's helpful to know if a network device has a carrier signal. Often it is monitored via netlink. This patchset allows a way for the struct atm_dev drivers to pass carrier on/off to the netdevice. For DSL, carrier is on when the line has reached showtime state. Currently this patchset only propagates the changes to br2684 vccs, as this is the only type of hardware I have to test. If you prefer git you can pull from: git://github.com/karlhiramoto/linux-2.6.git atm-v3 Karl Hiramoto (9): atm: propagate signal changes via notifier atm/br2684: register notifier event for carrier signal changes. atm/adummy: add syfs DEVICE_ATTR to change signal atm/idt77105.c: call atm_dev_signal_change() when signal changes. atm/solos-pci: call atm_dev_signal_change() when signal changes. atm/suni.c: call atm_dev_signal_change() when signal changes. usb/atm/cxacru.c: call atm_dev_signal_change() when signal changes. usb/atm/speedtch.c: call atm_dev_signal_change() when signal changes. usb/atm/ueagle-atm.c: call atm_dev_signal_change() when signal changes. drivers/atm/adummy.c | 39 ++++++++++++++++++++++++ drivers/atm/idt77105.c | 11 ++++--- drivers/atm/solos-pci.c | 6 ++-- drivers/atm/suni.c | 5 ++- drivers/usb/atm/cxacru.c | 18 ++++++------ drivers/usb/atm/speedtch.c | 10 +++--- drivers/usb/atm/ueagle-atm.c | 13 ++++++-- include/linux/atmdev.h | 19 ++++++++++++ net/atm/br2684.c | 66 ++++++++++++++++++++++++++++++++++++++++- net/atm/common.c | 30 +++++++++++++++++++ 10 files changed, 188 insertions(+), 29 deletions(-) |
From: Karl H. <ka...@hi...> - 2010-07-07 08:50:55
|
Add notifier chain for changes in atm_dev. Clients like br2684 will call register_atmdevice_notifier() to be notified of changes. Drivers will call atm_dev_signal_change() to notify clients like br2684 of the change. On DSL and ATM devices it's usefull to have a know if you have a carrier signal. netdevice LOWER_UP changes can be propagated to userspace via netlink monitor. Signed-off-by: Karl Hiramoto <ka...@hi...> --- include/linux/atmdev.h | 19 +++++++++++++++++++ net/atm/common.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 0 deletions(-) diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 817b237..7c6dfd3 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -431,6 +431,15 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, int number,unsigned long *flags); /* number == -1: pick first available */ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); + +/** +* atm_dev_signal_change +* +* Propagate lower layer signal change in atm_dev->signal to netdevice. +* The event will be sent via a notifier call chain. +*/ +void atm_dev_signal_change(struct atm_dev *dev, char signal); + void vcc_insert_socket(struct sock *sk); @@ -510,6 +519,16 @@ void register_atm_ioctl(struct atm_ioctl *); */ void deregister_atm_ioctl(struct atm_ioctl *); + +/** +* register_atmdevice_notifier - register atm_dev notify events +* +* Clients like br2684 will register notify events +* Currently we notify of signal found/lost +*/ +int register_atmdevice_notifier(struct notifier_block *nb); +void unregister_atmdevice_notifier(struct notifier_block *nb); + #endif /* __KERNEL__ */ #endif diff --git a/net/atm/common.c b/net/atm/common.c index b43feb1..940404a 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -37,6 +37,8 @@ EXPORT_SYMBOL(vcc_hash); DEFINE_RWLOCK(vcc_sklist_lock); EXPORT_SYMBOL(vcc_sklist_lock); +static ATOMIC_NOTIFIER_HEAD(atm_dev_notify_chain); + static void __vcc_insert_socket(struct sock *sk) { struct atm_vcc *vcc = atm_sk(sk); @@ -212,6 +214,22 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) } EXPORT_SYMBOL(vcc_release_async); +void atm_dev_signal_change(struct atm_dev *dev, char signal) +{ + pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", + __func__, signal, dev, dev->number, dev->signal); + + /* atm driver sending invalid signal */ + WARN_ON(signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND); + + if (dev->signal == signal) + return; /* no change */ + + dev->signal = signal; + + atomic_notifier_call_chain(&atm_dev_notify_chain, signal, dev); +} +EXPORT_SYMBOL(atm_dev_signal_change); void atm_dev_release_vccs(struct atm_dev *dev) { @@ -781,6 +799,18 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len); } +int register_atmdevice_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&atm_dev_notify_chain, nb); +} +EXPORT_SYMBOL_GPL(register_atmdevice_notifier); + +void unregister_atmdevice_notifier(struct notifier_block *nb) +{ + atomic_notifier_chain_unregister(&atm_dev_notify_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_atmdevice_notifier); + static int __init atm_init(void) { int error; -- 1.7.1 |