diff options
Diffstat (limited to 'drivers')
145 files changed, 2910 insertions, 2131 deletions
diff --git a/drivers/acorn/block/Makefile b/drivers/acorn/block/Makefile index 9f5953b39..481d7f328 100644 --- a/drivers/acorn/block/Makefile +++ b/drivers/acorn/block/Makefile @@ -9,26 +9,45 @@ # parent makefile. # -L_TARGET := acorn-block.a -L_OBJS := -M_OBJS := -MOD_LIST_NAME := ACORN_BLOCK_MODULES - -ifeq ($(CONFIG_BLK_DEV_FD1772),y) - L_OBJS += fd1772.o fd1772dma.o -else - ifeq ($(CONFIG_BLK_DEV_FD1772),m) - M_OBJS += fd1772_mod.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_MFM),y) - L_OBJS += mfmhd.o mfm.o -else - ifeq ($(CONFIG_BLK_DEV_MFM),m) - M_OBJS += mfmhd_mod.o - endif -endif +L_TARGET := acorn-block.a +MOD_LIST_NAME := ACORN_BLOCK_MODULES + +obj-y := +obj-m := +obj-n := +obj- := + +export-objs := +list-multi := fd1772_mod.o mfmhd_mod.o +fd1772_mod-objs := fd1772.o fd1772dma.o +mfmhd_mod-objs := mfmhd.o mfm.o + +obj-$(CONFIG_BLK_DEV_FD1772) += fd1772_mod.o +obj-$(CONFIG_BLK_DEV_MFM) += mfmhd.o mfm.o + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are intermediate files used to build the multi's. + +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) + +# Take multi-part drivers out of obj-y and put components in. + +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. + +L_OBJS := $(filter-out $(export-objs), $(obj-y)) +LX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c index 0d65a1493..f2e2f995c 100644 --- a/drivers/acorn/block/mfmhd.c +++ b/drivers/acorn/block/mfmhd.c @@ -1280,7 +1280,6 @@ void mfm_setup(char *str, int *ints) * Set the CHS from the ADFS boot block if it is present. This is not ideal * since if there are any non-ADFS partitions on the disk, this won't work! * Hence, I want to get rid of this... - * Please, do. It does seriously sucking things. */ void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads, unsigned long discsize, unsigned int secsize) diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile index 2d08a90cb..24bab45a9 100644 --- a/drivers/acorn/char/Makefile +++ b/drivers/acorn/char/Makefile @@ -10,37 +10,35 @@ # O_TARGET := acorn-char.o -M_OBJS := -O_OBJS := i2c.o pcf8583.o - -O_OBJS_arc := keyb_arc.o -O_OBJS_a5k := keyb_arc.o -O_OBJS_rpc := keyb_ps2.o - -ifeq ($(CONFIG_RPCMOUSE),y) - OX_OBJS += mouse_rpc.o -else - ifeq ($(CONFIG_RPCSMOUSE),m) - MX_OBJS += mouse_rpc.o - endif -endif - -ifeq ($(CONFIG_ATOMWIDE_SERIAL),y) - O_OBJS += serial-atomwide.o -else - ifeq ($(CONFIG_ATOMWIDE_SERIAL),m) - O_OBJS += serial-atomwide.o - endif -endif - -ifeq ($(CONFIG_DUALSP_SERIAL),y) - O_OBJS += serial-dualsp.o -else - ifeq ($(CONFIG_DUALSP_SERIAL),m) - M_OBJS += serial-dualsp.o - endif -endif - -O_OBJS += $(O_OBJS_$(MACHINE)) + +O_OBJS := +OX_OBJS := +M_OBJS := +MX_OBJS := + +# Object file lists. + +obj-y := i2c.o pcf8583.o +obj-m := +obj-n := +obj- := + +# All the objects that export symbols. +export-objs := mouse_rpc.o + +obj-arc := keyb_arc.o +obj-a5k := keyb_arc.o +obj-rpc := keyb_ps2.o + +obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o +obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o +obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o + +obj-y += $(obj-$(MACHINE)) + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff --git a/drivers/acorn/net/Makefile b/drivers/acorn/net/Makefile index 5f79d1ab8..27811e92f 100644 --- a/drivers/acorn/net/Makefile +++ b/drivers/acorn/net/Makefile @@ -4,32 +4,18 @@ # L_TARGET := acorn-net.a -L_OBJS := -M_OBJS := MOD_LIST_NAME := ACORN_NET_MODULES -ifeq ($(CONFIG_ARM_ETHER1),y) - L_OBJS += ether1.o -else - ifeq ($(CONFIG_ARM_ETHER1),m) - M_OBJS += ether1.o - endif -endif +obj-y := +obj-m := +obj-n := +obj- := -ifeq ($(CONFIG_ARM_ETHER3),y) - L_OBJS += ether3.o -else - ifeq ($(CONFIG_ARM_ETHER3),m) - M_OBJS += ether3.o - endif -endif +obj-$(CONFIG_ARM_ETHER1) += ether1.o +obj-$(CONFIG_ARM_ETHER3) += ether3.o +obj-$(CONFIG_ARM_ETHERH) += etherh.o -ifeq ($(CONFIG_ARM_ETHERH),y) - L_OBJS += etherh.o -else - ifeq ($(CONFIG_ARM_ETHERH),m) - M_OBJS += etherh.o - endif -endif +L_OBJS := $(obj-y) +M_OBJS := $(obj-m) include $(TOPDIR)/Rules.make diff --git a/drivers/acorn/scsi/Makefile b/drivers/acorn/scsi/Makefile index ee7152a44..a2c94a0d5 100644 --- a/drivers/acorn/scsi/Makefile +++ b/drivers/acorn/scsi/Makefile @@ -2,109 +2,50 @@ # Makefile for drivers/acorn/scsi # -L_TARGET := acorn-scsi.a -L_OBJS := -LX_OBJS := -M_OBJS := -MX_OBJS := -MOD_LIST_NAME := ACORN_SCSI_MODULES +L_TARGET := acorn-scsi.a +MOD_LIST_NAME := ACORN_SCSI_MODULES -CONFIG_QUEUE_BUILTIN := -CONFIG_FAS216_BUILTIN := -CONFIG_QUEUE_MODULE := -CONFIG_FAS216_MODULE := +obj-y := +obj-m := +obj-n := +obj- := -ifeq ($(CONFIG_SCSI_ACORNSCSI_3),y) - L_OBJS += acornscsi.o acornscsi-io.o - CONFIG_QUEUE_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_ACORNSCSI_3),m) - M_OBJS += acornscsi_mod.o - CONFIG_QUEUE_MODULE=y - endif -endif +export-objs := fas216.o queue.o msgqueue.o +list-multi := acornscsi_mod.o +acornscsi_mod-objs := acornscsi.o acornscsi-io.o -ifeq ($(CONFIG_SCSI_ARXESCSI),y) - L_OBJS += arxescsi.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_ARXESCSI),m) - M_OBJS += arxescsi.o - CONFIG_FAS216_MODULE=y - endif -endif +obj-$(CONFIG_SCSI_ACORNSCSI_3) += acornscsi_mod.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_ARXESCSI) += arxescsi.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_CUMANA_1) += cumana_1.o +obj-$(CONFIG_SCSI_CUMANA_2) += cumana_2.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_ECOSCSI) += ecoscsi.o +obj-$(CONFIG_SCSI_OAK1) += oak.o +obj-$(CONFIG_SCSI_POWERTECSCSI) += powertec.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_EESOXSCSI) += eesox.o fas216.o queue.o msgqueue.o -ifeq ($(CONFIG_SCSI_CUMANA_1),y) - L_OBJS += cumana_1.o -else - ifeq ($(CONFIG_SCSI_CUMANA_1),m) - M_OBJS += cumana_1.o - endif -endif +# Extract lists of the multi-part drivers. +# The 'int-*' lists are intermediate files used to build the multi's. -ifeq ($(CONFIG_SCSI_CUMANA_2),y) - L_OBJS += cumana_2.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_CUMANA_2),m) - M_OBJS += cumana_2.o - CONFIG_FAS216_MODULE=y - endif -endif +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) -ifeq ($(CONFIG_SCSI_ECOSCSI),y) - L_OBJS += ecoscsi.o -else - ifeq ($(CONFIG_SCSI_ECOSCSI),m) - M_OBJS += ecoscsi.o - endif -endif +# Files that are both resident and modular; remove from modular. -ifeq ($(CONFIG_SCSI_OAK1),y) - L_OBJS += oak.o -else - ifeq ($(CONFIG_SCSI_OAK1),m) - M_OBJS += oak.o - endif -endif +obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) -ifeq ($(CONFIG_SCSI_POWERTECSCSI),y) - L_OBJS += powertec.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_POWERTECSCSI),m) - M_OBJS += powertec.o - CONFIG_FAS216_MODULE=y - endif -endif +# Take multi-part drivers out of obj-y and put components in. -ifeq ($(CONFIG_SCSI_EESOXSCSI),y) - L_OBJS += eesox.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_EESOXSCSI),m) - M_OBJS += eesox.o - CONFIG_FAS216_MODULE=y - endif -endif +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) -ifeq ($(CONFIG_FAS216_BUILTIN),y) - LX_OBJS += fas216.o - CONFIG_QUEUE_BUILTIN=y -else - ifeq ($(CONFIG_FAS216_MODULE),y) - MX_OBJS += fas216.o - CONFIG_QUEUE_MODULE=y - endif -endif +# Translate to Rules.make lists. -ifeq ($(CONFIG_QUEUE_BUILTIN),y) - LX_OBJS += queue.o msgqueue.o -else - ifeq ($(CONFIG_QUEUE_MODULE),y) - MX_OBJS += queue.o msgqueue.o - endif -endif +L_OBJS := $(filter-out $(export-objs), $(obj-y)) +LX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff --git a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c index 2a0ee9d1c..cc1701708 100644 --- a/drivers/acorn/scsi/arxescsi.c +++ b/drivers/acorn/scsi/arxescsi.c @@ -24,8 +24,8 @@ #include <linux/proc_fs.h> #include <linux/unistd.h> #include <linux/stat.h> +#include <linux/delay.h> -#include <asm/delay.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/drivers/block/Config.in b/drivers/block/Config.in index d4ba3f06b..64432480b 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -27,6 +27,7 @@ else if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE fi + dep_tristate ' PCMCIA IDE support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index d912f8c08..1495809d6 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -3583,7 +3583,7 @@ static void DAC960_DestroyProcEntries(void) int init_module(void) { - int ControllerNumber, LogicalDriveNumber; + int ControllerNumber; DAC960_Initialize(); if (DAC960_ActiveControllerCount == 0) return -1; for (ControllerNumber = 0; diff --git a/drivers/block/Makefile b/drivers/block/Makefile index be158ca1a..9e00cfa89 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -262,6 +262,14 @@ endif ############ +ifeq ($(CONFIG_BLK_DEV_IDECS),y) +L_OBJS += ide-cs.o +else + ifeq ($(CONFIG_BLK_DEV_IDECS),m) + M_OBJS += ide-cs.o + endif +endif + ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) L_OBJS += ide-disk.o else diff --git a/drivers/block/amd7409.c b/drivers/block/amd7409.c index b12847843..7d2018029 100644 --- a/drivers/block/amd7409.c +++ b/drivers/block/amd7409.c @@ -6,6 +6,7 @@ * */ +#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> diff --git a/drivers/block/cmd64x.c b/drivers/block/cmd64x.c index 4e98893ec..40b5c7797 100644 --- a/drivers/block/cmd64x.c +++ b/drivers/block/cmd64x.c @@ -11,6 +11,7 @@ * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) */ +#include <linux/config.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/delay.h> diff --git a/drivers/block/cpqarray.h b/drivers/block/cpqarray.h index fa51d3dee..fedbb46ac 100644 --- a/drivers/block/cpqarray.h +++ b/drivers/block/cpqarray.h @@ -30,7 +30,7 @@ #include <linux/locks.h> #include <linux/malloc.h> #include <linux/proc_fs.h> -#include <linux/md.h> +#include <linux/raid/md.h> #include <linux/timer.h> #endif diff --git a/drivers/block/cs5530.c b/drivers/block/cs5530.c index 0f2f04990..bb68f7b2e 100644 --- a/drivers/block/cs5530.c +++ b/drivers/block/cs5530.c @@ -8,6 +8,7 @@ * by the nice folks at National Semiconductor. */ +#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> diff --git a/drivers/block/ide-pci.c b/drivers/block/ide-pci.c index 2ddbbc8bd..f667ee6dd 100644 --- a/drivers/block/ide-pci.c +++ b/drivers/block/ide-pci.c @@ -243,9 +243,12 @@ extern void ide_init_sis5513(ide_hwif_t *); #ifdef CONFIG_BLK_DEV_SL82C105 extern void ide_init_sl82c105(ide_hwif_t *); +extern void ide_dmacapable_sl82c105(ide_hwif_t *, unsigned long); #define INIT_W82C105 &ide_init_sl82c105 +#define DMA_W82C105 &ide_dmacapable_sl82c105 #else #define INIT_W82C105 IDE_IGNORE +#define DMA_W82C105 NULL #endif #ifdef CONFIG_BLK_DEV_TRM290 @@ -316,7 +319,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_TRM290, "TRM290", NULL, NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_NS87415, "NS87415", NULL, NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AEC6210, "AEC6210", PCI_AEC6210, NULL, INIT_AEC6210, DMA_AEC6210, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, - {DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, NULL, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, + {DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, {DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, diff --git a/drivers/block/piix.c b/drivers/block/piix.c index 4c2d94c99..97e57fa55 100644 --- a/drivers/block/piix.c +++ b/drivers/block/piix.c @@ -85,8 +85,8 @@ #include <linux/pci.h> #include <linux/hdreg.h> #include <linux/ide.h> +#include <linux/delay.h> -#include <asm/delay.h> #include <asm/io.h> #include "ide_modes.h" diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 19f485df0..9686f05b6 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -87,7 +87,7 @@ void rd_load(void); static int crd_load(struct file *fp, struct file *outfp); #ifdef CONFIG_BLK_DEV_INITRD -static int initrd_users = 0; +static int initrd_users; #endif #endif @@ -122,13 +122,13 @@ int rd_blocksize = BLOCK_SIZE; /* Size of the RAM disks */ #ifndef MODULE -int rd_doload = 0; /* 1 = load RAM disk, 0 = don't load */ +int rd_doload; /* 1 = load RAM disk, 0 = don't load */ int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */ -int rd_image_start = 0; /* starting block # of image */ +int rd_image_start; /* starting block # of image */ #ifdef CONFIG_BLK_DEV_INITRD -unsigned long initrd_start,initrd_end; +unsigned long initrd_start, initrd_end; int mount_initrd = 1; /* zero if initrd should not be mounted */ -int initrd_below_start_ok = 0; +int initrd_below_start_ok; static int __init no_initrd(char *str) { @@ -293,11 +293,15 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un switch (cmd) { case BLKFLSBUF: - if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; /* special: we want to release the ramdisk memory, it's not like with the other blockdevices where this ioctl only flushes away the buffer cache. */ + if ((atomic_read(&inode->i_bdev->bd_openers) > 2)) + return -EBUSY; destroy_buffers(inode->i_rdev); + rd_blocksizes[minor] = 0; break; case BLKGETSIZE: /* Return device size */ @@ -338,6 +342,8 @@ static int initrd_release(struct inode *inode,struct file *file) extern void free_initrd_mem(unsigned long, unsigned long); if (--initrd_users) return 0; + blkdev_put(inode->i_bdev, BDEV_FILE); + iput(inode); free_initrd_mem(initrd_start, initrd_end); initrd_start = 0; return 0; @@ -366,7 +372,6 @@ static int rd_open(struct inode * inode, struct file * filp) if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS) return -ENXIO; - filp->f_op = &def_blk_fops; MOD_INC_USE_COUNT; return 0; @@ -389,12 +394,18 @@ static void __exit rd_cleanup (void) { int i; - for (i = 0 ; i < NUM_RAMDISKS; i++) + for (i = 0 ; i < NUM_RAMDISKS; i++) { + struct block_device *bdev; + bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i))); + atomic_dec(&bdev->bd_openers); destroy_buffers(MKDEV(MAJOR_NR, i)); + } devfs_unregister (devfs_handle); unregister_blkdev( MAJOR_NR, "ramdisk" ); blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); + blksize_size[MAJOR_NR] = NULL; + blk_size[MAJOR_NR] = NULL; } /* This is the registration and initialization section of the RAM disk driver */ @@ -432,16 +443,21 @@ int __init rd_init (void) hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */ blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */ - blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */ - for (i = 0; i < NUM_RAMDISKS; i++) + for (i = 0; i < NUM_RAMDISKS; i++) { + struct block_device *bdev; register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &fd_fops, rd_size<<1); + bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i))); + atomic_inc(&bdev->bd_openers); /* avoid invalidate_buffers() */ + } #ifdef CONFIG_BLK_DEV_INITRD /* We ought to separate initrd operations here */ register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &fd_fops, rd_size<<1); #endif + blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */ + /* rd_size is given in kB */ printk("RAMDISK driver initialized: " "%d RAM disks of %dK size %d blocksize\n", @@ -584,26 +600,28 @@ static void __init rd_load_image(kdev_t device, int offset, int unit) ram_device = MKDEV(MAJOR_NR, unit); + if ((inode = get_empty_inode()) == NULL) + return; memset(&infile, 0, sizeof(infile)); memset(&in_dentry, 0, sizeof(in_dentry)); - inode = get_empty_inode(); - inode->i_rdev = device; - inode->i_bdev = bdget(kdev_t_to_nr(device)); infile.f_mode = 1; /* read only */ infile.f_dentry = &in_dentry; in_dentry.d_inode = inode; + infile.f_op = &def_blk_fops; + init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device)); + if ((out_inode = get_empty_inode()) == NULL) + goto free_inode; memset(&outfile, 0, sizeof(outfile)); memset(&out_dentry, 0, sizeof(out_dentry)); - out_inode = get_empty_inode(); - out_inode->i_rdev = ram_device; - out_inode->i_bdev = bdget(kdev_t_to_nr(ram_device)); outfile.f_mode = 3; /* read/write */ outfile.f_dentry = &out_dentry; out_dentry.d_inode = out_inode; + outfile.f_op = &def_blk_fops; + init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device)); if (blkdev_open(inode, &infile) != 0) - goto free_inodes; + goto free_inode; if (blkdev_open(out_inode, &outfile) != 0) goto free_inodes; @@ -697,9 +715,12 @@ done: if (infile.f_op->release) infile.f_op->release(inode, &infile); set_fs(fs); -free_inodes: - iput(inode); + return; +free_inodes: /* free inodes on error */ iput(out_inode); + blkdev_put(inode->i_bdev, BDEV_FILE); +free_inode: + iput(inode); } diff --git a/drivers/block/sl82c105.c b/drivers/block/sl82c105.c index 29f006682..483a98fde 100644 --- a/drivers/block/sl82c105.c +++ b/drivers/block/sl82c105.c @@ -26,6 +26,8 @@ #include "ide_modes.h" +extern char *ide_xfer_verbose (byte xfer_rate); + #ifdef CONFIG_ARCH_NETWINDER /* * Convert a PIO mode and cycle time to the required on/off @@ -50,42 +52,7 @@ static unsigned int get_timing_sl82c105(ide_pio_data_t *p) if (cmd_off == 0) cmd_off = 1; - return (cmd_on - 1) << 8 | (cmd_off - 1); -} - -/* - * Tell the drive to enable the specified PIO mode. - * This should be in ide.c, maybe as a special command - * (see do_special). - */ -static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio) -{ - ide_hwif_t *hwif = HWIF(drive); - ide_startstop_t startstop; - - if (pio > 2) { - /* FIXME: I don't believe that this SELECT_DRIVE is required, - * since ide.c only calls tuneproc from do_special, after - * the correct drive has been selected. - */ - SELECT_DRIVE(hwif, drive); - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); - OUT_BYTE(0x08 | pio, IDE_NSECTOR_REG); - OUT_BYTE(0x03, IDE_FEATURE_REG); - OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); - - if (ide_wait_stat(&startstop, drive, DRIVE_READY, - BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD)) { - printk("%s: drive not ready for command\n", - drive->name); - return 1; /* return startstop; ?? */ - } - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); - } - - return 0; /* return startstop; ?? */ + return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00); } /* @@ -97,27 +64,49 @@ static void tune_sl82c105(ide_drive_t *drive, byte pio) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; ide_pio_data_t p; - unsigned int drv_ctrl = 0x909; + unsigned short drv_ctrl = 0x909; + unsigned int xfer_mode, reg; - pio = ide_get_best_pio_mode(drive, pio, 5, &p); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (!ide_set_drive_pio_mode(drive, pio)) { - drv_ctrl = get_timing_sl82c105(&p); + pio = ide_get_best_pio_mode(drive, pio, 5, &p); - if (p.use_iordy) - drv_ctrl |= 0x40; + switch (pio) { + default: + case 0: xfer_mode = XFER_PIO_0; break; + case 1: xfer_mode = XFER_PIO_1; break; + case 2: xfer_mode = XFER_PIO_2; break; + case 3: xfer_mode = XFER_PIO_3; break; + case 4: xfer_mode = XFER_PIO_4; break; } - pci_write_config_word(dev, - (hwif->channel ? 0x4c : 0x44) - + (drive->select.b.unit ? 4 : 0), - drv_ctrl); + if (ide_config_drive_speed(drive, xfer_mode) == 0) + drv_ctrl = get_timing_sl82c105(&p); - printk("%s: selected PIO mode %d (%dns)\n", - drive->name, p.pio_mode, p.cycle_time); + pci_write_config_word(dev, reg, drv_ctrl); + pci_read_config_word(dev, reg, &drv_ctrl); + + printk("%s: selected %s (%dns) (%04X)\n", drive->name, + ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); } #endif +void ide_dmacapable_sl82c105(ide_hwif_t *hwif, unsigned long dmabase) +{ + unsigned char rev; + + pci_read_config_byte(hwif->pci_dev, PCI_REVISION_ID, &rev); + + if (rev <= 5) { + hwif->autodma = 0; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + printk(" %s: revision %d, Bus-Master DMA disabled\n", + hwif->name, rev); + } + ide_setup_dma(hwif, dmabase, 8); +} + void ide_init_sl82c105(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 97e1f1f58..11f10b785 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -11,6 +11,10 @@ fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL if [ "$CONFIG_SERIAL" = "y" ]; then bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL + tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL + fi fi bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then @@ -116,9 +120,23 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD + if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then + tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG + if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG + fi + fi fi endmenu +if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate 'NetWinder thermometer support' CONFIG_DS1620 + tristate 'NetWinder Button' CONFIG_NWBUTTON + if [ "$CONFIG_NWBUTTON" != "n" ]; then + bool ' Reboot Using Button' CONFIG_NWBUTTON_REBOOT + fi + tristate 'NetWinder flash support' CONFIG_NWFLASH +fi tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC @@ -188,6 +206,7 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then fi fi dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV + dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_SGI" = "y" ]; then dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 7f3c6133b..9e3ffd93a 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -251,6 +251,7 @@ obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o +obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o ifeq ($(CONFIG_FTAPE),y) diff --git a/drivers/char/README.epca b/drivers/char/README.epca index 6da319688..da2e11400 100644 --- a/drivers/char/README.epca +++ b/drivers/char/README.epca @@ -515,3 +515,11 @@ Description (Verbose) : Updated driver: Files affected : epca.c Release version : 1.3.0-K ----------------------------------------------------------------------- +Programmer : Jeff Garzik +Date : February 26, 2000 +Description (Verbose) : Updated driver: + 1. Use new kernel PCI interfaces. + 2. Updated list of includes. +Files affected : epca.c +Release version : 1.3.0.1-LK +----------------------------------------------------------------------- diff --git a/drivers/char/c-qcam.c b/drivers/char/c-qcam.c index 209298c6c..1e0582bdf 100644 --- a/drivers/char/c-qcam.c +++ b/drivers/char/c-qcam.c @@ -1,7 +1,20 @@ /* * Video4Linux Colour QuickCam driver - * Copyright 1997-1999 Philip Blundell <philb@gnu.org> + * Copyright 1997-2000 Philip Blundell <philb@gnu.org> * + * Module parameters: + * + * parport=auto -- probe all parports (default) + * parport=0 -- parport0 becomes qcam1 + * parport=2,0,1 -- parports 2,0,1 are tried in that order + * + * probe=0 -- do no probing, assume camera is present + * probe=1 -- use IEEE-1284 autoprobe data only (default) + * probe=2 -- probe aggressively for cameras + * + * The parport parameter controls which parports will be scanned. + * Scanning all parports causes some printers to print a garbage page. + * -- March 14, 1999 Billy Donahue <billy@escape.com> */ #include <linux/module.h> @@ -32,6 +45,9 @@ struct qcam_device { struct semaphore lock; }; +/* cameras maximum */ +#define MAX_CAMS 4 + /* The three possible QuickCam modes */ #define QC_MILLIONS 0x18 #define QC_BILLIONS 0x10 @@ -42,6 +58,11 @@ struct qcam_device { #define QC_DECIMATION_2 2 #define QC_DECIMATION_4 4 +#define BANNER "Colour QuickCam for Video4Linux v0.05" + +static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; +static int probe = 2; + static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) { /* note: the QC specs refer to the PCAck pin by voltage, not @@ -159,6 +180,22 @@ static int qc_detect(struct qcam_device *qcam) { unsigned int stat, ostat, i, count = 0; + /* The probe routine below is not very reliable. The IEEE-1284 + probe takes precedence. */ + /* XXX Currently parport provides no way to distinguish between + "the IEEE probe was not done" and "the probe was done, but + no device was found". Fix this one day. */ + if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA + && qcam->pport->probe_info[0].model + && !strcmp(qcam->pdev->port->probe_info[0].model, + "Color QuickCam 2.0")) { + printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n"); + return 1; + } + + if (probe < 2) + return 0; + parport_write_control(qcam->pport, 0xc); /* look for a heartbeat */ @@ -174,6 +211,26 @@ static int qc_detect(struct qcam_device *qcam) } } + /* Reset the camera and try again */ + parport_write_control(qcam->pport, 0xc); + parport_write_control(qcam->pport, 0x8); + mdelay(1); + parport_write_control(qcam->pport, 0xc); + mdelay(1); + count = 0; + + ostat = stat = parport_read_status(qcam->pport); + for (i=0; i<250; i++) + { + mdelay(1); + stat = parport_read_status(qcam->pport); + if (ostat != stat) + { + if (++count >= 3) return 1; + ostat = stat; + } + } + /* no (or flatline) camera, give up */ return 0; } @@ -627,7 +684,7 @@ static long qcam_read(struct video_device *v, char *buf, unsigned long count, i /* video device template */ static struct video_device qcam_template= { - "Colour Quickcam", + "Colour QuickCam", VID_TYPE_CAPTURE, VID_HARDWARE_QCAM_C, qcam_open, @@ -681,7 +738,6 @@ static struct qcam_device *qcam_init(struct parport *port) return q; } -#define MAX_CAMS 4 static struct qcam_device *qcams[MAX_CAMS]; static unsigned int num_cams = 0; @@ -689,6 +745,19 @@ int init_cqcam(struct parport *port) { struct qcam_device *qcam; + if (parport[0] != -1) + { + /* The user gave specific instructions */ + int i, found = 0; + for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) + { + if (parport[0] == port->number) + found = 1; + } + if (!found) + return -ENODEV; + } + if (num_cams == MAX_CAMS) return -ENOSPC; @@ -700,7 +769,7 @@ int init_cqcam(struct parport *port) qc_reset(qcam); - if (qc_detect(qcam)==0) + if (probe && qc_detect(qcam)==0) { parport_release(qcam->pdev); parport_unregister_device(qcam->pdev); @@ -712,16 +781,18 @@ int init_cqcam(struct parport *port) parport_release(qcam->pdev); - printk(KERN_INFO "Colour Quickcam found on %s\n", - qcam->pport->name); - if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1) { + printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", + qcam->pport->name); parport_unregister_device(qcam->pdev); kfree(qcam); return -ENODEV; } + printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", + qcam->vdev.minor, qcam->pport->name); + qcams[num_cams++] = qcam; return 0; @@ -734,8 +805,6 @@ void close_cqcam(struct qcam_device *qcam) kfree(qcam); } -#define BANNER "Connectix Colour Quickcam driver v0.03" - static void cq_attach(struct parport *port) { init_cqcam(port); @@ -756,11 +825,16 @@ static struct parport_driver cqcam_driver = { static int __init cqcam_init (void) { printk(BANNER "\n"); + return parport_register_driver(&cqcam_driver); } MODULE_AUTHOR("Philip Blundell <philb@gnu.org>"); MODULE_DESCRIPTION(BANNER); +MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method \n\ +probe=<0|1|2> # for camera detection method"); +MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i"); +MODULE_PARM(probe, "i"); static void __exit cqcam_cleanup (void) { diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index e3a37611d..5a89e008a 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -352,18 +352,10 @@ static struct proc_dir_entry *proc_therm_ds1620; #endif static struct file_operations ds1620_fops = { - NULL, /* lseek */ - ds1620_read, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - ds1620_ioctl, /* ioctl */ - NULL, /* mmap */ - ds1620_open, /* open */ - NULL, /* flush */ - ds1620_release, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ + read: ds1620_read, + ioctl: ds1620_ioctl, + open: ds1620_open, + release: ds1620_release, }; static struct miscdevice ds1620_miscdev = { diff --git a/drivers/char/dz.c b/drivers/char/dz.c index ceea1ff25..b8165ef98 100644 --- a/drivers/char/dz.c +++ b/drivers/char/dz.c @@ -29,6 +29,7 @@ #define MOD_DEC_USE_COUNT #endif +#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 8261e4ef2..e8de397bf 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -28,95 +28,38 @@ /* See README.epca for change history --DAT*/ -#ifdef MODVERSIONS -#ifndef MODULE -#define MODULE -#endif -#endif - -/* ----------------------------------------------------------------------- - This way modules should work regardless if they defined MODULE or - MODVERSIONS. (MODVERSIONS is for the newer kernels ... --------------------------------------------------------------------------- */ - -#ifdef MODULE #include <linux/config.h> -#endif /* MODULE */ - -#include <linux/version.h> - -#define NEW_MODULES - -#ifdef NEW_MODULES -#ifdef MODVERSIONS -#include <linux/modversions.h> -#endif /* MODVERSIONS */ -#endif /* NEW_MODULES */ - -#ifdef MODULE #include <linux/module.h> -#endif /* MODULE */ - - -#include <linux/errno.h> -#include <linux/major.h> -#include <linux/delay.h> -#include <linux/tty.h> -#include <linux/serial.h> -#include <linux/tty_driver.h> #include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/malloc.h> -#include <linux/mm.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/delay.h> #include <linux/ctype.h> -#include <asm/system.h> -#include <asm/io.h> -#include <asm/segment.h> - - -#include <asm/bitops.h> - -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/interrupt.h> +#include <linux/tty.h> #include <linux/tty_flip.h> -#include <linux/string.h> -#include <linux/fcntl.h> -#include <linux/ptrace.h> -#include <linux/ioport.h> - -#ifdef MODULE -#ifndef NEW_MODULES -char kernel_version[]=UTS_RELEASE; -#endif /* NEW_MODULE */ -#endif /* MODULE */ - +#include <asm/uaccess.h> #ifdef CONFIG_PCI #define ENABLE_PCI #endif /* CONFIG_PCI */ - - -#include <asm/uaccess.h> #define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2) #define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2) - - #ifdef ENABLE_PCI #include <linux/pci.h> -#include <linux/digiPCI.h> +#include "digiPCI.h" #endif /* ENABLE_PCI */ -#include <linux/digi1.h> -#include <linux/digiFep1.h> -#include <linux/epca.h> -#include <linux/epcaconfig.h> +#include "digi1.h" +#include "digiFep1.h" +#include "epca.h" +#include "epcaconfig.h" /* ---------------------- Begin defines ------------------------ */ -#define VERSION "1.3.0-K" +#define VERSION "1.3.0.1-LK" /* This major needs to be submitted to Linux to join the majors list */ @@ -127,6 +70,8 @@ char kernel_version[]=UTS_RELEASE; #define MAXCARDS 7 #define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) +#define PFX "epca: " + /* ----------------- Begin global definitions ------------------- */ static char mesg[100]; @@ -140,7 +85,7 @@ static int invalid_lilo_config = 0; MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. --------------------------------------------------------------------------*/ -static struct board_info boards[7]; +static struct board_info boards[MAXBOARDS]; /* ------------- Begin structures used for driver registeration ---------- */ @@ -284,11 +229,7 @@ static int pc_write(struct tty_struct *, int, const unsigned char *, int); int pc_init(void); #ifdef ENABLE_PCI -static int init_PCI(int); -static int get_PCI_configuration(unsigned char, unsigned char, - unsigned int *, unsigned int *, - unsigned int *, unsigned int *, - unsigned int *, unsigned int *); +static int init_PCI(void); #endif /* ENABLE_PCI */ @@ -1588,7 +1529,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp) #ifdef MODULE /* -------------------- Begin init_module ---------------------- */ -int init_module() +int __init init_module() { /* Begin init_module */ unsigned long flags; @@ -1606,6 +1547,11 @@ int init_module() #endif #ifdef MODULE /* -------------------- Begin cleanup_module ---------------------- */ + +#ifdef ENABLE_PCI +static struct pci_driver epca_driver; +#endif + void cleanup_module() { /* Begin cleanup_module */ @@ -1654,6 +1600,9 @@ void cleanup_module() } /* End for each port */ } /* End for each card */ +#ifdef ENABLE_PCI + pci_unregister_driver (&epca_driver); +#endif restore_flags(flags); @@ -1662,7 +1611,7 @@ void cleanup_module() /* ------------------ Begin pc_init ---------------------- */ -int pc_init(void) +int __init pc_init(void) { /* Begin pc_init */ /* ---------------------------------------------------------------- @@ -1748,7 +1697,7 @@ int pc_init(void) if (pci_present()) { if(num_cards < MAXBOARDS) - pci_boards_found += init_PCI(num_cards); + pci_boards_found += init_PCI(); num_cards += pci_boards_found; } else @@ -2039,10 +1988,7 @@ static void post_fep_init(unsigned int crd) epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); - if (bd->membase < (unsigned char *)0x100000) - memaddr = (unchar *) bd->membase; - else /* Else get special mapped memory above RAM */ - memaddr = (unchar *)bd->re_map_membase; + memaddr = (unchar *)bd->re_map_membase; /* The below command is necessary because newer kernels (2.1.x and @@ -2356,12 +2302,7 @@ static void doevent(int crd) assertgwinon(chan0); - if (bd->membase < (unsigned char *)0x100000) - eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->membase + tail + ISTART)); - else - { - eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART)); - } + eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART)); /* Get the channel the event occurred on */ channel = eventbuf[0]; @@ -2522,10 +2463,7 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte, cmdMax = (cmdStart + 4 + (ch->mailbox->cmax)); - if (ch->board->membase < (unsigned char *)0x100000) - memaddr = ch->board->membase; - else - memaddr = ch->board->re_map_membase; + memaddr = ch->board->re_map_membase; /* The below command is necessary because newer kernels (2.1.x and @@ -4036,231 +3974,128 @@ void epca_setup(char *str, int *ints) #ifdef ENABLE_PCI -/* --------------------- Begin get_PCI_configuration ---------------------- */ - -int get_PCI_configuration(unsigned char bus, unsigned char device_fn, - unsigned int *base_addr0, unsigned int *base_addr1, - unsigned int *base_addr2, unsigned int *base_addr3, - unsigned int *base_addr4, unsigned int *base_addr5) -{ /* Begin get_PCI_configuration */ - - struct pci_dev *dev = pci_find_slot(bus, device_fn); - - if (!dev) - return(0); - - *base_addr0 = dev->resource[0].start; - *base_addr1 = dev->resource[1].start; - *base_addr2 = dev->resource[2].start; - *base_addr3 = dev->resource[3].start; - *base_addr4 = dev->resource[4].start; - *base_addr5 = dev->resource[5].start; - - /* ------------------------------------------------------------------------ - NOTE - The code below mask out either the 2 or 4 bits dependent on the - space being addressed. (base_addr value reflecting io space, have their - first 2 bits mask out, while base_addr value reflecting mem space, have - their first 4 bits mask out.) These bits are flag bits and should always - be 0 when used as an address. - ---------------------------------------------------------------------------- */ - - return(1); -} /* End get_PCI_configuration */ - /* ------------------------ Begin init_PCI --------------------------- */ -int init_PCI(int boards_found) -{ /* Begin init_PCI */ - - unsigned char bus, device_fn; - int i, pci_count = 0; - unsigned int base_addr0, base_addr1, base_addr2, - base_addr3, base_addr4, base_addr5; +enum epic_board_types { + brd_xr = 0, + brd_xem, + brd_cx, + brd_xrj, +}; - base_addr0 = base_addr1 = base_addr2 = 0; - base_addr3 = base_addr4 = base_addr5 = 0; - for(i = 0; i < (MAXBOARDS - boards_found); i++) - { /* Begin for each POSSIBLE remaining board */ +/* indexed directly by epic_board_types enum */ +static struct { + unsigned char board_type; + unsigned bar_idx; /* PCI base address region */ +} epca_info_tbl[] = { + { PCIXR, 0, }, + { PCIXEM, 0, }, + { PCICX, 0, }, + { PCIXRJ, 2, }, +}; - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XR, - i, &bus, &device_fn)) - { /* Begin found XR */ - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Store a PCI/XR into the boards structure */ +static int __init epca_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int board_num = -1; + int board_idx, info_idx = ent->driver_data; + unsigned long addr; + + board_num++; + board_idx = board_num + num_cards; + if (board_idx >= MAXBOARDS) + goto err_out; + + addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx); + if (!addr) { + printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n", + epca_info_tbl[info_idx].bar_idx); + goto err_out; + } - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXR; - - boards[boards_found + pci_count].numports = 0x0; - - boards[boards_found + pci_count].port = (unsigned char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - ioremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/XR into the board structure */ - - } /* End found XR */ - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XEM, - i, &bus, &device_fn)) - { /* Begin found XEM */ - - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/XEM into the boards structure */ - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXEM; - - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/XEM into the boards structure */ - - } /* End found XEM */ - - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_CX, - i, &bus, &device_fn)) - { /* Begin found CX */ - - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/CX into the boards structure */ - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCICX; - - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/CX into the boards structure */ + boards[board_idx].status = ENABLED; + boards[board_idx].type = epca_info_tbl[info_idx].board_type; + boards[board_idx].numports = 0x0; + boards[board_idx].port = + (unsigned char *)((char *) addr + PCI_IO_OFFSET); + boards[board_idx].membase = + (unsigned char *)((char *) addr); + + if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) { + printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out; + } - } /* End found CX */ + boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000); + if (!boards[board_idx].re_map_port) { + printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_pciio; + } - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, - i, &bus, &device_fn)) - { /* Begin found XRJ */ + if (!request_mem_region (addr, 0x200000, "epca")) { + printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr); + goto err_out_free_iounmap; + } - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/XRJ into the boards structure */ + boards[board_idx].re_map_membase = ioremap(addr, 0x200000); + if (!boards[board_idx].re_map_membase) { + printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_memregion; + } - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXRJ; + /* -------------------------------------------------------------- + I don't know what the below does, but the hardware guys say + its required on everything except PLX (In this case XRJ). + ---------------------------------------------------------------- */ + if (info_idx != brd_xrj) { + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x46, 0); + } + + return 0; - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (unsigned char *)(base_addr2 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr2; +err_out_free_memregion: + release_mem_region (addr, 0x200000); +err_out_free_iounmap: + iounmap (boards[board_idx].re_map_port); +err_out_free_pciio: + release_mem_region (addr + PCI_IO_OFFSET, 0x200000); +err_out: + return -ENODEV; +} - if (base_addr2 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr2 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr2, 0x200000); - } - pci_count++; +static struct pci_device_id epca_pci_tbl[] __initdata = { + { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem }, + { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj }, + { 0, }, /* terminate list */ +}; - } /* End store a PCI/XRJ into the boards structure */ - } /* End found XRJ */ +int __init init_PCI (void) +{ /* Begin init_PCI */ + + int pci_count; + + memset (&epca_driver, 0, sizeof (epca_driver)); + epca_driver.name = "epca"; + epca_driver.id_table = epca_pci_tbl; + epca_driver.probe = epca_init_one; - } /* End for each POSSIBLE remaining board */ + pci_count = pci_register_driver (&epca_driver); + + if (pci_count <= 0) { + pci_unregister_driver (&epca_driver); + pci_count = 0; + } return(pci_count); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 824ef94e4..2ca3145d9 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -84,7 +84,7 @@ static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp, written+=sz; } #endif - if (copy_from_user(p, buf, count)) + if (copy_from_user(p, buf, count)) return -EFAULT; written += count; *ppos += written; @@ -637,12 +637,12 @@ int __init chr_dev_init(void) misc_init(); #ifdef CONFIG_SOUND soundcore_init(); -#ifdef CONFIG_SOUND_OSS +#ifdef CONFIG_SOUND_OSS soundcard_init(); -#endif +#endif #ifdef CONFIG_DMASOUND dmasound_init(); -#endif +#endif #endif #ifdef CONFIG_SPARCAUDIO sparcaudio_init(); diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 7c9bafc3b..986b728db 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c @@ -207,16 +207,9 @@ static int button_release (struct inode *inode, struct file *filp) */ static struct file_operations button_fops = { - NULL, /* lseek */ - button_read, - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* mmap */ - button_open, - NULL, /* flush */ - button_release, + read: button_read, + open: button_open, + release: button_release, }; /* diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index a905be058..cbe0ec79f 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -60,20 +60,12 @@ extern spinlock_t gpio_lock; static struct file_operations flash_fops = { - flash_llseek, /* llseek */ - flash_read, /* read */ - flash_write, /* write */ - NULL, /* no special readdir */ - NULL, /* no special select */ - flash_ioctl, - NULL, /* no special mmap */ - open_flash, - NULL, /* no special flush */ - release_flash, - NULL, /* no special fsync */ - NULL, /* no special fasync */ - NULL, /* no special check_media_change */ - NULL /* no special revaldate */ + llseek: flash_llseek, + read: flash_read, + write: flash_write, + ioctl: flash_ioctl, + open: open_flash, + release: release_flash, }; static struct miscdevice flash_miscdev = diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index d04f90964..fad27b0d5 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -59,11 +59,14 @@ * Revision 1.8: Jul 1 1997 * port to linux-2.1.43 kernel. * Revision 1.9: Oct 9 1998 - * Added stuff for the IO8+/PCI version. . + * Added stuff for the IO8+/PCI version. + * Revision 1.10: Oct 22 1999 / Jan 21 2000. + * Added stuff for setserial. + * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) * */ -#define VERSION "1.8" +#define VERSION "1.10" /* @@ -1070,10 +1073,17 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p /* * Now we must calculate some speed depended things */ - + /* Set baud rate for port */ - tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + - CD186x_TPC/2) / CD186x_TPC); + tmp = port->custom_divisor ; + if ( tmp ) + printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n" + "This is an untested option, please be carefull.\n", + port_No (port), tmp); + else + tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + + CD186x_TPC/2) / CD186x_TPC); + if ((tmp < 0x10) && time_before(again, jiffies)) { again = jiffies + HZ * 60; /* Page 48 of version 2.0 of the CL-CD1865 databook */ @@ -1095,9 +1105,13 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); sx_out(bp, CD186x_RBPRL, tmp & 0xff); sx_out(bp, CD186x_TBPRL, tmp & 0xff); - - baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ - + + if (port->custom_divisor) { + baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; + baud = ( baud + 5 ) / 10; + } else + baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ + /* Two timer ticks seems enough to wakeup something like SLIP driver */ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? @@ -1860,7 +1874,8 @@ extern inline int sx_set_serial_info(struct specialix_port * port, if (error) return error; - copy_from_user(&tmp, newinfo, sizeof(tmp)); + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) + return -EFAULT; #if 0 if ((tmp.irq != bp->irq) || @@ -1875,6 +1890,7 @@ extern inline int sx_set_serial_info(struct specialix_port * port, change_speed = ((port->flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); + change_speed |= (tmp.custom_divisor != port->custom_divisor); if (!capable(CAP_SYS_ADMIN)) { if ((tmp.close_delay != port->close_delay) || @@ -1884,11 +1900,13 @@ extern inline int sx_set_serial_info(struct specialix_port * port, return -EPERM; port->flags = ((port->flags & ~ASYNC_USR_MASK) | (tmp.flags & ASYNC_USR_MASK)); + port->custom_divisor = tmp.custom_divisor; } else { port->flags = ((port->flags & ~ASYNC_FLAGS) | (tmp.flags & ASYNC_FLAGS)); port->close_delay = tmp.close_delay; port->closing_wait = tmp.closing_wait; + port->custom_divisor = tmp.custom_divisor; } if (change_speed) { save_flags(flags); cli(); @@ -1919,8 +1937,10 @@ extern inline int sx_get_serial_info(struct specialix_port * port, tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; tmp.close_delay = port->close_delay * HZ/100; tmp.closing_wait = port->closing_wait * HZ/100; + tmp.custom_divisor = port->custom_divisor; tmp.xmit_fifo_size = CD186x_NFIFO; - copy_to_user(retinfo, &tmp, sizeof(tmp)); + if (copy_to_user(retinfo, &tmp, sizeof(tmp))) + return -EFAULT; return 0; } diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 1da60703e..5138c76b8 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -49,7 +49,7 @@ static int vcs_size(struct inode *inode) { int size; - int currcons = MINOR(inode->i_rdev) & 127; + int currcons = MINOR(inode->i_rdev) & 127; if (currcons == 0) currcons = fg_console; else diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 8425e64da..9d0cae4ff 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -203,7 +203,7 @@ do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kb if (!(key_map = key_maps[s])) { int j; - if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && + if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !capable(CAP_SYS_RESOURCE)) return -EPERM; diff --git a/drivers/char/wdt285.c b/drivers/char/wdt285.c index b5dc94e2f..6efdd7f76 100644 --- a/drivers/char/wdt285.c +++ b/drivers/char/wdt285.c @@ -153,18 +153,10 @@ static int watchdog_ioctl(struct inode *inode, struct file *file, static struct file_operations watchdog_fops= { - NULL, /* Seek */ - NULL, /* Read */ - watchdog_write, /* Write */ - NULL, /* Readdir */ - NULL, /* Select */ - watchdog_ioctl, /* Ioctl */ - NULL, /* MMap */ - watchdog_open, - NULL, /* flush */ - watchdog_release, - NULL, - NULL /* Fasync */ + write: watchdog_write, + ioctl: watchdog_ioctl, + open: watchdog_open, + release: watchdog_release, }; static struct miscdevice watchdog_miscdev= diff --git a/drivers/char/wdt977.c b/drivers/char/wdt977.c index c45e63d60..9bfbf0cc6 100644 --- a/drivers/char/wdt977.c +++ b/drivers/char/wdt977.c @@ -162,18 +162,9 @@ static ssize_t wdt977_write(struct file *file, const char *data, size_t len, lof static struct file_operations wdt977_fops= { - NULL, /* Seek */ - NULL, /* Read */ - wdt977_write, /* Write */ - NULL, /* Readdir */ - NULL, /* Select */ - NULL, /* Ioctl */ - NULL, /* MMap */ - wdt977_open, - NULL, /* flush */ - wdt977_release, - NULL, - NULL /* Fasync */ + write: wdt977_write, + open: wdt977_open, + release: wdt977_release, }; static struct miscdevice wdt977_miscdev= diff --git a/drivers/i2o/i2o_lan.c b/drivers/i2o/i2o_lan.c index d6aa43398..ddcefd1a6 100644 --- a/drivers/i2o/i2o_lan.c +++ b/drivers/i2o/i2o_lan.c @@ -131,7 +131,7 @@ static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, switch (msg[1] >> 24) { case LAN_RECEIVE_POST: { - if (dev->start) { + if (netif_running(dev)) { if (!(msg[4]>>24)) { i2o_lan_receive_post_reply(dev,msg); break; @@ -162,10 +162,8 @@ static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, trl_count--; } - if (dev->tbusy) { - clear_bit(0,(void*)&dev->tbusy); - mark_bh(NET_BH); /* inform upper layers */ - } + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); break; } @@ -536,8 +534,7 @@ static int i2o_lan_open(struct net_device *dev) return -ENOMEM; priv->i2o_fbl_tail = -1; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); i2o_set_batch_mode(dev); i2o_lan_receive_post(dev); @@ -562,8 +559,7 @@ static int i2o_lan_close(struct net_device *dev) printk(KERN_WARNING "%s: Unable to clear the event mask.\n", #endif dev->name); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); i2o_lan_suspend(dev); if (i2o_release_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) @@ -617,15 +613,6 @@ static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev) u32 m, *msg; u32 *sgl_elem; - /* - * Keep interrupt from changing dev->tbusy from underneath us - * (Do we really need to do this?) - */ - - if (test_and_set_bit(0,(void*)&dev->tbusy) != 0) { - return 1; - } - priv->tx_count++; priv->tx_out++; @@ -673,8 +660,8 @@ static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev) /* If HDMs TxMaxPktOut reached, stay busy (don't clean tbusy) */ - if (priv->tx_out < priv->tx_max_out) - clear_bit(0, (void *)&dev->tbusy); + if (priv->tx_out >= priv->tx_max_out) + netif_stop_queue(dev); return 0; } diff --git a/drivers/ieee1394/aic5800.c b/drivers/ieee1394/aic5800.c index 73c1928cd..be6516684 100644 --- a/drivers/ieee1394/aic5800.c +++ b/drivers/ieee1394/aic5800.c @@ -26,11 +26,11 @@ #include <linux/pci.h> #include <linux/fs.h> #include <linux/poll.h> +#include <linux/delay.h> #include <asm/byteorder.h> #include <asm/atomic.h> #include <asm/io.h> #include <asm/uaccess.h> -#include <asm/delay.h> #include "ieee1394_types.h" #include "hosts.h" diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c index fb8a32460..6cd9cf3e4 100644 --- a/drivers/isdn/avmb1/capi.c +++ b/drivers/isdn/avmb1/capi.c @@ -515,18 +515,13 @@ capi_release(struct inode *inode, struct file *file) static struct file_operations capi_fops = { - capi_llseek, - capi_read, - capi_write, - NULL, /* capi_readdir */ - capi_poll, - capi_ioctl, - NULL, /* capi_mmap */ - capi_open, - NULL, /* capi_flush */ - capi_release, - NULL, /* capi_fsync */ - NULL, /* capi_fasync */ + llseek: capi_llseek, + read: capi_read, + write: capi_write, + poll: capi_poll, + ioctl: capi_ioctl, + open: capi_open, + release: capi_release, }; /* -------- /proc functions ----------------------------------- */ diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index de56823c0..5dc6924e1 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -302,17 +302,13 @@ isdn_divert_lseek(struct file *file, loff_t offset, int orig) static struct file_operations isdn_fops = { - isdn_divert_lseek, - isdn_divert_read, - isdn_divert_write, - NULL, /* isdn_readdir */ - isdn_divert_poll, /* isdn_poll */ - isdn_divert_ioctl, /* isdn_ioctl */ - NULL, /* isdn_mmap */ - isdn_divert_open, - NULL, /* flush */ - isdn_divert_close, - NULL /* fsync */ + llseek: isdn_divert_lseek, + read: isdn_divert_read, + write: isdn_divert_write, + poll: isdn_divert_poll, + ioctl: isdn_divert_ioctl, + open: isdn_divert_open, + release: isdn_divert_close, }; /****************************/ diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 85040aabf..71bc7db99 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -41,7 +41,6 @@ * */ -#include <linux/config.h> #define __NO_VERSION__ #include "hisax.h" #include "hfc_sx.h" diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 4cb480588..20d69e32f 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -403,17 +403,11 @@ hysdn_conf_close(struct inode *ino, struct file *filep) /******************************************************/ static struct file_operations conf_fops = { - hysdn_dummy_lseek, - hysdn_conf_read, - hysdn_conf_write, - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - hysdn_conf_open, - NULL, /* flush */ - hysdn_conf_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_conf_read, + write: hysdn_conf_write, + open: hysdn_conf_open, + release: hysdn_conf_close, }; /*****************************/ diff --git a/drivers/isdn/hysdn/hysdn_procfs.c b/drivers/isdn/hysdn/hysdn_procfs.c index b43e2ade7..867b22766 100644 --- a/drivers/isdn/hysdn/hysdn_procfs.c +++ b/drivers/isdn/hysdn/hysdn_procfs.c @@ -338,17 +338,12 @@ hysdn_log_poll(struct file *file, poll_table * wait) /**************************************************/ static struct file_operations log_fops = { - hysdn_dummy_lseek, - hysdn_log_read, - hysdn_log_write, - NULL, /* readdir */ - hysdn_log_poll, /* poll */ - NULL, /*hysdn_log_ioctl, *//* ioctl */ - NULL, /* mmap */ - hysdn_log_open, - NULL, /* flush */ - hysdn_log_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_log_read, + write: hysdn_log_write, + poll: hysdn_log_poll, + open: hysdn_log_open, + release: hysdn_log_close, }; /*****************************************/ diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 67a91cf0f..4a585053a 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -420,17 +420,12 @@ hysdn_log_poll(struct file *file, poll_table * wait) /**************************************************/ static struct file_operations log_fops = { - hysdn_dummy_lseek, - hysdn_log_read, - hysdn_log_write, - NULL, /* readdir */ - hysdn_log_poll, /* poll */ - NULL, - NULL, /* mmap */ - hysdn_log_open, - NULL, /* flush */ - hysdn_log_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_log_read, + write: hysdn_log_write, + poll: hysdn_log_poll, + open: hysdn_log_open, + release: hysdn_log_close, }; /***********************************************************************************/ diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c index b259cdc4b..b8e9efa0f 100644 --- a/drivers/isdn/isdn_common.c +++ b/drivers/isdn/isdn_common.c @@ -2070,17 +2070,13 @@ isdn_close(struct inode *ino, struct file *filep) static struct file_operations isdn_fops = { - isdn_lseek, - isdn_read, - isdn_write, - NULL, /* isdn_readdir */ - isdn_poll, /* isdn_poll */ - isdn_ioctl, /* isdn_ioctl */ - NULL, /* isdn_mmap */ - isdn_open, - NULL, /* flush */ - isdn_close, - NULL /* fsync */ + llseek: isdn_lseek, + read: isdn_read, + write: isdn_write, + poll: isdn_poll, + ioctl: isdn_ioctl, + open: isdn_open, + release: isdn_close, }; char * diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index 0c14baed5..473700fa8 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -1038,16 +1038,10 @@ static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp, } static struct file_operations pmu_device_fops = { - NULL, /* no seek */ - pmu_read, - pmu_write, - NULL, /* no readdir */ - NULL, /* no poll yet */ - pmu_ioctl, - NULL, /* no mmap */ - pmu_open, - NULL, /* flush */ - NULL /* no release */ + read: pmu_read, + write: pmu_write, + ioctl: pmu_ioctl, + open: pmu_open, }; static struct miscdevice pmu_device = { diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 5a5d5fcf0..5e948c7e7 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1242,12 +1242,12 @@ static void elp_set_mc_list(struct net_device *dev) adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) { - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); printk("%s: couldn't send 82586 configure command\n", dev->name); } else { int timeout = jiffies + TIMEOUT; - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 36f15f0cb..80f56adf7 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -11,6 +11,8 @@ Center of Excellence in Space Data and Information Sciences Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + 2/2/00- Added support for kernel-level ISAPnP + by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox. */ @@ -46,6 +48,7 @@ static int max_interrupt_work = 20; #include <linux/module.h> #include <linux/version.h> +#include <linux/isapnp.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -349,6 +352,21 @@ static struct media_table { { "Default", 0, 0xFF, XCVR_10baseT, 10000}, }; +#ifdef CONFIG_ISAPNP +struct corkscrew_isapnp_adapters_struct { + unsigned short vendor, function; + char *name; +}; +struct corkscrew_isapnp_adapters_struct corkscrew_isapnp_adapters[] = { + {ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051), "3Com Fast EtherLink ISA"}, + {0, } +}; +int corkscrew_isapnp_phys_addr[3] = { + 0, 0, 0 +}; +#endif +static int nopnp = 0; + static int corkscrew_scan(struct net_device *dev); static struct net_device *corkscrew_found_device(struct net_device *dev, int ioaddr, int irq, @@ -422,11 +440,79 @@ int tc515_probe(struct net_device *dev) static int corkscrew_scan(struct net_device *dev) { int cards_found = 0; - static int ioaddr = 0x100; + short i; + static int ioaddr; + static int pnp_cards = 0; + +#ifdef CONFIG_ISAPNP + if(nopnp == 1) + goto no_pnp; + for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) { + struct pci_dev *idev = NULL; + int irq, j; + while((idev = isapnp_find_dev(NULL, + corkscrew_isapnp_adapters[i].vendor, + corkscrew_isapnp_adapters[i].function, + idev))) { + + if(idev->active) idev->deactivate(idev); + + if(idev->prepare(idev)<0) + continue; + if (!(idev->resource[0].flags & IORESOURCE_IO)) + continue; + if(idev->activate(idev)<0) { + printk("isapnp configure failed (out of resources?)\n"); + return -ENOMEM; + } + if (!idev->resource[0].start || check_region(idev->resource[0].start,16)) + continue; + ioaddr = idev->resource[0].start; + irq = idev->irq_resource[0].start; + if(corkscrew_debug) + printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n", + corkscrew_isapnp_adapters[i].name,ioaddr, irq); + + if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) + continue; + /* Verify by reading the device ID from the EEPROM. */ + { + int timer; + outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd); + /* Pause for at least 162 us. for the read to take place. */ + for (timer = 4; timer >= 0; timer--) { + udelay(162); + if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) + == 0) + break; + } + if (inw(ioaddr + Wn0EepromData) != 0x6d50) + continue; + } + printk(KERN_INFO "3c515 Resource configuraiton register %#4.4x, DCR %4.4x.\n", + inl(ioaddr + 0x2002), inw(ioaddr + 0x2000)); + /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */ + corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr; + corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev + && dev->mem_start ? dev-> + mem_start : options[cards_found]); + dev = 0; + pnp_cards++; + cards_found++; + } + } +no_pnp: +#endif /* not CONFIG_ISAPNP */ /* Check all locations on the ISA bus -- evil! */ - for (; ioaddr < 0x400; ioaddr += 0x20) { + for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) { int irq; +#ifdef CONFIG_ISAPNP + /* Make sure this was not already picked up by isapnp */ + if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue; + if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue; + if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue; +#endif if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE)) continue; /* Check the resource configuration for a matching ioaddr. */ @@ -455,7 +541,6 @@ static int corkscrew_scan(struct net_device *dev) dev = 0; cards_found++; } - if (corkscrew_debug) printk(KERN_INFO "%d 3c515 cards found.\n", cards_found); return cards_found; diff --git a/drivers/net/Config.in b/drivers/net/Config.in index abf7958ef..64edb30c1 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -5,6 +5,7 @@ source drivers/net/arcnet/Config.in tristate 'Dummy net driver support' CONFIG_DUMMY +tristate 'Bonding driver support' CONFIG_BONDING tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_NETLINK" = "y" ]; then diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 550a97ae2..6a7b1f06a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -228,6 +228,7 @@ obj-$(CONFIG_STRIP) += strip.o obj-$(CONFIG_DE650) += de650.o 8390.o obj-$(CONFIG_3C589) += 3c589.o obj-$(CONFIG_DUMMY) += dummy.o +obj-$(CONFIG_BONDING) += bonding.o obj-$(CONFIG_DE600) += de600.o obj-$(CONFIG_DE620) += de620.o obj-$(CONFIG_AT1500) += lance.o diff --git a/drivers/net/Space.c b/drivers/net/Space.c index d497f72d5..bccd82b04 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -681,6 +681,15 @@ static struct net_device tr0_dev = { -struct net_device *dev_base = NEXT_DEV; +/* + * The loopback device is global so it can be directly referenced + * by the network code. Also, it must be first on device list. + */ + +extern int loopback_init(struct net_device *dev); +struct net_device loopback_dev = + {"lo", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, loopback_init}; + +struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff --git a/drivers/net/aironet4500.h b/drivers/net/aironet4500.h index 95f0d23af..914976a70 100644 --- a/drivers/net/aironet4500.h +++ b/drivers/net/aironet4500.h @@ -19,17 +19,7 @@ /*#include <linux/module.h> #include <linux/kernel.h> */ -#if LINUX_VERSION_CODE < 0x2030E -#define NET_DEVICE device -#error bad kernel version code -#else -#define NET_DEVICE net_device -#endif - -#if LINUX_VERSION_CODE < 0x20300 -#define init_MUTEX(a) *(a) = MUTEX; -#endif /* #include <linux/types.h> #include <linux/netdevice.h> @@ -63,11 +53,6 @@ typedef spinlock_t my_spinlock_t ; #define my_spin_unlock_irqrestore(a,b) spin_unlock_irqrestore(a,b) -#if LINUX_VERSION_CODE <= 0x20100 -#define in_interrupt() intr_count -#endif - - #define AWC_ERROR -1 #define AWC_SUCCESS 0 @@ -81,6 +66,10 @@ struct awc_cis { }; +/* timeout for transmit watchdog timer */ +#define TX_TIMEOUT (HZ * 3) + + /*************************** REGISTER OFFSETS *********************/ #define awc_Command_register 0x00 @@ -137,7 +126,7 @@ struct awc_bap { struct awc_command { volatile int state; volatile int lock_state; - struct NET_DEVICE * dev; + struct net_device * dev; struct awc_private * priv; u16 port; struct awc_bap * bap; @@ -1293,7 +1282,7 @@ struct awc_strings { /***************************** R I D ***************/ #define AWC_NOF_RIDS 18 -extern int awc_rid_setup(struct NET_DEVICE * dev); +extern int awc_rid_setup(struct net_device * dev); struct aironet4500_rid_selector{ const u16 selector; @@ -1427,7 +1416,7 @@ struct awc_rid_dir{ const struct aironet4500_rid_selector * selector; const int size; const struct aironet4500_RID * rids; - struct NET_DEVICE * dev ; + struct net_device * dev ; void * buff; int bufflen; // just checking }; @@ -1490,8 +1479,6 @@ struct awc_private { int large_buff_mem; int small_buff_no; - int tx_timeout; - volatile int mac_enabled; u16 link_status; u8 link_status_changed; @@ -1533,60 +1520,59 @@ struct awc_private { int card_type; }; -extern int awc_init(struct NET_DEVICE * dev); -extern void awc_reset(struct NET_DEVICE *dev); -extern int awc_config(struct NET_DEVICE *dev); -extern int awc_open(struct NET_DEVICE *dev); -extern void awc_tx_timeout(struct NET_DEVICE *dev); -extern int awc_tx_done(struct awc_fid * rx_fid); -extern int awc_start_xmit(struct sk_buff *, struct NET_DEVICE *); +extern int awc_init(struct net_device * dev); +extern void awc_reset(struct net_device *dev); +extern int awc_config(struct net_device *dev); +extern int awc_open(struct net_device *dev); +extern void awc_tx_timeout(struct net_device *dev); +extern int awc_start_xmit(struct sk_buff *, struct net_device *); extern void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs); -extern struct enet_statistics * awc_get_stats(struct NET_DEVICE *dev); -extern int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid); -extern void awc_set_multicast_list(struct NET_DEVICE *dev); -extern int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu); -extern int awc_close(struct NET_DEVICE *dev); -extern int awc_private_init(struct NET_DEVICE * dev); +extern struct enet_statistics * awc_get_stats(struct net_device *dev); +extern int awc_rx(struct net_device *dev, struct awc_fid * rx_fid); +extern void awc_set_multicast_list(struct net_device *dev); +extern int awc_change_mtu(struct net_device *dev, int new_mtu); +extern int awc_close(struct net_device *dev); +extern int awc_private_init(struct net_device * dev); extern int awc_register_proc(int (*awc_proc_set_device) (int),int (*awc_proc_unset_device)(int)); extern int awc_unregister_proc(void); extern int (* awc_proc_set_fun) (int) ; extern int (* awc_proc_unset_fun) (int) ; -extern int awc_interrupt_process(struct NET_DEVICE * dev); -extern int awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ); -extern int awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf); -extern int awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ); -extern int awc_writerid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid); -extern int awc_tx_alloc(struct NET_DEVICE * dev) ; -extern int awc_tx_dealloc(struct NET_DEVICE * dev); -extern struct awc_fid *awc_tx_fid_lookup(struct NET_DEVICE * dev, u16 fid); -extern int awc_issue_soft_reset(struct NET_DEVICE * dev); -extern int awc_issue_noop(struct NET_DEVICE * dev); -extern int awc_dump_registers(struct NET_DEVICE * dev); +extern int awc_interrupt_process(struct net_device * dev); +extern int awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ); +extern int awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf); +extern int awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ); +extern int awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid); +extern int awc_tx_alloc(struct net_device * dev) ; +extern int awc_tx_dealloc(struct net_device * dev); +extern struct awc_fid *awc_tx_fid_lookup(struct net_device * dev, u16 fid); +extern int awc_issue_soft_reset(struct net_device * dev); +extern int awc_issue_noop(struct net_device * dev); +extern int awc_dump_registers(struct net_device * dev); extern unsigned short awc_issue_command_and_block(struct awc_command * cmd); -extern int awc_enable_MAC(struct NET_DEVICE * dev); -extern int awc_disable_MAC(struct NET_DEVICE * dev); -extern int awc_read_all_rids(struct NET_DEVICE * dev); -extern int awc_write_all_rids(struct NET_DEVICE * dev); -extern int awc_receive_packet(struct NET_DEVICE * dev); -extern int awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) ; -extern int awc_tx_complete_check(struct NET_DEVICE * dev); -extern int awc_interrupt_process(struct NET_DEVICE * dev); -extern void awc_bh(struct NET_DEVICE *dev); -extern int awc_802_11_find_copy_path(struct NET_DEVICE * dev, struct awc_fid * rx_buff); -extern void awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff); -extern int awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, struct sk_buff * skb); -extern void awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, struct awc_fid * tx_buff); -extern void awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev,struct awc_fid * tx_buff); -extern void awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff); -extern void awc_802_11_failed_rx_copy(struct NET_DEVICE * dev,struct awc_fid * rx_buff); -extern int awc_tx_alloc(struct NET_DEVICE * dev) ; -extern int awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid); -extern int awc_tx_dealloc(struct NET_DEVICE * dev); +extern int awc_enable_MAC(struct net_device * dev); +extern int awc_disable_MAC(struct net_device * dev); +extern int awc_read_all_rids(struct net_device * dev); +extern int awc_write_all_rids(struct net_device * dev); +extern int awc_receive_packet(struct net_device * dev); +extern int awc_transmit_packet(struct net_device * dev, struct awc_fid * tx_buff) ; +extern int awc_tx_complete_check(struct net_device * dev); +extern int awc_interrupt_process(struct net_device * dev); +extern void awc_bh(struct net_device *dev); +extern int awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff); +extern void awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff); +extern int awc_802_11_tx_find_path_and_post(struct net_device * dev, struct sk_buff * skb); +extern void awc_802_11_after_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff); +extern void awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev,struct awc_fid * tx_buff); +extern void awc_802_11_after_tx_complete(struct net_device * dev, struct awc_fid * tx_buff); +extern void awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff); +extern int awc_tx_alloc(struct net_device * dev) ; +extern int awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid); +extern int awc_tx_dealloc(struct net_device * dev); extern struct awc_fid * - awc_tx_fid_lookup_and_remove(struct NET_DEVICE * dev, u16 fid_handle); -extern int awc_queues_init(struct NET_DEVICE * dev); -extern int awc_queues_destroy(struct NET_DEVICE * dev); -extern int awc_rids_setup(struct NET_DEVICE * dev); + awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle); +extern int awc_queues_init(struct net_device * dev); +extern int awc_queues_destroy(struct net_device * dev); +extern int awc_rids_setup(struct net_device * dev); @@ -1603,7 +1589,7 @@ extern int tx_rate; extern int awc_full_stats; #define MAX_AWCS 4 -extern struct NET_DEVICE * aironet4500_devices[MAX_AWCS]; +extern struct net_device * aironet4500_devices[MAX_AWCS]; #define AWC_DEBUG 1 @@ -1615,16 +1601,4 @@ extern struct NET_DEVICE * aironet4500_devices[MAX_AWCS]; #define AWC_ENTRY_EXIT_DEBUG(a) #endif -#if LINUX_VERSION_CODE < 0x20100 -#ifndef test_and_set_bit - #define test_and_set_bit(a,b) set_bit(a,b) -#endif -#endif - -#if LINUX_VERSION_CODE < 0x20100 - #define FREE_SKB(a) dev_kfree_skb(a, FREE_WRITE) -#else - #define FREE_SKB(a) dev_kfree_skb(a) -#endif - #endif /* AIRONET4500_H */ diff --git a/drivers/net/aironet4500_card.c b/drivers/net/aironet4500_card.c index b6a00e875..b271b18f4 100644 --- a/drivers/net/aironet4500_card.c +++ b/drivers/net/aironet4500_card.c @@ -7,11 +7,13 @@ * * Revision 0.1 ,started 30.12.1998 * + * Revision 0.2, Feb 27, 2000 + * Jeff Garzik - softnet, cleanups * */ #ifdef MODULE static const char *awc_version = -"aironet4500_cards.c v0.1 28/03/99 Elmer Joandi, elmer@ylenurme.ee.\n"; +"aironet4500_cards.c v0.2 Feb 27, 2000 Elmer Joandi, elmer@ylenurme.ee.\n"; #endif #include <linux/version.h> @@ -36,9 +38,6 @@ static const char *awc_version = #include <linux/if_arp.h> #include <linux/ioport.h> #include <linux/delay.h> -#if LINUX_VERSION_CODE < 0x20100 -#include <linux/bios32.h> -#endif #include "aironet4500.h" @@ -64,11 +63,11 @@ static const char *awc_version = static int reverse_probe =0 ; -static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, +static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ; -int awc4500_pci_probe(struct NET_DEVICE *dev) +int awc4500_pci_probe(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; /* Static, for multiple probe calls. */ @@ -77,7 +76,7 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) unsigned char awc_pci_dev, awc_pci_bus; - if (!pcibios_present()) + if (!pci_present()) return -1; for (;pci_index < 0xff; pci_index++) { @@ -85,10 +84,8 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) u32 pci_memaddr; u32 pci_ioaddr; u32 pci_cisaddr; -#if LINUX_VERSION_CODE < 0x20100 - u16 pci_caps =0; - u8 pci_caps_ptr =0; -#endif + struct pci_dev *pdev; + if (pcibios_find_class (PCI_CLASS_NETWORK_OTHER << 8, reverse_probe ? 0xfe - pci_index : pci_index, &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){ @@ -98,31 +95,16 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) break; } } - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_DEVICE_ID, &device); -#if LINUX_VERSION_CODE >= 0x20300 - pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq; - pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[0].start; - pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[1].start; - pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[2].start; -#else -#if LINUX_VERSION_CODE >= 0x20155 - pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq; - pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[0]; - pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[1]; - pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[2]; -#else - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_0, &pci_memaddr); - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_1, &pci_cisaddr); - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_2, &pci_ioaddr); - pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev,PCI_STATUS, &pci_caps); - pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, 0x34, &pci_caps_ptr); - -#endif // 2.2 -#endif // 2.3 + pdev = pci_find_slot(awc_pci_bus, awc_pci_dev); + if (!pdev) + continue; + vendor = pdev->vendor; + device = pdev->device; + pci_irq_line = pdev->irq; + pci_memaddr = pci_resource_start (pdev, 0); + pci_cisaddr = pci_resource_start (pdev, 1); + pci_ioaddr = pci_resource_start (pdev, 2); + // printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr); /* Remove I/O space marker in bit 0. */ @@ -132,17 +114,7 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) device != PCI_DEVICE_AIRONET_4800 && device != PCI_DEVICE_AIRONET_4500 ) continue; -#if LINUX_VERSION_CODE < 0x20300 - - if (!(pci_ioaddr & 1)){ - printk("awc4X00 ioaddr location mismatch \n"); - return -1; - }; - pci_ioaddr &= ~3; - pci_cisaddr &= ~0xf; - pci_memaddr &= ~0xf; -#endif // if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) || // check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) || // check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) { @@ -153,33 +125,28 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) // request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis"); // request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem"); -// pcibios_write_config_word(awc_pci_bus, awc_pci_dev, -// PCI_COMMAND, 0); +// pci_write_config_word(pdev, PCI_COMMAND, 0); udelay(10000); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_COMMAND, &pci_command); + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); new_command = pci_command |0x100 | PCI_COMMAND_MEMORY|PCI_COMMAND_IO; if (pci_command != new_command) { printk(KERN_INFO " The PCI BIOS has not enabled this" " device! Updating PCI command %4.4x->%4.4x.\n", pci_command, new_command); - pcibios_write_config_word(awc_pci_bus, awc_pci_dev, - PCI_COMMAND, new_command); + pci_write_config_word(pdev, PCI_COMMAND, new_command); } /* if (device == PCI_DEVICE_AIRONET_4800) - pcibios_write_config_dword(awc_pci_bus, awc_pci_dev, - 0x40, 0x00000000); + pci_write_config_dword(pdev, 0x40, 0x00000000); udelay(1000); */ if (device == PCI_DEVICE_AIRONET_4800) - pcibios_write_config_dword(awc_pci_bus, awc_pci_dev, - 0x40, 0x40000000); + pci_write_config_dword(pdev, 0x40, 0x40000000); - if (awc_pci_init(dev, awc_pci_bus, awc_pci_dev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){ + if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){ printk(KERN_ERR "awc4800 pci init failed \n"); break; } @@ -191,7 +158,7 @@ int awc4500_pci_probe(struct NET_DEVICE *dev) } -static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, +static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) { int i; @@ -218,18 +185,15 @@ static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = ioaddr; - - dev->irq = pci_irq_line; -#if LINUX_VERSION_CODE > 0x20100 - request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#else + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); + request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#endif + awc_private_init( dev); awc_init(dev); @@ -244,17 +208,11 @@ static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - - // if (register_netdev(dev) != 0) { // printk(KERN_NOTICE "awc_cs: register_netdev() failed\n"); // goto failed; // } - - return 0; // failed: // return -1; @@ -285,7 +243,7 @@ static void awc_pci_release(void) { unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -304,14 +262,9 @@ static void awc_pci_release(void) { #ifdef CONFIG_AIRONET4500_PNP -#if LINUX_VERSION_CODE > 0x20300 #include <linux/isapnp.h> -#else -#include "isapnp.h" -#endif #define AIRONET4X00_IO_SIZE 0x40 -#if LINUX_VERSION_CODE > 0x20300 #define isapnp_logdev pci_dev #define isapnp_dev pci_bus #define isapnp_find_device isapnp_find_card @@ -319,17 +272,11 @@ static void awc_pci_release(void) { #define PNP_BUS bus #define PNP_BUS_NUMBER number #define PNP_DEV_NUMBER devfn -#else -#define PNP_BUS dev -#define PNP_BUS_NUMBER csn -#define PNP_DEV_NUMBER number -#endif -int awc4500_pnp_hw_reset(struct NET_DEVICE *dev){ + +int awc4500_pnp_hw_reset(struct net_device *dev){ struct isapnp_logdev *logdev; -#if LINUX_VERSION_CODE < 0x20300 - struct isapnp_config cfg; -#endif + DEBUG(0, "awc_pnp_reset \n"); if (!dev->priv ) { @@ -357,30 +304,14 @@ int awc4500_pnp_hw_reset(struct NET_DEVICE *dev){ dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER); return -EAGAIN; } -#if LINUX_VERSION_CODE < 0x20300 - if (isapnp_config_init(&cfg, logdev)<0) { - printk("cfg init failed \n"); - isapnp_cfg_end(); - return -EAGAIN; - } - cfg.port[0] = dev->base_addr; - cfg.irq[0] = dev->irq; - if (isapnp_configure(&cfg)<0) { - printk("%s hw_reset, isapnp configure failed (out of resources?)\n",dev->name); - isapnp_cfg_end(); - return -ENOMEM; - } -#else - -#endif isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */ isapnp_cfg_end(); return 0; } -int awc4500_pnp_probe(struct NET_DEVICE *dev) +int awc4500_pnp_probe(struct net_device *dev) { int isa_index = 0; int isa_irq_line = 0; @@ -389,21 +320,13 @@ int awc4500_pnp_probe(struct NET_DEVICE *dev) int i=0; struct isapnp_dev * pnp_dev ; struct isapnp_logdev *logdev; -#if LINUX_VERSION_CODE < 0x20300 - struct isapnp_config cfg; -#endif while (1) { pnp_dev = isapnp_find_device( ISAPNP_VENDOR('A','W','L'), ISAPNP_DEVICE(1), -#if LINUX_VERSION_CODE < 0x20300 - isa_index -#else - 0 -#endif - ); + 0); if (!pnp_dev) break; @@ -421,28 +344,11 @@ int awc4500_pnp_probe(struct NET_DEVICE *dev) logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER); return -EAGAIN; } -#if LINUX_VERSION_CODE < 0x20300 - if (isapnp_config_init(&cfg, logdev)<0) { - printk("cfg init failed \n"); - isapnp_cfg_end(); - return -EAGAIN; - } - if (isapnp_configure(&cfg)<0) { - printk("isapnp configure failed (out of resources?)\n"); - isapnp_cfg_end(); - return -ENOMEM; - } -#endif isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */ isapnp_cfg_end(); -#if LINUX_VERSION_CODE < 0x20300 - isa_ioaddr = cfg.port[0]; - isa_irq_line = cfg.irq[0]; -#else isa_irq_line = logdev->irq; isa_ioaddr = logdev->resource[0].start; -#endif request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"); if (!dev) { @@ -468,18 +374,14 @@ int awc4500_pnp_probe(struct NET_DEVICE *dev) dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = isa_ioaddr; - - dev->irq = isa_irq_line; -#if LINUX_VERSION_CODE > 0x20100 + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); + request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#else - request_irq(dev->irq,awc_interrupt, SA_SHIRQ ,"Aironet 4X00",dev); -#endif awc_private_init( dev); @@ -512,9 +414,6 @@ int awc4500_pnp_probe(struct NET_DEVICE *dev) return -1; } - dev->tbusy = 1; - dev->start = 0; - card++; } @@ -557,7 +456,7 @@ static void awc_pnp_release(void) { unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -580,16 +479,14 @@ static int io[] = {0,0,0,0,0}; EXPORT_SYMBOL(irq); EXPORT_SYMBOL(io); */ -#if LINUX_VERSION_CODE >= 0x20100 MODULE_PARM(irq,"i"); MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required"); MODULE_PARM(io,"i"); MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required"); -#endif -int awc4500_isa_probe(struct NET_DEVICE *dev) +int awc4500_isa_probe(struct net_device *dev) { // int cards_found = 0; // static int isa_index = 0; /* Static, for multiple probe calls. */ @@ -638,19 +535,14 @@ int awc4500_isa_probe(struct NET_DEVICE *dev) dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = isa_ioaddr; - - dev->irq = isa_irq_line; + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); -#if LINUX_VERSION_CODE > 0x20100 request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev); -#else - request_irq(dev->irq,awc_interrupt ,0 ,"Aironet 4X00",dev); -#endif awc_private_init( dev); if ( awc_init(dev) ){ @@ -671,9 +563,6 @@ int awc4500_isa_probe(struct NET_DEVICE *dev) awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - card++; } if (card == 0 ) { @@ -707,7 +596,7 @@ static void awc_isa_release(void) { unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -906,7 +795,7 @@ int awc_i365_probe_once(struct i365_socket * s ){ static int awc_i365_init(struct i365_socket * s) { - struct NET_DEVICE * dev; + struct net_device * dev; int i; @@ -923,11 +812,12 @@ static int awc_i365_init(struct i365_socket * s) { dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; dev->irq = s->irq; dev->base_addr = s->io; + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + netif_start_queue (dev); awc_private_init( dev); @@ -943,24 +833,18 @@ static int awc_i365_init(struct i365_socket * s) { awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - - if (register_netdev(dev) != 0) { printk(KERN_NOTICE "awc_cs: register_netdev() failed\n"); goto failed; } - - return 0; failed: return -1; - } + static void awc_i365_release(void) { // long flags; @@ -983,7 +867,7 @@ static void awc_i365_release(void) { unregister_netdev(aironet4500_devices[i]); //kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; diff --git a/drivers/net/aironet4500_core.c b/drivers/net/aironet4500_core.c index 1b82d4715..205a43d97 100644 --- a/drivers/net/aironet4500_core.c +++ b/drivers/net/aironet4500_core.c @@ -72,7 +72,7 @@ const char * awc_print_string( struct awc_strings* strings, int code){ return "UNKNOWN"; }; -int awc_dump_registers(struct NET_DEVICE * dev){ +int awc_dump_registers(struct net_device * dev){ #ifdef AWC_DEBUG int i; @@ -108,7 +108,7 @@ int awc_dump_registers(struct NET_DEVICE * dev){ inline -int awc_command_busy_clear_wait(struct NET_DEVICE * dev){ +int awc_command_busy_clear_wait(struct net_device * dev){ // long long jiff = jiffies; u16 active_interrupts; int cnt= 0; @@ -319,7 +319,7 @@ awc_issue_command(struct awc_command * cmd){ inline unsigned short -awc_issue_command_no_ack(struct NET_DEVICE * dev, +awc_issue_command_no_ack(struct net_device * dev, u16 com, u16 par1, u16 par2, u16 par3){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -695,7 +695,7 @@ struct awc_rid_dir awc_rids_temp[]={ int -awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ){ +awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ){ struct awc_command cmd; int sleep_state ; @@ -728,7 +728,7 @@ awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ){ } int -awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf){ +awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf){ struct awc_command cmd; int sleep_state ; @@ -765,7 +765,7 @@ awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf){ } int -awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ){ +awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ){ struct awc_command cmd; int sleep_state; @@ -798,7 +798,7 @@ awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ){ } int -awc_writerid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid){ +awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid){ struct awc_command cmd; int sleep_state ; @@ -847,7 +847,7 @@ EXPORT_SYMBOL(awc_writerid_dir); inline int -awc_issue_blocking_command(struct NET_DEVICE * dev,u16 comm){ +awc_issue_blocking_command(struct net_device * dev,u16 comm){ struct awc_command cmd; // struct awc_private * priv = (struct awc_private *)dev->priv; @@ -872,7 +872,7 @@ awc_issue_blocking_command(struct NET_DEVICE * dev,u16 comm){ }; int -awc_issue_soft_reset(struct NET_DEVICE * dev){ +awc_issue_soft_reset(struct net_device * dev){ u16 status ; // int i= 0; @@ -912,7 +912,7 @@ awc_issue_soft_reset(struct NET_DEVICE * dev){ }; int -awc_issue_noop(struct NET_DEVICE * dev){ +awc_issue_noop(struct net_device * dev){ int retval; AWC_OUT(dev->base_addr + 0x28, 0); AWC_OUT(dev->base_addr + 0x2A, 0); @@ -925,7 +925,7 @@ awc_issue_noop(struct NET_DEVICE * dev){ EXPORT_SYMBOL(awc_enable_MAC); int -awc_enable_MAC(struct NET_DEVICE * dev){ +awc_enable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_enable_MAC "); @@ -950,7 +950,7 @@ awc_enable_MAC(struct NET_DEVICE * dev){ EXPORT_SYMBOL(awc_disable_MAC); int -awc_disable_MAC(struct NET_DEVICE * dev){ +awc_disable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_disable_MAC "); @@ -973,7 +973,7 @@ awc_disable_MAC(struct NET_DEVICE * dev){ int -awc_read_all_rids(struct NET_DEVICE * dev){ +awc_read_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int status,i; @@ -992,7 +992,7 @@ awc_read_all_rids(struct NET_DEVICE * dev){ } int -awc_write_all_rids(struct NET_DEVICE * dev){ +awc_write_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int i,status ; @@ -1012,7 +1012,7 @@ awc_write_all_rids(struct NET_DEVICE * dev){ -int awc_tx_alloc(struct NET_DEVICE * dev) { +int awc_tx_alloc(struct net_device * dev) { struct awc_command cmd; int k=0; @@ -1116,7 +1116,7 @@ int awc_tx_alloc(struct NET_DEVICE * dev) { }; int -awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid){ +awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid){ struct awc_command cmd; int fid_handle = 0; @@ -1150,7 +1150,7 @@ awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid){ }; int -awc_tx_dealloc(struct NET_DEVICE * dev){ +awc_tx_dealloc(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1177,7 +1177,7 @@ awc_tx_dealloc(struct NET_DEVICE * dev){ inline struct awc_fid * -awc_tx_fid_lookup_and_remove(struct NET_DEVICE * dev, u16 fid_handle){ +awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle){ struct awc_private * priv = (struct awc_private *)dev->priv; // int k = 0; @@ -1272,7 +1272,7 @@ awc_tx_fid_lookup_and_remove(struct NET_DEVICE * dev, u16 fid_handle){ int -awc_queues_init(struct NET_DEVICE * dev){ +awc_queues_init(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; @@ -1302,7 +1302,7 @@ awc_queues_init(struct NET_DEVICE * dev){ int -awc_queues_destroy(struct NET_DEVICE * dev){ +awc_queues_destroy(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; @@ -1325,7 +1325,7 @@ awc_queues_destroy(struct NET_DEVICE * dev){ /****************************** 802.11router ******************/ inline int -awc_802_11_copy_path_skb(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ +awc_802_11_copy_path_skb(struct net_device * dev, struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; @@ -1360,7 +1360,7 @@ awc_802_11_copy_path_skb(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ int -awc_802_11_find_copy_path(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ +awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff){ // struct awc_private * priv = (struct awc_private * )dev->priv; // u8 is_802_3 = 0; @@ -1386,7 +1386,7 @@ awc_802_11_find_copy_path(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ int parse_not_8023= 0; void -awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ +awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; struct sk_buff * skb = rx_buff->skb; @@ -1531,7 +1531,7 @@ awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ DEBUG(0x200,"%s packet dropped in packet hdr parse \n ",dev->name); if (rx_buff->skb && (rx_buff->type & p80211copy_path_skb)){ - FREE_SKB(rx_buff->skb); + dev_kfree_skb_irq(rx_buff->skb); rx_buff->skb = NULL; rx_buff->u.rx.payload = NULL; }; @@ -1541,13 +1541,13 @@ awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ }; void -awc_802_11_failed_rx_copy(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ +awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; AWC_ENTRY_EXIT_DEBUG("awc_802_11_failed_rx_copy"); if (rx_buff->skb) - FREE_SKB(rx_buff->skb); + dev_kfree_skb_irq(rx_buff->skb); rx_buff->skb = NULL; rx_buff->u.rx.payload = NULL; priv->stats.rx_errors++; @@ -1566,7 +1566,7 @@ awc_802_11_failed_rx_copy(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ int -awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, +awc_802_11_tx_find_path_and_post(struct net_device * dev, struct sk_buff * skb){ @@ -1750,10 +1750,6 @@ awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, udelay(1); awc_transmit_packet(dev,fid); UP(&priv->tx_buff_semaphore); - if (priv->tx_large_ready.size > 0 ){ - dev->tbusy = 0; - mark_bh(NET_BH); - } AWC_ENTRY_EXIT_DEBUG("exit\n"); return 0; @@ -1763,7 +1759,7 @@ awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, #ifdef AWC_DEBUG // printk("s"); #endif - dev->tbusy = 1; //weell, here it must be set anyway and before + netif_stop_queue (dev); //weell, here it must be set anyway and before //priv->stats.tx_fifo_errors++; UP(&priv->tx_buff_semaphore); AWC_ENTRY_EXIT_DEBUG("NoSpaceExit\n"); @@ -1771,9 +1767,7 @@ awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, final: priv->stats.tx_errors++; UP(&priv->tx_buff_semaphore); - dev->tbusy = 0; - FREE_SKB(skb); - mark_bh(NET_BH); + dev_kfree_skb(skb); AWC_ENTRY_EXIT_DEBUG("BADExit\n"); return -1; @@ -1788,7 +1782,7 @@ awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, void -awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, +awc_802_11_after_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff){ @@ -1799,10 +1793,10 @@ awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, }; if(tx_buff->skb){ - FREE_SKB(tx_buff->skb); + dev_kfree_skb(tx_buff->skb); tx_buff->skb = NULL; } - mark_bh(NET_BH); + netif_wake_queue (dev); AWC_ENTRY_EXIT_DEBUG("exit\n"); }; @@ -1815,7 +1809,7 @@ awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, */ void -awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev, +awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1827,7 +1821,7 @@ awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev, }; if(tx_buff->skb){ - FREE_SKB(tx_buff->skb); + dev_kfree_skb(tx_buff->skb); tx_buff->skb = NULL; tx_buff->busy =0; printk(KERN_ERR "%s packet to card write failed \n",dev->name); @@ -1845,7 +1839,7 @@ awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev, }; void -awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff){ +awc_802_11_after_tx_complete(struct net_device * dev, struct awc_fid * tx_buff){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1866,8 +1860,7 @@ awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff){ } tx_buff->busy = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); AWC_ENTRY_EXIT_DEBUG("exit\n"); }; @@ -1880,7 +1873,7 @@ awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff){ inline int -awc_receive_packet(struct NET_DEVICE * dev){ +awc_receive_packet(struct net_device * dev){ struct awc_command cmd; u16 Fid; @@ -2010,7 +2003,7 @@ awc_receive_packet(struct NET_DEVICE * dev){ int -awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) { +awc_transmit_packet(struct net_device * dev, struct awc_fid * tx_buff) { struct awc_command cmd; u16 size ; @@ -2143,7 +2136,7 @@ awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) { inline int -awc_tx_complete_check(struct NET_DEVICE * dev){ +awc_tx_complete_check(struct net_device * dev){ struct awc_fid * fid; struct awc_command cmd; @@ -2197,7 +2190,7 @@ awc_tx_complete_check(struct NET_DEVICE * dev){ void -awc_bh(struct NET_DEVICE *dev){ +awc_bh(struct net_device *dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int active_interrupts; @@ -2226,8 +2219,7 @@ start: if (active_interrupts == 0xffff){ printk(KERN_CRIT "%s device ejected in interrupt, disabling\n",dev->name); - dev->tbusy = 1; - dev->start = 0; + netif_device_detach (dev); if (priv->command_semaphore_on){ priv->command_semaphore_on--; AWC_UNLOCK_COMMAND_ISSUING(priv); @@ -2286,7 +2278,7 @@ start: inline int -awc_interrupt_process(struct NET_DEVICE * dev){ +awc_interrupt_process(struct net_device * dev){ struct awc_private * priv ; int active_interrupts; @@ -2327,10 +2319,6 @@ awc_interrupt_process(struct NET_DEVICE * dev){ // printk("ikka interruptis\n"); - if (test_and_set_bit( 0, (void *) &dev->interrupt) ) { - printk("RI\n"); - goto reenter_end_here; - } priv->interrupt_count++; if (priv->interrupt_count > 1 ) printk(" interrupt count on\n "); @@ -2354,12 +2342,10 @@ start: printk(KERN_CRIT "%s device ejected, got interrupt, disabling\n",dev->name); //priv-> - dev->tbusy = 1; - dev->start = 0; + netif_device_detach (dev); priv->ejected = 1; if (priv->bh_active || priv->bh_running){ priv->interrupt_count--; - dev->interrupt = 0; goto bad_end; } else if (priv->command_semaphore_on){ @@ -2368,7 +2354,6 @@ start: AWC_QUEUE_BH; } priv->interrupt_count--; - dev->interrupt = 0; goto bad_end; } @@ -2458,8 +2443,7 @@ start: awc_fid_queue_push_tail(&priv->tx_small_ready,fid); else awc_fid_queue_push_tail(&priv->tx_large_ready,fid); - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } else printk(KERN_ERR "awc fid %x not found\n",tx_fid); @@ -2502,7 +2486,6 @@ start: priv->interrupt_count--; - dev->interrupt = 0; awc_ints_enable(dev->base_addr, 0x0000); @@ -2523,15 +2506,8 @@ start: // restore_flags(flags); return 0; -reenter_end_here: - - AWC_ENTRY_EXIT_DEBUG(" reenter-bad end exit \n"); -// enable_irq(dev->irq); -// restore_flags(flags); - return 0; bad_end: - dev->interrupt = 0; AWC_ENTRY_EXIT_DEBUG(" bad_end exit \n"); // enable_irq(dev->irq); // restore_flags(flags); @@ -2543,7 +2519,7 @@ bad_end: static const char *aironet4500_core_version = "aironet4500.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n"; -struct NET_DEVICE * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; +struct net_device * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; static int awc_debug = 0; // 0xffffff; static int p802_11_send = 0; // 1 @@ -2595,7 +2571,6 @@ EXPORT_SYMBOL(awc_debug); EXPORT_SYMBOL(awc_private_init); EXPORT_SYMBOL(awc_tx_timeout); EXPORT_SYMBOL(awc_start_xmit); -EXPORT_SYMBOL(awc_tx_done); EXPORT_SYMBOL(awc_rx); EXPORT_SYMBOL(awc_interrupt); EXPORT_SYMBOL(awc_get_stats); @@ -2611,7 +2586,7 @@ EXPORT_SYMBOL(awc_unregister_proc); /*************************** RESET INIT CONFIG ***********************/ - void awc_reset(struct NET_DEVICE *dev) + void awc_reset(struct net_device *dev) { long long jiff; @@ -2633,7 +2608,7 @@ EXPORT_SYMBOL(awc_unregister_proc); } - int awc_config(struct NET_DEVICE *dev) + int awc_config(struct net_device *dev) { // struct awc_private *priv = (struct awc_private *)dev->priv; @@ -2654,7 +2629,7 @@ EXPORT_SYMBOL(awc_unregister_proc); char name[] = "ElmerLinux"; - int awc_init(struct NET_DEVICE *dev){ + int awc_init(struct net_device *dev){ struct awc_private *priv = (struct awc_private *)dev->priv; int i; const char * radioType; @@ -2785,8 +2760,6 @@ char name[] = "ElmerLinux"; // here we go, bad aironet memset(&priv->SSIDs,0,sizeof(priv->SSIDs)); - my_spin_lock_init(&priv->queues_lock); - priv->SSIDs.ridLen =0; if (!SSID) { priv->SSIDs.SSID[0].SSID[0] ='a'; @@ -2834,7 +2807,7 @@ char name[] = "ElmerLinux"; }; -int awc_private_init(struct NET_DEVICE * dev){ +int awc_private_init(struct net_device * dev){ struct awc_private * priv = (struct awc_private *) dev->priv; int i = 0; @@ -2906,7 +2879,6 @@ int awc_private_init(struct NET_DEVICE * dev){ priv->ejected =0; - dev->interrupt =0; priv->interrupt_count =0; return 0; @@ -2916,7 +2888,7 @@ int awc_private_init(struct NET_DEVICE * dev){ /**************************** OPEN CLOSE **********************/ - int awc_open(struct NET_DEVICE *dev) + int awc_open(struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; @@ -2924,9 +2896,6 @@ int awc_private_init(struct NET_DEVICE * dev){ DEBUG(2, "%s: awc_open \n", dev->name); - dev->interrupt = 0; dev->tbusy = 1; dev->start = 0; - - if( awc_queues_init(dev) ) goto final; if( awc_config(dev) ) goto final; @@ -2945,24 +2914,23 @@ int awc_private_init(struct NET_DEVICE * dev){ MOD_INC_USE_COUNT; // kernel_thread(awc_thread,dev,0); - dev->tbusy = 0; dev->start = 1; + netif_start_queue (dev); return 0; /* Always succeed */ final: - dev->tbusy = 0; dev->start = 0; + netif_device_detach (dev); printk(KERN_ERR "aironet open failed \n"); return -1; } - int awc_close(struct NET_DEVICE *dev) + int awc_close(struct net_device *dev) { struct awc_private * priv = (struct awc_private *) dev->priv; DEBUG(2, "%s: closing device.\n", dev->name); - dev->start = 0; - dev->tbusy=1; + netif_stop_queue (dev); awc_disable_MAC(dev); awc_queues_destroy(dev); @@ -2986,32 +2954,58 @@ int awc_private_init(struct NET_DEVICE * dev){ - void awc_tx_timeout(struct NET_DEVICE *dev) +void awc_tx_timeout (struct net_device *dev) { - struct awc_private *priv = (struct awc_private *)dev->priv; + struct awc_private *priv = (struct awc_private *) dev->priv; + struct awc_fid * fid; + int cnt; - DEBUG(2, "%s: awc_tx_timeout \n", dev->name); + DEBUG (2, "%s: awc_tx_timeout \n", dev->name); - printk(KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d \n ", - dev->name,priv->tx_small_buffs_total ,priv->tx_buffs_total, - priv->tx_in_transmit.size,priv->tx_post_process.size, - priv->tx_large_ready.size,priv->tx_small_ready.size); + printk (KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d \n ", + dev->name, priv->tx_small_buffs_total, priv->tx_buffs_total, + priv->tx_in_transmit.size, priv->tx_post_process.size, + priv->tx_large_ready.size, priv->tx_small_ready.size); priv->stats.tx_errors++; + // save_flags(flags); + // cli(); + fid = priv->tx_in_transmit.head; + cnt = 0; + while (fid) { + if (jiffies - fid->transmit_start_time > (HZ)) { + // printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name, + // jiffies - fid->transmit_start_time ); + awc_fid_queue_remove (&priv->tx_in_transmit, fid); + if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE) + awc_fid_queue_push_tail (&priv->tx_small_ready, fid); + else + awc_fid_queue_push_tail (&priv->tx_large_ready, fid); + } + fid = fid->next; + if (cnt++ > 200) { + printk ("bbb in awc_fid_queue\n"); + // restore_flags(flags); + return; + }; + + } + //restore_flags(flags); + //debug =0x8; + dev->trans_start = jiffies; - dev->tbusy = 0; + netif_start_queue (dev); } + long long last_tx_q_hack = 0; int direction = 1; - int awc_start_xmit(struct sk_buff *skb, struct NET_DEVICE *dev) { + int awc_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; int retval = 0; // unsigned long flags; - struct awc_fid * fid = NULL; - int cnt=0; DEBUG(2, "%s: awc_start_xmit \n", dev->name); @@ -3021,48 +3015,13 @@ int direction = 1; return -1; }; - /* Transmitter timeout, serious problems. */ - if (test_and_set_bit( 0, (void *) &dev->tbusy) ) { - if (jiffies - dev->trans_start > 3* HZ ){ - // save_flags(flags); - // cli(); - fid = priv->tx_in_transmit.head; - cnt = 0; - while (fid){ - if (jiffies - fid->transmit_start_time > (HZ)){ - // printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name, - // jiffies - fid->transmit_start_time ); - awc_fid_queue_remove(&priv->tx_in_transmit, fid); - if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE) - awc_fid_queue_push_tail(&priv->tx_small_ready,fid); - else - awc_fid_queue_push_tail(&priv->tx_large_ready,fid); - dev->tbusy = 0; - } - fid = fid->next; - if (cnt++ > 200) { - printk("bbb in awc_fid_queue\n"); - // restore_flags(flags); - return -1; - }; - - } - //restore_flags(flags); - //debug =0x8; - }; - if (jiffies - dev->trans_start >= (5* HZ) ) { - awc_tx_timeout(dev); - } - return 1; - } - if (!skb) { DEBUG(1, " xmit skb=NULL, jiffie %ld \n",jiffies); return -1; }; if (test_and_set_bit( 0, (void *) &priv->tx_chain_active) ) { - dev->tbusy=0; + netif_start_queue (dev); return 1; } @@ -3075,15 +3034,7 @@ int direction = 1; return retval; } -int awc_tx_done(struct awc_fid * rx_fid){ - -// dev->tbusy = 0; - mark_bh(NET_BH); - - return 0; -}; - -int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { +int awc_rx(struct net_device *dev, struct awc_fid * rx_fid) { // struct awc_private *lp = (struct awc_private *)dev->priv; @@ -3109,7 +3060,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct NET_DEVICE *dev = (struct NET_DEVICE *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; // struct awc_private *lp; // unsigned long flags; @@ -3133,7 +3084,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { - struct enet_statistics *awc_get_stats(struct NET_DEVICE *dev) + struct enet_statistics *awc_get_stats(struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; // unsigned long flags; @@ -3142,7 +3093,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { DEBUG(2, "%s: awc_get_stats \n", dev->name); - if (!dev->start) { + if (!netif_running(dev)) { return 0; } // save_flags(flags); @@ -3175,7 +3126,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { } -int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ +int awc_change_mtu(struct net_device *dev, int new_mtu){ // struct awc_private *priv = (struct awc_private *)dev->priv; // unsigned long flags; @@ -3183,7 +3134,7 @@ int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ if ((new_mtu < 256 ) || (new_mtu > 2312) || (max_mtu && new_mtu > max_mtu) ) return -EINVAL; - if (dev->start) { + if (netif_running(dev)) { printk("PLEASE, ifconfig %s down for mtu change\n",dev->name); }; @@ -3207,7 +3158,7 @@ int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ void -awc_set_multicast_list(struct NET_DEVICE *dev) { +awc_set_multicast_list(struct net_device *dev) { // int ioaddr = dev->base_addr; /* if (dev->flags & IFF_PROMISC) diff --git a/drivers/net/aironet4500_proc.c b/drivers/net/aironet4500_proc.c index 2b28f1a63..b9da62ab7 100644 --- a/drivers/net/aironet4500_proc.c +++ b/drivers/net/aironet4500_proc.c @@ -264,7 +264,7 @@ int awc_proc_fun(ctl_table *ctl, int write, struct file * filp, struct awc_rid_dir * rid_dir; - struct NET_DEVICE * dev= NULL; + struct net_device * dev= NULL; struct aironet4500_RID * rid = (struct aironet4500_RID * ) ctl->extra2; diff --git a/drivers/net/aironet4500_rid.c b/drivers/net/aironet4500_rid.c index f1fb95dd6..7d52269f9 100644 --- a/drivers/net/aironet4500_rid.c +++ b/drivers/net/aironet4500_rid.c @@ -2134,7 +2134,7 @@ struct awc_rid_dir awc_rids[]={ int awc_nof_rids = (sizeof(awc_rids) / sizeof(struct awc_rid_dir)) -1; -int awc_rids_setup(struct NET_DEVICE * dev){ +int awc_rids_setup(struct net_device * dev){ struct awc_private * priv = (struct awc_private *) dev->priv; int i=0; diff --git a/drivers/net/am79c961a.c b/drivers/net/am79c961a.c index cfb48ca03..9c00c4cbd 100644 --- a/drivers/net/am79c961a.c +++ b/drivers/net/am79c961a.c @@ -20,13 +20,13 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/delay.h> #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/ecard.h> -#include <asm/delay.h> #define TX_BUFFERS 15 #define RX_BUFFERS 25 diff --git a/drivers/net/arlan.c b/drivers/net/arlan.c index d2a02efcb..0e3b982fe 100644 --- a/drivers/net/arlan.c +++ b/drivers/net/arlan.c @@ -102,6 +102,7 @@ static int arlan_hw_config (struct net_device * dev); static void arlan_tx_done_interrupt (struct net_device * dev, int status); static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short); static void arlan_process_interrupt (struct net_device * dev); +static void arlan_tx_timeout (struct net_device *dev); int arlan_command(struct net_device * dev, int command); EXPORT_SYMBOL(arlan_command); @@ -182,10 +183,7 @@ extern inline int arlan_drop_tx(struct net_device *dev) priv->txOffset = 0; priv->bad = 0; if (!priv->under_reset && !priv->under_config) - { - dev->tbusy = 0; - mark_bh(NET_BH); - } + netif_wake_queue (dev); } return 1; }; @@ -288,15 +286,9 @@ int arlan_command(struct net_device *dev, int command_p) } } if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) - { priv->under_reset = 1; - dev->start = 0; - } if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) - { priv->under_config = 1; - dev->start = 0; - } /* Issuing command */ arlan_lock_card_access(dev); @@ -341,14 +333,14 @@ int arlan_command(struct net_device *dev, int command_p) else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) { priv->under_reset=1; - dev->tbusy = 1; + netif_stop_queue (dev); arlan_drop_tx(dev); if (priv->tx_command_given || priv->rx_command_given) { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); }; - dev->tbusy = 1; + netif_stop_queue (dev); if (arlan_debug & ARLAN_DEBUG_RESET) printk(KERN_ERR "%s: Doing chip reset\n", dev->name); priv->lastReset = jiffies; @@ -388,7 +380,6 @@ int arlan_command(struct net_device *dev, int command_p) { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); } - dev->start = 0; arlan_drop_tx(dev); setInterruptEnable(dev); arlan_hw_config(dev); @@ -437,13 +428,11 @@ int arlan_command(struct net_device *dev, int command_p) } else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) { - if ( !registrationBad(dev) && (dev->tbusy || !dev->start) ) + if ( !registrationBad(dev) && + (netif_queue_stopped(dev) || !netif_running(dev)) ) { priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR; - - dev->tbusy = 0; - dev->start = 1; - mark_bh(NET_BH); + netif_wake_queue (dev); }; } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) @@ -587,8 +576,7 @@ extern inline void arlan_retransmit_now(struct net_device *dev) else IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty"); priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); return; } @@ -650,11 +638,8 @@ static void arlan_registration_timer(unsigned long data) priv->registrationLastSeen = jiffies; priv->registrationLostCount = 0; priv->reRegisterExp = 1; - if (dev->start == 0) - { - dev->start = 1; - mark_bh(NET_BH); - } + if (!netif_running(dev)) + netif_wake_queue(dev); } @@ -682,8 +667,7 @@ static void arlan_registration_timer(unsigned long data) if (!(TXHEAD(dev).offset && TXTAIL(dev).offset)) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } priv->tx_done_delayed = 0; bh_mark_needed = 1; @@ -691,8 +675,7 @@ static void arlan_registration_timer(unsigned long data) if (bh_mark_needed) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } arlan_process_interrupt(dev); @@ -788,7 +771,7 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) } else { - dev->tbusy = 1; + netif_stop_queue (dev); return -1; IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds); @@ -811,11 +794,11 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) } if (TXHEAD(dev).offset && TXTAIL(dev).offset) { - dev->tbusy = 1; + netif_stop_queue (dev); return 0; } else - dev->tbusy = 0; + netif_start_queue (dev); IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) @@ -1161,7 +1144,7 @@ static int arlan_mac_addr(struct net_device *dev, void *p) ARLAN_DEBUG_ENTRY("arlan_mac_addr"); return -EINVAL; - if (dev->start) + if (!netif_running(dev)) return -EBUSY; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); @@ -1223,8 +1206,8 @@ static int __init dev->set_multicast_list = arlan_set_multicast; dev->change_mtu = arlan_change_mtu; dev->set_mac_address = arlan_mac_addr; - dev->tbusy = 1; - dev->start = 0; + dev->tx_timeout = arlan_tx_timeout; + dev->watchdog_timeo = 3*HZ; ((struct arlan_private *) dev->priv)->irq_test_done = 0; arlan_device[num] = dev; @@ -1302,14 +1285,13 @@ static int arlan_open(struct net_device *dev) priv->open_time = jiffies; memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6); memset(dev->broadcast, 0xff, 6); - dev->tbusy = 1; priv->txOffset = 0; - dev->interrupt = 0; - dev->start = 0; dev->tx_queue_len = tx_queue_len; priv->interrupt_processing_active = 0; priv->command_lock = 0; + netif_start_queue (dev); + init_MUTEX(&priv->card_lock); myATOMIC_INIT(priv->card_users, 1); /* damn 2.0.33 */ priv->registrationLostCount = 0; @@ -1327,7 +1309,6 @@ static int arlan_open(struct net_device *dev) priv->Conf->writeEEPROM = 0; priv->Conf->registrationInterrupts = 1; - dev->tbusy = 0; init_timer(&priv->timer); priv->timer.expires = jiffies + HZ / 10; priv->timer.data = (unsigned long) dev; @@ -1335,8 +1316,6 @@ static int arlan_open(struct net_device *dev) arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW); udelay(200000); - dev->tbusy = 0; - dev->start = 1; add_timer(&priv->timer); MOD_INC_USE_COUNT; @@ -1351,69 +1330,43 @@ static int arlan_open(struct net_device *dev) } +static void arlan_tx_timeout (struct net_device *dev) +{ + printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); + /* Try to restart the adaptor. */ + arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); + dev->trans_start = jiffies; + netif_start_queue (dev); +} static int arlan_tx(struct sk_buff *skb, struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); - struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; + short length; + unsigned char *buf; ARLAN_DEBUG_ENTRY("arlan_tx"); - - if (dev->tbusy) - { - /* - * If we get here, some higher level has decided we are broken. - * There should really be a "kick me" function call instead. - */ - int tickssofar = jiffies - dev->trans_start; - - if (((tickssofar * 1000) / HZ) * 2 > conf->txTimeoutMs) - arlan_command(dev, ARLAN_COMMAND_TX_ABORT); - - if (((tickssofar * 1000) / HZ) < conf->txTimeoutMs) - { - // up(&priv->card_lock); - goto bad_end; - } - printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); - /* Try to restart the adaptor. */ - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - dev->trans_start = jiffies; - goto bad_end; - - } + /* - * Block a timer-based transmit from overlapping. This could better be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. + * If some higher layer thinks we've missed an tx-done interrupt + * we are passed NULL. Caution: dev_tint() handles the cli()/sti() + * itself. */ - if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) - { - printk(KERN_ERR "%s: Transmitter access conflict.\n", - dev->name); - } - else - { - short length; - unsigned char *buf; - - /* - * If some higher layer thinks we've missed an tx-done interrupt - * we are passed NULL. Caution: dev_tint() handles the cli()/sti() - * itself. - */ - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - buf = skb->data; + length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + buf = skb->data; + + if (priv->txOffset + length + 0x12 > 0x800) { + printk(KERN_ERR "TX RING overflow \n"); + netif_stop_queue (dev); + } - if (priv->txOffset + length + 0x12 > 0x800) - printk(KERN_ERR "TX RING overflow \n"); + if (arlan_hw_tx(dev, buf, length) == -1) + goto bad_end; - if (arlan_hw_tx(dev, buf, length) == -1) - goto bad_end; + dev->trans_start = jiffies; - dev->trans_start = jiffies; - } dev_kfree_skb(skb); arlan_process_interrupt(dev); @@ -1424,6 +1377,7 @@ static int arlan_tx(struct sk_buff *skb, struct net_device *dev) bad_end: arlan_process_interrupt(dev); priv->tx_chain_active = 0; + netif_stop_queue (dev); ARLAN_DEBUG_EXIT("arlan_tx"); return 1; } @@ -1522,8 +1476,7 @@ static void arlan_tx_done_interrupt(struct net_device *dev, int status) if (!TXHEAD(dev).offset || !TXTAIL(dev).offset) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } } @@ -1852,15 +1805,12 @@ static void arlan_process_interrupt(struct net_device *dev) WRITESHMB(arlan->rxStatus, 0x00); arlan_command(dev, ARLAN_COMMAND_RX); if (registrationBad(dev)) - dev->start = 0; + netif_device_detach(dev); if (!registrationBad(dev)) { priv->registrationLastSeen = jiffies; - if (!dev->tbusy && !priv->under_reset && !priv->under_config) - { - mark_bh(NET_BH); - dev->start = 1; - } + if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config) + netif_wake_queue (dev); } goto ends; } @@ -1900,12 +1850,10 @@ static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (!rxStatus && !txStatus) priv->interrupt_ack_requested++; - dev->interrupt++; arlan_process_interrupt(dev); priv->irq_test_done = 1; - dev->interrupt--; ARLAN_DEBUG_EXIT("arlan_interrupt"); return; @@ -1938,8 +1886,7 @@ static int arlan_close(struct net_device *dev) printk(KERN_NOTICE "%s: Closing device\n", dev->name); priv->open_time = 0; - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); free_irq(dev->irq, dev); MOD_DEC_USE_COUNT; diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c index 785a3fafd..28d50eb8c 100644 --- a/drivers/net/fc/iph5526.c +++ b/drivers/net/fc/iph5526.c @@ -218,6 +218,7 @@ static void update_scsi_oxid(struct fc_info *fi); Scsi_Host_Template driver_template = IPH5526_SCSI_FC; +static void iph5526_timeout(struct net_device *dev); #ifdef CONFIG_PCI static int iph5526_probe_pci(struct net_device *dev); @@ -286,6 +287,8 @@ static int __init fcdev_init(struct net_device *dev) dev->get_stats = iph5526_get_stats; dev->set_multicast_list = NULL; dev->change_mtu = iph5526_change_mtu; + dev->tx_timeout = iph5526_timeout; + dev->watchdog_timeo = 5*HZ; #ifndef MODULE fc_setup(dev); #endif diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 10b249b4e..c55556cc9 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -320,16 +320,14 @@ static void ax_changedmtu(struct ax_disp *ax) /* Set the "sending" flag. This must be atomic, hence the ASM. */ static inline void ax_lock(struct ax_disp *ax) { - if (test_and_set_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "mkiss: %s: trying to lock already locked device!\n", ax->dev->name); + netif_stop_queue(ax->dev); } /* Clear the "sending" flag. This must be atomic, hence the ASM. */ static inline void ax_unlock(struct ax_disp *ax) { - if (!test_and_clear_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "mkiss: %s: trying to unlock already unlocked device!\n", ax->dev->name); + netif_start_queue(ax->dev); } /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ @@ -435,7 +433,7 @@ static void ax25_write_wakeup(struct tty_struct *tty) struct mkiss_channel *mkiss; /* First make sure we're connected. */ - if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start) + if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) return; if (ax->xleft <= 0) { /* Now serial buffer is almost free & we can start @@ -449,8 +447,7 @@ static void ax25_write_wakeup(struct tty_struct *tty) ax_unlock(ax->mkiss); } - ax_unlock(ax); - mark_bh(NET_BH); + netif_wake_queue(ax->dev); return; } @@ -474,22 +471,22 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) tmp_ax = ax->mkiss; } - if (!dev->start) { + if (!netif_running(dev)) { printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); return 1; } if (tmp_ax != NULL) - if (tmp_ax->dev->tbusy) + if (netif_queue_stopped(tmp_ax->dev)) return 1; if (tmp_ax != NULL) - if (dev->tbusy) { + if (netif_queue_stopped(dev)) { printk(KERN_ERR "mkiss: dev busy while serial dev is free\n"); ax_unlock(ax); } - if (dev->tbusy) { + if (netif_queue_stopped(dev)) { /* * May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin. @@ -583,9 +580,8 @@ static int ax_open(struct net_device *dev) ax->xleft = 0; ax->flags &= (1 << AXF_INUSE); /* Clear ESCAPE & ERROR flags */ - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); return 0; /* Cleanup */ @@ -609,8 +605,7 @@ static int ax_close(struct net_device *dev) ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); return 0; } @@ -630,7 +625,7 @@ static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch { struct ax_disp *ax = (struct ax_disp *)tty->disc_data; - if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start) + if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) return; /* @@ -691,7 +686,7 @@ static int ax25_open(struct tty_struct *tty) if (mkiss->magic == MKISS_DRIVER_MAGIC) { for (cnt = 1; cnt < ax25_maxdev; cnt++) { if (ax25_ctrls[cnt]) { - if (ax25_ctrls[cnt]->dev.start) { + if (netif_running(&ax25_ctrls[cnt]->dev)) { if (ax == &ax25_ctrls[cnt]->ctrl) { cnt--; tmp_ax = &ax25_ctrls[cnt]->ctrl; @@ -802,7 +797,7 @@ int kiss_esc(unsigned char *s, unsigned char *d, int len) static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len) { unsigned char *ptr = d; - unsigned char c; + unsigned char c=0; *ptr++ = END; while (len > 0) { @@ -1221,7 +1216,7 @@ void cleanup_module(void) * VSV = if dev->start==0, then device * unregistred while close proc. */ - if (ax25_ctrls[i]->dev.start) + if (netif_running(&ax25_ctrls[i]->dev)) unregister_netdev(&(ax25_ctrls[i]->dev)); kfree(ax25_ctrls[i]); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 94645b12d..185af1262 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -48,7 +48,6 @@ * - Use hardware checksums. * - Convert to using the PCI infrastructure / IOC3 meta driver. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/kernel.h> diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 7a6cc5091..2dd149bf1 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -6,7 +6,7 @@ * Status: Stable. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Fri Feb 18 01:48:51 2000 + * Modified at: Wed Mar 1 11:29:34 2000 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no> @@ -715,9 +715,9 @@ static int nsc_ircc_setup(chipio_t *info) switch_bank(iobase, BANK2); outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); - /* IRCR2: FEND_MD is set */ + /* IRCR2: FEND_MD is not set */ switch_bank(iobase, BANK5); - outb(0x2a, iobase+4); + outb(0x02, iobase+4); /* Make sure that some defaults are OK */ switch_bank(iobase, BANK6); diff --git a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c index 2acd2e46a..5d72f7778 100644 --- a/drivers/net/pcmcia/aironet4500_cs.c +++ b/drivers/net/pcmcia/aironet4500_cs.c @@ -112,13 +112,13 @@ static void flush_stale_links(void) by the net software, because we only register already-found cards. */ -static int awc_pcmcia_init(struct NET_DEVICE *dev) +static int awc_pcmcia_init(struct net_device *dev) { return awc_init(dev); } -static int awc_pcmcia_open(struct NET_DEVICE *dev) +static int awc_pcmcia_open(struct net_device *dev) { dev_link_t *link; int status; @@ -136,7 +136,7 @@ static int awc_pcmcia_open(struct NET_DEVICE *dev) return status; } -static int awc_pcmcia_close(struct NET_DEVICE *dev) +static int awc_pcmcia_close(struct net_device *dev) { // int ioaddr = dev->base_addr; dev_link_t *link; @@ -170,7 +170,7 @@ static dev_link_t *awc_attach(void) { client_reg_t client_reg; dev_link_t *link = NULL; - struct NET_DEVICE *dev = NULL; + struct net_device *dev = NULL; int ret; PC_DEBUG(0, "awc_attach()\n"); @@ -199,8 +199,8 @@ static dev_link_t *awc_attach(void) /* Create the network device object. */ - dev = kmalloc(sizeof(struct NET_DEVICE ), GFP_KERNEL); - memset(dev,0,sizeof(struct NET_DEVICE)); + dev = kmalloc(sizeof(struct net_device ), GFP_KERNEL); + memset(dev,0,sizeof(struct net_device)); // dev = init_etherdev(0, sizeof(struct awc_private) ); if (!dev ) { printk(KERN_CRIT "out of mem on dev alloc \n"); @@ -321,10 +321,10 @@ static void awc_detach(dev_link_t *link) } if (link->priv) { - //struct NET_DEVICE *dev = link->priv; + //struct net_device *dev = link->priv; // dam dam damn mif (dev->priv) // kfree_s(dev->priv, sizeof(struct awc_private)); - kfree_s(link->priv, sizeof(struct NET_DEVICE)); + kfree_s(link->priv, sizeof(struct net_device)); } kfree_s(link->dev, sizeof(struct dev_node_t)); kfree_s(link, sizeof(struct dev_link_t)); @@ -345,7 +345,7 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void awc_pcmcia_config(dev_link_t *link) { client_handle_t handle; - struct NET_DEVICE *dev; + struct net_device *dev; struct awc_private *lp; tuple_t tuple; int ii; @@ -520,7 +520,7 @@ failed: static void awc_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct NET_DEVICE *dev = link->priv; + struct net_device *dev = link->priv; DEBUG(0, "awc_release(0x%p)\n", link); @@ -558,7 +558,7 @@ static int awc_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct NET_DEVICE *dev = link->priv; + struct net_device *dev = link->priv; PC_DEBUG(1, "awc_event(0x%06x)\n", event); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index baec21158..6853cc403 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -309,7 +309,7 @@ static void com20020_detach(dev_link_t *link) { DEBUG(1,"unregister...\n"); - if (dev->start) + if (netif_running(dev)) dev->stop(dev); /* @@ -501,7 +501,7 @@ static int com20020_event(event_t event, int priority, case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { - dev->tbusy = 1; dev->start = 0; + netif_device_detach(dev); link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; add_timer(&link->release); @@ -517,7 +517,7 @@ static int com20020_event(event_t event, int priority, case CS_EVENT_RESET_PHYSICAL: if (link->state & DEV_CONFIG) { if (link->open) { - dev->tbusy = 1; dev->start = 0; + netif_device_detach(dev); } CardServices(ReleaseConfiguration, link->handle); } diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 8e2e4f72e..a3a0018cb 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1,7 +1,7 @@ /* * rrunner.c: Linux driver for the Essential RoadRunner HIPPI board. * - * Written 1998 by Jes Sorensen, <Jes.Sorensen@cern.ch>. + * Copyright (C) 1998-2000 by Jes Sorensen, <Jes.Sorensen@cern.ch>. * * Thanks to Essential Communication for providing us with hardware * and very comprehensive documentation without which I would not have @@ -13,6 +13,12 @@ * 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. + * + * Thanks to Jayaram Bhat from ODS/Essential for fixing some of the + * stupid bugs in my code. + * + * Softnet support and various other patches from Val Henson of + * ODS/Essential. */ #define DEBUG 1 @@ -20,7 +26,7 @@ #define PKT_COPY_THRESHOLD 512 #include <linux/module.h> - +#include <linux/version.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/ioport.h> @@ -32,17 +38,53 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/mm.h> -#include <linux/cache.h> #include <net/sock.h> #include <asm/system.h> +#include <asm/cache.h> #include <asm/byteorder.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/uaccess.h> +#if (LINUX_VERSION_CODE < 0x02030e) +#define net_device device +#endif + +#if (LINUX_VERSION_CODE >= 0x02031b) +#define NEW_NETINIT +#endif + +#if (LINUX_VERSION_CODE < 0x02032b) +/* + * SoftNet changes + */ +#define dev_kfree_skb_irq(a) dev_kfree_skb(a) +#define netif_wake_queue(dev) clear_bit(0, &dev->tbusy) +#define netif_stop_queue(dev) set_bit(0, &dev->tbusy) + +static inline void netif_start_queue(struct net_device *dev) +{ + dev->tbusy = 0; + dev->start = 1; +} + +#define rr_mark_net_bh(foo) mark_bh(foo) +#define rr_if_busy(dev) dev->tbusy +#define rr_if_running(dev) dev->start /* Currently unused. */ +#define rr_if_down(dev) {do{dev->start = 0;}while (0);} +#else +#define NET_BH 0 +#define rr_mark_net_bh(foo) {do{} while(0);} +#define rr_if_busy(dev) test_bit(LINK_STATE_XOFF, &dev->state) +#define rr_if_running(dev) test_bit(LINK_STATE_START, &dev->state) +#define rr_if_down(dev) {do{} while(0);} +#endif + #include "rrunner.h" +#define RUN_AT(x) (jiffies + (x)) + /* * Implementation notes: @@ -59,7 +101,9 @@ * stack will need to know about I/O vectors or something similar. */ -static const char __initdata *version = "rrunner.c: v0.17 03/09/99 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; +static const char __initdata *version = "rrunner.c: v0.22 03/01/2000 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; + +static struct net_device *root_dev = NULL; /* @@ -72,11 +116,17 @@ extern __u32 sysctl_rmem_max; static int probed __initdata = 0; +#ifdef NEW_NETINIT int __init rr_hippi_probe (void) +#else +int __init rr_hippi_probe (struct net_device *dev) +#endif { +#ifdef NEW_NETINIT + struct net_device *dev; +#endif int boards_found = 0; int version_disp; /* was version info already displayed? */ - struct net_device *dev; struct pci_dev *pdev = NULL; struct pci_dev *opdev = NULL; u8 pci_latency; @@ -128,10 +178,11 @@ int __init rr_hippi_probe (void) dev->get_stats = &rr_get_stats; dev->do_ioctl = &rr_ioctl; - /* - * Dummy value. - */ - dev->base_addr = 42; +#if (LINUX_VERSION_CODE < 0x02030d) + dev->base_addr = pdev->base_address[0]; +#else + dev->base_addr = pdev->resource[0].start; +#endif /* display version info if adapter is found */ if (!version_disp) @@ -153,14 +204,14 @@ int __init rr_hippi_probe (void) printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI " "at 0x%08lx, irq %i, PCI latency %i\n", dev->name, - pdev->resource[0].start, dev->irq, pci_latency); + dev->base_addr, dev->irq, pci_latency); /* * Remap the regs into kernel space. */ rrpriv->regs = (struct rr_regs *) - ioremap(pdev->resource[0].start, 0x1000); + ioremap(dev->base_addr, 0x1000); if (!rrpriv->regs){ printk(KERN_ERR "%s: Unable to map I/O register, " @@ -193,10 +244,16 @@ int __init rr_hippi_probe (void) * 1 or more boards. Otherwise, return failure (-ENODEV). */ +#ifdef MODULE return boards_found; +#else + if (boards_found > 0) + return 0; + else + return -ENODEV; +#endif } -static struct net_device *root_dev = NULL; #ifdef MODULE #if LINUX_VERSION_CODE > 0x20118 @@ -204,10 +261,18 @@ MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@cern.ch>"); MODULE_DESCRIPTION("Essential RoadRunner HIPPI driver"); #endif - int init_module(void) { - return rr_hippi_probe()? 0 : -ENODEV; + int cards; + + root_dev = NULL; + +#ifdef NEW_NETINIT + cards = rr_hippi_probe(); +#else + cards = rr_hippi_probe(NULL); +#endif + return cards ? 0 : -ENODEV; } void cleanup_module(void) @@ -260,11 +325,11 @@ static void rr_issue_cmd(struct rr_private *rrpriv, struct cmd *cmd) idx = rrpriv->info->cmd_ctrl.pi; writel(*(u32*)(cmd), ®s->CmdRing[idx]); - mb(); + wmb(); idx = (idx - 1) % CMD_RING_ENTRIES; rrpriv->info->cmd_ctrl.pi = idx; - mb(); + wmb(); if (readl(®s->Mode) & FATAL_ERR) printk("error code %02x\n", readl(®s->Fail1)); @@ -363,8 +428,8 @@ static int rr_reset(struct net_device *dev) /* * Why 32 ? is this not cache line size dependant? */ - writel(WBURST_32, ®s->PciState); - mb(); + writel(RBURST_64|WBURST_64, ®s->PciState); + wmb(); start_pc = rr_read_eeprom_word(rrpriv, &hw->rncd_info.FwStart); @@ -374,11 +439,11 @@ static int rr_reset(struct net_device *dev) #endif writel(start_pc + 0x800, ®s->Pc); - mb(); + wmb(); udelay(5); writel(start_pc, ®s->Pc); - mb(); + wmb(); return 0; } @@ -495,7 +560,9 @@ static int __init rr_init(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; + struct eeprom *hw = NULL; u32 sram_size, rev; + int i; rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -519,6 +586,26 @@ static int __init rr_init(struct net_device *dev) printk(" Maximum receive rings %i\n", readl(®s->MaxRxRng)); #endif + /* + * Read the hardware address from the eeprom. The HW address + * is not really necessary for HIPPI but awfully convenient. + * The pointer arithmetic to put it in dev_addr is ugly, but + * Donald Becker does it this way for the GigE version of this + * card and it's shorter and more portable than any + * other method I've seen. -VAL + */ + + *(u16 *)(dev->dev_addr) = + htons(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA)); + *(u32 *)(dev->dev_addr+2) = + htonl(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA[4])); + + printk(" MAC: "); + + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[i]); + sram_size = rr_read_eeprom_word(rrpriv, (void *)8); printk(" SRAM size 0x%06x\n", sram_size); @@ -545,9 +632,10 @@ static int rr_init1(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; - u32 hostctrl; unsigned long myjif, flags; struct cmd cmd; + u32 hostctrl; + int ecode = 0; short i; rrpriv = (struct rr_private *)dev->priv; @@ -557,13 +645,14 @@ static int rr_init1(struct net_device *dev) hostctrl = readl(®s->HostCtrl); writel(hostctrl | HALT_NIC | RR_CLEAR_INT, ®s->HostCtrl); - mb(); + wmb(); if (hostctrl & PARITY_ERR){ printk("%s: Parity error halting NIC - this is serious!\n", dev->name); spin_unlock_irqrestore(&rrpriv->lock, flags); - return -EFAULT; + ecode = -EFAULT; + goto error; } set_rxaddr(regs, rrpriv->rx_ctrl); @@ -607,45 +696,36 @@ static int rr_init1(struct net_device *dev) rr_reset(dev); - writel(0x60, ®s->IntrTmr); - /* - * These seem to have no real effect as the Firmware sets - * it's own default values - */ - writel(0x10, ®s->WriteDmaThresh); - writel(0x20, ®s->ReadDmaThresh); + /* Tuning values */ + writel(0x5000, ®s->ConRetry); + writel(0x100, ®s->ConRetryTmr); + writel(0x500000, ®s->ConTmout); + writel(0x60, ®s->IntrTmr); + writel(0x500000, ®s->TxDataMvTimeout); + writel(0x200000, ®s->RxDataMvTimeout); + writel(0x80, ®s->WriteDmaThresh); + writel(0x80, ®s->ReadDmaThresh); rrpriv->fw_running = 0; - mb(); + wmb(); hostctrl &= ~(HALT_NIC | INVALID_INST_B | PARITY_ERR); writel(hostctrl, ®s->HostCtrl); - mb(); + wmb(); spin_unlock_irqrestore(&rrpriv->lock, flags); - udelay(1000); - - /* - * Now start the FirmWare. - */ - cmd.code = C_START_FW; - cmd.ring = 0; - cmd.index = 0; - - rr_issue_cmd(rrpriv, &cmd); - - /* - * Give the FirmWare time to chew on the `get running' command. - */ - myjif = jiffies + 5 * HZ; - while ((jiffies < myjif) && !rrpriv->fw_running); - for (i = 0; i < RX_RING_ENTRIES; i++) { struct sk_buff *skb; rrpriv->rx_ring[i].mode = 0; skb = alloc_skb(dev->mtu + HIPPI_HLEN, GFP_ATOMIC); + if (!skb) { + printk(KERN_WARNING "%s: Unable to allocate memory " + "for receive ring - halting NIC\n", dev->name); + ecode = -ENOMEM; + goto error; + } rrpriv->rx_skbuff[i] = skb; /* * Sanity test to see if we conflict with the DMA @@ -662,28 +742,43 @@ static int rr_init1(struct net_device *dev) rrpriv->rx_ctrl[4].entries = RX_RING_ENTRIES; rrpriv->rx_ctrl[4].mode = 8; rrpriv->rx_ctrl[4].pi = 0; - mb(); + wmb(); set_rraddr(&rrpriv->rx_ctrl[4].rngptr, rrpriv->rx_ring); - cmd.code = C_NEW_RNG; - cmd.ring = 4; + udelay(1000); + + /* + * Now start the FirmWare. + */ + cmd.code = C_START_FW; + cmd.ring = 0; cmd.index = 0; + rr_issue_cmd(rrpriv, &cmd); -#if 0 -{ - u32 tmp; - tmp = readl(®s->ExtIo); - writel(0x80, ®s->ExtIo); - - i = jiffies + 1 * HZ; - while (jiffies < i); - writel(tmp, ®s->ExtIo); -} -#endif - dev->tbusy = 0; - dev->start = 1; - return 0; + /* + * Give the FirmWare time to chew on the `get running' command. + */ + myjif = jiffies + 5 * HZ; + while ((jiffies < myjif) && !rrpriv->fw_running); + + netif_start_queue(dev); + + return ecode; + + error: + /* + * We might have gotten here because we are out of memory, + * make sure we release everything we allocated before failing + */ + for (i = 0; i < RX_RING_ENTRIES; i++) { + if (rrpriv->rx_skbuff[i]) { + rrpriv->rx_ring[i].size = 0; + set_rraddr(&rrpriv->rx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->rx_skbuff[i]); + } + } + return ecode; } @@ -705,81 +800,147 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) switch (rrpriv->evt_ring[eidx].code){ case E_NIC_UP: tmp = readl(®s->FwRev); - printk("%s: Firmware revision %i.%i.%i up and running\n", - dev->name, (tmp >> 16), ((tmp >> 8) & 0xff), - (tmp & 0xff)); + printk(KERN_INFO "%s: Firmware revision %i.%i.%i " + "up and running\n", dev->name, + (tmp >> 16), ((tmp >> 8) & 0xff), (tmp & 0xff)); rrpriv->fw_running = 1; - mb(); + writel(RX_RING_ENTRIES - 1, ®s->IpRxPi); + wmb(); break; case E_LINK_ON: - printk("%s: Optical link ON\n", dev->name); + printk(KERN_INFO "%s: Optical link ON\n", dev->name); break; case E_LINK_OFF: - printk("%s: Optical link OFF\n", dev->name); + printk(KERN_INFO "%s: Optical link OFF\n", dev->name); break; case E_RX_IDLE: - printk("%s: RX data not moving\n", dev->name); + printk(KERN_WARNING "%s: RX data not moving\n", + dev->name); break; case E_WATCHDOG: - printk("%s: The watchdog is here to see us\n", + printk(KERN_INFO "%s: The watchdog is here to see " + "us\n", dev->name); + break; + case E_INTERN_ERR: + printk(KERN_ERR "%s: HIPPI Internal NIC error\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_HOST_ERR: + printk(KERN_ERR "%s: Host software error\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; /* * TX events. */ case E_CON_REJ: - printk("%s: Connection rejected\n", dev->name); + printk(KERN_WARNING "%s: Connection rejected\n", + dev->name); rrpriv->stats.tx_aborted_errors++; break; case E_CON_TMOUT: - printk("%s: Connection timeout\n", dev->name); + printk(KERN_WARNING "%s: Connection timeout\n", + dev->name); break; case E_DISC_ERR: - printk("%s: HIPPI disconnect error\n", dev->name); + printk(KERN_WARNING "%s: HIPPI disconnect error\n", + dev->name); rrpriv->stats.tx_aborted_errors++; break; + case E_INT_PRTY: + printk(KERN_ERR "%s: HIPPI Internal Parity error\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; case E_TX_IDLE: - printk("%s: Transmitter idle\n", dev->name); + printk(KERN_WARNING "%s: Transmitter idle\n", + dev->name); break; case E_TX_LINK_DROP: - printk("%s: Link lost during transmit\n", dev->name); + printk(KERN_WARNING "%s: Link lost during transmit\n", + dev->name); rrpriv->stats.tx_aborted_errors++; + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_RNG: + printk(KERN_ERR "%s: Invalid send ring block\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_BUF: + printk(KERN_ERR "%s: Invalid send buffer address\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_DSC: + printk(KERN_ERR "%s: Invalid descriptor address\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; /* * RX events. */ - case E_VAL_RNG: /* Should be ignored */ -#if (DEBUG > 2) - printk("%s: RX ring valid event\n", dev->name); -#endif - writel(RX_RING_ENTRIES - 1, ®s->IpRxPi); - break; - case E_INV_RNG: - printk("%s: RX ring invalid event\n", dev->name); - break; case E_RX_RNG_OUT: - printk("%s: Receive ring full\n", dev->name); + printk(KERN_INFO "%s: Receive ring full\n", dev->name); break; case E_RX_PAR_ERR: - printk("%s: Receive parity error.\n", dev->name); + printk(KERN_WARNING "%s: Receive parity error\n", + dev->name); break; case E_RX_LLRC_ERR: - printk("%s: Receive LLRC error.\n", dev->name); + printk(KERN_WARNING "%s: Receive LLRC error\n", + dev->name); break; case E_PKT_LN_ERR: - printk("%s: Receive packet length error.\n", + printk(KERN_WARNING "%s: Receive packet length " + "error\n", dev->name); + break; + case E_RX_INV_BUF: + printk(KERN_ERR "%s: Invalid receive buffer " + "address\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_RX_INV_DSC: + printk(KERN_ERR "%s: Invalid receive descriptor " + "address\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_RNG_BLK: + printk(KERN_ERR "%s: Invalid ring block\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; default: - printk("%s: Unhandled event 0x%02x\n", + printk(KERN_WARNING "%s: Unhandled event 0x%02x\n", dev->name, rrpriv->evt_ring[eidx].code); } eidx = (eidx + 1) % EVT_RING_ENTRIES; } rrpriv->info->evt_ctrl.pi = eidx; - mb(); + wmb(); return eidx; } @@ -787,10 +948,10 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; - u32 pkt_len; struct rr_regs *regs = rrpriv->regs; do { + u32 pkt_len; pkt_len = rrpriv->rx_ring[index].size; #if (DEBUG > 2) printk("index %i, rxlimit %i\n", index, rxlimit); @@ -803,8 +964,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) if (pkt_len < PKT_COPY_THRESHOLD) { skb = alloc_skb(pkt_len, GFP_ATOMIC); if (skb == NULL){ - printk("%s: Out of memory deferring " - "packet\n", dev->name); + printk(KERN_WARNING "%s: Unable to allocate skb (%i bytes), deferring packet\n", dev->name, pkt_len); rrpriv->stats.rx_dropped++; goto defer; }else @@ -847,7 +1007,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) } while(index != rxlimit); rrpriv->cur_rx = index; - mb(); + wmb(); } @@ -857,7 +1017,6 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) struct rr_regs *regs; struct net_device *dev = (struct net_device *)dev_id; u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon; - unsigned long flags; rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -865,7 +1024,7 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) if (!(readl(®s->HostCtrl) & RR_INT)) return; - spin_lock_irqsave(&rrpriv->lock, flags); + spin_lock(&rrpriv->lock); prodidx = readl(®s->EvtPrd); txcsmr = (prodidx >> 8) & 0xff; @@ -886,7 +1045,7 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) do { rrpriv->stats.tx_packets++; rrpriv->stats.tx_bytes +=rrpriv->tx_skbuff[txcon]->len; - dev_kfree_skb(rrpriv->tx_skbuff[txcon]); + dev_kfree_skb_irq(rrpriv->tx_skbuff[txcon]); rrpriv->tx_skbuff[txcon] = NULL; rrpriv->tx_ring[txcon].size = 0; @@ -895,15 +1054,15 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) txcon = (txcon + 1) % TX_RING_ENTRIES; } while (txcsmr != txcon); - mb(); + wmb(); rrpriv->dirty_tx = txcon; - if (rrpriv->tx_full && dev->tbusy && + if (rrpriv->tx_full && rr_if_busy(dev) && (((rrpriv->info->tx_ctrl.pi + 1) % TX_RING_ENTRIES) != rrpriv->dirty_tx)){ rrpriv->tx_full = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue(dev); + rr_mark_net_bh(NET_BH); } } @@ -913,9 +1072,51 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) eidx |= ((txcsmr << 8) | (rxlimit << 16)); writel(eidx, ®s->EvtCon); - mb(); + wmb(); - spin_unlock_irqrestore(&rrpriv->lock, flags); + spin_unlock(&rrpriv->lock); +} + + +static void rr_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_regs *regs = rrpriv->regs; + unsigned long flags; + int i; + + if (readl(®s->HostCtrl) & NIC_HALTED){ + printk("%s: Restarting nic\n", dev->name); + memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl)); + memset(rrpriv->info, 0, sizeof(struct rr_info)); + wmb(); + for (i = 0; i < TX_RING_ENTRIES; i++) { + if (rrpriv->tx_skbuff[i]) { + rrpriv->tx_ring[i].size = 0; + set_rraddr(&rrpriv->tx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->tx_skbuff[i]); + rrpriv->tx_skbuff[i] = NULL; + } + } + + for (i = 0; i < RX_RING_ENTRIES; i++) { + if (rrpriv->rx_skbuff[i]) { + rrpriv->rx_ring[i].size = 0; + set_rraddr(&rrpriv->rx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->rx_skbuff[i]); + rrpriv->rx_skbuff[i] = NULL; + } + } + if (rr_init1(dev)) { + spin_lock_irqsave(&rrpriv->lock, flags); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + spin_unlock_irqrestore(&rrpriv->lock, flags); + } + } + rrpriv->timer.expires = RUN_AT(5*HZ); + add_timer(&rrpriv->timer); } @@ -936,22 +1137,21 @@ static int rr_open(struct net_device *dev) goto error; } - rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl), - GFP_KERNEL | GFP_DMA); + rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl), GFP_KERNEL); if (!rrpriv->rx_ctrl) { ecode = -ENOMEM; goto error; } - rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA); + rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL); if (!rrpriv->info){ - kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; ecode = -ENOMEM; goto error; } memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl)); memset(rrpriv->info, 0, sizeof(struct rr_info)); - mb(); + wmb(); spin_lock_irqsave(&rrpriv->lock, flags); writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl); @@ -965,22 +1165,40 @@ static int rr_open(struct net_device *dev) goto error; } - rr_init1(dev); + if ((ecode = rr_init1(dev))) + goto error; - dev->tbusy = 0; - dev->start = 1; + /* Set the timer to switch to check for link beat and perhaps switch + to an alternate media type. */ + init_timer(&rrpriv->timer); + rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */ + rrpriv->timer.data = (unsigned long)dev; + rrpriv->timer.function = &rr_timer; /* timer handler */ + add_timer(&rrpriv->timer); + + netif_start_queue(dev); MOD_INC_USE_COUNT; - return 0; + return ecode; error: spin_lock_irqsave(&rrpriv->lock, flags); writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl); spin_unlock_irqrestore(&rrpriv->lock, flags); - dev->tbusy = 1; - dev->start = 0; - return -ENOMEM; + if (rrpriv->info) { + kfree(rrpriv->info); + rrpriv->info = NULL; + } + if (rrpriv->rx_ctrl) { + kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; + } + + netif_stop_queue(dev); + rr_if_down(dev); + + return ecode; } @@ -1055,9 +1273,9 @@ static int rr_close(struct net_device *dev) u32 tmp; short i; - dev->start = 0; - set_bit(0, (void*)&dev->tbusy); - + netif_stop_queue(dev); + rr_if_down(dev); + rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -1074,11 +1292,13 @@ static int rr_close(struct net_device *dev) }else{ tmp |= HALT_NIC | RR_CLEAR_INT; writel(tmp, ®s->HostCtrl); - mb(); + wmb(); } rrpriv->fw_running = 0; + del_timer(&rrpriv->timer); + writel(0, ®s->TxPi); writel(0, ®s->IpRxPi); @@ -1098,6 +1318,7 @@ static int rr_close(struct net_device *dev) rrpriv->tx_ring[i].size = 0; set_rraddr(&rrpriv->tx_ring[i].addr, 0); dev_kfree_skb(rrpriv->tx_skbuff[i]); + rrpriv->tx_skbuff[i] = NULL; } } @@ -1106,11 +1327,18 @@ static int rr_close(struct net_device *dev) rrpriv->rx_ring[i].size = 0; set_rraddr(&rrpriv->rx_ring[i].addr, 0); dev_kfree_skb(rrpriv->rx_skbuff[i]); + rrpriv->rx_skbuff[i] = NULL; } } - kfree(rrpriv->rx_ctrl); - kfree(rrpriv->info); + if (rrpriv->rx_ctrl) { + kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; + } + if (rrpriv->info) { + kfree(rrpriv->info); + rrpriv->info = NULL; + } free_irq(dev->irq, dev); spin_unlock(&rrpriv->lock); @@ -1142,7 +1370,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) printk("incoming skb too small - reallocating\n"); if (!(new_skb = dev_alloc_skb(len + 8))) { dev_kfree_skb(skb); - dev->tbusy = 0; + netif_wake_queue(dev); return -EBUSY; } skb_reserve(new_skb, 8); @@ -1172,11 +1400,12 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) rrpriv->tx_ring[index].size = len + 8; /* include IFIELD */ rrpriv->tx_ring[index].mode = PACKET_START | PACKET_END; txctrl->pi = (index + 1) % TX_RING_ENTRIES; + wmb(); writel(txctrl->pi, ®s->TxPi); if (txctrl->pi == rrpriv->dirty_tx){ rrpriv->tx_full = 1; - set_bit(0, (void*)&dev->tbusy); + netif_stop_queue(dev); } spin_unlock_irqrestore(&rrpriv->lock, flags); diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index f7d86c103..283602e44 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -42,9 +42,9 @@ static const char *version = #include <linux/malloc.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/delay.h> #include <asm/system.h> #include <asm/bitops.h> -#include <asm/delay.h> #include <asm/io.h> #include <asm/dma.h> #include <linux/errno.h> diff --git a/drivers/net/setup.c b/drivers/net/setup.c index 472b23a8c..d47b1062e 100644 --- a/drivers/net/setup.c +++ b/drivers/net/setup.c @@ -185,27 +185,6 @@ static void __init appletalk_device_init(void) #endif /* CONFIG_IPDDP */ } - -/* - * The loopback device is global so it can be directly referenced - * by the network code. - */ - -extern int loopback_init(struct net_device *dev); -struct net_device loopback_dev = -{ - "lo" __PAD2, /* Software Loopback interface */ - 0x0, /* recv memory end */ - 0x0, /* recv memory start */ - 0x0, /* memory end */ - 0x0, /* memory start */ - 0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - loopback_init /* loopback_init should set up the rest */ -}; - static void special_device_init(void) { #ifdef CONFIG_DUMMY @@ -248,12 +227,20 @@ static void special_device_init(void) extern int sb1000_probe(struct net_device *dev); static struct net_device sb1000_dev = { - "cm0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe + "cm0 __PAD3", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe }; register_netdev(&sb1000_dev); } #endif - register_netdev(&loopback_dev); +#ifdef CONFIG_BONDING + { + extern int bond_init(struct net_device *dev); + static struct net_device bond_dev = { + "bond" __PAD4, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, bond_init, + }; + register_netdev(&bond_dev); + } +#endif } /* diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index e17304fd0..3a210c024 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.99 2000/02/16 10:36:14 davem Exp $ +/* $Id: sunlance.c,v 1.100 2000/02/27 09:38:12 anton Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -1287,8 +1287,10 @@ static void lance_set_multicast(struct net_device *dev) static void lance_set_multicast_retry(unsigned long _opaque) { struct net_device *dev = (struct net_device *) _opaque; + struct lance_private *lp = (struct lance_private *) dev->priv; lance_set_multicast(dev); + timer_exit(&lp->multicast_timer); } static void lance_free_hwresources(struct lance_private *lp) diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index b81815e25..0dfffbc8e 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -83,6 +83,11 @@ * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting * i.e. using functional address C0 00 00 04 00 00 to transmit and * receive multicast packets. + * + * Changes by Mike Sullivan (based on original sram patch by Dave Grothe + * to support windowing into on adapter shared ram. + * i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging + * will shift this 16K window over the entire available shared RAM. */ /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value @@ -102,7 +107,8 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ #define NO_AUTODETECT 1 #undef NO_AUTODETECT -#undef ENABLE_PAGING +/* #undef ENABLE_PAGING */ +#define ENABLE_PAGING 1 #define FALSE 0 @@ -119,7 +125,8 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ static char *version = "ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" " v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n" -" v2.2.0 12/30/98 Joel Sloan <jjs@c-me.com>\n"; +" v2.2.0 12/30/98 Joel Sloan <jjs@c-me.com>\n" +" v2.2.1 02/08/00 Mike Sullivan <sullivam@us.ibm.com>\n"; static char pcchannelid[] = { 0x05, 0x00, 0x04, 0x09, @@ -570,7 +577,7 @@ static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) ti->mapped_ram_size = ti->avail_shared_ram; } else { #ifdef ENABLE_PAGING - unsigned char pg_size; + unsigned char pg_size=0; #endif #if !TR_NEWFORMAT @@ -590,15 +597,16 @@ static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) pg_size=64; /* 32KB page size */ break; case 0xc: - ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); - /* nb/dwm: I did this because RRR (3,2) bits are documented as - R/O and I can't find how to select which page size - Also, the above conditional statement sequence is invalid - as page_mask will always be set by the second stmt */ - kfree_s(ti, sizeof(struct tok_info)); - return -ENODEV; + switch (ti->mapped_ram_size) { + case 32: + ti->page_mask=0xc0; + pg_size=32; + break; + case 64: + ti->page_mask=0x80; + pg_size=64; + break; + } break; default: DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); @@ -606,16 +614,22 @@ static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) return -ENODEV; break; } + + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("Shared RAM paging code: " + "%02X mapped RAM size: %dK shared RAM size: %dK page mask: %0xX\n:", + ti->shared_ram_paging, ti->mapped_ram_size/2, ti->avail_shared_ram/2, ti->page_mask); + if (ti->page_mask) { if (pg_size > ti->mapped_ram_size) { DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", - pg_size, ti->mapped_ram_size); + pg_size/2, ti->mapped_ram_size/2); ti->page_mask = 0; /* reset paging */ - } else { - ti->mapped_ram_size=ti->avail_shared_ram; - DPRINTK("Shared RAM paging enabled. Page size : %uK\n", - ((ti->page_mask^ 0xff)+1)>>2); - } + } + } else if (pg_size > ti->mapped_ram_size) { + DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", + pg_size/2, ti->mapped_ram_size/2); + } #endif } /* finish figuring the shared RAM address */ @@ -673,9 +687,17 @@ static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (ti->page_mask) + DPRINTK("Shared RAM paging enabled. Page size: %uK Shared Ram size %dK\n", + ((ti->page_mask ^ 0xff)+1)>>2,ti->avail_shared_ram/2); + else + DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n",ti->page_mask); #endif /* Calculate the maximum DHB we can use */ - switch (ti->mapped_ram_size) { + if (!ti->page_mask) { + ti->avail_shared_ram=ti->mapped_ram_size; + } + switch (ti->avail_shared_ram) { case 16 : /* 8KB shared RAM */ ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; @@ -685,34 +707,34 @@ static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) ti->rbuf_cnt16 = 2; break; case 32 : /* 16KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 520; ti->rbuf_cnt4 = 9; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 4096); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; /* 1024 usable */ ti->rbuf_cnt16 = 4; break; case 64 : /* 32KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 10240); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 10; break; case 127 : /* 63KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 16384); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 16; break; case 128 : /* 64KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 17960); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 18; break; @@ -764,6 +786,7 @@ static int __init trdev_init(struct net_device *dev) { struct tok_info *ti=(struct tok_info *)dev->priv; + SET_PAGE(ti->srb_page); ti->open_status = CLOSED; dev->init = tok_init_card; @@ -802,7 +825,7 @@ static void tok_set_multicast_list(struct net_device *dev) address[3] |= mclist->dmi_addr[5]; mclist = mclist->next; } - SET_PAGE(ti->srb); + SET_PAGE(ti->srb_page); for (i=0; i<sizeof(struct srb_set_funct_addr); i++) isa_writeb(0, ti->srb+i); @@ -848,7 +871,7 @@ static int tok_close(struct net_device *dev) struct tok_info *ti=(struct tok_info *) dev->priv; netif_stop_queue(dev); - + SET_PAGE(ti->srb_page); isa_writeb(DIR_CLOSE_ADAPTER, ti->srb + offsetof(struct srb_close_adapter, command)); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -857,6 +880,7 @@ static int tok_close(struct net_device *dev) sleep_on(&ti->wait_for_tok_int); + SET_PAGE(ti->srb_page); if (isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))) DPRINTK("close adapter failed: %02X\n", (int)isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))); @@ -875,6 +899,9 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) unsigned char status; struct tok_info *ti; struct net_device *dev; +#ifdef ENABLE_PAGING + unsigned char save_srpr; +#endif dev = dev_id; #if TR_VERBOSE @@ -882,6 +909,9 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) #endif ti = (struct tok_info *) dev->priv; spin_lock(&(ti->lock)); +#ifdef ENABLE_PAGING + save_srpr=isa_readb(ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); +#endif /* Disable interrupts till processing is finished */ isa_writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); @@ -907,17 +937,15 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) if (status == 0xFF) { DPRINTK("PCMCIA card removed.\n"); - spin_unlock(&(ti->lock)); - return; + goto return_point ; } /* Check ISRP EVEN too. */ if ( isa_readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF) { DPRINTK("PCMCIA card removed.\n"); - spin_unlock(&(ti->lock)); - return; - } + goto return_point ; + } #endif @@ -925,8 +953,15 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) int i; __u32 check_reason; + __u8 check_reason_page=0; - check_reason=ti->mmio + ntohs(isa_readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN)); + check_reason=ntohs(isa_readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN)); + if (ti->page_mask) { + check_reason_page=(check_reason>>8) & ti->page_mask; + check_reason &= ~(ti->page_mask << 8); + } + check_reason += ti->sram; + SET_PAGE(check_reason_page); DPRINTK("Adapter check interrupt\n"); DPRINTK("8 reason bytes follow: "); @@ -951,6 +986,12 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) /* SRB, ASB, ARB or SSB response */ if (status & SRB_RESP_INT) { /* SRB response */ + SET_PAGE(ti->srb_page); +#if TR_VERBOSE + DPRINTK("SRB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->srb), + isa_readb(ti->srb + offsetof(struct srb_xmit, ret_code))); +#endif switch(isa_readb(ti->srb)) { /* SRB command check */ @@ -962,7 +1003,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) DPRINTK("error on xmit_dir_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; } netif_wake_queue(dev); @@ -979,7 +1020,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) DPRINTK("error on xmit_ui_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; } netif_wake_queue(dev); @@ -993,10 +1034,25 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) unsigned char open_ret_code; __u16 open_error_code; - ti->srb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr))); - ti->ssb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr))); - ti->arb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr))); - ti->asb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr))); + ti->srb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr))); + ti->ssb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr))); + ti->arb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr))); + ti->asb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr))); + if (ti->page_mask) { + ti->srb_page=(ti->srb>>8) & ti->page_mask; + ti->srb &= ~(ti->page_mask<<8); + ti->ssb_page=(ti->ssb>>8) & ti->page_mask; + ti->ssb &= ~(ti->page_mask<<8); + ti->arb_page=(ti->arb>>8) & ti->page_mask; + ti->arb &= ~(ti->page_mask<<8); + ti->asb_page=(ti->asb>>8) & ti->page_mask; + ti->asb &= ~(ti->page_mask<<8); + } + ti->srb+=ti->sram; + ti->ssb+=ti->sram; + ti->arb+=ti->sram; + ti->asb+=ti->sram; + ti->current_skb=NULL; open_ret_code = isa_readb(ti->init_srb +offsetof(struct srb_open_response, ret_code)); @@ -1125,6 +1181,10 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) } /* SRB response */ if (status & ASB_FREE_INT) { /* ASB response */ + SET_PAGE(ti->asb_page); +#if TR_VERBOSE + DPRINTK("ASB resp: cmd=%02X\n", isa_readb(ti->asb)); + #endif switch(isa_readb(ti->asb)) { /* ASB command check */ @@ -1147,6 +1207,12 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) } /* ASB response */ if (status & ARB_CMD_INT) { /* ARB response */ + SET_PAGE(ti->arb_page); +#if TR_VERBOSE + DPRINTK("ARB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->arb), + isa_readb(ti->arb + offsetof(struct arb_dlc_status, status))); +#endif switch (isa_readb(ti->arb)) { /* ARB command check */ @@ -1203,6 +1269,11 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) if (status & SSB_RESP_INT) { /* SSB response */ unsigned char retcode; + SET_PAGE(ti->ssb_page); +#if TR_VERBOSE + DPRINTK("SSB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->ssb), isa_readb(ti->ssb+2)); +#endif switch (isa_readb(ti->ssb)) { /* SSB command check */ case XMIT_DIR_FRAME: @@ -1216,6 +1287,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) case XMIT_XID_CMD: DPRINTK("xmit xid ret_code: %02X\n", (int)isa_readb(ti->ssb+2)); + break; default: DPRINTK("Unknown command %02X in ssb\n", (int)isa_readb(ti->ssb)); @@ -1240,6 +1312,13 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) DPRINTK("Unexpected interrupt from tr adapter\n"); } +#ifdef PCMCIA + return_point: +#endif +#ifdef ENABLE_PAGING + isa_writeb(save_srpr, ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); +#endif + spin_unlock(&(ti->lock)); } @@ -1262,9 +1341,26 @@ static void initial_tok_int(struct net_device *dev) isa_writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN); ti->sram=((__u32)ti->sram_base << 12); } - ti->init_srb=ti->sram - +ntohs((unsigned short)isa_readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); - SET_PAGE(ntohs((unsigned short)isa_readw(ti->mmio+ACA_OFFSET + WRBR_EVEN))); + ti->init_srb=ntohs((unsigned short)isa_readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); + if (ti->page_mask) { + ti->init_srb_page=(ti->init_srb>>8)&ti->page_mask; + ti->init_srb &= ~(ti->page_mask<<8); + } + ti->init_srb+=ti->sram; + + if (ti->avail_shared_ram == 127) { + int i; + int last_512=0xfe00; + if (ti->page_mask) { + last_512 &= ~(ti->page_mask<<8); + } + /* initialize high section of ram (if necessary) */ + SET_PAGE(0xc0); + for (i=0; i<512; i++) { + isa_writeb(0,ti->sram+last_512+i); + } + } + SET_PAGE(ti->init_srb_page); dev->mem_start = ti->sram; dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1; @@ -1272,7 +1368,7 @@ static void initial_tok_int(struct net_device *dev) #if TR_VERBOSE { int i; - DPRINTK("init_srb(%p):", ti->init_srb); + DPRINTK("init_srb(%lx):", (long)ti->init_srb); for (i=0;i<17;i++) printk("%02X ", (int)isa_readb(ti->init_srb+i)); printk("\n"); } @@ -1325,11 +1421,6 @@ static int tok_init_card(struct net_device *dev) /* Reset adapter */ netif_stop_queue(dev); -#ifdef ENABLE_PAGING - if(ti->page_mask) - isa_writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - isa_writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); #if !TR_NEWFORMAT @@ -1339,6 +1430,10 @@ static int tok_init_card(struct net_device *dev) outb(0, PIOaddr+ADAPTRESET); for (i=jiffies+TR_RESET_INTERVAL; time_before_eq(jiffies, i);); /* wait 50ms */ outb(0,PIOaddr+ADAPTRESETREL); +#ifdef ENABLE_PAGING + if(ti->page_mask) + isa_writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif #if !TR_NEWFORMAT DPRINTK("card reset\n"); @@ -1354,7 +1449,7 @@ static void open_sap(unsigned char type,struct net_device *dev) int i; struct tok_info *ti=(struct tok_info *) dev->priv; - SET_PAGE(ti->srb); + SET_PAGE(ti->srb_page); for (i=0; i<sizeof(struct dlc_open_sap); i++) isa_writeb(0, ti->srb+i); @@ -1417,6 +1512,12 @@ void tok_open_adapter(unsigned long dev_addr) ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta)); ti->srb=ti->init_srb; /* We use this one in the interrupt handler */ + ti->srb_page=ti->init_srb_page; + DPRINTK("Opend adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n", + isa_readb(ti->init_srb+offsetof(struct dir_open_adapter,num_dhb)), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,dhb_length))), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,num_rcv_buf))), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,rcv_buf_len))) ); isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -1432,7 +1533,11 @@ static void tr_tx(struct net_device *dev) unsigned char xmit_command; int i; struct trllc *llc; + struct srb_xmit xsrb; + __u8 dhb_page=0; + __u8 llc_ssap; + SET_PAGE(ti->asb_page); if (isa_readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF) DPRINTK("ASB not free !!!\n"); @@ -1441,8 +1546,13 @@ static void tr_tx(struct net_device *dev) providing a shared memory address for us to stuff with data. Here we compute the effective address where we will place data.*/ - dhb=ti->sram - +ntohs(isa_readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address))); + SET_PAGE(ti->arb_page); + dhb=ntohs(isa_readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address))); + if (ti->page_mask) { + dhb_page=(dhb >> 8) & ti->page_mask; + dhb &= ~(ti->page_mask << 8); + } + dhb+=ti->sram; /* Figure out the size of the 802.5 header */ if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */ @@ -1453,13 +1563,17 @@ static void tr_tx(struct net_device *dev) llc = (struct trllc *)(ti->current_skb->data + hdr_len); - xmit_command = isa_readb(ti->srb + offsetof(struct srb_xmit, command)); - + llc_ssap=llc->ssap; + SET_PAGE(ti->srb_page); + isa_memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb)); + SET_PAGE(ti->asb_page); + xmit_command=xsrb.command; + isa_writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command)); - isa_writew(isa_readb(ti->srb + offsetof(struct srb_xmit, station_id)), + isa_writew(xsrb.station_id, ti->asb + offsetof(struct asb_xmit_resp, station_id)); - isa_writeb(llc->ssap, ti->asb + offsetof(struct asb_xmit_resp, rsap_value)); - isa_writeb(isa_readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)), + isa_writeb(llc_ssap, ti->asb + offsetof(struct asb_xmit_resp, rsap_value)); + isa_writeb(xsrb.cmd_corr, ti->asb + offsetof(struct asb_xmit_resp, cmd_corr)); isa_writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code)); @@ -1468,6 +1582,7 @@ static void tr_tx(struct net_device *dev) isa_writew(htons(0x11), ti->asb + offsetof(struct asb_xmit_resp, frame_length)); isa_writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length)); + SET_PAGE(dhb_page); isa_writeb(AC, dhb); isa_writeb(LLC_FRAME, dhb+1); @@ -1487,11 +1602,12 @@ static void tr_tx(struct net_device *dev) isa_writew(htons(ti->current_skb->len), ti->asb + offsetof(struct asb_xmit_resp, frame_length)); + SET_PAGE(dhb_page); isa_memcpy_toio(dhb, ti->current_skb->data, ti->current_skb->len); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); ti->tr_stats.tx_bytes+=ti->current_skb->len; - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; netif_wake_queue(dev); if (ti->readlog_pending) ibmtr_readlog(dev); @@ -1501,6 +1617,7 @@ static void tr_rx(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; __u32 rbuffer, rbufdata; + __u8 rbuffer_page=0; __u32 llc; unsigned char *data; unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length; @@ -1509,31 +1626,40 @@ static void tr_rx(struct net_device *dev) int IPv4_p = 0; unsigned int chksum = 0; struct iphdr *iph; + struct arb_rec_req rarb; - rbuffer=(ti->sram - +ntohs(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2; - + SET_PAGE(ti->arb_page); + isa_memcpy_fromio(&rarb, ti->arb, sizeof(rarb)); + rbuffer=ntohs(rarb.rec_buf_addr)+2; + if (ti->page_mask) { + rbuffer_page=(rbuffer >> 8) & ti->page_mask; + rbuffer &= ~(ti->page_mask<<8); + } + rbuffer += ti->sram; + + SET_PAGE(ti->asb_page); if(isa_readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF) DPRINTK("ASB not free !!!\n"); isa_writeb(REC_DATA, ti->asb + offsetof(struct asb_rec, command)); - isa_writew(isa_readw(ti->arb + offsetof(struct arb_rec_req, station_id)), + isa_writew(rarb.station_id, ti->asb + offsetof(struct asb_rec, station_id)); - isa_writew(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)), + isa_writew(rarb.rec_buf_addr, ti->asb + offsetof(struct asb_rec, rec_buf_addr)); - lan_hdr_len=isa_readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len)); + lan_hdr_len=rarb.lan_hdr_len; hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr); - + + SET_PAGE(rbuffer_page); llc=(rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len); #if TR_VERBOSE DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n", (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len); - DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc, - ntohs(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), - ti->sram); + DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %lx\n", llc, + ntohs(rarb.rec_buf_addr), + (long)ti->sram); DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, " "ethertype: %04X\n", (int)isa_readb(llc + offsetof(struct trllc, dsap)), @@ -1545,14 +1671,15 @@ static void tr_rx(struct net_device *dev) (int)isa_readw(llc + offsetof(struct trllc, ethertype))); #endif if (isa_readb(llc + offsetof(struct trllc, llc))!=UI_CMD) { + SET_PAGE(ti->asb_page); isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); ti->tr_stats.rx_dropped++; isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); return; } - length = ntohs(isa_readw(ti->arb+offsetof(struct arb_rec_req, frame_len))); - if ((isa_readb(llc + offsetof(struct trllc, dsap))==EXTENDED_SAP) && + length = ntohs(rarb.frame_len); + if ((isa_readb(llc + offsetof(struct trllc, dsap))==EXTENDED_SAP) && (isa_readb(llc + offsetof(struct trllc, ssap))==EXTENDED_SAP) && (length>=hdr_len)) { IPv4_p = 1; @@ -1585,11 +1712,12 @@ static void tr_rx(struct net_device *dev) } #endif - skb_size = length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc); + skb_size = length; if (!(skb=dev_alloc_skb(skb_size))) { DPRINTK("out of memory. frame dropped.\n"); ti->tr_stats.rx_dropped++; + SET_PAGE(ti->asb_page); isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); return; @@ -1630,11 +1758,17 @@ static void tr_rx(struct net_device *dev) break; length -= rbuffer_len; data += rbuffer_len; + if (ti->page_mask) { + rbuffer_page=(rbuffer>>8) & ti->page_mask; + rbuffer &= ~(ti->page_mask << 8); + } rbuffer += ti->sram; + SET_PAGE(rbuffer_page); rbuffer_len = ntohs(isa_readw(rbuffer + offsetof(struct rec_buf, buf_len))); rbufdata = rbuffer + offsetof(struct rec_buf, data); } + SET_PAGE(ti->asb_page); isa_writeb(0, ti->asb + offsetof(struct asb_rec, ret_code)); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -1663,6 +1797,7 @@ static int tok_send_packet(struct sk_buff *skb, struct net_device *dev) /* Save skb; we'll need it when the adapter asks for the data */ ti->current_skb=skb; + SET_PAGE(ti->srb_page); isa_writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command)); isa_writew(ti->exsap_station_id, ti->srb +offsetof(struct srb_xmit, station_id)); @@ -1685,6 +1820,7 @@ void ibmtr_readlog(struct net_device *dev) { ti=(struct tok_info *) dev->priv; ti->readlog_pending = 0; + SET_PAGE(ti->srb_page); isa_writeb(DIR_READ_LOG, ti->srb); isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); diff --git a/drivers/net/tokenring/ibmtr.h b/drivers/net/tokenring/ibmtr.h index 769af277a..3e341078b 100644 --- a/drivers/net/tokenring/ibmtr.h +++ b/drivers/net/tokenring/ibmtr.h @@ -133,9 +133,9 @@ #define TCR_ODD 0x0D #define TVR_EVEN 0x0E /* Timer value registers - even and odd */ #define TVR_ODD 0x0F -#define SRPR_EVEN 0x10 /* Shared RAM paging registers - even and odd */ +#define SRPR_EVEN 0x18 /* Shared RAM paging registers - even and odd */ #define SRPR_ENABLE_PAGING 0xc0 -#define SRPR_ODD 0x11 /* Not used. */ +#define SRPR_ODD 0x19 /* Not used. */ #define TOKREAD 0x60 #define TOKOR 0x40 #define TOKAND 0x20 @@ -162,7 +162,7 @@ #define ACA_RW 0x00 #ifdef ENABLE_PAGING -#define SET_PAGE(x) (isa_writeb(((x>>8)&ti.page_mask), \ +#define SET_PAGE(x) (isa_writeb((x), \ ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)) #else #define SET_PAGE(x) @@ -205,6 +205,11 @@ struct tok_info { __u32 ssb; /* System Status Block address */ __u32 arb; /* Adapter Request Block address */ __u32 asb; /* Adapter Status Block address */ + __u8 init_srb_page; + __u8 srb_page; + __u8 ssb_page; + __u8 arb_page; + __u8 asb_page; unsigned short exsap_station_id; unsigned short global_int_enable; struct sk_buff *current_skb; diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 7ac6aa08d..b009a8a4b 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -56,6 +56,12 @@ static struct eeprom_fixup eeprom_fixups[] __devinitdata = { 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */ 0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */ }}, + {"NetWinder", 0x00, 0x10, 0x57, + /* Default media = MII + * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1 + */ + { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 } + }, {0, 0, 0, 0, {}}}; diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 3642a13b4..a5cdc6b8d 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -50,7 +50,6 @@ enum chips { DC21140 = 2, DC21142 = 3, DC21143 = 3, LC82C168, - NGMC169, MX98713, MX98715, MX98725, @@ -242,8 +241,10 @@ struct mediainfo { struct tulip_private { const char *product_name; struct net_device *next_module; - struct tulip_rx_desc rx_ring[RX_RING_SIZE]; - struct tulip_tx_desc tx_ring[TX_RING_SIZE]; + struct tulip_rx_desc *rx_ring; + struct tulip_tx_desc *tx_ring; + dma_addr_t rx_ring_dma; + dma_addr_t tx_ring_dma; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct sk_buff *tx_skbuff[TX_RING_SIZE]; /* The addresses of receive-in-place skbuffs. */ diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 3be78468b..dbbaaa5d7 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -19,7 +19,7 @@ */ -static const char version[] = "Linux Tulip driver version 0.9.3 (Feb 23, 2000)\n"; +static const char version[] = "Linux Tulip driver version 0.9.4 (Feb 28, 2000)\n"; #include <linux/module.h> #include "tulip.h" @@ -51,7 +51,7 @@ const char * const medianame[] = { }; /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ -#ifdef __alpha__ +#if defined(__alpha__) || defined(__arm__) static int rx_copybreak = 1518; #else static int rx_copybreak = 100; @@ -74,6 +74,8 @@ static int rx_copybreak = 100; static int csr0 = 0x01A00000 | 0xE000; #elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__) static int csr0 = 0x01A00000 | 0x8000; +#elif defined(__arm__) +static int csr0 = 0x01A00000 | 0x4800; #else #warning Processor architecture undefined! static int csr0 = 0x00A00000 | 0x4800; @@ -123,8 +125,6 @@ struct tulip_chip_table tulip_tbl[] = { t21142_timer }, { "Lite-On 82c168 PNIC", 256, 0x0001ebef, HAS_MII | HAS_PNICNWAY, pnic_timer }, - { "NETGEAR NGMC169 MAC", 256, 0x0001ebef, - HAS_MII | HAS_PNICNWAY, pnic_timer }, { "Macronix 98713 PMAC", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, { "Macronix 98715 PMAC", 256, 0x0001ebef, @@ -155,7 +155,6 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 }, { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 }, { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 }, - { 0x1385, 0xf004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NGMC169 }, { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 }, { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 }, @@ -301,8 +300,8 @@ static void tulip_up(struct net_device *dev) tp->cur_tx++; } - outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3); - outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4); + outl(tp->rx_ring_dma, ioaddr + CSR3); + outl(tp->tx_ring_dma, ioaddr + CSR4); tp->saved_if_port = dev->if_port; if (dev->if_port == 0) @@ -569,12 +568,12 @@ static void tulip_init_ring(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { tp->rx_ring[i].status = 0x00000000; tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ); - tp->rx_ring[i].buffer2 = virt_to_le32desc(&tp->rx_ring[i+1]); + tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1)); tp->rx_skbuff[i] = NULL; } /* Mark the last entry as wrapping the ring. */ tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP); - tp->rx_ring[i-1].buffer2 = virt_to_le32desc(&tp->rx_ring[0]); + tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma); for (i = 0; i < RX_RING_SIZE; i++) { /* Note the receive buffer must be longword aligned. @@ -595,9 +594,9 @@ static void tulip_init_ring(struct net_device *dev) for (i = 0; i < TX_RING_SIZE; i++) { tp->tx_skbuff[i] = 0; tp->tx_ring[i].status = 0x00000000; - tp->tx_ring[i].buffer2 = virt_to_le32desc(&tp->tx_ring[i+1]); + tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1)); } - tp->tx_ring[i-1].buffer2 = virt_to_le32desc(&tp->tx_ring[0]); + tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma); } static int @@ -1033,6 +1032,13 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, */ tp = dev->priv; + tp->rx_ring = pci_alloc_consistent(pdev, + sizeof(struct tulip_rx_desc) * RX_RING_SIZE + + sizeof(struct tulip_tx_desc) * TX_RING_SIZE, + &tp->rx_ring_dma); + tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); + tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; + tp->chip_id = chip_idx; tp->flags = tulip_tbl[chip_idx].flags; tp->pdev = pdev; @@ -1352,6 +1358,11 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev) if (dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; + pci_free_consistent(pdev, + sizeof(struct tulip_rx_desc) * RX_RING_SIZE + + sizeof(struct tulip_tx_desc) * TX_RING_SIZE, + tp->rx_ring, + tp->rx_ring_dma); unregister_netdev(dev); release_region(dev->base_addr, tulip_tbl[tp->chip_id].io_size); diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 64165cd0e..e7875649e 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -565,7 +565,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master) flp->dlci[i] = -*(short *)(master->dev_addr); master->mtu = slave->mtu; - if (netif_running(dev)) { + if (netif_running(slave)) { if (flp->config.station == FRAD_STATION_CPE) sdla_reconfig(slave); else diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c index c0b419afa..4bc7762cb 100644 --- a/drivers/net/wan/sdla_chdlc.c +++ b/drivers/net/wan/sdla_chdlc.c @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Feb 28, 2000 Jeff Garzik softnet updates * Nov 20, 1999 Nenad Corbic Fixed zero length API bug. * Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup. * Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing @@ -64,6 +65,7 @@ #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) +#define TX_TIMEOUT (5*HZ) /******Data Structures*****************************************************/ @@ -130,6 +132,7 @@ static int del_if (wan_device_t* wandev, struct net_device* dev); static int if_init (struct net_device* dev); static int if_open (struct net_device* dev); static int if_close (struct net_device* dev); +static void if_tx_timeout (struct net_device *dev); static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len); #ifdef LINUX_2_1 @@ -441,7 +444,7 @@ static int update (wan_device_t* wandev) if(test_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - if(!dev->start) + if(!netif_running(dev)) return -ENODEV; flags = card->u.c.flags; @@ -652,6 +655,8 @@ static int if_init (struct net_device* dev) dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->flags |= IFF_POINTTOPOINT; @@ -709,7 +714,7 @@ static int if_open (struct net_device* dev) /* Only one open per interface is allowed */ - if(dev->start) + if(netif_running(dev)) return -EBUSY; if(test_and_set_bit(1, (void*)&card->wandev.critical)) { @@ -774,9 +779,7 @@ static int if_open (struct net_device* dev) do_gettimeofday(&tv); chdlc_priv_area->router_start_time = tv.tv_sec; - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); dev->flags |= IFF_POINTTOPOINT; wanpipe_open(card); @@ -796,7 +799,7 @@ static int if_close (struct net_device* dev) if(test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); port_set_state(card, WAN_DISCONNECTED); chdlc_set_intr_mode(card, 0); @@ -843,6 +846,30 @@ static int if_rebuild_hdr (void* hdr, struct net_device* dev, unsigned long radd } #endif + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit timeout !\n", + card->devname); + + /* unbusy the interface */ + netif_start_queue (dev); +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -875,30 +902,10 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) */ printk(KERN_INFO "%s: interface %s got kicked!\n", card->devname, dev->name); - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } - if(dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - ++card->wandev.stats.collisions; - - if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) { - return 1; - } - - printk (KERN_INFO "%s: Transmit timeout !\n", - card->devname); - - /* unbusy the interface */ - dev->tbusy = 0; - } - if(ntohs(skb->protocol) != 0x16) { /* check the udp packet type */ @@ -977,31 +984,24 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) } if(chdlc_send(card, data, len)) { - dev->tbusy = 1; + netif_stop_queue(dev); chdlc_priv_area->tick_counter = jiffies; chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; } else { ++card->wandev.stats.tx_packets; -#ifdef LINUX_2_1 card->wandev.stats.tx_bytes += len; -#endif } } - if (!dev->tbusy) { -#ifdef LINUX_2_1 + if (!netif_queue_stopped(dev)) dev_kfree_skb(skb); -#else - dev_kfree_skb(skb, FREE_WRITE); -#endif - } clear_bit(0, (void*)&card->wandev.critical); if(card->hw.type != SDLA_S514){ s508_unlock(card,&smp_flags); } - return dev->tbusy; + return netif_queue_stopped(dev); } @@ -1521,8 +1521,7 @@ STATIC void wpc_isr (sdla_t* card) ~APP_INT_ON_TX_FRAME; chdlc_priv_area = dev->priv; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue(dev); break; case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */ @@ -1606,7 +1605,7 @@ static void rx_intr (sdla_t* card) dev = card->wandev.dev; chdlc_priv_area = dev->priv; - if(dev && dev->start) { + if(dev && netif_running(dev)) { len = rxbuf->frame_length; diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c index f4431c9dc..14257cc85 100644 --- a/drivers/net/wan/sdla_fr.c +++ b/drivers/net/wan/sdla_fr.c @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Feb 28, 2000 Jeff Garzik o softnet updates * Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function * o Removed the ARP support. This has to be done * in the next version. @@ -108,7 +109,6 @@ * Jan 02, 1997 Gene Kozin Initial version. *****************************************************************************/ -#include <linux/version.h> #include <linux/kernel.h> /* printk(), and other useful stuff */ #include <linux/stddef.h> /* offsetof(), etc. */ #include <linux/errno.h> /* return codes */ @@ -129,9 +129,6 @@ #include <linux/if.h> #include <linux/sdla_fr.h> /* frame relay firmware API definitions */ -#if LINUX_VERSION_CODE < 0x020125 -#define test_and_set_bit set_bit -#endif /****** Defines & Macros ****************************************************/ @@ -157,6 +154,8 @@ #define API 0x01 #define FRAME_RELAY_API 1 +#define TX_TIMEOUT (5*HZ) + /* For handle_IPXWAN() */ #define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) @@ -273,6 +272,7 @@ static int if_close(struct net_device *dev); static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); static int if_send(struct sk_buff *skb, struct net_device *dev); +static void if_tx_timeout (struct net_device *dev); static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, struct sk_buff *skb); static struct net_device_stats *if_stats(struct net_device *dev); @@ -939,6 +939,8 @@ static int if_init (struct net_device* dev) dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->type = ARPHRD_DLCI; /* ARP h/w type */ @@ -993,7 +995,7 @@ static int if_open (struct net_device* dev) int err = 0; struct timeval tv; - if (dev->start) + if (netif_running(dev)) return -EBUSY; /* only one open is allowed */ if (test_and_set_bit(1, (void*)&card->wandev.critical)) @@ -1034,9 +1036,7 @@ static int if_open (struct net_device* dev) fr_activate_dlci(card, chan->dlci); } - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); wanpipe_open(card); update_chan_state(dev); do_gettimeofday( &tv ); @@ -1058,7 +1058,7 @@ static int if_close (struct net_device* dev) if (test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); if (card->wandev.station == WANOPT_NODE) { fr_delete_dlci (card,chan->dlci); @@ -1113,6 +1113,30 @@ static int if_rebuild_hdr (struct sk_buff* skb) return 1; } + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + chan->drvstats_if_send.if_send_tbusy++; + ++chan->ifstats.collisions; + + printk (KERN_INFO "%s: Transmit timed out\n", chan->name); + chan->drvstats_if_send.if_send_tbusy_timeout++; + netif_start_queue (dev); + +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -1153,7 +1177,7 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) printk(KERN_INFO "%s: interface %s got kicked!\n", card->devname, dev->name); chan->drvstats_if_send.if_send_skb_null ++; - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } @@ -1164,33 +1188,13 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) */ set_bit(2, (void*)&card->wandev.critical); if(chan->transmit_length) { - dev->tbusy = 1; + netif_stop_queue(dev); chan->tick_counter = jiffies; clear_bit(2, (void*)&card->wandev.critical); return 1; } clear_bit(2, (void*)&card->wandev.critical); - if (dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - - chan->drvstats_if_send.if_send_tbusy++; - ++chan->ifstats.collisions; - - if ((jiffies - chan->tick_counter) < (5 * HZ)) { - return 1; - } - - printk(KERN_INFO "%s: Transmit timed out\n", chan->name); - chan->drvstats_if_send.if_send_tbusy_timeout ++; - dev->tbusy = 0; - } - data = skb->data; sendpacket = skb->data; len = skb->len; @@ -1318,15 +1322,14 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) } } - if (!dev->tbusy) { + if (!netif_queue_stopped(dev)) dev_kfree_skb(skb); - } clear_bit(0, (void*)&card->wandev.critical); s508_s514_unlock(card,&smp_flags); - return (dev->tbusy); + return (netif_queue_stopped(dev)); } @@ -1743,10 +1746,10 @@ static void rx_intr (sdla_t* card) skb = dev_alloc_skb(len); - if (!dev->start || (skb == NULL)) { + if (!netif_running(dev) || (skb == NULL)) { ++chan->ifstats.rx_dropped; - if(dev->start) { + if(netif_running(dev)) { printk(KERN_INFO "%s: no socket buffers available!\n", @@ -1920,8 +1923,7 @@ static void tx_intr(sdla_t *card) if(!(-- card->u.f.tx_interrupts_pending)) flags->imask &= ~FR_INTR_TXRDY; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } @@ -2704,7 +2706,7 @@ static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) "%s: DLCI %u is inactive!\n", card->devname, dlci); - if (dev && dev->start) + if (dev && netif_running(dev)) set_chan_state(dev, WAN_DISCONNECTED); } @@ -2714,7 +2716,7 @@ static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) "%s: DLCI %u has been deleted!\n", card->devname, dlci); - if (dev && dev->start) { + if (dev && netif_running(dev)) { fr_channel_t *chan = dev->priv; if (chan->route_flag == ROUTE_ADDED) { @@ -2738,7 +2740,7 @@ static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) */ chan->dlci_configured = DLCI_CONFIG_PENDING; - if (dev && dev->start) + if (dev && netif_running(dev)) set_chan_state(dev, WAN_CONNECTED); } @@ -3004,7 +3006,7 @@ static int process_udp_mgmt_pkt(sdla_t* card) test_bit(2, (void*)&card->wandev.critical)) { return 0; } - if((dev->tbusy) || (card->u.f.tx_interrupts_pending)) { + if((netif_queue_stopped(dev)) || (card->u.f.tx_interrupts_pending)) { return 0; } } diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c index f3dcc129b..40134ff72 100644 --- a/drivers/net/wan/sdla_ppp.c +++ b/drivers/net/wan/sdla_ppp.c @@ -142,9 +142,8 @@ #define NUM_AUTH_REQ_WITHOUT_REPLY 10 #define END_OFFSET 0x1F0 -#if LINUX_VERSION_CODE < 0x020125 -#define test_and_set_bit set_bit -#endif + +#define TX_TIMEOUT (5*HZ) /******Data Structures*****************************************************/ @@ -213,6 +212,7 @@ static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data); static int if_init(struct net_device *dev); static int if_open(struct net_device *dev); static int if_close(struct net_device *dev); +static void if_tx_timeout (struct net_device *dev); static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); @@ -585,7 +585,8 @@ static int if_init(struct net_device *dev) dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; - + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->type = ARPHRD_PPP; /* ARP h/w type */ @@ -632,7 +633,7 @@ static int if_open(struct net_device *dev) struct timeval tv; int err = 0; - if (dev->start) + if (netif_running(dev)) return -EBUSY; /* only one open is allowed */ if (test_and_set_bit(0, (void*)&card->wandev.critical)) @@ -714,13 +715,10 @@ static int if_open(struct net_device *dev) return err; } - wanpipe_set_state(card, WAN_CONNECTING); wanpipe_open(card); dev->mtu = min(dev->mtu, card->wandev.mtu); - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); do_gettimeofday( &tv ); ppp_priv_area->router_start_time = tv.tv_sec; card->wandev.critical = 0; @@ -741,7 +739,7 @@ static int if_close(struct net_device *dev) if (test_and_set_bit(0, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); wanpipe_set_state(card, WAN_DISCONNECTED); ppp_set_intr_mode(card, 0); @@ -795,6 +793,35 @@ static int if_rebuild_hdr (struct sk_buff *skb) return 1; } + +/*============================================================================ + * Handle transmit timeout from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++ppp_priv_area->if_send_stat.if_send_tbusy; + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit times out\n", card->devname); + + ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout; + ++card->wandev.stats.collisions; + + /* unbusy the card (because only one interface per card) */ + netif_start_queue(dev); +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -835,34 +862,11 @@ static int if_send (struct sk_buff *skb, struct net_device *dev) ++ppp_priv_area->if_send_stat.if_send_skb_null; - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } - if (dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - - ++ppp_priv_area->if_send_stat.if_send_tbusy; - ++card->wandev.stats.collisions; - - if ((jiffies - ppp_priv_area->tick_counter) < (5*HZ)) { - return 1; - } - - printk (KERN_INFO "%s: Transmit times out\n",card->devname); - - ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout; - ++card->wandev.stats.collisions; - - /* unbusy the card (because only one interface per card)*/ - dev->tbusy = 0; - } sendpacket = skb->data; udp_type = udp_pkt_type( skb, card ); @@ -930,7 +934,7 @@ static int if_send (struct sk_buff *skb, struct net_device *dev) if (ppp_send(card, skb->data, skb->len, skb->protocol)) { retry = 1; - dev->tbusy = 1; + netif_stop_queue(dev); ++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full; ++ppp_priv_area->if_send_stat.if_send_tx_int_enabled; ppp_priv_area->tick_counter = jiffies; @@ -1530,7 +1534,7 @@ STATIC void wpp_isr(sdla_t *card) case PPP_INTR_TXRDY: /* transmit interrupt 0x02 (bit 1)*/ ++card->statistics.isr_tx; flags->imask &= ~PPP_INTR_TXRDY; - dev->tbusy = 0; + netif_wake_queue (dev); card->buff_int_mode_unbusy = 1; break; @@ -1564,9 +1568,8 @@ STATIC void wpp_isr(sdla_t *card) flags->iflag = 0; card->wandev.critical = 0; - if(card->buff_int_mode_unbusy) { - mark_bh(NET_BH); - } + if(card->buff_int_mode_unbusy) + netif_wake_queue(dev); } /*============================================================================ @@ -1603,7 +1606,7 @@ static void rx_intr(sdla_t *card) } - if (dev && dev->start) { + if (dev && netif_running(dev)) { len = rxbuf->length; ppp_priv_area = dev->priv; @@ -2006,7 +2009,7 @@ static void poll_disconnected(sdla_t *card) { struct net_device *dev = card->wandev.dev; - if (dev && dev->start && + if (dev && netif_running(dev) && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c index 17b285ba4..45592eacf 100644 --- a/drivers/net/wavelan.c +++ b/drivers/net/wavelan.c @@ -3726,7 +3726,7 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) } /* Release spinlock here so that wv_hw_reset() can grab it */ - spin_unlock (&lp->lock); + spin_unlock (&lp->spinlock); /* Check the state of the command unit. */ if (((status & SCB_ST_CNA) == SCB_ST_CNA) || @@ -4006,7 +4006,7 @@ static int __init wavelan_config(device * dev) lp->mc_count = 0; /* Init spinlock */ - spin_lock_init(&lp->lock); + spin_lock_init(&lp->spinlock); /* * Fill in the fields of the device structure diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index a907847c0..7eb759b94 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -103,6 +103,22 @@ static int gx_fix = 0; #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) +#ifdef USE_IO_OPS +#define YF_INB inb +#define YF_INW inw +#define YF_INL inl +#define YF_OUTB outb +#define YF_OUTW outw +#define YF_OUTL outl +#else +#define YF_INB readb +#define YF_INW readw +#define YF_INL readl +#define YF_OUTB writeb +#define YF_OUTW writew +#define YF_OUTL writel +#endif + /* Theory of Operation @@ -357,11 +373,11 @@ static int __devinit read_eeprom(long ioaddr, int location) { int bogus_cnt = 10000; /* Typical 33Mhz: 1050 ticks */ - outb(location, ioaddr + EEAddr); - outb(0x30 | ((location >> 8) & 7), ioaddr + EECtrl); - while ((inb(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0) + YF_OUTB(location, ioaddr + EEAddr); + YF_OUTB(0x30 | ((location >> 8) & 7), ioaddr + EECtrl); + while ((YF_INB(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0) ; - return inb(ioaddr + EERead); + return YF_INB(ioaddr + EERead); } /* MII Managemen Data I/O accesses. @@ -372,24 +388,24 @@ static int mdio_read(long ioaddr, int phy_id, int location) { int i; - outw((phy_id<<8) + location, ioaddr + MII_Addr); - outw(1, ioaddr + MII_Cmd); + YF_OUTW((phy_id<<8) + location, ioaddr + MII_Addr); + YF_OUTW(1, ioaddr + MII_Cmd); for (i = 10000; i >= 0; i--) - if ((inw(ioaddr + MII_Status) & 1) == 0) + if ((YF_INW(ioaddr + MII_Status) & 1) == 0) break; - return inw(ioaddr + MII_Rd_Data); + return YF_INW(ioaddr + MII_Rd_Data); } static void mdio_write(long ioaddr, int phy_id, int location, int value) { int i; - outw((phy_id<<8) + location, ioaddr + MII_Addr); - outw(value, ioaddr + MII_Wr_Data); + YF_OUTW((phy_id<<8) + location, ioaddr + MII_Addr); + YF_OUTW(value, ioaddr + MII_Wr_Data); /* Wait for the command to finish. */ for (i = 10000; i >= 0; i--) - if ((inw(ioaddr + MII_Status) & 1) == 0) + if ((YF_INW(ioaddr + MII_Status) & 1) == 0) break; return; } @@ -402,7 +418,7 @@ static int yellowfin_open(struct net_device *dev) int i; /* Reset the chip. */ - outl(0x80000000, ioaddr + DMACtrl); + YF_OUTL(0x80000000, ioaddr + DMACtrl); if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev)) return -EAGAIN; @@ -415,30 +431,30 @@ static int yellowfin_open(struct net_device *dev) yellowfin_init_ring(dev); - outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr); - outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr); + YF_OUTL(virt_to_bus(yp->rx_ring), ioaddr + RxPtr); + YF_OUTL(virt_to_bus(yp->tx_ring), ioaddr + TxPtr); for (i = 0; i < 6; i++) - outb(dev->dev_addr[i], ioaddr + StnAddr + i); + YF_OUTB(dev->dev_addr[i], ioaddr + StnAddr + i); /* Set up various condition 'select' registers. There are no options here. */ - outl(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */ - outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */ - outl(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */ - outl(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */ - outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */ - outl(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */ + YF_OUTL(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */ + YF_OUTL(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */ + YF_OUTL(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */ + YF_OUTL(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */ + YF_OUTL(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */ + YF_OUTL(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */ /* Initialize other registers: with so many this eventually this will converted to an offset/value list. */ - outl(dma_ctrl, ioaddr + DMACtrl); - outw(fifo_cfg, ioaddr + FIFOcfg); + YF_OUTL(dma_ctrl, ioaddr + DMACtrl); + YF_OUTW(fifo_cfg, ioaddr + FIFOcfg); /* Enable automatic generation of flow control frames, period 0xffff. */ - outl(0x0030FFFF, ioaddr + FlowCtrl); + YF_OUTL(0x0030FFFF, ioaddr + FlowCtrl); yp->tx_threshold = 32; - outl(yp->tx_threshold, ioaddr + TxThreshold); + YF_OUTL(yp->tx_threshold, ioaddr + TxThreshold); if (dev->if_port == 0) dev->if_port = yp->default_port; @@ -449,19 +465,19 @@ static int yellowfin_open(struct net_device *dev) if (yp->flags & IsGigabit) { /* We are always in full-duplex mode with gigabit! */ yp->full_duplex = 1; - outw(0x01CF, ioaddr + Cnfg); + YF_OUTW(0x01CF, ioaddr + Cnfg); } else { - outw(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */ - outw(0x1018, ioaddr + FrameGap1); - outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); + YF_OUTW(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */ + YF_OUTW(0x1018, ioaddr + FrameGap1); + YF_OUTW(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); } set_rx_mode(dev); /* Enable interrupts by setting the interrupt mask. */ - outw(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */ - outw(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ - outl(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */ - outl(0x80008000, ioaddr + TxCtrl); + YF_OUTW(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */ + YF_OUTW(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ + YF_OUTL(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */ + YF_OUTL(0x80008000, ioaddr + TxCtrl); if (yellowfin_debug > 2) { printk(KERN_DEBUG "%s: Done yellowfin_open().\n", @@ -486,7 +502,7 @@ static void yellowfin_timer(unsigned long data) if (yellowfin_debug > 3) { printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n", - dev->name, inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + IntrStatus)); } if (yp->mii_cnt) { @@ -503,7 +519,7 @@ static void yellowfin_timer(unsigned long data) || (negotiated & 0x00C0) == 0x0040)) { yp->full_duplex = 1; } - outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); + YF_OUTW(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); if (mii_reg1 & 0x0004) next_tick = 60*HZ; @@ -523,7 +539,7 @@ static void yellowfin_tx_timeout(struct net_device *dev) printk(KERN_WARNING "%s: Yellowfin transmit timed out at %d/%d Tx " "status %4.4x, Rx status %4.4x, resetting...\n", dev->name, yp->cur_tx, yp->dirty_tx, - inl(ioaddr + TxStatus), inl(ioaddr + RxStatus)); + YF_INL(ioaddr + TxStatus), YF_INL(ioaddr + RxStatus)); /* Note: these should be KERN_DEBUG. */ if (yellowfin_debug) { @@ -543,7 +559,7 @@ static void yellowfin_tx_timeout(struct net_device *dev) dev->if_port = 0; /* Wake the potentially-idle transmit channel. */ - outl(0x10001000, dev->base_addr + TxCtrl); + YF_OUTL(0x10001000, dev->base_addr + TxCtrl); if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE) netif_wake_queue (dev); /* Typical path */ @@ -681,7 +697,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Non-x86 Todo: explicitly flush cache lines here. */ /* Wake the potentially-idle transmit channel. */ - outl(0x10001000, dev->base_addr + TxCtrl); + YF_OUTL(0x10001000, dev->base_addr + TxCtrl); if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE) netif_start_queue (dev); /* Typical path */ @@ -717,7 +733,7 @@ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *reg spin_lock (&yp->lock); do { - u16 intr_status = inw(ioaddr + IntrClear); + u16 intr_status = YF_INW(ioaddr + IntrClear); if (yellowfin_debug > 4) printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n", @@ -728,7 +744,7 @@ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *reg if (intr_status & (IntrRxDone | IntrEarlyRx)) { yellowfin_rx(dev); - outl(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */ + YF_OUTL(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */ } #ifdef NO_TXSTATS @@ -845,7 +861,7 @@ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *reg if (yellowfin_debug > 3) printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + IntrStatus)); /* Code that should never be run! Perhaps remove after testing.. */ { @@ -1023,18 +1039,19 @@ static int yellowfin_close(struct net_device *dev) if (yellowfin_debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n", - dev->name, inw(ioaddr + TxStatus), - inw(ioaddr + RxStatus), inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + TxStatus), + YF_INW(ioaddr + RxStatus), + YF_INW(ioaddr + IntrStatus)); printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx); } /* Disable interrupts by clearing the interrupt mask. */ - outw(0x0000, ioaddr + IntrEnb); + YF_OUTW(0x0000, ioaddr + IntrEnb); /* Stop the chip's Tx and Rx processes. */ - outl(0x80000000, ioaddr + RxCtrl); - outl(0x80000000, ioaddr + TxCtrl); + YF_OUTL(0x80000000, ioaddr + RxCtrl); + YF_OUTL(0x80000000, ioaddr + TxCtrl); del_timer(&yp->timer); @@ -1043,7 +1060,7 @@ static int yellowfin_close(struct net_device *dev) printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring)); for (i = 0; i < TX_RING_SIZE*2; i++) printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n", - inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', + YF_INL(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr, yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status); printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status); @@ -1055,7 +1072,7 @@ static int yellowfin_close(struct net_device *dev) printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring)); for (i = 0; i < RX_RING_SIZE; i++) { printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n", - inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ', + YF_INL(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ', i, yp->rx_ring[i].dbdma_cmd, yp->rx_ring[i].addr, yp->rx_ring[i].result_status); if (yellowfin_debug > 6) { @@ -1134,17 +1151,17 @@ static void set_rx_mode(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; - u16 cfg_value = inw(ioaddr + Cnfg); + u16 cfg_value = YF_INW(ioaddr + Cnfg); /* Stop the Rx process to change any value. */ - outw(cfg_value & ~0x1000, ioaddr + Cnfg); + YF_OUTW(cfg_value & ~0x1000, ioaddr + Cnfg); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ /* Unconditionally log net taps. */ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); - outw(0x000F, ioaddr + AddrMode); + YF_OUTW(0x000F, ioaddr + AddrMode); } else if ((dev->mc_count > 64) || (dev->flags & IFF_ALLMULTI)) { /* Too many to filter well, or accept all multicasts. */ - outw(0x000B, ioaddr + AddrMode); + YF_OUTW(0x000B, ioaddr + AddrMode); } else if (dev->mc_count > 0) { /* Must use the multicast hash table. */ struct dev_mc_list *mclist; u16 hash_table[4]; @@ -1167,13 +1184,13 @@ static void set_rx_mode(struct net_device *dev) } /* Copy the hash table to the chip. */ for (i = 0; i < 4; i++) - outw(hash_table[i], ioaddr + HashTbl + i*2); - outw(0x0003, ioaddr + AddrMode); + YF_OUTW(hash_table[i], ioaddr + HashTbl + i*2); + YF_OUTW(0x0003, ioaddr + AddrMode); } else { /* Normal, unicast/broadcast-only mode. */ - outw(0x0001, ioaddr + AddrMode); + YF_OUTW(0x0001, ioaddr + AddrMode); } /* Restart the Rx process. */ - outw(cfg_value | 0x1000, ioaddr + Cnfg); + YF_OUTW(cfg_value | 0x1000, ioaddr + Cnfg); } #ifdef HAVE_PRIVATE_IOCTL @@ -1209,7 +1226,7 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, int option, i, irq; int flags, chip_idx; static int find_cnt = 0; - long ioaddr; + long ioaddr, real_ioaddr; chip_idx = ent->driver_data; flags = chip_info[chip_idx].flags; @@ -1243,18 +1260,20 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, pci_set_master (pdev); #ifdef USE_IO_OPS - ioaddr = pci_resource_start (pdev, 0); + real_ioaddr = ioaddr = pci_resource_start (pdev, 0); #else - ioaddr = pci_resource_start (pdev, 1); + real_ioaddr = ioaddr = pci_resource_start (pdev, 1); + ioaddr = ioremap(ioaddr, YELLOWFIN_SIZE); #endif irq = pdev->irq; printk(KERN_INFO "%s: %s type %8x at 0x%lx, ", - dev->name, chip_info[chip_idx].name, inl(ioaddr + ChipRev), ioaddr); + dev->name, chip_info[chip_idx].name, + YF_INL(ioaddr + ChipRev), real_ioaddr); if (flags & IsGigabit) for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + StnAddr + i); + dev->dev_addr[i] = YF_INB(ioaddr + StnAddr + i); else { int ee_offset = (read_eeprom(ioaddr, 6) == 0xff ? 0x100 : 0); for (i = 0; i < 6; i++) @@ -1265,7 +1284,7 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); /* Reset the chip. */ - outl(0x80000000, ioaddr + DMACtrl); + YF_OUTL(0x80000000, ioaddr + DMACtrl); dev->base_addr = ioaddr; dev->irq = irq; diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index c4003dd27..3b13ea71a 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c @@ -160,10 +160,10 @@ void parport_daisy_fini (struct parport *port) while (prev) { dev = prev->next; - if (dev && dev->port == port) + if (dev && dev->port == port) { prev->next = dev->next; - - kfree (dev); + kfree (dev); + } prev = prev->next; } diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 8db17e5c9..6b9c9e47f 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -165,6 +165,7 @@ int parport_wait_peripheral(struct parport *port, /* Terminate a negotiated mode. */ static void parport_ieee1284_terminate (struct parport *port) { + int r; port = port->physport; /* EPP terminates differently. */ @@ -199,9 +200,12 @@ static void parport_ieee1284_terminate (struct parport *port) | PARPORT_CONTROL_AUTOFD); /* Event 49: PError goes high */ - parport_wait_peripheral (port, - PARPORT_STATUS_PAPEROUT, - PARPORT_STATUS_PAPEROUT); + r = parport_wait_peripheral (port, + PARPORT_STATUS_PAPEROUT, + PARPORT_STATUS_PAPEROUT); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 49\n", + port->name); parport_data_forward (port); DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", @@ -221,7 +225,10 @@ static void parport_ieee1284_terminate (struct parport *port) PARPORT_CONTROL_SELECT); /* Event 24: nAck goes low */ - parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); + r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 24\n", + port->name); /* Event 25: Set nAutoFd low */ parport_frob_control (port, @@ -229,9 +236,12 @@ static void parport_ieee1284_terminate (struct parport *port) PARPORT_CONTROL_AUTOFD); /* Event 27: nAck goes high */ - parport_wait_peripheral (port, - PARPORT_STATUS_ACK, - PARPORT_STATUS_ACK); + r = parport_wait_peripheral (port, + PARPORT_STATUS_ACK, + PARPORT_STATUS_ACK); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 27\n", + port->name); /* Event 29: Set nAutoFd high */ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); @@ -260,6 +270,7 @@ int parport_negotiate (struct parport *port, int mode) return -1; #else int m = mode & ~IEEE1284_ADDR; + int r; unsigned char xflag; port = port->physport; @@ -367,7 +378,7 @@ int parport_negotiate (struct parport *port, int mode) /* xflag should be high for all modes other than nibble (0). */ if (mode && !xflag) { /* Mode not supported. */ - DPRINTK (KERN_DEBUG "%s: Mode 0x%02x not supported\n", + DPRINTK (KERN_DEBUG "%s: Mode 0x%02x rejected by peripheral\n", port->name, mode); parport_ieee1284_terminate (port); return 1; @@ -434,7 +445,7 @@ int parport_negotiate (struct parport *port, int mode) port->ieee1284.mode = mode; /* But ECP is special */ - if (!(mode & IEEE1284_EXT_LINK) && (mode & IEEE1284_MODE_ECP)) { + if (!(mode & IEEE1284_EXT_LINK) && (m & IEEE1284_MODE_ECP)) { port->ieee1284.phase = IEEE1284_PH_ECP_SETUP; /* Event 30: Set nAutoFd low */ @@ -443,10 +454,11 @@ int parport_negotiate (struct parport *port, int mode) PARPORT_CONTROL_AUTOFD); /* Event 31: PError goes high. */ - parport_wait_peripheral (port, - PARPORT_STATUS_PAPEROUT, - PARPORT_STATUS_PAPEROUT); - /* (Should check that this works..) */ + r = parport_wait_peripheral (port, + PARPORT_STATUS_PAPEROUT, + PARPORT_STATUS_PAPEROUT); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 31\n"); port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index cf0e092bf..49e530ace 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1503,7 +1503,7 @@ out: /* --- DMA detection -------------------------------------- */ -/* Only if supports ECP mode */ +/* Only if chipset conforms to ECP ISA Interface Standard */ static int __devinit programmable_dma_support (struct parport *p) { unsigned char oecr = inb (ECONTROL (p)); @@ -1511,8 +1511,10 @@ static int __devinit programmable_dma_support (struct parport *p) frob_econtrol (p, 0xe0, ECR_CNF << 5); - dma = inb (CONFIGB(p)) & 0x03; - if (!dma) + dma = inb (CONFIGB(p)) & 0x07; + /* 000: Indicates jumpered 8-bit DMA if read-only. + 100: Indicates jumpered 16-bit DMA if read-only. */ + if ((dma & 0x03) == 0) dma = PARPORT_DMA_NONE; outb (oecr, ECONTROL (p)); @@ -1722,6 +1724,7 @@ struct parport *__devinit parport_pc_probe_port (unsigned long int base, } +/* Via support maintained by Jeff Garzik <jgarzik@mandrakesoft.com> */ static int __devinit sio_via_686a_probe (struct pci_dev *pdev) { u8 dma, irq, tmp; @@ -1835,6 +1838,7 @@ static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = { static int __devinit parport_pc_init_superio(void) { +#ifdef CONFIG_PCI const struct pci_device_id *id; struct pci_dev *pdev; @@ -1845,11 +1849,11 @@ static int __devinit parport_pc_init_superio(void) return parport_pc_superio_info[id->driver_data].probe (pdev); } +#endif /* CONFIG_PCI */ return 0; /* zero devices found */ } - /* Look for PCI parallel port cards. */ static int __init parport_pc_init_pci (int irq, int dma) { @@ -1991,6 +1995,7 @@ static int __init parport_pc_init_pci (int irq, int dma) } } +#ifdef CONFIG_PCI /* Look for parallel controllers that we don't know about. */ pci_for_each_dev(pcidev) { const int class_noprogif = pcidev->class & ~0xff; @@ -2011,6 +2016,7 @@ static int __init parport_pc_init_pci (int irq, int dma) "tim@cyberelk.demon.co.uk\n", pcidev->vendor, pcidev->device); } +#endif return count; } @@ -2034,9 +2040,16 @@ static int dmaval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PAR static int irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY }; static const char *irq[PARPORT_PC_MAX_PORTS] = { NULL, }; static const char *dma[PARPORT_PC_MAX_PORTS] = { NULL, }; + +MODULE_AUTHOR("Phil Blundell, Tim Waugh, others"); +MODULE_DESCRIPTION("PC-style parallel port driver"); +MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i"); +MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)"); MODULE_PARM(io_hi, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i"); +MODULE_PARM_DESC(irq, "IRQ line"); MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); +MODULE_PARM_DESC(dma, "DMA channel"); MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); int init_module(void) diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 945b19bd4..c2e6ebdf9 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -14,11 +14,8 @@ L_TARGET := pci.a # Nasty trick as we need to link files with no references from the outside. O_TARGET := pci_core.o L_OBJS := pci_core.o -O_OBJS := pci.o quirks.o - -ifdef CONFIG_MODULES -OX_OBJS += pcisyms.o -endif +O_OBJS := quirks.o +OX_OBJS := pci.o ifdef CONFIG_PROC_FS O_OBJS += proc.o diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cc76f78db..1837c2467 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -10,6 +10,7 @@ */ #include <linux/config.h> +#include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -19,6 +20,7 @@ #include <linux/ioport.h> #include <asm/page.h> +#include <asm/dma.h> /* isa_dma_bridge_buggy */ #undef DEBUG @@ -987,3 +989,50 @@ static int __init pci_setup(char *str) } __setup("pci=", pci_setup); + + +EXPORT_SYMBOL(pci_read_config_byte); +EXPORT_SYMBOL(pci_read_config_word); +EXPORT_SYMBOL(pci_read_config_dword); +EXPORT_SYMBOL(pci_write_config_byte); +EXPORT_SYMBOL(pci_write_config_word); +EXPORT_SYMBOL(pci_write_config_dword); +EXPORT_SYMBOL(pci_devices); +EXPORT_SYMBOL(pci_root_buses); +EXPORT_SYMBOL(pci_enable_device); +EXPORT_SYMBOL(pci_find_capability); +EXPORT_SYMBOL(pci_find_class); +EXPORT_SYMBOL(pci_find_device); +EXPORT_SYMBOL(pci_find_slot); +EXPORT_SYMBOL(pci_find_subsys); +EXPORT_SYMBOL(pci_set_master); +EXPORT_SYMBOL(pci_set_power_state); +EXPORT_SYMBOL(pci_assign_resource); +EXPORT_SYMBOL(pci_register_driver); +EXPORT_SYMBOL(pci_unregister_driver); +EXPORT_SYMBOL(pci_match_device); +EXPORT_SYMBOL(pci_find_parent_resource); + +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pci_setup_device); +EXPORT_SYMBOL(pci_insert_device); +EXPORT_SYMBOL(pci_remove_device); +#endif + +/* Obsolete functions */ + +EXPORT_SYMBOL(pcibios_present); +EXPORT_SYMBOL(pcibios_read_config_byte); +EXPORT_SYMBOL(pcibios_read_config_word); +EXPORT_SYMBOL(pcibios_read_config_dword); +EXPORT_SYMBOL(pcibios_write_config_byte); +EXPORT_SYMBOL(pcibios_write_config_word); +EXPORT_SYMBOL(pcibios_write_config_dword); +EXPORT_SYMBOL(pcibios_find_class); +EXPORT_SYMBOL(pcibios_find_device); + +/* Quirk info */ + +EXPORT_SYMBOL(isa_dma_bridge_buggy); +EXPORT_SYMBOL(pci_pci_problems); + diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 1dfedc0dd..21a6a4ff1 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -2225,6 +2225,7 @@ 1277 Comstream 1278 Transtech Parallel Systems Ltd. 1279 Transmeta Corporation + 0295 Virtual Northbridge 127a Rockwell International 1002 HCF 56k V90 FaxModem 1003 HCF 56k V90 FaxModem diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index cda39a5c1..8029b1982 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -113,6 +113,55 @@ static void __init quirk_s3_64M(struct pci_dev *dev) } } +static void __init quirk_io_region(struct pci_dev *dev, unsigned region, unsigned size, int nr) +{ + region &= ~(size-1); + if (region) { + struct resource *res = dev->resource + nr; + + res->name = dev->name; + res->start = region; + res->end = region + size - 1; + res->flags = IORESOURCE_IO; + pci_claim_resource(dev, nr); + } +} + +/* + * Let's make the southbridge information explicit instead + * of having to worry about people probing the ACPI areas, + * for example.. (Yes, it happens, and if you read the wrong + * ACPI register it will put the machine to sleep with no + * way of waking it up again. Bummer). + * + * ALI M7101: Two IO regions pointed to by words at + * 0xE0 (64 bytes of ACPI registers) + * 0xE2 (32 bytes of SMB registers) + */ +static void __init quirk_ali7101(struct pci_dev *dev) +{ + u16 region; + + pci_read_config_word(dev, 0xE0, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES); + pci_read_config_word(dev, 0xE2, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1); +} + +/* + * PIIX4 ACPI: Two IO regions pointed to by longwords at + * 0x40 (64 bytes of ACPI registers) + * 0x90 (32 bytes of SMB registers) + */ +static void __init quirk_piix4acpi(struct pci_dev *dev) +{ + u32 region; + + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES); + pci_read_config_dword(dev, 0x90, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1); +} /* * The main table of quirks. @@ -143,6 +192,8 @@ static struct pci_fixup pci_fixups[] __initdata = { { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4acpi }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101 }, { 0 } }; diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 74114b4fe..7898c76a2 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -186,6 +186,9 @@ void read_cb_mem(socket_info_t * s, u_char fn, int space, DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len); + if (!s->cb_config) + goto fail; + dev = &s->cb_config[fn].dev; /* Config space? */ diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 7025263d4..4439f7c29 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -82,14 +82,12 @@ static const char *version = #else #define CB_OPT "" #endif -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) || defined(CONFIG_ACPI) -#define APM_OPT " [apm]" +#ifdef CONFIG_PM +#define APM_OPT " [pm]" #else #define APM_OPT "" #endif -#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && \ - !defined(CONFIG_APM) && !defined(CONFIG_APM_MODULE) && \ - !defined(CONFIG_ACPI) +#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM) #define OPTIONS " none" #else #define OPTIONS PCI_OPT CB_OPT APM_OPT @@ -125,7 +123,7 @@ static int cis_speed = 300; /* ns */ static int io_speed = 0; /* ns */ /* Optional features */ -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) || defined(CONFIG_ACPI) +#ifdef CONFIG_PM static int do_apm = 1; MODULE_PARM(do_apm, "i"); #else diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index d059c4fdb..f15605123 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -102,10 +102,11 @@ static irq_info_t irq_table[NR_IRQS] = { { 0, 0, 0 }, /* etc */ }; /*====================================================================== Linux resource management extensions - + ======================================================================*/ -#define check_io_region(b,n) (0) +#define check_io_resource(b,n) check_resource(&ioport_resource, (b), (n)) +#define check_mem_resource(b,n) check_resource(&iomem_resource, (b), (n)) /*====================================================================== @@ -191,7 +192,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) b = kmalloc(256, GFP_KERNEL); memset(b, 0, 256); for (i = base, most = 0; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_io_resource(i, 8)) continue; hole = inb(i); for (j = 1; j < 8; j++) @@ -204,7 +205,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) bad = any = 0; for (i = base; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_io_resource(i, 8)) continue; for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -255,13 +256,13 @@ static int do_mem_probe(u_long base, u_long num, for (i = base; i < base+num; i = j + step) { if (!fail) { for (j = i; j < base+num; j += step) - if ((check_mem_region(j, step) == 0) && is_valid(j)) + if ((check_mem_resource(j, step) == 0) && is_valid(j)) break; fail = ((i == base) && (j == base+num)); } if (fail) { for (j = i; j < base+num; j += 2*step) - if ((check_mem_region(j, 2*step) == 0) && + if ((check_mem_resource(j, 2*step) == 0) && do_cksum(j) && do_cksum(j+step)) break; } @@ -375,8 +376,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, for (try = (try >= m->base) ? try : try+align; (try >= m->base) && (try+num <= m->base+m->num); try += align) { - if ((check_region(try, num) == 0) && - (check_io_region(try, num) == 0)) { + if (check_io_resource(try, num) == 0) { *base = try; request_region(try, num, name); return 0; @@ -401,7 +401,7 @@ int find_mem_region(u_long *base, u_long num, u_long align, for (try = (try >= m->base) ? try : try+align; (try >= m->base) && (try+num <= m->base+m->num); try += align) { - if (check_mem_region(try, num) == 0) { + if (check_mem_resource(try, num) == 0) { request_mem_region(try, num, name); *base = try; return 0; diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c index 3531348bb..fc971cc74 100644 --- a/drivers/pcmcia/yenta.c +++ b/drivers/pcmcia/yenta.c @@ -235,16 +235,18 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state) socket->io_irq = state->io_irq; bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { + u8 intr; bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0; /* ISA interrupt control? */ + intr = exca_readb(socket, I365_INTCTL); + intr = (intr & ~0xf); if (!socket->cb_irq) { - u8 intr = exca_readb(socket, I365_INTCTL); - intr = (intr & ~0xf) | state->io_irq; - exca_writeb(socket, I365_INTCTL, intr); + intr |= state->io_irq; bridge |= CB_BRIDGE_INTR; } - } else { + exca_writeb(socket, I365_INTCTL, intr); + } else { u8 reg; bridge |= CB_BRIDGE_INTR; diff --git a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c index 6aef8ae63..7f14fc61b 100644 --- a/drivers/scsi/pci2000.c +++ b/drivers/scsi/pci2000.c @@ -660,7 +660,7 @@ int Pci2000_Detect (Scsi_Host_Template *tpnt) padapter = HOSTDATA(pshost); #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) - padapter->basePort = pdev->base_address[1] & 0xFFFE; + padapter->basePort = pci_resource_start (pdev, 1); #else pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &padapter->basePort); padapter->basePort &= 0xFFFE; diff --git a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c index fabb61c0c..b84ff1723 100644 --- a/drivers/scsi/pci2220i.c +++ b/drivers/scsi/pci2220i.c @@ -2448,15 +2448,9 @@ static USHORT GetRegs (struct Scsi_Host *pshost, BOOL bigd, UCHAR pci_bus, UCHAR memset (&DaleSetup, 0, sizeof (DaleSetup)); memset (DiskMirror, 0, sizeof (DiskMirror)); -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) - zr = pcidev->base_address[1] & 0xFFFE; - zl = pcidev->base_address[2] & 0xFFFE; -#else - pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &zr); - zr &= 0xFFFE; - pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &zl); - zl &= 0xFFFE; -#endif + zr = pci_resource_start (pcidev, 1); + zl = pci_resource_start (pcidev, 2); + padapter->basePort = zr; padapter->regRemap = zr + RTR_LOCAL_REMAP; // 32 bit local space remap padapter->regDesc = zr + RTR_REGIONS; // 32 bit local region descriptor diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 40a7cb124..4060872bf 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -108,6 +108,7 @@ static struct dev_info device_list[] = {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 * extra reset */ + {"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */ {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */ diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 9b82cc839..c8c5dd54d 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -89,7 +89,7 @@ #include <linux/string.h> #include <linux/proc_fs.h> #include <linux/init.h> - +#include <linux/delay.h> #include <linux/blk.h> #include "scsi.h" #include "hosts.h" @@ -99,7 +99,6 @@ #include <asm/uaccess.h> #include "sd.h" #include <scsi/scsi_ioctl.h> -#include <asm/delay.h> #ifdef DEBUG #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index f897cba9a..1de7686dc 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -11,7 +11,7 @@ Copyright 1992 - 2000 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Sat Feb 19 17:22:34 2000 by makisara@kai.makisara.local + Last modified: Tue Feb 29 20:47:03 2000 by makisara@kai.makisara.local Some small formal changes - aeb, 950809 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support @@ -172,21 +172,22 @@ static int st_int_ioctl(struct inode *inode, unsigned int cmd_in, /* Convert the result to success code */ static int st_chk_result(Scsi_Request * SRpnt) { - int dev = TAPE_NR(SRpnt->sr_request.rq_dev); + int dev; int result = SRpnt->sr_result; unsigned char *sense = SRpnt->sr_sense_buffer, scode; DEB(const char *stp;) - if (!result) + if (!result) { + sense[0] = 0; /* We don't have sense data if this byte is zero */ return 0; + } if (driver_byte(result) & DRIVER_SENSE) scode = sense[2] & 0x0f; - else { - sense[0] = 0; /* We don't have sense data if this byte is zero */ + else scode = 0; - } + dev = TAPE_NR(SRpnt->sr_request.rq_dev); DEB( if (debugging) { printk(ST_DEB_MSG "st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", @@ -294,7 +295,7 @@ static Scsi_Request * { unsigned char *bp; - if (SRpnt == NULL) + if (SRpnt == NULL) { SRpnt = scsi_allocate_request(STp->device); if (SRpnt == NULL) { DEBC( printk(KERN_ERR "st%d: Can't get SCSI request.\n", @@ -305,6 +306,7 @@ static Scsi_Request * (STp->buffer)->syscall_result = (-EBUSY); return NULL; } + } cmd[1] |= (SRpnt->sr_device->lun << 5) & 0xe0; init_MUTEX_LOCKED(&STp->sem); diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 4aa159dec..379b55874 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -1948,7 +1948,7 @@ int u14_34f_release(struct Scsi_Host *shpnt) { if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n", driver_name); - if( sh[j]->block != NULL ) { + if( sh[j]->unchecked_isa_dma ) { scsi_deregister_blocked_host(sh[j]); } diff --git a/drivers/sgi/char/graphics_syms.c b/drivers/sgi/char/graphics_syms.c index 6e07d3b8b..0a36ed76e 100644 --- a/drivers/sgi/char/graphics_syms.c +++ b/drivers/sgi/char/graphics_syms.c @@ -8,7 +8,6 @@ */ #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> /* extern int rrm_command (unsigned int cmd, void *arg); diff --git a/drivers/sgi/char/newport.c b/drivers/sgi/char/newport.c index 7fa4d65fe..74c9f294c 100644 --- a/drivers/sgi/char/newport.c +++ b/drivers/sgi/char/newport.c @@ -12,7 +12,6 @@ #include <asm/ng1.h> #include <asm/uaccess.h> #include <video/newport.h> -#include <linux/config.h> #include <linux/module.h> struct newport_regs *npregs; diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c index 175cd38e0..95bafcf20 100644 --- a/drivers/sound/ac97_codec.c +++ b/drivers/sound/ac97_codec.c @@ -28,7 +28,10 @@ #include <linux/module.h> #include <linux/version.h> #include <linux/kernel.h> +#include <linux/string.h> +#include <linux/errno.h> #include <linux/ac97_codec.h> +#include <asm/uaccess.h> static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel); static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c index e45609e5c..8813d519e 100644 --- a/drivers/sound/ad1816.c +++ b/drivers/sound/ad1816.c @@ -53,7 +53,6 @@ Changes: */ -#include <linux/config.h> #include <linux/module.h> #include <linux/stddef.h> #include "soundmodule.h" diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c index ba7231aa9..ffb88a7b4 100644 --- a/drivers/sound/audio.c +++ b/drivers/sound/audio.c @@ -23,7 +23,6 @@ * Horst von Brand: Add missing #include <linux/string.h> */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/string.h> #include <linux/kmod.h> diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c index 1296da1ea..c0edb593f 100644 --- a/drivers/sound/dmabuf.c +++ b/drivers/sound/dmabuf.c @@ -21,8 +21,6 @@ * * Rob Riggs Added persistent DMA buffers (1998/10/17) */ - -#include <linux/config.h> #define BE_CONSERVATIVE #define SAMPLE_ROUNDUP 0 diff --git a/drivers/sound/gus_midi.c b/drivers/sound/gus_midi.c index 175eeb6a1..92987f46d 100644 --- a/drivers/sound/gus_midi.c +++ b/drivers/sound/gus_midi.c @@ -10,8 +10,6 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ -#include <linux/config.h> - #include "sound_config.h" #include "gus_hw.h" diff --git a/drivers/sound/gus_vol.c b/drivers/sound/gus_vol.c index 783ff7d03..8951cbfc3 100644 --- a/drivers/sound/gus_vol.c +++ b/drivers/sound/gus_vol.c @@ -9,8 +9,6 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ -#include <linux/config.h> - #include "sound_config.h" #include "gus_linearvol.h" diff --git a/drivers/sound/ics2101.c b/drivers/sound/ics2101.c index 7cf9cc031..a6b6fb4cc 100644 --- a/drivers/sound/ics2101.c +++ b/drivers/sound/ics2101.c @@ -13,9 +13,6 @@ /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) */ -#include <linux/config.h> - - #include "sound_config.h" #include <linux/ultrasound.h> diff --git a/drivers/sound/midi_synth.c b/drivers/sound/midi_synth.c index 6e524e21d..9f1b9ef59 100644 --- a/drivers/sound/midi_synth.c +++ b/drivers/sound/midi_synth.c @@ -14,8 +14,6 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Andrew Veliath : fixed running status in MIDI input state machine */ -#include <linux/config.h> - #define USE_SEQ_MACROS #define USE_SIMPLE_MACROS diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c index 32549ed2a..782c9d877 100644 --- a/drivers/sound/midibuf.c +++ b/drivers/sound/midibuf.c @@ -13,7 +13,6 @@ /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kmod.h> diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c index b57c2dbca..8a334d263 100644 --- a/drivers/sound/mpu401.c +++ b/drivers/sound/mpu401.c @@ -15,7 +15,6 @@ * Alan Cox modularisation, use normal request_irq, use dev_id */ -#include <linux/config.h> #include <linux/module.h> #define USE_SEQ_MACROS diff --git a/drivers/sound/opl3sa.c b/drivers/sound/opl3sa.c index 213a0a099..721157fdd 100644 --- a/drivers/sound/opl3sa.c +++ b/drivers/sound/opl3sa.c @@ -18,7 +18,6 @@ * Check for install of mpu etc is wrong, should check result of the mss stuff */ -#include <linux/config.h> #include <linux/module.h> #undef SB_OK diff --git a/drivers/sound/pas2_midi.c b/drivers/sound/pas2_midi.c index 0dda4df5c..83d6ff5bd 100644 --- a/drivers/sound/pas2_midi.c +++ b/drivers/sound/pas2_midi.c @@ -10,8 +10,6 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ -#include <linux/config.h> - #include "sound_config.h" static int midi_busy = 0, input_opened = 0; diff --git a/drivers/sound/pas2_mixer.c b/drivers/sound/pas2_mixer.c index 3b9b167c1..1f2f12336 100644 --- a/drivers/sound/pas2_mixer.c +++ b/drivers/sound/pas2_mixer.c @@ -15,8 +15,6 @@ /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) */ -#include <linux/config.h> - #include "sound_config.h" #ifndef DEB diff --git a/drivers/sound/pas2_pcm.c b/drivers/sound/pas2_pcm.c index c0776ae4f..36fc7f72b 100644 --- a/drivers/sound/pas2_pcm.c +++ b/drivers/sound/pas2_pcm.c @@ -14,8 +14,6 @@ * more things module options. */ -#include <linux/config.h> - #include "sound_config.h" #ifndef DEB diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h index 13c1cce55..b2eef8254 100644 --- a/drivers/sound/sb.h +++ b/drivers/sound/sb.h @@ -1,5 +1,3 @@ -#include <linux/config.h> - #define DSP_RESET (devc->base + 0x6) #define DSP_READ (devc->base + 0xA) #define DSP_WRITE (devc->base + 0xC) diff --git a/drivers/sound/sb_audio.c b/drivers/sound/sb_audio.c index 672b8f408..bba7baba8 100644 --- a/drivers/sound/sb_audio.c +++ b/drivers/sound/sb_audio.c @@ -21,7 +21,6 @@ * the same. */ -#include <linux/config.h> #include "sound_config.h" #include "sb_mixer.h" diff --git a/drivers/sound/sb_midi.c b/drivers/sound/sb_midi.c index 9c3cef2bb..59cbfca03 100644 --- a/drivers/sound/sb_midi.c +++ b/drivers/sound/sb_midi.c @@ -11,7 +11,6 @@ * for more info. */ -#include <linux/config.h> #include "sound_config.h" #include "sb.h" diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c index f786b69b5..f441be0aa 100644 --- a/drivers/sound/sb_mixer.c +++ b/drivers/sound/sb_mixer.c @@ -16,7 +16,6 @@ * Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999) */ -#include <linux/config.h> #include "sound_config.h" #define __SB_MIXER_C__ diff --git a/drivers/sound/sb_mixer.h b/drivers/sound/sb_mixer.h index 1e1a1b8d2..ab7442615 100644 --- a/drivers/sound/sb_mixer.h +++ b/drivers/sound/sb_mixer.h @@ -23,8 +23,6 @@ * Moved static stuff to sb_mixer.c * */ -#include <linux/config.h> - /* * Mixer registers * diff --git a/drivers/sound/sequencer.c b/drivers/sound/sequencer.c index 0ef3b67ad..61650d660 100644 --- a/drivers/sound/sequencer.c +++ b/drivers/sound/sequencer.c @@ -14,7 +14,6 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Alan Cox : reformatted and fixed a pair of null pointer bugs */ -#include <linux/config.h> #include <linux/kmod.h> #define SEQUENCER_C diff --git a/drivers/sound/sgalaxy.c b/drivers/sound/sgalaxy.c index 1f23125a8..6859b20c3 100644 --- a/drivers/sound/sgalaxy.c +++ b/drivers/sound/sgalaxy.c @@ -18,7 +18,6 @@ * for more info. */ -#include <linux/config.h> #include <linux/module.h> #include "sound_config.h" diff --git a/drivers/sound/softoss_rs.c b/drivers/sound/softoss_rs.c index 75f1bbb90..627ff9b4a 100644 --- a/drivers/sound/softoss_rs.c +++ b/drivers/sound/softoss_rs.c @@ -13,9 +13,6 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ -#include <linux/config.h> - - #include "sound_config.h" #include "softoss.h" diff --git a/drivers/sound/sound_timer.c b/drivers/sound/sound_timer.c index b32759008..33901aa1b 100644 --- a/drivers/sound/sound_timer.c +++ b/drivers/sound/sound_timer.c @@ -11,7 +11,6 @@ /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) */ -#include <linux/config.h> #include <linux/string.h> diff --git a/drivers/sound/sys_timer.c b/drivers/sound/sys_timer.c index 5a8a7787a..88a4aaf1c 100644 --- a/drivers/sound/sys_timer.c +++ b/drivers/sound/sys_timer.c @@ -15,9 +15,6 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Andrew Veliath : adapted tmr2ticks from level 1 sequencer (avoid overflow) */ -#include <linux/config.h> - - #include "sound_config.h" static volatile int opened = 0, tmr_running = 0; diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c index a59fa7c99..c4f105ef5 100644 --- a/drivers/sound/uart401.c +++ b/drivers/sound/uart401.c @@ -19,7 +19,6 @@ * Untested */ -#include <linux/config.h> #include <linux/module.h> #include "sound_config.h" diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c index dfa6ed417..b0548d513 100644 --- a/drivers/sound/uart6850.c +++ b/drivers/sound/uart6850.c @@ -16,7 +16,6 @@ * Status: Testing required * */ -#include <linux/config.h> #include <linux/module.h> /* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl: diff --git a/drivers/sound/v_midi.c b/drivers/sound/v_midi.c index caeda1e41..0cab16199 100644 --- a/drivers/sound/v_midi.c +++ b/drivers/sound/v_midi.c @@ -18,7 +18,6 @@ * Untested */ -#include <linux/config.h> #include <linux/module.h> #include "sound_config.h" diff --git a/drivers/sound/vidc.c b/drivers/sound/vidc.c index 4fed93e06..578d4dff9 100644 --- a/drivers/sound/vidc.c +++ b/drivers/sound/vidc.c @@ -13,6 +13,7 @@ * We currently support a mixer device, but it is currently non-functional. */ +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index 7f7b8687e..bf6c23b53 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -43,8 +43,10 @@ comment 'USB Devices' bool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG fi dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT - dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB - dep_tristate ' PLUSB Prolific USB-Network driver' CONFIG_USB_PLUSB $CONFIG_USB + dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB + dep_tristate ' PLUSB Prolific USB-Network driver' CONFIG_USB_PLUSB $CONFIG_USB + dep_tristate ' USB ADMteks Pegasus based devices support' CONFIG_USB_PEGASUS $CONFIG_USB + dep_tristate ' USB Diamond Rio500 support' CONFIG_USB_RIO500 $CONFIG_USB comment 'USB HID' dep_tristate ' USB Human Interface Device (HID) support' CONFIG_USB_HID $CONFIG_USB @@ -52,7 +54,7 @@ comment 'USB HID' dep_tristate ' USB HIDBP Keyboard support' CONFIG_USB_KBD $CONFIG_USB dep_tristate ' USB HIDBP Mouse support' CONFIG_USB_MOUSE $CONFIG_USB fi - dep_tristate ' Wacom Graphire tablet support' CONFIG_USB_GRAPHIRE $CONFIG_USB + dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB dep_tristate ' Logitech WingMan Force joystick support' CONFIG_USB_WMFORCE $CONFIG_USB dep_tristate ' Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_USB dep_tristate ' Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_USB diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 3a0ef10b7..6f8ebb3f6 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -47,7 +47,7 @@ obj-$(CONFIG_USB_OHCI) += usb-ohci.o obj-$(CONFIG_USB_MOUSE) += usbmouse.o input.o obj-$(CONFIG_USB_HID) += hid.o input.o obj-$(CONFIG_USB_KBD) += usbkbd.o input.o -obj-$(CONFIG_USB_GRAPHIRE) += graphire.o input.o +obj-$(CONFIG_USB_WACOM) += wacom.o input.o obj-$(CONFIG_USB_WMFORCE) += wmforce.o input.o obj-$(CONFIG_INPUT_KEYBDEV) += keybdev.o input.o obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o input.o @@ -67,6 +67,8 @@ obj-$(CONFIG_USB_USS720) += uss720.o obj-$(CONFIG_USB_DABUSB) += dabusb.o obj-$(CONFIG_USB_PLUSB) += plusb.o obj-$(CONFIG_USB_OV511) += ov511.o +obj-$(CONFIG_USB_PEGASUS) += pegasus.o +obj-$(CONFIG_USB_RIO500) += rio500.o # Extract lists of the multi-part drivers. # The 'int-*' lists are the intermediate files used to build the multi's. diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c index d93391340..b1f889e89 100644 --- a/drivers/usb/acm.c +++ b/drivers/usb/acm.c @@ -193,10 +193,13 @@ static void acm_ctrl_irq(struct urb *urb) newctrl = le16_to_cpup((__u16 *) data); +#if 0 + /* Please someone tell me how to do this properly to kill pppd and not kill minicom */ if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { dbg("calling hangup"); tty_hangup(acm->tty); } +#endif acm->ctrlin = newctrl; @@ -428,6 +431,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_ struct acm *acm = tty->driver_data; struct termios *termios = tty->termios; struct acm_line newline; + int newctrl = acm->ctrlout; if (!ACM_READY(acm)) return; @@ -439,20 +443,20 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_ newline.databits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; acm->clocal = termios->c_cflag & CLOCAL; - - if (!memcmp(&acm->line, &newline, sizeof(struct acm_line))) - return; - - memcpy(&acm->line, &newline, sizeof(struct acm_line)); - + if (!newline.speed) { - if (acm->ctrlout) acm_set_control(acm, acm->ctrlout = 0); - return; - } + newline.speed = acm->line.speed; + newctrl &= ~ACM_CTRL_DTR; + } else newctrl |= ACM_CTRL_DTR; - acm_set_line(acm, &acm->line); + if (newctrl != acm->ctrlout) + acm_set_control(acm, acm->ctrlout = newctrl); - dbg("set line: %d %d %d %d", newline.speed, newline.stopbits, newline.parity, newline.databits); + if (memcmp(&acm->line, &newline, sizeof(struct acm_line))) { + memcpy(&acm->line, &newline, sizeof(struct acm_line)); + dbg("set line: %d %d %d %d", newline.speed, newline.stopbits, newline.parity, newline.databits); + acm_set_line(acm, &acm->line); + } } /* diff --git a/drivers/usb/hid.c b/drivers/usb/hid.c index 778bb3532..3f98d9b14 100644 --- a/drivers/usb/hid.c +++ b/drivers/usb/hid.c @@ -65,14 +65,15 @@ static unsigned char hid_keyboard[256] = { 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95, - 120,121,122,123,unk,138,unk,unk,128,129,131,137,133,135,136,113, + 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113, 115,114,unk,unk,unk,unk,unk,124,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - 134,130,132,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - 29, 42, 56,125, 97, 54,100,126 + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, + 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; static struct { @@ -728,14 +729,16 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie case HID_UP_KEYBOARD: + set_bit(EV_REP, input->evbit); + usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + if ((usage->hid & HID_USAGE) < 256) { if (!(usage->code = hid_keyboard[usage->hid & HID_USAGE])) return; + clear_bit(usage->code, bit); } else usage->code = KEY_UNKNOWN; - set_bit(EV_REP, input->evbit); - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; break; case HID_UP_BUTTON: diff --git a/drivers/usb/hid.h b/drivers/usb/hid.h index 2449039b8..4a4caf401 100644 --- a/drivers/usb/hid.h +++ b/drivers/usb/hid.h @@ -201,7 +201,7 @@ struct hid_global { * This is the local enviroment. It is resistent up the the next main-item. */ -#define MAX_USAGES 512 +#define MAX_USAGES 1024 struct hid_local { unsigned usage[MAX_USAGES]; /* usage array */ diff --git a/drivers/usb/ibmcam.c b/drivers/usb/ibmcam.c index 831c454b3..89e02b4ca 100644 --- a/drivers/usb/ibmcam.c +++ b/drivers/usb/ibmcam.c @@ -67,9 +67,7 @@ static const int imgheight = V4L_FRAME_HEIGHT; static const int min_imgwidth = 8; static const int min_imgheight = 4; -#define LIGHTING_MIN 0 /* 0=Bright 1=Med 2=Low */ -#define LIGHTING_MAX 2 -static int lighting = (LIGHTING_MIN + LIGHTING_MAX) / 2; /* Medium */ +static int lighting = 1; /* Medium */ #define SHARPNESS_MIN 0 #define SHARPNESS_MAX 6 @@ -82,7 +80,9 @@ static int framerate = 2; /* Lower, reliable frame rate (8-12 fps) */ enum { VIDEOSIZE_128x96 = 0, VIDEOSIZE_176x144, - VIDEOSIZE_352x288 + VIDEOSIZE_352x288, + VIDEOSIZE_320x240, + VIDEOSIZE_352x240, }; static int videosize = VIDEOSIZE_352x288; @@ -117,6 +117,12 @@ static int init_color = 128; static int init_hue = 128; static int hue_correction = 128; +/* Settings for camera model 2 */ +static int init_model2_rg = -1; +static int init_model2_rg2 = -1; +static int init_model2_sat = -1; +static int init_model2_yb = -1; + MODULE_PARM(debug, "i"); MODULE_PARM(flags, "i"); MODULE_PARM(framerate, "i"); @@ -129,6 +135,11 @@ MODULE_PARM(init_color, "i"); MODULE_PARM(init_hue, "i"); MODULE_PARM(hue_correction, "i"); +MODULE_PARM(init_model2_rg, "i"); +MODULE_PARM(init_model2_rg2, "i"); +MODULE_PARM(init_model2_sat, "i"); +MODULE_PARM(init_model2_yb, "i"); + MODULE_AUTHOR ("module author"); MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000"); @@ -140,6 +151,15 @@ static const unsigned short contrast_14 = 0x0014; static const unsigned short light_27 = 0x0027; static const unsigned short sharp_13 = 0x0013; +/* i2c commands for Model 2 cameras */ +static const unsigned short mod2_brightness = 0x001a; /* $5b .. $ee; default=$5a */ +static const unsigned short mod2_set_framerate = 0x001c; /* 0 (fast).. $1F (slow) */ +static const unsigned short mod2_color_balance_rg2 = 0x001e; /* 0 (red) .. $7F (green) */ +static const unsigned short mod2_saturation = 0x0020; /* 0 (b/w) - $7F (full color) */ +static const unsigned short mod2_color_balance_yb = 0x0022; /* 0..$7F, $50 is about right */ +static const unsigned short mod2_color_balance_rg = 0x0024; /* 0..$7F, $70 is about right */ +static const unsigned short mod2_sensitivity = 0x0028; /* 0 (min) .. $1F (max) */ + #define MAX_IBMCAM 4 struct usb_ibmcam cams[MAX_IBMCAM]; @@ -262,6 +282,24 @@ static void rvfree(void *mem, unsigned long size) vfree(mem); } +#if ENABLE_HEXDUMP +static void ibmcam_hexdump(const unsigned char *data, int len) +{ + char tmp[80]; + int i, k; + + for (i=k=0; len > 0; i++, len--) { + if (i > 0 && (i%16 == 0)) { + printk("%s\n", tmp); + k=0; + } + k += sprintf(&tmp[k], "%02x ", data[i]); + } + if (k > 0) + printk("%s\n", tmp); +} +#endif + /* * usb_ibmcam_overlaychar() * @@ -485,7 +523,7 @@ void usb_ibmcam_testpattern(struct usb_ibmcam *ibmcam, int fullframe, int pmode) usb_ibmcam_overlaystats(ibmcam, frame); } -static unsigned char *ibmcam_find_header(const unsigned char hdr_sig, unsigned char *data, int len) +static unsigned char *ibmcam_model1_find_header(unsigned char hdr_sig, unsigned char *data, int len) { while (len >= 4) { @@ -498,7 +536,7 @@ static unsigned char *ibmcam_find_header(const unsigned char hdr_sig, unsigned c if (data[3] == hdr_sig) { if (debug > 2) printk(KERN_DEBUG "Header found.\n"); - return data; + return data+4; } } ++data; @@ -507,6 +545,38 @@ static unsigned char *ibmcam_find_header(const unsigned char hdr_sig, unsigned c return NULL; } +static unsigned char *ibmcam_model2_find_header(unsigned char hdr_sig, unsigned char *data, int len) +{ + int marker_len = 0; + + switch (videosize) { + case VIDEOSIZE_176x144: + marker_len = 10; + break; + default: + marker_len = 2; + break; + } + while (len >= marker_len) + { + if ((data[0] == 0x00) && (data[1] == 0xFF)) + { +#if 0 + /* This code helps to detect new frame markers */ + static int pass = 0; + if (pass++ == 0) + ibmcam_hexdump(data, (len > 16) ? 16 : len); +#endif + if (debug > 2) + printk(KERN_DEBUG "Header found.\n"); + return data+marker_len; + } + ++data; + --len; + } + return NULL; +} + /* How much data is left in the scratch buf? */ #define scratch_left(x) (ibmcam->scratchlen - (int)((char *)x - (char *)ibmcam->scratch)) @@ -537,7 +607,13 @@ static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam) data = ibmcam->scratch; frame = &ibmcam->frame[ibmcam->curframe]; - tmp = ibmcam_find_header(frame->hdr_sig, data, scratch_left(data)); + + if (ibmcam->camera_model == IBMCAM_MODEL_1) + tmp = ibmcam_model1_find_header(frame->hdr_sig, data, scratch_left(data)); + else if (ibmcam->camera_model == IBMCAM_MODEL_2) + tmp = ibmcam_model2_find_header(frame->hdr_sig, data, scratch_left(data)); + else + tmp = NULL; if (tmp == NULL) { /* No header - entire scratch buffer is useless! */ @@ -547,7 +623,7 @@ static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam) return scan_EndParse; } /* Header found */ - data = tmp+4; + data = tmp; ibmcam->has_hdr = 1; ibmcam->header_count++; @@ -623,6 +699,24 @@ static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcop return scan_Out; } +#if 0 + { /* This code prints beginning of the source frame */ + static int pass = 0; + if ((pass++ % 3000) == 0) + ibmcam_hexdump(data, 16); + } +#endif + +#if 0 + if (frame->curline == 10 || frame->curline == 11) { + /* This code prints beginning of 10th (mono), 11th (chroma) line */ + static int pass = 0; + if ((pass % 100) == 0) + ibmcam_hexdump(data, 16); + if (frame->curline == 11) + pass++; + } +#endif /* * Make sure that our writing into output buffer * will not exceed the buffer. Mind that we may write @@ -674,7 +768,7 @@ static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcop * each byte of multi-byte data element if it is multi-byte. */ #if 1 - if (scratch_left(data) >= (4+2)) { + if ((ibmcam->camera_model == IBMCAM_MODEL_1) && (scratch_left(data) >= (4+2))) { unsigned char *dp; int j; @@ -711,18 +805,29 @@ static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcop goto make_pixel; } - y = mono_plane ? data[0] : data[1]; + if (mono_plane || frame->order_yc) + y = data[0]; + else + y = data[1]; if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */ rv = gv = bv = y; else { - if (frame->order_uv) { - u = chromaLine[(i >> 1) << 2] + hue_corr; - v = chromaLine[((i >> 1) << 2) + 2] + hue2_corr; - } else { - v = chromaLine[(i >> 1) << 2] + hue2_corr; - u = chromaLine[((i >> 1) << 2) + 2] + hue_corr; + int off_0, off_2; + + off_0 = (i >> 1) << 2; + off_2 = off_0 + 2; + + if (frame->order_yc) { + off_0++; + off_2++; } + if (!frame->order_uv) { + off_0 += 2; + off_2 -= 2; + } + u = chromaLine[off_0] + hue_corr; + v = chromaLine[off_2] + hue2_corr; /* Apply color correction */ if (color_corr != 0) { @@ -778,6 +883,162 @@ static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcop } /* + * usb_ibmcam_model2_parse_lines() + * + * This procedure deals with a weird RGB format that is produced by IBM + * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175, + * depending on horizontal size of the picture: + * + * <--- 160 or 176 pairs of RA,RB bytes -----> + * *-----------------------------------------* \ + * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx | \ + * |-----+-----+-----+-----+ ... +-----+-----| *- This is pair of horizontal lines, + * | B0 | G0 | B1 | G1 | ... | Bx | Gx | / total 240 or 288 lines (120 or 144 + * |=====+=====+=====+=====+ ... +=====+=====| / such pairs). + * + * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1 + * defines ONE pixel. Therefore this format yields 176x144 "decoded" + * resolution at best. I do not know why camera sends such format - the + * previous model just used I420 and everyone was happy. + * + * I do not know what is the difference between RAi and RBi bytes. Both + * seemingly represent R component, but slightly vary in value (so that + * the picture looks a bit colored if one or another is used). I use + * them both as R component in attempt to at least partially recover the + * lost resolution. + */ +static scan_state_t usb_ibmcam_model2_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen) +{ + struct ibmcam_frame *frame; + unsigned char *data, *f, *la, *lb; + unsigned int len; + const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL; /* V4L line offset */ + int i, j, frame_done=0, color_corr; + + color_corr = (ibmcam->vpic.colour) >> 8; /* 0..+255 */ + + data = ibmcam->scratch; + frame = &ibmcam->frame[ibmcam->curframe]; + + /* Here we deal with pairs of horizontal lines */ + + len = frame->frmwidth * 2; /* 2 lines */ + /*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/ + + /* Make sure there's enough data for the entire line */ + if (scratch_left(data) < (len+32)) { + /*printk(KERN_DEBUG "out of data, need %u.\n", len);*/ + return scan_Out; + } + + /* + * Make sure that our writing into output buffer + * will not exceed the buffer. Mind that we may write + * not into current output scanline but in several after + * it as well (if we enlarge image vertically.) + */ + if ((frame->curline + 1) >= V4L_FRAME_HEIGHT) + return scan_NextFrame; + + if ((frame->curline & 1) == 0) { + la = data; + lb = data + frame->frmwidth; + } else { + la = data + frame->frmwidth; + lb = data; + } + + /* + * Now we are sure that entire line (representing all 'frame->frmwidth' + * pixels from the camera) is available in the scratch buffer. We + * start copying the line left-aligned to the V4L buffer (which + * might be larger - not smaller, hopefully). If the camera + * line is shorter then we should pad the V4L buffer with something + * (black in this case) to complete the line. + */ + f = frame->data + (v4l_linesize * frame->curline); + + /* Fill the 2-line strip */ + for (i = 0; i < frame->frmwidth; i++) { + int y, rv, gv, bv; /* RGB components */ + + j = i & (~1); + + /* Check for various visual debugging hints (colorized pixels) */ + if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) { + if (ibmcam->has_hdr == 1) { + bv = 0; /* Yellow marker */ + gv = 0xFF; + rv = 0xFF; + } else { + bv = 0xFF; /* Cyan marker */ + gv = 0xFF; + rv = 0; + } + ibmcam->has_hdr = 0; + goto make_pixel; + } + + /* + * Here I use RA and RB components, one per physical pixel. + * This causes fine vertical grid on the picture but may improve + * horizontal resolution. If you prefer replicating, use this: + * rv = la[j + 0]; ... or ... rv = la[j + 1]; + * then the pixel will be replicated. + */ + rv = la[i]; + gv = lb[j + 1]; + bv = lb[j + 0]; + + y = (rv + gv + bv) / 3; /* Brightness (badly calculated) */ + + if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */ + rv = gv = bv = y; + else if (color_corr != 128) { + + /* Calculate difference between color and brightness */ + rv -= y; + gv -= y; + bv -= y; + + /* Scale differences */ + rv = (rv * color_corr) / 128; + gv = (gv * color_corr) / 128; + bv = (bv * color_corr) / 128; + + /* Reapply brightness */ + rv += y; + gv += y; + bv += y; + + /* Watch for overflows */ + RESTRICT_TO_RANGE(rv, 0, 255); + RESTRICT_TO_RANGE(gv, 0, 255); + RESTRICT_TO_RANGE(bv, 0, 255); + } + + make_pixel: + IBMCAM_PUTPIXEL(frame, i, frame->curline, rv, gv, bv); + IBMCAM_PUTPIXEL(frame, i, frame->curline+1, rv, gv, bv); + } + /* + * Account for number of bytes that we wrote into output V4L frame. + * We do it here, after we are done with the scanline, because we + * may fill more than one output scanline if we do vertical + * enlargement. + */ + frame->curline += 2; + *pcopylen += v4l_linesize * 2; + data += frame->frmwidth * 2; + usb_ibmcam_align_scratch(ibmcam, data); + + if (frame_done || (frame->curline >= frame->frmheight)) + return scan_NextFrame; + else + return scan_Continue; +} + +/* * ibmcam_parse_data() * * Generic routine to parse the scratch buffer. It employs either @@ -805,8 +1066,15 @@ static void ibmcam_parse_data(struct usb_ibmcam *ibmcam) if (scratch_left(data)) { if (frame->scanstate == STATE_SCANNING) newstate = usb_ibmcam_find_header(ibmcam); - else if (frame->scanstate == STATE_LINES) - newstate = usb_ibmcam_parse_lines(ibmcam, ©len); + else if (frame->scanstate == STATE_LINES) { + if ((ibmcam->camera_model == IBMCAM_MODEL_2) && + (videosize >= VIDEOSIZE_352x288)) { + newstate = usb_ibmcam_model2_parse_lines(ibmcam, ©len); + } + else { + newstate = usb_ibmcam_parse_lines(ibmcam, ©len); + } + } } if (newstate == scan_Continue) continue; @@ -834,24 +1102,6 @@ static void ibmcam_parse_data(struct usb_ibmcam *ibmcam) frame->scanlength += copylen; } -#if ENABLE_HEXDUMP -static void ibmcam_hexdump(const unsigned char *data, int len) -{ - char tmp[80]; - int i, k; - - for (i=k=0; len > 0; i++, len--) { - if (i > 0 && (i%16 == 0)) { - printk("%s\n", tmp); - k=0; - } - k += sprintf(&tmp[k], "%02x ", data[i]); - } - if (k > 0) - printk("%s\n", tmp); -} -#endif - /* * Make all of the blocks of data contiguous */ @@ -1177,6 +1427,24 @@ static void usb_ibmcam_PacketFormat2(struct usb_ibmcam *ibmcam, unsigned char fk usb_ibmcam_send_x_00_05_02 (ibmcam, val); } +static void usb_ibmcam_model2_Packet2(struct usb_ibmcam *ibmcam) +{ + usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x012d); + usb_ibmcam_veio(ibmcam, 0, 0xfea3, 0x0124); +} + +static void usb_ibmcam_model2_Packet1(struct usb_ibmcam *ibmcam, unsigned short v1, unsigned short v2) +{ + usb_ibmcam_veio(ibmcam, 0, 0x00aa, 0x012d); + usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x012e); + usb_ibmcam_veio(ibmcam, 0, v1, 0x012f); + usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x0130); + usb_ibmcam_veio(ibmcam, 0, 0xc719, 0x0124); + usb_ibmcam_veio(ibmcam, 0, v2, 0x0127); + + usb_ibmcam_model2_Packet2(ibmcam); +} + /* * usb_ibmcam_adjust_contrast() * @@ -1198,11 +1466,15 @@ static void usb_ibmcam_adjust_contrast(struct usb_ibmcam *ibmcam) new_contrast = 15; new_contrast = 15 - new_contrast; if (new_contrast != ibmcam->vpic_old.contrast) { - int i; ibmcam->vpic_old.contrast = new_contrast; - for (i=0; i < ntries; i++) { - usb_ibmcam_Packet_Format1(ibmcam, contrast_14, new_contrast); - usb_ibmcam_send_FF_04_02(ibmcam); + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + int i; + for (i=0; i < ntries; i++) { + usb_ibmcam_Packet_Format1(ibmcam, contrast_14, new_contrast); + usb_ibmcam_send_FF_04_02(ibmcam); + } + } else { + /* Camera model 2 does not have this control; implemented in software. */ } } } @@ -1210,44 +1482,86 @@ static void usb_ibmcam_adjust_contrast(struct usb_ibmcam *ibmcam) /* * usb_ibmcam_change_lighting_conditions() * + * Camera model 1: * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low. + * + * Camera model 2: + * We have 16 levels of lighting, 0 for bright light and up to 15 for + * low light. But values above 5 or so are useless because camera is + * not really capable to produce anything worth viewing at such light. + * This setting may be altered only in certain camera state. + * * Low lighting forces slower FPS. Lighting is set as a module parameter. * * History: * 1/5/00 Created. + * 2/20/00 Added support for Model 2 cameras. */ static void usb_ibmcam_change_lighting_conditions(struct usb_ibmcam *ibmcam) { static const char proc[] = "usb_ibmcam_change_lighting_conditions"; - const int ntries = 5; - int i; - RESTRICT_TO_RANGE(lighting, LIGHTING_MIN, LIGHTING_MAX); if (debug > 0) printk(KERN_INFO "%s: Set lighting to %hu.\n", proc, lighting); - for (i=0; i < ntries; i++) - usb_ibmcam_Packet_Format1(ibmcam, light_27, (unsigned short) lighting); + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + const int ntries = 5; + int i; + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(ibmcam, light_27, (unsigned short) lighting); + } else { + /* + * This command apparently requires camera to be stopped. My + * experiments showed that it -is- possible to alter the lighting + * conditions setting "on the fly", but why bother? This setting does + * not work reliably in all cases, so I decided simply to leave the + * setting where Xirlink put it - in the camera setup phase. This code + * is commented out because it does not work at -any- moment, so its + * presence makes no sense. You may use it for experiments. + */ +#if 0 + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x010c); /* Stop camera */ + usb_ibmcam_model2_Packet1(ibmcam, mod2_sensitivity, lighting); + usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); /* Start camera */ +#endif + } } +/* + * usb_ibmcam_set_sharpness() + * + * Cameras model 1 have internal smoothing feature. It is controlled by value in + * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess). + * Recommended value is 4. Cameras model 2 do not have this feature at all. + */ static void usb_ibmcam_set_sharpness(struct usb_ibmcam *ibmcam) { static const char proc[] = "usb_ibmcam_set_sharpness"; - static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; - unsigned short i, sv; - RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); - if (debug > 0) - printk(KERN_INFO "%s: Set sharpness to %hu.\n", proc, sharpness); + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; + unsigned short i, sv; - sv = sa[sharpness - SHARPNESS_MIN]; - for (i=0; i < 2; i++) { - usb_ibmcam_send_x_01_00_05 (ibmcam, unknown_88); - usb_ibmcam_send_x_00_05 (ibmcam, sharp_13); - usb_ibmcam_send_x_00_05_02 (ibmcam, sv); + RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); + if (debug > 0) + printk(KERN_INFO "%s: Set sharpness to %hu.\n", proc, sharpness); + + sv = sa[sharpness - SHARPNESS_MIN]; + for (i=0; i < 2; i++) { + usb_ibmcam_send_x_01_00_05 (ibmcam, unknown_88); + usb_ibmcam_send_x_00_05 (ibmcam, sharp_13); + usb_ibmcam_send_x_00_05_02 (ibmcam, sv); + } + } else { + /* Camera model 2 does not have this control */ } } +/* + * usb_ibmcam_set_brightness() + * + * This procedure changes brightness of the picture. + */ static void usb_ibmcam_set_brightness(struct usb_ibmcam *ibmcam) { static const char proc[] = "usb_ibmcam_set_brightness"; @@ -1263,18 +1577,41 @@ static void usb_ibmcam_set_brightness(struct usb_ibmcam *ibmcam) printk(KERN_INFO "%s: Set brightness to (%hu,%hu,%hu)\n", proc, bv[0], bv[1], bv[2]); - for (j=0; j < 3; j++) - for (i=0; i < n; i++) - usb_ibmcam_Packet_Format1(ibmcam, bright_3x[j], bv[j]); + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + for (j=0; j < 3; j++) + for (i=0; i < n; i++) + usb_ibmcam_Packet_Format1(ibmcam, bright_3x[j], bv[j]); + } else { + i = ibmcam->vpic.brightness >> 12; /* 0 .. 15 */ + j = 0x60 + i * ((0xee - 0x60) / 16); /* 0x60 .. 0xee or so */ + usb_ibmcam_model2_Packet1(ibmcam, mod2_brightness, j); + } } +static void usb_ibmcam_model2_set_hue(struct usb_ibmcam *ibmcam) +{ + unsigned short hue = ibmcam->vpic.hue >> 9; /* 0 .. 7F */ + + usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg, hue); + /* usb_ibmcam_model2_Packet1(ibmcam, mod2_saturation, sat); */ +} + +/* + * usb_ibmcam_adjust_picture() + * + * This procedure gets called from V4L interface to update picture settings. + * Here we change brightness and contrast. + */ static void usb_ibmcam_adjust_picture(struct usb_ibmcam *ibmcam) { usb_ibmcam_adjust_contrast(ibmcam); usb_ibmcam_set_brightness(ibmcam); + if (ibmcam->camera_model == IBMCAM_MODEL_2) { + usb_ibmcam_model2_set_hue(ibmcam); + } } -static int usb_ibmcam_setup(struct usb_ibmcam *ibmcam) +static int usb_ibmcam_model1_setup(struct usb_ibmcam *ibmcam) { const int ntries = 5; int i; @@ -1283,7 +1620,7 @@ static int usb_ibmcam_setup(struct usb_ibmcam *ibmcam) usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100); /* LED On */ usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); - usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100); /* LED Off */ + usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100); /* LED Off */ usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100); /* LED On */ usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0108); @@ -1468,16 +1805,68 @@ static int usb_ibmcam_setup(struct usb_ibmcam *ibmcam) usb_ibmcam_veio(ibmcam, 0, 0xf6, 0x0107); break; } - return 0; /* TODO: return actual completion status! */ + return IBMCAM_IS_OPERATIONAL(ibmcam); +} + +static int usb_ibmcam_model2_setup(struct usb_ibmcam *ibmcam) +{ + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100); /* LED on */ + usb_ibmcam_veio(ibmcam, 1, 0x0000, 0x0116); + usb_ibmcam_veio(ibmcam, 0, 0x0060, 0x0116); + usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0112); + usb_ibmcam_veio(ibmcam, 0, 0x00bc, 0x012c); + usb_ibmcam_veio(ibmcam, 0, 0x0008, 0x012b); + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0108); + usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0133); + usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0102); + switch (videosize) { + case VIDEOSIZE_176x144: + usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ + usb_ibmcam_veio(ibmcam, 0, 0x00b9, 0x010a); /* Unique to this mode */ + usb_ibmcam_veio(ibmcam, 0, 0x0038, 0x0119); /* Unique to this mode */ + usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x0090, 0x0107); /* Unique to every mode*/ + break; + case VIDEOSIZE_320x240: + usb_ibmcam_veio(ibmcam, 0, 0x0028, 0x0103); /* Unique to this mode */ + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ + usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x0098, 0x0107); /* Unique to every mode*/ + break; + case VIDEOSIZE_352x240: + usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ + usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x00da, 0x0107); /* Unique to every mode*/ + break; + case VIDEOSIZE_352x288: + usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ + usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ + usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ + usb_ibmcam_veio(ibmcam, 0, 0x00fe, 0x0107); /* Unique to every mode*/ + break; + } + return IBMCAM_IS_OPERATIONAL(ibmcam); } /* - * usb_ibmcam_setup_after_video_if() + * usb_ibmcam_model1_setup_after_video_if() * * This code adds finishing touches to the video data interface. * Here we configure the frame rate and turn on the LED. */ -static void usb_ibmcam_setup_after_video_if(struct usb_ibmcam *ibmcam) +static void usb_ibmcam_model1_setup_after_video_if(struct usb_ibmcam *ibmcam) { unsigned short internal_frame_rate; @@ -1489,6 +1878,188 @@ static void usb_ibmcam_setup_after_video_if(struct usb_ibmcam *ibmcam) usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c); } +static void usb_ibmcam_model2_setup_after_video_if(struct usb_ibmcam *ibmcam) +{ + unsigned short setup_model2_rg, setup_model2_rg2, setup_model2_sat, setup_model2_yb; + + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100); /* LED on */ + + switch (videosize) { + case VIDEOSIZE_176x144: + usb_ibmcam_veio(ibmcam, 0, 0x0050, 0x0111); + usb_ibmcam_veio(ibmcam, 0, 0x00d0, 0x0111); + break; + case VIDEOSIZE_320x240: + case VIDEOSIZE_352x240: + case VIDEOSIZE_352x288: + usb_ibmcam_veio(ibmcam, 0, 0x0040, 0x0111); + usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x0111); + break; + } + usb_ibmcam_veio(ibmcam, 0, 0x009b, 0x010f); + usb_ibmcam_veio(ibmcam, 0, 0x00bb, 0x010f); + + /* + * Hardware settings, may affect CMOS sensor; not user controls! + * ------------------------------------------------------------- + * 0x0004: no effect + * 0x0006: hardware effect + * 0x0008: no effect + * 0x000a: stops video stream, probably important h/w setting + * 0x000c: changes color in hardware manner (not user setting) + * 0x0012: changes number of colors (does not affect speed) + * 0x002a: no effect + * 0x002c: hardware setting (related to scan lines) + * 0x002e: stops video stream, probably important h/w setting + */ + usb_ibmcam_model2_Packet1(ibmcam, 0x000a, 0x005c); + usb_ibmcam_model2_Packet1(ibmcam, 0x0004, 0x0000); + usb_ibmcam_model2_Packet1(ibmcam, 0x0006, 0x00fb); + usb_ibmcam_model2_Packet1(ibmcam, 0x0008, 0x0000); + usb_ibmcam_model2_Packet1(ibmcam, 0x000c, 0x0009); + usb_ibmcam_model2_Packet1(ibmcam, 0x0012, 0x000a); + usb_ibmcam_model2_Packet1(ibmcam, 0x002a, 0x0000); + usb_ibmcam_model2_Packet1(ibmcam, 0x002c, 0x0000); + usb_ibmcam_model2_Packet1(ibmcam, 0x002e, 0x0008); + + /* + * Function 0x0030 pops up all over the place. Apparently + * it is a hardware control register, with every bit assigned to + * do something. + */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0000); + + /* + * Magic control of CMOS sensor. Only lower values like + * 0-3 work, and picture shifts left or right. Don't change. + */ + switch (videosize) { + case VIDEOSIZE_176x144: + usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0002); + usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */ + break; + case VIDEOSIZE_320x240: + usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009); + usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0005); /* Horizontal shift */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Another hardware setting */ + break; + case VIDEOSIZE_352x240: + /* This mode doesn't work as Windows programs it; changed to work */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009); /* Windows sets this to 8 */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0003); /* Horizontal shift */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ + break; + case VIDEOSIZE_352x288: + usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0003); + usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */ + break; + } + + usb_ibmcam_model2_Packet1(ibmcam, mod2_brightness, 0x005a); + + /* + * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest). + * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the + * slowest setting. However for all practical reasons high settings make no + * sense because USB is not fast enough to support high FPS. Be aware that + * the picture datastream will be severely disrupted if you ask for + * frame rate faster than allowed for the video size - see below: + * + * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz): + * ----------------------------------------------------------------- + * 176x144: [6..31] + * 320x240: [8..31] + * 352x240: [10..31] + * 352x288: [16..31] I have to raise lower threshold for stability... + * + * As usual, slower FPS provides better sensitivity. + */ + { + short hw_fps=31, i_framerate; + + RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); + i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN; + switch (videosize) { + case VIDEOSIZE_176x144: + hw_fps = 6 + i_framerate*4; + break; + case VIDEOSIZE_320x240: + hw_fps = 8 + i_framerate*3; + break; + case VIDEOSIZE_352x240: + hw_fps = 10 + i_framerate*2; + break; + case VIDEOSIZE_352x288: + hw_fps = 28 + i_framerate/2; + break; + } + if (debug > 0) + printk(KERN_DEBUG "Framerate (hardware): %hd.\n", hw_fps); + RESTRICT_TO_RANGE(hw_fps, 0, 31); + usb_ibmcam_model2_Packet1(ibmcam, mod2_set_framerate, hw_fps); + } + + /* + * This setting does not visibly affect pictures; left it here + * because it was present in Windows USB data stream. This function + * does not allow arbitrary values and apparently is a bit mask, to + * be activated only at appropriate time. Don't change it randomly! + */ + switch (videosize) { + case VIDEOSIZE_176x144: + usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x00c2); + break; + case VIDEOSIZE_320x240: + usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0044); + break; + case VIDEOSIZE_352x240: + usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0046); + break; + case VIDEOSIZE_352x288: + usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0048); + break; + } + + usb_ibmcam_model2_Packet1(ibmcam, mod2_sensitivity, lighting); + + if (init_model2_rg >= 0) { + RESTRICT_TO_RANGE(init_model2_rg, 0, 255); + setup_model2_rg = init_model2_rg; + } else + setup_model2_rg = 0x0070; + + if (init_model2_rg2 >= 0) { + RESTRICT_TO_RANGE(init_model2_rg2, 0, 255); + setup_model2_rg2 = init_model2_rg2; + } else + setup_model2_rg2 = 0x002f; + + if (init_model2_sat >= 0) { + RESTRICT_TO_RANGE(init_model2_sat, 0, 255); + setup_model2_sat = init_model2_sat; + } else + setup_model2_sat = 0x0034; + + if (init_model2_yb >= 0) { + RESTRICT_TO_RANGE(init_model2_yb, 0, 255); + setup_model2_yb = init_model2_yb; + } else + setup_model2_yb = 0x00a0; + + usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg2, setup_model2_rg2); + usb_ibmcam_model2_Packet1(ibmcam, mod2_saturation, setup_model2_sat); + usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_yb, setup_model2_yb); + usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg, setup_model2_rg); + + /* Hardware control command */ + usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004); + + usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); /* Go camera, go! */ + usb_clear_halt(ibmcam->dev, ibmcam->video_endp); +} + /* * usb_ibmcam_setup_video_stop() * @@ -1497,14 +2068,29 @@ static void usb_ibmcam_setup_after_video_if(struct usb_ibmcam *ibmcam) */ static void usb_ibmcam_setup_video_stop(struct usb_ibmcam *ibmcam) { - usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); - usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); - usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114); - usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c); - usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); - usb_ibmcam_send_FF_04_02(ibmcam); - usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); - usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100); /* LED Off */ + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); + usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); + usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114); + usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c); + usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); + usb_ibmcam_send_FF_04_02(ibmcam); + usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); + usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100); /* LED Off */ + } else if (ibmcam->camera_model == IBMCAM_MODEL_2) { + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x010c); /* Stop the camera */ + + usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004); + + usb_ibmcam_veio(ibmcam, 0, 0x0080, 0x0100); /* LED Off */ + usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111); + usb_ibmcam_veio(ibmcam, 0, 0x00a0, 0x0111); + + usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0002); + + usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111); + usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0112); + } } /* @@ -1519,13 +2105,16 @@ static void usb_ibmcam_setup_video_stop(struct usb_ibmcam *ibmcam) */ static void usb_ibmcam_reinit_iso(struct usb_ibmcam *ibmcam, int do_stop) { - if (do_stop) - usb_ibmcam_setup_video_stop(ibmcam); - - usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0114); - usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); - usb_clear_halt(ibmcam->dev, ibmcam->video_endp); - usb_ibmcam_setup_after_video_if(ibmcam); + if (ibmcam->camera_model == IBMCAM_MODEL_1) { + if (do_stop) + usb_ibmcam_setup_video_stop(ibmcam); + usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0114); + usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); + usb_clear_halt(ibmcam->dev, ibmcam->video_endp); + usb_ibmcam_model1_setup_after_video_if(ibmcam); + } else if (ibmcam->camera_model == IBMCAM_MODEL_2) { + usb_ibmcam_model2_setup_after_video_if(ibmcam); + } } /* @@ -1602,7 +2191,7 @@ static int ibmcam_init_isoc(struct usb_ibmcam *ibmcam) } ibmcam->streaming = 1; - // printk(KERN_DEBUG "streaming=1 ibmcam->video_endp=$%02x\n", ibmcam->video_endp); + /* printk(KERN_DEBUG "streaming=1 ibmcam->video_endp=$%02x\n", ibmcam->video_endp); */ return 0; } @@ -1686,6 +2275,14 @@ static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum) frame->order_uv = 1; /* U Y V Y ... */ frame->hdr_sig = 0x0E; /* 00 FF 00 0E */ break; + case VIDEOSIZE_320x240: /* For model 2 only */ + frame->frmwidth = 320; + frame->frmheight = 240; + break; + case VIDEOSIZE_352x240: /* For model 2 only */ + frame->frmwidth = 352; + frame->frmheight = 240; + break; case VIDEOSIZE_352x288: frame->frmwidth = 352; frame->frmheight = 288; @@ -1693,6 +2290,7 @@ static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum) frame->hdr_sig = 0x00; /* 00 FF 00 00 */ break; } + frame->order_yc = (ibmcam->camera_model == IBMCAM_MODEL_2); width = frame->width; RESTRICT_TO_RANGE(width, min_imgwidth, imgwidth); @@ -1786,9 +2384,15 @@ static int ibmcam_open(struct video_device *dev, int flags) if (!err) { /* Send init sequence only once, it's large! */ if (!ibmcam->initialized) { - err = usb_ibmcam_setup(ibmcam); - if (!err) + int setup_ok = 0; + if (ibmcam->camera_model == IBMCAM_MODEL_1) + setup_ok = usb_ibmcam_model1_setup(ibmcam); + else if (ibmcam->camera_model == IBMCAM_MODEL_2) + setup_ok = usb_ibmcam_model2_setup(ibmcam); + if (setup_ok) ibmcam->initialized = 1; + else + err = -EBUSY; } if (!err) { ibmcam->user++; @@ -2239,7 +2843,7 @@ static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam) memset(&ibmcam->vcap, 0, sizeof(ibmcam->vcap)); strcpy(ibmcam->vcap.name, "IBM USB Camera"); - ibmcam->vcap.type = VID_TYPE_CAPTURE /*| VID_TYPE_SUBCAPTURE*/; + ibmcam->vcap.type = VID_TYPE_CAPTURE; ibmcam->vcap.channels = 1; ibmcam->vcap.audios = 0; ibmcam->vcap.maxwidth = imgwidth; @@ -2267,11 +2871,20 @@ static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam) */ static int ibmcam_find_struct(void) { - int u; + int i, u; for (u = 0; u < MAX_IBMCAM; u++) { - if (!cams[u].ibmcam_used) /* This one is free */ + struct usb_ibmcam *ibmcam = &cams[u]; + if (!ibmcam->ibmcam_used) /* This one is free */ + { + ibmcam->ibmcam_used = 1; /* In use now */ + for (i=0; i < IBMCAM_NUMFRAMES; i++) + init_waitqueue_head(&ibmcam->frame[i].wq); + init_MUTEX(&ibmcam->lock); /* to 1 == available */ + ibmcam->dev = NULL; + memcpy(&ibmcam->vdev, &ibmcam_template, sizeof(ibmcam_template)); return u; + } } return -1; } @@ -2289,8 +2902,10 @@ static int ibmcam_find_struct(void) static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_ibmcam *ibmcam = NULL; - struct usb_interface_descriptor *interface; - int devnum; + const unsigned char *p_rev; + const struct usb_interface_descriptor *interface; + const struct usb_endpoint_descriptor *endpoint; + int devnum, model=0; if (debug >= 1) printk(KERN_DEBUG "ibmcam_probe(%p,%u.)\n", dev, ifnum); @@ -2304,14 +2919,49 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) (dev->descriptor.idProduct != 0x8080)) return NULL; - interface = &dev->actconfig->interface[ifnum].altsetting[0]; + /* Check the version/revision */ + p_rev = (const unsigned char *) &dev->descriptor.bcdDevice; + if (p_rev[1] == 0x00 && p_rev[0] == 0x02) { + if (ifnum != 2) + return NULL; + printk(KERN_INFO "IBM USB camera found (model 1).\n"); + model = IBMCAM_MODEL_1; + } else if (p_rev[1] == 0x03 && p_rev[0] == 0x0A) { + if (ifnum != 0) + return NULL; + printk(KERN_INFO "IBM USB camera found (model 2).\n"); + model = IBMCAM_MODEL_2; + } else { + printk(KERN_ERR "IBM camera revision=%02x.%02x not supported\n", + p_rev[1], p_rev[0]); + return NULL; + } - /* Camera confirmed. We claim only interface 2 (video data) */ - if (ifnum != 2) + /* Validate found interface: must have one ISO endpoint */ + interface = &dev->actconfig->interface[ifnum].altsetting[0]; + if (interface->bNumEndpoints != 1) { + printk(KERN_ERR "IBM camera: interface %d. has %u. endpoints!\n", + ifnum, (unsigned)(interface->bNumEndpoints)); + return NULL; + } + endpoint = &interface->endpoint[0]; + if ((endpoint->bmAttributes & 0x03) != 0x01) { + printk(KERN_ERR "IBM camera: interface %d. has non-ISO endpoint!\n", ifnum); + return NULL; + } + if ((endpoint->bEndpointAddress & 0x80) == 0) { + printk(KERN_ERR "IBM camera: interface %d. has ISO OUT endpoint!\n", ifnum); return NULL; + } - /* We found an IBM camera */ - printk(KERN_INFO "IBM USB camera found (interface %u.)\n", ifnum); + /* Validate options */ + if (model == IBMCAM_MODEL_1) { + RESTRICT_TO_RANGE(lighting, 0, 2); + RESTRICT_TO_RANGE(videosize, VIDEOSIZE_128x96, VIDEOSIZE_352x288); + } else { + RESTRICT_TO_RANGE(lighting, 0, 15); + RESTRICT_TO_RANGE(videosize, VIDEOSIZE_176x144, VIDEOSIZE_352x240); + } devnum = ibmcam_find_struct(); if (devnum == -1) { @@ -2321,14 +2971,14 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) ibmcam = &cams[devnum]; down(&ibmcam->lock); - ibmcam->ibmcam_used = 1; /* In use now */ + ibmcam->camera_model = model; ibmcam->remove_pending = 0; ibmcam->last_error = 0; ibmcam->dev = dev; ibmcam->iface = ifnum; ibmcam->ifaceAltInactive = 0; ibmcam->ifaceAltActive = 1; - ibmcam->video_endp = 0x82; + ibmcam->video_endp = endpoint->bEndpointAddress; ibmcam->iso_packet_len = 1014; ibmcam->compress = 0; ibmcam->user=0; @@ -2425,19 +3075,12 @@ static struct usb_driver ibmcam_driver = { */ int usb_ibmcam_init(void) { - unsigned i, u; + unsigned u; /* Initialize struct */ for (u = 0; u < MAX_IBMCAM; u++) { struct usb_ibmcam *ibmcam = &cams[u]; memset (ibmcam, 0, sizeof(struct usb_ibmcam)); - - init_waitqueue_head (&ibmcam->remove_ok); - for (i=0; i < IBMCAM_NUMFRAMES; i++) - init_waitqueue_head(&ibmcam->frame[i].wq); - init_MUTEX(&ibmcam->lock); /* to 1 == available */ - ibmcam->dev = NULL; - memcpy(&ibmcam->vdev, &ibmcam_template, sizeof(ibmcam_template)); } return usb_register(&ibmcam_driver); } diff --git a/drivers/usb/ibmcam.h b/drivers/usb/ibmcam.h index cdaaec8ef..b2511dbdc 100644 --- a/drivers/usb/ibmcam.h +++ b/drivers/usb/ibmcam.h @@ -153,6 +153,7 @@ struct ibmcam_sbuf { struct ibmcam_frame { char *data; /* Frame buffer */ int order_uv; /* True=UV False=VU */ + int order_yc; /* True=Yc False=cY ('c'=either U or V) */ unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */ int width; /* Width application is expecting */ @@ -172,6 +173,9 @@ struct ibmcam_frame { wait_queue_head_t wq; /* Processes waiting */ }; +#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */ +#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */ + struct usb_ibmcam { struct video_device vdev; @@ -186,6 +190,7 @@ struct usb_ibmcam { int ibmcam_used; /* Is this structure in use? */ int initialized; /* Had we already sent init sequence? */ + int camera_model; /* What type of IBM camera we got? */ int streaming; /* Are we streaming Isochronous? */ int grabbing; /* Are we grabbing? */ int last_error; /* What calamity struck us? */ @@ -201,7 +206,6 @@ struct usb_ibmcam { int cursbuf; /* Current receiving sbuf */ struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */ volatile int remove_pending; /* If set then about to exit */ - wait_queue_head_t remove_ok; /* Wait here until removal is safe */ /* * Scratch space from the Isochronous pipe. diff --git a/drivers/usb/inode.c b/drivers/usb/inode.c index 2306615f0..a641e098b 100644 --- a/drivers/usb/inode.c +++ b/drivers/usb/inode.c @@ -45,9 +45,6 @@ static LIST_HEAD(superlist); -extern struct inode_operations usbdevfs_bus_inode_operations; -extern struct file_operations usbdevfs_bus_file_operations; - struct special { const char *name; struct file_operations *fops; diff --git a/drivers/usb/joydev.c b/drivers/usb/joydev.c index e2e1d2961..a5dcabdab 100644 --- a/drivers/usb/joydev.c +++ b/drivers/usb/joydev.c @@ -464,7 +464,7 @@ static struct input_handler joydev_handler = { disconnect: joydev_disconnect, }; -static int joydev_init(void) +static int __init joydev_init(void) { if (register_chrdev(JOYDEV_MAJOR, "js", &joydev_fops)) { printk(KERN_ERR "joydev: unable to get major %d for joystick\n", JOYDEV_MAJOR); @@ -474,7 +474,7 @@ static int joydev_init(void) return 0; } -static void joydev_exit(void) +static void __exit joydev_exit(void) { input_unregister_handler(&joydev_handler); if (unregister_chrdev(JOYSTICK_MAJOR, "js")) diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c index aa0531a89..4c69d4221 100644 --- a/drivers/usb/scanner.c +++ b/drivers/usb/scanner.c @@ -793,18 +793,11 @@ ioctl_scanner(struct inode *inode, struct file *file, static struct file_operations usb_scanner_fops = { - NULL, /* seek */ - read_scanner, - write_scanner, - NULL, /* readdir */ - NULL, /* poll */ - ioctl_scanner, - NULL, /* mmap */ - open_scanner, - NULL, /* flush */ - close_scanner, - NULL, - NULL, /* fasync */ + read: read_scanner, + write: write_scanner, + ioctl: ioctl_scanner, + open: open_scanner, + release: close_scanner, }; static struct diff --git a/drivers/usb/usb-debug.c b/drivers/usb/usb-debug.c index 356a4373b..df72e0abc 100644 --- a/drivers/usb/usb-debug.c +++ b/drivers/usb/usb-debug.c @@ -143,14 +143,17 @@ void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc) USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength == USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)"; char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" }; + printk(" Endpoint:\n"); - printk(" bLength = %4d%s\n", desc->bLength, - LengthCommentString); + printk(" bLength = %4d%s\n", + desc->bLength, LengthCommentString); printk(" bDescriptorType = %02x\n", desc->bDescriptorType); printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress, - (desc->bEndpointAddress & 0x80) ? "in" : "out"); + (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL ? "i/o" : + (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out"); printk(" bmAttributes = %02x (%s)\n", desc->bmAttributes, - EndpointType[3 & desc->bmAttributes]); + EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]); printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize); printk(" bInterval = %02x\n", desc->bInterval); diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index ebd64b6c5..573e0485d 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -1375,8 +1375,13 @@ static void usb_set_maxpacket(struct usb_device *dev) int e; for (e=0; e<as->bNumEndpoints; e++) { - b = ep[e].bEndpointAddress & 0x0f; - if (usb_endpoint_out(ep[e].bEndpointAddress)) { + b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */ + dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; + dev->epmaxpacketin [b] = ep[e].wMaxPacketSize; + } + else if (usb_endpoint_out(ep[e].bEndpointAddress)) { if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b]) dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; } diff --git a/drivers/usb/usb.h b/drivers/usb/usb.h index a7b027bf2..d1381c107 100644 --- a/drivers/usb/usb.h +++ b/drivers/usb/usb.h @@ -85,9 +85,22 @@ /* * USB Packet IDs (PIDs) */ -#define USB_PID_OUT 0xe1 -#define USB_PID_IN 0x69 -#define USB_PID_SETUP 0x2d +#define USB_PID_UNDEF_0 0xf0 +#define USB_PID_OUT 0xe1 +#define USB_PID_ACK 0xd2 +#define USB_PID_DATA0 0xc3 +#define USB_PID_UNDEF_4 0xb4 +#define USB_PID_SOF 0xa5 +#define USB_PID_UNDEF_6 0x96 +#define USB_PID_UNDEF_7 0x87 +#define USB_PID_UNDEF_8 0x78 +#define USB_PID_IN 0x69 +#define USB_PID_NAK 0x5a +#define USB_PID_DATA1 0x4b +#define USB_PID_PREAMBLE 0x3c +#define USB_PID_SETUP 0x2d +#define USB_PID_STALL 0x1e +#define USB_PID_UNDEF_F 0x0f /* * Standard requests diff --git a/drivers/usb/usbdevice_fs.h b/drivers/usb/usbdevice_fs.h index be3424a88..95eaa937a 100644 --- a/drivers/usb/usbdevice_fs.h +++ b/drivers/usb/usbdevice_fs.h @@ -157,7 +157,10 @@ struct dev_state { extern struct usb_driver usbdevfs_driver; extern struct file_operations usbdevfs_drivers_fops; extern struct file_operations usbdevfs_devices_fops; +extern struct file_operations usbdevfs_device_file_operations; extern struct inode_operations usbdevfs_device_inode_operations; +extern struct inode_operations usbdevfs_bus_inode_operations; +extern struct file_operations usbdevfs_bus_file_operations; extern void usbdevfs_conn_disc_event(void); diff --git a/drivers/usb/usbkbd.c b/drivers/usb/usbkbd.c index 00fecea9d..ebc8ab45b 100644 --- a/drivers/usb/usbkbd.c +++ b/drivers/usb/usbkbd.c @@ -45,14 +45,15 @@ static unsigned char usb_kbd_keycode[256] = { 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95, - 120,121,122,123, 0,138, 0, 0,128,129,131,137,133,135,136,113, + 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113, 115,114, 0, 0, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 134,130,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 42, 56,125, 97, 54,100,126 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, + 150,158,159,128,136,177,178,176,142,152,173,140 }; struct usb_kbd { diff --git a/drivers/video/Config.in b/drivers/video/Config.in index 9d12bf42a..850755767 100644 --- a/drivers/video/Config.in +++ b/drivers/video/Config.in @@ -11,7 +11,7 @@ if [ "$CONFIG_FB" = "y" ]; then define_bool CONFIG_DUMMY_CONSOLE y if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_PCI" = "y" ]; then - bool ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA + tristate ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA fi if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then tristate ' Cirrus Logic support (EXPERIMENTAL)' CONFIG_FB_CLGEN @@ -105,10 +105,12 @@ if [ "$CONFIG_FB" = "y" ]; then bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100 - dep_tristate ' Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT - if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then - dep_tristate ' G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C - fi + if [ "$CONFIG_I2C" != "n" ]; then + dep_tristate ' Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT + if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then + dep_tristate ' G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C + fi + fi bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD fi tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 75896bbf8..0f8b53c3f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -5,7 +5,7 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) matrox +ALL_SUB_DIRS := $(SUB_DIRS) matrox riva O_TARGET := video.o O_OBJS := @@ -16,11 +16,12 @@ M_OBJS := # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. -export-objs := fbmem.o fbcmap.o fbcon.o fbcon-afb.o fbcon-ilbm.o fbcon-vga.o \ - fbcon-iplan2p2.o fbcon-iplan2p4.o fbcon-iplan2p8.o fbcon-vga-planes.o \ - fbcon-cfb16.o fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o fbcon-cfb8.o \ - fbcon-mac.o fbcon-mfb.o fbcon-vga8-planes.o \ - matrox/matroxfb.o +export-objs := fbmem.o fbcmap.o fbcon.o fbcon-afb.o fbcon-ilbm.o \ + fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \ + fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \ + fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \ + fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o fbcon-vga8-planes.o \ + matrox/matroxfb.o cyber2000fb.o # Object file lists. obj-y := @@ -62,7 +63,6 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o -obj-$(CONFIG_FB_RIVA) += rivafb.o riva_hw.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o obj-$(CONFIG_FB_HP300) += hpfb.o @@ -99,6 +99,16 @@ else endif endif +ifeq ($(CONFIG_FB_RIVA),y) +SUB_DIRS += riva +obj-y += riva/rivafb.o +MOD_SUB_DIRS += riva +else + ifeq ($(CONFIG_FB_RIVA),m) + MOD_SUB_DIRS += riva + endif +endif + # Generic Low Level Drivers obj-$(CONFIG_FBCON_AFB) += fbcon-afb.o diff --git a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c index 388b0e1d2..ceb289eb8 100644 --- a/drivers/video/aty128fb.c +++ b/drivers/video/aty128fb.c @@ -1,13 +1,8 @@ /* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $ * linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128 * - * Copyright (C) 1999-2000, Anthony Tong <atong@uiuc.edu> - * - * Brad Douglas <brad@neruo.com> - * - x86 support - * - MTRR - * - Probe ROM for PLL - * - modedb + * Copyright (C) 1999-2000, Brad Douglas <brad@neruo.com> + * Copyright (C) 1999, Anthony Tong <atong@uiuc.edu> * * Ani Joshi / Jeff Garzik * - Code cleanup @@ -23,7 +18,7 @@ * - determine MCLK from previous setting -done for x86 * - calculate XCLK, rather than probe BIOS * - hardware cursor support - * - acceleration + * - acceleration (do not use with Rage128 Pro!) * - ioctl()'s */ @@ -56,7 +51,9 @@ #if defined(CONFIG_PPC) #include <asm/prom.h> #include <asm/pci-bridge.h> +#ifdef CONFIG_NVRAM #include <linux/nvram.h> +#endif #include <video/macmodes.h> #endif @@ -76,16 +73,6 @@ #include "aty128.h" -/* compatibility with older kernels */ -#ifndef LINUX_VERSION_CODE -#include <linux/version.h> -#endif - -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(x,y,z) (((x)<<16)+(y)<<8)+(z)) -#endif - - /* Debug flag */ #undef DEBUG @@ -104,7 +91,6 @@ static struct fb_var_screeninfo default_var = { 0, FB_VMODE_NONINTERLACED }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1) #ifndef MODULE /* default modedb mode */ static struct fb_videomode defaultmode __initdata = { @@ -113,7 +99,6 @@ static struct fb_videomode defaultmode __initdata = { 0, FB_VMODE_NONINTERLACED }; #endif -#endif /* chip description information */ struct aty128_chip_info { @@ -192,10 +177,15 @@ static unsigned int initdepth __initdata = 8; static const char *mode_option __initdata = NULL; #endif -#if defined(CONFIG_PPC) +#ifdef CONFIG_PPC +#ifdef CONFIG_NVRAM_NOT_DEFINED +static int default_vmode __initdata = VMODE_NVRAM; +static int default_cmode __initdata = CMODE_NVRAM; +#else static int default_vmode __initdata = VMODE_CHOOSE; static int default_cmode __initdata = CMODE_8; #endif +#endif #ifdef CONFIG_MTRR static int mtrr = 1; @@ -313,10 +303,7 @@ static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd, * Interface to the low level console driver */ -void aty128fb_init(void); -#ifdef CONFIG_FB_OF -void aty128fb_of_init(struct device_node *dp); -#endif +int aty128fb_init(void); static int aty128fbcon_switch(int con, struct fb_info *info); static void aty128fbcon_blank(int blank, struct fb_info *info); @@ -334,11 +321,8 @@ static int aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, static int aty128_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info); static void do_install_cmap(int con, struct fb_info *info); -#ifndef CONFIG_FB_OF -static void aty128pci_probe(void); static int aty128_pci_register(struct pci_dev *pdev, const struct aty128_chip_info *aci); -#endif static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list, struct fb_info_aty128 *new_node); #ifndef CONFIG_PPC @@ -1444,10 +1428,16 @@ aty128_encode_fix(struct fb_fix_screeninfo *fix, memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, aty128fb_name); - fix->smem_start = (long)info->frame_buffer_phys; - fix->smem_len = (u32)info->vram_size; +#ifdef CONFIG_PPC /* why? I don't know */ + *fix->smem_start = (long)info->frame_buffer_phys; + *fix->mmio_start = (long)info->regbase_phys; +#else + fix->smem_start = (long)info->frame_buffer_phys; fix->mmio_start = (long)info->regbase_phys; +#endif + + fix->smem_len = (u32)info->vram_size; fix->mmio_len = 0x1fff; fix->type = FB_TYPE_PACKED_PIXELS; @@ -1673,7 +1663,7 @@ aty128_init(struct fb_info_aty128 *info, const char *name) int j, k; u8 chip_rev; const struct aty128_chip_info *aci = &aty128_pci_probe_list[0]; - char *video_card = NULL; + char *video_card = "Rage128"; if (!register_test(info)) { printk(KERN_ERR "aty128fb: Can't write to video registers\n"); @@ -1712,23 +1702,29 @@ aty128_init(struct fb_info_aty128 *info, const char *name) var = default_var; #else memset(&var, 0, sizeof(var)); +#ifdef CONFIG_NVRAM + if (default_vmode == VMODE_NVRAM) { + default_vmode = nvram_read_byte(NV_VMODE); + if (default_vmode <= 0 || default_vmode > VMODE_MAX) + default_vmode = VMODE_CHOOSE; + } +#endif #ifdef CONFIG_PPC if (default_vmode == VMODE_CHOOSE) { var = default_var; #endif /* CONFIG_PPC */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1) if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, &defaultmode, initdepth)) var = default_var; -#endif #ifdef CONFIG_PPC - } else { - if (mac_vmode_to_var(default_vmode, default_cmode, &var)) - var = default_var; +#ifdef CONFIG_NVRAM + if (default_cmode == CMODE_NVRAM) + default_cmode = nvram_read_byte(NV_CMODE); +#endif } -#endif /* CONFIG_PPC */ +#endif #endif /* MODULE */ if (noaccel) @@ -1737,7 +1733,7 @@ aty128_init(struct fb_info_aty128 *info, const char *name) var.accel_flags |= FB_ACCELF_TEXT; if (aty128_decode_var(&var, &info->default_par, info)) { - printk(KERN_ERR "Cannot set default mode.\n"); + printk(KERN_ERR "aty128fb: Cannot set default mode.\n"); return 0; } @@ -1790,21 +1786,10 @@ fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list, } -void __init +int __init aty128fb_init(void) { -#if defined(CONFIG_FB_OF) - /* let offb handle init */ -#elif defined (CONFIG_PCI) - aty128pci_probe(); -#endif -} - - -#ifndef CONFIG_FB_OF -void __init -aty128pci_probe(void) -{ +#ifdef CONFIG_PCI struct pci_dev *pdev = NULL; const struct aty128_chip_info *aci = &aty128_pci_probe_list[0]; @@ -1812,16 +1797,18 @@ aty128pci_probe(void) pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev); while (pdev != NULL) { if (aty128_pci_register(pdev, aci) == 0) - return; + return 0; pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev); } aci++; } +#endif - return; + return 0; } +#ifdef CONFIG_PCI /* register a card ++ajoshi */ static int __init aty128_pci_register(struct pci_dev *pdev, @@ -1831,31 +1818,27 @@ aty128_pci_register(struct pci_dev *pdev, unsigned long fb_addr, reg_addr = 0; u16 tmp; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1) struct resource *rp; rp = &pdev->resource[0]; fb_addr = rp->start; fb_addr &= PCI_BASE_ADDRESS_MEM_MASK; - request_mem_region(rp->start, rp->end - rp->start + 1, "aty128fb"); - - rp = &pdev->resource[2]; - reg_addr = rp->start; - reg_addr &= PCI_BASE_ADDRESS_MEM_MASK; - - if (!reg_addr) { + if (!request_mem_region(rp->start, rp->end - rp->start + 1, + "aty128fb FB")) { release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); return -1; } -#else - fb_addr = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK; - reg_addr = pdev->base_address[2] & PCI_BASE_ADDRESS_MEM_MASK; - if (!reg_addr) - return -1; -#endif + + rp = &pdev->resource[2]; + reg_addr = rp->start; + reg_addr &= PCI_BASE_ADDRESS_MEM_MASK; + + if (!request_mem_region(rp->start, rp->end - rp->start + 1, + "aty128fb MMIO")) + goto unmap_out; info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC); if(!info) { @@ -1917,18 +1900,16 @@ aty128_pci_register(struct pci_dev *pdev, err_out: kfree(info); unmap_out: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1) release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); release_mem_region(pdev->resource[2].start, pdev->resource[2].end - pdev->resource[2].start + 1); -#endif return -1; } -#endif /* ! CONFIG_FB_OF */ +#endif /* CONFIG_PCI */ #ifndef CONFIG_PPC @@ -2062,76 +2043,6 @@ aty128_get_pllinfo(struct fb_info_aty128 *info) #endif /* ! CONFIG_PPC */ -#ifdef CONFIG_FB_OF -void __init -aty128fb_of_init(struct device_node *dp) -{ - unsigned long addr, reg_addr, fb_addr; - struct fb_info_aty128 *info; - u8 bus, devfn; - u16 cmd; - - switch (dp->n_addrs) { - case 3: - fb_addr = dp->addrs[0].address; - reg_addr = dp->addrs[2].address; - break; - default: - printk(KERN_ERR "aty128fb: TODO unexpected addresses\n"); - return; - } - - addr = (unsigned long) ioremap(reg_addr, 0x1FFF); - if (!addr) { - printk(KERN_ERR "aty128fb: can't map memory registers\n"); - return; - } - - info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC); - if (!info) { - printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n"); - return; - } - memset((void *) info, 0, sizeof(struct fb_info_aty128)); - - info->regbase_phys = reg_addr; - info->regbase = (void *) addr; - - /* enabled memory-space accesses using config-space command register */ - if (pci_device_loc(dp, &bus, &devfn) == 0) { - pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd); - if (!(cmd & PCI_COMMAND_MEMORY)) { - cmd |= PCI_COMMAND_MEMORY; - pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd); - } - } - - info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; - info->frame_buffer_phys = fb_addr; - info->frame_buffer = (void *) ioremap(fb_addr, info->vram_size); - - if (!info->frame_buffer) { - printk(KERN_ERR "aty128fb: can't map frame buffer\n"); - kfree(info); - return; - } - - /* fall back to defaults */ - aty128_timings(info); - - if (!aty128_init(info, dp->full_name)) { - kfree(info); - return; - } - -#ifdef CONFIG_FB_COMPAT_XPMAC - if (!console_fb_info) - console_fb_info = &info->fb_info; -#endif -} -#endif /* CONFIG_FB_OF */ - - /* fill in known card constants if pll_block is not available */ static void __init aty128_timings(struct fb_info_aty128 *info) @@ -2572,7 +2483,7 @@ MODULE_DESCRIPTION("FBDev driver for ATI Rage128 cards"); int __init init_module(void) { - aty128pci_probe(); + aty128fb_init(); return 0; } @@ -2594,14 +2505,12 @@ cleanup_module(void) iounmap(info->regbase); iounmap(&info->frame_buffer); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1) release_mem_region(info->pdev->resource[0].start, info->pdev->resource[0].end - info->pdev->resource[0].start + 1); release_mem_region(info->pdev->resource[2].start, info->pdev->resource[2].end - info->pdev->resource[2].start + 1); -#endif kfree(info); } diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c index 98a517f9f..9f05d7f03 100644 --- a/drivers/video/clgenfb.c +++ b/drivers/video/clgenfb.c @@ -31,7 +31,7 @@ * */ -#define CLGEN_VERSION "1.9.4.4" +#define CLGEN_VERSION "1.9.4.5" #include <linux/config.h> #include <linux/module.h> @@ -46,7 +46,6 @@ #include <linux/init.h> #include <linux/selection.h> #include <asm/pgtable.h> -#include <asm/delay.h> #include <asm/io.h> #ifdef CONFIG_ZORRO #include <linux/zorro.h> diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 32f584b54..0a227193b 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1,6 +1,8 @@ /* * linux/drivers/video/cyber2000fb.c * + * Copyright (C) 1998-2000 Russell King + * * Integraphics Cyber2000 frame buffer device * * Based on cyberfb.c diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 717cc94f0..740e23860 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -247,15 +247,20 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *private) { struct fb_info **fi; + int clen; - len = 0; + clen = 0; for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000; fi++) if (*fi) - len += sprintf(buf + len, "%d %s\n", - GET_FB_IDX((*fi)->node), - (*fi)->modename); + clen += sprintf(buf + clen, "%d %s\n", + GET_FB_IDX((*fi)->node), + (*fi)->modename); *start = buf + offset; - return len > offset ? len - offset : 0; + if (clen > offset) + clen -= offset; + else + clen = 0; + return clen < len ? clen : len; } static ssize_t diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index a8af1c68c..ad1262c25 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -1954,6 +1954,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm struct matrox_fb_info* minfo; struct display* d; int err; + u_int32_t cmd; #ifndef CONFIG_FB_MATROX_MULTIHEAD static int registered = 0; #endif @@ -1976,6 +1977,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm dev--; return -1; } + pci_read_config_dword(pdev, PCI_COMMAND, &cmd); if (pci_enable_device(pdev)) { return -1; } @@ -2008,9 +2010,19 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm memcpy(ACCESS_FBINFO(fbcon.fontname), fontname, sizeof(ACCESS_FBINFO(fbcon.fontname))); /* DEVFLAGS */ ACCESS_FBINFO(devflags.inverse) = inverse; - ACCESS_FBINFO(devflags.novga) = novga; - ACCESS_FBINFO(devflags.nobios) = nobios; - ACCESS_FBINFO(devflags.noinit) = noinit; + if (cmd & PCI_COMMAND_MEMORY) { + ACCESS_FBINFO(devflags.novga) = novga; + ACCESS_FBINFO(devflags.nobios) = nobios; + ACCESS_FBINFO(devflags.noinit) = noinit; + /* subsequent heads always needs initialization and must not enable BIOS */ + novga = 1; + nobios = 1; + noinit = 0; + } else { + ACCESS_FBINFO(devflags.novga) = 1; + ACCESS_FBINFO(devflags.nobios) = 1; + ACCESS_FBINFO(devflags.noinit) = 0; + } ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry; ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24; ACCESS_FBINFO(devflags.precise_width) = option_precise_width; @@ -2033,13 +2045,11 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm ACCESS_FBINFO(output.ph) = MATROXFB_OUTPUT_CONN_PRIMARY; ACCESS_FBINFO(output.sh) = 0; - /* subsequent heads always needs initialization and must not enable BIOS */ - noinit = 0; - nobios = 1; - novga = 1; - err = initMatrox2(PMINFO d, b); if (!err) { +#ifndef CONFIG_FB_MATROX_MULTIHEAD + registered = 1; +#endif matroxfb_register_device(MINFO); return 0; } diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 63ae5c2a1..1a346c5aa 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -550,7 +550,7 @@ int __init vesafb_init(void) video_vbase = ioremap(video_base, video_size); - printk(KERN_INFO "vesafb: framebuffer at 0x%lu, mapped to 0x%p, size %dk\n", + printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", video_base, video_vbase, video_size/1024); printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", video_width, video_height, video_bpp, video_linelength, screen_info.pages); |