[dahdi-commits] dahdi/linux.git branch "master" updated.

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Thu May 23 16:31:29 CDT 2013


branch "master" has been updated
       via  1f20b5f8fa3c0c28ad1c0fac51050e1fba16e7c8 (commit)
       via  ba2fdf2dac7c6136e30eff52f686095e644d56ac (commit)
       via  84ccc652b6cb3f57e6cff6ceab201a553bfe9561 (commit)
      from  40da50faed00df800e4c540260fca3248e54e9e4 (commit)

Summary of changes:
 drivers/dahdi/dahdi-base.c          |   26 +++--
 drivers/dahdi/dahdi_dynamic_ethmf.c |   63 ++++++------
 drivers/dahdi/xpp/card_bri.c        |  105 ++++++++++----------
 drivers/dahdi/xpp/card_fxo.c        |  173 +++++++++++++++++----------------
 drivers/dahdi/xpp/card_fxs.c        |  125 ++++++++++++------------
 drivers/dahdi/xpp/xbus-core.c       |  182 +++++++++++++++++------------------
 drivers/dahdi/xpp/xpp_dahdi.c       |  130 +++++++++++--------------
 drivers/dahdi/xpp/xpp_usb.c         |   87 ++++++++---------
 include/dahdi/kernel.h              |   25 +++++
 9 files changed, 464 insertions(+), 452 deletions(-)


- Log -----------------------------------------------------------------
commit 1f20b5f8fa3c0c28ad1c0fac51050e1fba16e7c8
Author: Shaun Ruffell <sruffell at digium.com>
Date:   Tue May 21 15:33:18 2013 -0500

    xpp: Don't use create_proc_read_entry()
    
    Don't use create_proc_read_entry() as that is deprecated, but rather use
    proc_create_data() and seq_file instead.
    
    This is needed to compile against Linux 3.10.
    
    Signed-off-by: Shaun Ruffell <sruffell at digium.com>
    [tzafrir.cohen at xorcom.com: fixed passing /proc/xpp/XPD/summary xbus number]
    Acked-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
    Cc: Russ Meyerriecks <rmeyerriecks at digium.com>
    Cc: Oron Peled <oron.peled at xorcom.com>

diff --git a/drivers/dahdi/xpp/card_bri.c b/drivers/dahdi/xpp/card_bri.c
index 3ef9ddb..5138ab7 100644
--- a/drivers/dahdi/xpp/card_bri.c
+++ b/drivers/dahdi/xpp/card_bri.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/seq_file.h>
 #include "xpd.h"
 #include "xproto.h"
 #include "xpp_dahdi.h"
@@ -152,8 +153,7 @@ static int write_state_register(xpd_t *xpd, __u8 value);
 static bool bri_packet_is_valid(xpacket_t *pack);
 static void bri_packet_dump(const char *msg, xpacket_t *pack);
 #ifdef	CONFIG_PROC_FS
-static int proc_bri_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data);
+static const struct file_operations proc_bri_info_ops;
 #endif
 static int bri_spanconfig(struct file *file, struct dahdi_span *span,
 			  struct dahdi_lineconfig *lc);
@@ -673,9 +673,8 @@ static int bri_proc_create(xbus_t *xbus, xpd_t *xpd)
 	XPD_DBG(PROC, xpd, "\n");
 #ifdef	CONFIG_PROC_FS
 	XPD_DBG(PROC, xpd, "Creating '%s'\n", PROC_BRI_INFO_FNAME);
-	priv->bri_info =
-	    create_proc_read_entry(PROC_BRI_INFO_FNAME, 0444, xpd->proc_xpd_dir,
-				   proc_bri_info_read, xpd);
+	priv->bri_info = proc_create_data(PROC_BRI_INFO_FNAME, 0444,
+				 xpd->proc_xpd_dir, &proc_bri_info_ops, xpd);
 	if (!priv->bri_info) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_BRI_INFO_FNAME);
@@ -1667,12 +1666,10 @@ static void bri_packet_dump(const char *msg, xpacket_t *pack)
 /*------------------------- REGISTER Handling --------------------------*/
 
 #ifdef	CONFIG_PROC_FS
-static int proc_bri_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data)
+static int proc_bri_info_show(struct seq_file *sfile, void *not_used)
 {
-	int len = 0;
 	unsigned long flags;
-	xpd_t *xpd = data;
+	xpd_t *xpd = sfile->private;
 	struct BRI_priv_data *priv;
 
 	DBG(PROC, "\n");
@@ -1681,69 +1678,65 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count,
 	spin_lock_irqsave(&xpd->lock, flags);
 	priv = xpd->priv;
 	BUG_ON(!priv);
-	len += sprintf(page + len, "%05d Layer 1: ", priv->poll_counter);
+	seq_printf(sfile, "%05d Layer 1: ", priv->poll_counter);
 	if (priv->reg30_good) {
-		len +=
-		    sprintf(page + len, "%-5s ",
-			    (priv->layer1_up) ? "UP" : "DOWN");
-		len +=
-		    sprintf(page + len,
-			    "%c%d %-15s -- fr_sync=%d t2_exp=%d info0=%d g2_g3=%d\n",
-			    IS_NT(xpd) ? 'G' : 'F',
-			    priv->state_register.bits.v_su_sta,
-			    xhfc_state_name(IS_NT(xpd),
-					    priv->state_register.bits.v_su_sta),
-			    priv->state_register.bits.v_su_fr_sync,
-			    priv->state_register.bits.v_su_t2_exp,
-			    priv->state_register.bits.v_su_info0,
-			    priv->state_register.bits.v_g2_g3);
-	} else
-		len += sprintf(page + len, "Unknown\n");
+		seq_printf(sfile, "%-5s ", (priv->layer1_up) ? "UP" : "DOWN");
+		seq_printf(sfile,
+			   "%c%d %-15s -- fr_sync=%d t2_exp=%d info0=%d g2_g3=%d\n",
+			   IS_NT(xpd) ? 'G' : 'F',
+			   priv->state_register.bits.v_su_sta,
+			   xhfc_state_name(IS_NT(xpd),
+				    priv->state_register.bits.v_su_sta),
+			   priv->state_register.bits.v_su_fr_sync,
+			   priv->state_register.bits.v_su_t2_exp,
+			   priv->state_register.bits.v_su_info0,
+			   priv->state_register.bits.v_g2_g3);
+	} else {
+		seq_printf(sfile, "Unknown\n");
+	}
 	if (IS_NT(xpd))
-		len += sprintf(page + len, "T1 Timer: %d\n", priv->t1);
+		seq_printf(sfile, "T1 Timer: %d\n", priv->t1);
 	else
-		len += sprintf(page + len, "T3 Timer: %d\n", priv->t3);
-	len += sprintf(page + len, "Tick Counter: %d\n", priv->tick_counter);
-	len +=
-	    sprintf(page + len, "Last Poll Reply: %d ticks ago\n",
+		seq_printf(sfile, "T3 Timer: %d\n", priv->t3);
+	seq_printf(sfile, "Tick Counter: %d\n", priv->tick_counter);
+	seq_printf(sfile, "Last Poll Reply: %d ticks ago\n",
 		    priv->reg30_ticks);
-	len += sprintf(page + len, "reg30_good=%d\n", priv->reg30_good);
-	len +=
-	    sprintf(page + len, "D-Channel: TX=[%5d]    RX=[%5d]    BAD=[%5d] ",
+	seq_printf(sfile, "reg30_good=%d\n", priv->reg30_good);
+	seq_printf(sfile, "D-Channel: TX=[%5d]    RX=[%5d]    BAD=[%5d] ",
 		    priv->dchan_tx_counter, priv->dchan_rx_counter,
 		    priv->dchan_rx_drops);
 	if (priv->dchan_alive) {
-		len +=
-		    sprintf(page + len, "(alive %d K-ticks)\n",
+		seq_printf(sfile, "(alive %d K-ticks)\n",
 			    priv->dchan_alive_ticks / 1000);
 	} else {
-		len += sprintf(page + len, "(dead)\n");
+		seq_printf(sfile, "(dead)\n");
 	}
-	len +=
-	    sprintf(page + len, "dchan_notx_ticks: %d\n",
+	seq_printf(sfile, "dchan_notx_ticks: %d\n",
 		    priv->dchan_notx_ticks);
-	len +=
-	    sprintf(page + len, "dchan_norx_ticks: %d\n",
+	seq_printf(sfile, "dchan_norx_ticks: %d\n",
 		    priv->dchan_norx_ticks);
-	len +=
-	    sprintf(page + len, "LED: %-10s = %d\n", "GREEN",
+	seq_printf(sfile, "LED: %-10s = %d\n", "GREEN",
 		    priv->ledstate[GREEN_LED]);
-	len +=
-	    sprintf(page + len, "LED: %-10s = %d\n", "RED",
+	seq_printf(sfile, "LED: %-10s = %d\n", "RED",
 		    priv->ledstate[RED_LED]);
-	len += sprintf(page + len, "\nDCHAN:\n");
-	len += sprintf(page + len, "\n");
+	seq_printf(sfile, "\nDCHAN:\n");
+	seq_printf(sfile, "\n");
 	spin_unlock_irqrestore(&xpd->lock, flags);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
 }
+
+static int proc_bri_info_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_bri_info_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_bri_info_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_bri_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif
 
 static int bri_xpd_probe(struct device *dev)
diff --git a/drivers/dahdi/xpp/card_fxo.c b/drivers/dahdi/xpp/card_fxo.c
index 49c8886..6a11b43 100644
--- a/drivers/dahdi/xpp/card_fxo.c
+++ b/drivers/dahdi/xpp/card_fxo.c
@@ -24,6 +24,8 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include "xpd.h"
 #include "xproto.h"
 #include "xpp_dahdi.h"
@@ -105,11 +107,9 @@ enum fxo_leds {
 static bool fxo_packet_is_valid(xpacket_t *pack);
 static void fxo_packet_dump(const char *msg, xpacket_t *pack);
 #ifdef CONFIG_PROC_FS
-static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data);
+static const struct file_operations proc_fxo_info_ops;
 #ifdef	WITH_METERING
-static int proc_xpd_metering_read(char *page, char **start, off_t off,
-				  int count, int *eof, void *data);
+static const struct file_operations proc_xpd_metering_ops;
 #endif
 #endif
 static void dahdi_report_battery(xpd_t *xpd, lineno_t chan);
@@ -440,7 +440,6 @@ static void fxo_proc_remove(xbus_t *xbus, xpd_t *xpd)
 #ifdef	WITH_METERING
 	if (priv->meteringfile) {
 		XPD_DBG(PROC, xpd, "Removing xpd metering tone file\n");
-		priv->meteringfile->data = NULL;
 		remove_proc_entry(PROC_METERING_FNAME, xpd->proc_xpd_dir);
 		priv->meteringfile = NULL;
 	}
@@ -461,9 +460,9 @@ static int fxo_proc_create(xbus_t *xbus, xpd_t *xpd)
 	priv = xpd->priv;
 #ifdef	CONFIG_PROC_FS
 	XPD_DBG(PROC, xpd, "Creating FXO_INFO file\n");
-	priv->fxo_info =
-	    create_proc_read_entry(PROC_FXO_INFO_FNAME, 0444, xpd->proc_xpd_dir,
-				   proc_fxo_info_read, xpd);
+	priv->fxo_info = proc_create_data(PROC_FXO_INFO_FNAME, 0444,
+					  xpd->proc_xpd_dir,
+					  &proc_fxo_info_ops, xpd);
 	if (!priv->fxo_info) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_FXO_INFO_FNAME);
@@ -473,9 +472,9 @@ static int fxo_proc_create(xbus_t *xbus, xpd_t *xpd)
 	SET_PROC_DIRENTRY_OWNER(priv->fxo_info);
 #ifdef	WITH_METERING
 	XPD_DBG(PROC, xpd, "Creating Metering tone file\n");
-	priv->meteringfile =
-	    create_proc_read_entry(PROC_METERING_FNAME, 0444, xpd->proc_xpd_dir,
-				   proc_xpd_metering_read, xpd);
+	priv->meteringfile = proc_create_data(PROC_METERING_FNAME, 0444,
+					      xpd->proc_xpd_dir,
+					      &proc_xpd_metering_ops, xpd);
 	if (!priv->meteringfile) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_METERING_FNAME);
@@ -1347,12 +1346,10 @@ static void fxo_packet_dump(const char *msg, xpacket_t *pack)
 /*------------------------- DAA Handling --------------------------*/
 
 #ifdef	CONFIG_PROC_FS
-static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data)
+static int proc_fxo_info_show(struct seq_file *sfile, void *not_used)
 {
-	int len = 0;
 	unsigned long flags;
-	xpd_t *xpd = data;
+	xpd_t *xpd = sfile->private;
 	struct FXO_priv_data *priv;
 	int i;
 
@@ -1361,42 +1358,43 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
 	spin_lock_irqsave(&xpd->lock, flags);
 	priv = xpd->priv;
 	BUG_ON(!priv);
-	len += sprintf(page + len, "\t%-17s: ", "Channel");
+	seq_printf(sfile, "\t%-17s: ", "Channel");
 	for_each_line(xpd, i) {
 		if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
-		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-			len += sprintf(page + len, "%4d ", i % 10);
+		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) {
+			seq_printf(sfile, "%4d ", i % 10);
+		}
 	}
-	len += sprintf(page + len, "\nLeds:");
-	len += sprintf(page + len, "\n\t%-17s: ", "state");
+	seq_printf(sfile, "\nLeds:");
+	seq_printf(sfile, "\n\t%-17s: ", "state");
 	for_each_line(xpd, i) {
 		if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
-		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-			len +=
-			    sprintf(page + len, "  %d%d ",
-				    IS_SET(priv->ledstate[LED_GREEN], i),
-				    IS_SET(priv->ledstate[LED_RED], i));
+		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) {
+			seq_printf(sfile, "  %d%d ",
+				   IS_SET(priv->ledstate[LED_GREEN], i),
+				   IS_SET(priv->ledstate[LED_RED], i));
+		}
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "blinking");
+	seq_printf(sfile, "\n\t%-17s: ", "blinking");
 	for_each_line(xpd, i) {
 		if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
-		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-			len +=
-			    sprintf(page + len, "  %d%d ",
-				    IS_BLINKING(priv, i, LED_GREEN),
-				    IS_BLINKING(priv, i, LED_RED));
+		    && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) {
+			seq_printf(sfile, "  %d%d ",
+				   IS_BLINKING(priv, i, LED_GREEN),
+				   IS_BLINKING(priv, i, LED_RED));
+		}
 	}
-	len += sprintf(page + len, "\nBattery-Data:");
-	len += sprintf(page + len, "\n\t%-17s: ", "voltage");
+	seq_printf(sfile, "\nBattery-Data:");
+	seq_printf(sfile, "\n\t%-17s: ", "voltage");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->battery_voltage[i]);
+		seq_printf(sfile, "%4d ", priv->battery_voltage[i]);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "current");
+	seq_printf(sfile, "\n\t%-17s: ", "current");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->battery_current[i]);
+		seq_printf(sfile, "%4d ", priv->battery_current[i]);
 	}
-	len += sprintf(page + len, "\nBattery:");
-	len += sprintf(page + len, "\n\t%-17s: ", "on");
+	seq_printf(sfile, "\nBattery:");
+	seq_printf(sfile, "\n\t%-17s: ", "on");
 	for_each_line(xpd, i) {
 		char *bat;
 
@@ -1406,14 +1404,14 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
 			bat = "-";
 		else
 			bat = ".";
-		len += sprintf(page + len, "%4s ", bat);
+		seq_printf(sfile, "%4s ", bat);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "debounce");
+	seq_printf(sfile, "\n\t%-17s: ", "debounce");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->nobattery_debounce[i]);
+		seq_printf(sfile, "%4d ", priv->nobattery_debounce[i]);
 	}
-	len += sprintf(page + len, "\nPolarity-Reverse:");
-	len += sprintf(page + len, "\n\t%-17s: ", "polarity");
+	seq_printf(sfile, "\nPolarity-Reverse:");
+	seq_printf(sfile, "\n\t%-17s: ", "polarity");
 	for_each_line(xpd, i) {
 		char *polname;
 
@@ -1423,14 +1421,14 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
 			polname = "-";
 		else
 			polname = ".";
-		len += sprintf(page + len, "%4s ", polname);
+		seq_printf(sfile, "%4s ", polname);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "debounce");
+	seq_printf(sfile, "\n\t%-17s: ", "debounce");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->polarity_debounce[i]);
+		seq_printf(sfile, "%4d ", priv->polarity_debounce[i]);
 	}
-	len += sprintf(page + len, "\nPower-Denial:");
-	len += sprintf(page + len, "\n\t%-17s: ", "power");
+	seq_printf(sfile, "\nPower-Denial:");
+	seq_printf(sfile, "\n\t%-17s: ", "power");
 	for_each_line(xpd, i) {
 		char *curr;
 
@@ -1440,45 +1438,46 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count,
 			curr = "-";
 		else
 			curr = ".";
-		len += sprintf(page + len, "%4s ", curr);
+		seq_printf(sfile, "%4s ", curr);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "safezone");
+	seq_printf(sfile, "\n\t%-17s: ", "safezone");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%4d ", priv->power_denial_safezone[i]);
+		seq_printf(sfile, "%4d ", priv->power_denial_safezone[i]);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "delay");
+	seq_printf(sfile, "\n\t%-17s: ", "delay");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->power_denial_delay[i]);
+		seq_printf(sfile, "%4d ", priv->power_denial_delay[i]);
 	}
 #ifdef	WITH_METERING
-	len += sprintf(page + len, "\nMetering:");
-	len += sprintf(page + len, "\n\t%-17s: ", "count");
+	seq_printf(sfile, "\nMetering:");
+	seq_printf(sfile, "\n\t%-17s: ", "count");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d ", priv->metering_count[i]);
+		seq_printf(sfile, "%4d ", priv->metering_count[i]);
 	}
 #endif
-	len += sprintf(page + len, "\n");
+	seq_printf(sfile, "\n");
 	spin_unlock_irqrestore(&xpd->lock, flags);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
 }
-#endif
+
+static int proc_fxo_info_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_fxo_info_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_fxo_info_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_fxo_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 #ifdef	WITH_METERING
-static int proc_xpd_metering_read(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static int proc_xpd_metering_show(struct seq_file *sfile, void *not_used)
 {
-	int len = 0;
 	unsigned long flags;
-	xpd_t *xpd = data;
+	xpd_t *xpd = sfile->private;
 	struct FXO_priv_data *priv;
 	int i;
 
@@ -1487,25 +1486,31 @@ static int proc_xpd_metering_read(char *page, char **start, off_t off,
 	priv = xpd->priv;
 	BUG_ON(!priv);
 	spin_lock_irqsave(&xpd->lock, flags);
-	len += sprintf(page + len, "# Chan\tMeter (since last read)\n");
+	seq_printf(sfile, "# Chan\tMeter (since last read)\n");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%d\t%d\n", i, priv->metering_count[i]);
+		seq_printf(sfile, "%d\t%d\n", i, priv->metering_count[i]);
 	}
 	spin_unlock_irqrestore(&xpd->lock, flags);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
 	/* Zero meters */
 	for_each_line(xpd, i)
 	    priv->metering_count[i] = 0;
-	return len;
+	return 0;
 }
+
+static int proc_xpd_metering_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_xpd_metering_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_xpd_metering_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_xpd_metering_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+#endif
 #endif
 
 static DEVICE_ATTR_READER(fxo_battery_show, dev, buf)
diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index 48fb27a..921a3c2 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/seq_file.h>
 #include "xpd.h"
 #include "xproto.h"
 #include "xpp_dahdi.h"
@@ -120,11 +121,9 @@ enum fxs_state {
 static bool fxs_packet_is_valid(xpacket_t *pack);
 static void fxs_packet_dump(const char *msg, xpacket_t *pack);
 #ifdef CONFIG_PROC_FS
-static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data);
+static const struct file_operations proc_fxs_info_ops;
 #ifdef	WITH_METERING
-static int proc_xpd_metering_write(struct file *file,
-	const char __user *buffer, unsigned long count, void *data);
+static const struct file_operations proc_xpd_metering_ops;
 #endif
 #endif
 static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos);
@@ -399,7 +398,6 @@ static void fxs_proc_remove(xbus_t *xbus, xpd_t *xpd)
 #ifdef	WITH_METERING
 	if (priv->meteringfile) {
 		XPD_DBG(PROC, xpd, "Removing xpd metering tone file\n");
-		priv->meteringfile->data = NULL;
 		remove_proc_entry(PROC_METERING_FNAME, xpd->proc_xpd_dir);
 		priv->meteringfile = NULL;
 	}
@@ -421,9 +419,9 @@ static int fxs_proc_create(xbus_t *xbus, xpd_t *xpd)
 
 #ifdef	CONFIG_PROC_FS
 	XPD_DBG(PROC, xpd, "Creating FXS_INFO file\n");
-	priv->fxs_info =
-	    create_proc_read_entry(PROC_FXS_INFO_FNAME, 0444, xpd->proc_xpd_dir,
-				   proc_fxs_info_read, xpd);
+	priv->fxs_info = proc_create_data(PROC_FXS_INFO_FNAME, 0444,
+					  xpd->proc_xpd_dir,
+					  &proc_fxs_info_ops, xpd);
 	if (!priv->fxs_info) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_FXS_INFO_FNAME);
@@ -433,18 +431,15 @@ static int fxs_proc_create(xbus_t *xbus, xpd_t *xpd)
 	SET_PROC_DIRENTRY_OWNER(priv->fxs_info);
 #ifdef	WITH_METERING
 	XPD_DBG(PROC, xpd, "Creating Metering tone file\n");
-	priv->meteringfile =
-	    create_proc_entry(PROC_METERING_FNAME, 0200, xpd->proc_xpd_dir);
+	priv->meteringfile = proc_create_data(PROC_METERING_FNAME, 0200,
+					      xpd->proc_xpd_dir,
+					      &proc_xpd_metering_ops, xpd);
 	if (!priv->meteringfile) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_METERING_FNAME);
 		fxs_proc_remove(xbus, xpd);
 		return -EINVAL;
 	}
-	SET_PROC_DIRENTRY_OWNER(priv->meteringfile);
-	priv->meteringfile->write_proc = proc_xpd_metering_write;
-	priv->meteringfile->read_proc = NULL;
-	priv->meteringfile->data = xpd;
 #endif
 #endif
 	return 0;
@@ -1691,12 +1686,10 @@ static void fxs_packet_dump(const char *msg, xpacket_t *pack)
 /*------------------------- SLIC Handling --------------------------*/
 
 #ifdef	CONFIG_PROC_FS
-static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
-			      int *eof, void *data)
+static int proc_fxs_info_show(struct seq_file *sfile, void *not_used)
 {
-	int len = 0;
 	unsigned long flags;
-	xpd_t *xpd = data;
+	xpd_t *xpd = sfile->private;
 	struct FXS_priv_data *priv;
 	int i;
 	int led;
@@ -1706,11 +1699,11 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
 	spin_lock_irqsave(&xpd->lock, flags);
 	priv = xpd->priv;
 	BUG_ON(!priv);
-	len += sprintf(page + len, "%-12s", "Channel:");
+	seq_printf(sfile, "%-12s", "Channel:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d", i);
+		seq_printf(sfile, "%4d", i);
 	}
-	len += sprintf(page + len, "\n%-12s", "");
+	seq_printf(sfile, "\n%-12s", "");
 	for_each_line(xpd, i) {
 		char *chan_type;
 
@@ -1720,84 +1713,85 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
 			chan_type = "in";
 		else
 			chan_type = "";
-		len += sprintf(page + len, "%4s", chan_type);
+		seq_printf(sfile, "%4s", chan_type);
 	}
-	len += sprintf(page + len, "\n%-12s", "idletxhook:");
+	seq_printf(sfile, "\n%-12s", "idletxhook:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d", priv->idletxhookstate[i]);
+		seq_printf(sfile, "%4d", priv->idletxhookstate[i]);
 	}
-	len += sprintf(page + len, "\n%-12s", "lasttxhook:");
+	seq_printf(sfile, "\n%-12s", "lasttxhook:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d", priv->lasttxhook[i]);
+		seq_printf(sfile, "%4d", priv->lasttxhook[i]);
 	}
-	len += sprintf(page + len, "\n%-12s", "ohttimer:");
+	seq_printf(sfile, "\n%-12s", "ohttimer:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d", priv->ohttimer[i]);
+		seq_printf(sfile, "%4d", priv->ohttimer[i]);
 	}
-	len += sprintf(page + len, "\n%-12s", "neon_blink:");
+	seq_printf(sfile, "\n%-12s", "neon_blink:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d",
+		seq_printf(sfile, "%4d",
 			    IS_SET(priv->neon_blinking, i));
 	}
-	len += sprintf(page + len, "\n%-12s", "search_fsk:");
+	seq_printf(sfile, "\n%-12s", "search_fsk:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d",
+		seq_printf(sfile, "%4d",
 			    IS_SET(priv->search_fsk_pattern, i));
 	}
-	len += sprintf(page + len, "\n%-12s", "vbat_h:");
+	seq_printf(sfile, "\n%-12s", "vbat_h:");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%4d",
+		seq_printf(sfile, "%4d",
 			test_bit(i, (unsigned long *)&priv->vbat_h));
 	}
-	len += sprintf(page + len, "\n");
+	seq_printf(sfile, "\n");
 	for (led = 0; led < NUM_LEDS; led++) {
-		len += sprintf(page + len, "\nLED #%d\t%-12s: ",
+		seq_printf(sfile, "\nLED #%d\t%-12s: ",
 			led, "ledstate");
 		for_each_line(xpd, i) {
 			if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
 			    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-				len +=
-				    sprintf(page + len, "%d ",
+				seq_printf(sfile, "%d ",
 					    IS_SET(priv->ledstate[led], i));
 		}
-		len += sprintf(page + len, "\nLED #%d\t%-12s: ",
+		seq_printf(sfile, "\nLED #%d\t%-12s: ",
 			led, "ledcontrol");
 		for_each_line(xpd, i) {
 			if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
 			    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-				len +=
-				    sprintf(page + len, "%d ",
+				seq_printf(sfile, "%d ",
 					    IS_SET(priv->ledcontrol[led], i));
 		}
-		len += sprintf(page + len, "\nLED #%d\t%-12s: ",
+		seq_printf(sfile, "\nLED #%d\t%-12s: ",
 			led, "led_counter");
 		for_each_line(xpd, i) {
 			if (!IS_SET(PHONEDEV(xpd).digital_outputs, i)
 			    && !IS_SET(PHONEDEV(xpd).digital_inputs, i))
-				len +=
-				    sprintf(page + len, "%d ",
+				seq_printf(sfile, "%d ",
 					    LED_COUNTER(priv, i, led));
 		}
 	}
-	len += sprintf(page + len, "\n");
+	seq_printf(sfile, "\n");
 	spin_unlock_irqrestore(&xpd->lock, flags);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
 }
-#endif
+
+static int proc_fxs_info_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_fxs_info_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_fxs_info_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_fxs_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 #ifdef	WITH_METERING
-static int proc_xpd_metering_write(struct file *file, const char
-		__user *buffer, unsigned long count, void *data)
+static ssize_t proc_xpd_metering_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *offset)
 {
-	xpd_t *xpd = data;
+	xpd_t *xpd = file->private_data;
 	char buf[MAX_PROC_WRITE];
 	lineno_t chan;
 	int num;
@@ -1806,7 +1800,7 @@ static int proc_xpd_metering_write(struct file *file, const char
 	if (!xpd)
 		return -ENODEV;
 	if (count >= MAX_PROC_WRITE - 1) {
-		XPD_ERR(xpd, "Metering string too long (%lu)\n", count);
+		XPD_ERR(xpd, "Metering string too long (%zu)\n", count);
 		return -EINVAL;
 	}
 	if (copy_from_user(&buf, buffer, count))
@@ -1829,6 +1823,19 @@ static int proc_xpd_metering_write(struct file *file, const char
 	}
 	return count;
 }
+
+static int proc_xpd_metering_open(struct inode *inode, struct file *file)
+{
+	file->private_data = PDE_DATA(inode);
+}
+
+static const struct file_operations proc_xpd_metering_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_xpd_metering_open,
+	.write		= proc_xpd_metering_write,
+	.release	= single_release,
+};
+#endif
 #endif
 
 static int fxs_xpd_probe(struct device *dev)
diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index bab64e5..ed589be 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #ifdef	PROTOCOL_DEBUG
 #include <linux/ctype.h>
 #endif
@@ -47,8 +48,7 @@ static const char rcsid[] = "$Id$";
 #ifdef	PROTOCOL_DEBUG
 #ifdef	CONFIG_PROC_FS
 #define	PROC_XBUS_COMMAND	"command"
-static int proc_xbus_command_write(struct file *file,
-		const char __user *buffer, unsigned long count, void *data);
+static const struct file_operations proc_xbus_command_ops;
 #endif
 #endif
 
@@ -63,8 +63,7 @@ static DEF_PARM_BOOL(dahdi_autoreg, 0, 0644,
 		     "Register devices automatically (1) or not (0)");
 
 #ifdef	CONFIG_PROC_FS
-static int xbus_read_proc(char *page, char **start, off_t off, int count,
-			  int *eof, void *data);
+static const struct file_operations xbus_read_proc_ops;
 #endif
 static void transport_init(xbus_t *xbus, struct xbus_ops *ops,
 			   ushort max_send_size,
@@ -1532,29 +1531,26 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size,
 		err = -EIO;
 		goto nobus;
 	}
-	xbus->proc_xbus_summary =
-	    create_proc_read_entry(PROC_XBUS_SUMMARY, 0444, xbus->proc_xbus_dir,
-				   xbus_read_proc,
-				   (void *)((unsigned long)(xbus->num)));
+	xbus->proc_xbus_summary = proc_create_data(PROC_XBUS_SUMMARY, 0444,
+					xbus->proc_xbus_dir,
+					&xbus_read_proc_ops,
+					(void *)((unsigned long)xbus->num));
 	if (!xbus->proc_xbus_summary) {
 		XBUS_ERR(xbus, "Failed to create proc file '%s'\n",
 			 PROC_XBUS_SUMMARY);
 		err = -EIO;
 		goto nobus;
 	}
-	SET_PROC_DIRENTRY_OWNER(xbus->proc_xbus_summary);
 #ifdef	PROTOCOL_DEBUG
-	xbus->proc_xbus_command =
-	    create_proc_entry(PROC_XBUS_COMMAND, 0200, xbus->proc_xbus_dir);
+	xbus->proc_xbus_command = proc_create_data(PROC_XBUS_COMMAND, 0200,
+					xbus->proc_xbus_dir,
+					&proc_xbus_command_ops, xbus);
 	if (!xbus->proc_xbus_command) {
 		XBUS_ERR(xbus, "Failed to create proc file '%s'\n",
 			 PROC_XBUS_COMMAND);
 		err = -EIO;
 		goto nobus;
 	}
-	xbus->proc_xbus_command->write_proc = proc_xbus_command_write;
-	xbus->proc_xbus_command->data = xbus;
-	SET_PROC_DIRENTRY_OWNER(xbus->proc_xbus_command);
 #endif
 #endif
 	xframe_queue_init(&xbus->command_queue, 10, command_queue_length,
@@ -1668,106 +1664,96 @@ out:
 
 #ifdef CONFIG_PROC_FS
 
-static int xbus_fill_proc_queue(char *p, struct xframe_queue *q)
+static void xbus_fill_proc_queue(struct seq_file *sfile, struct xframe_queue *q)
 {
-	int len;
-
-	len = sprintf(p,
+	seq_printf(sfile,
 		"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d "
 		"worst_lag %02ld.%ld ms\n",
 		q->name, q->steady_state_count, q->count, q->max_count,
 		q->worst_count, q->overflows, q->worst_lag_usec / 1000,
 		q->worst_lag_usec % 1000);
 	xframe_queue_clearstats(q);
-	return len;
 }
 
-static int xbus_read_proc(char *page, char **start, off_t off, int count,
-			  int *eof, void *data)
+static int xbus_proc_show(struct seq_file *sfile, void *data)
 {
 	xbus_t *xbus;
 	unsigned long flags;
 	int len = 0;
-	int i = (int)((unsigned long)data);
+	int i = (int)((unsigned long)sfile->private);
 
-	xbus = get_xbus(__func__, i);	/* until end of xbus_read_proc */
+	xbus = get_xbus(__func__, i);	/* until end of xbus_proc_show() */
 	if (!xbus)
-		goto out;
+		return -EINVAL;
 	spin_lock_irqsave(&xbus->lock, flags);
 
-	len +=
-	    sprintf(page + len, "%s: CONNECTOR=%s LABEL=[%s] STATUS=%s\n",
+	seq_printf(sfile, "%s: CONNECTOR=%s LABEL=[%s] STATUS=%s\n",
 		    xbus->busname, xbus->connector, xbus->label,
 		    (XBUS_FLAGS(xbus, CONNECTED)) ? "connected" : "missing");
-	len += xbus_fill_proc_queue(page + len, &xbus->send_pool);
-	len += xbus_fill_proc_queue(page + len, &xbus->receive_pool);
-	len += xbus_fill_proc_queue(page + len, &xbus->command_queue);
-	len += xbus_fill_proc_queue(page + len, &xbus->receive_queue);
-	len += xbus_fill_proc_queue(page + len, &xbus->pcm_tospan);
+	xbus_fill_proc_queue(sfile, &xbus->send_pool);
+	xbus_fill_proc_queue(sfile, &xbus->receive_pool);
+	xbus_fill_proc_queue(sfile, &xbus->command_queue);
+	xbus_fill_proc_queue(sfile, &xbus->receive_queue);
+	xbus_fill_proc_queue(sfile, &xbus->pcm_tospan);
 	if (rx_tasklet) {
-		len += sprintf(page + len, "\ncpu_rcv_intr:    ");
+		seq_printf(sfile, "\ncpu_rcv_intr:    ");
 		for_each_online_cpu(i)
-		    len += sprintf(page + len, "%5d ", xbus->cpu_rcv_intr[i]);
-		len += sprintf(page + len, "\ncpu_rcv_tasklet: ");
+		    seq_printf(sfile, "%5d ", xbus->cpu_rcv_intr[i]);
+		seq_printf(sfile, "\ncpu_rcv_tasklet: ");
 		for_each_online_cpu(i)
-		    len +=
-		    sprintf(page + len, "%5d ", xbus->cpu_rcv_tasklet[i]);
-		len += sprintf(page + len, "\n");
+		    seq_printf(sfile, "%5d ", xbus->cpu_rcv_tasklet[i]);
+		seq_printf(sfile, "\n");
 	}
-	len +=
-	    sprintf(page + len, "self_ticking: %d (last_tick at %ld)\n",
+	seq_printf(sfile, "self_ticking: %d (last_tick at %ld)\n",
 		    xbus->self_ticking, xbus->ticker.last_sample.tv.tv_sec);
-	len +=
-	    sprintf(page + len, "command_tick: %d\n",
+	seq_printf(sfile, "command_tick: %d\n",
 		    xbus->command_tick_counter);
-	len += sprintf(page + len, "usec_nosend: %d\n", xbus->usec_nosend);
-	len +=
-	    sprintf(page + len, "xbus: pcm_rx_counter = %d, frag = %d\n",
+	seq_printf(sfile, "usec_nosend: %d\n", xbus->usec_nosend);
+	seq_printf(sfile, "xbus: pcm_rx_counter = %d, frag = %d\n",
 		    atomic_read(&xbus->pcm_rx_counter), xbus->xbus_frag_count);
-	len +=
-	    sprintf(page + len, "max_rx_process = %2ld.%ld ms\n",
+	seq_printf(sfile, "max_rx_process = %2ld.%ld ms\n",
 		    xbus->max_rx_process / 1000, xbus->max_rx_process % 1000);
 	xbus->max_rx_process = 0;
-	len +=
-	    sprintf(page + len, "\nTRANSPORT: max_send_size=%d refcount=%d\n",
+	seq_printf(sfile, "\nTRANSPORT: max_send_size=%d refcount=%d\n",
 		    MAX_SEND_SIZE(xbus),
 		    atomic_read(&xbus->transport.transport_refcount)
 	    );
-	len += sprintf(page + len, "PCM Metrices:\n");
-	len +=
-	    sprintf(page + len, "\tPCM TX: min=%ld  max=%ld\n",
+	seq_printf(sfile, "PCM Metrices:\n");
+	seq_printf(sfile, "\tPCM TX: min=%ld  max=%ld\n",
 		    xbus->min_tx_sync, xbus->max_tx_sync);
-	len +=
-	    sprintf(page + len, "\tPCM RX: min=%ld  max=%ld\n",
+	seq_printf(sfile, "\tPCM RX: min=%ld  max=%ld\n",
 		    xbus->min_rx_sync, xbus->max_rx_sync);
-	len += sprintf(page + len, "COUNTERS:\n");
+	seq_printf(sfile, "COUNTERS:\n");
 	for (i = 0; i < XBUS_COUNTER_MAX; i++) {
-		len +=
-		    sprintf(page + len, "\t%-15s = %d\n", xbus_counters[i].name,
+		seq_printf(sfile, "\t%-15s = %d\n", xbus_counters[i].name,
 			    xbus->counters[i]);
 	}
-	len += sprintf(page + len, "<-- len=%d\n", len);
+	seq_printf(sfile, "<-- len=%d\n", len);
 	spin_unlock_irqrestore(&xbus->lock, flags);
-	put_xbus(__func__, xbus);	/* from xbus_read_proc() */
-out:
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	put_xbus(__func__, xbus);	/* from xbus_proc_show() */
+	return 0;
+
+}
 
+static int xbus_read_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xbus_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations xbus_read_proc_ops = {
+	.owner		= THIS_MODULE,
+	.open		= xbus_read_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 #ifdef	PROTOCOL_DEBUG
-static int proc_xbus_command_write(struct file *file,
-		const char __user *buffer, unsigned long count, void *data)
+static ssize_t proc_xbus_command_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *offset)
 {
 	char *buf;
-	xbus_t *xbus = data;
+	xbus_t *xbus = file->private_data;
 	char *p;
 	__u8 *pack_start;
 	__u8 *q;
@@ -1777,7 +1763,7 @@ static int proc_xbus_command_write(struct file *file,
 	const size_t max_text = max_len * 3 + 10;
 
 	if (count > max_text) {
-		XBUS_ERR(xbus, "%s: line too long (%ld > %zd)\n", __func__,
+		XBUS_ERR(xbus, "%s: line too long (%zd > %zd)\n", __func__,
 			 count, max_len);
 		return -EFBIG;
 	}
@@ -1790,7 +1776,7 @@ static int proc_xbus_command_write(struct file *file,
 		goto out;
 	}
 	buf[count] = '\0';
-	XBUS_DBG(GENERAL, xbus, "count=%ld\n", count);
+	XBUS_DBG(GENERAL, xbus, "count=%zd\n", count);
 	/*
 	 * We replace the content of buf[] from
 	 * ascii representation to packet content
@@ -1846,20 +1832,29 @@ out:
 	kfree(buf);
 	return count;
 }
+
+static int proc_xbus_command_open(struct inode *inode, struct file *file)
+{
+	file->private_data = PDE_DATA(inode);
+	return 0;
+}
+
+static const struct file_operations proc_xbus_command_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_xbus_command_open,
+	.write		= proc_xbus_command_write,
+};
 #endif
 
-static int read_proc_xbuses(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int xpp_proc_read_show(struct seq_file *sfile, void *data)
 {
-	int len = 0;
 	int i;
 
 	for (i = 0; i < MAX_BUSES; i++) {
 		xbus_t *xbus = get_xbus(__func__, i);
 
 		if (xbus) {
-			len +=
-			    sprintf(page + len,
+			seq_printf(sfile,
 				    "%s: CONNECTOR=%s LABEL=[%s] STATUS=%s\n",
 				    xbus->busname, xbus->connector, xbus->label,
 				    (XBUS_FLAGS(xbus, CONNECTED)) ? "connected"
@@ -1868,19 +1863,24 @@ static int read_proc_xbuses(char *page, char **start, off_t off, int count,
 		}
 	}
 #if 0
-	len += sprintf(page + len, "<-- len=%d\n", len);
+	seq_printf(sfile, "<-- len=%d\n", len);
 #endif
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
+}
 
+static int xpp_proc_read_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xpp_proc_read_show, PDE_DATA(inode));
 }
+
+static const struct file_operations xpp_proc_read_ops = {
+	.owner		= THIS_MODULE,
+	.open		= xpp_proc_read_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 #endif
 
 static void transport_init(xbus_t *xbus, struct xbus_ops *ops,
@@ -1971,15 +1971,13 @@ int __init xbus_core_init(void)
 	INFO("FEATURE: with PROTOCOL_DEBUG\n");
 #endif
 #ifdef CONFIG_PROC_FS
-	proc_xbuses =
-	    create_proc_read_entry(PROC_XBUSES, 0444, xpp_proc_toplevel,
-				   read_proc_xbuses, NULL);
+	proc_xbuses = proc_create_data(PROC_XBUSES, 0444, xpp_proc_toplevel,
+				       &xpp_proc_read_ops, NULL);
 	if (!proc_xbuses) {
 		ERR("Failed to create proc file %s\n", PROC_XBUSES);
 		ret = -EFAULT;
 		goto err;
 	}
-	SET_PROC_DIRENTRY_OWNER(proc_xbuses);
 #endif
 	if ((ret = xpp_driver_init()) < 0)
 		goto err;
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index aca99b7..ffcd6dd 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -34,6 +34,7 @@
 #include <linux/delay.h>	/* for udelay */
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <dahdi/kernel.h>
 #include "xbus-core.h"
 #include "xproto.h"
@@ -102,8 +103,7 @@ int total_registered_spans(void)
 }
 
 #ifdef	CONFIG_PROC_FS
-static int xpd_read_proc(char *page, char **start, off_t off, int count,
-			 int *eof, void *data);
+static const struct file_operations xpd_read_proc_ops;
 #endif
 
 /*------------------------- XPD Management -------------------------*/
@@ -169,9 +169,9 @@ static int xpd_proc_create(xbus_t *xbus, xpd_t *xpd)
 		XPD_ERR(xpd, "Failed to create proc directory\n");
 		goto err;
 	}
-	xpd->proc_xpd_summary =
-	    create_proc_read_entry(PROC_XPD_SUMMARY, 0444, xpd->proc_xpd_dir,
-				   xpd_read_proc, xpd);
+	xpd->proc_xpd_summary = proc_create_data(PROC_XPD_SUMMARY, 0444,
+						 xpd->proc_xpd_dir,
+						 &xpd_read_proc_ops, xpd);
 	if (!xpd->proc_xpd_summary) {
 		XPD_ERR(xpd, "Failed to create proc file '%s'\n",
 			PROC_XPD_SUMMARY);
@@ -254,89 +254,72 @@ EXPORT_SYMBOL(create_xpd);
 
 /**
  * Prints a general procfs entry for the bus, under xpp/BUSNAME/summary
- * @page TODO: figure out procfs
- * @start TODO: figure out procfs
- * @off TODO: figure out procfs
- * @count TODO: figure out procfs
- * @eof TODO: figure out procfs
- * @data an xbus_t pointer with the bus data.
  */
-static int xpd_read_proc(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int xpd_read_proc_show(struct seq_file *sfile, void *data)
 {
 	int len = 0;
-	xpd_t *xpd = data;
+	xpd_t *xpd = sfile->private;
 	int i;
 
 	if (!xpd)
-		goto out;
+		return -EINVAL;
 
-	len +=
-	    sprintf(page + len,
+	seq_printf(sfile,
 		    "%s (%s, card %s, span %d)\n" "timing_priority: %d\n"
 		    "timer_count: %d span->mainttimer=%d\n", xpd->xpdname,
 		    xpd->type_name, (xpd->card_present) ? "present" : "missing",
 		    (SPAN_REGISTERED(xpd)) ? PHONEDEV(xpd).span.spanno : 0,
 		    PHONEDEV(xpd).timing_priority, xpd->timer_count,
 		    PHONEDEV(xpd).span.mainttimer);
-	len +=
-	    sprintf(page + len, "xpd_state: %s (%d)\n",
+	seq_printf(sfile, "xpd_state: %s (%d)\n",
 		    xpd_statename(xpd->xpd_state), xpd->xpd_state);
-	len +=
-	    sprintf(page + len, "open_counter=%d refcount=%d\n",
+	seq_printf(sfile, "open_counter=%d refcount=%d\n",
 		    atomic_read(&PHONEDEV(xpd).open_counter),
 		    refcount_xpd(xpd));
-	len +=
-	    sprintf(page + len, "Address: U=%d S=%d\n", xpd->addr.unit,
+	seq_printf(sfile, "Address: U=%d S=%d\n", xpd->addr.unit,
 		    xpd->addr.subunit);
-	len += sprintf(page + len, "Subunits: %d\n", xpd->subunits);
-	len += sprintf(page + len, "Type: %d.%d\n\n", xpd->type, xpd->subtype);
-	len += sprintf(page + len, "pcm_len=%d\n\n", PHONEDEV(xpd).pcm_len);
-	len +=
-	    sprintf(page + len, "wanted_pcm_mask=0x%04X\n\n",
+	seq_printf(sfile, "Subunits: %d\n", xpd->subunits);
+	seq_printf(sfile, "Type: %d.%d\n\n", xpd->type, xpd->subtype);
+	seq_printf(sfile, "pcm_len=%d\n\n", PHONEDEV(xpd).pcm_len);
+	seq_printf(sfile, "wanted_pcm_mask=0x%04X\n\n",
 		    PHONEDEV(xpd).wanted_pcm_mask);
-	len +=
-	    sprintf(page + len, "mute_dtmf=0x%04X\n\n",
+	seq_printf(sfile, "mute_dtmf=0x%04X\n\n",
 		    PHONEDEV(xpd).mute_dtmf);
-	len += sprintf(page + len, "STATES:");
-	len += sprintf(page + len, "\n\t%-17s: ", "output_relays");
+	seq_printf(sfile, "STATES:");
+	seq_printf(sfile, "\n\t%-17s: ", "output_relays");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%d ",
+		seq_printf(sfile, "%d ",
 			    IS_SET(PHONEDEV(xpd).digital_outputs, i));
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "input_relays");
+	seq_printf(sfile, "\n\t%-17s: ", "input_relays");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%d ",
+		seq_printf(sfile, "%d ",
 			    IS_SET(PHONEDEV(xpd).digital_inputs, i));
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "offhook");
+	seq_printf(sfile, "\n\t%-17s: ", "offhook");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%d ", IS_OFFHOOK(xpd, i));
+		seq_printf(sfile, "%d ", IS_OFFHOOK(xpd, i));
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "oht_pcm_pass");
+	seq_printf(sfile, "\n\t%-17s: ", "oht_pcm_pass");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%d ",
+		seq_printf(sfile, "%d ",
 			    IS_SET(PHONEDEV(xpd).oht_pcm_pass, i));
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "msg_waiting");
+	seq_printf(sfile, "\n\t%-17s: ", "msg_waiting");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%d ", PHONEDEV(xpd).msg_waiting[i]);
+		seq_printf(sfile, "%d ", PHONEDEV(xpd).msg_waiting[i]);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "ringing");
+	seq_printf(sfile, "\n\t%-17s: ", "ringing");
 	for_each_line(xpd, i) {
-		len += sprintf(page + len, "%d ", PHONEDEV(xpd).ringing[i]);
+		seq_printf(sfile, "%d ", PHONEDEV(xpd).ringing[i]);
 	}
-	len += sprintf(page + len, "\n\t%-17s: ", "no_pcm");
+	seq_printf(sfile, "\n\t%-17s: ", "no_pcm");
 	for_each_line(xpd, i) {
-		len +=
-		    sprintf(page + len, "%d ", IS_SET(PHONEDEV(xpd).no_pcm, i));
+		seq_printf(sfile, "%d ", IS_SET(PHONEDEV(xpd).no_pcm, i));
 	}
 #if 1
 	if (SPAN_REGISTERED(xpd)) {
-		len += sprintf(page + len,
+		seq_printf(sfile,
 			"\nPCM:\n            |"
 			"         [readchunk]       |"
 			"         [writechunk]      | W D");
@@ -358,16 +341,16 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count,
 			wp = chan->writechunk;
 			memcpy(rchunk, rp, DAHDI_CHUNKSIZE);
 			memcpy(wchunk, wp, DAHDI_CHUNKSIZE);
-			len += sprintf(page + len, "\n  port %2d>  |  ", i);
+			seq_printf(sfile, "\n  port %2d>  |  ", i);
 			for (j = 0; j < DAHDI_CHUNKSIZE; j++)
-				len += sprintf(page + len, "%02X ", rchunk[j]);
-			len += sprintf(page + len, " |  ");
+				seq_printf(sfile, "%02X ", rchunk[j]);
+			seq_printf(sfile, " |  ");
 			for (j = 0; j < DAHDI_CHUNKSIZE; j++)
-				len += sprintf(page + len, "%02X ", wchunk[j]);
-			len += sprintf(page + len, " | %c",
+				seq_printf(sfile, "%02X ", wchunk[j]);
+			seq_printf(sfile, " | %c",
 				(IS_SET(PHONEDEV(xpd).wanted_pcm_mask, i))
 					?  '+' : ' ');
-			len += sprintf(page + len, " %c",
+			seq_printf(sfile, " %c",
 				(IS_SET(PHONEDEV(xpd).mute_dtmf, i))
 					? '-' : ' ');
 		}
@@ -375,36 +358,37 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count,
 #endif
 #if 0
 	if (SPAN_REGISTERED(xpd)) {
-		len += sprintf(page + len, "\nSignalling:\n");
+		seq_printf(sfile, "\nSignalling:\n");
 		for_each_line(xpd, i) {
 			struct dahdi_chan *chan = XPD_CHAN(xpd, i);
-			len +=
-			    sprintf(page + len,
+			seq_printf(sfile,
 				    "\t%2d> sigcap=0x%04X sig=0x%04X\n", i,
 				    chan->sigcap, chan->sig);
 		}
 	}
 #endif
-	len += sprintf(page + len, "\nCOUNTERS:\n");
+	seq_printf(sfile, "\nCOUNTERS:\n");
 	for (i = 0; i < XPD_COUNTER_MAX; i++) {
-		len +=
-		    sprintf(page + len, "\t\t%-20s = %d\n",
+		seq_printf(sfile, "\t\t%-20s = %d\n",
 			    xpd_counters[i].name, xpd->counters[i]);
 	}
-	len += sprintf(page + len, "<-- len=%d\n", len);
-out:
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	seq_printf(sfile, "<-- len=%d\n", len);
+	return 0;
+}
 
+static int xpd_read_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xpd_read_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations xpd_read_proc_ops = {
+	.owner		= THIS_MODULE,
+	.open		= xpd_read_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 #endif
 
 const char *xpd_statename(enum xpd_state st)
diff --git a/drivers/dahdi/xpp/xpp_usb.c b/drivers/dahdi/xpp/xpp_usb.c
index 8a55963..8ad2b9c 100644
--- a/drivers/dahdi/xpp/xpp_usb.c
+++ b/drivers/dahdi/xpp/xpp_usb.c
@@ -231,8 +231,7 @@ static int xusb_probe(struct usb_interface *interface,
 		      const struct usb_device_id *id);
 static void xusb_disconnect(struct usb_interface *interface);
 #ifdef	CONFIG_PROC_FS
-static int xusb_read_proc(char *page, char **start, off_t off, int count,
-			  int *eof, void *data);
+static const struct file_operations xusb_read_proc_ops;
 #endif
 
 /*------------------------------------------------------------------*/
@@ -743,9 +742,9 @@ static int xusb_probe(struct usb_interface *interface,
 #ifdef CONFIG_PROC_FS
 	DBG(PROC,
 	    "Creating proc entry " PROC_USBXPP_SUMMARY " in bus proc dir.\n");
-	procsummary =
-	    create_proc_read_entry(PROC_USBXPP_SUMMARY, 0444,
-				   xbus->proc_xbus_dir, xusb_read_proc, xusb);
+	procsummary = proc_create_data(PROC_USBXPP_SUMMARY, 0444,
+				   xbus->proc_xbus_dir, &xusb_read_proc_ops,
+				   xusb);
 	if (!procsummary) {
 		XBUS_ERR(xbus, "Failed to create proc file '%s'\n",
 			 PROC_USBXPP_SUMMARY);
@@ -753,7 +752,6 @@ static int xusb_probe(struct usb_interface *interface,
 		retval = -EIO;
 		goto probe_failed;
 	}
-	SET_PROC_DIRENTRY_OWNER(procsummary);
 #endif
 	bus_count++;
 	xusb->xbus_num = xbus->num;
@@ -1020,90 +1018,83 @@ static void __exit xpp_usb_shutdown(void)
 
 #ifdef CONFIG_PROC_FS
 
-static int xusb_read_proc(char *page, char **start, off_t off, int count,
-			  int *eof, void *data)
+static int xusb_read_proc_show(struct seq_file *sfile, void *data)
 {
-	int len = 0;
 	unsigned long flags;
 	int i;
 	//unsigned long stamp = jiffies;
-	xusb_t *xusb = data;
+	xusb_t *xusb = sfile->private;
 	uint usb_tx_delay[NUM_BUCKETS];
 	const int mark_limit = tx_sluggish / USEC_BUCKET;
 
 	if (!xusb)
-		goto out;
+		return 0;
+
 	// TODO: probably needs a per-xusb lock:
 	spin_lock_irqsave(&xusb_lock, flags);
-	len +=
-	    sprintf(page + len, "Device: %03d/%03d\n", xusb->udev->bus->busnum,
+	seq_printf(sfile, "Device: %03d/%03d\n", xusb->udev->bus->busnum,
 		    xusb->udev->devnum);
-	len +=
-	    sprintf(page + len, "USB: manufacturer=%s\n", xusb->manufacturer);
-	len += sprintf(page + len, "USB: product=%s\n", xusb->product);
-	len += sprintf(page + len, "USB: serial=%s\n", xusb->serial);
-	len +=
-	    sprintf(page + len, "Minor: %d\nModel Info: %s\n", xusb->minor,
+	seq_printf(sfile, "USB: manufacturer=%s\n", xusb->manufacturer);
+	seq_printf(sfile, "USB: product=%s\n", xusb->product);
+	seq_printf(sfile, "USB: serial=%s\n", xusb->serial);
+	seq_printf(sfile, "Minor: %d\nModel Info: %s\n", xusb->minor,
 		    xusb->model_info->desc);
-	len +=
-	    sprintf(page + len,
+	seq_printf(sfile,
 		    "Endpoints:\n" "\tIn:  0x%02X  - Size: %d)\n"
 		    "\tOut: 0x%02X  - Size: %d)\n",
 		    xusb->endpoints[XUSB_RECV].ep_addr,
 		    xusb->endpoints[XUSB_RECV].max_size,
 		    xusb->endpoints[XUSB_SEND].ep_addr,
 		    xusb->endpoints[XUSB_SEND].max_size);
-	len +=
-	    sprintf(page + len, "\npending_writes=%d\n",
+	seq_printf(sfile, "\npending_writes=%d\n",
 		    atomic_read(&xusb->pending_writes));
-	len +=
-	    sprintf(page + len, "pending_reads=%d\n",
+	seq_printf(sfile, "pending_reads=%d\n",
 		    atomic_read(&xusb->pending_reads));
-	len += sprintf(page + len, "max_tx_delay=%d\n", xusb->max_tx_delay);
+	seq_printf(sfile, "max_tx_delay=%d\n", xusb->max_tx_delay);
 	xusb->max_tx_delay = 0;
 #ifdef	DEBUG_PCM_TIMING
-	len +=
-	    sprintf(page + len,
+	seq_printf(sfile,
 		    "\nstamp_last_pcm_read=%lld accumulate_diff=%lld\n",
 		    stamp_last_pcm_read, accumulate_diff);
 #endif
 	memcpy(usb_tx_delay, xusb->usb_tx_delay, sizeof(usb_tx_delay));
-	len +=
-	    sprintf(page + len, "usb_tx_delay[%d,%d,%d]: ", USEC_BUCKET,
+	seq_printf(sfile, "usb_tx_delay[%d,%d,%d]: ", USEC_BUCKET,
 		    BUCKET_START, NUM_BUCKETS);
 	for (i = BUCKET_START; i < NUM_BUCKETS; i++) {
-		len += sprintf(page + len, "%6d ", usb_tx_delay[i]);
+		seq_printf(sfile, "%6d ", usb_tx_delay[i]);
 		if (i == mark_limit)
-			len += sprintf(page + len, "| ");
+			seq_printf(sfile, "| ");
 	}
-	len +=
-	    sprintf(page + len, "\nPCM_TX_DROPS: %5d (sluggish: %d)\n",
+	seq_printf(sfile, "\nPCM_TX_DROPS: %5d (sluggish: %d)\n",
 		    atomic_read(&xusb->pcm_tx_drops),
 		    atomic_read(&xusb->usb_sluggish_count)
 	    );
-	len += sprintf(page + len, "\nCOUNTERS:\n");
+	seq_printf(sfile, "\nCOUNTERS:\n");
 	for (i = 0; i < XUSB_COUNTER_MAX; i++) {
-		len +=
-		    sprintf(page + len, "\t%-15s = %d\n", xusb_counters[i].name,
+		seq_printf(sfile, "\t%-15s = %d\n", xusb_counters[i].name,
 			    xusb->counters[i]);
 	}
 #if 0
-	len += sprintf(page + len, "<-- len=%d\n", len);
+	seq_printf(sfile, "<-- len=%d\n", len);
 #endif
 	spin_unlock_irqrestore(&xusb_lock, flags);
-out:
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
+}
 
+static int xusb_read_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xusb_read_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations xusb_read_proc_ops = {
+	.owner		= THIS_MODULE,
+	.open		= xusb_read_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
 #endif
 
 MODULE_DESCRIPTION("XPP USB Transport Driver");

commit ba2fdf2dac7c6136e30eff52f686095e644d56ac
Author: Shaun Ruffell <sruffell at digium.com>
Date:   Tue May 21 15:33:17 2013 -0500

    dahdi_dynamic_ethmf: Don't use create_proc_read_entry()
    
    Don't use create_proc_read_entry() as that is deprecated, but rather use
    proc_create_data() and seq_file instead.
    
    This is needed to compile against Linux 3.10.
    
    Signed-off-by: Shaun Ruffell <sruffell at digium.com>
    Acked-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
    Cc: Russ Meyerriecks <rmeyerriecks at digium.com>
    Cc: Oron Peled <oron.peled at xorcom.com>

diff --git a/drivers/dahdi/dahdi_dynamic_ethmf.c b/drivers/dahdi/dahdi_dynamic_ethmf.c
index dd1214d..dec368b 100644
--- a/drivers/dahdi/dahdi_dynamic_ethmf.c
+++ b/drivers/dahdi/dahdi_dynamic_ethmf.c
@@ -36,6 +36,7 @@
 #include <linux/netdevice.h>
 #include <linux/notifier.h>
 #include <linux/crc32.h>
+#include <linux/seq_file.h>
 
 /**
  * Undefine USE_PROC_FS, if you do not want the /proc/dahdi/dynamic-ethmf
@@ -696,71 +697,69 @@ static void timer_callback(unsigned long param)
 #ifdef USE_PROC_FS
 static struct proc_dir_entry *proc_entry;
 static const char *ztdethmf_procname = "dahdi/dynamic-ethmf";
-static int ztdethmf_proc_read(char *page, char **start, off_t off, int count,
-		int *eof, void *data)
+
+static int ztdethmf_proc_show(struct seq_file *sfile, void *not_used)
 {
 	struct ztdeth *z = NULL;
-	int len = 0, i = 0;
+	int i = 0;
 	unsigned int group = 0, c = 0;
 
 	rcu_read_lock();
 
-	len += sprintf(page + len, "Errors: %d\n\n", atomic_read(&errcount));
+	seq_printf(sfile, "Errors: %d\n\n", atomic_read(&errcount));
 
 	for (group = 0; group < ETHMF_MAX_GROUPS; ++group) {
 		if (atomic_read(&(ethmf_groups[group].spans))) {
-			len += sprintf(page + len, "Group #%d (0x%x)\n", i++, ethmf_groups[group].hash_addr);
-			len += sprintf(page + len, "  Spans: %d\n",
-				atomic_read(&(ethmf_groups[group].spans)));
+			seq_printf(sfile, "Group #%d (0x%x)\n", i++,
+				   ethmf_groups[group].hash_addr);
+			seq_printf(sfile, "Spans: %d\n",
+				   atomic_read(&(ethmf_groups[group].spans)));
 
 			c = 1;
 			list_for_each_entry_rcu(z, &ethmf_list, list) {
 				if (z->addr_hash == ethmf_groups[group].hash_addr) {
 					if (c == 1) {
-						len += sprintf(page + len,
+						seq_printf(sfile,
 							"  Device: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x)\n",
 							z->ethdev,
 							z->addr[0], z->addr[1], z->addr[2],
 							z->addr[3], z->addr[4], z->addr[5]);
 					}
-					len += sprintf(page + len, "    Span %d: subaddr=%u ready=%d delay=%d real_channels=%d no_front_padding=%d\n",
+					seq_printf(sfile, "    Span %d: subaddr=%u ready=%d delay=%d real_channels=%d no_front_padding=%d\n",
 						c++, ntohs(z->subaddr),
 						atomic_read(&z->ready), atomic_read(&z->delay),
 						z->real_channels, atomic_read(&z->no_front_padding));
 				}
 			}
-			len += sprintf(page + len, "  Device UPs: %u\n",
+			seq_printf(sfile, "  Device UPs: %u\n",
 				atomic_read(&(ethmf_groups[group].devupcount)));
-			len += sprintf(page + len, "  Device DOWNs: %u\n",
+			seq_printf(sfile, "  Device DOWNs: %u\n",
 				atomic_read(&(ethmf_groups[group].devdowncount)));
-			len += sprintf(page + len, "  Rx Frames: %u\n",
+			seq_printf(sfile, "  Rx Frames: %u\n",
 				atomic_read(&(ethmf_groups[group].rxframecount)));
-			len += sprintf(page + len, "  Tx Frames: %u\n",
+			seq_printf(sfile, "  Tx Frames: %u\n",
 				atomic_read(&(ethmf_groups[group].txframecount)));
-			len += sprintf(page + len, "  Rx Bytes: %u\n",
+			seq_printf(sfile, "  Rx Bytes: %u\n",
 				atomic_read(&(ethmf_groups[group].rxbytecount)));
-			len += sprintf(page + len, "  Tx Bytes: %u\n",
+			seq_printf(sfile, "  Tx Bytes: %u\n",
 				atomic_read(&(ethmf_groups[group].txbytecount)));
-			if (len <= off) {
-				off -= len;
-				len = 0;
-			}
-			if (len > off+count)
-				break;
 		}
 	}
 	rcu_read_unlock();
+	return 0;
+}
 
-	if (len <= off) {
-		off -= len;
-		len = 0;
-	}
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	return len;
+static int ztdethmf_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ztdethmf_proc_show, NULL);
 }
+
+static const struct file_operations ztdethmf_proc_fops = {
+	.open           = ztdethmf_proc_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = seq_release,
+};
 #endif
 
 static int __init ztdethmf_init(void)
@@ -778,8 +777,8 @@ static int __init ztdethmf_init(void)
 	skb_queue_head_init(&skbs);
 
 #ifdef USE_PROC_FS
-	proc_entry = create_proc_read_entry(ztdethmf_procname, 0444, NULL,
-		ztdethmf_proc_read, NULL);
+	proc_entry = proc_create_data(ztdethmf_procname, 0444, NULL,
+				      &ztdethmf_proc_fops, NULL);
 	if (!proc_entry) {
 		printk(KERN_ALERT "create_proc_read_entry failed.\n");
 	}

commit 84ccc652b6cb3f57e6cff6ceab201a553bfe9561
Author: Shaun Ruffell <sruffell at digium.com>
Date:   Tue May 21 15:33:16 2013 -0500

    dahdi: Replace create_proc_entry() with proc_create_data()
    
    create_proc_entry() was deprecated and replace with proc_create_data() since
    it's open to a race condition where the proc entry is visible before the file
    operations have been set for it.
    
    The PDE() macro also is no longer available as of Linux 3.10 and is replaced
    with PDE_DATA() to get the data member from a proc entry. This is due to the
    fact that 'struct proc_dir_entry' is now private to the proc_fs.
    
    This commit changes the core of DAHDI and also introduces proc_create_data() and
    PDE_DATA() for older kernels.
    
    Signed-off-by: Shaun Ruffell <sruffell at digium.com>
    Acked-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
    Cc: Russ Meyerriecks <rmeyerriecks at digium.com>
    Cc: Oron Peled <oron.peled at xorcom.com>

diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 72aa5e3..f9cc628 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -900,7 +900,7 @@ static void seq_fill_alarm_string(struct seq_file *sfile, int alarms)
 		seq_printf(sfile, "%s", tmp);
 }
 
-static int dahdi_seq_show(struct seq_file *sfile, void *v)
+static int dahdi_seq_show(struct seq_file *sfile, void *data)
 {
 	long spanno = (long)sfile->private;
 	int x;
@@ -992,7 +992,7 @@ static int dahdi_seq_show(struct seq_file *sfile, void *v)
 
 static int dahdi_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, dahdi_seq_show, PDE(inode)->data);
+	return single_open(file, dahdi_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations dahdi_proc_ops = {
@@ -7260,15 +7260,14 @@ static int _dahdi_assign_span(struct dahdi_span *span, unsigned int spanno,
 	{
 		char tempfile[17];
 		snprintf(tempfile, sizeof(tempfile), "%d", span->spanno);
-		span->proc_entry = create_proc_entry(tempfile, 0444,
-					root_proc_entry);
+		span->proc_entry = proc_create_data(tempfile, 0444,
+					root_proc_entry, &dahdi_proc_ops,
+					(void *)((unsigned long)span->spanno));
 		if (!span->proc_entry) {
 			res = -EFAULT;
 			span_err(span, "Error creating procfs entry\n");
 			goto cleanup;
 		}
-		span->proc_entry->data = (void *)(long)span->spanno;
-		span->proc_entry->proc_fops = &dahdi_proc_ops;
 	}
 #endif
 
@@ -7416,6 +7415,15 @@ static void disable_span(struct dahdi_span *span)
 	module_printk(KERN_INFO, "%s: span %d\n", __func__, span->spanno);
 }
 
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+static inline void proc_remove(struct proc_dir_entry *proc_entry)
+{
+	remove_proc_entry(proc_entry->name, root_proc_entry);
+}
+#endif
+#endif
+
 /**
  * _dahdi_unassign_span() - unassign a DAHDI span
  * @span:	the DAHDI span
@@ -7454,8 +7462,10 @@ static int _dahdi_unassign_span(struct dahdi_span *span)
 	if (debug & DEBUG_MAIN)
 		module_printk(KERN_NOTICE, "Unassigning Span '%s' with %d channels\n", span->name, span->channels);
 #ifdef CONFIG_PROC_FS
-	if (span->proc_entry)
-		remove_proc_entry(span->proc_entry->name, root_proc_entry);
+	if (span->proc_entry) {
+		proc_remove(span->proc_entry);
+		span->proc_entry = NULL;
+	}
 #endif /* CONFIG_PROC_FS */
 
 	span_sysfs_remove(span);
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index fca8ec1..8f3dc76 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -1401,9 +1401,33 @@ static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss)
 /*! Maximum audio mask */
 #define DAHDI_FORMAT_AUDIO_MASK	((1 << 16) - 1)
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+static inline void *PDE_DATA(const struct inode *inode)
+{
+	return PDE(inode)->data;
+}
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
 #define KERN_CONT ""
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+static inline struct proc_dir_entry *proc_create_data(const char *name,
+					mode_t mode,
+					struct proc_dir_entry *parent,
+					const struct file_operations *proc_fops,
+					void *data)
+{
+	struct proc_dir_entry *pde = create_proc_entry(name, mode, parent);
+	if (!pde)
+		return NULL;
+	pde->proc_fops = proc_fops;
+	pde->data = data;
+	return pde;
+}
+#endif /* CONFIG_PROC_FS */
 #ifndef clamp
 #define clamp(x, low, high) min(max(low, x), high)
 #endif
@@ -1456,6 +1480,7 @@ static inline int strcasecmp(const char *s1, const char *s2)
 #endif /* 2.6.25 */
 #endif /* 2.6.26 */
 #endif /* 2.6.31 */
+#endif /* 3.10.0 */
 
 #ifndef DEFINE_SPINLOCK
 #define DEFINE_SPINLOCK(x)      spinlock_t x = SPIN_LOCK_UNLOCKED

-----------------------------------------------------------------------


-- 
dahdi/linux.git



More information about the dahdi-commits mailing list