diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:45:22 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:45:22 +0000 |
commit | 5b35aa5cd29bb111d847b2a2ed18110acbfb1f44 (patch) | |
tree | c7bbaa1137528330d3c74d14056ef7016a52be72 /drivers/net/irda | |
parent | 511bcd7c5924ce9e98ad1cb851988f7448dfef0f (diff) |
Merge with Linux 2.3.24.
Diffstat (limited to 'drivers/net/irda')
-rw-r--r-- | drivers/net/irda/actisys.c | 179 | ||||
-rw-r--r-- | drivers/net/irda/airport.c | 60 | ||||
-rw-r--r-- | drivers/net/irda/esi.c | 111 | ||||
-rw-r--r-- | drivers/net/irda/girbil.c | 209 | ||||
-rw-r--r-- | drivers/net/irda/irport.c | 416 | ||||
-rw-r--r-- | drivers/net/irda/irtty.c | 623 | ||||
-rw-r--r-- | drivers/net/irda/litelink.c | 85 | ||||
-rw-r--r-- | drivers/net/irda/pc87108.c | 785 | ||||
-rw-r--r-- | drivers/net/irda/smc-ircc.c | 114 | ||||
-rw-r--r-- | drivers/net/irda/tekram.c | 192 | ||||
-rw-r--r-- | drivers/net/irda/toshoboe.c | 310 | ||||
-rw-r--r-- | drivers/net/irda/uircc.c | 62 | ||||
-rw-r--r-- | drivers/net/irda/w83977af_ir.c | 522 |
13 files changed, 2029 insertions, 1639 deletions
diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c index f83fce38c..10d6cf208 100644 --- a/drivers/net/irda/actisys.c +++ b/drivers/net/irda/actisys.c @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Sat Jun 26 16:57:57 1999 + * Modified at: Mon Oct 18 23:37:06 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -32,33 +32,31 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/dongle.h> -static void actisys_reset(struct irda_device *dev); -static void actisys_open(struct irda_device *idev, int type); -static void actisys_close(struct irda_device *dev); -static void actisys_change_speed( struct irda_device *dev, __u32 speed); -static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos); +static int actisys_change_speed(struct irda_task *task); +static int actisys_reset(struct irda_task *task); +static void actisys_open(dongle_t *self, struct qos_info *qos); +static void actisys_close(dongle_t *self); /* These are the baudrates supported */ -static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400}; +static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 }; -static struct dongle dongle = { - ACTISYS_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_ACTISYS_DONGLE, actisys_open, actisys_close, actisys_reset, actisys_change_speed, - actisys_init_qos, }; -static struct dongle dongle_plus = { - ACTISYS_PLUS_DONGLE, +static struct dongle_reg dongle_plus = { + Q_NULL, + IRDA_ACTISYS_PLUS_DONGLE, actisys_open, actisys_close, actisys_reset, actisys_change_speed, - actisys_init_qos, }; int __init actisys_init(void) @@ -82,20 +80,23 @@ void actisys_cleanup(void) irda_device_unregister_dongle(&dongle_plus); } -static void actisys_open(struct irda_device *idev, int type) +static void actisys_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> actisys"); + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + /* Remove support for 38400 if this is not a 220L+ dongle */ + if (self->issue->type == IRDA_ACTISYS_DONGLE) + qos->baud_rate.bits &= ~IR_38400; + + qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ MOD_INC_USE_COUNT; } -static void actisys_close(struct irda_device *idev) +static void actisys_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } @@ -107,52 +108,84 @@ static void actisys_close(struct irda_device *idev) * To cycle through the available baud rates, pulse RTS low for a few * ms. */ -static void actisys_change_speed(struct irda_device *idev, __u32 speed) +static int actisys_change_speed(struct irda_task *task) { - __u32 current_baudrate; + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; + __u32 current_speed; int index = 0; + int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - current_baudrate = idev->qos.baud_rate.value; + current_speed = self->speed; /* Find the correct baudrate index for the currently used baudrate */ - while (current_baudrate != baud_rates[index]) + while (current_speed != baud_rates[index]) index++; - DEBUG( 4, __FUNCTION__ "(), index=%d\n", index); + IRDA_DEBUG(4, __FUNCTION__ "(), index=%d\n", index); - /* Cycle through avaiable baudrates until we reach the correct one */ - while (current_baudrate != speed) { - DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + ret = MSECS_TO_JIFFIES(100); + break; + } + + IRDA_DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); /* Set DTR, clear RTS */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); - /* Wait at a few ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + irda_task_next_state(task, IRDA_TASK_WAIT1); + /* Wait at a few ms */ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT1: /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); - /* Wait at a few ms again */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + irda_task_next_state(task, IRDA_TASK_WAIT2); + /* Wait at a few ms again */ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT2: /* Go to next baudrate */ - if (idev->io.dongle_id == ACTISYS_DONGLE) + if (self->issue->type == IRDA_ACTISYS_DONGLE) index = (index+1) % 4; /* IR-220L */ else index = (index+1) % 5; /* IR-220L+ */ - current_baudrate = baud_rates[index]; + current_speed = baud_rates[index]; + + /* Check if we need to go some more rounds */ + if (current_speed != speed) + irda_task_next_state(task, IRDA_TASK_INIT); + else { + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + } + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; + break; } - DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); + + self->speed = speed; + + IRDA_DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", + baud_rates[index]); + + return ret; } /* @@ -162,45 +195,42 @@ static void actisys_change_speed(struct irda_device *idev, __u32 speed) * called with a process context! * * 1. Clear DTR for a few ms. - * */ -static void actisys_reset(struct irda_device *idev) +static int actisys_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - /* Clear DTR */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + dongle_t *self = (dongle_t *) task->instance; + int ret = 0; - /* Sleep 10-20 ms*/ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); - - idev->qos.baud_rate.value = 9600; -} + ASSERT(task != NULL, return -1;); -/* - * Function actisys_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + switch (task->state) { + case IRDA_TASK_INIT: + /* Clear DTR */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + + irda_task_next_state(task, IRDA_TASK_WAIT); - /* Remove support for 38400 if this is not a 220L+ dongle */ - if (idev->io.dongle_id == ACTISYS_DONGLE) - qos->baud_rate.bits &= ~IR_38400; + /* Sleep 10-20 ms*/ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); - qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ + irda_task_next_state(task, IRDA_TASK_DONE); + + self->speed = 9600; + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver"); @@ -225,5 +255,4 @@ void cleanup_module(void) { actisys_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/airport.c b/drivers/net/irda/airport.c index edfc2e6e6..a1eee252b 100644 --- a/drivers/net/irda/airport.c +++ b/drivers/net/irda/airport.c @@ -56,7 +56,7 @@ int __init airport_init(void) { int ret; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ret = irda_device_register_dongle(&dongle); if (ret < 0) return ret; @@ -65,17 +65,17 @@ int __init airport_init(void) void airport_cleanup(void) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_unregister_dongle(&dongle); } static void airport_open(struct irda_device *idev, int type) { - DEBUG(2, __FUNCTION__ "(,%d)\n", type); + IRDA_DEBUG(2, __FUNCTION__ "(,%d)\n", type); if (strlen(idev->description) < sizeof(idev->description) - 13) strcat(idev->description, " <-> airport"); else - DEBUG(0, __FUNCTION__ " description too long: %s\n", + IRDA_DEBUG(0, __FUNCTION__ " description too long: %s\n", idev->description); idev->io.dongle_id = type; @@ -86,7 +86,7 @@ static void airport_open(struct irda_device *idev, int type) static void airport_close(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); /* Power off dongle */ irda_device_set_dtr_rts(idev, FALSE, FALSE); @@ -95,13 +95,13 @@ static void airport_close(struct irda_device *idev) static void airport_set_command_mode(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_set_dtr_rts(idev, FALSE, TRUE); } static void airport_set_normal_mode(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_set_dtr_rts(idev, TRUE, TRUE); } @@ -109,7 +109,7 @@ static void airport_set_normal_mode(struct irda_device *idev) void airport_write_char(struct irda_device *idev, unsigned char c) { int actual; - DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff); + IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff); actual = idev->raw_write(idev, &c, 1); ASSERT(actual == 1, return;); } @@ -120,22 +120,22 @@ static int airport_waitfor_char(struct irda_device *idev, unsigned char c) { int i, found = FALSE; int before; - DEBUG(2, __FUNCTION__ "(,0x%x)\n", c); + IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c); /* Sleep approx. 10 ms */ before = jiffies; current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); - DEBUG(4, __FUNCTION__ " waited %ldms\n", + IRDA_DEBUG(4, __FUNCTION__ " waited %ldms\n", JIFFIES_TO_MSECS(jiffies - before)); for ( i = 0 ; !found && i < idev->rx_buff.len ; i++ ) { - /* DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */ + /* IRDA_DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */ found = c == idev->rx_buff.data[i]; } idev->rx_buff.len = 0; - DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false")); + IRDA_DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false")); return found; } @@ -144,7 +144,7 @@ static int airport_check_command_mode(struct irda_device *idev) int i; int found = FALSE; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); airport_set_command_mode(idev); @@ -160,9 +160,9 @@ static int airport_check_command_mode(struct irda_device *idev) } if (found) { - DEBUG(2, __FUNCTION__ " OK. (%d)\n", i); + IRDA_DEBUG(2, __FUNCTION__ " OK. (%d)\n", i); } else { - DEBUG(0, __FUNCTION__ " FAILED!\n"); + IRDA_DEBUG(0, __FUNCTION__ " FAILED!\n"); } return found; } @@ -173,7 +173,7 @@ static int airport_write_register(struct irda_device *idev, unsigned char reg) int ok = FALSE; int i; - DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg); + IRDA_DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg); airport_check_command_mode(idev); for ( i = 0 ; i < 6 ; i++ ) { @@ -191,9 +191,9 @@ static int airport_write_register(struct irda_device *idev, unsigned char reg) airport_set_normal_mode(idev); if (ok) { - DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg); + IRDA_DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg); } else { - DEBUG(0, __FUNCTION__ "(,0x%x) returns False!\n", reg); + IRDA_DEBUG(0, __FUNCTION__ "(,0x%x) returns False!\n", reg); } return ok; } @@ -209,7 +209,7 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) __u32 current_baudrate; int baudcode; - DEBUG(4, __FUNCTION__ "(,%d)\n", speed); + IRDA_DEBUG(4, __FUNCTION__ "(,%d)\n", speed); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -224,16 +224,16 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) case 57600: baudcode = 0x60; break; case 115200: baudcode = 0x70; break; default: - DEBUG(0, __FUNCTION__ " bad baud rate: %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ " bad baud rate: %d\n", speed); return; } current_baudrate = idev->qos.baud_rate.value; - DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate); + IRDA_DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate); /* The dongle falls back to 9600 baud */ if (current_baudrate != 9600) { - DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n"); + IRDA_DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n"); ASSERT(idev->change_speed , return;); idev->change_speed(idev, 9600); idev->qos.baud_rate.value = 9600; @@ -247,11 +247,11 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) if (airport_write_register(idev, baudcode|0x01)) { /* ok */ } else { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ " Cannot set new speed in second register\n"); } } else { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ " Cannot set new speed in first register\n"); } @@ -260,7 +260,7 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) /* How do I signal an error in these functions? */ - DEBUG(4, __FUNCTION__ " returning\n"); + IRDA_DEBUG(4, __FUNCTION__ " returning\n"); } @@ -275,7 +275,7 @@ static void airport_reset(struct irda_device *idev) { int ok; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); ASSERT(idev->set_raw_mode /* The airport needs this */, return;); @@ -286,10 +286,10 @@ static void airport_reset(struct irda_device *idev) airport_set_normal_mode(idev); /* Sleep 2000 ms */ - DEBUG(2, __FUNCTION__ " waiting for powerup\n"); + IRDA_DEBUG(2, __FUNCTION__ " waiting for powerup\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(2000)); - DEBUG(2, __FUNCTION__ " finished waiting for powerup\n"); + IRDA_DEBUG(2, __FUNCTION__ " finished waiting for powerup\n"); /* set dongle speed to 9600 */ ok = TRUE; @@ -322,12 +322,12 @@ static void airport_reset(struct irda_device *idev) current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); - DEBUG(4, __FUNCTION__ " waited 20ms\n"); + IRDA_DEBUG(4, __FUNCTION__ " waited 20ms\n"); idev->qos.baud_rate.value = 9600; if (!ok) MESSAGE(__FUNCTION__ "() failed.\n"); - DEBUG(2, __FUNCTION__ " returning.\n"); + IRDA_DEBUG(2, __FUNCTION__ " returning.\n"); } /* diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c index f531c1af4..bc6f28da7 100644 --- a/drivers/net/irda/esi.c +++ b/drivers/net/irda/esi.c @@ -1,27 +1,33 @@ /********************************************************************* * * Filename: esi.c - * Version: 1.4 + * Version: 1.5 * Description: Driver for the Extended Systems JetEye PC dongle * Status: Experimental. - * Author: Thomas Davis, <ratbert@radiks.net> + * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Sat Jun 26 16:50:17 1999 + * Modified at: Mon Oct 18 12:35:43 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> - * Sources: esi.c - * - * Copyright (c) 1998-1999, Dag Brattli, <dagb@cs.uit.no> - * Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, + * + * Copyright (c) 1999 Dag Brattli, <dagb@cs.uit.no>, + * Copyright (c) 1998 Thomas Davis, <ratbert@radiks.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 + * + * 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. - * - * I, Thomas Davis, provide no warranty for any of this software. - * This material is provided "AS-IS" and at no charge. - * + * + * 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 + * ********************************************************************/ #include <linux/module.h> @@ -34,22 +40,19 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void esi_open(struct irda_device *idev, int type); -static void esi_close(struct irda_device *driver); -static void esi_change_speed(struct irda_device *idev, __u32 speed); -static void esi_reset(struct irda_device *idev); -static void esi_qos_init(struct irda_device *idev, struct qos_info *qos); +static void esi_open(dongle_t *self, struct qos_info *qos); +static void esi_close(dongle_t *self); +static int esi_change_speed(struct irda_task *task); +static int esi_reset(struct irda_task *task); -static struct dongle dongle = { - ESI_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_ESI_DONGLE, esi_open, esi_close, esi_reset, esi_change_speed, - esi_qos_init, }; int __init esi_init(void) @@ -62,37 +65,40 @@ void esi_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void esi_open(struct irda_device *idev, int type) +static void esi_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> esi"); - - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + 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(struct irda_device *idev) +static void esi_close(dongle_t *dongle) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + dongle->set_dtr_rts(dongle->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function esi_change_speed (idev, speed) + * Function esi_change_speed (task) * * Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle * */ -static void esi_change_speed(struct irda_device *idev, __u32 speed) +static int esi_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; int dtr, rts; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + switch (speed) { case 19200: dtr = TRUE; @@ -109,28 +115,34 @@ static void esi_change_speed(struct irda_device *idev, __u32 speed) } /* Change speed of dongle */ - irda_device_set_dtr_rts(idev, dtr, rts); -} + self->set_dtr_rts(self->dev, dtr, rts); + self->speed = speed; -static void esi_reset( struct irda_device *idev) -{ - /* Empty */ + irda_task_next_state(task, IRDA_TASK_DONE); + + /* Unlock */ + self->busy = 0; + + return 0; } /* - * Function esi_qos_init (qos) + * Function esi_reset (task) * - * Init QoS capabilities for the dongle + * Reset dongle; * */ -static void esi_qos_init(struct irda_device *idev, struct qos_info *qos) +static int esi_reset(struct irda_task *task) { - qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200; - qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */ + dongle_t *self = (dongle_t *) task->instance; + + self->set_dtr_rts(self->dev, FALSE, FALSE); + irda_task_next_state(task, IRDA_TASK_DONE); + + return 0; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver"); @@ -155,6 +167,5 @@ void cleanup_module(void) { esi_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c index 2d1d1f269..4fa2ec59f 100644 --- a/drivers/net/irda/girbil.c +++ b/drivers/net/irda/girbil.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Feb 6 21:02:33 1999 - * Modified at: Sun Jul 18 12:09:26 1999 + * Modified at: Mon Oct 18 22:15:20 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -32,13 +32,11 @@ #include <net/irda/irmod.h> #include <net/irda/irda_device.h> #include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void girbil_reset(struct irda_device *dev); -static void girbil_open(struct irda_device *dev, int type); -static void girbil_close(struct irda_device *dev); -static void girbil_change_speed(struct irda_device *dev, __u32 speed); -static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); +static int girbil_reset(struct irda_task *task); +static void girbil_open(dongle_t *self, struct qos_info *qos); +static void girbil_close(dongle_t *self); +static int girbil_change_speed(struct irda_task *task); /* Control register 1 */ #define GIRBIL_TXEN 0x01 /* Enable transmitter */ @@ -67,13 +65,13 @@ static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); /* Control register 2 (0x5) */ #define GIRBIL_LOAD 0x51 /* Load the new baud rate value */ -static struct dongle dongle = { - GIRBIL_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_GIRBIL_DONGLE, girbil_open, girbil_close, girbil_reset, girbil_change_speed, - girbil_init_qos, }; int __init girbil_init(void) @@ -86,20 +84,18 @@ void girbil_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void girbil_open(struct irda_device *idev, int type) +static void girbil_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> girbil"); + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0x03; - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; - MOD_INC_USE_COUNT; } -static void girbil_close(struct irda_device *idev) +static void girbil_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } @@ -111,47 +107,80 @@ static void girbil_close(struct irda_device *idev) * function must be called with a process context! * */ -static void girbil_change_speed(struct irda_device *idev, __u32 speed) +static int girbil_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; __u8 control[2]; - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - switch (speed) { - case 9600: - default: - control[0] = GIRBIL_9600; + int ret = 0; + + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + + /* Need to reset the dongle and go to 9600 bps before + programming */ + if (irda_task_execute(self, girbil_reset, NULL, task, + (void *) speed)) + { + /* Dongle need more time to reset */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); + + /* Give reset 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } break; - case 19200: - control[0] = GIRBIL_19200; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + ret = -1; break; - case 34800: - control[0] = GIRBIL_38400; + case IRDA_TASK_CHILD_DONE: + /* Set DTR and Clear RTS to enter command mode */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + + switch (speed) { + case 9600: + default: + control[0] = GIRBIL_9600; + break; + case 19200: + control[0] = GIRBIL_19200; + break; + case 34800: + control[0] = GIRBIL_38400; + break; + case 57600: + control[0] = GIRBIL_57600; + break; + case 115200: + control[0] = GIRBIL_115200; + break; + } + control[1] = GIRBIL_LOAD; + + /* Write control bytes */ + self->write(self->dev, control, 2); + irda_task_next_state(task, IRDA_TASK_WAIT); + ret = MSECS_TO_JIFFIES(100); break; - case 57600: - control[0] = GIRBIL_57600; + case IRDA_TASK_WAIT: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; break; - case 115200: - control[0] = GIRBIL_115200; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; break; } - control[1] = GIRBIL_LOAD; - - /* Need to reset the dongle and go to 9600 bps before programming */ - girbil_reset(idev); - - /* Set DTR and Clear RTS to enter command mode */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); - - /* Write control bytes */ - irda_device_raw_write(idev, control, 2); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(100)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + return ret; } /* @@ -164,54 +193,47 @@ static void girbil_change_speed(struct irda_device *idev, __u32 speed) * 0. set RTS, and wait at least 5 ms * 1. clear RTS */ -void girbil_reset(struct irda_device *idev) +static int girbil_reset(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; __u8 control = GIRBIL_TXEN | GIRBIL_RXEN; - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - /* Make sure the IrDA chip also goes to defalt speed */ - if (idev->change_speed) - idev->change_speed(idev, 9600); - - /* Reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); - - /* Sleep at least 5 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(10)); - - /* Set DTR and clear RTS to enter command mode */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(10)); - - /* Write control byte */ - irda_device_raw_write(idev, &control, 1); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); -} - -/* - * Function girbil_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits &= 0x03; + int ret = 0; + + switch (task->state) { + case IRDA_TASK_INIT: + /* Reset dongle */ + self->set_dtr_rts(self->dev, TRUE, FALSE); + irda_task_next_state(task, IRDA_TASK_WAIT1); + /* Sleep at least 5 ms */ + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT1: + /* Set DTR and clear RTS to enter command mode */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + irda_task_next_state(task, IRDA_TASK_WAIT2); + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT2: + /* Write control byte */ + self->write(self->dev, &control, 1); + irda_task_next_state(task, IRDA_TASK_WAIT3); + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT3: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); @@ -236,5 +258,4 @@ void cleanup_module(void) { girbil_cleanup(); } - #endif /* MODULE */ diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index b60241a40..d4f4f6d71 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Tue Aug 31 13:54:27 1999 + * Modified at: Wed Oct 20 00:07:42 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: serial.c by Linus Torvalds * @@ -48,6 +48,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/spinlock.h> +#include <linux/rtnetlink.h> #include <asm/system.h> #include <asm/bitops.h> @@ -69,22 +70,22 @@ static unsigned int irq[] = { 0, 0, 0, 0 }; static unsigned int qos_mtt_bits = 0x03; -static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL}; +static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL}; static char *driver_name = "irport"; static int irport_open(int i, unsigned int iobase, unsigned int irq); -static int irport_close(struct irda_device *idev); +static int irport_close(struct irport_cb *self); -static void irport_write_wakeup(struct irda_device *idev); +static void irport_write_wakeup(struct irport_cb *self); static int irport_write(int iobase, int fifo_size, __u8 *buf, int len); -static void irport_receive(struct irda_device *idev); +static void irport_receive(struct irport_cb *self); static int irport_net_init(struct net_device *dev); static int irport_net_open(struct net_device *dev); static int irport_net_close(struct net_device *dev); -static int irport_is_receiving(struct irda_device *idev); -static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts); -static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len); +static int irport_is_receiving(struct irport_cb *self); +static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts); +static int irport_raw_write(struct net_device *dev, __u8 *buf, int len); int __init irport_init(void) { @@ -114,7 +115,7 @@ static void irport_cleanup(void) { int i; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) @@ -125,108 +126,154 @@ static void irport_cleanup(void) static int irport_open(int i, unsigned int iobase, unsigned int irq) { - struct irda_device *idev; + struct net_device *dev; + struct irport_cb *self; int ret; + int err; - DEBUG( 0, __FUNCTION__ "()\n"); - -/* if (irport_probe(iobase, irq) == -1) */ -/* return -1; */ + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* * Allocate new instance of the driver */ - idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL); - if (idev == NULL) { - printk( KERN_ERR "IrDA: Can't allocate memory for " - "IrDA control block!\n"); + self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL); + if (!self) { + ERROR(__FUNCTION__ "(), can't allocate memory for " + "control block!\n"); return -ENOMEM; } - memset(idev, 0, sizeof(struct irda_device)); + memset(self, 0, sizeof(struct irport_cb)); + spin_lock_init(&self->lock); + /* Need to store self somewhere */ - dev_self[i] = idev; + dev_self[i] = self; /* Initialize IO */ - idev->io.iobase2 = iobase; - idev->io.irq2 = irq; - idev->io.io_ext = IO_EXTENT; - idev->io.fifo_size = 16; - - idev->netdev.base_addr = iobase; - idev->netdev.irq = irq; + self->io.iobase2 = iobase; + self->io.irq2 = irq; + self->io.io_ext = IO_EXTENT; + self->io.fifo_size = 16; /* Lock the port that we need */ - ret = check_region(idev->io.iobase2, idev->io.io_ext); + ret = check_region(self->io.iobase2, self->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase2); - /* irport_cleanup(self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase2); + /* irport_cleanup(self->self); */ return -ENODEV; } - request_region(idev->io.iobase2, idev->io.io_ext, idev->name); + request_region(self->io.iobase2, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200; - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_SIR|IFF_PIO; + self->flags = IFF_SIR|IFF_PIO; - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL; - idev->tx_buff.flags = GFP_KERNEL; - - idev->rx_buff.truesize = 4000; - idev->tx_buff.truesize = 4000; + /* Specify how much memory we want */ + self->rx_buff.truesize = 4000; + self->tx_buff.truesize = 4000; - /* Initialize callbacks */ - idev->change_speed = irport_change_speed; - idev->wait_until_sent = irport_wait_until_sent; - idev->is_receiving = irport_is_receiving; - idev->set_dtr_rts = irport_set_dtr_rts; - idev->raw_write = irport_raw_write; + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL); + if (self->rx_buff.head == NULL) + return -ENOMEM; + memset(self->rx_buff.head, 0, self->rx_buff.truesize); + } + if (self->tx_buff.truesize > 0) { + self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, + GFP_KERNEL); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + self->mode = IRDA_IRLAP; + + 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; /* Override the network functions we need to use */ - idev->netdev.init = irport_net_init; - idev->netdev.hard_start_xmit = irport_hard_xmit; - idev->netdev.open = irport_net_open; - idev->netdev.stop = irport_net_close; + dev->init = irport_net_init; + dev->hard_start_xmit = irport_hard_xmit; + dev->open = irport_net_open; + dev->stop = irport_net_close; + + /* Make ifconfig display some details */ + dev->base_addr = iobase; + dev->irq = irq; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } + MESSAGE("IrDA: Registered device %s\n", dev->name); - /* Open the IrDA device */ - irda_device_open(idev, driver_name, NULL); - return 0; } -static int irport_close(struct irda_device *idev) +static int irport_close(struct irport_cb *self) { - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - /* Release the IO-port that this driver is using */ - DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", - idev->io.iobase2); - release_region(idev->io.iobase2, idev->io.io_ext); + /* We are not using any dongle anymore! */ + if (self->dongle) + irda_device_dongle_cleanup(self->dongle); + self->dongle = NULL; + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } - irda_device_close(idev); + /* Release the IO-port that this driver is using */ + IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", + self->io.iobase2); + release_region(self->io.iobase2, self->io.io_ext); - kfree(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); + + kfree(self); return 0; } -void irport_start(struct irda_device *idev, int iobase) +void irport_start(struct irport_cb *self, int iobase) { unsigned long flags; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); - irport_stop(idev, iobase); + irport_stop(self, iobase); /* Initialize UART */ outb(UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */ @@ -235,14 +282,14 @@ void irport_start(struct irda_device *idev, int iobase) /* Turn on interrups */ outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } -void irport_stop(struct irda_device *idev, int iobase) +void irport_stop(struct irport_cb *self, int iobase) { unsigned long flags; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); /* Reset UART */ outb(0, iobase+UART_MCR); @@ -250,7 +297,7 @@ void irport_stop(struct irda_device *idev, int iobase) /* Turn off interrupts */ outb(0, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } /* @@ -261,18 +308,18 @@ void irport_stop(struct irda_device *idev, int iobase) */ int irport_probe(int iobase) { - DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase); + IRDA_DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase); return 0; } /* - * Function irport_change_speed (idev, speed) + * Function irport_change_speed (self, speed) * * Set speed of IrDA port to specified baudrate * */ -void irport_change_speed(struct irda_device *idev, __u32 speed) +void irport_change_speed(struct irport_cb *self, __u32 speed) { unsigned long flags; int iobase; @@ -280,17 +327,16 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) int lcr; /* Line control reg */ int divisor; - DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed); + IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); /* Turn off interrupts */ outb(0, iobase+UART_IER); @@ -304,7 +350,7 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) * almost 1,7 ms at 19200 bps. At speeds above that we can just forget * about this timeout since it will always be fast enough. */ - if (idev->io.baudrate < 38400) + if (self->io.speed < 38400) fcr |= UART_FCR_TRIGGER_1; else fcr |= UART_FCR_TRIGGER_14; @@ -321,7 +367,7 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) /* Turn on interrups */ outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } /* @@ -331,39 +377,38 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) * more packets to send, we send them here. * */ -static void irport_write_wakeup(struct irda_device *idev) +static void irport_write_wakeup(struct irport_cb *self) { int actual = 0; int iobase; int fcr; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Finished with frame? */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { /* Write data left in transmit buffer */ - actual = irport_write(idev->io.iobase2, idev->io.fifo_size, - idev->tx_buff.data, idev->tx_buff.len); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + actual = irport_write(self->io.iobase2, self->io.fifo_size, + self->tx_buff.data, self->tx_buff.len); + self->tx_buff.data += actual; + self->tx_buff.len -= actual; } else { - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* * Now serial buffer is almost free & we can start * transmission of another packet */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; /* Schedule network layer, so we can get some more frames */ mark_bh(NET_BH); fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR; - if (idev->io.baudrate < 38400) + if (self->io.speed < 38400) fcr |= UART_FCR_TRIGGER_1; else fcr |= UART_FCR_TRIGGER_14; @@ -391,7 +436,7 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len) /* Tx FIFO should be empty! */ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n"); return -1; } @@ -415,19 +460,19 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len) */ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; unsigned long flags; int actual = 0; int iobase; + __u32 speed; ASSERT(dev != NULL, return 0;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) { @@ -436,28 +481,32 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) return -EBUSY; WARNING("%s: transmit timed out\n", dev->name); - irport_start(idev, iobase); - irport_change_speed(idev, idev->io.baudrate); + irport_start(self, iobase); + irport_change_speed(self, self->io.speed ); dev->trans_start = jiffies; } - spin_lock_irqsave(&idev->lock, flags); + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) + irport_change_speed(self, speed); + + spin_lock_irqsave(&self->lock, flags); /* Init tx buffer */ - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); @@ -465,30 +514,31 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) } /* - * Function irport_receive (idev) + * Function irport_receive (self) * * Receive one frame from the infrared port * */ -static void irport_receive(struct irda_device *idev) +static void irport_receive(struct irport_cb *self) { int boguscount = 0; int iobase; - ASSERT(idev != NULL, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* * Receive all characters in Rx FIFO, unwrap and unstuff them. * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(idev, inb(iobase+UART_RX)); + async_unwrap_char(self->netdev, &self->rx_buff, + inb(iobase+UART_RX)); /* Make sure we don't stay here to long */ if (boguscount++ > 32) { - DEBUG(2,__FUNCTION__ "(), breaking!\n"); + IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n"); break; } } while (inb(iobase+UART_LSR) & UART_LSR_DR); @@ -501,45 +551,47 @@ static void irport_receive(struct irda_device *idev) */ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct irda_device *idev = (struct irda_device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; + struct irport_cb *self; + int boguscount = 0; int iobase; int iir, lsr; - int boguscount = 0; - if (!idev) { + if (!dev) { WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq); return; } + self = (struct irport_cb *) dev->priv; - spin_lock(&idev->lock); + spin_lock(&self->lock); - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; iir = inb(iobase+UART_IIR) & UART_IIR_ID; while (iir) { /* Clear interrupt */ lsr = inb(iobase+UART_LSR); - DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", iir, lsr, iobase); switch (iir) { case UART_IIR_RLSI: - DEBUG(2, __FUNCTION__ "(), RLSI\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n"); break; case UART_IIR_RDI: /* Receive interrupt */ - irport_receive(idev); + irport_receive(self); break; case UART_IIR_THRI: if (lsr & UART_LSR_THRE) /* Transmitter ready for data */ - irport_write_wakeup(idev); + irport_write_wakeup(self); break; default: - DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir); + IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir); break; } @@ -549,9 +601,9 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) iir = inb(iobase + UART_IIR) & UART_IIR_ID; } - idev->netdev.interrupt = 0; + dev->interrupt = 0; - spin_unlock(&idev->lock); + spin_unlock(&self->lock); } static int irport_net_init(struct net_device *dev) @@ -572,24 +624,32 @@ static int irport_net_init(struct net_device *dev) */ static int irport_net_open(struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; int iobase; ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; - if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name, - (void *) idev)) + if (request_irq(self->io.irq2, irport_interrupt, 0, dev->name, + (void *) dev)) return -EAGAIN; - irport_start(idev, iobase); - irda_device_net_open(dev); + irport_start(self, iobase); + + /* 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); - /* Change speed to make sure dongles follow us again */ - if (idev->change_speed) - idev->change_speed(idev, 9600); + /* FIXME: change speed of dongle */ MOD_INC_USE_COUNT; @@ -597,30 +657,37 @@ static int irport_net_open(struct net_device *dev) } /* - * Function irport_net_close (idev) + * Function irport_net_close (self) * * * */ static int irport_net_close(struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;) + ASSERT(self != NULL, return -1;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; - irda_device_net_close(dev); - irport_stop(idev, iobase); + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; - free_irq(idev->io.irq2, idev); + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; + + irport_stop(self, iobase); + + free_irq(self->io.irq2, dev); MOD_DEC_USE_COUNT; @@ -628,34 +695,36 @@ static int irport_net_close(struct net_device *dev) } /* - * Function irport_wait_until_sent (idev) + * Function irport_wait_until_sent (self) * * Delay exectution until finished transmitting * */ -void irport_wait_until_sent(struct irda_device *idev) +#if 0 +void irport_wait_until_sent(struct irport_cb *self) { int iobase; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Wait until Tx FIFO is empty */ while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG(2, __FUNCTION__ "(), waiting!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), waiting!\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(60)); } } +#endif /* - * Function irport_is_receiving (idev) + * Function irport_is_receiving (self) * * Returns true is we are currently receiving data * */ -static int irport_is_receiving(struct irda_device *idev) +static int irport_is_receiving(struct irport_cb *self) { - return (idev->rx_buff.state != OUTSIDE_FRAME); + return (self->rx_buff.state != OUTSIDE_FRAME); } /* @@ -664,14 +733,14 @@ static int irport_is_receiving(struct irda_device *idev) * This function can be used by dongles etc. to set or reset the status * of the dtr and rts lines */ -static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts) +static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts) { + struct irport_cb *self = dev->priv; int iobase; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; if (dtr) dtr = UART_MCR_DTR; @@ -681,19 +750,19 @@ static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts) outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR); } -static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len) +static int irport_raw_write(struct net_device *dev, __u8 *buf, int len) { - int iobase; + struct irport_cb *self = (struct irport_cb *) dev->priv; int actual = 0; + int iobase; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Tx FIFO should be empty! */ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n"); return -1; } @@ -708,33 +777,20 @@ static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len) } #ifdef MODULE - MODULE_PARM(io, "1-4i"); MODULE_PARM(irq, "1-4i"); MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode"); -/* - * Function cleanup_module (void) - * - * - * - */ void cleanup_module(void) { irport_cleanup(); } -/* - * Function init_module (void) - * - * - */ int init_module(void) { return irport_init(); } - #endif /* MODULE */ diff --git a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c index 6a439a1a8..b6a9dad59 100644 --- a/drivers/net/irda/irtty.c +++ b/drivers/net/irda/irtty.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Dec 9 21:18:38 1997 - * Modified at: Tue Sep 28 08:39:29 1999 + * Modified at: Wed Oct 20 00:05:43 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: slip.c by Laurence Culhane, <loz@holmes.demon.co.uk> * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> @@ -29,6 +29,8 @@ #include <linux/tty.h> #include <linux/init.h> #include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/rtnetlink.h> #include <asm/segment.h> #include <asm/uaccess.h> @@ -36,7 +38,6 @@ #include <net/irda/irda.h> #include <net/irda/irtty.h> #include <net/irda/wrapper.h> -#include <net/irda/irlap.h> #include <net/irda/timer.h> #include <net/irda/irda_device.h> @@ -46,27 +47,31 @@ static struct tty_ldisc irda_ldisc; static int qos_mtt_bits = 0x03; /* 5 ms or more */ +/* Network device fuction prototypes */ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev); -static void irtty_wait_until_sent(struct irda_device *driver); -static int irtty_is_receiving(struct irda_device *idev); -static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts); -static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len); -static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, - int timeout); -static void irtty_set_raw_mode(struct irda_device *dev, int mode); static int irtty_net_init(struct net_device *dev); static int irtty_net_open(struct net_device *dev); static int irtty_net_close(struct net_device *dev); +static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct net_device_stats *irtty_net_get_stats(struct net_device *dev); +/* Line discipline function prototypes */ static int irtty_open(struct tty_struct *tty); static void irtty_close(struct tty_struct *tty); static int irtty_ioctl(struct tty_struct *, void *, int, void *); static int irtty_receive_room(struct tty_struct *tty); -static void irtty_change_speed(struct irda_device *dev, __u32 speed); static void irtty_write_wakeup(struct tty_struct *tty); - static void irtty_receive_buf(struct tty_struct *, const unsigned char *, char *, int); + +/* IrDA specific function protoctypes */ +static int irtty_is_receiving(struct irtty_cb *self); +static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts); +static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len); +static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len); +static int irtty_set_mode(struct net_device *dev, int mode); +static int irtty_change_speed(struct irda_task *task); + char *driver_name = "irtty"; int __init irtty_init(void) @@ -140,13 +145,16 @@ static void irtty_cleanup(void) */ static int irtty_open(struct tty_struct *tty) { + struct net_device *dev; struct irtty_cb *self; char name[16]; + int err; ASSERT(tty != NULL, return -EEXIST;); /* First make sure we're not already connected. */ self = (struct irtty_cb *) tty->disc_data; + if (self != NULL && self->magic == IRTTY_MAGIC) return -EEXIST; @@ -168,9 +176,8 @@ static int irtty_open(struct tty_struct *tty) sprintf(name, "%s%d", tty->driver.name, MINOR(tty->device) - tty->driver.minor_start + tty->driver.name_base); - - /* hashbin_insert( irtty, (QUEUE*) self, 0, self->name); */ - hashbin_insert(irtty, (QUEUE*) self, (int) self, NULL); + + hashbin_insert(irtty, (queue_t *) self, (int) self, NULL); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); @@ -179,11 +186,7 @@ static int irtty_open(struct tty_struct *tty) tty->ldisc.flush_buffer(tty); self->magic = IRTTY_MAGIC; - - /* - * Initialize driver - */ - self->idev.rx_buff.state = OUTSIDE_FRAME; + self->rx_buff.state = OUTSIDE_FRAME; /* * Initialize QoS capabilities, we fill in all the stuff that @@ -191,40 +194,71 @@ static int irtty_open(struct tty_struct *tty) * that are not device dependent (such as link disconnect time) so * this parameter can be set by IrLAP (or the user) instead. DB */ - irda_init_max_qos_capabilies(&self->idev.qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ - self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200; - self->idev.qos.min_turn_time.bits = qos_mtt_bits; - self->idev.flags = IFF_SIR | IFF_PIO; - irda_qos_bits_to_value(&self->idev.qos); - - /* Specify which buffer allocation policy we need */ - self->idev.rx_buff.flags = GFP_KERNEL; - self->idev.tx_buff.flags = GFP_KERNEL; + self->qos.min_turn_time.bits = qos_mtt_bits; + self->flags = IFF_SIR | IFF_PIO; + irda_qos_bits_to_value(&self->qos); /* Specify how much memory we want */ - self->idev.rx_buff.truesize = 4000; - self->idev.tx_buff.truesize = 4000; - - /* Initialize callbacks */ - self->idev.change_speed = irtty_change_speed; - self->idev.is_receiving = irtty_is_receiving; - self->idev.wait_until_sent = irtty_wait_until_sent; - self->idev.set_dtr_rts = irtty_set_dtr_rts; - self->idev.set_raw_mode = irtty_set_raw_mode; - self->idev.raw_write = irtty_raw_write; - self->idev.raw_read = irtty_raw_read; + self->rx_buff.truesize = 4000; + self->tx_buff.truesize = 4000; + + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL); + if (self->rx_buff.head == NULL) + return -ENOMEM; + memset(self->rx_buff.head, 0, self->rx_buff.truesize); + } + if (self->tx_buff.truesize > 0) { + self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, + GFP_KERNEL); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->magic = IRTTY_MAGIC; + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; /* Override the network functions we need to use */ - self->idev.netdev.init = irtty_net_init; - self->idev.netdev.hard_start_xmit = irtty_hard_xmit; - self->idev.netdev.open = irtty_net_open; - self->idev.netdev.stop = irtty_net_close; + dev->init = irtty_net_init; + dev->hard_start_xmit = irtty_hard_xmit; + dev->open = irtty_net_open; + dev->stop = irtty_net_close; + dev->get_stats = irtty_net_get_stats; + dev->do_ioctl = irtty_net_ioctl; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - /* Open the IrDA device */ - irda_device_open(&self->idev, name, self); + MESSAGE("IrDA: Registered device %s\n", dev->name); MOD_INC_USE_COUNT; @@ -245,39 +279,50 @@ static void irtty_close(struct tty_struct *tty) /* First make sure we're connected. */ ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); - - /* Remove driver */ - irda_device_close(&self->idev); - + /* Stop tty */ tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); tty->disc_data = 0; - + + /* We are not using any dongle anymore! */ + if (self->dongle) + irda_device_dongle_cleanup(self->dongle); + self->dongle = NULL; + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } + self->tty = NULL; self->magic = 0; self = hashbin_remove(irtty, (int) self, NULL); - - if (self != NULL) - kfree(self); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); + + kfree(self); + MOD_DEC_USE_COUNT; } /* - * Function irtty_stop_receiver (irda_device, stop) + * Function irtty_stop_receiver (self, stop) * * * */ -static void irtty_stop_receiver(struct irda_device *idev, int stop) +static void irtty_stop_receiver(struct irtty_cb *self, int stop) { struct termios old_termios; - struct irtty_cb *self; int cflag; - self = (struct irtty_cb *) idev->priv; - old_termios = *(self->tty->termios); cflag = self->tty->termios->c_cflag; @@ -291,24 +336,16 @@ static void irtty_stop_receiver(struct irda_device *idev, int stop) } /* - * Function irtty_change_speed (self, speed) + * Function irtty_do_change_speed (self, speed) * - * Change the speed of the serial port. The driver layer must check that - * all transmission has finished using the irtty_wait_until_sent() - * function. + * Change the speed of the serial port. */ -static void irtty_change_speed(struct irda_device *idev, __u32 speed) +static void __irtty_change_speed(struct irtty_cb *self, __u32 speed) { struct termios old_termios; - struct irtty_cb *self; int cflag; - DEBUG(4, __FUNCTION__ "(), <%ld>\n", jiffies); - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - self = (struct irtty_cb *) idev->priv; + IRDA_DEBUG(0, __FUNCTION__ "(), <%ld>\n", jiffies); ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); @@ -318,7 +355,7 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) cflag &= ~CBAUD; - DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), Setting speed to %d\n", speed); switch (speed) { case 1200: @@ -350,6 +387,81 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) self->tty->termios->c_cflag = cflag; self->tty->driver.set_termios(self->tty, &old_termios); + + self->io.speed = speed; +} + +/* + * Function irtty_change_speed (instance, state, param) + * + * State machine for changing speed of the device. We do it this way since + * we cannot use schedule_timeout() when we are in interrupt context + */ +static int irtty_change_speed(struct irda_task *task) +{ + struct irtty_cb *self; + __u32 speed = (__u32) task->param; + int ret = 0; + + IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); + + self = (struct irtty_cb *) task->instance; + + ASSERT(self != NULL, return -1;); + + switch (task->state) { + case IRDA_TASK_INIT: + case IRDA_TASK_WAIT: + /* Are we ready to change speed yet? */ + if (self->tty->driver.chars_in_buffer(self->tty)) { + task->state = IRDA_TASK_WAIT; + + /* Try again later */ + ret = MSECS_TO_JIFFIES(20); + break; + } + + if (self->dongle) + irda_task_next_state(task, IRDA_TASK_CHILD_INIT); + else + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_INIT: + /* Go to default speed */ + __irtty_change_speed(self, 9600); + + /* Change speed of dongle */ + if (irda_task_execute(self->dongle, + self->dongle->issue->change_speed, + NULL, task, (void *) speed)) + { + /* Dongle need more time to change its speed */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); + + /* Give dongle 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } else + /* Child finished immediately */ + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ + "(), changing speed of dongle timed out!\n"); + ret = -1; + break; + case IRDA_TASK_CHILD_DONE: + /* Finally we are ready to change the speed */ + __irtty_change_speed(self, speed); + + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } /* @@ -360,9 +472,11 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) */ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) { + dongle_t *dongle; + struct irtty_info info; struct irtty_cb *self; - int err = 0; int size = _IOC_SIZE(cmd); + int err = 0; self = (struct irtty_cb *) tty->disc_data; @@ -370,13 +484,13 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;); if (_IOC_DIR(cmd) & _IOC_READ) - err = verify_area( VERIFY_WRITE, (void *) arg, size); + err = verify_area(VERIFY_WRITE, (void *) arg, size); else if (_IOC_DIR(cmd) & _IOC_WRITE) - err = verify_area( VERIFY_READ, (void *) arg, size); + err = verify_area(VERIFY_READ, (void *) arg, size); if (err) return err; - switch(cmd) { + switch (cmd) { case TCGETS: case TCGETA: return n_tty_ioctl(tty, (struct file *) file, cmd, @@ -384,7 +498,34 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) break; case IRTTY_IOCTDONGLE: /* Initialize dongle */ - irda_device_init_dongle(&self->idev, (int) arg); + dongle = irda_device_dongle_init(self->netdev, (int) arg); + if (!dongle) + break; + + /* Initialize callbacks */ + dongle->set_mode = irtty_set_mode; + dongle->read = irtty_raw_read; + dongle->write = irtty_raw_write; + dongle->set_dtr_rts = irtty_set_dtr_rts; + + /* Bind dongle */ + self->dongle = dongle; + + /* Now initialize the dongle! */ + dongle->issue->open(dongle, &self->qos); + + /* Reset dongle */ + irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, + NULL); + break; + case IRTTY_IOCGET: + ASSERT(self->netdev != NULL, return -1;); + + memset(&info, 0, sizeof(struct irtty_info)); + strncpy(info.name, self->netdev->name, 5); + + if (copy_to_user(arg, &info, sizeof(struct irtty_info))) + return -EFAULT; break; default: return -ENOIOCTLCMD; @@ -405,34 +546,61 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; - DEBUG(5, __FUNCTION__ "(,,,count=%d)\n", count); /* Read the characters out of the buffer */ while (count--) { /* * Characters received with a parity error, etc? */ if (fp && *fp++) { - DEBUG( 0, "Framing or parity error!\n"); - irda_device_set_media_busy(&self->idev.netdev, TRUE); - + IRDA_DEBUG(0, "Framing or parity error!\n"); + irda_device_set_media_busy(self->netdev, TRUE); + cp++; continue; } + + switch (self->mode) { + case IRDA_IRLAP: + /* Unwrap and destuff one byte */ + async_unwrap_char(self->netdev, &self->rx_buff, *cp++); + break; + case IRDA_RAW: + /* What should we do when the buffer is full? */ + if (self->rx_buff.len == self->rx_buff.truesize) + self->rx_buff.len = 0; + + self->rx_buff.data[self->rx_buff.len++] = *cp++; + break; + default: + break; + } + } +} - DEBUG(6, __FUNCTION__ " char=0x%02x\n", *cp); - if (self->idev.raw_mode) { - struct irda_device *idev = &self->idev; +/* + * Function irtty_change_speed_complete (task) + * + * Called when the change speed operation completes + * + */ +static int irtty_change_speed_complete(struct irda_task *task) +{ + struct irtty_cb *self; - /* What should we do when the buffer is full? */ - if (idev->rx_buff.len == idev->rx_buff.truesize) - idev->rx_buff.len = 0; + IRDA_DEBUG(0, __FUNCTION__ "()\n"); - idev->rx_buff.data[idev->rx_buff.len++] = *cp++; - } else { - /* Unwrap and destuff one byte */ - async_unwrap_char(&self->idev, *cp++); - } - } + self = (struct irtty_cb *) task->instance; + + ASSERT(self != NULL, return -1;); + ASSERT(self->netdev != NULL, return -1;); + + /* Finished changing speed, so we are not busy any longer */ + self->netdev->tbusy = 0; + + /* Signal network layer so it can try to send the frame */ + mark_bh(NET_BH); + + return 0; } /* @@ -444,29 +612,34 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irtty_cb *self; - struct irda_device *idev; int actual = 0; + __u32 speed; - idev = (struct irda_device *) dev->priv; - - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - - self = (struct irtty_cb *) idev->priv; - + self = (struct irtty_cb *) dev->priv; ASSERT(self != NULL, return 0;); - ASSERT(self->magic == IRTTY_MAGIC, return 0;); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; + + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) { + if (irda_task_execute(self, irtty_change_speed, + irtty_change_speed_complete, NULL, + (void *) speed)) + /* + * Task not finished yet, so make the netdevice + * layer requeue the frame + */ + return -EBUSY; + } /* Init tx buffer*/ - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); @@ -474,22 +647,22 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) if (self->tty->driver.write) actual = self->tty->driver.write(self->tty, 0, - idev->tx_buff.data, - idev->tx_buff.len); + self->tx_buff.data, + self->tx_buff.len); /* Hide the part we just transmitted */ - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->stats.tx_packets++; - idev->stats.tx_bytes += idev->tx_buff.len; + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.len; #if 0 /* * Did we transmit the whole frame? Commented out for now since * I must check if this optimalization really works. DB. */ - if ((idev->tx_buff.len) == 0) { - DEBUG( 4, "irtty_xmit_buf: finished with frame!\n"); + if ((self->tx_buff.len) == 0) { + IRDA_DEBUG( 4, "irtty_xmit_buf: finished with frame!\n"); self->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); irda_unlock( &self->tbusy); } @@ -507,7 +680,7 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) */ static int irtty_receive_room(struct tty_struct *tty) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); return 65536; /* We can handle an infinite amount of data. :-) */ } @@ -521,7 +694,6 @@ static int irtty_receive_room(struct tty_struct *tty) static void irtty_write_wakeup(struct tty_struct *tty) { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; - struct irda_device *idev; int actual = 0; /* @@ -530,26 +702,24 @@ static void irtty_write_wakeup(struct tty_struct *tty) ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); - idev = &self->idev; - /* Finished with frame? */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { /* Write data left in transmit buffer */ - actual = tty->driver.write(tty, 0, idev->tx_buff.data, - idev->tx_buff.len); + actual = tty->driver.write(tty, 0, self->tx_buff.data, + self->tx_buff.len); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; } else { /* * Now serial buffer is almost free & we can start * transmission of another packet */ - DEBUG(5, __FUNCTION__ "(), finished with frame!\n"); + IRDA_DEBUG(5, __FUNCTION__ "(), finished with frame!\n"); tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - idev->netdev.tbusy = 0; /* Unlock */ + self->netdev->tbusy = 0; /* Unlock */ /* Tell network layer that we want more frames */ mark_bh(NET_BH); @@ -557,34 +727,14 @@ static void irtty_write_wakeup(struct tty_struct *tty) } /* - * Function irtty_is_receiving (idev) + * Function irtty_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int irtty_is_receiving(struct irda_device *idev) +static int irtty_is_receiving(struct irtty_cb *self) { - return (idev->rx_buff.state != OUTSIDE_FRAME); -} - -/* - * Function irtty_change_speed_ready (idev) - * - * Are we completely finished with transmitting frames so its possible - * to change the speed of the serial port. Warning this function must - * be called with a process context! - */ -static void irtty_wait_until_sent(struct irda_device *idev) -{ - struct irtty_cb *self = (struct irtty_cb *) idev->priv; - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRTTY_MAGIC, return;); - - DEBUG(4, "Chars in buffer %d\n", - self->tty->driver.chars_in_buffer(self->tty)); - - tty_wait_until_sent(self->tty, 0); + return (self->rx_buff.state != OUTSIDE_FRAME); } /* @@ -593,15 +743,14 @@ static void irtty_wait_until_sent(struct irda_device *idev) * This function can be used by dongles etc. to set or reset the status * of the dtr and rts lines */ -static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts) +static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts) { - struct tty_struct *tty; struct irtty_cb *self; + struct tty_struct *tty; mm_segment_t fs; int arg = 0; - self = (struct irtty_cb *) idev->priv; - + self = (struct irtty_cb *) dev->priv; tty = self->tty; #ifdef TIOCM_OUT2 /* Not defined for ARM */ @@ -627,52 +776,62 @@ static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts) ERROR(__FUNCTION__ "(), error doing ioctl!\n"); } set_fs(fs); + + return 0; } /* - * Function irtty_set_raw_mode (idev, status) + * Function irtty_set_mode (self, status) * * For the airport dongle, we need support for reading raw characters * from the IrDA device. This function switches between those modes. * FALSE is the default mode, and will then treat incoming data as IrDA * packets. */ -void irtty_set_raw_mode(struct irda_device *idev, int status) +int irtty_set_mode(struct net_device *dev, int mode) { struct irtty_cb *self; - DEBUG(2, __FUNCTION__ "(), status=%s\n", status ? "TRUE" : "FALSE"); + self = (struct irtty_cb *) dev->priv; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - self = (struct irtty_cb *) idev->priv; + ASSERT(self != NULL, return -1;); + IRDA_DEBUG(2, __FUNCTION__ "(), mode=%s\n", infrared_mode[mode]); + /* save status for driver */ - self->idev.raw_mode = status; + self->mode = mode; /* reset the buffer state */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; - idev->rx_buff.state = OUTSIDE_FRAME; + self->rx_buff.data = self->rx_buff.head; + self->rx_buff.len = 0; + self->rx_buff.state = OUTSIDE_FRAME; + + return 0; } /* - * Function irtty_raw_read (idev, buf, len) + * Function irtty_raw_read (self, buf, len) * * Receive incomming data. This function sleeps, so it must only be * called with a process context. Timeout is currently defined to be * a multiple of 10 ms. */ -static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, - int timeout) +static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len) { + struct irtty_cb *self; int count; - buf = idev->rx_buff.data; + self = (struct irtty_cb *) dev->priv; + + ASSERT(self != NULL, return 0;); + ASSERT(self->magic == IRTTY_MAGIC, return 0;); + + return 0; +#if 0 + buf = self->rx_buff.data; /* Wait for the requested amount of data to arrive */ - while (len < idev->rx_buff.len) { + while (len < self->rx_buff.len) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(10)); @@ -680,30 +839,27 @@ static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, break; } - count = idev->rx_buff.len < len ? idev->rx_buff.len : len; + count = self->rx_buff.len < len ? self->rx_buff.len : len; /* * Reset the state, this mean that a raw read is sort of a * datagram read, and _not_ a stream style read. Be aware of the * difference. Implementing it the other way will just be painful ;-) */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; - idev->rx_buff.state = OUTSIDE_FRAME; - + self->rx_buff.data = self->rx_buff.head; + self->rx_buff.len = 0; + self->rx_buff.state = OUTSIDE_FRAME; +#endif /* Return the amount we were able to get */ return count; } -static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) +static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len) { struct irtty_cb *self; int actual = 0; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - - self = (struct irtty_cb *) idev->priv; + self = (struct irtty_cb *) dev->priv; ASSERT(self != NULL, return 0;); ASSERT(self->magic == IRTTY_MAGIC, return 0;); @@ -714,8 +870,6 @@ static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) return actual; } - - static int irtty_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ @@ -728,12 +882,26 @@ static int irtty_net_init(struct net_device *dev) static int irtty_net_open(struct net_device *dev) { - struct irda_device *idev = dev->priv; + struct irtty_cb *self = (struct irtty_cb *) dev->priv; - irda_device_net_open(dev); + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); + + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + + /* Ready to play! */ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; /* Make sure we can receive more data */ - irtty_stop_receiver(idev, FALSE); + irtty_stop_receiver(self, FALSE); + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); MOD_INC_USE_COUNT; @@ -742,18 +910,105 @@ static int irtty_net_open(struct net_device *dev) static int irtty_net_close(struct net_device *dev) { - struct irda_device *idev = dev->priv; + struct irtty_cb *self = (struct irtty_cb *) dev->priv; + + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); /* Make sure we don't receive more data */ - irtty_stop_receiver(idev, TRUE); + irtty_stop_receiver(self, TRUE); - irda_device_net_close(dev); + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; MOD_DEC_USE_COUNT; return 0; } +/* + * Function irtty_net_ioctl (dev, rq, cmd) + * + * Process IOCTL commands for this device + * + */ +static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *) rq; + struct irtty_cb *self; + dongle_t *dongle; + unsigned long flags; + int ret = 0; + + ASSERT(dev != NULL, return -1;); + + self = dev->priv; + + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); + + IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd); + + /* Disable interrupts & save flags */ + save_flags(flags); + cli(); + + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + irda_task_execute(self, irtty_change_speed, NULL, NULL, + (void *) irq->ifr_baudrate); + break; + case SIOCSDONGLE: /* Set dongle */ + /* Initialize dongle */ + dongle = irda_device_dongle_init(dev, irq->ifr_dongle); + if (!dongle) + break; + + dongle->set_mode = irtty_set_mode; + dongle->read = irtty_raw_read; + dongle->write = irtty_raw_write; + dongle->set_dtr_rts = irtty_set_dtr_rts; + + self->dongle = dongle; + + /* Now initialize the dongle! */ + dongle->issue->open(dongle, &self->qos); + + /* Reset dongle */ + irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, + NULL); + break; + case SIOCSMEDIABUSY: /* Set media busy */ + irda_device_set_media_busy(self->netdev, TRUE); + break; + case SIOCGRECEIVING: /* Check if we are receiving right now */ + irq->ifr_receiving = irtty_is_receiving(self); + break; + case SIOCSDTRRTS: + irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts); + break; + default: + ret = -EOPNOTSUPP; + } + + restore_flags(flags); + + return ret; +} + +static struct net_device_stats *irtty_net_get_stats(struct net_device *dev) +{ + struct irtty_cb *self = (struct irtty_cb *) dev->priv; + + return &self->stats; +} + #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c index 203838cea..f5da3faf6 100644 --- a/drivers/net/irda/litelink.c +++ b/drivers/net/irda/litelink.c @@ -6,7 +6,7 @@ * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri May 7 12:50:33 1999 - * Modified at: Sat Jun 26 17:01:05 1999 + * Modified at: Mon Oct 18 12:45:51 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -37,27 +37,25 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/dongle.h> #define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */ #define MAX_DELAY 10000 /* 1 ms */ -static void litelink_open(struct irda_device *idev, int type); -static void litelink_close(struct irda_device *dev); -static void litelink_change_speed(struct irda_device *dev, __u32); -static void litelink_reset(struct irda_device *dev); -static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos); +static void litelink_open(dongle_t *self, struct qos_info *qos); +static void litelink_close(dongle_t *self); +static int litelink_change_speed(struct irda_task *task); +static int litelink_reset(struct irda_task *task); /* These are the baudrates supported */ static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 }; -static struct dongle dongle = { - LITELINK_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_LITELINK_DONGLE, litelink_open, litelink_close, litelink_reset, litelink_change_speed, - litelink_init_qos, }; int __init litelink_init(void) @@ -70,114 +68,102 @@ void litelink_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void litelink_open(struct irda_device *idev, int type) +static void litelink_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> litelink"); - - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ MOD_INC_USE_COUNT; } -static void litelink_close(struct irda_device *idev) +static void litelink_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function litelink_change_speed (idev, speed) + * Function litelink_change_speed (task) * * Change speed of the Litelink dongle. To cycle through the available * baud rates, pulse RTS low for a few ms. */ -static void litelink_change_speed(struct irda_device *idev, __u32 speed) +static int litelink_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; int i; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - /* Clear RTS to reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Cycle through avaiable baudrates until we reach the correct one */ for (i=0; i<5 && baud_rates[i] != speed; i++) { - /* Set DTR, clear RTS */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + self->set_dtr_rts(self->dev, FALSE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); } + + irda_task_next_state(task, IRDA_TASK_DONE); + + return 0; } /* - * Function litelink_reset (dev) + * Function litelink_reset (task) * * Reset the Litelink type dongle. Warning, this function must only be * called with a process context! * */ -static void litelink_reset(struct irda_device *idev) +static int litelink_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - + dongle_t *self = (dongle_t *) task->instance; + /* Power on dongle */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Clear RTS to reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* This dongles speed defaults to 115200 bps */ - idev->qos.baud_rate.value = 115200; -} + self->speed = 115200; -/* - * Function litelink_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ + return 0; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Parallax Litelink dongle driver"); @@ -202,5 +188,4 @@ void cleanup_module(void) { litelink_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/pc87108.c b/drivers/net/irda/pc87108.c index 3b575d01e..fae329ac9 100644 --- a/drivers/net/irda/pc87108.c +++ b/drivers/net/irda/pc87108.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Wed Aug 11 09:26:26 1999 + * Modified at: Wed Oct 20 00:08:41 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -29,11 +29,11 @@ * * __u8 bank; * - * bank = inb( iobase+BSR); + * bank = inb(iobase+BSR); * * do_your_stuff_here(); * - * outb( bank, iobase+BSR); + * outb(bank, iobase+BSR); * * If you find bugs in this file, its very likely that the same bug * will also be in w83977af_ir.c since the implementations is quite @@ -51,6 +51,7 @@ #include <linux/delay.h> #include <linux/malloc.h> #include <linux/init.h> +#include <linux/rtnetlink.h> #include <asm/io.h> #include <asm/dma.h> @@ -101,19 +102,19 @@ static char *dongle_types[] = { static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, unsigned int irq, unsigned int dma); #ifdef MODULE -static int pc87108_close(struct irda_device *idev); +static int pc87108_close(struct pc87108 *self); #endif /* MODULE */ static int pc87108_probe(int iobase, int board_addr, int irq, int dma); -static void pc87108_pio_receive(struct irda_device *idev); -static int pc87108_dma_receive(struct irda_device *idev); -static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase); +static void pc87108_pio_receive(struct pc87108 *self); +static int pc87108_dma_receive(struct pc87108 *self); +static int pc87108_dma_receive_complete(struct pc87108 *self, int iobase); static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size); -static void pc87108_dma_write(struct irda_device *idev, int iobase); -static void pc87108_change_speed(struct irda_device *idev, __u32 baud); +static void pc87108_dma_write(struct pc87108 *self, int iobase); +static void pc87108_change_speed(struct pc87108 *self, __u32 baud); static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void pc87108_wait_until_sent(struct irda_device *idev); -static int pc87108_is_receiving(struct irda_device *idev); +static void pc87108_wait_until_sent(struct pc87108 *self); +static int pc87108_is_receiving(struct pc87108 *self); static int pc87108_read_dongle_id (int iobase); static void pc87108_init_dongle_interface (int iobase, int dongle_id); @@ -152,11 +153,11 @@ static void pc87108_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) - pc87108_close(&(dev_self[i]->idev)); + pc87108_close(dev_self[i]); } } #endif /* MODULE */ @@ -170,12 +171,13 @@ static void pc87108_cleanup(void) static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, unsigned int irq, unsigned int dma) { + struct net_device *dev; struct pc87108 *self; - struct irda_device *idev; - int ret; int dongle_id; + int ret; + int err; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if ((dongle_id = pc87108_probe(iobase, board_addr, irq, dma)) == -1) return -1; @@ -194,90 +196,127 @@ static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, /* Need to store self somewhere */ dev_self[i] = self; - idev = &self->idev; - /* Initialize IO */ - idev->io.iobase = iobase; - idev->io.irq = irq; - idev->io.io_ext = CHIP_IO_EXTENT; - idev->io.dma = dma; - idev->io.fifo_size = 32; + self->io.iobase = iobase; + self->io.irq = irq; + self->io.io_ext = CHIP_IO_EXTENT; + self->io.dma = dma; + self->io.fifo_size = 32; /* Lock the port that we need */ - ret = check_region(idev->io.iobase, idev->io.io_ext); + ret = check_region(self->io.iobase, self->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase); - /* pc87108_cleanup( self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase); + /* pc87108_cleanup(self->self); */ return -ENODEV; } - request_region(idev->io.iobase, idev->io.io_ext, idev->name); + request_region(self->io.iobase, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE; - - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; - idev->tx_buff.flags = GFP_KERNEL | GFP_DMA; + self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE; /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ - idev->rx_buff.truesize = 14384; - idev->tx_buff.truesize = 4000; + self->rx_buff.truesize = 14384; + self->tx_buff.truesize = 4000; + + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL|GFP_DMA); + if (self->rx_buff.head == NULL) + return -ENOMEM; + memset(self->rx_buff.head, 0, self->rx_buff.truesize); + } + if (self->tx_buff.truesize > 0) { + self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, + GFP_KERNEL|GFP_DMA); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; - /* Initialize callbacks */ - idev->change_speed = pc87108_change_speed; - idev->wait_until_sent = pc87108_wait_until_sent; - idev->is_receiving = pc87108_is_receiving; - + 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; + /* Override the network functions we need to use */ - idev->netdev.init = pc87108_net_init; - idev->netdev.hard_start_xmit = pc87108_hard_xmit; - idev->netdev.open = pc87108_net_open; - idev->netdev.stop = pc87108_net_close; + dev->init = pc87108_net_init; + dev->hard_start_xmit = pc87108_hard_xmit; + dev->open = pc87108_net_open; + dev->stop = pc87108_net_close; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - idev->io.dongle_id = dongle_id; + MESSAGE("IrDA: Registered device %s\n", dev->name); + + self->io.dongle_id = dongle_id; pc87108_init_dongle_interface(iobase, dongle_id); - /* Open the IrDA device */ - irda_device_open(idev, driver_name, self); - return 0; } #ifdef MODULE /* - * Function pc87108_close (idev) + * Function pc87108_close (self) * * Close driver instance * */ -static int pc87108_close(struct irda_device *idev) +static int pc87108_close(struct pc87108 *self) { - struct pc87108 *self; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); + + ASSERT(self != NULL, return -1;); - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + iobase = self->io.iobase; - iobase = idev->io.iobase; - self = (struct pc87108 *) idev->priv; + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdev(self->netdev); + rtnl_unlock(); + } /* Release the PORT that this driver is using */ - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); - release_region(idev->io.iobase, idev->io.io_ext); + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", self->io.iobase); + release_region(self->io.iobase, self->io.io_ext); - irda_device_close(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); kfree(self); @@ -297,7 +336,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) __u8 temp=0; int dongle_id; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Base Address and Interrupt Control Register BAIC */ outb(0, board_addr); @@ -326,7 +365,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) case 0: outb(0x08+temp, board_addr+1); break; case 1: outb(0x10+temp, board_addr+1); break; case 3: outb(0x18+temp, board_addr+1); break; - default: DEBUG( 0, __FUNCTION__ "(), invalid dma"); + default: IRDA_DEBUG(0, __FUNCTION__ "(), invalid dma"); } /* Mode Control Register MCTL */ @@ -344,13 +383,13 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) } /* Switch to advanced mode */ - switch_bank( iobase, BANK2); + switch_bank(iobase, BANK2); outb(ECR1_EXT_SL, iobase+ECR1); switch_bank(iobase, BANK0); dongle_id = pc87108_read_dongle_id(iobase); - DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n", - dongle_types[ dongle_id]); + IRDA_DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n", + dongle_types[dongle_id]); /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */ switch_bank(iobase, BANK0); @@ -380,7 +419,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) outb(2048 & 0xff, iobase+4); outb((2048 >> 8) & 0x1f, iobase+5); - DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version); + IRDA_DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version); /* Enable receive interrupts */ switch_bank(iobase, BANK0); @@ -397,14 +436,14 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) * that the user may have plugged/unplugged the IrDA Dongle. * */ -static int pc87108_read_dongle_id ( int iobase) +static int pc87108_read_dongle_id (int iobase) { int dongle_id; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ switch_bank(iobase, BANK7); @@ -416,7 +455,7 @@ static int pc87108_read_dongle_id ( int iobase) udelay(50); /* IRCFG1: read the ID bits */ - dongle_id = inb( iobase+4) & 0x0f; + dongle_id = inb(iobase+4) & 0x0f; #ifdef BROKEN_DONGLE_ID if (dongle_id == 0x0a) @@ -426,7 +465,7 @@ static int pc87108_read_dongle_id ( int iobase) /* Go back to bank 0 before returning */ switch_bank(iobase, BANK0); - DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id); + IRDA_DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id); outb(bank, iobase+BSR); @@ -446,49 +485,49 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) int bank; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ - switch_bank( iobase, BANK7); + switch_bank(iobase, BANK7); /* IRCFG4: set according to dongle_id */ switch (dongle_id) { case 0x00: /* same as */ case 0x01: /* Differential serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); break; case 0x05: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet", dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); break; case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ - outb_p( 0x28, iobase+7); /* Set irsl[0-2] as output */ + outb_p(0x28, iobase+7); /* Set irsl[0-2] as output */ break; case 0x0A: /* same as */ case 0x0B: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x0C: /* same as */ @@ -497,28 +536,28 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) * Set irsl0 as input, irsl[1-2] as output, and separate * inputs are used for SIR and MIR/FIR */ - outb( 0x48, iobase+7); + outb(0x48, iobase+7); break; case 0x0E: /* Supports SIR Mode only */ - outb( 0x28, iobase+7); /* Set irsl[0-2] as output */ + outb(0x28, iobase+7); /* Set irsl[0-2] as output */ break; case 0x0F: /* No dongle connected */ - DEBUG( 0, __FUNCTION__ "(), %s\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s\n", dongle_types[dongle_id]); - DEBUG( 0, "***\n"); + IRDA_DEBUG(0, "***\n"); - switch_bank( iobase, BANK0); - outb( 0x62, iobase+MCR); + switch_bank(iobase, BANK0); + outb(0x62, iobase+MCR); break; default: - DEBUG( 0, __FUNCTION__ "(), invalid dongle_id %#x", dongle_id); + IRDA_DEBUG(0, __FUNCTION__ "(), invalid dongle_id %#x", dongle_id); } /* IRCFG1: IRSL1 and 2 are set to IrDA mode */ - outb( 0x00, iobase+4); + outb(0x00, iobase+4); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* set_up_dongle_interface */ @@ -528,66 +567,66 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) * Change speed of the attach dongle * */ -static void pc87108_change_dongle_speed( int iobase, int speed, int dongle_id) +static void pc87108_change_dongle_speed(int iobase, int speed, int dongle_id) { unsigned long flags; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ - switch_bank( iobase, BANK7); + switch_bank(iobase, BANK7); /* IRCFG1: set according to dongle_id */ switch (dongle_id) { case 0x00: /* same as */ case 0x01: /* Differential serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); case 0x05: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ - switch_bank( iobase, BANK7); - outb_p( 0x01, iobase+4); + switch_bank(iobase, BANK7); + outb_p(0x01, iobase+4); - if ( speed == 4000000) { + if (speed == 4000000) { save_flags(flags); cli(); - outb( 0x81, iobase+4); - outb( 0x80, iobase+4); + outb(0x81, iobase+4); + outb(0x80, iobase+4); restore_flags(flags); } else - outb_p( 0x00, iobase+4); + outb_p(0x00, iobase+4); break; case 0x0A: /* same as */ case 0x0B: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x0C: /* same as */ @@ -596,78 +635,77 @@ static void pc87108_change_dongle_speed( int iobase, int speed, int dongle_id) case 0x0E: /* Supports SIR Mode only */ break; case 0x0F: /* No dongle connected */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); - switch_bank( iobase, BANK0); - outb( 0x62, iobase+MCR); + switch_bank(iobase, BANK0); + outb(0x62, iobase+MCR); break; default: - DEBUG( 0, __FUNCTION__ "(), invalid data_rate\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), invalid data_rate\n"); } /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* - * Function pc87108_change_speed (idev, baud) + * Function pc87108_change_speed (self, baud) * * Change the speed of the device * */ -static void pc87108_change_speed(struct irda_device *idev, __u32 speed) +static void pc87108_change_speed(struct pc87108 *self, __u32 speed) { __u8 mcr = MCR_SIR; __u8 bank; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( idev != NULL, return;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Disable interrupts */ - switch_bank( iobase, BANK0); - outb( 0, iobase+IER); + switch_bank(iobase, BANK0); + outb(0, iobase+IER); /* Select Bank 2 */ - switch_bank( iobase, BANK2); - - outb( 0x00, iobase+BGDH); - switch ( speed) { - case 9600: outb( 0x0c, iobase+BGDL); break; - case 19200: outb( 0x06, iobase+BGDL); break; - case 37600: outb( 0x03, iobase+BGDL); break; - case 57600: outb( 0x02, iobase+BGDL); break; - case 115200: outb( 0x01, iobase+BGDL); break; + switch_bank(iobase, BANK2); + + outb(0x00, iobase+BGDH); + switch (speed) { + case 9600: outb(0x0c, iobase+BGDL); break; + case 19200: outb(0x06, iobase+BGDL); break; + case 37600: outb(0x03, iobase+BGDL); break; + case 57600: outb(0x02, iobase+BGDL); break; + case 115200: outb(0x01, iobase+BGDL); break; case 576000: - switch_bank( iobase, BANK5); + switch_bank(iobase, BANK5); /* IRCR2: MDRS is set */ - outb( inb( iobase+4) | 0x04, iobase+4); + outb(inb(iobase+4) | 0x04, iobase+4); mcr = MCR_MIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: mcr = MCR_MIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: mcr = MCR_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); break; default: mcr = MCR_FIR; - DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -676,34 +714,34 @@ static void pc87108_change_speed(struct irda_device *idev, __u32 speed) outb(mcr | MCR_TX_DFR, iobase+MCR); /* Give some hits to the transceiver */ - pc87108_change_dongle_speed( iobase, speed, idev->io.dongle_id); + pc87108_change_dongle_speed(iobase, speed, self->io.dongle_id); /* Set FIFO threshold to TX17, RX16 */ - switch_bank( iobase, BANK0); - outb( FCR_RXTH| /* Set Rx FIFO threshold */ + switch_bank(iobase, BANK0); + outb(FCR_RXTH| /* Set Rx FIFO threshold */ FCR_TXTH| /* Set Tx FIFO threshold */ FCR_TXSR| /* Reset Tx FIFO */ FCR_RXSR| /* Reset Rx FIFO */ FCR_FIFO_EN, /* Enable FIFOs */ iobase+FCR); - /* outb( 0xa7, iobase+FCR); */ + /* outb(0xa7, iobase+FCR); */ /* Set FIFO size to 32 */ - switch_bank( iobase, BANK2); - outb( EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); + switch_bank(iobase, BANK2); + outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); - idev->netdev.tbusy = 0; + self->netdev->tbusy = 0; /* Enable some interrupts so we can receive frames */ - switch_bank( iobase, BANK0); - if ( speed > 115200) { - outb( IER_SFIF_IE, iobase+IER); - pc87108_dma_receive( idev); + switch_bank(iobase, BANK0); + if (speed > 115200) { + outb(IER_SFIF_IE, iobase+IER); + pc87108_dma_receive(self); } else - outb( IER_RXHDL_IE, iobase+IER); + outb(IER_RXHDL_IE, iobase+IER); /* Restore BSR */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* @@ -712,107 +750,106 @@ static void pc87108_change_speed(struct irda_device *idev, __u32 speed) * Transmit the frame! * */ -static int pc87108_hard_xmit( struct sk_buff *skb, struct net_device *dev) +static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; int mtt; - idev = (struct irda_device *) dev->priv; + self = (struct pc87108 *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Lock transmit buffer */ - if ( irda_lock( (void *) &dev->tbusy) == FALSE) + if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Decide if we should use PIO or DMA transfer */ - if ( idev->io.baudrate > 115200) { - idev->tx_buff.data = idev->tx_buff.head; - memcpy(idev->tx_buff.data, skb->data, skb->len); - idev->tx_buff.len = skb->len; + if (self->io.speed > 115200) { + self->tx_buff.data = self->tx_buff.head; + memcpy(self->tx_buff.data, skb->data, skb->len); + self->tx_buff.len = skb->len; - mtt = irda_get_mtt( skb); - if ( mtt > 50) { + mtt = irda_get_mtt(skb); + if (mtt > 50) { /* Adjust for timer resolution */ mtt = mtt / 125 + 1; /* Setup timer */ - switch_bank( iobase, BANK4); - outb( mtt & 0xff, iobase+TMRL); - outb(( mtt >> 8) & 0x0f, iobase+TMRH); + switch_bank(iobase, BANK4); + outb(mtt & 0xff, iobase+TMRL); + outb((mtt >> 8) & 0x0f, iobase+TMRH); /* Start timer */ - outb( IRCR1_TMR_EN, iobase+IRCR1); - idev->io.direction = IO_XMIT; + outb(IRCR1_TMR_EN, iobase+IRCR1); + self->io.direction = IO_XMIT; /* Enable timer interrupt */ - switch_bank( iobase, BANK0); - outb( IER_TMR_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_TMR_IE, iobase+IER); } else { /* Use udelay for delays less than 50 us. */ if (mtt) - udelay( mtt); + udelay(mtt); /* Enable DMA interrupt */ - switch_bank( iobase, BANK0); - outb( IER_DMA_IE, iobase+IER); - pc87108_dma_write( idev, iobase); + switch_bank(iobase, BANK0); + outb(IER_DMA_IE, iobase+IER); + pc87108_dma_write(self, iobase); } } else { - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Add interrupt on tx low level (will fire immediately) */ - switch_bank( iobase, BANK0); - outb( IER_TXLDL_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_TXLDL_IE, iobase+IER); } - dev_kfree_skb( skb); + dev_kfree_skb(skb); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return 0; } /* - * Function pc87108_dma_xmit (idev, iobase) + * Function pc87108_dma_xmit (self, iobase) * * Transmit data using DMA * */ -static void pc87108_dma_write( struct irda_device *idev, int iobase) +static void pc87108_dma_write(struct pc87108 *self, int iobase) { int bsr; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bsr = inb( iobase+BSR); + bsr = inb(iobase+BSR); /* Disable DMA */ switch_bank(iobase, BANK0); - outb( inb( iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); + outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); - setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, + setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, DMA_MODE_WRITE); - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Choose transmit DMA channel */ switch_bank(iobase, BANK2); - outb( inb( iobase+ECR1) | ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, + outb(inb(iobase+ECR1) | ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1); /* Enable DMA */ @@ -824,7 +861,7 @@ static void pc87108_dma_write( struct irda_device *idev, int iobase) } /* - * Function pc87108_pio_xmit (idev, iobase) + * Function pc87108_pio_xmit (self, iobase) * * Transmit data using PIO. Returns the number of bytes that actually * got transfered @@ -835,17 +872,17 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); - switch_bank( iobase, BANK0); - if (!(inb_p( iobase+LSR) & LSR_TXEMP)) { - DEBUG( 4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); + switch_bank(iobase, BANK0); + if (!(inb_p(iobase+LSR) & LSR_TXEMP)) { + IRDA_DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); fifo_size -= 17; - DEBUG( 4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); + IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); } /* Fill FIFO with current frame */ @@ -854,7 +891,7 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) outb(buf[actual++], iobase+TXD); } - DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", + IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", fifo_size, actual, len); /* Restore bank */ @@ -864,74 +901,69 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } /* - * Function pc87108_dma_xmit_complete (idev) + * Function pc87108_dma_xmit_complete (self) * * The transfer of a frame in finished. This function will only be called * by the interrupt handler * */ -static void pc87108_dma_xmit_complete( struct irda_device *idev) +static void pc87108_dma_xmit_complete(struct pc87108 *self) { int iobase; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( idev != NULL, return;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Disable DMA */ - switch_bank( iobase, BANK0); - outb( inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); + switch_bank(iobase, BANK0); + outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); /* Check for underrrun! */ - if ( inb( iobase+ASCR) & ASCR_TXUR) { - idev->stats.tx_errors++; - idev->stats.tx_fifo_errors++; + if (inb(iobase+ASCR) & ASCR_TXUR) { + self->stats.tx_errors++; + self->stats.tx_fifo_errors++; /* Clear bit, by writing 1 into it */ - outb( ASCR_TXUR, iobase+ASCR); + outb(ASCR_TXUR, iobase+ASCR); } else { - idev->stats.tx_packets++; - idev->stats.tx_bytes += idev->tx_buff.len; + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.len; } /* Unlock tx_buff and request another frame */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->media_busy = FALSE; + self->netdev->tbusy = 0; /* Unlock */ /* Tell the network layer, that we can accept more frames */ - mark_bh( NET_BH); + mark_bh(NET_BH); /* Restore bank */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* - * Function pc87108_dma_receive (idev) + * Function pc87108_dma_receive (self) * * Get ready for receiving a frame. The device will initiate a DMA * if it starts to receive a frame. * */ -static int pc87108_dma_receive(struct irda_device *idev) +static int pc87108_dma_receive(struct pc87108 *self) { - struct pc87108 *self; int iobase; __u8 bsr; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ bsr = inb(iobase+BSR); @@ -940,12 +972,12 @@ static int pc87108_dma_receive(struct irda_device *idev) switch_bank(iobase, BANK0); outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); - setup_dma(idev->io.dma, idev->rx_buff.data, - idev->rx_buff.truesize, DMA_MODE_READ); + setup_dma(self->io.dma, self->rx_buff.data, + self->rx_buff.truesize, DMA_MODE_READ); /* driver->media_busy = FALSE; */ - idev->io.direction = IO_RECV; - idev->rx_buff.data = idev->rx_buff.head; + self->io.direction = IO_RECV; + self->rx_buff.data = self->rx_buff.head; /* Reset Rx FIFO. This will also flush the ST_FIFO */ outb(FCR_RXTH|FCR_TXTH|FCR_RXSR|FCR_FIFO_EN, iobase+FCR); @@ -953,7 +985,7 @@ static int pc87108_dma_receive(struct irda_device *idev) /* Choose DMA Rx, DMA Fairness, and Advanced mode */ switch_bank(iobase, BANK2); - outb((inb( iobase+ECR1) & ~ECR1_DMASWP)|ECR1_DMANF|ECR1_EXT_SL, + outb((inb(iobase+ECR1) & ~ECR1_DMASWP)|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1); /* enable DMA */ @@ -963,40 +995,38 @@ static int pc87108_dma_receive(struct irda_device *idev) /* Restore bank register */ outb(bsr, iobase+BSR); - DEBUG(4, __FUNCTION__ "(), done!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), done!\n"); return 0; } /* - * Function pc87108_dma_receive_complete (idev) + * Function pc87108_dma_receive_complete (self) * * Finished with receiving frames * * */ -static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) +static int pc87108_dma_receive_complete(struct pc87108 *self, int iobase) { struct sk_buff *skb; - struct pc87108 *self; struct st_fifo *st_fifo; - int len; __u8 bank; __u8 status; + int len; - self = idev->priv; st_fifo = &self->st_fifo; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Read status FIFO */ switch_bank(iobase, BANK5); - while (( status = inb( iobase+FRM_ST)) & FRM_ST_VLD) { - st_fifo->entries[ st_fifo->tail].status = status; + while ((status = inb(iobase+FRM_ST)) & FRM_ST_VLD) { + st_fifo->entries[st_fifo->tail].status = status; - st_fifo->entries[ st_fifo->tail].len = inb(iobase+RFLFL); - st_fifo->entries[ st_fifo->tail].len |= inb(iobase+RFLFH) << 8; + st_fifo->entries[st_fifo->tail].len = inb(iobase+RFLFL); + st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8; st_fifo->tail++; st_fifo->len++; @@ -1016,28 +1046,28 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) if (status & FRM_ST_ERR_MSK) { if (status & FRM_ST_LOST_FR) { /* Add number of lost frames to stats */ - idev->stats.rx_errors += len; + self->stats.rx_errors += len; } else { /* Skip frame */ - idev->stats.rx_errors++; + self->stats.rx_errors++; - idev->rx_buff.data += len; + self->rx_buff.data += len; if (status & FRM_ST_MAX_LEN) - idev->stats.rx_length_errors++; + self->stats.rx_length_errors++; if (status & FRM_ST_PHY_ERR) - idev->stats.rx_frame_errors++; + self->stats.rx_frame_errors++; if (status & FRM_ST_BAD_CRC) - idev->stats.rx_crc_errors++; + self->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FRM_ST_OVR1) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; if (status & FRM_ST_OVR2) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; } else { /* Check if we have transfered all data to memory */ @@ -1057,10 +1087,10 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) /* Should be OK then */ skb = dev_alloc_skb(len+1); if (skb == NULL) { - printk( KERN_INFO __FUNCTION__ + printk(KERN_INFO __FUNCTION__ "(), memory squeeze, dropping frame.\n"); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return FALSE; } @@ -1069,22 +1099,22 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) skb_reserve(skb, 1); /* Copy frame without CRC */ - if (idev->io.baudrate < 4000000) { + if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, idev->rx_buff.data, len-2); + memcpy(skb->data, self->rx_buff.data, len-2); } else { skb_put(skb, len-4); - memcpy(skb->data, idev->rx_buff.data, len-4); + memcpy(skb->data, self->rx_buff.data, len-4); } /* Move to next frame */ - idev->rx_buff.data += len; - idev->stats.rx_packets++; + self->rx_buff.data += len; + self->stats.rx_packets++; - skb->dev = &idev->netdev; + skb->dev = self->netdev; skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IRDA); - netif_rx( skb); + netif_rx(skb); } } /* Restore bank register */ @@ -1094,60 +1124,59 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) } /* - * Function pc87108_pio_receive (idev) + * Function pc87108_pio_receive (self) * * Receive all data in receiver FIFO * */ -static void pc87108_pio_receive( struct irda_device *idev) +static void pc87108_pio_receive(struct pc87108 *self) { __u8 byte = 0x00; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RXD); - async_unwrap_char(idev, byte); + async_unwrap_char(self->netdev, &self->rx_buff, byte); } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */ } /* - * Function pc87108_sir_interrupt (idev, eir) + * Function pc87108_sir_interrupt (self, eir) * * Handle SIR interrupt * */ -static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) +static __u8 pc87108_sir_interrupt(struct pc87108 *self, int eir) { int actual; __u8 new_ier = 0; /* Transmit FIFO low on data */ - if ( eir & EIR_TXLDL_EV) { + if (eir & EIR_TXLDL_EV) { /* Write data left in transmit buffer */ - actual = pc87108_pio_write(idev->io.iobase, - idev->tx_buff.data, - idev->tx_buff.len, - idev->io.fifo_size); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + actual = pc87108_pio_write(self->io.iobase, + self->tx_buff.data, + self->tx_buff.len, + self->io.fifo_size); + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Check if finished */ - if (idev->tx_buff.len > 0) + if (self->tx_buff.len > 0) new_ier |= IER_TXLDL_IE; else { - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; mark_bh(NET_BH); @@ -1156,16 +1185,16 @@ static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) } /* Check if transmission has completed */ - if ( eir & EIR_TXEMP_EV) { + if (eir & EIR_TXEMP_EV) { /* Turn around and get ready to receive some data */ - idev->io.direction = IO_RECV; + self->io.direction = IO_RECV; new_ier |= IER_RXHDL_IE; } /* Rx FIFO threshold or timeout */ - if ( eir & EIR_RXHDL_EV) { - pc87108_pio_receive( idev); + if (eir & EIR_RXHDL_EV) { + pc87108_pio_receive(self); /* Keep receiving */ new_ier |= IER_RXHDL_IE; @@ -1174,22 +1203,22 @@ static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) } /* - * Function pc87108_fir_interrupt (idev, eir) + * Function pc87108_fir_interrupt (self, eir) * * Handle MIR/FIR interrupt * */ -static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, - int eir) +static __u8 pc87108_fir_interrupt(struct pc87108 *self, int iobase, + int eir) { __u8 new_ier = 0; __u8 bank; - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Status event, or end of frame detected in FIFO */ if (eir & (EIR_SFIF_EV|EIR_LS_EV)) { - if (pc87108_dma_receive_complete( idev, iobase)) { + if (pc87108_dma_receive_complete(self, iobase)) { /* Wait for next status FIFO interrupt */ new_ier |= IER_SFIF_IE; @@ -1197,52 +1226,52 @@ static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, /* DMA not finished yet */ /* Set timer value, resolution 125 us */ - switch_bank( iobase, BANK4); - outb( 0x0f, iobase+TMRL); /* 125 us */ - outb( 0x00, iobase+TMRH); + switch_bank(iobase, BANK4); + outb(0x0f, iobase+TMRL); /* 125 us */ + outb(0x00, iobase+TMRH); /* Start timer */ - outb( IRCR1_TMR_EN, iobase+IRCR1); + outb(IRCR1_TMR_EN, iobase+IRCR1); new_ier |= IER_TMR_IE; } } /* Timer finished */ - if ( eir & EIR_TMR_EV) { + if (eir & EIR_TMR_EV) { /* Disable timer */ - switch_bank( iobase, BANK4); - outb( 0, iobase+IRCR1); + switch_bank(iobase, BANK4); + outb(0, iobase+IRCR1); /* Clear timer event */ switch_bank(iobase, BANK0); - outb( ASCR_CTE, iobase+ASCR); + outb(ASCR_CTE, iobase+ASCR); /* Check if this is a TX timer interrupt */ - if ( idev->io.direction == IO_XMIT) { - pc87108_dma_write( idev, iobase); + if (self->io.direction == IO_XMIT) { + pc87108_dma_write(self, iobase); /* Interrupt on DMA */ new_ier |= IER_DMA_IE; } else { /* Check if DMA has now finished */ - pc87108_dma_receive_complete( idev, iobase); + pc87108_dma_receive_complete(self, iobase); new_ier |= IER_SFIF_IE; } } /* Finished with transmission */ - if ( eir & EIR_DMA_EV) { - pc87108_dma_xmit_complete( idev); + if (eir & EIR_DMA_EV) { + pc87108_dma_xmit_complete(self); /* Check if there are more frames to be transmitted */ - if ( irda_device_txqueue_empty( idev)) { + if (irda_device_txqueue_empty(self->netdev)) { /* Prepare for receive */ - pc87108_dma_receive( idev); + pc87108_dma_receive(self); new_ier = IER_LS_IE|IER_SFIF_IE; } } - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return new_ier; } @@ -1255,51 +1284,52 @@ static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, */ static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + struct net_device *dev = (struct net_device *) dev_id; + struct pc87108 *self; __u8 bsr, eir, ier; int iobase; - struct irda_device *idev = (struct irda_device *) dev_id; - - if (idev == NULL) { - printk( KERN_WARNING "%s: irq %d for unknown device.\n", + if (!dev) { + printk(KERN_WARNING "%s: irq %d for unknown device.\n", driver_name, irq); return; } + self = (struct pc87108 *) dev->priv; - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ - bsr = inb( iobase+BSR); + bsr = inb(iobase+BSR); - switch_bank( iobase, BANK0); - ier = inb( iobase+IER); - eir = inb( iobase+EIR) & ier; /* Mask out the interesting ones */ + switch_bank(iobase, BANK0); + ier = inb(iobase+IER); + eir = inb(iobase+EIR) & ier; /* Mask out the interesting ones */ - outb( 0, iobase+IER); /* Disable interrupts */ + outb(0, iobase+IER); /* Disable interrupts */ - if ( eir) { + if (eir) { /* Dispatch interrupt handler for the current speed */ - if ( idev->io.baudrate > 115200) - ier = pc87108_fir_interrupt( idev, iobase, eir); + if (self->io.speed > 115200) + ier = pc87108_fir_interrupt(self, iobase, eir); else - ier = pc87108_sir_interrupt( idev, eir); + ier = pc87108_sir_interrupt(self, eir); } - outb( ier, iobase+IER); /* Restore interrupts */ - outb( bsr, iobase+BSR); /* Restore bank register */ + outb(ier, iobase+IER); /* Restore interrupts */ + outb(bsr, iobase+BSR); /* Restore bank register */ - idev->netdev.interrupt = 0; + dev->interrupt = 0; } /* - * Function pc87108_wait_until_sent (idev) + * Function pc87108_wait_until_sent (self) * * This function should put the current thread to sleep until all data * have been sent, so it is safe to f.eks. change the speed. */ -static void pc87108_wait_until_sent( struct irda_device *idev) +static void pc87108_wait_until_sent(struct pc87108 *self) { /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; @@ -1307,33 +1337,32 @@ static void pc87108_wait_until_sent( struct irda_device *idev) } /* - * Function pc87108_is_receiving (idev) + * Function pc87108_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int pc87108_is_receiving( struct irda_device *idev) +static int pc87108_is_receiving(struct pc87108 *self) { int status = FALSE; int iobase; __u8 bank; - ASSERT( idev != NULL, return FALSE;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); + ASSERT(self != NULL, return FALSE;); - if ( idev->io.baudrate > 115200) { - iobase = idev->io.iobase; + if (self->io.speed > 115200) { + iobase = self->io.iobase; /* Check if rx FIFO is not empty */ - bank = inb( iobase+BSR); - switch_bank( iobase, BANK2); - if (( inb( iobase+RXFLV) & 0x3f) != 0) { + bank = inb(iobase+BSR); + switch_bank(iobase, BANK2); + if ((inb(iobase+RXFLV) & 0x3f) != 0) { /* We are receiving something */ status = TRUE; } - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } else - status = ( idev->rx_buff.state != OUTSIDE_FRAME); + status = (self->rx_buff.state != OUTSIDE_FRAME); return status; } @@ -1344,12 +1373,12 @@ static int pc87108_is_receiving( struct irda_device *idev) * Initialize network device * */ -static int pc87108_net_init( struct net_device *dev) +static int pc87108_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); + irda_device_setup(dev); /* Insert overrides below this line! */ @@ -1363,46 +1392,54 @@ static int pc87108_net_init( struct net_device *dev) * Start the device * */ -static int pc87108_net_open( struct net_device *dev) +static int pc87108_net_open(struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + ASSERT(dev != NULL, return -1;); + self = (struct pc87108 *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - if (request_irq( idev->io.irq, pc87108_interrupt, 0, idev->name, - (void *) idev)) { + if (request_irq(self->io.irq, pc87108_interrupt, 0, dev->name, + (void *) dev)) { return -EAGAIN; } /* * Always allocate the DMA channel after the IRQ, * and clean up on failure. */ - if (request_dma(idev->io.dma, idev->name)) { - free_irq( idev->io.irq, idev); + if (request_dma(self->io.dma, dev->name)) { + free_irq(self->io.irq, self); return -EAGAIN; } /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* turn on interrupts */ - switch_bank( iobase, BANK0); - outb( IER_LS_IE | IER_RXHDL_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_LS_IE | IER_RXHDL_IE, iobase+IER); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); - 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); MOD_INC_USE_COUNT; @@ -1417,23 +1454,29 @@ static int pc87108_net_open( struct net_device *dev) */ static int pc87108_net_close(struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - irda_device_net_close(dev); - ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct pc87108 *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + 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; - iobase = idev->io.iobase; + iobase = self->io.iobase; - disable_dma(idev->io.dma); + disable_dma(self->io.dma); /* Save current bank */ bank = inb(iobase+BSR); @@ -1442,8 +1485,8 @@ static int pc87108_net_close(struct net_device *dev) switch_bank(iobase, BANK0); outb(0, iobase+IER); - free_irq(idev->io.irq, idev); - free_dma(idev->io.dma); + free_irq(self->io.irq, self); + free_dma(self->io.dma); /* Restore bank register */ outb(bank, iobase+BSR); diff --git a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c index 00ab408d6..06b2af81b 100644 --- a/drivers/net/irda/smc-ircc.c +++ b/drivers/net/irda/smc-ircc.c @@ -106,7 +106,7 @@ int __init ircc_init(void) { int i; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); for ( i=0; (io[i] < 2000) && (i < 4); i++) { int ioaddr = io[i]; if (check_region(ioaddr, CHIP_IO_EXTENT)) @@ -114,7 +114,7 @@ int __init ircc_init(void) if (ircc_open( i, io[i], io2[i]) == 0) return 0; } - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return -ENODEV; } @@ -130,13 +130,13 @@ static void ircc_cleanup(void) { int i; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); for ( i=0; i < 4; i++) { if ( dev_self[i]) ircc_close( &(dev_self[i]->idev)); } - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } #endif /* MODULE */ @@ -153,10 +153,10 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) int ret; int config; - DEBUG( ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG( ircc_debug, __FUNCTION__ " -->\n"); if ((config = ircc_probe( iobase, iobase2)) == -1) { - DEBUG(ircc_debug, + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": addr 0x%04x - no device found!\n", iobase); return -1; } @@ -199,14 +199,14 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) /* Lock the port that we need */ ret = check_region( idev->io.iobase, idev->io.io_ext); if ( ret < 0) { - DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", + IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", idev->io.iobase); /* ircc_cleanup( self->idev); */ return -ENODEV; } ret = check_region( idev->io.iobase2, idev->io.io_ext2); if ( ret < 0) { - DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", + IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", idev->io.iobase2); /* ircc_cleanup( self->idev); */ return -ENODEV; @@ -256,7 +256,7 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) /* Open the IrDA device */ irda_device_open( idev, driver_name, self); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -271,7 +271,7 @@ static int ircc_close( struct irda_device *idev) { int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return -1;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -291,20 +291,20 @@ static int ircc_close( struct irda_device *idev) serial_out(iobase, UART_SCE_CFGB, UART_CFGB_IR); /* Release the PORT that this driver is using */ - DEBUG( ircc_debug, + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase); release_region( idev->io.iobase, idev->io.io_ext); if ( idev->io.iobase2) { - DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase2); release_region( idev->io.iobase2, idev->io.io_ext2); } irda_device_close( idev); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } #endif /* MODULE */ @@ -320,7 +320,7 @@ static int ircc_probe(int iobase, int iobase2) int version = 1; int low, high, chip, config, dma, irq; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); register_bank(iobase, 3); high = serial_in(iobase, UART_ID_HIGH); @@ -332,7 +332,7 @@ static int ircc_probe(int iobase, int iobase2) dma = config & 0x0f; if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) { - DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, " + IRDA_DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, " "port 0x%04x, dma %d, interrupt %d\n", chip & 0x0f, version, iobase, dma, irq); } else { @@ -341,7 +341,7 @@ static int ircc_probe(int iobase, int iobase2) serial_out(iobase, UART_MASTER, 0); - DEBUG(ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n"); return config; } @@ -357,7 +357,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) struct ircc_cb *self; int iobase, ir_mode, select, fast; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -374,7 +374,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) case 37600: case 57600: case 115200: - DEBUG(ircc_debug+1, + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": using irport to change speed to %d\n", speed); register_bank(iobase, 0); @@ -390,22 +390,22 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) ir_mode = UART_CFGA_IRDA_HDLC; select = 0; fast = 0; - DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n"); + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n"); break; case 1152000: ir_mode = UART_CFGA_IRDA_HDLC; select = UART_1152; fast = 0; - DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 1152000\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 1152000\n"); break; case 4000000: ir_mode = UART_CFGA_IRDA_4PPM; select = 0; fast = UART_LCR_A_FAST; - DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n"); break; default: - DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed); + IRDA_DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed); return; } @@ -443,7 +443,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) serial_out(iobase, UART_LCR_A, fast); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -458,7 +458,7 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) int iobase; int mtt; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); idev = (struct irda_device *) dev->priv; ASSERT( idev != NULL, return 0;); @@ -466,15 +466,15 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) iobase = idev->io.iobase; - DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Use irport for SIR speeds */ if (idev->io.baudrate <= 115200) { - DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n"); return irport_hard_xmit(skb, dev); } - DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) @@ -502,7 +502,7 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) dev_kfree_skb( skb); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -516,7 +516,7 @@ static void ircc_dma_write( struct irda_device *idev, int iobase) { struct ircc_cb *self; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -557,7 +557,7 @@ static void ircc_dma_write( struct irda_device *idev, int iobase) serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -572,7 +572,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) struct ircc_cb *self; int iobase, d; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -585,7 +585,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) d = get_dma_residue(idev->io.dma); - DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", d, idev->tx_buff.len, idev->tx_buff.len - d); self = idev->priv; @@ -608,7 +608,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) /* Tell the network layer, that we can accept more frames */ mark_bh( NET_BH); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -623,7 +623,7 @@ static int ircc_dma_receive( struct irda_device *idev) struct ircc_cb *self; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return -1;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -660,7 +660,7 @@ static int ircc_dma_receive( struct irda_device *idev) serial_in(iobase, UART_SCE_CFGB) | UART_CFGB_DMA_ENABLE | UART_CFGB_DMA_BURST); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -677,18 +677,18 @@ static int ircc_dma_receive_complete( struct irda_device *idev, int iobase) struct ircc_cb *self; int len, msgcnt; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); self = idev->priv; msgcnt = serial_in(idev->io.iobase, UART_LCR_B) & 0x08; - DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", get_dma_residue(idev->io.dma)); len = idev->rx_buff.truesize - get_dma_residue(idev->io.dma) - 4; - DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len); skb = dev_alloc_skb( len+1); @@ -715,7 +715,7 @@ static int ircc_dma_receive_complete( struct irda_device *idev, int iobase) serial_in(idev->io.iobase, UART_SCE_CFGB) & ~UART_CFGB_DMA_ENABLE); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return TRUE; } @@ -731,7 +731,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct irda_device *idev = (struct irda_device *) dev_id; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); if (idev == NULL) { printk( KERN_WARNING "%s: irq %d for unknown device.\n", @@ -740,7 +740,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (idev->io.baudrate <= 115200) { - DEBUG(ircc_debug+1, __FUNCTION__ + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": routing interrupt to irport_interrupt\n"); return irport_interrupt( irq, dev_id, regs); } @@ -757,10 +757,10 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) serial_out(iobase, UART_IER, 0); - DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir); if (iir & UART_IIR_EOM) { - DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n"); if (idev->io.direction == IO_RECV) { ircc_dma_receive_complete(idev, iobase); } else { @@ -770,7 +770,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (iir & UART_IIR_ACTIVE_FRAME) { - DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n"); idev->rx_buff.state = INSIDE_FRAME; #if 0 ircc_dma_receive(idev); @@ -778,7 +778,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (iir & UART_IIR_RAW_MODE) { - DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n"); } idev->netdev.interrupt = 0; @@ -787,7 +787,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME|UART_IER_EOM); serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -798,13 +798,13 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ static void ircc_wait_until_sent( struct irda_device *idev) { - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(60)); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -818,17 +818,17 @@ static int ircc_is_receiving( struct irda_device *idev) int status = FALSE; /* int iobase; */ - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return FALSE;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); - DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", get_dma_residue(idev->io.dma)); status = ( idev->rx_buff.state != OUTSIDE_FRAME); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return status; } @@ -841,14 +841,14 @@ static int ircc_is_receiving( struct irda_device *idev) */ static int ircc_net_init( struct net_device *dev) { - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); /* Setup to be a normal IrDA network device driver */ irda_device_setup( dev); /* Insert overrides below this line! */ - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -864,7 +864,7 @@ static int ircc_net_open( struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -894,7 +894,7 @@ static int ircc_net_open( struct net_device *dev) MOD_INC_USE_COUNT; - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -909,7 +909,7 @@ static int ircc_net_close(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -930,7 +930,7 @@ static int ircc_net_close(struct net_device *dev) MOD_DEC_USE_COUNT; - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c index 6f3c49f6f..35504cfd3 100644 --- a/drivers/net/irda/tekram.c +++ b/drivers/net/irda/tekram.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Thu Jul 15 01:17:53 1999 + * Modified at: Mon Oct 18 23:25:44 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -29,15 +29,14 @@ #include <linux/init.h> #include <net/irda/irda.h> +#include <net/irda/irmod.h> #include <net/irda/irda_device.h> #include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void tekram_reset(struct irda_device *dev); -static void tekram_open(struct irda_device *dev, int type); -static void tekram_close(struct irda_device *dev); -static void tekram_change_speed(struct irda_device *dev, __u32 speed); -static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos); +static void tekram_open(dongle_t *self, struct qos_info *qos); +static void tekram_close(dongle_t *self); +static int tekram_change_speed(struct irda_task *task); +static int tekram_reset(struct irda_task *task); #define TEKRAM_115200 0x00 #define TEKRAM_57600 0x01 @@ -47,13 +46,13 @@ static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos); #define TEKRAM_PW 0x10 /* Pulse select bit */ -static struct dongle dongle = { - TEKRAM_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_TEKRAM_DONGLE, tekram_open, tekram_close, tekram_reset, tekram_change_speed, - tekram_init_qos, }; int __init tekram_init(void) @@ -66,26 +65,29 @@ void tekram_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void tekram_open(struct irda_device *idev, int type) +static void tekram_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> tekram"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + 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); - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; - MOD_INC_USE_COUNT; } -static void tekram_close(struct irda_device *idev) -{ +static void tekram_close(dongle_t *self) +{ + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function tekram_change_speed (tty, speed) + * Function tekram_change_speed (dev, state, speed) * * Set the speed for the Tekram IRMate 210 type dongle. Warning, this * function must be called with a process context! @@ -100,14 +102,16 @@ static void tekram_close(struct irda_device *idev) * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here * after */ -static void tekram_change_speed(struct irda_device *idev, __u32 speed) +static int tekram_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; __u8 byte; + int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(task != NULL, return -1;); switch (speed) { default: @@ -128,24 +132,65 @@ static void tekram_change_speed(struct irda_device *idev, __u32 speed) break; } - /* Need to reset the dongle and go to 9600 bps before programming */ - tekram_reset(idev); - - /* Set DTR, Clear RTS */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); - - /* Wait at least 7us */ - udelay(10); + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + irda_task_next_state(task, IRDA_TASK_CHILD_INIT); + break; + case IRDA_TASK_CHILD_INIT: + /* + * Need to reset the dongle and go to 9600 bps before + * programming + */ + if (irda_task_execute(self, tekram_reset, NULL, task, + (void *) speed)) + { + /* Dongle need more time to reset */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); - /* Write control byte */ - irda_device_raw_write(idev, &byte, 1); + /* Give reset 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } else + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + ret = -1; + break; + case IRDA_TASK_CHILD_DONE: + /* Set DTR, Clear RTS */ + self->set_dtr_rts(self->dev, TRUE, FALSE); - /* Wait at least 100 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(100)); - - /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + /* Wait at least 7us */ + udelay(10); + + /* Write control byte */ + self->write(self->dev, &byte, 1); + + irda_task_next_state(task, IRDA_TASK_WAIT); + + /* Wait at least 100 ms */ + ret = MSECS_TO_JIFFIES(100); + break; + case IRDA_TASK_WAIT: + /* Set DTR, Set RTS */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; + break; + } + return ret; } /* @@ -161,50 +206,52 @@ static void tekram_change_speed(struct irda_device *idev, __u32 speed) * 3. clear DTR to SPACE state, wait at least 50 us for further * operation */ -void tekram_reset(struct irda_device *idev) +int tekram_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + dongle_t *self = (dongle_t *) task->instance; + int ret = 0; + + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + ASSERT(task != NULL, return -1;); /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); - - /* Sleep 50 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(50)); + self->set_dtr_rts(self->dev, FALSE, FALSE); - /* Clear DTR, Set RTS */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + switch (task->state) { + case IRDA_TASK_INIT: + irda_task_next_state(task, IRDA_TASK_WAIT1); - /* Should sleep 1 ms, but 10-20 should not do any harm */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + /* Sleep 50 ms */ + ret = MSECS_TO_JIFFIES(50); + break; + case IRDA_TASK_WAIT1: + /* Clear DTR, Set RTS */ + self->set_dtr_rts(self->dev, FALSE, TRUE); - /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); - - udelay(50); + irda_task_next_state(task, IRDA_TASK_WAIT2); + + /* Should sleep 1 ms, but 10 should not do any harm */ + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT2: + /* Set DTR, Set RTS */ + self->set_dtr_rts(self->dev, TRUE, TRUE); - /* Make sure the IrDA chip also goes to defalt speed */ - if (idev->change_speed) - idev->change_speed(idev, 9600); -} + udelay(50); -/* - * Function tekram_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void tekram_init_qos(struct irda_device *idev, 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); + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + + ret = -1; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver"); @@ -229,5 +276,4 @@ void cleanup_module(void) { tekram_cleanup(); } - #endif /* MODULE */ 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 diff --git a/drivers/net/irda/uircc.c b/drivers/net/irda/uircc.c index 869ccd5d6..2726700bb 100644 --- a/drivers/net/irda/uircc.c +++ b/drivers/net/irda/uircc.c @@ -113,7 +113,7 @@ static void uircc_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) @@ -135,7 +135,7 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2, struct irda_device *idev; int ret; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if ((uircc_probe(iobase, iobase2, irq, dma)) == -1) return -1; @@ -168,14 +168,14 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2, /* Lock the port that we need */ ret = check_region(idev->io.iobase, idev->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", idev->io.iobase); /* uircc_cleanup( self->idev); */ return -ENODEV; } ret = check_region(idev->io.iobase2, idev->io.io_ext2); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", idev->io.iobase2); /* uircc_cleanup( self->idev); */ return -ENODEV; @@ -235,7 +235,7 @@ static int uircc_close(struct irda_device *idev) int iobase; int status; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return -1;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -252,11 +252,11 @@ static int uircc_close(struct irda_device *idev) irport_stop(idev, idev->io.iobase2); /* Release the PORT that this driver is using */ - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); release_region(idev->io.iobase, idev->io.io_ext); if (idev->io.iobase2) { - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase2); release_region(idev->io.iobase2, idev->io.io_ext2); } @@ -278,13 +278,13 @@ static int uircc_probe(int iobase, int iobase2, int irq, int dma) { int version; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* read the chip version, should be 0x03 */ version = inb(iobase+UIRCC_SR8); if (version != 0x03) { - DEBUG(0, __FUNCTION__ "(), Wrong chip version"); + IRDA_DEBUG(0, __FUNCTION__ "(), Wrong chip version"); return -1; } printk(KERN_INFO "Sharp UIRCC IrDA driver loaded. Version: 0x%02x\n", @@ -298,7 +298,7 @@ static int uircc_probe(int iobase, int iobase2, int irq, int dma) outb(0, iobase+UIRCC_CR11); outb(0, iobase+UIRCC_CR9); - DEBUG(0, __FUNCTION__ "(), sr15=%#x\n", inb(iobase+UIRCC_SR15)); + IRDA_DEBUG(0, __FUNCTION__ "(), sr15=%#x\n", inb(iobase+UIRCC_SR15)); /* Enable DMA single mode */ outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET, @@ -325,7 +325,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) int modem = UIRCC_CR10_SIR; int status; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Just test the high speed stuff */ /*speed = 4000000;*/ @@ -358,11 +358,11 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) break; case 576000: - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: irport_stop(idev, idev->io.iobase2); @@ -371,7 +371,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001); modem = UIRCC_CR10_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); /* Set self pole address */ //outb(0xfe, iobase+UIRCC_CR8); @@ -379,7 +379,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) /* outb(0x10, iobase+UIRCC_CR11); */ break; default: - DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -419,7 +419,7 @@ static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) iobase = idev->io.iobase; - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Reset carrier latch */ /*outb(0x02, iobase+UIRCC_CR0);*/ @@ -429,7 +429,7 @@ static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) return irport_hard_xmit(skb, dev); } - DEBUG(0, __FUNCTION__ "(), sr0=%#x, sr1=%#x, sr2=%#x, sr3=%#x, sr10=%#x, sr11=%#x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), sr0=%#x, sr1=%#x, sr2=%#x, sr3=%#x, sr10=%#x, sr11=%#x\n", inb(iobase+UIRCC_SR0), inb(iobase+UIRCC_SR3), inb(iobase+UIRCC_SR2), inb(iobase+UIRCC_SR3), inb(iobase+UIRCC_SR10), inb(iobase+UIRCC_SR11)); @@ -473,7 +473,7 @@ static void uircc_dma_write(struct irda_device *idev, int iobase) { struct uircc_cb *self; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -519,7 +519,7 @@ static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun) int iobase; int len; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -535,7 +535,7 @@ static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun) len = inb(iobase+UIRCC_SR4); /* Low byte */ len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */ - DEBUG(4, __FUNCTION__ "(), sent %d bytes\n", len); + IRDA_DEBUG(4, __FUNCTION__ "(), sent %d bytes\n", len); /* Disable transmit */ self->cr3 &= ~UIRCC_CR3_XMIT_EN; @@ -576,7 +576,7 @@ static int uircc_dma_receive(struct irda_device *idev) ASSERT(idev != NULL, return -1;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); self = idev->priv; iobase= idev->io.iobase; @@ -614,7 +614,7 @@ static int uircc_dma_receive(struct irda_device *idev) self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN); outb(self->cr3, iobase+UIRCC_CR3); #endif - DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3); + IRDA_DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3); /* Address check? */ @@ -636,11 +636,11 @@ static int uircc_dma_receive_complete(struct irda_device *idev, int iobase) self = idev->priv; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Check for CRC or framing error */ if (inb(iobase+UIRCC_SR0) & UIRCC_SR0_RX_CRCFRM) { - DEBUG(0, __FUNCTION__ "(), CRC or FRAME error\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), CRC or FRAME error\n"); return -1; } @@ -651,7 +651,7 @@ static int uircc_dma_receive_complete(struct irda_device *idev, int iobase) len = inb(iobase+UIRCC_SR4); /* Low byte */ len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */ - DEBUG(0, __FUNCTION__ "(), len=%d\n", len); + IRDA_DEBUG(0, __FUNCTION__ "(), len=%d\n", len); /* Receiving disable */ self->cr3 &= ~UIRCC_CR3_RECV_EN; @@ -716,12 +716,12 @@ static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* Read interrupt status */ sr3 = inb( iobase+UIRCC_SR3); if (!sr3) { - DEBUG(4,"**\n"); + IRDA_DEBUG(4,"**\n"); return; } idev->netdev.interrupt = 1; - DEBUG(4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n", inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2), inb( iobase+UIRCC_SR10)); @@ -750,7 +750,7 @@ static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) iobase+UIRCC_CR11); break; default: - DEBUG(0, __FUNCTION__ "(), unknown interrupt status=%#x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), unknown interrupt status=%#x\n", sr3); break; } @@ -800,7 +800,7 @@ static int uircc_is_receiving( struct irda_device *idev) */ static int uircc_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); @@ -822,7 +822,7 @@ static int uircc_net_open(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -866,7 +866,7 @@ static int uircc_net_close(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 32e965275..422f691ab 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Wed Nov 4 11:46:16 1998 - * Modified at: Wed Aug 11 09:27:54 1999 + * Modified at: Wed Oct 20 00:08:30 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -49,6 +49,7 @@ #include <linux/delay.h> #include <linux/malloc.h> #include <linux/init.h> +#include <linux/rtnetlink.h> #include <asm/io.h> #include <asm/dma.h> @@ -83,17 +84,16 @@ static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL}; /* Some prototypes */ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, unsigned int dma); -static int w83977af_close(struct irda_device *idev); +static int w83977af_close(struct w83977af_ir *self); static int w83977af_probe(int iobase, int irq, int dma); -static int w83977af_dma_receive(struct irda_device *idev); -static int w83977af_dma_receive_complete(struct irda_device *idev); +static int w83977af_dma_receive(struct w83977af_ir *self); +static int w83977af_dma_receive_complete(struct w83977af_ir *self); static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size); -static void w83977af_dma_write(struct irda_device *idev, int iobase); -static void w83977af_change_speed(struct irda_device *idev, __u32 speed); +static void w83977af_dma_write(struct w83977af_ir *self, int iobase); +static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed); static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void w83977af_wait_until_sent(struct irda_device *idev); -static int w83977af_is_receiving(struct irda_device *idev); +static int w83977af_is_receiving(struct w83977af_ir *self); static int w83977af_net_init(struct net_device *dev); static int w83977af_net_open(struct net_device *dev); @@ -109,13 +109,13 @@ int __init w83977af_init(void) { int i; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); for (i=0; (io[i] < 2000) && (i < 4); i++) { int ioaddr = io[i]; if (check_region(ioaddr, CHIP_IO_EXTENT) < 0) continue; - if (w83977af_open( i, io[i], irq[i], dma[i]) == 0) + if (w83977af_open(i, io[i], irq[i], dma[i]) == 0) return 0; } return -ENODEV; @@ -132,11 +132,11 @@ void w83977af_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) - w83977af_close(&(dev_self[i]->idev)); + w83977af_close(dev_self[i]); } } #endif /* MODULE */ @@ -147,14 +147,15 @@ void w83977af_cleanup(void) * Open driver instance * */ -int w83977af_open( int i, unsigned int iobase, unsigned int irq, - unsigned int dma) +int w83977af_open(int i, unsigned int iobase, unsigned int irq, + unsigned int dma) { - struct irda_device *idev; + struct net_device *dev; struct w83977af_ir *self; int ret; + int err; - DEBUG( 0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if (w83977af_probe(iobase, irq, dma) == -1) return -1; @@ -173,83 +174,107 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq, /* Need to store self somewhere */ dev_self[i] = self; - idev = &self->idev; - /* Initialize IO */ - idev->io.iobase = iobase; - idev->io.irq = irq; - idev->io.io_ext = CHIP_IO_EXTENT; - idev->io.dma = dma; - idev->io.fifo_size = 32; + self->io.iobase = iobase; + self->io.irq = irq; + self->io.io_ext = CHIP_IO_EXTENT; + self->io.dma = dma; + self->io.fifo_size = 32; /* Lock the port that we need */ - ret = check_region(idev->io.iobase, idev->io.io_ext); + ret = check_region(self->io.iobase, self->io.io_ext); if (ret < 0) { - DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase); - /* w83977af_cleanup( self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase); + /* w83977af_cleanup( self); */ return -ENODEV; } - request_region(idev->io.iobase, idev->io.io_ext, idev->name); + request_region(self->io.iobase, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ /* FIXME: The HP HDLS-1100 does not support 1152000! */ - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); /* The HP HDLS-1100 needs 1 ms according to the specs */ - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; - - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; - idev->tx_buff.flags = GFP_KERNEL | GFP_DMA; + self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ - idev->rx_buff.truesize = 14384; - idev->tx_buff.truesize = 4000; + self->rx_buff.truesize = 14384; + self->tx_buff.truesize = 4000; - /* Initialize callbacks */ - idev->change_speed = w83977af_change_speed; - idev->wait_until_sent = w83977af_wait_until_sent; - idev->is_receiving = w83977af_is_receiving; + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL|GFP_DMA); + if (self->rx_buff.head == NULL) + return -ENOMEM; + memset(self->rx_buff.head, 0, self->rx_buff.truesize); + } + if (self->tx_buff.truesize > 0) { + self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, + GFP_KERNEL|GFP_DMA); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + + 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; /* Override the network functions we need to use */ - idev->netdev.init = w83977af_net_init; - idev->netdev.hard_start_xmit = w83977af_hard_xmit; - idev->netdev.open = w83977af_net_open; - idev->netdev.stop = w83977af_net_close; + dev->init = w83977af_net_init; + dev->hard_start_xmit = w83977af_hard_xmit; + dev->open = w83977af_net_open; + dev->stop = w83977af_net_close; + + rtnl_lock(); + err = register_netdev(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - /* Open the IrDA device */ - irda_device_open(idev, driver_name, self); + MESSAGE("IrDA: Registered device %s\n", dev->name); return 0; } /* - * Function w83977af_close (idev) + * Function w83977af_close (self) * * Close driver instance * */ -static int w83977af_close( struct irda_device *idev) +static int w83977af_close(struct w83977af_ir *self) { - struct w83977af_ir *self; int iobase; - DEBUG(0, __FUNCTION__ "()\n"); - - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); - iobase = idev->io.iobase; - self = (struct w83977af_ir *) idev->priv; + iobase = self->io.iobase; #ifdef CONFIG_USE_W977_PNP /* enter PnP configuration mode */ @@ -262,12 +287,24 @@ static int w83977af_close( struct irda_device *idev) w977_efm_exit(); #endif /* CONFIG_USE_W977_PNP */ + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdev(self->netdev); + rtnl_unlock(); + } + /* Release the PORT that this driver is using */ - DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", - idev->io.iobase); - release_region(idev->io.iobase, idev->io.io_ext); + IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", + self->io.iobase); + release_region(self->io.iobase, self->io.io_ext); - irda_device_close(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); kfree(self); @@ -284,7 +321,7 @@ int w83977af_probe( int iobase, int irq, int dma) { int version; - DEBUG( 0, __FUNCTION__ "()\n"); + IRDA_DEBUG( 0, __FUNCTION__ "()\n"); #ifdef CONFIG_USE_W977_PNP /* Enter PnP configuration mode */ w977_efm_enter(); @@ -333,7 +370,7 @@ int w83977af_probe( int iobase, int irq, int dma) /* Should be 0x1? */ if (0x10 != (version & 0xf0)) { - DEBUG( 0, __FUNCTION__ "(), Wrong chip version"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Wrong chip version"); return -1; } @@ -365,30 +402,21 @@ int w83977af_probe( int iobase, int irq, int dma) switch_bank(iobase, SET7); outb(0x40, iobase+7); - DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version); + IRDA_DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version); return 0; } -/* - * Function w83977af_change_speed (idev, baud) - * - * Change the speed of the device - * - */ -void w83977af_change_speed(struct irda_device *idev, __u32 speed) +void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) { int ir_mode = HCR_SIR; int iobase; __u8 set; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; /* Save current bank */ set = inb(iobase+SSR); @@ -409,19 +437,19 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) case 115200: outb(0x01, iobase+ABLL); break; case 576000: ir_mode = HCR_MIR_576; - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: ir_mode = HCR_MIR_1152; - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: ir_mode = HCR_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); break; default: ir_mode = HCR_FIR; - DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -440,13 +468,13 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) outb(UFR_EN_FIFO, iobase+UFR); /* First we must enable FIFO */ outb(0xa7, iobase+UFR); - idev->netdev.tbusy = 0; + self->netdev->tbusy = 0; /* Enable some interrupts so we can receive frames */ switch_bank(iobase, SET0); if (speed > PIO_MAX_SPEED) { outb(ICR_EFSFI, iobase+ICR); - w83977af_dma_receive(idev); + w83977af_dma_receive(self); } else outb(ICR_ERBRI, iobase+ICR); @@ -462,32 +490,34 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) */ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; + __u32 speed; int iobase; __u8 set; int mtt; - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + iobase = self->io.iobase; - iobase = idev->io.iobase; - - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) + w83977af_change_speed(self, speed); + /* Save current set */ set = inb(iobase+SSR); /* Decide if we should use PIO or DMA transfer */ - if (idev->io.baudrate > PIO_MAX_SPEED) { - idev->tx_buff.data = idev->tx_buff.head; - memcpy(idev->tx_buff.data, skb->data, skb->len); - idev->tx_buff.len = skb->len; + if (self->io.speed > PIO_MAX_SPEED) { + self->tx_buff.data = self->tx_buff.head; + memcpy(self->tx_buff.data, skb->data, skb->len); + self->tx_buff.len = skb->len; mtt = irda_get_mtt(skb); #ifdef CONFIG_USE_INTERNAL_TIMER @@ -502,28 +532,28 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* Start timer */ outb(IR_MSL_EN_TMR, iobase+IR_MSL); - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Enable timer interrupt */ switch_bank(iobase, SET0); outb(ICR_ETMRI, iobase+ICR); } else { #endif - DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt); + IRDA_DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt); if (mtt) udelay(mtt); /* Enable DMA interrupt */ switch_bank(iobase, SET0); outb(ICR_EDMAI, iobase+ICR); - w83977af_dma_write(idev, iobase); + w83977af_dma_write(self, iobase); #ifdef CONFIG_USE_INTERNAL_TIMER } #endif } else { - idev->tx_buff.data = idev->tx_buff.head; - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.data = self->tx_buff.head; + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); /* Add interrupt on tx low level (will fire immediately) */ switch_bank(iobase, SET0); @@ -538,19 +568,19 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) } /* - * Function w83977af_dma_write (idev, iobase) + * Function w83977af_dma_write (self, iobase) * * Send frame using DMA * */ -static void w83977af_dma_write(struct irda_device *idev, int iobase) +static void w83977af_dma_write(struct w83977af_ir *self, int iobase) { __u8 set; #ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS unsigned long flags; __u8 hcr; #endif - DEBUG(4, __FUNCTION__ "(), len=%d\n", idev->tx_buff.len); + IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", self->tx_buff.len); /* Save current set */ set = inb(iobase+SSR); @@ -566,23 +596,23 @@ static void w83977af_dma_write(struct irda_device *idev, int iobase) save_flags(flags); cli(); - disable_dma(idev->io.dma); - clear_dma_ff(idev->io.dma); - set_dma_mode(idev->io.dma, DMA_MODE_READ); - set_dma_addr(idev->io.dma, virt_to_bus(idev->tx_buff.data)); - set_dma_count(idev->io.dma, idev->tx_buff.len); + disable_dma(self->io.dma); + clear_dma_ff(self->io.dma); + set_dma_mode(self->io.dma, DMA_MODE_READ); + set_dma_addr(self->io.dma, virt_to_bus(self->tx_buff.data)); + set_dma_count(self->io.dma, self->tx_buff.len); #else - setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, + setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, DMA_MODE_WRITE); #endif - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Enable DMA */ switch_bank(iobase, SET0); #ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS hcr = inb(iobase+HCR); outb(hcr | HCR_EN_DMA, iobase+HCR); - enable_dma(idev->io.dma); + enable_dma(self->io.dma); restore_flags(flags); #else outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR); @@ -603,17 +633,17 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 set; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ set = inb(iobase+SSR); switch_bank(iobase, SET0); if (!(inb_p(iobase+USR) & USR_TSRE)) { - DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); fifo_size -= 17; - DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); + IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); } /* Fill FIFO with current frame */ @@ -622,7 +652,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) outb(buf[actual++], iobase+TBR); } - DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", + IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", fifo_size, actual, len); /* Restore bank */ @@ -632,23 +662,22 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } /* - * Function w83977af_dma_xmit_complete (idev) + * Function w83977af_dma_xmit_complete (self) * * The transfer of a frame in finished. So do the necessary things * * */ -void w83977af_dma_xmit_complete(struct irda_device *idev) +void w83977af_dma_xmit_complete(struct w83977af_ir *self) { int iobase; __u8 set; - DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies); + IRDA_DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current set */ set = inb(iobase+SSR); @@ -659,19 +688,18 @@ void w83977af_dma_xmit_complete(struct irda_device *idev) /* Check for underrrun! */ if (inb(iobase+AUDR) & AUDR_UNDR) { - DEBUG(0, __FUNCTION__ "(), Transmit underrun!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Transmit underrun!\n"); - idev->stats.tx_errors++; - idev->stats.tx_fifo_errors++; + self->stats.tx_errors++; + self->stats.tx_fifo_errors++; /* Clear bit, by writing 1 to it */ outb(AUDR_UNDR, iobase+AUDR); } else - idev->stats.tx_packets++; + self->stats.tx_packets++; /* Unlock tx_buff and request another frame */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->media_busy = FALSE; + self->netdev->tbusy = 0; /* Unlock */ /* Tell the network layer, that we want more frames */ mark_bh(NET_BH); @@ -681,15 +709,14 @@ void w83977af_dma_xmit_complete(struct irda_device *idev) } /* - * Function w83977af_dma_receive (idev) + * Function w83977af_dma_receive (self) * * Get ready for receiving a frame. The device will initiate a DMA * if it starts to receive a frame. * */ -int w83977af_dma_receive(struct irda_device *idev) +int w83977af_dma_receive(struct w83977af_ir *self) { - struct w83977af_ir *self; int iobase; __u8 set; #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS @@ -697,13 +724,11 @@ int w83977af_dma_receive(struct irda_device *idev) __u8 hcr; #endif - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; - iobase= idev->io.iobase; + iobase= self->io.iobase; /* Save current set */ set = inb(iobase+SSR); @@ -717,20 +742,20 @@ int w83977af_dma_receive(struct irda_device *idev) outb((inb(iobase+ADCR1) & ~ADCR1_D_CHSW)/*|ADCR1_DMA_F*/|ADCR1_ADV_SL, iobase+ADCR1); - idev->io.direction = IO_RECV; - idev->rx_buff.data = idev->rx_buff.head; + self->io.direction = IO_RECV; + self->rx_buff.data = self->rx_buff.head; #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS save_flags(flags); cli(); - disable_dma(idev->io.dma); - clear_dma_ff(idev->io.dma); - set_dma_mode(idev->io.dma, DMA_MODE_READ); - set_dma_addr(idev->io.dma, virt_to_bus(idev->rx_buff.data)); - set_dma_count(idev->io.dma, idev->rx_buff.truesize); + disable_dma(self->io.dma); + clear_dma_ff(self->io.dma); + set_dma_mode(self->io.dma, DMA_MODE_READ); + set_dma_addr(self->io.dma, virt_to_bus(self->rx_buff.data)); + set_dma_count(self->io.dma, self->rx_buff.truesize); #else - setup_dma(idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize, + setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, DMA_MODE_READ); #endif /* @@ -747,7 +772,7 @@ int w83977af_dma_receive(struct irda_device *idev) #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS hcr = inb(iobase+HCR); outb(hcr | HCR_EN_DMA, iobase+HCR); - enable_dma(idev->io.dma); + enable_dma(self->io.dma); restore_flags(flags); #else outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR); @@ -759,32 +784,30 @@ int w83977af_dma_receive(struct irda_device *idev) } /* - * Function w83977af_receive_complete (idev) + * Function w83977af_receive_complete (self) * * Finished with receiving a frame * */ -int w83977af_dma_receive_complete(struct irda_device *idev) +int w83977af_dma_receive_complete(struct w83977af_ir *self) { struct sk_buff *skb; - struct w83977af_ir *self; struct st_fifo *st_fifo; int len; int iobase; __u8 set; __u8 status; - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; st_fifo = &self->st_fifo; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current set */ set = inb(iobase+SSR); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Read status FIFO */ switch_bank(iobase, SET5); @@ -809,28 +832,28 @@ int w83977af_dma_receive_complete(struct irda_device *idev) if (status & FS_FO_ERR_MSK) { if (status & FS_FO_LST_FR) { /* Add number of lost frames to stats */ - idev->stats.rx_errors += len; + self->stats.rx_errors += len; } else { /* Skip frame */ - idev->stats.rx_errors++; + self->stats.rx_errors++; - idev->rx_buff.data += len; + self->rx_buff.data += len; if (status & FS_FO_MX_LEX) - idev->stats.rx_length_errors++; + self->stats.rx_length_errors++; if (status & FS_FO_PHY_ERR) - idev->stats.rx_frame_errors++; + self->stats.rx_frame_errors++; if (status & FS_FO_CRC_ERR) - idev->stats.rx_crc_errors++; + self->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FS_FO_RX_OV) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; if (status & FS_FO_FSF_OV) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; } else { /* Check if we have transfered all data to memory */ @@ -866,19 +889,19 @@ int w83977af_dma_receive_complete(struct irda_device *idev) skb_reserve(skb, 1); /* Copy frame without CRC */ - if (idev->io.baudrate < 4000000) { + if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, idev->rx_buff.data, len-2); + memcpy(skb->data, self->rx_buff.data, len-2); } else { skb_put(skb, len-4); - memcpy(skb->data, idev->rx_buff.data, len-4); + memcpy(skb->data, self->rx_buff.data, len-4); } /* Move to next frame */ - idev->rx_buff.data += len; - idev->stats.rx_packets++; + self->rx_buff.data += len; + self->stats.rx_packets++; - skb->dev = &idev->netdev; + skb->dev = self->netdev; skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); @@ -891,61 +914,60 @@ int w83977af_dma_receive_complete(struct irda_device *idev) } /* - * Function pc87108_pio_receive (idev) + * Function pc87108_pio_receive (self) * * Receive all data in receiver FIFO * */ -static void w83977af_pio_receive(struct irda_device *idev) +static void w83977af_pio_receive(struct w83977af_ir *self) { __u8 byte = 0x00; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RBR); - async_unwrap_char(idev, byte); + async_unwrap_char(self->netdev, &self->rx_buff, byte); } while (inb(iobase+USR) & USR_RDR); /* Data available */ } /* - * Function w83977af_sir_interrupt (idev, eir) + * Function w83977af_sir_interrupt (self, eir) * * Handle SIR interrupt * */ -static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) +static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) { int actual; __u8 new_icr = 0; __u8 set; int iobase; - DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr); + IRDA_DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Transmit FIFO low on data */ if (isr & ISR_TXTH_I) { /* Write data left in transmit buffer */ - actual = w83977af_pio_write(idev->io.iobase, - idev->tx_buff.data, - idev->tx_buff.len, - idev->io.fifo_size); + actual = w83977af_pio_write(self->io.iobase, + self->tx_buff.data, + self->tx_buff.len, + self->io.fifo_size); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Check if finished */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { new_icr |= ICR_ETXTHI; } else { set = inb(iobase+SSR); @@ -953,8 +975,8 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) outb(AUDR_SFEND, iobase+AUDR); outb(set, iobase+SSR); - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; /* Schedule network layer */ mark_bh(NET_BH); @@ -966,13 +988,13 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) if (isr & ISR_TXEMP_I) { /* Turn around and get ready to receive some data */ - idev->io.direction = IO_RECV; + self->io.direction = IO_RECV; new_icr |= ICR_ERBRI; } /* Rx FIFO threshold or timeout */ if (isr & ISR_RXTH_I) { - w83977af_pio_receive(idev); + w83977af_pio_receive(self); /* Keep receiving */ new_icr |= ICR_ERBRI; @@ -981,23 +1003,23 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) } /* - * Function pc87108_fir_interrupt (idev, eir) + * Function pc87108_fir_interrupt (self, eir) * * Handle MIR/FIR interrupt * */ -static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) +static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr) { __u8 new_icr = 0; __u8 set; int iobase; - iobase = idev->io.iobase; + iobase = self->io.iobase; set = inb(iobase+SSR); /* End of frame detected in FIFO */ if (isr & (ISR_FEND_I|ISR_FSF_I)) { - if (w83977af_dma_receive_complete(idev)) { + if (w83977af_dma_receive_complete(self)) { /* Wait for next status FIFO interrupt */ new_icr |= ICR_EFSFI; @@ -1026,29 +1048,29 @@ static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) /* outb(ASCR_CTE, iobase+ASCR); */ /* Check if this is a TX timer interrupt */ - if (idev->io.direction == IO_XMIT) { - w83977af_dma_write(idev, iobase); + if (self->io.direction == IO_XMIT) { + w83977af_dma_write(self, iobase); new_icr |= ICR_EDMAI; } else { /* Check if DMA has now finished */ - w83977af_dma_receive_complete(idev); + w83977af_dma_receive_complete(self); new_icr |= ICR_EFSFI; } } /* Finished with DMA */ if (isr & ISR_DMA_I) { - w83977af_dma_xmit_complete(idev); + w83977af_dma_xmit_complete(self); /* Check if there are more frames to be transmitted */ - /* if (irda_device_txqueue_empty(idev)) { */ + /* if (irda_device_txqueue_empty(self)) { */ /* Prepare for receive * * ** Netwinder Tx DMA likes that we do this anyway ** */ - w83977af_dma_receive(idev); + w83977af_dma_receive(self); new_icr = ICR_EFSFI; /* } */ } @@ -1067,20 +1089,21 @@ static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) */ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + struct net_device *dev = (struct net_device *) dev_id; + struct w83977af_ir *self; __u8 set, icr, isr; int iobase; - struct irda_device *idev = (struct irda_device *) dev_id; - - if (idev == NULL) { + if (!dev) { printk(KERN_WARNING "%s: irq %d for unknown device.\n", driver_name, irq); return; } + self = (struct w83977af_ir *) dev->priv; - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ set = inb(iobase+SSR); @@ -1093,47 +1116,34 @@ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (isr) { /* Dispatch interrupt handler for the current speed */ - if (idev->io.baudrate > PIO_MAX_SPEED ) - icr = w83977af_fir_interrupt(idev, isr); + if (self->io.speed > PIO_MAX_SPEED ) + icr = w83977af_fir_interrupt(self, isr); else - icr = w83977af_sir_interrupt(idev, isr); + icr = w83977af_sir_interrupt(self, isr); } outb(icr, iobase+ICR); /* Restore (new) interrupts */ outb(set, iobase+SSR); /* Restore bank register */ - idev->netdev.interrupt = 0; + self->netdev->interrupt = 0; } /* - * Function w83977af_wait_until_sent (idev) - * - * This function should put the current thread to sleep until all data - * have been sent, so it is safe to f.eks. change the speed. - */ -static void w83977af_wait_until_sent(struct irda_device *idev) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(60*HZ/1000); -} - -/* - * Function w83977af_is_receiving (idev) + * Function w83977af_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int w83977af_is_receiving(struct irda_device *idev) +static int w83977af_is_receiving(struct w83977af_ir *self) { int status = FALSE; int iobase; __u8 set; - ASSERT(idev != NULL, return FALSE;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); + ASSERT(self != NULL, return FALSE;); - if (idev->io.baudrate > 115200) { - iobase = idev->io.iobase; + if (self->io.speed > 115200) { + iobase = self->io.iobase; /* Check if rx FIFO is not empty */ set = inb(iobase+SSR); @@ -1144,7 +1154,7 @@ static int w83977af_is_receiving(struct irda_device *idev) } outb(set, iobase+SSR); } else - status = (idev->rx_buff.state != OUTSIDE_FRAME); + status = (self->rx_buff.state != OUTSIDE_FRAME); return status; } @@ -1157,7 +1167,7 @@ static int w83977af_is_receiving(struct irda_device *idev) */ static int w83977af_net_init(struct net_device *dev) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -1176,30 +1186,29 @@ static int w83977af_net_init(struct net_device *dev) */ static int w83977af_net_open(struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; int iobase; __u8 set; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - if (request_irq(idev->io.irq, w83977af_interrupt, 0, idev->name, - (void *) idev)) { + if (request_irq(self->io.irq, w83977af_interrupt, 0, dev->name, + (void *) dev)) { return -EAGAIN; } /* * Always allocate the DMA channel after the IRQ, * and clean up on failure. */ - if (request_dma(idev->io.dma, idev->name)) { - free_irq(idev->io.irq, idev); + if (request_dma(self->io.dma, dev->name)) { + free_irq(self->io.irq, self); return -EAGAIN; } @@ -1208,9 +1217,9 @@ static int w83977af_net_open(struct net_device *dev) /* Enable some interrupts so we can receive frames again */ switch_bank(iobase, SET0); - if (idev->io.baudrate > 115200) { + if (self->io.speed > 115200) { outb(ICR_EFSFI, iobase+ICR); - w83977af_dma_receive(idev); + w83977af_dma_receive(self); } else outb(ICR_ERBRI, iobase+ICR); @@ -1218,7 +1227,15 @@ static int w83977af_net_open(struct net_device *dev) outb(set, iobase+SSR); /* Ready to play! */ - irda_device_net_open(dev); + 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); MOD_INC_USE_COUNT; @@ -1233,25 +1250,30 @@ static int w83977af_net_open(struct net_device *dev) */ static int w83977af_net_close(struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; int iobase; __u8 set; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Stop device */ - irda_device_net_close(dev); + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; - disable_dma(idev->io.dma); + disable_dma(self->io.dma); /* Save current set */ set = inb(iobase+SSR); @@ -1260,8 +1282,8 @@ static int w83977af_net_close(struct net_device *dev) switch_bank(iobase, SET0); outb(0, iobase+ICR); - free_irq(idev->io.irq, idev); - free_dma(idev->io.dma); + free_irq(self->io.irq, self); + free_dma(self->io.dma); /* Restore bank register */ outb(set, iobase+SSR); |