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