Commit 3e65b7a3 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/disk1/davem/BK/network-2.5

into nuts.ninka.net:/disk1/davem/BK/net-2.5
parents db4cf641 83055835
......@@ -84,12 +84,12 @@ static int act200l_change_speed(struct irda_task *task);
#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */
static struct dongle_reg dongle = {
Q_NULL,
IRDA_ACT200L_DONGLE,
act200l_open,
act200l_close,
act200l_reset,
act200l_change_speed,
.type = IRDA_ACT200L_DONGLE,
.open = act200l_open,
.close = act200l_close,
.reset = act200l_reset,
.change_speed = act200l_change_speed,
.owner = THIS_MODULE,
};
int __init act200l_init(void)
......@@ -112,8 +112,6 @@ static void act200l_open(dongle_t *self, struct qos_info *qos)
/* Set the speeds we can accept */
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x03;
MOD_INC_USE_COUNT;
}
static void act200l_close(dongle_t *self)
......@@ -122,8 +120,6 @@ static void act200l_close(dongle_t *self)
/* Power off the dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -64,21 +64,21 @@ static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 };
#define MAX_SPEEDS 5
static struct dongle_reg dongle = {
Q_NULL,
IRDA_ACTISYS_DONGLE,
actisys_open,
actisys_close,
actisys_reset,
actisys_change_speed,
.type = IRDA_ACTISYS_DONGLE,
.open = actisys_open,
.close = actisys_close,
.reset = actisys_reset,
.change_speed = actisys_change_speed,
.owner = THIS_MODULE,
};
static struct dongle_reg dongle_plus = {
Q_NULL,
IRDA_ACTISYS_PLUS_DONGLE,
actisys_open,
actisys_close,
actisys_reset,
actisys_change_speed,
.type = IRDA_ACTISYS_PLUS_DONGLE,
.open = actisys_open,
.close = actisys_close,
.reset = actisys_reset,
.change_speed = actisys_change_speed,
.owner = THIS_MODULE,
};
/*
......@@ -128,16 +128,12 @@ static void actisys_open(dongle_t *self, struct qos_info *qos)
qos->baud_rate.bits &= ~IR_38400;
qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
MOD_INC_USE_COUNT;
}
static void actisys_close(dongle_t *self)
{
/* Power off the dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -24,12 +24,12 @@ static int ep7211_ir_change_speed(struct irda_task *task);
static int ep7211_ir_reset(struct irda_task *task);
static struct dongle_reg dongle = {
Q_NULL,
IRDA_EP7211_IR,
ep7211_ir_open,
ep7211_ir_close,
ep7211_ir_reset,
ep7211_ir_change_speed,
.type = IRDA_EP7211_IR,
.open = ep7211_ir_open,
.close = ep7211_ir_close,
.reset = ep7211_ir_reset,
.change_speed = ep7211_ir_change_speed,
.owner = THIS_MODULE,
};
static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
......@@ -47,8 +47,6 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
UART (interrupt #14). */
restore_flags(flags);
MOD_INC_USE_COUNT;
}
static void ep7211_ir_close(dongle_t *self)
......@@ -66,8 +64,6 @@ static void ep7211_ir_close(dongle_t *self)
reset them back to their original state. */
restore_flags(flags);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -44,12 +44,12 @@ static int esi_change_speed(struct irda_task *task);
static int esi_reset(struct irda_task *task);
static struct dongle_reg dongle = {
Q_NULL,
IRDA_ESI_DONGLE,
esi_open,
esi_close,
esi_reset,
esi_change_speed,
.type = IRDA_ESI_DONGLE,
.open = esi_open,
.close = esi_close,
.reset = esi_reset,
.change_speed = esi_change_speed,
.owner = THIS_MODULE,
};
int __init esi_init(void)
......@@ -66,16 +66,12 @@ static void esi_open(dongle_t *self, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
MOD_INC_USE_COUNT;
}
static void esi_close(dongle_t *dongle)
{
/* Power off dongle */
dongle->set_dtr_rts(dongle->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -63,12 +63,12 @@ static int girbil_change_speed(struct irda_task *task);
#define GIRBIL_LOAD 0x51 /* Load the new baud rate value */
static struct dongle_reg dongle = {
Q_NULL,
IRDA_GIRBIL_DONGLE,
girbil_open,
girbil_close,
girbil_reset,
girbil_change_speed,
.type = IRDA_GIRBIL_DONGLE,
.open = girbil_open,
.close = girbil_close,
.reset = girbil_reset,
.change_speed = girbil_change_speed,
.owner = THIS_MODULE,
};
int __init girbil_init(void)
......@@ -85,16 +85,12 @@ static void girbil_open(dongle_t *self, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x03;
MOD_INC_USE_COUNT;
}
static void girbil_close(dongle_t *self)
{
/* Power off dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -48,12 +48,12 @@ static int litelink_reset(struct irda_task *task);
static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 };
static struct dongle_reg dongle = {
Q_NULL,
IRDA_LITELINK_DONGLE,
litelink_open,
litelink_close,
litelink_reset,
litelink_change_speed,
.type = IRDA_LITELINK_DONGLE,
.open = litelink_open,
.close = litelink_close,
.reset = litelink_reset,
.change_speed = litelink_change_speed,
.owner = THIS_MODULE,
};
int __init litelink_init(void)
......@@ -70,16 +70,12 @@ static void litelink_open(dongle_t *self, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
MOD_INC_USE_COUNT;
}
static void litelink_close(dongle_t *self)
{
/* Power off dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -74,12 +74,12 @@ static int ma600_reset(struct irda_task *task);
#define MA600_2400 0x08
static struct dongle_reg dongle = {
Q_NULL,
IRDA_MA600_DONGLE,
ma600_open,
ma600_close,
ma600_reset,
ma600_change_speed,
.type = IRDA_MA600_DONGLE,
.open = ma600_open,
.close = ma600_close,
.reset = ma600_reset,
.change_speed = ma600_change_speed,
.owner = THIS_MODULE,
};
int __init ma600_init(void)
......@@ -115,8 +115,6 @@ static void ma600_open(dongle_t *self, struct qos_info *qos)
self->set_dtr_rts(self->dev, TRUE, TRUE);
// should wait 1 second
MOD_INC_USE_COUNT;
}
static void ma600_close(dongle_t *self)
......@@ -125,8 +123,6 @@ static void ma600_close(dongle_t *self)
/* Power off dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
static __u8 get_control_byte(__u32 speed)
......
......@@ -40,12 +40,12 @@ static int mcp2120_change_speed(struct irda_task *task);
#define MCP2120_COMMIT 0x11
static struct dongle_reg dongle = {
Q_NULL,
IRDA_MCP2120_DONGLE,
mcp2120_open,
mcp2120_close,
mcp2120_reset,
mcp2120_change_speed,
.type = IRDA_MCP2120_DONGLE,
.open = mcp2120_open,
.close = mcp2120_close,
.reset = mcp2120_reset,
.change_speed = mcp2120_change_speed,
.owner = THIS_MODULE,
};
int __init mcp2120_init(void)
......@@ -62,8 +62,6 @@ static void mcp2120_open(dongle_t *self, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x01;
MOD_INC_USE_COUNT;
}
static void mcp2120_close(dongle_t *self)
......@@ -72,8 +70,6 @@ static void mcp2120_close(dongle_t *self)
/* reset and inhibit mcp2120 */
self->set_dtr_rts(self->dev, TRUE, TRUE);
//self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -74,12 +74,12 @@ static int old_belkin_reset(struct irda_task *task);
/* static __u32 baud_rates[] = { 9600 }; */
static struct dongle_reg dongle = {
Q_NULL,
IRDA_OLD_BELKIN_DONGLE,
old_belkin_open,
old_belkin_close,
old_belkin_reset,
old_belkin_change_speed,
.type = IRDA_OLD_BELKIN_DONGLE,
.open = old_belkin_open,
.close = old_belkin_close,
.reset = old_belkin_reset,
.change_speed = old_belkin_change_speed,
.owner = THIS_MODULE,
};
int __init old_belkin_init(void)
......@@ -98,16 +98,12 @@ static void old_belkin_open(dongle_t *self, struct qos_info *qos)
qos->baud_rate.bits &= IR_9600;
/* Needs at least 10 ms (totally wild guess, can do probably better) */
qos->min_turn_time.bits = 0x01;
MOD_INC_USE_COUNT;
}
static void old_belkin_close(dongle_t *self)
{
/* Power off dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -44,12 +44,12 @@ static int tekram_reset(struct irda_task *task);
#define TEKRAM_PW 0x10 /* Pulse select bit */
static struct dongle_reg dongle = {
Q_NULL,
IRDA_TEKRAM_DONGLE,
tekram_open,
tekram_close,
tekram_reset,
tekram_change_speed,
.type = IRDA_TEKRAM_DONGLE,
.open = tekram_open,
.close = tekram_close,
.reset = tekram_reset,
.change_speed = tekram_change_speed,
.owner = THIS_MODULE,
};
int __init tekram_init(void)
......@@ -69,8 +69,6 @@ static void tekram_open(dongle_t *self, struct qos_info *qos)
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
irda_qos_bits_to_value(qos);
MOD_INC_USE_COUNT;
}
static void tekram_close(dongle_t *self)
......@@ -84,8 +82,6 @@ static void tekram_close(dongle_t *self)
irda_task_delete(self->reset_task);
if (self->speed_task)
irda_task_delete(self->speed_task);
MOD_DEC_USE_COUNT;
}
/*
......
......@@ -1300,12 +1300,9 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
switch( cmd ) {
case SIOCDEVGETINSTATS :
error = verify_area( VERIFY_WRITE, ifr->ifr_data,
sizeof(struct sbni_in_stats) );
if( !error )
if (copy_to_user( ifr->ifr_data, &nl->in_stats,
sizeof(struct sbni_in_stats) ))
return -EFAULT;
if (copy_to_user( ifr->ifr_data, &nl->in_stats,
sizeof(struct sbni_in_stats) ))
error = -EFAULT;
break;
case SIOCDEVRESINSTATS :
......@@ -1321,11 +1318,8 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
flags.rxl = nl->cur_rxl_index;
flags.fixed_rxl = nl->delta_rxl == 0;
error = verify_area( VERIFY_WRITE, ifr->ifr_data,
sizeof flags );
if( !error )
if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
return -EFAULT;
if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
error = -EFAULT;
break;
case SIOCDEVSHWSTATE :
......@@ -1353,10 +1347,6 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
if( current->euid != 0 ) /* root only */
return -EPERM;
if( (error = verify_area( VERIFY_READ, ifr->ifr_data,
sizeof slave_name )) != 0 )
return error;
if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
return -EFAULT;
slave_dev = dev_get_by_name( slave_name );
......
......@@ -236,7 +236,7 @@ void sppp_input (struct net_device *dev, struct sk_buff *skb)
sp->ipkts++;
}
if (skb->len <= PPP_HEADER_LEN) {
if (!pskb_may_pull(skb, PPP_HEADER_LEN)) {
/* Too small packet, drop it. */
if (sp->pp_flags & PP_DEBUG)
printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",
......@@ -473,7 +473,7 @@ static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb)
u8 *p, opt[6];
u32 rmagic;
if (len < 4) {
if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
if (sp->pp_flags & PP_DEBUG)
printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n",
dev->name, len);
......@@ -707,7 +707,9 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
struct cisco_packet *h;
struct net_device *dev = sp->pp_if;
if (skb->len != CISCO_PACKET_LEN && skb->len != CISCO_BIG_PACKET_LEN) {
if (!pskb_may_pull(skb, sizeof(struct cisco_packet))
|| (skb->len != CISCO_PACKET_LEN
&& skb->len != CISCO_BIG_PACKET_LEN)) {
if (sp->pp_flags & PP_DEBUG)
printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n",
dev->name, skb->len);
......@@ -1211,8 +1213,7 @@ static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb)
struct net_device *dev = sp->pp_if;
int len = skb->len;
if (len < 4)
{
if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
if (sp->pp_flags & PP_DEBUG)
printk (KERN_WARNING "%s: invalid ipcp packet length: %d bytes\n",
dev->name, len);
......
......@@ -128,6 +128,7 @@ struct dongle_reg {
void (*close)(dongle_t *dongle);
int (*reset)(struct irda_task *task);
int (*change_speed)(struct irda_task *task);
struct module *owner;
};
/*
......
......@@ -85,7 +85,7 @@ static void irda_task_timer_expired(void *data);
int __init irda_device_init( void)
{
dongles = hashbin_new(HB_LOCK);
dongles = hashbin_new(HB_NOLOCK);
if (dongles == NULL) {
printk(KERN_WARNING "IrDA: Can't allocate dongles hashbin!\n");
return -ENOMEM;
......@@ -109,7 +109,9 @@ void __exit irda_device_cleanup(void)
IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
spin_lock(&dongles->hb_spinlock);
hashbin_delete(dongles, NULL);
spin_unlock(&dongles->hb_spinlock);
}
/*
......@@ -424,25 +426,34 @@ int irda_device_txqueue_empty(struct net_device *dev)
dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
{
struct dongle_reg *reg;
dongle_t *dongle;
dongle_t *dongle = NULL;
ASSERT(dev != NULL, return NULL;);
might_sleep();
spin_lock(&dongles->hb_spinlock);
reg = hashbin_find(dongles, type, NULL);
#ifdef CONFIG_KMOD
ASSERT(!in_interrupt(), return NULL;);
/* Try to load the module needed */
request_module("irda-dongle-%d", type);
if (!reg && capable(CAP_SYS_MODULE)) {
spin_unlock(&dongles->hb_spinlock);
request_module("irda-dongle-%d", type);
spin_lock(&dongles->hb_spinlock);
reg = hashbin_find(dongles, type, NULL);
}
#endif
if (!(reg = hashbin_lock_find(dongles, type, NULL))) {
ERROR("IrDA: Unable to find requested dongle\n");
return NULL;
if (!reg || !try_module_get(reg->owner) ) {
ERROR("IrDA: Unable to find requested dongle type %x\n", type);
goto out;
}
/* Allocate dongle info for this instance */
dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL);
if (!dongle)
return NULL;
goto out;
memset(dongle, 0, sizeof(dongle_t));
......@@ -450,6 +461,8 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
dongle->issue = reg;
dongle->dev = dev;
out:
spin_unlock(&dongles->hb_spinlock);
return dongle;
}
......@@ -461,7 +474,7 @@ int irda_device_dongle_cleanup(dongle_t *dongle)
ASSERT(dongle != NULL, return -1;);
dongle->issue->close(dongle);
module_put(dongle->issue->owner);
kfree(dongle);
return 0;
......@@ -472,14 +485,16 @@ int irda_device_dongle_cleanup(dongle_t *dongle)
*/
int irda_device_register_dongle(struct dongle_reg *new)
{
spin_lock(&dongles->hb_spinlock);
/* Check if this dongle has been registered before */
if (hashbin_lock_find(dongles, new->type, NULL)) {
MESSAGE("%s: Dongle already registered\n", __FUNCTION__);
return 0;
}
/* Insert IrDA dongle into hashbin */
hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
if (hashbin_find(dongles, new->type, NULL)) {
MESSAGE("%s: Dongle type %x already registered\n",
__FUNCTION__, new->type);
} else {
/* Insert IrDA dongle into hashbin */
hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
}
spin_unlock(&dongles->hb_spinlock);
return 0;
}
......@@ -494,11 +509,11 @@ void irda_device_unregister_dongle(struct dongle_reg *dongle)
{
struct dongle *node;
spin_lock(&dongles->hb_spinlock);
node = hashbin_remove(dongles, dongle->type, NULL);
if (!node) {
if (!node)
ERROR("%s: dongle not found!\n", __FUNCTION__);
return;
}
spin_unlock(&dongles->hb_spinlock);
}
/*
......
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