summaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/toshoboe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda/toshoboe.c')
-rw-r--r--drivers/net/irda/toshoboe.c310
1 files changed, 116 insertions, 194 deletions
diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c
index d0dbaa4f7..55e0e5b84 100644
--- a/drivers/net/irda/toshoboe.c
+++ b/drivers/net/irda/toshoboe.c
@@ -95,6 +95,7 @@ static char *rcsid = "$Id: toshoboe.c,v 1.9 1999/06/29 14:21:06 root Exp $";
#include <linux/malloc.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/rtnetlink.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -122,7 +123,7 @@ static int max_baud = 4000000;
static void
toshoboe_stopchip (struct toshoboe_cb *self)
{
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
outb_p (0x0e, OBOE_REG_11);
@@ -143,7 +144,7 @@ static void
toshoboe_setbaud (struct toshoboe_cb *self, int baud)
{
unsigned long flags;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
printk (KERN_WARNING "ToshOboe: seting baud to %d\n", baud);
@@ -212,7 +213,7 @@ toshoboe_startchip (struct toshoboe_cb *self)
{
__u32 physaddr;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
outb_p (0, OBOE_LOCK);
@@ -241,7 +242,7 @@ toshoboe_startchip (struct toshoboe_cb *self)
static void
toshoboe_enablebm (struct toshoboe_cb *self)
{
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
pci_set_master (self->pdev);
}
@@ -250,7 +251,7 @@ static void
toshoboe_disablebm (struct toshoboe_cb *self)
{
__u8 command;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
command &= ~PCI_COMMAND_MASTER;
@@ -265,7 +266,7 @@ toshoboe_initbuffs (struct toshoboe_cb *self)
int i;
unsigned long flags;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
save_flags (flags);
cli ();
@@ -287,29 +288,27 @@ toshoboe_initbuffs (struct toshoboe_cb *self)
restore_flags (flags);
}
-
-
-
/*Transmit something */
static int
toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
{
- struct irda_device *idev;
struct toshoboe_cb *self;
+ __u32 speed;
int mtt, len;
- idev = (struct irda_device *) dev->priv;
- ASSERT (idev != NULL, return 0;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;
- );
+ self = (struct toshoboe_cb *) dev->priv;
- self = idev->priv;
ASSERT (self != NULL, return 0;
);
- if (self->stopped)
+ /* Check if we need to change the speed */
+ if ((speed = irda_get_speed(skb)) != self->io.speed)
+ toshoboe_setbaud (self, speed);
+
+ if (self->stopped) {
+ dev_kfree_skb(skb);
return 0;
+ }
#ifdef ONETASK
if (self->txpending)
@@ -376,24 +375,18 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
static void
toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
- struct irda_device *idev = (struct irda_device *) dev_id;
- struct toshoboe_cb *self;
+ struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
__u8 irqstat;
struct sk_buff *skb;
- if (idev == NULL)
+ if (self == NULL)
{
printk (KERN_WARNING "%s: irq %d for unknown device.\n",
driver_name, irq);
return;
}
- self = idev->priv;
-
- if (!self)
- return;
-
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
irqstat = inb_p (OBOE_ISR);
@@ -409,10 +402,10 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
self->txpending--;
- idev->stats.tx_packets++;
+ self->stats.tx_packets++;
- idev->media_busy = FALSE;
- idev->netdev.tbusy = 0;
+ /* idev->media_busy = FALSE; */
+ self->netdev->tbusy = 0;
mark_bh (NET_BH);
}
@@ -441,8 +434,8 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
skb_put (skb, len);
memcpy (skb->data, self->recv_bufs[self->rxs], len);
- idev->stats.rx_packets++;
- skb->dev = &idev->netdev;
+ self->stats.rx_packets++;
+ skb->dev = self->netdev;
skb->mac.raw = skb->data;
skb->protocol = htons (ETH_P_IRDA);
}
@@ -479,79 +472,18 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
/*FIXME: I think this is a TX or RX error of some sort */
- idev->stats.tx_errors++;
- idev->stats.rx_errors++;
+ self->stats.tx_errors++;
+ self->stats.rx_errors++;
}
}
-
-
-/* Change the baud rate */
-static void
-toshoboe_change_speed (struct irda_device *idev, __u32 speed)
-{
- struct toshoboe_cb *self;
- DEBUG (4, __FUNCTION__ "()\n");
-
- ASSERT (idev != NULL, return;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;
- );
-
- self = idev->priv;
- ASSERT (self != NULL, return;
- );
-
-
- idev->io.baudrate = speed;
-
- if (self->stopped)
- return;
-
- toshoboe_setbaud (self, speed);
-
-}
-
-
-/* Check all xmit_tasks finished */
-static void
-toshoboe_wait_until_sent (struct irda_device *idev)
-{
- struct toshoboe_cb *self;
- int i;
-
- DEBUG (4, __FUNCTION__ "()\n");
-
- ASSERT (idev != NULL, return;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;
- );
-
- self = idev->priv;
- ASSERT (self != NULL, return;
- );
-
- if (self->stopped)
- return;
-
- for (i = 0; i < TX_SLOTS; ++i)
- {
- while (self->taskfile->xmit[i].control)
- {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout (MSECS_TO_JIFFIES(60));
- }
- }
-
-}
-
static int
-toshoboe_is_receiving (struct irda_device *idev)
+toshoboe_is_receiving (struct toshoboe_cb *self)
{
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
/*FIXME Can't tell! */
return (FALSE);
@@ -561,7 +493,7 @@ toshoboe_is_receiving (struct irda_device *idev)
static int
toshoboe_net_init (struct net_device *dev)
{
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
/* Setup to be a normal IrDA network device driver */
irda_device_setup (dev);
@@ -607,30 +539,22 @@ toshoboe_initptrs (struct toshoboe_cb *self)
static int
toshoboe_net_open (struct net_device *dev)
{
- struct irda_device *idev;
struct toshoboe_cb *self;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
ASSERT (dev != NULL, return -1;
);
- idev = (struct irda_device *) dev->priv;
-
- ASSERT (idev != NULL, return 0;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;
- );
+ self = (struct toshoboe_cb *) dev->priv;
- self = idev->priv;
ASSERT (self != NULL, return 0;
);
if (self->stopped)
return 0;
-
- if (request_irq (idev->io.irq, toshoboe_interrupt,
- SA_SHIRQ | SA_INTERRUPT, idev->name, (void *) idev))
+ if (request_irq (self->io.irq, toshoboe_interrupt,
+ SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self))
{
return -EAGAIN;
@@ -641,8 +565,17 @@ toshoboe_net_open (struct net_device *dev)
toshoboe_startchip (self);
toshoboe_initptrs (self);
- irda_device_net_open(dev);
-
+ /* Ready to play! */
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ /*
+ * Open new IrLAP layer instance, now that everything should be
+ * initialized properly
+ */
+ self->irlap = irlap_open(dev, &self->qos);
+
self->open = 1;
MOD_INC_USE_COUNT;
@@ -654,30 +587,26 @@ toshoboe_net_open (struct net_device *dev)
static int
toshoboe_net_close (struct net_device *dev)
{
- struct irda_device *idev;
struct toshoboe_cb *self;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
ASSERT (dev != NULL, return -1;
);
- idev = (struct irda_device *) dev->priv;
+ self = (struct toshoboe_cb *) dev->priv;
- ASSERT (idev != NULL, return 0;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;
- );
-
- irda_device_net_close(dev);
-
- self = idev->priv;
-
- ASSERT (self != NULL, return 0;
- );
+ /* Stop device */
+ dev->tbusy = 1;
+ dev->start = 0;
+
+ /* Stop and remove instance of IrLAP */
+ if (self->irlap)
+ irlap_close(self->irlap);
+ self->irlap = NULL;
self->open = 0;
- free_irq (idev->io.irq, (void *) idev);
+ free_irq (self->io.irq, (void *) self);
if (!self->stopped)
{
@@ -698,19 +627,11 @@ toshoboe_net_close (struct net_device *dev)
MODULE_PARM (max_baud, "i");
static int
-toshoboe_close (struct irda_device *idev)
+toshoboe_close (struct toshoboe_cb *self)
{
- struct toshoboe_cb *self;
int i;
- DEBUG (4, __FUNCTION__ "()\n");
-
- ASSERT (idev != NULL, return -1;
- );
- ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return -1;
- );
-
- self = idev->priv;
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
ASSERT (self != NULL, return -1;
);
@@ -721,7 +642,7 @@ toshoboe_close (struct irda_device *idev)
toshoboe_disablebm (self);
}
- release_region (idev->io.iobase, idev->io.io_ext);
+ release_region (self->io.iobase, self->io.io_ext);
for (i = 0; i < TX_SLOTS; ++i)
@@ -736,14 +657,17 @@ toshoboe_close (struct irda_device *idev)
self->recv_bufs[i] = NULL;
}
+ if (self->netdev) {
+ /* Remove netdevice */
+ rtnl_lock();
+ unregister_netdevice(self->netdev);
+ rtnl_unlock();
+ }
kfree (self->taskfilebuf);
self->taskfilebuf = NULL;
self->taskfile = NULL;
-
- irda_device_close (idev);
-
return (0);
}
@@ -756,12 +680,12 @@ static int
toshoboe_open (struct pci_dev *pci_dev)
{
struct toshoboe_cb *self;
- struct irda_device *idev;
+ struct net_device *dev;
int i = 0;
int ok = 0;
+ int err;
-
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
while (dev_self[i])
i++;
@@ -790,21 +714,17 @@ toshoboe_open (struct pci_dev *pci_dev)
self->pdev = pci_dev;
self->base = pci_dev->resource[0].start;
- idev = &self->idev;
-
- /*Setup idev */
-
- idev->io.iobase = self->base;
- idev->io.irq = pci_dev->irq;
- idev->io.io_ext = CHIP_IO_EXTENT;
- idev->io.baudrate = 9600;
+ self->io.iobase = self->base;
+ self->io.irq = pci_dev->irq;
+ self->io.io_ext = CHIP_IO_EXTENT;
+ self->io.speed = 9600;
/* Lock the port that we need */
- i = check_region (idev->io.iobase, idev->io.io_ext);
+ i = check_region (self->io.iobase, self->io.io_ext);
if (i < 0)
{
- DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
- idev->io.iobase);
+ IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+ self->io.iobase);
dev_self[i] = NULL;
kfree (self);
@@ -813,57 +733,39 @@ toshoboe_open (struct pci_dev *pci_dev)
}
- irda_init_max_qos_capabilies (&idev->qos);
- idev->qos.baud_rate.bits = 0;
+ irda_init_max_qos_capabilies (&self->qos);
+ self->qos.baud_rate.bits = 0;
if (max_baud >= 2400)
- idev->qos.baud_rate.bits |= IR_2400;
+ self->qos.baud_rate.bits |= IR_2400;
/*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
if (max_baud >= 9600)
- idev->qos.baud_rate.bits |= IR_9600;
+ self->qos.baud_rate.bits |= IR_9600;
if (max_baud >= 19200)
- idev->qos.baud_rate.bits |= IR_19200;
+ self->qos.baud_rate.bits |= IR_19200;
if (max_baud >= 115200)
- idev->qos.baud_rate.bits |= IR_115200;
+ self->qos.baud_rate.bits |= IR_115200;
#ifdef ENABLE_FAST
if (max_baud >= 576000)
- idev->qos.baud_rate.bits |= IR_576000;
+ self->qos.baud_rate.bits |= IR_576000;
if (max_baud >= 1152000)
- idev->qos.baud_rate.bits |= IR_1152000;
+ self->qos.baud_rate.bits |= IR_1152000;
if (max_baud >= 4000000)
- idev->qos.baud_rate.bits |= (IR_4000000 << 8);
+ self->qos.baud_rate.bits |= (IR_4000000 << 8);
#endif
- idev->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */
+ self->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */
- irda_qos_bits_to_value (&idev->qos);
+ irda_qos_bits_to_value (&self->qos);
- idev->flags = IFF_SIR | IFF_DMA | IFF_PIO;
+ self->flags = IFF_SIR | IFF_DMA | IFF_PIO;
#ifdef ENABLE_FAST
if (max_baud >= 576000)
- idev->flags |= IFF_FIR;
+ self->flags |= IFF_FIR;
#endif
- /* These aren't much use as we need to have a whole panoply of
- * buffers running */
-
- idev->rx_buff.flags = 0;
- idev->tx_buff.flags = 0;
- idev->rx_buff.truesize = 0;
- idev->rx_buff.truesize = 0;
-
- idev->change_speed = toshoboe_change_speed;
- idev->wait_until_sent = toshoboe_wait_until_sent;
- idev->is_receiving = toshoboe_is_receiving;
-
- idev->netdev.init = toshoboe_net_init;
- idev->netdev.hard_start_xmit = toshoboe_hard_xmit;
- idev->netdev.open = toshoboe_net_open;
- idev->netdev.stop = toshoboe_net_close;
-
-
/* Now setup the endless buffers we need */
self->txs = 0;
@@ -922,9 +824,32 @@ toshoboe_open (struct pci_dev *pci_dev)
}
- request_region (idev->io.iobase, idev->io.io_ext, driver_name);
+ request_region (self->io.iobase, self->io.io_ext, driver_name);
- irda_device_open (idev, driver_name, self);
+ if (!(dev = dev_alloc("irda%d", &err))) {
+ ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+ return -ENOMEM;
+ }
+ /* dev_alloc doesn't clear the struct, so lets do a little hack */
+ memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*));
+
+ dev->priv = (void *) self;
+ self->netdev = dev;
+
+ MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+ dev->init = toshoboe_net_init;
+ dev->hard_start_xmit = toshoboe_hard_xmit;
+ dev->open = toshoboe_net_open;
+ dev->stop = toshoboe_net_close;
+
+ rtnl_lock();
+ err = register_netdevice(dev);
+ rtnl_unlock();
+ if (err) {
+ ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
+ return -1;
+ }
printk (KERN_WARNING "ToshOboe: Using ");
#ifdef ONETASK
@@ -969,8 +894,7 @@ toshoboe_gotosleep (struct toshoboe_cb *self)
static void
toshoboe_wakeup (struct toshoboe_cb *self)
{
- struct irda_device *idev = &self->idev;
- struct net_device *dev = &idev->netdev;
+ struct net_device *dev = self->netdev;
unsigned long flags;
if (!self->stopped)
@@ -989,12 +913,10 @@ toshoboe_wakeup (struct toshoboe_cb *self)
toshoboe_enablebm (self);
toshoboe_startchip (self);
- toshoboe_setbaud (self, idev->io.baudrate);
+ toshoboe_setbaud (self, self->io.speed);
toshoboe_initptrs (self);
-
-
dev->tbusy = 0;
dev->interrupt = 0;
dev->start = 1;
@@ -1093,12 +1015,12 @@ toshoboe_cleanup (void)
{
int i;
- DEBUG (4, __FUNCTION__ "()\n");
+ IRDA_DEBUG (4, __FUNCTION__ "()\n");
for (i = 0; i < 4; i++)
{
if (dev_self[i])
- toshoboe_close (&(dev_self[i]->idev));
+ toshoboe_close (dev_self[i]);
}
#ifdef CONFIG_APM