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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <linux/module.h>
00040
00041 #include <linux/kernel.h>
00042 #include <linux/types.h>
00043 #include <linux/ioport.h>
00044 #include <linux/malloc.h>
00045 #include <linux/string.h>
00046 #include <linux/skbuff.h>
00047 #include <linux/serial_reg.h>
00048 #include <linux/errno.h>
00049 #include <linux/init.h>
00050 #include <asm/spinlock.h>
00051 #include <linux/rtnetlink.h>
00052
00053 #include <asm/system.h>
00054 #include <asm/bitops.h>
00055 #include <asm/io.h>
00056
00057 #include <net/irda/irda.h>
00058 #include <net/irda/irmod.h>
00059 #include <net/irda/wrapper.h>
00060 #include <net/irda/irport.h>
00061
00062 #define IO_EXTENT 8
00063
00064
00065
00066
00067
00068 static unsigned int io[] = { ~0, ~0, ~0, ~0 };
00069 static unsigned int irq[] = { 0, 0, 0, 0 };
00070
00071 static unsigned int qos_mtt_bits = 0x03;
00072
00073 static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
00074 static char *driver_name = "irport";
00075
00076 static void irport_write_wakeup(struct irport_cb *self);
00077 static int irport_write(int iobase, int fifo_size, __u8 *buf, int len);
00078 static void irport_receive(struct irport_cb *self);
00079
00080 static int irport_net_init(struct device *dev);
00081 static int irport_net_ioctl(struct device *dev, struct ifreq *rq,
00082 int cmd);
00083 static int irport_is_receiving(struct irport_cb *self);
00084 static int irport_set_dtr_rts(struct device *dev, int dtr, int rts);
00085 static int irport_raw_write(struct device *dev, __u8 *buf, int len);
00086 static struct net_device_stats *irport_net_get_stats(struct device *dev);
00087 static int irport_change_speed_complete(struct irda_task *task);
00088
00089 EXPORT_SYMBOL(irport_open);
00090 EXPORT_SYMBOL(irport_close);
00091 EXPORT_SYMBOL(irport_start);
00092 EXPORT_SYMBOL(irport_stop);
00093 EXPORT_SYMBOL(irport_interrupt);
00094 EXPORT_SYMBOL(irport_hard_xmit);
00095 EXPORT_SYMBOL(irport_change_speed);
00096 EXPORT_SYMBOL(irport_net_open);
00097 EXPORT_SYMBOL(irport_net_close);
00098
00099 int __init irport_init(void)
00100 {
00101 int i;
00102
00103 for (i=0; (io[i] < 2000) && (i < 4); i++) {
00104 int ioaddr = io[i];
00105 if (check_region(ioaddr, IO_EXTENT))
00106 continue;
00107 if (irport_open(i, io[i], irq[i]) != NULL)
00108 return 0;
00109 }
00110
00111
00112
00113 return 0;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 #ifdef MODULE
00123 static void irport_cleanup(void)
00124 {
00125 int i;
00126
00127 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
00128
00129 for (i=0; i < 4; i++) {
00130 if (dev_self[i])
00131 irport_close(dev_self[i]);
00132 }
00133 }
00134 #endif
00135
00136 struct irport_cb *
00137 irport_open(int i, unsigned int iobase, unsigned int irq)
00138 {
00139 struct device *dev;
00140 struct irport_cb *self;
00141 int ret;
00142 int err;
00143
00144 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00145
00146
00147
00148
00149 self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL);
00150 if (!self) {
00151 ERROR(__FUNCTION__ "(), can't allocate memory for "
00152 "control block!\n");
00153 return NULL;
00154 }
00155 memset(self, 0, sizeof(struct irport_cb));
00156 spin_lock_init(&self->lock);
00157
00158
00159 dev_self[i] = self;
00160 self->priv = self;
00161 self->index = i;
00162
00163
00164 self->io.sir_base = iobase;
00165 self->io.sir_ext = IO_EXTENT;
00166 self->io.irq = irq;
00167 self->io.fifo_size = 16;
00168
00169
00170 ret = check_region(self->io.sir_base, self->io.sir_ext);
00171 if (ret < 0) {
00172 IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
00173 self->io.sir_base);
00174 return NULL;
00175 }
00176 request_region(self->io.sir_base, self->io.sir_ext, driver_name);
00177
00178
00179 irda_init_max_qos_capabilies(&self->qos);
00180
00181 self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
00182 IR_115200;
00183
00184 self->qos.min_turn_time.bits = qos_mtt_bits;
00185 irda_qos_bits_to_value(&self->qos);
00186
00187 self->flags = IFF_SIR|IFF_PIO;
00188
00189
00190 self->rx_buff.truesize = 4000;
00191 self->tx_buff.truesize = 4000;
00192
00193
00194 if (self->rx_buff.truesize > 0) {
00195 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
00196 GFP_KERNEL);
00197 if (self->rx_buff.head == NULL)
00198 return NULL;
00199 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
00200 }
00201 if (self->tx_buff.truesize > 0) {
00202 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
00203 GFP_KERNEL);
00204 if (self->tx_buff.head == NULL) {
00205 kfree(self->rx_buff.head);
00206 return NULL;
00207 }
00208 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
00209 }
00210 self->rx_buff.in_frame = FALSE;
00211 self->rx_buff.state = OUTSIDE_FRAME;
00212 self->tx_buff.data = self->tx_buff.head;
00213 self->rx_buff.data = self->rx_buff.head;
00214 self->mode = IRDA_IRLAP;
00215
00216 if (!(dev = dev_alloc("irda%d", &err))) {
00217 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
00218 return NULL;
00219 }
00220
00221 memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct device)-sizeof(char*));
00222
00223 self->netdev = dev;
00224
00225
00226 dev->priv = (void *) self;
00227 self->interrupt = irport_interrupt;
00228 self->change_speed = irport_change_speed;
00229
00230
00231 dev->init = irport_net_init;
00232 dev->hard_start_xmit = irport_hard_xmit;
00233 dev->open = irport_net_open;
00234 dev->stop = irport_net_close;
00235 dev->get_stats = irport_net_get_stats;
00236 dev->do_ioctl = irport_net_ioctl;
00237
00238
00239 dev->base_addr = iobase;
00240 dev->irq = irq;
00241
00242 rtnl_lock();
00243 err = register_netdevice(dev);
00244 rtnl_unlock();
00245 if (err) {
00246 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
00247 return NULL;
00248 }
00249 MESSAGE("IrDA: Registered device %s\n", dev->name);
00250
00251 return self;
00252 }
00253
00254 int irport_close(struct irport_cb *self)
00255 {
00256 ASSERT(self != NULL, return -1;);
00257
00258
00259 if (self->dongle)
00260 irda_device_dongle_cleanup(self->dongle);
00261 self->dongle = NULL;
00262
00263
00264 if (self->netdev) {
00265 rtnl_lock();
00266 unregister_netdevice(self->netdev);
00267 rtnl_unlock();
00268
00269 kfree(self->netdev);
00270 }
00271
00272
00273 IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n",
00274 self->io.sir_base);
00275 release_region(self->io.sir_base, self->io.sir_ext);
00276
00277 if (self->tx_buff.head)
00278 kfree(self->tx_buff.head);
00279
00280 if (self->rx_buff.head)
00281 kfree(self->rx_buff.head);
00282
00283
00284 dev_self[self->index] = NULL;
00285 kfree(self);
00286
00287 return 0;
00288 }
00289
00290 void irport_start(struct irport_cb *self)
00291 {
00292 unsigned long flags;
00293 int iobase;
00294
00295 iobase = self->io.sir_base;
00296
00297 spin_lock_irqsave(&self->lock, flags);
00298
00299 irport_stop(self);
00300
00301
00302 outb(UART_LCR_WLEN8, iobase+UART_LCR);
00303 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
00304
00305
00306 outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
00307
00308 spin_unlock_irqrestore(&self->lock, flags);
00309 }
00310
00311 void irport_stop(struct irport_cb *self)
00312 {
00313 unsigned long flags;
00314 int iobase;
00315
00316 iobase = self->io.sir_base;
00317
00318 spin_lock_irqsave(&self->lock, flags);
00319
00320
00321 outb(0, iobase+UART_MCR);
00322
00323
00324 outb(0, iobase+UART_IER);
00325
00326 spin_unlock_irqrestore(&self->lock, flags);
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 int irport_probe(int iobase)
00336 {
00337 IRDA_DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
00338
00339 return 0;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 void irport_change_speed(void *priv, __u32 speed)
00349 {
00350 struct irport_cb *self = (struct irport_cb *) priv;
00351 unsigned long flags;
00352 int iobase;
00353 int fcr;
00354 int lcr;
00355 int divisor;
00356
00357 IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed);
00358
00359 ASSERT(self != NULL, return;);
00360
00361 iobase = self->io.sir_base;
00362
00363
00364 self->io.speed = speed;
00365
00366 spin_lock_irqsave(&self->lock, flags);
00367
00368
00369 outb(0, iobase+UART_IER);
00370
00371 divisor = SPEED_MAX/speed;
00372
00373 fcr = UART_FCR_ENABLE_FIFO;
00374
00375
00376
00377
00378
00379
00380 if (self->io.speed < 38400)
00381 fcr |= UART_FCR_TRIGGER_1;
00382 else
00383 fcr |= UART_FCR_TRIGGER_14;
00384
00385
00386 lcr = UART_LCR_WLEN8;
00387
00388 outb(UART_LCR_DLAB | lcr, iobase+UART_LCR);
00389 outb(divisor & 0xff, iobase+UART_DLL);
00390 outb(divisor >> 8, iobase+UART_DLM);
00391 outb(lcr, iobase+UART_LCR);
00392 outb(fcr, iobase+UART_FCR);
00393
00394
00395 outb(UART_IER_RDI, iobase+UART_IER);
00396
00397 spin_unlock_irqrestore(&self->lock, flags);
00398 }
00399
00400
00401
00402
00403
00404
00405
00406 int __irport_change_speed(struct irda_task *task)
00407 {
00408 struct irport_cb *self;
00409 __u32 speed = (__u32) task->param;
00410 int ret = 0;
00411
00412 IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies);
00413
00414 self = (struct irport_cb *) task->instance;
00415
00416 ASSERT(self != NULL, return -1;);
00417
00418 switch (task->state) {
00419 case IRDA_TASK_INIT:
00420 case IRDA_TASK_WAIT:
00421
00422 if (self->tx_buff.len > 0) {
00423 task->state = IRDA_TASK_WAIT;
00424
00425
00426 ret = MSECS_TO_JIFFIES(20);
00427 break;
00428 }
00429
00430 if (self->dongle)
00431 irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
00432 else
00433 irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00434 break;
00435 case IRDA_TASK_CHILD_INIT:
00436
00437 self->change_speed(self->priv, 9600);
00438
00439
00440 if (irda_task_execute(self->dongle,
00441 self->dongle->issue->change_speed,
00442 NULL, task, (void *) speed))
00443 {
00444
00445 irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
00446
00447
00448 ret = MSECS_TO_JIFFIES(1000);
00449 } else
00450
00451 irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00452 break;
00453 case IRDA_TASK_CHILD_WAIT:
00454 WARNING(__FUNCTION__
00455 "(), changing speed of dongle timed out!\n");
00456 ret = -1;
00457 break;
00458 case IRDA_TASK_CHILD_DONE:
00459
00460 self->change_speed(self->priv, speed);
00461
00462 irda_task_next_state(task, IRDA_TASK_DONE);
00463 break;
00464 default:
00465 ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
00466 irda_task_next_state(task, IRDA_TASK_DONE);
00467 ret = -1;
00468 break;
00469 }
00470 return ret;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 static void irport_write_wakeup(struct irport_cb *self)
00481 {
00482 int actual = 0;
00483 int iobase;
00484 int fcr;
00485
00486 ASSERT(self != NULL, return;);
00487
00488 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00489
00490 iobase = self->io.sir_base;
00491
00492
00493 if (self->tx_buff.len > 0) {
00494
00495 actual = irport_write(iobase, self->io.fifo_size,
00496 self->tx_buff.data, self->tx_buff.len);
00497 self->tx_buff.data += actual;
00498 self->tx_buff.len -= actual;
00499 } else {
00500
00501
00502
00503
00504
00505
00506 if (self->new_speed) {
00507 IRDA_DEBUG(5, __FUNCTION__ "(), Changing speed!\n");
00508 irda_task_execute(self, __irport_change_speed,
00509 irport_change_speed_complete,
00510 NULL, (void *) self->new_speed);
00511 self->new_speed = 0;
00512 } else {
00513 self->netdev->tbusy = 0;
00514
00515
00516 mark_bh(NET_BH);
00517 }
00518 self->stats.tx_packets++;
00519
00520
00521 mark_bh(NET_BH);
00522
00523
00524
00525
00526
00527 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR;
00528 if (self->io.speed < 38400)
00529 fcr |= UART_FCR_TRIGGER_1;
00530 else
00531 fcr |= UART_FCR_TRIGGER_14;
00532
00533 outb(fcr, iobase+UART_FCR);
00534
00535
00536 outb(UART_IER_RDI, iobase+UART_IER);
00537 }
00538 }
00539
00540
00541
00542
00543
00544
00545
00546 static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
00547 {
00548 int actual = 0;
00549
00550
00551 if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
00552 IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
00553 return 0;
00554 }
00555
00556
00557 while ((fifo_size-- > 0) && (actual < len)) {
00558
00559 outb(buf[actual], iobase+UART_TX);
00560
00561 actual++;
00562 }
00563
00564 return actual;
00565 }
00566
00567
00568
00569
00570
00571
00572
00573 static int irport_change_speed_complete(struct irda_task *task)
00574 {
00575 struct irport_cb *self;
00576
00577 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00578
00579 self = (struct irport_cb *) task->instance;
00580
00581 ASSERT(self != NULL, return -1;);
00582 ASSERT(self->netdev != NULL, return -1;);
00583
00584
00585 self->netdev->tbusy = 0;
00586
00587
00588 mark_bh(NET_BH);
00589
00590 return 0;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600 int irport_hard_xmit(struct sk_buff *skb, struct device *dev)
00601 {
00602 struct irport_cb *self;
00603 unsigned long flags;
00604 int iobase;
00605 __u32 speed;
00606
00607 ASSERT(dev != NULL, return 0;);
00608
00609 self = (struct irport_cb *) dev->priv;
00610 ASSERT(self != NULL, return 0;);
00611
00612 iobase = self->io.sir_base;
00613
00614
00615 if (irda_lock((void *) &dev->tbusy) == FALSE) {
00616 int tickssofar = jiffies - dev->trans_start;
00617 if ((tickssofar < 5) || !dev->start)
00618 return -EBUSY;
00619
00620 WARNING("%s: transmit timed out\n", dev->name);
00621 irport_start(self);
00622 self->change_speed(self->priv, self->io.speed);
00623
00624 dev->trans_start = jiffies;
00625 }
00626
00627
00628 if ((speed = irda_get_speed(skb)) != self->io.speed)
00629 self->new_speed = speed;
00630
00631 spin_lock_irqsave(&self->lock, flags);
00632
00633
00634 self->tx_buff.data = self->tx_buff.head;
00635
00636
00637 self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
00638 self->tx_buff.truesize);
00639
00640 self->stats.tx_bytes += self->tx_buff.len;
00641
00642
00643 outb(UART_IER_THRI, iobase+UART_IER);
00644
00645 spin_unlock_irqrestore(&self->lock, flags);
00646
00647 dev_kfree_skb(skb);
00648
00649 return 0;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658 static void irport_receive(struct irport_cb *self)
00659 {
00660 int boguscount = 0;
00661 int iobase;
00662
00663 ASSERT(self != NULL, return;);
00664
00665 iobase = self->io.sir_base;
00666
00667
00668
00669
00670
00671 do {
00672 async_unwrap_char(self->netdev, &self->stats, &self->rx_buff,
00673 inb(iobase+UART_RX));
00674
00675
00676 if (boguscount++ > 32) {
00677 IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n");
00678 break;
00679 }
00680 } while (inb(iobase+UART_LSR) & UART_LSR_DR);
00681 }
00682
00683
00684
00685
00686
00687
00688 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
00689 {
00690 struct device *dev = (struct device *) dev_id;
00691 struct irport_cb *self;
00692 int boguscount = 0;
00693 int iobase;
00694 int iir, lsr;
00695
00696 if (!dev) {
00697 WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq);
00698 return;
00699 }
00700 self = (struct irport_cb *) dev->priv;
00701
00702 spin_lock(&self->lock);
00703
00704 dev->interrupt = 1;
00705
00706 iobase = self->io.sir_base;
00707
00708 iir = inb(iobase+UART_IIR) & UART_IIR_ID;
00709 while (iir) {
00710
00711 lsr = inb(iobase+UART_LSR);
00712
00713 IRDA_DEBUG(4, __FUNCTION__
00714 "(), iir=%02x, lsr=%02x, iobase=%#x\n",
00715 iir, lsr, iobase);
00716
00717 switch (iir) {
00718 case UART_IIR_RLSI:
00719 IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n");
00720 break;
00721 case UART_IIR_RDI:
00722
00723 irport_receive(self);
00724 break;
00725 case UART_IIR_THRI:
00726 if (lsr & UART_LSR_THRE)
00727
00728 irport_write_wakeup(self);
00729 break;
00730 default:
00731 IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
00732 break;
00733 }
00734
00735
00736 if (boguscount++ > 100)
00737 break;
00738
00739 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
00740 }
00741 dev->interrupt = 0;
00742
00743 spin_unlock(&self->lock);
00744 }
00745
00746 static int irport_net_init(struct device *dev)
00747 {
00748
00749 irda_device_setup(dev);
00750
00751
00752
00753 return 0;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762 int irport_net_open(struct device *dev)
00763 {
00764 struct irport_cb *self;
00765 int iobase;
00766
00767 ASSERT(dev != NULL, return -1;);
00768 self = (struct irport_cb *) dev->priv;
00769
00770 iobase = self->io.sir_base;
00771
00772 if (request_irq(self->io.irq, self->interrupt, 0, dev->name,
00773 (void *) dev))
00774 return -EAGAIN;
00775
00776 irport_start(self);
00777
00778
00779 dev->tbusy = 0;
00780 dev->interrupt = 0;
00781 dev->start = 1;
00782
00783
00784
00785
00786
00787 self->irlap = irlap_open(dev, &self->qos);
00788
00789
00790
00791 MOD_INC_USE_COUNT;
00792
00793 return 0;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802 int irport_net_close(struct device *dev)
00803 {
00804 struct irport_cb *self;
00805 int iobase;
00806
00807 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00808
00809 ASSERT(dev != NULL, return -1;);
00810 self = (struct irport_cb *) dev->priv;
00811
00812 ASSERT(self != NULL, return -1;);
00813
00814 iobase = self->io.sir_base;
00815
00816
00817 dev->tbusy = 1;
00818 dev->start = 0;
00819
00820
00821 if (self->irlap)
00822 irlap_close(self->irlap);
00823 self->irlap = NULL;
00824
00825 irport_stop(self);
00826
00827 free_irq(self->io.irq, dev);
00828
00829 MOD_DEC_USE_COUNT;
00830
00831 return 0;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840 #if 0
00841 void irport_wait_until_sent(struct irport_cb *self)
00842 {
00843 int iobase;
00844
00845 iobase = self->io.sir_base;
00846
00847
00848 while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
00849 IRDA_DEBUG(2, __FUNCTION__ "(), waiting!\n");
00850 current->state = TASK_INTERRUPTIBLE;
00851 schedule_timeout(MSECS_TO_JIFFIES(60));
00852 }
00853 }
00854 #endif
00855
00856
00857
00858
00859
00860
00861
00862 static int irport_is_receiving(struct irport_cb *self)
00863 {
00864 return (self->rx_buff.state != OUTSIDE_FRAME);
00865 }
00866
00867
00868
00869
00870
00871
00872
00873 static int irport_set_dtr_rts(struct device *dev, int dtr, int rts)
00874 {
00875 struct irport_cb *self = dev->priv;
00876 int iobase;
00877
00878 ASSERT(self != NULL, return -1;);
00879
00880 iobase = self->io.sir_base;
00881
00882 if (dtr)
00883 dtr = UART_MCR_DTR;
00884 if (rts)
00885 rts = UART_MCR_RTS;
00886
00887 outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
00888
00889 return 0;
00890 }
00891
00892 static int irport_raw_write(struct device *dev, __u8 *buf, int len)
00893 {
00894 struct irport_cb *self = (struct irport_cb *) dev->priv;
00895 int actual = 0;
00896 int iobase;
00897
00898 ASSERT(self != NULL, return -1;);
00899
00900 iobase = self->io.sir_base;
00901
00902
00903 if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
00904 IRDA_DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
00905 return -1;
00906 }
00907
00908
00909 while (actual < len) {
00910
00911 outb(buf[actual], iobase+UART_TX);
00912 actual++;
00913 }
00914
00915 return actual;
00916 }
00917
00918
00919
00920
00921
00922
00923
00924 static int irport_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
00925 {
00926 struct if_irda_req *irq = (struct if_irda_req *) rq;
00927 struct irport_cb *self;
00928 dongle_t *dongle;
00929 unsigned long flags;
00930 int ret = 0;
00931
00932 ASSERT(dev != NULL, return -1;);
00933
00934 self = dev->priv;
00935
00936 ASSERT(self != NULL, return -1;);
00937
00938 IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
00939
00940
00941 save_flags(flags);
00942 cli();
00943
00944 switch (cmd) {
00945 case SIOCSBANDWIDTH:
00946
00947
00948
00949
00950
00951 if (!in_interrupt() && !capable(CAP_NET_ADMIN))
00952 return -EPERM;
00953 irda_task_execute(self, __irport_change_speed, NULL, NULL,
00954 (void *) irq->ifr_baudrate);
00955 break;
00956 case SIOCSDONGLE:
00957 if (!capable(CAP_NET_ADMIN))
00958 return -EPERM;
00959
00960 dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
00961 if (!dongle)
00962 break;
00963
00964 dongle->set_mode = NULL;
00965 dongle->read = NULL;
00966 dongle->write = irport_raw_write;
00967 dongle->set_dtr_rts = irport_set_dtr_rts;
00968
00969 self->dongle = dongle;
00970
00971
00972 dongle->issue->open(dongle, &self->qos);
00973
00974
00975 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL,
00976 NULL);
00977 break;
00978 case SIOCSMEDIABUSY:
00979 if (!capable(CAP_NET_ADMIN))
00980 return -EPERM;
00981 irda_device_set_media_busy(self->netdev, TRUE);
00982 break;
00983 case SIOCGRECEIVING:
00984 irq->ifr_receiving = irport_is_receiving(self);
00985 break;
00986 case SIOCSDTRRTS:
00987 if (!capable(CAP_NET_ADMIN))
00988 return -EPERM;
00989 irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
00990 break;
00991 default:
00992 ret = -EOPNOTSUPP;
00993 }
00994
00995 restore_flags(flags);
00996
00997 return ret;
00998 }
00999
01000 static struct net_device_stats *irport_net_get_stats(struct device *dev)
01001 {
01002 struct irport_cb *self = (struct irport_cb *) dev->priv;
01003
01004 return &self->stats;
01005 }
01006
01007 #ifdef MODULE
01008 MODULE_PARM(io, "1-4i");
01009 MODULE_PARM(irq, "1-4i");
01010
01011 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
01012 MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
01013
01014 void cleanup_module(void)
01015 {
01016 irport_cleanup();
01017 }
01018
01019 int init_module(void)
01020 {
01021 return irport_init();
01022 }
01023 #endif
01024