sync hh.org
[hh.org.git] / drivers / l3 / l3-core.c
blobdbff62b6108128249f2f2cc2eb83b8a71023101b
1 /*
2 * linux/drivers/l3/l3-core.c
4 * Copyright (C) 2001 Russell King
6 * General structure taken from i2c-core.c by Simon G. Vogl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License.
12 * See linux/Documentation/l3 for further documentation.
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/slab.h>
18 #include <linux/proc_fs.h>
19 #include <linux/kmod.h>
20 #include <linux/init.h>
21 #include <linux/l3/l3.h>
23 static DECLARE_MUTEX(adapter_lock);
24 static LIST_HEAD(adapter_list);
26 static DECLARE_MUTEX(driver_lock);
27 static LIST_HEAD(driver_list);
29 /**
30 * l3_add_adapter - register a new L3 bus adapter
31 * @adap: l3_adapter structure for the registering adapter
33 * Make the adapter available for use by clients using name adap->name.
34 * The adap->adapters list is initialised by this function.
36 * Returns 0;
38 int l3_add_adapter(struct l3_adapter *adap)
40 down(&adapter_lock);
41 list_add(&adap->adapters, &adapter_list);
42 up(&adapter_lock);
43 return 0;
46 /**
47 * l3_del_adapter - unregister a L3 bus adapter
48 * @adap: l3_adapter structure to unregister
50 * Remove an adapter from the list of available L3 Bus adapters.
52 * Returns 0;
54 int l3_del_adapter(struct l3_adapter *adap)
56 down(&adapter_lock);
57 list_del(&adap->adapters);
58 up(&adapter_lock);
59 return 0;
62 static struct l3_adapter *__l3_get_adapter(const char *name)
64 struct list_head *l;
66 list_for_each(l, &adapter_list) {
67 struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);
69 if (strcmp(adap->name, name) == 0)
70 return adap;
73 return NULL;
76 /**
77 * l3_get_adapter - get a reference to an adapter
78 * @name: driver name
80 * Obtain a l3_adapter structure for the specified adapter. If the adapter
81 * is not currently load, then load it. The adapter will be locked in core
82 * until all references are released via l3_put_adapter.
84 struct l3_adapter *l3_get_adapter(const char *name)
86 struct l3_adapter *adap;
87 int try;
89 for (try = 0; try < 2; try ++) {
90 down(&adapter_lock);
91 adap = __l3_get_adapter(name);
92 if (adap && !try_module_get(adap->owner))
93 adap = NULL;
94 up(&adapter_lock);
96 if (adap)
97 break;
99 if (try == 0)
100 request_module(name);
103 return adap;
107 * l3_put_adapter - release a reference to an adapter
108 * @adap: driver to release reference
110 * Indicate to the L3 core that you no longer require the adapter reference.
111 * The adapter module may be unloaded when there are no references to its
112 * data structure.
114 * You must not use the reference after calling this function.
116 void l3_put_adapter(struct l3_adapter *adap)
118 if (adap && adap->owner)
119 module_put(adap->owner);
123 * l3_transfer - transfer information on an L3 bus
124 * @adap: adapter structure to perform transfer on
125 * @msgs: array of l3_msg structures describing transfer
126 * @num: number of l3_msg structures
128 * Transfer the specified messages to/from a device on the L3 bus.
130 * Returns number of messages successfully transferred, otherwise negative
131 * error code.
133 int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
135 int ret = -ENOSYS;
137 if (adap->algo->xfer) {
138 down(adap->lock);
139 ret = adap->algo->xfer(adap, msgs, num);
140 up(adap->lock);
142 return ret;
146 * l3_write - send data to a device on an L3 bus
147 * @adap: L3 bus adapter
148 * @addr: L3 bus address
149 * @buf: buffer for bytes to send
150 * @len: number of bytes to send
152 * Send len bytes pointed to by buf to device address addr on the L3 bus
153 * described by client.
155 * Returns the number of bytes transferred, or negative error code.
157 int l3_write(struct l3_adapter *adap, int addr, const char *buf, int len)
159 struct l3_msg msg;
160 int ret;
162 msg.addr = addr;
163 msg.flags = 0;
164 msg.buf = (char *)buf;
165 msg.len = len;
167 ret = l3_transfer(adap, &msg, 1);
168 return ret == 1 ? len : ret;
172 * l3_read - receive data from a device on an L3 bus
173 * @adap: L3 bus adapter
174 * @addr: L3 bus address
175 * @buf: buffer for bytes to receive
176 * @len: number of bytes to receive
178 * Receive len bytes from device address addr on the L3 bus described by
179 * client to a buffer pointed to by buf.
181 * Returns the number of bytes transferred, or negative error code.
183 int l3_read(struct l3_adapter *adap, int addr, char *buf, int len)
185 struct l3_msg msg;
186 int ret;
188 msg.addr = addr;
189 msg.flags = L3_M_RD;
190 msg.buf = buf;
191 msg.len = len;
193 ret = l3_transfer(adap, &msg, 1);
194 return ret == 1 ? len : ret;
197 EXPORT_SYMBOL(l3_add_adapter);
198 EXPORT_SYMBOL(l3_del_adapter);
199 EXPORT_SYMBOL(l3_get_adapter);
200 EXPORT_SYMBOL(l3_put_adapter);
201 EXPORT_SYMBOL(l3_transfer);
202 EXPORT_SYMBOL(l3_write);
203 EXPORT_SYMBOL(l3_read);