| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /********************************************************************* | |||
| 2 | * | |||
| 3 | * Filename: irtty-sir.c | |||
| 4 | * Version: 2.0 | |||
| 5 | * Description: IrDA line discipline implementation | |||
| 6 | * Status: Experimental. | |||
| 7 | * Author: Dag Brattli <dagb@cs.uit.no> | |||
| 8 | * Created at: Tue Dec 9 21:18:38 1997 | |||
| 9 | * Modified at: Sun Oct 27 22:13:30 2002 | |||
| 10 | * Modified by: Martin Diehl <mad@mdiehl.de> | |||
| 11 | * Sources: slip.c by Laurence Culhane, <loz@holmes.demon.co.uk> | |||
| 12 | * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> | |||
| 13 | * | |||
| 14 | * Copyright (c) 1998-2000 Dag Brattli, | |||
| 15 | * Copyright (c) 2002 Martin Diehl, | |||
| 16 | * All Rights Reserved. | |||
| 17 | * | |||
| 18 | * This program is free software; you can redistribute it and/or | |||
| 19 | * modify it under the terms of the GNU General Public License as | |||
| 20 | * published by the Free Software Foundation; either version 2 of | |||
| 21 | * the License, or (at your option) any later version. | |||
| 22 | * | |||
| 23 | * Neither Dag Brattli nor University of Tromsų admit liability nor | |||
| 24 | * provide warranty for any of this software. This material is | |||
| 25 | * provided "AS-IS" and at no charge. | |||
| 26 | * | |||
| 27 | ********************************************************************/ | |||
| 28 | ||||
| 29 | #include <linux/module.h> | |||
| 30 | #include <linux/kernel.h> | |||
| 31 | #include <linux/tty.h> | |||
| 32 | #include <linux/init.h> | |||
| 33 | #include <asm/uaccess.h> | |||
| 34 | #include <linux/smp_lock.h> | |||
| 35 | #include <linux/delay.h> | |||
| 36 | ||||
| 37 | #include <net/irda/irda.h> | |||
| 38 | #include <net/irda/irda_device.h> | |||
| 39 | ||||
| 40 | #include "sir-dev.h" | |||
| 41 | #include "irtty-sir.h" | |||
| 42 | ||||
| 43 | static int qos_mtt_bits = 0x03; /* 5 ms or more */ | |||
| 44 | ||||
| 0 | 0 | - | 45 | module_param(qos_mtt_bits, int, 0); |
| 0 | - | 45 | return ( & ( qos_mtt_bits ) ) | |
| 46 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); | |||
| 47 | ||||
| 48 | /* ------------------------------------------------------- */ | |||
| 49 | ||||
| 50 | /* device configuration callbacks always invoked with irda-thread context */ | |||
| 51 | ||||
| 52 | /* find out, how many chars we have in buffers below us | |||
| 53 | * this is allowed to lie, i.e. return less chars than we | |||
| 54 | * actually have. The returned value is used to determine | |||
| 55 | * how long the irdathread should wait before doing the | |||
| 56 | * real blocking wait_until_sent() | |||
| 57 | */ | |||
| 58 | ||||
| 0 | 0 | - | 59 | static int irtty_chars_in_buffer(struct sir_dev *dev) |
| 60 | { | |||
| 61 | struct sirtty_cb *priv = dev->priv; | |||
| 62 | ||||
| 63 | IRDA_ASSERT(priv != NULL, return -1;); | |||
| 0 | 0 | - | 63 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 63 | return - 1 | |
| 0 | 0 | - | 63 | do-while (0) |
| 64 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); | |||
| 0 | 0 | - | 64 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 64 | return - 1 | |
| 0 | 0 | - | 64 | do-while (0) |
| 65 | ||||
| 0 | - | 66 | return priv->tty->driver->chars_in_buffer(priv->tty); | |
| 67 | } | |||
| 68 | ||||
| 69 | /* Wait (sleep) until underlaying hardware finished transmission | |||
| 70 | * i.e. hardware buffers are drained | |||
| 71 | * this must block and not return before all characters are really sent | |||
| 72 | * | |||
| 73 | * If the tty sits on top of a 16550A-like uart, there are typically | |||
| 74 | * up to 16 bytes in the fifo - f.e. 9600 bps 8N1 needs 16.7 msec | |||
| 75 | * | |||
| 76 | * With usbserial the uart-fifo is basically replaced by the converter's | |||
| 77 | * outgoing endpoint buffer, which can usually hold 64 bytes (at least). | |||
| 78 | * With pl2303 it appears we are safe with 60msec here. | |||
| 79 | * | |||
| 80 | * I really wish all serial drivers would provide | |||
| 81 | * correct implementation of wait_until_sent() | |||
| 82 | */ | |||
| 83 | ||||
| 84 | #define USBSERIAL_TX_DONE_DELAY 60 | |||
| 85 | ||||
| 0 | 0 | - | 86 | static void irtty_wait_until_sent(struct sir_dev *dev) |
| 87 | { | |||
| 88 | struct sirtty_cb *priv = dev->priv; | |||
| 89 | struct tty_struct *tty; | |||
| 90 | ||||
| 91 | IRDA_ASSERT(priv != NULL, return;); | |||
| 0 | 0 | - | 91 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 91 | return | |
| 0 | 0 | - | 91 | do-while (0) |
| 92 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); | |||
| 0 | 0 | - | 92 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 92 | return | |
| 0 | 0 | - | 92 | do-while (0) |
| 93 | ||||
| 94 | tty = priv->tty; | |||
| 0 | 0 | - | 95 | if (tty->driver->wait_until_sent) { |
| 96 | lock_kernel(); | |||
| 0 | 0 | - | 96 | do-while (0) |
| 97 | tty->driver->wait_until_sent(tty, msecs_to_jiffies(100)); | |||
| 98 | unlock_kernel(); | |||
| 0 | 0 | - | 98 | do-while (0) |
| 99 | } | |||
| 100 | else { | |||
| 101 | msleep(USBSERIAL_TX_DONE_DELAY); | |||
| 102 | } | |||
| 103 | } | |||
| 104 | ||||
| 105 | /* | |||
| 106 | * Function irtty_change_speed (dev, speed) | |||
| 107 | * | |||
| 108 | * Change the speed of the serial port. | |||
| 109 | * | |||
| 110 | * This may sleep in set_termios (usbserial driver f.e.) and must | |||
| 111 | * not be called from interrupt/timer/tasklet therefore. | |||
| 112 | * All such invocations are deferred to kIrDAd now so we can sleep there. | |||
| 113 | */ | |||
| 114 | ||||
| 0 | 0 | - | 115 | static int irtty_change_speed(struct sir_dev *dev, unsigned speed) |
| 116 | { | |||
| 117 | struct sirtty_cb *priv = dev->priv; | |||
| 118 | struct tty_struct *tty; | |||
| 119 | struct termios old_termios; | |||
| 120 | int cflag; | |||
| 121 | ||||
| 122 | IRDA_ASSERT(priv != NULL, return -1;); | |||
| 0 | 0 | - | 122 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 122 | return - 1 | |
| 0 | 0 | - | 122 | do-while (0) |
| 123 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); | |||
| 0 | 0 | - | 123 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 123 | return - 1 | |
| 0 | 0 | - | 123 | do-while (0) |
| 124 | ||||
| 125 | tty = priv->tty; | |||
| 126 | ||||
| 127 | lock_kernel(); | |||
| 0 | 0 | - | 127 | do-while (0) |
| 128 | old_termios = *(tty->termios); | |||
| 129 | cflag = tty->termios->c_cflag; | |||
| 130 | ||||
| 131 | cflag &= ~CBAUD; | |||
| 132 | ||||
| 133 | IRDA_DEBUG(2, "%s(), Setting speed to %d\n", __FUNCTION__, speed); | |||
| 0 | 0 | - | 133 | if (irda_debug >= ( 2 )) |
| 0 | 0 | - | 133 | do-while (0) |
| 134 | ||||
| 135 | switch (speed) { | |||
| 0 | - | 136 | case 1200: | |
| 137 | cflag |= B1200; | |||
| 0 | - | 138 | break; | |
| 0 | - | 139 | case 2400: | |
| 140 | cflag |= B2400; | |||
| 0 | - | 141 | break; | |
| 0 | - | 142 | case 4800: | |
| 143 | cflag |= B4800; | |||
| 0 | - | 144 | break; | |
| 0 | - | 145 | case 19200: | |
| 146 | cflag |= B19200; | |||
| 0 | - | 147 | break; | |
| 0 | - | 148 | case 38400: | |
| 149 | cflag |= B38400; | |||
| 0 | - | 150 | break; | |
| 0 | - | 151 | case 57600: | |
| 152 | cflag |= B57600; | |||
| 0 | - | 153 | break; | |
| 0 | - | 154 | case 115200: | |
| 155 | cflag |= B115200; | |||
| 0 | - | 156 | break; | |
| 0 | - | 157 | case 9600: | |
| 0 | - | 158 | default: | |
| 159 | cflag |= B9600; | |||
| 0 | - | 160 | break; | |
| 161 | } | |||
| 162 | ||||
| 163 | tty->termios->c_cflag = cflag; | |||
| 0 | 0 | - | 164 | if (tty->driver->set_termios) |
| 165 | tty->driver->set_termios(tty, &old_termios); | |||
| 166 | unlock_kernel(); | |||
| 0 | 0 | - | 166 | do-while (0) |
| 167 | ||||
| 168 | priv->io.speed = speed; | |||
| 169 | ||||
| 0 | - | 170 | return 0; | |
| 171 | } | |||
| 172 | ||||
| 173 | /* | |||
| 174 | * Function irtty_set_dtr_rts (dev, dtr, rts) | |||
| 175 | * | |||
| 176 | * This function can be used by dongles etc. to set or reset the status | |||
| 177 | * of the dtr and rts lines | |||
| 178 | */ | |||
| 179 | ||||
| 0 | 0 | - | 180 | static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts) |
| 181 | { | |||
| 182 | struct sirtty_cb *priv = dev->priv; | |||
| 183 | int set = 0; | |||
| 184 | int clear = 0; | |||
| 185 | ||||
| 186 | IRDA_ASSERT(priv != NULL, return -1;); | |||
| 0 | 0 | - | 186 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 186 | return - 1 | |
| 0 | 0 | - | 186 | do-while (0) |
| 187 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); | |||
| 0 | 0 | - | 187 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 187 | return - 1 | |
| 0 | 0 | - | 187 | do-while (0) |
| 188 | ||||
| 0 | 0 | - | 189 | if (rts) |
| 190 | set |= TIOCM_RTS; | |||
| 191 | else | |||
| 192 | clear |= TIOCM_RTS; | |||
| 0 | 0 | - | 193 | if (dtr) |
| 194 | set |= TIOCM_DTR; | |||
| 195 | else | |||
| 196 | clear |= TIOCM_DTR; | |||
| 197 | ||||
| 198 | /* | |||
| 199 | * We can't use ioctl() because it expects a non-null file structure, | |||
| 200 | * and we don't have that here. | |||
| 201 | * This function is not yet defined for all tty driver, so | |||
| 202 | * let's be careful... Jean II | |||
| 203 | */ | |||
| 204 | IRDA_ASSERT(priv->tty->driver->tiocmset != NULL, return -1;); | |||
| 0 | 0 | - | 204 | if (! ( priv -> tty -> driver -> tiocmset !=.. |
| 0 | - | 204 | return - 1 | |
| 0 | 0 | - | 204 | do-while (0) |
| 205 | priv->tty->driver->tiocmset(priv->tty, NULL, set, clear); | |||
| 206 | ||||
| 0 | - | 207 | return 0; | |
| 208 | } | |||
| 209 | ||||
| 210 | /* ------------------------------------------------------- */ | |||
| 211 | ||||
| 212 | /* called from sir_dev when there is more data to send | |||
| 213 | * context is either netdev->hard_xmit or some transmit-completion bh | |||
| 214 | * i.e. we are under spinlock here and must not sleep. | |||
| 215 | */ | |||
| 216 | ||||
| 0 | 0 | - | 217 | static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t len) |
| 218 | { | |||
| 219 | struct sirtty_cb *priv = dev->priv; | |||
| 220 | struct tty_struct *tty; | |||
| 221 | int writelen; | |||
| 222 | ||||
| 223 | IRDA_ASSERT(priv != NULL, return -1;); | |||
| 0 | 0 | - | 223 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 223 | return - 1 | |
| 0 | 0 | - | 223 | do-while (0) |
| 224 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); | |||
| 0 | 0 | - | 224 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 224 | return - 1 | |
| 0 | 0 | - | 224 | do-while (0) |
| 225 | ||||
| 226 | tty = priv->tty; | |||
| 0 | 0 | - | 227 | if (!tty->driver->write) |
| 0 | - | 228 | return 0; | |
| 229 | tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | |||
| 0 | 0 | - | 230 | if (tty->driver->write_room) { |
| 231 | writelen = tty->driver->write_room(tty); | |||
| 0 | 0 | - | 232 | if (writelen > len) |
| 233 | writelen = len; | |||
| 234 | } | |||
| 235 | else | |||
| 236 | writelen = len; | |||
| 0 | - | 237 | return tty->driver->write(tty, ptr, writelen); | |
| 238 | } | |||
| 239 | ||||
| 240 | /* ------------------------------------------------------- */ | |||
| 241 | ||||
| 242 | /* irda line discipline callbacks */ | |||
| 243 | ||||
| 244 | /* | |||
| 245 | * Function irtty_receive_buf( tty, cp, count) | |||
| 246 | * | |||
| 247 | * Handle the 'receiver data ready' interrupt. This function is called | |||
| 248 | * by the 'tty_io' module in the kernel when a block of IrDA data has | |||
| 249 | * been received, which can now be decapsulated and delivered for | |||
| 250 | * further processing | |||
| 251 | * | |||
| 252 | * calling context depends on underlying driver and tty->low_latency! | |||
| 253 | * for example (low_latency: 1 / 0): | |||
| 254 | * serial.c: uart-interrupt / softint | |||
| 255 | * usbserial: urb-complete-interrupt / softint | |||
| 256 | */ | |||
| 257 | ||||
| 0 | 0 | - | 258 | static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
| 259 | char *fp, int count) | |||
| 260 | { | |||
| 261 | struct sir_dev *dev; | |||
| 262 | struct sirtty_cb *priv = tty->disc_data; | |||
| 263 | int i; | |||
| 264 | ||||
| 265 | IRDA_ASSERT(priv != NULL, return;); | |||
| 0 | 0 | - | 265 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 265 | return | |
| 0 | 0 | - | 265 | do-while (0) |
| 266 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); | |||
| 0 | 0 | - | 266 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 266 | return | |
| 0 | 0 | - | 266 | do-while (0) |
| 267 | ||||
| 0 | 0 | - | 268 | if (unlikely(count==0)) /* yes, this happens */ |
| 0 | - | 269 | return; | |
| 270 | ||||
| 271 | dev = priv->dev; | |||
| 0 | 0 | - | 272 | if (!dev) { |
| 273 | IRDA_WARNING("%s(), not ready yet!\n", __FUNCTION__); | |||
| 0 | 0 | - | 273 | if (net_ratelimit ( )) |
| 0 | 0 | - | 273 | do-while (0) |
| 0 | - | 274 | return; | |
| 275 | } | |||
| 276 | ||||
| 0 | 0 | - | 277 | for (i = 0; i < count; i++) { |
| 278 | /* | |||
| 279 | * Characters received with a parity error, etc? | |||
| 280 | */ | |||
| 0 | 0 | - | 281 | if (fp && *fp++) { |
| 0 | - | 281 | T && T | |
| 0 | - | 281 | T && F | |
| 0 | - | 281 | F && _ | |
| 282 | IRDA_DEBUG(0, "Framing or parity error!\n"); | |||
| 0 | 0 | - | 282 | if (irda_debug >= ( 0 )) |
| 0 | 0 | - | 282 | do-while (0) |
| 283 | sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ | |||
| 0 | - | 284 | return; | |
| 285 | } | |||
| 286 | } | |||
| 287 | ||||
| 288 | sirdev_receive(dev, cp, count); | |||
| 289 | } | |||
| 290 | ||||
| 291 | /* | |||
| 292 | * Function irtty_write_wakeup (tty) | |||
| 293 | * | |||
| 294 | * Called by the driver when there's room for more data. If we have | |||
| 295 | * more packets to send, we send them here. | |||
| 296 | * | |||
| 297 | */ | |||
| 0 | 0 | - | 298 | static void irtty_write_wakeup(struct tty_struct *tty) |
| 299 | { | |||
| 300 | struct sirtty_cb *priv = tty->disc_data; | |||
| 301 | ||||
| 302 | IRDA_ASSERT(priv != NULL, return;); | |||
| 0 | 0 | - | 302 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 302 | return | |
| 0 | 0 | - | 302 | do-while (0) |
| 303 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); | |||
| 0 | 0 | - | 303 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 303 | return | |
| 0 | 0 | - | 303 | do-while (0) |
| 304 | ||||
| 305 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | |||
| 306 | ||||
| 0 | 0 | - | 307 | if (priv->dev) |
| 308 | sirdev_write_complete(priv->dev); | |||
| 309 | } | |||
| 310 | ||||
| 311 | /* ------------------------------------------------------- */ | |||
| 312 | ||||
| 313 | /* | |||
| 314 | * Function irtty_stop_receiver (tty, stop) | |||
| 315 | * | |||
| 316 | */ | |||
| 317 | ||||
| 0 | 0 | - | 318 | static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) |
| 319 | { | |||
| 320 | struct termios old_termios; | |||
| 321 | int cflag; | |||
| 322 | ||||
| 323 | lock_kernel(); | |||
| 0 | 0 | - | 323 | do-while (0) |
| 324 | old_termios = *(tty->termios); | |||
| 325 | cflag = tty->termios->c_cflag; | |||
| 326 | ||||
| 0 | 0 | - | 327 | if (stop) |
| 328 | cflag &= ~CREAD; | |||
| 329 | else | |||
| 330 | cflag |= CREAD; | |||
| 331 | ||||
| 332 | tty->termios->c_cflag = cflag; | |||
| 0 | 0 | - | 333 | if (tty->driver->set_termios) |
| 334 | tty->driver->set_termios(tty, &old_termios); | |||
| 335 | unlock_kernel(); | |||
| 0 | 0 | - | 335 | do-while (0) |
| 336 | } | |||
| 337 | ||||
| 338 | /*****************************************************************/ | |||
| 339 | ||||
| 340 | /* serialize ldisc open/close with sir_dev */ | |||
| 341 | static DECLARE_MUTEX(irtty_sem); | |||
| 342 | ||||
| 343 | /* notifier from sir_dev when irda% device gets opened (ifup) */ | |||
| 344 | ||||
| 0 | 0 | - | 345 | static int irtty_start_dev(struct sir_dev *dev) |
| 346 | { | |||
| 347 | struct sirtty_cb *priv; | |||
| 348 | struct tty_struct *tty; | |||
| 349 | ||||
| 350 | /* serialize with ldisc open/close */ | |||
| 351 | down(&irtty_sem); | |||
| 352 | ||||
| 353 | priv = dev->priv; | |||
| 0 | 0 | - | 354 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { |
| 355 | up(&irtty_sem); | |||
| 0 | - | 356 | return -ESTALE; | |
| 357 | } | |||
| 358 | ||||
| 359 | tty = priv->tty; | |||
| 360 | ||||
| 0 | 0 | - | 361 | if (tty->driver->start) |
| 362 | tty->driver->start(tty); | |||
| 363 | /* Make sure we can receive more data */ | |||
| 364 | irtty_stop_receiver(tty, FALSE); | |||
| 365 | ||||
| 366 | up(&irtty_sem); | |||
| 0 | - | 367 | return 0; | |
| 368 | } | |||
| 369 | ||||
| 370 | /* notifier from sir_dev when irda% device gets closed (ifdown) */ | |||
| 371 | ||||
| 0 | 0 | - | 372 | static int irtty_stop_dev(struct sir_dev *dev) |
| 373 | { | |||
| 374 | struct sirtty_cb *priv; | |||
| 375 | struct tty_struct *tty; | |||
| 376 | ||||
| 377 | /* serialize with ldisc open/close */ | |||
| 378 | down(&irtty_sem); | |||
| 379 | ||||
| 380 | priv = dev->priv; | |||
| 0 | 0 | - | 381 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { |
| 382 | up(&irtty_sem); | |||
| 0 | - | 383 | return -ESTALE; | |
| 384 | } | |||
| 385 | ||||
| 386 | tty = priv->tty; | |||
| 387 | ||||
| 388 | /* Make sure we don't receive more data */ | |||
| 389 | irtty_stop_receiver(tty, TRUE); | |||
| 0 | 0 | - | 390 | if (tty->driver->stop) |
| 391 | tty->driver->stop(tty); | |||
| 392 | ||||
| 393 | up(&irtty_sem); | |||
| 394 | ||||
| 0 | - | 395 | return 0; | |
| 396 | } | |||
| 397 | ||||
| 398 | /* ------------------------------------------------------- */ | |||
| 399 | ||||
| 400 | static struct sir_driver sir_tty_drv = { | |||
| 401 | .owner = THIS_MODULE, | |||
| 402 | .driver_name = "sir_tty", | |||
| 403 | .start_dev = irtty_start_dev, | |||
| 404 | .stop_dev = irtty_stop_dev, | |||
| 405 | .do_write = irtty_do_write, | |||
| 406 | .chars_in_buffer = irtty_chars_in_buffer, | |||
| 407 | .wait_until_sent = irtty_wait_until_sent, | |||
| 408 | .set_speed = irtty_change_speed, | |||
| 409 | .set_dtr_rts = irtty_set_dtr_rts, | |||
| 410 | }; | |||
| 411 | ||||
| 412 | /* ------------------------------------------------------- */ | |||
| 413 | ||||
| 414 | /* | |||
| 415 | * Function irtty_ioctl (tty, file, cmd, arg) | |||
| 416 | * | |||
| 417 | * The Swiss army knife of system calls :-) | |||
| 418 | * | |||
| 419 | */ | |||
| 0 | 0 | - | 420 | static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) |
| 421 | { | |||
| 422 | struct irtty_info { char name[6]; } info; | |||
| 423 | struct sir_dev *dev; | |||
| 424 | struct sirtty_cb *priv = tty->disc_data; | |||
| 425 | int err = 0; | |||
| 426 | ||||
| 427 | IRDA_ASSERT(priv != NULL, return -ENODEV;); | |||
| 0 | 0 | - | 427 | if (! ( priv != ( ( void * ) 0 ) )) |
| 0 | - | 427 | return - 19 | |
| 0 | 0 | - | 427 | do-while (0) |
| 428 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EBADR;); | |||
| 0 | 0 | - | 428 | if (! ( priv -> magic == 0x2357 )) |
| 0 | - | 428 | return - 53 | |
| 0 | 0 | - | 428 | do-while (0) |
| 429 | ||||
| 430 | IRDA_DEBUG(3, "%s(cmd=0x%X)\n", __FUNCTION__, cmd); | |||
| 0 | 0 | - | 430 | if (irda_debug >= ( 3 )) |
| 0 | 0 | - | 430 | do-while (0) |
| 431 | ||||
| 432 | dev = priv->dev; | |||
| 433 | IRDA_ASSERT(dev != NULL, return -1;); | |||
| 0 | 0 | - | 433 | if (! ( dev != ( ( void * ) 0 ) )) |
| 0 | - | 433 | return - 1 | |
| 0 | 0 | - | 433 | do-while (0) |
| 434 | ||||
| 435 | switch (cmd) { | |||
| 0 | - | 436 | case TCGETS: | |
| 0 | - | 437 | case TCGETA: | |
| 438 | err = n_tty_ioctl(tty, file, cmd, arg); | |||
| 0 | - | 439 | break; | |
| 440 | ||||
| 0 | - | 441 | case IRTTY_IOCTDONGLE: | |
| 442 | /* this call blocks for completion */ | |||
| 443 | err = sirdev_set_dongle(dev, (IRDA_DONGLE) arg); | |||
| 0 | - | 444 | break; | |
| 445 | ||||
| 0 | - | 446 | case IRTTY_IOCGET: | |
| 447 | IRDA_ASSERT(dev->netdev != NULL, return -1;); | |||
| 0 | 0 | - | 447 | if (! ( dev -> netdev != ( ( void * ) 0 ) )) |
| 0 | - | 447 | return - 1 | |
| 0 | 0 | - | 447 | do-while (0) |
| 448 | ||||
| 449 | memset(&info, 0, sizeof(info)); | |||
| 450 | strncpy(info.name, dev->netdev->name, sizeof(info.name)-1); | |||
| 451 | ||||