A
download xbus-sysfs.c
Language: C
License: GPL
Copyright: (C) 2004-2006, Xorcom
LOC: 197
Project Info
zaptel
Server: Digium
Type: svn
Digium\z\zaptel\trunk\xpp\
   .version
   card_bri.c
   card_bri.h
   card_fxo.c
   card_fxo.h
   card_fxs.c
   card_fxs.h
   card_global.c
   card_global.h
   parport_debug.c
   parport_debug.h
   README.Astribank
   README.metering
   xbus-core.c
   xbus-core.h
   xbus-sysfs.c
   xdefs.h
   xpd.h
   xpp_log.h
   xpp_usb.c
   xpp_zap.c
   xpp_zap.h
   xproto.c
   xproto.h
   zap_debug.c
   zap_debug.h

/*
 * Written by Oron Peled <oron@actcom.co.il>
 * Copyright (C) 2004-2006, Xorcom
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#include <linux/version.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#  warning "This module is tested only with 2.6 kernels"
#endif

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#ifdef	PROTOCOL_DEBUG
#include <linux/ctype.h>
#endif
#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/delay.h>	/* for msleep() to debug */
#include "xpd.h"
#include "xpp_zap.h"
#include "xbus-core.h"
#ifdef	XPP_DEBUGFS
#include "xpp_log.h"
#endif
#include "zap_debug.h"

static const char rcsid[] = "$Id: xbus-sysfs.c 2867 2007-08-16 21:45:13Z tzafrir $";

/* Command line parameters */
extern int print_dbg;


/* Kernel versions... */
/*
 * Hotplug replaced with uevent in 2.6.16
 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
#define	OLD_HOPLUG_SUPPORT	// for older kernels
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
#define	DEVICE_ATTR_FUNC(name,dev,buf)	\
		ssize_t name(struct device *dev, struct device_attribute *attr, char *buf)
#else
#define	DEVICE_ATTR_FUNC(name,dev,buf)	\
		ssize_t name(struct device *dev, char *buf)
#endif

/*--------- Sysfs Bus handling ----*/
static int xpp_bus_match(struct device *dev, struct device_driver *driver)
{
	DBG(GENERAL, "dev->bus_id = %s, driver->name = %s\n", dev->bus_id, driver->name);
	return 1;
}

#ifdef OLD_HOPLUG_SUPPORT
static int xpp_bus_hotplug(struct device *dev, char **envp, int envnum, char *buff, int bufsize)
{
	xbus_t	*xbus;

	if(!dev)
		return -ENODEV;
	xbus = dev_to_xbus(dev);
	envp[0] = buff;
	if(snprintf(buff, bufsize, "XBUS_NAME=%s", xbus->busname) >= bufsize)
		return -ENOMEM;
	envp[1] = NULL;
	return 0;
}
#else

#define XBUS_ADD_UEVENT_VAR(fmt, val...)			\
	do {							\
		int err = add_uevent_var(envp, num_envp, &i,	\
				buffer, buffer_size, &len,	\
				fmt, val);			\
		if (err)					\
		return err;					\
	} while (0)

static int xpp_bus_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
	xbus_t	*xbus;
	int	i = 0;
	int	len = 0;

	if(!dev)
		return -ENODEV;
	xbus = dev_to_xbus(dev);
	DBG(GENERAL, "bus_id=%s xbus=%s\n", dev->bus_id, xbus->busname);
	XBUS_ADD_UEVENT_VAR("XBUS_NUM=%02d", xbus->num);
	XBUS_ADD_UEVENT_VAR("XBUS_NAME=%s", xbus->busname);
	envp[i] = NULL;
	return 0;
}
#endif

static void xpp_bus_release(struct device *dev)
{
	DBG(GENERAL, "\n");
}

static void xpp_dev_release(struct device *dev)
{
	xbus_t	*xbus;

	BUG_ON(!dev);
	xbus = dev_to_xbus(dev);
	XBUS_DBG(GENERAL, xbus, "\n");
}

static struct bus_type xpp_bus_type = {
	.name           = "astribanks",
	.match          = xpp_bus_match,
#ifdef OLD_HOPLUG_SUPPORT
	.hotplug 	= xpp_bus_hotplug,
#else
	.uevent         = xpp_bus_uevent,
#endif
};

static struct device xpp_bus = {
	.bus_id		= "xppbus",
	.release	= xpp_bus_release
};

static struct device_driver xpp_driver = {
	.name		= "xppdrv",
	.bus		= &xpp_bus_type,
#ifndef OLD_HOPLUG_SUPPORT
	.owner		= THIS_MODULE
#endif
};

int register_xpp_bus(void)
{
	int	ret;

	if((ret = bus_register(&xpp_bus_type)) < 0) {
		ERR("%s: bus_register failed. Error number %d", __FUNCTION__, ret);
		goto failed_bus;
	}
	if((ret = device_register(&xpp_bus)) < 0) {
		ERR("%s: registration of xpp_bus failed. Error number %d",
			__FUNCTION__, ret);
		goto failed_busdevice;
	}
	if((ret = driver_register(&xpp_driver)) < 0) {
		ERR("%s: driver_register failed. Error number %d", __FUNCTION__, ret);
		goto failed_driver;
	}
	return 0;
failed_driver:
	device_unregister(&xpp_bus);
failed_busdevice:
	bus_unregister(&xpp_bus_type);
failed_bus:
	return ret;
}

void unregister_xpp_bus(void)
{
	driver_unregister(&xpp_driver);
	device_unregister(&xpp_bus);
	bus_unregister(&xpp_bus_type);
}

/*--------- Sysfs Device handling ----*/
static DEVICE_ATTR_FUNC(connector_show, dev, buf)
{
	xbus_t	*xbus;
	int	ret;

	xbus = dev_to_xbus(dev);
	ret = snprintf(buf, PAGE_SIZE, "%s\n", xbus->busdesc);
	return ret;
}

static DEVICE_ATTR_FUNC(status_show, dev, buf)
{
	xbus_t	*xbus;
	int	ret;

	xbus = dev_to_xbus(dev);
	ret = snprintf(buf, PAGE_SIZE, "%s\n", (xbus->hardware_exists)?"connected":"missing");
	return ret;
}

static	DEVICE_ATTR(connector, S_IRUGO, connector_show, NULL);
static	DEVICE_ATTR(status, S_IRUGO, status_show, NULL);

void xbus_sysfs_remove(xbus_t *xbus)
{
	struct device	*astribank;

	BUG_ON(!xbus);
	XBUS_DBG(GENERAL, xbus, "\n");
	astribank = &xbus->astribank;
	BUG_ON(!astribank);
	device_remove_file(&xbus->astribank, &dev_attr_status);
	device_remove_file(&xbus->astribank, &dev_attr_connector);
	device_unregister(&xbus->astribank);
}

int xbus_sysfs_create(xbus_t *xbus)
{
	struct device	*astribank;
	int		ret = 0;

	BUG_ON(!xbus);
	astribank = &xbus->astribank;
	BUG_ON(!astribank);
	XBUS_DBG(GENERAL, xbus, "\n");
	device_initialize(astribank);
	astribank->bus = &xpp_bus_type;
	astribank->parent = &xpp_bus;
	snprintf(astribank->bus_id, BUS_ID_SIZE, "xbus-%02d", xbus->num);
	astribank->driver_data = NULL;	/* FIXME: add some usefull data */
	astribank->release = xpp_dev_release;
	ret = device_register(astribank);
	if(ret) {
		XBUS_ERR(xbus, "%s: device_add failed: %d\n", __FUNCTION__, ret);
		goto out;
	}
	ret = device_create_file(astribank, &dev_attr_connector);
	if(ret) {
		XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
		goto out;
	}
	ret = device_create_file(astribank, &dev_attr_status);
	if(ret) {
		XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
		goto out;
	}
out:
	return ret;
}

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us