Commit 01166d96 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/jgarzik/irda-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents e71eb380 df3a5c9f
...@@ -289,16 +289,29 @@ config TOSHIBA_FIR ...@@ -289,16 +289,29 @@ config TOSHIBA_FIR
<file:Documentation/modules.txt>. <file:Documentation/modules.txt>.
The module will be called donauboe. The module will be called donauboe.
config SMC_IRCC_FIR config SMC_IRCC_OLD
tristate "SMC IrCC (EXPERIMENTAL)" tristate "SMC IrCC (old driver) (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA depends on EXPERIMENTAL && IRDA
help help
Say Y here if you want to build support for the SMC Infrared Say Y here if you want to build support for the SMC Infrared
Communications Controller. It is used in the Fujitsu Lifebook 635t Communications Controller. It is used in the Fujitsu Lifebook 635t
and Sony PCG-505TX. If you want to compile it as a module, say M and Sony PCG-505TX. This driver is obsolete, will no more be
here and read <file:Documentation/modules.txt>. The module will be maintained and will be removed in favor of the new driver.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. The module will be
called smc-ircc. called smc-ircc.
config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA
help
Say Y here if you want to build support for the SMC Infrared
Communications Controller. It is used in a wide variety of
laptops (Fujitsu, Sony, Compaq and some Toshiba).
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. The module will be
called smsc-ircc2.o.
config ALI_FIR config ALI_FIR
tristate "ALi M5123 FIR (EXPERIMENTAL)" tristate "ALi M5123 FIR (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA depends on EXPERIMENTAL && IRDA
......
...@@ -15,13 +15,14 @@ obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o ...@@ -15,13 +15,14 @@ obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o
obj-$(CONFIG_TOSHIBA_OLD) += toshoboe.o obj-$(CONFIG_TOSHIBA_OLD) += toshoboe.o
obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o
obj-$(CONFIG_SMC_IRCC_FIR) += smc-ircc.o irport.o obj-$(CONFIG_SMC_IRCC_OLD) += smc-ircc.o irport.o
obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_ALI_FIR) += ali-ircc.o
obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
# Old dongle drivers for old SIR drivers # Old dongle drivers for old SIR drivers
obj-$(CONFIG_ESI_OLD) += esi.o obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
obj-$(CONFIG_TEKRAM_OLD) += tekram.o obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
obj-$(CONFIG_ACTISYS_OLD) += actisys.o obj-$(CONFIG_ACTISYS_DONGLE_OLD) += actisys.o
obj-$(CONFIG_GIRBIL_DONGLE) += girbil.o obj-$(CONFIG_GIRBIL_DONGLE) += girbil.o
obj-$(CONFIG_LITELINK_DONGLE) += litelink.o obj-$(CONFIG_LITELINK_DONGLE) += litelink.o
obj-$(CONFIG_OLD_BELKIN_DONGLE) += old_belkin.o obj-$(CONFIG_OLD_BELKIN_DONGLE) += old_belkin.o
......
...@@ -1451,6 +1451,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1451,6 +1451,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Check for empty frame */ /* Check for empty frame */
if (!skb->len) { if (!skb->len) {
ali_ircc_change_speed(self, speed); ali_ircc_change_speed(self, speed);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -1560,6 +1561,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1560,6 +1561,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Restore bank register */ /* Restore bank register */
switch_bank(iobase, BANK0); switch_bank(iobase, BANK0);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1974,6 +1976,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1974,6 +1976,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Check for empty frame */ /* Check for empty frame */
if (!skb->len) { if (!skb->len) {
ali_ircc_change_speed(self, speed); ali_ircc_change_speed(self, speed);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -1993,6 +1996,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1993,6 +1996,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Turn on transmit finished interrupt. Will fire immediately! */ /* Turn on transmit finished interrupt. Will fire immediately! */
outb(UART_IER_THRI, iobase+UART_IER); outb(UART_IER_THRI, iobase+UART_IER);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
......
...@@ -1051,7 +1051,9 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) ...@@ -1051,7 +1051,9 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
toshoboe_checkstuck (self); toshoboe_checkstuck (self);
/* Check if we need to change the speed */ dev->trans_start = jiffies;
/* Check if we need to change the speed */
/* But not now. Wait after transmission if mtt not required */ /* But not now. Wait after transmission if mtt not required */
speed=irda_get_next_speed(skb); speed=irda_get_next_speed(skb);
if ((speed != self->io.speed) && (speed != -1)) if ((speed != self->io.speed) && (speed != -1))
......
This diff is collapsed.
...@@ -504,10 +504,7 @@ static int irtty_open(struct tty_struct *tty) ...@@ -504,10 +504,7 @@ static int irtty_open(struct tty_struct *tty)
struct sirtty_cb *priv; struct sirtty_cb *priv;
int ret = 0; int ret = 0;
/* unfortunately, there's no tty_ldisc->owner field /* Module stuff handled via irda_ldisc.owner - Jean II */
* so there is some window for SMP race with rmmod
*/
MOD_INC_USE_COUNT;
/* First make sure we're not already connected. */ /* First make sure we're not already connected. */
if (tty->disc_data != NULL) { if (tty->disc_data != NULL) {
...@@ -569,7 +566,6 @@ static int irtty_open(struct tty_struct *tty) ...@@ -569,7 +566,6 @@ static int irtty_open(struct tty_struct *tty)
out_put: out_put:
sirdev_put_instance(dev); sirdev_put_instance(dev);
out: out:
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
...@@ -614,8 +610,6 @@ static void irtty_close(struct tty_struct *tty) ...@@ -614,8 +610,6 @@ static void irtty_close(struct tty_struct *tty)
tty->driver->stop(tty); tty->driver->stop(tty);
kfree(priv); kfree(priv);
MOD_DEC_USE_COUNT;
} }
/* ------------------------------------------------------- */ /* ------------------------------------------------------- */
...@@ -633,6 +627,7 @@ static struct tty_ldisc irda_ldisc = { ...@@ -633,6 +627,7 @@ static struct tty_ldisc irda_ldisc = {
.receive_buf = irtty_receive_buf, .receive_buf = irtty_receive_buf,
.receive_room = irtty_receive_room, .receive_room = irtty_receive_room,
.write_wakeup = irtty_write_wakeup, .write_wakeup = irtty_write_wakeup,
.owner = THIS_MODULE,
}; };
/* ------------------------------------------------------- */ /* ------------------------------------------------------- */
......
...@@ -1096,6 +1096,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) ...@@ -1096,6 +1096,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
* to make sure packets gets through the * to make sure packets gets through the
* proper xmit handler - Jean II */ * proper xmit handler - Jean II */
} }
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -1120,6 +1121,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) ...@@ -1120,6 +1121,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
/* Restore bank register */ /* Restore bank register */
outb(bank, iobase+BSR); outb(bank, iobase+BSR);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1164,6 +1166,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) ...@@ -1164,6 +1166,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
* the speed change has been done. * the speed change has been done.
* Jean II */ * Jean II */
} }
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -1250,6 +1253,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) ...@@ -1250,6 +1253,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
/* Restore bank register */ /* Restore bank register */
outb(bank, iobase+BSR); outb(bank, iobase+BSR);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->lock, flags); spin_unlock_irqrestore(&self->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
......
...@@ -151,6 +151,13 @@ static int irda_thread(void *startup) ...@@ -151,6 +151,13 @@ static int irda_thread(void *startup)
while (irda_rq_queue.thread != NULL) { while (irda_rq_queue.thread != NULL) {
/* We use TASK_INTERRUPTIBLE, rather than
* TASK_UNINTERRUPTIBLE. Andrew Morton made this
* change ; he told me that it is safe, because "signal
* blocking is now handled in daemonize()", he added
* that the problem is that "uninterruptible sleep
* contributes to load average", making user worry.
* Jean II */
set_task_state(current, TASK_INTERRUPTIBLE); set_task_state(current, TASK_INTERRUPTIBLE);
add_wait_queue(&irda_rq_queue.kick, &wait); add_wait_queue(&irda_rq_queue.kick, &wait);
if (list_empty(&irda_rq_queue.request_list)) if (list_empty(&irda_rq_queue.request_list))
......
...@@ -529,6 +529,9 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base) ...@@ -529,6 +529,9 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
irport->priv = self; irport->priv = self;
/* Keep track of module usage */
SET_MODULE_OWNER(self->netdev);
/* Initialize IO */ /* Initialize IO */
self->io = &irport->io; self->io = &irport->io;
self->io->fir_base = fir_base; self->io->fir_base = fir_base;
...@@ -747,6 +750,7 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -747,6 +750,7 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Check for empty frame */ /* Check for empty frame */
if (!skb->len) { if (!skb->len) {
ircc_change_speed(self, speed); ircc_change_speed(self, speed);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->irport->lock, flags); spin_unlock_irqrestore(&self->irport->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -776,6 +780,7 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -776,6 +780,7 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Transmit frame */ /* Transmit frame */
ircc_dma_xmit(self, iobase, 0); ircc_dma_xmit(self, iobase, 0);
} }
dev->trans_start = jiffies;
spin_unlock_irqrestore(&self->irport->lock, flags); spin_unlock_irqrestore(&self->irport->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1090,8 +1095,6 @@ static int ircc_net_open(struct net_device *dev) ...@@ -1090,8 +1095,6 @@ static int ircc_net_open(struct net_device *dev)
WARNING("%s(), unable to allocate DMA=%d\n", __FUNCTION__, self->io->dma); WARNING("%s(), unable to allocate DMA=%d\n", __FUNCTION__, self->io->dma);
return -EAGAIN; return -EAGAIN;
} }
MOD_INC_USE_COUNT;
return 0; return 0;
} }
...@@ -1124,8 +1127,6 @@ static int ircc_net_close(struct net_device *dev) ...@@ -1124,8 +1127,6 @@ static int ircc_net_close(struct net_device *dev)
free_dma(self->io->dma); free_dma(self->io->dma);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -1187,6 +1188,9 @@ static int __exit ircc_close(struct ircc_cb *self) ...@@ -1187,6 +1188,9 @@ static int __exit ircc_close(struct ircc_cb *self)
iobase = self->irport->io.fir_base; iobase = self->irport->io.fir_base;
if (self->pmdev)
pm_unregister(self->pmdev);
/* This will destroy irport */ /* This will destroy irport */
irport_close(self->irport); irport_close(self->irport);
......
This diff is collapsed.
/*********************************************************************
* $Id: smsc-ircc2.h,v 1.12.2.1 2002/10/27 10:52:37 dip Exp $
*
* Description: Definitions for the SMC IrCC chipset
* Status: Experimental.
* Author: Daniele Peri (peri@csai.unipa.it)
*
* Copyright (c) 2002 Daniele Peri
* All Rights Reserved.
*
* Based on smc-ircc.h:
*
* Copyright (c) 1999-2000, Dag Brattli <dagb@cs.uit.no>
* Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net>
* All Rights Reserved
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef SMSC_IRCC2_H
#define SMSC_IRCC2_H
/* DMA modes needed */
#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */
#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */
/* Master Control Register */
#define IRCC_MASTER 0x07
#define IRCC_MASTER_POWERDOWN 0x80
#define IRCC_MASTER_RESET 0x40
#define IRCC_MASTER_INT_EN 0x20
#define IRCC_MASTER_ERROR_RESET 0x10
/* Register block 0 */
/* Interrupt Identification */
#define IRCC_IIR 0x01
#define IRCC_IIR_ACTIVE_FRAME 0x80
#define IRCC_IIR_EOM 0x40
#define IRCC_IIR_RAW_MODE 0x20
#define IRCC_IIR_FIFO 0x10
/* Interrupt Enable */
#define IRCC_IER 0x02
#define IRCC_IER_ACTIVE_FRAME 0x80
#define IRCC_IER_EOM 0x40
#define IRCC_IER_RAW_MODE 0x20
#define IRCC_IER_FIFO 0x10
/* Line Status Register */
#define IRCC_LSR 0x03
#define IRCC_LSR_UNDERRUN 0x80
#define IRCC_LSR_OVERRUN 0x40
#define IRCC_LSR_FRAME_ERROR 0x20
#define IRCC_LSR_SIZE_ERROR 0x10
#define IRCC_LSR_CRC_ERROR 0x80
#define IRCC_LSR_FRAME_ABORT 0x40
/* Line Status Address Register */
#define IRCC_LSAR 0x03
#define IRCC_LSAR_ADDRESS_MASK 0x07
/* Line Control Register A */
#define IRCC_LCR_A 0x04
#define IRCC_LCR_A_FIFO_RESET 0x80
#define IRCC_LCR_A_FAST 0x40
#define IRCC_LCR_A_GP_DATA 0x20
#define IRCC_LCR_A_RAW_TX 0x10
#define IRCC_LCR_A_RAW_RX 0x08
#define IRCC_LCR_A_ABORT 0x04
#define IRCC_LCR_A_DATA_DONE 0x02
/* Line Control Register B */
#define IRCC_LCR_B 0x05
#define IRCC_LCR_B_SCE_DISABLED 0x00
#define IRCC_LCR_B_SCE_TRANSMIT 0x40
#define IRCC_LCR_B_SCE_RECEIVE 0x80
#define IRCC_LCR_B_SCE_UNDEFINED 0xc0
#define IRCC_LCR_B_SIP_ENABLE 0x20
#define IRCC_LCR_B_BRICK_WALL 0x10
/* Bus Status Register */
#define IRCC_BSR 0x06
#define IRCC_BSR_NOT_EMPTY 0x80
#define IRCC_BSR_FIFO_FULL 0x40
#define IRCC_BSR_TIMEOUT 0x20
/* Register block 1 */
#define IRCC_FIFO_THRESHOLD 0x02
#define IRCC_SCE_CFGA 0x00
#define IRCC_CFGA_AUX_IR 0x80
#define IRCC_CFGA_HALF_DUPLEX 0x04
#define IRCC_CFGA_TX_POLARITY 0x02
#define IRCC_CFGA_RX_POLARITY 0x01
#define IRCC_CFGA_COM 0x00
#define IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK 0x87
#define IRCC_CFGA_IRDA_SIR_A 0x08
#define IRCC_CFGA_ASK_SIR 0x10
#define IRCC_CFGA_IRDA_SIR_B 0x18
#define IRCC_CFGA_IRDA_HDLC 0x20
#define IRCC_CFGA_IRDA_4PPM 0x28
#define IRCC_CFGA_CONSUMER 0x30
#define IRCC_CFGA_RAW_IR 0x38
#define IRCC_CFGA_OTHER 0x40
#define IRCC_IR_HDLC 0x04
#define IRCC_IR_4PPM 0x01
#define IRCC_IR_CONSUMER 0x02
#define IRCC_SCE_CFGB 0x01
#define IRCC_CFGB_LOOPBACK 0x20
#define IRCC_CFGB_LPBCK_TX_CRC 0x10
#define IRCC_CFGB_NOWAIT 0x08
#define IRCC_CFGB_STRING_MOVE 0x04
#define IRCC_CFGB_DMA_BURST 0x02
#define IRCC_CFGB_DMA_ENABLE 0x01
#define IRCC_CFGB_MUX_COM 0x00
#define IRCC_CFGB_MUX_IR 0x40
#define IRCC_CFGB_MUX_AUX 0x80
#define IRCC_CFGB_MUX_INACTIVE 0xc0
/* Register block 3 - Identification Registers! */
#define IRCC_ID_HIGH 0x00 /* 0x10 */
#define IRCC_ID_LOW 0x01 /* 0xB8 */
#define IRCC_CHIP_ID 0x02 /* 0xF1 */
#define IRCC_VERSION 0x03 /* 0x01 */
#define IRCC_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */
#define IRCC_INTERFACE_DMA_MASK 0x0F /* low 4 = DMA, high 4 = IRQ */
#define IRCC_INTERFACE_IRQ_MASK 0xF0 /* low 4 = DMA, high 4 = IRQ */
/* Register block 4 - IrDA */
#define IRCC_CONTROL 0x00
#define IRCC_BOF_COUNT_LO 0x01 /* Low byte */
#define IRCC_BOF_COUNT_HI 0x00 /* High nibble (bit 0-3) */
#define IRCC_BRICKWALL_CNT_LO 0x02 /* Low byte */
#define IRCC_BRICKWALL_CNT_HI 0x03 /* High nibble (bit 4-7) */
#define IRCC_TX_SIZE_LO 0x04 /* Low byte */
#define IRCC_TX_SIZE_HI 0x03 /* High nibble (bit 0-3) */
#define IRCC_RX_SIZE_HI 0x05 /* High nibble (bit 0-3) */
#define IRCC_RX_SIZE_LO 0x06 /* Low byte */
#define IRCC_1152 0x80
#define IRCC_CRC 0x40
/* Register block 5 - IrDA */
#define IRCC_ATC 0x00
#define IRCC_ATC_nPROGREADY 0x80
#define IRCC_ATC_SPEED 0x40
#define IRCC_ATC_ENABLE 0x20
#define IRCC_ATC_MASK 0xE0
#define IRCC_IRHALFDUPLEX_TIMEOUT 0x01
#define IRCC_SCE_TX_DELAY_TIMER 0x02
/*
* Other definitions
*/
#define SMSC_IRCC2_MAX_SIR_SPEED 115200
#define SMSC_IRCC2_FIR_CHIP_IO_EXTENT 8
#define SMSC_IRCC2_SIR_CHIP_IO_EXTENT 8
#define SMSC_IRCC2_FIFO_SIZE 16
#define SMSC_IRCC2_FIFO_THRESHOLD 64
/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
#define SMSC_IRCC2_RX_BUFF_TRUESIZE 14384
#define SMSC_IRCC2_TX_BUFF_TRUESIZE 14384
#define SMSC_IRCC2_MIN_TURN_TIME 0x07
#define SMSC_IRCC2_WINDOW_SIZE 0x07
/* Maximum wait for hw transmitter to finish */
#define SMSC_IRCC2_HW_TRANSMITTER_TIMEOUT_US 1000 /* 1 ms */
/* Maximum wait for ATC transceiver programming to finish */
#define SMSC_IRCC2_ATC_PROGRAMMING_TIMEOUT_JIFFIES 1
#endif /* SMSC_IRCC2_H */
#ifndef SMSC_SIO_H
#define SMSC_SIO_H
/******************************************
Keys. They should work with every SMsC SIO
******************************************/
#define SMSCSIO_CFGACCESSKEY 0x55
#define SMSCSIO_CFGEXITKEY 0xaa
/*****************************
* Generic SIO Flat (!?) *
*****************************/
/* Register 0x0d */
#define SMSCSIOFLAT_DEVICEID_REG 0x0d
/* Register 0x0c */
#define SMSCSIOFLAT_UARTMODE0C_REG 0x0c
#define SMSCSIOFLAT_UART2MODE_MASK 0x38
#define SMSCSIOFLAT_UART2MODE_VAL_COM 0x00
#define SMSCSIOFLAT_UART2MODE_VAL_IRDA 0x08
#define SMSCSIOFLAT_UART2MODE_VAL_ASKIR 0x10
/* Register 0x25 */
#define SMSCSIOFLAT_UART2BASEADDR_REG 0x25
/* Register 0x2b */
#define SMSCSIOFLAT_FIRBASEADDR_REG 0x2b
/* Register 0x2c */
#define SMSCSIOFLAT_FIRDMASELECT_REG 0x2c
#define SMSCSIOFLAT_FIRDMASELECT_MASK 0x0f
/* Register 0x28 */
#define SMSCSIOFLAT_UARTIRQSELECT_REG 0x28
#define SMSCSIOFLAT_UART2IRQSELECT_MASK 0x0f
#define SMSCSIOFLAT_UART1IRQSELECT_MASK 0xf0
#define SMSCSIOFLAT_UARTIRQSELECT_VAL_NONE 0x00
/*********************
* LPC47N227 *
*********************/
#define LPC47N227_CFGACCESSKEY 0x55
#define LPC47N227_CFGEXITKEY 0xaa
/* Register 0x00 */
#define LPC47N227_FDCPOWERVALIDCONF_REG 0x00
#define LPC47N227_FDCPOWER_MASK 0x08
#define LPC47N227_VALID_MASK 0x80
/* Register 0x02 */
#define LPC47N227_UART12POWER_REG 0x02
#define LPC47N227_UART1POWERDOWN_MASK 0x08
#define LPC47N227_UART2POWERDOWN_MASK 0x80
/* Register 0x07 */
#define LPC47N227_APMBOOTDRIVE_REG 0x07
#define LPC47N227_PARPORT2AUTOPWRDOWN_MASK 0x10 /* auto power down on if set */
#define LPC47N227_UART2AUTOPWRDOWN_MASK 0x20 /* auto power down on if set */
#define LPC47N227_UART1AUTOPWRDOWN_MASK 0x40 /* auto power down on if set */
/* Register 0x0c */
#define LPC47N227_UARTMODE0C_REG 0x0c
#define LPC47N227_UART2MODE_MASK 0x38
#define LPC47N227_UART2MODE_VAL_COM 0x00
#define LPC47N227_UART2MODE_VAL_IRDA 0x08
#define LPC47N227_UART2MODE_VAL_ASKIR 0x10
/* Register 0x0d */
#define LPC47N227_DEVICEID_REG 0x0d
#define LPC47N227_DEVICEID_DEFVAL 0x5a
/* Register 0x0e */
#define LPC47N227_REVISIONID_REG 0x0e
/* Register 0x25 */
#define LPC47N227_UART2BASEADDR_REG 0x25
/* Register 0x28 */
#define LPC47N227_UARTIRQSELECT_REG 0x28
#define LPC47N227_UART2IRQSELECT_MASK 0x0f
#define LPC47N227_UART1IRQSELECT_MASK 0xf0
#define LPC47N227_UARTIRQSELECT_VAL_NONE 0x00
/* Register 0x2b */
#define LPC47N227_FIRBASEADDR_REG 0x2b
/* Register 0x2c */
#define LPC47N227_FIRDMASELECT_REG 0x2c
#define LPC47N227_FIRDMASELECT_MASK 0x0f
#define LPC47N227_FIRDMASELECT_VAL_DMA1 0x01 /* 47n227 has three dma channels */
#define LPC47N227_FIRDMASELECT_VAL_DMA2 0x02
#define LPC47N227_FIRDMASELECT_VAL_DMA3 0x03
#define LPC47N227_FIRDMASELECT_VAL_NONE 0x0f
#endif
...@@ -524,6 +524,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -524,6 +524,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Check for empty frame */ /* Check for empty frame */
if (!skb->len) { if (!skb->len) {
w83977af_change_speed(self, speed); w83977af_change_speed(self, speed);
dev->trans_start = jiffies;
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
} else } else
...@@ -579,6 +580,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -579,6 +580,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
switch_bank(iobase, SET0); switch_bank(iobase, SET0);
outb(ICR_ETXTHI, iobase+ICR); outb(ICR_ETXTHI, iobase+ICR);
} }
dev->trans_start = jiffies;
dev_kfree_skb(skb); dev_kfree_skb(skb);
/* Restore set register */ /* Restore set register */
......
...@@ -66,7 +66,7 @@ struct iriap_cb { ...@@ -66,7 +66,7 @@ struct iriap_cb {
__u32 daddr; __u32 daddr;
__u8 operation; __u8 operation;
struct sk_buff *skb; struct sk_buff *request_skb;
struct lsap_cb *lsap; struct lsap_cb *lsap;
__u8 slsap_sel; __u8 slsap_sel;
......
...@@ -195,8 +195,6 @@ struct irlan_cb { ...@@ -195,8 +195,6 @@ struct irlan_cb {
struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr); struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
void irlan_close(struct irlan_cb *self); void irlan_close(struct irlan_cb *self);
void irlan_close_tsaps(struct irlan_cb *self); void irlan_close_tsaps(struct irlan_cb *self);
void irlan_mod_inc_use_count(void);
void irlan_mod_dec_use_count(void);
int irlan_register_netdev(struct irlan_cb *self); int irlan_register_netdev(struct irlan_cb *self);
void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel); void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel);
......
...@@ -79,26 +79,6 @@ typedef enum { ...@@ -79,26 +79,6 @@ typedef enum {
LM_LAP_IDLE_TIMEOUT, LM_LAP_IDLE_TIMEOUT,
} IRLMP_EVENT; } IRLMP_EVENT;
/*
* Information which is used by the current thread, when executing in the
* state machine.
*/
struct irlmp_event {
IRLMP_EVENT *event;
struct sk_buff *skb;
__u8 hint;
__u32 daddr;
__u32 saddr;
__u8 slsap;
__u8 dlsap;
int reason;
struct discovery_t *discovery;
};
extern const char *irlmp_state[]; extern const char *irlmp_state[];
extern const char *irlsap_state[]; extern const char *irlsap_state[];
......
...@@ -67,6 +67,7 @@ struct irport_cb { ...@@ -67,6 +67,7 @@ struct irport_cb {
__u32 new_speed; __u32 new_speed;
int mode; int mode;
int index; /* Instance index */ int index; /* Instance index */
int transmitting; /* Are we transmitting ? */
spinlock_t lock; /* For serializing operations */ spinlock_t lock; /* For serializing operations */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc. * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
* *
* Copyright (c) 1999 Dag Brattli <dagb@cs.uit.no> * Copyright (c) 1999 Dag Brattli <dagb@cs.uit.no>
* Copyright (c) 1999-2001 Jean Tourrilhes <jt@hpl.hp.com> * Copyright (c) 1999-2003 Jean Tourrilhes <jt@hpl.hp.com>
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -190,6 +190,9 @@ static void irda_connect_confirm(void *instance, void *sap, ...@@ -190,6 +190,9 @@ static void irda_connect_confirm(void *instance, void *sap,
if (sk == NULL) if (sk == NULL)
return; return;
dev_kfree_skb(skb);
// Should be ??? skb_queue_tail(&sk->receive_queue, skb);
/* How much header space do we need to reserve */ /* How much header space do we need to reserve */
self->max_header_size = max_header_size; self->max_header_size = max_header_size;
...@@ -220,8 +223,6 @@ static void irda_connect_confirm(void *instance, void *sap, ...@@ -220,8 +223,6 @@ static void irda_connect_confirm(void *instance, void *sap,
self->max_data_size); self->max_data_size);
memcpy(&self->qos_tx, qos, sizeof(struct qos_info)); memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
dev_kfree_skb(skb);
// Should be ??? skb_queue_tail(&sk->receive_queue, skb);
/* We are now connected! */ /* We are now connected! */
sk->state = TCP_ESTABLISHED; sk->state = TCP_ESTABLISHED;
...@@ -260,6 +261,7 @@ static void irda_connect_indication(void *instance, void *sap, ...@@ -260,6 +261,7 @@ static void irda_connect_indication(void *instance, void *sap,
case SOCK_STREAM: case SOCK_STREAM:
if (max_sdu_size != 0) { if (max_sdu_size != 0) {
ERROR("%s: max_sdu_size must be 0\n", __FUNCTION__); ERROR("%s: max_sdu_size must be 0\n", __FUNCTION__);
kfree_skb(skb);
return; return;
} }
self->max_data_size = irttp_get_max_seg_size(self->tsap); self->max_data_size = irttp_get_max_seg_size(self->tsap);
...@@ -267,6 +269,7 @@ static void irda_connect_indication(void *instance, void *sap, ...@@ -267,6 +269,7 @@ static void irda_connect_indication(void *instance, void *sap,
case SOCK_SEQPACKET: case SOCK_SEQPACKET:
if (max_sdu_size == 0) { if (max_sdu_size == 0) {
ERROR("%s: max_sdu_size cannot be 0\n", __FUNCTION__); ERROR("%s: max_sdu_size cannot be 0\n", __FUNCTION__);
kfree_skb(skb);
return; return;
} }
self->max_data_size = max_sdu_size; self->max_data_size = max_sdu_size;
...@@ -359,7 +362,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) ...@@ -359,7 +362,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
* doesn't touch the dtsap_sel and save the full value structure... * doesn't touch the dtsap_sel and save the full value structure...
*/ */
static void irda_getvalue_confirm(int result, __u16 obj_id, static void irda_getvalue_confirm(int result, __u16 obj_id,
struct ias_value *value, void *priv) struct ias_value *value, void *priv)
{ {
struct irda_sock *self; struct irda_sock *self;
...@@ -908,6 +911,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -908,6 +911,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
new->tsap = irttp_dup(self->tsap, new); new->tsap = irttp_dup(self->tsap, new);
if (!new->tsap) { if (!new->tsap) {
IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__); IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
kfree_skb(skb);
return -1; return -1;
} }
...@@ -926,6 +930,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -926,6 +930,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
/* Clean up the original one to keep it in listen state */ /* Clean up the original one to keep it in listen state */
irttp_listen(self->tsap); irttp_listen(self->tsap);
/* Wow ! What is that ? Jean II */
skb->sk = NULL; skb->sk = NULL;
skb->destructor = NULL; skb->destructor = NULL;
kfree_skb(skb); kfree_skb(skb);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* Modified by: Dag Brattli <dagb@cs.uit.no> * Modified by: Dag Brattli <dagb@cs.uit.no>
* *
* Copyright (c) 1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -251,7 +252,6 @@ void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -251,7 +252,6 @@ void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb,
info->max_header_size, skb); info->max_header_size, skb);
else { else {
IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
...@@ -295,7 +295,6 @@ void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -295,7 +295,6 @@ void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb,
info->max_header_size, skb); info->max_header_size, skb);
else { else {
IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
...@@ -338,7 +337,6 @@ void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb) ...@@ -338,7 +337,6 @@ void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb)
self->notify.data_indication(self->notify.instance, self, skb); self->notify.data_indication(self->notify.instance, self, skb);
else { else {
IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
...@@ -370,9 +368,8 @@ void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb) ...@@ -370,9 +368,8 @@ void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb)
if (skb->len) if (skb->len)
ircomm_data_indication(self, skb); ircomm_data_indication(self, skb);
else { else {
IRDA_DEBUG(4, IRDA_DEBUG(4, "%s(), data was control info only!\n",
"%s(), data was control info only!\n", __FUNCTION__ ); __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
...@@ -408,24 +405,28 @@ EXPORT_SYMBOL(ircomm_control_request); ...@@ -408,24 +405,28 @@ EXPORT_SYMBOL(ircomm_control_request);
static void ircomm_control_indication(struct ircomm_cb *self, static void ircomm_control_indication(struct ircomm_cb *self,
struct sk_buff *skb, int clen) struct sk_buff *skb, int clen)
{ {
struct sk_buff *ctrl_skb;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
ctrl_skb = skb_clone(skb, GFP_ATOMIC); /* Use udata for delivering data on the control channel */
if (!ctrl_skb) if (self->notify.udata_indication) {
return; struct sk_buff *ctrl_skb;
/* We don't own the skb, so clone it */
ctrl_skb = skb_clone(skb, GFP_ATOMIC);
if (!ctrl_skb)
return;
/* Remove data channel from control channel */ /* Remove data channel from control channel */
skb_trim(ctrl_skb, clen+1); skb_trim(ctrl_skb, clen+1);
/* Use udata for delivering data on the control channel */
if (self->notify.udata_indication)
self->notify.udata_indication(self->notify.instance, self, self->notify.udata_indication(self->notify.instance, self,
ctrl_skb); ctrl_skb);
else {
/* Drop reference count -
* see ircomm_tty_control_indication(). */
dev_kfree_skb(ctrl_skb);
} else {
IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
...@@ -470,7 +471,6 @@ void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -470,7 +471,6 @@ void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb,
info->reason, skb); info->reason, skb);
} else { } else {
IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
dev_kfree_skb(skb);
} }
} }
......
...@@ -109,9 +109,7 @@ static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, ...@@ -109,9 +109,7 @@ static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
default: default:
IRDA_DEBUG(4, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(4, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_event[event]); ircomm_event[event]);
if (skb) ret = -EINVAL;
dev_kfree_skb(skb);
return -EINVAL;
} }
return ret; return ret;
} }
...@@ -141,8 +139,6 @@ static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, ...@@ -141,8 +139,6 @@ static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
default: default:
IRDA_DEBUG(0, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(0, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_event[event]); ircomm_event[event]);
if (skb)
dev_kfree_skb(skb);
ret = -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
...@@ -176,8 +172,6 @@ static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, ...@@ -176,8 +172,6 @@ static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
default: default:
IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ , IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
ircomm_event[event]); ircomm_event[event]);
if (skb)
dev_kfree_skb(skb);
ret = -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
...@@ -220,8 +214,6 @@ static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, ...@@ -220,8 +214,6 @@ static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
default: default:
IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ , IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
ircomm_event[event]); ircomm_event[event]);
if (skb)
dev_kfree_skb(skb);
ret = -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* Sources: Previous IrLPT work by Thomas Davis * Sources: Previous IrLPT work by Thomas Davis
* *
* Copyright (c) 1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -93,6 +94,10 @@ int ircomm_lmp_connect_request(struct ircomm_cb *self, ...@@ -93,6 +94,10 @@ int ircomm_lmp_connect_request(struct ircomm_cb *self,
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
/* Don't forget to refcount it - should be NULL anyway */
if(userdata)
skb_get(userdata);
ret = irlmp_connect_request(self->lsap, info->dlsap_sel, ret = irlmp_connect_request(self->lsap, info->dlsap_sel,
info->saddr, info->daddr, NULL, userdata); info->saddr, info->daddr, NULL, userdata);
return ret; return ret;
...@@ -106,29 +111,32 @@ int ircomm_lmp_connect_request(struct ircomm_cb *self, ...@@ -106,29 +111,32 @@ int ircomm_lmp_connect_request(struct ircomm_cb *self,
*/ */
int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *userdata) int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *userdata)
{ {
struct sk_buff *skb; struct sk_buff *tx_skb;
int ret; int ret;
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
/* Any userdata supplied? */ /* Any userdata supplied? */
if (userdata == NULL) { if (userdata == NULL) {
skb = dev_alloc_skb(64); tx_skb = dev_alloc_skb(64);
if (!skb) if (!tx_skb)
return -ENOMEM; return -ENOMEM;
/* Reserve space for MUX and LAP header */ /* Reserve space for MUX and LAP header */
skb_reserve(skb, LMP_MAX_HEADER); skb_reserve(tx_skb, LMP_MAX_HEADER);
} else { } else {
skb = userdata;
/* /*
* Check that the client has reserved enough space for * Check that the client has reserved enough space for
* headers * headers
*/ */
ASSERT(skb_headroom(skb) >= LMP_MAX_HEADER, return -1;); ASSERT(skb_headroom(userdata) >= LMP_MAX_HEADER, return -1;);
/* Don't forget to refcount it - should be NULL anyway */
skb_get(userdata);
tx_skb = userdata;
} }
ret = irlmp_connect_response(self->lsap, skb); ret = irlmp_connect_response(self->lsap, tx_skb);
return 0; return 0;
} }
...@@ -137,20 +145,24 @@ int ircomm_lmp_disconnect_request(struct ircomm_cb *self, ...@@ -137,20 +145,24 @@ int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
struct sk_buff *userdata, struct sk_buff *userdata,
struct ircomm_info *info) struct ircomm_info *info)
{ {
struct sk_buff *skb; struct sk_buff *tx_skb;
int ret; int ret;
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
if (!userdata) { if (!userdata) {
skb = dev_alloc_skb(64); tx_skb = dev_alloc_skb(64);
if (!skb) if (!tx_skb)
return -ENOMEM; return -ENOMEM;
/* Reserve space for MUX and LAP header */ /* Reserve space for MUX and LAP header */
skb_reserve(skb, LMP_MAX_HEADER); skb_reserve(tx_skb, LMP_MAX_HEADER);
userdata = skb; userdata = tx_skb;
} else {
/* Don't forget to refcount it - should be NULL anyway */
skb_get(userdata);
} }
ret = irlmp_disconnect_request(self->lsap, userdata); ret = irlmp_disconnect_request(self->lsap, userdata);
return ret; return ret;
...@@ -217,8 +229,11 @@ int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -217,8 +229,11 @@ int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
IRDA_DEBUG(4, "%s(), sending frame\n", __FUNCTION__ ); IRDA_DEBUG(4, "%s(), sending frame\n", __FUNCTION__ );
/* Don't forget to refcount it - see ircomm_tty_do_softint() */
skb_get(skb);
skb->destructor = ircomm_lmp_flow_control; skb->destructor = ircomm_lmp_flow_control;
if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) { if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) {
IRDA_DEBUG(2, "%s(), asking TTY to slow down!\n", __FUNCTION__ ); IRDA_DEBUG(2, "%s(), asking TTY to slow down!\n", __FUNCTION__ );
self->flow_status = FLOW_STOP; self->flow_status = FLOW_STOP;
...@@ -229,7 +244,7 @@ int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -229,7 +244,7 @@ int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
ret = irlmp_data_request(self->lsap, skb); ret = irlmp_data_request(self->lsap, skb);
if (ret) { if (ret) {
ERROR("%s(), failed\n", __FUNCTION__); ERROR("%s(), failed\n", __FUNCTION__);
dev_kfree_skb(skb); /* irlmp_data_request already free the packet */
} }
return ret; return ret;
...@@ -254,6 +269,9 @@ int ircomm_lmp_data_indication(void *instance, void *sap, ...@@ -254,6 +269,9 @@ int ircomm_lmp_data_indication(void *instance, void *sap,
ircomm_do_event(self, IRCOMM_LMP_DATA_INDICATION, skb, NULL); ircomm_do_event(self, IRCOMM_LMP_DATA_INDICATION, skb, NULL);
/* Drop reference count - see ircomm_tty_data_indication(). */
dev_kfree_skb(skb);
return 0; return 0;
} }
...@@ -285,6 +303,9 @@ void ircomm_lmp_connect_confirm(void *instance, void *sap, ...@@ -285,6 +303,9 @@ void ircomm_lmp_connect_confirm(void *instance, void *sap,
info.qos = qos; info.qos = qos;
ircomm_do_event(self, IRCOMM_LMP_CONNECT_CONFIRM, skb, &info); ircomm_do_event(self, IRCOMM_LMP_CONNECT_CONFIRM, skb, &info);
/* Drop reference count - see ircomm_tty_connect_confirm(). */
dev_kfree_skb(skb);
} }
/* /*
...@@ -315,6 +336,9 @@ void ircomm_lmp_connect_indication(void *instance, void *sap, ...@@ -315,6 +336,9 @@ void ircomm_lmp_connect_indication(void *instance, void *sap,
info.qos = qos; info.qos = qos;
ircomm_do_event(self, IRCOMM_LMP_CONNECT_INDICATION, skb, &info); ircomm_do_event(self, IRCOMM_LMP_CONNECT_INDICATION, skb, &info);
/* Drop reference count - see ircomm_tty_connect_indication(). */
dev_kfree_skb(skb);
} }
/* /*
...@@ -338,4 +362,8 @@ void ircomm_lmp_disconnect_indication(void *instance, void *sap, ...@@ -338,4 +362,8 @@ void ircomm_lmp_disconnect_indication(void *instance, void *sap,
info.reason = reason; info.reason = reason;
ircomm_do_event(self, IRCOMM_LMP_DISCONNECT_INDICATION, skb, &info); ircomm_do_event(self, IRCOMM_LMP_DISCONNECT_INDICATION, skb, &info);
/* Drop reference count - see ircomm_tty_disconnect_indication(). */
if(skb)
dev_kfree_skb(skb);
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* Modified by: Dag Brattli <dagb@cs.uit.no> * Modified by: Dag Brattli <dagb@cs.uit.no>
* *
* Copyright (c) 1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -94,9 +95,14 @@ int ircomm_ttp_connect_request(struct ircomm_cb *self, ...@@ -94,9 +95,14 @@ int ircomm_ttp_connect_request(struct ircomm_cb *self,
IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
/* Don't forget to refcount it - should be NULL anyway */
if(userdata)
skb_get(userdata);
ret = irttp_connect_request(self->tsap, info->dlsap_sel, ret = irttp_connect_request(self->tsap, info->dlsap_sel,
info->saddr, info->daddr, NULL, info->saddr, info->daddr, NULL,
TTP_SAR_DISABLE, userdata); TTP_SAR_DISABLE, userdata);
return ret; return ret;
} }
...@@ -106,13 +112,18 @@ int ircomm_ttp_connect_request(struct ircomm_cb *self, ...@@ -106,13 +112,18 @@ int ircomm_ttp_connect_request(struct ircomm_cb *self,
* *
* *
*/ */
int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb) int ircomm_ttp_connect_response(struct ircomm_cb *self,
struct sk_buff *userdata)
{ {
int ret; int ret;
IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, skb); /* Don't forget to refcount it - should be NULL anyway */
if(userdata)
skb_get(userdata);
ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, userdata);
return ret; return ret;
} }
...@@ -126,7 +137,8 @@ int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb) ...@@ -126,7 +137,8 @@ int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb)
* some of them are sent after connection establishment, so this can * some of them are sent after connection establishment, so this can
* increase the latency a bit. * increase the latency a bit.
*/ */
int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, int ircomm_ttp_data_request(struct ircomm_cb *self,
struct sk_buff *skb,
int clen) int clen)
{ {
int ret; int ret;
...@@ -140,6 +152,10 @@ int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -140,6 +152,10 @@ int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
* only frames, to make things easier and avoid queueing * only frames, to make things easier and avoid queueing
*/ */
ASSERT(skb_headroom(skb) >= IRCOMM_HEADER_SIZE, return -1;); ASSERT(skb_headroom(skb) >= IRCOMM_HEADER_SIZE, return -1;);
/* Don't forget to refcount it - see ircomm_tty_do_softint() */
skb_get(skb);
skb_push(skb, IRCOMM_HEADER_SIZE); skb_push(skb, IRCOMM_HEADER_SIZE);
skb->data[0] = clen; skb->data[0] = clen;
...@@ -147,7 +163,7 @@ int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, ...@@ -147,7 +163,7 @@ int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
ret = irttp_data_request(self->tsap, skb); ret = irttp_data_request(self->tsap, skb);
if (ret) { if (ret) {
ERROR("%s(), failed\n", __FUNCTION__); ERROR("%s(), failed\n", __FUNCTION__);
dev_kfree_skb(skb); /* irttp_data_request already free the packet */
} }
return ret; return ret;
...@@ -172,6 +188,9 @@ int ircomm_ttp_data_indication(void *instance, void *sap, ...@@ -172,6 +188,9 @@ int ircomm_ttp_data_indication(void *instance, void *sap,
ircomm_do_event(self, IRCOMM_TTP_DATA_INDICATION, skb, NULL); ircomm_do_event(self, IRCOMM_TTP_DATA_INDICATION, skb, NULL);
/* Drop reference count - see ircomm_tty_data_indication(). */
dev_kfree_skb(skb);
return 0; return 0;
} }
...@@ -189,12 +208,11 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap, ...@@ -189,12 +208,11 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap,
ASSERT(self != NULL, return;); ASSERT(self != NULL, return;);
ASSERT(self->magic == IRCOMM_MAGIC, return;); ASSERT(self->magic == IRCOMM_MAGIC, return;);
ASSERT(skb != NULL, return;); ASSERT(skb != NULL, return;);
ASSERT(qos != NULL, return;); ASSERT(qos != NULL, goto out;);
if (max_sdu_size != TTP_SAR_DISABLE) { if (max_sdu_size != TTP_SAR_DISABLE) {
ERROR("%s(), SAR not allowed for IrCOMM!\n", __FUNCTION__); ERROR("%s(), SAR not allowed for IrCOMM!\n", __FUNCTION__);
dev_kfree_skb(skb); goto out;
return;
} }
info.max_data_size = irttp_get_max_seg_size(self->tsap) info.max_data_size = irttp_get_max_seg_size(self->tsap)
...@@ -203,6 +221,10 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap, ...@@ -203,6 +221,10 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap,
info.qos = qos; info.qos = qos;
ircomm_do_event(self, IRCOMM_TTP_CONNECT_CONFIRM, skb, &info); ircomm_do_event(self, IRCOMM_TTP_CONNECT_CONFIRM, skb, &info);
out:
/* Drop reference count - see ircomm_tty_connect_confirm(). */
dev_kfree_skb(skb);
} }
/* /*
...@@ -226,12 +248,11 @@ void ircomm_ttp_connect_indication(void *instance, void *sap, ...@@ -226,12 +248,11 @@ void ircomm_ttp_connect_indication(void *instance, void *sap,
ASSERT(self != NULL, return;); ASSERT(self != NULL, return;);
ASSERT(self->magic == IRCOMM_MAGIC, return;); ASSERT(self->magic == IRCOMM_MAGIC, return;);
ASSERT(skb != NULL, return;); ASSERT(skb != NULL, return;);
ASSERT(qos != NULL, return;); ASSERT(qos != NULL, goto out;);
if (max_sdu_size != TTP_SAR_DISABLE) { if (max_sdu_size != TTP_SAR_DISABLE) {
ERROR("%s(), SAR not allowed for IrCOMM!\n", __FUNCTION__); ERROR("%s(), SAR not allowed for IrCOMM!\n", __FUNCTION__);
dev_kfree_skb(skb); goto out;
return;
} }
info.max_data_size = irttp_get_max_seg_size(self->tsap) info.max_data_size = irttp_get_max_seg_size(self->tsap)
...@@ -240,6 +261,10 @@ void ircomm_ttp_connect_indication(void *instance, void *sap, ...@@ -240,6 +261,10 @@ void ircomm_ttp_connect_indication(void *instance, void *sap,
info.qos = qos; info.qos = qos;
ircomm_do_event(self, IRCOMM_TTP_CONNECT_INDICATION, skb, &info); ircomm_do_event(self, IRCOMM_TTP_CONNECT_INDICATION, skb, &info);
out:
/* Drop reference count - see ircomm_tty_connect_indication(). */
dev_kfree_skb(skb);
} }
/* /*
...@@ -254,6 +279,10 @@ int ircomm_ttp_disconnect_request(struct ircomm_cb *self, ...@@ -254,6 +279,10 @@ int ircomm_ttp_disconnect_request(struct ircomm_cb *self,
{ {
int ret; int ret;
/* Don't forget to refcount it - should be NULL anyway */
if(userdata)
skb_get(userdata);
ret = irttp_disconnect_request(self->tsap, userdata, P_NORMAL); ret = irttp_disconnect_request(self->tsap, userdata, P_NORMAL);
return ret; return ret;
...@@ -280,6 +309,10 @@ void ircomm_ttp_disconnect_indication(void *instance, void *sap, ...@@ -280,6 +309,10 @@ void ircomm_ttp_disconnect_indication(void *instance, void *sap,
info.reason = reason; info.reason = reason;
ircomm_do_event(self, IRCOMM_TTP_DISCONNECT_INDICATION, skb, &info); ircomm_do_event(self, IRCOMM_TTP_DISCONNECT_INDICATION, skb, &info);
/* Drop reference count - see ircomm_tty_disconnect_indication(). */
if(skb)
dev_kfree_skb(skb);
} }
/* /*
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* Sources: serial.c and previous IrCOMM work by Takahide Higuchi * Sources: serial.c and previous IrCOMM work by Takahide Higuchi
* *
* Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -663,8 +664,12 @@ static void ircomm_tty_do_softint(void *private_) ...@@ -663,8 +664,12 @@ static void ircomm_tty_do_softint(void *private_)
spin_unlock_irqrestore(&self->spinlock, flags); spin_unlock_irqrestore(&self->spinlock, flags);
/* Flush control buffer if any */ /* Flush control buffer if any */
if (ctrl_skb && self->flow == FLOW_START) if(ctrl_skb) {
ircomm_control_request(self->ircomm, ctrl_skb); if(self->flow == FLOW_START)
ircomm_control_request(self->ircomm, ctrl_skb);
/* Drop reference count - see ircomm_ttp_data_request(). */
dev_kfree_skb(ctrl_skb);
}
if (tty->hw_stopped) if (tty->hw_stopped)
return; return;
...@@ -678,8 +683,11 @@ static void ircomm_tty_do_softint(void *private_) ...@@ -678,8 +683,11 @@ static void ircomm_tty_do_softint(void *private_)
spin_unlock_irqrestore(&self->spinlock, flags); spin_unlock_irqrestore(&self->spinlock, flags);
/* Flush transmit buffer if any */ /* Flush transmit buffer if any */
if (skb) if (skb) {
ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL); ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL);
/* Drop reference count - see ircomm_ttp_data_request(). */
dev_kfree_skb(skb);
}
/* Check if user (still) wants to be waken up */ /* Check if user (still) wants to be waken up */
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
...@@ -1179,7 +1187,6 @@ static int ircomm_tty_data_indication(void *instance, void *sap, ...@@ -1179,7 +1187,6 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
if (!self->tty) { if (!self->tty) {
IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ );
dev_kfree_skb(skb);
return 0; return 0;
} }
...@@ -1204,7 +1211,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap, ...@@ -1204,7 +1211,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
* handler * handler
*/ */
self->tty->ldisc.receive_buf(self->tty, skb->data, NULL, skb->len); self->tty->ldisc.receive_buf(self->tty, skb->data, NULL, skb->len);
dev_kfree_skb(skb);
/* No need to kfree_skb - see ircomm_ttp_data_indication() */
return 0; return 0;
} }
...@@ -1231,7 +1239,8 @@ static int ircomm_tty_control_indication(void *instance, void *sap, ...@@ -1231,7 +1239,8 @@ static int ircomm_tty_control_indication(void *instance, void *sap,
irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen), irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen),
&ircomm_param_info); &ircomm_param_info);
dev_kfree_skb(skb);
/* No need to kfree_skb - see ircomm_control_indication() */
return 0; return 0;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* Modified by: Dag Brattli <dagb@cs.uit.no> * Modified by: Dag Brattli <dagb@cs.uit.no>
* *
* Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -236,8 +237,9 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) ...@@ -236,8 +237,9 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self)
irias_insert_object(self->obj); irias_insert_object(self->obj);
} }
self->skey = irlmp_register_service(hints); self->skey = irlmp_register_service(hints);
self->ckey = irlmp_register_client( self->ckey = irlmp_register_client(hints,
hints, ircomm_tty_discovery_indication, NULL, (void *) self); ircomm_tty_discovery_indication,
NULL, (void *) self);
} }
/* /*
...@@ -459,7 +461,7 @@ void ircomm_tty_connect_confirm(void *instance, void *sap, ...@@ -459,7 +461,7 @@ void ircomm_tty_connect_confirm(void *instance, void *sap,
ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_CONFIRM, NULL, NULL); ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_CONFIRM, NULL, NULL);
dev_kfree_skb(skb); /* No need to kfree_skb - see ircomm_ttp_connect_confirm() */
} }
/* /*
...@@ -496,7 +498,7 @@ void ircomm_tty_connect_indication(void *instance, void *sap, ...@@ -496,7 +498,7 @@ void ircomm_tty_connect_indication(void *instance, void *sap,
ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL); ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL);
dev_kfree_skb(skb); /* No need to kfree_skb - see ircomm_ttp_connect_indication() */
} }
/* /*
...@@ -647,7 +649,7 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, ...@@ -647,7 +649,7 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
...@@ -718,7 +720,7 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self, ...@@ -718,7 +720,7 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
...@@ -774,7 +776,7 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self, ...@@ -774,7 +776,7 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
...@@ -822,7 +824,7 @@ static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self, ...@@ -822,7 +824,7 @@ static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
...@@ -874,7 +876,7 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self, ...@@ -874,7 +876,7 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
...@@ -917,7 +919,7 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, ...@@ -917,7 +919,7 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
default: default:
IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ , IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
ircomm_tty_event[event]); ircomm_tty_event[event]);
return -EINVAL; ret = -EINVAL;
} }
return ret; return ret;
} }
......
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* *
* Copyright (c) 1997, 1999-2000 Dag Brattli <dagb@cs.uit.no>, * Copyright (c) 1997, 1999-2000 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved. * All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -174,8 +175,11 @@ static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -174,8 +175,11 @@ static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
switch (event) { switch (event) {
case IAP_CALL_REQUEST_GVBC: case IAP_CALL_REQUEST_GVBC:
iriap_next_client_state(self, S_CONNECTING); iriap_next_client_state(self, S_CONNECTING);
ASSERT(self->skb == NULL, return;); ASSERT(self->request_skb == NULL, return;);
self->skb = skb; /* Don't forget to refcount it -
* see iriap_getvaluebyclass_request(). */
skb_get(skb);
self->request_skb = skb;
iriap_connect_request(self); iriap_connect_request(self);
break; break;
case IAP_LM_DISCONNECT_INDICATION: case IAP_LM_DISCONNECT_INDICATION:
...@@ -251,20 +255,21 @@ static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -251,20 +255,21 @@ static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event,
static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event, static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct sk_buff *tx_skb;
ASSERT(self != NULL, return;); ASSERT(self != NULL, return;);
switch (event) { switch (event) {
case IAP_CALL_REQUEST: case IAP_CALL_REQUEST:
skb = self->skb; /* Already refcounted - see state_s_disconnect() */
self->skb = NULL; tx_skb = self->request_skb;
self->request_skb = NULL;
irlmp_data_request(self->lsap, skb); irlmp_data_request(self->lsap, tx_skb);
iriap_next_call_state(self, S_OUTSTANDING); iriap_next_call_state(self, S_OUTSTANDING);
break; break;
default: default:
IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event); IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
if (skb)
dev_kfree_skb(skb);
break; break;
} }
} }
...@@ -379,10 +384,6 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -379,10 +384,6 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
* care about LM_Idle_request()! * care about LM_Idle_request()!
*/ */
iriap_next_r_connect_state(self, R_RECEIVING); iriap_next_r_connect_state(self, R_RECEIVING);
if (skb)
dev_kfree_skb(skb);
break; break;
default: default:
IRDA_DEBUG(0, "%s(), unknown event %d\n", __FUNCTION__, event); IRDA_DEBUG(0, "%s(), unknown event %d\n", __FUNCTION__, event);
...@@ -450,7 +451,6 @@ static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -450,7 +451,6 @@ static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event,
IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__); IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
break; break;
} }
} }
/* /*
...@@ -465,11 +465,8 @@ static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -465,11 +465,8 @@ static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event,
IRDA_DEBUG(4, "%s()\n", __FUNCTION__); IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
ASSERT(skb != NULL, return;); ASSERT(skb != NULL, return;);
ASSERT(self != NULL, return;);
if (!self || self->magic != IAS_MAGIC) { ASSERT(self->magic == IAS_MAGIC, return;);
IRDA_DEBUG(0, "%s(), bad pointer self\n", __FUNCTION__);
return;
}
switch (event) { switch (event) {
case IAP_CALL_RESPONSE: case IAP_CALL_RESPONSE:
...@@ -479,6 +476,10 @@ static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event, ...@@ -479,6 +476,10 @@ static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event,
*/ */
iriap_next_r_connect_state(self, R_RECEIVING); iriap_next_r_connect_state(self, R_RECEIVING);
/* Don't forget to refcount it - see
* iriap_getvaluebyclass_response(). */
skb_get(skb);
irlmp_data_request(self->lsap, skb); irlmp_data_request(self->lsap, skb);
break; break;
default: default:
......
...@@ -1180,20 +1180,6 @@ void print_ret_code(__u8 code) ...@@ -1180,20 +1180,6 @@ void print_ret_code(__u8 code)
} }
} }
void irlan_mod_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
void irlan_mod_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/inetdevice.h> #include <linux/inetdevice.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/module.h>
#include <net/arp.h> #include <net/arp.h>
#include <net/irda/irda.h> #include <net/irda/irda.h>
...@@ -61,6 +62,7 @@ int irlan_eth_init(struct net_device *dev) ...@@ -61,6 +62,7 @@ int irlan_eth_init(struct net_device *dev)
dev->hard_start_xmit = irlan_eth_xmit; dev->hard_start_xmit = irlan_eth_xmit;
dev->get_stats = irlan_eth_get_stats; dev->get_stats = irlan_eth_get_stats;
dev->set_multicast_list = irlan_eth_set_multicast_list; dev->set_multicast_list = irlan_eth_set_multicast_list;
SET_MODULE_OWNER(dev);
ether_setup(dev); ether_setup(dev);
...@@ -112,8 +114,6 @@ int irlan_eth_open(struct net_device *dev) ...@@ -112,8 +114,6 @@ int irlan_eth_open(struct net_device *dev)
self->disconnect_reason = 0; self->disconnect_reason = 0;
irlan_client_wakeup(self, self->saddr, self->daddr); irlan_client_wakeup(self, self->saddr, self->daddr);
irlan_mod_inc_use_count();
/* Make sure we have a hardware address before we return, so DHCP clients gets happy */ /* Make sure we have a hardware address before we return, so DHCP clients gets happy */
interruptible_sleep_on(&self->open_wait); interruptible_sleep_on(&self->open_wait);
...@@ -138,8 +138,6 @@ int irlan_eth_close(struct net_device *dev) ...@@ -138,8 +138,6 @@ int irlan_eth_close(struct net_device *dev)
/* Stop device */ /* Stop device */
netif_stop_queue(dev); netif_stop_queue(dev);
irlan_mod_dec_use_count();
irlan_close_data_channel(self); irlan_close_data_channel(self);
irlan_close_tsaps(self); irlan_close_tsaps(self);
...@@ -206,7 +204,7 @@ int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -206,7 +204,7 @@ int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
* confuse do_dev_queue_xmit() in dev.c! I have * confuse do_dev_queue_xmit() in dev.c! I have
* tried :-) DB * tried :-) DB
*/ */
dev_kfree_skb(skb); /* irttp_data_request already free the packet */
self->stats.tx_dropped++; self->stats.tx_dropped++;
} else { } else {
self->stats.tx_packets++; self->stats.tx_packets++;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Modified by: Dag Brattli <dagb@cs.uit.no> * Modified by: Dag Brattli <dagb@cs.uit.no>
* *
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -244,7 +244,6 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) ...@@ -244,7 +244,6 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
irlap_init_qos_capabilities(self, NULL); /* No user QoS! */ irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
skb_get(skb); /*LEVEL4*/
irlmp_link_connect_indication(self->notify.instance, self->saddr, irlmp_link_connect_indication(self->notify.instance, self->saddr,
self->daddr, &self->qos_tx, skb); self->daddr, &self->qos_tx, skb);
} }
...@@ -255,12 +254,11 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) ...@@ -255,12 +254,11 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
* Service user has accepted incoming connection * Service user has accepted incoming connection
* *
*/ */
void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) void irlap_connect_response(struct irlap_cb *self, struct sk_buff *userdata)
{ {
IRDA_DEBUG(4, "%s()\n", __FUNCTION__); IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
irlap_do_event(self, CONNECT_RESPONSE, skb, NULL); irlap_do_event(self, CONNECT_RESPONSE, userdata, NULL);
kfree_skb(skb);
} }
/* /*
...@@ -305,7 +303,6 @@ void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb) ...@@ -305,7 +303,6 @@ void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb)
ASSERT(self != NULL, return;); ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;); ASSERT(self->magic == LAP_MAGIC, return;);
skb_get(skb); /*LEVEL4*/
irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb); irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb);
} }
...@@ -322,7 +319,6 @@ void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb, ...@@ -322,7 +319,6 @@ void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,
/* Hide LAP header from IrLMP layer */ /* Hide LAP header from IrLMP layer */
skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER); skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
skb_get(skb); /*LEVEL4*/
irlmp_link_data_indication(self->notify.instance, skb, unreliable); irlmp_link_data_indication(self->notify.instance, skb, unreliable);
} }
...@@ -354,6 +350,9 @@ void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, ...@@ -354,6 +350,9 @@ void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
else else
skb->data[1] = I_FRAME; skb->data[1] = I_FRAME;
/* Don't forget to refcount it - see irlmp_connect_request(). */
skb_get(skb);
/* Add at the end of the queue (keep ordering) - Jean II */ /* Add at the end of the queue (keep ordering) - Jean II */
skb_queue_tail(&self->txq, skb); skb_queue_tail(&self->txq, skb);
...@@ -392,6 +391,8 @@ void irlap_unitdata_request(struct irlap_cb *self, struct sk_buff *skb) ...@@ -392,6 +391,8 @@ void irlap_unitdata_request(struct irlap_cb *self, struct sk_buff *skb)
skb->data[0] = CBROADCAST; skb->data[0] = CBROADCAST;
skb->data[1] = UI_FRAME; skb->data[1] = UI_FRAME;
/* Don't need to refcount, see irlmp_connless_data_request() */
skb_queue_tail(&self->txq_ultra, skb); skb_queue_tail(&self->txq_ultra, skb);
irlap_do_event(self, SEND_UI_FRAME, NULL, NULL); irlap_do_event(self, SEND_UI_FRAME, NULL, NULL);
...@@ -416,7 +417,6 @@ void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb) ...@@ -416,7 +417,6 @@ void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb)
/* Hide LAP header from IrLMP layer */ /* Hide LAP header from IrLMP layer */
skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER); skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
skb_get(skb); /*LEVEL4*/
irlmp_link_unitdata_indication(self->notify.instance, skb); irlmp_link_unitdata_indication(self->notify.instance, skb);
} }
#endif /* CONFIG_IRDA_ULTRA */ #endif /* CONFIG_IRDA_ULTRA */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Copyright (c) 1998-2000 Dag Brattli <dag@brattli.net>, * Copyright (c) 1998-2000 Dag Brattli <dag@brattli.net>,
* Copyright (c) 1998 Thomas Davis <ratbert@radiks.net> * Copyright (c) 1998 Thomas Davis <ratbert@radiks.net>
* All Rights Reserved. * All Rights Reserved.
* Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -287,6 +287,9 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, ...@@ -287,6 +287,9 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
/* Send one frame */ /* Send one frame */
ret = (*state[self->state])(self, SEND_I_CMD, ret = (*state[self->state])(self, SEND_I_CMD,
skb, NULL); skb, NULL);
/* Drop reference count.
* It will be increase as needed in
* irlap_send_data_xxx() */
kfree_skb(skb); kfree_skb(skb);
/* Poll the higher layers for one more frame */ /* Poll the higher layers for one more frame */
...@@ -517,6 +520,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, ...@@ -517,6 +520,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
CMD_FRAME); CMD_FRAME);
else else
break; break;
/* irlap_send_ui_frame() won't increase skb reference
* count, so no dev_kfree_skb() - Jean II */
} }
if (i == 2) { if (i == 2) {
/* Force us to listen 500 ms again */ /* Force us to listen 500 ms again */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -229,6 +229,11 @@ ...@@ -229,6 +229,11 @@
* v14 - 20.2.03 - Jean II * v14 - 20.2.03 - Jean II
* o Add discovery hint bits in the control channel. * o Add discovery hint bits in the control channel.
* o Remove obsolete MOD_INC/DEC_USE_COUNT in favor of .owner * o Remove obsolete MOD_INC/DEC_USE_COUNT in favor of .owner
*
* v15 - 7.4.03 - Jean II
* o Replace spin_lock_irqsave() with spin_lock_bh() so that we can
* use ppp_unit_number(). It's probably also better overall...
* o Disable call to ppp_unregister_channel(), because we can't do it.
*/ */
/***************************** INCLUDES *****************************/ /***************************** INCLUDES *****************************/
...@@ -276,6 +281,7 @@ ...@@ -276,6 +281,7 @@
#undef CONNECT_INDIC_KICK /* Might mess IrDA, not needed */ #undef CONNECT_INDIC_KICK /* Might mess IrDA, not needed */
#undef FAIL_SEND_DISCONNECT /* Might mess IrDA, not needed */ #undef FAIL_SEND_DISCONNECT /* Might mess IrDA, not needed */
#undef PASS_CONNECT_PACKETS /* Not needed ? Safe */ #undef PASS_CONNECT_PACKETS /* Not needed ? Safe */
#undef MISSING_PPP_API /* Stuff I wish I could do */
/* PPP side of the business */ /* PPP side of the business */
#define BLOCK_WHEN_CONNECT /* Block packets when connecting */ #define BLOCK_WHEN_CONNECT /* Block packets when connecting */
......
This diff is collapsed.
...@@ -927,7 +927,7 @@ ppp_irnet_send(struct ppp_channel * chan, ...@@ -927,7 +927,7 @@ ppp_irnet_send(struct ppp_channel * chan,
* Jean II * Jean II
*/ */
DERROR(PPP_ERROR, "IrTTP doesn't like this packet !!! (0x%X)\n", ret); DERROR(PPP_ERROR, "IrTTP doesn't like this packet !!! (0x%X)\n", ret);
dev_kfree_skb(skb); /* irttp_data_request already free the packet */
} }
DEXIT(PPP_TRACE, "\n"); DEXIT(PPP_TRACE, "\n");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment