From: Linus Torvalds Date: Fri, 23 Nov 2007 20:18:34 +0000 (-0500) Subject: Import 2.2.6pre2 X-Git-Tag: 2.2.6pre2 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=97b454c28e8a198aaa78dec13bf802575c9135ea;p=history.git Import 2.2.6pre2 --- diff --git a/Documentation/Changes b/Documentation/Changes index d2df634401bb..617ef4976511 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -258,6 +258,11 @@ available from http://juanjox.linuxhq.com/ . The ISDN code in the stock 2.2 kernel may not work for you. If it doesn't, look in ftp://ftp.suse.com/pub/isdn4linux for updated versions. + In 2.0.x the kernel could be configured to drop source routed IP +packets via a compile time configuration option. In 2.2.x, this has +been replaced by a sysctl. See Documentation/networking/ip-sysctl.txt +for more information. + Memory ====== @@ -282,6 +287,20 @@ Util-linux (including mount) larger swap spaces, you need the new mkswap found in util-linux. You also need to upgrade util-linux to get the latest version of mount. + Partitions on 2048 byte sectored media (certain magneto opticals +most prominently) were broken throughout the whole of 2.1 kernel +series, meaning that you will be unable to use 2.1-partitioned media on +Linux 2.2. This is not a 2.2 bug - 2.2 finally does the right thing! +[If you have to interchange media between Linux 2.1 and 2.2, your best +bet is to not use partitions at all but create the filesystem on the +raw device (e.g. /dev/sda) instead. This is also known as the +superfloppy format.] + + To properly create partitions on 2048 byte sectored media with Linux +2.2, be sure to use no less than fdisk version 2.9i and invoke fdisk +using '-b 2048' as an option. + + RPM === diff --git a/Documentation/sound/PCM1-pro b/Documentation/sound/PCM1-pro new file mode 100644 index 000000000000..f4bff17c1be9 --- /dev/null +++ b/Documentation/sound/PCM1-pro @@ -0,0 +1,17 @@ +In Documentation/sound/README.OSS was a remark saying noone was sure the +mixer on the PCM1-pro worked with the ACI driver. Well, it does. +I've been using the drivers for the MAD16 and the driver for the mixer +since kernel 2.0.32 with a MiroSound PCM1-pro and it works great. + +I've got it working with the following configuration: + +MAD16 audio I/O base = 530 +MAD16 audio IRQ = 7 +MAD16 Audio DMA = 1 +MAD16 MIDI I/O = 330 +MAD16 MIDI IRQ = 9 + +And I've enabled the ACI mixer (miro PCM12) . + + +Bas van der Linden. diff --git a/Documentation/sound/mwave b/Documentation/sound/mwave index b0f847cd6387..858334bb46b0 100644 --- a/Documentation/sound/mwave +++ b/Documentation/sound/mwave @@ -1,14 +1,8 @@ How to try to survive an IBM Mwave under Linux SB drivers -* IBM refuses to provide documentation. If anyone can ever find out what - MWD50430.EXE actually does to load firmware then this comedy could go - away. - -* If you'd like to ask IBM why they don't release Mwave information. - phone IBM (425-556-8822) and ask them why they still haven't - released any documentation. - [http://204.200.238.31/cgi-bin/link.pl?co=i&cl=/ts/ibm/contact.html] ++ IBM have now released documentation of sorts and Torsten is busy + trying to make the Mwave work. This is not however a trivial task. ---------------------------------------------------------------------------- diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 6d48ecb98479..79f3a9547fd1 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -220,6 +220,10 @@ endif ifeq ($(CONFIG_BLK_DEV_PS2),y) L_OBJS += ps2esdi.o +else + ifeq ($(CONFIG_BLK_DEV_PS2),m) + M_OBJS += ps2esdi.o + endif endif ifeq ($(CONFIG_BLK_DEV_XD),y) diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 88ebc23b40ae..3169a9bfda72 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -776,11 +776,14 @@ static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec #endif /* CONFIG_SUN_PARTITION */ #ifdef CONFIG_SGI_PARTITION +#include static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) { int i, csum; unsigned int *ui; + unsigned int start, blocks, cs; + int magic; struct buffer_head *bh; struct sgi_disklabel { int magic_mushroom; /* Big fat spliff... */ @@ -810,15 +813,18 @@ static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec } label = (struct sgi_disklabel *) bh->b_data; p = &label->partitions[0]; - if(label->magic_mushroom != SGI_LABEL_MAGIC) { + magic = label->magic_mushroom; + if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { printk("Dev %s SGI disklabel: bad magic %08x\n", - kdevname(dev), label->magic_mushroom); + kdevname(dev), magic); brelse(bh); return 0; } ui = ((unsigned int *) (label + 1)) - 1; - for(csum = 0; ui >= ((unsigned int *) label);) - csum += *ui--; + for(csum = 0; ui >= ((unsigned int *) label);) { + cs = *ui--; + csum += be32_to_cpu(cs); + } if(csum) { printk("Dev %s SGI disklabel: csum bad, label corrupted\n", kdevname(dev)); @@ -831,9 +837,11 @@ static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec * current_minor. */ for(i = 0; i < 16; i++, p++) { - if(!(p->num_blocks)) + blocks = be32_to_cpu(p->num_blocks); + start = be32_to_cpu(p->first_block); + if(!blocks) continue; - add_partition(hd, current_minor, p->first_block, p->num_blocks); + add_partition(hd, current_minor, start, blocks); current_minor++; } printk("\n"); diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c index 96203af85e51..7e07eda65966 100644 --- a/drivers/block/ide-cd.c +++ b/drivers/block/ide-cd.c @@ -3005,9 +3005,6 @@ int ide_cdrom_setup (ide_drive_t *drive) CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432")) CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; - else if (!strcmp (drive->id->model, "GCD-R580B")) - CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; - /* 124/SECTORS_PER_FRAME; ? */ } #if ! STANDARD_ATAPI diff --git a/drivers/cdrom/Config.in b/drivers/cdrom/Config.in index bc69156a4bc4..3ecee30b2c5e 100644 --- a/drivers/cdrom/Config.in +++ b/drivers/cdrom/Config.in @@ -14,6 +14,10 @@ if [ "$CONFIG_SBPCD" = "y" ]; then fi fi tristate 'Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD +if [ "$CONFIG_MCD" != "n" ]; then + int 'MCD IRQ' CONFIG_MCD_IRQ 11 + hex 'MCD I/O base' CONFIG_MCD_BASE 300 +fi tristate 'Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX tristate 'Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206 diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c index b69f9e834f7a..f4292af14123 100644 --- a/drivers/cdrom/mcd.c +++ b/drivers/cdrom/mcd.c @@ -67,6 +67,7 @@ a CD. November 1997 -- ported to the Uniform CD-ROM driver by Erik Andersen. + March 1999 -- made io base and irq CONFIG_ options (Tigran Aivazian). */ #include @@ -83,6 +84,7 @@ #include #include #include +#include /* #define REALLY_SLOW_IO */ #include @@ -155,8 +157,8 @@ static int MCMD_DATA_READ= MCMD_PLAY_READ; int mitsumi_bug_93_wait = 0; #endif /* WORK_AROUND_MITSUMI_BUG_93 */ -static short mcd_port = MCD_BASE_ADDR; /* used as "mcd" by "insmod" */ -static int mcd_irq = MCD_INTR_NR; /* must directly follow mcd_port */ +static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */ +static int mcd_irq = CONFIG_MCD_IRQ; /* must directly follow mcd_port */ MODULE_PARM(mcd, "1-2i"); static int McdTimeout, McdTries; diff --git a/drivers/cdrom/mcd.h b/drivers/cdrom/mcd.h index 9997f4390b2b..fffaa92a66a1 100644 --- a/drivers/cdrom/mcd.h +++ b/drivers/cdrom/mcd.h @@ -21,20 +21,6 @@ * */ -/* *** change this to set the I/O port address */ -#define MCD_BASE_ADDR 0x300 - -/* *** change this to set the interrupt number */ -#define MCD_INTR_NR 11 - -/* *** make the following line uncommented, if you're sure, - * *** all configuration is done */ - -/* #define I_WAS_HERE */ - - - - /* Increase this if you get lots of timeouts */ #define MCD_STATUS_DELAY 1000 @@ -121,8 +107,3 @@ struct mcd_Toc { struct msf trackTime; struct msf diskTime; }; - -#ifndef I_WAS_HERE -#warning You have not edited mcd.h -#warning Perhaps irq and i/o settings are wrong. -#endif diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c index 631dbffa6e00..7e69e8e50e21 100644 --- a/drivers/cdrom/sjcd.c +++ b/drivers/cdrom/sjcd.c @@ -45,11 +45,14 @@ * Allow only to set io base address on command line: sjcd= * Changes to Documentation/cdrom/sjcd * Added cleanup after any error in the initialisation. + * 1.7 Added code to set the sector size tables to prevent the bug present in + * the previous version of this driver. Coded added by Anthony Barbachan + * from bugfix tip originally suggested by Alan Cox. * */ #define SJCD_VERSION_MAJOR 1 -#define SJCD_VERSION_MINOR 6 +#define SJCD_VERSION_MINOR 7 #ifdef MODULE #include @@ -1437,6 +1440,9 @@ static struct file_operations sjcd_fops = { NULL /* revalidate */ }; +static int blksize = 2048; +static int secsize = 2048; + /* * Following stuff is intended for initialization of the cdrom. It * first looks for presence of device. If the device is present, it @@ -1461,6 +1467,9 @@ __initfunc(int sjcd_init( void )){ printk("SJCD: sjcd=0x%x: ", sjcd_base); #endif + hardsect_size[MAJOR_NR] = &secsize; + blksize_size[MAJOR_NR] = &blksize; + if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){ printk( "SJCD: Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR ); return( -EIO ); diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index 1f452ac58374..5ce2fa70fb13 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -541,6 +541,8 @@ static struct tvcard tvcards[] = { 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}}, /* Zoltrix TV-Max */ { 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}}, + /* Pixelview PlayTV (bt878) */ + { 3, 4, 0, 2, 0x01e000, { 2, 0, 1, 1}, {0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }}, }; #define TVCARDS (sizeof(tvcards)/sizeof(tvcard)) @@ -2388,7 +2390,7 @@ static void radio_close(struct video_device *dev) btv->user--; btv->radio = 0; - audio(btv, AUDIO_MUTE); + /*audio(btv, AUDIO_MUTE);*/ MOD_DEC_USE_COUNT; } @@ -2927,6 +2929,12 @@ static void idcard(int i) btv->pll.pll_crystal=BT848_IFORM_XT0; } } + + if (btv->type == BTTV_PIXVIEWPLAYTV) { + btv->pll.pll_ifreq=28636363; + btv->pll.pll_crystal=BT848_IFORM_XT0; + } + if(btv->type==BTTV_AVERMEDIA98) { btv->pll.pll_ifreq=28636363; diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h index 07b194b6403f..59776cc20a80 100644 --- a/drivers/char/bttv.h +++ b/drivers/char/bttv.h @@ -208,6 +208,7 @@ struct bttv #define BTTV_AVERMEDIA98 0x0d #define BTTV_VHX 0x0e #define BTTV_ZOLTRIX 0x0f +#define BTTV_PIXVIEWPLAYTV 0x10 #define AUDIO_TUNER 0x00 #define AUDIO_RADIO 0x01 diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 58ce881b30e5..5f0c31ecf4c2 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -114,6 +114,7 @@ static int ISILoad_open(struct inode *inode, struct file *filp) #ifdef ISICOM_DEBUG printk(KERN_DEBUG "ISILoad:Firmware loader Opened!!!\n"); #endif + MOD_INC_USE_COUNT; return 0; } @@ -122,6 +123,7 @@ static int ISILoad_release(struct inode *inode, struct file *filp) #ifdef ISICOM_DEBUG printk(KERN_DEBUG "ISILoad:Firmware loader Close(Release)d\n",); #endif + MOD_DEC_USE_COUNT; return 0; } diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c index c611b5344818..dc14c0e17a07 100644 --- a/drivers/char/softdog.c +++ b/drivers/char/softdog.c @@ -144,11 +144,9 @@ static int softdog_ioctl(struct inode *inode, struct file *file, default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info)); - if (i) - return i; - else - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)); + if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + return -EFAULT; + return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0,(int *)arg); diff --git a/drivers/net/rclanmtl.c b/drivers/net/rclanmtl.c index 971fb49b6d7e..504cd865e006 100644 --- a/drivers/net/rclanmtl.c +++ b/drivers/net/rclanmtl.c @@ -2,7 +2,7 @@ ** ************************************************************************* ** ** -** R C L A N M T L . C $Revision: 5 $ +** R C L A N M T L . C $Revision: 6 $ ** ** ** RedCreek I2O LAN Message Transport Layer program module. @@ -29,6 +29,10 @@ ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** 1998-1999, LAN API was modified and enhanced by Alice Hennessy. +** +** Sometime in 1997, LAN API was written from scratch by Wendell Nichols. ** ************************************************************************* */ @@ -200,7 +204,7 @@ extern int printk(const char * fmt, ...); /* Special TID Assignments */ #define I2O_IOP_TID 0 -#define I2O_HOST_TID 1 +#define I2O_HOST_TID 0xB91 /* RedCreek I2O private message codes */ #define RC_PRIVATE_GET_MAC_ADDR 0x0001/**/ /* OBSOLETE */ diff --git a/drivers/net/rclanmtl.h b/drivers/net/rclanmtl.h index 2521b1ceecf3..2e594440cdf2 100644 --- a/drivers/net/rclanmtl.h +++ b/drivers/net/rclanmtl.h @@ -2,7 +2,7 @@ ** ************************************************************************* ** ** -** R C L A N M T L . H $Revision: 5 $ +** R C L A N M T L . H $Revision: 6 $ ** ** ** RedCreek I2O LAN Message Transport Layer header file. diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c index 2c5a070eef8e..0aa979bc1648 100644 --- a/drivers/net/rcpci45.c +++ b/drivers/net/rcpci45.c @@ -1,4 +1,5 @@ /* +** ** RCpci45.c ** ** @@ -36,16 +37,18 @@ ** ** ** Pete Popov, January 11,99: Fixed a couple of 2.1.x problems -** (virt_to_bus() not called), tested it under 2.2pre5, and added a -** #define to enable the use of the same file for both, the 2.0.x kernels -** as well as the 2.1.x. +** (virt_to_bus() not called), tested it under 2.2pre5 (as a module), and +** added a #define(s) to enable the use of the same file for both, the 2.0.x +** kernels as well as the 2.1.x. ** ** Ported to 2.1.x by Alan Cox 1998/12/9. ** +** Sometime in mid 1998, written by Pete Popov and Brian Moyle. +** ***************************************************************************/ static char *version = -"RedCreek Communications PCI linux driver version 2.00\n"; +"RedCreek Communications PCI linux driver version 2.02\n"; #include @@ -155,11 +158,10 @@ static PDPA PCIAdapters[MAX_ADAPTERS] = }; -static int RCscan(void); -static struct device -*RCfound_device(struct device *, int, int, int, int, int, int); +static int RCinit(struct device *dev); +static int RCscan(struct device *dev); +static int RCfound_device(struct device *, int, int, int, int, int, int); -static int RCprobe1(struct device *); static int RCopen(struct device *); static int RC_xmit_packet(struct sk_buff *, struct device *); static void RCinterrupt(int, void *, struct pt_regs *); @@ -180,134 +182,143 @@ static struct device *root_RCdev = NULL; #ifdef MODULE int init_module(void) #else -int rcpci_probe(struct netdevice *dev) +int rcpci_probe(struct device *dev) #endif { int cards_found; - printk(version); - - root_RCdev = NULL; - cards_found = RCscan(); #ifdef MODULE - return cards_found ? 0 : -ENODEV; + cards_found = RCscan(NULL); #else - return -1; + cards_found = RCscan(dev); #endif + if (cards_found) + printk(version); + return cards_found ? 0 : -ENODEV; } -static int RCscan() +static int RCscan(struct device *dev) { int cards_found = 0; - struct device *dev = 0; + static int pci_index = 0; + + if (!pcibios_present()) + return cards_found; - if (pcibios_present()) + for (;pci_index < 0x8; pci_index++) { - static int pci_index = 0; unsigned char pci_bus, pci_device_fn; int scan_status; int board_index = 0; - - for (;pci_index < 0xff; pci_index++) - { - unsigned char pci_irq_line; - unsigned short pci_command, vendor, device, class; - unsigned int pci_ioaddr; + unsigned char pci_irq_line; + unsigned short pci_command, vendor, device, class; + unsigned int pci_ioaddr; - scan_status = - (pcibios_find_device (RC_PCI45_VENDOR_ID, - RC_PCI45_DEVICE_ID, - pci_index, - &pci_bus, - &pci_device_fn)); + scan_status = + (pcibios_find_device (RC_PCI45_VENDOR_ID, + RC_PCI45_DEVICE_ID, + pci_index, + &pci_bus, + &pci_device_fn)); #ifdef RCDEBUG - printk("rc scan_status = 0x%X\n", scan_status); + printk("rc scan_status = 0x%X\n", scan_status); #endif - if (scan_status != PCIBIOS_SUCCESSFUL) - break; - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_DEVICE_ID, &device); - pcibios_read_config_byte(pci_bus, - pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, - pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_CLASS_DEVICE, &class); - - pci_ioaddr &= ~0xf; + if (scan_status != PCIBIOS_SUCCESSFUL) + break; + pcibios_read_config_word(pci_bus, + pci_device_fn, + PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pci_bus, + pci_device_fn, + PCI_DEVICE_ID, &device); + pcibios_read_config_byte(pci_bus, + pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq_line); + pcibios_read_config_dword(pci_bus, + pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + pcibios_read_config_word(pci_bus, + pci_device_fn, + PCI_CLASS_DEVICE, &class); + + pci_ioaddr &= ~0xf; #ifdef RCDEBUG - printk("rc: Found RedCreek PCI adapter\n"); - printk("rc: pci class = 0x%x 0x%x \n", class, class>>8); - printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn); - printk("rc: pci_irq_line = 0x%x \n", pci_irq_line); - printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr); + printk("rc: Found RedCreek PCI adapter\n"); + printk("rc: pci class = 0x%x 0x%x \n", class, class>>8); + printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn); + printk("rc: pci_irq_line = 0x%x \n", pci_irq_line); + printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr); #endif -#if 1 - if (check_region(pci_ioaddr, 2*32768)) - { - printk("rc: check_region failed\n"); - continue; - } - else - { - printk("rc: check_region passed\n"); - } + if (check_region(pci_ioaddr, 2*32768)) + { + printk("rc: check_region failed\n"); + continue; + } +#ifdef RCDEBUG + else + { + printk("rc: check_region passed\n"); + } #endif - + + /* + * Get and check the bus-master and latency values. + * Some PCI BIOSes fail to set the master-enable bit. + */ + + pcibios_read_config_word(pci_bus, + pci_device_fn, + PCI_COMMAND, + &pci_command); + if ( ! (pci_command & PCI_COMMAND_MASTER)) { + printk("rc: PCI Master Bit has not been set!\n"); + + pci_command |= PCI_COMMAND_MASTER; + pcibios_write_config_word(pci_bus, + pci_device_fn, + PCI_COMMAND, + pci_command); + } + if ( ! (pci_command & PCI_COMMAND_MEMORY)) { /* - * Get and check the bus-master and latency values. - * Some PCI BIOSes fail to set the master-enable bit. + * If the BIOS did not set the memory enable bit, what else + * did it not initialize? Skip this adapter. */ - - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_COMMAND, - &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk("rc: PCI Master Bit has not been set!\n"); - - pci_command |= PCI_COMMAND_MASTER; - pcibios_write_config_word(pci_bus, - pci_device_fn, - PCI_COMMAND, - pci_command); - } - if ( ! (pci_command & PCI_COMMAND_MEMORY)) { - /* - * If the BIOS did not set the memory enable bit, what else - * did it not initialize? Skip this adapter. - */ - printk("rc: Adapter %d, PCI Memory Bit has not been set!\n", - cards_found); - printk("rc: Bios problem? \n"); - continue; - } - - dev = RCfound_device(dev, pci_ioaddr, pci_irq_line, - pci_bus, pci_device_fn, - board_index++, cards_found); - - if (dev) { - dev = 0; - cards_found++; - } + printk("rc: Adapter %d, PCI Memory Bit has not been set!\n", + cards_found); + printk("rc: Bios problem? \n"); + continue; + } + + if (!RCfound_device(dev, pci_ioaddr, pci_irq_line, + pci_bus, pci_device_fn, + board_index++, cards_found)) + { + dev = 0; + cards_found++; } } +#ifdef RCDEBUG printk("rc: found %d cards \n", cards_found); +#endif return cards_found; } -static struct device * +static int RCinit(struct device *dev) +{ + dev->open = &RCopen; + dev->hard_start_xmit = &RC_xmit_packet; + dev->stop = &RCclose; + dev->get_stats = &RCget_stats; + dev->do_ioctl = &RCioctl; + dev->set_config = &RCconfig; + return 0; +} + +static int RCfound_device(struct device *dev, int memaddr, int irq, int bus, int function, int product_index, int card_idx) { @@ -324,18 +335,37 @@ RCfound_device(struct device *dev, int memaddr, int irq, * assigned to DPA; and finally, the rest will be assigned to the * the LAN API layer. */ + +#ifdef MODULE dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + if (!dev) + { + printk("rc: unable to kmalloc dev\n"); + return 1; + } memset(dev, 0, dev_size); -#ifdef RCDEBUG - printk("rc: dev = 0x%08X\n", (uint)dev); -#endif - /* * dev->priv will point to the start of DPA. */ dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15); +#else + dev->priv = 0; + dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + if (!dev->priv) + { + printk("rc: unable to kmalloc private area\n"); + return 1; + } + memset(dev->priv, 0, dev_size); +#endif + +#ifdef RCDEBUG + printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv); +#endif + pDpa = dev->priv; - dev->name = pDpa->devname; + if (!dev->name) + dev->name = pDpa->devname; pDpa->dev = dev; /* this is just for easy reference */ pDpa->function = function; @@ -378,24 +408,21 @@ RCfound_device(struct device *dev, int memaddr, int irq, printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq ); iounmap(vaddr); kfree(dev); - return 0; + return 1; } init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, - pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA), - (PFNTXCALLBACK)RCxmit_callback, - (PFNRXCALLBACK)RCrecv_callback, - (PFNCALLBACK)RCreboot_callback); -#ifdef RCDEBUG - printk("rc: I2O msg initted: status = 0x%x\n", init_status); -#endif + pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA), + (PFNTXCALLBACK)RCxmit_callback, + (PFNRXCALLBACK)RCrecv_callback, + (PFNCALLBACK)RCreboot_callback); if (init_status) { printk("rc: Unable to initialize msg layer\n"); free_irq(dev->irq, dev); iounmap(vaddr); kfree(dev); - return 0; + return 1; } if (RCGetMAC(pDpa->id, dev->dev_addr, NULL)) { @@ -403,38 +430,34 @@ RCfound_device(struct device *dev, int memaddr, int irq, free_irq(dev->irq, dev); iounmap(vaddr); kfree(dev); - return 0; + return 1; } DriverControlWord |= WARM_REBOOT_CAPABLE; RCReportDriverCapability(pDpa->id, DriverControlWord); - dev->init = RCprobe1; + dev->init = &RCinit; ether_setup(dev); /* linux kernel interface */ pDpa->next = root_RCdev; root_RCdev = dev; +#ifdef MODULE if (register_netdev(dev) != 0) /* linux kernel interface */ { printk("rc: unable to register device \n"); free_irq(dev->irq, dev); iounmap(vaddr); kfree(dev); - return 0; + return 1; } - return dev; -} +#else + RCinit(dev); +#endif + printk("%s: RedCreek Communications IPSEC VPN adapter\n", + dev->name); -static int RCprobe1(struct device *dev) -{ - dev->open = RCopen; - dev->hard_start_xmit = RC_xmit_packet; - dev->stop = RCclose; - dev->get_stats = RCget_stats; - dev->do_ioctl = RCioctl; - dev->set_config = RCconfig; - return 0; + return 0; /* success */ } static int @@ -516,6 +539,7 @@ RC_xmit_packet(struct sk_buff *skb, struct device *dev) #ifdef RCDEBUG printk("rc: RC_xmit_packet: tbusy!\n"); #endif + dev->tbusy = 1; return 1; } @@ -658,7 +682,7 @@ RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID) RCShutdownLANCard(pDpa->id,0,0,0); printk("rc: scheduling timer...\n"); init_timer(&pDpa->timer); - pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */ + pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */ pDpa->timer.data = (unsigned long)dev; pDpa->timer.function = &rc_timer; /* timer handler */ add_timer(&pDpa->timer); @@ -757,9 +781,11 @@ RCrecv_callback(U32 Status, if (!pDpa->shutdown && !pDpa->reboot) printk("rc: RCrecv error: status = 0x%x\n", (uint)Status); +#ifdef RCDEBUG else printk("rc: Returning %d buffers, status = 0x%x\n", PktCount, (uint)Status); +#endif /* * TO DO: check the nature of the failure and put the adapter in * failed mode if it's a hard failure. Send a reset to the adapter @@ -808,6 +834,8 @@ RCrecv_callback(U32 Status, (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2], (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]); #endif + +#ifdef PROMISCUOUS_BY_DEFAULT /* early 2.x firmware */ if ( (memcmp(dev->dev_addr, skb->data, 6)) && (!broadcast_packet(skb->data))) { @@ -838,6 +866,7 @@ RCrecv_callback(U32 Status, } } else +#endif /* PROMISCUOUS_BY_DEFAULT */ { len = PacketDescBlock[2]; skb->dev = dev; @@ -883,10 +912,10 @@ RCinterrupt(int irq, void *dev_id, struct pt_regs *regs) pDpa = (PDPA) (dev->priv); +#ifdef RCDEBUG if (pDpa->shutdown) printk("rc: shutdown: service irq\n"); -#ifdef RCDEBUG printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", (uint)pDpa, (uint)dev, (uint)pDpa->id); printk("dev = 0x%x\n", (uint)dev); @@ -901,7 +930,8 @@ RCinterrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -#define REBOOT_REINIT_RETRY_LIMIT 10 + +#define REBOOT_REINIT_RETRY_LIMIT 4 static void rc_timer(unsigned long data) { struct device *dev = (struct device *)data; @@ -914,12 +944,12 @@ static void rc_timer(unsigned long data) if (pDpa->reboot) { - init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, - pDpa->PLanApiPA, pDpa->PLanApiPA, - (PFNTXCALLBACK)RCxmit_callback, - (PFNRXCALLBACK)RCrecv_callback, - (PFNCALLBACK)RCreboot_callback); + pDpa->PLanApiPA, + (PU8)virt_to_bus((void *)pDpa->PLanApiPA), + (PFNTXCALLBACK)RCxmit_callback, + (PFNRXCALLBACK)RCrecv_callback, + (PFNCALLBACK)RCreboot_callback); switch(init_status) { @@ -949,14 +979,16 @@ static void rc_timer(unsigned long data) (uint)pDpa->numOutRcvBuffers); } printk("rc: Initialization done.\n"); + dev->tbusy=0; + retry=0; return; case RC_RTN_FREE_Q_EMPTY: retry++; - printk("rc: inbound free q emtpy\n"); + printk("rc: inbound free q empty\n"); break; default: retry++; - printk("rc: unexpected bad status after reboot\n"); + printk("rc: bad status after reboot: %d\n", init_status); break; } @@ -972,7 +1004,7 @@ static void rc_timer(unsigned long data) { printk("rc: rescheduling timer...\n"); init_timer(&pDpa->timer); - pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */ + pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */ pDpa->timer.data = (unsigned long)dev; pDpa->timer.function = &rc_timer; /* timer handler */ add_timer(&pDpa->timer); @@ -1286,6 +1318,8 @@ static int RCconfig(struct device *dev, struct ifmap *map) return 0; } + +#ifdef MODULE void cleanup_module(void) { @@ -1315,6 +1349,8 @@ cleanup_module(void) root_RCdev = next; } } +#endif + static int RC_allocate_and_post_buffers(struct device *dev, int numBuffers) diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 8094f8b801a0..f476b62596e6 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -1877,6 +1877,7 @@ TLan_ResetAdapter( struct device *dev ) u8 data8; priv->tlanFullDuplex = FALSE; + priv->phyOnline=0; /* 1. Assert reset bit. */ data = inl(dev->base_addr + TLAN_HOST_CMD); diff --git a/drivers/net/z85230.c b/drivers/net/z85230.c index aea2aef27edc..b70ba6aa0a50 100644 --- a/drivers/net/z85230.c +++ b/drivers/net/z85230.c @@ -1176,11 +1176,10 @@ static void z8530_tx_done(struct z8530_channel *c) spin_lock_irqsave(&z8530_buffer_lock, flags); c->netdevice->tbusy=0; - /* Can't happen */ + /* Actually this can happen.*/ if(c->tx_skb==NULL) { spin_unlock_irqrestore(&z8530_buffer_lock, flags); - printk(KERN_WARNING "%s: spurious tx done\n", c->dev->name); return; } skb=c->tx_skb; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 70d233f37906..82d55ada87d8 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -343,6 +343,7 @@ #include #include #include +#include #include "aha152x.h" #include @@ -489,6 +490,7 @@ struct aha152x_hostdata { int ext_trans; int swint; + int service; unsigned char syncrate[8]; @@ -500,7 +502,7 @@ struct aha152x_hostdata { #endif }; -void aha152x_intr(int irq, void *dev_id, struct pt_regs *); +static void aha152x_intr(int irq, void *dev_id, struct pt_regs *); void aha152x_done(struct Scsi_Host *shpnt, int error); void aha152x_setup(char *str, int *ints); int aha152x_checksetup(struct aha152x_setup *setup); @@ -1550,38 +1552,72 @@ void aha152x_done(struct Scsi_Host *shpnt, int error) aha152x_panic(shpnt, "done() called outside of command"); } + +static void aha152x_complete(struct Scsi_Host *); + +static struct tq_struct aha152x_tq; + /* - * Interrupts handler (main routine of the driver) + * Run service completions on the card with interrupts enabled. */ -void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs) + +static void aha152x_run(void) { - struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN]; - unsigned int flags; - int done=0, phase; + int i; + for(i=0;iservice) + { + HOSTDATA(shpnt)->service=0; + aha152x_complete(shpnt); + } + } +} + +/* + * Interrupts handler (main routine of the driver) + */ + +static void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs) +{ + struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN]; #if defined(DEBUG_RACE) - enter_driver("intr"); + enter_driver("intr"); #else #if defined(DEBUG_INTR) - if(HOSTDATA(shpnt)->debug & debug_intr) - printk("\naha152x: intr(), "); + if(HOSTDATA(shpnt)->debug & debug_intr) + printk("\naha152x: intr(), "); #endif #endif - if(!shpnt) - panic("aha152x: catched interrupt for unknown controller.\n"); - - /* no more interrupts from the controller, while we're busy. - INTEN has to be restored, when we're ready to leave - intr(). To avoid race conditions, we have to return - immediately afterwards. */ - CLRBITS(DMACNTRL0, INTEN); - /* sti(); FIXME!!! Yes, sti() really needs to be here if we want to lock up */ - - /* disconnected target is trying to reconnect. - Only possible, if we have disconnected nexuses and - nothing is occupying the bus. - */ + if(!shpnt) + panic("aha152x: catched interrupt for unknown controller.\n"); + + /* no more interrupts from the controller, while we're busy. + INTEN is restored by the BH handler */ + + CLRBITS(DMACNTRL0, INTEN); + + /* Poke the BH handler */ + + HOSTDATA(shpnt)->service=1; + aha152x_tq.routine = (void *)aha152x_run; + queue_task(&aha152x_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void aha152x_complete(struct Scsi_Host *shpnt) +{ + unsigned int flags; + int done=0, phase; + + /* disconnected target is trying to reconnect. + Only possible, if we have disconnected nexuses and + nothing is occupying the bus. + */ + if(TESTHI(SSTAT0, SELDI) && DISCONNECTED_SC && (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) { diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index bd909ef8992e..12b105d4f9a4 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -1457,6 +1457,8 @@ Scsi_Cmnd *tmp, *prev; if (tmp == cmd) { if (prev) prev->host_scribble = cmd->host_scribble; + else + hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble; cmd->host_scribble = NULL; cmd->result = DID_ABORT << 16; printk("scsi%d: Abort - removing command %ld from input_Q. ", diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c index c80c9517c269..baa0907711a0 100644 --- a/drivers/sound/ad1848.c +++ b/drivers/sound/ad1848.c @@ -137,6 +137,21 @@ static ad1848_info adev_info[MAX_AUDIO_DEV]; #define io_Status(d) ((d)->base+2) #define io_Polled_IO(d) ((d)->base+3) +static struct { + unsigned char flags; +#define CAP_F_TIMER 0x01 +} capabilities [9 /*devc->model */ ] = { + {0} + ,{0} /* MD_1848 */ + ,{CAP_F_TIMER} /* MD_4231 */ + ,{CAP_F_TIMER} /* MD_4231A */ + ,{CAP_F_TIMER} /* MD_1845 */ + ,{CAP_F_TIMER} /* MD_4232 */ + ,{0} /* MD_C930 */ + ,{CAP_F_TIMER} /* MD_IWAVE */ + ,{0} /* MD_4235 */ +}; + static int ad1848_open(int dev, int mode); static void ad1848_close(int dev); static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag); @@ -1894,7 +1909,7 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt /* Don't free it either then.. */ devc->irq = 0; } - if (devc->model != MD_1848 && devc->model != MD_C930) + if (capabilities[devc->model].flags & CAP_F_TIMER) { #ifndef __SMP__ int x; @@ -1927,8 +1942,8 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt irq2dev[-irq] = devc->dev_no = my_dev; #if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS) - if (devc->model != MD_1848 && - devc->model != MD_C930 && devc->irq_ok) + if ((capabilities[devc->model].flags & CAP_F_TIMER) && + devc->irq_ok) ad1848_tmr_install(my_dev); #endif diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c index 605a03ba5088..ac2b6d40a20b 100644 --- a/drivers/sound/audio.c +++ b/drivers/sound/audio.c @@ -60,7 +60,10 @@ static int set_format(int dev, int fmt) else return audio_devs[dev]->local_format; - return audio_devs[dev]->local_format; + if (audio_devs[dev]->local_conversion) + return audio_devs[dev]->local_conversion; + else + return audio_devs[dev]->local_format; } int audio_open(int dev, struct file *file) @@ -387,7 +390,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg) return 0; case SNDCTL_DSP_GETFMTS: - val = audio_devs[dev]->format_mask; + val = audio_devs[dev]->format_mask | AFMT_MU_LAW; break; case SNDCTL_DSP_SETFMT: diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c index 9a6b4c72f59a..dd12a0c68d06 100644 --- a/drivers/sound/dev_table.c +++ b/drivers/sound/dev_table.c @@ -437,6 +437,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, memset((char *) op, 0, sizeof(struct audio_operations)); init_waitqueue(&op->in_sleeper); init_waitqueue(&op->out_sleeper); + init_waitqueue(&op->poll_sleeper); if (driver_size < sizeof(struct audio_driver)) memset((char *) d, 0, sizeof(struct audio_driver)); diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h index 019b915c5d04..cf6475662ea5 100644 --- a/drivers/sound/dev_table.h +++ b/drivers/sound/dev_table.h @@ -236,6 +236,7 @@ struct audio_operations /* fields formerly in dmabuf.c */ struct wait_queue *in_sleeper; struct wait_queue *out_sleeper; + struct wait_queue *poll_sleeper; /* fields formerly in audio.c */ int audio_mode; diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c index ccde8519ae0d..85bde7d48fc3 100644 --- a/drivers/sound/dmabuf.c +++ b/drivers/sound/dmabuf.c @@ -935,6 +935,7 @@ static void finish_output_interrupt(int dev, struct dma_buffparms *dmap) if (dmap->audio_callback != NULL) dmap->audio_callback(dev, dmap->callback_parm); wake_up(&adev->out_sleeper); + wake_up(&adev->poll_sleeper); } static void do_outputintr(int dev, int dummy) @@ -1103,7 +1104,10 @@ static void do_inputintr(int dev) } dmap->flags |= DMA_ACTIVE; if (dmap->qlen > 0) + { wake_up(&adev->in_sleeper); + wake_up(&adev->poll_sleeper); + } } void DMAbuf_inputintr(int dev) @@ -1217,7 +1221,6 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait) if (!(adev->open_mode & OPEN_READ)) return 0; if (dmap->mapping_flags & DMA_MAP_MAPPED) { - poll_wait(file, &adev->in_sleeper, wait); if (dmap->qlen) return POLLIN | POLLRDNORM; return 0; @@ -1228,7 +1231,6 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait) !dmap->qlen && adev->go) { unsigned long flags; - poll_wait(file, &adev->in_sleeper, wait); save_flags(flags); cli(); DMAbuf_activate_recording(dev, dmap); @@ -1236,7 +1238,6 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait) } return 0; } - poll_wait(file, &adev->in_sleeper, wait); if (!dmap->qlen) return 0; return POLLIN | POLLRDNORM; @@ -1250,14 +1251,12 @@ static unsigned int poll_output(struct file * file, int dev, poll_table *wait) if (!(adev->open_mode & OPEN_WRITE)) return 0; if (dmap->mapping_flags & DMA_MAP_MAPPED) { - poll_wait(file, &adev->out_sleeper, wait); if (dmap->qlen) return POLLOUT | POLLWRNORM; return 0; } if (dmap->dma_mode == DMODE_INPUT) return 0; - poll_wait(file, &adev->out_sleeper, wait); if (dmap->dma_mode == DMODE_NONE) return POLLOUT | POLLWRNORM; if (!DMAbuf_space_in_queue(dev)) @@ -1267,6 +1266,8 @@ static unsigned int poll_output(struct file * file, int dev, poll_table *wait) unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait) { + struct audio_operations *adev = audio_devs[dev]; + poll_wait(file, &adev->poll_sleeper, wait); return poll_input(file, dev, wait) | poll_output(file, dev, wait); } diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c index 9226318ef9eb..1ce70dc7b28f 100644 --- a/drivers/sound/es1370.c +++ b/drivers/sound/es1370.c @@ -3,7 +3,7 @@ /* * es1370.c -- Ensoniq ES1370/Asahi Kasei AK4531 audio driver. * - * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -87,6 +87,11 @@ * reported by Johan Maes * 22.03.99 0.19 return EAGAIN instead of EBUSY when O_NONBLOCK * read/write cannot be executed + * 07.04.99 0.20 implemented the following ioctl's: SOUND_PCM_READ_RATE, + * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; + * Alpha fixes reported by Peter Jones + * Note: joystick address handling might still be wrong on archs + * other than i386 * * some important things missing in Ensoniq documentation: * @@ -287,7 +292,8 @@ struct es1370_state { int dev_midi; /* hardware resources */ - unsigned int io, irq; + unsigned long io; /* long for SPARC */ + unsigned int irq; /* mixer registers; there is no HW readback */ struct { @@ -1526,11 +1532,19 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd s->dma_dac2.subdivision = val; return 0; - case SOUND_PCM_WRITE_FILTER: - case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_RATE: + return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg); + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? + 2 : 1, (int *)arg); + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? + 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_FILTER: return -EINVAL; @@ -1903,11 +1917,17 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int s->dma_dac1.subdivision = val; return 0; - case SOUND_PCM_WRITE_FILTER: - case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_RATE: + return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg); + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg); + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_FILTER: return -EINVAL; @@ -2275,7 +2295,7 @@ __initfunc(int init_es1370(void)) if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1370: version v0.19 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1370: version v0.20 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) { if (pcidev->base_address[0] == 0 || @@ -2299,7 +2319,7 @@ __initfunc(int init_es1370(void)) s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; s->irq = pcidev->irq; if (check_region(s->io, ES1370_EXTENT)) { - printk(KERN_ERR "es1370: io ports %#x-%#x in use\n", s->io, s->io+ES1370_EXTENT-1); + printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1); goto err_region; } request_region(s->io, ES1370_EXTENT, "es1370"); @@ -2320,7 +2340,7 @@ __initfunc(int init_es1370(void)) if (micz[index]) s->ctrl |= CTRL_XCTL1; s->sctrl = 0; - printk(KERN_INFO "es1370: found adapter at io %#06x irq %u\n" + printk(KERN_INFO "es1370: found adapter at io %#lx irq %u\n" KERN_INFO "es1370: features: joystick %s, line %s, mic impedance %s\n", s->io, s->irq, (s->ctrl & CTRL_JYSTK_EN) ? "on" : "off", (s->ctrl & CTRL_XCTL0) ? "out" : "in", diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c index 6c9bd5ecc44d..fa2efd25f714 100644 --- a/drivers/sound/es1371.c +++ b/drivers/sound/es1371.c @@ -58,6 +58,13 @@ * reported by Johan Maes * 22.03.99 0.10 return EAGAIN instead of EBUSY when O_NONBLOCK * read/write cannot be executed + * 07.04.99 0.11 implemented the following ioctl's: SOUND_PCM_READ_RATE, + * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; + * Alpha fixes reported by Peter Jones + * Another Alpha fix (wait_src_ready in init routine) + * reported by "Ivan N. Kokshaysky" + * Note: joystick address handling might still be wrong on archs + * other than i386 * */ @@ -334,7 +341,8 @@ struct es1371_state { int dev_midi; /* hardware resources */ - unsigned int io, irq; + unsigned long io; /* long for SPARC */ + unsigned int irq; /* mixer registers; there is no HW readback */ struct { @@ -1968,11 +1976,17 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd s->dma_dac2.subdivision = val; return 0; - case SOUND_PCM_WRITE_FILTER: - case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg); + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg); + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_FILTER: return -EINVAL; @@ -2338,11 +2352,17 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int s->dma_dac1.subdivision = val; return 0; - case SOUND_PCM_WRITE_FILTER: - case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_RATE: + return put_user(s->dac1rate, (int *)arg); + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg); + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_FILTER: return -EINVAL; @@ -2712,7 +2732,7 @@ __initfunc(int init_es1371(void)) if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1371: version v0.10 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1371: version v0.11 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) { if (pcidev->base_address[0] == 0 || @@ -2736,7 +2756,7 @@ __initfunc(int init_es1371(void)) s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; s->irq = pcidev->irq; if (check_region(s->io, ES1371_EXTENT)) { - printk(KERN_ERR "es1371: io ports %#x-%#x in use\n", s->io, s->io+ES1371_EXTENT-1); + printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); goto err_region; } request_region(s->io, ES1371_EXTENT, "es1371"); @@ -2744,7 +2764,7 @@ __initfunc(int init_es1371(void)) printk(KERN_ERR "es1371: irq %u in use\n", s->irq); goto err_irq; } - printk(KERN_INFO "es1371: found adapter at io %#06x irq %u\n" + printk(KERN_INFO "es1371: found adapter at io %#lx irq %u\n" KERN_INFO "es1371: features: joystick 0x%x\n", s->io, s->irq, joystick[index]); /* register devices */ if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0) @@ -2796,6 +2816,7 @@ __initfunc(int init_es1371(void)) * be stuck high, and I've found no way to rectify this other than * power cycle) */ + wait_src_ready(s); outl(0, s->io+ES1371_REG_SRCONV); /* codec init */ wrcodec(s, 0x00, 0); /* reset codec */ diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h index a47d7099fd65..2cb785565d69 100644 --- a/drivers/sound/sb.h +++ b/drivers/sound/sb.h @@ -48,6 +48,7 @@ #define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */ #define MDL_AEDSP 15 /* Audio Excel DSP 16 */ #define MDL_ESSPCI 16 /* ESS PCI card */ +#define MDL_YMPCI 17 /* Yamaha PCI sb in emulation */ #define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */ /* register assignment */ diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c index e2630f0b751c..44b40e736476 100644 --- a/drivers/sound/sb_card.c +++ b/drivers/sound/sb_card.c @@ -222,5 +222,8 @@ EXPORT_SYMBOL(attach_sb_card); EXPORT_SYMBOL(probe_sb); EXPORT_SYMBOL(unload_sb); EXPORT_SYMBOL(sb_be_quiet); +EXPORT_SYMBOL(attach_sbmpu); +EXPORT_SYMBOL(probe_sbmpu); +EXPORT_SYMBOL(unload_sbmpu); #endif diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index ab85fd3fb508..d162e470d5a5 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -261,7 +261,7 @@ static void dsp_get_vers(sb_devc * devc) } } } - DDB(printk("DSP version %d.%d\n", devc->major, devc->minor)); + DDB(printk("DSP version %d.%02d\n", devc->major, devc->minor)); restore_flags(flags); } @@ -532,8 +532,12 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio) if(pci == SB_PCI_YAMAHA) { + devc->model = MDL_YMPCI; devc->caps |= SB_PCI_IRQ; hw_config->driver_use_1 |= SB_PCI_IRQ; + hw_config->card_subtype = MDL_YMPCI; + + printk("Yamaha PCI mode.\n"); } if (acer) @@ -600,6 +604,12 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio) if(devc->type == MDL_ESSPCI) devc->model = MDL_ESSPCI; + if(devc->type == MDL_YMPCI) + { + printk("YMPCI selected\n"); + devc->model = MDL_YMPCI; + } + /* * Save device information for sb_dsp_init() */ @@ -612,7 +622,7 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio) return 0; } memcpy((char *) detected_devc, (char *) devc, sizeof(sb_devc)); - MDB(printk(KERN_INFO "SB %d.%d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base)); + MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base)); return 1; } @@ -648,7 +658,7 @@ int sb_dsp_init(struct address_info *hw_config) devc->caps = hw_config->driver_use_1; - if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && hw_config->irq > 0) + if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0) { /* IRQ setup */ /* @@ -807,7 +817,7 @@ int sb_dsp_init(struct address_info *hw_config) if (hw_config->name == NULL) hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)"; - sprintf(name, "%s (%d.%d)", hw_config->name, devc->major, devc->minor); + sprintf(name, "%s (%d.%02d)", hw_config->name, devc->major, devc->minor); conf_printf(name, hw_config); /* @@ -828,7 +838,7 @@ int sb_dsp_init(struct address_info *hw_config) } else if (!sb_be_quiet && devc->model == MDL_SBPRO) { - printk(KERN_INFO "SB DSP version is just %d.%d which means that your card is\n", devc->major, devc->minor); + printk(KERN_INFO "SB DSP version is just %d.%02d which means that your card is\n", devc->major, devc->minor); printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n"); printk(KERN_INFO "is incorrectly configured.\n"); } @@ -1233,6 +1243,10 @@ int probe_sbmpu(struct address_info *hw_config) return 0; break; + case MDL_YMPCI: + hw_config->name = "Yamaha PCI Legacy"; + printk("Yamaha PCI legacy UART401 check.\n"); + break; default: return 0; } diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c index 4f10108b928f..06af0f434ba5 100644 --- a/drivers/sound/sb_mixer.c +++ b/drivers/sound/sb_mixer.c @@ -674,6 +674,7 @@ int sb_mixer_init(sb_devc * devc) switch (devc->model) { case MDL_ESSPCI: + case MDL_YMPCI: case MDL_SBPRO: case MDL_AZTECH: case MDL_JAZZ: diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c index c2d9774f8a19..c6d30d43f980 100644 --- a/drivers/sound/sonicvibes.c +++ b/drivers/sound/sonicvibes.c @@ -3,7 +3,7 @@ /* * sonicvibes.c -- S3 Sonic Vibes audio driver. * - * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,6 +55,19 @@ * reported by Johan Maes * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK * read/write cannot be executed + * 05.04.99 0.13 added code to sv_read and sv_write which should detect + * lockups of the sound chip and revive it. This is basically + * an ugly hack, but at least applications using this driver + * won't hang forever. I don't know why these lockups happen, + * it might well be the motherboard chipset (an early 486 PCI + * board with ALI chipset), since every busmastering 100MB + * ethernet card I've tried (Realtek 8139 and Macronix tulip clone) + * exhibit similar behaviour (they work for a couple of packets + * and then lock up and can be revived by ifconfig down/up). + * 07.04.99 0.14 implemented the following ioctl's: SOUND_PCM_READ_RATE, + * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; + * Alpha fixes reported by Peter Jones + * Note: dmaio hack might still be wrong on archs other than i386 * */ @@ -255,7 +268,8 @@ struct sv_state { int dev_dmfm; /* hardware resources */ - unsigned int iosb, ioenh, iosynth, iomidi, iogame, iodmaa, iodmac, irq; + unsigned long iosb, ioenh, iosynth, iomidi, iogame; /* long for SPARC */ + unsigned int iodmaa, iodmac, irq; /* mixer stuff */ struct { @@ -1298,7 +1312,19 @@ static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *pp start_adc(s); if (file->f_flags & O_NONBLOCK) return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_adc.wait); + if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { + printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", + s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, + s->dma_adc.hwptr, s->dma_adc.swptr); + stop_adc(s); + spin_lock_irqsave(&s->lock, flags); + set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift); + /* program enhanced mode registers */ + wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8); + wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); + s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; + spin_unlock_irqrestore(&s->lock, flags); + } if (signal_pending(current)) return ret ? ret : -ERESTARTSYS; continue; @@ -1358,7 +1384,19 @@ static ssize_t sv_write(struct file *file, const char *buffer, size_t count, lof start_dac(s); if (file->f_flags & O_NONBLOCK) return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac.wait); + if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) { + printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", + s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, + s->dma_dac.hwptr, s->dma_dac.swptr); + stop_dac(s); + spin_lock_irqsave(&s->lock, flags); + set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift); + /* program enhanced mode registers */ + wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8); + wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); + s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; + spin_unlock_irqrestore(&s->lock, flags); + } if (signal_pending(current)) return ret ? ret : -ERESTARTSYS; continue; @@ -1717,11 +1755,19 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un s->dma_dac.subdivision = val; return 0; - case SOUND_PCM_WRITE_FILTER: - case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + case SOUND_PCM_READ_CHANNELS: + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) + : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg); + case SOUND_PCM_READ_BITS: + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) + : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: case SOUND_PCM_READ_FILTER: return -EINVAL; @@ -2275,7 +2321,7 @@ __initfunc(int init_sonicvibes(void)) if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "sv: version v0.12 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "sv: version v0.14 time " __TIME__ " " __DATE__ "\n"); #if 0 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); @@ -2329,7 +2375,7 @@ __initfunc(int init_sonicvibes(void)) } pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */ pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */ - printk(KERN_DEBUG "sv: io ports: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n", s->iosb, s->ioenh, s->iosynth, s->iomidi, s->iogame, s->iodmaa, s->iodmac); if (s->ioenh == 0 || s->iodmaa == 0 || s->iodmac == 0) continue; @@ -2339,7 +2385,7 @@ __initfunc(int init_sonicvibes(void)) pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12); /* wavetable base address */ if (check_region(s->ioenh, SV_EXTENT_ENH)) { - printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1); + printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1); goto err_region5; } request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM"); @@ -2354,12 +2400,12 @@ __initfunc(int init_sonicvibes(void)) } request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC"); if (check_region(s->iomidi, SV_EXTENT_MIDI)) { - printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1); + printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1); goto err_region2; } request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi"); if (check_region(s->iosynth, SV_EXTENT_SYNTH)) { - printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1); + printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1); goto err_region1; } request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth"); @@ -2390,7 +2436,7 @@ __initfunc(int init_sonicvibes(void)) printk(KERN_ERR "sv: irq %u in use\n", s->irq); goto err_irq; } - printk(KERN_INFO "sv: found adapter at io %#06x irq %u dmaa %#06x dmac %#06x revision %u\n", + printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n", s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION)); /* register devices */ if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 48017eeed7bb..25bfaf3a7e19 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -943,7 +943,9 @@ int init_module(void) mpu_config.irq = mpu_irq; mpu_config.io_base = mpu_io; - + /* WEH - Try to get right dma channel */ + mpu_config.dma = dma; + if(spea != -1) { old_hardware = spea; diff --git a/fs/open.c b/fs/open.c index 6d25e409fa8e..a7cd5d554ab2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -294,11 +294,16 @@ asmlinkage int sys_access(const char * filename, int mode) /* Clear the capabilities if we switch to a non-root user */ if (current->uid) cap_clear(current->cap_effective); - + else + current->cap_effective = current->cap_permitted; + dentry = namei(filename); res = PTR_ERR(dentry); if (!IS_ERR(dentry)) { res = permission(dentry->d_inode, mode); + /* SuS v2 requires we report a read only fs too */ + if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode)) + res = -EROFS; dput(dentry); } diff --git a/fs/proc/link.c b/fs/proc/link.c index 70c31f21a0b5..b120507675be 100644 --- a/fs/proc/link.c +++ b/fs/proc/link.c @@ -158,7 +158,7 @@ static int do_proc_readlink(struct dentry *dentry, char * buffer, int buflen) path = tmp; } else { path = d_path(dentry, tmp, PAGE_SIZE); - len = tmp + PAGE_SIZE - path; + len = tmp + PAGE_SIZE - 1 - path; } if (len < buflen) diff --git a/ipc/shm.c b/ipc/shm.c index b7224f330054..12cdf51b5527 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -24,7 +24,8 @@ static int shm_map (struct vm_area_struct *shmd); static void killseg (int id); static void shm_open (struct vm_area_struct *shmd); static void shm_close (struct vm_area_struct *shmd); -static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long); +static unsigned long shm_nopage(struct vm_area_struct *, unsigned long, int); +static int shm_swapout(struct vm_area_struct *, struct page *); static int shm_tot = 0; /* total number of shared memory pages */ static int shm_rss = 0; /* number of shared memory pages that are in memory */ @@ -364,10 +365,10 @@ static struct vm_operations_struct shm_vm_ops = { NULL, /* protect */ NULL, /* sync */ NULL, /* advise */ - NULL, /* nopage (done with swapin) */ + shm_nopage, /* nopage */ NULL, /* wppage */ - NULL, /* swapout (hardcoded right now) */ - shm_swap_in /* swapin */ + shm_swapout, /* swapout */ + NULL /* swapin */ }; /* Insert shmd into the list shp->attaches */ @@ -393,11 +394,7 @@ static inline void remove_attach (struct shmid_kernel * shp, struct vm_area_stru */ static int shm_map (struct vm_area_struct *shmd) { - pgd_t *page_dir; - pmd_t *page_middle; - pte_t *page_table; - unsigned long tmp, shm_sgn; - int error; + unsigned long tmp; /* clear old mappings */ do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start); @@ -411,30 +408,7 @@ static int shm_map (struct vm_area_struct *shmd) insert_vm_struct(current->mm, shmd); merge_segments(current->mm, shmd->vm_start, shmd->vm_end); - /* map page range */ - error = 0; - shm_sgn = shmd->vm_pte + - SWP_ENTRY(0, (shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT); - flush_cache_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end); - for (tmp = shmd->vm_start; - tmp < shmd->vm_end; - tmp += PAGE_SIZE, shm_sgn += SWP_ENTRY(0, 1 << SHM_IDX_SHIFT)) - { - page_dir = pgd_offset(shmd->vm_mm,tmp); - page_middle = pmd_alloc(page_dir,tmp); - if (!page_middle) { - error = -ENOMEM; - break; - } - page_table = pte_alloc(page_middle,tmp); - if (!page_table) { - error = -ENOMEM; - break; - } - set_pte(page_table, __pte(shm_sgn)); - } - flush_tlb_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end); - return error; + return 0; } /* @@ -614,45 +588,47 @@ asmlinkage int sys_shmdt (char *shmaddr) return 0; } +/* + * Enter the shm page into the SHM data structures. + * + * The way "nopage" is done, we don't actually have to + * do anything here: nopage will have filled in the shm + * data structures already, and shm_swap_out() will just + * work off them.. + */ +static int shm_swapout(struct vm_area_struct * vma, struct page * page) +{ + return 0; +} + /* * page not present ... go through shm_pages */ -static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, unsigned long code) +static unsigned long shm_nopage(struct vm_area_struct * shmd, unsigned long address, int no_share) { pte_t pte; struct shmid_kernel *shp; unsigned int id, idx; - id = SWP_OFFSET(code) & SHM_ID_MASK; + id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK; + idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT; + #ifdef DEBUG_SHM - if (id != (SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK)) { - printk ("shm_swap_in: code id = %d and shmd id = %ld differ\n", - id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK); - return BAD_PAGE; - } if (id > max_shmid) { - printk ("shm_swap_in: id=%d too big. proc mem corrupted\n", id); - return BAD_PAGE; + printk ("shm_nopage: id=%d too big. proc mem corrupted\n", id); + return 0; } #endif shp = shm_segs[id]; #ifdef DEBUG_SHM if (shp == IPC_UNUSED || shp == IPC_NOID) { - printk ("shm_swap_in: id=%d invalid. Race.\n", id); - return BAD_PAGE; - } -#endif - idx = (SWP_OFFSET(code) >> SHM_IDX_SHIFT) & SHM_IDX_MASK; -#ifdef DEBUG_SHM - if (idx != (offset >> PAGE_SHIFT)) { - printk ("shm_swap_in: code idx = %u and shmd idx = %lu differ\n", - idx, offset >> PAGE_SHIFT); - return BAD_PAGE; + printk ("shm_nopage: id=%d invalid. Race.\n", id); + return 0; } if (idx >= shp->shm_npages) { - printk ("shm_swap_in : too large page index. id=%d\n", id); - return BAD_PAGE; + printk ("shm_nopage : too large page index. id=%d\n", id); + return 0; } #endif @@ -661,7 +637,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns unsigned long page = get_free_page(GFP_KERNEL); if (!page) { oom(current); - return BAD_PAGE; + return 0; } pte = __pte(shp->shm_pages[idx]); if (pte_present(pte)) { @@ -687,7 +663,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns done: /* pte_val(pte) == shp->shm_pages[idx] */ current->min_flt++; atomic_inc(&mem_map[MAP_NR(pte_page(pte))].count); - return pte_modify(pte, shmd->vm_page_prot); + return pte_page(pte); } /* @@ -700,7 +676,6 @@ int shm_swap (int prio, int gfp_mask) { pte_t page; struct shmid_kernel *shp; - struct vm_area_struct *shmd; unsigned long swap_nr; unsigned long id, idx; int loop = 0; @@ -742,61 +717,6 @@ int shm_swap (int prio, int gfp_mask) swap_free (swap_nr); return 0; } - if (shp->attaches) - for (shmd = shp->attaches; ; ) { - do { - pgd_t *page_dir; - pmd_t *page_middle; - pte_t *page_table, pte; - unsigned long tmp; - - if ((SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK) != id) { - printk ("shm_swap: id=%ld does not match shmd->vm_pte.id=%ld\n", - id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK); - continue; - } - tmp = shmd->vm_start + (idx << PAGE_SHIFT) - shmd->vm_offset; - if (!(tmp >= shmd->vm_start && tmp < shmd->vm_end)) - continue; - page_dir = pgd_offset(shmd->vm_mm,tmp); - if (pgd_none(*page_dir) || pgd_bad(*page_dir)) { - printk("shm_swap: bad pgtbl! id=%ld start=%lx idx=%ld\n", - id, shmd->vm_start, idx); - pgd_clear(page_dir); - continue; - } - page_middle = pmd_offset(page_dir,tmp); - if (pmd_none(*page_middle) || pmd_bad(*page_middle)) { - printk("shm_swap: bad pgmid! id=%ld start=%lx idx=%ld\n", - id, shmd->vm_start, idx); - pmd_clear(page_middle); - continue; - } - page_table = pte_offset(page_middle,tmp); - pte = *page_table; - if (!pte_present(pte)) - continue; - if (pte_young(pte)) { - set_pte(page_table, pte_mkold(pte)); - continue; - } - if (pte_page(pte) != pte_page(page)) - printk("shm_swap_out: page and pte mismatch %lx %lx\n", - pte_page(pte),pte_page(page)); - flush_cache_page(shmd, tmp); - set_pte(page_table, - __pte(shmd->vm_pte + SWP_ENTRY(0, idx << SHM_IDX_SHIFT))); - atomic_dec(&mem_map[MAP_NR(pte_page(pte))].count); - if (shmd->vm_mm->rss > 0) - shmd->vm_mm->rss--; - flush_tlb_page(shmd, tmp); - /* continue looping through the linked list */ - } while (0); - shmd = shmd->vm_next_share; - if (!shmd) - break; - } - if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) != 1) goto check_table; shp->shm_pages[idx] = swap_nr; diff --git a/mm/memory.c b/mm/memory.c index fd4cf87a603d..9cdfe35df226 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -585,7 +585,8 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig return 0; } if (!pte_none(*pte)) { - printk("put_dirty_page: page already exists\n"); + printk("put_dirty_page: pte %08lx already exists\n", + pte_val(*pte)); free_page(page); return 0; } diff --git a/mm/mmap.c b/mm/mmap.c index 3a0f947932e6..7d86c9d1fa15 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -567,8 +567,8 @@ static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev, if (!prev) goto no_mmaps; if (prev->vm_end > start) { - if (last > prev->vm_end) - last = prev->vm_end; + if (last > prev->vm_start) + last = prev->vm_start; goto no_mmaps; } } diff --git a/net/README b/net/README index 9281cc13d9fd..6f1b0beb8d4a 100644 --- a/net/README +++ b/net/README @@ -16,7 +16,7 @@ ipx/spx Jay.Schulist@spacs.k12.wi.us lapb g4klx@g4klx.demon.co.uk netrom g4klx@g4klx.demon.co.uk rose g4klx@g4klx.demon.co.uk -wanrouter genek@compuserve.com and dm@sangoma.com +wanrouter gene@compuserve.com, jaspreet@sangoma and dm@sangoma.com unix alan@lxorguk.ukuu.org.uk x25 g4klx@g4klx.demon.co.uk diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 6d59b2338407..79c6c7e457ef 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -128,6 +128,8 @@ static void aarp_send_query(struct aarp_entry *a) skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length); eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp)); + skb->protocol = htons(ETH_P_ATALK); + skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; /* @@ -186,6 +188,8 @@ static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_ad skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length); eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp)); + skb->protocol = htons(ETH_P_ATALK); + skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; /* @@ -246,7 +250,8 @@ void aarp_send_probe(struct device *dev, struct at_addr *us) skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length); eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp)); - + skb->protocol = htons(ETH_P_ATALK); + skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; /* @@ -365,12 +370,10 @@ static void aarp_expire_timeout(unsigned long unused) aarp_expire_timer(&unresolved[ct]); aarp_expire_timer(&proxies[ct]); } - del_timer(&aarp_timer); - if(unresolved_count==0) - aarp_timer.expires=jiffies+sysctl_aarp_expiry_time; - else - aarp_timer.expires=jiffies+sysctl_aarp_tick_time; - add_timer(&aarp_timer); + + mod_timer(&aarp_timer, jiffies + + (unresolved_count ? sysctl_aarp_tick_time: + sysctl_aarp_expiry_time)); } /* @@ -750,9 +753,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo if(unresolved_count==1) { - del_timer(&aarp_timer); - aarp_timer.expires=jiffies+sysctl_aarp_tick_time; - add_timer(&aarp_timer); + mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); } /* @@ -939,9 +940,8 @@ static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type aarp_resolved(&unresolved[hash],a,hash); if(unresolved_count==0) { - del_timer(&aarp_timer); - aarp_timer.expires=jiffies+sysctl_aarp_expiry_time; - add_timer(&aarp_timer); + mod_timer(&aarp_timer, jiffies + + sysctl_aarp_expiry_time); } break;