⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l3-core_c.txt

📁 2410uda1341的测试代码
💻 TXT
字号:
/*
 *  linux/drivers/l3/l3-core.c
 *
 *  Copyright (C) 2001 Russell King
 *
 *  General structure taken from i2c-core.c by Simon G. Vogl
 *
 * 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.
 *
 *  See linux/Documentation/l3 for further documentation.
 */
//#define DEBUG 1
#include "debug.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/kmod.h>
#include <linux/init.h>

#include "l3.h"

#ifdef DEBUG
#undef pr_debug
#define pr_debug(fmt,arg...) printk(fmt,##arg)
#endif

static DECLARE_MUTEX(adapter_lock);
static LIST_HEAD(adapter_list);

static DECLARE_MUTEX(driver_lock);
static LIST_HEAD(driver_list);

/**
 * l3_add_adapter - register a new L3 bus adapter
 * @adap: l3_adapter structure for the registering adapter
 *
 * Make the adapter available for use by clients using name adap->name.
 * The adap->adapters list is initialised by this function.
 *
 * Returns 0;
 */
int l3_add_adapter(struct l3_adapter *adap)
{
	pr_debug("--- %s\n", __FUNCTION__);
	down(&adapter_lock);
	list_add(&adap->adapters, &adapter_list);
	up(&adapter_lock);
	return 0;	
}

/**
 * l3_del_adapter - unregister a L3 bus adapter
 * @adap: l3_adapter structure to unregister
 *
 * Remove an adapter from the list of available L3 Bus adapters.
 *
 * Returns 0;
 */
int l3_del_adapter(struct l3_adapter *adap)
{
	pr_debug("--- %s\n", __FUNCTION__);
	down(&adapter_lock);
	list_del(&adap->adapters);
	up(&adapter_lock);
	return 0;
}

static struct l3_adapter *__l3_get_adapter(const char *name)
{
	struct list_head *l;

	pr_debug("--- %s\n", __FUNCTION__);
	list_for_each(l, &adapter_list) {
		struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);

		if (strcmp(adap->name, name) == 0)
			return adap;
	}

	return NULL;
}

/**
 * l3_get_adapter - get a reference to an adapter
 * @name: driver name
 *
 * Obtain a l3_adapter structure for the specified adapter.  If the adapter
 * is not currently load, then load it.  The adapter will be locked in core
 * until all references are released via l3_put_adapter.
 */
struct l3_adapter *l3_get_adapter(const char *name)
{
	struct l3_adapter *adap;
	int try;

	pr_debug("--- %s\n", __FUNCTION__);
	for (try = 0; try < 2; try ++) {
		down(&adapter_lock);
		adap = __l3_get_adapter(name);
		if (adap && !try_module_get(adap->owner))
			adap = NULL;
		up(&adapter_lock);

		if (adap)
			break;

		if (try == 0)
			request_module(name);
	}

	return adap;
}

/**
 * l3_put_adapter - release a reference to an adapter
 * @adap: driver to release reference
 *
 * Indicate to the L3 core that you no longer require the adapter reference.
 * The adapter module may be unloaded when there are no references to its
 * data structure.
 *
 * You must not use the reference after calling this function.
 */
void l3_put_adapter(struct l3_adapter *adap)
{
	pr_debug("--- %s\n", __FUNCTION__);
	if (adap && adap->owner)
		module_put(adap->owner);
}

/**
 * l3_transfer - transfer information on an L3 bus
 * @adap: adapter structure to perform transfer on
 * @msgs: array of l3_msg structures describing transfer
 * @num: number of l3_msg structures
 *
 * Transfer the specified messages to/from a device on the L3 bus.
 *
 * Returns number of messages successfully transferred, otherwise negative
 * error code.
 */
int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
{
	int ret = -ENOSYS;

	pr_debug("--- %s\n", __FUNCTION__);
	if (adap->algo->xfer) {
		down(adap->lock);
		ret = adap->algo->xfer(adap, msgs, num);
		up(adap->lock);
	}
	return ret;
}

/**
 * l3_write - send data to a device on an L3 bus
 * @adap: L3 bus adapter
 * @addr: L3 bus address
 * @buf: buffer for bytes to send
 * @len: number of bytes to send
 *
 * Send len bytes pointed to by buf to device address addr on the L3 bus
 * described by client.
 *
 * Returns the number of bytes transferred, or negative error code.
 */
int l3_write(struct l3_adapter *adap, int addr, const unsigned char *buf, int len)
{
	struct l3_msg msg;
	int ret;

	pr_debug("--- %s\n", __FUNCTION__);
	msg.addr = addr;
	msg.flags = 0;
	msg.buf = (char *)buf;
	msg.len = len;

#ifdef DEBUG 
	//DEBUG
	{
	  int i;
	  printk("-> %02x:", addr);
	  for(i=0;i<len;i++)
	    printk(" %02x", buf[i]);
	  printk("\n");
	}
#endif

	ret = l3_transfer(adap, &msg, 1);
	return ret == 1 ? len : ret;
}

/**
 * l3_read - receive data from a device on an L3 bus
 * @adap: L3 bus adapter
 * @addr: L3 bus address
 * @buf: buffer for bytes to receive
 * @len: number of bytes to receive
 *
 * Receive len bytes from device address addr on the L3 bus described by
 * client to a buffer pointed to by buf.
 *
 * Returns the number of bytes transferred, or negative error code.
 */
int l3_read(struct l3_adapter *adap, int addr, char *buf, int len)
{
	struct l3_msg msg;
	int ret;

	pr_debug("--- %s\n", __FUNCTION__);
	msg.addr = addr;
	msg.flags = L3_M_RD;
	msg.buf = buf;
	msg.len = len;

	ret = l3_transfer(adap, &msg, 1);
	return ret == 1 ? len : ret;
}

EXPORT_SYMBOL(l3_add_adapter);
EXPORT_SYMBOL(l3_del_adapter);
EXPORT_SYMBOL(l3_get_adapter);
EXPORT_SYMBOL(l3_put_adapter);
EXPORT_SYMBOL(l3_transfer);
EXPORT_SYMBOL(l3_write);
EXPORT_SYMBOL(l3_read);


MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("l3 core");
MODULE_AUTHOR("RMK");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -