From: NIIBE Y. <gn...@m1...> - 2002-01-08 07:01:58
|
David Woodhouse wrote: > You ought to be able to remove asm-sh/segment.h now too. Thanks for your effort. Will do for our repository. Here's another turn. Changes from mainline. 2002-01-08 NIIBE Yutaka <gn...@m1...> Updated to 2.5.2-pre10. * Makefile, Documentation/Configure.help, arch/sh/kernel/process.c, arch/sh/kernel/setup.c, drivers/block/rd.c, drivers/char/sh-sci.c, drivers/char/shwdt.c, init/do_mounts.c, init/main.c, kernel/ptrace.c, mm/memory.c: Include changes from mainline (2.5.2-pre10). * drivers/cdrom/gdrom.c (DEVICE_NR): MINOR -> minor. (gdrom_init): MKDEV -> mk_kdev. * arch/sh/mm/fault.c (do_page_fault): Use yield. * include/asm-sh/mmu_context.h (sched_find_first_zero_bit): Implemented. (Just copied from x86 implementation.) * arch/sh/kernel/setup.c (sh_console_device): Returns /dev/null. * arch/sh/kernel/irq.c: Include <linux/mm.h>. * arch/sh/kernel/process.c: Include <linux/mm.h>. (cpu_idle): Don't call init_idle here. Remove setting of ->nice. Index: Makefile =================================================================== RCS file: /cvsroot/linuxsh/linux/Makefile,v retrieving revision 1.3 diff -u -3 -p -r1.3 Makefile --- Makefile 2002/01/07 03:57:47 1.3 +++ Makefile 2002/01/08 06:57:46 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 1 -EXTRAVERSION = +SUBLEVEL = 2 +EXTRAVERSION =-pre10 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Index: Documentation/Configure.help =================================================================== RCS file: /cvsroot/linuxsh/linux/Documentation/Configure.help,v retrieving revision 1.3 diff -u -3 -p -r1.3 Configure.help --- Documentation/Configure.help 2002/01/07 03:57:47 1.3 +++ Documentation/Configure.help 2002/01/08 06:57:48 @@ -12541,6 +12541,30 @@ CONFIG_USB_LONG_TIMEOUT If you have an MGE Ellipse UPS, or you see timeouts in HID transactions, say Y; otherwise say N. +EHCI (USB 2.0) support +CONFIG_USB_EHCI_HCD + The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 + "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. + If your USB host controller supports USB 2.0, you will likely want to + configure this Host Controller Driver. At this writing, the primary + implementation of EHCI is a chip from NEC, widely available in add-on + PCI cards, but implementations are in the works from other vendors + including Intel and Philips. Motherboard support is appearing. + + EHCI controllers are packaged with "companion" host controllers (OHCI + or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports + will connect to EHCI if it the device is high speed, otherwise they + connect to a companion controller. If you configure EHCI, you should + probably configure the OHCI (for NEC and some other vendors) USB Host + Controller Driver too. + + You may want to read <file:Documentation/usb/ehci.txt>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called ehci-hcd.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + UHCI (Intel PIIX4, VIA, ...) support CONFIG_USB_UHCI The Universal Host Controller Interface is a standard by Intel for @@ -12841,6 +12865,17 @@ CONFIG_USB_SERIAL_VISOR The module will be called visor.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +USB Compaq iPAQ Driver +CONFIG_USB_SERIAL_IPAQ + Say Y here if you want to connect to your Compaq iPAQ running + Windows CE 3.0 using a USB autosync cable. For information on using + the driver, read <file:Documentation/usb/usb-serial.txt>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called ipaq.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + USB IR Dongle Serial Driver CONFIG_USB_SERIAL_IR Say Y here if you want to enable simple serial support for USB IrDA @@ -13061,6 +13096,22 @@ CONFIG_USB_SERIAL_EDGEPORT The module will be called io_edgeport.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +USB PalmConnect (and other KL5KUSB105-based) Single Port Serial Driver +CONFIG_USB_SERIAL_KLSI + Say Y here if you want to use a KL5KUSB105 - based single port + serial adapter. The most widely known -- and currently the only + tested -- device in this category is the PalmConnect USB Serial + adapter sold by Palm Inc. for use with their Palm III and Palm V + series PDAs. + + Please read <file:Documentation/usb/usb-serial.txt> for more + information. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called kl5kusb105.o. If you want to compile it as + a module, say M here and read <file:Documentation/modules.txt>. + USB Serial Converter verbose debug CONFIG_USB_SERIAL_DEBUG Say Y here if you want verbose debug messages from the USB Serial @@ -13167,6 +13218,54 @@ CONFIG_USB_PWC The module will be called pwc.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +USB SE401 Camera support +CONFIG_USB_SE401 + Say Y here if you want to connect this type of camera to your + computer's USB port. See <file:Documentation/usb/se401.txt> for more + information and for a list of supported cameras. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called se401.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + +USB STV680 (Pencam) Camera support +CONFIG_USB_STV680 + Say Y here if you want to connect this type of camera to your + computer's USB port. This includes the Pencam line of cameras. + See <file:Documentation/usb/stv680.txt> for more information and for + a list of supported cameras. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called stv680.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + +Vicam +CONFIG_USB_VICAM + Say Y here if you have 3com homeconnect camera (vicam). + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called vicam.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + + Pegasus/Pegasus II based USB-Ethernet device support CONFIG_USB_PEGASUS Say Y here if you know you have Pegasus or Pegasus II based adapter. @@ -13415,6 +13514,16 @@ CONFIG_USB_RIO500 The module will be called rio500.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +USB Auerswald ISDN device support +CONFIG_USB_AUERSWALD + Say Y here if you want to connect an Auerswald USB ISDN Device + to your computer's USB port. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called auerswald.o. If you want to compile it as + a module, say M here and read <file:Documentation/modules.txt>. + D-Link DSB-R100 FM radio support CONFIG_USB_DSBR Say Y here if you want to connect this type of radio to your @@ -16960,22 +17069,6 @@ CONFIG_PM Note that, even if you say N here, Linux on the x86 architecture will issue the hlt instruction if nothing is to be done, thereby sending the processor to sleep and saving power. - -USB SE401 Camera support -CONFIG_USB_SE401 - Say Y here if you want to connect this type of camera to your - computer's USB port. See <file:Documentation/usb/se401.txt> for more - information and for a list of supported cameras. - - This driver uses the Video For Linux API. You must say Y or M to - "Video For Linux" (under Multimedia Devices) to use this driver. - Information on this API and pointers to "v4l" programs may be found - on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. - - This code is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called se401.o. If you want to compile it as a - module, say M here and read <file:Documentation/modules.txt>. ACPI support CONFIG_ACPI Index: arch/sh/kernel/irq.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/irq.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 irq.c --- arch/sh/kernel/irq.c 2002/01/07 03:57:48 1.2 +++ arch/sh/kernel/irq.c 2002/01/08 06:57:48 @@ -22,6 +22,7 @@ #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/timex.h> +#include <linux/mm.h> #include <linux/slab.h> #include <linux/random.h> #include <linux/smp.h> Index: arch/sh/kernel/process.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/process.c,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 process.c --- arch/sh/kernel/process.c 2001/10/15 20:44:51 1.1.1.1 +++ arch/sh/kernel/process.c 2002/01/08 06:57:48 @@ -12,6 +12,7 @@ */ #include <linux/unistd.h> +#include <linux/mm.h> #include <linux/slab.h> #include <asm/io.h> @@ -39,10 +40,6 @@ void enable_hlt(void) void cpu_idle(void *unused) { /* endless idle loop with no priority at all */ - init_idle(); - current->nice = 20; - current->counter = -100; - while (1) { if (hlt_counter) { if (current->need_resched) Index: arch/sh/kernel/setup.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/setup.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 setup.c --- arch/sh/kernel/setup.c 2001/12/03 22:15:34 1.2 +++ arch/sh/kernel/setup.c 2002/01/08 06:57:48 @@ -140,20 +140,10 @@ static void sh_console_write(struct cons sh_bios_console_write(s, count); } -/* - * Receive character from the serial port - */ -static int sh_console_wait_key(struct console *co) -{ - /* Not implemented yet */ - return 0; -} - static kdev_t sh_console_device(struct console *c) { - /* TODO: this is totally bogus */ - /* return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index); */ - return 0; + /* /dev/null */ + return mk_kdev(MEM_MAJOR, 3); } /* @@ -183,7 +173,6 @@ static struct console sh_console = { name: "bios", write: sh_console_write, device: sh_console_device, - wait_key: sh_console_wait_key, setup: sh_console_setup, flags: CON_PRINTBUFFER, index: -1, Index: arch/sh/mm/fault.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/fault.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 fault.c --- arch/sh/mm/fault.c 2001/12/26 19:30:07 1.2 +++ arch/sh/mm/fault.c 2002/01/08 06:57:48 @@ -207,8 +207,7 @@ no_context: out_of_memory: up_read(&mm->mmap_sem); if (current->pid == 1) { - current->policy |= SCHED_YIELD; - schedule(); + yield(); down_read(&mm->mmap_sem); goto survive; } Index: drivers/block/rd.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/block/rd.c,v retrieving revision 1.3 diff -u -3 -p -r1.3 rd.c --- drivers/block/rd.c 2001/12/17 07:25:45 1.3 +++ drivers/block/rd.c 2002/01/08 06:57:49 @@ -43,29 +43,12 @@ */ #include <linux/config.h> -#include <linux/sched.h> -#include <linux/minix_fs.h> -#include <linux/ext2_fs.h> -#include <linux/romfs_fs.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/hdreg.h> #include <linux/string.h> -#include <linux/mm.h> -#include <linux/mman.h> #include <linux/slab.h> -#include <linux/ioctl.h> -#include <linux/fd.h> #include <linux/module.h> #include <linux/init.h> #include <linux/devfs_fs_kernel.h> -#include <linux/smp_lock.h> - -#include <asm/system.h> #include <asm/uaccess.h> -#include <asm/byteorder.h> - -extern void wait_for_keypress(void); /* * 35 has been officially registered as the RAMDISK major number, but @@ -79,17 +62,11 @@ extern void wait_for_keypress(void); /* The RAM disk size is now a parameter */ #define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */ -#ifndef MODULE -/* We don't have to load RAM disks or gunzip them in a module. */ -#define RD_LOADER -#define BUILD_CRAMDISK - -void rd_load(void); -static int crd_load(struct file *fp, struct file *outfp); - #ifdef CONFIG_BLK_DEV_INITRD static int initrd_users; -#endif +static spinlock_t initrd_users_lock = SPIN_LOCK_UNLOCKED; +unsigned long initrd_start, initrd_end; +int initrd_below_start_ok; #endif /* Various static variables go here. Most are used only in the RAM disk code. @@ -98,7 +75,7 @@ static int initrd_users; static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */ static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */ static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */ -static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ +static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ static devfs_handle_t devfs_handle; static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */ @@ -122,70 +99,6 @@ int rd_size = CONFIG_BLK_DEV_RAM_SIZE; */ int rd_blocksize = BLOCK_SIZE; /* blocksize of the RAM disks */ -#ifndef MODULE - -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; /* starting block # of image */ -#ifdef CONFIG_BLK_DEV_INITRD -unsigned long initrd_start, initrd_end; -int mount_initrd = 1; /* zero if initrd should not be mounted */ -int initrd_below_start_ok; - -static int __init no_initrd(char *str) -{ - mount_initrd = 0; - return 1; -} - -__setup("noinitrd", no_initrd); - -#endif - -static int __init ramdisk_start_setup(char *str) -{ - rd_image_start = simple_strtol(str,NULL,0); - return 1; -} - -static int __init load_ramdisk(char *str) -{ - rd_doload = simple_strtol(str,NULL,0) & 3; - return 1; -} - -static int __init prompt_ramdisk(char *str) -{ - rd_prompt = simple_strtol(str,NULL,0) & 1; - return 1; -} - -static int __init ramdisk_size(char *str) -{ - rd_size = simple_strtol(str,NULL,0); - return 1; -} - -static int __init ramdisk_size2(char *str) -{ - return ramdisk_size(str); -} - -static int __init ramdisk_blocksize(char *str) -{ - rd_blocksize = simple_strtol(str,NULL,0); - return 1; -} - -__setup("ramdisk_start=", ramdisk_start_setup); -__setup("load_ramdisk=", load_ramdisk); -__setup("prompt_ramdisk=", prompt_ramdisk); -__setup("ramdisk=", ramdisk_size); -__setup("ramdisk_size=", ramdisk_size2); -__setup("ramdisk_blocksize=", ramdisk_blocksize); - -#endif - /* * Copyright (C) 2000 Linus Torvalds. * 2000 Transmeta Corp. @@ -227,19 +140,19 @@ static struct address_space_operations r commit_write: ramdisk_commit_write, }; -static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor) +static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, + sector_t sector, int minor) { struct address_space * mapping; unsigned long index; int offset, size, err; - err = -EIO; err = 0; mapping = rd_bdev[minor]->bd_inode->i_mapping; - index = sbh->b_rsector >> (PAGE_CACHE_SHIFT - 9); - offset = (sbh->b_rsector << 9) & ~PAGE_CACHE_MASK; - size = sbh->b_size; + index = sector >> (PAGE_CACHE_SHIFT - 9); + offset = (sector << 9) & ~PAGE_CACHE_MASK; + size = vec->bv_len; do { int count; @@ -276,18 +189,18 @@ static int rd_blkdev_pagecache_IO(int rw if (rw == READ) { src = kmap(page); src += offset; - dst = bh_kmap(sbh); + dst = kmap(vec->bv_page) + vec->bv_offset; } else { dst = kmap(page); dst += offset; - src = bh_kmap(sbh); + src = kmap(vec->bv_page) + vec->bv_offset; } offset = 0; memcpy(dst, src, count); kunmap(page); - bh_kunmap(sbh); + kunmap(vec->bv_page); if (rw == READ) { flush_dcache_page(page); @@ -303,6 +216,22 @@ static int rd_blkdev_pagecache_IO(int rw return err; } +static int rd_blkdev_bio_IO(struct bio *bio, unsigned int minor) +{ + struct bio_vec *bvec; + sector_t sector; + int ret = 0, i, rw; + + sector = bio->bi_sector; + rw = bio_data_dir(bio); + bio_for_each_segment(bvec, bio, i) { + ret |= rd_blkdev_pagecache_IO(rw, bvec, sector, minor); + sector += bvec->bv_len >> 9; + } + + return ret; +} + /* * Basically, my strategy here is to set up a buffer-head which can't be * deleted, and make that my Ramdisk. If the request is outside of the @@ -311,19 +240,19 @@ static int rd_blkdev_pagecache_IO(int rw * 19-JAN-1998 Richard Gooch <rg...@at...> Added devfs support * */ -static int rd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh) +static int rd_make_request(request_queue_t * q, struct bio *sbh) { unsigned int minor; unsigned long offset, len; + int rw = sbh->bi_rw; - minor = MINOR(sbh->b_rdev); + minor = minor(sbh->bi_dev); if (minor >= NUM_RAMDISKS) goto fail; - - offset = sbh->b_rsector << 9; - len = sbh->b_size; + offset = sbh->bi_sector << 9; + len = sbh->bi_size; if ((offset + len) > rd_length[minor]) goto fail; @@ -335,13 +264,14 @@ static int rd_make_request(request_queue goto fail; } - if (rd_blkdev_pagecache_IO(rw, sbh, minor)) + if (rd_blkdev_bio_IO(sbh, minor)) goto fail; - sbh->b_end_io(sbh,1); + set_bit(BIO_UPTODATE, &sbh->bi_flags); + sbh->bi_end_io(sbh, len >> 9); return 0; fail: - sbh->b_end_io(sbh,0); + bio_io_error(sbh); return 0; } @@ -350,10 +280,10 @@ static int rd_ioctl(struct inode *inode, int error = -EINVAL; unsigned int minor; - if (!inode || !inode->i_rdev) + if (!inode || kdev_none(inode->i_rdev)) goto out; - minor = MINOR(inode->i_rdev); + minor = minor(inode->i_rdev); switch (cmd) { case BLKFLSBUF: @@ -408,12 +338,15 @@ static int initrd_release(struct inode * { extern void free_initrd_mem(unsigned long, unsigned long); - lock_kernel(); + spin_lock(&initrd_users_lock); if (!--initrd_users) { + spin_unlock(&initrd_users_lock); free_initrd_mem(initrd_start, initrd_end); initrd_start = 0; + } else { + spin_unlock(&initrd_users_lock); } - unlock_kernel(); + blkdev_put(inode->i_bdev, BDEV_FILE); return 0; } @@ -433,8 +366,11 @@ static int rd_open(struct inode * inode, #ifdef CONFIG_BLK_DEV_INITRD if (unit == INITRD_MINOR) { - if (!initrd_start) return -ENODEV; + spin_lock(&initrd_users_lock); initrd_users++; + spin_unlock(&initrd_users_lock); + if (!initrd_start) + return -ENODEV; filp->f_op = &initrd_fops; return 0; } @@ -461,7 +397,6 @@ static struct block_device_operations rd ioctl: rd_ioctl, }; -#ifdef MODULE /* Before freeing the module, invalidate all of the protected buffers! */ static void __exit rd_cleanup (void) { @@ -472,19 +407,16 @@ static void __exit rd_cleanup (void) rd_bdev[i] = NULL; if (bdev) blkdev_put(bdev, BDEV_FILE); - destroy_buffers(MKDEV(MAJOR_NR, i)); + destroy_buffers(mk_kdev(MAJOR_NR, i)); } devfs_unregister (devfs_handle); unregister_blkdev( MAJOR_NR, "ramdisk" ); - hardsect_size[MAJOR_NR] = NULL; - blksize_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = NULL; + blk_clear(MAJOR_NR); } -#endif /* This is the registration and initialization section of the RAM disk driver */ -int __init rd_init (void) +static int __init rd_init (void) { int i; @@ -517,14 +449,15 @@ int __init rd_init (void) &rd_bd_op, NULL); for (i = 0; i < NUM_RAMDISKS; i++) - register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &rd_bd_op, rd_size<<1); + register_disk(NULL, mk_kdev(MAJOR_NR,i), 1, &rd_bd_op, rd_size<<1); #ifdef CONFIG_BLK_DEV_INITRD /* We ought to separate initrd operations here */ - register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1); + register_disk(NULL, mk_kdev(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1); + devfs_register(devfs_handle, "initrd", DEVFS_FL_DEFAULT, MAJOR_NR, + INITRD_MINOR, S_IFBLK | S_IRUSR, &rd_bd_op, NULL); #endif - 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 */ @@ -536,474 +469,34 @@ int __init rd_init (void) return 0; } -#ifdef MODULE module_init(rd_init); module_exit(rd_cleanup); -#endif - -/* loadable module support */ -MODULE_PARM (rd_size, "1i"); -MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes."); -MODULE_PARM (rd_blocksize, "i"); -MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes."); - -MODULE_LICENSE("GPL"); - -/* End of non-loading portions of the RAM disk driver */ - -#ifdef RD_LOADER -/* - * This routine tries to find a RAM disk image to load, and returns the - * number of blocks to read for a non-compressed image, 0 if the image - * is a compressed image, and -1 if an image with the right magic - * numbers could not be found. - * - * We currently check for the following magic numbers: - * minix - * ext2 - * romfs - * gzip - */ -static int __init -identify_ramdisk_image(kdev_t device, struct file *fp, int start_block) -{ - const int size = 512; - struct minix_super_block *minixsb; - struct ext2_super_block *ext2sb; - struct romfs_super_block *romfsb; - int nblocks = -1; - unsigned char *buf; - - buf = kmalloc(size, GFP_KERNEL); - if (buf == 0) - return -1; - - minixsb = (struct minix_super_block *) buf; - ext2sb = (struct ext2_super_block *) buf; - romfsb = (struct romfs_super_block *) buf; - memset(buf, 0xe5, size); - - /* - * Read block 0 to test for gzipped kernel - */ - if (fp->f_op->llseek) - fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); - fp->f_pos = start_block * BLOCK_SIZE; - - fp->f_op->read(fp, buf, size, &fp->f_pos); - - /* - * If it matches the gzip magic numbers, return -1 - */ - if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { - printk(KERN_NOTICE - "RAMDISK: Compressed image found at block %d\n", - start_block); - nblocks = 0; - goto done; - } - - /* romfs is at block zero too */ - if (romfsb->word0 == ROMSB_WORD0 && - romfsb->word1 == ROMSB_WORD1) { - printk(KERN_NOTICE - "RAMDISK: romfs filesystem found at block %d\n", - start_block); - nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; - goto done; - } - - /* - * Read block 1 to test for minix and ext2 superblock - */ - if (fp->f_op->llseek) - fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0); - fp->f_pos = (start_block+1) * BLOCK_SIZE; - - fp->f_op->read(fp, buf, size, &fp->f_pos); - - /* Try minix */ - if (minixsb->s_magic == MINIX_SUPER_MAGIC || - minixsb->s_magic == MINIX_SUPER_MAGIC2) { - printk(KERN_NOTICE - "RAMDISK: Minix filesystem found at block %d\n", - start_block); - nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; - goto done; - } - - /* Try ext2 */ - if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { - printk(KERN_NOTICE - "RAMDISK: ext2 filesystem found at block %d\n", - start_block); - nblocks = le32_to_cpu(ext2sb->s_blocks_count); - goto done; - } - - printk(KERN_NOTICE - "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", - start_block); - -done: - if (fp->f_op->llseek) - fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); - fp->f_pos = start_block * BLOCK_SIZE; - - kfree(buf); - return nblocks; -} -/* - * This routine loads in the RAM disk image. - */ -static void __init rd_load_image(kdev_t device, int offset, int unit) -{ - struct inode *inode, *out_inode; - struct file infile, outfile; - struct dentry in_dentry, out_dentry; - mm_segment_t fs; - kdev_t ram_device; - int nblocks, i; - char *buf; - unsigned short rotate = 0; - unsigned short devblocks = 0; -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES) - char rotator[4] = { '|' , '/' , '-' , '\\' }; -#endif - 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)); - 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)); - 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) { - iput(out_inode); - goto free_inode; - } - if (blkdev_open(out_inode, &outfile) != 0) - goto free_inodes; - - fs = get_fs(); - set_fs(KERNEL_DS); - - nblocks = identify_ramdisk_image(device, &infile, offset); - if (nblocks < 0) - goto done; - - if (nblocks == 0) { -#ifdef BUILD_CRAMDISK - if (crd_load(&infile, &outfile) == 0) - goto successful_load; -#else - printk(KERN_NOTICE - "RAMDISK: Kernel does not support compressed " - "RAM disk images\n"); -#endif - goto done; - } - - /* - * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so - * rd_load_image will work only with filesystem BLOCK_SIZE wide! - * So make sure to use 1k blocksize while generating ext2fs - * ramdisk-images. - */ - if (nblocks > (rd_length[unit] >> BLOCK_SIZE_BITS)) { - printk("RAMDISK: image too big! (%d/%ld blocks)\n", - nblocks, rd_length[unit] >> BLOCK_SIZE_BITS); - goto done; - } - - /* - * OK, time to copy in the data - */ - buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); - if (buf == 0) { - printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); - goto done; - } - - if (blk_size[MAJOR(device)]) - devblocks = blk_size[MAJOR(device)][MINOR(device)]; - -#ifdef CONFIG_BLK_DEV_INITRD - if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR) - devblocks = nblocks; -#endif - - if (devblocks == 0) { - printk(KERN_ERR "RAMDISK: could not determine device size\n"); - goto done; - } - - printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", - nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); - for (i=0; i < nblocks; i++) { - if (i && (i % devblocks == 0)) { - printk("done disk #%d.\n", i/devblocks); - rotate = 0; - if (infile.f_op->release(inode, &infile) != 0) { - printk("Error closing the disk.\n"); - goto noclose_input; - } - printk("Please insert disk #%d and press ENTER\n", i/devblocks+1); - wait_for_keypress(); - if (blkdev_open(inode, &infile) != 0) { - printk("Error opening disk.\n"); - goto noclose_input; - } - infile.f_pos = 0; - printk("Loading disk #%d... ", i/devblocks+1); - } - infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos); - outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos); -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES) - if (!(i % 16)) { - printk("%c\b", rotator[rotate & 0x3]); - rotate++; - } -#endif - } - printk("done.\n"); - kfree(buf); - -successful_load: - ROOT_DEV = MKDEV(MAJOR_NR, unit); - if (ROOT_DEVICE_NAME != NULL) strcpy (ROOT_DEVICE_NAME, "rd/0"); - -done: - infile.f_op->release(inode, &infile); -noclose_input: - blkdev_close(out_inode, &outfile); - iput(inode); - iput(out_inode); - set_fs(fs); - return; -free_inodes: /* free inodes on error */ - iput(out_inode); - infile.f_op->release(inode, &infile); -free_inode: - iput(inode); -} - -#ifdef CONFIG_MAC_FLOPPY -int swim3_fd_eject(int devnum); -#endif - -static void __init rd_load_disk(int n) -{ - - if (rd_doload == 0) - return; - - if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR -#ifdef CONFIG_BLK_DEV_INITRD - && MAJOR(real_root_dev) != FLOPPY_MAJOR -#endif - ) - return; - - if (rd_prompt) { -#ifdef CONFIG_BLK_DEV_FD - floppy_eject(); -#endif -#ifdef CONFIG_MAC_FLOPPY - if(MAJOR(ROOT_DEV) == FLOPPY_MAJOR) - swim3_fd_eject(MINOR(ROOT_DEV)); - else if(MAJOR(real_root_dev) == FLOPPY_MAJOR) - swim3_fd_eject(MINOR(real_root_dev)); -#endif - printk(KERN_NOTICE - "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n"); - wait_for_keypress(); - } - - rd_load_image(ROOT_DEV,rd_image_start, n); - -} - -void __init rd_load(void) +/* options - nonmodular */ +#ifndef MODULE +static int __init ramdisk_size(char *str) { - rd_load_disk(0); + rd_size = simple_strtol(str,NULL,0); + return 1; } - -void __init rd_load_secondary(void) +static int __init ramdisk_size2(char *str) /* kludge */ { - rd_load_disk(1); + return ramdisk_size(str); } - -#ifdef CONFIG_BLK_DEV_INITRD -void __init initrd_load(void) +static int __init ramdisk_blocksize(char *str) { - rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0); + rd_blocksize = simple_strtol(str,NULL,0); + return 1; } +__setup("ramdisk=", ramdisk_size); +__setup("ramdisk_size=", ramdisk_size2); +__setup("ramdisk_blocksize=", ramdisk_blocksize); #endif - -#endif /* RD_LOADER */ - -#ifdef BUILD_CRAMDISK - -/* - * gzip declarations - */ - -#define OF(args) args - -#ifndef memzero -#define memzero(s, n) memset ((s), 0, (n)) -#endif - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define INBUFSIZ 4096 -#define WSIZE 0x8000 /* window size--must be a power of two, and */ - /* at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ -static int exit_code; -static long bytes_out; -static struct file *crd_infp, *crd_outfp; - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static - -static int fill_inbuf(void); -static void flush_window(void); -static void *malloc(int size); -static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -#include "../../lib/inflate.c" - -static void __init *malloc(int size) -{ - return kmalloc(size, GFP_KERNEL); -} - -static void __init free(void *where) -{ - kfree(where); -} - -static void __init gzip_mark(void **ptr) -{ -} - -static void __init gzip_release(void **ptr) -{ -} - - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -static int __init fill_inbuf(void) -{ - if (exit_code) return -1; - - insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ, - &crd_infp->f_pos); - if (insize == 0) return -1; - inptr = 1; - - return inbuf[0]; -} - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - - crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos); - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; -} - -static void __init error(char *x) -{ - printk(KERN_ERR "%s", x); - exit_code = 1; -} - -static int __init -crd_load(struct file * fp, struct file *outfp) -{ - int result; - - insize = 0; /* valid bytes in inbuf */ - inptr = 0; /* index of next byte to be processed in inbuf */ - outcnt = 0; /* bytes in output buffer */ - exit_code = 0; - bytes_out = 0; - crc = (ulg)0xffffffffL; /* shift register contents */ - - crd_infp = fp; - crd_outfp = outfp; - inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); - if (inbuf == 0) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); - return -1; - } - window = kmalloc(WSIZE, GFP_KERNEL); - if (window == 0) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); - kfree(inbuf); - return -1; - } - makecrc(); - result = gunzip(); - kfree(inbuf); - kfree(window); - return result; -} - -#endif /* BUILD_CRAMDISK */ +/* options - modular */ +MODULE_PARM (rd_size, "1i"); +MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes."); +MODULE_PARM (rd_blocksize, "i"); +MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes."); +MODULE_LICENSE("GPL"); Index: drivers/cdrom/gdrom.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/cdrom/gdrom.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 gdrom.c --- drivers/cdrom/gdrom.c 2001/12/04 18:58:02 1.2 +++ drivers/cdrom/gdrom.c 2002/01/08 06:57:49 @@ -30,7 +30,7 @@ #define DEVICE_NAME "GD-ROM" #define DEVICE_REQUEST do_gdrom_request -#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_NR(device) (minor(device)) #define DEVICE_STR "gdrom" #include <linux/blk.h> @@ -486,7 +486,7 @@ static int __init gdrom_init(void) hardsect_size[MAJOR_NR] = &gdrom_hardsecsize; read_ahead[MAJOR_NR] = 4; - gdrom_info.dev = MKDEV(MAJOR_NR,0); + gdrom_info.dev = mk_kdev(MAJOR_NR,0); if (register_cdrom(&gdrom_info) != 0) { printk(KERN_ERR "Cannot register SEGA GD-ROM!\n"); free_irq(GDROM_IRQ, NULL); Index: drivers/char/sh-sci.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/char/sh-sci.c,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 sh-sci.c --- drivers/char/sh-sci.c 2001/10/15 20:44:59 1.1.1.1 +++ drivers/char/sh-sci.c 2002/01/08 06:57:49 @@ -813,7 +813,7 @@ static int sci_open(struct tty_struct * struct sci_port *port; int retval, line; - line = MINOR(tty->device) - SCI_MINOR_START; + line = minor(tty->device) - SCI_MINOR_START; if ((line < 0) || (line >= SCI_NPORTS)) return -ENODEV; @@ -1181,18 +1181,9 @@ static void serial_console_write(struct put_string(sercons_port, s, count); } -/* - * Receive character from the serial port - */ -static int serial_console_wait_key(struct console *co) -{ - /* Not implemented yet */ - return 0; -} - static kdev_t serial_console_device(struct console *c) { - return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index); + return mk_kdev(SCI_MAJOR, SCI_MINOR_START + c->index); } /* @@ -1273,7 +1264,6 @@ static struct console sercons = { name: "ttySC", write: serial_console_write, device: serial_console_device, - wait_key: serial_console_wait_key, setup: serial_console_setup, flags: CON_PRINTBUFFER, index: -1, Index: drivers/char/shwdt.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/char/shwdt.c,v retrieving revision 1.3 diff -u -3 -p -r1.3 shwdt.c --- drivers/char/shwdt.c 2001/12/17 00:50:05 1.3 +++ drivers/char/shwdt.c 2002/01/08 06:57:49 @@ -170,7 +170,7 @@ static void sh_wdt_ping(unsigned long da */ static int sh_wdt_open(struct inode *inode, struct file *file) { - switch (MINOR(inode->i_rdev)) { + switch (minor(inode->i_rdev)) { case WATCHDOG_MINOR: if (test_and_set_bit(0, &sh_is_open)) return -EBUSY; @@ -195,7 +195,7 @@ static int sh_wdt_open(struct inode *ino */ static int sh_wdt_close(struct inode *inode, struct file *file) { - if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { + if (minor(inode->i_rdev) == WATCHDOG_MINOR) { #ifndef CONFIG_WATCHDOG_NOWAYOUT sh_wdt_stop(); #endif Index: include/asm-sh/mmu_context.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/mmu_context.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 mmu_context.h --- include/asm-sh/mmu_context.h 2001/10/15 20:45:10 1.1.1.1 +++ include/asm-sh/mmu_context.h 2002/01/08 06:57:49 @@ -185,4 +185,29 @@ static __inline__ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 168-bit bitmap where the first 128 bits are + * unlikely to be set. It's guaranteed that at least one of the 168 + * bits is cleared. + */ +#if MAX_RT_PRIO != 128 || MAX_PRIO != 168 +# error update this function. +#endif + +static inline int sched_find_first_zero_bit(char *bitmap) +{ + unsigned int *b = (unsigned int *)bitmap; + unsigned int rt; + + rt = b[0] & b[1] & b[2] & b[3]; + if (unlikely(rt != 0xffffffff)) + return find_first_zero_bit(bitmap, MAX_RT_PRIO); + + if (b[4] != ~0) + return ffz(b[4]) + MAX_RT_PRIO; + return ffz(b[5]) + 32 + MAX_RT_PRIO; +} + #endif /* __ASM_SH_MMU_CONTEXT_H */ Index: init/do_mounts.c =================================================================== RCS file: /cvsroot/linuxsh/linux/init/do_mounts.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 do_mounts.c --- init/do_mounts.c 2002/01/07 03:57:48 1.1 +++ init/do_mounts.c 2002/01/08 06:57:49 @@ -1,15 +1,15 @@ #define __KERNEL_SYSCALLS__ #include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> #include <linux/slab.h> #include <linux/devfs_fs_kernel.h> #include <linux/unistd.h> -#include <linux/string.h> #include <linux/ctype.h> -#include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/blk.h> -#include <linux/tty.h> #include <linux/fd.h> +#include <linux/tty.h> +#include <linux/init.h> #include <linux/nfs_fs.h> #include <linux/nfs_fs_sb.h> @@ -18,12 +18,9 @@ #include <linux/ext2_fs.h> #include <linux/romfs_fs.h> -#include <asm/uaccess.h> - #define BUILD_CRAMDISK extern int get_filesystem_list(char * buf); -extern void wait_for_keypress(void); asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type, unsigned long flags, void *data); @@ -38,12 +35,21 @@ asmlinkage long sys_ioctl(int fd, int cm #ifdef CONFIG_BLK_DEV_INITRD unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ -#endif -#ifdef CONFIG_BLK_DEV_RAM -extern int rd_doload; +static int __initdata mount_initrd = 1; + +static int __init no_initrd(char *str) +{ + mount_initrd = 0; + return 1; +} + +__setup("noinitrd", no_initrd); #else -static int rd_doload = 0; +static int __initdata mount_initrd = 0; #endif + +int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ + int root_mountflags = MS_RDONLY | MS_VERBOSE; static char root_device_name[64]; @@ -52,6 +58,13 @@ kdev_t ROOT_DEV; static int do_devfs = 0; +static int __init load_ramdisk(char *str) +{ + rd_doload = simple_strtol(str,NULL,0) & 3; + return 1; +} +__setup("load_ramdisk=", load_ramdisk); + static int __init readonly(char *str) { if (*str) @@ -342,8 +355,8 @@ static int __init create_dev(char *name, if (!do_devfs) return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev)); - handle = devfs_find_handle(NULL, dev ? NULL : devfs_name, - MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1); + handle = devfs_find_handle(NULL, kdev_none(dev) ? devfs_name : NULL, + major(dev), minor(dev), DEVFS_SPECIAL_BLK, 1); if (!handle) return -1; n = devfs_generate_path(handle, path + 5, sizeof (path) - 5); @@ -354,8 +367,9 @@ static int __init create_dev(char *name, static void __init change_floppy(char *fmt, ...) { - extern void wait_for_keypress(void); + struct termios termios; char buf[80]; + char c; int fd; va_list args; va_start(args, fmt); @@ -367,11 +381,38 @@ static void __init change_floppy(char *f close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); - wait_for_keypress(); + fd = open("/dev/console", O_RDWR, 0); + if (fd >= 0) { + sys_ioctl(fd, TCGETS, (long)&termios); + termios.c_lflag &= ~ICANON; + sys_ioctl(fd, TCSETSF, (long)&termios); + read(fd, &c, 1); + termios.c_lflag |= ICANON; + sys_ioctl(fd, TCSETSF, (long)&termios); + close(fd); + } } #ifdef CONFIG_BLK_DEV_RAM +int __initdata rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */ + +static int __init prompt_ramdisk(char *str) +{ + rd_prompt = simple_strtol(str,NULL,0) & 1; + return 1; +} +__setup("prompt_ramdisk=", prompt_ramdisk); + +int __initdata rd_image_start; /* starting block # of image */ + +static int __init ramdisk_start_setup(char *str) +{ + rd_image_start = simple_strtol(str,NULL,0); + return 1; +} +__setup("ramdisk_start=", ramdisk_start_setup); + static int __init crd_load(int in_fd, int out_fd); /* @@ -589,18 +630,74 @@ out: static int __init rd_load_disk(int n) { #ifdef CONFIG_BLK_DEV_RAM - extern int rd_prompt; if (rd_prompt) change_floppy("root floppy disk to be loaded into RAM disk"); - create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL); + create_dev("/dev/ram", mk_kdev(RAMDISK_MAJOR, n), NULL); #endif return rd_load_image("/dev/root"); } +#ifdef CONFIG_DEVFS_FS + +static void __init convert_name(char *prefix, char *name, char *p, int part) +{ + int host, bus, target, lun; + char dest[64]; + char src[64]; + char *base = p - 1; + + /* Decode "c#b#t#u#" */ + if (*p++ != 'c') + return; + host = simple_strtol(p, &p, 10); + if (*p++ != 'b') + return; + bus = simple_strtol(p, &p, 10); + if (*p++ != 't') + return; + target = simple_strtol(p, &p, 10); + if (*p++ != 'u') + return; + lun = simple_strtol(p, &p, 10); + if (!part) + sprintf(dest, "%s/host%d/bus%d/target%d/lun%d", + prefix, host, bus, target, lun); + else if (*p++ == 'p') + sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/part%s", + prefix, host, bus, target, lun, p); + else + sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/disc", + prefix, host, bus, target, lun); + *base = '\0'; + sprintf(src, "/dev/%s", name); + sys_mkdir(src, 0755); + *base = '/'; + sprintf(src, "/dev/%s", name); + sys_symlink(dest, src); +} + +static void __init devfs_make_root(char *name) +{ + + if (!strncmp(name, "sd/", 3)) + convert_name("../scsi", name, name+3, 1); + else if (!strncmp(name, "sr/", 3)) + convert_name("../scsi", name, name+3, 0); + else if (!strncmp(name, "ide/hd/", 7)) + convert_name("..", name, name + 7, 1); + else if (!strncmp(name, "ide/cd/", 7)) + convert_name("..", name, name + 7, 0); +} +#else +static void __init devfs_make_root(char *name) +{ +} +#endif + static void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { + if (major(ROOT_DEV) == UNNAMED_MAJOR) { if (mount_nfs_root()) { sys_chdir("/root"); ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; @@ -608,17 +705,17 @@ static void __init mount_root(void) return; } printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); - ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0); + ROOT_DEV = mk_kdev(FLOPPY_MAJOR, 0); } #endif devfs_make_root(root_device_name); create_dev("/dev/root", ROOT_DEV, root_device_name); #ifdef CONFIG_BLK_DEV_FD - if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { + if (major(ROOT_DEV) == FLOPPY_MAJOR) { /* rd_doload is 2 for a dual initrd/ramload setup */ if (rd_doload==2) { if (rd_load_disk(1)) { - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1); + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 1); create_dev("/dev/root", ROOT_DEV, NULL); } } else @@ -653,7 +750,7 @@ static int do_linuxrc(void * shell) static void __init handle_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD - int ram0 = kdev_t_to_nr(MKDEV(RAMDISK_MAJOR,0)); + kdev_t ram0 = mk_kdev(RAMDISK_MAJOR,0); int error; int i, pid; @@ -664,21 +761,19 @@ static void __init handle_initrd(void) pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); if (pid > 0) { - while (pid != wait(&i)) { - current->policy |= SCHED_YIELD; - schedule(); - } + while (pid != wait(&i)) + yield(); } sys_mount("..", ".", NULL, MS_MOVE, NULL); sys_umount("/old/dev", 0); - if (real_root_dev == ram0) { + if (real_root_dev == kdev_t_to_nr(ram0)) { sys_chdir("/old"); return; } - ROOT_DEV = real_root_dev; + ROOT_DEV = to_kdev_t(real_root_dev); mount_root(); printk(KERN_NOTICE "Trying to move old root to /initrd ... "); @@ -705,8 +800,8 @@ static void __init handle_initrd(void) static int __init initrd_load(void) { #ifdef CONFIG_BLK_DEV_INITRD - create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL); - create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL); + create_dev("/dev/ram", mk_kdev(RAMDISK_MAJOR, 0), NULL); + create_dev("/dev/initrd", mk_kdev(RAMDISK_MAJOR, INITRD_MINOR), NULL); #endif return rd_load_image("/dev/initrd"); } @@ -716,30 +811,28 @@ static int __init initrd_load(void) */ void prepare_namespace(void) { - int do_initrd = 0; - int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; + int is_floppy = major(ROOT_DEV) == FLOPPY_MAJOR; #ifdef CONFIG_BLK_DEV_INITRD if (!initrd_start) mount_initrd = 0; - if (mount_initrd) - do_initrd = 1; - real_root_dev = ROOT_DEV; + real_root_dev = kdev_t_to_nr(ROOT_DEV); #endif sys_mkdir("/dev", 0700); sys_mkdir("/root", 0700); + sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(TTYAUX_MAJOR, 1)); #ifdef CONFIG_DEVFS_FS sys_mount("devfs", "/dev", "devfs", 0, NULL); do_devfs = 1; #endif create_dev("/dev/root", ROOT_DEV, NULL); - if (do_initrd) { - if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) { + if (mount_initrd) { + if (initrd_load() && kdev_same(ROOT_DEV, mk_kdev(RAMDISK_MAJOR, 0))) { handle_initrd(); goto out; } } else if (is_floppy && rd_doload && rd_load_disk(0)) - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); mount_root(); out: sys_umount("/dev", 0); Index: init/main.c =================================================================== RCS file: /cvsroot/linuxsh/linux/init/main.c,v retrieving revision 1.3 diff -u -3 -p -r1.3 main.c --- init/main.c 2002/01/07 03:57:48 1.3 +++ init/main.c 2002/01/08 06:57:49 @@ -312,18 +312,9 @@ static void __init smp_init(void) /* Get other processors into their bootup holding patterns. */ smp_boot_cpus(); wait_init_idle = cpu_online_map; - clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */ smp_threads_ready=1; smp_commence(); - - /* Wait for the other cpus to set up their idle processes */ - printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle); - while (wait_init_idle) { - cpu_relax(); - barrier(); - } - printk("All processors have done init_idle\n"); } #endif @@ -339,7 +330,7 @@ static void rest_init(void) { kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); unlock_kernel(); - current->need_resched = 1; + init_idle(); /* This will also wait for all other CPUs */ cpu_idle(); } Index: kernel/ptrace.c =================================================================== RCS file: /cvsroot/linuxsh/linux/kernel/ptrace.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 ptrace.c --- kernel/ptrace.c 2001/12/03 22:15:35 1.2 +++ kernel/ptrace.c 2002/01/08 06:57:49 @@ -31,20 +31,7 @@ int ptrace_check_attach(struct task_stru if (child->state != TASK_STOPPED) return -ESRCH; #ifdef CONFIG_SMP - /* Make sure the child gets off its CPU.. */ - for (;;) { - task_lock(child); - if (!task_has_cpu(child)) - break; - task_unlock(child); - do { - if (child->state != TASK_STOPPED) - return -ESRCH; - barrier(); - cpu_relax(); - } while (task_has_cpu(child)); - } - task_unlock(child); + wait_task_inactive(child); #endif } @@ -121,120 +108,17 @@ int ptrace_detach(struct task_struct *ch } /* - * Access another process' address space, one page at a time. + * Access another process' address space. + * Source/target buffer must be kernel space, + * Do not walk the page table directly, use get_user_pages */ -static int access_one_page(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write) -{ - pgd_t * pgdir; - pmd_t * pgmiddle; - pte_t * pgtable; - char *maddr; - struct page *page; - -repeat: - spin_lock(&mm->page_table_lock); - pgdir = pgd_offset(vma->vm_mm, addr); - if (pgd_none(*pgdir)) - goto fault_in_page; - if (pgd_bad(*pgdir)) - goto bad_pgd; - pgmiddle = pmd_offset(pgdir, addr); - if (pmd_none(*pgmiddle)) - goto fault_in_page; - if (pmd_bad(*pgmiddle)) - goto bad_pmd; - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) - goto fault_in_page; - if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable))) - goto fault_in_page; - page = pte_page(*pgtable); - - /* ZERO_PAGE is special: reads from it are ok even though it's marked reserved */ - if (page != ZERO_PAGE(addr) || write) { - if ((!VALID_PAGE(page)) || PageReserved(page)) { - spin_unlock(&mm->page_table_lock); - return 0; - } - } - get_page(page); - spin_unlock(&mm->page_table_lock); - flush_cache_page(vma, addr); - - if (write) { - maddr = kmap(page); - memcpy(maddr + (addr & ~PAGE_MASK), buf, len); - flush_dcache_page(page); - flush_page_to_ram(page); - flush_icache_page(vma, page); - kunmap(page); - } else { - maddr = kmap(page); - memcpy(buf, maddr + (addr & ~PAGE_MASK), len); - flush_page_to_ram(page); - kunmap(page); - } - put_page(page); - return len; - -fault_in_page: - spin_unlock(&mm->page_table_lock); - /* -1: out of memory. 0 - unmapped page */ - if (handle_mm_fault(mm, vma, addr, write) > 0) - goto repeat; - return 0; - -bad_pgd: - spin_unlock(&mm->page_table_lock); - pgd_ERROR(*pgdir); - return 0; - -bad_pmd: - spin_unlock(&mm->page_table_lock); - pmd_ERROR(*pgmiddle); - return 0; -} - -static int access_mm(struct mm_struct *mm, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write) -{ - int copied = 0; - for (;;) { - unsigned long offset = addr & ~PAGE_MASK; - int this_len = PAGE_SIZE - offset; - int retval; - - if (this_len > len) - this_len = len; - retval = access_one_page(mm, vma, addr, buf, this_len, write); - copied += retval; - if (retval != this_len) - break; - - len -= retval; - if (!len) - break; - - addr += retval; - buf += retval; - - if (addr < vma->vm_end) - continue; - if (!vma->vm_next) - break; - if (vma->vm_next->vm_start != vma->vm_end) - break; - - vma = vma->vm_next; - } - return copied; -} - int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) { - int copied; struct mm_struct *mm; - struct vm_area_struct * vma; + struct vm_area_struct *vma; + struct page *page; + void *old_buf = buf; /* Worry about races with exit() */ task_lock(tsk); @@ -246,14 +130,41 @@ int access_process_vm(struct task_struct return 0; down_read(&mm->mmap_sem); - vma = find_extend_vma(mm, addr); - copied = 0; - if (vma) - copied = access_mm(mm, vma, addr, buf, len, write); + /* ignore errors, just check how much was sucessfully transfered */ + while (len) { + int bytes, ret, offset; + void *maddr; + + ret = get_user_pages(current, mm, addr, 1, + write, 1, &page, &vma); + if (ret <= 0) + break; + + bytes = len; + offset = addr & (PAGE_SIZE-1); + if (bytes > PAGE_SIZE-offset) + bytes = PAGE_SIZE-offset; + + flush_cache_page(vma, addr); + maddr = kmap(page); + if (write) { + memcpy(maddr + offset, buf, bytes); + flush_page_to_ram(page); + flush_icache_page(vma, page); + } else { + memcpy(buf, maddr + offset, bytes); + flush_page_to_ram(page); + } + kunmap(page); + put_page(page); + len -= bytes; + buf += bytes; + } up_read(&mm->mmap_sem); mmput(mm); - return copied; + + return buf - old_buf; } int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len) Index: mm/memory.c =================================================================== RCS file: /cvsroot/linuxsh/linux/mm/memory.c,v retrieving revision 1.4 diff -u -3 -p -r1.4 memory.c --- mm/memory.c 2002/01/07 03:57:48 1.4 +++ mm/memory.c 2002/01/08 06:57:49 @@ -397,17 +397,16 @@ void zap_page_range(struct mm_struct *mm spin_unlock(&mm->page_table_lock); } - /* * Do a quick page-table lookup for a single page. */ -static struct page * follow_page(unsigned long address, int write) +static struct page * follow_page(struct mm_struct *mm, unsigned long address, int write) { pgd_t *pgd; pmd_t *pmd; pte_t *ptep, pte; - pgd = pgd_offset(current->mm, address); + pgd = pgd_offset(mm, address); if (pgd_none(*pgd) || pgd_bad(*pgd)) goto out; @@ -443,21 +442,74 @@ static inline struct page * get_page_map return page; } +int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, + int len, int write, int force, struct page **pages, struct vm_area_struct **vmas) +{ + int i = 0; + + do { + struct vm_area_struct * vma; + + vma = find_extend_vma(mm, start); + + if ( !vma || + (!force && + ((write && (!(vma->vm_flags & VM_WRITE))) || + (!write && (!(vma->vm_flags & VM_READ))) ) )) { + if (i) return i; + return -EFAULT; + } + + spin_lock(&mm->page_table_lock); + do { + struct page *map; + while (!(map = follow_page(mm, start, write))) { + spin_unlock(&mm->page_table_lock); + switch (handle_mm_fault(mm, vma, start, write)) { + case 1: + tsk->min_flt++; + break; + case 2: + tsk->maj_flt++; + break; + case 0: + if (i) return i; + return -EFAULT; + default: + if (i) return i; + return -ENOMEM; + } + spin_lock(&mm->page_table_lock); + } + if (pages) { + pages[i] = get_page_map(map); + /* FIXME: call the correct function, + * depending on the type of the found page + */ + if (pages[i]) + page_cache_get(pages[i]); + } + if (vmas) + vmas[i] = vma; + i++; + start += PAGE_SIZE; + len--; + } while(len && start < vma->vm_end); + spin_unlock(&mm->page_table_lock); + } while(len); + return i; +} + /* * Force in an entire range of pages from the current process's user VA, * and pin them in physical memory. */ - #define dprintk(x...) + int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len) { - unsigned long ptr, end; - int err; + int pgcount, err; struct mm_struct * mm; - struct vm_area_struct * vma = 0; - struct page * map; - int i; - int datain = (rw == READ); /* Make sure the iobuf is not already mapped somewhere. */ if (iobuf->nr_pages) @@ -466,79 +518,37 @@ int map_user_kiobuf(int rw, struct kiobu mm = current->mm; dprintk ("map_user_kiobuf: begin\n"); - ptr = va & PAGE_MASK; - end = (va + len + PAGE_SIZE - 1) & PAGE_MASK; - err = expand_kiobuf(iobuf, (end - ptr) >> PAGE_SHIFT); + pgcount = (va + len + PAGE_SIZE - 1)/PAGE_SIZE - va/PAGE_SIZE; + /* mapping 0 bytes is not permitted */ + if (!pgcount) BUG(); + err = expand_kiobuf(iobuf, pgcount); if (err) return err; - down_read(&mm->mmap_sem); - - err = -EFAULT; iobuf->locked = 0; - iobuf->offset = va & ~PAGE_MASK; + iobuf->offset = va & (PAGE_SIZE-1); iobuf->length = len; - i = 0; - - /* - * First of all, try to fault in all of the necessary pages - */ - while (ptr < end) { - if (!vma || ptr >= vma->vm_end) { - vma = find_vma(current->mm, ptr); - if (!vma) - goto out_unlock; - if (vma->vm_start > ptr) { - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto out_unlock; - if (expand_stack(vma, ptr)) - goto out_unlock; - } - if (((datain) && (!(vma->vm_flags & VM_WRITE))) || - (!(vma->vm_flags & VM_READ))) { - err = -EACCES; - goto out_unlock; - } - } - spin_lock(&mm->page_table_lock); - while (!(map = follow_page(ptr, datain))) { - int ret; - - spin_unlock(&mm->page_table_lock); - ret = handle_mm_fault(current->mm, vma, ptr, datain); - if (ret <= 0) { - if (!ret) - goto out_unlock; - else { - err = -ENOMEM; - goto out_unlock; - } - } - spin_lock(&mm->page_table_lock); - } - map = get_page_map(map); - if (map) { - flush_dcache_page(map); - page_cache_get(map); - } else - printk (KERN_INFO "Mapped page missing [%d]\n", i); - spin_unlock(&mm->page_table_lock); - iobuf->maplist[i] = map; - iobuf->nr_pages = ++i; - - ptr += PAGE_SIZE; - } - + /* Try to fault in all of the necessary pages */ + down_read(&mm->mmap_sem); + /* rw==READ means read from disk, write into memory area */ + err = get_user_pages(current, mm, va, pgcount, + (rw==READ), 0, iobuf->maplist, NULL); up_read(&mm->mmap_sem); + if (err < 0) { + unmap_kiobuf(iobuf); + dprintk ("map_user_kiobuf: end %d\n", err); + return err; + } + iobuf->nr_pages = err; + while (pgcount--) { + /* FIXME: flush superflous for rw==READ, + * probably wrong function for rw==WRITE + */ + flush_dcache_page(iobuf->maplist[pgcount]); + } dprintk ("map_user_kiobuf: end OK\n"); return 0; - - out_unlock: - up_read(&mm->mmap_sem); - unmap_kiobuf(iobuf); - dprintk ("map_user_kiobuf: end %d\n", err); - return err; } /* @@ -588,6 +598,9 @@ void unmap_kiobuf (struct kiobuf *iobuf) if (map) { if (iobuf->locked) UnlockPage(map); + /* FIXME: cache flush missing for rw==READ + * FIXME: call the correct reference counting function + */ page_cache_release(map); } } @@ -1418,23 +1431,19 @@ out: return pte_offset(pmd, address); } -/* - * Simplistic page force-in.. - */ int make_pages_present(unsigned long addr, unsigned long end) { - int write; - struct mm_struct *mm = current->mm; + int ret, len, write; struct vm_area_struct * vma; - vma = find_vma(mm, addr); + vma = find_vma(current->mm, addr); write = (vma->vm_flags & VM_WRITE) != 0; if (addr >= end) BUG(); - do { - if (handle_mm_fault(mm, vma, addr, write) < 0) - return -1; - addr += PAGE_SIZE; - } while (addr < end); - return 0; + if (end > vma->vm_end) + BUG(); + len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE; + ret = get_user_pages(current, current->mm, addr, + len, write, 0, NULL, NULL); + return ret == len ? 0 : -1; } -- |