Compare commits

...

7 Commits

Author SHA1 Message Date
Shaun Ruffell
b9a8000bbd dahdi: Fix failure to read / write on kernel 3.16+
Kernel version 3.16+, since upstream commit (7f7f25e82d54870d "replace checking
for ->read/->aio_read presence with check in ->f_mode" )[1], does not like it
when dahdi changes the set of allowed file operations on a file descriptor
outside of the context of an open() system call.

DAHDI changes the available file operations when a channel is opened by first
opening /dev/dahdi/channel and then calling the DAHDI_SPECIFY ioctl to bind it
to a particular DAHDI channel. Until DAHDI_SPECIFY is called there weren't any
read()/write() callbacks implemented and therefore after the initial open, the
kernel was setting not setting FMODE_CAN_{WRITE,READ} on the file descriptor
indicating that those operations were not allowed.

Now define empty shell functions on the general dahdi_fops so the vfs layer will
not mark a file descriptor as unwritteable or unreadable on open.

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7f7f25e82d54870df24d415a7007fbd327da027b

Internal-Issue-ID: DAHLIN-340
Reported-and-tested-by: Thomas B. Clark
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-09-17 16:29:16 -05:00
Michael Walton
eedb4bf944 dynamic: Prevent oops due to inverted compile flag
The logic on ENABLE_TASKELETS compiler flag was inverted causing an oops on
normal dahdi_cfg of a dynamic span.

Issue-id: https://issues.asterisk.org/jira/browse/DAHLIN-328

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
2014-08-15 14:58:47 -05:00
Russ Meyerriecks
91bc5a3b57 net: Update dahdi for alloc_netdev() api change in 3.17+
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c835a677331495cf137a7f8a023463afd9f0~

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
2014-08-11 09:53:02 -05:00
Russ Meyerriecks
8428452ad1 wcte43x: Reset span alarm to RED on startup
A fresh modprobe and dahdi_cfg would cause a temporary green alarm state on the
spans for a second while the alarm debounced into RED. New logic keeps the
spans alarm state as NONE during the unconfigured state, but sets the alarm
state to RED after the framer reset in the startup logic.

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-08-01 16:16:08 -05:00
Russ Meyerriecks
90b6712d01 wcte13xp: Reset span alarm to RED on startup
A fresh modprobe and dahdi_cfg would cause a temporary green alarm state on the
driver for a second while the alarm debounced into RED. New logic keeps the
spans alarm state as NONE during the unconfigured state, but sets the alarm
state to RED after the framer reset in the startup logic.

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
2014-07-23 16:24:01 -05:00
Shaun Ruffell
31cbf7a90e wcte43x: Fix failure to download firmware.
The firmware/Makefile missed a line that added the firmware for the TE436 to the
download list.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
2014-07-18 10:19:09 -05:00
Russ Meyerriecks
bce1ecafda wcte43x: Add support for new te436/te236 cards
Adds driver support for Digium's new te436 and te236 quad and dual span T1/E1 cards.

[removed whitespace at end of line]
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2014-07-17 15:18:10 -05:00
9 changed files with 96 additions and 16 deletions

View File

@@ -10284,6 +10284,18 @@ MODULE_PARM_DESC(auto_assign_spans,
"channel numbers assigned by the driver. If 0, user space "
"will need to assign them via /sys/bus/dahdi_devices.");
static ssize_t dahdi_no_read(struct file *file, char __user *usrbuf,
size_t count, loff_t *ppos)
{
return -ENOSYS;
}
static ssize_t dahdi_no_write(struct file *file, const char __user *usrbuf,
size_t count, loff_t *ppos)
{
return -ENOSYS;
}
static const struct file_operations dahdi_fops = {
.owner = THIS_MODULE,
.open = dahdi_open,
@@ -10297,6 +10309,8 @@ static const struct file_operations dahdi_fops = {
.ioctl = dahdi_ioctl,
#endif
.poll = dahdi_poll,
.read = dahdi_no_read,
.write = dahdi_no_write,
};
static const struct file_operations dahdi_timer_fops = {
@@ -10311,6 +10325,8 @@ static const struct file_operations dahdi_timer_fops = {
.ioctl = dahdi_timer_ioctl,
#endif
.poll = dahdi_timer_poll,
.read = dahdi_no_read,
.write = dahdi_no_write,
};
/*

View File

@@ -201,7 +201,9 @@ static void dahdi_dynamic_sendmessage(struct dahdi_dynamic *d)
static void __dahdi_dynamic_run(void)
{
struct dahdi_dynamic *d;
#ifdef ENABLE_TASKLETS
struct dahdi_dynamic_driver *drv;
#endif
rcu_read_lock();
list_for_each_entry_rcu(d, &dspan_list, list) {
@@ -211,6 +213,13 @@ static void __dahdi_dynamic_run(void)
}
#ifdef ENABLE_TASKLETS
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
#else
/* If tasklets are not enabled, the above section will be called in
* interrupt context and the flushing of each driver will be called in a
* separate tasklet that only handles that. This is necessary since some
@@ -221,13 +230,6 @@ static void __dahdi_dynamic_run(void)
*
*/
tasklet_hi_schedule(&dahdi_dynamic_flush_tlet);
#else
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
#endif
rcu_read_unlock();
}

View File

@@ -1063,12 +1063,23 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
used = pvc_is_used(pvc);
if (type == ARPHRD_ETHER)
if (type == ARPHRD_ETHER) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvceth%d", NET_NAME_UNKNOWN, ether_setup);
#else
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvceth%d", ether_setup);
else
#endif
} else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvc%d", NET_NAME_UNKNOWN, dlci_setup);
#else
dev = alloc_netdev(sizeof(struct net_device_stats),
"pvc%d", dlci_setup);
#endif
}
if (!dev) {
printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",

View File

@@ -282,7 +282,12 @@ static void hdlc_setup(struct net_device *dev)
struct net_device *alloc_hdlcdev(void *priv)
{
struct net_device *dev;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d",
NET_NAME_UNKNOWN, hdlc_setup);
#else
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup);
#endif
if (dev)
dev_to_hdlc(dev)->priv = priv;
return dev;

View File

@@ -34,6 +34,7 @@ WCT820_VERSION:=1.76
TE133_VERSION:=780019
TE134_VERSION:=780017
TE435_VERSION:=e0019
TE436_VERSION:=10017
A8A_VERSION:=1d0017
A8B_VERSION:=1d0019
A4A_VERSION:=a0017
@@ -43,7 +44,7 @@ FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
ALL_FIRMWARE=FIRMWARE-OCT6114-032 FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-OCT6114-256
ALL_FIRMWARE+=FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032 FIRMWARE-TE820 FIRMWARE-TE133 FIRMWARE-TE134
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435 FIRMWARE-TE436
# Firmware files should use the naming convention: dahdi-fw-<base name>-<sub name>-<version> or dahdi-fw-<base name>-<version>
# First example: dahdi-fw-oct6114-064-1.05.01
@@ -63,6 +64,7 @@ FIRMWARE:=$(FIRMWARE:FIRMWARE-TE820=dahdi-fw-te820-$(WCT820_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE133=dahdi-fw-te133-$(TE133_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE134=dahdi-fw-te134-$(TE134_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE435=dahdi-fw-te435-$(TE435_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE436=dahdi-fw-te436-$(TE436_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8A=dahdi-fw-a8b-$(A8B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8B=dahdi-fw-a8a-$(A8A_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4A=dahdi-fw-a4b-$(A4B_VERSION).tar.gz)
@@ -138,6 +140,7 @@ hotplug-install: $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware $(F
@$(call RUN_INST,dahdi-fw-te133,$(TE133_VERSION))
@$(call RUN_INST,dahdi-fw-te134,$(TE134_VERSION))
@$(call RUN_INST,dahdi-fw-te435,$(TE435_VERSION))
@$(call RUN_INST,dahdi-fw-te436,$(TE436_VERSION))
@$(call RUN_INST,dahdi-fw-a8a,$(A8A_VERSION))
@$(call RUN_INST,dahdi-fw-a8b,$(A8B_VERSION))
@$(call RUN_INST,dahdi-fw-a4a,$(A4A_VERSION))

View File

@@ -207,7 +207,13 @@ int vb_net_register(struct voicebus *vb, const char *board_name)
struct voicebus_netdev_priv *priv;
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
netdev = alloc_netdev(sizeof(*priv), board_name,
NET_NAME_UNKNOWN, ether_setup);
#else
netdev = alloc_netdev(sizeof(*priv), board_name, ether_setup);
#endif
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);

View File

@@ -657,7 +657,13 @@ wctc4xxp_net_register(struct wcdte *wc)
struct wcdte_netdev_priv *priv;
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
netdev = alloc_netdev(sizeof(*priv), wc->board_name,
NET_NAME_UNKNOWN, ether_setup);
#else
netdev = alloc_netdev(sizeof(*priv), wc->board_name, ether_setup);
#endif
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);

View File

@@ -1316,6 +1316,10 @@ static int t13x_startup(struct file *file, struct dahdi_span *span)
/* Reset framer with proper parameters and start */
t13x_framer_start(wc);
/* Reset span alarm state to RED to prevent false
* temporary GREEN state on span bringup */
span->alarms |= DAHDI_ALARM_RED;
/* Do we want to SYNC on receive or not. This must always happen after
* the framer is fully reset. */
wcxb_set_clksrc(&wc->xb,

View File

@@ -65,7 +65,9 @@ static inline int delayed_work_pending(struct work_struct *work)
#endif
static const char *TE435_FW_FILENAME = "dahdi-fw-te435.bin";
static const char *TE436_FW_FILENAME = "dahdi-fw-te436.bin";
static const u32 TE435_VERSION = 0xe0019;
static const u32 TE436_VERSION = 0x10017;
/* #define RPC_RCLK */
@@ -794,6 +796,8 @@ struct t43x_desc {
static const struct t43x_desc te435 = {"Wildcard TE435"}; /* pci express quad */
static const struct t43x_desc te235 = {"Wildcard TE235"}; /* pci express dual */
static const struct t43x_desc te436 = {"Wildcard TE436"}; /* pci quad */
static const struct t43x_desc te236 = {"Wildcard TE236"}; /* pci dual */
static int __t43x_pci_get(struct t43x *wc, unsigned int addr)
{
@@ -1762,6 +1766,10 @@ static void t43x_framer_start(struct t43x *wc)
t43x_set_cas_mode(wc, unit);
set_bit(DAHDI_FLAGBIT_RUNNING, &ts->span.flags);
/* Reset span alarm state to RED to prevent false
* temporary GREEN state on span bringup */
ts->span.alarms |= DAHDI_ALARM_RED;
}
for (unit = 0; unit < wc->numspans; unit++) {
@@ -3449,12 +3457,6 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
goto fail_exit;
}
/* Check for field updatable firmware */
res = wcxb_check_firmware(&wc->xb, TE435_VERSION,
TE435_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
if (res)
goto fail_exit;
wc->ddev->hardware_id = t43x_read_serial(wc);
if (wc->ddev->hardware_id == NULL) {
@@ -3464,11 +3466,21 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
}
if (strncmp(wc->ddev->hardware_id, "1TE435F", 7) == 0) {
/* Quad-span PCIE */
wc->numspans = 4;
wc->devtype = &te435;
} else if (strncmp(wc->ddev->hardware_id, "1TE235F", 7) == 0) {
/* Dual-span PCIE */
wc->numspans = 2;
wc->devtype = &te235;
} else if (strncmp(wc->ddev->hardware_id, "1TE436F", 7) == 0) {
/* Quad-span PCI */
wc->numspans = 4;
wc->devtype = &te436;
} else if (strncmp(wc->ddev->hardware_id, "1TE236F", 7) == 0) {
/* Dual-span PCI */
wc->numspans = 2;
wc->devtype = &te236;
} else {
dev_info(&wc->xb.pdev->dev,
"Unable to identify board type from serial number %s\n",
@@ -3477,6 +3489,20 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
goto fail_exit;
}
/* Check for field updatable firmware */
if ((wc->devtype == &te435) || (wc->devtype == &te235)) {
res = wcxb_check_firmware(&wc->xb, TE435_VERSION,
TE435_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
} else if ((wc->devtype == &te436) || (wc->devtype == &te236)) {
res = wcxb_check_firmware(&wc->xb, TE436_VERSION,
TE436_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
} else {
res = -EIO;
}
if (res)
goto fail_exit;
for (x = 0; x < wc->numspans; x++) {
ts = kzalloc(sizeof(*wc->tspans[x]), GFP_KERNEL);
if (!ts) {
@@ -3595,6 +3621,7 @@ static void __devexit t43x_remove_one(struct pci_dev *pdev)
static DEFINE_PCI_DEVICE_TABLE(t43x_pci_tbl) = {
{ 0xd161, 0x800e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0xd161, 0x8013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0 }
};