diff options
Diffstat (limited to 'drivers/net/irda')
58 files changed, 8157 insertions, 6836 deletions
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 7c8ccc09b60..8d101d63abc 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -5,7 +5,7 @@ comment "SIR device drivers" config IRTTY_SIR tristate "IrTTY (uses Linux serial driver)" - depends on IRDA + depends on IRDA && TTY help Say Y here if you want to build support for the IrTTY line discipline. To compile it as a module, choose M here: the module @@ -17,6 +17,61 @@ config IRTTY_SIR If unsure, say Y. +config BFIN_SIR + tristate "Blackfin SIR on UART" + depends on BLACKFIN && IRDA + default n + help + Say Y here if your want to enable SIR function on Blackfin UART + devices. + + To activate this driver you can start irattach like: + "irattach irda0 -s" + + Saying M, it will be built as a module named bfin_sir. + + Note that you need to turn off one of the serial drivers for SIR + to use that UART. + +config BFIN_SIR0 + bool "Blackfin SIR on UART0" + depends on BFIN_SIR && !SERIAL_BFIN_UART0 + +config BFIN_SIR1 + bool "Blackfin SIR on UART1" + depends on BFIN_SIR && !SERIAL_BFIN_UART1 && (!BF531 && !BF532 && !BF533 && !BF561) + +config BFIN_SIR2 + bool "Blackfin SIR on UART2" + depends on BFIN_SIR && !SERIAL_BFIN_UART2 && (BF54x || BF538 || BF539) + +config BFIN_SIR3 + bool "Blackfin SIR on UART3" + depends on BFIN_SIR && !SERIAL_BFIN_UART3 && (BF54x) + +choice + prompt "SIR Mode" + depends on BFIN_SIR + default SIR_BFIN_DMA + +config SIR_BFIN_DMA + bool "DMA mode" + depends on !DMA_UNCACHED_NONE + +config SIR_BFIN_PIO + bool "PIO mode" +endchoice + +config SH_SIR + tristate "SuperH SIR on UART" + depends on IRDA && SUPERH && \ + (CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7723 || \ + CPU_SUBTYPE_SH7724) + default n + help + Say Y here if your want to enable SIR function on SuperH UART + devices. + comment "Dongle support" config DONGLE @@ -85,7 +140,7 @@ config LITELINK_DONGLE config MA600_DONGLE tristate "Mobile Action MA600 dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on IRTTY_SIR && DONGLE && IRDA help Say Y here if you want to build support for the Mobile Action MA600 dongle. To compile it as a module, choose M here. The MA600 dongle @@ -98,7 +153,7 @@ config MA600_DONGLE config GIRBIL_DONGLE tristate "Greenwich GIrBIL dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on IRTTY_SIR && DONGLE && IRDA help Say Y here if you want to build support for the Greenwich GIrBIL dongle. If you want to compile it as a module, choose M here. @@ -109,7 +164,7 @@ config GIRBIL_DONGLE config MCP2120_DONGLE tristate "Microchip MCP2120" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on IRTTY_SIR && DONGLE && IRDA help Say Y here if you want to build support for the Microchip MCP2120 dongle. If you want to compile it as a module, choose M here. @@ -123,16 +178,16 @@ config MCP2120_DONGLE config OLD_BELKIN_DONGLE tristate "Old Belkin dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on IRTTY_SIR && DONGLE && IRDA help Say Y here if you want to build support for the Adaptec Airport 1000 and 2000 dongles. If you want to compile it as a module, choose M here. Some information is contained in the comments - at the top of <file:drivers/net/irda/old_belkin.c>. + at the top of <file:drivers/net/irda/old_belkin-sir.c>. config ACT200L_DONGLE tristate "ACTiSYS IR-200L dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on IRTTY_SIR && DONGLE && IRDA help Say Y here if you want to build support for the ACTiSYS IR-200L dongle. If you want to compile it as a module, choose M here. @@ -141,146 +196,47 @@ config ACT200L_DONGLE To activate support for ACTiSYS IR-200L dongle you will have to start irattach like this: "irattach -d act200l". -comment "Old SIR device drivers" - -config IRPORT_SIR - tristate "IrPORT (IrDA serial driver)" - depends on IRDA && BROKEN_ON_SMP - ---help--- - Say Y here if you want to build support for the IrPORT IrDA device - driver. To compile it as a module, choose M here: the module will be - called irport. IrPORT can be used instead of IrTTY and sometimes - this can be better. One example is if your IrDA port does not - have echo-canceling, which will work OK with IrPORT since this - driver is working in half-duplex mode only. You don't need to use - irattach with IrPORT, but you just insert it the same way as FIR - drivers (insmod irport io=0x3e8 irq=11). Notice that IrPORT is a - SIR device driver which means that speed is limited to 115200 bps. - - If unsure, say Y. - -comment "Old Serial dongle support" - -config DONGLE_OLD - bool "Old Serial dongle support" - depends on IRPORT_SIR && BROKEN_ON_SMP - help - Say Y here if you have an infrared device that connects to your - computer's serial port. These devices are called dongles. Then say Y - or M to the driver for your particular dongle below. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about serial dongles. - -config ESI_DONGLE_OLD - tristate "ESI JetEye PC dongle" - depends on DONGLE_OLD && IRDA - help - Say Y here if you want to build support for the Extended Systems - JetEye PC dongle. To compile it as a module, choose M here. The ESI - dongle attaches to the normal 9-pin serial port connector, and can - currently only be used by IrTTY. To activate support for ESI - dongles you will have to start irattach like this: - "irattach -d esi". - -config ACTISYS_DONGLE_OLD - tristate "ACTiSYS IR-220L and IR220L+ dongle" - depends on DONGLE_OLD && IRDA - help - Say Y here if you want to build support for the ACTiSYS IR-220L and - IR220L+ dongles. To compile it as a module, choose M here. The - ACTiSYS dongles attaches to the normal 9-pin serial port connector, - and can currently only be used by IrTTY. To activate support for - ACTiSYS dongles you will have to start irattach like this: - "irattach -d actisys" or "irattach -d actisys+". - -config TEKRAM_DONGLE_OLD - tristate "Tekram IrMate 210B dongle" - depends on DONGLE_OLD && IRDA +config KINGSUN_DONGLE + tristate "KingSun/DonShine DS-620 IrDA-USB dongle" + depends on IRDA && USB help - Say Y here if you want to build support for the Tekram IrMate 210B - dongle. To compile it as a module, choose M here. The Tekram dongle - attaches to the normal 9-pin serial port connector, and can - currently only be used by IrTTY. To activate support for Tekram - dongles you will have to start irattach like this: - "irattach -d tekram". + Say Y or M here if you want to build support for the KingSun/DonShine + DS-620 IrDA-USB bridge device driver. -config GIRBIL_DONGLE_OLD - tristate "Greenwich GIrBIL dongle" - depends on DONGLE_OLD && IRDA - help - Say Y here if you want to build support for the Greenwich GIrBIL - dongle. To compile it as a module, choose M here. The Greenwich - dongle attaches to the normal 9-pin serial port connector, and can - currently only be used by IrTTY. To activate support for Greenwich - dongles you will have to insert "irattach -d girbil" in the - /etc/irda/drivers script. + This USB bridge does not conform to the IrDA-USB device class + specification, and therefore needs its own specific driver. This + dongle supports SIR speed only (9600 bps). -config LITELINK_DONGLE_OLD - tristate "Parallax LiteLink dongle" - depends on DONGLE_OLD && IRDA - help - Say Y here if you want to build support for the Parallax Litelink - dongle. To compile it as a module, choose M here. The Parallax - dongle attaches to the normal 9-pin serial port connector, and can - currently only be used by IrTTY. To activate support for Parallax - dongles you will have to start irattach like this: - "irattach -d litelink". + To compile it as a module, choose M here: the module will be called + kingsun-sir. -config MCP2120_DONGLE_OLD - tristate "Microchip MCP2120" - depends on DONGLE_OLD && IRDA +config KSDAZZLE_DONGLE + tristate "KingSun Dazzle IrDA-USB dongle" + depends on IRDA && USB help - Say Y here if you want to build support for the Microchip MCP2120 - dongle. To compile it as a module, choose M here. The MCP2120 dongle - attaches to the normal 9-pin serial port connector, and can - currently only be used by IrTTY. To activate support for MCP2120 - dongles you will have to insert "irattach -d mcp2120" in the - /etc/irda/drivers script. + Say Y or M here if you want to build support for the KingSun Dazzle + IrDA-USB bridge device driver. - You must build this dongle yourself. For more information see: - <http://www.eyetap.org/~tangf/irda_sir_linux.html> + This USB bridge does not conform to the IrDA-USB device class + specification, and therefore needs its own specific driver. This + dongle supports SIR speeds only (9600 through 115200 bps). -config OLD_BELKIN_DONGLE_OLD - tristate "Old Belkin dongle" - depends on DONGLE_OLD && IRDA - help - Say Y here if you want to build support for the Adaptec Airport 1000 - and 2000 dongles. To compile it as a module, choose M here: the module - will be called old_belkin. Some information is contained in the - comments at the top of <file:drivers/net/irda/old_belkin.c>. + To compile it as a module, choose M here: the module will be called + ksdazzle-sir. -config ACT200L_DONGLE_OLD - tristate "ACTiSYS IR-200L dongle (EXPERIMENTAL)" - depends on DONGLE_OLD && EXPERIMENTAL && IRDA +config KS959_DONGLE + tristate "KingSun KS-959 IrDA-USB dongle" + depends on IRDA && USB help - Say Y here if you want to build support for the ACTiSYS IR-200L - dongle. To compile it as a module, choose M here. The ACTiSYS - IR-200L dongle attaches to the normal 9-pin serial port connector, - and can currently only be used by IrTTY. To activate support for - ACTiSYS IR-200L dongles you will have to start irattach like this: - "irattach -d act200l". - -config MA600_DONGLE_OLD - tristate "Mobile Action MA600 dongle (EXPERIMENTAL)" - depends on DONGLE_OLD && EXPERIMENTAL && IRDA - ---help--- - Say Y here if you want to build support for the Mobile Action MA600 - dongle. To compile it as a module, choose M here. The MA600 dongle - attaches to the normal 9-pin serial port connector, and can - currently only be tested on IrCOMM. To activate support for MA600 - dongles you will have to insert "irattach -d ma600" in the - /etc/irda/drivers script. Note: irutils 0.9.15 requires no - modification. irutils 0.9.9 needs modification. For more - information, download the following tar gzip file. + Say Y or M here if you want to build support for the KingSun KS-959 + IrDA-USB bridge device driver. - There is a pre-compiled module on - <http://engsvr.ust.hk/~eetwl95/ma600.html> + This USB bridge does not conform to the IrDA-USB device class + specification, and therefore needs its own specific driver. This + dongle supports SIR speeds only (9600 through 57600 bps). -config EP7211_IR - tristate "EP7211 I/R support" - depends on DONGLE_OLD && ARCH_EP7211 && IRDA + To compile it as a module, choose M here: the module will be called + ks959-sir. comment "FIR device drivers" @@ -301,8 +257,8 @@ config USB_IRDA you will need both USB and IrDA support in your kernel... config SIGMATEL_FIR - tristate "SigmaTel STIr4200 bridge (EXPERIMENTAL)" - depends on IRDA && USB && EXPERIMENTAL + tristate "SigmaTel STIr4200 bridge" + depends on IRDA && USB select CRC32 ---help--- Say Y here if you want to build support for the SigmaTel STIr4200 @@ -341,7 +297,7 @@ config WINBOND_FIR config TOSHIBA_FIR tristate "Toshiba Type-O IR Port" - depends on IRDA && PCI && !64BIT + depends on IRDA && PCI && !64BIT && VIRT_TO_BUS help Say Y here if you want to build support for the Toshiba Type-O IR and Donau oboe chipsets. These chipsets are used by the Toshiba @@ -350,12 +306,16 @@ config TOSHIBA_FIR donauboe. config AU1000_FIR - tristate "Alchemy Au1000 SIR/FIR" - depends on SOC_AU1000 && IRDA + tristate "Alchemy IrDA SIR/FIR" + depends on IRDA && MIPS_ALCHEMY + help + Say Y/M here to build support the IrDA peripheral on the + Alchemy Au1000 and Au1100 SoCs. + Say M to build a module; it will be called au1k_ir.ko config SMC_IRCC_FIR - tristate "SMSC IrCC (EXPERIMENTAL)" - depends on EXPERIMENTAL && IRDA && ISA_DMA_API + tristate "SMSC IrCC" + depends on IRDA && ISA_DMA_API help Say Y here if you want to build support for the SMC Infrared Communications Controller. It is used in a wide variety of @@ -364,8 +324,8 @@ config SMC_IRCC_FIR smsc-ircc2.o. config ALI_FIR - tristate "ALi M5123 FIR (EXPERIMENTAL)" - depends on EXPERIMENTAL && IRDA && ISA_DMA_API + tristate "ALi M5123 FIR" + depends on IRDA && ISA_DMA_API help Say Y here if you want to build support for the ALi M5123 FIR Controller. The ALi M5123 FIR Controller is embedded in ALi M1543C, @@ -376,8 +336,8 @@ config ALI_FIR ali-ircc. config VLSI_FIR - tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)" - depends on EXPERIMENTAL && IRDA && PCI + tristate "VLSI 82C147 SIR/MIR/FIR" + depends on IRDA && PCI help Say Y here if you want to build support for the VLSI 82C147 PCI-IrDA Controller. This controller is used by the HP OmniBook 800 @@ -389,7 +349,7 @@ config VLSI_FIR config SA1100_FIR tristate "SA1100 Internal IR" - depends on ARCH_SA1100 && IRDA + depends on ARCH_SA1100 && IRDA && DMA_SA11X0 config VIA_FIR tristate "VIA VT8231/VT1211 SIR/MIR/FIR" @@ -420,7 +380,8 @@ config PXA_FICP config MCS_FIR tristate "MosChip MCS7780 IrDA-USB dongle" - depends on IRDA && USB && EXPERIMENTAL + depends on IRDA && USB + select CRC32 help Say Y or M here if you want to build support for the MosChip MCS7780 IrDA-USB bridge device driver. @@ -433,5 +394,12 @@ config MCS_FIR To compile it as a module, choose M here: the module will be called mcs7780. +config SH_IRDA + tristate "SuperH IrDA driver" + depends on IRDA + depends on ARCH_SHMOBILE || COMPILE_TEST + help + Say Y here if your want to enable SuperH IrDA devices. + endmenu diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 5be09f1b9ee..be8ab5b9a4a 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -# Old SIR drivers -obj-$(CONFIG_IRPORT_SIR) += irport.o # FIR drivers obj-$(CONFIG_USB_IRDA) += irda-usb.o obj-$(CONFIG_SIGMATEL_FIR) += stir4200.o @@ -20,21 +18,13 @@ obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o obj-$(CONFIG_VIA_FIR) += via-ircc.o obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o obj-$(CONFIG_MCS_FIR) += mcs7780.o -# Old dongle drivers for old SIR drivers -obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o -obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o -obj-$(CONFIG_ACTISYS_DONGLE_OLD) += actisys.o -obj-$(CONFIG_GIRBIL_DONGLE_OLD) += girbil.o -obj-$(CONFIG_LITELINK_DONGLE_OLD) += litelink.o -obj-$(CONFIG_OLD_BELKIN_DONGLE_OLD) += old_belkin.o -obj-$(CONFIG_MCP2120_DONGLE_OLD) += mcp2120.o -obj-$(CONFIG_ACT200L_DONGLE_OLD) += act200l.o -obj-$(CONFIG_MA600_DONGLE_OLD) += ma600.o -obj-$(CONFIG_EP7211_IR) += ep7211_ir.o obj-$(CONFIG_AU1000_FIR) += au1k_ir.o -# New SIR drivers +obj-$(CONFIG_SH_IRDA) += sh_irda.o +# SIR drivers obj-$(CONFIG_IRTTY_SIR) += irtty-sir.o sir-dev.o -# New dongles drivers for new SIR drivers +obj-$(CONFIG_BFIN_SIR) += bfin_sir.o +obj-$(CONFIG_SH_SIR) += sh_sir.o +# dongle drivers for SIR drivers obj-$(CONFIG_ESI_DONGLE) += esi-sir.o obj-$(CONFIG_TEKRAM_DONGLE) += tekram-sir.o obj-$(CONFIG_ACTISYS_DONGLE) += actisys-sir.o @@ -45,6 +35,9 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o +obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o +obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o +obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o # The SIR helper module sir-dev-objs := sir_dev.o sir_dongle.o diff --git a/drivers/net/irda/act200l-sir.c b/drivers/net/irda/act200l-sir.c index d8b89c74aab..8ff084f1d23 100644 --- a/drivers/net/irda/act200l-sir.c +++ b/drivers/net/irda/act200l-sir.c @@ -107,7 +107,7 @@ static int act200l_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s()\n", __func__ ); /* Power on the dongle */ sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -124,7 +124,7 @@ static int act200l_open(struct sir_dev *dev) static int act200l_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s()\n", __func__ ); /* Power off the dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -143,7 +143,7 @@ static int act200l_change_speed(struct sir_dev *dev, unsigned speed) u8 control[3]; int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s()\n", __func__ ); /* Clear DTR and set RTS to enter command mode */ sirdev_set_dtr_rts(dev, FALSE, TRUE); @@ -199,7 +199,7 @@ static int act200l_reset(struct sir_dev *dev) { unsigned state = dev->fsm.substate; unsigned delay = 0; - u8 control[9] = { + static const u8 control[9] = { ACT200L_REG15, ACT200L_REG13 | ACT200L_SHDW, ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, @@ -212,7 +212,7 @@ static int act200l_reset(struct sir_dev *dev) }; int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s()\n", __func__ ); switch (state) { case SIRDEV_STATE_DONGLE_RESET: @@ -240,7 +240,7 @@ static int act200l_reset(struct sir_dev *dev) dev->speed = 9600; break; default: - IRDA_ERROR("%s(), unknown state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s(), unknown state %d\n", __func__, state); ret = -1; break; } diff --git a/drivers/net/irda/act200l.c b/drivers/net/irda/act200l.c deleted file mode 100644 index 756cd44e857..00000000000 --- a/drivers/net/irda/act200l.c +++ /dev/null @@ -1,297 +0,0 @@ -/********************************************************************* - * - * Filename: act200l.c - * Version: 0.8 - * Description: Implementation for the ACTiSYS ACT-IR200L dongle - * Status: Experimental. - * Author: SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp> - * Created at: Fri Aug 3 17:35:42 2001 - * Modified at: Fri Aug 17 10:22:40 2001 - * Modified by: SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp> - * - * Copyright (c) 2001 SHIMIZU Takuya, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -static int act200l_reset(struct irda_task *task); -static void act200l_open(dongle_t *self, struct qos_info *qos); -static void act200l_close(dongle_t *self); -static int act200l_change_speed(struct irda_task *task); - -/* Regsiter 0: Control register #1 */ -#define ACT200L_REG0 0x00 -#define ACT200L_TXEN 0x01 /* Enable transmitter */ -#define ACT200L_RXEN 0x02 /* Enable receiver */ - -/* Register 1: Control register #2 */ -#define ACT200L_REG1 0x10 -#define ACT200L_LODB 0x01 /* Load new baud rate count value */ -#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */ - -/* Register 4: Output Power register */ -#define ACT200L_REG4 0x40 -#define ACT200L_OP0 0x01 /* Enable LED1C output */ -#define ACT200L_OP1 0x02 /* Enable LED2C output */ -#define ACT200L_BLKR 0x04 - -/* Register 5: Receive Mode register */ -#define ACT200L_REG5 0x50 -#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */ - -/* Register 6: Receive Sensitivity register #1 */ -#define ACT200L_REG6 0x60 -#define ACT200L_RS0 0x01 /* receive threshold bit 0 */ -#define ACT200L_RS1 0x02 /* receive threshold bit 1 */ - -/* Register 7: Receive Sensitivity register #2 */ -#define ACT200L_REG7 0x70 -#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */ - -/* Register 8,9: Baud Rate Dvider register #1,#2 */ -#define ACT200L_REG8 0x80 -#define ACT200L_REG9 0x90 - -#define ACT200L_2400 0x5f -#define ACT200L_9600 0x17 -#define ACT200L_19200 0x0b -#define ACT200L_38400 0x05 -#define ACT200L_57600 0x03 -#define ACT200L_115200 0x01 - -/* Register 13: Control register #3 */ -#define ACT200L_REG13 0xd0 -#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */ - -/* Register 15: Status register */ -#define ACT200L_REG15 0xf0 - -/* Register 21: Control register #4 */ -#define ACT200L_REG21 0x50 -#define ACT200L_EXCK 0x02 /* Disable clock output driver */ -#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */ - -static struct dongle_reg dongle = { - .type = IRDA_ACT200L_DONGLE, - .open = act200l_open, - .close = act200l_close, - .reset = act200l_reset, - .change_speed = act200l_change_speed, - .owner = THIS_MODULE, -}; - -static int __init act200l_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit act200l_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void act200l_open(dongle_t *self, struct qos_info *qos) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - /* Power on the dongle */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Set the speeds we can accept */ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits = 0x03; -} - -static void act200l_close(dongle_t *self) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - /* Power off the dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * Function act200l_change_speed (dev, speed) - * - * Set the speed for the ACTiSYS ACT-IR200L type dongle. - * - */ -static int act200l_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - __u8 control[3]; - int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - self->speed_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - if (irda_task_execute(self, act200l_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 IRDA_TASK_CHILD_WAIT: - IRDA_WARNING("%s(), resetting dongle timed out!\n", - __FUNCTION__); - ret = -1; - break; - case IRDA_TASK_CHILD_DONE: - /* Clear DTR and set RTS to enter command mode */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - - switch (speed) { - case 9600: - default: - control[0] = ACT200L_REG8 | (ACT200L_9600 & 0x0f); - control[1] = ACT200L_REG9 | ((ACT200L_9600 >> 4) & 0x0f); - break; - case 19200: - control[0] = ACT200L_REG8 | (ACT200L_19200 & 0x0f); - control[1] = ACT200L_REG9 | ((ACT200L_19200 >> 4) & 0x0f); - break; - case 38400: - control[0] = ACT200L_REG8 | (ACT200L_38400 & 0x0f); - control[1] = ACT200L_REG9 | ((ACT200L_38400 >> 4) & 0x0f); - break; - case 57600: - control[0] = ACT200L_REG8 | (ACT200L_57600 & 0x0f); - control[1] = ACT200L_REG9 | ((ACT200L_57600 >> 4) & 0x0f); - break; - case 115200: - control[0] = ACT200L_REG8 | (ACT200L_115200 & 0x0f); - control[1] = ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f); - break; - } - control[2] = ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE; - - /* Write control bytes */ - self->write(self->dev, control, 3); - irda_task_next_state(task, IRDA_TASK_WAIT); - ret = msecs_to_jiffies(5); - break; - 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->speed_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - ret = -1; - break; - } - return ret; -} - -/* - * Function act200l_reset (driver) - * - * Reset the ACTiSYS ACT-IR200L type dongle. - */ -static int act200l_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u8 control[9] = { - ACT200L_REG15, - ACT200L_REG13 | ACT200L_SHDW, - ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, - ACT200L_REG13, - ACT200L_REG7 | ACT200L_ENPOS, - ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1, - ACT200L_REG5 | ACT200L_RWIDL, - ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR, - ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN - }; - int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - self->reset_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - /* Power on the dongle */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - irda_task_next_state(task, IRDA_TASK_WAIT1); - ret = msecs_to_jiffies(50); - break; - case IRDA_TASK_WAIT1: - /* Reset the dongle : set RTS low for 25 ms */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - - irda_task_next_state(task, IRDA_TASK_WAIT2); - ret = msecs_to_jiffies(50); - break; - case IRDA_TASK_WAIT2: - /* Clear DTR and set RTS to enter command mode */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - - /* Write control bytes */ - self->write(self->dev, control, 9); - irda_task_next_state(task, IRDA_TASK_WAIT3); - ret = msecs_to_jiffies(15); - 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); - self->reset_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - break; - } - return ret; -} - -MODULE_AUTHOR("SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>"); -MODULE_DESCRIPTION("ACTiSYS ACT-IR200L dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-10"); /* IRDA_ACT200L_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize ACTiSYS ACT-IR200L module - * - */ -module_init(act200l_init); - -/* - * Function cleanup_module (void) - * - * Cleanup ACTiSYS ACT-IR200L module - * - */ -module_exit(act200l_cleanup); diff --git a/drivers/net/irda/actisys-sir.c b/drivers/net/irda/actisys-sir.c index 9715ab5572e..50b2141a610 100644 --- a/drivers/net/irda/actisys-sir.c +++ b/drivers/net/irda/actisys-sir.c @@ -21,7 +21,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -67,7 +67,7 @@ static int actisys_reset(struct sir_dev *); /* Note : the 220L doesn't support 38400, but we will fix that below */ static unsigned baud_rates[] = { 9600, 19200, 57600, 115200, 38400 }; -#define MAX_SPEEDS (sizeof(baud_rates)/sizeof(baud_rates[0])) +#define MAX_SPEEDS ARRAY_SIZE(baud_rates) static struct dongle_driver act220l = { .owner = THIS_MODULE, @@ -165,7 +165,7 @@ static int actisys_change_speed(struct sir_dev *dev, unsigned speed) int ret = 0; int i = 0; - IRDA_DEBUG(4, "%s(), speed=%d (was %d)\n", __FUNCTION__, + IRDA_DEBUG(4, "%s(), speed=%d (was %d)\n", __func__, speed, dev->speed); /* dongle was already resetted from irda_request state machine, diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c deleted file mode 100644 index b2e31f4a384..00000000000 --- a/drivers/net/irda/actisys.c +++ /dev/null @@ -1,288 +0,0 @@ -/********************************************************************* - * - * Filename: actisys.c - * Version: 1.0 - * Description: Implementation for the ACTiSYS IR-220L and IR-220L+ - * dongles - * Status: Beta. - * Authors: Dag Brattli <dagb@cs.uit.no> (initially) - * Jean Tourrilhes <jt@hpl.hp.com> (new version) - * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Fri Dec 17 09:10:43 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. - * Copyright (c) 1999 Jean Tourrilhes - * - * 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -/* - * Changelog - * - * 0.8 -> 0.9999 - Jean - * o New initialisation procedure : much safer and correct - * o New procedure the change speed : much faster and simpler - * o Other cleanups & comments - * Thanks to Lichen Wang @ Actisys for his excellent help... - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -/* - * Define the timing of the pulses we send to the dongle (to reset it, and - * to toggle speeds). Basically, the limit here is the propagation speed of - * the signals through the serial port, the dongle being much faster. Any - * serial port support 115 kb/s, so we are sure that pulses 8.5 us wide can - * go through cleanly . If you are on the wild side, you can try to lower - * this value (Actisys recommended me 2 us, and 0 us work for me on a P233!) - */ -#define MIN_DELAY 10 /* 10 us to be on the conservative side */ - -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, in the order available */ -/* Note : the 220L doesn't support 38400, but we will fix that below */ -static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 }; -#define MAX_SPEEDS 5 - -static struct dongle_reg dongle = { - .type = IRDA_ACTISYS_DONGLE, - .open = actisys_open, - .close = actisys_close, - .reset = actisys_reset, - .change_speed = actisys_change_speed, - .owner = THIS_MODULE, -}; - -static struct dongle_reg dongle_plus = { - .type = IRDA_ACTISYS_PLUS_DONGLE, - .open = actisys_open, - .close = actisys_close, - .reset = actisys_reset, - .change_speed = actisys_change_speed, - .owner = THIS_MODULE, -}; - -/* - * Function actisys_change_speed (task) - * - * There is two model of Actisys dongle we are dealing with, - * the 220L and 220L+. At this point, only irattach knows with - * kind the user has requested (it was an argument on irattach - * command line). - * So, we register a dongle of each sort and let irattach - * pick the right one... - */ -static int __init actisys_init(void) -{ - int ret; - - /* First, register an Actisys 220L dongle */ - ret = irda_device_register_dongle(&dongle); - if (ret < 0) - return ret; - /* Now, register an Actisys 220L+ dongle */ - ret = irda_device_register_dongle(&dongle_plus); - if (ret < 0) { - irda_device_unregister_dongle(&dongle); - return ret; - } - return 0; -} - -static void __exit actisys_cleanup(void) -{ - /* We have to remove both dongles */ - irda_device_unregister_dongle(&dongle); - irda_device_unregister_dongle(&dongle_plus); -} - -static void actisys_open(dongle_t *self, struct qos_info *qos) -{ - /* Power on the dongle */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Set the speeds we can accept */ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - - /* 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 = 0x7f; /* Needs 0.01 ms */ -} - -static void actisys_close(dongle_t *self) -{ - /* Power off the dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * Function actisys_change_speed (task) - * - * Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles. - * To cycle through the available baud rates, pulse RTS low for a few us. - * - * First, we reset the dongle to always start from a known state. - * Then, we cycle through the speeds by pulsing RTS low and then up. - * The dongle allow us to pulse quite fast, se we can set speed in one go, - * which is must faster ( < 100 us) and less complex than what is found - * in some other dongle drivers... - * Note that even if the new speed is the same as the current speed, - * we reassert the speed. This make sure that things are all right, - * and it's fast anyway... - * By the way, this function will work for both type of dongles, - * because the additional speed is at the end of the sequence... - */ -static int actisys_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; /* Target speed */ - int ret = 0; - int i = 0; - - IRDA_DEBUG(4, "%s(), speed=%d (was %d)\n", __FUNCTION__, speed, - self->speed); - - /* Go to a known state by reseting the dongle */ - - /* Reset the dongle : set DTR low for 10 us */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - udelay(MIN_DELAY); - - /* Go back to normal mode (we are now at 9600 b/s) */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* - * Now, we can set the speed requested. Send RTS pulses until we - * reach the target speed - */ - for (i=0; i<MAX_SPEEDS; i++) { - if (speed == baud_rates[i]) { - self->speed = baud_rates[i]; - break; - } - /* Make sure previous pulse is finished */ - udelay(MIN_DELAY); - - /* Set RTS low for 10 us */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - udelay(MIN_DELAY); - - /* Set RTS high for 10 us */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - } - - /* Check if life is sweet... */ - if (i >= MAX_SPEEDS) - ret = -1; /* This should not happen */ - - /* Basta lavoro, on se casse d'ici... */ - irda_task_next_state(task, IRDA_TASK_DONE); - - return ret; -} - -/* - * Function actisys_reset (task) - * - * Reset the Actisys type dongle. Warning, this function must only be - * called with a process context! - * - * We need to do two things in this function : - * o first make sure that the dongle is in a state where it can operate - * o second put the dongle in a know state - * - * The dongle is powered of the RTS and DTR lines. In the dongle, there - * is a big capacitor to accommodate the current spikes. This capacitor - * takes a least 50 ms to be charged. In theory, the Bios set those lines - * up, so by the time we arrive here we should be set. It doesn't hurt - * to be on the conservative side, so we will wait... - * Then, we set the speed to 9600 b/s to get in a known state (see in - * change_speed for details). It is needed because the IrDA stack - * has tried to set the speed immediately after our first return, - * so before we can be sure the dongle is up and running. - */ -static int actisys_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - int ret = 0; - - IRDA_ASSERT(task != NULL, return -1;); - - self->reset_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - /* Set both DTR & RTS to power up the dongle */ - /* In theory redundant with power up in actisys_open() */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Sleep 50 ms to make sure capacitor is charged */ - ret = msecs_to_jiffies(50); - irda_task_next_state(task, IRDA_TASK_WAIT); - break; - case IRDA_TASK_WAIT: - /* Reset the dongle : set DTR low for 10 us */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - udelay(MIN_DELAY); - - /* Go back to normal mode */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - self->speed = 9600; /* That's the default */ - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - break; - } - return ret; -} - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> - Jean Tourrilhes <jt@hpl.hp.com>"); -MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-2"); /* IRDA_ACTISYS_DONGLE */ -MODULE_ALIAS("irda-dongle-3"); /* IRDA_ACTISYS_PLUS_DONGLE */ - - -/* - * Function init_module (void) - * - * Initialize Actisys module - * - */ -module_init(actisys_init); - -/* - * Function cleanup_module (void) - * - * Cleanup Actisys module - * - */ -module_exit(actisys_cleanup); diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index cebf8c374bc..befa45f809c 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -22,6 +22,7 @@ ********************************************************************/ #include <linux/module.h> +#include <linux/gfp.h> #include <linux/kernel.h> #include <linux/types.h> @@ -29,8 +30,8 @@ #include <linux/netdevice.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/rtnetlink.h> #include <linux/serial_reg.h> #include <linux/dma-mapping.h> @@ -60,6 +61,7 @@ static struct platform_driver ali_ircc_driver = { .resume = ali_ircc_resume, .driver = { .name = ALI_IRCC_DRIVER_NAME, + .owner = THIS_MODULE, }, }; @@ -75,7 +77,7 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info); static int ali_ircc_init_43(ali_chip_t *chip, chipio_t *info); static int ali_ircc_init_53(ali_chip_t *chip, chipio_t *info); -/* These are the currently known ALi sourth-bridge chipsets, the only one difference +/* These are the currently known ALi south-bridge chipsets, the only one difference * is that M1543C doesn't support HP HDSL-3600 */ static ali_chip_t chips[] = @@ -108,10 +110,10 @@ static int ali_ircc_net_open(struct net_device *dev); static int ali_ircc_net_close(struct net_device *dev); static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud); -static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev); /* SIR function */ -static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t ali_ircc_sir_hard_xmit(struct sk_buff *skb, + struct net_device *dev); static irqreturn_t ali_ircc_sir_interrupt(struct ali_ircc_cb *self); static void ali_ircc_sir_receive(struct ali_ircc_cb *self); static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self); @@ -119,7 +121,8 @@ static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len); static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed); /* FIR function */ -static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t ali_ircc_fir_hard_xmit(struct sk_buff *skb, + struct net_device *dev); static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 speed); static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self); static int ali_ircc_dma_receive(struct ali_ircc_cb *self); @@ -140,7 +143,7 @@ static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable); * Function ali_ircc_init () * * Initialize chip. Find out whay kinds of chips we are dealing with - * and their configuation registers address + * and their configuration registers address */ static int __init ali_ircc_init(void) { @@ -151,7 +154,7 @@ static int __init ali_ircc_init(void) int reg, revision; int i = 0; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); ret = platform_driver_register(&ali_ircc_driver); if (ret) { @@ -165,7 +168,7 @@ static int __init ali_ircc_init(void) /* Probe for all the ALi chipsets we know about */ for (chip= chips; chip->name; chip++, i++) { - IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, chip->name); + IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __func__, chip->name); /* Try all config registers for this chip */ for (cfg=0; cfg<2; cfg++) @@ -195,11 +198,11 @@ static int __init ali_ircc_init(void) if (reg == chip->cid_value) { - IRDA_DEBUG(2, "%s(), Chip found at 0x%03x\n", __FUNCTION__, cfg_base); + IRDA_DEBUG(2, "%s(), Chip found at 0x%03x\n", __func__, cfg_base); outb(0x1F, cfg_base); revision = inb(cfg_base+1); - IRDA_DEBUG(2, "%s(), Found %s chip, revision=%d\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), Found %s chip, revision=%d\n", __func__, chip->name, revision); /* @@ -222,14 +225,14 @@ static int __init ali_ircc_init(void) } else { - IRDA_DEBUG(2, "%s(), No %s chip at 0x%03x\n", __FUNCTION__, chip->name, cfg_base); + IRDA_DEBUG(2, "%s(), No %s chip at 0x%03x\n", __func__, chip->name, cfg_base); } /* Exit configuration */ outb(0xbb, cfg_base); } } - IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__); if (ret) platform_driver_unregister(&ali_ircc_driver); @@ -247,7 +250,7 @@ static void __exit ali_ircc_cleanup(void) { int i; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); for (i=0; i < ARRAY_SIZE(dev_self); i++) { if (dev_self[i]) @@ -256,9 +259,23 @@ static void __exit ali_ircc_cleanup(void) platform_driver_unregister(&ali_ircc_driver); - IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__); } +static const struct net_device_ops ali_ircc_sir_ops = { + .ndo_open = ali_ircc_net_open, + .ndo_stop = ali_ircc_net_close, + .ndo_start_xmit = ali_ircc_sir_hard_xmit, + .ndo_do_ioctl = ali_ircc_net_ioctl, +}; + +static const struct net_device_ops ali_ircc_fir_ops = { + .ndo_open = ali_ircc_net_open, + .ndo_stop = ali_ircc_net_close, + .ndo_start_xmit = ali_ircc_fir_hard_xmit, + .ndo_do_ioctl = ali_ircc_net_ioctl, +}; + /* * Function ali_ircc_open (int i, chipio_t *inf) * @@ -272,11 +289,11 @@ static int ali_ircc_open(int i, chipio_t *info) int dongle_id; int err; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); if (i >= ARRAY_SIZE(dev_self)) { IRDA_ERROR("%s(), maximum number of supported chips reached!\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -287,11 +304,11 @@ static int ali_ircc_open(int i, chipio_t *info) dev = alloc_irdadev(sizeof(*self)); if (dev == NULL) { IRDA_ERROR("%s(), can't allocate memory for control block!\n", - __FUNCTION__); + __func__); return -ENOMEM; } - self = dev->priv; + self = netdev_priv(dev); self->netdev = dev; spin_lock_init(&self->lock); @@ -311,7 +328,7 @@ static int ali_ircc_open(int i, chipio_t *info) /* Reserve the ioports that we need */ if (!request_region(self->io.fir_base, self->io.fir_ext, ALI_IRCC_DRIVER_NAME)) { - IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__, + IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", __func__, self->io.fir_base); err = -ENODEV; goto err_out1; @@ -334,22 +351,20 @@ static int ali_ircc_open(int i, chipio_t *info) /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; @@ -360,32 +375,24 @@ static int ali_ircc_open(int i, chipio_t *info) self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; - - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - /* Override the network functions we need to use */ - dev->hard_start_xmit = ali_ircc_sir_hard_xmit; - dev->open = ali_ircc_net_open; - dev->stop = ali_ircc_net_close; - dev->do_ioctl = ali_ircc_net_ioctl; - dev->get_stats = ali_ircc_net_get_stats; + dev->netdev_ops = &ali_ircc_sir_ops; err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__); + IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); goto err_out4; } IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); /* Check dongle id */ dongle_id = ali_ircc_read_dongle_id(i, info); - IRDA_MESSAGE("%s(), %s, Found dongle: %s\n", __FUNCTION__, + IRDA_MESSAGE("%s(), %s, Found dongle: %s\n", __func__, ALI_IRCC_DRIVER_NAME, dongle_types[dongle_id]); self->io.dongle_id = dongle_id; - IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__); return 0; @@ -414,7 +421,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self) { int iobase; - IRDA_DEBUG(4, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(4, "%s(), ---------------- Start ----------------\n", __func__); IRDA_ASSERT(self != NULL, return -1;); @@ -424,7 +431,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self) unregister_netdev(self->netdev); /* Release the PORT that this driver is using */ - IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", __FUNCTION__, self->io.fir_base); + IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) @@ -438,7 +445,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self) dev_self[self->index] = NULL; free_netdev(self->netdev); - IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__); return 0; } @@ -481,7 +488,7 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info) int cfg_base = info->cfg_base; int hi, low, reg; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); /* Enter Configuration */ outb(chip->entr1, cfg_base); @@ -500,13 +507,13 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info) info->sir_base = info->fir_base; - IRDA_DEBUG(2, "%s(), probing fir_base=0x%03x\n", __FUNCTION__, info->fir_base); + IRDA_DEBUG(2, "%s(), probing fir_base=0x%03x\n", __func__, info->fir_base); /* Read IRQ control register */ outb(0x70, cfg_base); reg = inb(cfg_base+1); info->irq = reg & 0x0f; - IRDA_DEBUG(2, "%s(), probing irq=%d\n", __FUNCTION__, info->irq); + IRDA_DEBUG(2, "%s(), probing irq=%d\n", __func__, info->irq); /* Read DMA channel */ outb(0x74, cfg_base); @@ -514,26 +521,26 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info) info->dma = reg & 0x07; if(info->dma == 0x04) - IRDA_WARNING("%s(), No DMA channel assigned !\n", __FUNCTION__); + IRDA_WARNING("%s(), No DMA channel assigned !\n", __func__); else - IRDA_DEBUG(2, "%s(), probing dma=%d\n", __FUNCTION__, info->dma); + IRDA_DEBUG(2, "%s(), probing dma=%d\n", __func__, info->dma); /* Read Enabled Status */ outb(0x30, cfg_base); reg = inb(cfg_base+1); info->enabled = (reg & 0x80) && (reg & 0x01); - IRDA_DEBUG(2, "%s(), probing enabled=%d\n", __FUNCTION__, info->enabled); + IRDA_DEBUG(2, "%s(), probing enabled=%d\n", __func__, info->enabled); /* Read Power Status */ outb(0x22, cfg_base); reg = inb(cfg_base+1); info->suspended = (reg & 0x20); - IRDA_DEBUG(2, "%s(), probing suspended=%d\n", __FUNCTION__, info->suspended); + IRDA_DEBUG(2, "%s(), probing suspended=%d\n", __func__, info->suspended); /* Exit configuration */ outb(0xbb, cfg_base); - IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__); return 0; } @@ -551,7 +558,7 @@ static int ali_ircc_setup(chipio_t *info) int version; int iobase = info->fir_base; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); /* Locking comments : * Most operations here need to be protected. We are called before @@ -612,7 +619,7 @@ static int ali_ircc_setup(chipio_t *info) // outb(UART_IER_RDI, iobase+UART_IER); //benjamin 2000/11/23 01:25PM // Turn on the interrupts in ali_ircc_net_open - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__); return 0; } @@ -620,7 +627,7 @@ static int ali_ircc_setup(chipio_t *info) /* * Function ali_ircc_read_dongle_id (int index, info) * - * Try to read dongle indentification. This procedure needs to be executed + * Try to read dongle identification. This procedure needs to be executed * once after power-on/reset. It also needs to be used whenever you suspect * that the user may have plugged/unplugged the IrDA Dongle. */ @@ -629,7 +636,7 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info) int dongle_id, reg; int cfg_base = info->cfg_base; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); /* Enter Configuration */ outb(chips[i].entr1, cfg_base); @@ -643,13 +650,13 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info) outb(0xf0, cfg_base); reg = inb(cfg_base+1); dongle_id = ((reg>>6)&0x02) | ((reg>>5)&0x01); - IRDA_DEBUG(2, "%s(), probing dongle_id=%d, dongle_types=%s\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), probing dongle_id=%d, dongle_types=%s\n", __func__, dongle_id, dongle_types[dongle_id]); /* Exit configuration */ outb(0xbb, cfg_base); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__); return dongle_id; } @@ -666,9 +673,9 @@ static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id) struct ali_ircc_cb *self; int ret; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); - self = dev->priv; + self = netdev_priv(dev); spin_lock(&self->lock); @@ -680,7 +687,7 @@ static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id) spin_unlock(&self->lock); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__); return ret; } /* @@ -694,7 +701,7 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) __u8 eir, OldMessageCount; int iobase, tmp; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__); iobase = self->io.fir_base; @@ -707,10 +714,10 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) //self->ier = inb(iobase+FIR_IER); 2000/12/1 04:32PM eir = self->InterruptID & self->ier; /* Mask out the interesting ones */ - IRDA_DEBUG(1, "%s(), self->InterruptID = %x\n", __FUNCTION__,self->InterruptID); - IRDA_DEBUG(1, "%s(), self->LineStatus = %x\n", __FUNCTION__,self->LineStatus); - IRDA_DEBUG(1, "%s(), self->ier = %x\n", __FUNCTION__,self->ier); - IRDA_DEBUG(1, "%s(), eir = %x\n", __FUNCTION__,eir); + IRDA_DEBUG(1, "%s(), self->InterruptID = %x\n", __func__,self->InterruptID); + IRDA_DEBUG(1, "%s(), self->LineStatus = %x\n", __func__,self->LineStatus); + IRDA_DEBUG(1, "%s(), self->ier = %x\n", __func__,self->ier); + IRDA_DEBUG(1, "%s(), eir = %x\n", __func__,eir); /* Disable interrupts */ SetCOMInterrupts(self, FALSE); @@ -721,7 +728,7 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) { if (self->io.direction == IO_XMIT) /* TX */ { - IRDA_DEBUG(1, "%s(), ******* IIR_EOM (Tx) *******\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* IIR_EOM (Tx) *******\n", __func__); if(ali_ircc_dma_xmit_complete(self)) { @@ -740,23 +747,23 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) } else /* RX */ { - IRDA_DEBUG(1, "%s(), ******* IIR_EOM (Rx) *******\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* IIR_EOM (Rx) *******\n", __func__); if(OldMessageCount > ((self->LineStatus+1) & 0x07)) { self->rcvFramesOverflow = TRUE; - IRDA_DEBUG(1, "%s(), ******* self->rcvFramesOverflow = TRUE ******** \n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* self->rcvFramesOverflow = TRUE ********\n", __func__); } if (ali_ircc_dma_receive_complete(self)) { - IRDA_DEBUG(1, "%s(), ******* receive complete ******** \n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* receive complete ********\n", __func__); self->ier = IER_EOM; } else { - IRDA_DEBUG(1, "%s(), ******* Not receive complete ******** \n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* Not receive complete ********\n", __func__); self->ier = IER_EOM | IER_TIMER; } @@ -769,7 +776,7 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) if(OldMessageCount > ((self->LineStatus+1) & 0x07)) { self->rcvFramesOverflow = TRUE; - IRDA_DEBUG(1, "%s(), ******* self->rcvFramesOverflow = TRUE ******* \n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ******* self->rcvFramesOverflow = TRUE *******\n", __func__); } /* Disable Timer */ switch_bank(iobase, BANK1); @@ -801,7 +808,7 @@ static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self) /* Restore Interrupt */ SetCOMInterrupts(self, TRUE); - IRDA_DEBUG(1, "%s(), ----------------- End ---------------\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), ----------------- End ---------------\n", __func__); return IRQ_RETVAL(eir); } @@ -816,7 +823,7 @@ static irqreturn_t ali_ircc_sir_interrupt(struct ali_ircc_cb *self) int iobase; int iir, lsr; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); iobase = self->io.sir_base; @@ -825,13 +832,13 @@ static irqreturn_t ali_ircc_sir_interrupt(struct ali_ircc_cb *self) /* Clear interrupt */ lsr = inb(iobase+UART_LSR); - IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", __FUNCTION__, + IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", __func__, iir, lsr, iobase); switch (iir) { case UART_IIR_RLSI: - IRDA_DEBUG(2, "%s(), RLSI\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), RLSI\n", __func__); break; case UART_IIR_RDI: /* Receive interrupt */ @@ -845,14 +852,14 @@ static irqreturn_t ali_ircc_sir_interrupt(struct ali_ircc_cb *self) } break; default: - IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", __FUNCTION__, iir); + IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", __func__, iir); break; } } - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__); return IRQ_RETVAL(iir); } @@ -869,7 +876,7 @@ static void ali_ircc_sir_receive(struct ali_ircc_cb *self) int boguscount = 0; int iobase; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); IRDA_ASSERT(self != NULL, return;); iobase = self->io.sir_base; @@ -879,17 +886,17 @@ static void ali_ircc_sir_receive(struct ali_ircc_cb *self) * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, inb(iobase+UART_RX)); /* Make sure we don't stay here too long */ if (boguscount++ > 32) { - IRDA_DEBUG(2,"%s(), breaking!\n", __FUNCTION__); + IRDA_DEBUG(2,"%s(), breaking!\n", __func__); break; } } while (inb(iobase+UART_LSR) & UART_LSR_DR); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); } /* @@ -906,7 +913,7 @@ static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self) IRDA_ASSERT(self != NULL, return;); - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); iobase = self->io.sir_base; @@ -925,16 +932,16 @@ static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self) { /* We must wait until all data are gone */ while(!(inb(iobase+UART_LSR) & UART_LSR_TEMT)) - IRDA_DEBUG(1, "%s(), UART_LSR_THRE\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), UART_LSR_THRE\n", __func__ ); - IRDA_DEBUG(1, "%s(), Changing speed! self->new_speed = %d\n", __FUNCTION__ , self->new_speed); + IRDA_DEBUG(1, "%s(), Changing speed! self->new_speed = %d\n", __func__ , self->new_speed); ali_ircc_change_speed(self, self->new_speed); self->new_speed = 0; // benjamin 2000/11/10 06:32PM if (self->io.speed > 115200) { - IRDA_DEBUG(2, "%s(), ali_ircc_change_speed from UART_LSR_TEMT \n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ali_ircc_change_speed from UART_LSR_TEMT\n", __func__ ); self->ier = IER_EOM; // SetCOMInterrupts(self, TRUE); @@ -946,13 +953,13 @@ static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self) netif_wake_queue(self->netdev); } - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; /* Turn on receive interrupts */ outb(UART_IER_RDI, iobase+UART_IER); } - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); } static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud) @@ -960,9 +967,9 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud) struct net_device *dev = self->netdev; int iobase; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); - IRDA_DEBUG(2, "%s(), setting speed = %d \n", __FUNCTION__ , baud); + IRDA_DEBUG(2, "%s(), setting speed = %d\n", __func__ , baud); /* This function *must* be called with irq off and spin-lock. * - Jean II */ @@ -979,12 +986,12 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud) ali_ircc_fir_change_speed(self, baud); /* Install FIR xmit handler*/ - dev->hard_start_xmit = ali_ircc_fir_hard_xmit; + dev->netdev_ops = &ali_ircc_fir_ops; /* Enable Interuupt */ self->ier = IER_EOM; // benjamin 2000/11/20 07:24PM - /* Be ready for incomming frames */ + /* Be ready for incoming frames */ ali_ircc_dma_receive(self); // benajmin 2000/11/8 07:46PM not complete } /* Go to SIR Speed */ @@ -993,7 +1000,7 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud) ali_ircc_sir_change_speed(self, baud); /* Install SIR xmit handler*/ - dev->hard_start_xmit = ali_ircc_sir_hard_xmit; + dev->netdev_ops = &ali_ircc_sir_ops; } @@ -1001,24 +1008,24 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud) netif_wake_queue(self->netdev); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); } static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) { int iobase; - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; struct net_device *dev; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); IRDA_ASSERT(self != NULL, return;); dev = self->netdev; iobase = self->io.fir_base; - IRDA_DEBUG(1, "%s(), self->io.speed = %d, change to speed = %d\n", __FUNCTION__ ,self->io.speed,baud); + IRDA_DEBUG(1, "%s(), self->io.speed = %d, change to speed = %d\n", __func__ ,self->io.speed,baud); /* Come from SIR speed */ if(self->io.speed <=115200) @@ -1032,7 +1039,7 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) // Set Dongle Speed mode ali_ircc_change_dongle_speed(self, baud); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } /* @@ -1043,16 +1050,16 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) */ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) { - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; unsigned long flags; int iobase; int fcr; /* FIFO control reg */ int lcr; /* Line control reg */ int divisor; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); - IRDA_DEBUG(1, "%s(), Setting speed to: %d\n", __FUNCTION__ , speed); + IRDA_DEBUG(1, "%s(), Setting speed to: %d\n", __func__ , speed); IRDA_ASSERT(self != NULL, return;); @@ -1100,30 +1107,30 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) outb(lcr, iobase+UART_LCR); /* Set 8N1 */ outb(fcr, iobase+UART_FCR); /* Enable FIFO's */ - /* without this, the conection will be broken after come back from FIR speed, + /* without this, the connection will be broken after come back from FIR speed, but with this, the SIR connection is harder to established */ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR); spin_unlock_irqrestore(&self->lock, flags); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed) { - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; int iobase,dongle_id; int tmp = 0; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); iobase = self->io.fir_base; /* or iobase = self->io.sir_base; */ dongle_id = self->io.dongle_id; /* We are already locked, no need to do it again */ - IRDA_DEBUG(1, "%s(), Set Speed for %s , Speed = %d\n", __FUNCTION__ , dongle_types[dongle_id], speed); + IRDA_DEBUG(1, "%s(), Set Speed for %s , Speed = %d\n", __func__ , dongle_types[dongle_id], speed); switch_bank(iobase, BANK2); tmp = inb(iobase+FIR_IRDA_CR); @@ -1287,7 +1294,7 @@ static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed) switch_bank(iobase, BANK0); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } /* @@ -1300,11 +1307,11 @@ static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) { int actual = 0; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); /* Tx FIFO should be empty! */ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - IRDA_DEBUG(0, "%s(), failed, fifo not empty!\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), failed, fifo not empty!\n", __func__ ); return 0; } @@ -1316,7 +1323,7 @@ static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) actual++; } - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); return actual; } @@ -1332,11 +1339,11 @@ static int ali_ircc_net_open(struct net_device *dev) int iobase; char hwname[32]; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct ali_ircc_cb *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); @@ -1359,7 +1366,7 @@ static int ali_ircc_net_open(struct net_device *dev) IRDA_WARNING("%s, unable to allocate dma=%d\n", ALI_IRCC_DRIVER_NAME, self->io.dma); - free_irq(self->io.irq, self); + free_irq(self->io.irq, dev); return -EAGAIN; } @@ -1378,7 +1385,7 @@ static int ali_ircc_net_open(struct net_device *dev) */ self->irlap = irlap_open(dev, &self->qos, hwname); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); return 0; } @@ -1395,11 +1402,11 @@ static int ali_ircc_net_close(struct net_device *dev) struct ali_ircc_cb *self; //int iobase; - IRDA_DEBUG(4, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s(), ---------------- Start ----------------\n", __func__ ); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct ali_ircc_cb *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); /* Stop device */ @@ -1418,7 +1425,7 @@ static int ali_ircc_net_close(struct net_device *dev) free_irq(self->io.irq, dev); free_dma(self->io.dma); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); return 0; } @@ -1429,7 +1436,8 @@ static int ali_ircc_net_close(struct net_device *dev) * Transmit the frame * */ -static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ali_ircc_fir_hard_xmit(struct sk_buff *skb, + struct net_device *dev) { struct ali_ircc_cb *self; unsigned long flags; @@ -1437,9 +1445,9 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) __u32 speed; int mtt, diff; - IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ ); - self = (struct ali_ircc_cb *) dev->priv; + self = netdev_priv(dev); iobase = self->io.fir_base; netif_stop_queue(dev); @@ -1460,7 +1468,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -1470,11 +1478,10 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; - memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, - skb->len); - + skb_copy_from_linear_data(skb, self->tx_fifo.queue[self->tx_fifo.free].start, + skb->len); self->tx_fifo.len++; self->tx_fifo.free++; @@ -1492,7 +1499,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) diff = self->now.tv_usec - self->stamp.tv_usec; /* self->stamp is set from ali_ircc_dma_receive_complete() */ - IRDA_DEBUG(1, "%s(), ******* diff = %d ******* \n", __FUNCTION__ , diff); + IRDA_DEBUG(1, "%s(), ******* diff = %d *******\n", __func__ , diff); if (diff < 0) diff += 1000000; @@ -1514,7 +1521,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* Adjust for timer resolution */ mtt = (mtt+250) / 500; /* 4 discard, 5 get advanced, Let's round off */ - IRDA_DEBUG(1, "%s(), ************** mtt = %d ***********\n", __FUNCTION__ , mtt); + IRDA_DEBUG(1, "%s(), ************** mtt = %d ***********\n", __func__ , mtt); /* Setup timer */ if (mtt == 1) /* 500 us */ @@ -1571,8 +1578,8 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); - return 0; + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); + return NETDEV_TX_OK; } @@ -1582,7 +1589,7 @@ static void ali_ircc_dma_xmit(struct ali_ircc_cb *self) unsigned char FIFO_OPTI, Hi, Lo; - IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ ); iobase = self->io.fir_base; @@ -1633,7 +1640,7 @@ static void ali_ircc_dma_xmit(struct ali_ircc_cb *self) tmp = inb(iobase+FIR_LCR_B); tmp &= ~0x20; // Disable SIP outb(((unsigned char)(tmp & 0x3f) | LCR_B_TX_MODE) & ~LCR_B_BW, iobase+FIR_LCR_B); - IRDA_DEBUG(1, "%s(), ******* Change to TX mode: FIR_LCR_B = 0x%x ******* \n", __FUNCTION__ , inb(iobase+FIR_LCR_B)); + IRDA_DEBUG(1, "%s(), *** Change to TX mode: FIR_LCR_B = 0x%x ***\n", __func__ , inb(iobase+FIR_LCR_B)); outb(0, iobase+FIR_LSR); @@ -1643,7 +1650,7 @@ static void ali_ircc_dma_xmit(struct ali_ircc_cb *self) switch_bank(iobase, BANK0); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) @@ -1651,7 +1658,7 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) int iobase; int ret = TRUE; - IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ ); iobase = self->io.fir_base; @@ -1664,13 +1671,13 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) if((inb(iobase+FIR_LSR) & LSR_FRAME_ABORT) == LSR_FRAME_ABORT) { - IRDA_ERROR("%s(), ********* LSR_FRAME_ABORT *********\n", __FUNCTION__); - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + IRDA_ERROR("%s(), ********* LSR_FRAME_ABORT *********\n", __func__); + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; } /* Check if we need to change the speed */ @@ -1707,7 +1714,7 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) switch_bank(iobase, BANK0); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); return ret; } @@ -1722,7 +1729,7 @@ static int ali_ircc_dma_receive(struct ali_ircc_cb *self) { int iobase, tmp; - IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ ); iobase = self->io.fir_base; @@ -1760,7 +1767,7 @@ static int ali_ircc_dma_receive(struct ali_ircc_cb *self) //switch_bank(iobase, BANK0); tmp = inb(iobase+FIR_LCR_B); outb((unsigned char)(tmp &0x3f) | LCR_B_RX_MODE | LCR_B_BW , iobase + FIR_LCR_B); // 2000/12/1 05:16PM - IRDA_DEBUG(1, "%s(), *** Change To RX mode: FIR_LCR_B = 0x%x *** \n", __FUNCTION__ , inb(iobase+FIR_LCR_B)); + IRDA_DEBUG(1, "%s(), *** Change To RX mode: FIR_LCR_B = 0x%x ***\n", __func__ , inb(iobase+FIR_LCR_B)); /* Set Rx Threshold */ switch_bank(iobase, BANK1); @@ -1772,7 +1779,7 @@ static int ali_ircc_dma_receive(struct ali_ircc_cb *self) outb(CR_DMA_EN | CR_DMA_BURST, iobase+FIR_CR); switch_bank(iobase, BANK0); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); return 0; } @@ -1783,7 +1790,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) __u8 status, MessageCount; int len, i, iobase, val; - IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ ); st_fifo = &self->st_fifo; iobase = self->io.fir_base; @@ -1792,7 +1799,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) MessageCount = inb(iobase+ FIR_LSR)&0x07; if (MessageCount > 0) - IRDA_DEBUG(0, "%s(), Messsage count = %d,\n", __FUNCTION__ , MessageCount); + IRDA_DEBUG(0, "%s(), Message count = %d,\n", __func__ , MessageCount); for (i=0; i<=MessageCount; i++) { @@ -1805,11 +1812,11 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) len = len << 8; len |= inb(iobase+FIR_RX_DSR_LO); - IRDA_DEBUG(1, "%s(), RX Length = 0x%.2x,\n", __FUNCTION__ , len); - IRDA_DEBUG(1, "%s(), RX Status = 0x%.2x,\n", __FUNCTION__ , status); + IRDA_DEBUG(1, "%s(), RX Length = 0x%.2x,\n", __func__ , len); + IRDA_DEBUG(1, "%s(), RX Status = 0x%.2x,\n", __func__ , status); if (st_fifo->tail >= MAX_RX_WINDOW) { - IRDA_DEBUG(0, "%s(), window is full!\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), window is full!\n", __func__ ); continue; } @@ -1832,39 +1839,39 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) /* Check for errors */ if ((status & 0xd8) || self->rcvFramesOverflow || (len==0)) { - IRDA_DEBUG(0,"%s(), ************* RX Errors ************ \n", __FUNCTION__ ); + IRDA_DEBUG(0,"%s(), ************* RX Errors ************\n", __func__ ); /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & LSR_FIFO_UR) { - self->stats.rx_frame_errors++; - IRDA_DEBUG(0,"%s(), ************* FIFO Errors ************ \n", __FUNCTION__ ); + self->netdev->stats.rx_frame_errors++; + IRDA_DEBUG(0,"%s(), ************* FIFO Errors ************\n", __func__ ); } if (status & LSR_FRAME_ERROR) { - self->stats.rx_frame_errors++; - IRDA_DEBUG(0,"%s(), ************* FRAME Errors ************ \n", __FUNCTION__ ); + self->netdev->stats.rx_frame_errors++; + IRDA_DEBUG(0,"%s(), ************* FRAME Errors ************\n", __func__ ); } if (status & LSR_CRC_ERROR) { - self->stats.rx_crc_errors++; - IRDA_DEBUG(0,"%s(), ************* CRC Errors ************ \n", __FUNCTION__ ); + self->netdev->stats.rx_crc_errors++; + IRDA_DEBUG(0,"%s(), ************* CRC Errors ************\n", __func__ ); } if(self->rcvFramesOverflow) { - self->stats.rx_frame_errors++; - IRDA_DEBUG(0,"%s(), ************* Overran DMA buffer ************ \n", __FUNCTION__ ); + self->netdev->stats.rx_frame_errors++; + IRDA_DEBUG(0,"%s(), ************* Overran DMA buffer ************\n", __func__ ); } if(len == 0) { - self->stats.rx_frame_errors++; - IRDA_DEBUG(0,"%s(), ********** Receive Frame Size = 0 ********* \n", __FUNCTION__ ); + self->netdev->stats.rx_frame_errors++; + IRDA_DEBUG(0,"%s(), ********** Receive Frame Size = 0 *********\n", __func__ ); } } else @@ -1876,7 +1883,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) val = inb(iobase+FIR_BSR); if ((val& BSR_FIFO_NOT_EMPTY)== 0x80) { - IRDA_DEBUG(0, "%s(), ************* BSR_FIFO_NOT_EMPTY ************ \n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), ************* BSR_FIFO_NOT_EMPTY ************\n", __func__ ); /* Put this entry back in fifo */ st_fifo->head--; @@ -1913,8 +1920,8 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) { IRDA_WARNING("%s(), memory squeeze, " "dropping frame.\n", - __FUNCTION__); - self->stats.rx_dropped++; + __func__); + self->netdev->stats.rx_dropped++; return FALSE; } @@ -1924,24 +1931,23 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) /* Copy frame without CRC, CRC is removed by hardware*/ skb_put(skb, len); - memcpy(skb->data, self->rx_buff.data, len); + skb_copy_to_linear_data(skb, self->rx_buff.data, len); /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); - self->netdev->last_rx = jiffies; } } switch_bank(iobase, BANK0); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); return TRUE; } @@ -1953,19 +1959,20 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) * Transmit the frame! * */ -static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ali_ircc_sir_hard_xmit(struct sk_buff *skb, + struct net_device *dev) { struct ali_ircc_cb *self; unsigned long flags; int iobase; __u32 speed; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); - IRDA_ASSERT(dev != NULL, return 0;); + IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;); - self = (struct ali_ircc_cb *) dev->priv; - IRDA_ASSERT(self != NULL, return 0;); + self = netdev_priv(dev); + IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;); iobase = self->io.sir_base; @@ -1987,7 +1994,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -1999,7 +2006,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + self->netdev->stats.tx_bytes += self->tx_buff.len; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, iobase+UART_IER); @@ -2009,9 +2016,9 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); - return 0; + return NETDEV_TX_OK; } @@ -2028,19 +2035,19 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) unsigned long flags; int ret = 0; - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__ , dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__ , dev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ - IRDA_DEBUG(1, "%s(), SIOCSBANDWIDTH\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), SIOCSBANDWIDTH\n", __func__ ); /* * This function will also be used by IrLAP to change the * speed, so we still must allow for speed change within @@ -2054,13 +2061,13 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) spin_unlock_irqrestore(&self->lock, flags); break; case SIOCSMEDIABUSY: /* Set media busy */ - IRDA_DEBUG(1, "%s(), SIOCSMEDIABUSY\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), SIOCSMEDIABUSY\n", __func__ ); if (!capable(CAP_NET_ADMIN)) return -EPERM; irda_device_set_media_busy(self->netdev, TRUE); break; case SIOCGRECEIVING: /* Check if we are receiving right now */ - IRDA_DEBUG(2, "%s(), SIOCGRECEIVING\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), SIOCGRECEIVING\n", __func__ ); /* This is protected */ irq->ifr_receiving = ali_ircc_is_receiving(self); break; @@ -2068,7 +2075,7 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EOPNOTSUPP; } - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); return ret; } @@ -2085,7 +2092,7 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self) int status = FALSE; int iobase; - IRDA_DEBUG(2, "%s(), ---------------- Start -----------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ---------------- Start -----------------\n", __func__ ); IRDA_ASSERT(self != NULL, return FALSE;); @@ -2099,7 +2106,7 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self) if((inb(iobase+FIR_FIFO_FR) & 0x3f) != 0) { /* We are receiving something */ - IRDA_DEBUG(1, "%s(), We are receiving something\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), We are receiving something\n", __func__ ); status = TRUE; } switch_bank(iobase, BANK0); @@ -2111,22 +2118,11 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self) spin_unlock_irqrestore(&self->lock, flags); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); return status; } -static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev) -{ - struct ali_ircc_cb *self = (struct ali_ircc_cb *) dev->priv; - - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); - - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); - - return &self->stats; -} - static int ali_ircc_suspend(struct platform_device *dev, pm_message_t state) { struct ali_ircc_cb *self = platform_get_drvdata(dev); @@ -2168,7 +2164,7 @@ static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable) int iobase = self->io.fir_base; /* or sir_base */ - IRDA_DEBUG(2, "%s(), -------- Start -------- ( Enable = %d )\n", __FUNCTION__ , enable); + IRDA_DEBUG(2, "%s(), -------- Start -------- ( Enable = %d )\n", __func__ , enable); /* Enable the interrupt which we wish to */ if (enable){ @@ -2209,14 +2205,14 @@ static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable) else outb(newMask, iobase+UART_IER); - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); } static void SIR2FIR(int iobase) { //unsigned char tmp; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); /* Already protected (change_speed() or setup()), no need to lock. * Jean II */ @@ -2232,14 +2228,14 @@ static void SIR2FIR(int iobase) //tmp |= 0x20; //outb(tmp, iobase+FIR_LCR_B); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } static void FIR2SIR(int iobase) { unsigned char val; - IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); /* Already protected (change_speed() or setup()), no need to lock. * Jean II */ @@ -2255,12 +2251,13 @@ static void FIR2SIR(int iobase) val = inb(iobase+UART_LSR); val = inb(iobase+UART_MSR); - IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ ); } MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>"); MODULE_DESCRIPTION("ALi FIR Controller Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" ALI_IRCC_DRIVER_NAME); module_param_array(io, int, NULL, 0); diff --git a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h index e489c6661ee..0c8edb41bd0 100644 --- a/drivers/net/irda/ali-ircc.h +++ b/drivers/net/irda/ali-ircc.h @@ -173,13 +173,13 @@ struct st_fifo { struct frame_cb { void *start; /* Start of frame in DMA mem */ - int len; /* Lenght of frame in DMA mem */ + int len; /* Length of frame in DMA mem */ }; struct tx_fifo { struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ int ptr; /* Currently being sent */ - int len; /* Lenght of queue */ + int len; /* Length of queue */ int free; /* Next free slot */ void *tail; /* Next free start in DMA mem */ }; @@ -191,7 +191,6 @@ struct ali_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ @@ -219,8 +218,6 @@ struct ali_ircc_cb { int index; /* Instance index */ unsigned char fifo_opti_buf; - - struct pm_dev *dev; }; static inline void switch_bank(int iobase, int bank) diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h deleted file mode 100644 index 7a31d4659ed..00000000000 --- a/drivers/net/irda/au1000_ircc.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Au1000 IrDA driver. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef AU1000_IRCC_H -#define AU1000_IRCC_H - -#include <linux/time.h> - -#include <linux/spinlock.h> -#include <linux/pm.h> -#include <asm/io.h> - -#define NUM_IR_IFF 1 -#define NUM_IR_DESC 64 -#define RING_SIZE_4 0x0 -#define RING_SIZE_16 0x3 -#define RING_SIZE_64 0xF -#define MAX_NUM_IR_DESC 64 -#define MAX_BUF_SIZE 2048 - -#define BPS_115200 0 -#define BPS_57600 1 -#define BPS_38400 2 -#define BPS_19200 5 -#define BPS_9600 11 -#define BPS_2400 47 - -/* Ring descriptor flags */ -#define AU_OWN (1<<7) /* tx,rx */ - -#define IR_DIS_CRC (1<<6) /* tx */ -#define IR_BAD_CRC (1<<5) /* tx */ -#define IR_NEED_PULSE (1<<4) /* tx */ -#define IR_FORCE_UNDER (1<<3) /* tx */ -#define IR_DISABLE_TX (1<<2) /* tx */ -#define IR_HW_UNDER (1<<0) /* tx */ -#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) - -#define IR_PHY_ERROR (1<<6) /* rx */ -#define IR_CRC_ERROR (1<<5) /* rx */ -#define IR_MAX_LEN (1<<4) /* rx */ -#define IR_FIFO_OVER (1<<3) /* rx */ -#define IR_SIR_ERROR (1<<2) /* rx */ -#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ - IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) - -typedef struct db_dest { - struct db_dest *pnext; - volatile u32 *vaddr; - dma_addr_t dma_addr; -} db_dest_t; - - -typedef struct ring_desc { - u8 count_0; /* 7:0 */ - u8 count_1; /* 12:8 */ - u8 reserved; - u8 flags; - u8 addr_0; /* 7:0 */ - u8 addr_1; /* 15:8 */ - u8 addr_2; /* 23:16 */ - u8 addr_3; /* 31:24 */ -} ring_dest_t; - - -/* Private data for each instance */ -struct au1k_private { - - db_dest_t *pDBfree; - db_dest_t db[2*NUM_IR_DESC]; - volatile ring_dest_t *rx_ring[NUM_IR_DESC]; - volatile ring_dest_t *tx_ring[NUM_IR_DESC]; - db_dest_t *rx_db_inuse[NUM_IR_DESC]; - db_dest_t *tx_db_inuse[NUM_IR_DESC]; - u32 rx_head; - u32 tx_head; - u32 tx_tail; - u32 tx_full; - - iobuff_t rx_buff; - - struct net_device *netdev; - struct net_device_stats stats; - - struct timeval stamp; - struct timeval now; - struct qos_info qos; - struct irlap_cb *irlap; - - u8 open; - u32 speed; - u32 newspeed; - - u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ - struct timer_list timer; - - spinlock_t lock; /* For serializing operations */ - struct pm_dev *dev; -}; -#endif /* AU1000_IRCC_H */ diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 37914dc5b90..5f91e3e01c0 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -15,111 +15,222 @@ * 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. + * with this program; if not, see <http://www.gnu.org/licenses/>. */ + #include <linux/module.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/errno.h> #include <linux/netdevice.h> -#include <linux/slab.h> -#include <linux/rtnetlink.h> #include <linux/interrupt.h> -#include <linux/pm.h> -#include <linux/bitops.h> - -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/au1000.h> -#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) -#include <asm/pb1000.h> -#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) -#include <asm/db1x00.h> -#else -#error au1k_ir: unsupported board -#endif +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/time.h> +#include <linux/types.h> +#include <linux/ioport.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/wrapper.h> #include <net/irda/irda_device.h> -#include "au1000_ircc.h" - -static int au1k_irda_net_init(struct net_device *); -static int au1k_irda_start(struct net_device *); -static int au1k_irda_stop(struct net_device *dev); -static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *); -static int au1k_irda_rx(struct net_device *); -static void au1k_irda_interrupt(int, void *); -static void au1k_tx_timeout(struct net_device *); -static struct net_device_stats *au1k_irda_stats(struct net_device *); -static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int); -static int au1k_irda_set_speed(struct net_device *dev, int speed); - -static void *dma_alloc(size_t, dma_addr_t *); -static void dma_free(void *, size_t); +#include <asm/mach-au1x00/au1000.h> + +/* registers */ +#define IR_RING_PTR_STATUS 0x00 +#define IR_RING_BASE_ADDR_H 0x04 +#define IR_RING_BASE_ADDR_L 0x08 +#define IR_RING_SIZE 0x0C +#define IR_RING_PROMPT 0x10 +#define IR_RING_ADDR_CMPR 0x14 +#define IR_INT_CLEAR 0x18 +#define IR_CONFIG_1 0x20 +#define IR_SIR_FLAGS 0x24 +#define IR_STATUS 0x28 +#define IR_READ_PHY_CONFIG 0x2C +#define IR_WRITE_PHY_CONFIG 0x30 +#define IR_MAX_PKT_LEN 0x34 +#define IR_RX_BYTE_CNT 0x38 +#define IR_CONFIG_2 0x3C +#define IR_ENABLE 0x40 + +/* Config1 */ +#define IR_RX_INVERT_LED (1 << 0) +#define IR_TX_INVERT_LED (1 << 1) +#define IR_ST (1 << 2) +#define IR_SF (1 << 3) +#define IR_SIR (1 << 4) +#define IR_MIR (1 << 5) +#define IR_FIR (1 << 6) +#define IR_16CRC (1 << 7) +#define IR_TD (1 << 8) +#define IR_RX_ALL (1 << 9) +#define IR_DMA_ENABLE (1 << 10) +#define IR_RX_ENABLE (1 << 11) +#define IR_TX_ENABLE (1 << 12) +#define IR_LOOPBACK (1 << 14) +#define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \ + IR_RX_ALL | IR_RX_ENABLE | IR_SF | \ + IR_16CRC) + +/* ir_status */ +#define IR_RX_STATUS (1 << 9) +#define IR_TX_STATUS (1 << 10) +#define IR_PHYEN (1 << 15) + +/* ir_write_phy_config */ +#define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */ +#define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */ +#define IR_P(x) ((x) & 0x1f) /* preamble bits */ + +/* Config2 */ +#define IR_MODE_INV (1 << 0) +#define IR_ONE_PIN (1 << 1) +#define IR_PHYCLK_40MHZ (0 << 2) +#define IR_PHYCLK_48MHZ (1 << 2) +#define IR_PHYCLK_56MHZ (2 << 2) +#define IR_PHYCLK_64MHZ (3 << 2) +#define IR_DP (1 << 4) +#define IR_DA (1 << 5) +#define IR_FLT_HIGH (0 << 6) +#define IR_FLT_MEDHI (1 << 6) +#define IR_FLT_MEDLO (2 << 6) +#define IR_FLT_LO (3 << 6) +#define IR_IEN (1 << 8) + +/* ir_enable */ +#define IR_HC (1 << 3) /* divide SBUS clock by 2 */ +#define IR_CE (1 << 2) /* clock enable */ +#define IR_C (1 << 1) /* coherency bit */ +#define IR_BE (1 << 0) /* set in big endian mode */ + +#define NUM_IR_DESC 64 +#define RING_SIZE_4 0x0 +#define RING_SIZE_16 0x3 +#define RING_SIZE_64 0xF +#define MAX_NUM_IR_DESC 64 +#define MAX_BUF_SIZE 2048 + +/* Ring descriptor flags */ +#define AU_OWN (1 << 7) /* tx,rx */ +#define IR_DIS_CRC (1 << 6) /* tx */ +#define IR_BAD_CRC (1 << 5) /* tx */ +#define IR_NEED_PULSE (1 << 4) /* tx */ +#define IR_FORCE_UNDER (1 << 3) /* tx */ +#define IR_DISABLE_TX (1 << 2) /* tx */ +#define IR_HW_UNDER (1 << 0) /* tx */ +#define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER) + +#define IR_PHY_ERROR (1 << 6) /* rx */ +#define IR_CRC_ERROR (1 << 5) /* rx */ +#define IR_MAX_LEN (1 << 4) /* rx */ +#define IR_FIFO_OVER (1 << 3) /* rx */ +#define IR_SIR_ERROR (1 << 2) /* rx */ +#define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \ + IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR) + +struct db_dest { + struct db_dest *pnext; + volatile u32 *vaddr; + dma_addr_t dma_addr; +}; + +struct ring_dest { + u8 count_0; /* 7:0 */ + u8 count_1; /* 12:8 */ + u8 reserved; + u8 flags; + u8 addr_0; /* 7:0 */ + u8 addr_1; /* 15:8 */ + u8 addr_2; /* 23:16 */ + u8 addr_3; /* 31:24 */ +}; + +/* Private data for each instance */ +struct au1k_private { + void __iomem *iobase; + int irq_rx, irq_tx; + + struct db_dest *pDBfree; + struct db_dest db[2 * NUM_IR_DESC]; + volatile struct ring_dest *rx_ring[NUM_IR_DESC]; + volatile struct ring_dest *tx_ring[NUM_IR_DESC]; + struct db_dest *rx_db_inuse[NUM_IR_DESC]; + struct db_dest *tx_db_inuse[NUM_IR_DESC]; + u32 rx_head; + u32 tx_head; + u32 tx_tail; + u32 tx_full; + + iobuff_t rx_buff; + + struct net_device *netdev; + struct timeval stamp; + struct timeval now; + struct qos_info qos; + struct irlap_cb *irlap; + + u8 open; + u32 speed; + u32 newspeed; + + struct timer_list timer; + + struct resource *ioarea; + struct au1k_irda_platform_data *platdata; +}; static int qos_mtt_bits = 0x07; /* 1 ms or more */ -static struct net_device *ir_devs[NUM_IR_IFF]; -static char version[] __devinitdata = - "au1k_ircc:1.2 ppopov@mvista.com\n"; #define RUN_AT(x) (jiffies + (x)) -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) -static BCSR * const bcsr = (BCSR *)0xAE000000; -#endif - -static DEFINE_SPINLOCK(ir_lock); +static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode) +{ + if (p->platdata && p->platdata->set_phy_mode) + p->platdata->set_phy_mode(mode); +} -/* - * IrDA peripheral bug. You have to read the register - * twice to get the right value. - */ -u32 read_ir_reg(u32 addr) -{ - readl(addr); - return readl(addr); +static inline unsigned long irda_read(struct au1k_private *p, + unsigned long ofs) +{ + /* + * IrDA peripheral bug. You have to read the register + * twice to get the right value. + */ + (void)__raw_readl(p->iobase + ofs); + return __raw_readl(p->iobase + ofs); } +static inline void irda_write(struct au1k_private *p, unsigned long ofs, + unsigned long val) +{ + __raw_writel(val, p->iobase + ofs); + wmb(); +} /* * Buffer allocation/deallocation routines. The buffer descriptor returned - * has the virtual and dma address of a buffer suitable for + * has the virtual and dma address of a buffer suitable for * both, receive and transmit operations. */ -static db_dest_t *GetFreeDB(struct au1k_private *aup) +static struct db_dest *GetFreeDB(struct au1k_private *aup) { - db_dest_t *pDB; - pDB = aup->pDBfree; + struct db_dest *db; + db = aup->pDBfree; - if (pDB) { - aup->pDBfree = pDB->pnext; - } - return pDB; + if (db) + aup->pDBfree = db->pnext; + return db; } -static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB) -{ - db_dest_t *pDBfree = aup->pDBfree; - if (pDBfree) - pDBfree->pnext = pDB; - aup->pDBfree = pDB; -} - - /* DMA memory allocation, derived from pci_alloc_consistent. However, the Au1000 data cache is coherent (when programmed so), therefore we return KSEG0 address, not KSEG1. */ -static void *dma_alloc(size_t size, dma_addr_t * dma_handle) +static void *dma_alloc(size_t size, dma_addr_t *dma_handle) { void *ret; int gfp = GFP_ATOMIC | GFP_DMA; - ret = (void *) __get_free_pages(gfp, get_order(size)); + ret = (void *)__get_free_pages(gfp, get_order(size)); if (ret != NULL) { memset(ret, 0, size); @@ -129,7 +240,6 @@ static void *dma_alloc(size_t size, dma_addr_t * dma_handle) return ret; } - static void dma_free(void *vaddr, size_t size) { vaddr = (void *)KSEG0ADDR(vaddr); @@ -137,204 +247,306 @@ static void dma_free(void *vaddr, size_t size) } -static void -setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base) +static void setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base) { int i; - for (i=0; i<NUM_IR_DESC; i++) { - aup->rx_ring[i] = (volatile ring_dest_t *) - (rx_base + sizeof(ring_dest_t)*i); + for (i = 0; i < NUM_IR_DESC; i++) { + aup->rx_ring[i] = (volatile struct ring_dest *) + (rx_base + sizeof(struct ring_dest) * i); } - for (i=0; i<NUM_IR_DESC; i++) { - aup->tx_ring[i] = (volatile ring_dest_t *) - (tx_base + sizeof(ring_dest_t)*i); + for (i = 0; i < NUM_IR_DESC; i++) { + aup->tx_ring[i] = (volatile struct ring_dest *) + (tx_base + sizeof(struct ring_dest) * i); } } -static int au1k_irda_init(void) -{ - static unsigned version_printed = 0; - struct au1k_private *aup; - struct net_device *dev; - int err; - - if (version_printed++ == 0) printk(version); - - dev = alloc_irdadev(sizeof(struct au1k_private)); - if (!dev) - return -ENOMEM; - - dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */ - err = au1k_irda_net_init(dev); - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - ir_devs[0] = dev; - printk(KERN_INFO "IrDA: Registered device %s\n", dev->name); - return 0; - -out1: - aup = netdev_priv(dev); - dma_free((void *)aup->db[0].vaddr, - MAX_BUF_SIZE * 2*NUM_IR_DESC); - dma_free((void *)aup->rx_ring[0], - 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); - kfree(aup->rx_buff.head); -out: - free_netdev(dev); - return err; -} - static int au1k_irda_init_iobuf(iobuff_t *io, int size) { io->head = kmalloc(size, GFP_KERNEL); if (io->head != NULL) { - io->truesize = size; - io->in_frame = FALSE; - io->state = OUTSIDE_FRAME; - io->data = io->head; + io->truesize = size; + io->in_frame = FALSE; + io->state = OUTSIDE_FRAME; + io->data = io->head; } return io->head ? 0 : -ENOMEM; } -static int au1k_irda_net_init(struct net_device *dev) +/* + * Set the IrDA communications speed. + */ +static int au1k_irda_set_speed(struct net_device *dev, int speed) { struct au1k_private *aup = netdev_priv(dev); - int i, retval = 0, err; - db_dest_t *pDB, *pDBfree; - dma_addr_t temp; + volatile struct ring_dest *ptxd; + unsigned long control; + int ret = 0, timeout = 10, i; - err = au1k_irda_init_iobuf(&aup->rx_buff, 14384); - if (err) - goto out1; + if (speed == aup->speed) + return ret; - dev->open = au1k_irda_start; - dev->hard_start_xmit = au1k_irda_hard_xmit; - dev->stop = au1k_irda_stop; - dev->get_stats = au1k_irda_stats; - dev->do_ioctl = au1k_irda_ioctl; - dev->tx_timeout = au1k_tx_timeout; + /* disable PHY first */ + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); + irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN); - irda_init_max_qos_capabilies(&aup->qos); + /* disable RX/TX */ + irda_write(aup, IR_CONFIG_1, + irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE)); + msleep(20); + while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) { + msleep(20); + if (!timeout--) { + printk(KERN_ERR "%s: rx/tx disable timeout\n", + dev->name); + break; + } + } - /* The only value we must override it the baudrate */ - aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| - IR_115200|IR_576000 |(IR_4000000 << 8); - - aup->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&aup->qos); + /* disable DMA */ + irda_write(aup, IR_CONFIG_1, + irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE); + msleep(20); - retval = -ENOMEM; + /* After we disable tx/rx. the index pointers go back to zero. */ + aup->tx_head = aup->tx_tail = aup->rx_head = 0; + for (i = 0; i < NUM_IR_DESC; i++) { + ptxd = aup->tx_ring[i]; + ptxd->flags = 0; + ptxd->count_0 = 0; + ptxd->count_1 = 0; + } - /* Tx ring follows rx ring + 512 bytes */ - /* we need a 1k aligned buffer */ - aup->rx_ring[0] = (ring_dest_t *) - dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp); - if (!aup->rx_ring[0]) - goto out2; + for (i = 0; i < NUM_IR_DESC; i++) { + ptxd = aup->rx_ring[i]; + ptxd->count_0 = 0; + ptxd->count_1 = 0; + ptxd->flags = AU_OWN; + } - /* allocate the data buffers */ - aup->db[0].vaddr = - (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp); - if (!aup->db[0].vaddr) - goto out3; + if (speed == 4000000) + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR); + else + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR); - setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512); + switch (speed) { + case 9600: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12)); + irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); + break; + case 19200: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12)); + irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); + break; + case 38400: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12)); + irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); + break; + case 57600: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12)); + irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); + break; + case 115200: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12)); + irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); + break; + case 4000000: + irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15)); + irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE | + IR_RX_ENABLE); + break; + default: + printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed); + ret = -EINVAL; + break; + } - pDBfree = NULL; - pDB = aup->db; - for (i=0; i<(2*NUM_IR_DESC); i++) { - pDB->pnext = pDBfree; - pDBfree = pDB; - pDB->vaddr = - (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i); - pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); - pDB++; + aup->speed = speed; + irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN); + + control = irda_read(aup, IR_STATUS); + irda_write(aup, IR_RING_PROMPT, 0); + + if (control & (1 << 14)) { + printk(KERN_ERR "%s: configuration error\n", dev->name); + } else { + if (control & (1 << 11)) + printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); + if (control & (1 << 12)) + printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); + if (control & (1 << 13)) + printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); + if (control & (1 << 10)) + printk(KERN_DEBUG "%s TX enabled\n", dev->name); + if (control & (1 << 9)) + printk(KERN_DEBUG "%s RX enabled\n", dev->name); } - aup->pDBfree = pDBfree; - /* attach a data buffer to each descriptor */ - for (i=0; i<NUM_IR_DESC; i++) { - pDB = GetFreeDB(aup); - if (!pDB) goto out; - aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); - aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); - aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); - aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); - aup->rx_db_inuse[i] = pDB; + return ret; +} + +static void update_rx_stats(struct net_device *dev, u32 status, u32 count) +{ + struct net_device_stats *ps = &dev->stats; + + ps->rx_packets++; + + if (status & IR_RX_ERROR) { + ps->rx_errors++; + if (status & (IR_PHY_ERROR | IR_FIFO_OVER)) + ps->rx_missed_errors++; + if (status & IR_MAX_LEN) + ps->rx_length_errors++; + if (status & IR_CRC_ERROR) + ps->rx_crc_errors++; + } else + ps->rx_bytes += count; +} + +static void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) +{ + struct net_device_stats *ps = &dev->stats; + + ps->tx_packets++; + ps->tx_bytes += pkt_len; + + if (status & IR_TX_ERROR) { + ps->tx_errors++; + ps->tx_aborted_errors++; } - for (i=0; i<NUM_IR_DESC; i++) { - pDB = GetFreeDB(aup); - if (!pDB) goto out; - aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); - aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); - aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); - aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); - aup->tx_ring[i]->count_0 = 0; - aup->tx_ring[i]->count_1 = 0; - aup->tx_ring[i]->flags = 0; - aup->tx_db_inuse[i] = pDB; +} + +static void au1k_tx_ack(struct net_device *dev) +{ + struct au1k_private *aup = netdev_priv(dev); + volatile struct ring_dest *ptxd; + + ptxd = aup->tx_ring[aup->tx_tail]; + while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) { + update_tx_stats(dev, ptxd->flags, + (ptxd->count_1 << 8) | ptxd->count_0); + ptxd->count_0 = 0; + ptxd->count_1 = 0; + wmb(); + aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1); + ptxd = aup->tx_ring[aup->tx_tail]; + + if (aup->tx_full) { + aup->tx_full = 0; + netif_wake_queue(dev); + } } -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) - /* power on */ - bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; - bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL; - au_sync(); -#endif + if (aup->tx_tail == aup->tx_head) { + if (aup->newspeed) { + au1k_irda_set_speed(dev, aup->newspeed); + aup->newspeed = 0; + } else { + irda_write(aup, IR_CONFIG_1, + irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE); + irda_write(aup, IR_CONFIG_1, + irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE); + irda_write(aup, IR_RING_PROMPT, 0); + } + } +} - return 0; +static int au1k_irda_rx(struct net_device *dev) +{ + struct au1k_private *aup = netdev_priv(dev); + volatile struct ring_dest *prxd; + struct sk_buff *skb; + struct db_dest *pDB; + u32 flags, count; -out3: - dma_free((void *)aup->rx_ring[0], - 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); -out2: - kfree(aup->rx_buff.head); -out1: - printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval); - return retval; + prxd = aup->rx_ring[aup->rx_head]; + flags = prxd->flags; + + while (!(flags & AU_OWN)) { + pDB = aup->rx_db_inuse[aup->rx_head]; + count = (prxd->count_1 << 8) | prxd->count_0; + if (!(flags & IR_RX_ERROR)) { + /* good frame */ + update_rx_stats(dev, flags, count); + skb = alloc_skb(count + 1, GFP_ATOMIC); + if (skb == NULL) { + dev->stats.rx_dropped++; + continue; + } + skb_reserve(skb, 1); + if (aup->speed == 4000000) + skb_put(skb, count); + else + skb_put(skb, count - 2); + skb_copy_to_linear_data(skb, (void *)pDB->vaddr, + count - 2); + skb->dev = dev; + skb_reset_mac_header(skb); + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + prxd->count_0 = 0; + prxd->count_1 = 0; + } + prxd->flags |= AU_OWN; + aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1); + irda_write(aup, IR_RING_PROMPT, 0); + + /* next descriptor */ + prxd = aup->rx_ring[aup->rx_head]; + flags = prxd->flags; + + } + return 0; } +static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) +{ + struct net_device *dev = dev_id; + struct au1k_private *aup = netdev_priv(dev); + + irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */ + + au1k_irda_rx(dev); + au1k_tx_ack(dev); + + return IRQ_HANDLED; +} static int au1k_init(struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); + u32 enable, ring_address; int i; - u32 control; - u32 ring_address; - /* bring the device out of reset */ - control = 0xe; /* coherent, clock enable, one half system clock */ - + enable = IR_HC | IR_CE | IR_C; #ifndef CONFIG_CPU_LITTLE_ENDIAN - control |= 1; + enable |= IR_BE; #endif aup->tx_head = 0; aup->tx_tail = 0; aup->rx_head = 0; - for (i=0; i<NUM_IR_DESC; i++) { + for (i = 0; i < NUM_IR_DESC; i++) aup->rx_ring[i]->flags = AU_OWN; - } - writel(control, IR_INTERFACE_CONFIG); - au_sync_delay(10); + irda_write(aup, IR_ENABLE, enable); + msleep(20); - writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */ - au_sync_delay(1); + /* disable PHY */ + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); + irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN); + msleep(20); - writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN); + irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE); ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]); - writel(ring_address >> 26, IR_RING_BASE_ADDR_H); - writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L); + irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26); + irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff); - writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE); + irda_write(aup, IR_RING_SIZE, + (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); - writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */ - writel(0, IR_RING_ADDR_CMPR); + irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN); + irda_write(aup, IR_RING_ADDR_CMPR, 0); au1k_irda_set_speed(dev, 9600); return 0; @@ -342,25 +554,28 @@ static int au1k_init(struct net_device *dev) static int au1k_irda_start(struct net_device *dev) { - int retval; - char hwname[32]; struct au1k_private *aup = netdev_priv(dev); + char hwname[32]; + int retval; - if ((retval = au1k_init(dev))) { + retval = au1k_init(dev); + if (retval) { printk(KERN_ERR "%s: error in au1k_init\n", dev->name); return retval; } - if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, - 0, dev->name, dev))) { - printk(KERN_ERR "%s: unable to get IRQ %d\n", + retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0, + dev->name, dev); + if (retval) { + printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq); return retval; } - if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, - 0, dev->name, dev))) { - free_irq(AU1000_IRDA_TX_INT, dev); - printk(KERN_ERR "%s: unable to get IRQ %d\n", + retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0, + dev->name, dev); + if (retval) { + free_irq(aup->irq_tx, dev); + printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq); return retval; } @@ -370,9 +585,13 @@ static int au1k_irda_start(struct net_device *dev) aup->irlap = irlap_open(dev, &aup->qos, hwname); netif_start_queue(dev); - writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */ + /* int enable */ + irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN); + + /* power up */ + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR); - aup->timer.expires = RUN_AT((3*HZ)); + aup->timer.expires = RUN_AT((3 * HZ)); aup->timer.data = (unsigned long)dev; return 0; } @@ -381,11 +600,12 @@ static int au1k_irda_stop(struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); + au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); + /* disable interrupts */ - writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2); - writel(0, IR_CONFIG_1); - writel(0, IR_INTERFACE_CONFIG); /* disable clock */ - au_sync(); + irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN); + irda_write(aup, IR_CONFIG_1, 0); + irda_write(aup, IR_ENABLE, 0); /* disable clock */ if (aup->irlap) { irlap_close(aup->irlap); @@ -396,83 +616,12 @@ static int au1k_irda_stop(struct net_device *dev) del_timer(&aup->timer); /* disable the interrupt */ - free_irq(AU1000_IRDA_TX_INT, dev); - free_irq(AU1000_IRDA_RX_INT, dev); - return 0; -} - -static void __exit au1k_irda_exit(void) -{ - struct net_device *dev = ir_devs[0]; - struct au1k_private *aup = netdev_priv(dev); + free_irq(aup->irq_tx, dev); + free_irq(aup->irq_rx, dev); - unregister_netdev(dev); - - dma_free((void *)aup->db[0].vaddr, - MAX_BUF_SIZE * 2*NUM_IR_DESC); - dma_free((void *)aup->rx_ring[0], - 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); - kfree(aup->rx_buff.head); - free_netdev(dev); -} - - -static inline void -update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) -{ - struct au1k_private *aup = netdev_priv(dev); - struct net_device_stats *ps = &aup->stats; - - ps->tx_packets++; - ps->tx_bytes += pkt_len; - - if (status & IR_TX_ERROR) { - ps->tx_errors++; - ps->tx_aborted_errors++; - } -} - - -static void au1k_tx_ack(struct net_device *dev) -{ - struct au1k_private *aup = netdev_priv(dev); - volatile ring_dest_t *ptxd; - - ptxd = aup->tx_ring[aup->tx_tail]; - while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) { - update_tx_stats(dev, ptxd->flags, - ptxd->count_1<<8 | ptxd->count_0); - ptxd->count_0 = 0; - ptxd->count_1 = 0; - au_sync(); - - aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1); - ptxd = aup->tx_ring[aup->tx_tail]; - - if (aup->tx_full) { - aup->tx_full = 0; - netif_wake_queue(dev); - } - } - - if (aup->tx_tail == aup->tx_head) { - if (aup->newspeed) { - au1k_irda_set_speed(dev, aup->newspeed); - aup->newspeed = 0; - } - else { - writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, - IR_CONFIG_1); - au_sync(); - writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, - IR_CONFIG_1); - writel(0, IR_RING_PROMPT); - au_sync(); - } - } + return 0; } - /* * Au1000 transmit routine. */ @@ -480,15 +629,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); int speed = irda_get_next_speed(skb); - volatile ring_dest_t *ptxd; - u32 len; + volatile struct ring_dest *ptxd; + struct db_dest *pDB; + u32 len, flags; - u32 flags; - db_dest_t *pDB; - - if (speed != aup->speed && speed != -1) { + if (speed != aup->speed && speed != -1) aup->newspeed = speed; - } if ((skb->len == 0) && (aup->newspeed)) { if (aup->tx_tail == aup->tx_head) { @@ -496,7 +642,7 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) aup->newspeed = 0; } dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } ptxd = aup->tx_ring[aup->tx_head]; @@ -507,8 +653,7 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); aup->tx_full = 1; return 1; - } - else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { + } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { printk(KERN_DEBUG "%s: tx_full\n", dev->name); netif_stop_queue(dev); aup->tx_full = 1; @@ -518,132 +663,37 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) pDB = aup->tx_db_inuse[aup->tx_head]; #if 0 - if (read_ir_reg(IR_RX_BYTE_CNT) != 0) { - printk("tx warning: rx byte cnt %x\n", - read_ir_reg(IR_RX_BYTE_CNT)); + if (irda_read(aup, IR_RX_BYTE_CNT) != 0) { + printk(KERN_DEBUG "tx warning: rx byte cnt %x\n", + irda_read(aup, IR_RX_BYTE_CNT)); } #endif - + if (aup->speed == 4000000) { /* FIR */ - memcpy((void *)pDB->vaddr, skb->data, skb->len); + skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len); ptxd->count_0 = skb->len & 0xff; ptxd->count_1 = (skb->len >> 8) & 0xff; - - } - else { + } else { /* SIR */ len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE); ptxd->count_0 = len & 0xff; ptxd->count_1 = (len >> 8) & 0xff; ptxd->flags |= IR_DIS_CRC; - au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c); } ptxd->flags |= AU_OWN; - au_sync(); + wmb(); - writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); - writel(0, IR_RING_PROMPT); - au_sync(); + irda_write(aup, IR_CONFIG_1, + irda_read(aup, IR_CONFIG_1) | IR_TX_ENABLE); + irda_write(aup, IR_RING_PROMPT, 0); dev_kfree_skb(skb); aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1); - dev->trans_start = jiffies; - return 0; -} - - -static inline void -update_rx_stats(struct net_device *dev, u32 status, u32 count) -{ - struct au1k_private *aup = netdev_priv(dev); - struct net_device_stats *ps = &aup->stats; - - ps->rx_packets++; - - if (status & IR_RX_ERROR) { - ps->rx_errors++; - if (status & (IR_PHY_ERROR|IR_FIFO_OVER)) - ps->rx_missed_errors++; - if (status & IR_MAX_LEN) - ps->rx_length_errors++; - if (status & IR_CRC_ERROR) - ps->rx_crc_errors++; - } - else - ps->rx_bytes += count; + return NETDEV_TX_OK; } /* - * Au1000 receive routine. - */ -static int au1k_irda_rx(struct net_device *dev) -{ - struct au1k_private *aup = netdev_priv(dev); - struct sk_buff *skb; - volatile ring_dest_t *prxd; - u32 flags, count; - db_dest_t *pDB; - - prxd = aup->rx_ring[aup->rx_head]; - flags = prxd->flags; - - while (!(flags & AU_OWN)) { - pDB = aup->rx_db_inuse[aup->rx_head]; - count = prxd->count_1<<8 | prxd->count_0; - if (!(flags & IR_RX_ERROR)) { - /* good frame */ - update_rx_stats(dev, flags, count); - skb=alloc_skb(count+1,GFP_ATOMIC); - if (skb == NULL) { - aup->stats.rx_dropped++; - continue; - } - skb_reserve(skb, 1); - if (aup->speed == 4000000) - skb_put(skb, count); - else - skb_put(skb, count-2); - memcpy(skb->data, (void *)pDB->vaddr, count-2); - skb->dev = dev; - skb->mac.raw = skb->data; - skb->protocol = htons(ETH_P_IRDA); - netif_rx(skb); - prxd->count_0 = 0; - prxd->count_1 = 0; - } - prxd->flags |= AU_OWN; - aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1); - writel(0, IR_RING_PROMPT); - au_sync(); - - /* next descriptor */ - prxd = aup->rx_ring[aup->rx_head]; - flags = prxd->flags; - dev->last_rx = jiffies; - - } - return 0; -} - - -void au1k_irda_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - - if (dev == NULL) { - printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); - return; - } - - writel(0, IR_INT_CLEAR); /* ack irda interrupts */ - - au1k_irda_rx(dev); - au1k_tx_ack(dev); -} - - -/* * The Tx ring has been full longer than the watchdog timeout * value. The transmitter must be hung? */ @@ -660,142 +710,7 @@ static void au1k_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } - -/* - * Set the IrDA communications speed. - */ -static int -au1k_irda_set_speed(struct net_device *dev, int speed) -{ - unsigned long flags; - struct au1k_private *aup = netdev_priv(dev); - u32 control; - int ret = 0, timeout = 10, i; - volatile ring_dest_t *ptxd; -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) - unsigned long irda_resets; -#endif - - if (speed == aup->speed) - return ret; - - spin_lock_irqsave(&ir_lock, flags); - - /* disable PHY first */ - writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); - - /* disable RX/TX */ - writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), - IR_CONFIG_1); - au_sync_delay(1); - while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) { - mdelay(1); - if (!timeout--) { - printk(KERN_ERR "%s: rx/tx disable timeout\n", - dev->name); - break; - } - } - - /* disable DMA */ - writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1); - au_sync_delay(1); - - /* - * After we disable tx/rx. the index pointers - * go back to zero. - */ - aup->tx_head = aup->tx_tail = aup->rx_head = 0; - for (i=0; i<NUM_IR_DESC; i++) { - ptxd = aup->tx_ring[i]; - ptxd->flags = 0; - ptxd->count_0 = 0; - ptxd->count_1 = 0; - } - - for (i=0; i<NUM_IR_DESC; i++) { - ptxd = aup->rx_ring[i]; - ptxd->count_0 = 0; - ptxd->count_1 = 0; - ptxd->flags = AU_OWN; - } - - if (speed == 4000000) { -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) - bcsr->resets |= BCSR_RESETS_FIR_SEL; -#else /* Pb1000 and Pb1100 */ - writel(1<<13, CPLD_AUX1); -#endif - } - else { -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) - bcsr->resets &= ~BCSR_RESETS_FIR_SEL; -#else /* Pb1000 and Pb1100 */ - writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1); -#endif - } - - switch (speed) { - case 9600: - writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); - writel(IR_SIR_MODE, IR_CONFIG_1); - break; - case 19200: - writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); - writel(IR_SIR_MODE, IR_CONFIG_1); - break; - case 38400: - writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); - writel(IR_SIR_MODE, IR_CONFIG_1); - break; - case 57600: - writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); - writel(IR_SIR_MODE, IR_CONFIG_1); - break; - case 115200: - writel(12<<5, IR_WRITE_PHY_CONFIG); - writel(IR_SIR_MODE, IR_CONFIG_1); - break; - case 4000000: - writel(0xF, IR_WRITE_PHY_CONFIG); - writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); - break; - default: - printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed); - ret = -EINVAL; - break; - } - - aup->speed = speed; - writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE); - au_sync(); - - control = read_ir_reg(IR_ENABLE); - writel(0, IR_RING_PROMPT); - au_sync(); - - if (control & (1<<14)) { - printk(KERN_ERR "%s: configuration error\n", dev->name); - } - else { - if (control & (1<<11)) - printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); - if (control & (1<<12)) - printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); - if (control & (1<<13)) - printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); - if (control & (1<<10)) - printk(KERN_DEBUG "%s TX enabled\n", dev->name); - if (control & (1<<9)) - printk(KERN_DEBUG "%s RX enabled\n", dev->name); - } - - spin_unlock_irqrestore(&ir_lock, flags); - return ret; -} - -static int -au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) +static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) { struct if_irda_req *rq = (struct if_irda_req *)ifreq; struct au1k_private *aup = netdev_priv(dev); @@ -836,15 +751,207 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } +static const struct net_device_ops au1k_irda_netdev_ops = { + .ndo_open = au1k_irda_start, + .ndo_stop = au1k_irda_stop, + .ndo_start_xmit = au1k_irda_hard_xmit, + .ndo_tx_timeout = au1k_tx_timeout, + .ndo_do_ioctl = au1k_irda_ioctl, +}; -static struct net_device_stats *au1k_irda_stats(struct net_device *dev) +static int au1k_irda_net_init(struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); - return &aup->stats; + struct db_dest *pDB, *pDBfree; + int i, err, retval = 0; + dma_addr_t temp; + + err = au1k_irda_init_iobuf(&aup->rx_buff, 14384); + if (err) + goto out1; + + dev->netdev_ops = &au1k_irda_netdev_ops; + + irda_init_max_qos_capabilies(&aup->qos); + + /* The only value we must override it the baudrate */ + aup->qos.baud_rate.bits = IR_9600 | IR_19200 | IR_38400 | + IR_57600 | IR_115200 | IR_576000 | (IR_4000000 << 8); + + aup->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&aup->qos); + + retval = -ENOMEM; + + /* Tx ring follows rx ring + 512 bytes */ + /* we need a 1k aligned buffer */ + aup->rx_ring[0] = (struct ring_dest *) + dma_alloc(2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)), + &temp); + if (!aup->rx_ring[0]) + goto out2; + + /* allocate the data buffers */ + aup->db[0].vaddr = + dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); + if (!aup->db[0].vaddr) + goto out3; + + setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512); + + pDBfree = NULL; + pDB = aup->db; + for (i = 0; i < (2 * NUM_IR_DESC); i++) { + pDB->pnext = pDBfree; + pDBfree = pDB; + pDB->vaddr = + (u32 *)((unsigned)aup->db[0].vaddr + (MAX_BUF_SIZE * i)); + pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); + pDB++; + } + aup->pDBfree = pDBfree; + + /* attach a data buffer to each descriptor */ + for (i = 0; i < NUM_IR_DESC; i++) { + pDB = GetFreeDB(aup); + if (!pDB) + goto out3; + aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); + aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff); + aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff); + aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff); + aup->rx_db_inuse[i] = pDB; + } + for (i = 0; i < NUM_IR_DESC; i++) { + pDB = GetFreeDB(aup); + if (!pDB) + goto out3; + aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); + aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff); + aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff); + aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff); + aup->tx_ring[i]->count_0 = 0; + aup->tx_ring[i]->count_1 = 0; + aup->tx_ring[i]->flags = 0; + aup->tx_db_inuse[i] = pDB; + } + + return 0; + +out3: + dma_free((void *)aup->rx_ring[0], + 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); +out2: + kfree(aup->rx_buff.head); +out1: + printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval); + return retval; +} + +static int au1k_irda_probe(struct platform_device *pdev) +{ + struct au1k_private *aup; + struct net_device *dev; + struct resource *r; + int err; + + dev = alloc_irdadev(sizeof(struct au1k_private)); + if (!dev) + return -ENOMEM; + + aup = netdev_priv(dev); + + aup->platdata = pdev->dev.platform_data; + + err = -EINVAL; + r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!r) + goto out; + + aup->irq_tx = r->start; + + r = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + if (!r) + goto out; + + aup->irq_rx = r->start; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + goto out; + + err = -EBUSY; + aup->ioarea = request_mem_region(r->start, resource_size(r), + pdev->name); + if (!aup->ioarea) + goto out; + + aup->iobase = ioremap_nocache(r->start, resource_size(r)); + if (!aup->iobase) + goto out2; + + dev->irq = aup->irq_rx; + + err = au1k_irda_net_init(dev); + if (err) + goto out3; + err = register_netdev(dev); + if (err) + goto out4; + + platform_set_drvdata(pdev, dev); + + printk(KERN_INFO "IrDA: Registered device %s\n", dev->name); + return 0; + +out4: + dma_free((void *)aup->db[0].vaddr, + MAX_BUF_SIZE * 2 * NUM_IR_DESC); + dma_free((void *)aup->rx_ring[0], + 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); + kfree(aup->rx_buff.head); +out3: + iounmap(aup->iobase); +out2: + release_resource(aup->ioarea); + kfree(aup->ioarea); +out: + free_netdev(dev); + return err; } +static int au1k_irda_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct au1k_private *aup = netdev_priv(dev); + + unregister_netdev(dev); + + dma_free((void *)aup->db[0].vaddr, + MAX_BUF_SIZE * 2 * NUM_IR_DESC); + dma_free((void *)aup->rx_ring[0], + 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); + kfree(aup->rx_buff.head); + + iounmap(aup->iobase); + release_resource(aup->ioarea); + kfree(aup->ioarea); + + free_netdev(dev); + + return 0; +} + +static struct platform_driver au1k_irda_driver = { + .driver = { + .name = "au1000-irda", + .owner = THIS_MODULE, + }, + .probe = au1k_irda_probe, + .remove = au1k_irda_remove, +}; + +module_platform_driver(au1k_irda_driver); + MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>"); MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); - -module_init(au1k_irda_init); -module_exit(au1k_irda_exit); diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c new file mode 100644 index 00000000000..303c4bd26e1 --- /dev/null +++ b/drivers/net/irda/bfin_sir.c @@ -0,0 +1,818 @@ +/* + * Blackfin Infra-red Driver + * + * Copyright 2006-2009 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + * + */ +#include "bfin_sir.h" + +#ifdef CONFIG_SIR_BFIN_DMA +#define DMA_SIR_RX_XCNT 10 +#define DMA_SIR_RX_YCNT (PAGE_SIZE / DMA_SIR_RX_XCNT) +#define DMA_SIR_RX_FLUSH_JIFS (HZ * 4 / 250) +#endif + +#if ANOMALY_05000447 +static int max_rate = 57600; +#else +static int max_rate = 115200; +#endif + +static void turnaround_delay(unsigned long last_jif, int mtt) +{ + long ticks; + + mtt = mtt < 10000 ? 10000 : mtt; + ticks = 1 + mtt / (USEC_PER_SEC / HZ); + schedule_timeout_uninterruptible(ticks); +} + +static void bfin_sir_init_ports(struct bfin_sir_port *sp, struct platform_device *pdev) +{ + int i; + struct resource *res; + + for (i = 0; i < pdev->num_resources; i++) { + res = &pdev->resource[i]; + switch (res->flags) { + case IORESOURCE_MEM: + sp->membase = (void __iomem *)res->start; + break; + case IORESOURCE_IRQ: + sp->irq = res->start; + break; + case IORESOURCE_DMA: + sp->rx_dma_channel = res->start; + sp->tx_dma_channel = res->end; + break; + default: + break; + } + } + + sp->clk = get_sclk(); +#ifdef CONFIG_SIR_BFIN_DMA + sp->tx_done = 1; + init_timer(&(sp->rx_dma_timer)); +#endif +} + +static void bfin_sir_stop_tx(struct bfin_sir_port *port) +{ +#ifdef CONFIG_SIR_BFIN_DMA + disable_dma(port->tx_dma_channel); +#endif + + while (!(UART_GET_LSR(port) & THRE)) { + cpu_relax(); + continue; + } + + UART_CLEAR_IER(port, ETBEI); +} + +static void bfin_sir_enable_tx(struct bfin_sir_port *port) +{ + UART_SET_IER(port, ETBEI); +} + +static void bfin_sir_stop_rx(struct bfin_sir_port *port) +{ + UART_CLEAR_IER(port, ERBFI); +} + +static void bfin_sir_enable_rx(struct bfin_sir_port *port) +{ + UART_SET_IER(port, ERBFI); +} + +static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) +{ + int ret = -EINVAL; + unsigned int quot; + unsigned short val, lsr, lcr; + static int utime; + int count = 10; + + lcr = WLS(8); + + switch (speed) { + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + + /* + * IRDA is not affected by anomaly 05000230, so there is no + * need to tweak the divisor like he UART driver (which will + * slightly speed up the baud rate on us). + */ + quot = (port->clk + (8 * speed)) / (16 * speed); + + do { + udelay(utime); + lsr = UART_GET_LSR(port); + } while (!(lsr & TEMT) && count--); + + /* The useconds for 1 bits to transmit */ + utime = 1000000 / speed + 1; + + /* Clear UCEN bit to reset the UART state machine + * and control registers + */ + val = UART_GET_GCTL(port); + val &= ~UCEN; + UART_PUT_GCTL(port, val); + + /* Set DLAB in LCR to Access THR RBR IER */ + UART_SET_DLAB(port); + SSYNC(); + + UART_PUT_DLL(port, quot & 0xFF); + UART_PUT_DLH(port, (quot >> 8) & 0xFF); + SSYNC(); + + /* Clear DLAB in LCR */ + UART_CLEAR_DLAB(port); + SSYNC(); + + UART_PUT_LCR(port, lcr); + + val = UART_GET_GCTL(port); + val |= UCEN; + UART_PUT_GCTL(port, val); + + ret = 0; + break; + default: + printk(KERN_WARNING "bfin_sir: Invalid speed %d\n", speed); + break; + } + + val = UART_GET_GCTL(port); + /* If not add the 'RPOLC', we can't catch the receive interrupt. + * It's related with the HW layout and the IR transiver. + */ + val |= UMOD_IRDA | RPOLC; + UART_PUT_GCTL(port, val); + return ret; +} + +static int bfin_sir_is_receiving(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + if (!(UART_GET_IER(port) & ERBFI)) + return 0; + return self->rx_buff.state != OUTSIDE_FRAME; +} + +#ifdef CONFIG_SIR_BFIN_PIO +static void bfin_sir_tx_chars(struct net_device *dev) +{ + unsigned int chr; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + if (self->tx_buff.len != 0) { + chr = *(self->tx_buff.data); + UART_PUT_CHAR(port, chr); + self->tx_buff.data++; + self->tx_buff.len--; + } else { + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.data - self->tx_buff.head; + if (self->newspeed) { + bfin_sir_set_speed(port, self->newspeed); + self->speed = self->newspeed; + self->newspeed = 0; + } + bfin_sir_stop_tx(port); + bfin_sir_enable_rx(port); + /* I'm hungry! */ + netif_wake_queue(dev); + } +} + +static void bfin_sir_rx_chars(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + unsigned char ch; + + UART_CLEAR_LSR(port); + ch = UART_GET_CHAR(port); + async_unwrap_char(dev, &self->stats, &self->rx_buff, ch); + dev->last_rx = jiffies; +} + +static irqreturn_t bfin_sir_rx_int(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + spin_lock(&self->lock); + while ((UART_GET_LSR(port) & DR)) + bfin_sir_rx_chars(dev); + spin_unlock(&self->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t bfin_sir_tx_int(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + spin_lock(&self->lock); + if (UART_GET_LSR(port) & THRE) + bfin_sir_tx_chars(dev); + spin_unlock(&self->lock); + + return IRQ_HANDLED; +} +#endif /* CONFIG_SIR_BFIN_PIO */ + +#ifdef CONFIG_SIR_BFIN_DMA +static void bfin_sir_dma_tx_chars(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + if (!port->tx_done) + return; + port->tx_done = 0; + + if (self->tx_buff.len == 0) { + self->stats.tx_packets++; + if (self->newspeed) { + bfin_sir_set_speed(port, self->newspeed); + self->speed = self->newspeed; + self->newspeed = 0; + } + bfin_sir_enable_rx(port); + port->tx_done = 1; + netif_wake_queue(dev); + return; + } + + blackfin_dcache_flush_range((unsigned long)(self->tx_buff.data), + (unsigned long)(self->tx_buff.data+self->tx_buff.len)); + set_dma_config(port->tx_dma_channel, + set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP, + INTR_ON_BUF, DIMENSION_LINEAR, DATA_SIZE_8, + DMA_SYNC_RESTART)); + set_dma_start_addr(port->tx_dma_channel, + (unsigned long)(self->tx_buff.data)); + set_dma_x_count(port->tx_dma_channel, self->tx_buff.len); + set_dma_x_modify(port->tx_dma_channel, 1); + enable_dma(port->tx_dma_channel); +} + +static irqreturn_t bfin_sir_dma_tx_int(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + + spin_lock(&self->lock); + if (!(get_dma_curr_irqstat(port->tx_dma_channel) & DMA_RUN)) { + clear_dma_irqstat(port->tx_dma_channel); + bfin_sir_stop_tx(port); + + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.len; + self->tx_buff.len = 0; + if (self->newspeed) { + bfin_sir_set_speed(port, self->newspeed); + self->speed = self->newspeed; + self->newspeed = 0; + } + bfin_sir_enable_rx(port); + /* I'm hungry! */ + netif_wake_queue(dev); + port->tx_done = 1; + } + spin_unlock(&self->lock); + + return IRQ_HANDLED; +} + +static void bfin_sir_dma_rx_chars(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + int i; + + UART_CLEAR_LSR(port); + + for (i = port->rx_dma_buf.head; i < port->rx_dma_buf.tail; i++) + async_unwrap_char(dev, &self->stats, &self->rx_buff, port->rx_dma_buf.buf[i]); +} + +void bfin_sir_rx_dma_timeout(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + int x_pos, pos; + unsigned long flags; + + spin_lock_irqsave(&self->lock, flags); + x_pos = DMA_SIR_RX_XCNT - get_dma_curr_xcount(port->rx_dma_channel); + if (x_pos == DMA_SIR_RX_XCNT) + x_pos = 0; + + pos = port->rx_dma_nrows * DMA_SIR_RX_XCNT + x_pos; + + if (pos > port->rx_dma_buf.tail) { + port->rx_dma_buf.tail = pos; + bfin_sir_dma_rx_chars(dev); + port->rx_dma_buf.head = port->rx_dma_buf.tail; + } + spin_unlock_irqrestore(&self->lock, flags); +} + +static irqreturn_t bfin_sir_dma_rx_int(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + unsigned short irqstat; + + spin_lock(&self->lock); + + port->rx_dma_nrows++; + port->rx_dma_buf.tail = DMA_SIR_RX_XCNT * port->rx_dma_nrows; + bfin_sir_dma_rx_chars(dev); + if (port->rx_dma_nrows >= DMA_SIR_RX_YCNT) { + port->rx_dma_nrows = 0; + port->rx_dma_buf.tail = 0; + } + port->rx_dma_buf.head = port->rx_dma_buf.tail; + + irqstat = get_dma_curr_irqstat(port->rx_dma_channel); + clear_dma_irqstat(port->rx_dma_channel); + spin_unlock(&self->lock); + + mod_timer(&port->rx_dma_timer, jiffies + DMA_SIR_RX_FLUSH_JIFS); + return IRQ_HANDLED; +} +#endif /* CONFIG_SIR_BFIN_DMA */ + +static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev) +{ +#ifdef CONFIG_SIR_BFIN_DMA + dma_addr_t dma_handle; +#endif /* CONFIG_SIR_BFIN_DMA */ + + if (request_dma(port->rx_dma_channel, "BFIN_UART_RX") < 0) { + dev_warn(&dev->dev, "Unable to attach SIR RX DMA channel\n"); + return -EBUSY; + } + + if (request_dma(port->tx_dma_channel, "BFIN_UART_TX") < 0) { + dev_warn(&dev->dev, "Unable to attach SIR TX DMA channel\n"); + free_dma(port->rx_dma_channel); + return -EBUSY; + } + +#ifdef CONFIG_SIR_BFIN_DMA + + set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev); + set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev); + + port->rx_dma_buf.buf = dma_alloc_coherent(NULL, PAGE_SIZE, + &dma_handle, GFP_DMA); + port->rx_dma_buf.head = 0; + port->rx_dma_buf.tail = 0; + port->rx_dma_nrows = 0; + + set_dma_config(port->rx_dma_channel, + set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, + INTR_ON_ROW, DIMENSION_2D, + DATA_SIZE_8, DMA_SYNC_RESTART)); + set_dma_x_count(port->rx_dma_channel, DMA_SIR_RX_XCNT); + set_dma_x_modify(port->rx_dma_channel, 1); + set_dma_y_count(port->rx_dma_channel, DMA_SIR_RX_YCNT); + set_dma_y_modify(port->rx_dma_channel, 1); + set_dma_start_addr(port->rx_dma_channel, (unsigned long)port->rx_dma_buf.buf); + enable_dma(port->rx_dma_channel); + + port->rx_dma_timer.data = (unsigned long)(dev); + port->rx_dma_timer.function = (void *)bfin_sir_rx_dma_timeout; + +#else + + if (request_irq(port->irq, bfin_sir_rx_int, 0, "BFIN_SIR_RX", dev)) { + dev_warn(&dev->dev, "Unable to attach SIR RX interrupt\n"); + return -EBUSY; + } + + if (request_irq(port->irq+1, bfin_sir_tx_int, 0, "BFIN_SIR_TX", dev)) { + dev_warn(&dev->dev, "Unable to attach SIR TX interrupt\n"); + free_irq(port->irq, dev); + return -EBUSY; + } +#endif + + return 0; +} + +static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev) +{ + unsigned short val; + + bfin_sir_stop_rx(port); + + val = UART_GET_GCTL(port); + val &= ~(UCEN | UMOD_MASK | RPOLC); + UART_PUT_GCTL(port, val); + +#ifdef CONFIG_SIR_BFIN_DMA + disable_dma(port->tx_dma_channel); + disable_dma(port->rx_dma_channel); + del_timer(&(port->rx_dma_timer)); + dma_free_coherent(NULL, PAGE_SIZE, port->rx_dma_buf.buf, 0); +#else + free_irq(port->irq+1, dev); + free_irq(port->irq, dev); +#endif + free_dma(port->tx_dma_channel); + free_dma(port->rx_dma_channel); +} + +#ifdef CONFIG_PM +static int bfin_sir_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct bfin_sir_port *sir_port; + struct net_device *dev; + struct bfin_sir_self *self; + + sir_port = platform_get_drvdata(pdev); + if (!sir_port) + return 0; + + dev = sir_port->dev; + self = netdev_priv(dev); + if (self->open) { + flush_work(&self->work); + bfin_sir_shutdown(self->sir_port, dev); + netif_device_detach(dev); + } + + return 0; +} +static int bfin_sir_resume(struct platform_device *pdev) +{ + struct bfin_sir_port *sir_port; + struct net_device *dev; + struct bfin_sir_self *self; + struct bfin_sir_port *port; + + sir_port = platform_get_drvdata(pdev); + if (!sir_port) + return 0; + + dev = sir_port->dev; + self = netdev_priv(dev); + port = self->sir_port; + if (self->open) { + if (self->newspeed) { + self->speed = self->newspeed; + self->newspeed = 0; + } + bfin_sir_startup(port, dev); + bfin_sir_set_speed(port, 9600); + bfin_sir_enable_rx(port); + netif_device_attach(dev); + } + return 0; +} +#else +#define bfin_sir_suspend NULL +#define bfin_sir_resume NULL +#endif + +static void bfin_sir_send_work(struct work_struct *work) +{ + struct bfin_sir_self *self = container_of(work, struct bfin_sir_self, work); + struct net_device *dev = self->sir_port->dev; + struct bfin_sir_port *port = self->sir_port; + unsigned short val; + int tx_cnt = 10; + + while (bfin_sir_is_receiving(dev) && --tx_cnt) + turnaround_delay(dev->last_rx, self->mtt); + + bfin_sir_stop_rx(port); + + /* To avoid losting RX interrupt, we reset IR function before + * sending data. We also can set the speed, which will + * reset all the UART. + */ + val = UART_GET_GCTL(port); + val &= ~(UMOD_MASK | RPOLC); + UART_PUT_GCTL(port, val); + SSYNC(); + val |= UMOD_IRDA | RPOLC; + UART_PUT_GCTL(port, val); + SSYNC(); + /* bfin_sir_set_speed(port, self->speed); */ + +#ifdef CONFIG_SIR_BFIN_DMA + bfin_sir_dma_tx_chars(dev); +#endif + bfin_sir_enable_tx(port); + dev->trans_start = jiffies; +} + +static int bfin_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + int speed = irda_get_next_speed(skb); + + netif_stop_queue(dev); + + self->mtt = irda_get_mtt(skb); + + if (speed != self->speed && speed != -1) + self->newspeed = speed; + + self->tx_buff.data = self->tx_buff.head; + if (skb->len == 0) + self->tx_buff.len = 0; + else + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); + + schedule_work(&self->work); + dev_kfree_skb(skb); + + return 0; +} + +static int bfin_sir_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) +{ + struct if_irda_req *rq = (struct if_irda_req *)ifreq; + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + int ret = 0; + + switch (cmd) { + case SIOCSBANDWIDTH: + if (capable(CAP_NET_ADMIN)) { + if (self->open) { + ret = bfin_sir_set_speed(port, rq->ifr_baudrate); + bfin_sir_enable_rx(port); + } else { + dev_warn(&dev->dev, "SIOCSBANDWIDTH: !netif_running\n"); + ret = 0; + } + } + break; + + case SIOCSMEDIABUSY: + ret = -EPERM; + if (capable(CAP_NET_ADMIN)) { + irda_device_set_media_busy(dev, TRUE); + ret = 0; + } + break; + + case SIOCGRECEIVING: + rq->ifr_receiving = bfin_sir_is_receiving(dev); + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static struct net_device_stats *bfin_sir_stats(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + + return &self->stats; +} + +static int bfin_sir_open(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + struct bfin_sir_port *port = self->sir_port; + int err; + + self->newspeed = 0; + self->speed = 9600; + + spin_lock_init(&self->lock); + + err = bfin_sir_startup(port, dev); + if (err) + goto err_startup; + + bfin_sir_set_speed(port, 9600); + + self->irlap = irlap_open(dev, &self->qos, DRIVER_NAME); + if (!self->irlap) { + err = -ENOMEM; + goto err_irlap; + } + + INIT_WORK(&self->work, bfin_sir_send_work); + + /* + * Now enable the interrupt then start the queue + */ + self->open = 1; + bfin_sir_enable_rx(port); + + netif_start_queue(dev); + + return 0; + +err_irlap: + self->open = 0; + bfin_sir_shutdown(port, dev); +err_startup: + return err; +} + +static int bfin_sir_stop(struct net_device *dev) +{ + struct bfin_sir_self *self = netdev_priv(dev); + + flush_work(&self->work); + bfin_sir_shutdown(self->sir_port, dev); + + if (self->rxskb) { + dev_kfree_skb(self->rxskb); + self->rxskb = NULL; + } + + /* Stop IrLAP */ + if (self->irlap) { + irlap_close(self->irlap); + self->irlap = NULL; + } + + netif_stop_queue(dev); + self->open = 0; + + return 0; +} + +static int bfin_sir_init_iobuf(iobuff_t *io, int size) +{ + io->head = kmalloc(size, GFP_KERNEL); + if (!io->head) + return -ENOMEM; + io->truesize = size; + io->in_frame = FALSE; + io->state = OUTSIDE_FRAME; + io->data = io->head; + return 0; +} + +static const struct net_device_ops bfin_sir_ndo = { + .ndo_open = bfin_sir_open, + .ndo_stop = bfin_sir_stop, + .ndo_start_xmit = bfin_sir_hard_xmit, + .ndo_do_ioctl = bfin_sir_ioctl, + .ndo_get_stats = bfin_sir_stats, +}; + +static int bfin_sir_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct bfin_sir_self *self; + unsigned int baudrate_mask; + struct bfin_sir_port *sir_port; + int err; + + if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(per) && \ + per[pdev->id][3] == pdev->id) { + err = peripheral_request_list(per[pdev->id], DRIVER_NAME); + if (err) + return err; + } else { + dev_err(&pdev->dev, "Invalid pdev id, please check board file\n"); + return -ENODEV; + } + + err = -ENOMEM; + sir_port = kmalloc(sizeof(*sir_port), GFP_KERNEL); + if (!sir_port) + goto err_mem_0; + + bfin_sir_init_ports(sir_port, pdev); + + dev = alloc_irdadev(sizeof(*self)); + if (!dev) + goto err_mem_1; + + self = netdev_priv(dev); + self->dev = &pdev->dev; + self->sir_port = sir_port; + sir_port->dev = dev; + + err = bfin_sir_init_iobuf(&self->rx_buff, IRDA_SKB_MAX_MTU); + if (err) + goto err_mem_2; + err = bfin_sir_init_iobuf(&self->tx_buff, IRDA_SIR_MAX_FRAME); + if (err) + goto err_mem_3; + + dev->netdev_ops = &bfin_sir_ndo; + dev->irq = sir_port->irq; + + irda_init_max_qos_capabilies(&self->qos); + + baudrate_mask = IR_9600; + + switch (max_rate) { + case 115200: + baudrate_mask |= IR_115200; + case 57600: + baudrate_mask |= IR_57600; + case 38400: + baudrate_mask |= IR_38400; + case 19200: + baudrate_mask |= IR_19200; + case 9600: + break; + default: + dev_warn(&pdev->dev, "Invalid maximum baud rate, using 9600\n"); + } + + self->qos.baud_rate.bits &= baudrate_mask; + + self->qos.min_turn_time.bits = 1; /* 10 ms or more */ + + irda_qos_bits_to_value(&self->qos); + + err = register_netdev(dev); + + if (err) { + kfree(self->tx_buff.head); +err_mem_3: + kfree(self->rx_buff.head); +err_mem_2: + free_netdev(dev); +err_mem_1: + kfree(sir_port); +err_mem_0: + peripheral_free_list(per[pdev->id]); + } else + platform_set_drvdata(pdev, sir_port); + + return err; +} + +static int bfin_sir_remove(struct platform_device *pdev) +{ + struct bfin_sir_port *sir_port; + struct net_device *dev = NULL; + struct bfin_sir_self *self; + + sir_port = platform_get_drvdata(pdev); + if (!sir_port) + return 0; + dev = sir_port->dev; + self = netdev_priv(dev); + unregister_netdev(dev); + kfree(self->tx_buff.head); + kfree(self->rx_buff.head); + free_netdev(dev); + kfree(sir_port); + + return 0; +} + +static struct platform_driver bfin_ir_driver = { + .probe = bfin_sir_probe, + .remove = bfin_sir_remove, + .suspend = bfin_sir_suspend, + .resume = bfin_sir_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +module_platform_driver(bfin_ir_driver); + +module_param(max_rate, int, 0); +MODULE_PARM_DESC(max_rate, "Maximum baud rate (115200, 57600, 38400, 19200, 9600)"); + +MODULE_AUTHOR("Graf Yang <graf.yang@analog.com>"); +MODULE_DESCRIPTION("Blackfin IrDA driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h new file mode 100644 index 00000000000..29cbde8501e --- /dev/null +++ b/drivers/net/irda/bfin_sir.h @@ -0,0 +1,96 @@ +/* + * Blackfin Infra-red Driver + * + * Copyright 2006-2009 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + * + */ + +#include <linux/serial.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> + +#include <net/irda/irda.h> +#include <net/irda/wrapper.h> +#include <net/irda/irda_device.h> + +#include <asm/irq.h> +#include <asm/cacheflush.h> +#include <asm/dma.h> +#include <asm/portmux.h> +#undef DRIVER_NAME + +#ifdef CONFIG_SIR_BFIN_DMA +struct dma_rx_buf { + char *buf; + int head; + int tail; +}; +#endif + +struct bfin_sir_port { + unsigned char __iomem *membase; + unsigned int irq; + unsigned int lsr; + unsigned long clk; + struct net_device *dev; +#ifdef CONFIG_SIR_BFIN_DMA + int tx_done; + struct dma_rx_buf rx_dma_buf; + struct timer_list rx_dma_timer; + int rx_dma_nrows; +#endif + unsigned int tx_dma_channel; + unsigned int rx_dma_channel; +}; + +struct bfin_sir_port_res { + unsigned long base_addr; + int irq; + unsigned int rx_dma_channel; + unsigned int tx_dma_channel; +}; + +struct bfin_sir_self { + struct bfin_sir_port *sir_port; + spinlock_t lock; + unsigned int open; + int speed; + int newspeed; + + struct sk_buff *txskb; + struct sk_buff *rxskb; + struct net_device_stats stats; + struct device *dev; + struct irlap_cb *irlap; + struct qos_info qos; + + iobuff_t tx_buff; + iobuff_t rx_buff; + + struct work_struct work; + int mtt; +}; + +#define DRIVER_NAME "bfin_sir" + +#define port_membase(port) (((struct bfin_sir_port *)(port))->membase) +#define get_lsr_cache(port) (((struct bfin_sir_port *)(port))->lsr) +#define put_lsr_cache(port, v) (((struct bfin_sir_port *)(port))->lsr = (v)) +#include <asm/bfin_serial.h> + +static const unsigned short per[][4] = { + /* rx pin tx pin NULL uart_number */ + {P_UART0_RX, P_UART0_TX, 0, 0}, + {P_UART1_RX, P_UART1_TX, 0, 1}, + {P_UART2_RX, P_UART2_TX, 0, 2}, + {P_UART3_RX, P_UART3_TX, 0, 3}, +}; diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 16620bd97fb..768dfe9a931 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -49,10 +49,6 @@ /* Look at toshoboe.h (currently in include/net/irda) for details of */ /* Where to get documentation on the chip */ - -static char *rcsid = - "$Id: donauboe.c V2.18 ven jan 10 03:14:16 2003$"; - /* See below for a description of the logic in this driver */ /* User servicable parts */ @@ -60,7 +56,7 @@ static char *rcsid = /* do_probe module parameter Enable this code */ /* Probe code is very useful for understanding how the hardware works */ /* Use it with various combinations of TT_LEN, RX_LEN */ -/* Strongly recomended, disable if the probe fails on your machine */ +/* Strongly recommended, disable if the probe fails on your machine */ /* and send me <james@fishsoup.dhs.org> the output of dmesg */ #define USE_PROBE 1 #undef USE_PROBE @@ -156,10 +152,10 @@ static char *rcsid = #include <linux/delay.h> #include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/rtnetlink.h> -#include <asm/system.h> #include <asm/io.h> #include <net/irda/wrapper.h> @@ -188,7 +184,7 @@ static char *rcsid = #define CONFIG0H_DMA_ON_NORX CONFIG0H_DMA_OFF| OBOE_CONFIG0H_ENDMAC #define CONFIG0H_DMA_ON CONFIG0H_DMA_ON_NORX | OBOE_CONFIG0H_ENRX -static struct pci_device_id toshoboe_pci_tbl[] = { +static DEFINE_PCI_DEVICE_TABLE(toshoboe_pci_tbl) = { { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIRD01, PCI_ANY_ID, PCI_ANY_ID, }, { } /* Terminating entry */ @@ -200,7 +196,7 @@ static char *driver_name = DRIVER_NAME; static int max_baud = 4000000; #ifdef USE_PROBE -static int do_probe = 0; +static bool do_probe = false; #endif @@ -221,7 +217,7 @@ toshoboe_checkfcs (unsigned char *buf, int len) for (i = 0; i < len; ++i) fcs.value = irda_fcs (fcs.value, *(buf++)); - return (fcs.value == GOOD_FCS); + return fcs.value == GOOD_FCS; } /***********************************************************************/ @@ -249,7 +245,7 @@ toshoboe_dumpregs (struct toshoboe_cb *self) { __u32 ringbase; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); ringbase = INB (OBOE_RING_BASE0) << 10; ringbase |= INB (OBOE_RING_BASE1) << 18; @@ -297,7 +293,7 @@ static void toshoboe_disablebm (struct toshoboe_cb *self) { __u8 command; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); pci_read_config_byte (self->pdev, PCI_COMMAND, &command); command &= ~PCI_COMMAND_MASTER; @@ -309,7 +305,7 @@ toshoboe_disablebm (struct toshoboe_cb *self) static void toshoboe_stopchip (struct toshoboe_cb *self) { - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); /*Disable interrupts */ OUTB (0x0, OBOE_IER); @@ -354,7 +350,7 @@ toshoboe_setbaud (struct toshoboe_cb *self) __u16 pconfig = 0; __u8 config0l = 0; - IRDA_DEBUG (2, "%s(%d/%d)\n", __FUNCTION__, self->speed, self->io.speed); + IRDA_DEBUG (2, "%s(%d/%d)\n", __func__, self->speed, self->io.speed); switch (self->speed) { @@ -486,7 +482,7 @@ toshoboe_setbaud (struct toshoboe_cb *self) static void toshoboe_enablebm (struct toshoboe_cb *self) { - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); pci_set_master (self->pdev); } @@ -496,7 +492,7 @@ toshoboe_initring (struct toshoboe_cb *self) { int i; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); for (i = 0; i < TX_SLOTS; ++i) { @@ -554,7 +550,7 @@ toshoboe_startchip (struct toshoboe_cb *self) { __u32 physaddr; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); toshoboe_initring (self); toshoboe_enablebm (self); @@ -595,7 +591,7 @@ toshoboe_startchip (struct toshoboe_cb *self) OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1); OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2); - /*Enable DMA controler in byte mode and RX */ + /*Enable DMA controller in byte mode and RX */ OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H); /* Start up the clocks */ @@ -763,7 +759,7 @@ toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir) if (fir) { memset (buf, 0, TT_LEN); - return (TT_LEN); + return TT_LEN; } fcs.value = INIT_FCS; @@ -822,13 +818,13 @@ toshoboe_probe (struct toshoboe_cb *self) { int i, j, n; #ifdef USE_MIR - int bauds[] = { 9600, 115200, 4000000, 1152000 }; + static const int bauds[] = { 9600, 115200, 4000000, 1152000 }; #else - int bauds[] = { 9600, 115200, 4000000 }; + static const int bauds[] = { 9600, 115200, 4000000 }; #endif unsigned long flags; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); if (request_irq (self->io.irq, toshoboe_probeinterrupt, self->io.irqflags, "toshoboe", (void *) self)) @@ -840,7 +836,7 @@ toshoboe_probe (struct toshoboe_cb *self) /* test 1: SIR filter and back to back */ - for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j) + for (j = 0; j < ARRAY_SIZE(bauds); ++j) { int fir = (j > 1); toshoboe_stopchip (self); @@ -974,7 +970,7 @@ toshoboe_probe (struct toshoboe_cb *self) /* Netdev style code */ /* Transmit something */ -static int +static netdev_tx_t toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) { struct toshoboe_cb *self; @@ -983,14 +979,14 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) unsigned long flags; struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb; - self = (struct toshoboe_cb *) dev->priv; + self = netdev_priv(dev); - IRDA_ASSERT (self != NULL, return 0; ); + IRDA_ASSERT (self != NULL, return NETDEV_TX_OK; ); - IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __FUNCTION__ + IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __func__ ,skb->len,self->txpending,INB (OBOE_ENABLEH)); if (!cb->magic) { - IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __FUNCTION__, cb->magic); + IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __func__, cb->magic); #ifdef DUMP_PACKETS _dumpbufs(skb->data,skb->len,'>'); #endif @@ -998,16 +994,14 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) /* change speed pending, wait for its execution */ if (self->new_speed) - return -EBUSY; + return NETDEV_TX_BUSY; /* device stopped (apm) wait for restart */ if (self->stopped) - return -EBUSY; + return NETDEV_TX_BUSY; toshoboe_checkstuck (self); - dev->trans_start = jiffies; - /* Check if we need to change the speed */ /* But not now. Wait after transmission if mtt not required */ speed=irda_get_next_speed(skb); @@ -1019,13 +1013,13 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) { self->new_speed = speed; IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" , - __FUNCTION__, speed); + __func__, speed); /* if no data, that's all! */ if (!skb->len) { spin_unlock_irqrestore(&self->spinlock, flags); dev_kfree_skb (skb); - return 0; + return NETDEV_TX_OK; } /* True packet, go on, but */ /* do not accept anything before change speed execution */ @@ -1040,7 +1034,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) toshoboe_setbaud (self); spin_unlock_irqrestore(&self->spinlock, flags); dev_kfree_skb (skb); - return 0; + return NETDEV_TX_OK; } } @@ -1053,7 +1047,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) if (self->txpending) { spin_unlock_irqrestore(&self->spinlock, flags); - return -EBUSY; + return NETDEV_TX_BUSY; } /* If in SIR mode we need to generate a string of XBOFs */ @@ -1061,7 +1055,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) /* which we will add a wrong checksum to */ mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt); - IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __FUNCTION__ + IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __func__ ,skb->len,mtt,self->txpending); if (mtt) { @@ -1105,11 +1099,11 @@ dumpbufs(skb->data,skb->len,'>'); if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS) { - IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __FUNCTION__ + IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __func__ ,skb->len, self->ring->tx[self->txs].control, self->txpending); toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); spin_unlock_irqrestore(&self->spinlock, flags); - return -EBUSY; + return NETDEV_TX_BUSY; } if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON) @@ -1119,7 +1113,7 @@ dumpbufs(skb->data,skb->len,'>'); else { len = skb->len; - memcpy (self->tx_bufs[self->txs], skb->data, len); + skb_copy_from_linear_data(skb, self->tx_bufs[self->txs], len); } self->ring->tx[self->txs].len = len & 0x0fff; @@ -1147,7 +1141,7 @@ dumpbufs(skb->data,skb->len,'>'); spin_unlock_irqrestore(&self->spinlock, flags); dev_kfree_skb (skb); - return 0; + return NETDEV_TX_OK; } /*interrupt handler */ @@ -1183,7 +1177,7 @@ toshoboe_interrupt (int irq, void *dev_id) if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS) self->txpending++; } - IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __FUNCTION__ + IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __func__ ,irqstat,txp,self->txpending); txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK; @@ -1198,13 +1192,13 @@ toshoboe_interrupt (int irq, void *dev_id) txp = txpc; txpc++; txpc %= TX_SLOTS; - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX; } - self->stats.tx_packets--; + self->netdev->stats.tx_packets--; #else - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; #endif toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); } @@ -1213,7 +1207,7 @@ toshoboe_interrupt (int irq, void *dev_id) { self->speed = self->new_speed; IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n", - __FUNCTION__, self->speed); + __func__, self->speed); toshoboe_setbaud (self); } @@ -1228,7 +1222,7 @@ toshoboe_interrupt (int irq, void *dev_id) { int len = self->ring->rx[self->rxs].len; skb = NULL; - IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __FUNCTION__ + IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __func__ ,len,self->ring->rx[self->rxs].control); #ifdef DUMP_PACKETS @@ -1250,7 +1244,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); len -= 2; else len = 0; - IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __FUNCTION__, len,enable); + IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __func__, len,enable); } #ifdef USE_MIR @@ -1260,7 +1254,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); len -= 2; else len = 0; - IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __FUNCTION__, len,enable); + IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __func__, len,enable); } #endif else if (enable & OBOE_ENABLEH_FIRON) @@ -1269,10 +1263,10 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); len -= 4; /*FIXME: check this */ else len = 0; - IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __FUNCTION__, len,enable); + IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __func__, len,enable); } else - IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __FUNCTION__, len,enable); + IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __func__, len,enable); if (len) { @@ -1282,18 +1276,18 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); skb_reserve (skb, 1); skb_put (skb, len); - memcpy (skb->data, self->rx_bufs[self->rxs], len); - - self->stats.rx_packets++; + skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs], + len); + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons (ETH_P_IRDA); } else { printk (KERN_INFO "%s(), memory squeeze, dropping frame.\n", - __FUNCTION__); + __func__); } } } @@ -1305,7 +1299,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); /* (SIR) data is splitted in several slots. */ /* we have to join all the received buffers received */ /*in a large buffer before checking CRC. */ - IRDA_DEBUG (0, "%s.err:%x(%x)\n", __FUNCTION__ + IRDA_DEBUG (0, "%s.err:%x(%x)\n", __func__ ,len,self->ring->rx[self->rxs].control); } @@ -1333,7 +1327,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); if (irqstat & OBOE_INT_SIP) { self->int_sip++; - IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __FUNCTION__ + IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __func__ ,self->int_sip,irqstat,self->txpending); } return IRQ_HANDLED; @@ -1347,7 +1341,7 @@ toshoboe_net_open (struct net_device *dev) unsigned long flags; int rc; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); self = netdev_priv(dev); @@ -1358,7 +1352,7 @@ toshoboe_net_open (struct net_device *dev) return 0; rc = request_irq (self->io.irq, toshoboe_interrupt, - IRQF_SHARED | IRQF_DISABLED, dev->name, self); + IRQF_SHARED, dev->name, self); if (rc) return rc; @@ -1385,10 +1379,10 @@ toshoboe_net_close (struct net_device *dev) { struct toshoboe_cb *self; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); IRDA_ASSERT (dev != NULL, return -1; ); - self = (struct toshoboe_cb *) dev->priv; + self = netdev_priv(dev); /* Stop device */ netif_stop_queue(dev); @@ -1426,11 +1420,11 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) IRDA_ASSERT (dev != NULL, return -1; ); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT (self != NULL, return -1; ); - IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); /* Disable interrupts & save flags */ spin_lock_irqsave(&self->spinlock, flags); @@ -1442,7 +1436,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) * speed, so we still must allow for speed change within * interrupt context. */ - IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ + IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __func__ ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); if (!in_interrupt () && !capable (CAP_NET_ADMIN)) { ret = -EPERM; @@ -1455,7 +1449,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) self->new_speed = irq->ifr_baudrate; break; case SIOCSMEDIABUSY: /* Set media busy */ - IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ + IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __func__ ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); if (!capable (CAP_NET_ADMIN)) { ret = -EPERM; @@ -1465,11 +1459,11 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) break; case SIOCGRECEIVING: /* Check if we are receiving right now */ irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0; - IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __FUNCTION__ + IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __func__ ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving ); break; default: - IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); ret = -EOPNOTSUPP; } out: @@ -1494,9 +1488,9 @@ static void toshoboe_close (struct pci_dev *pci_dev) { int i; - struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); + struct toshoboe_cb *self = pci_get_drvdata(pci_dev); - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); IRDA_ASSERT (self != NULL, return; ); @@ -1528,6 +1522,13 @@ toshoboe_close (struct pci_dev *pci_dev) free_netdev(self->netdev); } +static const struct net_device_ops toshoboe_netdev_ops = { + .ndo_open = toshoboe_net_open, + .ndo_stop = toshoboe_net_close, + .ndo_start_xmit = toshoboe_hard_xmit, + .ndo_do_ioctl = toshoboe_net_ioctl, +}; + static int toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) { @@ -1537,7 +1538,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) int ok = 0; int err; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); if ((err=pci_enable_device(pci_dev))) return err; @@ -1550,7 +1551,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) return -ENOMEM; } - self = dev->priv; + self = netdev_priv(dev); self->netdev = dev; self->pdev = pci_dev; self->base = pci_resource_start(pci_dev,0); @@ -1558,7 +1559,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) self->io.fir_base = self->base; self->io.fir_ext = OBOE_IO_EXTENT; self->io.irq = pci_dev->irq; - self->io.irqflags = IRQF_SHARED | IRQF_DISABLED; + self->io.irqflags = IRQF_SHARED; self->speed = self->io.speed = 9600; self->async = 0; @@ -1603,10 +1604,9 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) irda_qos_bits_to_value (&self->qos); /* Allocate twice the size to guarantee alignment */ - self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL); + self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL); if (!self->ringbuf) { - printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n"); err = -ENOMEM; goto freeregion; } @@ -1645,7 +1645,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) if (!ok) { - printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n"); err = -ENOMEM; goto freebufs; } @@ -1660,12 +1659,8 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) } #endif - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pci_dev->dev); - dev->hard_start_xmit = toshoboe_hard_xmit; - dev->open = toshoboe_net_open; - dev->stop = toshoboe_net_close; - dev->do_ioctl = toshoboe_net_ioctl; + dev->netdev_ops = &toshoboe_netdev_ops; err = register_netdev(dev); if (err) @@ -1678,7 +1673,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) pci_set_drvdata(pci_dev,self); - printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid); + printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n"); return 0; @@ -1701,11 +1696,11 @@ freeself: static int toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap) { - struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); + struct toshoboe_cb *self = pci_get_drvdata(pci_dev); unsigned long flags; int i = 10; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); if (!self || self->stopped) return 0; @@ -1715,7 +1710,7 @@ toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap) /* Flush all packets */ while ((i--) && (self->txpending)) - udelay (10000); + msleep(10); spin_lock_irqsave(&self->spinlock, flags); @@ -1730,10 +1725,10 @@ toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap) static int toshoboe_wakeup (struct pci_dev *pci_dev) { - struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); + struct toshoboe_cb *self = pci_get_drvdata(pci_dev); unsigned long flags; - IRDA_DEBUG (4, "%s()\n", __FUNCTION__); + IRDA_DEBUG (4, "%s()\n", __func__); if (!self || !self->stopped) return 0; diff --git a/drivers/net/irda/donauboe.h b/drivers/net/irda/donauboe.h index 2ab173d9a0e..d92d54e839b 100644 --- a/drivers/net/irda/donauboe.h +++ b/drivers/net/irda/donauboe.h @@ -30,7 +30,7 @@ * or the type-DO IR port. * * IrDA chip set list from Toshiba Computer Engineering Corp. - * model method maker controler Version + * model method maker controller Version * Portege 320CT FIR,SIR Toshiba Oboe(Triangle) * Portege 3010CT FIR,SIR Toshiba Oboe(Sydney) * Portege 3015CT FIR,SIR Toshiba Oboe(Sydney) @@ -51,10 +51,10 @@ /* The documentation for this chip is allegedly released */ /* However I have not seen it, not have I managed to contact */ -/* anyone who has. HOWEVER the chip bears a striking resemblence */ +/* anyone who has. HOWEVER the chip bears a striking resemblance */ /* to the IrDA controller in the Toshiba RISC TMPR3922 chip */ /* the documentation for this is freely available at */ -/* http://www.toshiba.com/taec/components/Generic/TMPR3922.shtml */ +/* http://www.madingley.org/james/resources/toshoboe/TMPR3922.pdf */ /* The mapping between the registers in that document and the */ /* Registers in the 701 oboe chip are as follows */ @@ -113,7 +113,7 @@ /* RxOver overflow in Recv FIFO */ /* SipRcv received serial gap (or other condition you set) */ /* Interrupts are enabled by writing a one to the IER register */ -/* Interrupts are cleared by writting a one to the ISR register */ +/* Interrupts are cleared by writing a one to the ISR register */ /* */ /* 6. The remaining registers: 0x6 and 0x3 appear to be */ /* reserved parts of 16 or 32 bit registersthe remainder */ @@ -273,7 +273,7 @@ struct OboeSlot __u8 control; /*Slot control/status see below */ __u32 address; /*Slot buffer address */ } -__attribute__ ((packed)); +__packed; #define OBOE_NTASKS OBOE_TXRING_OFFSET_IN_SLOTS @@ -308,7 +308,6 @@ struct OboeRing struct toshoboe_cb { struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct tty_driver ttydev; struct irlap_cb *irlap; /* The link layer we are binded to */ diff --git a/drivers/net/irda/ep7211_ir.c b/drivers/net/irda/ep7211_ir.c deleted file mode 100644 index 4cba38f7e4a..00000000000 --- a/drivers/net/irda/ep7211_ir.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * IR port driver for the Cirrus Logic EP7211 processor. - * - * Copyright 2001, Blue Mug Inc. All rights reserved. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> -#include <linux/spinlock.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -#include <asm/io.h> -#include <asm/hardware.h> - -#define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */ -#define MAX_DELAY 10000 /* 1 ms */ - -static void ep7211_ir_open(dongle_t *self, struct qos_info *qos); -static void ep7211_ir_close(dongle_t *self); -static int ep7211_ir_change_speed(struct irda_task *task); -static int ep7211_ir_reset(struct irda_task *task); - -static DEFINE_SPINLOCK(ep7211_lock); - -static struct dongle_reg dongle = { - .type = IRDA_EP7211_IR, - .open = ep7211_ir_open, - .close = ep7211_ir_close, - .reset = ep7211_ir_reset, - .change_speed = ep7211_ir_change_speed, - .owner = THIS_MODULE, -}; - -static void ep7211_ir_open(dongle_t *self, struct qos_info *qos) -{ - unsigned int syscon1, flags; - - spin_lock_irqsave(&ep7211_lock, flags); - - /* Turn on the SIR encoder. */ - syscon1 = clps_readl(SYSCON1); - syscon1 |= SYSCON1_SIREN; - clps_writel(syscon1, SYSCON1); - - /* XXX: We should disable modem status interrupts on the first - UART (interrupt #14). */ - - spin_unlock_irqrestore(&ep7211_lock, flags); -} - -static void ep7211_ir_close(dongle_t *self) -{ - unsigned int syscon1, flags; - - spin_lock_irqsave(&ep7211_lock, flags); - - /* Turn off the SIR encoder. */ - syscon1 = clps_readl(SYSCON1); - syscon1 &= ~SYSCON1_SIREN; - clps_writel(syscon1, SYSCON1); - - /* XXX: If we've disabled the modem status interrupts, we should - reset them back to their original state. */ - - spin_unlock_irqrestore(&ep7211_lock, flags); -} - -/* - * Function ep7211_ir_change_speed (task) - * - * Change speed of the EP7211 I/R port. We don't really have to do anything - * for the EP7211 as long as the rate is being changed at the serial port - * level. - */ -static int ep7211_ir_change_speed(struct irda_task *task) -{ - irda_task_next_state(task, IRDA_TASK_DONE); - return 0; -} - -/* - * Function ep7211_ir_reset (task) - * - * Reset the EP7211 I/R. We don't really have to do anything. - * - */ -static int ep7211_ir_reset(struct irda_task *task) -{ - irda_task_next_state(task, IRDA_TASK_DONE); - return 0; -} - -/* - * Function ep7211_ir_init(void) - * - * Initialize EP7211 I/R module - * - */ -static int __init ep7211_ir_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -/* - * Function ep7211_ir_cleanup(void) - * - * Cleanup EP7211 I/R module - * - */ -static void __exit ep7211_ir_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -MODULE_AUTHOR("Jon McClintock <jonm@bluemug.com>"); -MODULE_DESCRIPTION("EP7211 I/R driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-8"); /* IRDA_EP7211_IR */ - -module_init(ep7211_ir_init); -module_exit(ep7211_ir_cleanup); diff --git a/drivers/net/irda/esi-sir.c b/drivers/net/irda/esi-sir.c index a908df7c4b9..019a3e848bc 100644 --- a/drivers/net/irda/esi-sir.c +++ b/drivers/net/irda/esi-sir.c @@ -25,9 +25,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c deleted file mode 100644 index d3a61af6402..00000000000 --- a/drivers/net/irda/esi.c +++ /dev/null @@ -1,149 +0,0 @@ -/********************************************************************* - * - * Filename: esi.c - * Version: 1.5 - * Description: Driver for the Extended Systems JetEye PC dongle - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Fri Dec 17 09:14:04 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * 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 - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -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_reg dongle = { - .type = IRDA_ESI_DONGLE, - .open = esi_open, - .close = esi_close, - .reset = esi_reset, - .change_speed = esi_change_speed, - .owner = THIS_MODULE, -}; - -static int __init esi_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit esi_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void esi_open(dongle_t *self, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200; - qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */ -} - -static void esi_close(dongle_t *dongle) -{ - /* Power off dongle */ - dongle->set_dtr_rts(dongle->dev, FALSE, FALSE); -} - -/* - * Function esi_change_speed (task) - * - * Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle - * - */ -static int esi_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - int dtr, rts; - - switch (speed) { - case 19200: - dtr = TRUE; - rts = FALSE; - break; - case 115200: - dtr = rts = TRUE; - break; - case 9600: - default: - dtr = FALSE; - rts = TRUE; - break; - } - - /* Change speed of dongle */ - self->set_dtr_rts(self->dev, dtr, rts); - self->speed = speed; - - irda_task_next_state(task, IRDA_TASK_DONE); - - return 0; -} - -/* - * Function esi_reset (task) - * - * Reset dongle; - * - */ -static int esi_reset(struct irda_task *task) -{ - 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; -} - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); -MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-1"); /* IRDA_ESI_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize ESI module - * - */ -module_init(esi_init); - -/* - * Function cleanup_module (void) - * - * Cleanup ESI module - * - */ -module_exit(esi_cleanup); - diff --git a/drivers/net/irda/girbil-sir.c b/drivers/net/irda/girbil-sir.c index 0d2fe87fb9b..96cdecff349 100644 --- a/drivers/net/irda/girbil-sir.c +++ b/drivers/net/irda/girbil-sir.c @@ -16,7 +16,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -38,7 +38,7 @@ static int girbil_change_speed(struct sir_dev *dev, unsigned speed); /* Control register 1 */ #define GIRBIL_TXEN 0x01 /* Enable transmitter */ #define GIRBIL_RXEN 0x02 /* Enable receiver */ -#define GIRBIL_ECAN 0x04 /* Cancel self emmited data */ +#define GIRBIL_ECAN 0x04 /* Cancel self emitted data */ #define GIRBIL_ECHO 0x08 /* Echo control characters */ /* LED Current Register (0x2) */ @@ -86,7 +86,7 @@ static int girbil_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power on dongle */ sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -102,7 +102,7 @@ static int girbil_open(struct sir_dev *dev) static int girbil_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -126,7 +126,7 @@ static int girbil_change_speed(struct sir_dev *dev, unsigned speed) u8 control[2]; static int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* dongle alread reset - port and dongle at default speed */ @@ -179,7 +179,7 @@ static int girbil_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s - undefined state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s - undefined state %d\n", __func__, state); ret = -EINVAL; break; } @@ -209,7 +209,7 @@ static int girbil_reset(struct sir_dev *dev) u8 control = GIRBIL_TXEN | GIRBIL_RXEN; int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); switch (state) { case SIRDEV_STATE_DONGLE_RESET: @@ -241,7 +241,7 @@ static int girbil_reset(struct sir_dev *dev) break; default: - IRDA_ERROR("%s(), undefined state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s(), undefined state %d\n", __func__, state); ret = -1; break; } diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c deleted file mode 100644 index 248aeb0c726..00000000000 --- a/drivers/net/irda/girbil.c +++ /dev/null @@ -1,250 +0,0 @@ -/********************************************************************* - * - * Filename: girbil.c - * Version: 1.2 - * Description: Implementation for the Greenwich GIrBIL dongle - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Sat Feb 6 21:02:33 1999 - * Modified at: Fri Dec 17 09:13:20 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1999 Dag Brattli, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -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 */ -#define GIRBIL_RXEN 0x02 /* Enable receiver */ -#define GIRBIL_ECAN 0x04 /* Cancel self emmited data */ -#define GIRBIL_ECHO 0x08 /* Echo control characters */ - -/* LED Current Register (0x2) */ -#define GIRBIL_HIGH 0x20 -#define GIRBIL_MEDIUM 0x21 -#define GIRBIL_LOW 0x22 - -/* Baud register (0x3) */ -#define GIRBIL_2400 0x30 -#define GIRBIL_4800 0x31 -#define GIRBIL_9600 0x32 -#define GIRBIL_19200 0x33 -#define GIRBIL_38400 0x34 -#define GIRBIL_57600 0x35 -#define GIRBIL_115200 0x36 - -/* Mode register (0x4) */ -#define GIRBIL_IRDA 0x40 -#define GIRBIL_ASK 0x41 - -/* Control register 2 (0x5) */ -#define GIRBIL_LOAD 0x51 /* Load the new baud rate value */ - -static struct dongle_reg dongle = { - .type = IRDA_GIRBIL_DONGLE, - .open = girbil_open, - .close = girbil_close, - .reset = girbil_reset, - .change_speed = girbil_change_speed, - .owner = THIS_MODULE, -}; - -static int __init girbil_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit girbil_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void girbil_open(dongle_t *self, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits = 0x03; -} - -static void girbil_close(dongle_t *self) -{ - /* Power off dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * Function girbil_change_speed (dev, speed) - * - * Set the speed for the Girbil type dongle. - * - */ -static int girbil_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - __u8 control[2]; - int ret = 0; - - self->speed_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - /* 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 IRDA_TASK_CHILD_WAIT: - IRDA_WARNING("%s(), resetting dongle timed out!\n", - __FUNCTION__); - ret = -1; - break; - 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 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->speed_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - ret = -1; - break; - } - return ret; -} - -/* - * Function girbil_reset (driver) - * - * This function resets the girbil dongle. - * - * Algorithm: - * 0. set RTS, and wait at least 5 ms - * 1. clear RTS - */ -static int girbil_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u8 control = GIRBIL_TXEN | GIRBIL_RXEN; - int ret = 0; - - self->reset_task = task; - - 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(20); - 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(20); - 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); - self->reset_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - break; - } - return ret; -} - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); -MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-4"); /* IRDA_GIRBIL_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize Girbil module - * - */ -module_init(girbil_init); - -/* - * Function cleanup_module (void) - * - * Cleanup Girbil module - * - */ -module_exit(girbil_cleanup); - diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6e95645e724..925b78cc979 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -58,7 +58,6 @@ #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/types.h> -#include <linux/init.h> #include <linux/skbuff.h> #include <linux/netdevice.h> #include <linux/slab.h> @@ -111,7 +110,8 @@ static void irda_usb_init_qos(struct irda_usb_cb *self) ; static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); static void irda_usb_disconnect(struct usb_interface *intf); static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); -static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb, + struct net_device *dev); static int irda_usb_open(struct irda_usb_cb *self); static void irda_usb_close(struct irda_usb_cb *self); static void speed_bulk_callback(struct urb *urb); @@ -122,7 +122,6 @@ static int irda_usb_net_open(struct net_device *dev); static int irda_usb_net_close(struct net_device *dev); static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void irda_usb_net_timeout(struct net_device *dev); -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev); /************************ TRANSMIT ROUTINES ************************/ /* @@ -177,12 +176,12 @@ static void irda_usb_build_header(struct irda_usb_cb *self, (!force) && (self->speed != -1)) { /* No speed and xbofs change here * (we'll do it later in the write callback) */ - IRDA_DEBUG(2, "%s(), not changing speed yet\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), not changing speed yet\n", __func__); *header = 0; return; } - IRDA_DEBUG(2, "%s(), changing speed to %d\n", __FUNCTION__, self->new_speed); + IRDA_DEBUG(2, "%s(), changing speed to %d\n", __func__, self->new_speed); self->speed = self->new_speed; /* We will do ` self->new_speed = -1; ' in the completion * handler just in case the current URB fail - Jean II */ @@ -228,7 +227,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, /* Set the negotiated additional XBOFS */ if (self->new_xbofs != -1) { - IRDA_DEBUG(2, "%s(), changing xbofs to %d\n", __FUNCTION__, self->new_xbofs); + IRDA_DEBUG(2, "%s(), changing xbofs to %d\n", __func__, self->new_xbofs); self->xbofs = self->new_xbofs; /* We will do ` self->new_xbofs = -1; ' in the completion * handler just in case the current URB fail - Jean II */ @@ -302,13 +301,13 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) struct urb *urb; int ret; - IRDA_DEBUG(2, "%s(), speed=%d, xbofs=%d\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), speed=%d, xbofs=%d\n", __func__, self->new_speed, self->new_xbofs); /* Grab the speed URB */ urb = self->speed_urb; if (urb->status != 0) { - IRDA_WARNING("%s(), URB still in use!\n", __FUNCTION__); + IRDA_WARNING("%s(), URB still in use!\n", __func__); return; } @@ -334,7 +333,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Irq disabled -> GFP_ATOMIC */ if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Speed URB\n", __FUNCTION__); + IRDA_WARNING("%s(), failed Speed URB\n", __func__); } } @@ -347,7 +346,7 @@ static void speed_bulk_callback(struct urb *urb) { struct irda_usb_cb *self = urb->context; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* We should always have a context */ IRDA_ASSERT(self != NULL, return;); @@ -357,7 +356,7 @@ static void speed_bulk_callback(struct urb *urb) /* Check for timeout and other USB nasties */ if (urb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ - IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags); + IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __func__, urb->status, urb->transfer_flags); /* Don't do anything here, that might confuse the USB layer. * Instead, we will wait for irda_usb_net_timeout(), the @@ -370,7 +369,7 @@ static void speed_bulk_callback(struct urb *urb) /* urb is now available */ //urb->status = 0; -> tested above - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; @@ -382,17 +381,17 @@ static void speed_bulk_callback(struct urb *urb) /* * Send an IrDA frame to the USB dongle (for transmission) */ -static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) +static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) { - struct irda_usb_cb *self = netdev->priv; + struct irda_usb_cb *self = netdev_priv(netdev); struct urb *urb = self->tx_urb; unsigned long flags; s32 speed; s16 xbofs; int res, mtt; - int err = 1; /* Failed */ - IRDA_DEBUG(4, "%s() on %s\n", __FUNCTION__, netdev->name); + IRDA_DEBUG(4, "%s() on %s\n", __func__, netdev->name); netif_stop_queue(netdev); @@ -403,7 +402,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) * We need to check self->present under the spinlock because * of irda_usb_disconnect() is synchronous - Jean II */ if (!self->present) { - IRDA_DEBUG(0, "%s(), Device is gone...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Device is gone...\n", __func__); goto drop; } @@ -431,35 +430,22 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) irda_usb_change_speed_xbofs(self); netdev->trans_start = jiffies; /* Will netif_wake_queue() in callback */ - err = 0; /* No error */ goto drop; } } if (urb->status != 0) { - IRDA_WARNING("%s(), URB still in use!\n", __FUNCTION__); + IRDA_WARNING("%s(), URB still in use!\n", __func__); goto drop; } - /* Make sure there is room for IrDA-USB header. The actual - * allocation will be done lower in skb_push(). - * Also, we don't use directly skb_cow(), because it require - * headroom >= 16, which force unnecessary copies - Jean II */ - if (skb_headroom(skb) < self->header_length) { - IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); - if (skb_cow(skb, self->header_length)) { - IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); - goto drop; - } - } + skb_copy_from_linear_data(skb, self->tx_buff + self->header_length, skb->len); /* Change setting for next frame */ - if (self->capability & IUC_STIR421X) { __u8 turnaround_time; - __u8* frame; + __u8* frame = self->tx_buff; turnaround_time = get_turnaround_time( skb ); - frame= skb_push(skb, self->header_length); irda_usb_build_header(self, frame, 0); frame[2] = turnaround_time; if ((skb->len != 0) && @@ -472,17 +458,17 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) frame[1] = 0; } } else { - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); + irda_usb_build_header(self, self->tx_buff, 0); } /* FIXME: Make macro out of this one */ ((struct irda_skb_cb *)skb->cb)->context = self; - usb_fill_bulk_urb(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), - skb->data, IRDA_SKB_MAX_MTU, + self->tx_buff, skb->len + self->header_length, write_bulk_callback, skb); - urb->transfer_buffer_length = skb->len; + /* This flag (URB_ZERO_PACKET) indicates that what we send is not * a continuous stream of data but separate packets. * In this case, the USB layer will insert an empty USB frame (TD) @@ -536,26 +522,26 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */ if ((res = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Tx URB\n", __FUNCTION__); - self->stats.tx_errors++; + IRDA_WARNING("%s(), failed Tx URB\n", __func__); + netdev->stats.tx_errors++; /* Let USB recover : We will catch that in the watchdog */ /*netif_start_queue(netdev);*/ } else { /* Increment packet stats */ - self->stats.tx_packets++; - self->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; netdev->trans_start = jiffies; } spin_unlock_irqrestore(&self->lock, flags); - return 0; + return NETDEV_TX_OK; drop: /* Drop silently the skb and exit */ dev_kfree_skb(skb); spin_unlock_irqrestore(&self->lock, flags); - return err; /* Usually 1 */ + return NETDEV_TX_OK; } /*------------------------------------------------------------------*/ @@ -568,7 +554,7 @@ static void write_bulk_callback(struct urb *urb) struct sk_buff *skb = urb->context; struct irda_usb_cb *self = ((struct irda_skb_cb *) skb->cb)->context; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* We should always have a context */ IRDA_ASSERT(self != NULL, return;); @@ -582,7 +568,7 @@ static void write_bulk_callback(struct urb *urb) /* Check for timeout and other USB nasties */ if (urb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ - IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags); + IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __func__, urb->status, urb->transfer_flags); /* Don't do anything here, that might confuse the USB layer, * and we could go in recursion and blow the kernel stack... @@ -601,7 +587,7 @@ static void write_bulk_callback(struct urb *urb) /* If the network is closed, stop everything */ if ((!self->netopen) || (!self->present)) { - IRDA_DEBUG(0, "%s(), Network is gone...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network is gone...\n", __func__); spin_unlock_irqrestore(&self->lock, flags); return; } @@ -612,10 +598,10 @@ static void write_bulk_callback(struct urb *urb) (self->new_xbofs != self->xbofs)) { /* We haven't changed speed yet (because of * IUC_SPEED_BUG), so do it now - Jean II */ - IRDA_DEBUG(1, "%s(), Changing speed now...\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), Changing speed now...\n", __func__); irda_usb_change_speed_xbofs(self); } else { - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; /* Done, waiting for next packet */ @@ -640,11 +626,11 @@ static void write_bulk_callback(struct urb *urb) static void irda_usb_net_timeout(struct net_device *netdev) { unsigned long flags; - struct irda_usb_cb *self = netdev->priv; + struct irda_usb_cb *self = netdev_priv(netdev); struct urb *urb; int done = 0; /* If we have made any progress */ - IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __func__); IRDA_ASSERT(self != NULL, return;); /* Protect us from USB callbacks, net Tx and else. */ @@ -652,7 +638,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) /* self->present *MUST* be read under spinlock */ if (!self->present) { - IRDA_WARNING("%s(), device not present!\n", __FUNCTION__); + IRDA_WARNING("%s(), device not present!\n", __func__); netif_stop_queue(netdev); spin_unlock_irqrestore(&self->lock, flags); return; @@ -689,7 +675,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, urb->status, urb->transfer_flags); /* Increase error count */ - self->stats.tx_errors++; + netdev->stats.tx_errors++; #ifdef IU_BUG_KICK_TIMEOUT /* Can't be a bad idea to reset the speed ;-) - Jean II */ @@ -775,7 +761,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc struct irda_skb_cb *cb; int ret; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* This should never happen */ IRDA_ASSERT(skb != NULL, return;); @@ -798,7 +784,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc /* If this ever happen, we are in deep s***. * Basically, the Rx path will stop... */ IRDA_WARNING("%s(), Failed to submit Rx URB %d\n", - __FUNCTION__, ret); + __func__, ret); } } @@ -819,7 +805,7 @@ static void irda_usb_receive(struct urb *urb) struct urb *next_urb; unsigned int len, docopy; - IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); + IRDA_DEBUG(2, "%s(), len=%d\n", __func__, urb->actual_length); /* Find ourselves */ cb = (struct irda_skb_cb *) skb->cb; @@ -829,7 +815,7 @@ static void irda_usb_receive(struct urb *urb) /* If the network is closed or the device gone, stop everything */ if ((!self->netopen) || (!self->present)) { - IRDA_DEBUG(0, "%s(), Network is gone!\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network is gone!\n", __func__); /* Don't re-submit the URB : will stall the Rx path */ return; } @@ -838,7 +824,7 @@ static void irda_usb_receive(struct urb *urb) if (urb->status != 0) { switch (urb->status) { case -EILSEQ: - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; /* Also precursor to a hot-unplug on UHCI. */ /* Fallthrough... */ case -ECONNRESET: @@ -851,8 +837,8 @@ static void irda_usb_receive(struct urb *urb) case -ETIME: /* Usually precursor to a hot-unplug on OHCI. */ default: - self->stats.rx_errors++; - IRDA_DEBUG(0, "%s(), RX status %d, transfer_flags 0x%04X \n", __FUNCTION__, urb->status, urb->transfer_flags); + self->netdev->stats.rx_errors++; + IRDA_DEBUG(0, "%s(), RX status %d, transfer_flags 0x%04X\n", __func__, urb->status, urb->transfer_flags); break; } /* If we received an error, we don't want to resubmit the @@ -865,7 +851,7 @@ static void irda_usb_receive(struct urb *urb) * hot unplug of the dongle... * Lowest effective timer is 10ms... * Jean II */ - self->rx_defer_timer.function = &irda_usb_rx_defer_expired; + self->rx_defer_timer.function = irda_usb_rx_defer_expired; self->rx_defer_timer.data = (unsigned long) urb; mod_timer(&self->rx_defer_timer, jiffies + (10 * HZ / 1000)); return; @@ -873,7 +859,7 @@ static void irda_usb_receive(struct urb *urb) /* Check for empty frames */ if (urb->actual_length <= self->header_length) { - IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); + IRDA_WARNING("%s(), empty frame!\n", __func__); goto done; } @@ -902,7 +888,7 @@ static void irda_usb_receive(struct urb *urb) IRDA_SKB_MAX_MTU); if (!newskb) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; /* We could deliver the current skb, but this would stall * the Rx path. Better drop the packet... Jean II */ goto done; @@ -914,7 +900,7 @@ static void irda_usb_receive(struct urb *urb) if(docopy) { /* Copy packet, so we can recycle the original */ - memcpy(newskb->data, skb->data, urb->actual_length); + skb_copy_from_linear_data(skb, newskb->data, urb->actual_length); /* Deliver this new skb */ dataskb = newskb; /* And hook the old skb to the URB @@ -933,15 +919,14 @@ static void irda_usb_receive(struct urb *urb) /* Ask the networking layer to queue the packet for the IrDA stack */ dataskb->dev = self->netdev; - dataskb->mac.raw = dataskb->data; + skb_reset_mac_header(dataskb); dataskb->protocol = htons(ETH_P_IRDA); len = dataskb->len; netif_rx(dataskb); /* Keep stats up to date */ - self->stats.rx_bytes += len; - self->stats.rx_packets++; - self->netdev->last_rx = jiffies; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; done: /* Note : at this point, the URB we've just received (urb) @@ -979,7 +964,7 @@ static void irda_usb_rx_defer_expired(unsigned long data) struct irda_skb_cb *cb; struct urb *next_urb; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Find ourselves */ cb = (struct irda_skb_cb *) skb->cb; @@ -1036,7 +1021,7 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) * Upload firmware code to SigmaTel 421X IRDA-USB dongle */ static int stir421x_fw_upload(struct irda_usb_cb *self, - unsigned char *patch, + const unsigned char *patch, const unsigned int patch_len) { int ret = -ENOMEM; @@ -1065,10 +1050,12 @@ static int stir421x_fw_upload(struct irda_usb_cb *self, patch_block, block_size, &actual_len, msecs_to_jiffies(500)); IRDA_DEBUG(3,"%s(): Bulk send %u bytes, ret=%d\n", - __FUNCTION__, actual_len, ret); + __func__, actual_len, ret); if (ret < 0) break; + + mdelay(10); } kfree(patch_block); @@ -1083,11 +1070,11 @@ static int stir421x_fw_upload(struct irda_usb_cb *self, */ static int stir421x_patch_device(struct irda_usb_cb *self) { - unsigned int i; - int ret; - char stir421x_fw_name[11]; - const struct firmware *fw; - unsigned char *fw_version_ptr; /* pointer to version string */ + unsigned int i; + int ret; + char stir421x_fw_name[12]; + const struct firmware *fw; + const unsigned char *fw_version_ptr; /* pointer to version string */ unsigned long fw_version = 0; /* @@ -1102,7 +1089,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) /* We get a patch from userspace */ IRDA_MESSAGE("%s(): Received firmware %s (%zu bytes)\n", - __FUNCTION__, stir421x_fw_name, fw->size); + __func__, stir421x_fw_name, fw->size); ret = -EINVAL; @@ -1126,21 +1113,21 @@ static int stir421x_patch_device(struct irda_usb_cb *self) + (build % 10); IRDA_DEBUG(3, "%s(): Firmware Product version %ld\n", - __FUNCTION__, fw_version); + __func__, fw_version); } } - if (self->usbdev->descriptor.bcdDevice == fw_version) { + if (self->usbdev->descriptor.bcdDevice == cpu_to_le16(fw_version)) { /* * If we're here, we've found a correct patch * The actual image starts after the "STMP" keyword * so forward to the firmware header tag */ - for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) - && (i < fw->size); i++) ; + for (i = 0; i < fw->size && fw->data[i] != + STIR421X_PATCH_END_OF_HDR_TAG; i++) ; /* here we check for the out of buffer case */ - if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) - && (i < STIR421X_PATCH_CODE_OFFSET)) { + if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size && + STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) { if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG, sizeof(STIR421X_PATCH_STMP_TAG) - 1)) { @@ -1178,23 +1165,27 @@ static int stir421x_patch_device(struct irda_usb_cb *self) static int irda_usb_net_open(struct net_device *netdev) { struct irda_usb_cb *self; + unsigned long flags; char hwname[16]; int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); IRDA_ASSERT(netdev != NULL, return -1;); - self = (struct irda_usb_cb *) netdev->priv; + self = netdev_priv(netdev); IRDA_ASSERT(self != NULL, return -1;); + spin_lock_irqsave(&self->lock, flags); /* Can only open the device if it's there */ if(!self->present) { - IRDA_WARNING("%s(), device not present!\n", __FUNCTION__); + spin_unlock_irqrestore(&self->lock, flags); + IRDA_WARNING("%s(), device not present!\n", __func__); return -1; } if(self->needspatch) { - IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; + spin_unlock_irqrestore(&self->lock, flags); + IRDA_WARNING("%s(), device needs patch\n", __func__) ; return -EIO ; } @@ -1208,6 +1199,7 @@ static int irda_usb_net_open(struct net_device *netdev) /* To do *before* submitting Rx urbs and starting net Tx queue * Jean II */ self->netopen = 1; + spin_unlock_irqrestore(&self->lock, flags); /* * Now that everything should be initialized properly, @@ -1236,7 +1228,7 @@ static int irda_usb_net_open(struct net_device *netdev) /* If this ever happen, we are in deep s***. * Basically, we can't start the Rx path... */ IRDA_WARNING("%s(), Failed to allocate Rx skb\n", - __FUNCTION__); + __func__); return -1; } //skb_reserve(newskb, USB_IRDA_HEADER - 1); @@ -1259,10 +1251,10 @@ static int irda_usb_net_close(struct net_device *netdev) struct irda_usb_cb *self; int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); IRDA_ASSERT(netdev != NULL, return -1;); - self = (struct irda_usb_cb *) netdev->priv; + self = netdev_priv(netdev); IRDA_ASSERT(self != NULL, return -1;); /* Clear this flag *before* unlinking the urbs and *before* @@ -1311,10 +1303,10 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int ret = 0; IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ @@ -1348,14 +1340,6 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /*------------------------------------------------------------------*/ -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev) -{ - struct irda_usb_cb *self = dev->priv; - return &self->stats; -} /********************* IRDA CONFIG SUBROUTINES *********************/ /* @@ -1372,7 +1356,7 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) { struct irda_class_desc *desc; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); desc = self->irda_desc; @@ -1389,7 +1373,7 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) self->qos.data_size.bits = desc->bmDataSize; IRDA_DEBUG(0, "%s(), dongle says speed=0x%X, size=0x%X, window=0x%X, bofs=0x%X, turn=0x%X\n", - __FUNCTION__, self->qos.baud_rate.bits, self->qos.data_size.bits, self->qos.window_size.bits, self->qos.additional_bofs.bits, self->qos.min_turn_time.bits); + __func__, self->qos.baud_rate.bits, self->qos.data_size.bits, self->qos.window_size.bits, self->qos.additional_bofs.bits, self->qos.min_turn_time.bits); /* Don't always trust what the dongle tell us */ if(self->capability & IUC_SIR_ONLY) @@ -1416,6 +1400,14 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) } /*------------------------------------------------------------------*/ +static const struct net_device_ops irda_usb_netdev_ops = { + .ndo_open = irda_usb_net_open, + .ndo_stop = irda_usb_net_close, + .ndo_do_ioctl = irda_usb_net_ioctl, + .ndo_start_xmit = irda_usb_hard_xmit, + .ndo_tx_timeout = irda_usb_net_timeout, +}; + /* * Initialise the network side of the irda-usb instance * Called when a new USB instance is registered in irda_usb_probe() @@ -1424,18 +1416,11 @@ static inline int irda_usb_open(struct irda_usb_cb *self) { struct net_device *netdev = self->netdev; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); - irda_usb_init_qos(self); + netdev->netdev_ops = &irda_usb_netdev_ops; - /* Override the network functions we need to use */ - netdev->hard_start_xmit = irda_usb_hard_xmit; - netdev->tx_timeout = irda_usb_net_timeout; - netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */ - netdev->open = irda_usb_net_open; - netdev->stop = irda_usb_net_close; - netdev->get_stats = irda_usb_net_get_stats; - netdev->do_ioctl = irda_usb_net_ioctl; + irda_usb_init_qos(self); return register_netdev(netdev); } @@ -1447,7 +1432,7 @@ static inline int irda_usb_open(struct irda_usb_cb *self) */ static inline void irda_usb_close(struct irda_usb_cb *self) { - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); /* Remove netdevice */ unregister_netdev(self->netdev); @@ -1455,6 +1440,9 @@ static inline void irda_usb_close(struct irda_usb_cb *self) /* Remove the speed buffer */ kfree(self->speed_buff); self->speed_buff = NULL; + + kfree(self->tx_buff); + self->tx_buff = NULL; } /********************** USB CONFIG SUBROUTINES **********************/ @@ -1517,17 +1505,15 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ /* This is our interrupt endpoint */ self->bulk_int_ep = ep; } else { - IRDA_ERROR("%s(), Unrecognised endpoint %02X.\n", __FUNCTION__, ep); + IRDA_ERROR("%s(), Unrecognised endpoint %02X.\n", __func__, ep); } } } IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", - __FUNCTION__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - /* Should be 8, 16, 32 or 64 bytes */ - IRDA_ASSERT(self->bulk_out_mtu == 64, ;); + __func__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); + return (self->bulk_in_ep != 0) && (self->bulk_out_ep != 0); } #ifdef IU_DUMP_CLASS_DESC @@ -1570,10 +1556,9 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf struct irda_class_desc *desc; int ret; - desc = kmalloc(sizeof (*desc), GFP_KERNEL); - if (desc == NULL) + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) return NULL; - memset(desc, 0, sizeof(*desc)); /* USB-IrDA class spec 1.0: * 6.1.3: Standard "Get Descriptor" Device Request is not @@ -1588,7 +1573,7 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf 0, intf->altsetting->desc.bInterfaceNumber, desc, sizeof(*desc), 500); - IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret); + IRDA_DEBUG(1, "%s(), ret=%d\n", __func__, ret); if (ret < sizeof(*desc)) { IRDA_WARNING("usb-irda: class_descriptor read %s (%d)\n", (ret<0) ? "failed" : "too short", ret); @@ -1626,7 +1611,7 @@ static int irda_usb_probe(struct usb_interface *intf, { struct net_device *net; struct usb_device *dev = interface_to_usbdev(intf); - struct irda_usb_cb *self = NULL; + struct irda_usb_cb *self; struct usb_host_interface *interface; struct irda_class_desc *irda_desc; int ret = -ENOMEM; @@ -1645,9 +1630,8 @@ static int irda_usb_probe(struct usb_interface *intf, if (!net) goto err_out; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); - self = net->priv; + self = netdev_priv(net); self->netdev = net; spin_lock_init(&self->lock); init_timer(&self->rx_defer_timer); @@ -1664,8 +1648,10 @@ static int irda_usb_probe(struct usb_interface *intf, self->header_length = USB_IRDA_HEADER; } - self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), + self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), GFP_KERNEL); + if (!self->rx_urb) + goto err_free_net; for (i = 0; i < self->max_rx_urb; i++) { self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); @@ -1684,7 +1670,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Is this really necessary? (no, except maybe for broken devices) */ if (usb_reset_configuration (dev) < 0) { - err("reset_configuration failed"); + dev_err(&intf->dev, "reset_configuration failed\n"); ret = -EIO; goto err_out_3; } @@ -1702,10 +1688,10 @@ static int irda_usb_probe(struct usb_interface *intf, /* Martin Diehl says if we get a -EPIPE we should * be fine and we don't need to do a usb_clear_halt(). * - Jean II */ - IRDA_DEBUG(0, "%s(), Received -EPIPE, ignoring...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Received -EPIPE, ignoring...\n", __func__); break; default: - IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret); + IRDA_DEBUG(0, "%s(), Unknown error %d\n", __func__, ret); ret = -EIO; goto err_out_3; } @@ -1714,7 +1700,7 @@ static int irda_usb_probe(struct usb_interface *intf, interface = intf->cur_altsetting; if(!irda_usb_parse_endpoints(self, interface->endpoint, interface->desc.bNumEndpoints)) { - IRDA_ERROR("%s(), Bogus endpoints...\n", __FUNCTION__); + IRDA_ERROR("%s(), Bogus endpoints...\n", __func__); ret = -EIO; goto err_out_3; } @@ -1724,7 +1710,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Find IrDA class descriptor */ irda_desc = irda_usb_find_class_desc(intf); ret = -ENODEV; - if (irda_desc == NULL) + if (!irda_desc) goto err_out_3; if (self->needspatch) { @@ -1747,15 +1733,18 @@ static int irda_usb_probe(struct usb_interface *intf, /* Don't change this buffer size and allocation without doing * some heavy and complete testing. Don't ask why :-( * Jean II */ - self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); - if (self->speed_buff == NULL) + self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); + if (!self->speed_buff) goto err_out_3; - memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); + self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, + GFP_KERNEL); + if (!self->tx_buff) + goto err_out_4; ret = irda_usb_open(self); if (ret) - goto err_out_4; + goto err_out_5; IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); @@ -1766,25 +1755,25 @@ static int irda_usb_probe(struct usb_interface *intf, self->needspatch = (ret < 0); if (self->needspatch) { IRDA_ERROR("STIR421X: Couldn't upload patch\n"); - goto err_out_5; + goto err_out_6; } /* replace IrDA class descriptor with what patched device is now reporting */ irda_desc = irda_usb_find_class_desc (self->usbintf); - if (irda_desc == NULL) { + if (!irda_desc) { ret = -ENODEV; - goto err_out_5; + goto err_out_6; } - if (self->irda_desc) - kfree (self->irda_desc); + kfree(self->irda_desc); self->irda_desc = irda_desc; irda_usb_init_qos(self); } return 0; - -err_out_5: +err_out_6: unregister_netdev(self->netdev); +err_out_5: + kfree(self->tx_buff); err_out_4: kfree(self->speed_buff); err_out_3: @@ -1795,6 +1784,8 @@ err_out_2: err_out_1: for (i = 0; i < self->max_rx_urb; i++) usb_free_urb(self->rx_urb[i]); + kfree(self->rx_urb); +err_free_net: free_netdev(net); err_out: return ret; @@ -1818,7 +1809,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) struct irda_usb_cb *self = usb_get_intfdata(intf); int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); usb_set_intfdata(intf, NULL); if (!self) @@ -1868,55 +1859,62 @@ static void irda_usb_disconnect(struct usb_interface *intf) /* Free self and network device */ free_netdev(self->netdev); - IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __func__); } -/*------------------------------------------------------------------*/ -/* - * USB device callbacks - */ -static struct usb_driver irda_driver = { - .name = "irda-usb", - .probe = irda_usb_probe, - .disconnect = irda_usb_disconnect, - .id_table = dongles, -}; +#ifdef CONFIG_PM +/* USB suspend, so power off the transmitter/receiver */ +static int irda_usb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct irda_usb_cb *self = usb_get_intfdata(intf); + int i; -/************************* MODULE CALLBACKS *************************/ -/* - * Deal with module insertion/removal - * Mostly tell USB about our existence - */ + netif_device_detach(self->netdev); -/*------------------------------------------------------------------*/ -/* - * Module insertion - */ -static int __init usb_irda_init(void) + if (self->tx_urb != NULL) + usb_kill_urb(self->tx_urb); + if (self->speed_urb != NULL) + usb_kill_urb(self->speed_urb); + for (i = 0; i < self->max_rx_urb; i++) { + if (self->rx_urb[i] != NULL) + usb_kill_urb(self->rx_urb[i]); + } + return 0; +} + +/* Coming out of suspend, so reset hardware */ +static int irda_usb_resume(struct usb_interface *intf) { - int ret; + struct irda_usb_cb *self = usb_get_intfdata(intf); + int i; - ret = usb_register(&irda_driver); - if (ret < 0) - return ret; + for (i = 0; i < self->max_rx_urb; i++) { + if (self->rx_urb[i] != NULL) + usb_submit_urb(self->rx_urb[i], GFP_KERNEL); + } - IRDA_MESSAGE("USB IrDA support registered\n"); + netif_device_attach(self->netdev); return 0; } -module_init(usb_irda_init); +#endif /*------------------------------------------------------------------*/ /* - * Module removal + * USB device callbacks */ -static void __exit usb_irda_cleanup(void) -{ - /* Deregister the driver and remove all pending instances */ - usb_deregister(&irda_driver); -} -module_exit(usb_irda_cleanup); +static struct usb_driver irda_driver = { + .name = "irda-usb", + .probe = irda_usb_probe, + .disconnect = irda_usb_disconnect, + .id_table = dongles, +#ifdef CONFIG_PM + .suspend = irda_usb_suspend, + .resume = irda_usb_resume, +#endif +}; + +module_usb_driver(irda_driver); -/*------------------------------------------------------------------*/ /* * Module parameters */ diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 6b2271f18e7..58ddb521491 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -117,15 +117,15 @@ struct irda_class_desc { __u8 bLength; __u8 bDescriptorType; - __u16 bcdSpecRevision; + __le16 bcdSpecRevision; __u8 bmDataSize; __u8 bmWindowSize; __u8 bmMinTurnaroundTime; - __u16 wBaudRate; + __le16 wBaudRate; __u8 bmAdditionalBOFs; __u8 bIrdaRateSniff; __u8 bMaxUnicastList; -} __attribute__ ((packed)); +} __packed; /* class specific interface request to get the IrDA-USB class descriptor * (6.2.5, USB-IrDA class spec 1.0) */ @@ -152,10 +152,10 @@ struct irda_usb_cb { struct urb *speed_urb; /* URB used to send speed commands */ struct net_device *netdev; /* Yes! we are some kind of netdev. */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; char *speed_buff; /* Buffer for speed changes */ + char *tx_buff; struct timeval stamp; struct timeval now; diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c deleted file mode 100644 index 654a68b490a..00000000000 --- a/drivers/net/irda/irport.c +++ /dev/null @@ -1,1126 +0,0 @@ -/********************************************************************* - * - * Filename: irport.c - * Version: 1.0 - * Description: Half duplex serial port SIR driver for IrDA. - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Fri Jan 28 20:22:38 2000 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * Sources: serial.c by Linus Torvalds - * - * Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved. - * Copyright (c) 2000-2003 Jean Tourrilhes, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * This driver is ment to be a small half duplex serial driver to be - * used for IR-chipsets that has a UART (16550) compatibility mode. - * Eventually it will replace irtty, because of irtty has some - * problems that is hard to get around when we don't have control - * over the serial driver. This driver may also be used by FIR - * drivers to handle SIR mode for them. - * - ********************************************************************/ - -#include <linux/module.h> - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/skbuff.h> -#include <linux/serial_reg.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/delay.h> -#include <linux/rtnetlink.h> -#include <linux/bitops.h> - -#include <asm/system.h> -#include <asm/io.h> - -#include <net/irda/irda.h> -#include <net/irda/wrapper.h> -#include "irport.h" - -#define IO_EXTENT 8 - -/* - * Currently you'll need to set these values using insmod like this: - * insmod irport io=0x3e8 irq=11 - */ -static unsigned int io[] = { ~0, ~0, ~0, ~0 }; -static unsigned int irq[] = { 0, 0, 0, 0 }; - -static unsigned int qos_mtt_bits = 0x03; - -static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL}; -static char *driver_name = "irport"; - -static inline void irport_write_wakeup(struct irport_cb *self); -static inline int irport_write(int iobase, int fifo_size, __u8 *buf, int len); -static inline void irport_receive(struct irport_cb *self); - -static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, - int cmd); -static inline int irport_is_receiving(struct irport_cb *self); -static int 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); -static struct net_device_stats *irport_net_get_stats(struct net_device *dev); -static int irport_change_speed_complete(struct irda_task *task); -static void irport_timeout(struct net_device *dev); - -static irqreturn_t irport_interrupt(int irq, void *dev_id); -static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); -static void irport_change_speed(void *priv, __u32 speed); -static int irport_net_open(struct net_device *dev); -static int irport_net_close(struct net_device *dev); - -static struct irport_cb * -irport_open(int i, unsigned int iobase, unsigned int irq) -{ - struct net_device *dev; - struct irport_cb *self; - - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); - - /* Lock the port that we need */ - if (!request_region(iobase, IO_EXTENT, driver_name)) { - IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n", - __FUNCTION__, iobase); - goto err_out1; - } - - /* - * Allocate new instance of the driver - */ - dev = alloc_irdadev(sizeof(struct irport_cb)); - if (!dev) { - IRDA_ERROR("%s(), can't allocate memory for " - "irda device!\n", __FUNCTION__); - goto err_out2; - } - - self = dev->priv; - spin_lock_init(&self->lock); - - /* Need to store self somewhere */ - dev_self[i] = self; - self->priv = self; - self->index = i; - - /* Initialize IO */ - self->io.sir_base = iobase; - self->io.sir_ext = IO_EXTENT; - self->io.irq = irq; - self->io.fifo_size = 16; /* 16550A and compatible */ - - /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&self->qos); - - self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| - IR_115200; - - self->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&self->qos); - - /* Bootstrap ZeroCopy Rx */ - self->rx_buff.truesize = IRDA_SKB_MAX_MTU; - self->rx_buff.skb = __dev_alloc_skb(self->rx_buff.truesize, - GFP_KERNEL); - if (self->rx_buff.skb == NULL) { - IRDA_ERROR("%s(), can't allocate memory for " - "receive buffer!\n", __FUNCTION__); - goto err_out3; - } - skb_reserve(self->rx_buff.skb, 1); - self->rx_buff.head = self->rx_buff.skb->data; - /* No need to memset the buffer, unless you are really pedantic */ - - /* Finish setup the Rx buffer descriptor */ - self->rx_buff.in_frame = FALSE; - self->rx_buff.state = OUTSIDE_FRAME; - self->rx_buff.data = self->rx_buff.head; - - /* Specify how much memory we want */ - self->tx_buff.truesize = 4000; - - /* Allocate memory if needed */ - if (self->tx_buff.truesize > 0) { - self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, - GFP_KERNEL); - if (self->tx_buff.head == NULL) { - IRDA_ERROR("%s(), can't allocate memory for " - "transmit buffer!\n", __FUNCTION__); - goto err_out4; - } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); - } - self->tx_buff.data = self->tx_buff.head; - - self->netdev = dev; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - - /* May be overridden by piggyback drivers */ - self->interrupt = irport_interrupt; - self->change_speed = irport_change_speed; - - /* Override the network functions we need to use */ - dev->hard_start_xmit = irport_hard_xmit; - dev->tx_timeout = irport_timeout; - dev->watchdog_timeo = HZ; /* Allow time enough for speed change */ - dev->open = irport_net_open; - dev->stop = irport_net_close; - dev->get_stats = irport_net_get_stats; - dev->do_ioctl = irport_net_ioctl; - - /* Make ifconfig display some details */ - dev->base_addr = iobase; - dev->irq = irq; - - if (register_netdev(dev)) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__); - goto err_out5; - } - IRDA_MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n", - dev->name, iobase, irq); - - return self; - err_out5: - kfree(self->tx_buff.head); - err_out4: - kfree_skb(self->rx_buff.skb); - err_out3: - free_netdev(dev); - dev_self[i] = NULL; - err_out2: - release_region(iobase, IO_EXTENT); - err_out1: - return NULL; -} - -static int irport_close(struct irport_cb *self) -{ - IRDA_ASSERT(self != NULL, return -1;); - - /* We are not using any dongle anymore! */ - if (self->dongle) - irda_device_dongle_cleanup(self->dongle); - self->dongle = NULL; - - /* Remove netdevice */ - unregister_netdev(self->netdev); - - /* Release the IO-port that this driver is using */ - IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", - __FUNCTION__, self->io.sir_base); - release_region(self->io.sir_base, self->io.sir_ext); - - kfree(self->tx_buff.head); - - if (self->rx_buff.skb) - kfree_skb(self->rx_buff.skb); - self->rx_buff.skb = NULL; - - /* Remove ourselves */ - dev_self[self->index] = NULL; - free_netdev(self->netdev); - - return 0; -} - -static void irport_stop(struct irport_cb *self) -{ - int iobase; - - iobase = self->io.sir_base; - - /* We can't lock, we may be called from a FIR driver - Jean II */ - - /* We are not transmitting any more */ - self->transmitting = 0; - - /* Reset UART */ - outb(0, iobase+UART_MCR); - - /* Turn off interrupts */ - outb(0, iobase+UART_IER); -} - -static void irport_start(struct irport_cb *self) -{ - int iobase; - - iobase = self->io.sir_base; - - irport_stop(self); - - /* We can't lock, we may be called from a FIR driver - Jean II */ - - /* Initialize UART */ - outb(UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */ - outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR); - - /* Turn on interrups */ - outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER); -} - -/* - * Function irport_get_fcr (speed) - * - * Compute value of fcr - * - */ -static inline unsigned int irport_get_fcr(__u32 speed) -{ - unsigned int fcr; /* FIFO control reg */ - - /* Enable fifos */ - fcr = UART_FCR_ENABLE_FIFO; - - /* - * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and - * 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 (speed < 38400) - fcr |= UART_FCR_TRIGGER_1; - else - //fcr |= UART_FCR_TRIGGER_14; - fcr |= UART_FCR_TRIGGER_8; - - return(fcr); -} - -/* - * Function irport_change_speed (self, speed) - * - * Set speed of IrDA port to specified baudrate - * - * This function should be called with irq off and spin-lock. - */ -static void irport_change_speed(void *priv, __u32 speed) -{ - struct irport_cb *self = (struct irport_cb *) priv; - int iobase; - unsigned int fcr; /* FIFO control reg */ - unsigned int lcr; /* Line control reg */ - int divisor; - - IRDA_ASSERT(self != NULL, return;); - IRDA_ASSERT(speed != 0, return;); - - IRDA_DEBUG(1, "%s(), Setting speed to: %d - iobase=%#x\n", - __FUNCTION__, speed, self->io.sir_base); - - /* We can't lock, we may be called from a FIR driver - Jean II */ - - iobase = self->io.sir_base; - - /* Update accounting for new speed */ - self->io.speed = speed; - - /* Turn off interrupts */ - outb(0, iobase+UART_IER); - - divisor = SPEED_MAX/speed; - - /* Get proper fifo configuration */ - fcr = irport_get_fcr(speed); - - /* IrDA ports use 8N1 */ - lcr = UART_LCR_WLEN8; - - outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */ - outb(divisor & 0xff, iobase+UART_DLL); /* Set speed */ - outb(divisor >> 8, iobase+UART_DLM); - outb(lcr, iobase+UART_LCR); /* Set 8N1 */ - outb(fcr, iobase+UART_FCR); /* Enable FIFO's */ - - /* Turn on interrups */ - /* This will generate a fatal interrupt storm. - * People calling us will do that properly - Jean II */ - //outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER); -} - -/* - * Function __irport_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 __irport_change_speed(struct irda_task *task) -{ - struct irport_cb *self; - __u32 speed = (__u32) task->param; - unsigned long flags = 0; - int wasunlocked = 0; - int ret = 0; - - IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); - - self = (struct irport_cb *) task->instance; - - IRDA_ASSERT(self != NULL, return -1;); - - /* Locking notes : this function may be called from irq context with - * spinlock, via irport_write_wakeup(), or from non-interrupt without - * spinlock (from the task timer). Yuck ! - * This is ugly, and unsafe is the spinlock is not already acquired. - * This will be fixed when irda-task get rewritten. - * Jean II */ - if (!spin_is_locked(&self->lock)) { - spin_lock_irqsave(&self->lock, flags); - wasunlocked = 1; - } - - switch (task->state) { - case IRDA_TASK_INIT: - case IRDA_TASK_WAIT: - /* Are we ready to change speed yet? */ - if (self->tx_buff.len > 0) { - 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 */ - self->change_speed(self->priv, 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: - IRDA_WARNING("%s(), changing speed of dongle timed out!\n", __FUNCTION__); - ret = -1; - break; - case IRDA_TASK_CHILD_DONE: - /* Finally we are ready to change the speed */ - self->change_speed(self->priv, speed); - - irda_task_next_state(task, IRDA_TASK_DONE); - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - ret = -1; - break; - } - /* Put stuff in the state we found them - Jean II */ - if(wasunlocked) { - spin_unlock_irqrestore(&self->lock, flags); - } - - return ret; -} - -/* - * Function irport_change_speed_complete (task) - * - * Called when the change speed operation completes - * - */ -static int irport_change_speed_complete(struct irda_task *task) -{ - struct irport_cb *self; - - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); - - self = (struct irport_cb *) task->instance; - - IRDA_ASSERT(self != NULL, return -1;); - IRDA_ASSERT(self->netdev != NULL, return -1;); - - /* Finished changing speed, so we are not busy any longer */ - /* Signal network layer so it can try to send the frame */ - - netif_wake_queue(self->netdev); - - return 0; -} - -/* - * Function irport_timeout (struct net_device *dev) - * - * The networking layer thinks we timed out. - * - */ - -static void irport_timeout(struct net_device *dev) -{ - struct irport_cb *self; - int iobase; - int iir, lsr; - unsigned long flags; - - self = (struct irport_cb *) dev->priv; - IRDA_ASSERT(self != NULL, return;); - iobase = self->io.sir_base; - - IRDA_WARNING("%s: transmit timed out, jiffies = %ld, trans_start = %ld\n", - dev->name, jiffies, dev->trans_start); - spin_lock_irqsave(&self->lock, flags); - - /* Debug what's happening... */ - - /* Get interrupt status */ - lsr = inb(iobase+UART_LSR); - /* Read interrupt register */ - iir = inb(iobase+UART_IIR); - IRDA_DEBUG(0, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", - __FUNCTION__, iir, lsr, iobase); - - IRDA_DEBUG(0, "%s(), transmitting=%d, remain=%d, done=%d\n", - __FUNCTION__, self->transmitting, self->tx_buff.len, - self->tx_buff.data - self->tx_buff.head); - - /* Now, restart the port */ - irport_start(self); - self->change_speed(self->priv, self->io.speed); - /* This will re-enable irqs */ - outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER); - dev->trans_start = jiffies; - spin_unlock_irqrestore(&self->lock, flags); - - netif_wake_queue(dev); -} - -/* - * Function irport_wait_hw_transmitter_finish () - * - * Wait for the real end of HW transmission - * - * The UART is a strict FIFO, and we get called only when we have finished - * pushing data to the FIFO, so the maximum amount of time we must wait - * is only for the FIFO to drain out. - * - * We use a simple calibrated loop. We may need to adjust the loop - * delay (udelay) to balance I/O traffic and latency. And we also need to - * adjust the maximum timeout. - * It would probably be better to wait for the proper interrupt, - * but it doesn't seem to be available. - * - * We can't use jiffies or kernel timers because : - * 1) We are called from the interrupt handler, which disable softirqs, - * so jiffies won't be increased - * 2) Jiffies granularity is usually very coarse (10ms), and we don't - * want to wait that long to detect stuck hardware. - * Jean II - */ - -static void irport_wait_hw_transmitter_finish(struct irport_cb *self) -{ - int iobase; - int count = 1000; /* 1 ms */ - - iobase = self->io.sir_base; - - /* Calibrated busy loop */ - while((count-- > 0) && !(inb(iobase+UART_LSR) & UART_LSR_TEMT)) - udelay(1); - - if(count == 0) - IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__); -} - -/* - * Function irport_hard_start_xmit (struct sk_buff *skb, struct net_device *dev) - * - * Transmits the current frame until FIFO is full, then - * waits until the next transmitt interrupt, and continues until the - * frame is transmitted. - */ -static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct irport_cb *self; - unsigned long flags; - int iobase; - s32 speed; - - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); - - IRDA_ASSERT(dev != NULL, return 0;); - - self = (struct irport_cb *) dev->priv; - IRDA_ASSERT(self != NULL, return 0;); - - iobase = self->io.sir_base; - - netif_stop_queue(dev); - - /* Make sure tests & speed change are atomic */ - spin_lock_irqsave(&self->lock, flags); - - /* Check if we need to change the speed */ - speed = irda_get_next_speed(skb); - if ((speed != self->io.speed) && (speed != -1)) { - /* Check for empty frame */ - if (!skb->len) { - /* - * We send frames one by one in SIR mode (no - * pipelining), so at this point, if we were sending - * a previous frame, we just received the interrupt - * telling us it is finished (UART_IIR_THRI). - * Therefore, waiting for the transmitter to really - * finish draining the fifo won't take too long. - * And the interrupt handler is not expected to run. - * - Jean II */ - irport_wait_hw_transmitter_finish(self); - /* Better go there already locked - Jean II */ - irda_task_execute(self, __irport_change_speed, - irport_change_speed_complete, - NULL, (void *) speed); - dev->trans_start = jiffies; - spin_unlock_irqrestore(&self->lock, flags); - dev_kfree_skb(skb); - return 0; - } else - self->new_speed = speed; - } - - /* Init tx buffer */ - self->tx_buff.data = self->tx_buff.head; - - /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ - self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, - self->tx_buff.truesize); - - self->stats.tx_bytes += self->tx_buff.len; - - /* We are transmitting */ - self->transmitting = 1; - - /* Turn on transmit finished interrupt. Will fire immediately! */ - outb(UART_IER_THRI, iobase+UART_IER); - - dev->trans_start = jiffies; - spin_unlock_irqrestore(&self->lock, flags); - - dev_kfree_skb(skb); - - return 0; -} - -/* - * Function irport_write (driver) - * - * Fill Tx FIFO with transmit data - * - * Called only from irport_write_wakeup() - */ -static inline int irport_write(int iobase, int fifo_size, __u8 *buf, int len) -{ - int actual = 0; - - /* Fill FIFO with current frame */ - while ((actual < fifo_size) && (actual < len)) { - /* Transmit next byte */ - outb(buf[actual], iobase+UART_TX); - - actual++; - } - - return actual; -} - -/* - * Function irport_write_wakeup (tty) - * - * Called by the driver when there's room for more data. If we have - * more packets to send, we send them here. - * - * Called only from irport_interrupt() - * Make sure this function is *not* called while we are receiving, - * otherwise we will reset fifo and loose data :-( - */ -static inline void irport_write_wakeup(struct irport_cb *self) -{ - int actual = 0; - int iobase; - unsigned int fcr; - - IRDA_ASSERT(self != NULL, return;); - - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); - - iobase = self->io.sir_base; - - /* Finished with frame? */ - if (self->tx_buff.len > 0) { - /* Write data left in transmit buffer */ - actual = irport_write(iobase, self->io.fifo_size, - self->tx_buff.data, self->tx_buff.len); - self->tx_buff.data += actual; - self->tx_buff.len -= actual; - } else { - /* - * Now serial buffer is almost free & we can start - * transmission of another packet. But first we must check - * if we need to change the speed of the hardware - */ - if (self->new_speed) { - irport_wait_hw_transmitter_finish(self); - irda_task_execute(self, __irport_change_speed, - irport_change_speed_complete, - NULL, (void *) self->new_speed); - self->new_speed = 0; - } else { - /* Tell network layer that we want more frames */ - netif_wake_queue(self->netdev); - } - self->stats.tx_packets++; - - /* - * Reset Rx FIFO to make sure that all reflected transmit data - * is discarded. This is needed for half duplex operation - */ - fcr = irport_get_fcr(self->io.speed); - fcr |= UART_FCR_CLEAR_RCVR; - outb(fcr, iobase+UART_FCR); - - /* Finished transmitting */ - self->transmitting = 0; - - /* Turn on receive interrupts */ - outb(UART_IER_RDI, iobase+UART_IER); - - IRDA_DEBUG(1, "%s() : finished Tx\n", __FUNCTION__); - } -} - -/* - * Function irport_receive (self) - * - * Receive one frame from the infrared port - * - * Called only from irport_interrupt() - */ -static inline void irport_receive(struct irport_cb *self) -{ - int boguscount = 0; - int iobase; - - IRDA_ASSERT(self != NULL, return;); - - iobase = self->io.sir_base; - - /* - * Receive all characters in Rx FIFO, unwrap and unstuff them. - * async_unwrap_char will deliver all found frames - */ - do { - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, - inb(iobase+UART_RX)); - - /* Make sure we don't stay here too long */ - if (boguscount++ > 32) { - IRDA_DEBUG(2,"%s(), breaking!\n", __FUNCTION__); - break; - } - } while (inb(iobase+UART_LSR) & UART_LSR_DR); -} - -/* - * Function irport_interrupt (irq, dev_id) - * - * Interrupt handler - */ -static irqreturn_t irport_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct irport_cb *self; - int boguscount = 0; - int iobase; - int iir, lsr; - int handled = 0; - - self = dev->priv; - - spin_lock(&self->lock); - - iobase = self->io.sir_base; - - /* Cut'n'paste interrupt routine from serial.c - * This version try to minimise latency and I/O operations. - * Simplified and modified to enforce half duplex operation. - * - Jean II */ - - /* Check status even is iir reg is cleared, more robust and - * eliminate a read on the I/O bus - Jean II */ - do { - /* Get interrupt status ; Clear interrupt */ - lsr = inb(iobase+UART_LSR); - - /* Are we receiving or transmitting ? */ - if(!self->transmitting) { - /* Received something ? */ - if (lsr & UART_LSR_DR) - irport_receive(self); - } else { - /* Room in Tx fifo ? */ - if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) - irport_write_wakeup(self); - } - - /* A bit hackish, but working as expected... Jean II */ - if(lsr & (UART_LSR_THRE | UART_LSR_TEMT | UART_LSR_DR)) - handled = 1; - - /* Make sure we don't stay here to long */ - if (boguscount++ > 10) { - IRDA_WARNING("%s() irq handler looping : lsr=%02x\n", - __FUNCTION__, lsr); - break; - } - - /* Read interrupt register */ - iir = inb(iobase+UART_IIR); - - /* Enable this debug only when no other options and at low - * bit rates, otherwise it may cause Rx overruns (lsr=63). - * - Jean II */ - IRDA_DEBUG(6, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", - __FUNCTION__, iir, lsr, iobase); - - /* As long as interrupt pending... */ - } while ((iir & UART_IIR_NO_INT) == 0); - - spin_unlock(&self->lock); - return IRQ_RETVAL(handled); -} - -/* - * Function irport_net_open (dev) - * - * Network device is taken up. Usually this is done by "ifconfig irda0 up" - * - */ -static int irport_net_open(struct net_device *dev) -{ - struct irport_cb *self; - int iobase; - char hwname[16]; - unsigned long flags; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - IRDA_ASSERT(dev != NULL, return -1;); - self = (struct irport_cb *) dev->priv; - - iobase = self->io.sir_base; - - if (request_irq(self->io.irq, self->interrupt, 0, dev->name, - (void *) dev)) { - IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", - __FUNCTION__, self->io.irq); - return -EAGAIN; - } - - spin_lock_irqsave(&self->lock, flags); - /* Init uart */ - irport_start(self); - /* Set 9600 bauds per default, including at the dongle */ - irda_task_execute(self, __irport_change_speed, - irport_change_speed_complete, - NULL, (void *) 9600); - spin_unlock_irqrestore(&self->lock, flags); - - - /* Give self a hardware name */ - sprintf(hwname, "SIR @ 0x%03x", self->io.sir_base); - - /* - * Open new IrLAP layer instance, now that everything should be - * initialized properly - */ - self->irlap = irlap_open(dev, &self->qos, hwname); - - /* Ready to play! */ - - netif_start_queue(dev); - - return 0; -} - -/* - * Function irport_net_close (self) - * - * Network device is taken down. Usually this is done by - * "ifconfig irda0 down" - */ -static int irport_net_close(struct net_device *dev) -{ - struct irport_cb *self; - int iobase; - unsigned long flags; - - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); - - IRDA_ASSERT(dev != NULL, return -1;); - self = (struct irport_cb *) dev->priv; - - IRDA_ASSERT(self != NULL, return -1;); - - iobase = self->io.sir_base; - - /* Stop device */ - netif_stop_queue(dev); - - /* Stop and remove instance of IrLAP */ - if (self->irlap) - irlap_close(self->irlap); - self->irlap = NULL; - - spin_lock_irqsave(&self->lock, flags); - irport_stop(self); - spin_unlock_irqrestore(&self->lock, flags); - - free_irq(self->io.irq, dev); - - return 0; -} - -/* - * Function irport_is_receiving (self) - * - * Returns true is we are currently receiving data - * - */ -static inline int irport_is_receiving(struct irport_cb *self) -{ - return (self->rx_buff.state != OUTSIDE_FRAME); -} - -/* - * Function irport_set_dtr_rts (tty, dtr, rts) - * - * This function can be used by dongles etc. to set or reset the status - * of the dtr and rts lines - */ -static int irport_set_dtr_rts(struct net_device *dev, int dtr, int rts) -{ - struct irport_cb *self = dev->priv; - int iobase; - - IRDA_ASSERT(self != NULL, return -1;); - - iobase = self->io.sir_base; - - if (dtr) - dtr = UART_MCR_DTR; - if (rts) - rts = UART_MCR_RTS; - - outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR); - - return 0; -} - -static int irport_raw_write(struct net_device *dev, __u8 *buf, int len) -{ - struct irport_cb *self = (struct irport_cb *) dev->priv; - int actual = 0; - int iobase; - - IRDA_ASSERT(self != NULL, return -1;); - - iobase = self->io.sir_base; - - /* Tx FIFO should be empty! */ - if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - IRDA_DEBUG( 0, "%s(), failed, fifo not empty!\n", __FUNCTION__); - return -1; - } - - /* Fill FIFO with current frame */ - while (actual < len) { - /* Transmit next byte */ - outb(buf[actual], iobase+UART_TX); - actual++; - } - - return actual; -} - -/* - * Function irport_net_ioctl (dev, rq, cmd) - * - * Process IOCTL commands for this device - * - */ -static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct if_irda_req *irq = (struct if_irda_req *) rq; - struct irport_cb *self; - dongle_t *dongle; - unsigned long flags; - int ret = 0; - - IRDA_ASSERT(dev != NULL, return -1;); - - self = dev->priv; - - IRDA_ASSERT(self != NULL, return -1;); - - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); - - switch (cmd) { - case SIOCSBANDWIDTH: /* Set bandwidth */ - if (!capable(CAP_NET_ADMIN)) - ret = -EPERM; - else - irda_task_execute(self, __irport_change_speed, NULL, - NULL, (void *) irq->ifr_baudrate); - break; - case SIOCSDONGLE: /* Set dongle */ - if (!capable(CAP_NET_ADMIN)) { - ret = -EPERM; - break; - } - - /* Locking : - * irda_device_dongle_init() can't be locked. - * irda_task_execute() doesn't need to be locked. - * Jean II - */ - - /* Initialize dongle */ - dongle = irda_device_dongle_init(dev, irq->ifr_dongle); - if (!dongle) - break; - - dongle->set_mode = NULL; - dongle->read = NULL; - dongle->write = irport_raw_write; - dongle->set_dtr_rts = irport_set_dtr_rts; - - /* Now initialize the dongle! */ - dongle->issue->open(dongle, &self->qos); - - /* Reset dongle */ - irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, - NULL); - - /* Make dongle available to driver only now to avoid - * race conditions - Jean II */ - self->dongle = dongle; - break; - case SIOCSMEDIABUSY: /* Set media busy */ - if (!capable(CAP_NET_ADMIN)) { - ret = -EPERM; - break; - } - - irda_device_set_media_busy(self->netdev, TRUE); - break; - case SIOCGRECEIVING: /* Check if we are receiving right now */ - irq->ifr_receiving = irport_is_receiving(self); - break; - case SIOCSDTRRTS: - if (!capable(CAP_NET_ADMIN)) { - ret = -EPERM; - break; - } - - /* No real need to lock... */ - spin_lock_irqsave(&self->lock, flags); - irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts); - spin_unlock_irqrestore(&self->lock, flags); - break; - default: - ret = -EOPNOTSUPP; - } - - return ret; -} - -static struct net_device_stats *irport_net_get_stats(struct net_device *dev) -{ - struct irport_cb *self = (struct irport_cb *) dev->priv; - - return &self->stats; -} - -static int __init irport_init(void) -{ - int i; - - for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) { - if (irport_open(i, io[i], irq[i]) != NULL) - return 0; - } - /* - * Maybe something failed, but we can still be usable for FIR drivers - */ - return 0; -} - -/* - * Function irport_cleanup () - * - * Close all configured ports - * - */ -static void __exit irport_cleanup(void) -{ - int i; - - IRDA_DEBUG( 4, "%s()\n", __FUNCTION__); - - for (i=0; i < ARRAY_SIZE(dev_self); i++) { - if (dev_self[i]) - irport_close(dev_self[i]); - } -} - -module_param_array(io, int, NULL, 0); -MODULE_PARM_DESC(io, "Base I/O addresses"); -module_param_array(irq, int, NULL, 0); -MODULE_PARM_DESC(irq, "IRQ lines"); - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); -MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode"); -MODULE_LICENSE("GPL"); - -module_init(irport_init); -module_exit(irport_cleanup); - diff --git a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h deleted file mode 100644 index 3f46b84c6c8..00000000000 --- a/drivers/net/irda/irport.h +++ /dev/null @@ -1,80 +0,0 @@ -/********************************************************************* - * - * Filename: irport.h - * Version: 0.1 - * Description: Serial driver for IrDA - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Fri Jan 14 10:21:10 2000 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1997, 1998-2000 Dag Brattli <dagb@cs.uit.no> - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRPORT_H -#define IRPORT_H - -#include <linux/netdevice.h> -#include <linux/skbuff.h> -#include <linux/types.h> -#include <linux/spinlock.h> - -#include <net/irda/irda_device.h> - -#define SPEED_DEFAULT 9600 -#define SPEED_MAX 115200 - -/* - * These are the supported serial types. - */ -#define PORT_UNKNOWN 0 -#define PORT_8250 1 -#define PORT_16450 2 -#define PORT_16550 3 -#define PORT_16550A 4 -#define PORT_CIRRUS 5 -#define PORT_16650 6 -#define PORT_MAX 6 - -#define FRAME_MAX_SIZE 2048 - -struct irport_cb { - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are attached to */ - - chipio_t io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - struct qos_info qos; /* QoS capabilities for this device */ - dongle_t *dongle; /* Dongle driver */ - - __u32 flags; /* Interface flags */ - __u32 new_speed; - int mode; - int index; /* Instance index */ - int transmitting; /* Are we transmitting ? */ - - spinlock_t lock; /* For serializing operations */ - - /* For piggyback drivers */ - void *priv; - void (*change_speed)(void *priv, __u32 speed); - irqreturn_t (*interrupt)(int irq, void *dev_id); -}; - -#endif /* IRPORT_H */ diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 6a98b7ae497..24b6dddd7f2 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -20,7 +20,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -28,10 +28,10 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/tty.h> #include <linux/init.h> #include <asm/uaccess.h> -#include <linux/smp_lock.h> #include <linux/delay.h> #include <linux/mutex.h> @@ -64,7 +64,7 @@ static int irtty_chars_in_buffer(struct sir_dev *dev) IRDA_ASSERT(priv != NULL, return -1;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); - return priv->tty->driver->chars_in_buffer(priv->tty); + return tty_chars_in_buffer(priv->tty); } /* Wait (sleep) until underlaying hardware finished transmission @@ -93,10 +93,8 @@ static void irtty_wait_until_sent(struct sir_dev *dev) IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); tty = priv->tty; - if (tty->driver->wait_until_sent) { - lock_kernel(); - tty->driver->wait_until_sent(tty, msecs_to_jiffies(100)); - unlock_kernel(); + if (tty->ops->wait_until_sent) { + tty->ops->wait_until_sent(tty, msecs_to_jiffies(100)); } else { msleep(USBSERIAL_TX_DONE_DELAY); @@ -117,7 +115,7 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed) { struct sirtty_cb *priv = dev->priv; struct tty_struct *tty; - struct termios old_termios; + struct ktermios old_termios; int cflag; IRDA_ASSERT(priv != NULL, return -1;); @@ -125,48 +123,14 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed) tty = priv->tty; - lock_kernel(); - old_termios = *(tty->termios); - cflag = tty->termios->c_cflag; - - cflag &= ~CBAUD; - - IRDA_DEBUG(2, "%s(), Setting speed to %d\n", __FUNCTION__, speed); - - switch (speed) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - - tty->termios->c_cflag = cflag; - if (tty->driver->set_termios) - tty->driver->set_termios(tty, &old_termios); - unlock_kernel(); - + down_write(&tty->termios_rwsem); + old_termios = tty->termios; + cflag = tty->termios.c_cflag; + tty_encode_baud_rate(tty, speed, speed); + if (tty->ops->set_termios) + tty->ops->set_termios(tty, &old_termios); priv->io.speed = speed; + up_write(&tty->termios_rwsem); return 0; } @@ -202,8 +166,8 @@ static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts) * This function is not yet defined for all tty driver, so * let's be careful... Jean II */ - IRDA_ASSERT(priv->tty->driver->tiocmset != NULL, return -1;); - priv->tty->driver->tiocmset(priv->tty, NULL, set, clear); + IRDA_ASSERT(priv->tty->ops->tiocmset != NULL, return -1;); + priv->tty->ops->tiocmset(priv->tty, set, clear); return 0; } @@ -225,17 +189,13 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); tty = priv->tty; - if (!tty->driver->write) + if (!tty->ops->write) return 0; - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); - if (tty->driver->write_room) { - writelen = tty->driver->write_room(tty); - if (writelen > len) - writelen = len; - } - else + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + writelen = tty_write_room(tty); + if (writelen > len) writelen = len; - return tty->driver->write(tty, ptr, writelen); + return tty->ops->write(tty, ptr, writelen); } /* ------------------------------------------------------- */ @@ -250,7 +210,7 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t * been received, which can now be decapsulated and delivered for * further processing * - * calling context depends on underlying driver and tty->low_latency! + * calling context depends on underlying driver and tty->port->low_latency! * for example (low_latency: 1 / 0): * serial.c: uart-interrupt / softint * usbserial: urb-complete-interrupt / softint @@ -271,7 +231,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, dev = priv->dev; if (!dev) { - IRDA_WARNING("%s(), not ready yet!\n", __FUNCTION__); + IRDA_WARNING("%s(), not ready yet!\n", __func__); return; } @@ -303,8 +263,7 @@ static void irtty_write_wakeup(struct tty_struct *tty) IRDA_ASSERT(priv != NULL, return;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); if (priv->dev) sirdev_write_complete(priv->dev); } @@ -318,22 +277,22 @@ static void irtty_write_wakeup(struct tty_struct *tty) static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) { - struct termios old_termios; + struct ktermios old_termios; int cflag; - lock_kernel(); - old_termios = *(tty->termios); - cflag = tty->termios->c_cflag; + down_write(&tty->termios_rwsem); + old_termios = tty->termios; + cflag = tty->termios.c_cflag; if (stop) cflag &= ~CREAD; else cflag |= CREAD; - tty->termios->c_cflag = cflag; - if (tty->driver->set_termios) - tty->driver->set_termios(tty, &old_termios); - unlock_kernel(); + tty->termios.c_cflag = cflag; + if (tty->ops->set_termios) + tty->ops->set_termios(tty, &old_termios); + up_write(&tty->termios_rwsem); } /*****************************************************************/ @@ -359,8 +318,8 @@ static int irtty_start_dev(struct sir_dev *dev) tty = priv->tty; - if (tty->driver->start) - tty->driver->start(tty); + if (tty->ops->start) + tty->ops->start(tty); /* Make sure we can receive more data */ irtty_stop_receiver(tty, FALSE); @@ -388,8 +347,8 @@ static int irtty_stop_dev(struct sir_dev *dev) /* Make sure we don't receive more data */ irtty_stop_receiver(tty, TRUE); - if (tty->driver->stop) - tty->driver->stop(tty); + if (tty->ops->stop) + tty->ops->stop(tty); mutex_unlock(&irtty_mutex); @@ -428,17 +387,12 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c IRDA_ASSERT(priv != NULL, return -ENODEV;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EBADR;); - IRDA_DEBUG(3, "%s(cmd=0x%X)\n", __FUNCTION__, cmd); + IRDA_DEBUG(3, "%s(cmd=0x%X)\n", __func__, cmd); dev = priv->dev; IRDA_ASSERT(dev != NULL, return -1;); switch (cmd) { - case TCGETS: - case TCGETA: - err = n_tty_ioctl(tty, file, cmd, arg); - break; - case IRTTY_IOCTDONGLE: /* this call blocks for completion */ err = sirdev_set_dongle(dev, (IRDA_DONGLE) arg); @@ -454,7 +408,7 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c err = -EFAULT; break; default: - err = -ENOIOCTLCMD; + err = tty_mode_ioctl(tty, file, cmd, arg); break; } return err; @@ -488,11 +442,10 @@ static int irtty_open(struct tty_struct *tty) /* stop the underlying driver */ irtty_stop_receiver(tty, TRUE); - if (tty->driver->stop) - tty->driver->stop(tty); + if (tty->ops->stop) + tty->ops->stop(tty); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); + tty_driver_flush_buffer(tty); /* apply mtt override */ sir_tty_drv.qos_mtt_bits = qos_mtt_bits; @@ -505,10 +458,11 @@ static int irtty_open(struct tty_struct *tty) } /* allocate private device info block */ - priv = kmalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; goto out_put; - memset(priv, 0, sizeof(*priv)); + } priv->magic = IRTTY_MAGIC; priv->tty = tty; @@ -523,7 +477,7 @@ static int irtty_open(struct tty_struct *tty) mutex_unlock(&irtty_mutex); - IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __FUNCTION__, tty->name); + IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __func__, tty->name); return 0; @@ -568,19 +522,18 @@ static void irtty_close(struct tty_struct *tty) sirdev_put_instance(priv->dev); /* Stop tty */ - irtty_stop_receiver(tty, TRUE); - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - if (tty->driver->stop) - tty->driver->stop(tty); + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + if (tty->ops->stop) + tty->ops->stop(tty); kfree(priv); - IRDA_DEBUG(0, "%s - %s: irda line discipline closed\n", __FUNCTION__, tty->name); + IRDA_DEBUG(0, "%s - %s: irda line discipline closed\n", __func__, tty->name); } /* ------------------------------------------------------- */ -static struct tty_ldisc irda_ldisc = { +static struct tty_ldisc_ops irda_ldisc = { .magic = TTY_LDISC_MAGIC, .name = "irda", .flags = 0, @@ -613,7 +566,7 @@ static void __exit irtty_sir_cleanup(void) if ((err = tty_unregister_ldisc(N_IRDA))) { IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n", - __FUNCTION__, err); + __func__, err); } } diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c new file mode 100644 index 00000000000..96fe3659012 --- /dev/null +++ b/drivers/net/irda/kingsun-sir.c @@ -0,0 +1,637 @@ +/***************************************************************************** +* +* Filename: kingsun-sir.c +* Version: 0.1.1 +* Description: Irda KingSun/DonShine USB Dongle +* Status: Experimental +* Author: Alex VillacÃs Lasso <a_villacis@palosanto.com> +* +* Based on stir4200 and mcs7780 drivers, with (strange?) differences +* +* 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. +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +/* + * This is my current (2007-04-25) understanding of how this dongle is supposed + * to work. This is based on reverse-engineering and examination of the packet + * data sent and received by the WinXP driver using USBSnoopy. Feel free to + * update here as more of this dongle is known: + * + * General: Unlike the other USB IrDA dongles, this particular dongle exposes, + * not two bulk (in and out) endpoints, but two *interrupt* ones. This dongle, + * like the bulk based ones (stir4200.c and mcs7780.c), requires polling in + * order to receive data. + * Transmission: Just like stir4200, this dongle uses a raw stream of data, + * which needs to be wrapped and escaped in a similar way as in stir4200.c. + * Reception: Poll-based, as in stir4200. Each read returns the contents of a + * 8-byte buffer, of which the first byte (LSB) indicates the number of bytes + * (1-7) of valid data contained within the remaining 7 bytes. For example, if + * the buffer had the following contents: + * 06 ff ff ff c0 01 04 aa + * This means that (06) there are 6 bytes of valid data. The byte 0xaa at the + * end is garbage (left over from a previous reception) and is discarded. + * If a read returns an "impossible" value as the length of valid data (such as + * 0x36) in the first byte, then the buffer is uninitialized (as is the case of + * first plug-in) and its contents should be discarded. There is currently no + * evidence that the top 5 bits of the 1st byte of the buffer can have values + * other than 0 once reception begins. + * Once valid bytes are collected, the assembled stream is a sequence of + * wrapped IrDA frames that is unwrapped and unescaped as in stir4200.c. + * BIG FAT WARNING: the dongle does *not* reset the RX buffer in any way after + * a successful read from the host, which means that in absence of further + * reception, repeated reads from the dongle will return the exact same + * contents repeatedly. Attempts to be smart and cache a previous read seem + * to result in corrupted packets, so this driver depends on the unwrap logic + * to sort out any repeated reads. + * Speed change: no commands observed so far to change speed, assumed fixed + * 9600bps (SIR). + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/usb.h> +#include <linux/device.h> +#include <linux/crc32.h> + +#include <asm/unaligned.h> +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +#include <net/irda/irda.h> +#include <net/irda/wrapper.h> +#include <net/irda/crc.h> + +/* + * According to lsusb, 0x07c0 is assigned to + * "Code Mercenaries Hard- und Software GmbH" + */ +#define KING_VENDOR_ID 0x07c0 +#define KING_PRODUCT_ID 0x4200 + +/* These are the currently known USB ids */ +static struct usb_device_id dongles[] = { + /* KingSun Co,Ltd IrDA/USB Bridge */ + { USB_DEVICE(KING_VENDOR_ID, KING_PRODUCT_ID) }, + { } +}; + +MODULE_DEVICE_TABLE(usb, dongles); + +#define KINGSUN_MTT 0x07 + +#define KINGSUN_FIFO_SIZE 4096 +#define KINGSUN_EP_IN 0 +#define KINGSUN_EP_OUT 1 + +struct kingsun_cb { + struct usb_device *usbdev; /* init: probe_irda */ + struct net_device *netdev; /* network layer */ + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct qos_info qos; + + __u8 *in_buf; /* receive buffer */ + __u8 *out_buf; /* transmit buffer */ + __u8 max_rx; /* max. atomic read from dongle + (usually 8), also size of in_buf */ + __u8 max_tx; /* max. atomic write to dongle + (usually 8) */ + + iobuff_t rx_buff; /* receive unwrap state machine */ + struct timeval rx_time; + spinlock_t lock; + int receiving; + + __u8 ep_in; + __u8 ep_out; + + struct urb *tx_urb; + struct urb *rx_urb; +}; + +/* Callback transmission routine */ +static void kingsun_send_irq(struct urb *urb) +{ + struct kingsun_cb *kingsun = urb->context; + struct net_device *netdev = kingsun->netdev; + + /* in process of stopping, just drop data */ + if (!netif_running(kingsun->netdev)) { + dev_err(&kingsun->usbdev->dev, + "kingsun_send_irq: Network not running!\n"); + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "kingsun_send_irq: urb asynchronously failed - %d\n", + urb->status); + } + netif_wake_queue(netdev); +} + +/* + * Called from net/core when new frame is available. + */ +static netdev_tx_t kingsun_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct kingsun_cb *kingsun; + int wraplen; + int ret = 0; + + netif_stop_queue(netdev); + + /* the IRDA wrapping routines don't deal with non linear skb */ + SKB_LINEAR_ASSERT(skb); + + kingsun = netdev_priv(netdev); + + spin_lock(&kingsun->lock); + + /* Append data to the end of whatever data remains to be transmitted */ + wraplen = async_wrap_skb(skb, + kingsun->out_buf, + KINGSUN_FIFO_SIZE); + + /* Calculate how much data can be transmitted in this urb */ + usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev, + usb_sndintpipe(kingsun->usbdev, kingsun->ep_out), + kingsun->out_buf, wraplen, kingsun_send_irq, + kingsun, 1); + + if ((ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC))) { + dev_err(&kingsun->usbdev->dev, + "kingsun_hard_xmit: failed tx_urb submit: %d\n", ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + netdev->stats.tx_errors++; + netif_start_queue(netdev); + } + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + } + + dev_kfree_skb(skb); + spin_unlock(&kingsun->lock); + + return NETDEV_TX_OK; +} + +/* Receive callback function */ +static void kingsun_rcv_irq(struct urb *urb) +{ + struct kingsun_cb *kingsun = urb->context; + int ret; + + /* in process of stopping, just drop data */ + if (!netif_running(kingsun->netdev)) { + kingsun->receiving = 0; + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "kingsun_rcv_irq: urb asynchronously failed - %d\n", + urb->status); + kingsun->receiving = 0; + return; + } + + if (urb->actual_length == kingsun->max_rx) { + __u8 *bytes = urb->transfer_buffer; + int i; + + /* The very first byte in the buffer indicates the length of + valid data in the read. This byte must be in the range + 1..kingsun->max_rx -1 . Values outside this range indicate + an uninitialized Rx buffer when the dongle has just been + plugged in. */ + if (bytes[0] >= 1 && bytes[0] < kingsun->max_rx) { + for (i = 1; i <= bytes[0]; i++) { + async_unwrap_char(kingsun->netdev, + &kingsun->netdev->stats, + &kingsun->rx_buff, bytes[i]); + } + do_gettimeofday(&kingsun->rx_time); + kingsun->receiving = + (kingsun->rx_buff.state != OUTSIDE_FRAME) + ? 1 : 0; + } + } else if (urb->actual_length > 0) { + dev_err(&kingsun->usbdev->dev, + "%s(): Unexpected response length, expected %d got %d\n", + __func__, kingsun->max_rx, urb->actual_length); + } + /* This urb has already been filled in kingsun_net_open */ + ret = usb_submit_urb(urb, GFP_ATOMIC); +} + +/* + * Function kingsun_net_open (dev) + * + * Network device is taken up. Usually this is done by "ifconfig irda0 up" + */ +static int kingsun_net_open(struct net_device *netdev) +{ + struct kingsun_cb *kingsun = netdev_priv(netdev); + int err = -ENOMEM; + char hwname[16]; + + /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */ + kingsun->receiving = 0; + + /* Initialize for SIR to copy data directly into skb. */ + kingsun->rx_buff.in_frame = FALSE; + kingsun->rx_buff.state = OUTSIDE_FRAME; + kingsun->rx_buff.truesize = IRDA_SKB_MAX_MTU; + kingsun->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); + if (!kingsun->rx_buff.skb) + goto free_mem; + + skb_reserve(kingsun->rx_buff.skb, 1); + kingsun->rx_buff.head = kingsun->rx_buff.skb->data; + do_gettimeofday(&kingsun->rx_time); + + kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->rx_urb) + goto free_mem; + + kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->tx_urb) + goto free_mem; + + /* + * Now that everything should be initialized properly, + * Open new IrLAP layer instance to take care of us... + */ + sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); + kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); + if (!kingsun->irlap) { + dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); + goto free_mem; + } + + /* Start first reception */ + usb_fill_int_urb(kingsun->rx_urb, kingsun->usbdev, + usb_rcvintpipe(kingsun->usbdev, kingsun->ep_in), + kingsun->in_buf, kingsun->max_rx, + kingsun_rcv_irq, kingsun, 1); + kingsun->rx_urb->status = 0; + err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + if (err) { + dev_err(&kingsun->usbdev->dev, + "first urb-submit failed: %d\n", err); + goto close_irlap; + } + + netif_start_queue(netdev); + + /* Situation at this point: + - all work buffers allocated + - urbs allocated and ready to fill + - max rx packet known (in max_rx) + - unwrap state machine initialized, in state outside of any frame + - receive request in progress + - IrLAP layer started, about to hand over packets to send + */ + + return 0; + + close_irlap: + irlap_close(kingsun->irlap); + free_mem: + if (kingsun->tx_urb) { + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + } + if (kingsun->rx_urb) { + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + } + if (kingsun->rx_buff.skb) { + kfree_skb(kingsun->rx_buff.skb); + kingsun->rx_buff.skb = NULL; + kingsun->rx_buff.head = NULL; + } + return err; +} + +/* + * Function kingsun_net_close (kingsun) + * + * Network device is taken down. Usually this is done by + * "ifconfig irda0 down" + */ +static int kingsun_net_close(struct net_device *netdev) +{ + struct kingsun_cb *kingsun = netdev_priv(netdev); + + /* Stop transmit processing */ + netif_stop_queue(netdev); + + /* Mop up receive && transmit urb's */ + usb_kill_urb(kingsun->tx_urb); + usb_kill_urb(kingsun->rx_urb); + + usb_free_urb(kingsun->tx_urb); + usb_free_urb(kingsun->rx_urb); + + kingsun->tx_urb = NULL; + kingsun->rx_urb = NULL; + + kfree_skb(kingsun->rx_buff.skb); + kingsun->rx_buff.skb = NULL; + kingsun->rx_buff.head = NULL; + kingsun->rx_buff.in_frame = FALSE; + kingsun->rx_buff.state = OUTSIDE_FRAME; + kingsun->receiving = 0; + + /* Stop and remove instance of IrLAP */ + if (kingsun->irlap) + irlap_close(kingsun->irlap); + + kingsun->irlap = NULL; + + return 0; +} + +/* + * IOCTLs : Extra out-of-band network commands... + */ +static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq, + int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *) rq; + struct kingsun_cb *kingsun = netdev_priv(netdev); + int ret = 0; + + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the device is still there */ + if (netif_device_present(kingsun->netdev)) + /* No observed commands for speed change */ + ret = -EOPNOTSUPP; + break; + + case SIOCSMEDIABUSY: /* Set media busy */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the IrDA stack is still there */ + if (netif_running(kingsun->netdev)) + irda_device_set_media_busy(kingsun->netdev, TRUE); + break; + + case SIOCGRECEIVING: + /* Only approximately true */ + irq->ifr_receiving = kingsun->receiving; + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +static const struct net_device_ops kingsun_ops = { + .ndo_start_xmit = kingsun_hard_xmit, + .ndo_open = kingsun_net_open, + .ndo_stop = kingsun_net_close, + .ndo_do_ioctl = kingsun_net_ioctl, +}; + +/* + * This routine is called by the USB subsystem for each new device + * in the system. We need to check if the device is ours, and in + * this case start handling it. + */ +static int kingsun_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + + struct usb_device *dev = interface_to_usbdev(intf); + struct kingsun_cb *kingsun = NULL; + struct net_device *net = NULL; + int ret = -ENOMEM; + int pipe, maxp_in, maxp_out; + __u8 ep_in; + __u8 ep_out; + + /* Check that there really are two interrupt endpoints. + Check based on the one in drivers/usb/input/usbmouse.c + */ + interface = intf->cur_altsetting; + if (interface->desc.bNumEndpoints != 2) { + dev_err(&intf->dev, + "kingsun-sir: expected 2 endpoints, found %d\n", + interface->desc.bNumEndpoints); + return -ENODEV; + } + endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; + if (!usb_endpoint_is_int_in(endpoint)) { + dev_err(&intf->dev, + "kingsun-sir: endpoint 0 is not interrupt IN\n"); + return -ENODEV; + } + + ep_in = endpoint->bEndpointAddress; + pipe = usb_rcvintpipe(dev, ep_in); + maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + if (maxp_in > 255 || maxp_in <= 1) { + dev_err(&intf->dev, + "endpoint 0 has max packet size %d not in range\n", + maxp_in); + return -ENODEV; + } + + endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; + if (!usb_endpoint_is_int_out(endpoint)) { + dev_err(&intf->dev, + "kingsun-sir: endpoint 1 is not interrupt OUT\n"); + return -ENODEV; + } + + ep_out = endpoint->bEndpointAddress; + pipe = usb_sndintpipe(dev, ep_out); + maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + /* Allocate network device container. */ + net = alloc_irdadev(sizeof(*kingsun)); + if(!net) + goto err_out1; + + SET_NETDEV_DEV(net, &intf->dev); + kingsun = netdev_priv(net); + kingsun->irlap = NULL; + kingsun->tx_urb = NULL; + kingsun->rx_urb = NULL; + kingsun->ep_in = ep_in; + kingsun->ep_out = ep_out; + kingsun->in_buf = NULL; + kingsun->out_buf = NULL; + kingsun->max_rx = (__u8)maxp_in; + kingsun->max_tx = (__u8)maxp_out; + kingsun->netdev = net; + kingsun->usbdev = dev; + kingsun->rx_buff.in_frame = FALSE; + kingsun->rx_buff.state = OUTSIDE_FRAME; + kingsun->rx_buff.skb = NULL; + kingsun->receiving = 0; + spin_lock_init(&kingsun->lock); + + /* Allocate input buffer */ + kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); + if (!kingsun->in_buf) + goto free_mem; + + /* Allocate output buffer */ + kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); + if (!kingsun->out_buf) + goto free_mem; + + printk(KERN_INFO "KingSun/DonShine IRDA/USB found at address %d, " + "Vendor: %x, Product: %x\n", + dev->devnum, le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + /* Initialize QoS for this device */ + irda_init_max_qos_capabilies(&kingsun->qos); + + /* That's the Rx capability. */ + kingsun->qos.baud_rate.bits &= IR_9600; + kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; + irda_qos_bits_to_value(&kingsun->qos); + + /* Override the network functions we need to use */ + net->netdev_ops = &kingsun_ops; + + ret = register_netdev(net); + if (ret != 0) + goto free_mem; + + dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n", + net->name); + + usb_set_intfdata(intf, kingsun); + + /* Situation at this point: + - all work buffers allocated + - urbs not allocated, set to NULL + - max rx packet known (in max_rx) + - unwrap state machine (partially) initialized, but skb == NULL + */ + + return 0; + +free_mem: + if (kingsun->out_buf) kfree(kingsun->out_buf); + if (kingsun->in_buf) kfree(kingsun->in_buf); + free_netdev(net); +err_out1: + return ret; +} + +/* + * The current device is removed, the USB layer tell us to shut it down... + */ +static void kingsun_disconnect(struct usb_interface *intf) +{ + struct kingsun_cb *kingsun = usb_get_intfdata(intf); + + if (!kingsun) + return; + + unregister_netdev(kingsun->netdev); + + /* Mop up receive && transmit urb's */ + if (kingsun->tx_urb != NULL) { + usb_kill_urb(kingsun->tx_urb); + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + } + if (kingsun->rx_urb != NULL) { + usb_kill_urb(kingsun->rx_urb); + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + } + + kfree(kingsun->out_buf); + kfree(kingsun->in_buf); + free_netdev(kingsun->netdev); + + usb_set_intfdata(intf, NULL); +} + +#ifdef CONFIG_PM +/* USB suspend, so power off the transmitter/receiver */ +static int kingsun_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct kingsun_cb *kingsun = usb_get_intfdata(intf); + + netif_device_detach(kingsun->netdev); + if (kingsun->tx_urb != NULL) usb_kill_urb(kingsun->tx_urb); + if (kingsun->rx_urb != NULL) usb_kill_urb(kingsun->rx_urb); + return 0; +} + +/* Coming out of suspend, so reset hardware */ +static int kingsun_resume(struct usb_interface *intf) +{ + struct kingsun_cb *kingsun = usb_get_intfdata(intf); + + if (kingsun->rx_urb != NULL) + usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + netif_device_attach(kingsun->netdev); + + return 0; +} +#endif + +/* + * USB device callbacks + */ +static struct usb_driver irda_driver = { + .name = "kingsun-sir", + .probe = kingsun_probe, + .disconnect = kingsun_disconnect, + .id_table = dongles, +#ifdef CONFIG_PM + .suspend = kingsun_suspend, + .resume = kingsun_resume, +#endif +}; + +module_usb_driver(irda_driver); + +MODULE_AUTHOR("Alex VillacÃs Lasso <a_villacis@palosanto.com>"); +MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun/DonShine"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c new file mode 100644 index 00000000000..e6b3804edac --- /dev/null +++ b/drivers/net/irda/ks959-sir.c @@ -0,0 +1,915 @@ +/***************************************************************************** +* +* Filename: ks959-sir.c +* Version: 0.1.2 +* Description: Irda KingSun KS-959 USB Dongle +* Status: Experimental +* Author: Alex VillacÃs Lasso <a_villacis@palosanto.com> +* with help from Domen Puncer <domen@coderock.org> +* +* Based on stir4200, mcs7780, kingsun-sir drivers. +* +* 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. +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +/* + * Following is my most current (2007-07-17) understanding of how the Kingsun + * KS-959 dongle is supposed to work. This information was deduced by + * reverse-engineering and examining the USB traffic captured with USBSnoopy + * from the WinXP driver. Feel free to update here as more of the dongle is + * known. + * + * My most sincere thanks must go to Domen Puncer <domen@coderock.org> for + * invaluable help in cracking the obfuscation and padding required for this + * dongle. + * + * General: This dongle exposes one interface with one interrupt IN endpoint. + * However, the interrupt endpoint is NOT used at all for this dongle. Instead, + * this dongle uses control transfers for everything, including sending and + * receiving the IrDA frame data. Apparently the interrupt endpoint is just a + * dummy to ensure the dongle has a valid interface to present to the PC.And I + * thought the DonShine dongle was weird... In addition, this dongle uses + * obfuscation (?!?!), applied at the USB level, to hide the traffic, both sent + * and received, from the dongle. I call it obfuscation because the XOR keying + * and padding required to produce an USB traffic acceptable for the dongle can + * not be explained by any other technical requirement. + * + * Transmission: To transmit an IrDA frame, the driver must prepare a control + * URB with the following as a setup packet: + * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE + * bRequest 0x09 + * wValue <length of valid data before padding, little endian> + * wIndex 0x0000 + * wLength <length of padded data> + * The payload packet must be manually wrapped and escaped (as in stir4200.c), + * then padded and obfuscated before being sent. Both padding and obfuscation + * are implemented in the procedure obfuscate_tx_buffer(). Suffice to say, the + * designer/programmer of the dongle used his name as a source for the + * obfuscation. WTF?! + * Apparently the dongle cannot handle payloads larger than 256 bytes. The + * driver has to perform fragmentation in order to send anything larger than + * this limit. + * + * Reception: To receive data, the driver must poll the dongle regularly (like + * kingsun-sir.c) with control URBs and the following as a setup packet: + * bRequestType USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE + * bRequest 0x01 + * wValue 0x0200 + * wIndex 0x0000 + * wLength 0x0800 (size of available buffer) + * If there is data to be read, it will be returned as the response payload. + * This data is (apparently) not padded, but it is obfuscated. To de-obfuscate + * it, the driver must XOR every byte, in sequence, with a value that starts at + * 1 and is incremented with each byte processed, and then with 0x55. The value + * incremented with each byte processed overflows as an unsigned char. The + * resulting bytes form a wrapped SIR frame that is unwrapped and unescaped + * as in stir4200.c The incremented value is NOT reset with each frame, but is + * kept across the entire session with the dongle. Also, the dongle inserts an + * extra garbage byte with value 0x95 (after decoding) every 0xff bytes, which + * must be skipped. + * + * Speed change: To change the speed of the dongle, the driver prepares a + * control URB with the following as a setup packet: + * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE + * bRequest 0x09 + * wValue 0x0200 + * wIndex 0x0001 + * wLength 0x0008 (length of the payload) + * The payload is a 8-byte record, apparently identical to the one used in + * drivers/usb/serial/cypress_m8.c to change speed: + * __u32 baudSpeed; + * unsigned int dataBits : 2; // 0 - 5 bits 3 - 8 bits + * unsigned int : 1; + * unsigned int stopBits : 1; + * unsigned int parityEnable : 1; + * unsigned int parityType : 1; + * unsigned int : 1; + * unsigned int reset : 1; + * unsigned char reserved[3]; // set to 0 + * + * For now only SIR speeds have been observed with this dongle. Therefore, + * nothing is known on what changes (if any) must be done to frame wrapping / + * unwrapping for higher than SIR speeds. This driver assumes no change is + * necessary and announces support for all the way to 57600 bps. Although the + * package announces support for up to 4MBps, tests with a Sony Ericcson K300 + * phone show corruption when receiving large frames at 115200 bps, the highest + * speed announced by the phone. However, transmission at 115200 bps is OK. Go + * figure. Since I don't know whether the phone or the dongle is at fault, max + * announced speed is 57600 bps until someone produces a device that can run + * at higher speeds with this dongle. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/usb.h> +#include <linux/device.h> +#include <linux/crc32.h> + +#include <asm/unaligned.h> +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +#include <net/irda/irda.h> +#include <net/irda/wrapper.h> +#include <net/irda/crc.h> + +#define KS959_VENDOR_ID 0x07d0 +#define KS959_PRODUCT_ID 0x4959 + +/* These are the currently known USB ids */ +static struct usb_device_id dongles[] = { + /* KingSun Co,Ltd IrDA/USB Bridge */ + {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, dongles); + +#define KINGSUN_MTT 0x07 +#define KINGSUN_REQ_RECV 0x01 +#define KINGSUN_REQ_SEND 0x09 + +#define KINGSUN_RCV_FIFO_SIZE 2048 /* Max length we can receive */ +#define KINGSUN_SND_FIFO_SIZE 2048 /* Max packet we can send */ +#define KINGSUN_SND_PACKET_SIZE 256 /* Max packet dongle can handle */ + +struct ks959_speedparams { + __le32 baudrate; /* baud rate, little endian */ + __u8 flags; + __u8 reserved[3]; +} __packed; + +#define KS_DATA_5_BITS 0x00 +#define KS_DATA_6_BITS 0x01 +#define KS_DATA_7_BITS 0x02 +#define KS_DATA_8_BITS 0x03 + +#define KS_STOP_BITS_1 0x00 +#define KS_STOP_BITS_2 0x08 + +#define KS_PAR_DISABLE 0x00 +#define KS_PAR_EVEN 0x10 +#define KS_PAR_ODD 0x30 +#define KS_RESET 0x80 + +struct ks959_cb { + struct usb_device *usbdev; /* init: probe_irda */ + struct net_device *netdev; /* network layer */ + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct qos_info qos; + + struct usb_ctrlrequest *tx_setuprequest; + struct urb *tx_urb; + __u8 *tx_buf_clear; + unsigned int tx_buf_clear_used; + unsigned int tx_buf_clear_sent; + __u8 *tx_buf_xored; + + struct usb_ctrlrequest *rx_setuprequest; + struct urb *rx_urb; + __u8 *rx_buf; + __u8 rx_variable_xormask; + iobuff_t rx_unwrap_buff; + struct timeval rx_time; + + struct usb_ctrlrequest *speed_setuprequest; + struct urb *speed_urb; + struct ks959_speedparams speedparams; + unsigned int new_speed; + + spinlock_t lock; + int receiving; +}; + +/* Procedure to perform the obfuscation/padding expected by the dongle + * + * buf_cleartext (IN) Cleartext version of the IrDA frame to transmit + * len_cleartext (IN) Length of the cleartext version of IrDA frame + * buf_xoredtext (OUT) Obfuscated version of frame built by proc + * len_maxbuf (OUT) Maximum space available at buf_xoredtext + * + * (return) length of obfuscated frame with padding + * + * If not enough space (as indicated by len_maxbuf vs. required padding), + * zero is returned + * + * The value of lookup_string is actually a required portion of the algorithm. + * Seems the designer of the dongle wanted to state who exactly is responsible + * for implementing obfuscation. Send your best (or other) wishes to him ]:-) + */ +static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext, + unsigned int len_cleartext, + __u8 * buf_xoredtext, + unsigned int len_maxbuf) +{ + unsigned int len_xoredtext; + + /* Calculate required length with padding, check for necessary space */ + len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10; + if (len_xoredtext <= len_maxbuf) { + static const __u8 lookup_string[] = "wangshuofei19710"; + __u8 xor_mask; + + /* Unlike the WinXP driver, we *do* clear out the padding */ + memset(buf_xoredtext, 0, len_xoredtext); + + xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55; + + while (len_cleartext-- > 0) { + *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask; + } + } else { + len_xoredtext = 0; + } + return len_xoredtext; +} + +/* Callback transmission routine */ +static void ks959_speed_irq(struct urb *urb) +{ + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&urb->dev->dev, + "ks959_speed_irq: urb asynchronously failed - %d\n", + urb->status); + } +} + +/* Send a control request to change speed of the dongle */ +static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed) +{ + static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400, + 57600, 115200, 576000, 1152000, 4000000, 0 + }; + int err; + unsigned int i; + + if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL) + return -ENOMEM; + + /* Check that requested speed is among the supported ones */ + for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ; + if (supported_speeds[i] == 0) + return -EOPNOTSUPP; + + memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams)); + kingsun->speedparams.baudrate = cpu_to_le32(speed); + kingsun->speedparams.flags = KS_DATA_8_BITS; + + /* speed_setuprequest pre-filled in ks959_probe */ + usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev, + usb_sndctrlpipe(kingsun->usbdev, 0), + (unsigned char *)kingsun->speed_setuprequest, + &(kingsun->speedparams), + sizeof(struct ks959_speedparams), ks959_speed_irq, + kingsun); + kingsun->speed_urb->status = 0; + err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC); + + return err; +} + +/* Submit one fragment of an IrDA frame to the dongle */ +static void ks959_send_irq(struct urb *urb); +static int ks959_submit_tx_fragment(struct ks959_cb *kingsun) +{ + unsigned int padlen; + unsigned int wraplen; + int ret; + + /* Check whether current plaintext can produce a padded buffer that fits + within the range handled by the dongle */ + wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10; + if (wraplen > kingsun->tx_buf_clear_used) + wraplen = kingsun->tx_buf_clear_used; + + /* Perform dongle obfuscation. Also remove the portion of the frame that + was just obfuscated and will now be sent to the dongle. */ + padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen, + kingsun->tx_buf_xored, + KINGSUN_SND_PACKET_SIZE); + + /* Calculate how much data can be transmitted in this urb */ + kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen); + kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen); + /* Rest of the fields were filled in ks959_probe */ + usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev, + usb_sndctrlpipe(kingsun->usbdev, 0), + (unsigned char *)kingsun->tx_setuprequest, + kingsun->tx_buf_xored, padlen, + ks959_send_irq, kingsun); + kingsun->tx_urb->status = 0; + ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC); + + /* Remember how much data was sent, in order to update at callback */ + kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0; + return ret; +} + +/* Callback transmission routine */ +static void ks959_send_irq(struct urb *urb) +{ + struct ks959_cb *kingsun = urb->context; + struct net_device *netdev = kingsun->netdev; + int ret = 0; + + /* in process of stopping, just drop data */ + if (!netif_running(kingsun->netdev)) { + dev_err(&kingsun->usbdev->dev, + "ks959_send_irq: Network not running!\n"); + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "ks959_send_irq: urb asynchronously failed - %d\n", + urb->status); + return; + } + + if (kingsun->tx_buf_clear_used > 0) { + /* Update data remaining to be sent */ + if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) { + memmove(kingsun->tx_buf_clear, + kingsun->tx_buf_clear + + kingsun->tx_buf_clear_sent, + kingsun->tx_buf_clear_used - + kingsun->tx_buf_clear_sent); + } + kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent; + kingsun->tx_buf_clear_sent = 0; + + if (kingsun->tx_buf_clear_used > 0) { + /* There is more data to be sent */ + if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { + dev_err(&kingsun->usbdev->dev, + "ks959_send_irq: failed tx_urb submit: %d\n", + ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + netdev->stats.tx_errors++; + netif_start_queue(netdev); + } + } + } else { + /* All data sent, send next speed && wake network queue */ + if (kingsun->new_speed != -1 && + cpu_to_le32(kingsun->new_speed) != + kingsun->speedparams.baudrate) + ks959_change_speed(kingsun, kingsun->new_speed); + + netif_wake_queue(netdev); + } + } +} + +/* + * Called from net/core when new frame is available. + */ +static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct ks959_cb *kingsun; + unsigned int wraplen; + int ret = 0; + + netif_stop_queue(netdev); + + /* the IRDA wrapping routines don't deal with non linear skb */ + SKB_LINEAR_ASSERT(skb); + + kingsun = netdev_priv(netdev); + + spin_lock(&kingsun->lock); + kingsun->new_speed = irda_get_next_speed(skb); + + /* Append data to the end of whatever data remains to be transmitted */ + wraplen = + async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE); + kingsun->tx_buf_clear_used = wraplen; + + if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { + dev_err(&kingsun->usbdev->dev, + "ks959_hard_xmit: failed tx_urb submit: %d\n", ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + netdev->stats.tx_errors++; + netif_start_queue(netdev); + } + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + + } + + dev_kfree_skb(skb); + spin_unlock(&kingsun->lock); + + return NETDEV_TX_OK; +} + +/* Receive callback function */ +static void ks959_rcv_irq(struct urb *urb) +{ + struct ks959_cb *kingsun = urb->context; + int ret; + + /* in process of stopping, just drop data */ + if (!netif_running(kingsun->netdev)) { + kingsun->receiving = 0; + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "kingsun_rcv_irq: urb asynchronously failed - %d\n", + urb->status); + kingsun->receiving = 0; + return; + } + + if (urb->actual_length > 0) { + __u8 *bytes = urb->transfer_buffer; + unsigned int i; + + for (i = 0; i < urb->actual_length; i++) { + /* De-obfuscation implemented here: variable portion of + xormask is incremented, and then used with the encoded + byte for the XOR. The result of the operation is used + to unwrap the SIR frame. */ + kingsun->rx_variable_xormask++; + bytes[i] = + bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u; + + /* rx_variable_xormask doubles as an index counter so we + can skip the byte at 0xff (wrapped around to 0). + */ + if (kingsun->rx_variable_xormask != 0) { + async_unwrap_char(kingsun->netdev, + &kingsun->netdev->stats, + &kingsun->rx_unwrap_buff, + bytes[i]); + } + } + do_gettimeofday(&kingsun->rx_time); + kingsun->receiving = + (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; + } + + /* This urb has already been filled in kingsun_net_open. Setup + packet must be re-filled, but it is assumed that urb keeps the + pointer to the initial setup packet, as well as the payload buffer. + Setup packet is already pre-filled at ks959_probe. + */ + urb->status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); +} + +/* + * Function kingsun_net_open (dev) + * + * Network device is taken up. Usually this is done by "ifconfig irda0 up" + */ +static int ks959_net_open(struct net_device *netdev) +{ + struct ks959_cb *kingsun = netdev_priv(netdev); + int err = -ENOMEM; + char hwname[16]; + + /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */ + kingsun->receiving = 0; + + /* Initialize for SIR to copy data directly into skb. */ + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU; + kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); + if (!kingsun->rx_unwrap_buff.skb) + goto free_mem; + + skb_reserve(kingsun->rx_unwrap_buff.skb, 1); + kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data; + do_gettimeofday(&kingsun->rx_time); + + kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->rx_urb) + goto free_mem; + + kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->tx_urb) + goto free_mem; + + kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->speed_urb) + goto free_mem; + + /* Initialize speed for dongle */ + kingsun->new_speed = 9600; + err = ks959_change_speed(kingsun, 9600); + if (err < 0) + goto free_mem; + + /* + * Now that everything should be initialized properly, + * Open new IrLAP layer instance to take care of us... + */ + sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); + kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); + if (!kingsun->irlap) { + err = -ENOMEM; + dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); + goto free_mem; + } + + /* Start reception. Setup request already pre-filled in ks959_probe */ + usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev, + usb_rcvctrlpipe(kingsun->usbdev, 0), + (unsigned char *)kingsun->rx_setuprequest, + kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE, + ks959_rcv_irq, kingsun); + kingsun->rx_urb->status = 0; + err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + if (err) { + dev_err(&kingsun->usbdev->dev, + "first urb-submit failed: %d\n", err); + goto close_irlap; + } + + netif_start_queue(netdev); + + /* Situation at this point: + - all work buffers allocated + - urbs allocated and ready to fill + - max rx packet known (in max_rx) + - unwrap state machine initialized, in state outside of any frame + - receive request in progress + - IrLAP layer started, about to hand over packets to send + */ + + return 0; + + close_irlap: + irlap_close(kingsun->irlap); + free_mem: + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + if (kingsun->rx_unwrap_buff.skb) { + kfree_skb(kingsun->rx_unwrap_buff.skb); + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->rx_unwrap_buff.head = NULL; + } + return err; +} + +/* + * Function kingsun_net_close (kingsun) + * + * Network device is taken down. Usually this is done by + * "ifconfig irda0 down" + */ +static int ks959_net_close(struct net_device *netdev) +{ + struct ks959_cb *kingsun = netdev_priv(netdev); + + /* Stop transmit processing */ + netif_stop_queue(netdev); + + /* Mop up receive && transmit urb's */ + usb_kill_urb(kingsun->tx_urb); + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + + usb_kill_urb(kingsun->speed_urb); + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + + usb_kill_urb(kingsun->rx_urb); + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + + kfree_skb(kingsun->rx_unwrap_buff.skb); + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->rx_unwrap_buff.head = NULL; + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->receiving = 0; + + /* Stop and remove instance of IrLAP */ + if (kingsun->irlap) + irlap_close(kingsun->irlap); + + kingsun->irlap = NULL; + + return 0; +} + +/* + * IOCTLs : Extra out-of-band network commands... + */ +static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *)rq; + struct ks959_cb *kingsun = netdev_priv(netdev); + int ret = 0; + + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the device is still there */ + if (netif_device_present(kingsun->netdev)) + return ks959_change_speed(kingsun, irq->ifr_baudrate); + break; + + case SIOCSMEDIABUSY: /* Set media busy */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the IrDA stack is still there */ + if (netif_running(kingsun->netdev)) + irda_device_set_media_busy(kingsun->netdev, TRUE); + break; + + case SIOCGRECEIVING: + /* Only approximately true */ + irq->ifr_receiving = kingsun->receiving; + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +static const struct net_device_ops ks959_ops = { + .ndo_start_xmit = ks959_hard_xmit, + .ndo_open = ks959_net_open, + .ndo_stop = ks959_net_close, + .ndo_do_ioctl = ks959_net_ioctl, +}; +/* + * This routine is called by the USB subsystem for each new device + * in the system. We need to check if the device is ours, and in + * this case start handling it. + */ +static int ks959_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct ks959_cb *kingsun = NULL; + struct net_device *net = NULL; + int ret = -ENOMEM; + + /* Allocate network device container. */ + net = alloc_irdadev(sizeof(*kingsun)); + if (!net) + goto err_out1; + + SET_NETDEV_DEV(net, &intf->dev); + kingsun = netdev_priv(net); + kingsun->netdev = net; + kingsun->usbdev = dev; + kingsun->irlap = NULL; + kingsun->tx_setuprequest = NULL; + kingsun->tx_urb = NULL; + kingsun->tx_buf_clear = NULL; + kingsun->tx_buf_xored = NULL; + kingsun->tx_buf_clear_used = 0; + kingsun->tx_buf_clear_sent = 0; + + kingsun->rx_setuprequest = NULL; + kingsun->rx_urb = NULL; + kingsun->rx_buf = NULL; + kingsun->rx_variable_xormask = 0; + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->receiving = 0; + spin_lock_init(&kingsun->lock); + + kingsun->speed_setuprequest = NULL; + kingsun->speed_urb = NULL; + kingsun->speedparams.baudrate = 0; + + /* Allocate input buffer */ + kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL); + if (!kingsun->rx_buf) + goto free_mem; + + /* Allocate input setup packet */ + kingsun->rx_setuprequest = + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!kingsun->rx_setuprequest) + goto free_mem; + kingsun->rx_setuprequest->bRequestType = + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV; + kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200); + kingsun->rx_setuprequest->wIndex = 0; + kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE); + + /* Allocate output buffer */ + kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL); + if (!kingsun->tx_buf_clear) + goto free_mem; + kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL); + if (!kingsun->tx_buf_xored) + goto free_mem; + + /* Allocate and initialize output setup packet */ + kingsun->tx_setuprequest = + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!kingsun->tx_setuprequest) + goto free_mem; + kingsun->tx_setuprequest->bRequestType = + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND; + kingsun->tx_setuprequest->wValue = 0; + kingsun->tx_setuprequest->wIndex = 0; + kingsun->tx_setuprequest->wLength = 0; + + /* Allocate and initialize speed setup packet */ + kingsun->speed_setuprequest = + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!kingsun->speed_setuprequest) + goto free_mem; + kingsun->speed_setuprequest->bRequestType = + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; + kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); + kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); + kingsun->speed_setuprequest->wLength = + cpu_to_le16(sizeof(struct ks959_speedparams)); + + printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, " + "Vendor: %x, Product: %x\n", + dev->devnum, le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + /* Initialize QoS for this device */ + irda_init_max_qos_capabilies(&kingsun->qos); + + /* Baud rates known to be supported. Please uncomment if devices (other + than a SonyEriccson K300 phone) can be shown to support higher speed + with this dongle. + */ + kingsun->qos.baud_rate.bits = + IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600; + kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; + irda_qos_bits_to_value(&kingsun->qos); + + /* Override the network functions we need to use */ + net->netdev_ops = &ks959_ops; + + ret = register_netdev(net); + if (ret != 0) + goto free_mem; + + dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n", + net->name); + + usb_set_intfdata(intf, kingsun); + + /* Situation at this point: + - all work buffers allocated + - setup requests pre-filled + - urbs not allocated, set to NULL + - max rx packet known (is KINGSUN_FIFO_SIZE) + - unwrap state machine (partially) initialized, but skb == NULL + */ + + return 0; + + free_mem: + kfree(kingsun->speed_setuprequest); + kfree(kingsun->tx_setuprequest); + kfree(kingsun->tx_buf_xored); + kfree(kingsun->tx_buf_clear); + kfree(kingsun->rx_setuprequest); + kfree(kingsun->rx_buf); + free_netdev(net); + err_out1: + return ret; +} + +/* + * The current device is removed, the USB layer tell us to shut it down... + */ +static void ks959_disconnect(struct usb_interface *intf) +{ + struct ks959_cb *kingsun = usb_get_intfdata(intf); + + if (!kingsun) + return; + + unregister_netdev(kingsun->netdev); + + /* Mop up receive && transmit urb's */ + if (kingsun->speed_urb != NULL) { + usb_kill_urb(kingsun->speed_urb); + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + } + if (kingsun->tx_urb != NULL) { + usb_kill_urb(kingsun->tx_urb); + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + } + if (kingsun->rx_urb != NULL) { + usb_kill_urb(kingsun->rx_urb); + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + } + + kfree(kingsun->speed_setuprequest); + kfree(kingsun->tx_setuprequest); + kfree(kingsun->tx_buf_xored); + kfree(kingsun->tx_buf_clear); + kfree(kingsun->rx_setuprequest); + kfree(kingsun->rx_buf); + free_netdev(kingsun->netdev); + + usb_set_intfdata(intf, NULL); +} + +#ifdef CONFIG_PM +/* USB suspend, so power off the transmitter/receiver */ +static int ks959_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct ks959_cb *kingsun = usb_get_intfdata(intf); + + netif_device_detach(kingsun->netdev); + if (kingsun->speed_urb != NULL) + usb_kill_urb(kingsun->speed_urb); + if (kingsun->tx_urb != NULL) + usb_kill_urb(kingsun->tx_urb); + if (kingsun->rx_urb != NULL) + usb_kill_urb(kingsun->rx_urb); + return 0; +} + +/* Coming out of suspend, so reset hardware */ +static int ks959_resume(struct usb_interface *intf) +{ + struct ks959_cb *kingsun = usb_get_intfdata(intf); + + if (kingsun->rx_urb != NULL) { + /* Setup request already filled in ks959_probe */ + usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + } + netif_device_attach(kingsun->netdev); + + return 0; +} +#endif + +/* + * USB device callbacks + */ +static struct usb_driver irda_driver = { + .name = "ks959-sir", + .probe = ks959_probe, + .disconnect = ks959_disconnect, + .id_table = dongles, +#ifdef CONFIG_PM + .suspend = ks959_suspend, + .resume = ks959_resume, +#endif +}; + +module_usb_driver(irda_driver); + +MODULE_AUTHOR("Alex VillacÃs Lasso <a_villacis@palosanto.com>"); +MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c new file mode 100644 index 00000000000..37f23a189b3 --- /dev/null +++ b/drivers/net/irda/ksdazzle-sir.c @@ -0,0 +1,813 @@ +/***************************************************************************** +* +* Filename: ksdazzle.c +* Version: 0.1.2 +* Description: Irda KingSun Dazzle USB Dongle +* Status: Experimental +* Author: Alex VillacÃs Lasso <a_villacis@palosanto.com> +* +* Based on stir4200, mcs7780, kingsun-sir drivers. +* +* 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. +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +/* + * Following is my most current (2007-07-26) understanding of how the Kingsun + * 07D0:4100 dongle (sometimes known as the MA-660) is supposed to work. This + * information was deduced by examining the USB traffic captured with USBSnoopy + * from the WinXP driver. Feel free to update here as more of the dongle is + * known. + * + * General: This dongle exposes one interface with two interrupt endpoints, one + * IN and one OUT. In this regard, it is similar to what the Kingsun/Donshine + * dongle (07c0:4200) exposes. Traffic is raw and needs to be wrapped and + * unwrapped manually as in stir4200, kingsun-sir, and ks959-sir. + * + * Transmission: To transmit an IrDA frame, it is necessary to wrap it, then + * split it into multiple segments of up to 7 bytes each, and transmit each in + * sequence. It seems that sending a single big block (like kingsun-sir does) + * won't work with this dongle. Each segment needs to be prefixed with a value + * equal to (unsigned char)0xF8 + <number of bytes in segment>, inside a payload + * of exactly 8 bytes. For example, a segment of 1 byte gets prefixed by 0xF9, + * and one of 7 bytes gets prefixed by 0xFF. The bytes at the end of the + * payload, not considered by the prefix, are ignored (set to 0 by this + * implementation). + * + * Reception: To receive data, the driver must poll the dongle regularly (like + * kingsun-sir.c) with interrupt URBs. If data is available, it will be returned + * in payloads from 0 to 8 bytes long. When concatenated, these payloads form + * a raw IrDA stream that needs to be unwrapped as in stir4200 and kingsun-sir + * + * Speed change: To change the speed of the dongle, the driver prepares a + * control URB with the following as a setup packet: + * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE + * bRequest 0x09 + * wValue 0x0200 + * wIndex 0x0001 + * wLength 0x0008 (length of the payload) + * The payload is a 8-byte record, apparently identical to the one used in + * drivers/usb/serial/cypress_m8.c to change speed: + * __u32 baudSpeed; + * unsigned int dataBits : 2; // 0 - 5 bits 3 - 8 bits + * unsigned int : 1; + * unsigned int stopBits : 1; + * unsigned int parityEnable : 1; + * unsigned int parityType : 1; + * unsigned int : 1; + * unsigned int reset : 1; + * unsigned char reserved[3]; // set to 0 + * + * For now only SIR speeds have been observed with this dongle. Therefore, + * nothing is known on what changes (if any) must be done to frame wrapping / + * unwrapping for higher than SIR speeds. This driver assumes no change is + * necessary and announces support for all the way to 115200 bps. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/usb.h> +#include <linux/device.h> +#include <linux/crc32.h> + +#include <asm/unaligned.h> +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +#include <net/irda/irda.h> +#include <net/irda/wrapper.h> +#include <net/irda/crc.h> + +#define KSDAZZLE_VENDOR_ID 0x07d0 +#define KSDAZZLE_PRODUCT_ID 0x4100 + +/* These are the currently known USB ids */ +static struct usb_device_id dongles[] = { + /* KingSun Co,Ltd IrDA/USB Bridge */ + {USB_DEVICE(KSDAZZLE_VENDOR_ID, KSDAZZLE_PRODUCT_ID)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, dongles); + +#define KINGSUN_MTT 0x07 +#define KINGSUN_REQ_RECV 0x01 +#define KINGSUN_REQ_SEND 0x09 + +#define KINGSUN_SND_FIFO_SIZE 2048 /* Max packet we can send */ +#define KINGSUN_RCV_MAX 2048 /* Max transfer we can receive */ + +struct ksdazzle_speedparams { + __le32 baudrate; /* baud rate, little endian */ + __u8 flags; + __u8 reserved[3]; +} __packed; + +#define KS_DATA_5_BITS 0x00 +#define KS_DATA_6_BITS 0x01 +#define KS_DATA_7_BITS 0x02 +#define KS_DATA_8_BITS 0x03 + +#define KS_STOP_BITS_1 0x00 +#define KS_STOP_BITS_2 0x08 + +#define KS_PAR_DISABLE 0x00 +#define KS_PAR_EVEN 0x10 +#define KS_PAR_ODD 0x30 +#define KS_RESET 0x80 + +#define KINGSUN_EP_IN 0 +#define KINGSUN_EP_OUT 1 + +struct ksdazzle_cb { + struct usb_device *usbdev; /* init: probe_irda */ + struct net_device *netdev; /* network layer */ + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct qos_info qos; + + struct urb *tx_urb; + __u8 *tx_buf_clear; + unsigned int tx_buf_clear_used; + unsigned int tx_buf_clear_sent; + __u8 tx_payload[8]; + + struct urb *rx_urb; + __u8 *rx_buf; + iobuff_t rx_unwrap_buff; + + struct usb_ctrlrequest *speed_setuprequest; + struct urb *speed_urb; + struct ksdazzle_speedparams speedparams; + unsigned int new_speed; + + __u8 ep_in; + __u8 ep_out; + + spinlock_t lock; + int receiving; +}; + +/* Callback transmission routine */ +static void ksdazzle_speed_irq(struct urb *urb) +{ + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) + dev_err(&urb->dev->dev, + "ksdazzle_speed_irq: urb asynchronously failed - %d\n", + urb->status); +} + +/* Send a control request to change speed of the dongle */ +static int ksdazzle_change_speed(struct ksdazzle_cb *kingsun, unsigned speed) +{ + static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400, + 57600, 115200, 576000, 1152000, 4000000, 0 + }; + int err; + unsigned int i; + + if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL) + return -ENOMEM; + + /* Check that requested speed is among the supported ones */ + for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ; + if (supported_speeds[i] == 0) + return -EOPNOTSUPP; + + memset(&(kingsun->speedparams), 0, sizeof(struct ksdazzle_speedparams)); + kingsun->speedparams.baudrate = cpu_to_le32(speed); + kingsun->speedparams.flags = KS_DATA_8_BITS; + + /* speed_setuprequest pre-filled in ksdazzle_probe */ + usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev, + usb_sndctrlpipe(kingsun->usbdev, 0), + (unsigned char *)kingsun->speed_setuprequest, + &(kingsun->speedparams), + sizeof(struct ksdazzle_speedparams), + ksdazzle_speed_irq, kingsun); + kingsun->speed_urb->status = 0; + err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC); + + return err; +} + +/* Submit one fragment of an IrDA frame to the dongle */ +static void ksdazzle_send_irq(struct urb *urb); +static int ksdazzle_submit_tx_fragment(struct ksdazzle_cb *kingsun) +{ + unsigned int wraplen; + int ret; + + /* We can send at most 7 bytes of payload at a time */ + wraplen = 7; + if (wraplen > kingsun->tx_buf_clear_used) + wraplen = kingsun->tx_buf_clear_used; + + /* Prepare payload prefix with used length */ + memset(kingsun->tx_payload, 0, 8); + kingsun->tx_payload[0] = (unsigned char)0xf8 + wraplen; + memcpy(kingsun->tx_payload + 1, kingsun->tx_buf_clear, wraplen); + + usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev, + usb_sndintpipe(kingsun->usbdev, kingsun->ep_out), + kingsun->tx_payload, 8, ksdazzle_send_irq, kingsun, 1); + kingsun->tx_urb->status = 0; + ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC); + + /* Remember how much data was sent, in order to update at callback */ + kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0; + return ret; +} + +/* Callback transmission routine */ +static void ksdazzle_send_irq(struct urb *urb) +{ + struct ksdazzle_cb *kingsun = urb->context; + struct net_device *netdev = kingsun->netdev; + int ret = 0; + + /* in process of stopping, just drop data */ + if (!netif_running(kingsun->netdev)) { + dev_err(&kingsun->usbdev->dev, + "ksdazzle_send_irq: Network not running!\n"); + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "ksdazzle_send_irq: urb asynchronously failed - %d\n", + urb->status); + return; + } + + if (kingsun->tx_buf_clear_used > 0) { + /* Update data remaining to be sent */ + if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) { + memmove(kingsun->tx_buf_clear, + kingsun->tx_buf_clear + + kingsun->tx_buf_clear_sent, + kingsun->tx_buf_clear_used - + kingsun->tx_buf_clear_sent); + } + kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent; + kingsun->tx_buf_clear_sent = 0; + + if (kingsun->tx_buf_clear_used > 0) { + /* There is more data to be sent */ + if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) { + dev_err(&kingsun->usbdev->dev, + "ksdazzle_send_irq: failed tx_urb submit: %d\n", + ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + netdev->stats.tx_errors++; + netif_start_queue(netdev); + } + } + } else { + /* All data sent, send next speed && wake network queue */ + if (kingsun->new_speed != -1 && + cpu_to_le32(kingsun->new_speed) != + kingsun->speedparams.baudrate) + ksdazzle_change_speed(kingsun, + kingsun->new_speed); + + netif_wake_queue(netdev); + } + } +} + +/* + * Called from net/core when new frame is available. + */ +static netdev_tx_t ksdazzle_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct ksdazzle_cb *kingsun; + unsigned int wraplen; + int ret = 0; + + netif_stop_queue(netdev); + + /* the IRDA wrapping routines don't deal with non linear skb */ + SKB_LINEAR_ASSERT(skb); + + kingsun = netdev_priv(netdev); + + spin_lock(&kingsun->lock); + kingsun->new_speed = irda_get_next_speed(skb); + + /* Append data to the end of whatever data remains to be transmitted */ + wraplen = + async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE); + kingsun->tx_buf_clear_used = wraplen; + + if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) { + dev_err(&kingsun->usbdev->dev, + "ksdazzle_hard_xmit: failed tx_urb submit: %d\n", ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + netdev->stats.tx_errors++; + netif_start_queue(netdev); + } + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + + } + + dev_kfree_skb(skb); + spin_unlock(&kingsun->lock); + + return NETDEV_TX_OK; +} + +/* Receive callback function */ +static void ksdazzle_rcv_irq(struct urb *urb) +{ + struct ksdazzle_cb *kingsun = urb->context; + struct net_device *netdev = kingsun->netdev; + + /* in process of stopping, just drop data */ + if (!netif_running(netdev)) { + kingsun->receiving = 0; + return; + } + + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) { + dev_err(&kingsun->usbdev->dev, + "ksdazzle_rcv_irq: urb asynchronously failed - %d\n", + urb->status); + kingsun->receiving = 0; + return; + } + + if (urb->actual_length > 0) { + __u8 *bytes = urb->transfer_buffer; + unsigned int i; + + for (i = 0; i < urb->actual_length; i++) { + async_unwrap_char(netdev, &netdev->stats, + &kingsun->rx_unwrap_buff, bytes[i]); + } + kingsun->receiving = + (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; + } + + /* This urb has already been filled in ksdazzle_net_open. It is assumed that + urb keeps the pointer to the payload buffer. + */ + urb->status = 0; + usb_submit_urb(urb, GFP_ATOMIC); +} + +/* + * Function ksdazzle_net_open (dev) + * + * Network device is taken up. Usually this is done by "ifconfig irda0 up" + */ +static int ksdazzle_net_open(struct net_device *netdev) +{ + struct ksdazzle_cb *kingsun = netdev_priv(netdev); + int err = -ENOMEM; + char hwname[16]; + + /* At this point, urbs are NULL, and skb is NULL (see ksdazzle_probe) */ + kingsun->receiving = 0; + + /* Initialize for SIR to copy data directly into skb. */ + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU; + kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); + if (!kingsun->rx_unwrap_buff.skb) + goto free_mem; + + skb_reserve(kingsun->rx_unwrap_buff.skb, 1); + kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data; + + kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->rx_urb) + goto free_mem; + + kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->tx_urb) + goto free_mem; + + kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kingsun->speed_urb) + goto free_mem; + + /* Initialize speed for dongle */ + kingsun->new_speed = 9600; + err = ksdazzle_change_speed(kingsun, 9600); + if (err < 0) + goto free_mem; + + /* + * Now that everything should be initialized properly, + * Open new IrLAP layer instance to take care of us... + */ + sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); + kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); + if (!kingsun->irlap) { + err = -ENOMEM; + dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); + goto free_mem; + } + + /* Start reception. */ + usb_fill_int_urb(kingsun->rx_urb, kingsun->usbdev, + usb_rcvintpipe(kingsun->usbdev, kingsun->ep_in), + kingsun->rx_buf, KINGSUN_RCV_MAX, ksdazzle_rcv_irq, + kingsun, 1); + kingsun->rx_urb->status = 0; + err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + if (err) { + dev_err(&kingsun->usbdev->dev, "first urb-submit failed: %d\n", err); + goto close_irlap; + } + + netif_start_queue(netdev); + + /* Situation at this point: + - all work buffers allocated + - urbs allocated and ready to fill + - max rx packet known (in max_rx) + - unwrap state machine initialized, in state outside of any frame + - receive request in progress + - IrLAP layer started, about to hand over packets to send + */ + + return 0; + + close_irlap: + irlap_close(kingsun->irlap); + free_mem: + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + if (kingsun->rx_unwrap_buff.skb) { + kfree_skb(kingsun->rx_unwrap_buff.skb); + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->rx_unwrap_buff.head = NULL; + } + return err; +} + +/* + * Function ksdazzle_net_close (dev) + * + * Network device is taken down. Usually this is done by + * "ifconfig irda0 down" + */ +static int ksdazzle_net_close(struct net_device *netdev) +{ + struct ksdazzle_cb *kingsun = netdev_priv(netdev); + + /* Stop transmit processing */ + netif_stop_queue(netdev); + + /* Mop up receive && transmit urb's */ + usb_kill_urb(kingsun->tx_urb); + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + + usb_kill_urb(kingsun->speed_urb); + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + + usb_kill_urb(kingsun->rx_urb); + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + + kfree_skb(kingsun->rx_unwrap_buff.skb); + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->rx_unwrap_buff.head = NULL; + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->receiving = 0; + + /* Stop and remove instance of IrLAP */ + irlap_close(kingsun->irlap); + + kingsun->irlap = NULL; + + return 0; +} + +/* + * IOCTLs : Extra out-of-band network commands... + */ +static int ksdazzle_net_ioctl(struct net_device *netdev, struct ifreq *rq, + int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *)rq; + struct ksdazzle_cb *kingsun = netdev_priv(netdev); + int ret = 0; + + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the device is still there */ + if (netif_device_present(kingsun->netdev)) + return ksdazzle_change_speed(kingsun, + irq->ifr_baudrate); + break; + + case SIOCSMEDIABUSY: /* Set media busy */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + /* Check if the IrDA stack is still there */ + if (netif_running(kingsun->netdev)) + irda_device_set_media_busy(kingsun->netdev, TRUE); + break; + + case SIOCGRECEIVING: + /* Only approximately true */ + irq->ifr_receiving = kingsun->receiving; + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +static const struct net_device_ops ksdazzle_ops = { + .ndo_start_xmit = ksdazzle_hard_xmit, + .ndo_open = ksdazzle_net_open, + .ndo_stop = ksdazzle_net_close, + .ndo_do_ioctl = ksdazzle_net_ioctl, +}; + +/* + * This routine is called by the USB subsystem for each new device + * in the system. We need to check if the device is ours, and in + * this case start handling it. + */ +static int ksdazzle_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + + struct usb_device *dev = interface_to_usbdev(intf); + struct ksdazzle_cb *kingsun = NULL; + struct net_device *net = NULL; + int ret = -ENOMEM; + int pipe, maxp_in, maxp_out; + __u8 ep_in; + __u8 ep_out; + + /* Check that there really are two interrupt endpoints. Check based on the + one in drivers/usb/input/usbmouse.c + */ + interface = intf->cur_altsetting; + if (interface->desc.bNumEndpoints != 2) { + dev_err(&intf->dev, "ksdazzle: expected 2 endpoints, found %d\n", + interface->desc.bNumEndpoints); + return -ENODEV; + } + endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; + if (!usb_endpoint_is_int_in(endpoint)) { + dev_err(&intf->dev, + "ksdazzle: endpoint 0 is not interrupt IN\n"); + return -ENODEV; + } + + ep_in = endpoint->bEndpointAddress; + pipe = usb_rcvintpipe(dev, ep_in); + maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + if (maxp_in > 255 || maxp_in <= 1) { + dev_err(&intf->dev, + "ksdazzle: endpoint 0 has max packet size %d not in range [2..255]\n", + maxp_in); + return -ENODEV; + } + + endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; + if (!usb_endpoint_is_int_out(endpoint)) { + dev_err(&intf->dev, + "ksdazzle: endpoint 1 is not interrupt OUT\n"); + return -ENODEV; + } + + ep_out = endpoint->bEndpointAddress; + pipe = usb_sndintpipe(dev, ep_out); + maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + /* Allocate network device container. */ + net = alloc_irdadev(sizeof(*kingsun)); + if (!net) + goto err_out1; + + SET_NETDEV_DEV(net, &intf->dev); + kingsun = netdev_priv(net); + kingsun->netdev = net; + kingsun->usbdev = dev; + kingsun->ep_in = ep_in; + kingsun->ep_out = ep_out; + kingsun->irlap = NULL; + kingsun->tx_urb = NULL; + kingsun->tx_buf_clear = NULL; + kingsun->tx_buf_clear_used = 0; + kingsun->tx_buf_clear_sent = 0; + + kingsun->rx_urb = NULL; + kingsun->rx_buf = NULL; + kingsun->rx_unwrap_buff.in_frame = FALSE; + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; + kingsun->rx_unwrap_buff.skb = NULL; + kingsun->receiving = 0; + spin_lock_init(&kingsun->lock); + + kingsun->speed_setuprequest = NULL; + kingsun->speed_urb = NULL; + kingsun->speedparams.baudrate = 0; + + /* Allocate input buffer */ + kingsun->rx_buf = kmalloc(KINGSUN_RCV_MAX, GFP_KERNEL); + if (!kingsun->rx_buf) + goto free_mem; + + /* Allocate output buffer */ + kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL); + if (!kingsun->tx_buf_clear) + goto free_mem; + + /* Allocate and initialize speed setup packet */ + kingsun->speed_setuprequest = + kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!kingsun->speed_setuprequest) + goto free_mem; + kingsun->speed_setuprequest->bRequestType = + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; + kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); + kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); + kingsun->speed_setuprequest->wLength = + cpu_to_le16(sizeof(struct ksdazzle_speedparams)); + + printk(KERN_INFO "KingSun/Dazzle IRDA/USB found at address %d, " + "Vendor: %x, Product: %x\n", + dev->devnum, le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + /* Initialize QoS for this device */ + irda_init_max_qos_capabilies(&kingsun->qos); + + /* Baud rates known to be supported. Please uncomment if devices (other + than a SonyEriccson K300 phone) can be shown to support higher speeds + with this dongle. + */ + kingsun->qos.baud_rate.bits = + IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200; + kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; + irda_qos_bits_to_value(&kingsun->qos); + + /* Override the network functions we need to use */ + net->netdev_ops = &ksdazzle_ops; + + ret = register_netdev(net); + if (ret != 0) + goto free_mem; + + dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n", + net->name); + + usb_set_intfdata(intf, kingsun); + + /* Situation at this point: + - all work buffers allocated + - setup requests pre-filled + - urbs not allocated, set to NULL + - max rx packet known (is KINGSUN_FIFO_SIZE) + - unwrap state machine (partially) initialized, but skb == NULL + */ + + return 0; + + free_mem: + kfree(kingsun->speed_setuprequest); + kfree(kingsun->tx_buf_clear); + kfree(kingsun->rx_buf); + free_netdev(net); + err_out1: + return ret; +} + +/* + * The current device is removed, the USB layer tell us to shut it down... + */ +static void ksdazzle_disconnect(struct usb_interface *intf) +{ + struct ksdazzle_cb *kingsun = usb_get_intfdata(intf); + + if (!kingsun) + return; + + unregister_netdev(kingsun->netdev); + + /* Mop up receive && transmit urb's */ + usb_kill_urb(kingsun->speed_urb); + usb_free_urb(kingsun->speed_urb); + kingsun->speed_urb = NULL; + + usb_kill_urb(kingsun->tx_urb); + usb_free_urb(kingsun->tx_urb); + kingsun->tx_urb = NULL; + + usb_kill_urb(kingsun->rx_urb); + usb_free_urb(kingsun->rx_urb); + kingsun->rx_urb = NULL; + + kfree(kingsun->speed_setuprequest); + kfree(kingsun->tx_buf_clear); + kfree(kingsun->rx_buf); + free_netdev(kingsun->netdev); + + usb_set_intfdata(intf, NULL); +} + +#ifdef CONFIG_PM +/* USB suspend, so power off the transmitter/receiver */ +static int ksdazzle_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct ksdazzle_cb *kingsun = usb_get_intfdata(intf); + + netif_device_detach(kingsun->netdev); + if (kingsun->speed_urb != NULL) + usb_kill_urb(kingsun->speed_urb); + if (kingsun->tx_urb != NULL) + usb_kill_urb(kingsun->tx_urb); + if (kingsun->rx_urb != NULL) + usb_kill_urb(kingsun->rx_urb); + return 0; +} + +/* Coming out of suspend, so reset hardware */ +static int ksdazzle_resume(struct usb_interface *intf) +{ + struct ksdazzle_cb *kingsun = usb_get_intfdata(intf); + + if (kingsun->rx_urb != NULL) { + /* Setup request already filled in ksdazzle_probe */ + usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); + } + netif_device_attach(kingsun->netdev); + + return 0; +} +#endif + +/* + * USB device callbacks + */ +static struct usb_driver irda_driver = { + .name = "ksdazzle-sir", + .probe = ksdazzle_probe, + .disconnect = ksdazzle_disconnect, + .id_table = dongles, +#ifdef CONFIG_PM + .suspend = ksdazzle_suspend, + .resume = ksdazzle_resume, +#endif +}; + +module_usb_driver(irda_driver); + +MODULE_AUTHOR("Alex VillacÃs Lasso <a_villacis@palosanto.com>"); +MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun Dazzle"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/litelink-sir.c b/drivers/net/irda/litelink-sir.c index 73261c54bbf..6827777cbee 100644 --- a/drivers/net/irda/litelink-sir.c +++ b/drivers/net/irda/litelink-sir.c @@ -22,9 +22,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ @@ -78,7 +76,7 @@ static int litelink_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power up dongle */ sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -95,7 +93,7 @@ static int litelink_open(struct sir_dev *dev) static int litelink_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -113,7 +111,7 @@ static int litelink_change_speed(struct sir_dev *dev, unsigned speed) { int i; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* dongle already reset by irda-thread - current speed (dongle and * port) is the default speed (115200 for litelink!) @@ -156,7 +154,7 @@ static int litelink_change_speed(struct sir_dev *dev, unsigned speed) */ static int litelink_reset(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* probably the power-up can be dropped here, but with only * 15 usec delay it's not worth the risk unless somebody with diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c deleted file mode 100644 index 7db11431d0f..00000000000 --- a/drivers/net/irda/litelink.c +++ /dev/null @@ -1,179 +0,0 @@ -/********************************************************************* - * - * Filename: litelink.c - * Version: 1.1 - * Description: Driver for the Parallax LiteLink dongle - * Status: Stable - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Fri May 7 12:50:33 1999 - * Modified at: Fri Dec 17 09:14:23 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1999 Dag Brattli, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.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(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_reg dongle = { - .type = IRDA_LITELINK_DONGLE, - .open = litelink_open, - .close = litelink_close, - .reset = litelink_reset, - .change_speed = litelink_change_speed, - .owner = THIS_MODULE, -}; - -static int __init litelink_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit litelink_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void litelink_open(dongle_t *self, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */ -} - -static void litelink_close(dongle_t *self) -{ - /* Power off dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * 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 int litelink_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - int i; - - /* Clear RTS to reset dongle */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* Go back to normal mode */ - 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 */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* Set DTR, Set RTS */ - 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 (task) - * - * Reset the Litelink type dongle. - * - */ -static int litelink_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - - /* Power on dongle */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* Clear RTS to reset dongle */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* Go back to normal mode */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* This dongles speed defaults to 115200 bps */ - self->speed = 115200; - - irda_task_next_state(task, IRDA_TASK_DONE); - - return 0; -} - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); -MODULE_DESCRIPTION("Parallax Litelink dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-5"); /* IRDA_LITELINK_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize Litelink module - * - */ -module_init(litelink_init); - -/* - * Function cleanup_module (void) - * - * Cleanup Litelink module - * - */ -module_exit(litelink_cleanup); diff --git a/drivers/net/irda/ma600-sir.c b/drivers/net/irda/ma600-sir.c index ebed168b7da..a9a81358477 100644 --- a/drivers/net/irda/ma600-sir.c +++ b/drivers/net/irda/ma600-sir.c @@ -25,16 +25,13 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ #include <linux/module.h> #include <linux/delay.h> #include <linux/init.h> -#include <linux/sched.h> #include <net/irda/irda.h> @@ -68,13 +65,13 @@ static struct dongle_driver ma600 = { static int __init ma600_sir_init(void) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); return irda_register_dongle(&ma600); } static void __exit ma600_sir_cleanup(void) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); irda_unregister_dongle(&ma600); } @@ -89,7 +86,7 @@ static int ma600_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -107,7 +104,7 @@ static int ma600_open(struct sir_dev *dev) static int ma600_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -177,7 +174,7 @@ static int ma600_change_speed(struct sir_dev *dev, unsigned speed) { u8 byte; - IRDA_DEBUG(2, "%s(), speed=%d (was %d)\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), speed=%d (was %d)\n", __func__, speed, dev->speed); /* dongle already reset, dongle and port at default speed (9600) */ @@ -202,12 +199,12 @@ static int ma600_change_speed(struct sir_dev *dev, unsigned speed) sirdev_raw_read(dev, &byte, sizeof(byte)); if (byte != get_control_byte(speed)) { IRDA_WARNING("%s(): bad control byte read-back %02x != %02x\n", - __FUNCTION__, (unsigned) byte, + __func__, (unsigned) byte, (unsigned) get_control_byte(speed)); return -1; } else - IRDA_DEBUG(2, "%s() control byte write read OK\n", __FUNCTION__); + IRDA_DEBUG(2, "%s() control byte write read OK\n", __func__); #endif /* Set DTR, Set RTS */ @@ -237,9 +234,9 @@ static int ma600_change_speed(struct sir_dev *dev, unsigned speed) * avoid the state machine complexity before we get things working */ -int ma600_reset(struct sir_dev *dev) +static int ma600_reset(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Reset the dongle : set DTR low for 10 ms */ sirdev_set_dtr_rts(dev, FALSE, TRUE); diff --git a/drivers/net/irda/ma600.c b/drivers/net/irda/ma600.c deleted file mode 100644 index f5e6836667f..00000000000 --- a/drivers/net/irda/ma600.c +++ /dev/null @@ -1,354 +0,0 @@ -/********************************************************************* - * - * Filename: ma600.c - * Version: 0.1 - * Description: Implementation of the MA600 dongle - * Status: Experimental. - * Author: Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95 - * Created at: Sat Jun 10 20:02:35 2000 - * Modified at: - * Modified by: - * - * Note: very thanks to Mr. Maru Wang <maru@mobileaction.com.tw> for providing - * information on the MA600 dongle - * - * Copyright (c) 2000 Leung, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -/* define this macro for release version */ -//#define NDEBUG - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -#ifndef NDEBUG - #undef IRDA_DEBUG - #define IRDA_DEBUG(n, args...) (printk(KERN_DEBUG args)) - - #undef ASSERT - #define ASSERT(expr, func) \ - if(!(expr)) { \ - printk( "Assertion failed! %s,%s,%s,line=%d\n",\ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - func} -#endif - -/* convert hex value to ascii hex */ -static const char hexTbl[] = "0123456789ABCDEF"; - - -static void ma600_open(dongle_t *self, struct qos_info *qos); -static void ma600_close(dongle_t *self); -static int ma600_change_speed(struct irda_task *task); -static int ma600_reset(struct irda_task *task); - -/* control byte for MA600 */ -#define MA600_9600 0x00 -#define MA600_19200 0x01 -#define MA600_38400 0x02 -#define MA600_57600 0x03 -#define MA600_115200 0x04 -#define MA600_DEV_ID1 0x05 -#define MA600_DEV_ID2 0x06 -#define MA600_2400 0x08 - -static struct dongle_reg dongle = { - .type = IRDA_MA600_DONGLE, - .open = ma600_open, - .close = ma600_close, - .reset = ma600_reset, - .change_speed = ma600_change_speed, - .owner = THIS_MODULE, -}; - -static int __init ma600_init(void) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - return irda_device_register_dongle(&dongle); -} - -static void __exit ma600_cleanup(void) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - irda_device_unregister_dongle(&dongle); -} - -/* - Power on: - (0) Clear RTS and DTR for 1 second - (1) Set RTS and DTR for 1 second - (2) 9600 bps now - Note: assume RTS, DTR are clear before -*/ -static void ma600_open(dongle_t *self, struct qos_info *qos) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400 - |IR_57600|IR_115200; - qos->min_turn_time.bits = 0x01; /* Needs at least 1 ms */ - irda_qos_bits_to_value(qos); - - //self->set_dtr_rts(self->dev, FALSE, FALSE); - // should wait 1 second - - self->set_dtr_rts(self->dev, TRUE, TRUE); - // should wait 1 second -} - -static void ma600_close(dongle_t *self) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - /* Power off dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -static __u8 get_control_byte(__u32 speed) -{ - __u8 byte; - - switch (speed) { - default: - case 115200: - byte = MA600_115200; - break; - case 57600: - byte = MA600_57600; - break; - case 38400: - byte = MA600_38400; - break; - case 19200: - byte = MA600_19200; - break; - case 9600: - byte = MA600_9600; - break; - case 2400: - byte = MA600_2400; - break; - } - - return byte; -} - -/* - * Function ma600_change_speed (dev, state, speed) - * - * Set the speed for the MA600 type dongle. Warning, this - * function must be called with a process context! - * - * Algorithm - * 1. Reset - * 2. clear RTS, set DTR and wait for 1ms - * 3. send Control Byte to the MA600 through TXD to set new baud rate - * wait until the stop bit of Control Byte is sent (for 9600 baud rate, - * it takes about 10 msec) - * 4. set RTS, set DTR (return to NORMAL Operation) - * 5. wait at least 10 ms, new setting (baud rate, etc) takes effect here - * after - */ -static int ma600_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - static __u8 byte; - __u8 byte_echo; - int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - ASSERT(task != NULL, return -1;); - - if (self->speed_task && self->speed_task != task) { - IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__); - return msecs_to_jiffies(10); - } else { - self->speed_task = task; - } - - switch (task->state) { - case IRDA_TASK_INIT: - case IRDA_TASK_CHILD_INIT: - /* - * Need to reset the dongle and go to 9600 bps before - * programming - */ - if (irda_task_execute(self, ma600_reset, NULL, task, - (void *) speed)) { - /* Dongle need more time to reset */ - irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); - - /* give 1 second to finish */ - ret = msecs_to_jiffies(1000); - } else { - irda_task_next_state(task, IRDA_TASK_CHILD_DONE); - } - break; - - case IRDA_TASK_CHILD_WAIT: - IRDA_WARNING("%s(), resetting dongle timed out!\n", - __FUNCTION__); - ret = -1; - break; - - case IRDA_TASK_CHILD_DONE: - /* Set DTR, Clear RTS */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - - ret = msecs_to_jiffies(1); /* Sleep 1 ms */ - irda_task_next_state(task, IRDA_TASK_WAIT); - break; - - case IRDA_TASK_WAIT: - speed = (__u32) task->param; - byte = get_control_byte(speed); - - /* Write control byte */ - self->write(self->dev, &byte, sizeof(byte)); - - irda_task_next_state(task, IRDA_TASK_WAIT1); - - /* Wait at least 10 ms */ - ret = msecs_to_jiffies(15); - break; - - case IRDA_TASK_WAIT1: - /* Read control byte echo */ - self->read(self->dev, &byte_echo, sizeof(byte_echo)); - - if(byte != byte_echo) { - /* if control byte != echo, I don't know what to do */ - printk(KERN_WARNING "%s() control byte written != read!\n", __FUNCTION__); - printk(KERN_WARNING "control byte = 0x%c%c\n", - hexTbl[(byte>>4)&0x0f], hexTbl[byte&0x0f]); - printk(KERN_WARNING "byte echo = 0x%c%c\n", - hexTbl[(byte_echo>>4) & 0x0f], - hexTbl[byte_echo & 0x0f]); - #ifndef NDEBUG - } else { - IRDA_DEBUG(2, "%s() control byte write read OK\n", __FUNCTION__); - #endif - } - - /* Set DTR, Set RTS */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - irda_task_next_state(task, IRDA_TASK_WAIT2); - - /* Wait at least 10 ms */ - ret = msecs_to_jiffies(10); - break; - - case IRDA_TASK_WAIT2: - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - break; - - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - ret = -1; - break; - } - return ret; -} - -/* - * Function ma600_reset (driver) - * - * This function resets the ma600 dongle. Warning, this function - * must be called with a process context!! - * - * Algorithm: - * 0. DTR=0, RTS=1 and wait 10 ms - * 1. DTR=1, RTS=1 and wait 10 ms - * 2. 9600 bps now - */ -int ma600_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - ASSERT(task != NULL, return -1;); - - if (self->reset_task && self->reset_task != task) { - IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__); - return msecs_to_jiffies(10); - } else - self->reset_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - /* Clear DTR and Set RTS */ - self->set_dtr_rts(self->dev, FALSE, TRUE); - irda_task_next_state(task, IRDA_TASK_WAIT1); - ret = msecs_to_jiffies(10); /* Sleep 10 ms */ - break; - case IRDA_TASK_WAIT1: - /* Set DTR and RTS */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - irda_task_next_state(task, IRDA_TASK_WAIT2); - ret = msecs_to_jiffies(10); /* Sleep 10 ms */ - break; - case IRDA_TASK_WAIT2: - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - } - return ret; -} - -MODULE_AUTHOR("Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95"); -MODULE_DESCRIPTION("MA600 dongle driver version 0.1"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-11"); /* IRDA_MA600_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize MA600 module - * - */ -module_init(ma600_init); - -/* - * Function cleanup_module (void) - * - * Cleanup MA600 module - * - */ -module_exit(ma600_cleanup); - diff --git a/drivers/net/irda/mcp2120-sir.c b/drivers/net/irda/mcp2120-sir.c index 67bd016e4df..5e2f4859cee 100644 --- a/drivers/net/irda/mcp2120-sir.c +++ b/drivers/net/irda/mcp2120-sir.c @@ -63,7 +63,7 @@ static int mcp2120_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* seems no explicit power-on required here and reset switching it on anyway */ @@ -76,7 +76,7 @@ static int mcp2120_open(struct sir_dev *dev) static int mcp2120_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ /* reset and inhibit mcp2120 */ @@ -102,7 +102,7 @@ static int mcp2120_change_speed(struct sir_dev *dev, unsigned speed) u8 control[2]; static int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); switch (state) { case SIRDEV_STATE_DONGLE_SPEED: @@ -155,7 +155,7 @@ static int mcp2120_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s(), undefine state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s(), undefine state %d\n", __func__, state); ret = -EINVAL; break; } @@ -187,7 +187,7 @@ static int mcp2120_reset(struct sir_dev *dev) unsigned delay = 0; int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); switch (state) { case SIRDEV_STATE_DONGLE_RESET: @@ -213,7 +213,7 @@ static int mcp2120_reset(struct sir_dev *dev) break; default: - IRDA_ERROR("%s(), undefined state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s(), undefined state %d\n", __func__, state); ret = -EINVAL; break; } diff --git a/drivers/net/irda/mcp2120.c b/drivers/net/irda/mcp2120.c deleted file mode 100644 index 5e6199eeef4..00000000000 --- a/drivers/net/irda/mcp2120.c +++ /dev/null @@ -1,240 +0,0 @@ -/********************************************************************* - * - * - * Filename: mcp2120.c - * Version: 1.0 - * Description: Implementation for the MCP2120 (Microchip) - * Status: Experimental. - * Author: Felix Tang (tangf@eyetap.org) - * Created at: Sun Mar 31 19:32:12 EST 2002 - * Based on code by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 2002 Felix Tang, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -static int mcp2120_reset(struct irda_task *task); -static void mcp2120_open(dongle_t *self, struct qos_info *qos); -static void mcp2120_close(dongle_t *self); -static int mcp2120_change_speed(struct irda_task *task); - -#define MCP2120_9600 0x87 -#define MCP2120_19200 0x8B -#define MCP2120_38400 0x85 -#define MCP2120_57600 0x83 -#define MCP2120_115200 0x81 - -#define MCP2120_COMMIT 0x11 - -static struct dongle_reg dongle = { - .type = IRDA_MCP2120_DONGLE, - .open = mcp2120_open, - .close = mcp2120_close, - .reset = mcp2120_reset, - .change_speed = mcp2120_change_speed, - .owner = THIS_MODULE, -}; - -static int __init mcp2120_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit mcp2120_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void mcp2120_open(dongle_t *self, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits = 0x01; -} - -static void mcp2120_close(dongle_t *self) -{ - /* Power off dongle */ - /* reset and inhibit mcp2120 */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - //self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * Function mcp2120_change_speed (dev, speed) - * - * Set the speed for the MCP2120. - * - */ -static int mcp2120_change_speed(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - __u32 speed = (__u32) task->param; - __u8 control[2]; - int ret = 0; - - self->speed_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - /* Need to reset the dongle and go to 9600 bps before - programming */ - //printk("Dmcp2120_change_speed irda_task_init\n"); - if (irda_task_execute(self, mcp2120_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 IRDA_TASK_CHILD_WAIT: - IRDA_WARNING("%s(), resetting dongle timed out!\n", - __FUNCTION__); - ret = -1; - break; - case IRDA_TASK_CHILD_DONE: - /* Set DTR to enter command mode */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - udelay(500); - - switch (speed) { - case 9600: - default: - control[0] = MCP2120_9600; - //printk("mcp2120 9600\n"); - break; - case 19200: - control[0] = MCP2120_19200; - //printk("mcp2120 19200\n"); - break; - case 34800: - control[0] = MCP2120_38400; - //printk("mcp2120 38400\n"); - break; - case 57600: - control[0] = MCP2120_57600; - //printk("mcp2120 57600\n"); - break; - case 115200: - control[0] = MCP2120_115200; - //printk("mcp2120 115200\n"); - break; - } - control[1] = MCP2120_COMMIT; - - /* Write control bytes */ - self->write(self->dev, control, 2); - - irda_task_next_state(task, IRDA_TASK_WAIT); - ret = msecs_to_jiffies(100); - //printk("mcp2120_change_speed irda_child_done\n"); - break; - case IRDA_TASK_WAIT: - /* Go back to normal mode */ - self->set_dtr_rts(self->dev, FALSE, FALSE); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - //printk("mcp2120_change_speed irda_task_wait\n"); - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - ret = -1; - break; - } - return ret; -} - -/* - * Function mcp2120_reset (driver) - * - * This function resets the mcp2120 dongle. - * - * Info: -set RTS to reset mcp2120 - * -set DTR to set mcp2120 software command mode - * -mcp2120 defaults to 9600 baud after reset - * - * Algorithm: - * 0. Set RTS to reset mcp2120. - * 1. Clear RTS and wait for device reset timer of 30 ms (max). - * - */ - - -static int mcp2120_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - int ret = 0; - - self->reset_task = task; - - switch (task->state) { - case IRDA_TASK_INIT: - //printk("mcp2120_reset irda_task_init\n"); - /* Reset dongle by setting RTS*/ - self->set_dtr_rts(self->dev, TRUE, TRUE); - irda_task_next_state(task, IRDA_TASK_WAIT1); - ret = msecs_to_jiffies(50); - break; - case IRDA_TASK_WAIT1: - //printk("mcp2120_reset irda_task_wait1\n"); - /* clear RTS and wait for at least 30 ms. */ - self->set_dtr_rts(self->dev, FALSE, FALSE); - irda_task_next_state(task, IRDA_TASK_WAIT2); - ret = msecs_to_jiffies(50); - break; - case IRDA_TASK_WAIT2: - //printk("mcp2120_reset irda_task_wait2\n"); - /* Go back to normal mode */ - self->set_dtr_rts(self->dev, FALSE, FALSE); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - break; - } - return ret; -} - -MODULE_AUTHOR("Felix Tang <tangf@eyetap.org>"); -MODULE_DESCRIPTION("Microchip MCP2120"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-9"); /* IRDA_MCP2120_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize MCP2120 module - * - */ -module_init(mcp2120_init); - -/* - * Function cleanup_module (void) - * - * Cleanup MCP2120 module - * - */ -module_exit(mcp2120_cleanup); diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index f0c61f3b2a8..16f8ffb50e0 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -48,10 +48,7 @@ #include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> -#include <linux/module.h> -#include <linux/kref.h> #include <linux/usb.h> #include <linux/device.h> #include <linux/crc32.h> @@ -193,21 +190,21 @@ static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs) goto error; ret = 0; - error: - return ret; +error: + return ret; } /* Setup a communication between mcs7780 and agilent chip. */ static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs) { - IRDA_WARNING("This transceiver type is not supported yet."); + IRDA_WARNING("This transceiver type is not supported yet.\n"); return 1; } /* Setup a communication between mcs7780 and sharp chip. */ static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs) { - IRDA_WARNING("This transceiver type is not supported yet."); + IRDA_WARNING("This transceiver type is not supported yet.\n"); return 1; } @@ -279,7 +276,7 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) break; default: - IRDA_WARNING("Unknown transceiver type: %d", + IRDA_WARNING("Unknown transceiver type: %d\n", mcs->transceiver_type); ret = 1; } @@ -318,7 +315,7 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) return ret; error: - IRDA_ERROR("%s", msg); + IRDA_ERROR("%s\n", msg); return ret; } @@ -353,7 +350,7 @@ static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf) buf[0] = len & 0xff; buf[1] = (len >> 8) & 0xff; /* copy the data into the tx buffer. */ - memcpy(buf+2, skb->data, skb->len); + skb_copy_from_linear_data(skb, buf + 2, skb->len); /* put the fcs in the last four bytes in little endian order. */ buf[len - 4] = fcs & 0xff; buf[len - 3] = (fcs >> 8) & 0xff; @@ -377,7 +374,7 @@ static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf) buf[0] = len & 0xff; buf[1] = (len >> 8) & 0xff; /* copy the data */ - memcpy(buf+2, skb->data, skb->len); + skb_copy_from_linear_data(skb, buf + 2, skb->len); /* put the fcs in last two bytes in little endian order. */ buf[len - 2] = fcs & 0xff; buf[len - 1] = (fcs >> 8) & 0xff; @@ -404,8 +401,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) if(unlikely(new_len <= 0)) { IRDA_ERROR("%s short frame length %d\n", mcs->netdev->name, new_len); - ++mcs->stats.rx_errors; - ++mcs->stats.rx_length_errors; + ++mcs->netdev->stats.rx_errors; + ++mcs->netdev->stats.rx_length_errors; return; } fcs = 0; @@ -414,30 +411,28 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) if(fcs != GOOD_FCS) { IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); - mcs->stats.rx_errors++; - mcs->stats.rx_crc_errors++; + mcs->netdev->stats.rx_errors++; + mcs->netdev->stats.rx_crc_errors++; return; } skb = dev_alloc_skb(new_len + 1); if(unlikely(!skb)) { - ++mcs->stats.rx_dropped; + ++mcs->netdev->stats.rx_dropped; return; } skb_reserve(skb, 1); - memcpy(skb->data, buf, new_len); + skb_copy_to_linear_data(skb, buf, new_len); skb_put(skb, new_len); - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); skb->dev = mcs->netdev; netif_rx(skb); - mcs->stats.rx_packets++; - mcs->stats.rx_bytes += new_len; - - return; + mcs->netdev->stats.rx_packets++; + mcs->netdev->stats.rx_bytes += new_len; } /* Unwrap received packets at FIR speed. A 32 bit crc_ccitt checksum is @@ -459,38 +454,36 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) if(unlikely(new_len <= 0)) { IRDA_ERROR("%s short frame length %d\n", mcs->netdev->name, new_len); - ++mcs->stats.rx_errors; - ++mcs->stats.rx_length_errors; + ++mcs->netdev->stats.rx_errors; + ++mcs->netdev->stats.rx_length_errors; return; } fcs = ~(crc32_le(~0, buf, new_len)); - if(fcs != le32_to_cpu(get_unaligned((u32 *)(buf+new_len)))) { + if(fcs != get_unaligned_le32(buf + new_len)) { IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); - mcs->stats.rx_errors++; - mcs->stats.rx_crc_errors++; + mcs->netdev->stats.rx_errors++; + mcs->netdev->stats.rx_crc_errors++; return; } skb = dev_alloc_skb(new_len + 1); if(unlikely(!skb)) { - ++mcs->stats.rx_dropped; + ++mcs->netdev->stats.rx_dropped; return; } skb_reserve(skb, 1); - memcpy(skb->data, buf, new_len); + skb_copy_to_linear_data(skb, buf, new_len); skb_put(skb, new_len); - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); skb->dev = mcs->netdev; netif_rx(skb); - mcs->stats.rx_packets++; - mcs->stats.rx_bytes += new_len; - - return; + mcs->netdev->stats.rx_packets++; + mcs->netdev->stats.rx_bytes += new_len; } @@ -507,8 +500,11 @@ static inline int mcs_setup_urbs(struct mcs_cb *mcs) return 0; mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mcs->rx_urb) + if (!mcs->rx_urb) { + usb_free_urb(mcs->tx_urb); + mcs->tx_urb = NULL; return 0; + } return 1; } @@ -586,15 +582,15 @@ static int mcs_speed_change(struct mcs_cb *mcs) mcs_get_reg(mcs, MCS_RESV_REG, &rval); } while(cnt++ < 100 && (rval & MCS_IRINTX)); - if(cnt >= 100) { - IRDA_ERROR("unable to change speed"); + if (cnt > 100) { + IRDA_ERROR("unable to change speed\n"); ret = -EIO; goto error; } mcs_get_reg(mcs, MCS_MODE_REG, &rval); - /* MINRXPW values recomended by MosChip */ + /* MINRXPW values recommended by MosChip */ if (mcs->new_speed <= 115200) { rval &= ~MCS_FIR; @@ -638,7 +634,7 @@ static int mcs_speed_change(struct mcs_cb *mcs) default: ret = 1; - IRDA_WARNING("Unknown transceiver type: %d", + IRDA_WARNING("Unknown transceiver type: %d\n", mcs->transceiver_type); } if (unlikely(ret)) @@ -649,9 +645,9 @@ static int mcs_speed_change(struct mcs_cb *mcs) ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); mcs->speed = mcs->new_speed; - error: - mcs->new_speed = 0; - return ret; +error: + mcs->new_speed = 0; + return ret; } /* Ioctl calls not supported at this time. Can be an area of future work. */ @@ -678,6 +674,8 @@ static int mcs_net_close(struct net_device *netdev) /* Stop transmit processing */ netif_stop_queue(netdev); + kfree_skb(mcs->rx_buff.skb); + /* kill and free the receive and transmit URBs */ usb_kill_urb(mcs->rx_urb); usb_free_urb(mcs->rx_urb); @@ -733,34 +731,29 @@ static int mcs_net_open(struct net_device *netdev) sprintf(hwname, "usb#%d", mcs->usbdev->devnum); mcs->irlap = irlap_open(netdev, &mcs->qos, hwname); if (!mcs->irlap) { - IRDA_ERROR("mcs7780: irlap_open failed"); + IRDA_ERROR("mcs7780: irlap_open failed\n"); goto error2; } if (!mcs_setup_urbs(mcs)) - goto error3; + goto error3; ret = mcs_receive_start(mcs); if (ret) - goto error3; + goto error4; netif_start_queue(netdev); return 0; - error3: - irlap_close(mcs->irlap); - error2: - kfree_skb(mcs->rx_buff.skb); - error1: - return ret; -} - - -/* Get device stats for /proc/net/dev and ifconfig */ -static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev) -{ - struct mcs_cb *mcs = netdev_priv(netdev); - return &mcs->stats; +error4: + usb_free_urb(mcs->rx_urb); + usb_free_urb(mcs->tx_urb); +error3: + irlap_close(mcs->irlap); +error2: + kfree_skb(mcs->rx_buff.skb); +error1: + return ret; } /* Receive callback function. */ @@ -785,14 +778,14 @@ static void mcs_receive_irq(struct urb *urb) */ /* SIR speed */ if(mcs->speed < 576000) { - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, 0xc0); for (i = 0; i < urb->actual_length; i++) - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, bytes[i]); - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, 0xc1); } /* MIR speed */ @@ -805,14 +798,13 @@ static void mcs_receive_irq(struct urb *urb) mcs_unwrap_fir(mcs, urb->transfer_buffer, urb->actual_length); } - mcs->netdev->last_rx = jiffies; do_gettimeofday(&mcs->rx_time); } ret = usb_submit_urb(urb, GFP_ATOMIC); } -/* Transmit callback funtion. */ +/* Transmit callback function. */ static void mcs_send_irq(struct urb *urb) { struct mcs_cb *mcs = urb->context; @@ -824,18 +816,15 @@ static void mcs_send_irq(struct urb *urb) netif_wake_queue(ndev); } -/* Transmit callback funtion. */ -static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev) +/* Transmit callback function. */ +static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb, + struct net_device *ndev) { unsigned long flags; struct mcs_cb *mcs; int wraplen; int ret = 0; - - if (skb == NULL || ndev == NULL) - return -EINVAL; - netif_stop_queue(ndev); mcs = netdev_priv(ndev); @@ -862,25 +851,32 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev) mcs->out_buf, wraplen, mcs_send_irq, mcs); if ((ret = usb_submit_urb(mcs->tx_urb, GFP_ATOMIC))) { - IRDA_ERROR("failed tx_urb: %d", ret); + IRDA_ERROR("failed tx_urb: %d\n", ret); switch (ret) { case -ENODEV: case -EPIPE: break; default: - mcs->stats.tx_errors++; + mcs->netdev->stats.tx_errors++; netif_start_queue(ndev); } } else { - mcs->stats.tx_packets++; - mcs->stats.tx_bytes += skb->len; + mcs->netdev->stats.tx_packets++; + mcs->netdev->stats.tx_bytes += skb->len; } dev_kfree_skb(skb); spin_unlock_irqrestore(&mcs->lock, flags); - return ret; + return NETDEV_TX_OK; } +static const struct net_device_ops mcs_netdev_ops = { + .ndo_open = mcs_net_open, + .ndo_stop = mcs_net_close, + .ndo_start_xmit = mcs_hard_xmit, + .ndo_do_ioctl = mcs_net_ioctl, +}; + /* * This function is called by the USB subsystem for each new device in the * system. Need to verify the device and if it is, then start handling it. @@ -897,15 +893,13 @@ static int mcs_probe(struct usb_interface *intf, if (!ndev) goto error1; - IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.", udev->devnum); + IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.\n", udev->devnum); - /* what is it realy for? */ - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &intf->dev); ret = usb_reset_configuration(udev); if (ret != 0) { - IRDA_ERROR("mcs7780: usb reset configuration failed"); + IRDA_ERROR("mcs7780: usb reset configuration failed\n"); goto error2; } @@ -929,15 +923,12 @@ static int mcs_probe(struct usb_interface *intf, /* Speed change work initialisation*/ INIT_WORK(&mcs->work, mcs_speed_work); - /* Override the network functions we need to use */ - ndev->hard_start_xmit = mcs_hard_xmit; - ndev->open = mcs_net_open; - ndev->stop = mcs_net_close; - ndev->get_stats = mcs_net_get_stats; - ndev->do_ioctl = mcs_net_ioctl; + ndev->netdev_ops = &mcs_netdev_ops; - if (!intf->cur_altsetting) + if (!intf->cur_altsetting) { + ret = -ENOMEM; goto error2; + } ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint, intf->cur_altsetting->desc.bNumEndpoints); @@ -950,7 +941,7 @@ static int mcs_probe(struct usb_interface *intf, if (ret != 0) goto error2; - IRDA_DEBUG(1, "IrDA: Registered MosChip MCS7780 device as %s", + IRDA_DEBUG(1, "IrDA: Registered MosChip MCS7780 device as %s\n", ndev->name); mcs->transceiver_type = transceiver_type; @@ -960,11 +951,11 @@ static int mcs_probe(struct usb_interface *intf, usb_set_intfdata(intf, mcs); return 0; - error2: - free_netdev(ndev); +error2: + free_netdev(ndev); - error1: - return ret; +error1: + return ret; } /* The current device is removed, the USB layer tells us to shut down. */ @@ -975,34 +966,13 @@ static void mcs_disconnect(struct usb_interface *intf) if (!mcs) return; - flush_scheduled_work(); + cancel_work_sync(&mcs->work); unregister_netdev(mcs->netdev); free_netdev(mcs->netdev); usb_set_intfdata(intf, NULL); - IRDA_DEBUG(0, "MCS7780 now disconnected."); -} - -/* Module insertion */ -static int __init mcs_init(void) -{ - int result; - - /* register this driver with the USB subsystem */ - result = usb_register(&mcs_driver); - if (result) - IRDA_ERROR("usb_register failed. Error number %d", result); - - return result; -} -module_init(mcs_init); - -/* Module removal */ -static void __exit mcs_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&mcs_driver); + IRDA_DEBUG(0, "MCS7780 now disconnected.\n"); } -module_exit(mcs_exit); +module_usb_driver(mcs_driver); diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h index b18148cee63..b10689b2887 100644 --- a/drivers/net/irda/mcs7780.h +++ b/drivers/net/irda/mcs7780.h @@ -104,7 +104,6 @@ struct mcs_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ struct qos_info qos; unsigned int speed; /* Current speed */ unsigned int new_speed; /* new speed */ @@ -154,11 +153,11 @@ static int mcs_speed_change(struct mcs_cb *mcs); static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd); static int mcs_net_close(struct net_device *netdev); static int mcs_net_open(struct net_device *netdev); -static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev); static void mcs_receive_irq(struct urb *urb); static void mcs_send_irq(struct urb *urb); -static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev); +static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb, + struct net_device *netdev); static int mcs_probe(struct usb_interface *intf, const struct usb_device_id *id); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 29b5ccd29d0..66bc03bdb13 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -20,7 +20,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -43,6 +43,7 @@ ********************************************************************/ #include <linux/module.h> +#include <linux/gfp.h> #include <linux/kernel.h> #include <linux/types.h> @@ -50,8 +51,8 @@ #include <linux/netdevice.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/rtnetlink.h> #include <linux/dma-mapping.h> #include <linux/pnp.h> @@ -100,7 +101,9 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); +#ifdef CONFIG_PNP static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); +#endif /* These are the known NSC chips */ static nsc_chip_t chips[] = { @@ -149,16 +152,19 @@ static char *dongle_types[] = { static chipio_t pnp_info; static const struct pnp_device_id nsc_ircc_pnp_table[] = { { .id = "NSC6001", .driver_data = 0 }, - { .id = "IBM0071", .driver_data = 0 }, + { .id = "HWPC224", .driver_data = 0 }, + { .id = "IBM0071", .driver_data = NSC_FORCE_DONGLE_TYPE9 }, { } }; MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); static struct pnp_driver nsc_ircc_pnp_driver = { +#ifdef CONFIG_PNP .name = "nsc-ircc", .id_table = nsc_ircc_pnp_table, .probe = nsc_ircc_pnp_probe, +#endif }; /* Some prototypes */ @@ -168,8 +174,10 @@ static int nsc_ircc_setup(chipio_t *info); static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self); static int nsc_ircc_dma_receive(struct nsc_ircc_cb *self); static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase); -static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev); -static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t nsc_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev); +static netdev_tx_t nsc_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev); static int nsc_ircc_pio_write(int iobase, __u8 *buf, int len, int fifo_size); static void nsc_ircc_dma_xmit(struct nsc_ircc_cb *self, int iobase); static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 baud); @@ -180,7 +188,6 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id); static int nsc_ircc_net_open(struct net_device *dev); static int nsc_ircc_net_close(struct net_device *dev); static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); /* Globals */ static int pnp_registered; @@ -218,7 +225,7 @@ static int __init nsc_ircc_init(void) /* Probe for all the NSC chipsets we know about */ for (chip = chips; chip->name ; chip++) { - IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __func__, chip->name); /* Try all config registers for this chip */ @@ -230,7 +237,7 @@ static int __init nsc_ircc_init(void) /* Read index register */ reg = inb(cfg_base); if (reg == 0xff) { - IRDA_DEBUG(2, "%s() no chip at 0x%03x\n", __FUNCTION__, cfg_base); + IRDA_DEBUG(2, "%s() no chip at 0x%03x\n", __func__, cfg_base); continue; } @@ -239,7 +246,7 @@ static int __init nsc_ircc_init(void) id = inb(cfg_base+1); if ((id & chip->cid_mask) == chip->cid_value) { IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n", - __FUNCTION__, chip->name, id & ~chip->cid_mask); + __func__, chip->name, id & ~chip->cid_mask); /* * If we found a correct PnP setting, @@ -290,7 +297,7 @@ static int __init nsc_ircc_init(void) } i++; } else { - IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id); + IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __func__, id); } } } @@ -327,6 +334,20 @@ static void __exit nsc_ircc_cleanup(void) pnp_registered = 0; } +static const struct net_device_ops nsc_ircc_sir_ops = { + .ndo_open = nsc_ircc_net_open, + .ndo_stop = nsc_ircc_net_close, + .ndo_start_xmit = nsc_ircc_hard_xmit_sir, + .ndo_do_ioctl = nsc_ircc_net_ioctl, +}; + +static const struct net_device_ops nsc_ircc_fir_ops = { + .ndo_open = nsc_ircc_net_open, + .ndo_stop = nsc_ircc_net_close, + .ndo_start_xmit = nsc_ircc_hard_xmit_fir, + .ndo_do_ioctl = nsc_ircc_net_ioctl, +}; + /* * Function nsc_ircc_open (iobase, irq) * @@ -340,7 +361,7 @@ static int __init nsc_ircc_open(chipio_t *info) void *ret; int err, chip_index; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) { @@ -349,7 +370,7 @@ static int __init nsc_ircc_open(chipio_t *info) } if (chip_index == ARRAY_SIZE(dev_self)) { - IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__); + IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __func__); return -ENOMEM; } @@ -364,11 +385,11 @@ static int __init nsc_ircc_open(chipio_t *info) dev = alloc_irdadev(sizeof(struct nsc_ircc_cb)); if (dev == NULL) { IRDA_ERROR("%s(), can't allocate memory for " - "control block!\n", __FUNCTION__); + "control block!\n", __func__); return -ENOMEM; } - self = dev->priv; + self = netdev_priv(dev); self->netdev = dev; spin_lock_init(&self->lock); @@ -388,7 +409,7 @@ static int __init nsc_ircc_open(chipio_t *info) ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name); if (!ret) { IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", - __FUNCTION__, self->io.fir_base); + __func__, self->io.fir_base); err = -ENODEV; goto out1; } @@ -409,23 +430,21 @@ static int __init nsc_ircc_open(chipio_t *info) /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; @@ -437,16 +456,11 @@ static int __init nsc_ircc_open(chipio_t *info) self->tx_fifo.tail = self->tx_buff.head; /* Override the network functions we need to use */ - SET_MODULE_OWNER(dev); - dev->hard_start_xmit = nsc_ircc_hard_xmit_sir; - dev->open = nsc_ircc_net_open; - dev->stop = nsc_ircc_net_close; - dev->do_ioctl = nsc_ircc_net_ioctl; - dev->get_stats = nsc_ircc_net_get_stats; + dev->netdev_ops = &nsc_ircc_sir_ops; err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__); + IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); goto out4; } IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); @@ -502,7 +516,7 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self) { int iobase; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + IRDA_DEBUG(4, "%s()\n", __func__); IRDA_ASSERT(self != NULL, return -1;); @@ -515,7 +529,7 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self) /* Release the PORT that this driver is using */ IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", - __FUNCTION__, self->io.fir_base); + __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) @@ -553,7 +567,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 0x2e8: outb(0x15, cfg_base+1); break; case 0x3f8: outb(0x16, cfg_base+1); break; case 0x2f8: outb(0x17, cfg_base+1); break; - default: IRDA_ERROR("%s(), invalid base_address", __FUNCTION__); + default: IRDA_ERROR("%s(), invalid base_address", __func__); } /* Control Signal Routing Register (CSRT) */ @@ -565,7 +579,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 9: temp = 0x05; break; case 11: temp = 0x06; break; case 15: temp = 0x07; break; - default: IRDA_ERROR("%s(), invalid irq", __FUNCTION__); + default: IRDA_ERROR("%s(), invalid irq", __func__); } outb(CFG_108_CSRT, cfg_base); @@ -573,7 +587,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 0: outb(0x08+temp, cfg_base+1); break; case 1: outb(0x10+temp, cfg_base+1); break; case 3: outb(0x18+temp, cfg_base+1); break; - default: IRDA_ERROR("%s(), invalid dma", __FUNCTION__); + default: IRDA_ERROR("%s(), invalid dma", __func__); } outb(CFG_108_MCTL, cfg_base); /* Mode Control Register (MCTL) */ @@ -612,7 +626,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info) break; } info->sir_base = info->fir_base; - IRDA_DEBUG(2, "%s(), probing fir_base=0x%03x\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(), probing fir_base=0x%03x\n", __func__, info->fir_base); /* Read control signals routing register (CSRT) */ @@ -645,7 +659,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info) info->irq = 15; break; } - IRDA_DEBUG(2, "%s(), probing irq=%d\n", __FUNCTION__, info->irq); + IRDA_DEBUG(2, "%s(), probing irq=%d\n", __func__, info->irq); /* Currently we only read Rx DMA but it will also be used for Tx */ switch ((reg >> 3) & 0x03) { @@ -662,7 +676,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info) info->dma = 3; break; } - IRDA_DEBUG(2, "%s(), probing dma=%d\n", __FUNCTION__, info->dma); + IRDA_DEBUG(2, "%s(), probing dma=%d\n", __func__, info->dma); /* Read mode control register (MCTL) */ outb(CFG_108_MCTL, cfg_base); @@ -701,7 +715,7 @@ static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info) int reg, com = 0; int pnp; - /* Read funtion enable register (FER) */ + /* Read function enable register (FER) */ outb(CFG_338_FER, cfg_base); reg = inb(cfg_base+1); @@ -819,7 +833,7 @@ static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info) /* User is sure about his config... accept it. */ IRDA_DEBUG(2, "%s(): nsc_ircc_init_39x (user settings): " "io=0x%04x, irq=%d, dma=%d\n", - __FUNCTION__, info->fir_base, info->irq, info->dma); + __func__, info->fir_base, info->irq, info->dma); /* Access bank for SP2 */ outb(CFG_39X_LDN, cfg_base); @@ -860,7 +874,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) int enabled, susp; IRDA_DEBUG(2, "%s(), nsc_ircc_probe_39x, base=%d\n", - __FUNCTION__, cfg_base); + __func__, cfg_base); /* This function should be executed with irq off to avoid * another driver messing with the Super I/O bank - Jean II */ @@ -894,7 +908,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) outb(CFG_39X_SPC, cfg_base); susp = 1 - ((inb(cfg_base+1) & 0x02) >> 1); - IRDA_DEBUG(2, "%s(): io=0x%02x%02x, irq=%d (type %d), rxdma=%d, txdma=%d, enabled=%d (suspended=%d)\n", __FUNCTION__, reg1,reg2,irq,irqt,dma1,dma2,enabled,susp); + IRDA_DEBUG(2, "%s(): io=0x%02x%02x, irq=%d (type %d), rxdma=%d, txdma=%d, enabled=%d (suspended=%d)\n", __func__, reg1,reg2,irq,irqt,dma1,dma2,enabled,susp); /* Configure SP2 */ @@ -917,6 +931,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) return 0; } +#ifdef CONFIG_PNP /* PNP probing */ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) { @@ -925,7 +940,10 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i pnp_info.dma = -1; pnp_succeeded = 1; - /* There don't seem to be any way to get the cfg_base. + if (id->driver_data & NSC_FORCE_DONGLE_TYPE9) + dongle_id = 0x9; + + /* There doesn't seem to be any way of getting the cfg_base. * On my box, cfg_base is in the PnP descriptor of the * motherboard. Oh well... Jean II */ @@ -942,7 +960,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i pnp_info.dma = pnp_dma(dev, 0); IRDA_DEBUG(0, "%s() : From PnP, found firbase 0x%03X ; irq %d ; dma %d.\n", - __FUNCTION__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma); + __func__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma); if((pnp_info.fir_base == 0) || (pnp_info.irq == -1) || (pnp_info.dma == -1)) { @@ -953,6 +971,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i return 0; } +#endif /* * Function nsc_ircc_setup (info) @@ -970,7 +989,7 @@ static int nsc_ircc_setup(chipio_t *info) version = inb(iobase+MID); IRDA_DEBUG(2, "%s() Driver %s Found chip version %02x\n", - __FUNCTION__, driver_name, version); + __func__, driver_name, version); /* Should be 0x2? */ if (0x20 != (version & 0xf0)) { @@ -1016,7 +1035,7 @@ static int nsc_ircc_setup(chipio_t *info) /* * Function nsc_ircc_read_dongle_id (void) * - * Try to read dongle indentification. This procedure needs to be executed + * Try to read dongle identification. This procedure needs to be executed * once after power-on/reset. It also needs to be used whenever you suspect * that the user may have plugged/unplugged the IrDA Dongle. */ @@ -1074,30 +1093,30 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id) case 0x00: /* same as */ case 0x01: /* Differential serial interface */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ break; case 0x05: /* Reserved, but this is what the Thinkpad reports */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ IRDA_DEBUG(0, "%s(), %s is not for IrDA mode\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ IRDA_DEBUG(0, "%s(), %s\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ outb(0x28, iobase+7); /* Set irsl[0-2] as output */ @@ -1105,7 +1124,7 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id) case 0x0A: /* same as */ case 0x0B: /* Reserved */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x0C: /* same as */ case 0x0D: /* HP HSDL-1100/HSDL-2100 */ @@ -1120,14 +1139,14 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id) break; case 0x0F: /* No dongle connected */ IRDA_DEBUG(0, "%s(), %s\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); switch_bank(iobase, BANK0); outb(0x62, iobase+MCR); break; default: IRDA_DEBUG(0, "%s(), invalid dongle_id %#x", - __FUNCTION__, dongle_id); + __func__, dongle_id); } /* IRCFG1: IRSL1 and 2 are set to IrDA mode */ @@ -1159,30 +1178,30 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id) case 0x00: /* same as */ case 0x01: /* Differential serial interface */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ break; case 0x05: /* Reserved */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ IRDA_DEBUG(0, "%s(), %s is not for IrDA mode\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ IRDA_DEBUG(0, "%s(), %s\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); outb(0x00, iobase+4); if (speed > 115200) outb(0x01, iobase+4); @@ -1201,7 +1220,7 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id) case 0x0A: /* same as */ case 0x0B: /* Reserved */ IRDA_DEBUG(0, "%s(), %s not defined by irda yet\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); break; case 0x0C: /* same as */ case 0x0D: /* HP HSDL-1100/HSDL-2100 */ @@ -1210,13 +1229,13 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id) break; case 0x0F: /* No dongle connected */ IRDA_DEBUG(0, "%s(), %s is not for IrDA mode\n", - __FUNCTION__, dongle_types[dongle_id]); + __func__, dongle_types[dongle_id]); switch_bank(iobase, BANK0); outb(0x62, iobase+MCR); break; default: - IRDA_DEBUG(0, "%s(), invalid data_rate\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), invalid data_rate\n", __func__); } /* Restore bank register */ outb(bank, iobase+BSR); @@ -1237,7 +1256,7 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) __u8 bank; __u8 ier; /* Interrupt enable register */ - IRDA_DEBUG(2, "%s(), speed=%d\n", __FUNCTION__, speed); + IRDA_DEBUG(2, "%s(), speed=%d\n", __func__, speed); IRDA_ASSERT(self != NULL, return 0;); @@ -1270,20 +1289,20 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) outb(inb(iobase+4) | 0x04, iobase+4); mcr = MCR_MIR; - IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __func__); break; case 1152000: mcr = MCR_MIR; - IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __func__); break; case 4000000: mcr = MCR_FIR; - IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __func__); break; default: mcr = MCR_FIR; IRDA_DEBUG(0, "%s(), unknown baud rate of %d\n", - __FUNCTION__, speed); + __func__, speed); break; } @@ -1313,12 +1332,12 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) switch_bank(iobase, BANK0); if (speed > 115200) { /* Install FIR xmit handler */ - dev->hard_start_xmit = nsc_ircc_hard_xmit_fir; + dev->netdev_ops = &nsc_ircc_fir_ops; ier = IER_SFIF_IE; nsc_ircc_dma_receive(self); } else { /* Install SIR xmit handler */ - dev->hard_start_xmit = nsc_ircc_hard_xmit_sir; + dev->netdev_ops = &nsc_ircc_sir_ops; ier = IER_RXHDL_IE; } /* Set our current interrupt mask */ @@ -1328,7 +1347,7 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) outb(bank, iobase+BSR); /* Make sure interrupt handlers keep the proper interrupt mask */ - return(ier); + return ier; } /* @@ -1337,7 +1356,8 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) * Transmit the frame! * */ -static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t nsc_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev) { struct nsc_ircc_cb *self; unsigned long flags; @@ -1345,9 +1365,9 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) __s32 speed; __u8 bank; - self = (struct nsc_ircc_cb *) dev->priv; + self = netdev_priv(dev); - IRDA_ASSERT(self != NULL, return 0;); + IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;); iobase = self->io.fir_base; @@ -1379,7 +1399,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -1392,7 +1412,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Add interrupt on tx low level (will fire immediately) */ switch_bank(iobase, BANK0); @@ -1406,10 +1426,11 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } -static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t nsc_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev) { struct nsc_ircc_cb *self; unsigned long flags; @@ -1418,7 +1439,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) __u8 bank; int mtt, diff; - self = (struct nsc_ircc_cb *) dev->priv; + self = netdev_priv(dev); iobase = self->io.fir_base; netif_stop_queue(dev); @@ -1449,7 +1470,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else { /* Change speed after current frame */ self->new_speed = speed; @@ -1464,11 +1485,10 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; - memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, - skb->len); - + skb_copy_from_linear_data(skb, self->tx_fifo.queue[self->tx_fifo.free].start, + skb->len); self->tx_fifo.len++; self->tx_fifo.free++; @@ -1537,7 +1557,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } /* @@ -1589,7 +1609,7 @@ static int nsc_ircc_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 bank; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + IRDA_DEBUG(4, "%s()\n", __func__); /* Save current bank */ bank = inb(iobase+BSR); @@ -1597,7 +1617,7 @@ static int nsc_ircc_pio_write(int iobase, __u8 *buf, int len, int fifo_size) switch_bank(iobase, BANK0); if (!(inb_p(iobase+LSR) & LSR_TXEMP)) { IRDA_DEBUG(4, "%s(), warning, FIFO not empty yet!\n", - __FUNCTION__); + __func__); /* FIFO may still be filled to the Tx interrupt threshold */ fifo_size -= 17; @@ -1610,7 +1630,7 @@ static int nsc_ircc_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } IRDA_DEBUG(4, "%s(), fifo_size %d ; %d sent of %d\n", - __FUNCTION__, fifo_size, actual, len); + __func__, fifo_size, actual, len); /* Restore bank */ outb(bank, iobase+BSR); @@ -1631,7 +1651,7 @@ static int nsc_ircc_dma_xmit_complete(struct nsc_ircc_cb *self) __u8 bank; int ret = TRUE; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); iobase = self->io.fir_base; @@ -1642,15 +1662,15 @@ static int nsc_ircc_dma_xmit_complete(struct nsc_ircc_cb *self) switch_bank(iobase, BANK0); outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); - /* Check for underrrun! */ + /* Check for underrun! */ if (inb(iobase+ASCR) & ASCR_TXUR) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Clear bit, by writing 1 into it */ outb(ASCR_TXUR, iobase+ASCR); } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; } /* Finished with this frame, so prepare for next */ @@ -1762,7 +1782,7 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) len = inb(iobase+RFLFL) | ((inb(iobase+RFLFH) & 0x1f) << 8); if (st_fifo->tail >= MAX_RX_WINDOW) { - IRDA_DEBUG(0, "%s(), window is full!\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), window is full!\n", __func__); continue; } @@ -1785,28 +1805,28 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) if (status & FRM_ST_ERR_MSK) { if (status & FRM_ST_LOST_FR) { /* Add number of lost frames to stats */ - self->stats.rx_errors += len; + self->netdev->stats.rx_errors += len; } else { /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & FRM_ST_MAX_LEN) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (status & FRM_ST_PHY_ERR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (status & FRM_ST_BAD_CRC) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FRM_ST_OVR1) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; if (status & FRM_ST_OVR2) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; } else { /* * First we must make sure that the frame we @@ -1854,8 +1874,8 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) if (skb == NULL) { IRDA_WARNING("%s(), memory squeeze, " "dropping frame.\n", - __FUNCTION__); - self->stats.rx_dropped++; + __func__); + self->netdev->stats.rx_dropped++; /* Restore bank register */ outb(bank, iobase+BSR); @@ -1869,22 +1889,25 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) /* Copy frame without CRC */ if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, self->rx_buff.data, len-2); + skb_copy_to_linear_data(skb, + self->rx_buff.data, + len - 2); } else { skb_put(skb, len-4); - memcpy(skb->data, self->rx_buff.data, len-4); + skb_copy_to_linear_data(skb, + self->rx_buff.data, + len - 4); } /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); - self->netdev->last_rx = jiffies; } } /* Restore bank register */ @@ -1909,8 +1932,8 @@ static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self) /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RXD); - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, - byte); + async_unwrap_char(self->netdev, &self->netdev->stats, + &self->rx_buff, byte); } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */ } @@ -1941,7 +1964,7 @@ static void nsc_ircc_sir_interrupt(struct nsc_ircc_cb *self, int eir) self->ier = IER_TXLDL_IE; else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; netif_wake_queue(self->netdev); self->ier = IER_TXEMP_IE; } @@ -1956,7 +1979,7 @@ static void nsc_ircc_sir_interrupt(struct nsc_ircc_cb *self, int eir) * Need to be after self->io.direction to avoid race with * nsc_ircc_hard_xmit_sir() - Jean II */ if (self->new_speed) { - IRDA_DEBUG(2, "%s(), Changing speed!\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), Changing speed!\n", __func__); self->ier = nsc_ircc_change_speed(self, self->new_speed); self->new_speed = 0; @@ -2042,7 +2065,7 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase, } else IRDA_WARNING("%s(), potential " "Tx queue lockup !\n", - __FUNCTION__); + __func__); } } else { /* Not finished yet, so interrupt on DMA again */ @@ -2073,7 +2096,7 @@ static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id) __u8 bsr, eir; int iobase; - self = dev->priv; + self = netdev_priv(dev); spin_lock(&self->lock); @@ -2151,10 +2174,10 @@ static int nsc_ircc_net_open(struct net_device *dev) char hwname[32]; __u8 bank; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + IRDA_DEBUG(4, "%s()\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct nsc_ircc_cb *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); @@ -2213,11 +2236,11 @@ static int nsc_ircc_net_close(struct net_device *dev) int iobase; __u8 bank; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + IRDA_DEBUG(4, "%s()\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct nsc_ircc_cb *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); /* Stop device */ @@ -2263,11 +2286,11 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ @@ -2296,13 +2319,6 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } -static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev) -{ - struct nsc_ircc_cb *self = (struct nsc_ircc_cb *) dev->priv; - - return &self->stats; -} - static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state) { struct nsc_ircc_cb *self = platform_get_drvdata(dev); diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h index dacf671abcd..32fa58211fa 100644 --- a/drivers/net/irda/nsc-ircc.h +++ b/drivers/net/irda/nsc-ircc.h @@ -19,7 +19,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -35,6 +35,9 @@ #include <linux/types.h> #include <asm/io.h> +/* Features for chips (set in driver_data) */ +#define NSC_FORCE_DONGLE_TYPE9 0x00000001 + /* DMA modes needed */ #define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ #define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ @@ -132,7 +135,7 @@ #define LSR_TXRDY 0x20 /* Transmitter ready */ #define LSR_TXEMP 0x40 /* Transmitter empty */ -#define ASCR 0x07 /* Auxillary Status and Control Register */ +#define ASCR 0x07 /* Auxiliary Status and Control Register */ #define ASCR_RXF_TOUT 0x01 /* Rx FIFO timeout */ #define ASCR_FEND_INF 0x02 /* Frame end bytes in rx FIFO */ #define ASCR_S_EOT 0x04 /* Set end of transmission */ @@ -231,13 +234,13 @@ struct st_fifo { struct frame_cb { void *start; /* Start of frame in DMA mem */ - int len; /* Lenght of frame in DMA mem */ + int len; /* Length of frame in DMA mem */ }; struct tx_fifo { struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ int ptr; /* Currently being sent */ - int len; /* Lenght of queue */ + int len; /* Length of queue */ int free; /* Next free slot */ void *tail; /* Next free start in DMA mem */ }; @@ -248,7 +251,6 @@ struct nsc_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ diff --git a/drivers/net/irda/old_belkin-sir.c b/drivers/net/irda/old_belkin-sir.c index 8c22c7374a2..f237136f382 100644 --- a/drivers/net/irda/old_belkin-sir.c +++ b/drivers/net/irda/old_belkin-sir.c @@ -22,9 +22,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ @@ -92,7 +90,7 @@ static int old_belkin_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power on dongle */ sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -110,7 +108,7 @@ static int old_belkin_open(struct sir_dev *dev) static int old_belkin_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -125,7 +123,7 @@ static int old_belkin_close(struct sir_dev *dev) */ static int old_belkin_change_speed(struct sir_dev *dev, unsigned speed) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); dev->speed = 9600; return (speed==dev->speed) ? 0 : -EINVAL; @@ -139,7 +137,7 @@ static int old_belkin_change_speed(struct sir_dev *dev, unsigned speed) */ static int old_belkin_reset(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* This dongles speed "defaults" to 9600 bps ;-) */ dev->speed = 9600; diff --git a/drivers/net/irda/old_belkin.c b/drivers/net/irda/old_belkin.c deleted file mode 100644 index 26f81fd2837..00000000000 --- a/drivers/net/irda/old_belkin.c +++ /dev/null @@ -1,164 +0,0 @@ -/********************************************************************* - * - * Filename: old_belkin.c - * Version: 1.1 - * Description: Driver for the Belkin (old) SmartBeam dongle - * Status: Experimental... - * Author: Jean Tourrilhes <jt@hpl.hp.com> - * Created at: 22/11/99 - * Modified at: Fri Dec 17 09:13:32 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1999 Jean Tourrilhes, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -/* - * Belkin is selling a dongle called the SmartBeam. - * In fact, there is two hardware version of this dongle, of course with - * the same name and looking the exactly same (grrr...). - * I guess that I've got the old one, because inside I don't have - * a jumper for IrDA/ASK... - * - * As far as I can make it from info on their web site, the old dongle - * support only 9600 b/s, which make our life much simpler as far as - * the driver is concerned, but you might not like it very much ;-) - * The new SmartBeam does 115 kb/s, and I've not tested it... - * - * Belkin claim that the correct driver for the old dongle (in Windows) - * is the generic Parallax 9500a driver, but the Linux LiteLink driver - * fails for me (probably because Linux-IrDA doesn't rate fallback), - * so I created this really dumb driver... - * - * In fact, this driver doesn't do much. The only thing it does is to - * prevent Linux-IrDA to use any other speed than 9600 b/s ;-) This - * driver is called "old_belkin" so that when the new SmartBeam is supported - * its driver can be called "belkin" instead of "new_belkin". - * - * Note : this driver was written without any info/help from Belkin, - * so a lot of info here might be totally wrong. Blame me ;-) - */ - -/* Let's guess */ -#define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */ - -static void old_belkin_open(dongle_t *self, struct qos_info *qos); -static void old_belkin_close(dongle_t *self); -static int old_belkin_change_speed(struct irda_task *task); -static int old_belkin_reset(struct irda_task *task); - -/* These are the baudrates supported */ -/* static __u32 baud_rates[] = { 9600 }; */ - -static struct dongle_reg dongle = { - .type = IRDA_OLD_BELKIN_DONGLE, - .open = old_belkin_open, - .close = old_belkin_close, - .reset = old_belkin_reset, - .change_speed = old_belkin_change_speed, - .owner = THIS_MODULE, -}; - -static int __init old_belkin_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit old_belkin_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void old_belkin_open(dongle_t *self, struct qos_info *qos) -{ - /* Not too fast, please... */ - qos->baud_rate.bits &= IR_9600; - /* Needs at least 10 ms (totally wild guess, can do probably better) */ - qos->min_turn_time.bits = 0x01; -} - -static void old_belkin_close(dongle_t *self) -{ - /* Power off dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); -} - -/* - * Function old_belkin_change_speed (task) - * - * With only one speed available, not much to do... - */ -static int old_belkin_change_speed(struct irda_task *task) -{ - irda_task_next_state(task, IRDA_TASK_DONE); - - return 0; -} - -/* - * Function old_belkin_reset (task) - * - * Reset the Old-Belkin type dongle. - * - */ -static int old_belkin_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - - /* Power on dongle */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Sleep a minimum of 15 us */ - udelay(MIN_DELAY); - - /* This dongles speed "defaults" to 9600 bps ;-) */ - self->speed = 9600; - - irda_task_next_state(task, IRDA_TASK_DONE); - - return 0; -} - -MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>"); -MODULE_DESCRIPTION("Belkin (old) SmartBeam dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-7"); /* IRDA_OLD_BELKIN_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize Old-Belkin module - * - */ -module_init(old_belkin_init); - -/* - * Function cleanup_module (void) - * - * Cleanup Old-Belkin module - * - */ -module_exit(old_belkin_cleanup); diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 9137e239fac..3eeaaf80049 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -12,33 +12,67 @@ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor * */ +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> #include <linux/module.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/errno.h> #include <linux/netdevice.h> -#include <linux/slab.h> -#include <linux/rtnetlink.h> -#include <linux/interrupt.h> -#include <linux/dma-mapping.h> +#include <linux/etherdevice.h> #include <linux/platform_device.h> -#include <linux/pm.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/slab.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/wrapper.h> #include <net/irda/irda_device.h> -#include <asm/irq.h> -#include <asm/dma.h> -#include <asm/delay.h> -#include <asm/hardware.h> -#include <asm/arch/irda.h> -#include <asm/arch/pxa-regs.h> - -#ifdef CONFIG_MACH_MAINSTONE -#include <asm/arch/mainstone.h> +#include <mach/dma.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <mach/regs-ost.h> +#include <mach/regs-uart.h> + +#define FICP __REG(0x40800000) /* Start of FICP area */ +#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ +#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ +#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ +#define ICDR __REG(0x4080000c) /* ICP Data Register */ +#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ +#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */ + +#define ICCR0_AME (1 << 7) /* Address match enable */ +#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ +#define ICCR0_RIE (1 << 5) /* Receive FIFO interrupt enable */ +#define ICCR0_RXE (1 << 4) /* Receive enable */ +#define ICCR0_TXE (1 << 3) /* Transmit enable */ +#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ +#define ICCR0_LBM (1 << 1) /* Loopback mode */ +#define ICCR0_ITR (1 << 0) /* IrDA transmission */ + +#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ +#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ +#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ +#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ +#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ +#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ + +#ifdef CONFIG_PXA27x +#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ #endif +#define ICSR0_FRE (1 << 5) /* Framing error */ +#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ +#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ +#define ICSR0_RAB (1 << 2) /* Receiver abort */ +#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */ +#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */ + +#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */ +#define ICSR1_CRE (1 << 5) /* CRC error */ +#define ICSR1_EOF (1 << 4) /* End of frame */ +#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */ +#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */ +#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */ +#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */ #define IrSR_RXPL_NEG_IS_ZERO (1<<4) #define IrSR_RXPL_POS_IS_ZERO 0x0 @@ -78,7 +112,9 @@ struct pxa_irda { int txdma; int rxdma; - struct net_device_stats stats; + int uart_irq; + int icp_irq; + struct irlap_cb *irlap; struct qos_info qos; @@ -87,8 +123,30 @@ struct pxa_irda { struct device *dev; struct pxaficp_platform_data *pdata; + struct clk *fir_clk; + struct clk *sir_clk; + struct clk *cur_clk; }; +static inline void pxa_irda_disable_clk(struct pxa_irda *si) +{ + if (si->cur_clk) + clk_disable_unprepare(si->cur_clk); + si->cur_clk = NULL; +} + +static inline void pxa_irda_enable_firclk(struct pxa_irda *si) +{ + si->cur_clk = si->fir_clk; + clk_prepare_enable(si->fir_clk); +} + +static inline void pxa_irda_enable_sirclk(struct pxa_irda *si) +{ + si->cur_clk = si->sir_clk; + clk_prepare_enable(si->sir_clk); +} + #define IS_FIR(si) ((si)->speed >= 4000000) #define IRDA_FRAME_SIZE_LIMIT 2047 @@ -112,6 +170,22 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si) } /* + * Set the IrDA communications mode. + */ +static void pxa_irda_set_mode(struct pxa_irda *si, int mode) +{ + if (si->pdata->transceiver_mode) + si->pdata->transceiver_mode(si->dev, mode); + else { + if (gpio_is_valid(si->pdata->gpio_pwdown)) + gpio_set_value(si->pdata->gpio_pwdown, + !(mode & IR_OFF) ^ + !si->pdata->gpio_pwdown_inverted); + pxa2xx_transceiver_mode(si->dev, mode); + } +} + +/* * Set the IrDA communications speed. */ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) @@ -134,17 +208,13 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) DCSR(si->rxdma) &= ~DCSR_RUN; /* disable FICP */ ICCR0 = 0; - pxa_set_cken(CKEN13_FICP, 0); + pxa_irda_disable_clk(si); /* set board transceiver to SIR mode */ - si->pdata->transceiver_mode(si->dev, IR_SIRMODE); - - /* configure GPIO46/47 */ - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); + pxa_irda_set_mode(si, IR_SIRMODE); /* enable the STUART clock */ - pxa_set_cken(CKEN5_STUART, 1); + pxa_irda_enable_sirclk(si); } /* disable STUART first */ @@ -169,20 +239,16 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) /* disable STUART */ STIER = 0; STISR = 0; - pxa_set_cken(CKEN5_STUART, 0); + pxa_irda_disable_clk(si); /* disable FICP first */ ICCR0 = 0; /* set board transceiver to FIR mode */ - si->pdata->transceiver_mode(si->dev, IR_FIRMODE); - - /* configure GPIO46/47 */ - pxa_gpio_mode(GPIO46_ICPRXD_MD); - pxa_gpio_mode(GPIO47_ICPTXD_MD); + pxa_irda_set_mode(si, IR_FIRMODE); /* enable the FICP clock */ - pxa_set_cken(CKEN13_FICP, 1); + pxa_irda_enable_firclk(si); si->speed = speed; pxa_irda_fir_dma_rx_start(si); @@ -214,19 +280,19 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) data = STRBR; if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); - si->stats.rx_errors++; + dev->stats.rx_errors++; if (lsr & LSR_FE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (lsr & LSR_OE) - si->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else { - si->stats.rx_bytes++; - async_unwrap_char(dev, &si->stats, &si->rx_buff, data); + dev->stats.rx_bytes++; + async_unwrap_char(dev, &dev->stats, + &si->rx_buff, data); } lsr = STLSR; } - dev->last_rx = jiffies; - si->last_oscr = OSCR; + si->last_oscr = readl_relaxed(OSCR); break; case 0x04: /* Received Data Available */ @@ -234,11 +300,10 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) case 0x0C: /* Character Timeout Indication */ do { - si->stats.rx_bytes++; - async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR); + dev->stats.rx_bytes++; + async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR); } while (STLSR & LSR_DR); - dev->last_rx = jiffies; - si->last_oscr = OSCR; + si->last_oscr = readl_relaxed(OSCR); break; case 0x02: /* Transmit FIFO Data Request */ @@ -248,14 +313,13 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) } if (si->tx_buff.len == 0) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->tx_buff.data - - si->tx_buff.head; + dev->stats.tx_packets++; + dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* We need to ensure that the transmitter has finished. */ while ((STLSR & LSR_TEMT) == 0) cpu_relax(); - si->last_oscr = OSCR; + si->last_oscr = readl_relaxed(OSCR); /* * Ok, we've finished transmitting. Now enable @@ -301,15 +365,15 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data) DCSR(channel) = dcsr & ~DCSR_RUN; if (dcsr & DCSR_ENDINTR) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->dma_tx_buff_len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += si->dma_tx_buff_len; } else { - si->stats.tx_errors++; + dev->stats.tx_errors++; } while (ICSR1 & ICSR1_TBY) cpu_relax(); - si->last_oscr = OSCR; + si->last_oscr = readl_relaxed(OSCR); /* * HACK: It looks like the TBY bit is dropped too soon. @@ -321,15 +385,22 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data) pxa_irda_set_speed(si, si->newspeed); si->newspeed = 0; } else { + int i = 64; + ICCR0 = 0; pxa_irda_fir_dma_rx_start(si); + while ((ICSR1 & ICSR1_RNE) && i--) + (void)ICDR; ICCR0 = ICCR0_ITR | ICCR0_RXE; + + if (i < 0) + printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n"); } netif_wake_queue(dev); } /* EIF(Error in FIFO/End in Frame) handler for FIR */ -static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev) +static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0) { unsigned int len, stat, data; @@ -343,14 +414,14 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev) data = ICDR; if (stat & (ICSR1_CRE | ICSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & ICSR1_CRE) { printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n"); - si->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } if (stat & ICSR1_ROR) { printk(KERN_DEBUG "pxa_ir: fir receive overrun\n"); - si->stats.rx_frame_errors++; + dev->stats.rx_over_errors++; } } else { si->dma_rx_buff[len++] = data; @@ -362,28 +433,34 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev) if (stat & ICSR1_EOF) { /* end of frame. */ - struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC); + struct sk_buff *skb; + + if (icsr0 & ICSR0_FRE) { + printk(KERN_ERR "pxa_ir: dropping erroneous frame\n"); + dev->stats.rx_dropped++; + return; + } + + skb = alloc_skb(len+1,GFP_ATOMIC); if (!skb) { printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n"); - si->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } /* Align IP header to 20 bytes */ skb_reserve(skb, 1); - memcpy(skb->data, si->dma_rx_buff, len); + skb_copy_to_linear_data(skb, si->dma_rx_buff, len); skb_put(skb, len); /* Feed it to IrLAP */ skb->dev = dev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); - si->stats.rx_packets++; - si->stats.rx_bytes += len; - - dev->last_rx = jiffies; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } } @@ -392,33 +469,38 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) { struct net_device *dev = dev_id; struct pxa_irda *si = netdev_priv(dev); - int icsr0; + int icsr0, i = 64; /* stop RX DMA */ DCSR(si->rxdma) &= ~DCSR_RUN; - si->last_oscr = OSCR; + si->last_oscr = readl_relaxed(OSCR); icsr0 = ICSR0; if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) { if (icsr0 & ICSR0_FRE) { printk(KERN_DEBUG "pxa_ir: fir receive frame error\n"); - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; } else { printk(KERN_DEBUG "pxa_ir: fir receive abort\n"); - si->stats.rx_errors++; + dev->stats.rx_errors++; } ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB); } if (icsr0 & ICSR0_EIF) { - /* An error in FIFO occured, or there is a end of frame */ - pxa_irda_fir_irq_eif(si, dev); + /* An error in FIFO occurred, or there is a end of frame */ + pxa_irda_fir_irq_eif(si, dev, icsr0); } ICCR0 = 0; pxa_irda_fir_dma_rx_start(si); + while ((ICSR1 & ICSR1_RNE) && i--) + (void)ICDR; ICCR0 = ICCR0_ITR | ICCR0_RXE; + if (i < 0) + printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n"); + return IRQ_HANDLED; } @@ -445,7 +527,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) pxa_irda_set_speed(si, speed); } dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } netif_stop_queue(dev); @@ -464,10 +546,10 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long mtt = irda_get_mtt(skb); si->dma_tx_buff_len = skb->len; - memcpy(si->dma_tx_buff, skb->data, skb->len); + skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len); if (mtt) - while ((unsigned)(OSCR - si->last_oscr)/4 < mtt) + while ((unsigned)(readl_relaxed(OSCR) - si->last_oscr)/4 < mtt) cpu_relax(); /* stop RX DMA, disable FICP */ @@ -479,8 +561,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) } dev_kfree_skb(skb); - dev->trans_start = jiffies; - return 0; + return NETDEV_TX_OK; } static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) @@ -529,12 +610,6 @@ static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } -static struct net_device_stats *pxa_irda_stats(struct net_device *dev) -{ - struct pxa_irda *si = netdev_priv(dev); - return &si->stats; -} - static void pxa_irda_startup(struct pxa_irda *si) { /* Disable STUART interrupts */ @@ -552,8 +627,8 @@ static void pxa_irda_startup(struct pxa_irda *si) ICCR2 = ICCR2_TXP | ICCR2_TRIG_32; /* configure DMAC */ - DRCMR17 = si->rxdma | DRCMR_MAPVLD; - DRCMR18 = si->txdma | DRCMR_MAPVLD; + DRCMR(17) = si->rxdma | DRCMR_MAPVLD; + DRCMR(18) = si->txdma | DRCMR_MAPVLD; /* force SIR reinitialization */ si->speed = 4000000; @@ -572,24 +647,23 @@ static void pxa_irda_shutdown(struct pxa_irda *si) STIER = 0; /* disable STUART SIR mode */ STISR = 0; - /* disable the STUART clock */ - pxa_set_cken(CKEN5_STUART, 0); /* disable DMA */ DCSR(si->txdma) &= ~DCSR_RUN; DCSR(si->rxdma) &= ~DCSR_RUN; /* disable FICP */ ICCR0 = 0; - /* disable the FICP clock */ - pxa_set_cken(CKEN13_FICP, 0); - DRCMR17 = 0; - DRCMR18 = 0; + /* disable the STUART or FICP clocks */ + pxa_irda_disable_clk(si); + + DRCMR(17) = 0; + DRCMR(18) = 0; local_irq_restore(flags); /* power off board transceiver */ - si->pdata->transceiver_mode(si->dev, IR_OFF); + pxa_irda_set_mode(si, IR_OFF); printk(KERN_DEBUG "pxa_ir: irda shutdown\n"); } @@ -601,19 +675,19 @@ static int pxa_irda_start(struct net_device *dev) si->speed = 9600; - err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev); + err = request_irq(si->uart_irq, pxa_irda_sir_irq, 0, dev->name, dev); if (err) goto err_irq1; - err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev); + err = request_irq(si->icp_irq, pxa_irda_fir_irq, 0, dev->name, dev); if (err) goto err_irq2; /* * The interrupt must remain disabled for now. */ - disable_irq(IRQ_STUART); - disable_irq(IRQ_ICP); + disable_irq(si->uart_irq); + disable_irq(si->icp_irq); err = -EBUSY; si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev); @@ -626,12 +700,12 @@ static int pxa_irda_start(struct net_device *dev) err = -ENOMEM; si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, - &si->dma_rx_buff_phy, GFP_KERNEL ); + &si->dma_rx_buff_phy, GFP_KERNEL); if (!si->dma_rx_buff) goto err_dma_rx_buff; si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, - &si->dma_tx_buff_phy, GFP_KERNEL ); + &si->dma_tx_buff_phy, GFP_KERNEL); if (!si->dma_tx_buff) goto err_dma_tx_buff; @@ -649,8 +723,8 @@ static int pxa_irda_start(struct net_device *dev) /* * Now enable the interrupt and start the queue */ - enable_irq(IRQ_STUART); - enable_irq(IRQ_ICP); + enable_irq(si->uart_irq); + enable_irq(si->icp_irq); netif_start_queue(dev); printk(KERN_DEBUG "pxa_ir: irda driver opened\n"); @@ -667,9 +741,9 @@ err_dma_rx_buff: err_tx_dma: pxa_free_dma(si->rxdma); err_rx_dma: - free_irq(IRQ_ICP, dev); + free_irq(si->icp_irq, dev); err_irq2: - free_irq(IRQ_STUART, dev); + free_irq(si->uart_irq, dev); err_irq1: return err; @@ -689,8 +763,8 @@ static int pxa_irda_stop(struct net_device *dev) si->irlap = NULL; } - free_irq(IRQ_STUART, dev); - free_irq(IRQ_ICP, dev); + free_irq(si->uart_irq, dev); + free_irq(si->icp_irq, dev); pxa_free_dma(si->rxdma); pxa_free_dma(si->txdma); @@ -746,6 +820,13 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } +static const struct net_device_ops pxa_irda_netdev_ops = { + .ndo_open = pxa_irda_start, + .ndo_stop = pxa_irda_stop, + .ndo_start_xmit = pxa_irda_hard_xmit, + .ndo_do_ioctl = pxa_irda_ioctl, +}; + static int pxa_irda_probe(struct platform_device *pdev) { struct net_device *dev; @@ -765,13 +846,26 @@ static int pxa_irda_probe(struct platform_device *pdev) goto err_mem_2; dev = alloc_irdadev(sizeof(struct pxa_irda)); - if (!dev) + if (!dev) { + err = -ENOMEM; goto err_mem_3; + } + SET_NETDEV_DEV(dev, &pdev->dev); si = netdev_priv(dev); si->dev = &pdev->dev; si->pdata = pdev->dev.platform_data; + si->uart_irq = platform_get_irq(pdev, 0); + si->icp_irq = platform_get_irq(pdev, 1); + + si->sir_clk = clk_get(&pdev->dev, "UARTCLK"); + si->fir_clk = clk_get(&pdev->dev, "FICPCLK"); + if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) { + err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk); + goto err_mem_4; + } + /* * Initialise the SIR buffers */ @@ -782,11 +876,28 @@ static int pxa_irda_probe(struct platform_device *pdev) if (err) goto err_mem_5; - dev->hard_start_xmit = pxa_irda_hard_xmit; - dev->open = pxa_irda_start; - dev->stop = pxa_irda_stop; - dev->do_ioctl = pxa_irda_ioctl; - dev->get_stats = pxa_irda_stats; + if (gpio_is_valid(si->pdata->gpio_pwdown)) { + err = gpio_request(si->pdata->gpio_pwdown, "IrDA switch"); + if (err) + goto err_startup; + err = gpio_direction_output(si->pdata->gpio_pwdown, + !si->pdata->gpio_pwdown_inverted); + if (err) { + gpio_free(si->pdata->gpio_pwdown); + goto err_startup; + } + } + + if (si->pdata->startup) { + err = si->pdata->startup(si->dev); + if (err) + goto err_startup; + } + + if (gpio_is_valid(si->pdata->gpio_pwdown) && si->pdata->startup) + dev_warn(si->dev, "gpio_pwdown and startup() both defined!\n"); + + dev->netdev_ops = &pxa_irda_netdev_ops; irda_init_max_qos_capabilies(&si->qos); @@ -804,13 +915,20 @@ static int pxa_irda_probe(struct platform_device *pdev) err = register_netdev(dev); if (err == 0) - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); if (err) { + if (si->pdata->shutdown) + si->pdata->shutdown(si->dev); +err_startup: kfree(si->tx_buff.head); err_mem_5: kfree(si->rx_buff.head); err_mem_4: + if (si->sir_clk && !IS_ERR(si->sir_clk)) + clk_put(si->sir_clk); + if (si->fir_clk && !IS_ERR(si->fir_clk)) + clk_put(si->fir_clk); free_netdev(dev); err_mem_3: release_mem_region(__PREG(FICP), 0x1c); @@ -828,8 +946,14 @@ static int pxa_irda_remove(struct platform_device *_dev) if (dev) { struct pxa_irda *si = netdev_priv(dev); unregister_netdev(dev); + if (gpio_is_valid(si->pdata->gpio_pwdown)) + gpio_free(si->pdata->gpio_pwdown); + if (si->pdata->shutdown) + si->pdata->shutdown(si->dev); kfree(si->tx_buff.head); kfree(si->rx_buff.head); + clk_put(si->fir_clk); + clk_put(si->sir_clk); free_netdev(dev); } @@ -842,6 +966,7 @@ static int pxa_irda_remove(struct platform_device *_dev) static struct platform_driver pxa_ir_driver = { .driver = { .name = "pxa2xx-ir", + .owner = THIS_MODULE, }, .probe = pxa_irda_probe, .remove = pxa_irda_remove, @@ -849,17 +974,7 @@ static struct platform_driver pxa_ir_driver = { .resume = pxa_irda_resume, }; -static int __init pxa_irda_init(void) -{ - return platform_driver_register(&pxa_ir_driver); -} - -static void __exit pxa_irda_exit(void) -{ - platform_driver_unregister(&pxa_ir_driver); -} - -module_init(pxa_irda_init); -module_exit(pxa_irda_exit); +module_platform_driver(pxa_ir_driver); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-ir"); diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 937372d0039..42fde9ed23e 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -15,7 +15,7 @@ * This driver takes one kernel command line parameter, sa1100ir=, with * the following options: * max_rate:baudrate - set the maximum baud rate - * power_leve:level - set the transmitter power level + * power_level:level - set the transmitter power level * tx_lpm:0|1 - set transmit low power mode */ #include <linux/module.h> @@ -30,22 +30,29 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> +#include <linux/sa11x0-dma.h> #include <net/irda/irda.h> #include <net/irda/wrapper.h> #include <net/irda/irda_device.h> -#include <asm/irq.h> -#include <asm/dma.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/mach/irda.h> static int power_level = 3; static int tx_lpm; static int max_rate = 4000000; +struct sa1100_buf { + struct device *dev; + struct sk_buff *skb; + struct scatterlist sg; + struct dma_chan *chan; + dma_cookie_t cookie; +}; + struct sa1100_irda { - unsigned char hscr0; unsigned char utcr4; unsigned char power; unsigned char open; @@ -53,14 +60,9 @@ struct sa1100_irda { int speed; int newspeed; - struct sk_buff *txskb; - struct sk_buff *rxskb; - dma_addr_t txbuf_dma; - dma_addr_t rxbuf_dma; - dma_regs_t *txdma; - dma_regs_t *rxdma; + struct sa1100_buf dma_rx; + struct sa1100_buf dma_tx; - struct net_device_stats stats; struct device *dev; struct irda_platform_data *pdata; struct irlap_cb *irlap; @@ -68,23 +70,103 @@ struct sa1100_irda { iobuff_t tx_buff; iobuff_t rx_buff; + + int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *); + irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *); }; +static int sa1100_irda_set_speed(struct sa1100_irda *, int); + #define IS_FIR(si) ((si)->speed >= 4000000) #define HPSIR_MAX_RXLEN 2047 +static struct dma_slave_config sa1100_irda_sir_tx = { + .direction = DMA_TO_DEVICE, + .dst_addr = __PREG(Ser2UTDR), + .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .dst_maxburst = 4, +}; + +static struct dma_slave_config sa1100_irda_fir_rx = { + .direction = DMA_FROM_DEVICE, + .src_addr = __PREG(Ser2HSDR), + .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .src_maxburst = 8, +}; + +static struct dma_slave_config sa1100_irda_fir_tx = { + .direction = DMA_TO_DEVICE, + .dst_addr = __PREG(Ser2HSDR), + .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .dst_maxburst = 8, +}; + +static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf) +{ + struct dma_chan *chan = buf->chan; + struct dma_tx_state state; + enum dma_status status; + + status = chan->device->device_tx_status(chan, buf->cookie, &state); + if (status != DMA_PAUSED) + return 0; + + return sg_dma_len(&buf->sg) - state.residue; +} + +static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf, + const char *name, struct dma_slave_config *cfg) +{ + dma_cap_mask_t m; + int ret; + + dma_cap_zero(m); + dma_cap_set(DMA_SLAVE, m); + + buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name); + if (!buf->chan) { + dev_err(dev, "unable to request DMA channel for %s\n", + name); + return -ENOENT; + } + + ret = dmaengine_slave_config(buf->chan, cfg); + if (ret) + dev_warn(dev, "DMA slave_config for %s returned %d\n", + name, ret); + + buf->dev = buf->chan->device->dev; + + return 0; +} + +static void sa1100_irda_dma_start(struct sa1100_buf *buf, + enum dma_transfer_direction dir, dma_async_tx_callback cb, void *cb_p) +{ + struct dma_async_tx_descriptor *desc; + struct dma_chan *chan = buf->chan; + + desc = dmaengine_prep_slave_sg(chan, &buf->sg, 1, dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (desc) { + desc->callback = cb; + desc->callback_param = cb_p; + buf->cookie = dmaengine_submit(desc); + dma_async_issue_pending(chan); + } +} + /* * Allocate and map the receive buffer, unless it is already allocated. */ static int sa1100_irda_rx_alloc(struct sa1100_irda *si) { - if (si->rxskb) + if (si->dma_rx.skb) return 0; - si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC); - - if (!si->rxskb) { + si->dma_rx.skb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC); + if (!si->dma_rx.skb) { printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n"); return -ENOMEM; } @@ -93,11 +175,14 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si) * Align any IP headers that may be contained * within the frame. */ - skb_reserve(si->rxskb, 1); + skb_reserve(si->dma_rx.skb, 1); + + sg_set_buf(&si->dma_rx.sg, si->dma_rx.skb->data, HPSIR_MAX_RXLEN); + if (dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE) == 0) { + dev_kfree_skb_any(si->dma_rx.skb); + return -ENOMEM; + } - si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data, - HPSIR_MAX_RXLEN, - DMA_FROM_DEVICE); return 0; } @@ -107,7 +192,7 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si) */ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) { - if (!si->rxskb) { + if (!si->dma_rx.skb) { printk(KERN_ERR "sa1100_ir: rx buffer went missing\n"); return; } @@ -115,251 +200,87 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) /* * First empty receive FIFO */ - Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; + Ser2HSCR0 = HSCR0_HSSP; /* * Enable the DMA, receiver and receive interrupt. */ - sa1100_clear_dma(si->rxdma); - sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN); - Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE; + dmaengine_terminate_all(si->dma_rx.chan); + sa1100_irda_dma_start(&si->dma_rx, DMA_DEV_TO_MEM, NULL, NULL); + + Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE; } -/* - * Set the IrDA communications speed. - */ -static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) +static void sa1100_irda_check_speed(struct sa1100_irda *si) { - unsigned long flags; - int brd, ret = -EINVAL; - - switch (speed) { - case 9600: case 19200: case 38400: - case 57600: case 115200: - brd = 3686400 / (16 * speed) - 1; - - /* - * Stop the receive DMA. - */ - if (IS_FIR(si)) - sa1100_stop_dma(si->rxdma); - - local_irq_save(flags); - - Ser2UTCR3 = 0; - Ser2HSCR0 = HSCR0_UART; - - Ser2UTCR1 = brd >> 8; - Ser2UTCR2 = brd; - - /* - * Clear status register - */ - Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; - Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; - - if (si->pdata->set_speed) - si->pdata->set_speed(si->dev, speed); - - si->speed = speed; - - local_irq_restore(flags); - ret = 0; - break; - - case 4000000: - local_irq_save(flags); - - si->hscr0 = 0; - - Ser2HSSR0 = 0xff; - Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; - Ser2UTCR3 = 0; - - si->speed = speed; - - if (si->pdata->set_speed) - si->pdata->set_speed(si->dev, speed); - - sa1100_irda_rx_alloc(si); - sa1100_irda_rx_dma_start(si); - - local_irq_restore(flags); - - break; - - default: - break; + if (si->newspeed) { + sa1100_irda_set_speed(si, si->newspeed); + si->newspeed = 0; } - - return ret; } /* - * Control the power state of the IrDA transmitter. - * State: - * 0 - off - * 1 - short range, lowest power - * 2 - medium range, medium power - * 3 - maximum range, high power - * - * Currently, only assabet is known to support this. + * HP-SIR format support. */ -static int -__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state) -{ - int ret = 0; - if (si->pdata->set_power) - ret = si->pdata->set_power(si->dev, state); - return ret; -} - -static inline int -sa1100_set_power(struct sa1100_irda *si, unsigned int state) +static void sa1100_irda_sirtxdma_irq(void *id) { - int ret; - - ret = __sa1100_irda_set_power(si, state); - if (ret == 0) - si->power = state; - - return ret; -} - -static int sa1100_irda_startup(struct sa1100_irda *si) -{ - int ret; + struct net_device *dev = id; + struct sa1100_irda *si = netdev_priv(dev); - /* - * Ensure that the ports for this device are setup correctly. - */ - if (si->pdata->startup) - si->pdata->startup(si->dev); + dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE); + dev_kfree_skb(si->dma_tx.skb); + si->dma_tx.skb = NULL; - /* - * Configure PPC for IRDA - we want to drive TXD2 low. - * We also want to drive this pin low during sleep. - */ - PPSR &= ~PPC_TXD2; - PSDR &= ~PPC_TXD2; - PPDR |= PPC_TXD2; + dev->stats.tx_packets++; + dev->stats.tx_bytes += sg_dma_len(&si->dma_tx.sg); - /* - * Enable HP-SIR modulation, and ensure that the port is disabled. - */ - Ser2UTCR3 = 0; - Ser2HSCR0 = HSCR0_UART; - Ser2UTCR4 = si->utcr4; - Ser2UTCR0 = UTCR0_8BitData; - Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL; + /* We need to ensure that the transmitter has finished. */ + do + rmb(); + while (Ser2UTSR1 & UTSR1_TBY); /* - * Clear status register + * Ok, we've finished transmitting. Now enable the receiver. + * Sometimes we get a receive IRQ immediately after a transmit... */ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; + Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; - ret = sa1100_irda_set_speed(si, si->speed = 9600); - if (ret) { - Ser2UTCR3 = 0; - Ser2HSCR0 = 0; - - if (si->pdata->shutdown) - si->pdata->shutdown(si->dev); - } - - return ret; -} - -static void sa1100_irda_shutdown(struct sa1100_irda *si) -{ - /* - * Stop all DMA activity. - */ - sa1100_stop_dma(si->rxdma); - sa1100_stop_dma(si->txdma); - - /* Disable the port. */ - Ser2UTCR3 = 0; - Ser2HSCR0 = 0; + sa1100_irda_check_speed(si); - if (si->pdata->shutdown) - si->pdata->shutdown(si->dev); + /* I'm hungry! */ + netif_wake_queue(dev); } -#ifdef CONFIG_PM -/* - * Suspend the IrDA interface. - */ -static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state) +static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev, + struct sa1100_irda *si) { - struct net_device *dev = platform_get_drvdata(pdev); - struct sa1100_irda *si; - - if (!dev) - return 0; - - si = dev->priv; - if (si->open) { - /* - * Stop the transmit queue - */ - netif_device_detach(dev); - disable_irq(dev->irq); - sa1100_irda_shutdown(si); - __sa1100_irda_set_power(si, 0); + si->tx_buff.data = si->tx_buff.head; + si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, + si->tx_buff.truesize); + + si->dma_tx.skb = skb; + sg_set_buf(&si->dma_tx.sg, si->tx_buff.data, si->tx_buff.len); + if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) { + si->dma_tx.skb = NULL; + netif_wake_queue(dev); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; } - return 0; -} - -/* - * Resume the IrDA interface. - */ -static int sa1100_irda_resume(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct sa1100_irda *si; - - if (!dev) - return 0; - - si = dev->priv; - if (si->open) { - /* - * If we missed a speed change, initialise at the new speed - * directly. It is debatable whether this is actually - * required, but in the interests of continuing from where - * we left off it is desireable. The converse argument is - * that we should re-negotiate at 9600 baud again. - */ - if (si->newspeed) { - si->speed = si->newspeed; - si->newspeed = 0; - } + sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_sirtxdma_irq, dev); - sa1100_irda_startup(si); - __sa1100_irda_set_power(si, si->power); - enable_irq(dev->irq); - - /* - * This automatically wakes up the queue - */ - netif_device_attach(dev); - } + /* + * The mean turn-around time is enforced by XBOF padding, + * so we don't have to do anything special here. + */ + Ser2UTCR3 = UTCR3_TXE; - return 0; + return NETDEV_TX_OK; } -#else -#define sa1100_irda_suspend NULL -#define sa1100_irda_resume NULL -#endif -/* - * HP-SIR format interrupt service routines. - */ -static void sa1100_irda_hpsir_irq(struct net_device *dev) +static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si) { - struct sa1100_irda *si = dev->priv; int status; status = Ser2UTSR0; @@ -375,13 +296,13 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) data = Ser2UTDR; if (stat & (UTSR1_FRE | UTSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & UTSR1_FRE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (stat & UTSR1_ROR) - si->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else - async_unwrap_char(dev, &si->stats, &si->rx_buff, data); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, data); status = Ser2UTSR0; } @@ -396,9 +317,9 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) * There are at least 4 bytes in the FIFO. Read 3 bytes * and leave the rest to the block below. */ - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); } if (status & (UTSR0_RFS | UTSR0_RID)) { @@ -406,58 +327,102 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) * Fifo contains more than 1 character. */ do { - async_unwrap_char(dev, &si->stats, &si->rx_buff, + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); } while (Ser2UTSR1 & UTSR1_RNE); - dev->last_rx = jiffies; } - if (status & UTSR0_TFS && si->tx_buff.len) { - /* - * Transmitter FIFO is not full - */ - do { - Ser2UTDR = *si->tx_buff.data++; - si->tx_buff.len -= 1; - } while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len); + return IRQ_HANDLED; +} - if (si->tx_buff.len == 0) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->tx_buff.data - - si->tx_buff.head; +/* + * FIR format support. + */ +static void sa1100_irda_firtxdma_irq(void *id) +{ + struct net_device *dev = id; + struct sa1100_irda *si = netdev_priv(dev); + struct sk_buff *skb; - /* - * We need to ensure that the transmitter has - * finished. - */ - do - rmb(); - while (Ser2UTSR1 & UTSR1_TBY); + /* + * Wait for the transmission to complete. Unfortunately, + * the hardware doesn't give us an interrupt to indicate + * "end of frame". + */ + do + rmb(); + while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY); - /* - * Ok, we've finished transmitting. Now enable - * the receiver. Sometimes we get a receive IRQ - * immediately after a transmit... - */ - Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; - Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; + /* + * Clear the transmit underrun bit. + */ + Ser2HSSR0 = HSSR0_TUR; - if (si->newspeed) { - sa1100_irda_set_speed(si, si->newspeed); - si->newspeed = 0; - } + /* + * Do we need to change speed? Note that we're lazy + * here - we don't free the old dma_rx.skb. We don't need + * to allocate a buffer either. + */ + sa1100_irda_check_speed(si); - /* I'm hungry! */ - netif_wake_queue(dev); - } + /* + * Start reception. This disables the transmitter for + * us. This will be using the existing RX buffer. + */ + sa1100_irda_rx_dma_start(si); + + /* Account and free the packet. */ + skb = si->dma_tx.skb; + if (skb) { + dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, + DMA_TO_DEVICE); + dev->stats.tx_packets ++; + dev->stats.tx_bytes += skb->len; + dev_kfree_skb_irq(skb); + si->dma_tx.skb = NULL; } + + /* + * Make sure that the TX queue is available for sending + * (for retries). TX has priority over RX at all times. + */ + netif_wake_queue(dev); +} + +static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev, + struct sa1100_irda *si) +{ + int mtt = irda_get_mtt(skb); + + si->dma_tx.skb = skb; + sg_set_buf(&si->dma_tx.sg, skb->data, skb->len); + if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) { + si->dma_tx.skb = NULL; + netif_wake_queue(dev); + dev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_firtxdma_irq, dev); + + /* + * If we have a mean turn-around time, impose the specified + * specified delay. We could shorten this by timing from + * the point we received the packet. + */ + if (mtt) + udelay(mtt); + + Ser2HSCR0 = HSCR0_HSSP | HSCR0_TXE; + + return NETDEV_TX_OK; } static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) { - struct sk_buff *skb = si->rxskb; - dma_addr_t dma_addr; + struct sk_buff *skb = si->dma_rx.skb; unsigned int len, stat, data; if (!skb) { @@ -468,11 +433,10 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev /* * Get the current data position. */ - dma_addr = sa1100_get_dma_pos(si->rxdma); - len = dma_addr - si->rxbuf_dma; + len = sa1100_irda_dma_xferred(&si->dma_rx); if (len > HPSIR_MAX_RXLEN) len = HPSIR_MAX_RXLEN; - dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE); + dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); do { /* @@ -483,11 +447,11 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev data = Ser2HSDR; if (stat & (HSSR1_CRE | HSSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & HSSR1_CRE) - si->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (stat & HSSR1_ROR) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; } else skb->data[len++] = data; @@ -500,14 +464,14 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev } while (Ser2HSSR0 & HSSR0_EIF); if (stat & HSSR1_EOF) { - si->rxskb = NULL; + si->dma_rx.skb = NULL; skb_put(skb, len); skb->dev = dev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); - si->stats.rx_packets++; - si->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; /* * Before we pass the buffer up, allocate a new one. @@ -515,31 +479,25 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev sa1100_irda_rx_alloc(si); netif_rx(skb); - dev->last_rx = jiffies; } else { /* - * Remap the buffer. + * Remap the buffer - it was previously mapped, and we + * hope that this succeeds. */ - si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data, - HPSIR_MAX_RXLEN, - DMA_FROM_DEVICE); + dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); } } /* - * FIR format interrupt service routine. We only have to - * handle RX events; transmit events go via the TX DMA handler. - * - * No matter what, we disable RX, process, and the restart RX. + * We only have to handle RX events here; transmit events go via the TX + * DMA handler. We disable RX, process, and the restart RX. */ -static void sa1100_irda_fir_irq(struct net_device *dev) +static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si) { - struct sa1100_irda *si = dev->priv; - /* * Stop RX DMA */ - sa1100_stop_dma(si->rxdma); + dmaengine_pause(si->dma_rx.chan); /* * Framing error - we throw away the packet completely. @@ -547,15 +505,15 @@ static void sa1100_irda_fir_irq(struct net_device *dev) * from the fifo. */ if (Ser2HSSR0 & (HSSR0_FRE | HSSR0_RAB)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (Ser2HSSR0 & HSSR0_FRE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; /* * Clear out the DMA... */ - Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; + Ser2HSCR0 = HSCR0_HSSP; /* * Clear selected status bits now, so we @@ -577,79 +535,129 @@ static void sa1100_irda_fir_irq(struct net_device *dev) * No matter what happens, we must restart reception. */ sa1100_irda_rx_dma_start(si); -} -static irqreturn_t sa1100_irda_irq(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - if (IS_FIR(((struct sa1100_irda *)dev->priv))) - sa1100_irda_fir_irq(dev); - else - sa1100_irda_hpsir_irq(dev); return IRQ_HANDLED; } /* - * TX DMA completion handler. + * Set the IrDA communications speed. */ -static void sa1100_irda_txdma_irq(void *id) +static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) { - struct net_device *dev = id; - struct sa1100_irda *si = dev->priv; - struct sk_buff *skb = si->txskb; + unsigned long flags; + int brd, ret = -EINVAL; - si->txskb = NULL; + switch (speed) { + case 9600: case 19200: case 38400: + case 57600: case 115200: + brd = 3686400 / (16 * speed) - 1; - /* - * Wait for the transmission to complete. Unfortunately, - * the hardware doesn't give us an interrupt to indicate - * "end of frame". - */ - do - rmb(); - while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY); + /* Stop the receive DMA, and configure transmit. */ + if (IS_FIR(si)) { + dmaengine_terminate_all(si->dma_rx.chan); + dmaengine_slave_config(si->dma_tx.chan, + &sa1100_irda_sir_tx); + } - /* - * Clear the transmit underrun bit. - */ - Ser2HSSR0 = HSSR0_TUR; + local_irq_save(flags); - /* - * Do we need to change speed? Note that we're lazy - * here - we don't free the old rxskb. We don't need - * to allocate a buffer either. - */ - if (si->newspeed) { - sa1100_irda_set_speed(si, si->newspeed); - si->newspeed = 0; - } + Ser2UTCR3 = 0; + Ser2HSCR0 = HSCR0_UART; - /* - * Start reception. This disables the transmitter for - * us. This will be using the existing RX buffer. - */ - sa1100_irda_rx_dma_start(si); + Ser2UTCR1 = brd >> 8; + Ser2UTCR2 = brd; - /* - * Account and free the packet. - */ - if (skb) { - dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE); - si->stats.tx_packets ++; - si->stats.tx_bytes += skb->len; - dev_kfree_skb_irq(skb); + /* + * Clear status register + */ + Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; + Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; + + if (si->pdata->set_speed) + si->pdata->set_speed(si->dev, speed); + + si->speed = speed; + si->tx_start = sa1100_irda_sir_tx_start; + si->irq = sa1100_irda_sir_irq; + + local_irq_restore(flags); + ret = 0; + break; + + case 4000000: + if (!IS_FIR(si)) + dmaengine_slave_config(si->dma_tx.chan, + &sa1100_irda_fir_tx); + + local_irq_save(flags); + + Ser2HSSR0 = 0xff; + Ser2HSCR0 = HSCR0_HSSP; + Ser2UTCR3 = 0; + + si->speed = speed; + si->tx_start = sa1100_irda_fir_tx_start; + si->irq = sa1100_irda_fir_irq; + + if (si->pdata->set_speed) + si->pdata->set_speed(si->dev, speed); + + sa1100_irda_rx_alloc(si); + sa1100_irda_rx_dma_start(si); + + local_irq_restore(flags); + + break; + + default: + break; } - /* - * Make sure that the TX queue is available for sending - * (for retries). TX has priority over RX at all times. - */ - netif_wake_queue(dev); + return ret; +} + +/* + * Control the power state of the IrDA transmitter. + * State: + * 0 - off + * 1 - short range, lowest power + * 2 - medium range, medium power + * 3 - maximum range, high power + * + * Currently, only assabet is known to support this. + */ +static int +__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state) +{ + int ret = 0; + if (si->pdata->set_power) + ret = si->pdata->set_power(si->dev, state); + return ret; +} + +static inline int +sa1100_set_power(struct sa1100_irda *si, unsigned int state) +{ + int ret; + + ret = __sa1100_irda_set_power(si, state); + if (ret == 0) + si->power = state; + + return ret; +} + +static irqreturn_t sa1100_irda_irq(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct sa1100_irda *si = netdev_priv(dev); + + return si->irq(dev, si); } static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct sa1100_irda *si = dev->priv; + struct sa1100_irda *si = netdev_priv(dev); int speed = irda_get_next_speed(skb); /* @@ -660,71 +668,26 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) if (speed != si->speed && speed != -1) si->newspeed = speed; - /* - * If this is an empty frame, we can bypass a lot. - */ + /* If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { - if (si->newspeed) { - si->newspeed = 0; - sa1100_irda_set_speed(si, speed); - } + sa1100_irda_check_speed(si); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } - if (!IS_FIR(si)) { - netif_stop_queue(dev); - - si->tx_buff.data = si->tx_buff.head; - si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, - si->tx_buff.truesize); - - /* - * Set the transmit interrupt enable. This will fire - * off an interrupt immediately. Note that we disable - * the receiver so we won't get spurious characteres - * received. - */ - Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE; - - dev_kfree_skb(skb); - } else { - int mtt = irda_get_mtt(skb); - - /* - * We must not be transmitting... - */ - BUG_ON(si->txskb); - - netif_stop_queue(dev); - - si->txskb = skb; - si->txbuf_dma = dma_map_single(si->dev, skb->data, - skb->len, DMA_TO_DEVICE); - - sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len); - - /* - * If we have a mean turn-around time, impose the specified - * specified delay. We could shorten this by timing from - * the point we received the packet. - */ - if (mtt) - udelay(mtt); - - Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE; - } + netif_stop_queue(dev); - dev->trans_start = jiffies; + /* We must not already have a skb to transmit... */ + BUG_ON(si->dma_tx.skb); - return 0; + return si->tx_start(skb, dev, si); } static int sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) { struct if_irda_req *rq = (struct if_irda_req *)ifreq; - struct sa1100_irda *si = dev->priv; + struct sa1100_irda *si = netdev_priv(dev); int ret = -EOPNOTSUPP; switch (cmd) { @@ -764,39 +727,87 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } -static struct net_device_stats *sa1100_irda_stats(struct net_device *dev) +static int sa1100_irda_startup(struct sa1100_irda *si) +{ + int ret; + + /* + * Ensure that the ports for this device are setup correctly. + */ + if (si->pdata->startup) { + ret = si->pdata->startup(si->dev); + if (ret) + return ret; + } + + /* + * Configure PPC for IRDA - we want to drive TXD2 low. + * We also want to drive this pin low during sleep. + */ + PPSR &= ~PPC_TXD2; + PSDR &= ~PPC_TXD2; + PPDR |= PPC_TXD2; + + /* + * Enable HP-SIR modulation, and ensure that the port is disabled. + */ + Ser2UTCR3 = 0; + Ser2HSCR0 = HSCR0_UART; + Ser2UTCR4 = si->utcr4; + Ser2UTCR0 = UTCR0_8BitData; + Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL; + + /* + * Clear status register + */ + Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; + + ret = sa1100_irda_set_speed(si, si->speed = 9600); + if (ret) { + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + + if (si->pdata->shutdown) + si->pdata->shutdown(si->dev); + } + + return ret; +} + +static void sa1100_irda_shutdown(struct sa1100_irda *si) { - struct sa1100_irda *si = dev->priv; - return &si->stats; + /* + * Stop all DMA activity. + */ + dmaengine_terminate_all(si->dma_rx.chan); + dmaengine_terminate_all(si->dma_tx.chan); + + /* Disable the port. */ + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + + if (si->pdata->shutdown) + si->pdata->shutdown(si->dev); } static int sa1100_irda_start(struct net_device *dev) { - struct sa1100_irda *si = dev->priv; + struct sa1100_irda *si = netdev_priv(dev); int err; si->speed = 9600; - err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev); - if (err) - goto err_irq; - - err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive", - NULL, NULL, &si->rxdma); + err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc", + &sa1100_irda_fir_rx); if (err) goto err_rx_dma; - err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit", - sa1100_irda_txdma_irq, dev, &si->txdma); + err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr", + &sa1100_irda_sir_tx); if (err) goto err_tx_dma; /* - * The interrupt must remain disabled for now. - */ - disable_irq(dev->irq); - - /* * Setup the serial port for the specified speed. */ err = sa1100_irda_startup(si); @@ -811,44 +822,60 @@ static int sa1100_irda_start(struct net_device *dev) if (!si->irlap) goto err_irlap; + err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev); + if (err) + goto err_irq; + /* * Now enable the interrupt and start the queue */ si->open = 1; sa1100_set_power(si, power_level); /* low power mode */ - enable_irq(dev->irq); + netif_start_queue(dev); return 0; +err_irq: + irlap_close(si->irlap); err_irlap: si->open = 0; sa1100_irda_shutdown(si); err_startup: - sa1100_free_dma(si->txdma); + dma_release_channel(si->dma_tx.chan); err_tx_dma: - sa1100_free_dma(si->rxdma); + dma_release_channel(si->dma_rx.chan); err_rx_dma: - free_irq(dev->irq, dev); -err_irq: return err; } static int sa1100_irda_stop(struct net_device *dev) { - struct sa1100_irda *si = dev->priv; + struct sa1100_irda *si = netdev_priv(dev); + struct sk_buff *skb; - disable_irq(dev->irq); + netif_stop_queue(dev); + + si->open = 0; sa1100_irda_shutdown(si); /* - * If we have been doing DMA receive, make sure we + * If we have been doing any DMA activity, make sure we * tidy that up cleanly. */ - if (si->rxskb) { - dma_unmap_single(si->dev, si->rxbuf_dma, HPSIR_MAX_RXLEN, - DMA_FROM_DEVICE); - dev_kfree_skb(si->rxskb); - si->rxskb = NULL; + skb = si->dma_rx.skb; + if (skb) { + dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, + DMA_FROM_DEVICE); + dev_kfree_skb(skb); + si->dma_rx.skb = NULL; + } + + skb = si->dma_tx.skb; + if (skb) { + dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, + DMA_TO_DEVICE); + dev_kfree_skb(skb); + si->dma_tx.skb = NULL; } /* Stop IrLAP */ @@ -857,14 +884,11 @@ static int sa1100_irda_stop(struct net_device *dev) si->irlap = NULL; } - netif_stop_queue(dev); - si->open = 0; - /* * Free resources */ - sa1100_free_dma(si->txdma); - sa1100_free_dma(si->rxdma); + dma_release_channel(si->dma_tx.chan); + dma_release_channel(si->dma_rx.chan); free_irq(dev->irq, dev); sa1100_set_power(si, 0); @@ -884,16 +908,27 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } +static const struct net_device_ops sa1100_irda_netdev_ops = { + .ndo_open = sa1100_irda_start, + .ndo_stop = sa1100_irda_stop, + .ndo_start_xmit = sa1100_irda_hard_xmit, + .ndo_do_ioctl = sa1100_irda_ioctl, +}; + static int sa1100_irda_probe(struct platform_device *pdev) { struct net_device *dev; struct sa1100_irda *si; unsigned int baudrate_mask; - int err; + int err, irq; if (!pdev->dev.platform_data) return -EINVAL; + irq = platform_get_irq(pdev, 0); + if (irq <= 0) + return irq < 0 ? irq : -ENXIO; + err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY; if (err) goto err_mem_1; @@ -905,29 +940,32 @@ static int sa1100_irda_probe(struct platform_device *pdev) goto err_mem_3; dev = alloc_irdadev(sizeof(struct sa1100_irda)); - if (!dev) + if (!dev) { + err = -ENOMEM; goto err_mem_4; + } - si = dev->priv; + SET_NETDEV_DEV(dev, &pdev->dev); + + si = netdev_priv(dev); si->dev = &pdev->dev; si->pdata = pdev->dev.platform_data; + sg_init_table(&si->dma_rx.sg, 1); + sg_init_table(&si->dma_tx.sg, 1); + /* * Initialise the HP-SIR buffers */ err = sa1100_irda_init_iobuf(&si->rx_buff, 14384); if (err) goto err_mem_5; - err = sa1100_irda_init_iobuf(&si->tx_buff, 4000); + err = sa1100_irda_init_iobuf(&si->tx_buff, IRDA_SIR_MAX_FRAME); if (err) goto err_mem_5; - dev->hard_start_xmit = sa1100_irda_hard_xmit; - dev->open = sa1100_irda_start; - dev->stop = sa1100_irda_stop; - dev->do_ioctl = sa1100_irda_ioctl; - dev->get_stats = sa1100_irda_stats; - dev->irq = IRQ_Ser2ICP; + dev->netdev_ops = &sa1100_irda_netdev_ops; + dev->irq = irq; irda_init_max_qos_capabilies(&si->qos); @@ -987,7 +1025,7 @@ static int sa1100_irda_remove(struct platform_device *pdev) struct net_device *dev = platform_get_drvdata(pdev); if (dev) { - struct sa1100_irda *si = dev->priv; + struct sa1100_irda *si = netdev_priv(dev); unregister_netdev(dev); kfree(si->tx_buff.head); kfree(si->rx_buff.head); @@ -1001,6 +1039,74 @@ static int sa1100_irda_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +/* + * Suspend the IrDA interface. + */ +static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct sa1100_irda *si; + + if (!dev) + return 0; + + si = netdev_priv(dev); + if (si->open) { + /* + * Stop the transmit queue + */ + netif_device_detach(dev); + disable_irq(dev->irq); + sa1100_irda_shutdown(si); + __sa1100_irda_set_power(si, 0); + } + + return 0; +} + +/* + * Resume the IrDA interface. + */ +static int sa1100_irda_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct sa1100_irda *si; + + if (!dev) + return 0; + + si = netdev_priv(dev); + if (si->open) { + /* + * If we missed a speed change, initialise at the new speed + * directly. It is debatable whether this is actually + * required, but in the interests of continuing from where + * we left off it is desirable. The converse argument is + * that we should re-negotiate at 9600 baud again. + */ + if (si->newspeed) { + si->speed = si->newspeed; + si->newspeed = 0; + } + + sa1100_irda_startup(si); + __sa1100_irda_set_power(si, si->power); + enable_irq(dev->irq); + + /* + * This automatically wakes up the queue + */ + netif_device_attach(dev); + } + + return 0; +} +#else +#define sa1100_irda_suspend NULL +#define sa1100_irda_resume NULL +#endif + static struct platform_driver sa1100ir_driver = { .probe = sa1100_irda_probe, .remove = sa1100_irda_remove, @@ -1008,6 +1114,7 @@ static struct platform_driver sa1100ir_driver = { .resume = sa1100_irda_resume, .driver = { .name = "sa11x0-ir", + .owner = THIS_MODULE, }, }; @@ -1041,3 +1148,4 @@ MODULE_LICENSE("GPL"); MODULE_PARM_DESC(power_level, "IrDA power level, 1 (low) to 3 (high)"); MODULE_PARM_DESC(tx_lpm, "Enable transmitter low power (1.6us) mode"); MODULE_PARM_DESC(max_rate, "Maximum baud rate (4000000, 115200, 57600, 38400, 19200, 9600)"); +MODULE_ALIAS("platform:sa11x0-ir"); diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c new file mode 100644 index 00000000000..c96b46b2c3a --- /dev/null +++ b/drivers/net/irda/sh_irda.c @@ -0,0 +1,875 @@ +/* + * SuperH IrDA Driver + * + * Copyright (C) 2010 Renesas Solutions Corp. + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * Based on sh_sir.c + * Copyright (C) 2009 Renesas Solutions Corp. + * Copyright 2006-2009 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * CAUTION + * + * This driver is very simple. + * So, it doesn't have below support now + * - MIR/FIR support + * - DMA transfer support + * - FIFO mode support + */ +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/clk.h> +#include <net/irda/wrapper.h> +#include <net/irda/irda_device.h> + +#define DRIVER_NAME "sh_irda" + +#define __IRDARAM_LEN 0x1039 + +#define IRTMR 0x1F00 /* Transfer mode */ +#define IRCFR 0x1F02 /* Configuration */ +#define IRCTR 0x1F04 /* IR control */ +#define IRTFLR 0x1F20 /* Transmit frame length */ +#define IRTCTR 0x1F22 /* Transmit control */ +#define IRRFLR 0x1F40 /* Receive frame length */ +#define IRRCTR 0x1F42 /* Receive control */ +#define SIRISR 0x1F60 /* SIR-UART mode interrupt source */ +#define SIRIMR 0x1F62 /* SIR-UART mode interrupt mask */ +#define SIRICR 0x1F64 /* SIR-UART mode interrupt clear */ +#define SIRBCR 0x1F68 /* SIR-UART mode baud rate count */ +#define MFIRISR 0x1F70 /* MIR/FIR mode interrupt source */ +#define MFIRIMR 0x1F72 /* MIR/FIR mode interrupt mask */ +#define MFIRICR 0x1F74 /* MIR/FIR mode interrupt clear */ +#define CRCCTR 0x1F80 /* CRC engine control */ +#define CRCIR 0x1F86 /* CRC engine input data */ +#define CRCCR 0x1F8A /* CRC engine calculation */ +#define CRCOR 0x1F8E /* CRC engine output data */ +#define FIFOCP 0x1FC0 /* FIFO current pointer */ +#define FIFOFP 0x1FC2 /* FIFO follow pointer */ +#define FIFORSMSK 0x1FC4 /* FIFO receive status mask */ +#define FIFORSOR 0x1FC6 /* FIFO receive status OR */ +#define FIFOSEL 0x1FC8 /* FIFO select */ +#define FIFORS 0x1FCA /* FIFO receive status */ +#define FIFORFL 0x1FCC /* FIFO receive frame length */ +#define FIFORAMCP 0x1FCE /* FIFO RAM current pointer */ +#define FIFORAMFP 0x1FD0 /* FIFO RAM follow pointer */ +#define BIFCTL 0x1FD2 /* BUS interface control */ +#define IRDARAM 0x0000 /* IrDA buffer RAM */ +#define IRDARAM_LEN __IRDARAM_LEN /* - 8/16/32 (read-only for 32) */ + +/* IRTMR */ +#define TMD_MASK (0x3 << 14) /* Transfer Mode */ +#define TMD_SIR (0x0 << 14) +#define TMD_MIR (0x3 << 14) +#define TMD_FIR (0x2 << 14) + +#define FIFORIM (1 << 8) /* FIFO receive interrupt mask */ +#define MIM (1 << 4) /* MIR/FIR Interrupt Mask */ +#define SIM (1 << 0) /* SIR Interrupt Mask */ +#define xIM_MASK (FIFORIM | MIM | SIM) + +/* IRCFR */ +#define RTO_SHIFT 8 /* shift for Receive Timeout */ +#define RTO (0x3 << RTO_SHIFT) + +/* IRTCTR */ +#define ARMOD (1 << 15) /* Auto-Receive Mode */ +#define TE (1 << 0) /* Transmit Enable */ + +/* IRRFLR */ +#define RFL_MASK (0x1FFF) /* mask for Receive Frame Length */ + +/* IRRCTR */ +#define RE (1 << 0) /* Receive Enable */ + +/* + * SIRISR, SIRIMR, SIRICR, + * MFIRISR, MFIRIMR, MFIRICR + */ +#define FRE (1 << 15) /* Frame Receive End */ +#define TROV (1 << 11) /* Transfer Area Overflow */ +#define xIR_9 (1 << 9) +#define TOT xIR_9 /* for SIR Timeout */ +#define ABTD xIR_9 /* for MIR/FIR Abort Detection */ +#define xIR_8 (1 << 8) +#define FER xIR_8 /* for SIR Framing Error */ +#define CRCER xIR_8 /* for MIR/FIR CRC error */ +#define FTE (1 << 7) /* Frame Transmit End */ +#define xIR_MASK (FRE | TROV | xIR_9 | xIR_8 | FTE) + +/* SIRBCR */ +#define BRC_MASK (0x3F) /* mask for Baud Rate Count */ + +/* CRCCTR */ +#define CRC_RST (1 << 15) /* CRC Engine Reset */ +#define CRC_CT_MASK 0x0FFF /* mask for CRC Engine Input Data Count */ + +/* CRCIR */ +#define CRC_IN_MASK 0x0FFF /* mask for CRC Engine Input Data */ + +/************************************************************************ + + + enum / structure + + +************************************************************************/ +enum sh_irda_mode { + SH_IRDA_NONE = 0, + SH_IRDA_SIR, + SH_IRDA_MIR, + SH_IRDA_FIR, +}; + +struct sh_irda_self; +struct sh_irda_xir_func { + int (*xir_fre) (struct sh_irda_self *self); + int (*xir_trov) (struct sh_irda_self *self); + int (*xir_9) (struct sh_irda_self *self); + int (*xir_8) (struct sh_irda_self *self); + int (*xir_fte) (struct sh_irda_self *self); +}; + +struct sh_irda_self { + void __iomem *membase; + unsigned int irq; + struct platform_device *pdev; + + struct net_device *ndev; + + struct irlap_cb *irlap; + struct qos_info qos; + + iobuff_t tx_buff; + iobuff_t rx_buff; + + enum sh_irda_mode mode; + spinlock_t lock; + + struct sh_irda_xir_func *xir_func; +}; + +/************************************************************************ + + + common function + + +************************************************************************/ +static void sh_irda_write(struct sh_irda_self *self, u32 offset, u16 data) +{ + unsigned long flags; + + spin_lock_irqsave(&self->lock, flags); + iowrite16(data, self->membase + offset); + spin_unlock_irqrestore(&self->lock, flags); +} + +static u16 sh_irda_read(struct sh_irda_self *self, u32 offset) +{ + unsigned long flags; + u16 ret; + + spin_lock_irqsave(&self->lock, flags); + ret = ioread16(self->membase + offset); + spin_unlock_irqrestore(&self->lock, flags); + + return ret; +} + +static void sh_irda_update_bits(struct sh_irda_self *self, u32 offset, + u16 mask, u16 data) +{ + unsigned long flags; + u16 old, new; + + spin_lock_irqsave(&self->lock, flags); + old = ioread16(self->membase + offset); + new = (old & ~mask) | data; + if (old != new) + iowrite16(data, self->membase + offset); + spin_unlock_irqrestore(&self->lock, flags); +} + +/************************************************************************ + + + mode function + + +************************************************************************/ +/*===================================== + * + * common + * + *=====================================*/ +static void sh_irda_rcv_ctrl(struct sh_irda_self *self, int enable) +{ + struct device *dev = &self->ndev->dev; + + sh_irda_update_bits(self, IRRCTR, RE, enable ? RE : 0); + dev_dbg(dev, "recv %s\n", enable ? "enable" : "disable"); +} + +static int sh_irda_set_timeout(struct sh_irda_self *self, int interval) +{ + struct device *dev = &self->ndev->dev; + + if (SH_IRDA_SIR != self->mode) + interval = 0; + + if (interval < 0 || interval > 2) { + dev_err(dev, "unsupported timeout interval\n"); + return -EINVAL; + } + + sh_irda_update_bits(self, IRCFR, RTO, interval << RTO_SHIFT); + return 0; +} + +static int sh_irda_set_baudrate(struct sh_irda_self *self, int baudrate) +{ + struct device *dev = &self->ndev->dev; + u16 val; + + if (baudrate < 0) + return 0; + + if (SH_IRDA_SIR != self->mode) { + dev_err(dev, "it is not SIR mode\n"); + return -EINVAL; + } + + /* + * Baud rate (bits/s) = + * (48 MHz / 26) / (baud rate counter value + 1) x 16 + */ + val = (48000000 / 26 / 16 / baudrate) - 1; + dev_dbg(dev, "baudrate = %d, val = 0x%02x\n", baudrate, val); + + sh_irda_update_bits(self, SIRBCR, BRC_MASK, val); + + return 0; +} + +static int sh_irda_get_rcv_length(struct sh_irda_self *self) +{ + return RFL_MASK & sh_irda_read(self, IRRFLR); +} + +/*===================================== + * + * NONE MODE + * + *=====================================*/ +static int sh_irda_xir_fre(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + dev_err(dev, "none mode: frame recv\n"); + return 0; +} + +static int sh_irda_xir_trov(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + dev_err(dev, "none mode: buffer ram over\n"); + return 0; +} + +static int sh_irda_xir_9(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + dev_err(dev, "none mode: time over\n"); + return 0; +} + +static int sh_irda_xir_8(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + dev_err(dev, "none mode: framing error\n"); + return 0; +} + +static int sh_irda_xir_fte(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + dev_err(dev, "none mode: frame transmit end\n"); + return 0; +} + +static struct sh_irda_xir_func sh_irda_xir_func = { + .xir_fre = sh_irda_xir_fre, + .xir_trov = sh_irda_xir_trov, + .xir_9 = sh_irda_xir_9, + .xir_8 = sh_irda_xir_8, + .xir_fte = sh_irda_xir_fte, +}; + +/*===================================== + * + * MIR/FIR MODE + * + * MIR/FIR are not supported now + *=====================================*/ +static struct sh_irda_xir_func sh_irda_mfir_func = { + .xir_fre = sh_irda_xir_fre, + .xir_trov = sh_irda_xir_trov, + .xir_9 = sh_irda_xir_9, + .xir_8 = sh_irda_xir_8, + .xir_fte = sh_irda_xir_fte, +}; + +/*===================================== + * + * SIR MODE + * + *=====================================*/ +static int sh_irda_sir_fre(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + u16 data16; + u8 *data = (u8 *)&data16; + int len = sh_irda_get_rcv_length(self); + int i, j; + + if (len > IRDARAM_LEN) + len = IRDARAM_LEN; + + dev_dbg(dev, "frame recv length = %d\n", len); + + for (i = 0; i < len; i++) { + j = i % 2; + if (!j) + data16 = sh_irda_read(self, IRDARAM + i); + + async_unwrap_char(self->ndev, &self->ndev->stats, + &self->rx_buff, data[j]); + } + self->ndev->last_rx = jiffies; + + sh_irda_rcv_ctrl(self, 1); + + return 0; +} + +static int sh_irda_sir_trov(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + + dev_err(dev, "buffer ram over\n"); + sh_irda_rcv_ctrl(self, 1); + return 0; +} + +static int sh_irda_sir_tot(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + + dev_err(dev, "time over\n"); + sh_irda_set_baudrate(self, 9600); + sh_irda_rcv_ctrl(self, 1); + return 0; +} + +static int sh_irda_sir_fer(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + + dev_err(dev, "framing error\n"); + sh_irda_rcv_ctrl(self, 1); + return 0; +} + +static int sh_irda_sir_fte(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + + dev_dbg(dev, "frame transmit end\n"); + netif_wake_queue(self->ndev); + + return 0; +} + +static struct sh_irda_xir_func sh_irda_sir_func = { + .xir_fre = sh_irda_sir_fre, + .xir_trov = sh_irda_sir_trov, + .xir_9 = sh_irda_sir_tot, + .xir_8 = sh_irda_sir_fer, + .xir_fte = sh_irda_sir_fte, +}; + +static void sh_irda_set_mode(struct sh_irda_self *self, enum sh_irda_mode mode) +{ + struct device *dev = &self->ndev->dev; + struct sh_irda_xir_func *func; + const char *name; + u16 data; + + switch (mode) { + case SH_IRDA_SIR: + name = "SIR"; + data = TMD_SIR; + func = &sh_irda_sir_func; + break; + case SH_IRDA_MIR: + name = "MIR"; + data = TMD_MIR; + func = &sh_irda_mfir_func; + break; + case SH_IRDA_FIR: + name = "FIR"; + data = TMD_FIR; + func = &sh_irda_mfir_func; + break; + default: + name = "NONE"; + data = 0; + func = &sh_irda_xir_func; + break; + } + + self->mode = mode; + self->xir_func = func; + sh_irda_update_bits(self, IRTMR, TMD_MASK, data); + + dev_dbg(dev, "switch to %s mode", name); +} + +/************************************************************************ + + + irq function + + +************************************************************************/ +static void sh_irda_set_irq_mask(struct sh_irda_self *self) +{ + u16 tmr_hole; + u16 xir_reg; + + /* set all mask */ + sh_irda_update_bits(self, IRTMR, xIM_MASK, xIM_MASK); + sh_irda_update_bits(self, SIRIMR, xIR_MASK, xIR_MASK); + sh_irda_update_bits(self, MFIRIMR, xIR_MASK, xIR_MASK); + + /* clear irq */ + sh_irda_update_bits(self, SIRICR, xIR_MASK, xIR_MASK); + sh_irda_update_bits(self, MFIRICR, xIR_MASK, xIR_MASK); + + switch (self->mode) { + case SH_IRDA_SIR: + tmr_hole = SIM; + xir_reg = SIRIMR; + break; + case SH_IRDA_MIR: + case SH_IRDA_FIR: + tmr_hole = MIM; + xir_reg = MFIRIMR; + break; + default: + tmr_hole = 0; + xir_reg = 0; + break; + } + + /* open mask */ + if (xir_reg) { + sh_irda_update_bits(self, IRTMR, tmr_hole, 0); + sh_irda_update_bits(self, xir_reg, xIR_MASK, 0); + } +} + +static irqreturn_t sh_irda_irq(int irq, void *dev_id) +{ + struct sh_irda_self *self = dev_id; + struct sh_irda_xir_func *func = self->xir_func; + u16 isr = sh_irda_read(self, SIRISR); + + /* clear irq */ + sh_irda_write(self, SIRICR, isr); + + if (isr & FRE) + func->xir_fre(self); + if (isr & TROV) + func->xir_trov(self); + if (isr & xIR_9) + func->xir_9(self); + if (isr & xIR_8) + func->xir_8(self); + if (isr & FTE) + func->xir_fte(self); + + return IRQ_HANDLED; +} + +/************************************************************************ + + + CRC function + + +************************************************************************/ +static void sh_irda_crc_reset(struct sh_irda_self *self) +{ + sh_irda_write(self, CRCCTR, CRC_RST); +} + +static void sh_irda_crc_add(struct sh_irda_self *self, u16 data) +{ + sh_irda_write(self, CRCIR, data & CRC_IN_MASK); +} + +static u16 sh_irda_crc_cnt(struct sh_irda_self *self) +{ + return CRC_CT_MASK & sh_irda_read(self, CRCCTR); +} + +static u16 sh_irda_crc_out(struct sh_irda_self *self) +{ + return sh_irda_read(self, CRCOR); +} + +static int sh_irda_crc_init(struct sh_irda_self *self) +{ + struct device *dev = &self->ndev->dev; + int ret = -EIO; + u16 val; + + sh_irda_crc_reset(self); + + sh_irda_crc_add(self, 0xCC); + sh_irda_crc_add(self, 0xF5); + sh_irda_crc_add(self, 0xF1); + sh_irda_crc_add(self, 0xA7); + + val = sh_irda_crc_cnt(self); + if (4 != val) { + dev_err(dev, "CRC count error %x\n", val); + goto crc_init_out; + } + + val = sh_irda_crc_out(self); + if (0x51DF != val) { + dev_err(dev, "CRC result error%x\n", val); + goto crc_init_out; + } + + ret = 0; + +crc_init_out: + + sh_irda_crc_reset(self); + return ret; +} + +/************************************************************************ + + + iobuf function + + +************************************************************************/ +static void sh_irda_remove_iobuf(struct sh_irda_self *self) +{ + kfree(self->rx_buff.head); + + self->tx_buff.head = NULL; + self->tx_buff.data = NULL; + self->rx_buff.head = NULL; + self->rx_buff.data = NULL; +} + +static int sh_irda_init_iobuf(struct sh_irda_self *self, int rxsize, int txsize) +{ + if (self->rx_buff.head || + self->tx_buff.head) { + dev_err(&self->ndev->dev, "iobuff has already existed."); + return -EINVAL; + } + + /* rx_buff */ + self->rx_buff.head = kmalloc(rxsize, GFP_KERNEL); + if (!self->rx_buff.head) + return -ENOMEM; + + self->rx_buff.truesize = rxsize; + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->rx_buff.data = self->rx_buff.head; + + /* tx_buff */ + self->tx_buff.head = self->membase + IRDARAM; + self->tx_buff.truesize = IRDARAM_LEN; + + return 0; +} + +/************************************************************************ + + + net_device_ops function + + +************************************************************************/ +static int sh_irda_hard_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct sh_irda_self *self = netdev_priv(ndev); + struct device *dev = &self->ndev->dev; + int speed = irda_get_next_speed(skb); + int ret; + + dev_dbg(dev, "hard xmit\n"); + + netif_stop_queue(ndev); + sh_irda_rcv_ctrl(self, 0); + + ret = sh_irda_set_baudrate(self, speed); + if (ret < 0) + goto sh_irda_hard_xmit_end; + + self->tx_buff.len = 0; + if (skb->len) { + unsigned long flags; + + spin_lock_irqsave(&self->lock, flags); + self->tx_buff.len = async_wrap_skb(skb, + self->tx_buff.head, + self->tx_buff.truesize); + spin_unlock_irqrestore(&self->lock, flags); + + if (self->tx_buff.len > self->tx_buff.truesize) + self->tx_buff.len = self->tx_buff.truesize; + + sh_irda_write(self, IRTFLR, self->tx_buff.len); + sh_irda_write(self, IRTCTR, ARMOD | TE); + } else + goto sh_irda_hard_xmit_end; + + dev_kfree_skb(skb); + + return 0; + +sh_irda_hard_xmit_end: + sh_irda_set_baudrate(self, 9600); + netif_wake_queue(self->ndev); + sh_irda_rcv_ctrl(self, 1); + dev_kfree_skb(skb); + + return ret; + +} + +static int sh_irda_ioctl(struct net_device *ndev, struct ifreq *ifreq, int cmd) +{ + /* + * FIXME + * + * This function is needed for irda framework. + * But nothing to do now + */ + return 0; +} + +static struct net_device_stats *sh_irda_stats(struct net_device *ndev) +{ + struct sh_irda_self *self = netdev_priv(ndev); + + return &self->ndev->stats; +} + +static int sh_irda_open(struct net_device *ndev) +{ + struct sh_irda_self *self = netdev_priv(ndev); + int err; + + pm_runtime_get_sync(&self->pdev->dev); + err = sh_irda_crc_init(self); + if (err) + goto open_err; + + sh_irda_set_mode(self, SH_IRDA_SIR); + sh_irda_set_timeout(self, 2); + sh_irda_set_baudrate(self, 9600); + + self->irlap = irlap_open(ndev, &self->qos, DRIVER_NAME); + if (!self->irlap) { + err = -ENODEV; + goto open_err; + } + + netif_start_queue(ndev); + sh_irda_rcv_ctrl(self, 1); + sh_irda_set_irq_mask(self); + + dev_info(&ndev->dev, "opened\n"); + + return 0; + +open_err: + pm_runtime_put_sync(&self->pdev->dev); + + return err; +} + +static int sh_irda_stop(struct net_device *ndev) +{ + struct sh_irda_self *self = netdev_priv(ndev); + + /* Stop IrLAP */ + if (self->irlap) { + irlap_close(self->irlap); + self->irlap = NULL; + } + + netif_stop_queue(ndev); + pm_runtime_put_sync(&self->pdev->dev); + + dev_info(&ndev->dev, "stopped\n"); + + return 0; +} + +static const struct net_device_ops sh_irda_ndo = { + .ndo_open = sh_irda_open, + .ndo_stop = sh_irda_stop, + .ndo_start_xmit = sh_irda_hard_xmit, + .ndo_do_ioctl = sh_irda_ioctl, + .ndo_get_stats = sh_irda_stats, +}; + +/************************************************************************ + + + platform_driver function + + +************************************************************************/ +static int sh_irda_probe(struct platform_device *pdev) +{ + struct net_device *ndev; + struct sh_irda_self *self; + struct resource *res; + int irq; + int err = -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || irq < 0) { + dev_err(&pdev->dev, "Not enough platform resources.\n"); + goto exit; + } + + ndev = alloc_irdadev(sizeof(*self)); + if (!ndev) + goto exit; + + self = netdev_priv(ndev); + self->membase = ioremap_nocache(res->start, resource_size(res)); + if (!self->membase) { + err = -ENXIO; + dev_err(&pdev->dev, "Unable to ioremap.\n"); + goto err_mem_1; + } + + err = sh_irda_init_iobuf(self, IRDA_SKB_MAX_MTU, IRDA_SIR_MAX_FRAME); + if (err) + goto err_mem_2; + + self->pdev = pdev; + pm_runtime_enable(&pdev->dev); + + irda_init_max_qos_capabilies(&self->qos); + + ndev->netdev_ops = &sh_irda_ndo; + ndev->irq = irq; + + self->ndev = ndev; + self->qos.baud_rate.bits &= IR_9600; /* FIXME */ + self->qos.min_turn_time.bits = 1; /* 10 ms or more */ + spin_lock_init(&self->lock); + + irda_qos_bits_to_value(&self->qos); + + err = register_netdev(ndev); + if (err) + goto err_mem_4; + + platform_set_drvdata(pdev, ndev); + err = devm_request_irq(&pdev->dev, irq, sh_irda_irq, 0, "sh_irda", self); + if (err) { + dev_warn(&pdev->dev, "Unable to attach sh_irda interrupt\n"); + goto err_mem_4; + } + + dev_info(&pdev->dev, "SuperH IrDA probed\n"); + + goto exit; + +err_mem_4: + pm_runtime_disable(&pdev->dev); + sh_irda_remove_iobuf(self); +err_mem_2: + iounmap(self->membase); +err_mem_1: + free_netdev(ndev); +exit: + return err; +} + +static int sh_irda_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct sh_irda_self *self = netdev_priv(ndev); + + if (!self) + return 0; + + unregister_netdev(ndev); + pm_runtime_disable(&pdev->dev); + sh_irda_remove_iobuf(self); + iounmap(self->membase); + free_netdev(ndev); + + return 0; +} + +static int sh_irda_runtime_nop(struct device *dev) +{ + /* Runtime PM callback shared between ->runtime_suspend() + * and ->runtime_resume(). Simply returns success. + * + * This driver re-initializes all registers after + * pm_runtime_get_sync() anyway so there is no need + * to save and restore registers here. + */ + return 0; +} + +static const struct dev_pm_ops sh_irda_pm_ops = { + .runtime_suspend = sh_irda_runtime_nop, + .runtime_resume = sh_irda_runtime_nop, +}; + +static struct platform_driver sh_irda_driver = { + .probe = sh_irda_probe, + .remove = sh_irda_remove, + .driver = { + .name = DRIVER_NAME, + .pm = &sh_irda_pm_ops, + }, +}; + +module_platform_driver(sh_irda_driver); + +MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); +MODULE_DESCRIPTION("SuperH IrDA driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c new file mode 100644 index 00000000000..e3fe9a28613 --- /dev/null +++ b/drivers/net/irda/sh_sir.c @@ -0,0 +1,811 @@ +/* + * SuperH IrDA Driver + * + * Copyright (C) 2009 Renesas Solutions Corp. + * Kuninori Morimoto <morimoto.kuninori@renesas.com> + * + * Based on bfin_sir.c + * Copyright 2006-2009 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <net/irda/wrapper.h> +#include <net/irda/irda_device.h> +#include <asm/clock.h> + +#define DRIVER_NAME "sh_sir" + +#define RX_PHASE (1 << 0) +#define TX_PHASE (1 << 1) +#define TX_COMP_PHASE (1 << 2) /* tx complete */ +#define NONE_PHASE (1 << 31) + +#define IRIF_RINTCLR 0x0016 /* DMA rx interrupt source clear */ +#define IRIF_TINTCLR 0x0018 /* DMA tx interrupt source clear */ +#define IRIF_SIR0 0x0020 /* IrDA-SIR10 control */ +#define IRIF_SIR1 0x0022 /* IrDA-SIR10 baudrate error correction */ +#define IRIF_SIR2 0x0024 /* IrDA-SIR10 baudrate count */ +#define IRIF_SIR3 0x0026 /* IrDA-SIR10 status */ +#define IRIF_SIR_FRM 0x0028 /* Hardware frame processing set */ +#define IRIF_SIR_EOF 0x002A /* EOF value */ +#define IRIF_SIR_FLG 0x002C /* Flag clear */ +#define IRIF_UART_STS2 0x002E /* UART status 2 */ +#define IRIF_UART0 0x0030 /* UART control */ +#define IRIF_UART1 0x0032 /* UART status */ +#define IRIF_UART2 0x0034 /* UART mode */ +#define IRIF_UART3 0x0036 /* UART transmit data */ +#define IRIF_UART4 0x0038 /* UART receive data */ +#define IRIF_UART5 0x003A /* UART interrupt mask */ +#define IRIF_UART6 0x003C /* UART baud rate error correction */ +#define IRIF_UART7 0x003E /* UART baud rate count set */ +#define IRIF_CRC0 0x0040 /* CRC engine control */ +#define IRIF_CRC1 0x0042 /* CRC engine input data */ +#define IRIF_CRC2 0x0044 /* CRC engine calculation */ +#define IRIF_CRC3 0x0046 /* CRC engine output data 1 */ +#define IRIF_CRC4 0x0048 /* CRC engine output data 2 */ + +/* IRIF_SIR0 */ +#define IRTPW (1 << 1) /* transmit pulse width select */ +#define IRERRC (1 << 0) /* Clear receive pulse width error */ + +/* IRIF_SIR3 */ +#define IRERR (1 << 0) /* received pulse width Error */ + +/* IRIF_SIR_FRM */ +#define EOFD (1 << 9) /* EOF detection flag */ +#define FRER (1 << 8) /* Frame Error bit */ +#define FRP (1 << 0) /* Frame processing set */ + +/* IRIF_UART_STS2 */ +#define IRSME (1 << 6) /* Receive Sum Error flag */ +#define IROVE (1 << 5) /* Receive Overrun Error flag */ +#define IRFRE (1 << 4) /* Receive Framing Error flag */ +#define IRPRE (1 << 3) /* Receive Parity Error flag */ + +/* IRIF_UART0_*/ +#define TBEC (1 << 2) /* Transmit Data Clear */ +#define RIE (1 << 1) /* Receive Enable */ +#define TIE (1 << 0) /* Transmit Enable */ + +/* IRIF_UART1 */ +#define URSME (1 << 6) /* Receive Sum Error Flag */ +#define UROVE (1 << 5) /* Receive Overrun Error Flag */ +#define URFRE (1 << 4) /* Receive Framing Error Flag */ +#define URPRE (1 << 3) /* Receive Parity Error Flag */ +#define RBF (1 << 2) /* Receive Buffer Full Flag */ +#define TSBE (1 << 1) /* Transmit Shift Buffer Empty Flag */ +#define TBE (1 << 0) /* Transmit Buffer Empty flag */ +#define TBCOMP (TSBE | TBE) + +/* IRIF_UART5 */ +#define RSEIM (1 << 6) /* Receive Sum Error Flag IRQ Mask */ +#define RBFIM (1 << 2) /* Receive Buffer Full Flag IRQ Mask */ +#define TSBEIM (1 << 1) /* Transmit Shift Buffer Empty Flag IRQ Mask */ +#define TBEIM (1 << 0) /* Transmit Buffer Empty Flag IRQ Mask */ +#define RX_MASK (RSEIM | RBFIM) + +/* IRIF_CRC0 */ +#define CRC_RST (1 << 15) /* CRC Engine Reset */ +#define CRC_CT_MASK 0x0FFF + +/************************************************************************ + + + structure + + +************************************************************************/ +struct sh_sir_self { + void __iomem *membase; + unsigned int irq; + struct clk *clk; + + struct net_device *ndev; + + struct irlap_cb *irlap; + struct qos_info qos; + + iobuff_t tx_buff; + iobuff_t rx_buff; +}; + +/************************************************************************ + + + common function + + +************************************************************************/ +static void sh_sir_write(struct sh_sir_self *self, u32 offset, u16 data) +{ + iowrite16(data, self->membase + offset); +} + +static u16 sh_sir_read(struct sh_sir_self *self, u32 offset) +{ + return ioread16(self->membase + offset); +} + +static void sh_sir_update_bits(struct sh_sir_self *self, u32 offset, + u16 mask, u16 data) +{ + u16 old, new; + + old = sh_sir_read(self, offset); + new = (old & ~mask) | data; + if (old != new) + sh_sir_write(self, offset, new); +} + +/************************************************************************ + + + CRC function + + +************************************************************************/ +static void sh_sir_crc_reset(struct sh_sir_self *self) +{ + sh_sir_write(self, IRIF_CRC0, CRC_RST); +} + +static void sh_sir_crc_add(struct sh_sir_self *self, u8 data) +{ + sh_sir_write(self, IRIF_CRC1, (u16)data); +} + +static u16 sh_sir_crc_cnt(struct sh_sir_self *self) +{ + return CRC_CT_MASK & sh_sir_read(self, IRIF_CRC0); +} + +static u16 sh_sir_crc_out(struct sh_sir_self *self) +{ + return sh_sir_read(self, IRIF_CRC4); +} + +static int sh_sir_crc_init(struct sh_sir_self *self) +{ + struct device *dev = &self->ndev->dev; + int ret = -EIO; + u16 val; + + sh_sir_crc_reset(self); + + sh_sir_crc_add(self, 0xCC); + sh_sir_crc_add(self, 0xF5); + sh_sir_crc_add(self, 0xF1); + sh_sir_crc_add(self, 0xA7); + + val = sh_sir_crc_cnt(self); + if (4 != val) { + dev_err(dev, "CRC count error %x\n", val); + goto crc_init_out; + } + + val = sh_sir_crc_out(self); + if (0x51DF != val) { + dev_err(dev, "CRC result error%x\n", val); + goto crc_init_out; + } + + ret = 0; + +crc_init_out: + + sh_sir_crc_reset(self); + return ret; +} + +/************************************************************************ + + + baud rate functions + + +************************************************************************/ +#define SCLK_BASE 1843200 /* 1.8432MHz */ + +static u32 sh_sir_find_sclk(struct clk *irda_clk) +{ + struct cpufreq_frequency_table *freq_table = irda_clk->freq_table; + struct cpufreq_frequency_table *pos; + struct clk *pclk = clk_get(NULL, "peripheral_clk"); + u32 limit, min = 0xffffffff, tmp; + int index = 0; + + limit = clk_get_rate(pclk); + clk_put(pclk); + + /* IrDA can not set over peripheral_clk */ + cpufreq_for_each_valid_entry(pos, freq_table) { + u32 freq = pos->frequency; + + /* IrDA should not over peripheral_clk */ + if (freq > limit) + continue; + + tmp = freq % SCLK_BASE; + if (tmp < min) { + min = tmp; + index = pos - freq_table; + } + } + + return freq_table[index].frequency; +} + +#define ERR_ROUNDING(a) ((a + 5000) / 10000) +static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate) +{ + struct clk *clk; + struct device *dev = &self->ndev->dev; + u32 rate; + u16 uabca, uabc; + u16 irbca, irbc; + u32 min, rerr, tmp; + int i; + + /* Baud Rate Error Correction x 10000 */ + u32 rate_err_array[] = { + 0, 625, 1250, 1875, + 2500, 3125, 3750, 4375, + 5000, 5625, 6250, 6875, + 7500, 8125, 8750, 9375, + }; + + /* + * FIXME + * + * it support 9600 only now + */ + switch (baudrate) { + case 9600: + break; + default: + dev_err(dev, "un-supported baudrate %d\n", baudrate); + return -EIO; + } + + clk = clk_get(NULL, "irda_clk"); + if (IS_ERR(clk)) { + dev_err(dev, "can not get irda_clk\n"); + return -EIO; + } + + clk_set_rate(clk, sh_sir_find_sclk(clk)); + rate = clk_get_rate(clk); + clk_put(clk); + + dev_dbg(dev, "selected sclk = %d\n", rate); + + /* + * CALCULATION + * + * 1843200 = system rate / (irbca + (irbc + 1)) + */ + + irbc = rate / SCLK_BASE; + + tmp = rate - (SCLK_BASE * irbc); + tmp *= 10000; + + rerr = tmp / SCLK_BASE; + + min = 0xffffffff; + irbca = 0; + for (i = 0; i < ARRAY_SIZE(rate_err_array); i++) { + tmp = abs(rate_err_array[i] - rerr); + if (min > tmp) { + min = tmp; + irbca = i; + } + } + + tmp = rate / (irbc + ERR_ROUNDING(rate_err_array[irbca])); + if ((SCLK_BASE / 100) < abs(tmp - SCLK_BASE)) + dev_warn(dev, "IrDA freq error margin over %d\n", tmp); + + dev_dbg(dev, "target = %d, result = %d, infrared = %d.%d\n", + SCLK_BASE, tmp, irbc, rate_err_array[irbca]); + + irbca = (irbca & 0xF) << 4; + irbc = (irbc - 1) & 0xF; + + if (!irbc) { + dev_err(dev, "sh_sir can not set 0 in IRIF_SIR2\n"); + return -EIO; + } + + sh_sir_write(self, IRIF_SIR0, IRTPW | IRERRC); + sh_sir_write(self, IRIF_SIR1, irbca); + sh_sir_write(self, IRIF_SIR2, irbc); + + /* + * CALCULATION + * + * BaudRate[bps] = system rate / (uabca + (uabc + 1) x 16) + */ + + uabc = rate / baudrate; + uabc = (uabc / 16) - 1; + uabc = (uabc + 1) * 16; + + tmp = rate - (uabc * baudrate); + tmp *= 10000; + + rerr = tmp / baudrate; + + min = 0xffffffff; + uabca = 0; + for (i = 0; i < ARRAY_SIZE(rate_err_array); i++) { + tmp = abs(rate_err_array[i] - rerr); + if (min > tmp) { + min = tmp; + uabca = i; + } + } + + tmp = rate / (uabc + ERR_ROUNDING(rate_err_array[uabca])); + if ((baudrate / 100) < abs(tmp - baudrate)) + dev_warn(dev, "UART freq error margin over %d\n", tmp); + + dev_dbg(dev, "target = %d, result = %d, uart = %d.%d\n", + baudrate, tmp, + uabc, rate_err_array[uabca]); + + uabca = (uabca & 0xF) << 4; + uabc = (uabc / 16) - 1; + + sh_sir_write(self, IRIF_UART6, uabca); + sh_sir_write(self, IRIF_UART7, uabc); + + return 0; +} + +/************************************************************************ + + + iobuf function + + +************************************************************************/ +static int __sh_sir_init_iobuf(iobuff_t *io, int size) +{ + io->head = kmalloc(size, GFP_KERNEL); + if (!io->head) + return -ENOMEM; + + io->truesize = size; + io->in_frame = FALSE; + io->state = OUTSIDE_FRAME; + io->data = io->head; + + return 0; +} + +static void sh_sir_remove_iobuf(struct sh_sir_self *self) +{ + kfree(self->rx_buff.head); + kfree(self->tx_buff.head); + + self->rx_buff.head = NULL; + self->tx_buff.head = NULL; +} + +static int sh_sir_init_iobuf(struct sh_sir_self *self, int rxsize, int txsize) +{ + int err = -ENOMEM; + + if (self->rx_buff.head || + self->tx_buff.head) { + dev_err(&self->ndev->dev, "iobuff has already existed."); + return err; + } + + err = __sh_sir_init_iobuf(&self->rx_buff, rxsize); + if (err) + goto iobuf_err; + + err = __sh_sir_init_iobuf(&self->tx_buff, txsize); + +iobuf_err: + if (err) + sh_sir_remove_iobuf(self); + + return err; +} + +/************************************************************************ + + + status function + + +************************************************************************/ +static void sh_sir_clear_all_err(struct sh_sir_self *self) +{ + /* Clear error flag for receive pulse width */ + sh_sir_update_bits(self, IRIF_SIR0, IRERRC, IRERRC); + + /* Clear frame / EOF error flag */ + sh_sir_write(self, IRIF_SIR_FLG, 0xffff); + + /* Clear all status error */ + sh_sir_write(self, IRIF_UART_STS2, 0); +} + +static void sh_sir_set_phase(struct sh_sir_self *self, int phase) +{ + u16 uart5 = 0; + u16 uart0 = 0; + + switch (phase) { + case TX_PHASE: + uart5 = TBEIM; + uart0 = TBEC | TIE; + break; + case TX_COMP_PHASE: + uart5 = TSBEIM; + uart0 = TIE; + break; + case RX_PHASE: + uart5 = RX_MASK; + uart0 = RIE; + break; + default: + break; + } + + sh_sir_write(self, IRIF_UART5, uart5); + sh_sir_write(self, IRIF_UART0, uart0); +} + +static int sh_sir_is_which_phase(struct sh_sir_self *self) +{ + u16 val = sh_sir_read(self, IRIF_UART5); + + if (val & TBEIM) + return TX_PHASE; + + if (val & TSBEIM) + return TX_COMP_PHASE; + + if (val & RX_MASK) + return RX_PHASE; + + return NONE_PHASE; +} + +static void sh_sir_tx(struct sh_sir_self *self, int phase) +{ + switch (phase) { + case TX_PHASE: + if (0 >= self->tx_buff.len) { + sh_sir_set_phase(self, TX_COMP_PHASE); + } else { + sh_sir_write(self, IRIF_UART3, self->tx_buff.data[0]); + self->tx_buff.len--; + self->tx_buff.data++; + } + break; + case TX_COMP_PHASE: + sh_sir_set_phase(self, RX_PHASE); + netif_wake_queue(self->ndev); + break; + default: + dev_err(&self->ndev->dev, "should not happen\n"); + break; + } +} + +static int sh_sir_read_data(struct sh_sir_self *self) +{ + u16 val = 0; + int timeout = 1024; + + while (timeout--) { + val = sh_sir_read(self, IRIF_UART1); + + /* data get */ + if (val & RBF) { + if (val & (URSME | UROVE | URFRE | URPRE)) + break; + + return (int)sh_sir_read(self, IRIF_UART4); + } + + udelay(1); + } + + dev_err(&self->ndev->dev, "UART1 %04x : STATUS %04x\n", + val, sh_sir_read(self, IRIF_UART_STS2)); + + /* read data register for clear error */ + sh_sir_read(self, IRIF_UART4); + + return -1; +} + +static void sh_sir_rx(struct sh_sir_self *self) +{ + int timeout = 1024; + int data; + + while (timeout--) { + data = sh_sir_read_data(self); + if (data < 0) + break; + + async_unwrap_char(self->ndev, &self->ndev->stats, + &self->rx_buff, (u8)data); + self->ndev->last_rx = jiffies; + + if (EOFD & sh_sir_read(self, IRIF_SIR_FRM)) + continue; + + break; + } +} + +static irqreturn_t sh_sir_irq(int irq, void *dev_id) +{ + struct sh_sir_self *self = dev_id; + struct device *dev = &self->ndev->dev; + int phase = sh_sir_is_which_phase(self); + + switch (phase) { + case TX_COMP_PHASE: + case TX_PHASE: + sh_sir_tx(self, phase); + break; + case RX_PHASE: + if (sh_sir_read(self, IRIF_SIR3)) + dev_err(dev, "rcv pulse width error occurred\n"); + + sh_sir_rx(self); + sh_sir_clear_all_err(self); + break; + default: + dev_err(dev, "unknown interrupt\n"); + } + + return IRQ_HANDLED; +} + +/************************************************************************ + + + net_device_ops function + + +************************************************************************/ +static int sh_sir_hard_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct sh_sir_self *self = netdev_priv(ndev); + int speed = irda_get_next_speed(skb); + + if ((0 < speed) && + (9600 != speed)) { + dev_err(&ndev->dev, "support 9600 only (%d)\n", speed); + return -EIO; + } + + netif_stop_queue(ndev); + + self->tx_buff.data = self->tx_buff.head; + self->tx_buff.len = 0; + if (skb->len) + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); + + sh_sir_set_phase(self, TX_PHASE); + dev_kfree_skb(skb); + + return 0; +} + +static int sh_sir_ioctl(struct net_device *ndev, struct ifreq *ifreq, int cmd) +{ + /* + * FIXME + * + * This function is needed for irda framework. + * But nothing to do now + */ + return 0; +} + +static struct net_device_stats *sh_sir_stats(struct net_device *ndev) +{ + struct sh_sir_self *self = netdev_priv(ndev); + + return &self->ndev->stats; +} + +static int sh_sir_open(struct net_device *ndev) +{ + struct sh_sir_self *self = netdev_priv(ndev); + int err; + + clk_enable(self->clk); + err = sh_sir_crc_init(self); + if (err) + goto open_err; + + sh_sir_set_baudrate(self, 9600); + + self->irlap = irlap_open(ndev, &self->qos, DRIVER_NAME); + if (!self->irlap) { + err = -ENODEV; + goto open_err; + } + + /* + * Now enable the interrupt then start the queue + */ + sh_sir_update_bits(self, IRIF_SIR_FRM, FRP, FRP); + sh_sir_read(self, IRIF_UART1); /* flag clear */ + sh_sir_read(self, IRIF_UART4); /* flag clear */ + sh_sir_set_phase(self, RX_PHASE); + + netif_start_queue(ndev); + + dev_info(&self->ndev->dev, "opened\n"); + + return 0; + +open_err: + clk_disable(self->clk); + + return err; +} + +static int sh_sir_stop(struct net_device *ndev) +{ + struct sh_sir_self *self = netdev_priv(ndev); + + /* Stop IrLAP */ + if (self->irlap) { + irlap_close(self->irlap); + self->irlap = NULL; + } + + netif_stop_queue(ndev); + + dev_info(&ndev->dev, "stopped\n"); + + return 0; +} + +static const struct net_device_ops sh_sir_ndo = { + .ndo_open = sh_sir_open, + .ndo_stop = sh_sir_stop, + .ndo_start_xmit = sh_sir_hard_xmit, + .ndo_do_ioctl = sh_sir_ioctl, + .ndo_get_stats = sh_sir_stats, +}; + +/************************************************************************ + + + platform_driver function + + +************************************************************************/ +static int sh_sir_probe(struct platform_device *pdev) +{ + struct net_device *ndev; + struct sh_sir_self *self; + struct resource *res; + char clk_name[8]; + int irq; + int err = -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || irq < 0) { + dev_err(&pdev->dev, "Not enough platform resources.\n"); + goto exit; + } + + ndev = alloc_irdadev(sizeof(*self)); + if (!ndev) + goto exit; + + self = netdev_priv(ndev); + self->membase = ioremap_nocache(res->start, resource_size(res)); + if (!self->membase) { + err = -ENXIO; + dev_err(&pdev->dev, "Unable to ioremap.\n"); + goto err_mem_1; + } + + err = sh_sir_init_iobuf(self, IRDA_SKB_MAX_MTU, IRDA_SIR_MAX_FRAME); + if (err) + goto err_mem_2; + + snprintf(clk_name, sizeof(clk_name), "irda%d", pdev->id); + self->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(self->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + err = -ENODEV; + goto err_mem_3; + } + + irda_init_max_qos_capabilies(&self->qos); + + ndev->netdev_ops = &sh_sir_ndo; + ndev->irq = irq; + + self->ndev = ndev; + self->qos.baud_rate.bits &= IR_9600; /* FIXME */ + self->qos.min_turn_time.bits = 1; /* 10 ms or more */ + + irda_qos_bits_to_value(&self->qos); + + err = register_netdev(ndev); + if (err) + goto err_mem_4; + + platform_set_drvdata(pdev, ndev); + err = devm_request_irq(&pdev->dev, irq, sh_sir_irq, 0, "sh_sir", self); + if (err) { + dev_warn(&pdev->dev, "Unable to attach sh_sir interrupt\n"); + goto err_mem_4; + } + + dev_info(&pdev->dev, "SuperH IrDA probed\n"); + + goto exit; + +err_mem_4: + clk_put(self->clk); +err_mem_3: + sh_sir_remove_iobuf(self); +err_mem_2: + iounmap(self->membase); +err_mem_1: + free_netdev(ndev); +exit: + return err; +} + +static int sh_sir_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct sh_sir_self *self = netdev_priv(ndev); + + if (!self) + return 0; + + unregister_netdev(ndev); + clk_put(self->clk); + sh_sir_remove_iobuf(self); + iounmap(self->membase); + free_netdev(ndev); + + return 0; +} + +static struct platform_driver sh_sir_driver = { + .probe = sh_sir_probe, + .remove = sh_sir_remove, + .driver = { + .name = DRIVER_NAME, + }, +}; + +module_platform_driver(sh_sir_driver); + +MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); +MODULE_DESCRIPTION("SuperH IrDA driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h index 2a57bc67ce3..f50b9c1c063 100644 --- a/drivers/net/irda/sir-dev.h +++ b/drivers/net/irda/sir-dev.h @@ -102,28 +102,29 @@ struct sir_driver { /* exported */ -extern int irda_register_dongle(struct dongle_driver *new); -extern int irda_unregister_dongle(struct dongle_driver *drv); +int irda_register_dongle(struct dongle_driver *new); +int irda_unregister_dongle(struct dongle_driver *drv); -extern struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name); -extern int sirdev_put_instance(struct sir_dev *self); +struct sir_dev *sirdev_get_instance(const struct sir_driver *drv, + const char *name); +int sirdev_put_instance(struct sir_dev *self); -extern int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type); -extern void sirdev_write_complete(struct sir_dev *dev); -extern int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count); +int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type); +void sirdev_write_complete(struct sir_dev *dev); +int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count); /* low level helpers for SIR device/dongle setup */ -extern int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len); -extern int sirdev_raw_read(struct sir_dev *dev, char *buf, int len); -extern int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts); +int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len); +int sirdev_raw_read(struct sir_dev *dev, char *buf, int len); +int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts); /* not exported */ -extern int sirdev_get_dongle(struct sir_dev *self, IRDA_DONGLE type); -extern int sirdev_put_dongle(struct sir_dev *self); +int sirdev_get_dongle(struct sir_dev *self, IRDA_DONGLE type); +int sirdev_put_dongle(struct sir_dev *self); -extern void sirdev_enable_rx(struct sir_dev *dev); -extern int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param); +void sirdev_enable_rx(struct sir_dev *dev); +int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param); /* inline helpers */ @@ -160,7 +161,6 @@ static inline int sirdev_schedule_mode(struct sir_dev *dev, int mode) struct sir_dev { struct net_device *netdev; - struct net_device_stats stats; struct irlap_cb *irlap; diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 17b0c3ab620..43e9ab4f4d7 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -11,10 +11,11 @@ * ********************************************************************/ +#include <linux/hardirq.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/delay.h> #include <net/irda/irda.h> @@ -81,7 +82,7 @@ static int sirdev_tx_complete_fsm(struct sir_dev *dev) return 0; default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + IRDA_ERROR("%s - undefined state\n", __func__); return -EINVAL; } fsm->substate = next_state; @@ -108,11 +109,11 @@ static void sirdev_config_fsm(struct work_struct *work) int ret = -1; unsigned delay; - IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); + IRDA_DEBUG(2, "%s(), <%ld>\n", __func__, jiffies); do { IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n", - __FUNCTION__, fsm->state, fsm->substate); + __func__, fsm->state, fsm->substate); next_state = fsm->state; delay = 0; @@ -221,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) break; case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->reset) { + if (dev->dongle_drv->set_speed) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; @@ -250,12 +251,12 @@ static void sirdev_config_fsm(struct work_struct *work) break; default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + IRDA_ERROR("%s - undefined state\n", __func__); fsm->result = -EINVAL; /* fall thru */ case SIRDEV_STATE_ERROR: - IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result); + IRDA_ERROR("%s - error: %d\n", __func__, fsm->result); #if 0 /* don't enable this before we have netdev->tx_timeout to recover */ netif_stop_queue(dev->netdev); @@ -285,11 +286,12 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par { struct sir_fsm *fsm = &dev->fsm; - IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); + IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __func__, + initial_state, param); if (down_trylock(&fsm->sem)) { if (in_interrupt() || in_atomic() || irqs_disabled()) { - IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), state machine busy!\n", __func__); return -EWOULDBLOCK; } else down(&fsm->sem); @@ -297,7 +299,7 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par if (fsm->state == SIRDEV_STATE_DEAD) { /* race with sirdev_close should never happen */ - IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__); + IRDA_ERROR("%s(), instance staled!\n", __func__); up(&fsm->sem); return -ESTALE; /* or better EPIPE? */ } @@ -335,14 +337,14 @@ static int sirdev_is_receiving(struct sir_dev *dev) if (!atomic_read(&dev->enable_rx)) return 0; - return (dev->rx_buff.state != OUTSIDE_FRAME); + return dev->rx_buff.state != OUTSIDE_FRAME; } int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type) { int err; - IRDA_DEBUG(3, "%s : requesting dongle %d.\n", __FUNCTION__, type); + IRDA_DEBUG(3, "%s : requesting dongle %d.\n", __func__, type); err = sirdev_schedule_dongle_open(dev, type); if (unlikely(err)) @@ -377,7 +379,7 @@ int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len) ret = dev->drv->do_write(dev, dev->tx_buff.data, dev->tx_buff.len); if (ret > 0) { - IRDA_DEBUG(3, "%s(), raw-tx started\n", __FUNCTION__); + IRDA_DEBUG(3, "%s(), raw-tx started\n", __func__); dev->tx_buff.data += ret; dev->tx_buff.len -= ret; @@ -415,7 +417,7 @@ EXPORT_SYMBOL(sirdev_raw_read); int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts) { int ret = -ENXIO; - if (dev->drv->set_dtr_rts != 0) + if (dev->drv->set_dtr_rts) ret = dev->drv->set_dtr_rts(dev, dtr, rts); return ret; } @@ -438,7 +440,7 @@ void sirdev_write_complete(struct sir_dev *dev) spin_lock_irqsave(&dev->tx_lock, flags); IRDA_DEBUG(3, "%s() - dev->tx_buff.len = %d\n", - __FUNCTION__, dev->tx_buff.len); + __func__, dev->tx_buff.len); if (likely(dev->tx_buff.len > 0)) { /* Write data left in transmit buffer */ @@ -451,12 +453,12 @@ void sirdev_write_complete(struct sir_dev *dev) else if (unlikely(actual<0)) { /* could be dropped later when we have tx_timeout to recover */ IRDA_ERROR("%s: drv->do_write failed (%d)\n", - __FUNCTION__, actual); + __func__, actual); if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; dev_kfree_skb_any(skb); - dev->stats.tx_errors++; - dev->stats.tx_dropped++; + dev->netdev->stats.tx_errors++; + dev->netdev->stats.tx_dropped++; } dev->tx_buff.len = 0; } @@ -472,7 +474,7 @@ void sirdev_write_complete(struct sir_dev *dev) * restarted when the irda-thread has completed the request. */ - IRDA_DEBUG(3, "%s(), raw-tx done\n", __FUNCTION__); + IRDA_DEBUG(3, "%s(), raw-tx done\n", __func__); dev->raw_tx = 0; goto done; /* no post-frame handling in raw mode */ } @@ -489,24 +491,24 @@ void sirdev_write_complete(struct sir_dev *dev) * re-activated. */ - IRDA_DEBUG(5, "%s(), finished with frame!\n", __FUNCTION__); + IRDA_DEBUG(5, "%s(), finished with frame!\n", __func__); if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + dev->netdev->stats.tx_packets++; + dev->netdev->stats.tx_bytes += skb->len; dev_kfree_skb_any(skb); } if (unlikely(dev->new_speed > 0)) { - IRDA_DEBUG(5, "%s(), Changing speed!\n", __FUNCTION__); + IRDA_DEBUG(5, "%s(), Changing speed!\n", __func__); err = sirdev_schedule_speed(dev, dev->new_speed); if (unlikely(err)) { /* should never happen * forget the speed change and hope the stack recovers */ IRDA_ERROR("%s - schedule speed change failed: %d\n", - __FUNCTION__, err); + __func__, err); netif_wake_queue(dev->netdev); } /* else: success @@ -533,13 +535,13 @@ EXPORT_SYMBOL(sirdev_write_complete); int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) { if (!dev || !dev->netdev) { - IRDA_WARNING("%s(), not ready yet!\n", __FUNCTION__); + IRDA_WARNING("%s(), not ready yet!\n", __func__); return -1; } if (!dev->irlap) { IRDA_WARNING("%s - too early: %p / %zd!\n", - __FUNCTION__, cp, count); + __func__, cp, count); return -1; } @@ -548,8 +550,8 @@ int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) * just update stats and set media busy */ irda_device_set_media_busy(dev->netdev, TRUE); - dev->stats.rx_dropped++; - IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __FUNCTION__, count); + dev->netdev->stats.rx_dropped++; + IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count); return 0; } @@ -557,7 +559,7 @@ int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) if (likely(atomic_read(&dev->enable_rx))) { while (count--) /* Unwrap and destuff one byte */ - async_unwrap_char(dev->netdev, &dev->stats, + async_unwrap_char(dev->netdev, &dev->netdev->stats, &dev->rx_buff, *cp++); } else { while (count--) { @@ -582,26 +584,20 @@ EXPORT_SYMBOL(sirdev_receive); /* callbacks from network layer */ -static struct net_device_stats *sirdev_get_stats(struct net_device *ndev) -{ - struct sir_dev *dev = ndev->priv; - - return (dev) ? &dev->stats : NULL; -} - -static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) +static netdev_tx_t sirdev_hard_xmit(struct sk_buff *skb, + struct net_device *ndev) { - struct sir_dev *dev = ndev->priv; + struct sir_dev *dev = netdev_priv(ndev); unsigned long flags; int actual = 0; int err; s32 speed; - IRDA_ASSERT(dev != NULL, return 0;); + IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;); netif_stop_queue(ndev); - IRDA_DEBUG(3, "%s(), skb->len = %d\n", __FUNCTION__, skb->len); + IRDA_DEBUG(3, "%s(), skb->len = %d\n", __func__, skb->len); speed = irda_get_next_speed(skb); if ((speed != dev->speed) && (speed != -1)) { @@ -614,7 +610,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) * stopped so the network layer will retry after the * fsm completes and wakes the queue. */ - return 1; + return NETDEV_TX_BUSY; } else if (unlikely(err)) { /* other fatal error - forget the speed change and @@ -628,7 +624,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) */ dev_kfree_skb_any(skb); - return 0; + return NETDEV_TX_OK; } else dev->new_speed = speed; } @@ -638,7 +634,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) /* Check problems */ if(spin_is_locked(&dev->tx_lock)) { - IRDA_DEBUG(3, "%s(), write not completed\n", __FUNCTION__); + IRDA_DEBUG(3, "%s(), write not completed\n", __func__); } /* serialize with write completion */ @@ -654,28 +650,27 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) */ atomic_set(&dev->enable_rx, 0); if (unlikely(sirdev_is_receiving(dev))) - dev->stats.collisions++; + dev->netdev->stats.collisions++; actual = dev->drv->do_write(dev, dev->tx_buff.data, dev->tx_buff.len); if (likely(actual > 0)) { dev->tx_skb = skb; - ndev->trans_start = jiffies; dev->tx_buff.data += actual; dev->tx_buff.len -= actual; } else if (unlikely(actual < 0)) { /* could be dropped later when we have tx_timeout to recover */ IRDA_ERROR("%s: drv->do_write failed (%d)\n", - __FUNCTION__, actual); + __func__, actual); dev_kfree_skb_any(skb); - dev->stats.tx_errors++; - dev->stats.tx_dropped++; + dev->netdev->stats.tx_errors++; + dev->netdev->stats.tx_dropped++; netif_wake_queue(ndev); } spin_unlock_irqrestore(&dev->tx_lock, flags); - return 0; + return NETDEV_TX_OK; } /* called from network layer with rtnl hold */ @@ -683,12 +678,12 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) static int sirdev_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { struct if_irda_req *irq = (struct if_irda_req *) rq; - struct sir_dev *dev = ndev->priv; + struct sir_dev *dev = netdev_priv(ndev); int ret = 0; IRDA_ASSERT(dev != NULL, return -1;); - IRDA_DEBUG(3, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, ndev->name, cmd); + IRDA_DEBUG(3, "%s(), %s, (cmd=0x%X)\n", __func__, ndev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ @@ -760,7 +755,8 @@ static int sirdev_alloc_buffers(struct sir_dev *dev) dev->rx_buff.truesize = IRDA_SKB_MAX_MTU; /* Bootstrap ZeroCopy Rx */ - dev->rx_buff.skb = __dev_alloc_skb(dev->rx_buff.truesize, GFP_KERNEL); + dev->rx_buff.skb = __netdev_alloc_skb(dev->netdev, dev->rx_buff.truesize, + GFP_KERNEL); if (dev->rx_buff.skb == NULL) return -ENOMEM; skb_reserve(dev->rx_buff.skb, 1); @@ -786,8 +782,7 @@ static int sirdev_alloc_buffers(struct sir_dev *dev) static void sirdev_free_buffers(struct sir_dev *dev) { - if (dev->rx_buff.skb) - kfree_skb(dev->rx_buff.skb); + kfree_skb(dev->rx_buff.skb); kfree(dev->tx_buff.head); dev->rx_buff.head = dev->tx_buff.head = NULL; dev->rx_buff.skb = NULL; @@ -795,7 +790,7 @@ static void sirdev_free_buffers(struct sir_dev *dev) static int sirdev_open(struct net_device *ndev) { - struct sir_dev *dev = ndev->priv; + struct sir_dev *dev = netdev_priv(ndev); const struct sir_driver *drv = dev->drv; if (!drv) @@ -805,7 +800,7 @@ static int sirdev_open(struct net_device *ndev) if (!try_module_get(drv->owner)) return -ESTALE; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); if (sirdev_alloc_buffers(dev)) goto errout_dec; @@ -823,7 +818,7 @@ static int sirdev_open(struct net_device *ndev) netif_wake_queue(ndev); - IRDA_DEBUG(2, "%s - done, speed = %d\n", __FUNCTION__, dev->speed); + IRDA_DEBUG(2, "%s - done, speed = %d\n", __func__, dev->speed); return 0; @@ -840,10 +835,10 @@ errout_dec: static int sirdev_close(struct net_device *ndev) { - struct sir_dev *dev = ndev->priv; + struct sir_dev *dev = netdev_priv(ndev); const struct sir_driver *drv; -// IRDA_DEBUG(0, "%s\n", __FUNCTION__); +// IRDA_DEBUG(0, "%s\n", __func__); netif_stop_queue(ndev); @@ -872,6 +867,12 @@ out: return 0; } +static const struct net_device_ops sirdev_ops = { + .ndo_start_xmit = sirdev_hard_xmit, + .ndo_open = sirdev_open, + .ndo_stop = sirdev_close, + .ndo_do_ioctl = sirdev_ioctl, +}; /* ----------------------------------------------------------------------------- */ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name) @@ -879,7 +880,7 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n struct net_device *ndev; struct sir_dev *dev; - IRDA_DEBUG(0, "%s - %s\n", __FUNCTION__, name); + IRDA_DEBUG(0, "%s - %s\n", __func__, name); /* instead of adding tests to protect against drv->do_write==NULL * at several places we refuse to create a sir_dev instance for @@ -893,10 +894,10 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n */ ndev = alloc_irdadev(sizeof(*dev)); if (ndev == NULL) { - IRDA_ERROR("%s - Can't allocate memory for IrDA control block!\n", __FUNCTION__); + IRDA_ERROR("%s - Can't allocate memory for IrDA control block!\n", __func__); goto out; } - dev = ndev->priv; + dev = netdev_priv(ndev); irda_init_max_qos_capabilies(&dev->qos); dev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; @@ -909,22 +910,16 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n dev->tx_skb = NULL; spin_lock_init(&dev->tx_lock); - init_MUTEX(&dev->fsm.sem); + sema_init(&dev->fsm.sem, 1); dev->drv = drv; dev->netdev = ndev; - SET_MODULE_OWNER(ndev); - /* Override the network functions we need to use */ - ndev->hard_start_xmit = sirdev_hard_xmit; - ndev->open = sirdev_open; - ndev->stop = sirdev_close; - ndev->get_stats = sirdev_get_stats; - ndev->do_ioctl = sirdev_ioctl; + ndev->netdev_ops = &sirdev_ops; if (register_netdev(ndev)) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__); + IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); goto out_freenetdev; } @@ -941,7 +936,7 @@ int sirdev_put_instance(struct sir_dev *dev) { int err = 0; - IRDA_DEBUG(0, "%s\n", __FUNCTION__); + IRDA_DEBUG(0, "%s\n", __func__); atomic_set(&dev->enable_rx, 0); @@ -951,7 +946,7 @@ int sirdev_put_instance(struct sir_dev *dev) if (dev->dongle_drv) err = sirdev_schedule_dongle_close(dev); if (err) - IRDA_ERROR("%s - error %d\n", __FUNCTION__, err); + IRDA_ERROR("%s - error %d\n", __func__, err); sirdev_close(dev->netdev); diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c index d7e32d9554f..cfbabb63f5c 100644 --- a/drivers/net/irda/sir_dongle.c +++ b/drivers/net/irda/sir_dongle.c @@ -13,8 +13,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/kmod.h> #include <linux/mutex.h> @@ -37,7 +35,7 @@ int irda_register_dongle(struct dongle_driver *new) struct dongle_driver *drv; IRDA_DEBUG(0, "%s : registering dongle \"%s\" (%d).\n", - __FUNCTION__, new->driver_name, new->type); + __func__, new->driver_name, new->type); mutex_lock(&dongle_list_lock); list_for_each(entry, &dongle_list) { @@ -68,9 +66,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) const struct dongle_driver *drv = NULL; int err = -EINVAL; -#ifdef CONFIG_KMOD request_module("irda-dongle-%d", type); -#endif if (dev->dongle_drv != NULL) return -EBUSY; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 31c623381ea..282120430f1 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -1,8 +1,6 @@ /********************************************************************* - * $Id: smsc-ircc2.c,v 1.19.2.5 2002/10/27 11:34:26 dip Exp $ * * Description: Driver for the SMC Infrared Communications Controller - * Status: Experimental. * Author: Daniele Peri (peri@csai.unipa.it) * Created at: * Modified at: @@ -36,9 +34,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ @@ -49,13 +45,14 @@ #include <linux/netdevice.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/rtnetlink.h> #include <linux/serial_reg.h> #include <linux/dma-mapping.h> #include <linux/pnp.h> #include <linux/platform_device.h> +#include <linux/gfp.h> #include <asm/io.h> #include <asm/dma.h> @@ -79,11 +76,17 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>"); MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); MODULE_LICENSE("GPL"); -static int ircc_dma = 255; +static bool smsc_nopnp = true; +module_param_named(nopnp, smsc_nopnp, bool, 0); +MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings, defaults to true"); + +#define DMA_INVAL 255 +static int ircc_dma = DMA_INVAL; module_param(ircc_dma, int, 0); MODULE_PARM_DESC(ircc_dma, "DMA channel"); -static int ircc_irq = 255; +#define IRQ_INVAL 255 +static int ircc_irq = IRQ_INVAL; module_param(ircc_irq, int, 0); MODULE_PARM_DESC(ircc_irq, "IRQ line"); @@ -110,7 +113,7 @@ struct smsc_ircc_subsystem_configuration { unsigned short vendor; /* PCI vendor ID */ unsigned short device; /* PCI vendor ID */ unsigned short subvendor; /* PCI subsystem vendor ID */ - unsigned short subdevice; /* PCI sybsystem device ID */ + unsigned short subdevice; /* PCI subsystem device ID */ unsigned short sir_io; /* I/O port for SIR */ unsigned short fir_io; /* I/O port for FIR */ unsigned char fir_irq; /* FIR IRQ */ @@ -145,7 +148,6 @@ struct smsc_chip_address { /* Private data for each instance */ struct smsc_ircc_cb { struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ chipio_t io; /* IrDA controller information */ @@ -190,8 +192,10 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self); static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self); static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self); static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self); -static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev); -static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev); +static netdev_tx_t smsc_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev); +static netdev_tx_t smsc_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev); static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs); static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self); static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed); @@ -210,7 +214,6 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cm #if SMSC_IRCC2_C_NET_TIMEOUT static void smsc_ircc_timeout(struct net_device *dev); #endif -static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev); static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self); static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self); static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed); @@ -315,6 +318,7 @@ static struct smsc_chip __initdata lpc_chips_flat[] = { /* Base address 0x2E or 0x4E */ { "47N227", KEY55_1|FIR|SERx4, 0x5a, 0x00 }, + { "47N227", KEY55_1|FIR|SERx4, 0x7a, 0x00 }, { "47N267", KEY55_1|FIR|SERx4, 0x5e, 0x00 }, { NULL } }; @@ -359,7 +363,6 @@ static inline void register_bank(int iobase, int bank) iobase + IRCC_MASTER); } -#ifdef CONFIG_PNP /* PNP hotplug support */ static const struct pnp_device_id smsc_ircc_pnp_table[] = { { .id = "SMCf010", .driver_data = 0 }, @@ -367,8 +370,39 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = { { } }; MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); -#endif +static int pnp_driver_registered; + +#ifdef CONFIG_PNP +static int smsc_ircc_pnp_probe(struct pnp_dev *dev, + const struct pnp_device_id *dev_id) +{ + unsigned int firbase, sirbase; + u8 dma, irq; + + if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && + pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0))) + return -EINVAL; + + sirbase = pnp_port_start(dev, 0); + firbase = pnp_port_start(dev, 1); + dma = pnp_dma(dev, 0); + irq = pnp_irq(dev, 0); + + if (smsc_ircc_open(firbase, sirbase, dma, irq)) + return -ENODEV; + + return 0; +} + +static struct pnp_driver smsc_ircc_pnp_driver = { + .name = "smsc-ircc2", + .id_table = smsc_ircc_pnp_table, + .probe = smsc_ircc_pnp_probe, +}; +#else /* CONFIG_PNP */ +static struct pnp_driver smsc_ircc_pnp_driver; +#endif /******************************************************************************* * @@ -378,23 +412,9 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); * *******************************************************************************/ -/* - * Function smsc_ircc_init () - * - * Initialize chip. Just try to find out how many chips we are dealing with - * and where they are - */ -static int __init smsc_ircc_init(void) +static int __init smsc_ircc_legacy_probe(void) { - int ret; - - IRDA_DEBUG(1, "%s\n", __FUNCTION__); - - ret = platform_driver_register(&smsc_ircc_driver); - if (ret) { - IRDA_ERROR("%s, Can't register driver!\n", driver_name); - return ret; - } + int ret = 0; #ifdef CONFIG_PCI if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { @@ -403,8 +423,6 @@ static int __init smsc_ircc_init(void) } #endif - dev_count = 0; - if (ircc_fir > 0 && ircc_sir > 0) { IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); @@ -427,26 +445,81 @@ static int __init smsc_ircc_init(void) if (smsc_ircc_look_for_chips() > 0) ret = 0; } + return ret; +} + +/* + * Function smsc_ircc_init () + * + * Initialize chip. Just try to find out how many chips we are dealing with + * and where they are + */ +static int __init smsc_ircc_init(void) +{ + int ret; + + IRDA_DEBUG(1, "%s\n", __func__); + + ret = platform_driver_register(&smsc_ircc_driver); + if (ret) { + IRDA_ERROR("%s, Can't register driver!\n", driver_name); + return ret; + } + + dev_count = 0; + + if (smsc_nopnp || !pnp_platform_devices || + ircc_cfg || ircc_fir || ircc_sir || + ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) { + ret = smsc_ircc_legacy_probe(); + } else { + if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0) + pnp_driver_registered = 1; + } - if (ret) + if (ret) { + if (pnp_driver_registered) + pnp_unregister_driver(&smsc_ircc_pnp_driver); platform_driver_unregister(&smsc_ircc_driver); + } return ret; } +static netdev_tx_t smsc_ircc_net_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct smsc_ircc_cb *self = netdev_priv(dev); + + if (self->io.speed > 115200) + return smsc_ircc_hard_xmit_fir(skb, dev); + else + return smsc_ircc_hard_xmit_sir(skb, dev); +} + +static const struct net_device_ops smsc_ircc_netdev_ops = { + .ndo_open = smsc_ircc_net_open, + .ndo_stop = smsc_ircc_net_close, + .ndo_do_ioctl = smsc_ircc_net_ioctl, + .ndo_start_xmit = smsc_ircc_net_xmit, +#if SMSC_IRCC2_C_NET_TIMEOUT + .ndo_tx_timeout = smsc_ircc_timeout, +#endif +}; + /* * Function smsc_ircc_open (firbase, sirbase, dma, irq) * * Try to open driver instance * */ -static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) +static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) { struct smsc_ircc_cb *self; struct net_device *dev; int err; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); err = smsc_ircc_present(fir_base, sir_base); if (err) @@ -454,7 +527,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u err = -ENOMEM; if (dev_count >= ARRAY_SIZE(dev_self)) { - IRDA_WARNING("%s(), too many devices!\n", __FUNCTION__); + IRDA_WARNING("%s(), too many devices!\n", __func__); goto err_out1; } @@ -463,21 +536,14 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u */ dev = alloc_irdadev(sizeof(struct smsc_ircc_cb)); if (!dev) { - IRDA_WARNING("%s() can't allocate net device\n", __FUNCTION__); + IRDA_WARNING("%s() can't allocate net device\n", __func__); goto err_out1; } - SET_MODULE_OWNER(dev); - - dev->hard_start_xmit = smsc_ircc_hard_xmit_sir; #if SMSC_IRCC2_C_NET_TIMEOUT - dev->tx_timeout = smsc_ircc_timeout; dev->watchdog_timeo = HZ * 2; /* Allow enough time for speed change */ #endif - dev->open = smsc_ircc_net_open; - dev->stop = smsc_ircc_net_close; - dev->do_ioctl = smsc_ircc_net_ioctl; - dev->get_stats = smsc_ircc_net_get_stats; + dev->netdev_ops = &smsc_ircc_netdev_ops; self = netdev_priv(dev); self->netdev = dev; @@ -494,25 +560,16 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE; self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); - if (self->rx_buff.head == NULL) { - IRDA_ERROR("%s, Can't allocate memory for receive buffer!\n", - driver_name); + dma_zalloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); + if (self->rx_buff.head == NULL) goto err_out2; - } self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); - if (self->tx_buff.head == NULL) { - IRDA_ERROR("%s, Can't allocate memory for transmit buffer!\n", - driver_name); + dma_zalloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); + if (self->tx_buff.head == NULL) goto err_out3; - } - - memset(self->rx_buff.head, 0, self->rx_buff.truesize); - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; @@ -581,14 +638,14 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) if (!request_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT, driver_name)) { IRDA_WARNING("%s: can't get fir_base of 0x%03x\n", - __FUNCTION__, fir_base); + __func__, fir_base); goto out1; } if (!request_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT, driver_name)) { IRDA_WARNING("%s: can't get sir_base of 0x%03x\n", - __FUNCTION__, sir_base); + __func__, sir_base); goto out2; } @@ -604,7 +661,7 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { IRDA_WARNING("%s(), addr 0x%04x - no device found!\n", - __FUNCTION__, fir_base); + __func__, fir_base); goto out3; } IRDA_MESSAGE("SMsC IrDA Controller found\n IrCC version %d.%d, " @@ -645,7 +702,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; - if (irq < 255) { + if (irq != IRQ_INVAL) { if (irq != chip_irq) IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", driver_name, chip_irq, irq); @@ -653,7 +710,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, } else self->io.irq = chip_irq; - if (dma < 255) { + if (dma != DMA_INVAL) { if (dma != chip_dma) IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", driver_name, chip_dma, dma); @@ -741,7 +798,7 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ @@ -782,13 +839,6 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd return ret; } -static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev) -{ - struct smsc_ircc_cb *self = netdev_priv(dev); - - return &self->stats; -} - #if SMSC_IRCC2_C_NET_TIMEOUT /* * Function smsc_ircc_timeout (struct net_device *dev) @@ -807,7 +857,7 @@ static void smsc_ircc_timeout(struct net_device *dev) spin_lock_irqsave(&self->lock, flags); smsc_ircc_sir_start(self); smsc_ircc_change_speed(self, self->io.speed); - dev->trans_start = jiffies; + dev->trans_start = jiffies; /* prevent tx timeout */ netif_wake_queue(dev); spin_unlock_irqrestore(&self->lock, flags); } @@ -820,18 +870,19 @@ static void smsc_ircc_timeout(struct net_device *dev) * waits until the next transmit interrupt, and continues until the * frame is transmitted. */ -int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t smsc_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev) { struct smsc_ircc_cb *self; unsigned long flags; s32 speed; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); - IRDA_ASSERT(dev != NULL, return 0;); + IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;); self = netdev_priv(dev); - IRDA_ASSERT(self != NULL, return 0;); + IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;); netif_stop_queue(dev); @@ -856,7 +907,7 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) smsc_ircc_change_speed(self, speed); spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } self->new_speed = speed; } @@ -868,7 +919,7 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, self->io.sir_base + UART_IER); @@ -877,7 +928,7 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } /* @@ -901,21 +952,21 @@ static void smsc_ircc_set_fir_speed(struct smsc_ircc_cb *self, u32 speed) ir_mode = IRCC_CFGA_IRDA_HDLC; ctrl = IRCC_CRC; fast = 0; - IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __func__); break; case 1152000: ir_mode = IRCC_CFGA_IRDA_HDLC; ctrl = IRCC_1152 | IRCC_CRC; fast = IRCC_LCR_A_FAST | IRCC_LCR_A_GP_DATA; IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", - __FUNCTION__); + __func__); break; case 4000000: ir_mode = IRCC_CFGA_IRDA_4PPM; ctrl = IRCC_CRC; fast = IRCC_LCR_A_FAST; IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", - __FUNCTION__); + __func__); break; } #if 0 @@ -943,7 +994,7 @@ static void smsc_ircc_fir_start(struct smsc_ircc_cb *self) struct net_device *dev; int fir_base; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(self != NULL, return;); dev = self->netdev; @@ -953,9 +1004,6 @@ static void smsc_ircc_fir_start(struct smsc_ircc_cb *self) /* Reset everything */ - /* Install FIR transmit handler */ - dev->hard_start_xmit = smsc_ircc_hard_xmit_fir; - /* Clear FIFO */ outb(inb(fir_base + IRCC_LCR_A) | IRCC_LCR_A_FIFO_RESET, fir_base + IRCC_LCR_A); @@ -991,7 +1039,7 @@ static void smsc_ircc_fir_stop(struct smsc_ircc_cb *self) { int fir_base; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(self != NULL, return;); @@ -1015,7 +1063,7 @@ static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed) struct net_device *dev; int last_speed_was_sir; - IRDA_DEBUG(0, "%s() changing speed to: %d\n", __FUNCTION__, speed); + IRDA_DEBUG(0, "%s() changing speed to: %d\n", __func__, speed); IRDA_ASSERT(self != NULL, return;); dev = self->netdev; @@ -1076,14 +1124,14 @@ static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed) * Set speed of IrDA port to specified baudrate * */ -void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed) +static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed) { int iobase; int fcr; /* FIFO control reg */ int lcr; /* Line control reg */ int divisor; - IRDA_DEBUG(0, "%s(), Setting speed to: %d\n", __FUNCTION__, speed); + IRDA_DEBUG(0, "%s(), Setting speed to: %d\n", __func__, speed); IRDA_ASSERT(self != NULL, return;); iobase = self->io.sir_base; @@ -1118,7 +1166,7 @@ void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed) /* Turn on interrups */ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); - IRDA_DEBUG(2, "%s() speed changed to: %d\n", __FUNCTION__, speed); + IRDA_DEBUG(2, "%s() speed changed to: %d\n", __func__, speed); } @@ -1128,16 +1176,17 @@ void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed) * Transmit the frame! * */ -static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t smsc_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev) { struct smsc_ircc_cb *self; unsigned long flags; s32 speed; int mtt; - IRDA_ASSERT(dev != NULL, return 0;); + IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;); self = netdev_priv(dev); - IRDA_ASSERT(self != NULL, return 0;); + IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;); netif_stop_queue(dev); @@ -1155,13 +1204,13 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) smsc_ircc_change_speed(self, speed); spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } self->new_speed = speed; } - memcpy(self->tx_buff.head, skb->data, skb->len); + skb_copy_from_linear_data(skb, self->tx_buff.head, skb->len); self->tx_buff.len = skb->len; self->tx_buff.data = self->tx_buff.head; @@ -1187,7 +1236,7 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } /* @@ -1201,7 +1250,7 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs) int iobase = self->io.fir_base; u8 ctrl; - IRDA_DEBUG(3, "%s\n", __FUNCTION__); + IRDA_DEBUG(3, "%s\n", __func__); #if 1 /* Disable Rx */ register_bank(iobase, 0); @@ -1255,7 +1304,7 @@ static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self) { int iobase = self->io.fir_base; - IRDA_DEBUG(3, "%s\n", __FUNCTION__); + IRDA_DEBUG(3, "%s\n", __func__); #if 0 /* Disable Tx */ register_bank(iobase, 0); @@ -1268,16 +1317,16 @@ static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self) /* Check for underrun! */ register_bank(iobase, 0); if (inb(iobase + IRCC_LSR) & IRCC_LSR_UNDERRUN) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Reset error condition */ register_bank(iobase, 0); outb(IRCC_MASTER_ERROR_RESET, iobase + IRCC_MASTER); outb(0x00, iobase + IRCC_MASTER); } else { - self->stats.tx_packets++; - self->stats.tx_bytes += self->tx_buff.len; + self->netdev->stats.tx_packets++; + self->netdev->stats.tx_bytes += self->tx_buff.len; } /* Check if it's time to change the speed */ @@ -1359,7 +1408,7 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) register_bank(iobase, 0); - IRDA_DEBUG(3, "%s\n", __FUNCTION__); + IRDA_DEBUG(3, "%s\n", __func__); #if 0 /* Disable Rx */ register_bank(iobase, 0); @@ -1370,22 +1419,22 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) lsr= inb(iobase + IRCC_LSR); msgcnt = inb(iobase + IRCC_LCR_B) & 0x08; - IRDA_DEBUG(2, "%s: dma count = %d\n", __FUNCTION__, + IRDA_DEBUG(2, "%s: dma count = %d\n", __func__, get_dma_residue(self->io.dma)); len = self->rx_buff.truesize - get_dma_residue(self->io.dma); /* Look for errors */ if (lsr & (IRCC_LSR_FRAME_ERROR | IRCC_LSR_CRC_ERROR | IRCC_LSR_SIZE_ERROR)) { - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; if (lsr & IRCC_LSR_FRAME_ERROR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (lsr & IRCC_LSR_CRC_ERROR) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; if (lsr & IRCC_LSR_SIZE_ERROR) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (lsr & (IRCC_LSR_UNDERRUN | IRCC_LSR_OVERRUN)) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; return; } @@ -1393,26 +1442,26 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) len -= self->io.speed < 4000000 ? 2 : 4; if (len < 2 || len > 2050) { - IRDA_WARNING("%s(), bogus len=%d\n", __FUNCTION__, len); + IRDA_WARNING("%s(), bogus len=%d\n", __func__, len); return; } - IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __FUNCTION__, msgcnt, len); + IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __func__, msgcnt, len); skb = dev_alloc_skb(len + 1); if (!skb) { IRDA_WARNING("%s(), memory squeeze, dropping frame.\n", - __FUNCTION__); + __func__); return; } /* Make sure IP header gets aligned */ skb_reserve(skb, 1); memcpy(skb_put(skb, len), self->rx_buff.data, len); - self->stats.rx_packets++; - self->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); } @@ -1437,12 +1486,12 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, inb(iobase + UART_RX)); /* Make sure we don't stay here to long */ if (boguscount++ > 32) { - IRDA_DEBUG(2, "%s(), breaking!\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), breaking!\n", __func__); break; } } while (inb(iobase + UART_LSR) & UART_LSR_DR); @@ -1455,22 +1504,13 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t smsc_ircc_interrupt(int dummy, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - struct smsc_ircc_cb *self; + struct net_device *dev = dev_id; + struct smsc_ircc_cb *self = netdev_priv(dev); int iobase, iir, lcra, lsr; irqreturn_t ret = IRQ_NONE; - if (dev == NULL) { - printk(KERN_WARNING "%s: irq %d for unknown device.\n", - driver_name, irq); - goto irq_ret; - } - - self = netdev_priv(dev); - IRDA_ASSERT(self != NULL, return IRQ_NONE;); - /* Serialise the interrupt handler in various CPUs, stop Tx path */ spin_lock(&self->lock); @@ -1493,7 +1533,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) lcra = inb(iobase + IRCC_LCR_A); lsr = inb(iobase + IRCC_LSR); - IRDA_DEBUG(2, "%s(), iir = 0x%02x\n", __FUNCTION__, iir); + IRDA_DEBUG(2, "%s(), iir = 0x%02x\n", __func__, iir); if (iir & IRCC_IIR_EOM) { if (self->io.direction == IO_RECV) @@ -1505,7 +1545,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) } if (iir & IRCC_IIR_ACTIVE_FRAME) { - /*printk(KERN_WARNING "%s(): Active Frame\n", __FUNCTION__);*/ + /*printk(KERN_WARNING "%s(): Active Frame\n", __func__);*/ } /* Enable interrupts again */ @@ -1515,7 +1555,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) irq_ret_unlock: spin_unlock(&self->lock); - irq_ret: + return ret; } @@ -1531,7 +1571,7 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) int iobase; int iir, lsr; - /* Already locked comming here in smsc_ircc_interrupt() */ + /* Already locked coming here in smsc_ircc_interrupt() */ /*spin_lock(&self->lock);*/ iobase = self->io.sir_base; @@ -1544,11 +1584,11 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) lsr = inb(iobase + UART_LSR); IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", - __FUNCTION__, iir, lsr, iobase); + __func__, iir, lsr, iobase); switch (iir) { case UART_IIR_RLSI: - IRDA_DEBUG(2, "%s(), RLSI\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), RLSI\n", __func__); break; case UART_IIR_RDI: /* Receive interrupt */ @@ -1561,7 +1601,7 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) break; default: IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", - __FUNCTION__, iir); + __func__, iir); break; } @@ -1588,11 +1628,11 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self) int status = FALSE; /* int iobase; */ - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(self != NULL, return FALSE;); - IRDA_DEBUG(0, "%s: dma count = %d\n", __FUNCTION__, + IRDA_DEBUG(0, "%s: dma count = %d\n", __func__, get_dma_residue(self->io.dma)); status = (self->rx_buff.state != OUTSIDE_FRAME); @@ -1609,7 +1649,7 @@ static int smsc_ircc_request_irq(struct smsc_ircc_cb *self) self->netdev->name, self->netdev); if (error) IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n", - __FUNCTION__, self->io.irq, error); + __func__, self->io.irq, error); return error; } @@ -1653,21 +1693,21 @@ static int smsc_ircc_net_open(struct net_device *dev) struct smsc_ircc_cb *self; char hwname[16]; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); if (self->io.suspended) { - IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), device is suspended\n", __func__); return -EAGAIN; } if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, (void *) dev)) { IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", - __FUNCTION__, self->io.irq); + __func__, self->io.irq); return -EAGAIN; } @@ -1691,7 +1731,7 @@ static int smsc_ircc_net_open(struct net_device *dev) smsc_ircc_net_close(dev); IRDA_WARNING("%s(), unable to allocate DMA=%d\n", - __FUNCTION__, self->io.dma); + __func__, self->io.dma); return -EAGAIN; } @@ -1710,7 +1750,7 @@ static int smsc_ircc_net_close(struct net_device *dev) { struct smsc_ircc_cb *self; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); self = netdev_priv(dev); @@ -1793,7 +1833,7 @@ static int smsc_ircc_resume(struct platform_device *dev) */ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) { - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); IRDA_ASSERT(self != NULL, return -1;); @@ -1805,12 +1845,12 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) smsc_ircc_stop_interrupts(self); /* Release the PORTS that this driver is using */ - IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, + IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); - IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, + IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __func__, self->io.sir_base); release_region(self->io.sir_base, self->io.sir_ext); @@ -1832,13 +1872,16 @@ static void __exit smsc_ircc_cleanup(void) { int i; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); for (i = 0; i < 2; i++) { if (dev_self[i]) smsc_ircc_close(dev_self[i]); } + if (pnp_driver_registered) + pnp_unregister_driver(&smsc_ircc_pnp_driver); + platform_driver_unregister(&smsc_ircc_driver); } @@ -1848,17 +1891,16 @@ static void __exit smsc_ircc_cleanup(void) * This function *must* be called with spinlock held, because it may * be called from the irq handler (via smsc_ircc_change_speed()). - Jean II */ -void smsc_ircc_sir_start(struct smsc_ircc_cb *self) +static void smsc_ircc_sir_start(struct smsc_ircc_cb *self) { struct net_device *dev; int fir_base, sir_base; - IRDA_DEBUG(3, "%s\n", __FUNCTION__); + IRDA_DEBUG(3, "%s\n", __func__); IRDA_ASSERT(self != NULL, return;); dev = self->netdev; IRDA_ASSERT(dev != NULL, return;); - dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir; fir_base = self->io.fir_base; sir_base = self->io.sir_base; @@ -1880,7 +1922,7 @@ void smsc_ircc_sir_start(struct smsc_ircc_cb *self) /* Turn on interrups */ outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, sir_base + UART_IER); - IRDA_DEBUG(3, "%s() - exit\n", __FUNCTION__); + IRDA_DEBUG(3, "%s() - exit\n", __func__); outb(0x00, fir_base + IRCC_MASTER); } @@ -1890,7 +1932,7 @@ void smsc_ircc_sir_stop(struct smsc_ircc_cb *self) { int iobase; - IRDA_DEBUG(3, "%s\n", __FUNCTION__); + IRDA_DEBUG(3, "%s\n", __func__); iobase = self->io.sir_base; /* Reset UART */ @@ -1916,7 +1958,7 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) IRDA_ASSERT(self != NULL, return;); - IRDA_DEBUG(4, "%s\n", __FUNCTION__); + IRDA_DEBUG(4, "%s\n", __func__); iobase = self->io.sir_base; @@ -1938,7 +1980,7 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) */ if (self->new_speed) { IRDA_DEBUG(5, "%s(), Changing speed to %d.\n", - __FUNCTION__, self->new_speed); + __func__, self->new_speed); smsc_ircc_sir_wait_hw_transmitter_finish(self); smsc_ircc_change_speed(self, self->new_speed); self->new_speed = 0; @@ -1946,7 +1988,7 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) /* Tell network layer that we want more frames */ netif_wake_queue(self->netdev); } - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->io.speed <= 115200) { /* @@ -1977,7 +2019,7 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) /* Tx FIFO should be empty! */ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE)) { - IRDA_WARNING("%s(), failed, fifo not empty!\n", __FUNCTION__); + IRDA_WARNING("%s(), failed, fifo not empty!\n", __func__); return 0; } @@ -1998,7 +2040,7 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) */ static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self) { - return (self->rx_buff.state != OUTSIDE_FRAME); + return self->rx_buff.state != OUTSIDE_FRAME; } @@ -2076,8 +2118,8 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) while (count-- > 0 && !(inb(iobase + UART_LSR) & UART_LSR_TEMT)) udelay(1); - if (count == 0) - IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__); + if (count < 0) + IRDA_DEBUG(0, "%s(): stuck transmitter\n", __func__); } @@ -2099,7 +2141,7 @@ static int __init smsc_ircc_look_for_chips(void) while (address->cfg_base) { cfg_base = address->cfg_base; - /*printk(KERN_WARNING "%s(): probing: 0x%02x for: 0x%02x\n", __FUNCTION__, cfg_base, address->type);*/ + /*printk(KERN_WARNING "%s(): probing: 0x%02x for: 0x%02x\n", __func__, cfg_base, address->type);*/ if (address->type & SMSCSIO_TYPE_FDC) { type = "FDC"; @@ -2138,7 +2180,7 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor u8 mode, dma, irq; int ret = -ENODEV; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); if (smsc_ircc_probe(cfgbase, SMSCSIOFLAT_DEVICEID_REG, chips, type) == NULL) return ret; @@ -2146,10 +2188,10 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor outb(SMSCSIOFLAT_UARTMODE0C_REG, cfgbase); mode = inb(cfgbase + 1); - /*printk(KERN_WARNING "%s(): mode: 0x%02x\n", __FUNCTION__, mode);*/ + /*printk(KERN_WARNING "%s(): mode: 0x%02x\n", __func__, mode);*/ if (!(mode & SMSCSIOFLAT_UART2MODE_VAL_IRDA)) - IRDA_WARNING("%s(): IrDA not enabled\n", __FUNCTION__); + IRDA_WARNING("%s(): IrDA not enabled\n", __func__); outb(SMSCSIOFLAT_UART2BASEADDR_REG, cfgbase); sirbase = inb(cfgbase + 1) << 2; @@ -2166,7 +2208,7 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor outb(SMSCSIOFLAT_UARTIRQSELECT_REG, cfgbase); irq = inb(cfgbase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; - IRDA_MESSAGE("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", __FUNCTION__, firbase, sirbase, dma, irq, mode); + IRDA_MESSAGE("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", __func__, firbase, sirbase, dma, irq, mode); if (firbase && smsc_ircc_open(firbase, sirbase, dma, irq) == 0) ret = 0; @@ -2188,7 +2230,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho unsigned short fir_io, sir_io; int ret = -ENODEV; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); if (smsc_ircc_probe(cfg_base, 0x20, chips, type) == NULL) return ret; @@ -2222,7 +2264,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho static int __init smsc_access(unsigned short cfg_base, unsigned char reg) { - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); outb(reg, cfg_base); return inb(cfg_base) != reg ? -1 : 0; @@ -2232,7 +2274,7 @@ static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, { u8 devid, xdevid, rev; - IRDA_DEBUG(1, "%s\n", __FUNCTION__); + IRDA_DEBUG(1, "%s\n", __func__); /* Leave configuration */ @@ -2307,7 +2349,7 @@ static int __init smsc_superio_fdc(unsigned short cfg_base) if (!request_region(cfg_base, 2, driver_name)) { IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", - __FUNCTION__, cfg_base); + __func__, cfg_base); } else { if (!smsc_superio_flat(fdc_chips_flat, cfg_base, "FDC") || !smsc_superio_paged(fdc_chips_paged, cfg_base, "FDC")) @@ -2325,7 +2367,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) if (!request_region(cfg_base, 2, driver_name)) { IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", - __FUNCTION__, cfg_base); + __func__, cfg_base); } else { if (!smsc_superio_flat(lpc_chips_flat, cfg_base, "LPC") || !smsc_superio_paged(lpc_chips_paged, cfg_base, "LPC")) @@ -2351,8 +2393,6 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) * addresses making a subsystem device table necessary. */ #ifdef CONFIG_PCI -#define PCIID_VENDOR_INTEL 0x8086 -#define PCIID_VENDOR_ALI 0x10b9 static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = { /* * Subsystems needing entries: @@ -2362,7 +2402,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini */ { /* Guessed entry */ - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x08bc, @@ -2375,7 +2415,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nx5000 family", }, { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x088c, @@ -2389,7 +2429,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nc8000 family", }, { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x0890, @@ -2402,7 +2442,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nc6000 family", }, { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x0e11, .subdevice = 0x0860, @@ -2417,7 +2457,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ - .vendor = PCIID_VENDOR_INTEL, + .vendor = PCI_VENDOR_ID_INTEL, .device = 0x24c0, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2430,7 +2470,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge", }, { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ + .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801CAM ISA bridge */ .device = 0x248c, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2444,7 +2484,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* 82801DBM (ICH4-M) LPC Interface Bridge */ - .vendor = PCIID_VENDOR_INTEL, + .vendor = PCI_VENDOR_ID_INTEL, .device = 0x24cc, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2458,7 +2498,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ - .vendor = PCIID_VENDOR_ALI, + .vendor = PCI_VENDOR_ID_AL, .device = 0x1533, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2769,7 +2809,6 @@ static void __init preconfigure_ali_port(struct pci_dev *dev, tmpbyte |= mask; pci_write_config_byte(dev, reg, tmpbyte); IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); - return; } static int __init preconfigure_through_ali(struct pci_dev *dev, @@ -2796,9 +2835,7 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, unsigned short ss_device = 0x0000; int ret = 0; - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); - - while (dev != NULL) { + for_each_pci_dev(dev) { struct smsc_ircc_subsystem_configuration *conf; /* @@ -2835,9 +2872,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, tmpconf.fir_io = ircc_fir; if (ircc_sir != 0) tmpconf.sir_io = ircc_sir; - if (ircc_dma != 0xff) + if (ircc_dma != DMA_INVAL) tmpconf.fir_dma = ircc_dma; - if (ircc_irq != 0xff) + if (ircc_irq != IRQ_INVAL) tmpconf.fir_irq = ircc_irq; IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); @@ -2847,7 +2884,6 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, ret = -ENODEV; } } - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); } return ret; @@ -2886,7 +2922,7 @@ static void smsc_ircc_set_transceiver_smsc_ircc_atc(int fir_base, u32 speed) /* empty */; if (val) - IRDA_WARNING("%s(): ATC: 0x%02x\n", __FUNCTION__, + IRDA_WARNING("%s(): ATC: 0x%02x\n", __func__, inb(fir_base + IRCC_ATC)); } diff --git a/drivers/net/irda/smsc-ircc2.h b/drivers/net/irda/smsc-ircc2.h index 0c36286d87f..4829fa22cb2 100644 --- a/drivers/net/irda/smsc-ircc2.h +++ b/drivers/net/irda/smsc-ircc2.h @@ -1,5 +1,4 @@ /********************************************************************* - * $Id: smsc-ircc2.h,v 1.12.2.1 2002/10/27 10:52:37 dip Exp $ * * Description: Definitions for the SMC IrCC chipset * Status: Experimental. @@ -26,9 +25,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index c14a74634fd..dd1bd1060ec 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -41,7 +41,6 @@ #include <linux/kernel.h> #include <linux/types.h> -#include <linux/init.h> #include <linux/time.h> #include <linux/skbuff.h> #include <linux/netdevice.h> @@ -52,14 +51,13 @@ #include <linux/kthread.h> #include <linux/freezer.h> #include <net/irda/irda.h> -#include <net/irda/irlap.h> #include <net/irda/irda_device.h> #include <net/irda/wrapper.h> #include <net/irda/crc.h> #include <asm/byteorder.h> #include <asm/unaligned.h> -MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); +MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200"); MODULE_LICENSE("GPL"); @@ -143,9 +141,6 @@ enum StirCtrl2Mask { }; enum StirFifoCtlMask { - FIFOCTL_EOF = 0x80, - FIFOCTL_UNDER = 0x40, - FIFOCTL_OVER = 0x20, FIFOCTL_DIR = 0x10, FIFOCTL_CLR = 0x08, FIFOCTL_EMPTY = 0x04, @@ -168,7 +163,7 @@ struct stir_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ + struct qos_info qos; unsigned speed; /* Current speed */ @@ -223,7 +218,7 @@ static inline int read_reg(struct stir_cb *stir, __u16 reg, static inline int isfir(u32 speed) { - return (speed == 4000000); + return speed == 4000000; } /* @@ -327,16 +322,16 @@ static void fir_eof(struct stir_cb *stir) pr_debug("%s: short frame len %d\n", stir->netdev->name, len); - ++stir->stats.rx_errors; - ++stir->stats.rx_length_errors; + ++stir->netdev->stats.rx_errors; + ++stir->netdev->stats.rx_length_errors; return; } fcs = ~(crc32_le(~0, rx_buff->data, len)); - if (fcs != le32_to_cpu(get_unaligned((u32 *)(rx_buff->data+len)))) { + if (fcs != get_unaligned_le32(rx_buff->data + len)) { pr_debug("crc error calc 0x%x len %d\n", fcs, len); - stir->stats.rx_errors++; - stir->stats.rx_crc_errors++; + stir->netdev->stats.rx_errors++; + stir->netdev->stats.rx_crc_errors++; return; } @@ -344,16 +339,16 @@ static void fir_eof(struct stir_cb *stir) if (len < IRDA_RX_COPY_THRESHOLD) { nskb = dev_alloc_skb(len + 1); if (unlikely(!nskb)) { - ++stir->stats.rx_dropped; + ++stir->netdev->stats.rx_dropped; return; } skb_reserve(nskb, 1); skb = nskb; - memcpy(nskb->data, rx_buff->data, len); + skb_copy_to_linear_data(nskb, rx_buff->data, len); } else { nskb = dev_alloc_skb(rx_buff->truesize); if (unlikely(!nskb)) { - ++stir->stats.rx_dropped; + ++stir->netdev->stats.rx_dropped; return; } skb_reserve(nskb, 1); @@ -364,14 +359,14 @@ static void fir_eof(struct stir_cb *stir) skb_put(skb, len); - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); skb->dev = stir->netdev; netif_rx(skb); - stir->stats.rx_packets++; - stir->stats.rx_bytes += len; + stir->netdev->stats.rx_packets++; + stir->netdev->stats.rx_bytes += len; rx_buff->data = rx_buff->head; rx_buff->len = 0; @@ -441,7 +436,7 @@ static void stir_fir_chars(struct stir_cb *stir, if (unlikely(rx_buff->len >= rx_buff->truesize)) { pr_debug("%s: fir frame exceeds %d\n", stir->netdev->name, rx_buff->truesize); - ++stir->stats.rx_over_errors; + ++stir->netdev->stats.rx_over_errors; goto error_recovery; } @@ -449,10 +444,10 @@ static void stir_fir_chars(struct stir_cb *stir, continue; frame_error: - ++stir->stats.rx_frame_errors; + ++stir->netdev->stats.rx_frame_errors; error_recovery: - ++stir->stats.rx_errors; + ++stir->netdev->stats.rx_errors; rx_buff->state = OUTSIDE_FRAME; rx_buff->in_frame = FALSE; } @@ -465,7 +460,7 @@ static void stir_sir_chars(struct stir_cb *stir, int i; for (i = 0; i < len; i++) - async_unwrap_char(stir->netdev, &stir->stats, + async_unwrap_char(stir->netdev, &stir->netdev->stats, &stir->rx_buff, bytes[i]); } @@ -510,7 +505,7 @@ static int change_speed(struct stir_cb *stir, unsigned speed) goto found; } - warn("%s: invalid speed %d", stir->netdev->name, speed); + dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed); return -EINVAL; found: @@ -564,7 +559,8 @@ static int change_speed(struct stir_cb *stir, unsigned speed) /* * Called from net/core when new frame is available. */ -static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev) +static netdev_tx_t stir_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) { struct stir_cb *stir = netdev_priv(netdev); @@ -582,7 +578,7 @@ static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev) dev_kfree_skb(skb); } - return 0; + return NETDEV_TX_OK; } /* @@ -595,14 +591,15 @@ static int fifo_txwait(struct stir_cb *stir, int space) { int err; unsigned long count, status; + unsigned long prev_count = 0x1fff; /* Read FIFO status and count */ - for(;;) { + for (;; prev_count = count) { err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, FIFO_REGS_SIZE); if (unlikely(err != FIFO_REGS_SIZE)) { - warn("%s: FIFO register read error: %d", - stir->netdev->name, err); + dev_warn(&stir->netdev->dev, + "FIFO register read error: %d\n", err); return err; } @@ -614,22 +611,26 @@ static int fifo_txwait(struct stir_cb *stir, int space) pr_debug("fifo status 0x%lx count %lu\n", status, count); /* is fifo receiving already, or empty */ - if (!(status & FIFOCTL_DIR) - || (status & FIFOCTL_EMPTY)) + if (!(status & FIFOCTL_DIR) || + (status & FIFOCTL_EMPTY)) return 0; if (signal_pending(current)) return -EINTR; /* shutting down? */ - if (!netif_running(stir->netdev) - || !netif_device_present(stir->netdev)) + if (!netif_running(stir->netdev) || + !netif_device_present(stir->netdev)) return -ESHUTDOWN; /* only waiting for some space */ if (space >= 0 && STIR_FIFO_SIZE - 4 > space + count) return 0; + /* queue confused */ + if (prev_count < count) + break; + /* estimate transfer time for remaining chars */ msleep((count * 8000) / stir->speed); } @@ -691,7 +692,7 @@ static void receive_stop(struct stir_cb *stir) usb_kill_urb(stir->rx_urb); if (stir->rx_buff.in_frame) - stir->stats.collisions++; + stir->netdev->stats.collisions++; } /* * Wrap data in socket buffer and send it. @@ -717,15 +718,15 @@ static void stir_send(struct stir_cb *stir, struct sk_buff *skb) if (!first_frame) fifo_txwait(stir, wraplen); - stir->stats.tx_packets++; - stir->stats.tx_bytes += skb->len; + stir->netdev->stats.tx_packets++; + stir->netdev->stats.tx_bytes += skb->len; stir->netdev->trans_start = jiffies; pr_debug("send %d (%d)\n", skb->len, wraplen); if (usb_bulk_msg(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1), stir->io_buf, wraplen, NULL, TRANSMIT_TIMEOUT)) - stir->stats.tx_errors++; + stir->netdev->stats.tx_errors++; } /* @@ -748,7 +749,7 @@ static int stir_transmit_thread(void *arg) write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); - refrigerator(); + try_to_freeze(); if (change_speed(stir, stir->speed)) break; @@ -774,16 +775,17 @@ static int stir_transmit_thread(void *arg) } /* nothing to send? start receiving */ - if (!stir->receiving - && irda_device_txqueue_empty(dev)) { + if (!stir->receiving && + irda_device_txqueue_empty(dev)) { /* Wait otherwise chip gets confused. */ if (fifo_txwait(stir, -1)) break; if (unlikely(receive_start(stir))) { if (net_ratelimit()) - info("%s: receive usb submit failed", - stir->netdev->name); + dev_info(&dev->dev, + "%s: receive usb submit failed\n", + stir->netdev->name); stir->receiving = 0; msleep(10); continue; @@ -822,7 +824,6 @@ static void stir_rcv_irq(struct urb *urb) unwrap_chars(stir, urb->transfer_buffer, urb->actual_length); - stir->netdev->last_rx = jiffies; do_gettimeofday(&stir->rx_time); } @@ -835,8 +836,8 @@ static void stir_rcv_irq(struct urb *urb) /* in case of error, the kernel thread will restart us */ if (err) { - warn("%s: usb receive submit error: %d", - stir->netdev->name, err); + dev_warn(&stir->netdev->dev, "usb receive submit error: %d\n", + err); stir->receiving = 0; wake_up_process(stir->thread); } @@ -902,7 +903,7 @@ static int stir_net_open(struct net_device *netdev) sprintf(hwname, "usb#%d", stir->usbdev->devnum); stir->irlap = irlap_open(netdev, &stir->qos, hwname); if (!stir->irlap) { - err("stir4200: irlap_open failed"); + dev_err(&stir->usbdev->dev, "irlap_open failed\n"); goto err_out5; } @@ -911,7 +912,7 @@ static int stir_net_open(struct net_device *netdev) "%s", stir->netdev->name); if (IS_ERR(stir->thread)) { err = PTR_ERR(stir->thread); - err("stir4200: unable to start kernel thread"); + dev_err(&stir->usbdev->dev, "unable to start kernel thread\n"); goto err_out6; } @@ -1006,14 +1007,12 @@ static int stir_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return ret; } -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *stir_net_get_stats(struct net_device *netdev) -{ - struct stir_cb *stir = netdev_priv(netdev); - return &stir->stats; -} +static const struct net_device_ops stir_netdev_ops = { + .ndo_open = stir_net_open, + .ndo_stop = stir_net_close, + .ndo_start_xmit = stir_hard_xmit, + .ndo_do_ioctl = stir_net_ioctl, +}; /* * This routine is called by the USB subsystem for each new device @@ -1035,7 +1034,6 @@ static int stir_probe(struct usb_interface *intf, if(!net) goto err_out1; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); stir = netdev_priv(net); stir->netdev = net; @@ -1043,7 +1041,7 @@ static int stir_probe(struct usb_interface *intf, ret = usb_reset_configuration(dev); if (ret != 0) { - err("stir4200: usb reset configuration failed"); + dev_err(&intf->dev, "usb reset configuration failed\n"); goto err_out2; } @@ -1063,17 +1061,14 @@ static int stir_probe(struct usb_interface *intf, irda_qos_bits_to_value(&stir->qos); /* Override the network functions we need to use */ - net->hard_start_xmit = stir_hard_xmit; - net->open = stir_net_open; - net->stop = stir_net_close; - net->get_stats = stir_net_get_stats; - net->do_ioctl = stir_net_ioctl; + net->netdev_ops = &stir_netdev_ops; ret = register_netdev(net); if (ret != 0) goto err_out2; - info("IrDA: Registered SigmaTel device %s", net->name); + dev_info(&intf->dev, "IrDA: Registered SigmaTel device %s\n", + net->name); usb_set_intfdata(intf, stir); @@ -1137,21 +1132,4 @@ static struct usb_driver irda_driver = { #endif }; -/* - * Module insertion - */ -static int __init stir_init(void) -{ - return usb_register(&irda_driver); -} -module_init(stir_init); - -/* - * Module removal - */ -static void __exit stir_cleanup(void) -{ - /* Deregister the driver and remove all pending instances */ - usb_deregister(&irda_driver); -} -module_exit(stir_cleanup); +module_usb_driver(irda_driver); diff --git a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c index 0dd6bc7af3f..048a1542284 100644 --- a/drivers/net/irda/tekram-sir.c +++ b/drivers/net/irda/tekram-sir.c @@ -18,7 +18,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -77,7 +77,7 @@ static int tekram_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); sirdev_set_dtr_rts(dev, TRUE, TRUE); @@ -92,7 +92,7 @@ static int tekram_open(struct sir_dev *dev) static int tekram_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -130,7 +130,7 @@ static int tekram_change_speed(struct sir_dev *dev, unsigned speed) u8 byte; static int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); switch(state) { case SIRDEV_STATE_DONGLE_SPEED: @@ -179,7 +179,7 @@ static int tekram_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s - undefined state %d\n", __FUNCTION__, state); + IRDA_ERROR("%s - undefined state %d\n", __func__, state); ret = -EINVAL; break; } @@ -204,7 +204,7 @@ static int tekram_change_speed(struct sir_dev *dev, unsigned speed) static int tekram_reset(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Clear DTR, Set RTS */ sirdev_set_dtr_rts(dev, FALSE, TRUE); diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c deleted file mode 100644 index 8f6258221cb..00000000000 --- a/drivers/net/irda/tekram.c +++ /dev/null @@ -1,282 +0,0 @@ -/********************************************************************* - * - * Filename: tekram.c - * Version: 1.2 - * Description: Implementation of the Tekram IrMate IR-210B dongle - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Fri Dec 17 09:13:09 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/init.h> - -#include <net/irda/irda.h> -#include <net/irda/irda_device.h> - -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 -#define TEKRAM_38400 0x02 -#define TEKRAM_19200 0x03 -#define TEKRAM_9600 0x04 - -#define TEKRAM_PW 0x10 /* Pulse select bit */ - -static struct dongle_reg dongle = { - .type = IRDA_TEKRAM_DONGLE, - .open = tekram_open, - .close = tekram_close, - .reset = tekram_reset, - .change_speed = tekram_change_speed, - .owner = THIS_MODULE, -}; - -static int __init tekram_init(void) -{ - return irda_device_register_dongle(&dongle); -} - -static void __exit tekram_cleanup(void) -{ - irda_device_unregister_dongle(&dongle); -} - -static void tekram_open(dongle_t *self, struct qos_info *qos) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - 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); -} - -static void tekram_close(dongle_t *self) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - /* Power off dongle */ - self->set_dtr_rts(self->dev, FALSE, FALSE); - - if (self->reset_task) - irda_task_delete(self->reset_task); - if (self->speed_task) - irda_task_delete(self->speed_task); -} - -/* - * 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! - * - * Algorithm - * 1. clear DTR - * 2. set RTS, and wait at least 7 us - * 3. send Control Byte to the IR-210 through TXD to set new baud rate - * wait until the stop bit of Control Byte is sent (for 9600 baud rate, - * it takes about 100 msec) - * 5. clear RTS (return to NORMAL Operation) - * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here - * after - */ -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; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - IRDA_ASSERT(task != NULL, return -1;); - - if (self->speed_task && self->speed_task != task) { - IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ ); - return msecs_to_jiffies(10); - } else - self->speed_task = task; - - switch (speed) { - default: - case 9600: - byte = TEKRAM_PW|TEKRAM_9600; - break; - case 19200: - byte = TEKRAM_PW|TEKRAM_19200; - break; - case 38400: - byte = TEKRAM_PW|TEKRAM_38400; - break; - case 57600: - byte = TEKRAM_PW|TEKRAM_57600; - break; - case 115200: - byte = TEKRAM_115200; - break; - } - - switch (task->state) { - case IRDA_TASK_INIT: - 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); - - /* 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: - IRDA_WARNING("%s(), resetting dongle timed out!\n", - __FUNCTION__); - ret = -1; - break; - case IRDA_TASK_CHILD_DONE: - /* Set DTR, Clear RTS */ - self->set_dtr_rts(self->dev, TRUE, FALSE); - - /* Wait at least 7us */ - udelay(14); - - /* 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(150); - 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->speed_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->speed_task = NULL; - ret = -1; - break; - } - return ret; -} - -/* - * Function tekram_reset (driver) - * - * This function resets the tekram dongle. Warning, this function - * must be called with a process context!! - * - * Algorithm: - * 0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 ) - * 1. clear RTS - * 2. set DTR, and wait at least 1 ms - * 3. clear DTR to SPACE state, wait at least 50 us for further - * operation - */ -int tekram_reset(struct irda_task *task) -{ - dongle_t *self = (dongle_t *) task->instance; - int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - IRDA_ASSERT(task != NULL, return -1;); - - if (self->reset_task && self->reset_task != task) { - IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ ); - return msecs_to_jiffies(10); - } else - self->reset_task = task; - - /* Power off dongle */ - //self->set_dtr_rts(self->dev, FALSE, FALSE); - self->set_dtr_rts(self->dev, TRUE, TRUE); - - switch (task->state) { - case IRDA_TASK_INIT: - irda_task_next_state(task, IRDA_TASK_WAIT1); - - /* 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); - - irda_task_next_state(task, IRDA_TASK_WAIT2); - - /* Should sleep 1 ms */ - ret = msecs_to_jiffies(1); - break; - case IRDA_TASK_WAIT2: - /* Set DTR, Set RTS */ - self->set_dtr_rts(self->dev, TRUE, TRUE); - - /* Wait at least 50 us */ - udelay(75); - - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - break; - default: - IRDA_ERROR("%s(), unknown state %d\n", - __FUNCTION__, task->state); - irda_task_next_state(task, IRDA_TASK_DONE); - self->reset_task = NULL; - ret = -1; - } - return ret; -} - -MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); -MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-0"); /* IRDA_TEKRAM_DONGLE */ - -/* - * Function init_module (void) - * - * Initialize Tekram module - * - */ -module_init(tekram_init); - -/* - * Function cleanup_module (void) - * - * Cleanup Tekram module - * - */ -module_exit(tekram_cleanup); diff --git a/drivers/net/irda/toim3232-sir.c b/drivers/net/irda/toim3232-sir.c index aa1a9b0ed83..19ad4606b79 100644 --- a/drivers/net/irda/toim3232-sir.c +++ b/drivers/net/irda/toim3232-sir.c @@ -78,7 +78,7 @@ * Target hardware: IRWave IR320ST-2 * * The IRWave IR320ST-2 is a simple dongle based on the Vishay/Temic - * TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transciever. + * TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transceiver. * It uses a hex inverter and some discrete components to buffer and * line convert the RS232 down to 5V. * @@ -120,6 +120,7 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/sched.h> #include <net/irda/irda.h> @@ -181,7 +182,7 @@ static int toim3232_open(struct sir_dev *dev) { struct qos_info *qos = &dev->qos; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Pull the lines high to start with. * @@ -209,7 +210,7 @@ static int toim3232_open(struct sir_dev *dev) static int toim3232_close(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Power off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); @@ -241,7 +242,7 @@ static int toim3232_change_speed(struct sir_dev *dev, unsigned speed) u8 byte; static int ret = 0; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); switch(state) { case SIRDEV_STATE_DONGLE_SPEED: @@ -299,7 +300,7 @@ static int toim3232_change_speed(struct sir_dev *dev, unsigned speed) break; default: - printk(KERN_ERR "%s - undefined state %d\n", __FUNCTION__, state); + printk(KERN_ERR "%s - undefined state %d\n", __func__, state); ret = -EINVAL; break; } @@ -344,7 +345,7 @@ static int toim3232_change_speed(struct sir_dev *dev, unsigned speed) static int toim3232_reset(struct sir_dev *dev) { - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Switch off both DTR and RTS to switch off dongle */ sirdev_set_dtr_rts(dev, FALSE, FALSE); diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index c3ed9b3067e..998bb89ede7 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -17,8 +17,7 @@ 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. +this program; if not, see <http://www.gnu.org/licenses/>. F01 Oct/02/02: Modify code for V0.11(move out back to back transfer) F02 Oct/28/02: Add SB device ID for 3147 and 3177. @@ -29,7 +28,7 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177. 2004-02-16: <sda@bdit.de> - Removed unneeded 'legacy' pci stuff. -- Make sure SIR mode is set (hw_init()) before calling mode-dependant stuff. +- Make sure SIR mode is set (hw_init()) before calling mode-dependent stuff. - On speed change from core, don't send SIR frame with new speed. Use current speed and change speeds later. - Make module-param dongle_id actually work. @@ -45,11 +44,12 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177. #include <linux/netdevice.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/rtnetlink.h> #include <linux/pci.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <asm/io.h> #include <asm/dma.h> @@ -75,22 +75,16 @@ static int dongle_id = 0; /* default: probe */ /* We can't guess the type of connected dongle, user *must* supply it. */ module_param(dongle_id, int, 0); -/* FIXME : we should not need this, because instances should be automatically - * managed by the PCI layer. Especially that we seem to only be using the - * first entry. Jean II */ -/* Max 4 instances for now */ -static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; - /* Some prototypes */ -static int via_ircc_open(int i, chipio_t * info, unsigned int id); -static int via_ircc_close(struct via_ircc_cb *self); +static int via_ircc_open(struct pci_dev *pdev, chipio_t *info, + unsigned int id); static int via_ircc_dma_receive(struct via_ircc_cb *self); static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, int iobase); -static int via_ircc_hard_xmit_sir(struct sk_buff *skb, - struct net_device *dev); -static int via_ircc_hard_xmit_fir(struct sk_buff *skb, - struct net_device *dev); +static netdev_tx_t via_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev); +static netdev_tx_t via_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev); static void via_hw_init(struct via_ircc_cb *self); static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud); static irqreturn_t via_ircc_interrupt(int irq, void *dev_id); @@ -101,16 +95,14 @@ static int via_ircc_net_open(struct net_device *dev); static int via_ircc_net_close(struct net_device *dev); static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *via_ircc_net_get_stats(struct net_device - *dev); static void via_ircc_change_dongle_speed(int iobase, int speed, int dongle_id); static int RxTimerHandler(struct via_ircc_cb *self, int iobase); static void hwreset(struct via_ircc_cb *self); static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase); static int upload_rxdata(struct via_ircc_cb *self, int iobase); -static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id); -static void __devexit via_remove_one (struct pci_dev *pdev); +static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id); +static void via_remove_one(struct pci_dev *pdev); /* FIXME : Should use udelay() instead, even if we are x86 only - Jean II */ static void iodelay(int udelay) @@ -123,7 +115,7 @@ static void iodelay(int udelay) } } -static struct pci_device_id via_pci_tbl[] = { +static DEFINE_PCI_DEVICE_TABLE(via_pci_tbl) = { { PCI_VENDOR_ID_VIA, 0x8231, PCI_ANY_ID, PCI_ANY_ID,0,0,0 }, { PCI_VENDOR_ID_VIA, 0x3109, PCI_ANY_ID, PCI_ANY_ID,0,0,1 }, { PCI_VENDOR_ID_VIA, 0x3074, PCI_ANY_ID, PCI_ANY_ID,0,0,2 }, @@ -139,7 +131,7 @@ static struct pci_driver via_driver = { .name = VIA_MODULE_NAME, .id_table = via_pci_tbl, .probe = via_init_one, - .remove = __devexit_p(via_remove_one), + .remove = via_remove_one, }; @@ -152,29 +144,29 @@ static int __init via_ircc_init(void) { int rc; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); rc = pci_register_driver(&via_driver); if (rc < 0) { IRDA_DEBUG(0, "%s(): error rc = %d, returning -ENODEV...\n", - __FUNCTION__, rc); + __func__, rc); return -ENODEV; } return 0; } -static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id) +static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) { int rc; u8 temp,oldPCI_40,oldPCI_44,bTmp,bTmp1; u16 Chipset,FirDRQ1,FirDRQ0,FirIRQ,FirIOBase; chipio_t info; - IRDA_DEBUG(2, "%s(): Device ID=(0X%X)\n", __FUNCTION__, id->device); + IRDA_DEBUG(2, "%s(): Device ID=(0X%X)\n", __func__, id->device); rc = pci_enable_device (pcidev); if (rc) { - IRDA_DEBUG(0, "%s(): error rc = %d\n", __FUNCTION__, rc); + IRDA_DEBUG(0, "%s(): error rc = %d\n", __func__, rc); return -ENODEV; } @@ -185,7 +177,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi Chipset=0x3076; if (Chipset==0x3076) { - IRDA_DEBUG(2, "%s(): Chipset = 3076\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(): Chipset = 3076\n", __func__); WriteLPCReg(7,0x0c ); temp=ReadLPCReg(0x30);//check if BIOS Enable Fir @@ -217,12 +209,11 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); pci_write_config_byte(pcidev,0x5a,0xc0); WriteLPCReg(0x28, 0x70 ); - if (via_ircc_open(0, &info,0x3076) == 0) - rc=0; + rc = via_ircc_open(pcidev, &info, 0x3076); } else rc = -ENODEV; //IR not turn on } else { //Not VT1211 - IRDA_DEBUG(2, "%s(): Chipset = 3096\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(): Chipset = 3096\n", __func__); pci_read_config_byte(pcidev,0x67,&bTmp);//check if BIOS Enable Fir if((bTmp&0x01)==1) { // BIOS enable FIR @@ -256,95 +247,61 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi info.irq=FirIRQ; info.dma=FirDRQ1; info.dma2=FirDRQ0; - if (via_ircc_open(0, &info,0x3096) == 0) - rc=0; + rc = via_ircc_open(pcidev, &info, 0x3096); } else rc = -ENODEV; //IR not turn on !!!!! }//Not VT1211 - IRDA_DEBUG(2, "%s(): End - rc = %d\n", __FUNCTION__, rc); + IRDA_DEBUG(2, "%s(): End - rc = %d\n", __func__, rc); return rc; } -/* - * Function via_ircc_clean () - * - * Close all configured chips - * - */ -static void via_ircc_clean(void) -{ - int i; - - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); - - for (i=0; i < ARRAY_SIZE(dev_self); i++) { - if (dev_self[i]) - via_ircc_close(dev_self[i]); - } -} - -static void __devexit via_remove_one (struct pci_dev *pdev) -{ - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); - - /* FIXME : This is ugly. We should use pci_get_drvdata(pdev); - * to get our driver instance and call directly via_ircc_close(). - * See vlsi_ir for details... - * Jean II */ - via_ircc_clean(); - - /* FIXME : This should be in via_ircc_close(), because here we may - * theoritically disable still configured devices :-( - Jean II */ - pci_disable_device(pdev); -} - static void __exit via_ircc_cleanup(void) { - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); - - /* FIXME : This should be redundant, as pci_unregister_driver() - * should call via_remove_one() on each device. - * Jean II */ - via_ircc_clean(); + IRDA_DEBUG(3, "%s()\n", __func__); /* Cleanup all instances of the driver */ pci_unregister_driver (&via_driver); } +static const struct net_device_ops via_ircc_sir_ops = { + .ndo_start_xmit = via_ircc_hard_xmit_sir, + .ndo_open = via_ircc_net_open, + .ndo_stop = via_ircc_net_close, + .ndo_do_ioctl = via_ircc_net_ioctl, +}; +static const struct net_device_ops via_ircc_fir_ops = { + .ndo_start_xmit = via_ircc_hard_xmit_fir, + .ndo_open = via_ircc_net_open, + .ndo_stop = via_ircc_net_close, + .ndo_do_ioctl = via_ircc_net_ioctl, +}; + /* - * Function via_ircc_open (iobase, irq) + * Function via_ircc_open(pdev, iobase, irq) * * Open driver instance * */ -static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) +static int via_ircc_open(struct pci_dev *pdev, chipio_t *info, unsigned int id) { struct net_device *dev; struct via_ircc_cb *self; int err; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); - - if (i >= ARRAY_SIZE(dev_self)) - return -ENOMEM; + IRDA_DEBUG(3, "%s()\n", __func__); /* Allocate new instance of the driver */ dev = alloc_irdadev(sizeof(struct via_ircc_cb)); if (dev == NULL) return -ENOMEM; - self = dev->priv; + self = netdev_priv(dev); self->netdev = dev; spin_lock_init(&self->lock); - /* FIXME : We should store our driver instance in the PCI layer, - * using pci_set_drvdata(), not in this array. - * See vlsi_ir for details... - Jean II */ - /* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */ - /* Need to store self somewhere */ - dev_self[i] = self; - self->index = i; + pci_set_drvdata(pdev, self); + /* Initialize Resource */ self->io.cfg_base = info->cfg_base; self->io.fir_base = info->fir_base; @@ -360,7 +317,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) /* Reserve the ioports that we need */ if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) { IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n", - __FUNCTION__, self->io.fir_base); + __func__, self->io.fir_base); err = -ENODEV; goto err_out1; } @@ -374,7 +331,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) self->io.dongle_id = dongle_id; /* The only value we must override it the baudrate */ - /* Maximum speeds and capabilities are dongle-dependant. */ + /* Maximum speeds and capabilities are dongle-dependent. */ switch( self->io.dongle_id ){ case 0x0d: self->qos.baud_rate.bits = @@ -403,22 +360,20 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(&pdev->dev, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(&pdev->dev, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; @@ -429,15 +384,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - /* Override the network functions we need to use */ - dev->hard_start_xmit = via_ircc_hard_xmit_sir; - dev->open = via_ircc_net_open; - dev->stop = via_ircc_net_close; - dev->do_ioctl = via_ircc_net_ioctl; - dev->get_stats = via_ircc_net_get_stats; + dev->netdev_ops = &via_ircc_sir_ops; err = register_netdev(dev); if (err) @@ -451,32 +399,30 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) via_hw_init(self); return 0; err_out4: - dma_free_coherent(NULL, self->tx_buff.truesize, + dma_free_coherent(&pdev->dev, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); err_out3: - dma_free_coherent(NULL, self->rx_buff.truesize, + dma_free_coherent(&pdev->dev, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: free_netdev(dev); - dev_self[i] = NULL; return err; } /* - * Function via_ircc_close (self) + * Function via_remove_one(pdev) * * Close driver instance * */ -static int via_ircc_close(struct via_ircc_cb *self) +static void via_remove_one(struct pci_dev *pdev) { + struct via_ircc_cb *self = pci_get_drvdata(pdev); int iobase; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); - - IRDA_ASSERT(self != NULL, return -1;); + IRDA_DEBUG(3, "%s()\n", __func__); iobase = self->io.fir_base; @@ -486,19 +432,18 @@ static int via_ircc_close(struct via_ircc_cb *self) /* Release the PORT that this driver is using */ IRDA_DEBUG(2, "%s(), Releasing Region %03x\n", - __FUNCTION__, self->io.fir_base); + __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - dma_free_coherent(NULL, self->tx_buff.truesize, + dma_free_coherent(&pdev->dev, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - dma_free_coherent(NULL, self->rx_buff.truesize, + dma_free_coherent(&pdev->dev, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); - dev_self[self->index] = NULL; free_netdev(self->netdev); - return 0; + pci_disable_device(pdev); } /* @@ -512,7 +457,7 @@ static void via_hw_init(struct via_ircc_cb *self) { int iobase = self->io.fir_base; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); SetMaxRxPacketSize(iobase, 0x0fff); //set to max:4095 // FIFO Init @@ -565,10 +510,8 @@ static void via_hw_init(struct via_ircc_cb *self) */ static int via_ircc_read_dongle_id(int iobase) { - int dongle_id = 9; /* Default to IBM */ - IRDA_ERROR("via-ircc: dongle probing not supported, please specify dongle_id module parameter.\n"); - return dongle_id; + return 9; /* Default to IBM */ } /* @@ -585,7 +528,7 @@ static void via_ircc_change_dongle_speed(int iobase, int speed, speed = speed; IRDA_DEBUG(1, "%s(): change_dongle_speed to %d for 0x%x, %d\n", - __FUNCTION__, speed, iobase, dongle_id); + __func__, speed, iobase, dongle_id); switch (dongle_id) { @@ -674,7 +617,7 @@ static void via_ircc_change_dongle_speed(int iobase, int speed, case 0x11: /* Temic TFDS4500 */ - IRDA_DEBUG(2, "%s: Temic TFDS4500: One RX pin, TX normal, RX inverted.\n", __FUNCTION__); + IRDA_DEBUG(2, "%s: Temic TFDS4500: One RX pin, TX normal, RX inverted.\n", __func__); UseOneRX(iobase, ON); //use ONE RX....RX1 InvertTX(iobase, OFF); @@ -692,7 +635,7 @@ static void via_ircc_change_dongle_speed(int iobase, int speed, SlowIRRXLowActive(iobase, OFF); } else{ - IRDA_DEBUG(0, "%s: Warning: TFDS4500 not running in SIR mode !\n", __FUNCTION__); + IRDA_DEBUG(0, "%s: Warning: TFDS4500 not running in SIR mode !\n", __func__); } break; @@ -710,7 +653,7 @@ static void via_ircc_change_dongle_speed(int iobase, int speed, default: IRDA_ERROR("%s: Error: dongle_id %d unsupported !\n", - __FUNCTION__, dongle_id); + __func__, dongle_id); } } @@ -729,7 +672,7 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed) iobase = self->io.fir_base; /* Update accounting for new speed */ self->io.speed = speed; - IRDA_DEBUG(1, "%s: change_speed to %d bps.\n", __FUNCTION__, speed); + IRDA_DEBUG(1, "%s: change_speed to %d bps.\n", __func__, speed); WriteReg(iobase, I_ST_CT_0, 0x0); @@ -804,11 +747,11 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed) if (speed > 115200) { /* Install FIR xmit handler */ - dev->hard_start_xmit = via_ircc_hard_xmit_fir; + dev->netdev_ops = &via_ircc_fir_ops; via_ircc_dma_receive(self); } else { /* Install SIR xmit handler */ - dev->hard_start_xmit = via_ircc_hard_xmit_sir; + dev->netdev_ops = &via_ircc_sir_ops; } netif_wake_queue(dev); } @@ -819,16 +762,16 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed) * Transmit the frame! * */ -static int via_ircc_hard_xmit_sir(struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t via_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev) { struct via_ircc_cb *self; unsigned long flags; u16 iobase; __u32 speed; - self = (struct via_ircc_cb *) dev->priv; - IRDA_ASSERT(self != NULL, return 0;); + self = netdev_priv(dev); + IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;); iobase = self->io.fir_base; netif_stop_queue(dev); @@ -840,7 +783,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb, via_ircc_change_speed(self, speed); dev->trans_start = jiffies; dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -858,7 +801,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb, async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Send this frame with old speed */ SetBaudRate(iobase, self->io.speed); SetPulseWidth(iobase, 12); @@ -888,22 +831,22 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb, dev->trans_start = jiffies; spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } -static int via_ircc_hard_xmit_fir(struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t via_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev) { struct via_ircc_cb *self; u16 iobase; __u32 speed; unsigned long flags; - self = (struct via_ircc_cb *) dev->priv; + self = netdev_priv(dev); iobase = self->io.fir_base; if (self->st_fifo.len) - return 0; + return NETDEV_TX_OK; if (self->chip_id == 0x3076) iodelay(1500); else @@ -915,7 +858,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb, via_ircc_change_speed(self, speed); dev->trans_start = jiffies; dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -924,9 +867,9 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb, self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; - memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, - skb->len); + dev->stats.tx_bytes += skb->len; + skb_copy_from_linear_data(skb, + self->tx_fifo.queue[self->tx_fifo.free].start, skb->len); self->tx_fifo.len++; self->tx_fifo.free++; //F01 if (self->tx_fifo.len == 1) { @@ -936,7 +879,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb, dev->trans_start = jiffies; dev_kfree_skb(skb); spin_unlock_irqrestore(&self->lock, flags); - return 0; + return NETDEV_TX_OK; } @@ -960,7 +903,7 @@ static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase) self->tx_buff.head) + self->tx_buff_dma, self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE); IRDA_DEBUG(1, "%s: tx_fifo.ptr=%x,len=%x,tx_fifo.len=%x..\n", - __FUNCTION__, self->tx_fifo.ptr, + __func__, self->tx_fifo.ptr, self->tx_fifo.queue[self->tx_fifo.ptr].len, self->tx_fifo.len); @@ -981,24 +924,23 @@ static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase) static int via_ircc_dma_xmit_complete(struct via_ircc_cb *self) { int iobase; - int ret = TRUE; u8 Tx_status; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); iobase = self->io.fir_base; /* Disable DMA */ // DisableDmaChannel(self->io.dma); - /* Check for underrrun! */ + /* Check for underrun! */ /* Clear bit, by writing 1 into it */ Tx_status = GetTXStatus(iobase); if (Tx_status & 0x08) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; hwreset(self); -// how to clear underrrun ? + /* how to clear underrun? */ } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; ResetChip(iobase, 3); ResetChip(iobase, 4); } @@ -1017,7 +959,7 @@ static int via_ircc_dma_xmit_complete(struct via_ircc_cb *self) } IRDA_DEBUG(1, "%s: tx_fifo.len=%x ,tx_fifo.ptr=%x,tx_fifo.free=%x...\n", - __FUNCTION__, + __func__, self->tx_fifo.len, self->tx_fifo.ptr, self->tx_fifo.free); /* F01_S // Any frames to be sent back-to-back? @@ -1038,7 +980,7 @@ F01_E*/ // Tell the network layer, that we can accept more frames netif_wake_queue(self->netdev); //F01 } - return ret; + return TRUE; } /* @@ -1053,7 +995,7 @@ static int via_ircc_dma_receive(struct via_ircc_cb *self) iobase = self->io.fir_base; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; @@ -1122,10 +1064,10 @@ static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, } // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); return TRUE; @@ -1137,13 +1079,13 @@ static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, return TRUE; //interrupt only, data maybe move by RxT if (((len - 4) < 2) || ((len - 4) > 2048)) { IRDA_DEBUG(1, "%s(): Trouble:len=%x,CurCount=%x,LastCount=%x..\n", - __FUNCTION__, len, RxCurCount(iobase, self), + __func__, len, RxCurCount(iobase, self), self->RxLastCount); hwreset(self); return FALSE; } IRDA_DEBUG(2, "%s(): fifo.len=%x,len=%x,CurCount=%x..\n", - __FUNCTION__, + __func__, st_fifo->len, len - 4, RxCurCount(iobase, self)); st_fifo->entries[st_fifo->tail].status = status; @@ -1178,27 +1120,28 @@ F01_E */ skb = dev_alloc_skb(len + 1 - 4); /* - * if frame size,data ptr,or skb ptr are wrong ,the get next + * if frame size, data ptr, or skb ptr are wrong, then get next * entry. */ - if ((skb == NULL) || (skb->data == NULL) - || (self->rx_buff.data == NULL) || (len < 6)) { - self->stats.rx_dropped++; + if ((skb == NULL) || (skb->data == NULL) || + (self->rx_buff.data == NULL) || (len < 6)) { + self->netdev->stats.rx_dropped++; + kfree_skb(skb); return TRUE; } skb_reserve(skb, 1); skb_put(skb, len - 4); - memcpy(skb->data, self->rx_buff.data, len - 4); - IRDA_DEBUG(2, "%s(): len=%x.rx_buff=%p\n", __FUNCTION__, + skb_copy_to_linear_data(skb, self->rx_buff.data, len - 4); + IRDA_DEBUG(2, "%s(): len=%x.rx_buff=%p\n", __func__, len - 4, self->rx_buff.data); // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); @@ -1220,31 +1163,31 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase) len = GetRecvByte(iobase, self); - IRDA_DEBUG(2, "%s(): len=%x\n", __FUNCTION__, len); + IRDA_DEBUG(2, "%s(): len=%x\n", __func__, len); if ((len - 4) < 2) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return FALSE; } skb = dev_alloc_skb(len + 1); if (skb == NULL) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return FALSE; } skb_reserve(skb, 1); skb_put(skb, len - 4 + 1); - memcpy(skb->data, self->rx_buff.data, len - 4 + 1); + skb_copy_to_linear_data(skb, self->rx_buff.data, len - 4 + 1); st_fifo->tail++; st_fifo->len++; if (st_fifo->tail > MAX_RX_WINDOW) st_fifo->tail = 0; // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); if (st_fifo->len < (MAX_RX_WINDOW + 2)) { @@ -1280,8 +1223,8 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) self->RetryCount++; if ((self->RetryCount >= 1) || - ((st_fifo->pending_bytes + 2048) > self->rx_buff.truesize) - || (st_fifo->len >= (MAX_RX_WINDOW))) { + ((st_fifo->pending_bytes + 2048) > self->rx_buff.truesize) || + (st_fifo->len >= (MAX_RX_WINDOW))) { while (st_fifo->len > 0) { //upload frame // Put this entry back in fifo if (st_fifo->head > MAX_RX_WINDOW) @@ -1296,24 +1239,24 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) * if frame size, data ptr, or skb ptr are wrong, * then get next entry. */ - if ((skb == NULL) || (skb->data == NULL) - || (self->rx_buff.data == NULL) || (len < 6)) { - self->stats.rx_dropped++; + if ((skb == NULL) || (skb->data == NULL) || + (self->rx_buff.data == NULL) || (len < 6)) { + self->netdev->stats.rx_dropped++; continue; } skb_reserve(skb, 1); skb_put(skb, len - 4); - memcpy(skb->data, self->rx_buff.data, len - 4); + skb_copy_to_linear_data(skb, self->rx_buff.data, len - 4); - IRDA_DEBUG(2, "%s(): len=%x.head=%x\n", __FUNCTION__, + IRDA_DEBUG(2, "%s(): len=%x.head=%x\n", __func__, len - 4, st_fifo->head); // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); } //while @@ -1321,15 +1264,15 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) IRDA_DEBUG(2, "%s(): End of upload HostStatus=%x,RxStatus=%x\n", - __FUNCTION__, + __func__, GetHostStatus(iobase), GetRXStatus(iobase)); /* * if frame is receive complete at this routine ,then upload * frame. */ - if ((GetRXStatus(iobase) & 0x10) - && (RxCurCount(iobase, self) != self->RxLastCount)) { + if ((GetRXStatus(iobase) & 0x10) && + (RxCurCount(iobase, self) != self->RxLastCount)) { upload_rxdata(self, iobase); if (irda_device_txqueue_empty(self->netdev)) via_ircc_dma_receive(self); @@ -1349,25 +1292,19 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t via_ircc_interrupt(int dummy, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - struct via_ircc_cb *self; + struct net_device *dev = dev_id; + struct via_ircc_cb *self = netdev_priv(dev); int iobase; u8 iHostIntType, iRxIntType, iTxIntType; - if (!dev) { - IRDA_WARNING("%s: irq %d for unknown device.\n", driver_name, - irq); - return IRQ_NONE; - } - self = (struct via_ircc_cb *) dev->priv; iobase = self->io.fir_base; spin_lock(&self->lock); iHostIntType = GetHostStatus(iobase); IRDA_DEBUG(4, "%s(): iHostIntType %02x: %s %s %s %02x\n", - __FUNCTION__, iHostIntType, + __func__, iHostIntType, (iHostIntType & 0x40) ? "Timer" : "", (iHostIntType & 0x20) ? "Tx" : "", (iHostIntType & 0x10) ? "Rx" : "", @@ -1397,7 +1334,7 @@ static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) iTxIntType = GetTXStatus(iobase); IRDA_DEBUG(4, "%s(): iTxIntType %02x: %s %s %s %s\n", - __FUNCTION__, iTxIntType, + __func__, iTxIntType, (iTxIntType & 0x08) ? "FIFO underr." : "", (iTxIntType & 0x04) ? "EOM" : "", (iTxIntType & 0x02) ? "FIFO ready" : "", @@ -1421,7 +1358,7 @@ static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) iRxIntType = GetRXStatus(iobase); IRDA_DEBUG(4, "%s(): iRxIntType %02x: %s %s %s %s %s %s %s\n", - __FUNCTION__, iRxIntType, + __func__, iRxIntType, (iRxIntType & 0x80) ? "PHY err." : "", (iRxIntType & 0x40) ? "CRC err" : "", (iRxIntType & 0x20) ? "FIFO overr." : "", @@ -1430,7 +1367,7 @@ static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) (iRxIntType & 0x02) ? "RxMaxLen" : "", (iRxIntType & 0x01) ? "SIR bad" : ""); if (!iRxIntType) - IRDA_DEBUG(3, "%s(): RxIRQ =0\n", __FUNCTION__); + IRDA_DEBUG(3, "%s(): RxIRQ =0\n", __func__); if (iRxIntType & 0x10) { if (via_ircc_dma_receive_complete(self, iobase)) { @@ -1440,7 +1377,7 @@ static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) } // No ERR else { //ERR IRDA_DEBUG(4, "%s(): RxIRQ ERR:iRxIntType=%x,HostIntType=%x,CurCount=%x,RxLastCount=%x_____\n", - __FUNCTION__, iRxIntType, iHostIntType, + __func__, iRxIntType, iHostIntType, RxCurCount(iobase, self), self->RxLastCount); @@ -1465,7 +1402,7 @@ static void hwreset(struct via_ircc_cb *self) int iobase; iobase = self->io.fir_base; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); ResetChip(iobase, 5); EnableDMA(iobase, OFF); @@ -1510,7 +1447,7 @@ static int via_ircc_is_receiving(struct via_ircc_cb *self) if (CkRxRecv(iobase, self)) status = TRUE; - IRDA_DEBUG(2, "%s(): status=%x....\n", __FUNCTION__, status); + IRDA_DEBUG(2, "%s(): status=%x....\n", __func__, status); return status; } @@ -1528,11 +1465,11 @@ static int via_ircc_net_open(struct net_device *dev) int iobase; char hwname[32]; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct via_ircc_cb *) dev->priv; - self->stats.rx_packets = 0; + self = netdev_priv(dev); + dev->stats.rx_packets = 0; IRDA_ASSERT(self != NULL, return 0;); iobase = self->io.fir_base; if (request_irq(self->io.irq, via_ircc_interrupt, 0, dev->name, dev)) { @@ -1547,14 +1484,15 @@ static int via_ircc_net_open(struct net_device *dev) if (request_dma(self->io.dma, dev->name)) { IRDA_WARNING("%s, unable to allocate dma=%d\n", driver_name, self->io.dma); - free_irq(self->io.irq, self); + free_irq(self->io.irq, dev); return -EAGAIN; } if (self->io.dma2 != self->io.dma) { if (request_dma(self->io.dma2, dev->name)) { IRDA_WARNING("%s, unable to allocate dma2=%d\n", driver_name, self->io.dma2); - free_irq(self->io.irq, self); + free_irq(self->io.irq, dev); + free_dma(self->io.dma); return -EAGAIN; } } @@ -1594,10 +1532,10 @@ static int via_ircc_net_close(struct net_device *dev) struct via_ircc_cb *self; int iobase; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct via_ircc_cb *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); /* Stop device */ @@ -1615,6 +1553,8 @@ static int via_ircc_net_close(struct net_device *dev) EnAllInt(iobase, OFF); free_irq(self->io.irq, dev); free_dma(self->io.dma); + if (self->io.dma2 != self->io.dma) + free_dma(self->io.dma2); return 0; } @@ -1634,9 +1574,9 @@ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int ret = 0; IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(1, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, + IRDA_DEBUG(1, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); /* Disable interrupts & save flags */ spin_lock_irqsave(&self->lock, flags); @@ -1666,14 +1606,6 @@ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, return ret; } -static struct net_device_stats *via_ircc_net_get_stats(struct net_device - *dev) -{ - struct via_ircc_cb *self = (struct via_ircc_cb *) dev->priv; - - return &self->stats; -} - MODULE_AUTHOR("VIA Technologies,inc"); MODULE_DESCRIPTION("VIA IrDA Device Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h index 204b1b34ffc..7ce820ecc36 100644 --- a/drivers/net/irda/via-ircc.h +++ b/drivers/net/irda/via-ircc.h @@ -18,8 +18,7 @@ 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. +this program; if not, see <http://www.gnu.org/licenses/>. * Comment: * jul/08/2002 : Rx buffer length should use Rx ring ptr. @@ -54,13 +53,13 @@ struct st_fifo { struct frame_cb { void *start; /* Start of frame in DMA mem */ - int len; /* Lenght of frame in DMA mem */ + int len; /* Length of frame in DMA mem */ }; struct tx_fifo { struct frame_cb queue[MAX_TX_WINDOW + 2]; /* Info about frames in queue */ int ptr; /* Currently being sent */ - int len; /* Lenght of queue */ + int len; /* Length of queue */ int free; /* Next free slot */ void *tail; /* Next free start in DMA mem */ }; @@ -95,7 +94,6 @@ struct via_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ @@ -118,7 +116,6 @@ struct via_ircc_cb { int index; /* Instance index */ struct eventflag EventFlag; - struct pm_dev *dev; unsigned int chip_id; /* to remember chip id */ unsigned int RetryCount; unsigned int RxDataReady; @@ -212,7 +209,7 @@ static void DisableDmaChannel(unsigned int channel) break; default: break; - }; //Switch + } } static unsigned char ReadLPCReg(int iRegNum) @@ -240,7 +237,7 @@ static void WriteLPCReg(int iRegNum, unsigned char iVal) static __u8 ReadReg(unsigned int BaseAddr, int iRegNum) { - return ((__u8) inb(BaseAddr + iRegNum)); + return (__u8) inb(BaseAddr + iRegNum); } static void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal) @@ -776,7 +773,7 @@ static void SetBaudRate(__u16 iobase, __u32 rate) break; default: break; - }; + } } else if (IsMIROn(iobase)) { value = 0; // will automatically be fixed in 1.152M } else if (IsFIROn(iobase)) { diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 18c68193bf1..485006604bb 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -15,9 +15,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ @@ -36,6 +34,7 @@ MODULE_LICENSE("GPL"); #include <linux/kernel.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/netdevice.h> @@ -44,7 +43,7 @@ MODULE_LICENSE("GPL"); #include <linux/time.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> #include <asm/uaccess.h> #include <asm/byteorder.h> @@ -59,7 +58,7 @@ MODULE_LICENSE("GPL"); static /* const */ char drivername[] = DRIVER_NAME; -static struct pci_device_id vlsi_irda_table [] = { +static DEFINE_PCI_DEVICE_TABLE(vlsi_irda_table) = { { .class = PCI_CLASS_WIRELESS_IRDA << 8, .class_mask = PCI_CLASS_SUBCLASS_MASK << 8, @@ -140,15 +139,15 @@ static void vlsi_ring_debug(struct vlsi_ring *r) unsigned i; printk(KERN_DEBUG "%s - ring %p / size %u / mask 0x%04x / len %u / dir %d / hw %p\n", - __FUNCTION__, r, r->size, r->mask, r->len, r->dir, r->rd[0].hw); - printk(KERN_DEBUG "%s - head = %d / tail = %d\n", __FUNCTION__, + __func__, r, r->size, r->mask, r->len, r->dir, r->rd[0].hw); + printk(KERN_DEBUG "%s - head = %d / tail = %d\n", __func__, atomic_read(&r->head) & r->mask, atomic_read(&r->tail) & r->mask); for (i = 0; i < r->size; i++) { rd = &r->rd[i]; - printk(KERN_DEBUG "%s - ring descr %u: ", __FUNCTION__, i); + printk(KERN_DEBUG "%s - ring descr %u: ", __func__, i); printk("skb=%p data=%p hw=%p\n", rd->skb, rd->buf, rd->hw); printk(KERN_DEBUG "%s - hw: status=%02x count=%u addr=0x%08x\n", - __FUNCTION__, (unsigned) rd_get_status(rd), + __func__, (unsigned) rd_get_status(rd), (unsigned) rd_get_count(rd), (unsigned) rd_get_addr(rd)); } } @@ -165,8 +164,8 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) unsigned iobase = pci_resource_start(pdev, 0); unsigned i; - seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n", - PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); + seq_printf(seq, "\n%s (vid/did: [%04x:%04x])\n", + pci_name(pdev), (int)pdev->vendor, (int)pdev->device); seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state); seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); @@ -178,7 +177,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); u8 byte; u16 word; unsigned delta1, delta2; @@ -291,14 +290,14 @@ static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev) now.tv_sec - idev->last_rx.tv_sec - delta1, delta2); seq_printf(seq, "RX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu", - idev->stats.rx_packets, idev->stats.rx_bytes, idev->stats.rx_errors, - idev->stats.rx_dropped); + ndev->stats.rx_packets, ndev->stats.rx_bytes, ndev->stats.rx_errors, + ndev->stats.rx_dropped); seq_printf(seq, " / overrun=%lu / length=%lu / frame=%lu / crc=%lu\n", - idev->stats.rx_over_errors, idev->stats.rx_length_errors, - idev->stats.rx_frame_errors, idev->stats.rx_crc_errors); + ndev->stats.rx_over_errors, ndev->stats.rx_length_errors, + ndev->stats.rx_frame_errors, ndev->stats.rx_crc_errors); seq_printf(seq, "TX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu / fifo=%lu\n", - idev->stats.tx_packets, idev->stats.tx_bytes, idev->stats.tx_errors, - idev->stats.tx_dropped, idev->stats.tx_fifo_errors); + ndev->stats.tx_packets, ndev->stats.tx_bytes, ndev->stats.tx_errors, + ndev->stats.tx_dropped, ndev->stats.tx_fifo_errors); } @@ -346,7 +345,7 @@ static void vlsi_proc_ring(struct seq_file *seq, struct vlsi_ring *r) static int vlsi_seq_show(struct seq_file *seq, void *v) { struct net_device *ndev = seq->private; - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); unsigned long flags; seq_printf(seq, "\n%s %s\n\n", DRIVER_NAME, DRIVER_VERSION); @@ -382,10 +381,10 @@ static int vlsi_seq_show(struct seq_file *seq, void *v) static int vlsi_seq_open(struct inode *inode, struct file *file) { - return single_open(file, vlsi_seq_show, PDE(inode)->data); + return single_open(file, vlsi_seq_show, PDE_DATA(inode)); } -static struct file_operations vlsi_proc_fops = { +static const struct file_operations vlsi_proc_fops = { .owner = THIS_MODULE, .open = vlsi_seq_open, .read = seq_read, @@ -431,11 +430,11 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr memset(rd, 0, sizeof(*rd)); rd->hw = hwmap + i; rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA); - if (rd->buf == NULL - || !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) { + if (rd->buf == NULL || + !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) { if (rd->buf) { IRDA_ERROR("%s: failed to create PCI-MAP for %p", - __FUNCTION__, rd->buf); + __func__, rd->buf); kfree(rd->buf); rd->buf = NULL; } @@ -489,7 +488,7 @@ static int vlsi_create_hwif(vlsi_irda_dev_t *idev) ringarea = pci_alloc_consistent(idev->pdev, HW_RING_AREA_SIZE, &idev->busaddr); if (!ringarea) { IRDA_ERROR("%s: insufficient memory for descriptor rings\n", - __FUNCTION__); + __func__); goto out; } memset(ringarea, 0, HW_RING_AREA_SIZE); @@ -542,8 +541,8 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd) int crclen, len = 0; struct sk_buff *skb; int ret = 0; - struct net_device *ndev = (struct net_device *)pci_get_drvdata(r->pdev); - vlsi_irda_dev_t *idev = ndev->priv; + struct net_device *ndev = pci_get_drvdata(r->pdev); + vlsi_irda_dev_t *idev = netdev_priv(ndev); pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir); /* dma buffer now owned by the CPU */ @@ -564,7 +563,7 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd) crclen = (idev->mode==IFF_FIR) ? sizeof(u32) : sizeof(u16); len -= crclen; /* remove trailing CRC */ if (len <= 0) { - IRDA_DEBUG(0, "%s: strange frame (len=%d)\n", __FUNCTION__, len); + IRDA_DEBUG(0, "%s: strange frame (len=%d)\n", __func__, len); ret |= VLSI_RX_DROP; goto done; } @@ -579,14 +578,14 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd) */ le16_to_cpus(rd->buf+len); if (irda_calc_crc16(INIT_FCS,rd->buf,len+crclen) != GOOD_FCS) { - IRDA_DEBUG(0, "%s: crc error\n", __FUNCTION__); + IRDA_DEBUG(0, "%s: crc error\n", __func__); ret |= VLSI_RX_CRC; goto done; } } if (!rd->skb) { - IRDA_WARNING("%s: rx packet lost\n", __FUNCTION__); + IRDA_WARNING("%s: rx packet lost\n", __func__); ret |= VLSI_RX_DROP; goto done; } @@ -595,12 +594,11 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd) rd->skb = NULL; skb->dev = ndev; memcpy(skb_put(skb,len), rd->buf, len); - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); if (in_interrupt()) netif_rx(skb); else netif_rx_ni(skb); - ndev->last_rx = jiffies; done: rd_set_status(rd, 0); @@ -617,7 +615,7 @@ static void vlsi_fill_rx(struct vlsi_ring *r) for (rd = ring_last(r); rd != NULL; rd = ring_put(r)) { if (rd_is_active(rd)) { IRDA_WARNING("%s: driver bug: rx descr race with hw\n", - __FUNCTION__); + __func__); vlsi_ring_debug(r); break; } @@ -638,7 +636,7 @@ static void vlsi_fill_rx(struct vlsi_ring *r) static void vlsi_rx_interrupt(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); struct vlsi_ring *r = idev->rx_ring; struct ring_descr *rd; int ret; @@ -652,21 +650,21 @@ static void vlsi_rx_interrupt(struct net_device *ndev) if (ret < 0) { ret = -ret; - idev->stats.rx_errors++; + ndev->stats.rx_errors++; if (ret & VLSI_RX_DROP) - idev->stats.rx_dropped++; + ndev->stats.rx_dropped++; if (ret & VLSI_RX_OVER) - idev->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; if (ret & VLSI_RX_LENGTH) - idev->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (ret & VLSI_RX_FRAME) - idev->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (ret & VLSI_RX_CRC) - idev->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; } else if (ret > 0) { - idev->stats.rx_packets++; - idev->stats.rx_bytes += ret; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += ret; } } @@ -676,7 +674,7 @@ static void vlsi_rx_interrupt(struct net_device *ndev) if (ring_first(r) == NULL) { /* we are in big trouble, if this should ever happen */ - IRDA_ERROR("%s: rx ring exhausted!\n", __FUNCTION__); + IRDA_ERROR("%s: rx ring exhausted!\n", __func__); vlsi_ring_debug(r); } else @@ -687,6 +685,7 @@ static void vlsi_rx_interrupt(struct net_device *ndev) static void vlsi_unarm_rx(vlsi_irda_dev_t *idev) { + struct net_device *ndev = pci_get_drvdata(idev->pdev); struct vlsi_ring *r = idev->rx_ring; struct ring_descr *rd; int ret; @@ -697,7 +696,7 @@ static void vlsi_unarm_rx(vlsi_irda_dev_t *idev) if (rd_is_active(rd)) { rd_set_status(rd, 0); if (rd_get_count(rd)) { - IRDA_DEBUG(0, "%s - dropping rx packet\n", __FUNCTION__); + IRDA_DEBUG(0, "%s - dropping rx packet\n", __func__); ret = -VLSI_RX_DROP; } rd_set_count(rd, 0); @@ -712,21 +711,21 @@ static void vlsi_unarm_rx(vlsi_irda_dev_t *idev) if (ret < 0) { ret = -ret; - idev->stats.rx_errors++; + ndev->stats.rx_errors++; if (ret & VLSI_RX_DROP) - idev->stats.rx_dropped++; + ndev->stats.rx_dropped++; if (ret & VLSI_RX_OVER) - idev->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; if (ret & VLSI_RX_LENGTH) - idev->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (ret & VLSI_RX_FRAME) - idev->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (ret & VLSI_RX_CRC) - idev->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; } else if (ret > 0) { - idev->stats.rx_packets++; - idev->stats.rx_bytes += ret; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += ret; } } } @@ -772,7 +771,7 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) int fifocnt; baudrate = idev->new_baud; - IRDA_DEBUG(2, "%s: %d -> %d\n", __FUNCTION__, idev->baud, idev->new_baud); + IRDA_DEBUG(2, "%s: %d -> %d\n", __func__, idev->baud, idev->new_baud); if (baudrate == 4000000) { mode = IFF_FIR; config = IRCFG_FIR; @@ -789,7 +788,7 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) switch(baudrate) { default: IRDA_WARNING("%s: undefined baudrate %d - fallback to 9600!\n", - __FUNCTION__, baudrate); + __func__, baudrate); baudrate = 9600; /* fallthru */ case 2400: @@ -806,7 +805,7 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) fifocnt = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; if (fifocnt != 0) { - IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); + IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __func__, fifocnt); } outw(0, iobase+VLSI_PIO_IRENABLE); @@ -830,14 +829,14 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) config ^= IRENABLE_SIR_ON; if (config != (IRENABLE_PHYANDCLOCK|IRENABLE_ENRXST)) { - IRDA_WARNING("%s: failed to set %s mode!\n", __FUNCTION__, + IRDA_WARNING("%s: failed to set %s mode!\n", __func__, (mode==IFF_SIR)?"SIR":((mode==IFF_MIR)?"MIR":"FIR")); ret = -1; } else { if (inw(iobase+VLSI_PIO_PHYCTL) != nphyctl) { IRDA_WARNING("%s: failed to apply baudrate %d\n", - __FUNCTION__, baudrate); + __func__, baudrate); ret = -1; } else { @@ -849,14 +848,15 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) } if (ret) - vlsi_reg_debug(iobase,__FUNCTION__); + vlsi_reg_debug(iobase,__func__); return ret; } -static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) +static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb, + struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); struct vlsi_ring *r = idev->tx_ring; struct ring_descr *rd; unsigned long flags; @@ -915,7 +915,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) */ spin_unlock_irqrestore(&idev->lock, flags); dev_kfree_skb_any(skb); - return 0; + return NETDEV_TX_OK; } /* sanity checks - simply drop the packet */ @@ -954,8 +954,8 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) } for(;;) { do_gettimeofday(&now); - if (now.tv_sec > ready.tv_sec - || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) + if (now.tv_sec > ready.tv_sec || + (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) break; udelay(100); /* must not sleep here - called under netif_tx_lock! */ @@ -982,7 +982,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (len >= r->len-5) IRDA_WARNING("%s: possible buffer overflow with SIR wrapping!\n", - __FUNCTION__); + __func__); } else { /* hw deals with MIR/FIR mode wrapping */ @@ -993,7 +993,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) goto drop; } else - memcpy(rd->buf, skb->data, len); + skb_copy_from_linear_data(skb, rd->buf, len); } rd->skb = skb; /* remember skb for tx-complete stats */ @@ -1027,7 +1027,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) fifocnt = inw(ndev->base_addr+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; if (fifocnt != 0) { - IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); + IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __func__, fifocnt); } config = inw(iobase+VLSI_PIO_IRCFG); @@ -1036,34 +1036,33 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) wmb(); outw(0, iobase+VLSI_PIO_PROMPT); } - ndev->trans_start = jiffies; if (ring_put(r) == NULL) { netif_stop_queue(ndev); - IRDA_DEBUG(3, "%s: tx ring full - queue stopped\n", __FUNCTION__); + IRDA_DEBUG(3, "%s: tx ring full - queue stopped\n", __func__); } spin_unlock_irqrestore(&idev->lock, flags); - return 0; + return NETDEV_TX_OK; drop_unlock: spin_unlock_irqrestore(&idev->lock, flags); drop: - IRDA_WARNING("%s: dropping packet - %s\n", __FUNCTION__, msg); + IRDA_WARNING("%s: dropping packet - %s\n", __func__, msg); dev_kfree_skb_any(skb); - idev->stats.tx_errors++; - idev->stats.tx_dropped++; + ndev->stats.tx_errors++; + ndev->stats.tx_dropped++; /* Don't even think about returning NET_XMIT_DROP (=1) here! * In fact any retval!=0 causes the packet scheduler to requeue the * packet for later retry of transmission - which isn't exactly * what we want after we've just called dev_kfree_skb_any ;-) */ - return 0; + return NETDEV_TX_OK; } static void vlsi_tx_interrupt(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); struct vlsi_ring *r = idev->tx_ring; struct ring_descr *rd; unsigned iobase; @@ -1079,15 +1078,15 @@ static void vlsi_tx_interrupt(struct net_device *ndev) if (ret < 0) { ret = -ret; - idev->stats.tx_errors++; + ndev->stats.tx_errors++; if (ret & VLSI_TX_DROP) - idev->stats.tx_dropped++; + ndev->stats.tx_dropped++; if (ret & VLSI_TX_FIFO) - idev->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; } else if (ret > 0){ - idev->stats.tx_packets++; - idev->stats.tx_bytes += ret; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += ret; } } @@ -1106,7 +1105,7 @@ static void vlsi_tx_interrupt(struct net_device *ndev) fifocnt = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; if (fifocnt != 0) { IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", - __FUNCTION__, fifocnt); + __func__, fifocnt); } outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG); } @@ -1115,7 +1114,7 @@ static void vlsi_tx_interrupt(struct net_device *ndev) if (netif_queue_stopped(ndev) && !idev->new_baud) { netif_wake_queue(ndev); - IRDA_DEBUG(3, "%s: queue awoken\n", __FUNCTION__); + IRDA_DEBUG(3, "%s: queue awoken\n", __func__); } } @@ -1123,6 +1122,7 @@ static void vlsi_tx_interrupt(struct net_device *ndev) static void vlsi_unarm_tx(vlsi_irda_dev_t *idev) { + struct net_device *ndev = pci_get_drvdata(idev->pdev); struct vlsi_ring *r = idev->tx_ring; struct ring_descr *rd; int ret; @@ -1138,7 +1138,7 @@ static void vlsi_unarm_tx(vlsi_irda_dev_t *idev) dev_kfree_skb_any(rd->skb); rd->skb = NULL; } - IRDA_DEBUG(0, "%s - dropping tx packet\n", __FUNCTION__); + IRDA_DEBUG(0, "%s - dropping tx packet\n", __func__); ret = -VLSI_TX_DROP; } else @@ -1146,15 +1146,15 @@ static void vlsi_unarm_tx(vlsi_irda_dev_t *idev) if (ret < 0) { ret = -ret; - idev->stats.tx_errors++; + ndev->stats.tx_errors++; if (ret & VLSI_TX_DROP) - idev->stats.tx_dropped++; + ndev->stats.tx_dropped++; if (ret & VLSI_TX_FIFO) - idev->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; } else if (ret > 0){ - idev->stats.tx_packets++; - idev->stats.tx_bytes += ret; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += ret; } } @@ -1188,7 +1188,7 @@ static int vlsi_start_clock(struct pci_dev *pdev) if (count < 3) { if (clksrc == 1) { /* explicitly asked for PLL hence bail out */ IRDA_ERROR("%s: no PLL or failed to lock!\n", - __FUNCTION__); + __func__); clkctl = CLKCTL_CLKSTP; pci_write_config_byte(pdev, VLSI_PCI_CLKCTL, clkctl); return -1; @@ -1197,7 +1197,7 @@ static int vlsi_start_clock(struct pci_dev *pdev) clksrc = 3; /* fallback to 40MHz XCLK (OB800) */ IRDA_DEBUG(0, "%s: PLL not locked, fallback to clksrc=%d\n", - __FUNCTION__, clksrc); + __func__, clksrc); } else clksrc = 1; /* got successful PLL lock */ @@ -1262,14 +1262,14 @@ static inline void vlsi_clear_regs(unsigned iobase) static int vlsi_init_chip(struct pci_dev *pdev) { struct net_device *ndev = pci_get_drvdata(pdev); - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); unsigned iobase; u16 ptr; /* start the clock and clean the registers */ if (vlsi_start_clock(pdev)) { - IRDA_ERROR("%s: no valid clock source\n", __FUNCTION__); + IRDA_ERROR("%s: no valid clock source\n", __func__); return -1; } iobase = ndev->base_addr; @@ -1374,19 +1374,12 @@ static int vlsi_stop_hw(vlsi_irda_dev_t *idev) /**************************************************************/ -static struct net_device_stats * vlsi_get_stats(struct net_device *ndev) -{ - vlsi_irda_dev_t *idev = ndev->priv; - - return &idev->stats; -} - static void vlsi_tx_timeout(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); - vlsi_reg_debug(ndev->base_addr, __FUNCTION__); + vlsi_reg_debug(ndev->base_addr, __func__); vlsi_ring_debug(idev->tx_ring); if (netif_running(ndev)) @@ -1401,14 +1394,14 @@ static void vlsi_tx_timeout(struct net_device *ndev) if (vlsi_start_hw(idev)) IRDA_ERROR("%s: failed to restart hw - %s(%s) unusable!\n", - __FUNCTION__, PCIDEV_NAME(idev->pdev), ndev->name); + __func__, pci_name(idev->pdev), ndev->name); else netif_start_queue(ndev); } static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); struct if_irda_req *irq = (struct if_irda_req *) rq; unsigned long flags; u16 fifocnt; @@ -1446,7 +1439,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) break; default: IRDA_WARNING("%s: notsupp - cmd=%04x\n", - __FUNCTION__, cmd); + __func__, cmd); ret = -EOPNOTSUPP; } @@ -1458,7 +1451,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) static irqreturn_t vlsi_interrupt(int irq, void *dev_instance) { struct net_device *ndev = dev_instance; - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); unsigned iobase; u8 irintr; int boguscount = 5; @@ -1491,7 +1484,7 @@ static irqreturn_t vlsi_interrupt(int irq, void *dev_instance) if (boguscount <= 0) IRDA_MESSAGE("%s: too much work in interrupt!\n", - __FUNCTION__); + __func__); return IRQ_RETVAL(handled); } @@ -1499,12 +1492,12 @@ static irqreturn_t vlsi_interrupt(int irq, void *dev_instance) static int vlsi_open(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); int err = -EAGAIN; char hwname[32]; if (pci_request_regions(idev->pdev, drivername)) { - IRDA_WARNING("%s: io resource busy\n", __FUNCTION__); + IRDA_WARNING("%s: io resource busy\n", __func__); goto errout; } ndev->base_addr = pci_resource_start(idev->pdev,0); @@ -1519,7 +1512,7 @@ static int vlsi_open(struct net_device *ndev) if (request_irq(ndev->irq, vlsi_interrupt, IRQF_SHARED, drivername, ndev)) { IRDA_WARNING("%s: couldn't get IRQ: %d\n", - __FUNCTION__, ndev->irq); + __func__, ndev->irq); goto errout_io; } @@ -1540,7 +1533,7 @@ static int vlsi_open(struct net_device *ndev) netif_start_queue(ndev); - IRDA_MESSAGE("%s: device %s operational\n", __FUNCTION__, ndev->name); + IRDA_MESSAGE("%s: device %s operational\n", __func__, ndev->name); return 0; @@ -1558,7 +1551,7 @@ errout: static int vlsi_close(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); netif_stop_queue(ndev); @@ -1574,18 +1567,24 @@ static int vlsi_close(struct net_device *ndev) pci_release_regions(idev->pdev); - IRDA_MESSAGE("%s: device %s stopped\n", __FUNCTION__, ndev->name); + IRDA_MESSAGE("%s: device %s stopped\n", __func__, ndev->name); return 0; } +static const struct net_device_ops vlsi_netdev_ops = { + .ndo_open = vlsi_open, + .ndo_stop = vlsi_close, + .ndo_start_xmit = vlsi_hard_start_xmit, + .ndo_do_ioctl = vlsi_ioctl, + .ndo_tx_timeout = vlsi_tx_timeout, +}; + static int vlsi_irda_init(struct net_device *ndev) { - vlsi_irda_dev_t *idev = ndev->priv; + vlsi_irda_dev_t *idev = netdev_priv(ndev); struct pci_dev *pdev = idev->pdev; - SET_MODULE_OWNER(ndev); - ndev->irq = pdev->irq; ndev->base_addr = pci_resource_start(pdev,0); @@ -1593,9 +1592,9 @@ static int vlsi_irda_init(struct net_device *ndev) * see include file for details why we need these 2 masks, in this order! */ - if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW) - || pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) { - IRDA_ERROR("%s: aborting due to PCI BM-DMA address limitations\n", __FUNCTION__); + if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW) || + pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) { + IRDA_ERROR("%s: aborting due to PCI BM-DMA address limitations\n", __func__); return -1; } @@ -1616,12 +1615,7 @@ static int vlsi_irda_init(struct net_device *ndev) ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; ndev->if_port = IF_PORT_UNKNOWN; - ndev->open = vlsi_open; - ndev->stop = vlsi_close; - ndev->get_stats = vlsi_get_stats; - ndev->hard_start_xmit = vlsi_hard_start_xmit; - ndev->do_ioctl = vlsi_ioctl; - ndev->tx_timeout = vlsi_tx_timeout; + ndev->netdev_ops = &vlsi_netdev_ops; ndev->watchdog_timeo = 500*HZ/1000; /* max. allowed turn time for IrLAP */ SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1631,7 +1625,7 @@ static int vlsi_irda_init(struct net_device *ndev) /**************************************************************/ -static int __devinit +static int vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *ndev; @@ -1643,68 +1637,66 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->current_state = 0; /* hw must be running now */ IRDA_MESSAGE("%s: IrDA PCI controller %s detected\n", - drivername, PCIDEV_NAME(pdev)); + drivername, pci_name(pdev)); - if ( !pci_resource_start(pdev,0) - || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { - IRDA_ERROR("%s: bar 0 invalid", __FUNCTION__); + if ( !pci_resource_start(pdev,0) || + !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { + IRDA_ERROR("%s: bar 0 invalid", __func__); goto out_disable; } ndev = alloc_irdadev(sizeof(*idev)); if (ndev==NULL) { IRDA_ERROR("%s: Unable to allocate device memory.\n", - __FUNCTION__); + __func__); goto out_disable; } - idev = ndev->priv; + idev = netdev_priv(ndev); spin_lock_init(&idev->lock); - init_MUTEX(&idev->sem); - down(&idev->sem); + mutex_init(&idev->mtx); + mutex_lock(&idev->mtx); idev->pdev = pdev; if (vlsi_irda_init(ndev) < 0) goto out_freedev; if (register_netdev(ndev) < 0) { - IRDA_ERROR("%s: register_netdev failed\n", __FUNCTION__); + IRDA_ERROR("%s: register_netdev failed\n", __func__); goto out_freedev; } if (vlsi_proc_root != NULL) { struct proc_dir_entry *ent; - ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root); + ent = proc_create_data(ndev->name, S_IFREG|S_IRUGO, + vlsi_proc_root, VLSI_PROC_FOPS, ndev); if (!ent) { IRDA_WARNING("%s: failed to create proc entry\n", - __FUNCTION__); + __func__); } else { - ent->data = ndev; - ent->proc_fops = VLSI_PROC_FOPS; - ent->size = 0; + proc_set_size(ent, 0); } idev->proc_entry = ent; } IRDA_MESSAGE("%s: registered device %s\n", drivername, ndev->name); pci_set_drvdata(pdev, ndev); - up(&idev->sem); + mutex_unlock(&idev->mtx); return 0; out_freedev: - up(&idev->sem); + mutex_unlock(&idev->mtx); free_netdev(ndev); out_disable: pci_disable_device(pdev); out: - pci_set_drvdata(pdev, NULL); return -ENODEV; } -static void __devexit vlsi_irda_remove(struct pci_dev *pdev) +static void vlsi_irda_remove(struct pci_dev *pdev) { struct net_device *ndev = pci_get_drvdata(pdev); vlsi_irda_dev_t *idev; @@ -1716,19 +1708,17 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) unregister_netdev(ndev); - idev = ndev->priv; - down(&idev->sem); + idev = netdev_priv(ndev); + mutex_lock(&idev->mtx); if (idev->proc_entry) { remove_proc_entry(ndev->name, vlsi_proc_root); idev->proc_entry = NULL; } - up(&idev->sem); + mutex_unlock(&idev->mtx); free_netdev(ndev); - pci_set_drvdata(pdev, NULL); - - IRDA_MESSAGE("%s: %s removed\n", drivername, PCIDEV_NAME(pdev)); + IRDA_MESSAGE("%s: %s removed\n", drivername, pci_name(pdev)); } #ifdef CONFIG_PM @@ -1747,20 +1737,20 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) vlsi_irda_dev_t *idev; if (!ndev) { - IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + IRDA_ERROR("%s - %s: no netdevice\n", + __func__, pci_name(pdev)); return 0; } - idev = ndev->priv; - down(&idev->sem); + idev = netdev_priv(ndev); + mutex_lock(&idev->mtx); if (pdev->current_state != 0) { /* already suspended */ if (state.event > pdev->current_state) { /* simply go deeper */ pci_set_power_state(pdev, pci_choose_state(pdev, state)); pdev->current_state = state.event; } else - IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, PCIDEV_NAME(pdev), pdev->current_state, state.event); - up(&idev->sem); + IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __func__, pci_name(pdev), pdev->current_state, state.event); + mutex_unlock(&idev->mtx); return 0; } @@ -1776,7 +1766,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) pci_set_power_state(pdev, pci_choose_state(pdev, state)); pdev->current_state = state.event; idev->resume_ok = 1; - up(&idev->sem); + mutex_unlock(&idev->mtx); return 0; } @@ -1786,16 +1776,16 @@ static int vlsi_irda_resume(struct pci_dev *pdev) vlsi_irda_dev_t *idev; if (!ndev) { - IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + IRDA_ERROR("%s - %s: no netdevice\n", + __func__, pci_name(pdev)); return 0; } - idev = ndev->priv; - down(&idev->sem); + idev = netdev_priv(ndev); + mutex_lock(&idev->mtx); if (pdev->current_state == 0) { - up(&idev->sem); + mutex_unlock(&idev->mtx); IRDA_WARNING("%s - %s: already resumed\n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __func__, pci_name(pdev)); return 0; } @@ -1814,8 +1804,8 @@ static int vlsi_irda_resume(struct pci_dev *pdev) * now we explicitly set pdev->current_state = 0 after enabling the * device and independently resume_ok should catch any garbage config. */ - IRDA_WARNING("%s - hm, nothing to resume?\n", __FUNCTION__); - up(&idev->sem); + IRDA_WARNING("%s - hm, nothing to resume?\n", __func__); + mutex_unlock(&idev->mtx); return 0; } @@ -1825,7 +1815,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) netif_device_attach(ndev); } idev->resume_ok = 0; - up(&idev->sem); + mutex_unlock(&idev->mtx); return 0; } @@ -1837,7 +1827,7 @@ static struct pci_driver vlsi_irda_driver = { .name = drivername, .id_table = vlsi_irda_table, .probe = vlsi_irda_probe, - .remove = __devexit_p(vlsi_irda_remove), + .remove = vlsi_irda_remove, #ifdef CONFIG_PM .suspend = vlsi_irda_suspend, .resume = vlsi_irda_resume, @@ -1877,13 +1867,6 @@ static int __init vlsi_mod_init(void) * without procfs - it's not required for the driver to work. */ vlsi_proc_root = proc_mkdir(PROC_DIR, NULL); - if (vlsi_proc_root) { - /* protect registered procdir against module removal. - * Because we are in the module init path there's no race - * window after create_proc_entry (and no barrier needed). - */ - vlsi_proc_root->owner = THIS_MODULE; - } ret = pci_register_driver(&vlsi_irda_driver); diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index c37f0bc4c7f..56399204e68 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -18,9 +18,7 @@ * 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 + * along with this program; if not, see <http://www.gnu.org/licenses/>. * ********************************************************************/ @@ -41,39 +39,6 @@ #define PCI_CLASS_SUBCLASS_MASK 0xffff #endif -/* in recent 2.5 interrupt handlers have non-void return value */ -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -/* some stuff need to check kernelversion. Not all 2.5 stuff was present - * in early 2.5.x - the test is merely to separate 2.4 from 2.5 - */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -/* PDE() introduced in 2.5.4 */ -#ifdef CONFIG_PROC_FS -#define PDE(inode) ((inode)->i_private) -#endif - -/* irda crc16 calculation exported in 2.5.42 */ -#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) - -/* we use this for unified pci device name access */ -#define PCIDEV_NAME(pdev) ((pdev)->name) - -#else /* 2.5 or later */ - -/* whatever we get from the associated struct device - bus:slot:dev.fn id */ -#define PCIDEV_NAME(pdev) (pci_name(pdev)) - -#endif - /* ================================================================ */ /* non-standard PCI registers */ @@ -242,7 +207,7 @@ enum vlsi_pio_irintr { IRINTR_ACTEN = 0x80, /* activity interrupt enable */ IRINTR_ACTIVITY = 0x40, /* activity monitor (traffic detected) */ IRINTR_RPKTEN = 0x20, /* receive packet interrupt enable*/ - IRINTR_RPKTINT = 0x10, /* rx-packet transfered from fifo to memory finished */ + IRINTR_RPKTINT = 0x10, /* rx-packet transferred from fifo to memory finished */ IRINTR_TPKTEN = 0x08, /* transmit packet interrupt enable */ IRINTR_TPKTINT = 0x04, /* last bit of tx-packet+crc shifted to ir-pulser */ IRINTR_OE_EN = 0x02, /* UART rx fifo overrun error interrupt enable */ @@ -570,16 +535,16 @@ calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect) */ struct ring_descr_hw { - volatile u16 rd_count; /* tx/rx count [11:0] */ - u16 reserved; + volatile __le16 rd_count; /* tx/rx count [11:0] */ + __le16 reserved; union { - u32 addr; /* [23:0] of the buffer's busaddress */ + __le32 addr; /* [23:0] of the buffer's busaddress */ struct { u8 addr_res[3]; volatile u8 status; /* descriptor status */ - } __attribute__((packed)) rd_s; - } __attribute((packed)) rd_u; -} __attribute__ ((packed)); + } __packed rd_s; + } __packed rd_u; +} __packed; #define rd_addr rd_u.addr #define rd_status rd_u.rd_s.status @@ -628,7 +593,7 @@ struct ring_descr { static inline int rd_is_active(struct ring_descr *rd) { - return ((rd->hw->rd_status & RD_ACTIVE) != 0); + return (rd->hw->rd_status & RD_ACTIVE) != 0; } static inline void rd_activate(struct ring_descr *rd) @@ -650,7 +615,7 @@ static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s) */ if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { - IRDA_ERROR("%s: pci busaddr inconsistency!\n", __FUNCTION__); + IRDA_ERROR("%s: pci busaddr inconsistency!\n", __func__); dump_stack(); return; } @@ -745,7 +710,6 @@ static inline struct ring_descr *ring_get(struct vlsi_ring *r) typedef struct vlsi_irda_dev { struct pci_dev *pdev; - struct net_device_stats stats; struct irlap_cb *irlap; @@ -761,7 +725,7 @@ typedef struct vlsi_irda_dev { struct timeval last_rx; spinlock_t lock; - struct semaphore sem; + struct mutex mtx; u8 resume_ok; struct proc_dir_entry *proc_entry; @@ -773,7 +737,7 @@ typedef struct vlsi_irda_dev { /* the remapped error flags we use for returning from frame * post-processing in vlsi_process_tx/rx() after it was completed * by the hardware. These functions either return the >=0 number - * of transfered bytes in case of success or the negative (-) + * of transferred bytes in case of success or the negative (-) * of the or'ed error flags. */ diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 4212657fa4f..11dbdf36d9c 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -46,10 +46,11 @@ #include <linux/netdevice.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/rtnetlink.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <asm/io.h> #include <asm/dma.h> @@ -61,11 +62,6 @@ #include "w83977af.h" #include "w83977af_ir.h" -#ifdef CONFIG_ARCH_NETWINDER /* Adjust to NetWinder differences */ -#undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */ -#define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */ -#endif -#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */ #define CONFIG_USE_W977_PNP /* Currently needed */ #define PIO_MAX_SPEED 115200 @@ -93,7 +89,8 @@ static int w83977af_close(struct w83977af_ir *self); static int w83977af_probe(int iobase, int irq, int dma); 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 netdev_tx_t 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 w83977af_ir *self, int iobase); static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed); @@ -102,7 +99,6 @@ static int w83977af_is_receiving(struct w83977af_ir *self); static int w83977af_net_open(struct net_device *dev); static int w83977af_net_close(struct net_device *dev); static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev); /* * Function w83977af_init () @@ -114,9 +110,9 @@ static int __init w83977af_init(void) { int i; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s()\n", __func__ ); - for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) { + for (i=0; i < ARRAY_SIZE(dev_self) && io[i] < 2000; i++) { if (w83977af_open(i, io[i], irq[i], dma[i]) == 0) return 0; } @@ -133,7 +129,7 @@ static void __exit w83977af_cleanup(void) { int i; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s()\n", __func__ ); for (i=0; i < ARRAY_SIZE(dev_self); i++) { if (dev_self[i]) @@ -141,25 +137,32 @@ static void __exit w83977af_cleanup(void) } } +static const struct net_device_ops w83977_netdev_ops = { + .ndo_open = w83977af_net_open, + .ndo_stop = w83977af_net_close, + .ndo_start_xmit = w83977af_hard_xmit, + .ndo_do_ioctl = w83977af_net_ioctl, +}; + /* * Function w83977af_open (iobase, irq) * * Open driver instance * */ -int w83977af_open(int i, unsigned int iobase, unsigned int irq, - unsigned int dma) +static int w83977af_open(int i, unsigned int iobase, unsigned int irq, + unsigned int dma) { struct net_device *dev; struct w83977af_ir *self; int err; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s()\n", __func__ ); /* Lock the port that we need */ if (!request_region(iobase, CHIP_IO_EXTENT, driver_name)) { IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n", - __FUNCTION__ , iobase); + __func__ , iobase); return -ENODEV; } @@ -178,7 +181,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq, goto err_out; } - self = dev->priv; + self = netdev_priv(dev); spin_lock_init(&self->lock); @@ -208,23 +211,20 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq, /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out1; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); - self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + dma_zalloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; @@ -232,19 +232,11 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq, self->rx_buff.data = self->rx_buff.head; self->netdev = dev; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - - /* Override the network functions we need to use */ - dev->hard_start_xmit = w83977af_hard_xmit; - dev->open = w83977af_net_open; - dev->stop = w83977af_net_close; - dev->do_ioctl = w83977af_net_ioctl; - dev->get_stats = w83977af_net_get_stats; + dev->netdev_ops = &w83977_netdev_ops; err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdevice() failed!\n", __FUNCTION__); + IRDA_ERROR("%s(), register_netdevice() failed!\n", __func__); goto err_out3; } IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); @@ -276,7 +268,7 @@ static int w83977af_close(struct w83977af_ir *self) { int iobase; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s()\n", __func__ ); iobase = self->io.fir_base; @@ -297,7 +289,7 @@ static int w83977af_close(struct w83977af_ir *self) /* Release the PORT that this driver is using */ IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", - __FUNCTION__ , self->io.fir_base); + __func__ , self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) @@ -313,13 +305,13 @@ static int w83977af_close(struct w83977af_ir *self) return 0; } -int w83977af_probe( int iobase, int irq, int dma) +static int w83977af_probe(int iobase, int irq, int dma) { int version; int i; for (i=0; i < 2; i++) { - IRDA_DEBUG( 0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG( 0, "%s()\n", __func__ ); #ifdef CONFIG_USE_W977_PNP /* Enter PnP configuration mode */ w977_efm_enter(efbase[i]); @@ -336,7 +328,7 @@ int w83977af_probe( int iobase, int irq, int dma) w977_write_reg(0x74, dma+1, efbase[i]); #else w977_write_reg(0x74, dma, efbase[i]); -#endif /*CONFIG_ARCH_NETWINDER */ +#endif /* CONFIG_ARCH_NETWINDER */ w977_write_reg(0x75, 0x04, efbase[i]); /* Disable Tx DMA */ /* Set append hardware CRC, enable IR bank selection */ @@ -406,13 +398,13 @@ int w83977af_probe( int iobase, int irq, int dma) return 0; } else { /* Try next extented function register address */ - IRDA_DEBUG( 0, "%s(), Wrong chip version", __FUNCTION__ ); + IRDA_DEBUG( 0, "%s(), Wrong chip version", __func__ ); } } return -1; } -void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) +static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) { int ir_mode = HCR_SIR; int iobase; @@ -442,19 +434,19 @@ void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) case 115200: outb(0x01, iobase+ABLL); break; case 576000: ir_mode = HCR_MIR_576; - IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __func__ ); break; case 1152000: ir_mode = HCR_MIR_1152; - IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __func__ ); break; case 4000000: ir_mode = HCR_FIR; - IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __func__ ); break; default: ir_mode = HCR_FIR; - IRDA_DEBUG(0, "%s(), unknown baud rate of %d\n", __FUNCTION__ , speed); + IRDA_DEBUG(0, "%s(), unknown baud rate of %d\n", __func__ , speed); break; } @@ -492,7 +484,8 @@ void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) * Sets up a DMA transfer to send the current frame. * */ -int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, + struct net_device *dev) { struct w83977af_ir *self; __s32 speed; @@ -500,11 +493,11 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) __u8 set; int mtt; - self = (struct w83977af_ir *) dev->priv; + self = netdev_priv(dev); iobase = self->io.fir_base; - IRDA_DEBUG(4, "%s(%ld), skb->len=%d\n", __FUNCTION__ , jiffies, + IRDA_DEBUG(4, "%s(%ld), skb->len=%d\n", __func__ , jiffies, (int) skb->len); /* Lock transmit buffer */ @@ -516,9 +509,8 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* Check for empty frame */ if (!skb->len) { w83977af_change_speed(self, speed); - dev->trans_start = jiffies; dev_kfree_skb(skb); - return 0; + return NETDEV_TX_OK; } else self->new_speed = speed; } @@ -529,30 +521,11 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* Decide if we should use PIO or DMA transfer */ if (self->io.speed > PIO_MAX_SPEED) { self->tx_buff.data = self->tx_buff.head; - memcpy(self->tx_buff.data, skb->data, skb->len); + skb_copy_from_linear_data(skb, self->tx_buff.data, skb->len); self->tx_buff.len = skb->len; mtt = irda_get_mtt(skb); -#ifdef CONFIG_USE_INTERNAL_TIMER - if (mtt > 50) { - /* Adjust for timer resolution */ - mtt /= 1000+1; - - /* Setup timer */ - switch_bank(iobase, SET4); - outb(mtt & 0xff, iobase+TMRL); - outb((mtt >> 8) & 0x0f, iobase+TMRH); - - /* Start timer */ - outb(IR_MSL_EN_TMR, iobase+IR_MSL); - self->io.direction = IO_XMIT; - - /* Enable timer interrupt */ - switch_bank(iobase, SET0); - outb(ICR_ETMRI, iobase+ICR); - } else { -#endif - IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __FUNCTION__ , jiffies, mtt); + IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt); if (mtt) udelay(mtt); @@ -560,9 +533,6 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) switch_bank(iobase, SET0); outb(ICR_EDMAI, iobase+ICR); w83977af_dma_write(self, iobase); -#ifdef CONFIG_USE_INTERNAL_TIMER - } -#endif } else { self->tx_buff.data = self->tx_buff.head; self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, @@ -572,13 +542,12 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) switch_bank(iobase, SET0); outb(ICR_ETXTHI, iobase+ICR); } - dev->trans_start = jiffies; dev_kfree_skb(skb); /* Restore set register */ outb(set, iobase+SSR); - return 0; + return NETDEV_TX_OK; } /* @@ -590,11 +559,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) 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 - IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__ , self->tx_buff.len); + IRDA_DEBUG(4, "%s(), len=%d\n", __func__ , self->tx_buff.len); /* Save current set */ set = inb(iobase+SSR); @@ -606,30 +571,13 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase) /* Choose transmit DMA channel */ switch_bank(iobase, SET2); outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1); -#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS - spin_lock_irqsave(&self->lock, flags); - - 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, self->tx_buff_dma); - set_dma_count(self->io.dma, self->tx_buff.len); -#else irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, DMA_MODE_WRITE); -#endif 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(self->io.dma); - spin_unlock_irqrestore(&self->lock, flags); -#else outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR); -#endif /* Restore set register */ outb(set, iobase+SSR); @@ -646,7 +594,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 set; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s()\n", __func__ ); /* Save current bank */ set = inb(iobase+SSR); @@ -654,11 +602,11 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) switch_bank(iobase, SET0); if (!(inb_p(iobase+USR) & USR_TSRE)) { IRDA_DEBUG(4, - "%s(), warning, FIFO not empty yet!\n", __FUNCTION__ ); + "%s(), warning, FIFO not empty yet!\n", __func__ ); fifo_size -= 17; IRDA_DEBUG(4, "%s(), %d bytes left in tx fifo\n", - __FUNCTION__ , fifo_size); + __func__ , fifo_size); } /* Fill FIFO with current frame */ @@ -668,7 +616,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } IRDA_DEBUG(4, "%s(), fifo_size %d ; %d sent of %d\n", - __FUNCTION__ , fifo_size, actual, len); + __func__ , fifo_size, actual, len); /* Restore bank */ outb(set, iobase+SSR); @@ -688,7 +636,7 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self) int iobase; __u8 set; - IRDA_DEBUG(4, "%s(%ld)\n", __FUNCTION__ , jiffies); + IRDA_DEBUG(4, "%s(%ld)\n", __func__ , jiffies); IRDA_ASSERT(self != NULL, return;); @@ -701,17 +649,17 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self) switch_bank(iobase, SET0); outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR); - /* Check for underrrun! */ + /* Check for underrun! */ if (inb(iobase+AUDR) & AUDR_UNDR) { - IRDA_DEBUG(0, "%s(), Transmit underrun!\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s(), Transmit underrun!\n", __func__ ); - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Clear bit, by writing 1 to it */ outb(AUDR_UNDR, iobase+AUDR); } else - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->new_speed) { @@ -734,17 +682,17 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self) * if it starts to receive a frame. * */ -int w83977af_dma_receive(struct w83977af_ir *self) +static int w83977af_dma_receive(struct w83977af_ir *self) { int iobase; __u8 set; -#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS +#ifdef CONFIG_ARCH_NETWINDER unsigned long flags; __u8 hcr; #endif IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(4, "%s\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s\n", __func__ ); iobase= self->io.fir_base; @@ -763,7 +711,7 @@ int w83977af_dma_receive(struct w83977af_ir *self) self->io.direction = IO_RECV; self->rx_buff.data = self->rx_buff.head; -#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS +#ifdef CONFIG_ARCH_NETWINDER spin_lock_irqsave(&self->lock, flags); disable_dma(self->io.dma); @@ -786,7 +734,7 @@ int w83977af_dma_receive(struct w83977af_ir *self) /* Enable DMA */ switch_bank(iobase, SET0); -#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS +#ifdef CONFIG_ARCH_NETWINDER hcr = inb(iobase+HCR); outb(hcr | HCR_EN_DMA, iobase+HCR); enable_dma(self->io.dma); @@ -806,7 +754,7 @@ int w83977af_dma_receive(struct w83977af_ir *self) * Finished with receiving a frame * */ -int w83977af_dma_receive_complete(struct w83977af_ir *self) +static int w83977af_dma_receive_complete(struct w83977af_ir *self) { struct sk_buff *skb; struct st_fifo *st_fifo; @@ -815,7 +763,7 @@ int w83977af_dma_receive_complete(struct w83977af_ir *self) __u8 set; __u8 status; - IRDA_DEBUG(4, "%s\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s\n", __func__ ); st_fifo = &self->st_fifo; @@ -849,53 +797,40 @@ int w83977af_dma_receive_complete(struct w83977af_ir *self) if (status & FS_FO_ERR_MSK) { if (status & FS_FO_LST_FR) { /* Add number of lost frames to stats */ - self->stats.rx_errors += len; + self->netdev->stats.rx_errors += len; } else { /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & FS_FO_MX_LEX) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (status & FS_FO_PHY_ERR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (status & FS_FO_CRC_ERR) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FS_FO_RX_OV) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; if (status & FS_FO_FSF_OV) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; } else { /* Check if we have transferred all data to memory */ switch_bank(iobase, SET0); if (inb(iobase+USR) & USR_RDR) { -#ifdef CONFIG_USE_INTERNAL_TIMER - /* Put this entry back in fifo */ - st_fifo->head--; - st_fifo->len++; - st_fifo->entries[st_fifo->head].status = status; - st_fifo->entries[st_fifo->head].len = len; - - /* Restore set register */ - outb(set, iobase+SSR); - - return FALSE; /* I'll be back! */ -#else udelay(80); /* Should be enough!? */ -#endif } skb = dev_alloc_skb(len+1); if (skb == NULL) { printk(KERN_INFO - "%s(), memory squeeze, dropping frame.\n", __FUNCTION__); + "%s(), memory squeeze, dropping frame.\n", __func__); /* Restore set register */ outb(set, iobase+SSR); @@ -908,21 +843,24 @@ int w83977af_dma_receive_complete(struct w83977af_ir *self) /* Copy frame without CRC */ if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, self->rx_buff.data, len-2); + skb_copy_to_linear_data(skb, + self->rx_buff.data, + len - 2); } else { skb_put(skb, len-4); - memcpy(skb->data, self->rx_buff.data, len-4); + skb_copy_to_linear_data(skb, + self->rx_buff.data, + len - 4); } /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_packets++; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); - self->netdev->last_rx = jiffies; } } /* Restore set register */ @@ -942,7 +880,7 @@ static void w83977af_pio_receive(struct w83977af_ir *self) __u8 byte = 0x00; int iobase; - IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(4, "%s()\n", __func__ ); IRDA_ASSERT(self != NULL, return;); @@ -951,7 +889,7 @@ static void w83977af_pio_receive(struct w83977af_ir *self) /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RBR); - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, byte); } while (inb(iobase+USR) & USR_RDR); /* Data available */ } @@ -969,7 +907,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) __u8 set; int iobase; - IRDA_DEBUG(4, "%s(), isr=%#x\n", __FUNCTION__ , isr); + IRDA_DEBUG(4, "%s(), isr=%#x\n", __func__ , isr); iobase = self->io.fir_base; /* Transmit FIFO low on data */ @@ -994,7 +932,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) outb(AUDR_SFEND, iobase+AUDR); outb(set, iobase+SSR); - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; /* Feed me more packets */ netif_wake_queue(self->netdev); @@ -1006,7 +944,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) /* Check if we need to change the speed? */ if (self->new_speed) { IRDA_DEBUG(2, - "%s(), Changing speed!\n", __FUNCTION__ ); + "%s(), Changing speed!\n", __func__ ); w83977af_change_speed(self, self->new_speed); self->new_speed = 0; } @@ -1118,7 +1056,7 @@ static irqreturn_t w83977af_interrupt(int irq, void *dev_id) __u8 set, icr, isr; int iobase; - self = dev->priv; + self = netdev_priv(dev); iobase = self->io.fir_base; @@ -1188,10 +1126,10 @@ static int w83977af_net_open(struct net_device *dev) char hwname[32]; __u8 set; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s()\n", __func__ ); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct w83977af_ir *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); @@ -1206,7 +1144,7 @@ static int w83977af_net_open(struct net_device *dev) * and clean up on failure. */ if (request_dma(self->io.dma, dev->name)) { - free_irq(self->io.irq, self); + free_irq(self->io.irq, dev); return -EAGAIN; } @@ -1251,11 +1189,11 @@ static int w83977af_net_close(struct net_device *dev) int iobase; __u8 set; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(0, "%s()\n", __func__ ); IRDA_ASSERT(dev != NULL, return -1;); - self = (struct w83977af_ir *) dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return 0;); @@ -1302,11 +1240,11 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__ , dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__ , dev->name, cmd); spin_lock_irqsave(&self->lock, flags); @@ -1336,13 +1274,6 @@ out: return ret; } -static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev) -{ - struct w83977af_ir *self = (struct w83977af_ir *) dev->priv; - - return &self->stats; -} - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h index 0b7661deafe..fefe9b11e20 100644 --- a/drivers/net/irda/w83977af_ir.h +++ b/drivers/net/irda/w83977af_ir.h @@ -16,7 +16,7 @@ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * - * Neither Dag Brattli nor University of Tromsø admit liability nor + * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * @@ -172,7 +172,6 @@ struct w83977af_ir { int tx_len; /* Number of frames in tx_buff */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ |
