00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <linux/module.h>
00028 #include <linux/kernel.h>
00029 #include <linux/tty.h>
00030 #include <linux/init.h>
00031 #include <linux/skbuff.h>
00032 #include <linux/if_arp.h>
00033 #include <linux/rtnetlink.h>
00034
00035 #include <asm/segment.h>
00036 #include <asm/uaccess.h>
00037 #include <asm/termios.h>
00038
00039 #include <net/irda/irda.h>
00040 #include <net/irda/irtty.h>
00041 #include <net/irda/wrapper.h>
00042 #include <net/irda/timer.h>
00043 #include <net/irda/irda_device.h>
00044
00045 static hashbin_t *irtty = NULL;
00046 static struct tty_ldisc irda_ldisc;
00047
00048 static int qos_mtt_bits = 0x03;
00049
00050
00051 static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
00052 static int irtty_net_init(struct device *dev);
00053 static int irtty_net_open(struct device *dev);
00054 static int irtty_net_close(struct device *dev);
00055 static int irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd);
00056 static struct net_device_stats *irtty_net_get_stats(struct device *dev);
00057
00058
00059 static int irtty_open(struct tty_struct *tty);
00060 static void irtty_close(struct tty_struct *tty);
00061 static int irtty_ioctl(struct tty_struct *, void *, int, void *);
00062 static int irtty_receive_room(struct tty_struct *tty);
00063 static void irtty_write_wakeup(struct tty_struct *tty);
00064 static void irtty_receive_buf(struct tty_struct *, const unsigned char *,
00065 char *, int);
00066
00067
00068 static int irtty_is_receiving(struct irtty_cb *self);
00069 static int irtty_set_dtr_rts(struct device *dev, int dtr, int rts);
00070 static int irtty_raw_write(struct device *dev, __u8 *buf, int len);
00071 static int irtty_raw_read(struct device *dev, __u8 *buf, int len);
00072 static int irtty_set_mode(struct device *dev, int mode);
00073 static int irtty_change_speed(struct irda_task *task);
00074
00075 char *driver_name = "irtty";
00076
00077 int __init irtty_init(void)
00078 {
00079 int status;
00080
00081 irtty = hashbin_new( HB_LOCAL);
00082 if ( irtty == NULL) {
00083 printk( KERN_WARNING "IrDA: Can't allocate irtty hashbin!\n");
00084 return -ENOMEM;
00085 }
00086
00087
00088 memset(&irda_ldisc, 0, sizeof( irda_ldisc));
00089
00090 irda_ldisc.magic = TTY_LDISC_MAGIC;
00091 irda_ldisc.name = "irda";
00092 irda_ldisc.flags = 0;
00093 irda_ldisc.open = irtty_open;
00094 irda_ldisc.close = irtty_close;
00095 irda_ldisc.read = NULL;
00096 irda_ldisc.write = NULL;
00097 irda_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
00098 unsigned int, unsigned long)) irtty_ioctl;
00099 irda_ldisc.poll = NULL;
00100 irda_ldisc.receive_buf = irtty_receive_buf;
00101 irda_ldisc.receive_room = irtty_receive_room;
00102 irda_ldisc.write_wakeup = irtty_write_wakeup;
00103
00104 if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) {
00105 ERROR("IrDA: can't register line discipline (err = %d)\n",
00106 status);
00107 }
00108
00109 return status;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 #ifdef MODULE
00119 static void irtty_cleanup(void)
00120 {
00121 int ret;
00122
00123
00124 if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
00125 ERROR(__FUNCTION__
00126 "(), can't unregister line discipline (err = %d)\n",
00127 ret);
00128 }
00129
00130
00131
00132
00133
00134
00135 hashbin_delete(irtty, NULL);
00136 }
00137 #endif
00138
00139
00140
00141
00142
00143
00144
00145
00146 static int irtty_open(struct tty_struct *tty)
00147 {
00148 struct device *dev;
00149 struct irtty_cb *self;
00150 char name[16];
00151 int err;
00152
00153 ASSERT(tty != NULL, return -EEXIST;);
00154
00155
00156 self = (struct irtty_cb *) tty->disc_data;
00157
00158 if (self != NULL && self->magic == IRTTY_MAGIC)
00159 return -EEXIST;
00160
00161
00162
00163
00164 self = kmalloc(sizeof(struct irtty_cb), GFP_KERNEL);
00165 if (self == NULL) {
00166 printk(KERN_ERR "IrDA: Can't allocate memory for "
00167 "IrDA control block!\n");
00168 return -ENOMEM;
00169 }
00170 memset(self, 0, sizeof(struct irtty_cb));
00171
00172 self->tty = tty;
00173 tty->disc_data = self;
00174
00175
00176 sprintf(name, "%s%d", tty->driver.name,
00177 MINOR(tty->device) - tty->driver.minor_start +
00178 tty->driver.name_base);
00179
00180 hashbin_insert(irtty, (queue_t *) self, (int) self, NULL);
00181
00182 if (tty->driver.flush_buffer)
00183 tty->driver.flush_buffer(tty);
00184
00185 if (tty->ldisc.flush_buffer)
00186 tty->ldisc.flush_buffer(tty);
00187
00188 self->magic = IRTTY_MAGIC;
00189 self->mode = IRDA_IRLAP;
00190
00191
00192
00193
00194
00195
00196
00197 irda_init_max_qos_capabilies(&self->qos);
00198
00199
00200 self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
00201 IR_115200;
00202 self->qos.min_turn_time.bits = qos_mtt_bits;
00203 self->flags = IFF_SIR | IFF_PIO;
00204 irda_qos_bits_to_value(&self->qos);
00205
00206
00207 self->rx_buff.truesize = 4000;
00208 self->tx_buff.truesize = 4000;
00209
00210
00211 if (self->rx_buff.truesize > 0) {
00212 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
00213 GFP_KERNEL);
00214 if (self->rx_buff.head == NULL)
00215 return -ENOMEM;
00216 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
00217 }
00218 if (self->tx_buff.truesize > 0) {
00219 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
00220 GFP_KERNEL);
00221 if (self->tx_buff.head == NULL) {
00222 kfree(self->rx_buff.head);
00223 return -ENOMEM;
00224 }
00225 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
00226 }
00227
00228 self->rx_buff.in_frame = FALSE;
00229 self->rx_buff.state = OUTSIDE_FRAME;
00230 self->tx_buff.data = self->tx_buff.head;
00231 self->rx_buff.data = self->rx_buff.head;
00232
00233 if (!(dev = dev_alloc("irda%d", &err))) {
00234 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
00235 return -ENOMEM;
00236 }
00237
00238 memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct device)-sizeof(char*));
00239
00240 dev->priv = (void *) self;
00241 self->netdev = dev;
00242
00243
00244 dev->init = irtty_net_init;
00245 dev->hard_start_xmit = irtty_hard_xmit;
00246 dev->open = irtty_net_open;
00247 dev->stop = irtty_net_close;
00248 dev->get_stats = irtty_net_get_stats;
00249 dev->do_ioctl = irtty_net_ioctl;
00250
00251 rtnl_lock();
00252 err = register_netdevice(dev);
00253 rtnl_unlock();
00254 if (err) {
00255 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
00256 return -1;
00257 }
00258
00259 MESSAGE("IrDA: Registered device %s\n", dev->name);
00260
00261 MOD_INC_USE_COUNT;
00262
00263 return 0;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273 static void irtty_close(struct tty_struct *tty)
00274 {
00275 struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00276
00277
00278 ASSERT(self != NULL, return;);
00279 ASSERT(self->magic == IRTTY_MAGIC, return;);
00280
00281
00282 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
00283 tty->disc_data = 0;
00284
00285
00286 if (self->dongle)
00287 irda_device_dongle_cleanup(self->dongle);
00288 self->dongle = NULL;
00289
00290
00291 if (self->netdev) {
00292 rtnl_lock();
00293 unregister_netdevice(self->netdev);
00294 rtnl_unlock();
00295
00296 kfree(self->netdev);
00297 }
00298
00299
00300 if (self->task)
00301 irda_task_delete(self->task);
00302
00303 self->tty = NULL;
00304 self->magic = 0;
00305
00306 self = hashbin_remove(irtty, (int) self, NULL);
00307
00308 if (self->tx_buff.head)
00309 kfree(self->tx_buff.head);
00310
00311 if (self->rx_buff.head)
00312 kfree(self->rx_buff.head);
00313
00314 kfree(self);
00315
00316 MOD_DEC_USE_COUNT;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 static void irtty_stop_receiver(struct irtty_cb *self, int stop)
00326 {
00327 struct termios old_termios;
00328 int cflag;
00329
00330 old_termios = *(self->tty->termios);
00331 cflag = self->tty->termios->c_cflag;
00332
00333 if (stop)
00334 cflag &= ~CREAD;
00335 else
00336 cflag |= CREAD;
00337
00338 self->tty->termios->c_cflag = cflag;
00339 self->tty->driver.set_termios(self->tty, &old_termios);
00340 }
00341
00342
00343
00344
00345
00346
00347 static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
00348 {
00349 struct termios old_termios;
00350 int cflag;
00351
00352 ASSERT(self != NULL, return;);
00353 ASSERT(self->magic == IRTTY_MAGIC, return;);
00354
00355 old_termios = *(self->tty->termios);
00356 cflag = self->tty->termios->c_cflag;
00357
00358 cflag &= ~CBAUD;
00359
00360 IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to %d\n", speed);
00361
00362 switch (speed) {
00363 case 1200:
00364 cflag |= B1200;
00365 break;
00366 case 2400:
00367 cflag |= B2400;
00368 break;
00369 case 4800:
00370 cflag |= B4800;
00371 break;
00372 case 19200:
00373 cflag |= B19200;
00374 break;
00375 case 38400:
00376 cflag |= B38400;
00377 break;
00378 case 57600:
00379 cflag |= B57600;
00380 break;
00381 case 115200:
00382 cflag |= B115200;
00383 break;
00384 case 9600:
00385 default:
00386 cflag |= B9600;
00387 break;
00388 }
00389
00390 self->tty->termios->c_cflag = cflag;
00391 self->tty->driver.set_termios(self->tty, &old_termios);
00392
00393 self->io.speed = speed;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 static int irtty_change_speed(struct irda_task *task)
00403 {
00404 struct irtty_cb *self;
00405 __u32 speed = (__u32) task->param;
00406 int ret = 0;
00407
00408 IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies);
00409
00410 self = (struct irtty_cb *) task->instance;
00411 ASSERT(self != NULL, return -1;);
00412
00413
00414 if (self->task && self->task != task) {
00415 IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
00416 return MSECS_TO_JIFFIES(10);
00417 } else
00418 self->task = task;
00419
00420 switch (task->state) {
00421 case IRDA_TASK_INIT:
00422
00423
00424
00425
00426 if (self->tty->driver.chars_in_buffer(self->tty)) {
00427
00428 ret = MSECS_TO_JIFFIES(10);
00429 break;
00430 } else {
00431
00432
00433
00434
00435 irda_task_next_state(task, IRDA_TASK_WAIT);
00436 ret = MSECS_TO_JIFFIES(13);
00437 }
00438 case IRDA_TASK_WAIT:
00439 if (self->dongle)
00440 irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
00441 else
00442 irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00443 break;
00444 case IRDA_TASK_CHILD_INIT:
00445
00446 __irtty_change_speed(self, 9600);
00447
00448
00449 if (irda_task_execute(self->dongle,
00450 self->dongle->issue->change_speed,
00451 NULL, task, (void *) speed))
00452 {
00453
00454 irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
00455
00456
00457 ret = MSECS_TO_JIFFIES(1000);
00458 } else
00459
00460 irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00461 break;
00462 case IRDA_TASK_CHILD_WAIT:
00463 WARNING(__FUNCTION__
00464 "(), changing speed of dongle timed out!\n");
00465 ret = -1;
00466 break;
00467 case IRDA_TASK_CHILD_DONE:
00468
00469 __irtty_change_speed(self, speed);
00470
00471 irda_task_next_state(task, IRDA_TASK_DONE);
00472 self->task = NULL;
00473 break;
00474 default:
00475 ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
00476 irda_task_next_state(task, IRDA_TASK_DONE);
00477 self->task = NULL;
00478 ret = -1;
00479 break;
00480 }
00481 return ret;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
00491 {
00492 dongle_t *dongle;
00493 struct irtty_info info;
00494 struct irtty_cb *self;
00495 int size = _IOC_SIZE(cmd);
00496 int err = 0;
00497
00498 self = (struct irtty_cb *) tty->disc_data;
00499
00500 ASSERT(self != NULL, return -ENODEV;);
00501 ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
00502
00503 if (_IOC_DIR(cmd) & _IOC_READ)
00504 err = verify_area(VERIFY_WRITE, (void *) arg, size);
00505 else if (_IOC_DIR(cmd) & _IOC_WRITE)
00506 err = verify_area(VERIFY_READ, (void *) arg, size);
00507 if (err)
00508 return err;
00509
00510 switch (cmd) {
00511 case TCGETS:
00512 case TCGETA:
00513 return n_tty_ioctl(tty, (struct file *) file, cmd,
00514 (unsigned long) arg);
00515 break;
00516 case IRTTY_IOCTDONGLE:
00517
00518 dongle = irda_device_dongle_init(self->netdev, (int) arg);
00519 if (!dongle)
00520 break;
00521
00522
00523 dongle->set_mode = irtty_set_mode;
00524 dongle->read = irtty_raw_read;
00525 dongle->write = irtty_raw_write;
00526 dongle->set_dtr_rts = irtty_set_dtr_rts;
00527
00528
00529 self->dongle = dongle;
00530
00531
00532 dongle->issue->open(dongle, &self->qos);
00533
00534
00535 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL,
00536 NULL);
00537 break;
00538 case IRTTY_IOCGET:
00539 ASSERT(self->netdev != NULL, return -1;);
00540
00541 memset(&info, 0, sizeof(struct irtty_info));
00542 strncpy(info.name, self->netdev->name, 5);
00543
00544 if (copy_to_user(arg, &info, sizeof(struct irtty_info)))
00545 return -EFAULT;
00546 break;
00547 default:
00548 return -ENOIOCTLCMD;
00549 }
00550 return 0;
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
00562 char *fp, int count)
00563 {
00564 struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00565
00566 IRDA_DEBUG(2, __FUNCTION__ "(%ld)\n", jiffies);
00567
00568 if (!self || !self->netdev) {
00569 IRDA_DEBUG(0, __FUNCTION__ "(), not ready yet!\n");
00570 return;
00571 }
00572
00573
00574 while (count--) {
00575
00576
00577
00578 if (fp && *fp++) {
00579 IRDA_DEBUG(0, "Framing or parity error!\n");
00580 irda_device_set_media_busy(self->netdev, TRUE);
00581
00582 cp++;
00583 continue;
00584 }
00585
00586 switch (self->mode) {
00587 case IRDA_IRLAP:
00588
00589 async_unwrap_char(self->netdev, &self->stats,
00590 &self->rx_buff, *cp++);
00591 break;
00592 case IRDA_RAW:
00593
00594 if (self->rx_buff.len == self->rx_buff.truesize)
00595 self->rx_buff.len = 0;
00596
00597 self->rx_buff.data[self->rx_buff.len++] = *cp++;
00598 break;
00599 default:
00600 break;
00601 }
00602 }
00603 }
00604
00605
00606
00607
00608
00609
00610
00611 static int irtty_change_speed_complete(struct irda_task *task)
00612 {
00613 struct irtty_cb *self;
00614
00615 IRDA_DEBUG(2, __FUNCTION__ "()\n");
00616
00617 self = (struct irtty_cb *) task->instance;
00618
00619 ASSERT(self != NULL, return -1;);
00620 ASSERT(self->netdev != NULL, return -1;);
00621
00622
00623 self->netdev->tbusy = 0;
00624
00625
00626 mark_bh(NET_BH);
00627
00628 return 0;
00629 }
00630
00631
00632
00633
00634
00635
00636
00637 static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev)
00638 {
00639 struct irtty_cb *self;
00640 int actual = 0;
00641 __u32 speed;
00642
00643 self = (struct irtty_cb *) dev->priv;
00644 ASSERT(self != NULL, return 0;);
00645
00646
00647 if (irda_lock((void *) &dev->tbusy) == FALSE)
00648 return -EBUSY;
00649
00650
00651 if ((speed = irda_get_speed(skb)) != self->io.speed)
00652 self->new_speed = speed;
00653
00654
00655 self->tx_buff.data = self->tx_buff.head;
00656
00657
00658 self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
00659 self->tx_buff.truesize);
00660
00661 self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
00662
00663 dev->trans_start = jiffies;
00664 self->stats.tx_bytes += self->tx_buff.len;
00665
00666 if (self->tty->driver.write)
00667 actual = self->tty->driver.write(self->tty, 0,
00668 self->tx_buff.data,
00669 self->tx_buff.len);
00670
00671 self->tx_buff.data += actual;
00672 self->tx_buff.len -= actual;
00673
00674 dev_kfree_skb(skb);
00675
00676 return 0;
00677 }
00678
00679
00680
00681
00682
00683
00684
00685 static int irtty_receive_room(struct tty_struct *tty)
00686 {
00687 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00688 return 65536;
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698 static void irtty_write_wakeup(struct tty_struct *tty)
00699 {
00700 struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00701 int actual = 0;
00702
00703
00704
00705
00706 ASSERT(self != NULL, return;);
00707 ASSERT(self->magic == IRTTY_MAGIC, return;);
00708
00709
00710 if (self->tx_buff.len > 0) {
00711
00712 actual = tty->driver.write(tty, 0, self->tx_buff.data,
00713 self->tx_buff.len);
00714
00715 self->tx_buff.data += actual;
00716 self->tx_buff.len -= actual;
00717 } else {
00718
00719
00720
00721
00722 IRDA_DEBUG(5, __FUNCTION__ "(), finished with frame!\n");
00723
00724 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
00725
00726 if (self->new_speed) {
00727 IRDA_DEBUG(5, __FUNCTION__ "(), Changing speed!\n");
00728 irda_task_execute(self, irtty_change_speed,
00729 irtty_change_speed_complete,
00730 NULL, (void *) self->new_speed);
00731 self->new_speed = 0;
00732 } else {
00733 self->netdev->tbusy = 0;
00734
00735
00736 mark_bh(NET_BH);
00737 }
00738 self->stats.tx_packets++;
00739 }
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 static int irtty_is_receiving(struct irtty_cb *self)
00749 {
00750 return (self->rx_buff.state != OUTSIDE_FRAME);
00751 }
00752
00753
00754
00755
00756
00757
00758
00759 static int irtty_set_dtr_rts(struct device *dev, int dtr, int rts)
00760 {
00761 struct irtty_cb *self;
00762 struct tty_struct *tty;
00763 mm_segment_t fs;
00764 int arg = 0;
00765
00766 self = (struct irtty_cb *) dev->priv;
00767 tty = self->tty;
00768
00769 #ifdef TIOCM_OUT2
00770 arg = TIOCM_OUT2;
00771 #endif
00772 if (rts)
00773 arg |= TIOCM_RTS;
00774 if (dtr)
00775 arg |= TIOCM_DTR;
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 fs = get_fs();
00786 set_fs(get_ds());
00787
00788 if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) {
00789 IRDA_DEBUG(2, __FUNCTION__ "(), error doing ioctl!\n");
00790 }
00791 set_fs(fs);
00792
00793 return 0;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 int irtty_set_mode(struct device *dev, int mode)
00805 {
00806 struct irtty_cb *self;
00807
00808 self = (struct irtty_cb *) dev->priv;
00809
00810 ASSERT(self != NULL, return -1;);
00811
00812 IRDA_DEBUG(2, __FUNCTION__ "(), mode=%s\n", infrared_mode[mode]);
00813
00814
00815 self->mode = mode;
00816
00817
00818 self->rx_buff.data = self->rx_buff.head;
00819 self->rx_buff.len = 0;
00820 self->rx_buff.state = OUTSIDE_FRAME;
00821
00822 return 0;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832 static int irtty_raw_read(struct device *dev, __u8 *buf, int len)
00833 {
00834 struct irtty_cb *self;
00835 int count;
00836
00837 self = (struct irtty_cb *) dev->priv;
00838
00839 ASSERT(self != NULL, return 0;);
00840 ASSERT(self->magic == IRTTY_MAGIC, return 0;);
00841
00842 return 0;
00843 #if 0
00844 buf = self->rx_buff.data;
00845
00846
00847 while (len < self->rx_buff.len) {
00848 current->state = TASK_INTERRUPTIBLE;
00849 schedule_timeout(MSECS_TO_JIFFIES(10));
00850
00851 if (!timeout--)
00852 break;
00853 }
00854
00855 count = self->rx_buff.len < len ? self->rx_buff.len : len;
00856
00857
00858
00859
00860
00861
00862 self->rx_buff.data = self->rx_buff.head;
00863 self->rx_buff.len = 0;
00864 self->rx_buff.state = OUTSIDE_FRAME;
00865 #endif
00866
00867 return count;
00868 }
00869
00870 static int irtty_raw_write(struct device *dev, __u8 *buf, int len)
00871 {
00872 struct irtty_cb *self;
00873 int actual = 0;
00874
00875 self = (struct irtty_cb *) dev->priv;
00876
00877 ASSERT(self != NULL, return 0;);
00878 ASSERT(self->magic == IRTTY_MAGIC, return 0;);
00879
00880 if (self->tty->driver.write)
00881 actual = self->tty->driver.write(self->tty, 0, buf, len);
00882
00883 return actual;
00884 }
00885
00886 static int irtty_net_init(struct device *dev)
00887 {
00888
00889 irda_device_setup(dev);
00890
00891
00892
00893 return 0;
00894 }
00895
00896 static int irtty_net_open(struct device *dev)
00897 {
00898 struct irtty_cb *self = (struct irtty_cb *) dev->priv;
00899
00900 ASSERT(self != NULL, return -1;);
00901 ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00902
00903 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00904
00905
00906 dev->tbusy = 0;
00907 dev->interrupt = 0;
00908 dev->start = 1;
00909
00910
00911 irtty_stop_receiver(self, FALSE);
00912
00913
00914
00915
00916
00917 self->irlap = irlap_open(dev, &self->qos);
00918
00919 MOD_INC_USE_COUNT;
00920
00921 return 0;
00922 }
00923
00924 static int irtty_net_close(struct device *dev)
00925 {
00926 struct irtty_cb *self = (struct irtty_cb *) dev->priv;
00927
00928 ASSERT(self != NULL, return -1;);
00929 ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00930
00931
00932 irtty_stop_receiver(self, TRUE);
00933
00934
00935 dev->tbusy = 1;
00936 dev->start = 0;
00937
00938
00939 if (self->irlap)
00940 irlap_close(self->irlap);
00941 self->irlap = NULL;
00942
00943 MOD_DEC_USE_COUNT;
00944
00945 return 0;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954 static int irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
00955 {
00956 struct if_irda_req *irq = (struct if_irda_req *) rq;
00957 struct irtty_cb *self;
00958 dongle_t *dongle;
00959 unsigned long flags;
00960 int ret = 0;
00961
00962 ASSERT(dev != NULL, return -1;);
00963
00964 self = dev->priv;
00965
00966 ASSERT(self != NULL, return -1;);
00967 ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00968
00969 IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
00970
00971
00972 save_flags(flags);
00973 cli();
00974
00975 switch (cmd) {
00976 case SIOCSBANDWIDTH:
00977
00978
00979
00980
00981
00982 if (!in_interrupt() && !capable(CAP_NET_ADMIN))
00983 return -EPERM;
00984 irda_task_execute(self, irtty_change_speed, NULL, NULL,
00985 (void *) irq->ifr_baudrate);
00986 break;
00987 case SIOCSDONGLE:
00988 if (!capable(CAP_NET_ADMIN))
00989 return -EPERM;
00990
00991 dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
00992 if (!dongle)
00993 break;
00994
00995 dongle->set_mode = irtty_set_mode;
00996 dongle->read = irtty_raw_read;
00997 dongle->write = irtty_raw_write;
00998 dongle->set_dtr_rts = irtty_set_dtr_rts;
00999
01000 self->dongle = dongle;
01001
01002
01003 dongle->issue->open(dongle, &self->qos);
01004
01005
01006 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL,
01007 NULL);
01008 break;
01009 case SIOCSMEDIABUSY:
01010 if (!capable(CAP_NET_ADMIN))
01011 return -EPERM;
01012 irda_device_set_media_busy(self->netdev, TRUE);
01013 break;
01014 case SIOCGRECEIVING:
01015 irq->ifr_receiving = irtty_is_receiving(self);
01016 break;
01017 case SIOCSDTRRTS:
01018 if (!capable(CAP_NET_ADMIN))
01019 return -EPERM;
01020 irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
01021 break;
01022 case SIOCSMODE:
01023 if (!capable(CAP_NET_ADMIN))
01024 return -EPERM;
01025 irtty_set_mode(dev, irq->ifr_mode);
01026 break;
01027 default:
01028 ret = -EOPNOTSUPP;
01029 }
01030
01031 restore_flags(flags);
01032
01033 return ret;
01034 }
01035
01036 static struct net_device_stats *irtty_net_get_stats(struct device *dev)
01037 {
01038 struct irtty_cb *self = (struct irtty_cb *) dev->priv;
01039
01040 return &self->stats;
01041 }
01042
01043 #ifdef MODULE
01044
01045 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
01046 MODULE_DESCRIPTION("IrDA TTY device driver");
01047
01048 MODULE_PARM(qos_mtt_bits, "i");
01049
01050
01051
01052
01053
01054
01055
01056 int init_module(void)
01057 {
01058 return irtty_init();
01059 }
01060
01061
01062
01063
01064
01065
01066
01067 void cleanup_module(void)
01068 {
01069 irtty_cleanup();
01070 }
01071
01072 #endif