1/*********************************************************************
2 *
3 * Filename:      irda_device.c
4 * Version:       0.9
5 * Description:   Utility functions used by the device drivers
6 * Status:        Experimental.
7 * Author:        Dag Brattli <dagb@cs.uit.no>
8 * Created at:    Sat Oct  9 09:22:27 1999
9 * Modified at:   Sun Jan 23 17:41:24 2000
10 * Modified by:   Dag Brattli <dagb@cs.uit.no>
11 *
12 *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 *     This program is free software; you can redistribute it and/or
16 *     modify it under the terms of the GNU General Public License as
17 *     published by the Free Software Foundation; either version 2 of
18 *     the License, or (at your option) any later version.
19 *
20 *     This program is distributed in the hope that it will be useful,
21 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
22 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 *     GNU General Public License for more details.
24 *
25 *     You should have received a copy of the GNU General Public License
26 *     along with this program; if not, write to the Free Software
27 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 *     MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/string.h>
33#include <linux/proc_fs.h>
34#include <linux/skbuff.h>
35#include <linux/capability.h>
36#include <linux/if.h>
37#include <linux/if_ether.h>
38#include <linux/if_arp.h>
39#include <linux/netdevice.h>
40#include <linux/init.h>
41#include <linux/tty.h>
42#include <linux/kmod.h>
43#include <linux/spinlock.h>
44
45#include <asm/ioctls.h>
46#include <asm/uaccess.h>
47#include <asm/dma.h>
48#include <asm/io.h>
49
50#include <net/irda/irda_device.h>
51#include <net/irda/irlap.h>
52#include <net/irda/timer.h>
53#include <net/irda/wrapper.h>
54
55static void __irda_task_delete(struct irda_task *task);
56
57static hashbin_t *dongles = NULL;
58static hashbin_t *tasks = NULL;
59
60#ifdef CONFIG_IRDA_DEBUG
61static const char *task_state[] = {
62	"IRDA_TASK_INIT",
63	"IRDA_TASK_DONE",
64	"IRDA_TASK_WAIT",
65	"IRDA_TASK_WAIT1",
66	"IRDA_TASK_WAIT2",
67	"IRDA_TASK_WAIT3",
68	"IRDA_TASK_CHILD_INIT",
69	"IRDA_TASK_CHILD_WAIT",
70	"IRDA_TASK_CHILD_DONE",
71};
72#endif	/* CONFIG_IRDA_DEBUG */
73
74static void irda_task_timer_expired(void *data);
75
76int __init irda_device_init( void)
77{
78	dongles = hashbin_new(HB_NOLOCK);
79	if (dongles == NULL) {
80		IRDA_WARNING("IrDA: Can't allocate dongles hashbin!\n");
81		return -ENOMEM;
82	}
83	spin_lock_init(&dongles->hb_spinlock);
84
85	tasks = hashbin_new(HB_LOCK);
86	if (tasks == NULL) {
87		IRDA_WARNING("IrDA: Can't allocate tasks hashbin!\n");
88		hashbin_delete(dongles, NULL);
89		return -ENOMEM;
90	}
91
92	/* We no longer initialise the driver ourselves here, we let
93	 * the system do it for us... - Jean II */
94
95	return 0;
96}
97
98static void __exit leftover_dongle(void *arg)
99{
100	struct dongle_reg *reg = arg;
101	IRDA_WARNING("IrDA: Dongle type %x not unregistered\n",
102		     reg->type);
103}
104
105void __exit irda_device_cleanup(void)
106{
107	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
108
109	hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
110
111	hashbin_delete(dongles, leftover_dongle);
112}
113
114/*
115 * Function irda_device_set_media_busy (self, status)
116 *
117 *    Called when we have detected that another station is transmitting
118 *    in contention mode.
119 */
120void irda_device_set_media_busy(struct net_device *dev, int status)
121{
122	struct irlap_cb *self;
123
124	IRDA_DEBUG(4, "%s(%s)\n", __FUNCTION__, status ? "TRUE" : "FALSE");
125
126	self = (struct irlap_cb *) dev->atalk_ptr;
127
128	/* Some drivers may enable the receive interrupt before calling
129	 * irlap_open(), or they may disable the receive interrupt
130	 * after calling irlap_close().
131	 * The IrDA stack is protected from this in irlap_driver_rcv().
132	 * However, the driver calls directly the wrapper, that calls
133	 * us directly. Make sure we protect ourselves.
134	 * Jean II */
135	if (!self || self->magic != LAP_MAGIC)
136		return;
137
138	if (status) {
139		self->media_busy = TRUE;
140		if (status == SMALL)
141			irlap_start_mbusy_timer(self, SMALLBUSY_TIMEOUT);
142		else
143			irlap_start_mbusy_timer(self, MEDIABUSY_TIMEOUT);
144		IRDA_DEBUG( 4, "Media busy!\n");
145	} else {
146		self->media_busy = FALSE;
147		irlap_stop_mbusy_timer(self);
148	}
149}
150EXPORT_SYMBOL(irda_device_set_media_busy);
151
152
153/*
154 * Function irda_device_is_receiving (dev)
155 *
156 *    Check if the device driver is currently receiving data
157 *
158 */
159int irda_device_is_receiving(struct net_device *dev)
160{
161	struct if_irda_req req;
162	int ret;
163
164	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
165
166	if (!dev->do_ioctl) {
167		IRDA_ERROR("%s: do_ioctl not impl. by device driver\n",
168			   __FUNCTION__);
169		return -1;
170	}
171
172	ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCGRECEIVING);
173	if (ret < 0)
174		return ret;
175
176	return req.ifr_receiving;
177}
178
179void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state)
180{
181	IRDA_DEBUG(2, "%s(), state = %s\n", __FUNCTION__, task_state[state]);
182
183	task->state = state;
184}
185EXPORT_SYMBOL(irda_task_next_state);
186
187static void __irda_task_delete(struct irda_task *task)
188{
189	del_timer(&task->timer);
190
191	kfree(task);
192}
193
194void irda_task_delete(struct irda_task *task)
195{
196	/* Unregister task */
197	hashbin_remove(tasks, (long) task, NULL);
198
199	__irda_task_delete(task);
200}
201EXPORT_SYMBOL(irda_task_delete);
202
203/*
204 * Function irda_task_kick (task)
205 *
206 *    Tries to execute a task possible multiple times until the task is either
207 *    finished, or askes for a timeout. When a task is finished, we do post
208 *    processing, and notify the parent task, that is waiting for this task
209 *    to complete.
210 */
211static int irda_task_kick(struct irda_task *task)
212{
213	int finished = TRUE;
214	int count = 0;
215	int timeout;
216
217	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
218
219	IRDA_ASSERT(task != NULL, return -1;);
220	IRDA_ASSERT(task->magic == IRDA_TASK_MAGIC, return -1;);
221
222	/* Execute task until it's finished, or askes for a timeout */
223	do {
224		timeout = task->function(task);
225		if (count++ > 100) {
226			IRDA_ERROR("%s: error in task handler!\n",
227				   __FUNCTION__);
228			irda_task_delete(task);
229			return TRUE;
230		}
231	} while ((timeout == 0) && (task->state != IRDA_TASK_DONE));
232
233	if (timeout < 0) {
234		IRDA_ERROR("%s: Error executing task!\n", __FUNCTION__);
235		irda_task_delete(task);
236		return TRUE;
237	}
238
239	/* Check if we are finished */
240	if (task->state == IRDA_TASK_DONE) {
241		del_timer(&task->timer);
242
243		/* Do post processing */
244		if (task->finished)
245			task->finished(task);
246
247		/* Notify parent */
248		if (task->parent) {
249			/* Check if parent is waiting for us to complete */
250			if (task->parent->state == IRDA_TASK_CHILD_WAIT) {
251				task->parent->state = IRDA_TASK_CHILD_DONE;
252
253				/* Stop timer now that we are here */
254				del_timer(&task->parent->timer);
255
256				/* Kick parent task */
257				irda_task_kick(task->parent);
258			}
259		}
260		irda_task_delete(task);
261	} else if (timeout > 0) {
262		irda_start_timer(&task->timer, timeout, (void *) task,
263				 irda_task_timer_expired);
264		finished = FALSE;
265	} else {
266		IRDA_DEBUG(0, "%s(), not finished, and no timeout!\n",
267			   __FUNCTION__);
268		finished = FALSE;
269	}
270
271	return finished;
272}
273
274/*
275 * Function irda_task_execute (instance, function, finished)
276 *
277 *    This function registers and tries to execute tasks that may take some
278 *    time to complete. We do it this hairy way since we may have been
279 *    called from interrupt context, so it's not possible to use
280 *    schedule_timeout()
281 * Two important notes :
282 *	o Make sure you irda_task_delete(task); in case you delete the
283 *	  calling instance.
284 *	o No real need to lock when calling this function, but you may
285 *	  want to lock within the task handler.
286 * Jean II
287 */
288struct irda_task *irda_task_execute(void *instance,
289				    IRDA_TASK_CALLBACK function,
290				    IRDA_TASK_CALLBACK finished,
291				    struct irda_task *parent, void *param)
292{
293	struct irda_task *task;
294
295	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
296
297	task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC);
298	if (!task)
299		return NULL;
300
301	task->state    = IRDA_TASK_INIT;
302	task->instance = instance;
303	task->function = function;
304	task->finished = finished;
305	task->parent   = parent;
306	task->param    = param;
307	task->magic    = IRDA_TASK_MAGIC;
308
309	init_timer(&task->timer);
310
311	/* Register task */
312	hashbin_insert(tasks, (irda_queue_t *) task, (long) task, NULL);
313
314	/* No time to waste, so lets get going! */
315	return irda_task_kick(task) ? NULL : task;
316}
317EXPORT_SYMBOL(irda_task_execute);
318
319/*
320 * Function irda_task_timer_expired (data)
321 *
322 *    Task time has expired. We now try to execute task (again), and restart
323 *    the timer if the task has not finished yet
324 */
325static void irda_task_timer_expired(void *data)
326{
327	struct irda_task *task;
328
329	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
330
331	task = (struct irda_task *) data;
332
333	irda_task_kick(task);
334}
335
336/*
337 * Function irda_device_setup (dev)
338 *
339 *    This function should be used by low level device drivers in a similar way
340 *    as ether_setup() is used by normal network device drivers
341 */
342static void irda_device_setup(struct net_device *dev)
343{
344	dev->hard_header_len = 0;
345	dev->addr_len        = LAP_ALEN;
346
347	dev->type            = ARPHRD_IRDA;
348	dev->tx_queue_len    = 8; /* Window size + 1 s-frame */
349
350	memset(dev->broadcast, 0xff, LAP_ALEN);
351
352	dev->mtu = 2048;
353	dev->flags = IFF_NOARP;
354}
355
356/*
357 * Funciton  alloc_irdadev
358 * 	Allocates and sets up an IRDA device in a manner similar to
359 * 	alloc_etherdev.
360 */
361struct net_device *alloc_irdadev(int sizeof_priv)
362{
363	return alloc_netdev(sizeof_priv, "irda%d", irda_device_setup);
364}
365EXPORT_SYMBOL(alloc_irdadev);
366
367/*
368 * Function irda_device_init_dongle (self, type, qos)
369 *
370 *    Initialize attached dongle.
371 *
372 * Important : request_module require us to call this function with
373 * a process context and irq enabled. - Jean II
374 */
375dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
376{
377	struct dongle_reg *reg;
378	dongle_t *dongle = kzalloc(sizeof(dongle_t), GFP_KERNEL);
379
380	might_sleep();
381
382	spin_lock(&dongles->hb_spinlock);
383	reg = hashbin_find(dongles, type, NULL);
384
385#ifdef CONFIG_KMOD
386	/* Try to load the module needed */
387	if (!reg && capable(CAP_SYS_MODULE)) {
388		spin_unlock(&dongles->hb_spinlock);
389
390		request_module("irda-dongle-%d", type);
391
392		spin_lock(&dongles->hb_spinlock);
393		reg = hashbin_find(dongles, type, NULL);
394	}
395#endif
396
397	if (!reg || !try_module_get(reg->owner) ) {
398		IRDA_ERROR("IrDA: Unable to find requested dongle type %x\n",
399			   type);
400		kfree(dongle);
401		dongle = NULL;
402	}
403	if (dongle) {
404		/* Bind the registration info to this particular instance */
405		dongle->issue = reg;
406		dongle->dev = dev;
407	}
408	spin_unlock(&dongles->hb_spinlock);
409	return dongle;
410}
411EXPORT_SYMBOL(irda_device_dongle_init);
412
413/*
414 * Function irda_device_dongle_cleanup (dongle)
415 */
416int irda_device_dongle_cleanup(dongle_t *dongle)
417{
418	IRDA_ASSERT(dongle != NULL, return -1;);
419
420	dongle->issue->close(dongle);
421	module_put(dongle->issue->owner);
422	kfree(dongle);
423
424	return 0;
425}
426EXPORT_SYMBOL(irda_device_dongle_cleanup);
427
428/*
429 * Function irda_device_register_dongle (dongle)
430 */
431int irda_device_register_dongle(struct dongle_reg *new)
432{
433	spin_lock(&dongles->hb_spinlock);
434	/* Check if this dongle has been registered before */
435	if (hashbin_find(dongles, new->type, NULL)) {
436		IRDA_MESSAGE("%s: Dongle type %x already registered\n",
437			     __FUNCTION__, new->type);
438	} else {
439		/* Insert IrDA dongle into hashbin */
440		hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
441	}
442	spin_unlock(&dongles->hb_spinlock);
443
444	return 0;
445}
446EXPORT_SYMBOL(irda_device_register_dongle);
447
448/*
449 * Function irda_device_unregister_dongle (dongle)
450 *
451 *    Unregister dongle, and remove dongle from list of registered dongles
452 *
453 */
454void irda_device_unregister_dongle(struct dongle_reg *dongle)
455{
456	struct dongle *node;
457
458	spin_lock(&dongles->hb_spinlock);
459	node = hashbin_remove(dongles, dongle->type, NULL);
460	if (!node)
461		IRDA_ERROR("%s: dongle not found!\n", __FUNCTION__);
462	spin_unlock(&dongles->hb_spinlock);
463}
464EXPORT_SYMBOL(irda_device_unregister_dongle);
465
466#ifdef CONFIG_ISA_DMA_API
467/*
468 * Function setup_dma (idev, buffer, count, mode)
469 *
470 *    Setup the DMA channel. Commonly used by LPC FIR drivers
471 *
472 */
473void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
474{
475	unsigned long flags;
476
477	flags = claim_dma_lock();
478
479	disable_dma(channel);
480	clear_dma_ff(channel);
481	set_dma_mode(channel, mode);
482	set_dma_addr(channel, buffer);
483	set_dma_count(channel, count);
484	enable_dma(channel);
485
486	release_dma_lock(flags);
487}
488EXPORT_SYMBOL(irda_setup_dma);
489#endif
490