From 175e8c6e72a6453cf6c219b21523c068f070e79b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:10:14 -0500 Subject: [PATCH] Import 1.3.28 --- Makefile | 4 +- arch/alpha/config.in | 44 ++--- arch/alpha/kernel/bios32.c | 2 +- arch/alpha/kernel/irq.c | 24 ++- arch/alpha/kernel/osf_sys.c | 10 +- arch/alpha/kernel/process.c | 13 -- arch/alpha/kernel/setup.c | 4 +- arch/alpha/vmlinux.lds | 1 + arch/i386/config.in | 46 +++--- arch/i386/kernel/setup.c | 2 +- arch/mips/kernel/setup.c | 2 +- drivers/Makefile | 4 +- drivers/block/README.ide | 47 ++++-- drivers/block/aztcd.c | 4 +- drivers/block/blk.h | 24 +-- drivers/block/cdu31a.c | 10 +- drivers/block/cm206.c | 5 +- drivers/block/floppy.c | 81 +++++----- drivers/block/genhd.c | 72 +++++---- drivers/block/gscd.c | 10 +- drivers/block/hd.c | 48 +++--- drivers/block/ide-cd.c | 96 +++++++---- drivers/block/ide.c | 130 ++++++++++----- drivers/block/ide.h | 10 +- drivers/block/ll_rw_blk.c | 75 +++++---- drivers/block/mcd.c | 4 +- drivers/block/mcdx.c | 18 ++- drivers/block/ramdisk.c | 4 +- drivers/block/sbpcd.c | 17 +- drivers/block/sjcd.c | 4 +- drivers/block/sonycd535.c | 6 +- drivers/block/triton.c | 1 - drivers/block/xd.c | 48 +++--- drivers/char/Makefile | 2 +- drivers/char/conmakehash.c | 198 ++++++++--------------- drivers/char/console.c | 95 +++++++---- drivers/char/consolemap.c | 301 ++++++++++++++++++++++------------- drivers/char/consolemap.h | 2 +- drivers/char/cyclades.c | 18 +-- drivers/char/lp.c | 83 ++++++---- drivers/char/scc.c | 19 ++- drivers/char/selection.c | 2 +- drivers/char/selection.h | 1 + drivers/char/serial.c | 10 +- drivers/char/tpqic02.c | 21 +-- drivers/char/tty_io.c | 61 +++---- drivers/char/tty_ioctl.c | 2 +- drivers/char/vt.c | 19 +++ drivers/net/3c507.c | 2 +- drivers/net/eexpress.c | 2 +- drivers/net/plip.c | 144 ++++++++++------- drivers/net/ppp.c | 1 + drivers/pci/pci.c | 8 +- drivers/scsi/53c7,8xx.c | 8 +- drivers/scsi/53c7,8xx.h | 16 +- drivers/scsi/ChangeLog | 8 + drivers/scsi/Makefile | 19 +-- drivers/scsi/aha152x.c | 13 +- drivers/scsi/aha152x.h | 9 +- drivers/scsi/aha1542.c | 21 ++- drivers/scsi/aha1542.h | 8 +- drivers/scsi/aha1740.c | 10 +- drivers/scsi/aha1740.h | 7 +- drivers/scsi/aic7xxx.c | 10 +- drivers/scsi/aic7xxx.h | 5 +- drivers/scsi/buslogic.c | 18 ++- drivers/scsi/buslogic.h | 6 +- drivers/scsi/constants.c | 13 +- drivers/scsi/eata.c | 8 + drivers/scsi/eata.h | 4 +- drivers/scsi/eata_dma.c | 48 ++++-- drivers/scsi/eata_dma.h | 15 +- drivers/scsi/eata_dma_proc.c | 18 ++- drivers/scsi/eata_pio.c | 7 + drivers/scsi/eata_pio.h | 13 +- drivers/scsi/fdomain.c | 185 +++++++++++++++------ drivers/scsi/fdomain.h | 7 +- drivers/scsi/g_NCR5380.c | 8 + drivers/scsi/g_NCR5380.h | 5 +- drivers/scsi/hosts.c | 12 +- drivers/scsi/hosts.h | 22 ++- drivers/scsi/in2000.c | 12 +- drivers/scsi/in2000.h | 7 +- drivers/scsi/pas16.c | 12 +- drivers/scsi/pas16.h | 4 +- drivers/scsi/qlogic.c | 10 +- drivers/scsi/qlogic.h | 5 +- drivers/scsi/scsi.c | 194 +++++++++++++--------- drivers/scsi/scsi.h | 17 +- drivers/scsi/scsi_debug.c | 35 ++-- drivers/scsi/scsi_debug.h | 8 +- drivers/scsi/scsi_ioctl.c | 20 ++- drivers/scsi/scsi_proc.c | 171 +++++--------------- drivers/scsi/scsi_syms.c | 8 +- drivers/scsi/scsicam.c | 5 +- drivers/scsi/sd.c | 142 +++++++++-------- drivers/scsi/sd.h | 8 +- drivers/scsi/sd_ioctl.c | 8 +- drivers/scsi/seagate.c | 9 +- drivers/scsi/seagate.h | 7 +- drivers/scsi/sg.c | 25 ++- drivers/scsi/sr.c | 99 ++++++------ drivers/scsi/sr_ioctl.c | 13 +- drivers/scsi/st.c | 184 ++++++++++++--------- drivers/scsi/t128.c | 11 +- drivers/scsi/t128.h | 4 +- drivers/scsi/u14-34f.c | 10 +- drivers/scsi/u14-34f.h | 5 +- drivers/scsi/ultrastor.c | 9 +- drivers/scsi/ultrastor.h | 6 +- drivers/scsi/wd7000.c | 13 +- drivers/scsi/wd7000.h | 6 +- drivers/sound/Makefile | 10 +- drivers/sound/dmabuf.c | 2 + drivers/sound/soundcard.c | 37 +++-- fs/binfmt_elf.c | 4 +- fs/block_dev.c | 4 +- fs/buffer.c | 101 ++++++------ fs/dcache.c | 12 +- fs/devices.c | 18 ++- fs/ext/dir.c | 6 +- fs/ext/freelists.c | 2 +- fs/ext/inode.c | 20 +-- fs/ext/namei.c | 31 ++-- fs/ext2/inode.c | 9 +- fs/ext2/namei.c | 2 +- fs/ext2/super.c | 32 ++-- fs/hpfs/hpfs_fs.c | 34 ++-- fs/inode.c | 30 ++-- fs/ioctl.c | 10 +- fs/isofs/inode.c | 13 +- fs/isofs/rock.c | 6 +- fs/minix/bitmap.c | 3 +- fs/minix/inode.c | 33 ++-- fs/minix/namei.c | 10 +- fs/msdos/fat.c | 31 ++-- fs/msdos/inode.c | 23 +-- fs/msdos/misc.c | 20 +-- fs/msdos/namei.c | 3 +- fs/namei.c | 8 +- fs/nfs/dir.c | 13 +- fs/nfs/inode.c | 2 +- fs/proc/array.c | 8 +- fs/proc/fd.c | 2 + fs/proc/inode.c | 29 ---- fs/proc/link.c | 13 +- fs/proc/root.c | 5 +- fs/proc/scsi.c | 105 +----------- fs/smbfs/inode.c | 2 +- fs/stat.c | 8 +- fs/super.c | 54 +++---- fs/sysv/dir.c | 6 +- fs/sysv/ialloc.c | 3 +- fs/sysv/inode.c | 34 ++-- fs/sysv/namei.c | 10 +- fs/umsdos/dir.c | 2 +- fs/xiafs/bitmap.c | 13 +- fs/xiafs/inode.c | 21 +-- fs/xiafs/namei.c | 2 +- include/asm-alpha/irq.h | 10 ++ include/asm-i386/irq.h | 2 + include/linux/blkdev.h | 9 +- include/linux/fd.h | 2 +- include/linux/fs.h | 78 +++++---- include/linux/kd.h | 4 +- include/linux/kdev_t.h | 114 +++++++++++++ include/linux/kernel_stat.h | 4 +- include/linux/mc146818rtc.h | 7 +- include/linux/module.h | 2 +- include/linux/msdos_fs.h | 7 +- include/linux/optcd.h | 2 +- include/linux/pci.h | 4 +- include/linux/proc_fs.h | 37 ++++- include/linux/scsicam.h | 3 +- include/linux/sysv_fs.h | 6 +- include/linux/timex.h | 133 +++++++++++++--- include/linux/tty.h | 4 +- include/linux/tty_driver.h | 2 +- include/linux/user.h | 1 + include/linux/xd.h | 2 +- init/main.c | 10 +- kernel/exit.c | 3 +- kernel/fork.c | 34 ++-- kernel/info.c | 4 +- kernel/sched.c | 159 ++++++++++++------ kernel/sys.c | 28 ++-- kernel/time.c | 156 ++++++++++++------ mm/kmalloc.c | 4 +- mm/swap.c | 5 +- mm/vmalloc.c | 5 +- net/ipv4/tcp.c | 5 +- net/netrom/nr_dev.c | 2 +- scripts/Configure | 36 ++++- 193 files changed, 3063 insertions(+), 2118 deletions(-) create mode 100644 include/linux/kdev_t.h diff --git a/Makefile b/Makefile index 63b44596dc5c..86a265a43d46 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 27 +SUBLEVEL = 28 ARCH = i386 @@ -98,7 +98,7 @@ ifdef CONFIG_SCSI DRIVERS := $(DRIVERS) drivers/scsi/scsi.a endif -ifdef CONFIG_SOUND +ifeq ($(CONFIG_SOUND),y) DRIVERS := $(DRIVERS) drivers/sound/sound.a endif diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 8b59574a3104..87b77f08b8fb 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -87,7 +87,7 @@ fi comment 'SCSI support' -bool 'SCSI support' CONFIG_SCSI y +tristate 'SCSI support' CONFIG_SCSI y if [ "$CONFIG_SCSI" = "n" ]; then @@ -97,10 +97,10 @@ else comment 'SCSI support type (disk, tape, CDrom)' -tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y -tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n -tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y -tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n +dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y $CONFIG_SCSI +dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n $CONFIG_SCSI +dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y $CONFIG_SCSI +dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n $CONFIG_SCSI comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' @@ -108,28 +108,28 @@ bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n comment 'SCSI low-level drivers' -tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n -tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n -tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y -tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n -tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n -tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n -tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n -tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n -tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n +dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n $CONFIG_SCSI +dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI +dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y $CONFIG_SCSI +dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI +dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI +dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI +dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n $CONFIG_SCSI +dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n $CONFIG_SCSI +dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n if [ "$CONFIG_PCI" = "y" ]; then - tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n + dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n $CONFIG_SCSI fi -tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n +dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n -tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n -tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n +dep_tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n $CONFIG_SCSI +dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n $CONFIG_SCSI bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n -tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n -tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n -tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n -#tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n +dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n $CONFIG_SCSI +dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n $CONFIG_SCSI +dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n $CONFIG_SCSI +#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n $CONFIG_SCSI fi diff --git a/arch/alpha/kernel/bios32.c b/arch/alpha/kernel/bios32.c index 2651a396d2dc..d2874a37e254 100644 --- a/arch/alpha/kernel/bios32.c +++ b/arch/alpha/kernel/bios32.c @@ -401,7 +401,7 @@ static inline void enable_ide(long ide_base) */ static inline void common_fixup(long min_idsel, long max_idsel, long irqs_per_slot, char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot], - long ide_base) + long ide_base) { struct pci_dev *dev; unsigned char pin; diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 4f87929b2f8d..74738dae6e07 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -31,13 +31,9 @@ static unsigned char cache_A1 = 0xff; static unsigned char cache_804 = 0xef; static unsigned char cache_805 = 0xff; static unsigned char cache_806 = 0xff; -# define NUM_IRQS 33 #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) static unsigned char cache_26 = 0xdf; static unsigned char cache_27 = 0xff; -# define NUM_IRQS 32 -#else -# define NUM_IRQS 16 #endif void disable_irq(unsigned int irq_nr) @@ -103,7 +99,7 @@ void enable_irq(unsigned int irq_nr) cache_806 &= mask; outb(cache_806, 0x806); #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) - } else if if (irq_nr < 24) { + } else if (irq_nr < 24) { cache_26 &= mask; outb(cache_26, 0x26); } else { @@ -124,14 +120,14 @@ struct irqaction { const char *name; }; -static struct irqaction irq_action[NUM_IRQS]; +static struct irqaction irq_action[NR_IRQS]; int get_irq_list(char *buf) { int i, len = 0; struct irqaction * action = irq_action; - for (i = 0 ; i < NUM_IRQS ; i++, action++) { + for (i = 0 ; i < NR_IRQS ; i++, action++) { if (!action->handler) continue; len += sprintf(buf+len, "%2d: %8d %c %s\n", @@ -225,7 +221,7 @@ int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), struct irqaction * action; unsigned long flags; - if (irq >= NUM_IRQS) + if (irq >= NR_IRQS) return -EINVAL; action = irq + irq_action; if (action->handler) @@ -251,7 +247,7 @@ void free_irq(unsigned int irq) struct irqaction * action = irq + irq_action; unsigned long flags; - if (irq >= NUM_IRQS) { + if (irq >= NR_IRQS) { printk("Trying to free IRQ%d\n", irq); return; } @@ -310,7 +306,7 @@ static inline void device_interrupt(int irq, int ack, struct pt_regs * regs) { struct irqaction * action; - if ((unsigned) irq > NUM_IRQS) { + if ((unsigned) irq > NR_IRQS) { printk("device_interrupt: unexpected interrupt %d\n", irq); return; } @@ -473,7 +469,7 @@ static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * r device_interrupt(irq, ack, regs); } -#if NUM_IRQS > 64 +#if NR_IRQS > 64 # error Number of irqs limited to 64 due to interrupt-probing. #endif @@ -486,7 +482,7 @@ unsigned long probe_irq_on(void) unsigned long delay; unsigned int i; - for (i = NUM_IRQS - 1; i > 0; i--) { + for (i = NR_IRQS - 1; i > 0; i--) { if (!irq_action[i].handler) { enable_irq(i); irqs |= (1 << i); @@ -505,7 +501,7 @@ unsigned long probe_irq_on(void) (((unsigned long)cache_806)<<24)); #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) irqmask |= ((((unsigned long)cache_26)<<16) | - (((unsigned long)cache_27)<<24); + (((unsigned long)cache_27)<<24)); #endif irqs &= ~irqmask; return irqs; @@ -528,7 +524,7 @@ int probe_irq_off(unsigned long irqs) (((unsigned long)cache_806)<<24)); #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) irqmask |= ((((unsigned long)cache_26)<<16) | - (((unsigned long)cache_27)<<24); + (((unsigned long)cache_27)<<24)); #endif irqs &= irqmask; if (!irqs) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index bfa4a884bca5..e58982b72b59 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -32,14 +32,14 @@ #include #include -extern int do_mount(dev_t, const char *, char *, int, void *); +extern int do_mount(kdev_t, const char *, char *, int, void *); extern int do_pipe(int *); extern struct file_operations * get_blkfops(unsigned int); extern struct file_operations * get_chrfops(unsigned int); -extern dev_t get_unnamed_dev(void); -extern void put_unnamed_dev(dev_t); +extern kdev_t get_unnamed_dev(void); +extern void put_unnamed_dev(kdev_t); extern asmlinkage int sys_umount(char *); extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags); @@ -240,7 +240,7 @@ struct procfs_args { static int getdev(const char * name, int rdonly, struct inode ** ino) { - dev_t dev; + kdev_t dev; struct inode * inode; struct file_operations * fops; int retval; @@ -337,7 +337,7 @@ static int osf_cdfs_mount(char * dirname, struct cdfs_args * args, int flags) static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags) { - dev_t dev; + kdev_t dev; int retval; struct procfs_args tmp; diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index ae7cfc059999..2d372111eda2 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -168,16 +168,3 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, putname(filename); return error; } - -/* - * This doesn't actually work correctly like this: we need to do the - * same stack setups that fork() does first. - */ -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs regs) -{ - if (!newsp) - newsp = rdusp(); - return do_fork(clone_flags, newsp, ®s); -} diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 0608c2956fec..2abb706040e9 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -55,7 +55,7 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; * code think we're on a VGA color display. */ struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ + 0, 25, /* orig-x, orig-y */ { 0, 0 }, /* unused */ 0, /* orig-video-page */ 0, /* orig-video-mode */ @@ -97,7 +97,7 @@ void setup_arch(char **cmdline_p, set_hae(hae.cache); /* sync HAE register w/hae_cache */ wrmces(0x7); /* reset enable correctable error reports */ - ROOT_DEV = 0x0802; /* sda2 */ + ROOT_DEV = to_kdev_t(0x0802); /* sda2 */ command_line[COMMAND_LINE_SIZE - 1] = '\0'; strcpy(command_line, COMMAND_LINE); diff --git a/arch/alpha/vmlinux.lds b/arch/alpha/vmlinux.lds index bc6c6b6a8ae9..f29ecfe1b73c 100644 --- a/arch/alpha/vmlinux.lds +++ b/arch/alpha/vmlinux.lds @@ -40,6 +40,7 @@ SECTIONS .sbss : { *(.sbss) *(.scommon) + . = ALIGN(16); } .bss : { *(.bss) diff --git a/arch/i386/config.in b/arch/i386/config.in index beb7ee41d64e..8662c5c49087 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -78,7 +78,7 @@ fi comment 'SCSI support' -bool 'SCSI support' CONFIG_SCSI y +tristate 'SCSI support' CONFIG_SCSI y if [ "$CONFIG_SCSI" = "n" ]; then @@ -88,10 +88,10 @@ else comment 'SCSI support type (disk, tape, CDrom)' -tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y -tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n -tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y -tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n +dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y $CONFIG_SCSI +dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n $CONFIG_SCSI +dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y $CONFIG_SCSI +dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n $CONFIG_SCSI comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' @@ -99,28 +99,28 @@ bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n comment 'SCSI low-level drivers' -tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y -tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n -tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n -tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n -tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n -tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n -tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n -tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n -tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n +dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y $CONFIG_SCSI +dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI +dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n $CONFIG_SCSI +dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI +dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI +dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI +dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n $CONFIG_SCSI +dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n $CONFIG_SCSI +dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n if [ "$CONFIG_PCI" = "y" ]; then - tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n + dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n $CONFIG_SCSI fi -tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n +dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n -tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n -tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n +dep_tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n $CONFIG_SCSI +dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n $CONFIG_SCSI bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n -tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n -tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n -tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n -#tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n +dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n $CONFIG_SCSI +dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n $CONFIG_SCSI +dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n $CONFIG_SCSI +#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n $CONFIG_SCSI fi @@ -303,7 +303,7 @@ fi comment 'Sound' -bool 'Sound card support' CONFIG_SOUND n +tristate 'Sound card support' CONFIG_SOUND n comment 'Kernel hacking' diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index f7cb717f70ac..a4637163311a 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -83,7 +83,7 @@ void setup_arch(char **cmdline_p, char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; - ROOT_DEV = ORIG_ROOT_DEV; + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; aux_device_present = AUX_DEVICE_INFO; diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 9bf2a5b4d3c9..c85927bf8f22 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -75,7 +75,7 @@ void setup_arch(char **cmdline_p, int len = 0; #if 0 - ROOT_DEV = ORIG_ROOT_DEV; + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); #endif drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; diff --git a/drivers/Makefile b/drivers/Makefile index 9992b24fd92a..99c683f4cf83 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -20,11 +20,9 @@ SUB_DIRS += scsi MOD_SUB_DIRS += scsi endif -# I think this should have an else clause for modules, but the original -# makefile did not, so I am not adding it. -# -jln 12 Aug 1995 ifdef CONFIG_SOUND SUB_DIRS += sound +MOD_SUB_DIRS += sound endif include $(TOPDIR)/Rules.make diff --git a/drivers/block/README.ide b/drivers/block/README.ide index 619360eb10ba..b2e5e4e3158f 100644 --- a/drivers/block/README.ide +++ b/drivers/block/README.ide @@ -29,26 +29,27 @@ NEW! (both are now probed for) - can co-exist with hd.c controlling the first interface - run-time selectable 32bit interface support (using hdparm-2.3) NEW! - support for reliable operation of buggy RZ1000 interfaces -NEW! - PCI support is automatic + - PCI support is automatic NEW! - support for reliable operation of buggy CMD-640 interfaces -NEW! - PCI support is automatic -NEW! - for VLB, use kernel command line option: ide0=cmd640_vlb -NEW! - this support also enables the secondary i/f on most cards + - PCI support is automatic + - for VLB, use kernel command line option: ide0=cmd640_vlb + - this support also enables the secondary i/f on most cards NEW! - support for secondary interface on the FGI/Holtek HT-6560B VLB i/f -NEW! - use kernel command line option: ide1=ht6560 + - use kernel command line option: ide1=ht6560 NEW! - experimental support for DTC-2278D interfaces -NEW! - use kernel command line option: ide1=dtc2278 + - use kernel command line option: ide1=dtc2278 NEW! - support for drives with a stuck WRERR_STAT bit NEW! - support for removeable devices, including door lock/unlock NEW! - transparent support for DiskManager 6.0x and "Dynamic Disk Overlay" -NEW! - works with Linux fdisk, LILO, loadlin, bootln, etc.. -NEW! - should work for for EZ-Drive disks as well (not verified) + - works with Linux fdisk, LILO, loadlin, bootln, etc.. +NEW! - mostly transparent support for EZ-Drive + - LILO is incompatible (also harmless) with EZ-Drive NEW! - ide-cd.c now compiles separate from ide.c NEW! - Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces -NEW! - for details, see comments at top of triton.c + - for details, see comments at top of triton.c NEW! - ide-cd.c now supports door locking and auto-loading. -NEW! Also preliminary support for multisession and direct -NEW! reads of audio data. + - Also preliminary support for multisession + and direct reads of audio data. For work in progress, see the comments in ide.c, ide-cd.c, and triton.c. @@ -451,3 +452,27 @@ Triblet@Almaden.IBM.Com San Jose, CA Silicon Valley - best day job in the world + +================================================================================ + + from: 'delman@mipg.upenn.edu' + subject: rz1000 + +Hi Mark! Looks like you managed to get the info from Intel to disable +the read-ahead feature of the RZ1000. My encounter with +Zeos (subsidiary of Micron which owns PCTech) has not been as +successful --- one guy needs to ask his supervisors about NDA, another +guy thinks that there is too much of a performance hit with read-ahead +disabled. + +Did the following benchmark to see how true the claim is. +With Linux 1.2.13, average of 10 "hdparm -t" in MB/s: + + hdparm -c0 hdparm -c1 +read-ahead enabled 4.28 4.25 +read-ahead disabled 3.58 4.30 + +Maybe -c1 should be the default for the RZ1000, or as a suggestion in +the README for people with the RZ1000. + +Cheers, Delman. diff --git a/drivers/block/aztcd.c b/drivers/block/aztcd.c index 2a1566d00be5..9186324e5ccc 100644 --- a/drivers/block/aztcd.c +++ b/drivers/block/aztcd.c @@ -195,7 +195,7 @@ static int aztPresent = 0; #endif #define CURRENT_VALID \ - (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR && CURRENT -> cmd == READ \ + (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \ && CURRENT -> sector != -1) #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA) @@ -547,7 +547,7 @@ static int aztSetDiskType(int type) /* * Checking if the media has been changed not yet implemented */ -static int check_aztcd_media_change(dev_t full_dev) +static int check_aztcd_media_change(kdev_t full_dev) { return 0; } diff --git a/drivers/block/blk.h b/drivers/block/blk.h index d568b944b799..51c9ab6d6dbc 100644 --- a/drivers/block/blk.h +++ b/drivers/block/blk.h @@ -19,7 +19,7 @@ */ #define IN_ORDER(s1,s2) \ ((s1)->cmd < (s2)->cmd || ((s1)->cmd == (s2)->cmd && \ -((s1)->dev < (s2)->dev || (((s1)->dev == (s2)->dev && \ +((s1)->rq_dev < (s2)->rq_dev || (((s1)->rq_dev == (s2)->rq_dev && \ (s1)->sector < (s2)->sector))))) /* @@ -30,8 +30,8 @@ #define SECTOR_MASK ((BLOCK_SIZE >> 9) - 1) #else #define SECTOR_MASK (blksize_size[MAJOR_NR] && \ - blksize_size[MAJOR_NR][MINOR(CURRENT->dev)] ? \ - ((blksize_size[MAJOR_NR][MINOR(CURRENT->dev)] >> 9) - 1) : \ + blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] ? \ + ((blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] >> 9) - 1) : \ ((BLOCK_SIZE >> 9) - 1)) #endif /* IDE_DRIVER */ @@ -73,7 +73,7 @@ extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end); #ifdef CONFIG_BLK_DEV_IDE extern unsigned long ide_init(unsigned long mem_start, unsigned long mem_end); #endif -extern void set_device_ro(int dev,int flag); +extern void set_device_ro(kdev_t dev,int flag); extern int floppy_init(void); extern void rd_load(void); @@ -107,7 +107,7 @@ extern unsigned long xd_init(unsigned long mem_start, unsigned long mem_end); /* ram disk */ #define DEVICE_NAME "ramdisk" #define DEVICE_REQUEST do_rd_request -#define DEVICE_NR(device) ((device) & 7) +#define DEVICE_NR(device) (MINOR(device) & 7) #define DEVICE_ON(device) #define DEVICE_OFF(device) @@ -118,7 +118,7 @@ static void floppy_off(unsigned int nr); #define DEVICE_NAME "floppy" #define DEVICE_INTR do_floppy #define DEVICE_REQUEST do_fd_request -#define DEVICE_NR(device) ( ((device) & 3) | (((device) & 0x80 ) >> 5 )) +#define DEVICE_NR(device) ( (MINOR(device) & 3) | ((MINOR(device) & 0x80 ) >> 5 )) #define DEVICE_ON(device) #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) @@ -283,7 +283,7 @@ static void floppy_off(unsigned int nr); #define CURRENT (blk_dev[MAJOR_NR].current_request) #endif -#define CURRENT_DEV DEVICE_NR(CURRENT->dev) +#define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev) #ifdef DEVICE_INTR void (*DEVICE_INTR)(void) = NULL; @@ -322,7 +322,7 @@ static void (DEVICE_REQUEST)(void); CLEAR_INTR; \ return; \ } \ - if (MAJOR(CURRENT->dev) != MAJOR_NR) \ + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ panic(DEVICE_NAME ": request list destroyed"); \ if (CURRENT->bh) { \ if (!CURRENT->bh->b_lock) \ @@ -351,8 +351,8 @@ static void end_request(int uptodate) { req->errors = 0; if (!uptodate) { - printk("end_request: I/O error, dev %04lX, sector %lu\n", - (unsigned long)req->dev, req->sector); + printk("end_request: I/O error, dev %s, sector %lu\n", + kdevname(req->rq_dev), req->sector); req->nr_sectors--; req->nr_sectors &= ~SECTOR_MASK; req->sector += (BLOCK_SIZE / 512); @@ -378,12 +378,12 @@ static void end_request(int uptodate) { #ifdef IDE_DRIVER hwgroup->rq = NULL; #else - DEVICE_OFF(req->dev); + DEVICE_OFF(req->rq_dev); CURRENT = req->next; #endif /* IDE_DRIVER */ if (req->sem != NULL) up(req->sem); - req->dev = -1; + req->rq_status = RQ_INACTIVE; wake_up(&wait_for_request); } #endif /* ndef _IDE_CD_C */ diff --git a/drivers/block/cdu31a.c b/drivers/block/cdu31a.c index 5b3388b89057..780bd099e29d 100644 --- a/drivers/block/cdu31a.c +++ b/drivers/block/cdu31a.c @@ -352,7 +352,7 @@ static int abort_read_started = 0; * check or 0 if it hasn't. */ static int -scd_disk_change(dev_t full_dev) +scd_disk_change(kdev_t full_dev) { int retval; @@ -1483,7 +1483,7 @@ do_cdu31a_request(void) if (current->signal & ~current->blocked) { restore_flags(flags); - if (CURRENT && (CURRENT->dev > 0)) + if (CURRENT && CURRENT->rq_status != RQ_INACTIVE) { end_request(0); } @@ -1513,7 +1513,7 @@ cdu31a_request_startover: * The beginning here is stolen from the hard disk driver. I hope * it's right. */ - if (!(CURRENT) || CURRENT->dev < 0) + if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) { goto end_do_cdu31a_request; } @@ -1525,14 +1525,14 @@ cdu31a_request_startover: /* This is a kludge to get a valid dev in an inode that scd_open can take. That's the only thing scd_open() uses the inode for. */ - in.i_rdev = CURRENT->dev; + in.i_rdev = CURRENT->rq_dev; scd_open(&in,NULL); } /* I don't use INIT_REQUEST because it calls return, which would return without unlocking the device. It shouldn't matter, but just to be safe... */ - if (MAJOR(CURRENT->dev) != MAJOR_NR) + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) { panic(DEVICE_NAME ": request list destroyed"); } diff --git a/drivers/block/cm206.c b/drivers/block/cm206.c index 487f7eb6c36d..e5409344213a 100644 --- a/drivers/block/cm206.c +++ b/drivers/block/cm206.c @@ -638,7 +638,7 @@ int try_adapter(int sector) } /* This is not a very smart implementation. We could optimize for - consecutive block numbers. I'm not conviced this would really + consecutive block numbers. I'm not convinced this would really bring down the processor load. */ static void do_cm206_request(void) { @@ -648,7 +648,8 @@ static void do_cm206_request(void) while(1) { /* repeat until all requests have been satisfied */ INIT_REQUEST; - if (CURRENT == NULL || CURRENT->dev == -1) return; + if (CURRENT == NULL || CURRENT->rq_status == RQ_INACTIVE) + return; if (CURRENT->cmd != READ) { debug(("Non-read command %d on cdrom\n", CURRENT->cmd)); end_request(0); diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index c5cf11fe03d6..c91c194bf252 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -105,7 +105,7 @@ static int print_unex=1; #include /* - * NB. we must include the kernel idenfication string in to install the module. + * NB. we must include the kernel identification string to install the module. */ #include char kernel_version[] = UTS_RELEASE; @@ -208,8 +208,19 @@ static int initialising=1; #define N_FDC 2 #define N_DRIVE 8 -#define TYPE(x) ( ((x)>>2) & 0x1f ) -#define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5)) +static inline int ITYPE(int x) { + return (x>>2) & 0x1f; +} +static inline int XTYPE(int x) { /* called with a fd_device field as arg */ + return ITYPE(x); +} +static inline int TYPE(kdev_t x) { + return (MINOR(x)>>2) & 0x1f; +} +static inline int DRIVE(kdev_t x) { + return (MINOR(x)&0x03) | ((MINOR(x)&0x80 ) >> 5); +} +#define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) #define UNIT(x) ( (x) & 0x03 ) /* drive on fdc */ #define FDC(x) ( ((x) & 0x04) >> 2 ) /* fdc of drive */ #define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 )) @@ -683,7 +694,7 @@ static int disk_change(int drive) DPRINT("Disk type is undefined after " "disk change\n"); current_type[drive] = NULL; - floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] = MAX_DISK_SIZE; + floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE; } } /*USETF(FD_DISK_NEWCHANGE);*/ @@ -1969,7 +1980,7 @@ static void bad_flp_intr(void) DRS->track = NEED_2_RECAL; } -static void set_floppy(int device) +static void set_floppy(kdev_t device) { if (TYPE(device)) floppy = TYPE(device) + floppy_type; @@ -2072,7 +2083,7 @@ static struct cont_t format_cont={ bad_flp_intr, generic_done }; -static int do_format(int device, struct format_descr *tmp_format_req) +static int do_format(kdev_t device, struct format_descr *tmp_format_req) { int ret; int drive=DRIVE(device); @@ -2208,8 +2219,7 @@ static void rw_interrupt(void) return; } current_type[current_drive] = floppy; - floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] = - floppy->size >> 1; + floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1; break; } @@ -2218,8 +2228,7 @@ static void rw_interrupt(void) DPRINT2("Auto-detected floppy type %s in fd%d\n", floppy->name,current_drive); current_type[current_drive] = floppy; - floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] = - floppy->size >> 1; + floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1; probing = 0; } @@ -2381,7 +2390,7 @@ static int make_raw_rw_request(void) int aligned_sector_t; int max_sector, max_size, tracksize, ssize; - set_fdc(DRIVE(CURRENT->dev)); + set_fdc(DRIVE(CURRENT->rq_dev)); raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; @@ -2616,18 +2625,18 @@ static int make_raw_rw_request(void) static void redo_fd_request(void) { #define REPEAT {request_done(0); continue; } - int device; + kdev_t device; int tmp; - int error; - +#if 0 + kdev_t error = 0; +#endif - error = -1; lastredo = jiffies; if (current_drive < N_DRIVE) floppy_off(current_drive); - if (CURRENT && CURRENT->dev < 0){ - DPRINT("current dev < 0!\n"); + if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){ + DPRINT("current not active!\n"); return; } @@ -2637,20 +2646,20 @@ static void redo_fd_request(void) unlock_fdc(); return; } - if (MAJOR(CURRENT->dev) != MAJOR_NR) + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) panic(DEVICE_NAME ": request list destroyed"); if (CURRENT->bh && !CURRENT->bh->b_lock) panic(DEVICE_NAME ": block not locked"); #if 0 if (!CURRENT->bh->b_count && - (CURRENT->errors || error == CURRENT->dev)){ - error=CURRENT->dev; + (CURRENT->errors || error == CURRENT->rq_dev)){ + error = CURRENT->rq_dev; DPRINT("skipping read ahead buffer\n"); REPEAT; } + error = 0; #endif - error=-1; - device = CURRENT->dev; + device = CURRENT->rq_dev; set_fdc( DRIVE(device)); reschedule_timeout(CURRENTD, "redo fd request", 0); @@ -2904,7 +2913,7 @@ static int raw_cmd_ioctl(void *param) return COPYOUT(raw_cmd); } -static int invalidate_drive(int rdev) +static int invalidate_drive(kdev_t rdev) { /* invalidate the buffer track to force a reread */ set_bit( DRIVE(rdev), &fake_change); @@ -2922,7 +2931,8 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, struct floppy_struct newparams; struct format_descr tmp_format_req; - int i,device,drive,type,cnt; + int i,drive,type,cnt; + kdev_t device; struct floppy_struct *this_floppy; const char *name; @@ -3021,7 +3031,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return -EPERM; LOCK_FDC(drive,1); for ( cnt = 0; cnt < N_DRIVE; cnt++){ - if (TYPE(drive_state[cnt].fd_device) == type && + if (XTYPE(drive_state[cnt].fd_device) == type && drive_state[cnt].fd_ref) set_bit(drive, &fake_change); } @@ -3035,10 +3045,9 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, floppy_type[type].size>>1; process_fd_request(); for ( cnt = 0; cnt < N_DRIVE; cnt++){ - if (TYPE(drive_state[cnt].fd_device) == type && - drive_state[cnt].fd_ref) - check_disk_change(drive_state[cnt]. - fd_device); + if (XTYPE(drive_state[cnt].fd_device) == type && + drive_state[cnt].fd_ref) + check_disk_change(to_kdev_t(drive_state[cnt].fd_device)); } return 0; } @@ -3203,7 +3212,7 @@ static void floppy_release(struct inode * inode, struct file * filp) static int floppy_open(struct inode * inode, struct file * filp) { int drive; - int old_dev; + kdev_t old_dev; int try; char *tmp; @@ -3221,7 +3230,7 @@ static int floppy_open(struct inode * inode, struct file * filp) if (TYPE(inode->i_rdev) >= NUMBER(floppy_type)) return -ENXIO; - old_dev = UDRS->fd_device; + old_dev = to_kdev_t(UDRS->fd_device); if (UDRS->fd_ref && old_dev != inode->i_rdev) return -EBUSY; @@ -3269,7 +3278,7 @@ static int floppy_open(struct inode * inode, struct file * filp) } } - UDRS->fd_device = inode->i_rdev; + UDRS->fd_device = kdev_t_to_nr(inode->i_rdev); if (old_dev && old_dev != inode->i_rdev) { if (buffer_drive == drive) @@ -3303,7 +3312,7 @@ static int floppy_open(struct inode * inode, struct file * filp) /* * Check if the disk has been changed or if a change has been faked. */ -static int check_floppy_change(dev_t dev) +static int check_floppy_change(kdev_t dev) { int drive = DRIVE( dev ); @@ -3333,7 +3342,7 @@ static int check_floppy_change(dev_t dev) * the bootblock (block 0). "Autodetection" is also needed to check whether * there is a disk in the drive at all... Thus we also do it for fixed * geometry formats */ -static int floppy_revalidate(dev_t dev) +static int floppy_revalidate(kdev_t dev) { #define NO_GEOM (!current_type[drive] && !TYPE(dev)) struct buffer_head * bh; @@ -3582,8 +3591,8 @@ int floppy_init(void) } for(i=0; i<256; i++) - if ( TYPE(i)) - floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1; + if ( ITYPE(i)) + floppy_sizes[i] = floppy_type[ITYPE(i)].size >> 1; else floppy_sizes[i] = MAX_DISK_SIZE; diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 16ac5294cc61..d99f67592171 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -75,7 +75,7 @@ static void add_partition (struct gendisk *hd, int minor, int start, int size) * only for the actual data partitions. */ -static void extended_partition(struct gendisk *hd, int dev) +static void extended_partition(struct gendisk *hd, kdev_t dev) { struct buffer_head *bh; struct partition *p; @@ -150,18 +150,19 @@ static void extended_partition(struct gendisk *hd, int dev) hd->part[current_minor].nr_sects = p->nr_sects; hd->part[current_minor].start_sect = first_sector + p->start_sect; this_sector = first_sector + p->start_sect; - dev = ((hd->major) << 8) | current_minor; + dev = MKDEV(hd->major, current_minor); brelse(bh); } done: brelse(bh); } -static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector) +static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) { int i, minor = current_minor; struct buffer_head *bh; struct partition *p; + unsigned char *data; int mask = (1 << hd->minor_shift) - 1; #ifdef CONFIG_BLK_DEV_IDE int tested_for_dm6 = 0; @@ -172,21 +173,40 @@ read_mbr: printk(" unable to read partition table\n"); return -1; } - if (*(unsigned short *) (0x1fe + bh->b_data) != 0xAA55) { + data = bh->b_data; + bh->b_dirt = 0; /* In some cases we modify the geometry */ + bh->b_uptodate = 0; /* of the drive (below), so ensure that */ + bh->b_req = 0; /* nobody else tries to re-use this data. */ +#ifdef CONFIG_BLK_DEV_IDE +check_table: +#endif + if (*(unsigned short *) (0x1fe + data) != 0xAA55) { brelse(bh); return 0; } - p = (struct partition *) (0x1be + bh->b_data); + p = (struct partition *) (0x1be + data); #ifdef CONFIG_BLK_DEV_IDE /* * Check for Disk Manager v6.0x (or EZ-DRIVE) with geometry translation */ if (!tested_for_dm6++) { /* only check for DM6 *once* */ - extern int ide_xlate_1024(dev_t, int, const char *); - /* check for DM6 with Dynamic Drive Overlay (DDO) */ - if (p->sys_ind == DM6_PARTITION || p->sys_ind == EZD_PARTITION) { - const char *label = (p->sys_ind == DM6_PARTITION)?" [DM6:DDO]":" [EZDRIVE]"; + extern int ide_xlate_1024(kdev_t, int, const char *); + /* check for various "disk managers" which do strange things */ + if (p->sys_ind == EZD_PARTITION) { + /* + * The remainder of the disk must be accessed using + * a translated geometry that reduces the number of + * apparent cylinders to less than 1024 if possible. + * + * ide_xlate_1024() will take care of the necessary + * adjustments to fool fdisk/LILO and partition check. + */ + if (ide_xlate_1024(dev, -1, " [EZD]")) { + data += 512; + goto check_table; + } + } else if (p->sys_ind == DM6_PARTITION) { /* * Everything on the disk is offset by 63 sectors, @@ -198,19 +218,16 @@ read_mbr: * ide_xlate_1024() will take care of the necessary * adjustments to fool fdisk/LILO and partition check. */ - if (ide_xlate_1024(dev, 1, label)) { - bh->b_dirt = 0; /* force re-read of MBR block */ - bh->b_uptodate = 0; - bh->b_req = 0; + if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) { brelse(bh); goto read_mbr; /* start over with new MBR */ } } else { /* look for DM6 signature in MBR, courtesy of OnTrack */ - unsigned int sig = *(unsigned short *)(bh->b_data + 2); + unsigned int sig = *(unsigned short *)(data + 2); if (sig <= 0x1ae - && *(unsigned short *)(bh->b_data + sig) == 0x55AA - && (1 & *(unsigned char *)(bh->b_data + sig + 2)) ) + && *(unsigned short *)(data + sig) == 0x55AA + && (1 & *(unsigned char *)(data + sig + 2)) ) { (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]"); } else { @@ -218,7 +235,7 @@ read_mbr: if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) { - (void)ide_xlate_1024(dev,0," [DM6:AUX]"); + (void)ide_xlate_1024(dev, 0, " [DM6:AUX]"); } } } @@ -242,7 +259,7 @@ read_mbr: */ hd->sizes[minor] = hd->part[minor].nr_sects >> (BLOCK_SIZE_BITS - 9); - extended_partition(hd, (hd->major << 8) | minor); + extended_partition(hd, MKDEV(hd->major, minor)); printk(" >"); /* prevent someone doing mkfs or mkswap on an extended partition */ @@ -252,8 +269,8 @@ read_mbr: /* * Check for old-style Disk Manager partition table */ - if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) { - p = (struct partition *) (0x1be + bh->b_data); + if (*(unsigned short *) (data+0xfc) == 0x55AA) { + p = (struct partition *) (0x1be + data); for (i = 4 ; i < 16 ; i++, current_minor++) { p--; if ((current_minor & mask) >= mask-2) @@ -340,7 +357,7 @@ static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long fir #endif /* CONFIG_OSF_PARTITION */ -static void check_partition(struct gendisk *hd, unsigned int dev) +static void check_partition(struct gendisk *hd, kdev_t dev) { static int first_time = 1; unsigned long first_sector; @@ -352,7 +369,7 @@ static void check_partition(struct gendisk *hd, unsigned int dev) /* * This is a kludge to allow the partition check to be - * skipped for specific drives (ie. IDE cd-rom drives) + * skipped for specific drives (e.g. IDE cd-rom drives) */ if ((int)first_sector == -1) { hd->part[MINOR(dev)].start_sect = 0; @@ -384,13 +401,12 @@ can start using the device while this function is being executed. */ void resetup_one_dev(struct gendisk *dev, int drive) { int i; - int major = dev->major << 8; int first_minor = drive << dev->minor_shift; int end_minor = first_minor + dev->max_p; blk_size[dev->major] = NULL; current_minor = 1 + first_minor; - check_partition(dev, major + first_minor); + check_partition(dev, MKDEV(dev->major, first_minor)); /* * We need to set the sizes array before we will be able to access @@ -406,7 +422,6 @@ void resetup_one_dev(struct gendisk *dev, int drive) static void setup_dev(struct gendisk *dev) { int i, drive; - int major = dev->major << 8; int end_minor = dev->max_nr * dev->max_p; blk_size[dev->major] = NULL; @@ -418,7 +433,7 @@ static void setup_dev(struct gendisk *dev) for (drive = 0 ; drive < dev->nr_real ; drive++) { int first_minor = drive << dev->minor_shift; current_minor = 1 + first_minor; - check_partition(dev, major + first_minor); + check_partition(dev, MKDEV(dev->major, first_minor)); } if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ for (i = 0; i < end_minor; i++) @@ -426,12 +441,15 @@ static void setup_dev(struct gendisk *dev) blk_size[dev->major] = dev->sizes; } } - + void device_setup(void) { + extern void console_map_init(void); struct gendisk *p; int nr=0; + console_map_init(); + for (p = gendisk_head ; p ; p=p->next) { setup_dev(p); nr += p->nr_real; diff --git a/drivers/block/gscd.c b/drivers/block/gscd.c index a4d181569ba7..ea001468607f 100644 --- a/drivers/block/gscd.c +++ b/drivers/block/gscd.c @@ -95,7 +95,7 @@ static void do_gscd_request (void); static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long); static int gscd_open (struct inode *, struct file *); static void gscd_release (struct inode *, struct file *); -static int check_gscd_med_chg (dev_t); +static int check_gscd_med_chg (kdev_t); /* GoldStar Funktionen */ @@ -177,7 +177,7 @@ static struct file_operations gscd_fops = { * Checking if the media has been changed * (not yet implemented) */ -static int check_gscd_med_chg (dev_t full_dev) +static int check_gscd_med_chg (kdev_t full_dev) { int target; @@ -270,9 +270,9 @@ unsigned int block,dev; unsigned int nsect; repeat: - if (!(CURRENT) || CURRENT->dev < 0) return; + if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) return; INIT_REQUEST; - dev = MINOR(CURRENT->dev); + dev = MINOR(CURRENT->rq_dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; @@ -286,7 +286,7 @@ repeat: goto repeat; } - if (MINOR(CURRENT -> dev) != 0) + if (MINOR(CURRENT -> rq_dev) != 0) { printk("GSCD: this version supports only one device\n"); end_request(0); diff --git a/drivers/block/hd.c b/drivers/block/hd.c index b044c60207ae..a9683f323535 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -44,7 +44,7 @@ #define MAJOR_NR HD_MAJOR #include "blk.h" -static int revalidate_hddisk(int, int); +static int revalidate_hddisk(kdev_t, int); #define HD_DELAY 0 @@ -131,7 +131,7 @@ static void dump_status (const char *msg, unsigned int stat) unsigned long flags; char devc; - devc = CURRENT ? 'a' + DEVICE_NR(CURRENT->dev) : '?'; + devc = CURRENT ? 'a' + DEVICE_NR(CURRENT->rq_dev) : '?'; save_flags (flags); sti(); printk("hd%c: %s: status=0x%02x { ", devc, msg, stat & 0xff); @@ -280,7 +280,7 @@ static void fixstring (unsigned char *s, int bytecount) static void identify_intr(void) { - unsigned int dev = DEVICE_NR(CURRENT->dev); + unsigned int dev = DEVICE_NR(CURRENT->rq_dev); unsigned short stat = inb_p(HD_STATUS); struct hd_driveid *id = hd_ident_info[dev]; @@ -333,7 +333,7 @@ static void identify_intr(void) static void set_multmode_intr(void) { - unsigned int dev = DEVICE_NR(CURRENT->dev), stat = inb_p(HD_STATUS); + unsigned int dev = DEVICE_NR(CURRENT->rq_dev), stat = inb_p(HD_STATUS); if (unmask_intr[dev]) sti(); @@ -447,7 +447,7 @@ static void bad_rw_intr(void) if (!CURRENT) return; - dev = DEVICE_NR(CURRENT->dev); + dev = DEVICE_NR(CURRENT->rq_dev); if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { end_request(0); special_op[dev] = recalibrate[dev] = 1; @@ -471,7 +471,7 @@ static inline int wait_DRQ(void) static void read_intr(void) { - unsigned int dev = DEVICE_NR(CURRENT->dev); + unsigned int dev = DEVICE_NR(CURRENT->rq_dev); int i, retries = 100000, msect = mult_count[dev], nsect; if (unmask_intr[dev]) @@ -546,7 +546,7 @@ static inline void multwrite (unsigned int dev) static void multwrite_intr(void) { int i; - unsigned int dev = DEVICE_NR(WCURRENT.dev); + unsigned int dev = DEVICE_NR(WCURRENT.rq_dev); if (unmask_intr[dev]) sti(); @@ -582,7 +582,7 @@ static void write_intr(void) int i; int retries = 100000; - if (unmask_intr[DEVICE_NR(WCURRENT.dev)]) + if (unmask_intr[DEVICE_NR(WCURRENT.rq_dev)]) sti(); do { i = (unsigned) inb_p(HD_STATUS); @@ -640,7 +640,7 @@ static void hd_times_out(void) disable_irq(HD_IRQ); sti(); reset = 1; - dev = DEVICE_NR(CURRENT->dev); + dev = DEVICE_NR(CURRENT->rq_dev); printk("hd%c: timeout\n", dev+'a'); if (++CURRENT->errors >= MAX_ERRORS) { #ifdef DEBUG @@ -695,7 +695,7 @@ static void hd_request(void) { unsigned int dev, block, nsect, sec, track, head, cyl; - if (CURRENT && CURRENT->dev < 0) return; + if (CURRENT && CURRENT->rq_status == RQ_INACTIVE) return; if (DEVICE_INTR) return; repeat: @@ -707,16 +707,17 @@ repeat: reset_hd(); return; } - dev = MINOR(CURRENT->dev); + dev = MINOR(CURRENT->rq_dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) { #ifdef DEBUG if (dev >= (NR_HD<<6)) - printk("hd: bad minor number: device=0x%04x\n", CURRENT->dev); + printk("hd: bad minor number: device=%s\n", + kdevname(CURRENT->rq_dev)); else printk("hd%c: bad access: block=%d, count=%d\n", - (CURRENT->dev>>6)+'a', block, nsect); + (MINOR(CURRENT->rq_dev)>>6)+'a', block, nsect); #endif end_request(0); goto repeat; @@ -781,7 +782,7 @@ static int hd_ioctl(struct inode * inode, struct file * file, int dev, err; unsigned long flags; - if ((!inode) || (!inode->i_rdev)) + if ((!inode) || !(inode->i_rdev)) return -EINVAL; dev = DEVICE_NR(inode->i_rdev); if (dev >= NR_HD) @@ -1076,16 +1077,16 @@ unsigned long hd_init(unsigned long mem_start, unsigned long mem_end) * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */ -static int revalidate_hddisk(int dev, int maxusage) +static int revalidate_hddisk(kdev_t dev, int maxusage) { - int target, major; + int target; struct gendisk * gdev; int max_p; int start; int i; long flags; - target = DEVICE_NR(dev); + target = DEVICE_NR(dev); gdev = &GENDISK_STRUCT; save_flags(flags); @@ -1099,14 +1100,15 @@ static int revalidate_hddisk(int dev, int maxusage) max_p = gdev->max_p; start = target << gdev->minor_shift; - major = MAJOR_NR << 8; for (i=max_p - 1; i >=0 ; i--) { - sync_dev(major | start | i); - invalidate_inodes(major | start | i); - invalidate_buffers(major | start | i); - gdev->part[start+i].start_sect = 0; - gdev->part[start+i].nr_sects = 0; + int minor = start + i; + kdev_t devi = MKDEV(MAJOR_NR, minor); + sync_dev(devi); + invalidate_inodes(devi); + invalidate_buffers(devi); + gdev->part[minor].start_sect = 0; + gdev->part[minor].nr_sects = 0; }; #ifdef MAYBE_REINIT diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c index 55e85ef68c38..e7551dbe83f2 100644 --- a/drivers/block/ide-cd.c +++ b/drivers/block/ide-cd.c @@ -41,7 +41,7 @@ * PLAYAUDIO12 is broken on the Aztech; work around it. * 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c * (my apologies to Scott, but now ide-cd.c is independent) - * 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl (UNTESTED). + * 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl. * Implement CDROMREADAUDIO ioctl (UNTESTED). * Use input_ide_data() and output_ide_data(). * Add door locking. @@ -63,11 +63,16 @@ * 3.01 Sep 2, 1995 -- Fix ordering of reenabling interrupts in * cdrom_queue_request. * Another try at using ide_[input,output]_data. + * 3.02 Sep 16, 1995 -- Stick total disk capacity in partition table as well. + * Make VERBOSE_IDE_CD_ERRORS dump failed command again. + * Dump out more information for ILLEGAL REQUEST errs. + * Fix handling of errors occuring before the + * packet command is transferred. + * Fix transfers with odd bytelengths. * - * NOTE: I've tried to implement support for multisession CDs and - * direct audio reads in this version, but i haven't been able to fully - * test them due to a lack of the proper hardware. I'd appreciate hearing - * if the multisession stuff works; i'd also be interested in hearing + * NOTE: I've tried to implement support for direct audio reads + * in this version, but i haven't been able to fully test it + * due to a lack of the proper hardware. I'd be interested in hearing * if you get anything other than a `Parameter not supported' * (asc=0x26, ascq=1) error when trying to do a direct audio read. * @@ -185,15 +190,18 @@ struct ide_cd_state_flags { * Routines to read and write data from/to the drive, using * the routines input_ide_data() and output_ide_data() from ide.c. * - * All transfer lengths should be multiples of 16-bit shorts. + * These routines will round up any request for an odd number of bytes, + * so if an odd bytecount is specified, be sure that there's at least one + * extra byte allocated for the buffer. */ static inline void cdrom_in_bytes (ide_drive_t *drive, void *buffer, uint bytecount) { + ++bytecount; ide_input_data (drive, buffer, bytecount / 4); - if ((bytecount & 0x03 >= 2)) + if ((bytecount & 0x03) >= 2) { insw (IDE_DATA_REG, buffer + (bytecount & ~0x03), 1); } @@ -203,8 +211,9 @@ void cdrom_in_bytes (ide_drive_t *drive, void *buffer, uint bytecount) static inline void cdrom_out_bytes (ide_drive_t *drive, void *buffer, uint bytecount) { + ++bytecount; ide_output_data (drive, buffer, bytecount / 4); - if ((bytecount & 0x03 >= 2)) + if ((bytecount & 0x03) >= 2) { outsw (IDE_DATA_REG, buffer + (bytecount & ~0x03), 1); } @@ -380,7 +389,7 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, printk ("ATAPI device %s:\n", drive->name); - printk (" Error code: %x\n", reqbuf->error_code); + printk (" Error code: 0x%02x\n", reqbuf->error_code); if (reqbuf->sense_key >= 0 && reqbuf->sense_key < ARY_LEN (sense_key_texts)) @@ -388,10 +397,10 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, else s = "(bad sense key)"; - printk (" Sense key: %x - %s\n", reqbuf->sense_key, s); + printk (" Sense key: 0x%02x - %s\n", reqbuf->sense_key, s); if (reqbuf->asc == 0x40) { - sprintf (buf, "Diagnostic failure on component %x", reqbuf->ascq); + sprintf (buf, "Diagnostic failure on component 0x%02x", reqbuf->ascq); s = buf; } @@ -425,7 +434,7 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, s = "(reserved error code)"; } - printk (" Additional sense data: %x, %x - %s\n", + printk (" Additional sense data: 0x%02x, 0x%02x - %s\n", reqbuf->asc, reqbuf->ascq, s); if (failed_command != NULL) { @@ -434,6 +443,24 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, printk ("%02x ", failed_command->c[i]); printk ("\n"); } + + if (reqbuf->sense_key == ILLEGAL_REQUEST && + (reqbuf->sense_key_specific[0] & 0x80) != 0) + { + printk (" Error in %s byte %d", + (reqbuf->sense_key_specific[0] & 0x40) != 0 + ? "command packet" + : "command data", + (reqbuf->sense_key_specific[1] << 8) + + reqbuf->sense_key_specific[2]); + + if ((reqbuf->sense_key_specific[0] & 0x40) != 0) + { + printk (" bit %d", reqbuf->sense_key_specific[0] & 0x07); + } + + printk ("\n"); + } } #else @@ -446,7 +473,7 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, reqbuf->asc == 0x3a))) return; - printk ("%s: code: %x key: %x asc: %x ascq: %x\n", + printk ("%s: code: 0x%02x key: 0x%02x asc: 0x%02x ascq: 0x%02x\n", drive->name, reqbuf->error_code, reqbuf->sense_key, reqbuf->asc, reqbuf->ascq); #endif @@ -470,7 +497,8 @@ static void restore_request (struct request *rq) static void cdrom_queue_request_sense (ide_drive_t *drive, struct semaphore *sem, - struct atapi_request_sense *reqbuf) + struct atapi_request_sense *reqbuf, + struct packet_command *failed_command) { struct request *rq; struct packet_command *pc; @@ -516,12 +544,11 @@ static void cdrom_queue_request_sense (ide_drive_t *drive, pc->c[4] = len; pc->buffer = (char *)reqbuf; pc->buflen = len; - pc->sense_data = reqbuf; /* The only reason to set this here is so - that cdrom_end_request can find the correct - buffer for dumps to the syslog. */ + pc->sense_data = (struct atapi_request_sense *)failed_command; rq = &HWIF(drive)->request_sense_request; - rq->dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); + rq->rq_status = RQ_ACTIVE; + rq->rq_dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); rq->cmd = REQUEST_SENSE_COMMAND; rq->errors = 0; rq->sector = 0; @@ -560,7 +587,9 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive) if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) { struct packet_command *pc = (struct packet_command *)rq->buffer; - cdrom_analyze_sense_data (drive, pc->sense_data, NULL); + cdrom_analyze_sense_data (drive, + (struct atapi_request_sense *)(pc->buffer - pc->c[4]), + (struct packet_command *)pc->sense_data); } ide_end_request (uptodate, HWGROUP(drive)); @@ -666,7 +695,7 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat, int *stat_ret cdrom_end_request (1, drive); if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense (drive, sem, pc->sense_data); + cdrom_queue_request_sense (drive, sem, pc->sense_data, pc); } else @@ -719,7 +748,7 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat, int *stat_ret /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense (drive, NULL, NULL); + cdrom_queue_request_sense (drive, NULL, NULL, NULL); } } @@ -768,9 +797,12 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen, /* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device registers must have already been prepared - by cdrom_start_packet_command. */ + by cdrom_start_packet_command. + HANDLER is the interrupt handler to call when the command completes + or there's data ready. */ static int cdrom_transfer_packet_command (ide_drive_t *drive, - char *cmd_buf, int cmd_len) + char *cmd_buf, int cmd_len, + ide_handler_t *handler) { if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { @@ -787,6 +819,9 @@ static int cdrom_transfer_packet_command (ide_drive_t *drive, if (ide_wait_stat (drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1; } + /* Arm the interrupt handler. */ + ide_set_handler (drive, handler); + /* Send the command to the device. */ cdrom_out_bytes (drive, cmd_buf, cmd_len); @@ -1140,11 +1175,9 @@ static void cdrom_start_read_continuation (ide_drive_t *drive) pc.c[5] = conv.b.b0; } - /* Set up to receive the data-ready interrupt from the drive. */ - ide_set_handler (drive, &cdrom_read_intr); - /* Send the command to the drive and return. */ - (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c)); + (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c), + &cdrom_read_intr); } @@ -1304,11 +1337,8 @@ static void cdrom_do_pc_continuation (ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; - /* Set up a handler for the data-ready interrupt. */ - ide_set_handler (drive, &cdrom_pc_intr); - /* Send the command to the drive and return. */ - cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c)); + cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c), &cdrom_pc_intr); } @@ -1347,7 +1377,8 @@ void cdrom_queue_request (ide_drive_t *drive, struct request *req) int major = HWIF(drive)->major; struct semaphore sem = MUTEX_LOCKED; - req->dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); + req->rq_dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); + req->rq_status = RQ_ACTIVE; req->sem = &sem; req->errors = 0; req->next = NULL; @@ -1782,6 +1813,7 @@ cdrom_read_toc (ide_drive_t *drive, HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS] = toc->capacity * SECTORS_PER_FRAME; + drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME; /* Remember that we've read this stuff. */ CDROM_STATE_FLAGS (drive)->toc_valid = 1; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index d6d90919fb25..c42f9a061460 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 5.13b Sep 9, 1995 + * linux/drivers/block/ide.c Version 5.14 Sep 14, 1995 * * Copyright (C) 1994, 1995 Linus Torvalds & authors (see below) */ @@ -141,11 +141,15 @@ * Version 5.13 fixed typo ('B'), thanks to houston@boyd.geog.mcgill.ca * fixed ht6560b support * Version 5.13b (sss) fix problem in calling ide_cdrom_setup() - * don't bother invalidating nonexistent partitions + * don't bother invalidating nonexistent partitions + * Version 5.14 fixes to cmd640 support.. maybe it works now(?) + * added & tested full EZ-DRIVE support -- don't use LILO! + * don't enable 2nd CMD640 PCI port during init - conflict * * Driver compile-time options are in ide.h * * To do, in likely order of completion: + * - figure out why Mitsumi ATAPI cdroms are having trouble.. * - add ioctls to get/set interface timings on cmd640, ht6560b, triton * - modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f * - improved CMD support: probably handing this off to someone else @@ -1318,10 +1322,11 @@ static inline void do_request (ide_hwif_t *hwif, struct request *rq) #ifdef DEBUG printk("%s: ide_do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); #endif - minor = MINOR(rq->dev); + minor = MINOR(rq->rq_dev); unit = minor >> PARTN_BITS; - if (MAJOR(rq->dev) != hwif->major || unit >= MAX_DRIVES) { - printk("%s: bad device number: 0x%04x\n", hwif->name, rq->dev); + if (MAJOR(rq->rq_dev) != hwif->major || unit >= MAX_DRIVES) { + printk("%s: bad device number: %s\n", + hwif->name, kdevname(rq->rq_dev)); goto kill_rq; } drive = &hwif->drives[unit]; @@ -1339,6 +1344,12 @@ static inline void do_request (ide_hwif_t *hwif, struct request *rq) goto kill_rq; } block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; +#if FAKE_FDISK_FOR_EZDRIVE + if (block == 0 && drive->ezdrive) { + block = 1; + printk("%s: [EZD] accessing sector 1 instead of sector 0\n", drive->name); + } +#endif /* FAKE_FDISK_FOR_EZDRIVE */ ((ide_hwgroup_t *)hwif->hwgroup)->drive = drive; #if (DISK_RECOVERY_TIME > 0) while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); @@ -1407,7 +1418,7 @@ void ide_do_request (ide_hwgroup_t *hwgroup) hwgroup->drive = NULL; /* paranoia */ do { rq = blk_dev[hwif->major].current_request; - if (rq != NULL && rq->dev != -1) + if (rq != NULL && rq->rq_status != RQ_INACTIVE) goto got_rq; } while ((hwif = hwif->next) != hwgroup->hwif); return; /* no work left for this hwgroup */ @@ -1575,7 +1586,7 @@ static void ide_intr (int irq, struct pt_regs *regs) * get_info_ptr() returns the (ide_drive_t *) for a given device number. * It returns NULL if the given device number does not match any present drives. */ -static ide_drive_t *get_info_ptr (int i_rdev) +static ide_drive_t *get_info_ptr (kdev_t i_rdev) { int major = MAJOR(i_rdev); unsigned int h; @@ -1605,7 +1616,7 @@ static ide_drive_t *get_info_ptr (int i_rdev) * If arg is NULL, it goes through all the motions, * but without actually sending a command to the drive. */ -int ide_do_drive_cmd(int rdev, char *args) +int ide_do_drive_cmd(kdev_t rdev, char *args) { unsigned long flags; unsigned int major = MAJOR(rdev); @@ -1624,7 +1635,8 @@ int ide_do_drive_cmd(int rdev, char *args) rq.bh = NULL; rq.bhtail = NULL; rq.next = NULL; - rq.dev = rdev; + rq.rq_status = RQ_ACTIVE; + rq.rq_dev = rdev; bdev = &blk_dev[major]; save_flags(flags); @@ -1701,7 +1713,7 @@ static void ide_release(struct inode * inode, struct file * file) * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */ -static int revalidate_disk(dev_t i_rdev) +static int revalidate_disk(kdev_t i_rdev) { ide_drive_t *drive; unsigned int p, major, minor; @@ -1710,7 +1722,7 @@ static int revalidate_disk(dev_t i_rdev) if ((drive = get_info_ptr(i_rdev)) == NULL) return -ENODEV; - major = MAJOR(i_rdev) << 8; + major = MAJOR(i_rdev); minor = drive->select.b.unit << PARTN_BITS; save_flags(flags); cli(); @@ -1723,9 +1735,10 @@ static int revalidate_disk(dev_t i_rdev) for (p = 0; p < (1<part[p].nr_sects > 0) { - sync_dev (major | (minor + p)); - invalidate_inodes (major | (minor + p)); - invalidate_buffers (major | (minor + p)); + kdev_t devp = MKDEV(major, minor+p); + sync_dev (devp); + invalidate_inodes (devp); + invalidate_buffers (devp); } drive->part[p].start_sect = 0; drive->part[p].nr_sects = 0; @@ -1760,7 +1773,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, ide_drive_t *drive; unsigned long flags; - if (!inode || !inode->i_rdev) + if (!inode || !(inode->i_rdev)) return -EINVAL; if ((drive = get_info_ptr(inode->i_rdev)) == NULL) return -ENODEV; @@ -1772,7 +1785,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, put_user(drive->bios_head, (byte *) &loc->heads); put_user(drive->bios_sect, (byte *) &loc->sectors); put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders); - put_user((unsigned)drive->part[inode->i_rdev&PARTN_MASK].start_sect, + put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect, (unsigned long *) &loc->start); return 0; @@ -1792,7 +1805,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]); case BLKGETSIZE: /* Return device size */ - return write_fs_long(arg, drive->part[inode->i_rdev&PARTN_MASK].nr_sects); + return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects); case BLKRRPART: /* Re-read partition tables */ return revalidate_disk(inode->i_rdev); @@ -1812,7 +1825,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, return write_fs_long(arg, drive->mult_count); case HDIO_GET_IDENTITY: - if (!arg || (inode->i_rdev & PARTN_MASK)) + if (!arg || (MINOR(inode->i_rdev) & PARTN_MASK)) return -EINVAL; if (drive->id == NULL) return -ENOMSG; @@ -1837,7 +1850,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, case HDIO_SET_CHIPSET: if (!suser()) return -EACCES; - if ((inode->i_rdev & PARTN_MASK)) + if ((MINOR(inode->i_rdev) & PARTN_MASK)) return -EINVAL; save_flags(flags); cli(); @@ -1874,7 +1887,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, case HDIO_SET_MULTCOUNT: if (!suser()) return -EACCES; - if (inode->i_rdev & PARTN_MASK) + if (MINOR(inode->i_rdev) & PARTN_MASK) return -EINVAL; if ((drive->id != NULL) && (arg > drive->id->max_multsect)) return -EINVAL; @@ -1920,7 +1933,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, } } -static int ide_check_media_change (dev_t i_rdev) +static int ide_check_media_change (kdev_t i_rdev) { ide_drive_t *drive; @@ -2302,7 +2315,7 @@ static void probe_for_drives (ide_hwif_t *hwif) #ifdef CONFIG_BLK_DEV_IDECD if (drive->present && drive->media == cdrom) ide_cdrom_setup(drive); -#endif /* CONFIG_BLK_DEV_IDECD */ +#endif /* CONFIG_BLK_DEV_IDECD */ } for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; @@ -2422,6 +2435,7 @@ void init_cmd640_vlb (void) } } write_cmd640_vlb(port, 0x51, read_cmd640_vlb(port, 0x51)|0xc8); + write_cmd640_vlb(port, 0x57, read_cmd640_vlb(port, 0x57)|0x0c); printk("disabled read-ahead, enabled secondary\n"); } @@ -2642,7 +2656,7 @@ done: * to "convert" a drive to a logical geometry with fewer than 1024 cyls * It mimics the method used by Ontrack Disk Manager. */ -int ide_xlate_1024 (dev_t i_rdev, int need_offset, const char *msg) +int ide_xlate_1024 (kdev_t i_rdev, int offset, const char *msg) { ide_drive_t *drive; static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; @@ -2665,12 +2679,19 @@ int ide_xlate_1024 (dev_t i_rdev, int need_offset, const char *msg) if (0 == *++heads) break; } - if (need_offset) { - drive->sect0 = 63; - drive->bios_cyl = (tracks - 1) / drive->bios_head; + if (offset) { +#if FAKE_FDISK_FOR_EZDRIVE + if (offset == -1) + drive->ezdrive = 1; + else +#endif /* FAKE_FDISK_FOR_EZDRIVE */ + { + drive->sect0 = 63; + drive->bios_cyl = (tracks - 1) / drive->bios_head; + } } drive->part[0].nr_sects = current_capacity(drive); - printk("%s [+%d,%d/%d/%d]", msg, drive->sect0, drive->bios_cyl, drive->bios_head, drive->bios_sect); + printk("%s [%d/%d/%d]", msg, drive->bios_cyl, drive->bios_head, drive->bios_sect); return 1; } @@ -2824,11 +2845,17 @@ void init_rz1000 (byte bus, byte fn) unsigned short reg; printk("ide: buggy RZ1000 interface: "); - if ((rc = pcibios_read_config_word(bus, fn, 0x40, ®)) - || (rc = pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff))) - buggy_interface_fallback (rc); - else - printk("disabled read-ahead\n"); + if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, ®))) { + ide_pci_access_error (rc); + } else if (!(reg & 1)) { + printk("not enabled\n"); + } else { + if ((rc = pcibios_read_config_word(bus, fn, 0x40, ®)) + || (rc = pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff))) + buggy_interface_fallback (rc); + else + printk("disabled read-ahead\n"); + } } #endif /* SUPPORT_RZ1000 */ @@ -2840,11 +2867,34 @@ void init_cmd640 (byte bus, byte fn) single_threaded = 1; printk("ide: buggy CMD640 interface: "); + +#if 0 /* funny.. the cmd640b I tried this on claimed to not be enabled.. */ + unsigned short sreg; + if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &sreg))) { + ide_pci_access_error (rc); + } else if (!(sreg & 1)) { + printk("not enabled\n"); + } else { +#endif /* 0 */ + + /* + * The first part is undocumented magic from the DOS driver. + * According to the datasheet, there is no port 0x5b on the cmd640. + */ + (void) pcibios_write_config_byte(bus, fn, 0x5b, 0xbd); + if (pcibios_write_config_byte(bus, fn, 0x5b, 0xbd) != 0xbd) + printk("init_cmd640: huh? 0x5b read back wrong\n"); + (void) pcibios_write_config_byte(bus, fn, 0x5b, 0); + /* + * The rest is from the cmd640b datasheet. + */ if ((rc = pcibios_read_config_byte(bus, fn, 0x51, ®)) - || (rc = pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc8))) + || (rc = pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc0)) /* 0xc8 to enable 2nd i/f */ + || (rc = pcibios_read_config_byte(bus, fn, 0x57, ®)) + || (rc = pcibios_write_config_byte(bus, fn, 0x57, reg | 0x0c))) buggy_interface_fallback (rc); else - printk("serialized, disabled read-ahead, enabled secondary\n"); + printk("serialized, disabled read-ahead\n"); } #endif /* SUPPORT_CMD640 */ @@ -2857,19 +2907,13 @@ typedef void (ide_pci_init_proc_t)(byte, byte); static void ide_probe_pci (unsigned short vendor, unsigned short device, ide_pci_init_proc_t *init) { unsigned long flags; - unsigned index = 0; + unsigned index; byte fn, bus; - int rc; save_flags(flags); cli(); for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) { - unsigned short command; - if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &command))) { - ide_pci_access_error (rc); - } else if (command & 1) { /* is device enabled? */ - init (bus, fn); - } + init (bus, fn); } restore_flags(flags); } @@ -2889,7 +2933,7 @@ static void ide_init_pci (void) ide_probe_pci (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, &init_cmd640); #endif #ifdef CONFIG_BLK_DEV_TRITON - ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371, &ide_init_triton); + ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_1, &ide_init_triton); #endif } #endif /* CONFIG_PCI */ diff --git a/drivers/block/ide.h b/drivers/block/ide.h index 59b3d19dcfb7..00ed6073f069 100644 --- a/drivers/block/ide.h +++ b/drivers/block/ide.h @@ -29,6 +29,9 @@ #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ #define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ #endif +#ifndef FAKE_FDISK_FOR_EZDRIVE /* 1 to help linux fdisk with EZDRIVE */ +#define FAKE_FDISK_FOR_EZDRIVE 1 /* 0 to reduce kernel size */ +#endif #ifndef SUPPORT_RZ1000 /* 1 to support RZ1000 chipset */ #define SUPPORT_RZ1000 1 /* 0 to reduce kernel size */ #endif @@ -248,6 +251,9 @@ typedef union { typedef struct ide_drive_s { special_t special; /* special action flags */ +#if FAKE_FDISK_FOR_EZDRIVE + unsigned ezdrive : 1; /* flag: partitioned with ezdrive */ +#endif /* FAKE_FDISK_FOR_EZDRIVE */ unsigned present : 1; /* drive is physically present */ unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned keep_settings : 1; /* restore settings after drive reset */ @@ -405,7 +411,7 @@ int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeou /* * This is called from genhd.c to correct DiskManager/EZ-Drive geometries */ -int ide_xlate_1024(dev_t, int, const char *); +int ide_xlate_1024(kdev_t, int, const char *); /* * Start a reset operation for an IDE interface. @@ -432,7 +438,7 @@ void *ide_alloc (unsigned long bytecount, unsigned long within_area); * * The value of arg is passed to the internal handler as rq->buffer. */ -int ide_do_drive_cmd(int rdev, char *args); +int ide_do_drive_cmd(kdev_t rdev, char *args); #ifdef CONFIG_BLK_DEV_IDECD diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 5cb63d89fe53..527c32b1974e 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -108,7 +108,7 @@ static void plug_device(struct blk_dev_struct * dev, struct request * plug) { unsigned long flags; - plug->dev = -1; + plug->rq_status = RQ_INACTIVE; plug->cmd = -1; plug->next = NULL; save_flags(flags); @@ -129,7 +129,7 @@ static void unplug_device(struct blk_dev_struct * dev) save_flags(flags); cli(); req = dev->current_request; - if (req && req->dev == -1 && req->cmd == -1) { + if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) { dev->current_request = req->next; (dev->request_fn)(); } @@ -141,7 +141,7 @@ static void unplug_device(struct blk_dev_struct * dev) * NOTE: interrupts must be disabled on the way in, and will still * be disabled on the way out. */ -static inline struct request * get_request(int n, int dev) +static inline struct request * get_request(int n, kdev_t dev) { static struct request *prev_found = NULL, *prev_limit = NULL; register struct request *req, *limit; @@ -157,20 +157,21 @@ static inline struct request * get_request(int n, int dev) req = prev_found; for (;;) { req = ((req > all_requests) ? req : limit) - 1; - if (req->dev < 0) + if (req->rq_status == RQ_INACTIVE) break; if (req == prev_found) return NULL; } prev_found = req; - req->dev = dev; + req->rq_status = RQ_ACTIVE; + req->rq_dev = dev; return req; } /* * wait until a free request in the first N entries is available. */ -static struct request * __get_request_wait(int n, int dev) +static struct request * __get_request_wait(int n, kdev_t dev) { register struct request *req; struct wait_queue wait = { current, NULL }; @@ -191,7 +192,7 @@ static struct request * __get_request_wait(int n, int dev) return req; } -static inline struct request * get_request_wait(int n, int dev) +static inline struct request * get_request_wait(int n, kdev_t dev) { register struct request *req; @@ -207,7 +208,7 @@ static inline struct request * get_request_wait(int n, int dev) static long ro_bits[MAX_BLKDEV][8]; -int is_read_only(int dev) +int is_read_only(kdev_t dev) { int minor,major; @@ -217,7 +218,7 @@ int is_read_only(int dev) return ro_bits[major][minor >> 5] & (1 << (minor & 31)); } -void set_device_ro(int dev,int flag) +void set_device_ro(kdev_t dev,int flag) { int minor,major; @@ -238,18 +239,22 @@ static void add_request(struct blk_dev_struct * dev, struct request * req) struct request * tmp; short disk_index; - switch (MAJOR(req->dev)) { - case SCSI_DISK_MAJOR: disk_index = (MINOR(req->dev) & 0x0070) >> 4; - if (disk_index < 4) - kstat.dk_drive[disk_index]++; - break; + switch (MAJOR(req->rq_dev)) { + case SCSI_DISK_MAJOR: + disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4; + if (disk_index < 4) + kstat.dk_drive[disk_index]++; + break; case IDE0_MAJOR: /* same as HD_MAJOR */ - case XT_DISK_MAJOR: disk_index = (MINOR(req->dev) & 0x0040) >> 6; - kstat.dk_drive[disk_index]++; - break; - case IDE1_MAJOR: disk_index = ((MINOR(req->dev) & 0x0040) >> 6) + 2; - kstat.dk_drive[disk_index]++; - default: break; + case XT_DISK_MAJOR: + disk_index = (MINOR(req->rq_dev) & 0x0040) >> 6; + kstat.dk_drive[disk_index]++; + break; + case IDE1_MAJOR: + disk_index = ((MINOR(req->rq_dev) & 0x0040) >> 6) + 2; + kstat.dk_drive[disk_index]++; + default: + break; } req->next = NULL; @@ -272,7 +277,7 @@ static void add_request(struct blk_dev_struct * dev, struct request * req) tmp->next = req; /* for SCSI devices, call request_fn unconditionally */ - if (scsi_major(MAJOR(req->dev))) + if (scsi_major(MAJOR(req->rq_dev))) (dev->request_fn)(); sti(); @@ -347,7 +352,7 @@ static void make_request(int major,int rw, struct buffer_head * bh) #endif CONFIG_BLK_DEV_HD req = req->next; while (req) { - if (req->dev == bh->b_dev && + if (req->rq_dev == bh->b_dev && !req->sem && req->cmd == rw && req->sector + req->nr_sectors == sector && @@ -361,7 +366,7 @@ static void make_request(int major,int rw, struct buffer_head * bh) return; } - if (req->dev == bh->b_dev && + if (req->rq_dev == bh->b_dev && !req->sem && req->cmd == rw && req->sector - count == sector && @@ -409,7 +414,7 @@ static void make_request(int major,int rw, struct buffer_head * bh) add_request(major+blk_dev,req); } -void ll_rw_page(int rw, int dev, unsigned long page, char * buffer) +void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer) { struct request * req; unsigned int major = MAJOR(dev); @@ -417,13 +422,15 @@ void ll_rw_page(int rw, int dev, unsigned long page, char * buffer) struct semaphore sem = MUTEX_LOCKED; if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) { - printk("Trying to read nonexistent block-device %04x (%ld)\n",dev,sector); + printk("Trying to read nonexistent block-device %s (%ld)\n", + kdevname(dev), sector); return; } if (rw!=READ && rw!=WRITE) panic("Bad block dev command, must be R/W"); if (rw == WRITE && is_read_only(dev)) { - printk("Can't page to read-only device 0x%X\n",dev); + printk("Can't page to read-only device %s\n", + kdevname(dev)); return; } req = get_request_wait(NR_REQUEST, dev); @@ -465,8 +472,8 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) dev = blk_dev + major; if (!dev || !dev->request_fn) { printk( - "ll_rw_block: Trying to read nonexistent block-device %04lX (%ld)\n", - (unsigned long) bh[0]->b_dev, bh[0]->b_blocknr); + "ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n", + kdevname(bh[0]->b_dev), bh[0]->b_blocknr); goto sorry; } @@ -489,7 +496,8 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) } if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) { - printk("Can't write to read-only device 0x%X\n",bh[0]->b_dev); + printk("Can't write to read-only device %s\n", + kdevname(bh[0]->b_dev)); goto sorry; } @@ -521,7 +529,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) return; } -void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf) +void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf) { int i, j; int buffersize; @@ -534,12 +542,13 @@ void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf) return; } - if (rw!=READ && rw!=WRITE) { + if (rw != READ && rw != WRITE) { printk("ll_rw_swap: bad block dev command, must be R/W"); return; } if (rw == WRITE && is_read_only(dev)) { - printk("Can't swap to read-only device 0x%X\n",dev); + printk("Can't swap to read-only device %s\n", + kdevname(dev)); return; } @@ -582,7 +591,7 @@ long blk_dev_init(long mem_start, long mem_end) req = all_requests + NR_REQUEST; while (--req >= all_requests) { - req->dev = -1; + req->rq_status = RQ_INACTIVE; req->next = NULL; } memset(ro_bits,0,sizeof(ro_bits)); diff --git a/drivers/block/mcd.c b/drivers/block/mcd.c index e29b076033fc..c01975bb9f8f 100644 --- a/drivers/block/mcd.c +++ b/drivers/block/mcd.c @@ -139,7 +139,7 @@ static int mcdPresent = 0; /* #define DOUBLE_QUICK_ONLY */ #define CURRENT_VALID \ - (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR && CURRENT -> cmd == READ \ + (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \ && CURRENT -> sector != -1) #define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA) #define MCD_BUF_SIZ 16 @@ -213,7 +213,7 @@ void mcd_setup(char *str, int *ints) static int -check_mcd_change(dev_t full_dev) +check_mcd_change(kdev_t full_dev) { int retval, target; diff --git a/drivers/block/mcdx.c b/drivers/block/mcdx.c index 1f8ef94eb5f2..6ebe24763983 100644 --- a/drivers/block/mcdx.c +++ b/drivers/block/mcdx.c @@ -194,7 +194,7 @@ struct s_drive_stuff { unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end); void do_mcdx_request(void); -int check_mcdx_media_change(dev_t); +int check_mcdx_media_change(kdev_t); /* already declared in init/main */ void mcdx_setup(char *, int *); @@ -546,19 +546,20 @@ void do_mcdx_request() TRACE((REQUEST, "do_request()\n")); - if ((CURRENT == NULL) || (CURRENT->dev < 0)) { + if ((CURRENT == NULL) || (CURRENT->rq_status == RQ_INACTIVE)) { TRACE((REQUEST, "do_request() done\n")); return; } - stuffp = mcdx_stuffp[MINOR(CURRENT->dev)]; + stuffp = mcdx_stuffp[MINOR(CURRENT->rq_dev)]; TRACE((REQUEST, "do_request() stuffp = %p\n", stuffp)); INIT_REQUEST; - dev = MINOR(CURRENT->dev); + dev = MINOR(CURRENT->rq_dev); if ((dev < 0) || (dev >= MCDX_NDRIVES) || (!stuffp->present)) { - WARN(("do_request(): bad device: 0x%04x\n", CURRENT->dev)); + WARN(("do_request(): bad device: %s\n", + kdevname(CURRENT->rq_dev))); end_request(0); goto again; } @@ -767,14 +768,15 @@ mcdx_close(struct inode *ip, struct file *fp) return; } -int check_mcdx_media_change(dev_t full_dev) +int check_mcdx_media_change(kdev_t full_dev) /* Return: 1 if media changed since last call to this function 0 else Setting flag to 0 resets the changed state. */ { - INFO(("check_mcdx_media_change(0x%x) called\n")); + INFO(("check_mcdx_media_change called for device %s\n", + kdevname(full_dev))); return 0; } @@ -1053,7 +1055,7 @@ unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end) } #else TRACE((INIT, "adjust mem_start\n")); - stuffp = mem_start; + stuffp = (struct s_drive_stuff *) mem_start; mem_start += size; #endif diff --git a/drivers/block/ramdisk.c b/drivers/block/ramdisk.c index 7b721b05279d..bf98ecf07247 100644 --- a/drivers/block/ramdisk.c +++ b/drivers/block/ramdisk.c @@ -40,7 +40,7 @@ repeat: addr = rd_start + (CURRENT->sector << 9); len = CURRENT->current_nr_sectors << 9; - if ((MINOR(CURRENT->dev) != RAMDISK_MINOR) || + if ((MINOR(CURRENT->rq_dev) != RAMDISK_MINOR) || (addr+len > rd_start+rd_length)) { end_request(0); goto repeat; @@ -190,7 +190,7 @@ static void do_load(void) printk("\ndone\n"); /* We loaded the file system image. Prepare for mounting it. */ - ROOT_DEV = ((MEM_MAJOR << 8) | RAMDISK_MINOR); + ROOT_DEV = MKDEV(MEM_MAJOR, RAMDISK_MINOR); return; } } diff --git a/drivers/block/sbpcd.c b/drivers/block/sbpcd.c index 2cff9a512504..fd25deec1552 100644 --- a/drivers/block/sbpcd.c +++ b/drivers/block/sbpcd.c @@ -434,7 +434,7 @@ static void sbp_read_cmd(void); static int sbp_data(void); static int cmd_out(void); static int DiskInfo(void); -static int sbpcd_chk_disk_change(dev_t); +static int sbpcd_chk_disk_change(kdev_t); /*==========================================================================*/ @@ -4340,7 +4340,7 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd, case BLKRASET: if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; + if(!(inode->i_rdev)) return -EINVAL; if(arg > 0xff) return -EINVAL; read_ahead[MAJOR(inode->i_rdev)] = arg; return (0); @@ -4383,17 +4383,20 @@ static void DO_SBPCD_REQUEST(void) INIT_REQUEST; sti(); - if ((CURRENT==NULL)||(CURRENT->dev<0)) goto err_done; - if (CURRENT -> sector == -1) goto err_done; + if ((CURRENT == NULL) || CURRENT->rq_status == RQ_INACTIVE) + goto err_done; + if (CURRENT -> sector == -1) + goto err_done; if (CURRENT->cmd != READ) { msg(DBG_INF, "bad cmd %d\n", CURRENT->cmd); goto err_done; } - i = MINOR(CURRENT->dev); + i = MINOR(CURRENT->rq_dev); if ( (i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1)) { - msg(DBG_INF, "do_request: bad device: %04X\n", CURRENT->dev); + msg(DBG_INF, "do_request: bad device: %s\n", + kdevname(CURRENT->rq_dev)); goto err_done; } while (busy_audio) sbp_sleep(HZ); /* wait a bit */ @@ -5358,7 +5361,7 @@ void cleanup_module(void) * used externally (isofs/inode.c, fs/buffer.c) * Currently disabled (has to get "synchronized"). */ -static int sbpcd_chk_disk_change(dev_t full_dev) +static int sbpcd_chk_disk_change(kdev_t full_dev) { int i, st; diff --git a/drivers/block/sjcd.c b/drivers/block/sjcd.c index 7e6b1931ad46..18ffd5838f87 100644 --- a/drivers/block/sjcd.c +++ b/drivers/block/sjcd.c @@ -427,7 +427,7 @@ static void sjcd_get_status( void ){ /* * Check the drive if the disk is changed. */ -static int sjcd_disk_change( dev_t full_dev ){ +static int sjcd_disk_change( kdev_t full_dev ){ #if 0 printk( "sjcd_disk_change( 0x%x )\n", full_dev ); #endif @@ -908,7 +908,7 @@ static void sjcd_invalidate_buffers( void ){ */ #define CURRENT_IS_VALID \ - ( CURRENT != NULL && MAJOR( CURRENT->dev ) == MAJOR_NR && \ + ( CURRENT != NULL && MAJOR( CURRENT->rq_dev ) == MAJOR_NR && \ CURRENT->cmd == READ && CURRENT->sector != -1 ) static void sjcd_transfer( void ){ diff --git a/drivers/block/sonycd535.c b/drivers/block/sonycd535.c index cfe425307153..36ad24882ef0 100644 --- a/drivers/block/sonycd535.c +++ b/drivers/block/sonycd535.c @@ -286,7 +286,7 @@ static struct wait_queue *cdu535_irq_wait = NULL; * check or 0 if it hasn't. Setting flag to 0 resets the changed flag. */ static int -cdu535_check_media_change(dev_t full_dev) +cdu535_check_media_change(kdev_t full_dev) { int retval; @@ -832,11 +832,11 @@ do_cdu535_request(void) * The beginning here is stolen from the hard disk driver. I hope * it's right. */ - if (!(CURRENT) || CURRENT->dev < 0) { + if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) { return; } INIT_REQUEST; - dev = MINOR(CURRENT->dev); + dev = MINOR(CURRENT->rq_dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; if (dev != 0) { diff --git a/drivers/block/triton.c b/drivers/block/triton.c index 659debc742f4..3d29a5cdb9c6 100644 --- a/drivers/block/triton.c +++ b/drivers/block/triton.c @@ -292,7 +292,6 @@ void ide_init_triton (byte bus, byte fn) unsigned int timings; extern ide_hwif_t ide_hwifs[]; - ++fn; /* IDE interface is 2nd function on this device */ /* * See if IDE and BM-DMA features are enabled: */ diff --git a/drivers/block/xd.c b/drivers/block/xd.c index dce78be09a39..b76e4ef11416 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -192,7 +192,7 @@ static void xd_geninit (struct gendisk *ignored) /* xd_open: open a device */ static int xd_open (struct inode *inode,struct file *file) { - int dev = DEVICE_NR(MINOR(inode->i_rdev)); + int dev = DEVICE_NR(inode->i_rdev); if (dev < xd_drives) { while (!xd_valid[dev]) @@ -216,8 +216,10 @@ static void do_xd_request (void) while (code = 0, CURRENT) { INIT_REQUEST; /* do some checking on the request structure */ - if (CURRENT_DEV < xd_drives && CURRENT->sector + CURRENT->nr_sectors <= xd[MINOR(CURRENT->dev)].nr_sects) { - block = CURRENT->sector + xd[MINOR(CURRENT->dev)].start_sect; + if (CURRENT_DEV < xd_drives + && CURRENT->sector + CURRENT->nr_sectors + <= xd[MINOR(CURRENT->rq_dev)].nr_sects) { + block = CURRENT->sector + xd[MINOR(CURRENT->rq_dev)].start_sect; count = CURRENT->nr_sectors; switch (CURRENT->cmd) { @@ -238,7 +240,7 @@ static void do_xd_request (void) static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) { XD_GEOMETRY *geometry = (XD_GEOMETRY *) arg; - int dev = DEVICE_NR(MINOR(inode->i_rdev)),err; + int dev = DEVICE_NR(inode->i_rdev),err; if (inode && (dev < xd_drives)) switch (cmd) { @@ -255,11 +257,14 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) } break; case BLKRASET: - if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; - if(arg > 0xff) return -EINVAL; - read_ahead[MAJOR(inode->i_rdev)] = arg; - return 0; + if(!suser()) + return -EACCES; + if(!(inode->i_rdev)) + return -EINVAL; + if(arg > 0xff) + return -EINVAL; + read_ahead[MAJOR(inode->i_rdev)] = arg; + return 0; case BLKGETSIZE: if (arg) { if ((err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long)))) @@ -271,7 +276,8 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) break; case BLKFLSBUF: if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; + if(!(inode->i_rdev)) + return -EINVAL; fsync_dev(inode->i_rdev); invalidate_buffers(inode->i_rdev); return 0; @@ -286,29 +292,33 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) /* xd_release: release the device */ static void xd_release (struct inode *inode, struct file *file) { - int dev = DEVICE_NR(MINOR(inode->i_rdev)); + int dev = DEVICE_NR(inode->i_rdev); if (dev < xd_drives) { - sync_dev(dev); + sync_dev(inode->i_rdev); xd_access[dev]--; } } /* xd_reread_partitions: rereads the partition table from a drive */ -static int xd_reread_partitions(int dev) +static int xd_reread_partitions(kdev_t dev) { - int target = DEVICE_NR(MINOR(dev)),start = target << xd_gendisk.minor_shift,partition; + int target = DEVICE_NR(dev); + int start = target << xd_gendisk.minor_shift; + int partition; cli(); xd_valid[target] = (xd_access[target] != 1); sti(); if (xd_valid[target]) return (-EBUSY); for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) { - sync_dev(MAJOR_NR << 8 | start | partition); - invalidate_inodes(MAJOR_NR << 8 | start | partition); - invalidate_buffers(MAJOR_NR << 8 | start | partition); - xd_gendisk.part[start + partition].start_sect = 0; - xd_gendisk.part[start + partition].nr_sects = 0; + int minor = (start | partition); + kdev_t devp = MKDEV(MAJOR_NR, minor); + sync_dev(devp); + invalidate_inodes(devp); + invalidate_buffers(devp); + xd_gendisk.part[minor].start_sect = 0; + xd_gendisk.part[minor].nr_sects = 0; }; xd_gendisk.part[start].nr_sects = xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors; diff --git a/drivers/char/Makefile b/drivers/char/Makefile index cf31434ec4af..781478fa74f5 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -114,4 +114,4 @@ conmakehash: conmakehash.c $(HOSTCC) -o conmakehash conmakehash.c uni_hash.tbl: $(FONTMAPFILE) conmakehash - ./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash.tbl + ./conmakehash $(FONTMAPFILE) > uni_hash.tbl diff --git a/drivers/char/conmakehash.c b/drivers/char/conmakehash.c index 2221ed477d9d..ce59eda4f72a 100644 --- a/drivers/char/conmakehash.c +++ b/drivers/char/conmakehash.c @@ -1,14 +1,17 @@ /* * conmakehash.c * - * Create a pre-initialized kernel Unicode hash table + * Create arrays for initializing the kernel folded tables (using a hash + * table turned out to be to limiting...) Unfortunately we can't simply + * preinitialize the tables at compile time since kfree() cannot accept + * memory not allocated by kmalloc(), and doing our own memory management + * just for this seems like massive overkill. * * Copyright (C) 1995 H. Peter Anvin * - * This program may be freely copied under the terms of the GNU - * General Public License (GPL), version 2, or at your option - * any later version. - * + * This program is a part of the Linux kernel, and may be freely + * copied under the terms of the GNU General Public License (GPL), + * version 2, or at your option any later version. */ #include @@ -17,13 +20,9 @@ #include #include -typedef unsigned short unicode; +#define MAX_FONTLEN 256 -struct unipair -{ - unsigned short glyph; /* Glyph code */ - unicode uc; /* Unicode listed */ -}; +typedef unsigned short unicode; void usage(char *argv0) { @@ -46,40 +45,33 @@ int getunicode(char **p0) return strtol(p+2,0,16); } -struct unipair *hashtable; -int hashsize = 641; /* Size of hash table */ -int hashstep = 189; /* Hash stepping */ -int maxhashlevel = 6; /* Maximum hash depth */ -int hashlevel = 0; /* Actual hash depth */ +unicode unitable[MAX_FONTLEN][255]; + /* Massive overkill, but who cares? */ +int unicount[MAX_FONTLEN]; void addpair(int fp, int un) { - int i, lct; + int i; unicode hu; - if ( un <= 0xFFFE ) + if ( un <= 0xfffe ) { - /* Add to hash table */ + /* Check it isn't a duplicate */ + + for ( i = 0 ; i < unicount[fp] ; i++ ) + if ( unitable[fp][i] == un ) + return; - i = un % hashsize; - lct = 1; - - while ( (hu = hashtable[i].uc) != 0xffff && hu != un ) + /* Add to list */ + + if ( unicount[fp] > 254 ) { - if (lct++ >= maxhashlevel) - { - fprintf(stderr, "ERROR: Hash table overflow\n"); - exit(EX_DATAERR); - } - i += hashstep; - if ( i >= hashsize ) - i -= hashsize; + fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n"); + exit(EX_DATAERR); } - if ( lct > hashlevel ) - hashlevel = lct; - hashtable[i].uc = un; - hashtable[i].glyph = fp; + unitable[fp][unicount[fp]] = un; + unicount[fp]++; } /* otherwise: ignore */ @@ -91,7 +83,7 @@ int main(int argc, char *argv[]) char *tblname; char buffer[65536]; int fontlen; - int i; + int i, nuni, nent; int fp0, fp1, un0, un1; char *p, *p1; @@ -113,69 +105,13 @@ int main(int argc, char *argv[]) } } - if ( argc > 2 ) - { - hashsize = atoi(argv[2]); - if ( hashsize < 256 || hashsize > 2048 ) - { - fprintf(stderr, "Illegal hash size\n"); - exit(EX_USAGE); - } - } - - if ( argc > 3 ) - { - hashstep = atoi(argv[3]) % hashsize; - if ( hashstep < 0 ) hashstep += hashsize; - if ( hashstep < 16 || hashstep >= hashsize-16 ) - { - fprintf(stderr, "Bad hash step\n"); - exit(EX_USAGE); - } - } - - /* Warn the user in case the hashstep and hashsize are not relatively - prime -- this algorithm could be massively improved */ - - for ( i = hashstep ; i > 1 ; i-- ) - { - if ( hashstep % i == 0 && hashsize % i == 0 ) - break; /* Found GCD */ - } - - if ( i > 1 ) - { - fprintf(stderr, - "WARNING: hashsize and hashstep have common factors (gcd = %d)\n", i); - } - - if ( argc > 4 ) - { - maxhashlevel = atoi(argv[4]); - if ( maxhashlevel < 1 || maxhashlevel > hashsize ) - { - fprintf(stderr, "Illegal max hash level\n"); - exit(EX_USAGE); - } - } - - /* For now we assume the default font is always 256 characters */ + /* For now we assume the default font is always 256 characters. */ fontlen = 256; - /* Initialize hash table */ - - hashtable = malloc(hashsize * sizeof(struct unipair)); - if ( !hashtable ) - { - fprintf(stderr, "Could not allocate memory for hash table\n"); - exit(EX_OSERR); - } + /* Initialize table */ - for ( i = 0 ; i < hashsize ; i++ ) - { - hashtable[i].uc = 0xffff; - hashtable[i].glyph = 0; - } + for ( i = 0 ; i < fontlen ; i++ ) + unicount[i] = 0; /* Now we come to the tricky part. Parse the input table. */ @@ -304,57 +240,57 @@ int main(int argc, char *argv[]) fclose(ctbl); + + /* Compute total size of Unicode list */ + nuni = 0; + for ( i = 0 ; i < fontlen ; i++ ) + nuni += unicount[i]; + printf("\ /*\n\ * uni_hash.tbl\n\ *\n\ * Do not edit this file; it was automatically generated by\n\ *\n\ - * conmakehash %s %d %d %d > uni_hash.tbl\n\ + * conmakehash %s > uni_hash.tbl\n\ *\n\ */\n\ \n\ +#include \n\ #include \n\ \n\ -#define HASHSIZE %d\n\ -#define HASHSTEP %d\n\ -#define MAXHASHLEVEL %d\n\ -#define DEF_HASHLEVEL %d\n\ -\n\ -static unsigned int hashsize = HASHSIZE;\n\ -static unsigned int hashstep = HASHSTEP;\n\ -static unsigned int maxhashlevel = MAXHASHLEVEL;\n\ -static unsigned int hashlevel = DEF_HASHLEVEL;\n\ -\n\ -static struct unipair hashtable[HASHSIZE] =\n\ -{\n\t", argv[1], hashsize, hashstep, maxhashlevel, - hashsize, hashstep, maxhashlevel, hashlevel); - - for ( i = 0 ; i < hashsize ; i++ ) +static u8 dfont_unicount[%d] = \n\ +{\n\t", argv[1], fontlen); + + for ( i = 0 ; i < fontlen ; i++ ) { - printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph); - if ( i == hashsize-1 ) - printf("\n};\n"); - else if ( i % 4 == 3 ) - printf(",\n\t"); + printf("%3d", unicount[i]); + if ( i == fontlen-1 ) + printf("\n};\n"); + else if ( i % 8 == 7 ) + printf(",\n\t"); else - printf(", "); + printf(", "); } - printf("\n\ -#ifdef NEED_BACKUP_HASHTABLE\n\ -\n\ -static const struct unipair backup_hashtable[HASHSIZE] = \n{\n\t"); - - for ( i = 0 ; i < hashsize ; i++ ) + printf("\nstatic u16 dfont_unitable[%d] = \n{\n\t", nuni); + + fp0 = 0; + nent = 0; + for ( i = 0 ; i < nuni ; i++ ) { - printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph); - if ( i == hashsize-1 ) - printf("\n};\n#endif\n"); - else if ( i % 4 == 3 ) - printf(",\n\t"); - else - printf(", "); + while ( nent >= unicount[fp0] ) + { + fp0++; + nent = 0; + } + printf("0x%04x", unitable[fp0][nent++]); + if ( i == nuni-1 ) + printf("\n};"); + else if ( i % 8 == 7 ) + printf(",\n\t"); + else + printf(", "); } exit(EX_OK); diff --git a/drivers/char/console.c b/drivers/char/console.c index 6d8f206939e5..71d669962da8 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -71,7 +71,8 @@ * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94 * * - * Improved loadable font/UTF-8 support by H. Peter Anvin, Feb 1995 + * Improved loadable font/UTF-8 support by H. Peter Anvin + * Feb-Sep 1995 * * improved scrollback, plus colour palette handling, by Simon Tatham * 17-Jun-95 @@ -154,8 +155,8 @@ extern void register_console(void (*proc)(const char *)); extern void vesa_blank(void); extern void vesa_unblank(void); extern void compute_shiftstate(void); -extern void reset_palette (int currcons) ; -extern void set_palette (void) ; +extern void reset_palette(int currcons); +extern void set_palette(void); /* Description of the hardware situation */ static unsigned char video_type; /* Type of display being used */ @@ -172,10 +173,12 @@ static unsigned char video_page; /* Initial video page (unused) */ static unsigned long video_screen_size; static int can_do_color = 0; static int printable = 0; /* Is console ready for printing? */ - /* these two also used in in vt.c */ + /* these also used in in vt.c */ int video_mode_512ch = 0; /* 512-character mode */ unsigned long video_font_height; /* Height of current screen font */ unsigned long video_scan_lines; /* Number of scan lines on screen */ + unsigned long default_font_height; /* Height of default screen font */ +static int video_font_is_default = 1; static unsigned short console_charmask = 0x0ff; static unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; @@ -1102,6 +1105,14 @@ unsigned short screen_word(int currcons, int offset, int viewed) return scr_readw(screenpos(currcons, offset, viewed)); } +/* used by selection - convert a screen word to a glyph number */ +int scrw2glyph(unsigned short scr_word) +{ + return ( video_mode_512ch ) + ? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff) + : scr_word & 0x00ff; +} + /* used by vcs - note the word offset */ unsigned short *screen_pos(int currcons, int w_offset, int viewed) { @@ -2152,7 +2163,6 @@ long con_init(long kmem_start) set_origin(currcons); csi_J(currcons, 0); - /* Figure out the size of the screen and screen font so we can figure out the appropriate screen size should we load a different font */ @@ -2161,9 +2171,10 @@ long con_init(long kmem_start) if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM ) { - video_font_height = ORIG_VIDEO_POINTS; + default_font_height = video_font_height = ORIG_VIDEO_POINTS; /* This may be suboptimal but is a safe bet - go with it */ video_scan_lines = video_font_height * video_num_lines; + printk("Console: %ld point font, %ld scans\n", video_font_height, video_scan_lines); } @@ -2396,6 +2407,7 @@ static int set_get_font(char * arg, int set, int ch512) char *charmap; int beg; unsigned short video_port_status = video_port_reg + 6; + int font_select = 0x00; /* no use to "load" CGA... */ @@ -2411,11 +2423,30 @@ static int set_get_font(char * arg, int set, int ch512) beg = 0x0a; } else return -EINVAL; + + if (arg) + { + i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, + ch512 ? 2*cmapsz : cmapsz); + if (i) + return i; + } + else + ch512 = 0; /* Default font is always 256 */ - i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, - ch512 ? 2*cmapsz : cmapsz); - if (i) - return i; + /* + * The default font is kept in slot 0 and is never touched. + * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch) + */ + + if (set) + { + video_font_is_default = !arg; + font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00; + } + + if ( !video_font_is_default ) + charmap += 4*cmapsz; cli(); outb_p( 0x00, seq_port_reg ); /* First, the sequencer */ @@ -2434,31 +2465,35 @@ static int set_get_font(char * arg, int set, int ch512) outb_p( 0x06, gr_port_reg ); outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */ sti(); - - if (set) - for (i=0; i= 0 && glyph < MAX_GLYPH && q[glyph] < 32) { + /* prefer '-' above SHY etc. */ + q[glyph] = j; + } + } } unsigned short *set_translate(int m) @@ -194,13 +202,18 @@ unsigned short *set_translate(int m) /* * Inverse translation is impossible for several reasons: - * 1. The translation maps are not 1-1 + * 1. The font<->character maps are not 1-1. * 2. The text may have been written while a different translation map - * was active + * was active, or using Unicode. * Still, it is now possible to a certain extent to cut and paste non-ASCII. */ -unsigned char inverse_translate(unsigned char c) { - return ((inv_translate && inv_translate[c]) ? inv_translate[c] : c); +unsigned char inverse_translate(int glyph) { + if ( glyph < 0 || glyph >= MAX_GLYPH ) + return 0; + else + return ((inv_translate && inv_translate[glyph]) + ? inv_translate[glyph] + : (unsigned char)(glyph & 0xff)); } /* @@ -209,7 +222,7 @@ unsigned char inverse_translate(unsigned char c) { * * The "old" variants are for translation directly to font (using the * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set - * unicodes explictly. + * Unicodes explictly. */ int con_set_trans_old(unsigned char * arg) { @@ -243,6 +256,7 @@ int con_get_trans_old(unsigned char * arg) } return 0; } + int con_set_trans_new(ushort * arg) { int i; @@ -280,128 +294,189 @@ int con_get_trans_new(ushort * arg) * Unicode -> current font conversion * * A font has at most 512 chars, usually 256. - * But one font position may represent several Unicode chars - * (and moreover, hashtables work best when they are not too full), - * so pick HASHSIZE somewhat larger than 512. - * Since there are likely to be long consecutive stretches - * (like U+0000 to U+00FF), HASHSTEP should not be too small. - * Searches longer than MAXHASHLEVEL steps are refused, unless - * requested explicitly. - * - * Note: no conversion tables are compiled in, so the user - * must supply an explicit mapping herself. See kbd-0.90 (or an - * earlier kernel version) for the default Unicode-to-PC mapping. - * Usually, the mapping will be loaded simultaneously with the font. + * But one font position may represent several Unicode chars. + * A hashtable is somewhat of a pain to deal with, so use a + * "paged table" instead. Simulation has shown the memory cost of + * this 3-level paged table scheme to be comparable to a hash table. */ #include "uni_hash.tbl" /* Include hash tables & parameters */ -int hashtable_contents_valid = 1; +int hashtable_contents_valid = 0; /* Use ASCII-only mode for bootup*/ + +static u16 **uni_pagedir[32] = +{ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +static int +con_insert_unipair(u_short unicode, u_short fontpos) +{ + int i, n; + u16 **p1, *p2; + + if ( !(p1 = uni_pagedir[n = unicode >> 11]) ) + { + p1 = uni_pagedir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL); + if ( !p1 ) + return -ENOMEM; + + for ( i = 0 ; i < 32 ; i++ ) + p1[i] = NULL; + } + + if ( !(p2 = p1[n = (unicode >> 6) & 0x1f]) ) + { + p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL); + if ( !p2 ) + return -ENOMEM; + + for ( i = 0 ; i < 64 ; i++ ) + p2[i] = 0xffff; /* No glyph for this character (yet) */ + } + + p2[unicode & 0x3f] = fontpos; + + return 0; +} + +/* ui is a leftover from using a hashtable, but might be used again */ void -con_clear_unimap(struct unimapinit *ui) { - int i; +con_clear_unimap(struct unimapinit *ui) +{ + int i, j; + u16 **p1; + + for ( i = 0 ; i < 32 ; i++ ) + { + if ( (p1 = uni_pagedir[i]) != NULL ) + { + for ( j = 0 ; j < 32 ; j++ ) + { + if ( p1[j] ) + kfree(p1[j]); + } + kfree(p1); + } + uni_pagedir[i] = NULL; + } - /* read advisory values for hash algorithm */ - hashsize = ui->advised_hashsize; - if (hashsize < 256 || hashsize > HASHSIZE) - hashsize = HASHSIZE; - hashstep = (ui->advised_hashstep % hashsize); - if (hashstep < 64) - hashstep = HASHSTEP; - maxhashlevel = ui->advised_hashlevel; - if (!maxhashlevel) - maxhashlevel = MAXHASHLEVEL; - if (maxhashlevel > hashsize) - maxhashlevel = hashsize; - - /* initialize */ - hashlevel = 0; - for (i=0; iunicode); - i = u % hashsize; - lct = 1; - while ((hu = hashtable[i].unicode) != 0xffff && hu != u) { - if (lct++ >= maxhashlevel) - return -ENOMEM; - i += hashstep; - if (i >= hashsize) - i -= hashsize; - } - if (lct > hashlevel) - hashlevel = lct; - hashtable[i].unicode = u; - hashtable[i].fontpos = get_user(&list->fontpos); - list++; - ct--; - } +con_set_unimap(ushort ct, struct unipair *list) +{ + int err = 0, err1, i; + + while( ct-- ) + { + if ( (err1 = con_insert_unipair(get_user(&list->unicode), + get_user(&list->fontpos))) != 0 ) + err = err1; + list++; + } + + for ( i = 0 ; i <= 3 ; i++ ) + set_inverse_transl(i); /* Update all inverse translations */ + + return err; +} - for ( i = 0 ; i <= 3 ; i++ ) - set_inverse_transl(i); /* Update all inverse translations */ +/* Loads the unimap for the hardware font, as defined in uni_hash.tbl. + The representation used was the most compact I could come up + with. This routine is executed at sys_setup time, and when the + PIO_FONTRESET ioctl is called. */ - return 0; +void +con_set_default_unimap(void) +{ + int i, j; + u16 *p; + + /* The default font is always 256 characters */ + + con_clear_unimap(NULL); + + p = dfont_unitable; + for ( i = 0 ; i < 256 ; i++ ) + for ( j = dfont_unicount[i] ; j ; j-- ) + con_insert_unipair(*(p++), i); + + for ( i = 0 ; i <= 3 ; i++ ) + set_inverse_transl(i); /* Update all inverse translations */ } int con_get_unimap(ushort ct, ushort *uct, struct unipair *list){ - int i, ect; + int i, j, k, ect; + u16 **p1, *p2; ect = 0; if (hashtable_contents_valid) - for (i = 0; iunicode); - put_user(hashtable[i].fontpos, &list->fontpos); - list++; - } - } + { + for ( i = 0 ; i < 32 ; i++ ) + if ( (p1 = uni_pagedir[i]) != NULL ) + for ( j = 0 ; j < 32 ; j++ ) + if ( (p2 = *(p1++)) != NULL ) + for ( k = 0 ; k < 64 ; k++ ) + { + if ( *p2 < MAX_GLYPH && ect++ < ct ) + { + put_user((u_short)((i<<11)+(j<<6)+k), + &list->unicode); + put_user((u_short) *p2, &list->fontpos); + list++; + } + p2++; + } + } put_user(ect, uct); return ((ect <= ct) ? 0 : -ENOMEM); } int -conv_uni_to_pc(long ucs) { - int i, h; - - /* Only 16-bit codes supported at this time */ - if (ucs > 0xffff) - ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ - else if (ucs < 0x20 || ucs >= 0xfffe) - return -1; /* Not a printable character */ - else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) - return -2; /* Zero-width space */ - /* - * UNI_DIRECT_BASE indicates the start of the region in the User Zone - * which always has a 1:1 mapping to the currently loaded font. The - * UNI_DIRECT_MASK indicates the bit span of the region. - */ - else if ( (ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE ) - return ucs & UNI_DIRECT_MASK; - - if (!hashtable_contents_valid) - return -3; - - h = ucs % hashsize; - for (i = 0; i < hashlevel; i++) { - if (hashtable[h].unicode == ucs) - return hashtable[h].fontpos; - if ((h += hashstep) >= hashsize) - h -= hashsize; - } - - return -4; /* not found */ +conv_uni_to_pc(long ucs) +{ + int h; + u16 **p1, *p2; + + /* Only 16-bit codes supported at this time */ + if (ucs > 0xffff) + ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ + else if (ucs < 0x20 || ucs >= 0xfffe) + return -1; /* Not a printable character */ + else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) + return -2; /* Zero-width space */ + /* + * UNI_DIRECT_BASE indicates the start of the region in the User Zone + * which always has a 1:1 mapping to the currently loaded font. The + * UNI_DIRECT_MASK indicates the bit span of the region. + */ + else if ( (ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE ) + return ucs & UNI_DIRECT_MASK; + + if (!hashtable_contents_valid) + return -3; + + if ( (p1 = uni_pagedir[ucs >> 11]) && + (p2 = p1[(ucs >> 6) & 0x1f]) && + (h = p2[ucs & 0x3f]) < MAX_GLYPH ) + return h; + + return -4; /* not found */ +} + +/* + * This is called at sys_setup time, after memory and the console are + * initialized. It must be possible to call kmalloc(..., GFP_KERNEL) + * from this function, hence the call from sys_setup. + */ +void +console_map_init(void) +{ + con_set_default_unimap(); } diff --git a/drivers/char/consolemap.h b/drivers/char/consolemap.h index 4b6caad40062..9aba19db33b9 100644 --- a/drivers/char/consolemap.h +++ b/drivers/char/consolemap.h @@ -9,6 +9,6 @@ #define USER_MAP 3 extern int hashtable_contents_valid; -extern unsigned char inverse_translate(unsigned char c); +extern unsigned char inverse_translate(int glyph); extern unsigned short *set_translate(int m); extern int conv_uni_to_pc(long ucs); diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 8ef658fa26f0..54b98a08a5aa 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -412,29 +412,29 @@ static void show_status(int); static inline int serial_paranoia_check(struct cyclades_port *info, - dev_t device, const char *routine) + kdev_t device, const char *routine) { #ifdef SERIAL_PARANOIA_CHECK static const char *badmagic = - "Warning: bad magic number for serial struct (%d, %d) in %s\n"; + "Warning: bad magic number for serial struct (%s) in %s\n"; static const char *badinfo = - "Warning: null cyclades_port for (%d, %d) in %s\n"; + "Warning: null cyclades_port for (%s) in %s\n"; static const char *badrange = - "Warning: cyclades_port out of range for (%d, %d) in %s\n"; + "Warning: cyclades_port out of range for (%s) in %s\n"; if (!info) { - printk(badinfo, MAJOR(device), MINOR(device), routine); + printk(badinfo, kdevname(device), routine); return 1; } if( (long)info < (long)(&cy_port[0]) || (long)(&cy_port[NR_PORTS]) < (long)info ){ - printk(badrange, MAJOR(device), MINOR(device), routine); + printk(badrange, kdevname(device), routine); return 1; } if (info->magic != CYCLADES_MAGIC) { - printk(badmagic, MAJOR(device), MINOR(device), routine); + printk(badmagic, kdevname(device), routine); return 1; } #endif @@ -1585,7 +1585,7 @@ cy_flush_chars(struct tty_struct *tty) */ static int cy_write(struct tty_struct * tty, int from_user, - unsigned char *buf, int count) + const unsigned char *buf, int count) { struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; @@ -2968,7 +2968,7 @@ cy_detect_pci() unsigned char cyy_bus, cyy_dev_fn, cyy_rev_id; unsigned long pci_intr_ctrl; unsigned char cy_pci_irq; - unsigned long cy_pci_address,cy_pci_io; + unsigned int cy_pci_address, cy_pci_io; unsigned short i,j,cy_pci_nchan; #ifndef CONFIG_PCI diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 6870bffa15db..6eba5ec7b2f9 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -528,8 +528,37 @@ static struct file_operations lp_fops = { lp_release }; +static int lp_probe(int offset) +{ + int base, size; + unsigned int testvalue; + + base = LP_B(offset); + size = (base == 0x3bc)? 3 : 8; + if (check_region(base, size) < 0) + return -1; + /* write to port & read back to check */ + outb_p(LP_DUMMY, base); + udelay(LP_DELAY); + testvalue = inb_p(base); + if (testvalue == LP_DUMMY) { + LP_F(offset) |= LP_EXIST; + lp_reset(offset); + printk("lp%d at 0x%04x, ", offset, base); + request_region(base, size, "lp"); + if (LP_IRQ(offset)) + printk("(irq = %d)\n", LP_IRQ(offset)); + else + printk("(polling)\n"); + return 1; + } else + return 0; +} + #ifdef MODULE char kernel_version[]=UTS_RELEASE; +int io[] = {0, 0, 0}; +int irq[] = {0, 0, 0}; int init_module(void) #else @@ -537,9 +566,7 @@ long lp_init(long kmem_start) #endif { int offset = 0; - unsigned int testvalue; int count = 0; - int base,size; if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) { printk("lp: unable to get major %d\n", LP_MAJOR); @@ -549,49 +576,52 @@ long lp_init(long kmem_start) return kmem_start; #endif } +#ifdef MODULE + /* When user feeds parameters, use them */ + for (offset=0; offset < LP_NO; offset++) { + int specified=0; + + if (io[offset] != 0) { + LP_B(offset) = io[offset]; + specified++; + } + if (irq[offset] != 0) { + LP_IRQ(offset) = irq[offset]; + specified++; + } + if (specified) { + if (lp_probe(offset) <= 0) { + printk(KERN_INFO "lp%d: Not found\n", offset); + return -EIO; + } else + count++; + } + } + if (count) + return 0; +#endif /* take on all known port values */ for (offset = 0; offset < LP_NO; offset++) { - base = LP_B(offset); - size = (base == 0x3bc)? 3 : 8; - if (check_region(base, size)) + int ret = lp_probe(offset); + if (ret < 0) continue; - /* write to port & read back to check */ - outb_p( LP_DUMMY, base); - udelay(LP_DELAY); - testvalue = inb_p(base); - if (testvalue == LP_DUMMY) { - LP_F(offset) |= LP_EXIST; - lp_reset(offset); - printk("lp%d at 0x%04x, ", offset,base); - request_region(base, size, "lp"); - if (LP_IRQ(offset)) - printk("(irq = %d)\n", LP_IRQ(offset)); - else - printk("(polling)\n"); - count++; - } + count += ret; } if (count == 0) printk("lp: Driver configured but no interfaces found.\n"); - #ifdef MODULE return 0; #else return kmem_start; #endif } - int base,size; #ifdef MODULE void cleanup_module(void) { int offset; - if(MOD_IN_USE) { - printk("lp: busy - remove delayed\n"); - return; - } unregister_chrdev(LP_MAJOR,"lp"); for (offset = 0; offset < LP_NO; offset++) { int base, size; @@ -601,5 +631,4 @@ void cleanup_module(void) release_region(LP_B(offset),size); } } - #endif diff --git a/drivers/char/scc.c b/drivers/char/scc.c index b6c71e03d037..ed76378da381 100644 --- a/drivers/char/scc.c +++ b/drivers/char/scc.c @@ -1685,21 +1685,22 @@ z8530_init(void) /* scc_paranoia_check(): warn user if something went wrong */ -static inline int scc_paranoia_check(struct scc_channel *scc, dev_t device, const char *routine) +static inline int scc_paranoia_check(struct scc_channel *scc, kdev_t device, + const char *routine) { #ifdef SCC_PARANOIA_CHECK static const char *badmagic = - "Warning: bad magic number for Z8530 SCC struct (%d, %d) in %s\n"; + "Warning: bad magic number for Z8530 SCC struct (%s) in %s\n"; static const char *badinfo = - "Warning: Z8530 not found for (%d, %d) in %s\n"; + "Warning: Z8530 not found for (%s) in %s\n"; if (!scc->init) { - printk(badinfo, MAJOR(device), MINOR(device), routine); + printk(badinfo, kdevname(device), routine); return 1; } if (scc->magic != SCC_MAGIC) { - printk(badmagic, MAJOR(device), MINOR(device), routine); + printk(badmagic, kdevname(device), routine); return 1; } #endif @@ -1729,7 +1730,9 @@ int scc_open(struct tty_struct *tty, struct file * filp) if (scc->magic != SCC_MAGIC) { - printk("ERROR: scc_open(): bad magic number for device (%d, %d)", MAJOR(tty->device), MINOR(tty->device)); + printk("ERROR: scc_open(): bad magic number for device (" + "%s)", + kdevname(tty->device)); return -ENODEV; } @@ -1838,8 +1841,8 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned if (scc->magic != SCC_MAGIC) { - printk("ERROR: scc_ioctl(): bad magic number for device %d,%d", - MAJOR(tty->device), MINOR(tty->device)); + printk("ERROR: scc_ioctl(): bad magic number for device %s", + kdevname(tty->device)); return -ENODEV; } diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 86ad6e9c5123..c9a77f606555 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c @@ -38,7 +38,7 @@ static int sel_end; static int sel_buffer_lth = 0; static char *sel_buffer = NULL; -#define sel_pos(n) inverse_translate(screen_word(sel_cons, n, 1) & 0xff) +#define sel_pos(n) inverse_translate(scrw2glyph(screen_word(sel_cons, n, 1))) /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ diff --git a/drivers/char/selection.h b/drivers/char/selection.h index 9d51f7e87065..7989992919a8 100644 --- a/drivers/char/selection.h +++ b/drivers/char/selection.h @@ -19,6 +19,7 @@ extern unsigned long video_size_row; extern void do_unblank_screen(void); extern unsigned short *screen_pos(int currcons, int w_offset, int viewed); extern unsigned short screen_word(int currcons, int offset, int viewed); +extern int scrw2glyph(unsigned short scr_word); extern void complement_pos(int currcons, int offset); extern void invert_screen(int currcons, int offset, int count, int shift); diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 5e3817083cca..48b4edfeaeb6 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -204,20 +204,20 @@ static unsigned char *tmp_buf = 0; static struct semaphore tmp_buf_sem = MUTEX; static inline int serial_paranoia_check(struct async_struct *info, - dev_t device, const char *routine) + kdev_t device, const char *routine) { #ifdef SERIAL_PARANOIA_CHECK static const char *badmagic = - "Warning: bad magic number for serial struct (%d, %d) in %s\n"; + "Warning: bad magic number for serial struct (%s) in %s\n"; static const char *badinfo = - "Warning: null async_struct for (%d, %d) in %s\n"; + "Warning: null async_struct for (%s) in %s\n"; if (!info) { - printk(badinfo, MAJOR(device), MINOR(device), routine); + printk(badinfo, kdevname(device), routine); return 1; } if (info->magic != SERIAL_MAGIC) { - printk(badmagic, MAJOR(device), MINOR(device), routine); + printk(badmagic, kdevname(device), routine); return 1; } #endif diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c index a9ff859c8e0d..69f20e8cfd11 100644 --- a/drivers/char/tpqic02.c +++ b/drivers/char/tpqic02.c @@ -287,7 +287,7 @@ static volatile unsigned long dma_bytes_done; static volatile unsigned dma_mode = 0; /* !=0 also means DMA in use */ static flag need_rewind = YES; -static dev_t current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0); +static kdev_t current_tape_dev; static int extra_blocks_left = BLOCKS_BEYOND_EW; @@ -1918,7 +1918,7 @@ static int qic02_tape_lseek(struct inode * inode, struct file * file, off_t offs static int qic02_tape_read(struct inode * inode, struct file * filp, char * buf, int count) { int error; - dev_t dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; int stat; @@ -2093,7 +2093,7 @@ static int qic02_tape_read(struct inode * inode, struct file * filp, char * buf, static int qic02_tape_write(struct inode * inode, struct file * filp, const char * buf, int count) { int error; - dev_t dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; @@ -2244,14 +2244,15 @@ static int qic02_tape_write(struct inode * inode, struct file * filp, const char */ static int qic02_tape_open(struct inode * inode, struct file * filp) { - dev_t dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; unsigned short flags = filp->f_flags; unsigned short dens = 0; int s; if (TP_DIAGS(dev)) { - printk("qic02_tape_open: dev=%x, flags=%x ", dev, flags); + printk("qic02_tape_open: dev=%s, flags=%x ", + kdevname(dev), flags); } if (MINOR(dev)==255) /* special case for resetting */ @@ -2419,7 +2420,7 @@ static int qic02_tape_open(struct inode * inode, struct file * filp) } if (s != 0) { status_dead = YES; /* force reset */ - current_tape_dev = 0xff80; + current_tape_dev = 0; /* earlier 0xff80 */ return -EIO; } @@ -2429,10 +2430,11 @@ static int qic02_tape_open(struct inode * inode, struct file * filp) static void qic02_tape_release(struct inode * inode, struct file * filp) { - dev_t dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; if (TP_DIAGS(dev)) - printk("qic02_tape_release: dev=%x\n", dev); + printk("qic02_tape_release: dev=%s\n", + kdevname(dev)); if (status_zombie==YES) /* don't rewind in zombie mode */ return; @@ -2868,7 +2870,6 @@ static int qic02_get_resources(void) } /* qic02_get_resources */ - long qic02_tape_init(long kmem_start) /* Shouldn't this be a caddr_t ? */ { @@ -2884,6 +2885,8 @@ long qic02_tape_init(long kmem_start) QIC02_TAPE_DEBUG = TPQD_DEFAULT_FLAGS; + current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0); + #ifndef CONFIG_QIC02_DYNCONF printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n", QIC02_TAPE_IRQ, QIC02_TAPE_DMA, diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 7b916bb59bf5..c5c1ea8e3177 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -40,6 +40,7 @@ * -- ctm@ardi.com, 9Sep95 */ +#include #include #include #include @@ -55,7 +56,6 @@ #include #include #include -#include #include #include @@ -134,21 +134,21 @@ char *tty_name(struct tty_struct *tty) return(_tty_name(tty, buf)); } -inline int tty_paranoia_check(struct tty_struct *tty, dev_t device, +inline int tty_paranoia_check(struct tty_struct *tty, kdev_t device, const char *routine) { #ifdef TTY_PARANOIA_CHECK static const char *badmagic = - "Warning: bad magic number for tty struct (%d, %d) in %s\n"; + "Warning: bad magic number for tty struct (%s) in %s\n"; static const char *badtty = - "Warning: null TTY for (%d, %d) in %s\n"; + "Warning: null TTY for (%s) in %s\n"; if (!tty) { - printk(badtty, MAJOR(device), MINOR(device), routine); + printk(badtty, kdevname(device), routine); return 1; } if (tty->magic != TTY_MAGIC) { - printk(badmagic, MAJOR(device), MINOR(device), routine); + printk(badmagic, kdevname(device), routine); return 1; } #endif @@ -173,9 +173,8 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) tty->link && tty->link->count) count++; if (tty->count != count) { - printk("Warning: dev (%d, %d) tty->count(%d) != #fd's(%d) in %s\n", - MAJOR(tty->device), MINOR(tty->device), tty->count, - count, routine); + printk("Warning: dev (%s) tty->count(%d) != #fd's(%d) in %s\n", + kdevname(tty->device), tty->count, count, routine); return count; } #endif @@ -246,7 +245,7 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) /* * This routine returns a tty driver structure, given a device number */ -struct tty_driver *get_tty_driver(dev_t device) +struct tty_driver *get_tty_driver(kdev_t device) { int major, minor; struct tty_driver *p; @@ -357,7 +356,8 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops) continue; if (filp->private_data != tty) continue; - if (filp->f_inode && filp->f_inode->i_rdev == CONSOLE_DEV) + if (filp->f_inode + && filp->f_inode->i_rdev == CONSOLE_DEV) continue; if (filp->f_op != &tty_fops) continue; @@ -763,7 +763,7 @@ static int tty_write(struct inode * inode, struct file * file, const char * buf, * unless you know exactly what you are doing. All the changes have to be * made atomically, or there may be incorrect pointers all over the place. */ -static int init_dev(dev_t device, struct tty_struct **ret_tty) +static int init_dev(kdev_t device, struct tty_struct **ret_tty) { struct tty_struct *tty, **tty_loc, *o_tty, **o_tty_loc; struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; @@ -824,7 +824,7 @@ repeat: o_ltp_loc = &driver->other->termios_locked[idx]; if (!*o_tty_loc && !o_tty) { - dev_t o_device; + kdev_t o_device; o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL); @@ -962,23 +962,25 @@ static void release_dev(struct file * filp) idx = MINOR(tty->device) - tty->driver.minor_start; #ifdef TTY_PARANOIA_CHECK if (idx < 0 || idx >= tty->driver.num) { - printk("release_dev: bad idx when trying to free (%d, %d)\n", - MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: bad idx when trying to free (%s)\n", + kdevname(tty->device)); return; } if (tty != tty->driver.table[idx]) { - printk("release_dev: driver.table[%d] not tty for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: driver.table[%d] not tty for (%s)\n", + idx, kdevname(tty->device)); return; } if (tp != tty->driver.termios[idx]) { - printk("release_dev: driver.termios[%d] not termios for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: driver.termios[%d] not termios for (" + "%s)\n", + idx, kdevname(tty->device)); return; } if (ltp != tty->driver.termios_locked[idx]) { - printk("release_dev: driver.termios_locked[%d] not termios_locked for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: driver.termios_locked[%d] not termios_locked for (" + "%s)\n", + idx, kdevname(tty->device)); return; } #endif @@ -995,18 +997,21 @@ static void release_dev(struct file * filp) #ifdef TTY_PARANOIA_CHECK if (tty->driver.other) { if (o_tty != tty->driver.other->table[idx]) { - printk("release_dev: other->table[%d] not o_tty for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: other->table[%d] not o_tty for (" + "%s)\n", + idx, kdevname(tty->device)); return; } if (o_tp != tty->driver.other->termios[idx]) { - printk("release_dev: other->termios[%d] not o_termios for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: other->termios[%d] not o_termios for (" + "%s)\n", + idx, kdevname(tty->device)); return; } if (o_ltp != tty->driver.other->termios_locked[idx]) { - printk("release_dev: other->termios_locked[%d] not o_termios_locked for (%d, %d)\n", - idx, MAJOR(tty->device), MINOR(tty->device)); + printk("release_dev: other->termios_locked[%d] not o_termios_locked for (" + "%s)\n", + idx, kdevname(tty->device)); return; } @@ -1132,7 +1137,7 @@ static int tty_open(struct inode * inode, struct file * filp) struct tty_struct *tty; int minor; int noctty, retval; - dev_t device; + kdev_t device; retry_open: noctty = filp->f_flags & O_NOCTTY; diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index f712fc28ffba..1991a0205188 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -210,7 +210,7 @@ static unsigned long inq_canon(struct tty_struct * tty) #ifdef TIOCGETP /* - * These are depracated, but there is limited support.. + * These are deprecated, but there is limited support.. * * The "sg_flags" translation is a joke.. */ diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 5a50ef1655f5..e3333b45b3cc 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -71,6 +71,7 @@ extern int con_get_trans_new(unsigned short * table); extern void con_clear_unimap(struct unimapinit *ui); extern int con_set_unimap(ushort ct, struct unipair *list); extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list); +extern void con_set_default_unimap(void); extern int con_set_font(char * fontmap, int ch512); extern int con_get_font(char * fontmap); extern int con_set_cmap(unsigned char *cmap); @@ -80,6 +81,7 @@ extern int con_adjust_height(unsigned long fontheight); extern int video_mode_512ch; extern unsigned long video_font_height; +extern unsigned long default_font_height; extern unsigned long video_scan_lines; /* @@ -976,6 +978,23 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return -EINVAL; } + case PIO_FONTRESET: + { + if (!perm) + return -EPERM; + if (vt_cons[fg_console]->vc_mode != KD_TEXT) + return -EINVAL; + + i = con_set_font(NULL, 0); /* Set font to default */ + if (i) return i; + + i = con_adjust_height(default_font_height); + if ( i > 0 ) kd_size_changed(i, 0); + con_set_default_unimap(); + + return 0; + } + case GIO_FONTX: { struct consolefontdesc cfdarg; diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 204cc76c94c6..487a5406d797 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -324,7 +324,7 @@ el16_probe(struct device *dev) return 0; } - return ENODEV; /* ENODEV would be more accurate. */ + return ENODEV; } int el16_probe1(struct device *dev, int ioaddr) diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 93e4fd417a7b..b5462ce4be54 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -340,7 +340,7 @@ express_probe(struct device *dev) return 0; } - return ENODEV; /* ENODEV would be more accurate. */ + return ENODEV; } int eexp_probe1(struct device *dev, short ioaddr) diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 87b25c81299c..7ad84018c5cb 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1,4 +1,4 @@ -/* $Id: plip.c,v 1.12 1995/02/11 10:26:05 gniibe Exp $ */ +/* $Id: plip.c,v 1.14 1995/09/18 04:57:24 gniibe Exp $ */ /* PLIP: A parallel port "network" driver for Linux. */ /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */ /* @@ -12,6 +12,19 @@ * Modularization and ifreq/ifmap support by Alan Cox. * Rewritten by Niibe Yutaka. * + * Fixes: + * 9-Sep-95 Philip Blundell + * - only claim 3 bytes of I/O space for port at 0x3bc + * - treat NULL return from register_netdev() as success in + * init_module() + * - added message if driver loaded as a module but no + * interfaces present. + * - release claimed I/O ports if malloc() fails during init. + * + * Niibe Yutaka + * - Module initialization. You can specify I/O addr and IRQ: + * # insmod plip.o io=0x3bc irq=7 + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -32,7 +45,7 @@ * So, this PLIP can't communicate the PLIP of Linux v1.0. */ -static const char *version = "NET3 PLIP version 2.0 gniibe@mri.co.jp\n"; +static const char *version = "NET3 PLIP version 2.1 gniibe@mri.co.jp\n"; /* Sources: @@ -205,9 +218,10 @@ int plip_init(struct device *dev) { struct net_local *nl; + int iosize = (PAR_DATA(dev) == 0x3bc) ? 3 : 8; /* Check region before the probe */ - if (check_region(PAR_DATA(dev), (PAR_DATA(dev) == 0x3bc)? 4 : 8) < 0) + if (check_region(PAR_DATA(dev), iosize) < 0) return -ENODEV; /* Check that there is something at base_addr. */ @@ -244,7 +258,7 @@ plip_init(struct device *dev) " Please set IRQ by ifconfig.\n", irq); } - request_region(PAR_DATA(dev), (PAR_DATA(dev) == 0x3bc)? 4 : 8, dev->name); + request_region(PAR_DATA(dev), iosize, dev->name); /* Fill in the generic fields of the device structure. */ ether_setup(dev); @@ -260,8 +274,11 @@ plip_init(struct device *dev) /* Set the private structure */ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL); - if (dev->priv == NULL) + if (dev->priv == NULL) { + printk(KERN_ERR "%s: out of memory\n", dev->name); + release_region(PAR_DATA(dev), iosize); return -ENOMEM; + } memset(dev->priv, 0, sizeof(struct net_local)); nl = (struct net_local *) dev->priv; @@ -467,12 +484,10 @@ plip_receive(unsigned short nibble_timeout, unsigned short status_addr, outb(0x00, --status_addr); /* send ACK */ status_addr++; *ns_p = PLIP_NB_BEGIN; - return OK; - case PLIP_NB_2: break; } - return TIMEOUT; /* XX: ?? */ + return OK; } /* PLIP_RECEIVE_PACKET --- receive a packet */ @@ -634,7 +649,7 @@ plip_send(unsigned short nibble_timeout, unsigned short data_addr, *ns_p = PLIP_NB_BEGIN; return OK; } - return TIMEOUT; + return OK; } /* PLIP_SEND_PACKET --- send a packet */ @@ -1036,67 +1051,84 @@ plip_ioctl(struct device *dev, struct ifreq *rq, int cmd) #ifdef MODULE char kernel_version[] = UTS_RELEASE; - -static struct device dev_plip0 = -{ - "plip0" /*"plip"*/, - 0, 0, 0, 0, /* memory */ - 0x3BC, 5, /* base, irq */ - 0, 0, 0, NULL, plip_init -}; - -static struct device dev_plip1 = -{ - "plip1" /*"plip"*/, - 0, 0, 0, 0, /* memory */ - 0x378, 7, /* base, irq */ - 0, 0, 0, NULL, plip_init -}; - -static struct device dev_plip2 = -{ - "plip2" /*"plip"*/, - 0, 0, 0, 0, /* memory */ - 0x278, 2, /* base, irq */ - 0, 0, 0, NULL, plip_init +int io[] = {0, 0, 0}; +int irq[] = {0, 0, 0}; + +static struct device dev_plip[] = { + { + "plip0", + 0, 0, 0, 0, /* memory */ + 0x3BC, 5, /* base, irq */ + 0, 0, 0, NULL, plip_init + }, + { + "plip1", + 0, 0, 0, 0, /* memory */ + 0x378, 7, /* base, irq */ + 0, 0, 0, NULL, plip_init + }, + { + "plip2", + 0, 0, 0, 0, /* memory */ + 0x278, 2, /* base, irq */ + 0, 0, 0, NULL, plip_init + } }; int init_module(void) { + int no_parameters=1; int devices=0; + int i; + + /* When user feeds parameters, use them */ + for (i=0; i < 3; i++) { + int specified=0; + + if (io[i] != 0) { + dev_plip[i].base_addr = io[i]; + specified++; + } + if (irq[i] != 0) { + dev_plip[i].irq = irq[i]; + specified++; + } + if (specified) { + if (register_netdev(&dev_plip[i]) != 0) { + printk(KERN_INFO "plip%d: Not found\n", i); + return -EIO; + } + no_parameters = 0; + } + } + if (!no_parameters) + return 0; - if (register_netdev(&dev_plip0) != 0) - devices++; - if (register_netdev(&dev_plip1) != 0) - devices++; - if (register_netdev(&dev_plip2) != 0) - devices++; - if (devices == 0) + /* No parameters. Default action is probing all interfaces. */ + for (i=0; i < 3; i++) { + if (register_netdev(&dev_plip[i]) == 0) + devices++; + } + if (devices == 0) { + printk(KERN_INFO "plip: no interfaces found\n"); return -EIO; + } return 0; } void cleanup_module(void) { - if (dev_plip0.priv) { - unregister_netdev(&dev_plip0); - release_region(PAR_DATA(&dev_plip0), (PAR_DATA(&dev_plip0) == 0x3bc)? 4 : 8); - kfree_s(dev_plip0.priv, sizeof(struct net_local)); - dev_plip0.priv = NULL; - } - if (dev_plip1.priv) { - unregister_netdev(&dev_plip1); - release_region(PAR_DATA(&dev_plip1), (PAR_DATA(&dev_plip1) == 0x3bc)? 4 : 8); - kfree_s(dev_plip1.priv, sizeof(struct net_local)); - dev_plip1.priv = NULL; - } - if (dev_plip2.priv) { - unregister_netdev(&dev_plip2); - release_region(PAR_DATA(&dev_plip2), (PAR_DATA(&dev_plip2) == 0x3bc)? 4 : 8); - kfree_s(dev_plip2.priv, sizeof(struct net_local)); - dev_plip2.priv = NULL; + int i; + + for (i=0; i < 3; i++) { + if (dev_plip[i].priv) { + unregister_netdev(&dev_plip[i]); + release_region(PAR_DATA(&dev_plip[i]), (PAR_DATA(&dev_plip[i]) == 0x3bc)? 3 : 8); + kfree_s(dev_plip[i].priv, sizeof(struct net_local)); + dev_plip[i].priv = NULL; + } } } #endif /* MODULE */ diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index d52d38d5b8f1..b096ef5ecd27 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -32,6 +32,7 @@ #define OPTIMIZE_FLAG_TIME ((HZ * 3)/2) /* */ #define CHECK_CHARACTERS +#include #ifdef MODULE #include #include diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c91df72ffe01..b8c9299be1df 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -109,7 +109,7 @@ struct pci_dev_info dev_info[] = { DEVICE( QLOGIC, QLOGIC_ISP1022, "ISP1022"), DEVICE( LEADTEK, LEADTEK_805, "S3 805"), DEVICE( CONTAQ, CONTAQ_82C599, "82C599"), - DEVICE( CMD, CMD_640, "640A"), + DEVICE( CMD, CMD_640, "640 (buggy)"), DEVICE( VISION, VISION_QD8500, "QD-8500"), DEVICE( VISION, VISION_QD8580, "QD-8580"), DEVICE( WINBOND, WINBOND_83769, "W83769F"), @@ -150,9 +150,9 @@ struct pci_dev_info dev_info[] = { BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00), DEVICE( INTEL, INTEL_7116, "SAA7116"), DEVICE( INTEL, INTEL_82865, "82865"), - DEVICE( INTEL, INTEL_82437, "82437 Triton"), - DEVICE( INTEL, INTEL_82371, "82371 Triton"), - DEVICE( INTEL, INTEL_82438, "82438"), + DEVICE( INTEL, INTEL_82437, "82437"), + DEVICE( INTEL, INTEL_82371_0, "82371 Triton PIIX"), + DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"), DEVICE( INTEL, INTEL_P6, "Experimental P6 bridge"), DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"), DEVICE( ADAPTEC, ADAPTEC_294x, "294x"), diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c index ef2bc826f4b7..d8603ef90c68 100644 --- a/drivers/scsi/53c7,8xx.c +++ b/drivers/scsi/53c7,8xx.c @@ -178,6 +178,12 @@ #include "53c7,8xx.h" #include "constants.h" #include "sd.h" +#include + +struct proc_dir_entry proc_scsi_ncr53c7xx = { + PROC_SCSI_NCR53C7xx, 9, "ncr53c7xx", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); static int NCR53c8xx_run_tests (struct Scsi_Host *host); @@ -987,7 +993,6 @@ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) { int count; /* Number of boards detected */ unsigned char pci_bus, pci_device_fn; static short pci_index=0; /* Device index to PCI BIOS calls */ - for (current_override = count = 0; current_override < OVERRIDE_LIMIT; ++current_override) { @@ -1115,6 +1120,7 @@ NCR53c8x0_init_fixup (struct Scsi_Host *host) { * SCRIPTS. */ + tpnt->proc_dir = &proc_scsi_ncr53c7xx; patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp); patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr); diff --git a/drivers/scsi/53c7,8xx.h b/drivers/scsi/53c7,8xx.h index 2200f38d1c61..220fb58967d0 100644 --- a/drivers/scsi/53c7,8xx.h +++ b/drivers/scsi/53c7,8xx.h @@ -59,7 +59,6 @@ #endif - /* * Prevent name space pollution in hosts.c, and only provide the * define we need to get the NCR53c7x0 driver into the host template @@ -68,6 +67,7 @@ #if defined(HOSTS_C) || defined(MODULE) #include + extern int NCR53c7xx_abort(Scsi_Cmnd *); extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt); extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); @@ -78,13 +78,13 @@ extern int NCR53c7xx_release(struct Scsi_Host *); #define NCR53c7xx_release NULL #endif -#define NCR53c7xx {NULL, NULL, NULL, "NCR53c7xx", \ - PROC_SCSI_NCR53C7xx, "NCR53c{7,8}xx (rel 4)", NCR53c7xx_detect, \ - NULL, /* info */ NULL, /* command, deprecated */ NULL, \ - NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \ - NULL /* slave attach */, scsicam_bios_param, /* can queue */ 1, \ - /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 1 , \ - /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} +#define NCR53c7xx {NULL, NULL, NULL, NULL, \ + "NCR53c{7,8}xx (rel 4)", NCR53c7xx_detect, \ + NULL, /* info */ NULL, /* command, deprecated */ NULL, \ + NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \ + NULL /* slave attach */, scsicam_bios_param, /* can queue */ 1, \ + /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 1 , \ + /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} #endif /* defined(HOSTS_C) || defined(MODULE) */ #ifndef HOSTS_C diff --git a/drivers/scsi/ChangeLog b/drivers/scsi/ChangeLog index d05207fdfbb4..97ea292162cd 100644 --- a/drivers/scsi/ChangeLog +++ b/drivers/scsi/ChangeLog @@ -1,3 +1,11 @@ +Wed Aug 9 22:37:04 1995 Andries Brouwer + + As a preparation for new device code, separated the various + functions the request->dev field had into the device proper, + request->rq_dev and a status field request->rq_status. + + The 2nd argument of bios_param is now a kdev_t. + Wed Jul 19 10:43:15 1995 Michael Neuffer * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 5f8af63b641b..140a9798b9c2 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -26,21 +26,22 @@ CFLAGS = -D__KERNEL__=1 \ include ../../.config -SYMTAB_OBJS = scsi_syms.o - TOPDIR = ../.. -include ../../versions.mk endif -ifdef CONFIG_SCSI +ifeq ($(CONFIG_SCSI),y) L_OBJS += hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o else -ifdef CONFIG_MODVERSIONS -# Create this before we build anything else. -SCSI_MODULE_VER := scsi_syms.ver -endif -M_OBJS += scsi_mod.o + ifeq ($(CONFIG_SCSI),m) + ifdef CONFIG_MODVERSIONS + # Create this before we build anything else. + SCSI_MODULE_VER := scsi_syms.ver + SYMTAB_OBJS := scsi_syms.o + include ../../versions.mk + endif + M_OBJS += scsi_mod.o + endif endif ifeq ($(CONFIG_CHR_DEV_ST),y) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 7846d8960a50..334a2df641a8 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -220,6 +220,12 @@ #include #include "aha152x.h" +#include + +struct proc_dir_entry proc_scsi_aha152x = { + PROC_SCSI_AHA152X, 7, "aha152x", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /* DEFINES */ @@ -568,6 +574,8 @@ int aha152x_detect(Scsi_Host_Template * tpnt) int interrupt_level; struct Scsi_Host *hreg; + tpnt->proc_dir = &proc_scsi_aha152x; + if(setup_called) { printk("aha152x: processing commandline: "); @@ -1108,13 +1116,14 @@ int aha152x_reset(Scsi_Cmnd * __unused) /* * Return the "logical geometry" */ -int aha152x_biosparam(Scsi_Disk * disk, int dev, int *info_array ) +int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array ) { int size = disk->capacity; #if defined(DEBUG_BIOSPARAM) if(aha152x_debug & debug_biosparam) - printk("aha152x_biosparam: dev=%x, size=%d, ", dev, size); + printk("aha152x_biosparam: dev=%s, size=%d, ", + kdevname(dev), size); #endif /* I took this from other SCSI drivers, since it provides diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h index 5e20e11218d7..c56393de8b49 100644 --- a/drivers/scsi/aha152x.h +++ b/drivers/scsi/aha152x.h @@ -16,7 +16,7 @@ int aha152x_command(Scsi_Cmnd *); int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int aha152x_abort(Scsi_Cmnd *); int aha152x_reset(Scsi_Cmnd *); -int aha152x_biosparam(Disk *, int, int*); +int aha152x_biosparam(Disk *, kdev_t, int*); /* number of queueable commands (unless we support more than 1 cmd_per_lun this should do) */ @@ -24,12 +24,13 @@ int aha152x_biosparam(Disk *, int, int*); #define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.9 $" +extern struct proc_dir_entry proc_scsi_aha152x; + /* Initial value of Scsi_Host entry */ #define AHA152X { /* next */ NULL, \ /* usage_count */ NULL, \ - NULL, \ - "aha152x", \ - PROC_SCSI_AHA152X, \ + &proc_scsi_aha152x, \ + NULL, \ /* name */ AHA152X_REVID, \ /* detect */ aha152x_detect, \ /* release */ NULL, \ diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 5d32223296ea..0944d193e975 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -9,7 +9,8 @@ * Set up on-board DMA controller, such that we do not have to * have the bios enabled to use the aha1542. * Modified by David Gentzel - * Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus controller). + * Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus + * controller). * Modified by Matti Aarnio * Accept parameters from LILO cmd-line. -- 1-Oct-94 */ @@ -37,6 +38,13 @@ #include "aha1542.h" +#include + +struct proc_dir_entry proc_scsi_aha1542 = { + PROC_SCSI_AHA1542, 7, "aha1542", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + #ifdef DEBUG #define DEB(x) x #else @@ -928,6 +936,8 @@ int aha1542_detect(Scsi_Host_Template * tpnt) DEB(printk("aha1542_detect: \n")); + tpnt->proc_dir = &proc_scsi_aha1542; + for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++) if(bases[indx] != 0 && !check_region(bases[indx], 4)) { shpnt = scsi_register(tpnt, @@ -1065,6 +1075,7 @@ int aha1542_detect(Scsi_Host_Template * tpnt) continue; }; + return count; } @@ -1137,13 +1148,15 @@ int aha1542_abort(Scsi_Cmnd * SCpnt) if(HOSTDATA(SCpnt->host)->SCint[i]) { if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) { - printk("Timed out command pending for %4.4x\n", SCpnt->request.dev); + printk("Timed out command pending for %s\n", + kdevname(SCpnt->request.rq_dev)); if (HOSTDATA(SCpnt->host)->mb[i].status) { printk("OGMB still full - restarting\n"); aha1542_out(SCpnt->host->io_port, &ahacmd, 1); }; } else - printk("Other pending command %4.4x\n", SCpnt->request.dev); + printk("Other pending command %s\n", + kdevname(SCpnt->request.rq_dev)); } #endif @@ -1259,7 +1272,7 @@ int aha1542_reset(Scsi_Cmnd * SCpnt) #include "sd.h" -int aha1542_biosparam(Scsi_Disk * disk, int dev, int * ip) +int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip) { int translation_algorithm; int size = disk->capacity; diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h index af093e310255..9dbc8863054f 100644 --- a/drivers/scsi/aha1542.h +++ b/drivers/scsi/aha1542.h @@ -32,6 +32,7 @@ */ #include +#include /* I/O Port interface 4.2 */ /* READ */ @@ -134,7 +135,7 @@ int aha1542_command(Scsi_Cmnd *); int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int aha1542_abort(Scsi_Cmnd *); int aha1542_reset(Scsi_Cmnd *); -int aha1542_biosparam(Disk *, int, int*); +int aha1542_biosparam(Disk *, kdev_t, int*); #define AHA1542_MAILBOXES 8 #define AHA1542_SCATTER 16 @@ -144,10 +145,11 @@ int aha1542_biosparam(Disk *, int, int*); #define NULL 0 #endif +extern struct proc_dir_entry proc_scsi_aha1542; + #define AHA1542 { NULL, NULL, \ + &proc_scsi_aha1542,/* proc_dir_entry */ \ NULL, \ - "aha1542", \ - PROC_SCSI_AHA1542, \ "Adaptec 1542", \ aha1542_detect, \ NULL, \ diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 462635e86889..f9b92d900986 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -38,6 +38,12 @@ #include "sd.h" #include "aha1740.h" +#include + +struct proc_dir_entry proc_scsi_aha1740 = { + PROC_SCSI_AHA1740, 7, "aha1740", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH IT WORK, THEN: @@ -434,6 +440,8 @@ void aha1740_getconfig(void) int aha1740_detect(Scsi_Host_Template * tpnt) { + tpnt->proc_dir = &proc_scsi_aha1740; + memset(&ecb, 0, sizeof(struct ecb)); DEB(printk("aha1740_detect: \n")); @@ -497,7 +505,7 @@ int aha1740_reset(Scsi_Cmnd * SCpnt) return SCSI_RESET_PUNT; } -int aha1740_biosparam(Disk * disk, int dev, int* ip) +int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip) { int size = disk->capacity; DEB(printk("aha1740_biosparam\n")); diff --git a/drivers/scsi/aha1740.h b/drivers/scsi/aha1740.h index 780a1318d798..0c5de11a223f 100644 --- a/drivers/scsi/aha1740.h +++ b/drivers/scsi/aha1740.h @@ -11,6 +11,7 @@ */ #include +#include /* Eisa Enhanced mode operation - slot locating and addressing */ #define MINEISA 1 /* I don't have an EISA Spec to know these ranges, so I */ @@ -157,7 +158,7 @@ int aha1740_command(Scsi_Cmnd *); int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int aha1740_abort(Scsi_Cmnd *); int aha1740_reset(Scsi_Cmnd *); -int aha1740_biosparam(Disk *, int, int*); +int aha1740_biosparam(Disk *, kdev_t, int*); #define AHA1740_ECBS 32 #define AHA1740_SCATTER 16 @@ -166,10 +167,10 @@ int aha1740_biosparam(Disk *, int, int*); #define NULL 0 #endif + #define AHA1740 {NULL, NULL, \ + NULL, \ NULL, \ - "aha1740", \ - PROC_SCSI_AHA1740, \ "Adaptec 174x (EISA)", \ aha1740_detect, \ NULL, \ diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 6eaf31e8677a..1c9d953ef525 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -64,6 +64,12 @@ #include "scsi.h" #include "hosts.h" #include "aic7xxx.h" +#include + +struct proc_dir_entry proc_scsi_aic7xxx = { + PROC_SCSI_AIC7XXX, 7, "aic7xxx", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; #define AIC7XXX_C_VERSION "$Revision: 2.0 $" @@ -3204,6 +3210,8 @@ aic7xxx_detect(Scsi_Host_Template *template) unsigned char irq = 0; int i; + template->proc_dir = &proc_scsi_aic7xxx; + /* * Since we may allow sharing of IRQs, it is imperative * that we "null-out" the aic7xxx_boards array. It is @@ -3995,7 +4003,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd) * Return the disk geometry for the given SCSI device. *-F*************************************************************************/ int -aic7xxx_biosparam(Disk *disk, int devno, int geom[]) +aic7xxx_biosparam(Disk *disk, kdev_t dev, int geom[]) { int heads, sectors, cylinders; struct aic7xxx_host *p; diff --git a/drivers/scsi/aic7xxx.h b/drivers/scsi/aic7xxx.h index f7bc1d54614c..c7929179032c 100644 --- a/drivers/scsi/aic7xxx.h +++ b/drivers/scsi/aic7xxx.h @@ -33,8 +33,7 @@ NULL, \ NULL, \ NULL, \ - "aic7xxx", \ - PROC_SCSI_AIC7XXX, \ + NULL, \ NULL, \ aic7xxx_detect, \ NULL, \ @@ -55,7 +54,7 @@ } extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -extern int aic7xxx_biosparam(Disk *, int, int[]); +extern int aic7xxx_biosparam(Disk *, kdev_t, int[]); extern int aic7xxx_detect(Scsi_Host_Template *); extern int aic7xxx_command(Scsi_Cmnd *); extern int aic7xxx_abort(Scsi_Cmnd *); diff --git a/drivers/scsi/buslogic.c b/drivers/scsi/buslogic.c index 298b63a674c2..4d06404e47d5 100644 --- a/drivers/scsi/buslogic.c +++ b/drivers/scsi/buslogic.c @@ -105,6 +105,13 @@ # define BUSLOGIC_DEBUG 0 #endif +#include + +struct proc_dir_entry proc_scsi_buslogic = { + PROC_SCSI_BUSLOGIC, 8, "buslogic", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + /* ??? Until kmalloc actually implements GFP_DMA, we can't depend on it... */ #undef GFP_DMA @@ -1121,6 +1128,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt) buslogic_printk("called\n"); #endif + tpnt->proc_dir = &proc_scsi_buslogic; tpnt->can_queue = BUSLOGIC_MAILBOXES; for (indx = 0; bases[indx] != 0; indx++) if (!check_region(bases[indx], 4)) { @@ -1395,15 +1403,15 @@ int buslogic_abort(Scsi_Cmnd *scpnt) for (i = 0; i < BUSLOGIC_MAILBOXES; i++) if (HOSTDATA(scpnt->host)->sc[i]) { if (HOSTDATA(scpnt->host)->sc[i] == scpnt) { - buslogic_printk("timed out command pending for %4.4X.\n", - scpnt->request.dev); + buslogic_printk("timed out command pending for %s.\n", + kdevname(scpnt->request.rq_dev)); if (HOSTDATA(scpnt->host)->mb[i].status != MBX_NOT_IN_USE) { buslogic_printk("OGMB still full - restarting...\n"); buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd); } } else - buslogic_printk("other pending command: %4.4X\n", - scpnt->request.dev); + buslogic_printk("other pending command: %s\n", + kdevname(scpnt->request.rq_dev)); } #endif @@ -1498,7 +1506,7 @@ int buslogic_reset(Scsi_Cmnd *scpnt) CMD_READ_FW_LOCAL_RAM command to check for the particular drive being queried. Note that series "C" boards can be differentiated by having HOSTDATA(disk->device->host)->firmware_rev[0] >= '4'. */ -int buslogic_biosparam(Disk *disk, int dev, int *ip) +int buslogic_biosparam(Disk *disk, kdev_t dev, int *ip) { unsigned int size = disk->capacity; diff --git a/drivers/scsi/buslogic.h b/drivers/scsi/buslogic.h index 4de173b305a1..a47c4903101a 100644 --- a/drivers/scsi/buslogic.h +++ b/drivers/scsi/buslogic.h @@ -10,12 +10,12 @@ int buslogic_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int buslogic_abort(Scsi_Cmnd *); const char *buslogic_info(struct Scsi_Host *); int buslogic_reset(Scsi_Cmnd *); -int buslogic_biosparam(Disk *, int, int *); +int buslogic_biosparam(Disk *, kdev_t, int *); + #define BUSLOGIC { NULL, NULL, \ NULL, \ - "buslogic", \ - PROC_SCSI_BUSLOGIC, \ + NULL, \ "BusLogic", \ buslogic_detect, \ 0, /* no release func */ \ diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 44a66bc86e4d..36701669301c 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -382,7 +382,6 @@ void print_sense(const char * devclass, Scsi_Cmnd * SCpnt) int sense_class, valid, code; unsigned char * sense_buffer = SCpnt->sense_buffer; const char * error = NULL; - int dev = SCpnt->request.dev; sense_class = (sense_buffer[0] >> 4) & 0x07; code = sense_buffer[0] & 0xf; @@ -413,9 +412,11 @@ void print_sense(const char * devclass, Scsi_Cmnd * SCpnt) printk("%s error ", error); #if (CONSTANTS & CONST_SENSE) - printk( "%s%x: sense key %s\n", devclass, dev, snstext[sense_buffer[2] & 0x0f]); + printk( "%s%s: sense key %s\n", devclass, + kdevname(SCpnt->request.rq_dev), snstext[sense_buffer[2] & 0x0f]); #else - printk("%s%x: sns = %2x %2x\n", devclass, dev, sense_buffer[0], sense_buffer[2]); + printk("%s%s: sns = %2x %2x\n", devclass, + kdevname(SCpnt->request.rq_dev), sense_buffer[0], sense_buffer[2]); #endif /* Check to see if additional sense information is available */ @@ -443,10 +444,12 @@ void print_sense(const char * devclass, Scsi_Cmnd * SCpnt) #if (CONSTANTS & CONST_SENSE) if (sense_buffer[0] < 15) - printk("%s%x: old sense key %s\n", devclass, dev, snstext[sense_buffer[0] & 0x0f]); + printk("%s%s: old sense key %s\n", devclass, + kdevname(SCpnt->request.rq_dev), snstext[sense_buffer[0] & 0x0f]); else #endif - printk("%s%x: sns = %2x %2x\n", devclass, dev, sense_buffer[0], sense_buffer[2]); + printk("%s%s: sns = %2x %2x\n", devclass, + kdevname(SCpnt->request.rq_dev), sense_buffer[0], sense_buffer[2]); printk("Non-extended sense class %d code 0x%0x ", sense_class, code); s = 4; diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index d5422f2e283d..1f380a337099 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -130,6 +130,12 @@ #include #include "linux/in.h" #include "eata.h" +#include + +struct proc_dir_entry proc_scsi_eata2x = { + PROC_SCSI_EATA2X, 6, "eata2x", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /* Subversion values */ #define ISA 0 @@ -555,6 +561,8 @@ int eata2x_detect (Scsi_Host_Template * tpnt) { ushort *port_base = io_port; + tpnt->proc_dir = &proc_scsi_eata2x; + save_flags(flags); cli(); diff --git a/drivers/scsi/eata.h b/drivers/scsi/eata.h index 36329c165105..aabcc8067079 100644 --- a/drivers/scsi/eata.h +++ b/drivers/scsi/eata.h @@ -14,12 +14,12 @@ int eata2x_reset(Scsi_Cmnd *); #define EATA_VERSION "2.01.00" + #define EATA { \ NULL, /* Ptr for modules */ \ NULL, /* usage count for modules */ \ NULL, \ - "eata2x", \ - PROC_SCSI_EATA2X, \ + NULL, \ "EATA/DMA 2.0x rev. " EATA_VERSION " ", \ eata2x_detect, \ NULL, /* Release */ \ diff --git a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c index 1b339191d084..9c917bf0d8b9 100644 --- a/drivers/scsi/eata_dma.c +++ b/drivers/scsi/eata_dma.c @@ -79,6 +79,12 @@ #include "eata_dma.h" #include "eata_dma_proc.h" +#include + +struct proc_dir_entry proc_scsi_eata_dma = { + PROC_SCSI_EATA, 8, "eata_dma", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; static u32 ISAbases[] = {0x1F0, 0x170, 0x330, 0x230}; @@ -103,7 +109,7 @@ static ulong queue_counter = 0; void eata_scsi_done (Scsi_Cmnd * scmd) { - scmd->request.dev = 0xfffe; + scmd->request.rq_status = RQ_SCSI_DONE; if (scmd->request.sem != NULL) up(scmd->request.sem); @@ -360,15 +366,31 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) } hd->last_ccb = y; - - if (x == sh->can_queue) { - DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n", - sh->can_queue, x, y)); + + if (x >= sh->can_queue) { + uint z; - panic("eata_dma: run out of queue slots cmdno:%ld intrno: %ld\n", - queue_counter, int_counter); + printk(KERN_EMERG "eata_dma: run out of queue slots cmdno:%ld" + " intrno: %ld, can_queue: %d, x: %d, y: %d\n", + queue_counter, int_counter, sh->can_queue, x, y); + printk(KERN_EMERG "List of free queueslots:"); + for(z = 0; z < sh->can_queue; z +=2) { + switch(hd->ccb[z].status) { + case FREE: + printk(KERN_EMERG "Slot %2d is FREE \t", z); + break; + case USED: + printk(KERN_EMERG "Slot %2d is USED \t", z); + break; + case LOCKED: + printk(KERN_EMERG "Slot %2d is LOCKED\t", z); + break; + default: + printk(KERN_EMERG "Slot %2d is UNKNOWN\t", z); + } + panic("\nSystem halted.\n"); + } } - cp = &hd->ccb[y]; memset(cp, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *)); @@ -405,7 +427,8 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) x = ntohl(*lon)/2; break; } - for(z = 0; z <= 11, x > (1 << z); z++) + + for(z = 0; (x > (1 << z)) && (z <= 11); z++) /* nothing */; cp->sizeindex = z; if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 || @@ -484,9 +507,8 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) cmd->result = DID_ERROR << 16; printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR," " done.\n", cmd->target, cmd->pid); - - restore_flags(flags); done(cmd); + restore_flags(flags); return(0); } DBG(DBG_QUEUE,printk("Queued base %#.4x pid: %ld target: %x lun: %x " @@ -921,7 +943,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, * ntohs(gc->queuesiz)); DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size)); - + sh = scsi_register(tpnt, size); if(sh == NULL) { @@ -1251,6 +1273,8 @@ int eata_detect(Scsi_Host_Template * tpnt) DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, printk("Using lots of delays to let you read the debugging output\n")); + tpnt->proc_dir = &proc_scsi_eata_dma; + status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA); dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA); diff --git a/drivers/scsi/eata_dma.h b/drivers/scsi/eata_dma.h index e099bef46716..dc31aaca2c1e 100644 --- a/drivers/scsi/eata_dma.h +++ b/drivers/scsi/eata_dma.h @@ -24,7 +24,7 @@ ************************************************************************/ #define CHECKPAL 0 /* EISA pal checking on/off */ -#define NEWSTUFF 1 /* Some changes for ISA/EISA boards */ +#define NEWSTUFF 0 /* Some changes for ISA/EISA boards */ /************************************************************************ * Debug options. * @@ -74,13 +74,12 @@ int eata_release(struct Scsi_Host *); #endif #define EATA_DMA { \ - NULL, NULL, \ - eata_proc_info,/* procinfo */ \ - "eata_dma", /* proc dir entry */ \ - PROC_SCSI_EATA,/* proc dir inode */ \ - "EATA (Extended Attachment) HBA driver", \ - eata_detect, \ - eata_release, \ + NULL, NULL, \ + NULL, /* proc_dir_entry */ \ + eata_proc_info, /* procinfo */ \ + "EATA (Extended Attachment) HBA driver", \ + eata_detect, \ + eata_release, \ NULL, NULL, \ eata_queue, \ eata_abort, \ diff --git a/drivers/scsi/eata_dma_proc.c b/drivers/scsi/eata_dma_proc.c index ea62b7a2470e..83d2a72d91cd 100644 --- a/drivers/scsi/eata_dma_proc.c +++ b/drivers/scsi/eata_dma_proc.c @@ -181,7 +181,7 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, /* Used for mutex if loading devices after boot */ scmd.request.sem = NULL; - scmd.request.dev = 0xffff; /* Mark busy */ + scmd.request.rq_status = RQ_SCSI_BUSY; scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66, eata_scsi_done, 1 * HZ, 1); @@ -190,16 +190,17 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, * booting, else do it right and use a mutex */ if (current->pid == 0) { - while (scmd.request.dev != 0xfffe) + while (scmd.request.rq_status != RQ_SCSI_DONE) barrier(); - } else if (scmd.request.dev != 0xfffe) { + } else if (scmd.request.rq_status != RQ_SCSI_DONE) { struct semaphore sem = MUTEX_LOCKED; scmd.request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (scmd.request.dev != 0xfffe) schedule(); + while (scmd.request.rq_status != RQ_SCSI_DONE) + schedule(); } size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt, @@ -320,7 +321,7 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, /* Used for mutex if loading devices after boot */ scmd.request.sem = NULL; - scmd.request.dev = 0xffff; /* Mark busy */ + scmd.request.rq_status = RQ_SCSI_BUSY; /* Mark busy */ scsi_do_cmd (&scmd, cmnd, buff2, 0x144, eata_scsi_done, 1 * HZ, 1); @@ -329,16 +330,17 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, * booting, else do it right and use a mutex */ if (current->pid == 0) - while (scmd.request.dev != 0xfffe) + while (scmd.request.rq_status != RQ_SCSI_DONE) barrier(); - else if (scmd.request.dev != 0xfffe) { + else if (scmd.request.rq_status != RQ_SCSI_DONE) { struct semaphore sem = MUTEX_LOCKED; scmd.request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (scmd.request.dev != 0xfffe) schedule(); + while (scmd.request.rq_status != RQ_SCSI_DONE) + schedule(); } swap_statistics(buff2); diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 340516970340..473f3619d9a9 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -57,6 +57,12 @@ #include "scsi.h" #include "sd.h" +#include +struct proc_dir_entry proc_scsi_eata_pio = { + PROC_SCSI_EATA_PIO, 9, "eata_pio", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + static uint ISAbases[MAXISA] = {0x1F0, 0x170, 0x330, 0x230}; static uint ISAirqs[MAXISA] = @@ -972,6 +978,7 @@ int eata_pio_detect(Scsi_Host_Template * tpnt) DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, printk("Using lots of delays to let you read the debugging output\n")); + tpnt->proc_dir = &proc_scsi_eata_pio; find_pio_PCI(&gc, tpnt); diff --git a/drivers/scsi/eata_pio.h b/drivers/scsi/eata_pio.h index f56f1bad0afa..4ad0402f8a20 100644 --- a/drivers/scsi/eata_pio.h +++ b/drivers/scsi/eata_pio.h @@ -26,7 +26,7 @@ ************************************************************************/ #define VERBOSE_SETUP /* show startup screen of 2001 */ -#define ALLOW_DMA_BOARDS 0 +#define ALLOW_DMA_BOARDS 1 /************************************************************************ * Debug options. * @@ -74,12 +74,11 @@ int eata_pio_release(struct Scsi_Host *); #endif -#define EATA_PIO { \ - NULL, NULL, \ - eata_pio_proc_info,/* procinfo */ \ - "eata_pio", /* proc dir entry */ \ - PROC_SCSI_EATA_PIO,/* proc dir inode */ \ - "EATA (Extended Attachment) PIO driver",\ +#define EATA_PIO { \ + NULL, NULL, \ + NULL, /* proc_dir_entry */ \ + eata_pio_proc_info, /* procinfo */ \ + "EATA (Extended Attachment) PIO driver", \ eata_pio_detect, \ eata_pio_release, \ NULL, NULL, \ diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 1f0c7bcd1df9..0be895b7820d 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -1,10 +1,10 @@ /* fdomain.c -- Future Domain TMC-16x0 SCSI driver * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu - * Revised: Tue Jul 4 13:58:47 1995 by r.faith@ieee.org + * Revised: Sun Sep 17 00:23:26 1995 by r.faith@ieee.org * Author: Rickard E. Faith, faith@cs.unc.edu * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith * - * $Id: fdomain.c,v 5.33 1995/07/04 18:59:49 faith Exp $ + * $Id: fdomain.c,v 5.36 1995/09/17 04:23:42 root Exp $ * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -137,9 +137,10 @@ Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the patch for the Quantum ISA-200S SCSI adapter. - Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, - and to Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to - some random TMC-1680 repackaged by IBM. + Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to + Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some + random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for + the version 3.61 BIOS siganture. Thanks for Mark Singer (elf@netcom.com) and Richard Simpson (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective @@ -149,6 +150,9 @@ providing patches for proper PCI BIOS32-mediated detection of the TMC-3260 card (a PCI bus card with the 36C70 chip). Please send James PCI-related bug reports. + + Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option + patches. All of the alpha testers deserve much thanks. @@ -205,8 +209,14 @@ #include #include #include +#include + +struct proc_dir_entry proc_scsi_fdomain = { + PROC_SCSI_FDOMAIN, 7, "fdomain", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; -#define VERSION "$Revision: 5.33 $" +#define VERSION "$Revision: 5.36 $" /* START OF USER DEFINABLE OPTIONS */ @@ -302,7 +312,10 @@ static int interrupt_level = 0; static volatile int in_command = 0; static Scsi_Cmnd *current_SC = NULL; static enum chip_type chip = unknown; -static int adapter_mask = 0x40; +static int adapter_mask = 0; +static int this_id = 0; +static int setup_called = 0; + #if DEBUG_RACE static volatile int in_interrupt_flag = 0; #endif @@ -391,6 +404,7 @@ struct signature { { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 }, { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 }, { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 }, + { "FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 }, { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 }, /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE @@ -411,17 +425,22 @@ struct signature { static void print_banner( struct Scsi_Host *shpnt ) { if (!shpnt) return; /* This won't ever happen */ - - printk( "scsi%d : BIOS version ", shpnt->host_no ); - if (bios_major >= 0) printk( "%d.", bios_major ); - else printk( "?." ); + if (bios_major < 0 && bios_minor < 0) { + printk( "scsi%d : No BIOS; using scsi id %d\n", + shpnt->host_no, shpnt->this_id ); + } else { + printk( "scsi%d : BIOS version ", shpnt->host_no ); + + if (bios_major >= 0) printk( "%d.", bios_major ); + else printk( "?." ); - if (bios_minor >= 0) printk( "%d", bios_minor ); - else printk( "?." ); + if (bios_minor >= 0) printk( "%d", bios_minor ); + else printk( "?." ); - printk( " at 0x%x using scsi id %d\n", - (unsigned)bios_base, shpnt->this_id ); + printk( " at 0x%x using scsi id %d\n", + (unsigned)bios_base, shpnt->this_id ); + } /* If this driver works for later FD PCI boards, we will have to modify banner @@ -442,6 +461,21 @@ static void print_banner( struct Scsi_Host *shpnt ) printk( "\n" ); } +void fdomain_setup( char *str, int *ints ) +{ + if (setup_called++ || ints[0] < 2 || ints[0] > 3) { + printk( "fdomain: usage: fdomain=,[,]\n" ); + printk( "fdomain: bad LILO parameters?\n" ); + } + + port_base = ints[0] >= 1 ? ints[1] : 0; + interrupt_level = ints[0] >= 2 ? ints[2] : 0; + adapter_mask = ints[0] >= 3 ? (1 << ints[3]) : 0; + + bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */ +} + + static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */ { unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */ @@ -814,7 +848,6 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase ) int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) { int i, j; - int flag = 0; int retcode; struct Scsi_Host *shpnt; #if DO_DETECT @@ -830,49 +863,65 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) #if DEBUG_DETECT printk( "fdomain_16x0_detect()," ); #endif + tpnt->proc_dir = &proc_scsi_fdomain; - for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { + if (setup_called) { #if DEBUG_DETECT - printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base ); -#endif - for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { - if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset), - signatures[j].signature, signatures[j].sig_length )) { - bios_major = signatures[j].major_bios_version; - bios_minor = signatures[j].minor_bios_version; - PCI_bus = (signatures[j].flag == 1); - Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0; - bios_base = addresses[i]; + printk( "no BIOS, using port_base = 0x%x, irq = %d\n", + port_base, interrupt_level ); +#endif + if (!fdomain_is_valid_port( port_base )) { + printk( "fdomain: cannot locate chip at port base 0x%x\n", + port_base ); + printk( "fdomain: bad LILO parameters?\n" ); + return 0; + } + } else { + int flag = 0; + + for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { +#if DEBUG_DETECT + printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base ); +#endif + for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { + if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset), + signatures[j].signature, signatures[j].sig_length )) { + bios_major = signatures[j].major_bios_version; + bios_minor = signatures[j].minor_bios_version; + PCI_bus = (signatures[j].flag == 1); + Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0; + bios_base = addresses[i]; + } } } - } - if (!bios_base) { + if (!bios_base) { #if DEBUG_DETECT - printk( " FAILED: NO BIOS\n" ); + printk( " FAILED: NO BIOS\n" ); #endif - return 0; - } + return 0; + } - if (!PCI_bus) { - flag = fdomain_isa_detect( &interrupt_level, &port_base ); - } else { + if (!PCI_bus) { + flag = fdomain_isa_detect( &interrupt_level, &port_base ); + } else { #ifdef CONFIG_PCI - flag = fdomain_pci_bios_detect( &interrupt_level, &port_base ); + flag = fdomain_pci_bios_detect( &interrupt_level, &port_base ); #else - flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base ); + flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base ); #endif - } + } - if (!flag) { + if (!flag) { #if DEBUG_DETECT - printk( " FAILED: NO PORT\n" ); + printk( " FAILED: NO PORT\n" ); #endif #ifdef CONFIG_PCI - printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" ); - printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" ); + printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" ); + printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" ); #endif - return 0; /* Cannot find valid set of ports */ + return 0; /* Cannot find valid set of ports */ + } } SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl; @@ -895,12 +944,25 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) #if DEBUG_DETECT printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" ); #endif + if (setup_called) { + printk( "fdomain: loopback test failed at port base 0x%x\n", + port_base ); + printk( "fdomain: bad LILO parameters?\n" ); + } return 0; } - if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { - adapter_mask = 0x80; - tpnt->this_id = 7; + if (this_id) { + tpnt->this_id = (this_id & 0x7); + adapter_mask = (1 << tpnt->this_id); + } else { + if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { + tpnt->this_id = 7; + adapter_mask = 0x80; + } else { + tpnt->this_id = 6; + adapter_mask = 0x40; + } } /* Print out a banner here in case we can't @@ -1015,6 +1077,33 @@ const char *fdomain_16x0_info( struct Scsi_Host *ignore ) return buffer; } +#if 0 + /* First pass at /proc information routine. */ +/* + * inout : decides on the direction of the dataflow and the meaning of the + * variables + * buffer: If inout==FALSE data is beeing written to it else read from it + * *start: If inout==FALSE start of the valid data in the buffer + * offset: If inout==FALSE offset from the beginning of the imaginary file + * from which we start writing into the buffer + * length: If inout==FALSE max number of bytes to be written into the buffer + * else number of bytes in the buffer + */ +int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset, + int length, int hostno, int inout ) +{ + int len = 0; + const char *info = fdomain_16x0_info( NULL ); + + if (inout) return -ENOSYS; + + strcpy( buffer, info ); + len += strlen( info ); + + return( len ); +} +#endif + #if 0 static int fdomain_arbitrate( void ) { @@ -1697,7 +1786,7 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt) #endif restore_flags( flags ); return SCSI_ABORT_NOT_RUNNING; - } + } else printk( "\n" ); #if DEBUG_ABORT print_info( SCpnt ); @@ -1749,7 +1838,7 @@ int fdomain_16x0_reset( Scsi_Cmnd *SCpnt ) #include "sd.h" #include "scsi_ioctl.h" -int fdomain_16x0_biosparam( Scsi_Disk *disk, int dev, int *info_array ) +int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array ) { int drive; unsigned char buf[512 + sizeof( int ) * 2]; diff --git a/drivers/scsi/fdomain.h b/drivers/scsi/fdomain.h index 2b90055e8eee..b8c2141eace1 100644 --- a/drivers/scsi/fdomain.h +++ b/drivers/scsi/fdomain.h @@ -31,13 +31,14 @@ int fdomain_16x0_abort( Scsi_Cmnd * ); const char *fdomain_16x0_info( struct Scsi_Host * ); int fdomain_16x0_reset( Scsi_Cmnd * ); int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) ); -int fdomain_16x0_biosparam( Disk *, int, int * ); +int fdomain_16x0_biosparam( Disk *, kdev_t, int * ); + +extern struct proc_dir_entry proc_scsi_fdomain; #define FDOMAIN_16X0 { NULL, \ NULL, \ NULL, \ - "fdomain", \ - PROC_SCSI_FUTURE_DOMAIN, \ + NULL, \ NULL, \ fdomain_16x0_detect, \ NULL, \ diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 73cf455d7e68..012135c782a5 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -67,6 +67,12 @@ #include "g_NCR5380.h" #include "NCR5380.h" #include "constants.h" +#include + +struct proc_dir_entry proc_scsi_g_ncr5380 = { + PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; static struct override { int port; @@ -121,6 +127,8 @@ int generic_NCR5380_detect(Scsi_Host_Template * tpnt) { int count; struct Scsi_Host *instance; + tpnt->proc_dir = &proc_scsi_g_ncr5380; + for (count = 0; current_override < NO_OVERRIDES; ++current_override) { if (!(overrides[current_override].port)) continue; diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index cb35a957c65c..d7a7ee638beb 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h @@ -53,8 +53,9 @@ int generic_NCR5380_reset(Scsi_Cmnd *); #ifdef HOSTS_C -#define GENERIC_NCR5380 {NULL, NULL, NULL, "g_NCR5380", \ - PROC_SCSI_GENERIC_NCR5380, "Trantor T128/T128F/T228", \ + +#define GENERIC_NCR5380 {NULL, NULL, NULL, NULL, \ + "Trantor T128/T128F/T228", \ generic_NCR5380_detect, NULL, NULL, NULL, \ generic_NCR5380_queue_command, generic_NCR5380_abort, \ generic_NCR5380_reset, NULL, \ diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 25a85cc91bdc..654913251f7f 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -360,14 +360,14 @@ unsigned int scsi_init() } tpnt->next = scsi_hosts; scsi_hosts = tpnt; - } - } - - /* Add the drivers to /proc/scsi */ + + /* Add the driver to /proc/scsi */ #if CONFIG_PROC_FS - build_proc_dir_entries(); + build_proc_dir_entries(tpnt); #endif - + } + } + for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) { if(shpnt->hostt->info) diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h index 94f8156b119a..3af06b511986 100644 --- a/drivers/scsi/hosts.h +++ b/drivers/scsi/hosts.h @@ -23,6 +23,7 @@ $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.h,v 1.3 1993/09/24 12:21:00 drew Exp drew $ */ +#include /* It is senseless to set SG_ALL any higher than this - the performance * does not get any better, and it wastes memory @@ -59,19 +60,16 @@ typedef struct SHT /* Used with loadable modules so that we know when it is safe to unload */ int * usage_count; + /* The pointer to the /proc/scsi directory entry */ + struct proc_dir_entry *proc_dir; + /* proc-fs info function. * Can be used to export driver statistics and other infos to the world * outside the kernel ie. userspace and it also provides an interface - * to feed the driver with information. Check eata_dma_proc.c for reference. + * to feed the driver with information. Check eata_dma_proc.c for reference */ int (*proc_info)(char *, char **, off_t, int, int, int); - - /* driver name that will appear in the /proc/scsi directory */ - const char *procname; - - /* low_ino of the drivers /proc/scsi entry. Defined in proc_fs.h */ - unsigned short low_ino; - + /* * The name pointer is a pointer to the name of the SCSI * device detected. @@ -173,7 +171,7 @@ typedef struct SHT * the host adapter. Parameters: * size, device number, list (heads, sectors, cylinders) */ - int (* bios_param)(Disk *, int, int []); + int (* bios_param)(Disk *, kdev_t, int []); /* * This determines if we will use a non-interrupt driven @@ -323,6 +321,9 @@ extern struct Scsi_Device_Template * scsi_devicelist; extern Scsi_Host_Template * scsi_hosts; +extern void build_proc_dir_entries(Scsi_Host_Template *); + + /* * scsi_init initializes the scsi hosts. */ @@ -337,9 +338,6 @@ extern Scsi_Host_Template * scsi_hosts; extern void * scsi_init_malloc(unsigned int size, int priority); extern void scsi_init_free(char * ptr, unsigned int size); -void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, - unchar hchannel, unchar hid, unchar hlun); - extern int next_scsi_host; extern int scsi_loadable_module_flag; diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 0f87ed960551..b6726ef90bda 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -73,6 +73,12 @@ #include "sd.h" #include "in2000.h" +#include + +struct proc_dir_entry proc_scsi_in2000 = { + PROC_SCSI_IN2000, 6, "in2000", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /*#define FAST_FIFO_IO*/ @@ -582,7 +588,9 @@ int in2000_detect(Scsi_Host_Template * tpnt) int loop, tmp; DEB(printk("in2000_detect: \n")); - + + tpnt->proc_dir = &proc_scsi_in2000; + for ( loop=0; loop < 4; loop++ ) { base = base_tab[loop]; @@ -684,7 +692,7 @@ int in2000_reset(Scsi_Cmnd * SCpnt) #endif } -int in2000_biosparam(Disk * disk, int dev, int* iinfo) +int in2000_biosparam(Disk * disk, kdev_t dev, int* iinfo) { int size = disk->capacity; DEB(printk("in2000_biosparam\n")); diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h index 5beae1401db2..abd44f6bed42 100644 --- a/drivers/scsi/in2000.h +++ b/drivers/scsi/in2000.h @@ -99,16 +99,17 @@ int in2000_command(Scsi_Cmnd *); int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int in2000_abort(Scsi_Cmnd *); int in2000_reset(Scsi_Cmnd *); -int in2000_biosparam(Disk *, int, int*); +int in2000_biosparam(Disk *, kdev_t, int*); #ifndef NULL #define NULL 0 #endif + /* next may be "SG_NONE" or "SG_ALL" or nr. of (1k) blocks per R/W Cmd. */ #define IN2000_SG SG_ALL -#define IN2000 {NULL, NULL, NULL, \ - "in2000", PROC_SCSI_IN2000, \ +#define IN2000 {NULL, NULL, \ + NULL, NULL, \ "Always IN2000", in2000_detect, NULL, \ NULL, in2000_command, \ in2000_queuecommand, \ diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index d5e915729485..6810366f64e7 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -120,6 +120,12 @@ #include "constants.h" #include "sd.h" +#include + +struct proc_dir_entry proc_scsi_pas16 = { + PROC_SCSI_PAS16, 5, "pas16", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; int scsi_irq_translate[] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; @@ -350,6 +356,8 @@ int pas16_detect(Scsi_Host_Template * tpnt) { unsigned short io_port; int count; + tpnt->proc_dir = &proc_scsi_pas16; + for (count = 0; current_override < NO_OVERRIDES; ++current_override) { io_port = 0; @@ -429,7 +437,7 @@ int pas16_detect(Scsi_Host_Template * tpnt) { } /* - * Function : int pas16_biosparam(Disk *disk, int dev, int *ip) + * Function : int pas16_biosparam(Disk *disk, kdev_t dev, int *ip) * * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for * the specified device / size. @@ -448,7 +456,7 @@ int pas16_detect(Scsi_Host_Template * tpnt) { * and matching the H_C_S coordinates to what DOS uses. */ -int pas16_biosparam(Disk * disk, int dev, int * ip) +int pas16_biosparam(Disk * disk, kdev_t dev, int * ip) { int size = disk->capacity; ip[0] = 64; diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index e0d0bf400e50..b62db4e4c7e1 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h @@ -115,7 +115,7 @@ #ifndef ASM int pas16_abort(Scsi_Cmnd *); -int pas16_biosparam(Disk *, int, int*); +int pas16_biosparam(Disk *, kdev_t, int*); int pas16_detect(Scsi_Host_Template *); int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int pas16_reset(Scsi_Cmnd *); @@ -140,7 +140,7 @@ int pas16_reset(Scsi_Cmnd *); #ifdef HOSTS_C -#define MV_PAS16 {NULL, NULL, NULL, "pas16", PROC_SCSI_PAS16, \ +#define MV_PAS16 {NULL, NULL, NULL, NULL, \ "Pro Audio Spectrum-16 SCSI", \ pas16_detect, NULL, NULL, \ NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, \ diff --git a/drivers/scsi/qlogic.c b/drivers/scsi/qlogic.c index 0ad4d17bc217..d7b05e1c8a66 100644 --- a/drivers/scsi/qlogic.c +++ b/drivers/scsi/qlogic.c @@ -131,6 +131,12 @@ #include "sd.h" #include "hosts.h" #include "qlogic.h" +#include + +struct proc_dir_entry proc_scsi_qlogic = { + PROC_SCSI_QLOGIC, 6, "qlogic", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /*----------------------------------------------------------------*/ /* driver state info, local to driver */ @@ -537,6 +543,8 @@ int qltyp; /* type of chip */ struct Scsi_Host *hreg; /* registered host structure */ unsigned long flags; +tpnt->proc_dir = &proc_scsi_qlogic; + /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the address - I check 230 first since MIDI cards are typically at 330 @@ -624,7 +632,7 @@ unsigned long flags; /*----------------------------------------------------------------*/ /* return bios parameters */ -int qlogic_biosparam(Disk * disk, int dev, int ip[]) +int qlogic_biosparam(Disk * disk, kdev_t dev, int ip[]) { /* This should mimic the DOS Qlogic driver's behavior exactly */ ip[0] = 0x40; diff --git a/drivers/scsi/qlogic.h b/drivers/scsi/qlogic.h index 1b41d74bf70d..0ff119ae72c4 100644 --- a/drivers/scsi/qlogic.h +++ b/drivers/scsi/qlogic.h @@ -7,18 +7,17 @@ int qlogic_command(Scsi_Cmnd *); int qlogic_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); int qlogic_abort(Scsi_Cmnd *); int qlogic_reset(Scsi_Cmnd *); -int qlogic_biosparam(Disk *,int,int[]); +int qlogic_biosparam(Disk *, kdev_t, int[]); #ifndef NULL #define NULL (0) #endif #define QLOGIC { \ + NULL, \ NULL, \ NULL, \ NULL, \ - "qlogic", \ - PROC_SCSI_QLOGIC, \ NULL, \ qlogic_detect, \ NULL, \ diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 377e3a94221e..d92b1cd09cdc 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -43,18 +43,21 @@ #include #include #include +#include #include "../block/blk.h" #include "scsi.h" #include "hosts.h" #include "constants.h" + #undef USE_STATIC_SCSI_MEMORY /* static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.5 1993/09/24 12:45:18 drew Exp drew $"; */ + /* Command groups 3 and 4 are reserved and should never be used. */ const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 12, 12, 10, 10 }; @@ -111,6 +114,14 @@ extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start, extern int dispatch_scsi_info(int ino, char *buffer, char **start, off_t offset, int length, int inout); +struct proc_dir_entry proc_scsi_scsi = { + PROC_SCSI_SCSI, 4, "scsi", + S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0, 0, + NULL, + NULL, NULL, + NULL, NULL, NULL +}; + /* * As the scsi do command functions are intelligent, and may need to @@ -333,7 +344,7 @@ static void scan_scsis_done (Scsi_Cmnd * SCpnt) #ifdef DEBUG printk ("scan_scsis_done(%p, %06x)\n", SCpnt->host, SCpnt->result); #endif - SCpnt->request.dev = 0xfffe; + SCpnt->request.rq_status = RQ_SCSI_DONE; if (SCpnt->request.sem != NULL) up(SCpnt->request.sem); @@ -359,7 +370,7 @@ void scsi_luns_setup(char *str, int *ints) { * lun address of all sequential devices to the tape driver, all random * devices to the disk driver. */ - +static void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, unchar hchannel, unchar hid, unchar hlun) { @@ -431,6 +442,7 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, */ SDpnt->borken = 1; SDpnt->was_reset = 0; + SDpnt->expecting_cc_ua = 0; scsi_cmd[0] = TEST_UNIT_READY; scsi_cmd[1] = lun << 5; @@ -445,8 +457,7 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, /* Used for mutex if loading devices after boot */ SCpnt->request.sem = NULL; - - SCpnt->request.dev = 0xffff; /* Mark not busy */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; scsi_do_cmd (SCpnt, (void *) scsi_cmd, (void *) scsi_result, @@ -458,16 +469,17 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, */ if (current->pid == 0) - while (SCpnt->request.dev != 0xfffe) + while (SCpnt->request.rq_status != RQ_SCSI_DONE) barrier(); - else if (SCpnt->request.dev != 0xfffe) { + else if (SCpnt->request.rq_status != RQ_SCSI_DONE) { struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); } #if defined(DEBUG) || defined(DEBUG_INIT) @@ -503,7 +515,7 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, scsi_cmd[4] = 255; scsi_cmd[5] = 0; - SCpnt->request.dev = 0xffff; /* Mark not busy */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->cmd_len = 0; scsi_do_cmd (SCpnt, (void *) scsi_cmd, @@ -511,16 +523,17 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, 256, scan_scsis_done, SCSI_TIMEOUT, 3); if (current->pid == 0) - while (SCpnt->request.dev != 0xfffe) + while (SCpnt->request.rq_status != RQ_SCSI_DONE) barrier(); - else if (SCpnt->request.dev != 0xfffe) { + else if (SCpnt->request.rq_status != RQ_SCSI_DONE) { struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); } the_result = SCpnt->result; @@ -674,7 +687,7 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, scsi_cmd[4] = 0x2a; scsi_cmd[5] = 0; - SCpnt->request.dev = 0xffff; /* Mark not busy */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->cmd_len = 0; scsi_do_cmd (SCpnt, (void *) scsi_cmd, @@ -682,15 +695,15 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, scan_scsis_done, SCSI_TIMEOUT, 3); if (current->pid == 0) - while (SCpnt->request.dev != 0xfffe); - else if (SCpnt->request.dev != 0xfffe) { + while (SCpnt->request.rq_status != RQ_SCSI_DONE); + else if (SCpnt->request.rq_status != RQ_SCSI_DONE) { struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (SCpnt->request.dev != 0xfffe) + while (SCpnt->request.rq_status != RQ_SCSI_DONE) schedule(); } } @@ -709,8 +722,8 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, /* * If we want to only allow I/O to one of the luns - * attached to this device at a time, then we set this - * flag. + * attached to this device at a time, then we set + * this flag. */ if(bflags & BLIST_SINGLELUN) { @@ -718,14 +731,15 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, } /* - * If this device is known to support multiple units, override - * the other settings, and scan all of them. + * If this device is known to support multiple + * units, override the other settings, and scan + * all of them. */ if(bflags & BLIST_FORCELUN) { /* - * We probably want to make this a variable, but this - * will do for now. + * We probably want to make this a variable, + * but this will do for now. */ max_dev_lun = 8; } @@ -743,8 +757,8 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, } /* if result == DID_OK ends */ /* - * This might screw us up with multi-lun devices, but the user can - * scan for them too. + * This might screw us up with multi-lun devices, but the + * user can scan for them too. */ if(hardcoded == 1) goto leave; @@ -756,7 +770,6 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded, leave: shpnt->host_queue = NULL; /* No longer needed here */ - /* Last device block does not exist. Free memory. */ if(SDpnt != NULL) scsi_init_free((char *) SDpnt, sizeof(Scsi_Device)); @@ -839,15 +852,15 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device) if (!device) panic ("No device passed to request_queueable().\n"); - if (req && req->dev <= 0) - panic("Invalid device in request_queueable"); + if (req && req->rq_status == RQ_INACTIVE) + panic("Inactive in request_queueable"); SCpnt = device->host->host_queue; /* * Look for a free command block. If we have been instructed not to queue - * multiple commands to multi-lun devices, then check to see what else is going on - * for this device first. + * multiple commands to multi-lun devices, then check to see what else is + * going for this device first. */ SCpnt = device->host->host_queue; @@ -855,7 +868,7 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device) while(SCpnt){ if(SCpnt->target == device->id && SCpnt->lun == device->lun) { - if(SCpnt->request.dev < 0) break; + if(SCpnt->request.rq_status == RQ_INACTIVE) break; } SCpnt = SCpnt->next; } @@ -864,16 +877,16 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device) if(SCpnt->target == device->id) { if (SCpnt->lun == device->lun) { if(found == NULL - && SCpnt->request.dev < 0) + && SCpnt->request.rq_status == RQ_INACTIVE) { found=SCpnt; } } - if(SCpnt->request.dev >= 0) { + if(SCpnt->request.rq_status != RQ_INACTIVE) { /* * I think that we should really limit things to one - * outstanding command per device - this is what tends to trip - * up buggy firmware. + * outstanding command per device - this is what tends + * to trip up buggy firmware. */ return NULL; } @@ -916,11 +929,11 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device) req->buffer = bh->b_data; SCpnt->request.sem = NULL; /* Wait until whole thing done */ } else { - req->dev = -1; + req->rq_status = RQ_INACTIVE; wake_up(&wait_for_request); } } else { - SCpnt->request.dev = 0xffff; /* Busy, but no request */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Busy, but no request */ SCpnt->request.sem = NULL; /* And no one is waiting for the device * either */ } @@ -954,7 +967,7 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device) Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, int wait) { - int dev = -1; + kdev_t dev; struct request * req = NULL; int tablesize; unsigned int flags; @@ -970,7 +983,11 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, if (reqp) req = *reqp; /* See if this request has already been queued by an interrupt routine */ - if (req && (dev = req->dev) <= 0) return NULL; + if (req) { + if(req->rq_status == RQ_INACTIVE) return NULL; + dev = req->rq_dev; + } else + dev = 0; /* unused */ host = device->host; @@ -983,7 +1000,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, if(SCpnt->target == device->id && SCpnt->lun == device->lun) { SCwait = SCpnt; - if(SCpnt->request.dev < 0) break; + if(SCpnt->request.rq_status == RQ_INACTIVE) break; } SCpnt = SCpnt->next; } @@ -993,16 +1010,16 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, if (SCpnt->lun == device->lun) { SCwait = SCpnt; if(found == NULL - && SCpnt->request.dev < 0) + && SCpnt->request.rq_status == RQ_INACTIVE) { found=SCpnt; } } - if(SCpnt->request.dev >= 0) { + if(SCpnt->request.rq_status != RQ_INACTIVE) { /* * I think that we should really limit things to one - * outstanding command per device - this is what tends to trip - * up buggy firmware. + * outstanding command per device - this is what tends + * to trip up buggy firmware. */ found = NULL; break; @@ -1017,11 +1034,11 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, cli(); /* See if this request has already been queued by an interrupt routine */ - if (req && ((req->dev < 0) || (req->dev != dev))) { + if (req && (req->rq_status == RQ_INACTIVE || req->rq_dev != dev)) { restore_flags(flags); return NULL; } - if (!SCpnt || SCpnt->request.dev >= 0) /* Might have changed */ + if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE) /* Might have changed */ { restore_flags(flags); if(!wait) return NULL; @@ -1031,7 +1048,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, panic("No device found in allocate_device\n"); } SCSI_SLEEP(&device->device_wait, - (SCwait->request.dev > 0)); + (SCwait->request.rq_status != RQ_INACTIVE)); } else { if (req) { memcpy(&SCpnt->request, req, sizeof(struct request)); @@ -1063,12 +1080,12 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, } else { - req->dev = -1; + req->rq_status = RQ_INACTIVE; *reqp = req->next; wake_up(&wait_for_request); } } else { - SCpnt->request.dev = 0xffff; /* Busy */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = NULL; /* And no one is waiting for this * to complete */ } @@ -1371,6 +1388,17 @@ static int check_sense (Scsi_Cmnd * SCpnt) return SUGGEST_RETRY; case NOT_READY: case UNIT_ATTENTION: + /* + * If we are expecting a CC/UA because of a bus reset that we + * performed, treat this just as a retry. Otherwise this is + * information that we should pass up to the upper-level driver + * so that we can deal with it there. + */ + if( SCpnt->device->expecting_cc_ua ) + { + SCpnt->device->expecting_cc_ua = 0; + return SUGGEST_RETRY; + } return SUGGEST_ABORT; /* these three are not supported */ @@ -1721,8 +1749,8 @@ static void scsi_done (Scsi_Cmnd * SCpnt) host_active = NULL; /* For block devices "wake_up" is done in end_scsi_request */ - if (MAJOR(SCpnt->request.dev) != SCSI_DISK_MAJOR && - MAJOR(SCpnt->request.dev) != SCSI_CDROM_MAJOR) { + if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR && + MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) { struct Scsi_Host * next; for (next = host->block; next != host; next = next->block) @@ -1775,7 +1803,7 @@ int scsi_abort (Scsi_Cmnd * SCpnt, int why, int pid) * Protect against races here. If the command is done, or we are * on a different command forget it. */ - if (SCpnt->request.dev == -1 || pid != SCpnt->pid) { + if (SCpnt->request.rq_status == RQ_INACTIVE || pid != SCpnt->pid) { restore_flags(flags); return 0; } @@ -1812,7 +1840,7 @@ int scsi_abort (Scsi_Cmnd * SCpnt, int why, int pid) SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->channel, (int) SCpnt->target, (int) SCpnt->lun); print_command (SCpnt->cmnd); - if (SCpnt->request.dev == -1 || pid != SCpnt->pid) + if (SCpnt->request.rq_status == RQ_INACTIVE || pid != SCpnt->pid) return 0; SCpnt->abort_reason = why; switch(host->hostt->abort(SCpnt)) { @@ -1898,7 +1926,7 @@ int scsi_reset (Scsi_Cmnd * SCpnt, int bus_reset_flag) */ SCpnt1 = host->host_queue; while(SCpnt1) { - if( SCpnt->request.dev > 0 + if( SCpnt->request.rq_status != RQ_INACTIVE && (SCpnt->flags & WAS_RESET) == 0 ) break; SCpnt1 = SCpnt1->next; @@ -1934,7 +1962,7 @@ int scsi_reset (Scsi_Cmnd * SCpnt, int bus_reset_flag) restore_flags(flags); SCpnt1 = host->host_queue; while(SCpnt1) { - if (SCpnt1->request.dev > 0) { + if (SCpnt1->request.rq_status != RQ_INACTIVE) { #if 0 if (!(SCpnt1->flags & IS_RESETTING) && !(SCpnt1->internal_timeout & IN_ABORT)) @@ -1973,6 +2001,7 @@ int scsi_reset (Scsi_Cmnd * SCpnt, int bus_reset_flag) SCpnt1 = host->host_queue; while(SCpnt1) { SCpnt1->device->was_reset = 1; + SCpnt1->device->expecting_cc_ua = 1; SCpnt1 = SCpnt1->next; } } @@ -2007,7 +2036,7 @@ int scsi_reset (Scsi_Cmnd * SCpnt, int bus_reset_flag) { SCpnt1 = host->host_queue; while(SCpnt1) { - if( SCpnt->request.dev > 0 + if( SCpnt->request.rq_status != RQ_INACTIVE && SCpnt1 != SCpnt) scsi_request_sense (SCpnt); SCpnt1 = SCpnt1->next; @@ -2317,7 +2346,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) SCpnt->target = SDpnt->id; SCpnt->lun = SDpnt->lun; SCpnt->channel = SDpnt->channel; - SCpnt->request.dev = -1; /* Mark not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; SCpnt->use_sg = 0; SCpnt->old_use_sg = 0; SCpnt->old_cmd_len = 0; @@ -2365,6 +2394,12 @@ unsigned long scsi_dev_init (unsigned long memory_start, unsigned long memory_en timer_table[SCSI_TIMER].fn = scsi_main_timeout; timer_table[SCSI_TIMER].expires = 0; + + /* Register the core /proc/scsi entry */ +#if CONFIG_PROC_FS + proc_scsi_register(0, &proc_scsi_scsi); +#endif + /* initialize all hosts */ scsi_init(); @@ -2525,7 +2560,8 @@ int scsi_proc_info(char *buffer, char **start, off_t offset, int length, pos = begin + len; while (HBA_ptr) { #if 0 - size += sprintf(buffer+len,"scsi%2d: %s\n", (int) HBA_ptr->host_no, HBA_ptr->hostt->procname); + size += sprintf(buffer+len,"scsi%2d: %s\n", (int) HBA_ptr->host_no, + HBA_ptr->hostt->procname); len += size; pos = begin + len; #endif @@ -2550,9 +2586,9 @@ int scsi_proc_info(char *buffer, char **start, off_t offset, int length, stop_output: *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Start slop */ + len-=(offset-begin); /* Start slop */ if(len>length) - len = length; /* Ending slop */ + len = length; /* Ending slop */ return (len); } @@ -2626,7 +2662,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) /* Add the new driver to /proc/scsi */ #if CONFIG_PROC_FS - build_proc_dir_entries(); + build_proc_dir_entries(tpnt); #endif for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) @@ -2794,14 +2830,15 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) { save_flags(flags); cli(); - if(SCpnt->request.dev != -1) { + if(SCpnt->request.rq_status != RQ_INACTIVE) { restore_flags(flags); for(SCpnt = shpnt->host_queue; SCpnt; SCpnt = SCpnt->next) - if(SCpnt->request.dev == 0xffe0) SCpnt->request.dev = -1; + if(SCpnt->request.rq_status == RQ_SCSI_DISCONNECTING) + SCpnt->request.rq_status = RQ_INACTIVE; printk("Device busy???\n"); return; } - SCpnt->request.dev = 0xffe0; /* Mark as busy */ + SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING; /* Mark as busy */ restore_flags(flags); } } @@ -2856,6 +2893,11 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) if(shpnt->hostt == tpnt) { if(shpnt->loaded_as_module) { pcount = next_scsi_host; + /* Remove the /proc/scsi directory entry */ +#if CONFIG_PROC_FS + proc_scsi_unregister(tpnt->proc_dir, + shpnt->host_no + PROC_SCSI_FILE); +#endif if(tpnt->release) (*tpnt->release)(shpnt); else { @@ -2905,7 +2947,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) /* Rebuild the /proc/scsi directory entries */ #if CONFIG_PROC_FS - build_proc_dir_entries(); + proc_scsi_unregister(tpnt->proc_dir, tpnt->proc_dir->low_ino); #endif MOD_DEC_USE_COUNT; } @@ -3075,12 +3117,12 @@ scsi_dump_status(void) for(SCpnt=shpnt->host_queue; SCpnt; SCpnt = SCpnt->next) { /* (0) 0:0:0:0 (802 123434 8 8 0) (3 3 2) (%d %d %d) %d %x */ - printk("(%d) %d:%d:%d:%d (%4.4x %ld %ld %ld %ld) (%d %d %x) (%d %d %d) %x %x %x\n", + printk("(%d) %d:%d:%d:%d (%s %ld %ld %ld %ld) (%d %d %x) (%d %d %d) %x %x %x\n", i++, SCpnt->host->host_no, SCpnt->channel, SCpnt->target, SCpnt->lun, - SCpnt->request.dev, + kdevname(SCpnt->request.rq_dev), SCpnt->request.sector, SCpnt->request.nr_sectors, SCpnt->request.current_nr_sectors, @@ -3105,8 +3147,8 @@ scsi_dump_status(void) printk("%d: ", i); req = blk_dev[i].current_request; while(req) { - printk("(%x %d %ld %ld %ld) ", - req->dev, + printk("(%s %d %ld %ld %ld) ", + kdevname(req->rq_dev), req->cmd, req->sector, req->nr_sectors, @@ -3125,18 +3167,10 @@ char kernel_version[] = UTS_RELEASE; extern struct symbol_table scsi_symbol_table; -int init_module(void) { - -#if CONFIG_PROC_FS - /* - * This will initialize the directory so that we do not have - * random crap in there. - */ - build_proc_dir_entries(); -#endif +int init_module(void) { /* - * This makes the real /proc/scsi visible. + * This makes /proc/scsi visible. */ dispatch_scsi_info_ptr = dispatch_scsi_info; @@ -3181,8 +3215,10 @@ void cleanup_module( void) */ for(i=0; i < dma_sectors >> 3; i++) scsi_init_free(dma_malloc_pages[i], PAGE_SIZE); - scsi_init_free((char *) dma_malloc_pages, dma_sectors>>1); - scsi_init_free(dma_malloc_freelist, dma_sectors>>3); + if (dma_malloc_pages) + scsi_init_free((char *) dma_malloc_pages, dma_sectors>>1); + if (dma_malloc_freelist) + scsi_init_free(dma_malloc_freelist, dma_sectors>>3); timer_table[SCSI_TIMER].fn = NULL; timer_table[SCSI_TIMER].expires = 0; diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index 5aea7b4b54b0..4687e1967f08 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -21,6 +21,7 @@ */ #include + /* * Some defs, in case these are not defined elsewhere. */ @@ -188,6 +189,8 @@ typedef struct scsi_device { one of the luns for the device at a time. */ unsigned was_reset:1; /* There was a bus reset on the bus for this device */ + unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN + because we did a bus reset. */ } Scsi_Device; /* @@ -440,12 +443,10 @@ extern int scsi_reset (Scsi_Cmnd *, int); extern int max_scsi_hosts; -extern void build_proc_dir_entries(void); extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int); - extern void print_command(unsigned char *); -extern void print_sense(const char *, Scsi_Cmnd *); +extern void print_sense(const char *, Scsi_Cmnd *); #if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR) @@ -459,8 +460,8 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors req = &SCpnt->request; req->errors = 0; if (!uptodate) { - printk(DEVICE_NAME " I/O error: dev %04x, sector %lu\n", - req->dev,req->sector); + printk(DEVICE_NAME " I/O error: dev %s, sector %lu\n", + kdevname(req->rq_dev), req->sector); } do { @@ -485,7 +486,7 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors req->buffer = bh->b_data; return SCpnt; }; - DEVICE_OFF(req->dev); + DEVICE_OFF(req->rq_dev); if (req->sem != NULL) { up(req->sem); } @@ -498,7 +499,7 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors wake_up(&next->host_wait); } - req->dev = -1; + req->rq_status = RQ_INACTIVE; wake_up(&wait_for_request); wake_up(&SCpnt->device->device_wait); return NULL; @@ -515,7 +516,7 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors restore_flags(flags); \ return; \ } \ - if (MAJOR(CURRENT->dev) != MAJOR_NR) \ + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ panic(DEVICE_NAME ": request list destroyed"); \ if (CURRENT->bh) { \ if (!CURRENT->bh->b_lock) \ diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3d8ef7ecdd27..e0dcbd1d4737 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -36,6 +36,14 @@ #include "sd.h" +#include + +struct proc_dir_entry proc_scsi_scsi_debug = { + PROC_SCSI_SCSI_DEBUG, 10, "scsi_debug", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + + /* A few options that we want selected */ /* Do not attempt to use a timer to simulate a real disk with latency */ @@ -76,31 +84,22 @@ static int npart = 0; #define VERIFY1_DEBUG(RW) \ if (bufflen != 1024) {printk("%d", bufflen); panic("(1)Bad bufflen");}; \ start = 0; \ - if ((SCpnt->request.dev & 0xf) != 0) start = starts[(SCpnt->request.dev & 0xf) - 1]; \ + if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1]; \ if (bh){ \ if (bh->b_size != 1024) panic ("Wrong bh size"); \ if ((bh->b_blocknr << 1) + start != block) \ { printk("Wrong bh block# %d %d ",bh->b_blocknr, block); \ panic ("Wrong bh block#"); \ }; \ - if (bh->b_dev != SCpnt->request.dev) panic ("Bad bh target");\ + if (bh->b_dev != SCpnt->request.rq_dev) \ + panic ("Bad bh target"); \ }; -#if 0 -/* This had been in the VERIFY_DEBUG macro, but it fails if there is already - * a disk on the system */ - if ((SCpnt->request.dev & 0xfff0) != ((target + NR_REAL) << 4) +(MAJOR_NR << 8)){ \ - printk("Dev #s %x %x ",SCpnt->request.dev, target); \ - panic ("Bad target");\ - }; \ - -#endif - #define VERIFY_DEBUG(RW) \ if (bufflen != 1024 && (!SCpnt->use_sg)) {printk("%x %d\n ",bufflen, SCpnt->use_sg); panic("Bad bufflen");}; \ start = 0; \ - if ((SCpnt->request.dev & 0xf) > npart) panic ("Bad partition"); \ - if ((SCpnt->request.dev & 0xf) != 0) start = starts[(SCpnt->request.dev & 0xf) - 1]; \ + if ((MINOR(SCpnt->request.rq_dev) & 0xf) > npart) panic ("Bad partition"); \ + if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1]; \ if (SCpnt->request.cmd != RW) panic ("Wrong operation"); \ if (SCpnt->request.sector + start != block) panic("Wrong block."); \ if (SCpnt->request.current_nr_sectors != 2 && (!SCpnt->use_sg)) panic ("Wrong # blocks"); \ @@ -110,7 +109,8 @@ static int npart = 0; { printk("Wrong bh block# %d %d ",SCpnt->request.bh->b_blocknr, block); \ panic ("Wrong bh block#"); \ }; \ - if (SCpnt->request.bh->b_dev != SCpnt->request.dev) panic ("Bad bh target");\ + if (SCpnt->request.bh->b_dev != SCpnt->request.rq_dev) \ + panic ("Bad bh target");\ }; #endif @@ -251,7 +251,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) break; case READ_CAPACITY: printk("Read Capacity\n"); - if(NR_REAL < 0) NR_REAL = (SCpnt->request.dev >> 4) & 0x0f; + if(NR_REAL < 0) NR_REAL = (MINOR(SCpnt->request.rq_dev) >> 4) & 0x0f; memset(buff, 0, bufflen); buff[0] = (CAPACITY >> 24); buff[1] = (CAPACITY >> 16) & 0xff; @@ -555,6 +555,7 @@ static void scsi_debug_intr_handle(void) int scsi_debug_detect(Scsi_Host_Template * tpnt) { + tpnt->proc_dir = &proc_scsi_scsi_debug; #ifndef IMMEDIATE timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle; timer_table[SCSI_DEBUG_TIMER].expires = 0; @@ -587,7 +588,7 @@ int scsi_debug_abort(Scsi_Cmnd * SCpnt) return SCSI_ABORT_SNOOZE; } -int scsi_debug_biosparam(Disk * disk, int dev, int* info){ +int scsi_debug_biosparam(Disk * disk, kdev_t dev, int* info){ int size = disk->capacity; info[0] = 32; info[1] = 64; diff --git a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h index b47055349eaa..87ae155f6f94 100644 --- a/drivers/scsi/scsi_debug.h +++ b/drivers/scsi/scsi_debug.h @@ -1,12 +1,13 @@ #ifndef _SCSI_DEBUG_H #include +#include int scsi_debug_detect(Scsi_Host_Template *); int scsi_debug_command(Scsi_Cmnd *); int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int scsi_debug_abort(Scsi_Cmnd *); -int scsi_debug_biosparam(Disk *, int, int[]); +int scsi_debug_biosparam(Disk *, kdev_t, int[]); int scsi_debug_reset(Scsi_Cmnd *); int scsi_debug_proc_info(char *, char **, off_t, int, int, int); @@ -14,10 +15,11 @@ int scsi_debug_proc_info(char *, char **, off_t, int, int, int); #define NULL 0 #endif + #define SCSI_DEBUG_MAILBOXES 8 -#define SCSI_DEBUG {NULL, NULL, scsi_debug_proc_info, "scsi_debug", \ - PROC_SCSI_SCSI_DEBUG, "SCSI DEBUG", scsi_debug_detect, NULL, \ +#define SCSI_DEBUG {NULL, NULL, NULL, scsi_debug_proc_info, \ + "SCSI DEBUG", scsi_debug_detect, NULL, \ NULL, scsi_debug_command, \ scsi_debug_queuecommand, \ scsi_debug_abort, \ diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 84e33e9983e1..dc112b0f404b 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -100,7 +100,7 @@ static void scsi_ioctl_done (Scsi_Cmnd * SCpnt) struct request * req; req = &SCpnt->request; - req->dev = 0xfffe; /* Busy, but indicate request done */ + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ if (req->sem != NULL) { up(req->sem); @@ -117,12 +117,13 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd) scsi_ioctl_done, MAX_TIMEOUT, MAX_RETRIES); - if (SCpnt->request.dev != 0xfffe){ + if (SCpnt->request.rq_status != RQ_SCSI_DONE){ struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); }; if(driver_byte(SCpnt->result) != 0) @@ -157,7 +158,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd) }; result = SCpnt->result; - SCpnt->request.dev = -1; + SCpnt->request.rq_status = RQ_INACTIVE; wake_up(&SCpnt->device->device_wait); return result; } @@ -251,12 +252,13 @@ static int ioctl_command(Scsi_Device *dev, void *buffer) scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, MAX_TIMEOUT, MAX_RETRIES); - if (SCpnt->request.dev != 0xfffe){ + if (SCpnt->request.rq_status != RQ_SCSI_DONE){ struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); } @@ -277,7 +279,9 @@ static int ioctl_command(Scsi_Device *dev, void *buffer) memcpy_tofs ((void *) cmd_in, buf, outlen); } result = SCpnt->result; - SCpnt->request.dev = -1; /* Mark as not busy */ + + SCpnt->request.rq_status = RQ_INACTIVE; + if (buf) scsi_free(buf, buf_needed); if(SCpnt->device->scsi_request_fn) @@ -324,7 +328,7 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) put_user(dev->id + (dev->lun << 8) + (dev->channel << 16) - + ((dev->host->hostt->low_ino & 0xff) << 24), + + ((dev->host->hostt->proc_dir->low_ino & 0xff) << 24), (unsigned long *) arg); put_user( dev->host->unique_id, (unsigned long *) arg+1); return 0; diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 91527fb57143..ff250511a9bb 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -7,7 +7,7 @@ * information directly to the lowlevel driver. * * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de - * Version: 0.99.7 last change: 95/07/18 + * Version: 0.99.8 last change: 95/09/13 * * generic command parser provided by: * Andreas Heilwagen @@ -32,6 +32,7 @@ #include #include #include +#include #include "../block/blk.h" #include "scsi.h" #include "hosts.h" @@ -41,36 +42,13 @@ #define FALSE 0 #endif -extern struct proc_dir_entry scsi_dir[]; -extern struct proc_dir_entry scsi_hba_dir[]; extern int scsi_proc_info(char *, char **, off_t, int, int, int); +struct scsi_dir { + struct proc_dir_entry entry; + char name[4]; +}; -int get_hba_index(int ino) -{ - Scsi_Host_Template *tpnt = scsi_hosts; - struct Scsi_Host *hpnt = scsi_hostlist; - uint x = 0; - - /* - * Danger - this has massive race conditions in it. - * If the someone adds/removes entries from the scsi chain - * while someone else is looking at /proc/scsi, unpredictable - * results will be obtained. - */ - while (tpnt) { - if (ino == tpnt->low_ino) - return(x); - x += 3; - while (hpnt) { - if(hpnt->hostt == tpnt) /* This gives us the correct index */ - x++; - hpnt = hpnt->next; - } - tpnt = tpnt->next; - } - return(0); -} /* generic_proc_info * Used if the driver currently has no own support for /proc/scsi @@ -106,118 +84,55 @@ extern int dispatch_scsi_info(int ino, char *buffer, char **start, off_t offset, int length, int func) { struct Scsi_Host *hpnt = scsi_hostlist; - - if(func != 2) { - if(ino == PROC_SCSI_SCSI) { - /* - * This is for the scsi core, rather than any specific - * lowlevel driver. - */ - return(scsi_proc_info(buffer, start, offset, length, 0, func)); - } - - while(hpnt) { - if (ino == (hpnt->host_no + PROC_SCSI_FILE)) { - if(hpnt->hostt->proc_info == NULL) - return generic_proc_info(buffer, start, offset, length, - hpnt->host_no, func); - else - return(hpnt->hostt->proc_info(buffer, start, offset, - length, hpnt->host_no, func)); - } - hpnt = hpnt->next; - } - return(-EBADF); - } else - return(get_hba_index(ino)); -} - -inline uint count_templates(void) -{ - Scsi_Host_Template *tpnt = scsi_hosts; - uint x = 0; - while (tpnt) { - tpnt = tpnt->next; - x++; + if(ino == PROC_SCSI_SCSI) { + /* + * This is for the scsi core, rather than any specific + * lowlevel driver. + */ + return(scsi_proc_info(buffer, start, offset, length, 0, func)); } - return (x); + + while(hpnt) { + if (ino == (hpnt->host_no + PROC_SCSI_FILE)) { + if(hpnt->hostt->proc_info == NULL) + return generic_proc_info(buffer, start, offset, length, + hpnt->host_no, func); + else + return(hpnt->hostt->proc_info(buffer, start, offset, + length, hpnt->host_no, func)); + } + hpnt = hpnt->next; + } + return(-EBADF); } -void build_proc_dir_hba_entries(void) +void build_proc_dir_entries(Scsi_Host_Template *tpnt) { - Scsi_Host_Template *tpnt = scsi_hosts; struct Scsi_Host *hpnt; - uint x, y; - - /* namespace for 16 HBAs with host_no 0-999 - * I don't think we'll need more. Having more than 2 - * HBAs in one system is already highly unusual - */ - static char names[PROC_SCSI_LAST - PROC_SCSI_FILE][4]; - - x = y = 0; - - while (tpnt) { - scsi_hba_dir[x].low_ino = tpnt->low_ino; - scsi_hba_dir[x].namelen = 1; - scsi_hba_dir[x++].name = "."; - scsi_hba_dir[x].low_ino = PROC_SCSI; - scsi_hba_dir[x].namelen = 2; - scsi_hba_dir[x++].name = ".."; - hpnt = scsi_hostlist; - while (hpnt) { - if (tpnt == hpnt->hostt) { - scsi_hba_dir[x].low_ino = PROC_SCSI_FILE + hpnt->host_no; - scsi_hba_dir[x].namelen = sprintf(names[y],"%d",hpnt->host_no); - scsi_hba_dir[x].name = names[y]; - y++; - x++; - } - hpnt = hpnt->next; - } - - scsi_hba_dir[x].low_ino = 0; - scsi_hba_dir[x].namelen = 0; - scsi_hba_dir[x++].name = NULL; - tpnt = tpnt->next; - } -} + struct scsi_dir *scsi_hba_dir; -void build_proc_dir_entries(void) -{ - Scsi_Host_Template *tpnt = scsi_hosts; + proc_scsi_register(0, tpnt->proc_dir); - uint newnum; - uint x; - - newnum = count_templates(); - - scsi_dir[0].low_ino = PROC_SCSI; - scsi_dir[0].namelen = 1; - scsi_dir[0].name = "."; - scsi_dir[1].low_ino = PROC_ROOT_INO; - scsi_dir[1].namelen = 2; - scsi_dir[1].name = ".."; - scsi_dir[2].low_ino = PROC_SCSI_SCSI; - scsi_dir[2].namelen = 4; - scsi_dir[2].name = "scsi"; - - for(x = 3; x < newnum + 3; x++, tpnt = tpnt->next) { - scsi_dir[x].low_ino = tpnt->low_ino; - scsi_dir[x].namelen = strlen(tpnt->procname); - scsi_dir[x].name = tpnt->procname; + hpnt = scsi_hostlist; + while (hpnt) { + if (tpnt == hpnt->hostt) { + scsi_hba_dir = scsi_init_malloc(sizeof(struct scsi_dir), GFP_KERNEL); + if(scsi_hba_dir == NULL) + panic("Not enough memory to register SCSI HBA in /proc/scsi !\n"); + memset(scsi_hba_dir, 0, sizeof(struct scsi_dir)); + scsi_hba_dir->entry.low_ino = PROC_SCSI_FILE + hpnt->host_no; + scsi_hba_dir->entry.namelen = sprintf(scsi_hba_dir->name,"%d", + hpnt->host_no); + scsi_hba_dir->entry.name = scsi_hba_dir->name; + scsi_hba_dir->entry.mode = S_IFREG | S_IRUGO | S_IWUSR; + proc_scsi_register(tpnt->proc_dir, &scsi_hba_dir->entry); + } + hpnt = hpnt->next; } - - scsi_dir[x].low_ino = 0; - scsi_dir[x].namelen = 0; - scsi_dir[x].name = NULL; - - build_proc_dir_hba_entries(); } - /* * parseHandle *parseInit(char *buf, char *cmdList, int cmdNum); * gets a pointer to a null terminated data buffer diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c index 3fd296416d38..c58ee79aeae7 100644 --- a/drivers/scsi/scsi_syms.c +++ b/drivers/scsi/scsi_syms.c @@ -31,6 +31,7 @@ #include "../block/blk.h" #include "scsi.h" +#include "scsi_ioctl.h" #include "hosts.h" #include "constants.h" @@ -39,15 +40,18 @@ * This source file contains the symbol table used by scsi loadable * modules. */ +extern int scsicam_bios_param (Disk * disk, + int dev, int *ip ); + extern void print_command (unsigned char *command); -extern void print_sense(char * devclass, Scsi_Cmnd * SCpnt); +extern void print_sense(const char * devclass, Scsi_Cmnd * SCpnt); struct symbol_table scsi_symbol_table = { #include #ifdef CONFIG_MODVERSIONS { (void *)1 /* Version version :-) */, - SYMBOL_NAME_STR("Using_Versions") }, + SYMBOL_NAME_STR(Using_Versions) }, #endif X(scsi_register_module), X(scsi_unregister_module), diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index 9f10df472a4b..97edb4804a21 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c @@ -49,13 +49,14 @@ static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds, */ int scsicam_bios_param (Disk *disk, /* SCSI disk */ - int dev, /* Device major, minor */ + kdev_t dev, /* Device major, minor */ int *ip /* Heads, sectors, cylinders in that order */) { + struct buffer_head *bh; int ret_code; int size = disk->capacity; - if (!(bh = bread(dev & ~0xf,0,1024))) + if (!(bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024))) return -1; #ifdef DEBUG diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b9781d3dc25d..28b7ab2982b9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -65,7 +65,6 @@ SC->device->type != TYPE_MOD) struct hd_struct * sd; -int revalidate_scsidisk(int dev, int maxusage); Scsi_Disk * rscsi_disks = NULL; static int * sd_sizes; @@ -74,8 +73,8 @@ static int * sd_hardsizes; /* Hardware sector size */ extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static int check_scsidisk_media_change(dev_t); -static int fop_revalidate_scsidisk(dev_t); +static int check_scsidisk_media_change(kdev_t); +static int fop_revalidate_scsidisk(kdev_t); static sd_init_onedisk(int); @@ -97,7 +96,7 @@ struct Scsi_Device_Template sd_template = static int sd_open(struct inode * inode, struct file * filp) { int target; - target = DEVICE_NR(MINOR(inode->i_rdev)); + target = DEVICE_NR(inode->i_rdev); if(target >= sd_template.dev_max || !rscsi_disks[target].device) return -ENXIO; /* No such device */ @@ -136,7 +135,7 @@ static void sd_release(struct inode * inode, struct file * file) int target; sync_dev(inode->i_rdev); - target = DEVICE_NR(MINOR(inode->i_rdev)); + target = DEVICE_NR(inode->i_rdev); rscsi_disks[target].device->access_count--; if (rscsi_disks[target].device->host->hostt->usage_count) @@ -206,7 +205,7 @@ static void rw_intr (Scsi_Cmnd *SCpnt) int this_count = SCpnt->bufflen >> 9; #ifdef DEBUG - printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.dev), + printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.rq_dev), SCpnt->host->host_no, result); #endif @@ -219,7 +218,7 @@ static void rw_intr (Scsi_Cmnd *SCpnt) if (!result) { #ifdef DEBUG - printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.dev), + printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.rq_dev), SCpnt->request.nr_sectors); printk("use_sg is %d\n ",SCpnt->use_sg); #endif @@ -267,7 +266,7 @@ static void rw_intr (Scsi_Cmnd *SCpnt) { #ifdef DEBUG printk("sd%c : handling page request, no buffer\n", - 'a' + MINOR(SCpnt->request.dev)); + 'a' + MINOR(SCpnt->request.rq_dev)); #endif /* * The SCpnt->request.nr_sectors field is always done in @@ -319,7 +318,7 @@ static void rw_intr (Scsi_Cmnd *SCpnt) * Not yet implemented. A read will fail after being remapped, * a write will call the strategy routine again. */ - if rscsi_disks[DEVICE_NR(SCpnt->request.dev)].remap + if rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].remap { result = 0; } @@ -329,11 +328,11 @@ static void rw_intr (Scsi_Cmnd *SCpnt) if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) { if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) { - if(rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->removable) { + if(rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->removable) { /* detected disc change. set a bit and quietly refuse * further access. */ - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->changed = 1; + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1; SCpnt = end_scsi_request(SCpnt, 0, this_count); requeue_sd_request(SCpnt); return; @@ -360,8 +359,8 @@ static void rw_intr (Scsi_Cmnd *SCpnt) */ if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) { - if (rscsi_disks[DEVICE_NR(SCpnt->request.dev)].ten) { - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].ten = 0; + if (rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten) { + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0; requeue_sd_request(SCpnt); result = 0; } else { @@ -371,10 +370,10 @@ static void rw_intr (Scsi_Cmnd *SCpnt) } /* driver byte != 0 */ if (result) { printk("SCSI disk error : host %d channel %d id %d lun %d return code = %x\n", - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->host->host_no, - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->channel, - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->id, - rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->lun, result); + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->channel, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->id, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->lun, result); if (driver_byte(result) & DRIVER_SENSE) print_sense("sd", SCpnt); @@ -401,13 +400,13 @@ static void do_sd_request (void) save_flags(flags); while (1==1){ cli(); - if (CURRENT != NULL && CURRENT->dev == -1) { + if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) { restore_flags(flags); return; }; INIT_SCSI_REQUEST; - SDev = rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device; + SDev = rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device; /* * I am not sure where the best place to do this is. We need @@ -444,7 +443,7 @@ static void do_sd_request (void) if (flag++ == 0) SCpnt = allocate_device(&CURRENT, - rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); + rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device, 0); else SCpnt = NULL; /* @@ -469,12 +468,12 @@ static void do_sd_request (void) cli(); req = CURRENT; while(req){ - SCpnt = request_queueable(req, rscsi_disks[DEVICE_NR(MINOR(req->dev))].device); + SCpnt = request_queueable(req, rscsi_disks[DEVICE_NR(req->rq_dev)].device); if(SCpnt) break; req1 = req; req = req->next; }; - if (SCpnt && req->dev == -1) { + if (SCpnt && req->rq_status == RQ_INACTIVE) { if (req == CURRENT) CURRENT = CURRENT->next; else @@ -492,7 +491,7 @@ static void do_sd_request (void) static void requeue_sd_request (Scsi_Cmnd * SCpnt) { - int dev, block, this_count; + int dev, devm, block, this_count; unsigned char cmd[10]; int bounce_size, contiguous; int max_sg; @@ -501,29 +500,30 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt) repeat: - if(!SCpnt || SCpnt->request.dev <= 0) { + if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) { do_sd_request(); return; } - dev = MINOR(SCpnt->request.dev); + devm = MINOR(SCpnt->request.rq_dev); + dev = DEVICE_NR(SCpnt->request.rq_dev); + block = SCpnt->request.sector; this_count = 0; #ifdef DEBUG - printk("Doing sd request, dev = %d, block = %d\n", dev, block); + printk("Doing sd request, dev = %d, block = %d\n", devm, block); #endif - if (dev >= (sd_template.dev_max << 4) || - !rscsi_disks[DEVICE_NR(dev)].device || - block + SCpnt->request.nr_sectors > sd[dev].nr_sects) + if (devm >= (sd_template.dev_max << 4) || + !rscsi_disks[dev].device || + block + SCpnt->request.nr_sectors > sd[devm].nr_sects) { SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); goto repeat; } - block += sd[dev].start_sect; - dev = DEVICE_NR(dev); + block += sd[devm].start_sect; if (rscsi_disks[dev].device->changed) { @@ -538,7 +538,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt) #ifdef DEBUG printk("sd%c : real dev = /dev/sd%c, block = %d\n", - 'a' + MINOR(SCpnt->request.dev), dev, block); + 'a' + devm, dev, block); #endif /* @@ -819,7 +819,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt) }; #ifdef DEBUG printk("sd%c : %s %d/%d 512 byte blocks.\n", - 'a' + MINOR(SCpnt->request.dev), + 'a' + devm, (SCpnt->request.cmd == WRITE) ? "writing" : "reading", this_count, SCpnt->request.nr_sectors); #endif @@ -880,13 +880,13 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt) MAX_RETRIES); } -static int check_scsidisk_media_change(dev_t full_dev){ +static int check_scsidisk_media_change(kdev_t full_dev){ int retval; int target; struct inode inode; int flag = 0; - target = DEVICE_NR(MINOR(full_dev)); + target = DEVICE_NR(full_dev); if (target >= sd_template.dev_max || !rscsi_disks[target].device) { @@ -919,7 +919,7 @@ static void sd_init_done (Scsi_Cmnd * SCpnt) struct request * req; req = &SCpnt->request; - req->dev = 0xfffe; /* Busy, but indicate request done */ + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ if (req->sem != NULL) { up(req->sem); @@ -953,7 +953,7 @@ static int sd_init_onedisk(int i) cmd[0] = TEST_UNIT_READY; cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); - SCpnt->request.dev = 0xffff; /* Mark as really busy again */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */ SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; @@ -963,7 +963,7 @@ static int sd_init_onedisk(int i) 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); - while(SCpnt->request.dev != 0xfffe) barrier(); + while(SCpnt->request.rq_status != RQ_SCSI_DONE) barrier(); the_result = SCpnt->result; retries++; @@ -985,7 +985,7 @@ static int sd_init_onedisk(int i) memset ((void *) &cmd[2], 0, 8); cmd[4] = 1; /* Start spin cycle */ /* Mark as really busy again */ - SCpnt->request.dev = 0xffff; + SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; @@ -995,8 +995,8 @@ static int sd_init_onedisk(int i) 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); - while(SCpnt->request.dev != 0xfffe) - barrier(); + while(SCpnt->request.rq_status != RQ_SCSI_DONE) + barrier(); spintime = jiffies; }; @@ -1021,7 +1021,7 @@ static int sd_init_onedisk(int i) cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); memset ((void *) buffer, 0, 8); - SCpnt->request.dev = 0xffff; /* Mark as really busy again */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */ SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; @@ -1031,25 +1031,26 @@ static int sd_init_onedisk(int i) 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES); - if (current->pid == 0) - while(SCpnt->request.dev != 0xfffe) - barrier(); - else - if (SCpnt->request.dev != 0xfffe){ + if (current->pid == 0) { + while(SCpnt->request.rq_status != RQ_SCSI_DONE) + barrier(); + } else { + if (SCpnt->request.rq_status != RQ_SCSI_DONE){ struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this one.. */ - while (SCpnt->request.dev != 0xfffe) - schedule(); - }; + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); + } + } the_result = SCpnt->result; retries--; } while(the_result && retries); - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ wake_up(&SCpnt->device->device_wait); @@ -1224,7 +1225,7 @@ static void sd_finish() if (MODULE_FLAG && !rscsi_disks[i].has_part_table) { sd_sizes[i << 4] = rscsi_disks[i].capacity; - revalidate_scsidisk(i << 4, 0); + revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0); } rscsi_disks[i].has_part_table = 1; } @@ -1288,15 +1289,15 @@ static int sd_attach(Scsi_Device * SDp){ * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */ -int revalidate_scsidisk(int dev, int maxusage){ - int target, major; +int revalidate_scsidisk(kdev_t dev, int maxusage){ + int target; struct gendisk * gdev; unsigned long flags; int max_p; int start; int i; - target = DEVICE_NR(MINOR(dev)); + target = DEVICE_NR(dev); gdev = &GENDISK_STRUCT; save_flags(flags); @@ -1311,14 +1312,15 @@ int revalidate_scsidisk(int dev, int maxusage){ max_p = gdev->max_p; start = target << gdev->minor_shift; - major = MAJOR_NR << 8; for (i=max_p - 1; i >=0 ; i--) { - sync_dev(major | start | i); - invalidate_inodes(major | start | i); - invalidate_buffers(major | start | i); - gdev->part[start+i].start_sect = 0; - gdev->part[start+i].nr_sects = 0; + int minor = start+i; + kdev_t devi = MKDEV(MAJOR_NR, minor); + sync_dev(devi); + invalidate_inodes(devi); + invalidate_buffers(devi); + gdev->part[minor].start_sect = 0; + gdev->part[minor].nr_sects = 0; /* * Reset the blocksize for everything so that we can read * the partition table. @@ -1337,7 +1339,7 @@ int revalidate_scsidisk(int dev, int maxusage){ return 0; } -static int fop_revalidate_scsidisk(dev_t dev){ +static int fop_revalidate_scsidisk(kdev_t dev){ return revalidate_scsidisk(dev, 0); } @@ -1347,7 +1349,6 @@ static void sd_detach(Scsi_Device * SDp) Scsi_Disk * dpnt; int i; int max_p; - int major; int start; for(dpnt = rscsi_disks, i=0; i=0 ; i--) { - sync_dev(major | start | i); - invalidate_inodes(major | start | i); - invalidate_buffers(major | start | i); - sd_gendisk.part[start+i].start_sect = 0; - sd_gendisk.part[start+i].nr_sects = 0; - sd_sizes[start+i] = 0; + int minor = start+i; + kdev_t devi = MKDEV(MAJOR_NR, minor); + sync_dev(devi); + invalidate_inodes(devi); + invalidate_buffers(devi); + sd_gendisk.part[minor].start_sect = 0; + sd_gendisk.part[minor].nr_sects = 0; + sd_sizes[minor] = 0; }; dpnt->has_part_table = 0; diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index c785a5fc9972..f0fcd714bd7f 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -23,12 +23,6 @@ #include #endif -/* - * This is an arbitrary constant, and may be changed to whatever - * suits your purposes. Note that smaller will get you a few bytes - * more in kernel space if that is your thing. - */ - extern struct hd_struct * sd; typedef struct scsi_disk { @@ -44,6 +38,8 @@ typedef struct scsi_disk { extern Scsi_Disk * rscsi_disks; +extern int revalidate_scsidisk(kdev_t dev, int maxusage); + #endif /* diff --git a/drivers/scsi/sd_ioctl.c b/drivers/scsi/sd_ioctl.c index 1f4c33bcd9e5..0df5d01bb850 100644 --- a/drivers/scsi/sd_ioctl.c +++ b/drivers/scsi/sd_ioctl.c @@ -19,11 +19,9 @@ #include "hosts.h" #include "sd.h" -extern int revalidate_scsidisk(int, int); - int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { - int dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; int error; struct Scsi_Host * host; int diskinfo[4]; @@ -58,13 +56,13 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne return 0; case BLKRASET: if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; + if(!(inode->i_rdev)) return -EINVAL; if(arg > 0xff) return -EINVAL; read_ahead[MAJOR(inode->i_rdev)] = arg; return 0; case BLKFLSBUF: if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; + if(!(inode->i_rdev)) return -EINVAL; fsync_dev(inode->i_rdev); invalidate_buffers(inode->i_rdev); return 0; diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index e66c24c32a95..befa51f5076a 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -63,6 +63,12 @@ #include "hosts.h" #include "seagate.h" #include "constants.h" +#include + +struct proc_dir_entry proc_scsi_seagate = { + PROC_SCSI_SEAGATE, 7, "seagate", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; #ifndef IRQ @@ -284,6 +290,7 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt) int i,j; #endif + tpnt->proc_dir = &proc_scsi_seagate; /* * First, we try for the manual override. */ @@ -1600,7 +1607,7 @@ int seagate_st0x_reset (Scsi_Cmnd * SCpnt) #include "sd.h" #include "scsi_ioctl.h" -int seagate_st0x_biosparam(Disk * disk, int dev, int* ip) { +int seagate_st0x_biosparam(Disk * disk, kdev_t dev, int* ip) { unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page; int *sizes, result, formatted_sectors, total_sectors; int cylinders, heads, sectors; diff --git a/drivers/scsi/seagate.h b/drivers/scsi/seagate.h index d9021d902e36..7210cb3dc174 100644 --- a/drivers/scsi/seagate.h +++ b/drivers/scsi/seagate.h @@ -24,10 +24,11 @@ int seagate_st0x_reset(Scsi_Cmnd *); #define NULL 0 #endif -int seagate_st0x_biosparam(Disk *, int, int*); +#include +int seagate_st0x_biosparam(Disk *, kdev_t, int*); -#define SEAGATE_ST0X { NULL, NULL, NULL, "seagate", \ - PROC_SCSI_SEAGATE, NULL, seagate_st0x_detect, \ +#define SEAGATE_ST0X { NULL, NULL, NULL, NULL, \ + NULL, seagate_st0x_detect, \ NULL, \ seagate_st0x_info, seagate_st0x_command, \ seagate_st0x_queue_command, seagate_st0x_abort, \ diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index aa3ee7733c3f..34b7c3b229a7 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -204,6 +204,7 @@ static int sg_read(struct inode *inode,struct file *filp,char *buf,int count) { int dev=MINOR(inode->i_rdev); int i; + unsigned long flags; struct scsi_generic *device=&scsi_generics[dev]; if ((i=verify_area(VERIFY_WRITE,buf,count))) return i; @@ -211,14 +212,23 @@ static int sg_read(struct inode *inode,struct file *filp,char *buf,int count) /* * Wait until the command is actually done. */ + save_flags(flags); + cli(); while(!device->pending || !device->complete) { if (filp->f_flags & O_NONBLOCK) + { + restore_flags(flags); return -EWOULDBLOCK; + } interruptible_sleep_on(&device->read_wait); if (current->signal & ~current->blocked) + { + restore_flags(flags); return -ERESTARTSYS; + } } + restore_flags(flags); /* * Now copy the result back to the user buffer. @@ -256,12 +266,12 @@ static int sg_read(struct inode *inode,struct file *filp,char *buf,int count) */ static void sg_command_done(Scsi_Cmnd * SCpnt) { - int dev=SCpnt->request.dev; - struct scsi_generic *device=&scsi_generics[dev]; + int dev = MINOR(SCpnt->request.rq_dev); + struct scsi_generic *device = &scsi_generics[dev]; if (!device->pending) { printk("unexpected done for sg %d\n",dev); - SCpnt->request.dev=-1; + SCpnt->request.rq_status = RQ_INACTIVE; return; } @@ -282,7 +292,7 @@ static void sg_command_done(Scsi_Cmnd * SCpnt) * result. */ device->complete=1; - SCpnt->request.dev=-1; + SCpnt->request.rq_status = RQ_INACTIVE; wake_up(&scsi_generics[dev].read_wait); } @@ -293,7 +303,8 @@ static int sg_write(struct inode *inode,struct file *filp,const char *buf,int co { int bsize,size,amt,i; unsigned char cmnd[MAX_COMMAND_SIZE]; - int dev=MINOR(inode->i_rdev); + kdev_t devt = inode->i_rdev; + int dev = MINOR(devt); struct scsi_generic * device=&scsi_generics[dev]; int direction; unsigned char opcode; @@ -394,7 +405,8 @@ static int sg_write(struct inode *inode,struct file *filp,const char *buf,int co /* * Now we need to grab the command itself from the user's buffer. */ - SCpnt->request.dev=dev; + SCpnt->request.rq_dev = devt; + SCpnt->request.rq_status = RQ_ACTIVE; SCpnt->sense_buffer[0]=0; opcode = get_user(buf); size=COMMAND_SIZE(opcode); @@ -462,7 +474,6 @@ static int sg_write(struct inode *inode,struct file *filp,const char *buf,int co static int sg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) { int dev=MINOR(inode->i_rdev); - int i; int r = 0; struct scsi_generic *device=&scsi_generics[dev]; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 772a937e5742..9d92012f5cfd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -67,7 +67,7 @@ static void get_sectorsize(int); extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long); void requeue_sr_request (Scsi_Cmnd * SCpnt); -static int check_cdrom_media_change(dev_t); +static int check_cdrom_media_change(kdev_t); static void sr_release(struct inode * inode, struct file * file) { @@ -87,7 +87,7 @@ static struct file_operations sr_fops = { NULL, /* lseek - default */ block_read, /* read - general block-dev read */ - block_write, /* write - general block-dev write */ + block_write, /* write - general block-dev write */ NULL, /* readdir - bad */ NULL, /* select */ sr_ioctl, /* ioctl */ @@ -110,7 +110,7 @@ static struct file_operations sr_fops = * an inode for that to work, and we do not always have one. */ -int check_cdrom_media_change(dev_t full_dev){ +int check_cdrom_media_change(kdev_t full_dev){ int retval, target; struct inode inode; int flag = 0; @@ -245,9 +245,9 @@ static void rw_intr (Scsi_Cmnd * SCpnt) /* detected disc change. set a bit and quietly refuse * further access. */ - scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1; + scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1; SCpnt = end_scsi_request(SCpnt, 0, this_count); - requeue_sr_request(SCpnt); + requeue_sr_request(SCpnt); return; } } @@ -257,15 +257,15 @@ static void rw_intr (Scsi_Cmnd * SCpnt) print_sense("sr", SCpnt); printk("command was: "); print_command(SCpnt->cmnd); - if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) { - scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0; + if (scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten) { + scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0; requeue_sr_request(SCpnt); result = 0; return; } else { - SCpnt = end_scsi_request(SCpnt, 0, this_count); - requeue_sr_request(SCpnt); /* Do next request */ - return; + SCpnt = end_scsi_request(SCpnt, 0, this_count); + requeue_sr_request(SCpnt); /* Do next request */ + return; } } @@ -281,9 +281,9 @@ static void rw_intr (Scsi_Cmnd * SCpnt) /* We only get this far if we have an error we have not recognized */ if(result) { printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", - scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host->host_no, - scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id, - scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun, + scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no, + scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->id, + scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->lun, result); if (status_byte(result) == CHECK_CONDITION) @@ -533,7 +533,7 @@ static int sr_open(struct inode * inode, struct file * filp) /* If this device did not have media in the drive at boot time, then * we would have been unable to get the sector size. Check to see if * this is the case, and try again. - */ + */ if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size) get_sectorsize(MINOR(inode->i_rdev)); @@ -559,14 +559,14 @@ static void do_sr_request (void) while (1==1){ save_flags(flags); cli(); - if (CURRENT != NULL && CURRENT->dev == -1) { + if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) { restore_flags(flags); return; }; INIT_SCSI_REQUEST; - SDev = scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device; + SDev = scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device; /* * I am not sure where the best place to do this is. We need @@ -590,7 +590,7 @@ static void do_sr_request (void) if (flag++ == 0) SCpnt = allocate_device(&CURRENT, - scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); + scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0); else SCpnt = NULL; restore_flags(flags); @@ -609,12 +609,12 @@ static void do_sr_request (void) req = CURRENT; while(req){ SCpnt = request_queueable(req, - scsi_CDs[DEVICE_NR(MINOR(req->dev))].device); + scsi_CDs[DEVICE_NR(req->rq_dev)].device); if(SCpnt) break; req1 = req; req = req->next; }; - if (SCpnt && req->dev == -1) { + if (SCpnt && req->rq_status == RQ_INACTIVE) { if (req == CURRENT) CURRENT = CURRENT->next; else @@ -642,34 +642,31 @@ void requeue_sr_request (Scsi_Cmnd * SCpnt) tries = 2; repeat: - if(!SCpnt || SCpnt->request.dev <= 0) { - do_sr_request(); - return; + if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) { + do_sr_request(); + return; } - dev = MINOR(SCpnt->request.dev); + dev = MINOR(SCpnt->request.rq_dev); block = SCpnt->request.sector; buffer = NULL; this_count = 0; - if (dev >= sr_template.nr_dev) - { + if (dev >= sr_template.nr_dev) { /* printk("CD-ROM request error: invalid device.\n"); */ SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); tries = 2; goto repeat; - } + } - if (!scsi_CDs[dev].use) - { + if (!scsi_CDs[dev].use) { /* printk("CD-ROM request error: device marked not in use.\n"); */ SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); tries = 2; goto repeat; - } + } - if (scsi_CDs[dev].device->changed) - { + if (scsi_CDs[dev].device->changed) { /* * quietly refuse to do anything to a changed disc * until the changed bit has been reset @@ -678,7 +675,7 @@ void requeue_sr_request (Scsi_Cmnd * SCpnt) SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); tries = 2; goto repeat; - } + } switch (SCpnt->request.cmd) { @@ -697,19 +694,20 @@ void requeue_sr_request (Scsi_Cmnd * SCpnt) /* * Now do the grungy work of figuring out which sectors we need, and - * where in memory we are going to put them. + * where in memory we are going to put them. * - * The variables we need are: + * The variables we need are: * - * this_count= number of 512 byte sectors being read - * block = starting cdrom sector to read. - * realcount = # of cdrom sectors to read + * this_count= number of 512 byte sectors being read + * block = starting cdrom sector to read. + * realcount = # of cdrom sectors to read * - * The major difference between a scsi disk and a scsi cdrom + * The major difference between a scsi disk and a scsi cdrom * is that we will always use scatter-gather if we can, because we can * work around the fact that the buffer cache has a block size of 1024, * and we have 2048 byte sectors. This code should work for buffers that - * are any multiple of 512 bytes long. */ + * are any multiple of 512 bytes long. + */ SCpnt->use_sg = 0; @@ -963,7 +961,7 @@ static void sr_init_done (Scsi_Cmnd * SCpnt) struct request * req; req = &SCpnt->request; - req->dev = 0xfffe; /* Busy, but indicate request done */ + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ if (req->sem != NULL) { up(req->sem); @@ -984,7 +982,7 @@ static void get_sectorsize(int i){ cmd[0] = READ_CAPACITY; cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); - SCpnt->request.dev = 0xffff; /* Mark as really busy */ + SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy */ SCpnt->cmd_len = 0; memset(buffer, 0, 8); @@ -995,15 +993,16 @@ static void get_sectorsize(int i){ MAX_RETRIES); if (current->pid == 0) - while(SCpnt->request.dev != 0xfffe) + while(SCpnt->request.rq_status != RQ_SCSI_DONE) barrier(); else - if (SCpnt->request.dev != 0xfffe){ + if (SCpnt->request.rq_status != RQ_SCSI_DONE){ struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); }; the_result = SCpnt->result; @@ -1011,7 +1010,7 @@ static void get_sectorsize(int i){ } while(the_result && retries); - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ wake_up(&SCpnt->device->device_wait); @@ -1114,18 +1113,18 @@ void sr_finish() static void sr_detach(Scsi_Device * SDp) { Scsi_CD * cpnt; - int i, major; - - major = MAJOR_NR << 8; + int i; for(cpnt = scsi_CDs, i=0; idevice == SDp) { + kdev_t devi = MKDEV(MAJOR_NR, i); + /* * Since the cdrom is read-only, no need to sync the device. * We should be kind to our buffer cache, however. */ - invalidate_inodes(major | i); - invalidate_buffers(major | i); + invalidate_inodes(devi); + invalidate_buffers(devi); /* * Reset things back to a sane state so that one can re-load a new diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index ce5f3e6cd1f4..dfa7df9bce39 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -29,7 +29,7 @@ static void sr_ioctl_done(Scsi_Cmnd * SCpnt) struct request * req; req = &SCpnt->request; - req->dev = 0xfffe; /* Busy, but indicate request done */ + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ if (req->sem != NULL) { up(req->sem); @@ -51,12 +51,13 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned IOCTL_TIMEOUT, IOCTL_RETRIES); - if (SCpnt->request.dev != 0xfffe){ + if (SCpnt->request.rq_status != RQ_SCSI_DONE){ struct semaphore sem = MUTEX_LOCKED; SCpnt->request.sem = &sem; down(&sem); /* Hmm.. Have to ask about this */ - while (SCpnt->request.dev != 0xfffe) schedule(); + while (SCpnt->request.rq_status != RQ_SCSI_DONE) + schedule(); }; result = SCpnt->result; @@ -88,7 +89,7 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned }; result = SCpnt->result; - SCpnt->request.dev = -1; /* Deallocate */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Deallocate */ wake_up(&SCpnt->device->device_wait); /* Wake up a process waiting for device*/ return result; @@ -98,7 +99,7 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne { u_char sr_cmd[10]; - int dev = inode->i_rdev; + kdev_t dev = inode->i_rdev; int result, target, err; target = MINOR(dev); @@ -445,7 +446,7 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne case BLKRASET: if(!suser()) return -EACCES; - if(!inode->i_rdev) return -EINVAL; + if(!(inode->i_rdev)) return -EINVAL; if(arg > 0xff) return -EINVAL; read_ahead[MAJOR(inode->i_rdev)] = arg; return 0; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 10aacb90152a..80cc4123b035 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -12,6 +12,7 @@ email Kai.Makisara@metla.fi Last modified: Sun Sep 10 20:33:24 1995 by makisara@kai.makisara.fi + Some small formal changes - aeb, 950809 */ #ifdef MODULE #include @@ -70,6 +71,8 @@ static int debugging = 1; #define ST_TIMEOUT (900 * HZ) #define ST_LONG_TIMEOUT (2000 * HZ) +#define TAPE_NR(x) (MINOR(x) & 127) + static int st_nbr_buffers; static int st_req_nbr_buffers; static ST_buffer **st_buffers; @@ -99,7 +102,7 @@ static int st_int_ioctl(struct inode * inode,struct file * file, static int st_chk_result(Scsi_Cmnd * SCpnt) { - int dev = SCpnt->request.dev; + int dev = TAPE_NR(SCpnt->request.rq_dev); int result = SCpnt->result; unsigned char * sense = SCpnt->sense_buffer, scode; const char *stp; @@ -158,10 +161,11 @@ st_chk_result(Scsi_Cmnd * SCpnt) static void st_sleep_done (Scsi_Cmnd * SCpnt) { - int st_nbr, remainder; + unsigned int st_nbr; + int remainder; Scsi_Tape * STp; - if ((st_nbr = SCpnt->request.dev) < st_template.nr_dev && st_nbr >= 0) { + if ((st_nbr = TAPE_NR(SCpnt->request.rq_dev)) < st_template.nr_dev) { STp = &(scsi_tapes[st_nbr]); if ((STp->buffer)->writing && (SCpnt->sense_buffer[0] & 0x70) == 0x70 && @@ -183,9 +187,9 @@ st_sleep_done (Scsi_Cmnd * SCpnt) (STp->buffer)->last_result = SCpnt->result; (STp->buffer)->last_result_fatal = st_chk_result(SCpnt); if ((STp->buffer)->writing) - SCpnt->request.dev = -1; + SCpnt->request.rq_status = RQ_INACTIVE; else - SCpnt->request.dev = 0xffff; + SCpnt->request.rq_status = RQ_SCSI_BUSY; if (!(STp->buffer)->writing || STp->write_pending) wake_up( &(STp->waiting) ); STp->write_pending = 0; @@ -199,8 +203,9 @@ st_sleep_done (Scsi_Cmnd * SCpnt) /* Handle the write-behind checking */ static void -write_behind_check(int dev) +write_behind_check(kdev_t devt) { + int dev = TAPE_NR(devt); Scsi_Tape * STp; ST_buffer * STbuffer; unsigned long flags; @@ -243,8 +248,9 @@ write_behind_check(int dev) /* Back over EOF if it has been inadvertently crossed (ioctl not used because it messes up the block number). */ static int -back_over_eof(int dev) +back_over_eof(kdev_t devt) { + int dev = TAPE_NR(devt); Scsi_Cmnd *SCpnt; Scsi_Tape *STp = &(scsi_tapes[dev]); unsigned char cmd[10]; @@ -256,7 +262,8 @@ back_over_eof(int dev) cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */ cmd[5] = 0; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 0, st_sleep_done, ST_TIMEOUT, MAX_RETRIES); @@ -264,10 +271,11 @@ back_over_eof(int dev) /* need to do the check with interrupts off. -RAB */ save_flags(flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); - SCpnt->request.dev = -1; + SCpnt->request.rq_status = RQ_INACTIVE; if ((STp->buffer)->last_result != 0) { printk("st%d: Backing over filemark failed.\n", dev); if ((STp->mt_status)->mt_fileno >= 0) @@ -281,8 +289,9 @@ back_over_eof(int dev) /* Flush the write buffer (never need to write if variable blocksize). */ static int -flush_write_buffer(int dev) +flush_write_buffer(kdev_t devt) { + int dev = TAPE_NR(devt); int offset, transfer, blks; int result; unsigned int flags; @@ -291,7 +300,7 @@ flush_write_buffer(int dev) Scsi_Tape *STp = &(scsi_tapes[dev]); if ((STp->buffer)->writing) { - write_behind_check(dev); + write_behind_check(devt); if ((STp->buffer)->last_result_fatal) { #if DEBUG if (debugging) @@ -327,7 +336,8 @@ flush_write_buffer(int dev) cmd[2] = blks >> 16; cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd (SCpnt, (void *) cmd, (STp->buffer)->b_data, transfer, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES); @@ -335,7 +345,8 @@ flush_write_buffer(int dev) /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); if ((STp->buffer)->last_result_fatal != 0) { @@ -357,7 +368,7 @@ flush_write_buffer(int dev) STp->dirty = 0; (STp->buffer)->buffer_bytes = 0; } - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ } return result; } @@ -368,12 +379,12 @@ flush_write_buffer(int dev) static int flush_buffer(struct inode * inode, struct file * filp, int seek_next) { - int dev; int backspace, result; Scsi_Tape * STp; ST_buffer * STbuffer; + kdev_t devt = inode->i_rdev; + int dev = TAPE_NR(devt); - dev = MINOR(inode->i_rdev) & 127; STp = &(scsi_tapes[dev]); STbuffer = STp->buffer; @@ -389,7 +400,7 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next) return 0; if (STp->rw == ST_WRITING) /* Writing */ - return flush_write_buffer(dev); + return flush_write_buffer(devt); if (STp->block_size == 0) return 0; @@ -403,7 +414,7 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next) result = 0; if (!seek_next) { if ((STp->eof == ST_FM) && !STp->eof_hit) { - result = back_over_eof(dev); /* Back over the EOF hit */ + result = back_over_eof(devt); /* Back over the EOF hit */ if (!result) { STp->eof = ST_NOEOF; STp->eof_hit = 0; @@ -421,15 +432,16 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next) static int scsi_tape_open(struct inode * inode, struct file * filp) { - int dev; unsigned short flags; unsigned int processor_flags; int i; unsigned char cmd[10]; Scsi_Cmnd * SCpnt; Scsi_Tape * STp; + kdev_t devt = inode->i_rdev; + int dev; - dev = MINOR(inode->i_rdev) & 127; + dev = TAPE_NR(devt); if (dev >= st_template.dev_max || !scsi_tapes[dev].device) return (-ENXIO); STp = &(scsi_tapes[dev]); @@ -475,7 +487,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10); cmd[0] = TEST_UNIT_READY; cmd[1] = (SCpnt->lun << 5) & 0xe0; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 0, st_sleep_done, ST_LONG_TIMEOUT, @@ -484,7 +497,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */ save_flags (processor_flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(processor_flags); if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 && @@ -493,7 +507,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10); cmd[0] = TEST_UNIT_READY; cmd[1] = (SCpnt->lun << 5) & 0xe0; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 0, st_sleep_done, ST_LONG_TIMEOUT, @@ -502,7 +517,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */ save_flags (processor_flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(processor_flags); (STp->mt_status)->mt_fileno = STp->drv_block = 0; @@ -519,8 +535,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) (STp->mt_status)->mt_fileno = STp->drv_block = (-1); STp->ready = ST_NOT_READY; } - SCpnt->request.dev = -1; /* Mark as not busy */ - STp->density = 0; /* Clear the erroneous "residue" */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ + STp->density = 0; /* Clear the erroneous "residue" */ STp->write_prot = 0; STp->block_size = 0; STp->eof = ST_NOEOF; @@ -535,7 +551,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10); cmd[0] = READ_BLOCK_LIMITS; cmd[1] = (SCpnt->lun << 5) & 0xe0; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 6, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES); @@ -543,7 +560,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */ save_flags (processor_flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(processor_flags); if (!SCpnt->result && !SCpnt->sense_buffer[0]) { @@ -569,7 +587,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) cmd[0] = MODE_SENSE; cmd[1] = (SCpnt->lun << 5) & 0xe0; cmd[4] = 12; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 12, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES); @@ -577,7 +596,8 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */ save_flags (processor_flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(processor_flags); if ((STp->buffer)->last_result_fatal != 0) { @@ -619,7 +639,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) return (-EIO); } } - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ if (STp->block_size > 0) { (STp->buffer)->buffer_blocks = st_buffer_size / STp->block_size; @@ -666,22 +686,23 @@ scsi_tape_open(struct inode * inode, struct file * filp) static void scsi_tape_close(struct inode * inode, struct file * filp) { - int dev; int result; int rewind; static unsigned char cmd[10]; Scsi_Cmnd * SCpnt; Scsi_Tape * STp; unsigned int flags; - - dev = MINOR(inode->i_rdev); - rewind = (dev & 0x80) == 0; - dev = dev & 127; + kdev_t devt = inode->i_rdev; + int dev; + + dev = TAPE_NR(devt); + rewind = (MINOR(devt) & 0x80) == 0; + STp = &(scsi_tapes[dev]); if ( STp->rw == ST_WRITING) { - result = flush_write_buffer(dev); + result = flush_write_buffer(devt); #if DEBUG if (debugging) { @@ -698,7 +719,8 @@ scsi_tape_close(struct inode * inode, struct file * filp) cmd[0] = WRITE_FILEMARKS; cmd[1] = (SCpnt->lun << 5) & 0xe0; cmd[4] = 1 + STp->two_fm; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd( SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, 0, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES); @@ -706,20 +728,21 @@ scsi_tape_close(struct inode * inode, struct file * filp) /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); if ((STp->buffer)->last_result_fatal != 0) { - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ printk("st%d: Error on write filemark.\n", dev); } else { - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ if ((STp->mt_status)->mt_fileno >= 0) (STp->mt_status)->mt_fileno++ ; STp->drv_block = 0; if (STp->two_fm) - back_over_eof(dev); + back_over_eof(devt); } } @@ -734,7 +757,7 @@ scsi_tape_close(struct inode * inode, struct file * filp) flush_buffer(inode, filp, 0); #else if ((STp->eof == ST_FM) && !STp->eof_hit) - back_over_eof(dev); + back_over_eof(devt); #endif } @@ -760,7 +783,6 @@ scsi_tape_close(struct inode * inode, struct file * filp) static int st_write(struct inode * inode, struct file * filp, const char * buf, int count) { - int dev; int total, do_count, blks, retval, transfer; int write_threshold; int doing_write = 0; @@ -769,8 +791,10 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) Scsi_Cmnd * SCpnt; Scsi_Tape * STp; unsigned int flags; + kdev_t devt = inode->i_rdev; + int dev; - dev = MINOR(inode->i_rdev) & 127; + dev = TAPE_NR(devt); STp = &(scsi_tapes[dev]); if (STp->ready != ST_READY) return (-EIO); @@ -810,7 +834,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) STp->moves_after_eof++; if ((STp->buffer)->writing) { - write_behind_check(dev); + write_behind_check(devt); if ((STp->buffer)->last_result_fatal) { #if DEBUG if (debugging) @@ -878,7 +902,8 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) cmd[2] = blks >> 16; cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd (SCpnt, (void *) cmd, (STp->buffer)->b_data, transfer, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES); @@ -886,7 +911,8 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); if ((STp->buffer)->last_result_fatal != 0) { @@ -939,7 +965,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) retval = (-EIO); } - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ (STp->buffer)->buffer_bytes = 0; STp->dirty = 0; if (count < total) @@ -969,7 +995,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) } if (doing_write && (STp->buffer)->last_result_fatal != 0) { - SCpnt->request.dev = -1; + SCpnt->request.rq_status = RQ_INACTIVE; return (STp->buffer)->last_result_fatal; } @@ -992,7 +1018,8 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) cmd[2] = blks >> 16; cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; STp->write_pending = 1; scsi_do_cmd (SCpnt, (void *) cmd, (STp->buffer)->b_data, @@ -1000,7 +1027,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES); } else - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ STp->at_sm &= (total != 0); return( total); @@ -1011,15 +1038,16 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) static int st_read(struct inode * inode, struct file * filp, char * buf, int count) { - int dev; int total; int transfer, blks, bytes; static unsigned char cmd[10]; Scsi_Cmnd * SCpnt; Scsi_Tape * STp; unsigned int flags; + kdev_t devt = inode->i_rdev; + int dev; - dev = MINOR(inode->i_rdev) & 127; + dev = TAPE_NR(devt); STp = &(scsi_tapes[dev]); if (STp->ready != ST_READY) return (-EIO); @@ -1090,7 +1118,8 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd (SCpnt, (void *) cmd, (STp->buffer)->b_data, bytes, st_sleep_done, ST_TIMEOUT, MAX_RETRIES); @@ -1098,7 +1127,8 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); (STp->buffer)->read_pointer = 0; @@ -1136,7 +1166,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) } else { printk("st%d: Incorrect block size.\n", dev); - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ return (-EIO); } } @@ -1173,7 +1203,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) if (debugging) printk("st%d: Tape error while reading.\n", dev); #endif - SCpnt->request.dev = -1; + SCpnt->request.rq_status = RQ_INACTIVE; STp->drv_block = (-1); if (total) return total; @@ -1193,7 +1223,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) } /* End of extended sense test */ else { transfer = (STp->buffer)->last_result_fatal; - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ return transfer; } } /* End of error handling */ @@ -1228,7 +1258,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) } else if (STp->eof != ST_NOEOF) { STp->eof_hit = 1; - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ if (total == 0 && STp->eof == ST_FM) { STp->eof = ST_NOEOF; STp->drv_block = 0; @@ -1247,7 +1277,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) } /* for (total = 0; total < count; ) */ - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ return total; } @@ -1258,10 +1288,12 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) static int st_set_options(struct inode * inode, long options) { - int dev, value; + int value; Scsi_Tape *STp; + kdev_t devt = inode->i_rdev; + int dev; - dev = MINOR(inode->i_rdev) & 127; + dev = TAPE_NR(devt); STp = &(scsi_tapes[dev]); if ((options & MT_ST_OPTIONS) == MT_ST_BOOLEANS) { STp->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0; @@ -1305,7 +1337,6 @@ st_set_options(struct inode * inode, long options) st_int_ioctl(struct inode * inode,struct file * file, unsigned int cmd_in, unsigned long arg) { - int dev = MINOR(inode->i_rdev); int timeout = ST_LONG_TIMEOUT; long ltmp; int ioctl_result; @@ -1314,8 +1345,9 @@ st_int_ioctl(struct inode * inode,struct file * file, Scsi_Tape * STp; int fileno, blkno, at_sm, undone, datalen; unsigned int flags; + kdev_t devt = inode->i_rdev; + int dev = TAPE_NR(devt); - dev = dev & 127; STp = &(scsi_tapes[dev]); if (STp->ready != ST_READY && cmd_in != MTLOAD) return (-EIO); @@ -1656,7 +1688,8 @@ st_int_ioctl(struct inode * inode,struct file * file, SCpnt = allocate_device(NULL, STp->device, 1); cmd[1] |= (SCpnt->lun << 5) & 0xe0; - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scsi_do_cmd(SCpnt, (void *) cmd, (void *) (STp->buffer)->b_data, datalen, st_sleep_done, timeout, MAX_RETRIES); @@ -1664,12 +1697,13 @@ st_int_ioctl(struct inode * inode,struct file * file, /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); ioctl_result = (STp->buffer)->last_result_fatal; - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ if (cmd_in == MTFSF) STp->moves_after_eof = 0; @@ -1789,7 +1823,6 @@ st_int_ioctl(struct inode * inode,struct file * file, st_ioctl(struct inode * inode,struct file * file, unsigned int cmd_in, unsigned long arg) { - int dev = MINOR(inode->i_rdev); int i, cmd, result; struct mtop mtc; struct mtpos mt_pos; @@ -1797,8 +1830,9 @@ st_ioctl(struct inode * inode,struct file * file, Scsi_Cmnd *SCpnt; Scsi_Tape *STp; unsigned int flags; + kdev_t devt = inode->i_rdev; + int dev = TAPE_NR(devt); - dev = dev & 127; STp = &(scsi_tapes[dev]); #if DEBUG if (debugging && !STp->in_use) { @@ -1946,7 +1980,8 @@ st_ioctl(struct inode * inode,struct file * file, scmd[0] = READ_POSITION; scmd[1] = 1; } - SCpnt->request.dev = dev; + SCpnt->request.rq_status = RQ_ACTIVE; + SCpnt->request.rq_dev = devt; scmd[1] |= (SCpnt->lun << 5) & 0xe0; scsi_do_cmd(SCpnt, (void *) scmd, (void *) (STp->buffer)->b_data, @@ -1955,7 +1990,8 @@ st_ioctl(struct inode * inode,struct file * file, /* this must be done with interrupts off */ save_flags (flags); cli(); - if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) ); + if (TAPE_NR(SCpnt->request.rq_dev) == dev) + sleep_on( &(STp->waiting) ); restore_flags(flags); if ((STp->buffer)->last_result_fatal != 0) { @@ -1980,7 +2016,7 @@ st_ioctl(struct inode * inode,struct file * file, } - SCpnt->request.dev = -1; /* Mark as not busy */ + SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos)); return result; diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index eac1105427a4..0b8fefa4c654 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -117,7 +117,12 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" +#include +struct proc_dir_entry proc_scsi_t128 = { + PROC_SCSI_T128, 4, "t128", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; static struct override { @@ -197,6 +202,8 @@ int t128_detect(Scsi_Host_Template * tpnt) { unsigned char *base; int sig, count; + tpnt->proc_dir = &proc_scsi_t128; + for (count = 0; current_override < NO_OVERRIDES; ++current_override) { base = NULL; @@ -270,7 +277,7 @@ int t128_detect(Scsi_Host_Template * tpnt) { } /* - * Function : int t128_biosparam(Disk * disk, int dev, int *ip) + * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip) * * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for * the specified device / size. @@ -289,7 +296,7 @@ int t128_detect(Scsi_Host_Template * tpnt) { * and matching the H_C_S coordinates to what DOS uses. */ -int t128_biosparam(Disk * disk, int dev, int * ip) +int t128_biosparam(Disk * disk, kdev_t dev, int * ip) { int size = disk->capacity; ip[0] = 64; diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index f9bf252ae970..dfb20ccfc2df 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h @@ -92,7 +92,7 @@ #ifndef ASM int t128_abort(Scsi_Cmnd *); -int t128_biosparam(Disk *, int, int*); +int t128_biosparam(Disk *, kdev_t, int*); int t128_detect(Scsi_Host_Template *); int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int t128_reset(Scsi_Cmnd *); @@ -117,7 +117,7 @@ int t128_reset(Scsi_Cmnd *); #ifdef HOSTS_C -#define TRANTOR_T128 {NULL, NULL, NULL, "t128", PROC_SCSI_T128, \ +#define TRANTOR_T128 {NULL, NULL, NULL, NULL, \ "Trantor T128/T128F/T228", t128_detect, NULL, \ NULL, \ NULL, t128_queue_command, t128_abort, t128_reset, NULL, \ diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 69e21acdf6a5..62a6e46447a1 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -155,6 +155,12 @@ #include #include #include "u14-34f.h" +#include + +struct proc_dir_entry proc_scsi_u14_34f = { + PROC_SCSI_U14_34F, 6, "u14_34f", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; /* Values for the PRODUCT_ID ports for the 14/34F */ #define PRODUCT_ID1 0x56 @@ -514,6 +520,8 @@ int u14_34f_detect (Scsi_Host_Template * tpnt) { ushort *port_base = io_port; + tpnt->proc_dir = &proc_scsi_u14_34f; + save_flags(flags); cli(); @@ -820,7 +828,7 @@ int u14_34f_reset(Scsi_Cmnd * SCarg) { } } -int u14_34f_biosparam(Disk * disk, int dev, int * dkinfo) { +int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) { unsigned int j = 0; int size = disk->capacity; diff --git a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h index b8483a45c3d0..2988824ebf16 100644 --- a/drivers/scsi/u14-34f.h +++ b/drivers/scsi/u14-34f.h @@ -8,7 +8,7 @@ int u14_34f_detect(Scsi_Host_Template *); int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int u14_34f_abort(Scsi_Cmnd *); int u14_34f_reset(Scsi_Cmnd *); -int u14_34f_biosparam(Disk *, int, int *); +int u14_34f_biosparam(Disk *, kdev_t, int *); #define U14_34F_VERSION "2.01.00" @@ -16,8 +16,7 @@ int u14_34f_biosparam(Disk *, int, int *); NULL, /* Ptr for modules */ \ NULL, /* usage count for modules */ \ NULL, \ - "u14_34f", \ - PROC_SCSI_U14_34F, \ + NULL, \ "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \ u14_34f_detect, \ NULL, /* Release */ \ diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 555f4a79e5ee..251861289e06 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -145,6 +145,12 @@ #include "hosts.h" #include "ultrastor.h" #include "sd.h" +#include + +struct proc_dir_entry proc_scsi_ultrastor = { + PROC_SCSI_ULTRASTOR, 9, "ultrastor", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; #define FALSE 0 #define TRUE 1 @@ -625,6 +631,7 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) int ultrastor_detect(Scsi_Host_Template * tpnt) { + tpnt->proc_dir = &proc_scsi_ultrastor; return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt); } @@ -1003,7 +1010,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt) } -int ultrastor_biosparam(Disk * disk, int dev, int * dkinfo) +int ultrastor_biosparam(Disk * disk, kdev_t dev, int * dkinfo) { int size = disk->capacity; unsigned int s = config.heads * config.sectors; diff --git a/drivers/scsi/ultrastor.h b/drivers/scsi/ultrastor.h index a6c6345a444b..10cf63f2e841 100644 --- a/drivers/scsi/ultrastor.h +++ b/drivers/scsi/ultrastor.h @@ -12,13 +12,14 @@ #ifndef _ULTRASTOR_H #define _ULTRASTOR_H +#include int ultrastor_detect(Scsi_Host_Template *); const char *ultrastor_info(struct Scsi_Host * shpnt); int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int ultrastor_abort(Scsi_Cmnd *); int ultrastor_reset(Scsi_Cmnd *); -int ultrastor_biosparam(Disk *, int, int *); +int ultrastor_biosparam(Disk *, kdev_t, int *); #define ULTRASTOR_14F_MAX_SG 16 @@ -32,8 +33,7 @@ int ultrastor_biosparam(Disk *, int, int *); #define ULTRASTOR_14F { NULL, NULL, /* Ptr for modules*/ \ NULL, \ - "ultrastor", \ - PROC_SCSI_ULTRASTOR, \ + NULL, \ "UltraStor 14F/24F/34F", \ ultrastor_detect, \ NULL, /* Release */ \ diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 6a8c8a92ab57..1f77e4f26823 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -126,6 +126,13 @@ #include "wd7000.h" +#include + +struct proc_dir_entry proc_scsi_wd7000 = { + PROC_SCSI_7000FASST, 6, "wd7000", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + /* * Mailbox structure sizes. @@ -988,7 +995,7 @@ int wd7000_diagnostics( Adapter *host, int code ) int wd7000_init( Adapter *host ) { InitCmd init_cmd = { - INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, 0,0,0, OGMB_CNT, ICMB_CNT + INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, {0,0,0}, OGMB_CNT, ICMB_CNT }; int diag; @@ -1104,6 +1111,8 @@ int wd7000_detect(Scsi_Host_Template * tpnt) Adapter *host = NULL; struct Scsi_Host *sh; + tpnt->proc_dir = &proc_scsi_wd7000; + /* Set up SCB free list, which is shared by all adapters */ init_scbs(); @@ -1210,7 +1219,7 @@ int wd7000_reset(Scsi_Cmnd * SCpnt) * this way, so I think it will work OK. Someone who is ambitious can * borrow a newer or more complete version from another driver. */ -int wd7000_biosparam(Disk * disk, int dev, int* ip) +int wd7000_biosparam(Disk * disk, kdev_t dev, int* ip) { int size = disk->capacity; ip[0] = 64; diff --git a/drivers/scsi/wd7000.h b/drivers/scsi/wd7000.h index 821f756841e1..e4aec6b50927 100644 --- a/drivers/scsi/wd7000.h +++ b/drivers/scsi/wd7000.h @@ -11,13 +11,14 @@ */ #include +#include int wd7000_detect(Scsi_Host_Template *); int wd7000_command(Scsi_Cmnd *); int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int wd7000_abort(Scsi_Cmnd *); int wd7000_reset(Scsi_Cmnd *); -int wd7000_biosparam(Disk *, int, int*); +int wd7000_biosparam(Disk *, kdev_t, int *); #ifndef NULL #define NULL 0L @@ -39,8 +40,7 @@ int wd7000_biosparam(Disk *, int, int*); #define WD7000 { NULL, NULL, \ NULL, \ - "wd7000", \ - PROC_SCSI_7000FASST, \ + NULL, \ "Western Digital WD-7000", \ wd7000_detect, \ NULL, \ diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 7c3ad38da507..d5dee6bc1785 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -17,7 +17,13 @@ OBJS = soundcard.o audio.o dmabuf.o sb_dsp.o dev_table.o \ sys_timer.o ics2101.o ad1848.o pss.o sscape.o trix.o aedsp16.o \ mad16.o +# Don't compile the sound driver during a normal kernel build if we have +# configured for a module build instead. +ifeq ($(CONFIG_SOUND),y) all: local.h sound.a +else +all: +endif sound.a: $(OBJS) -rm -f sound.a @@ -59,9 +65,9 @@ dep: setup-linux: @echo Compiling Sound Driver v $(VERSION) for Linux -sound.o: $(OBJS) +sound.o: sound.a -rm -f sound.o - $(LD) -r -o sound.o $(OBJS) + $(LD) -r -o sound.o soundcard.o sound.a modules: sound.o (cd ../../modules; ln -fs ../drivers/sound/sound.o .) diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c index 65c6abccea2f..e78e19153d6b 100644 --- a/drivers/sound/dmabuf.c +++ b/drivers/sound/dmabuf.c @@ -35,6 +35,8 @@ #if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_GUS) +static int space_in_queue (int dev); + DEFINE_WAIT_QUEUES (dev_sleeper[MAX_AUDIO_DEV], dev_sleep_flag[MAX_AUDIO_DEV]); static struct dma_buffparms dmaps[MAX_AUDIO_DEV] = diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 9f90434c58a0..04d5a2015841 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -58,14 +58,13 @@ sound_read (struct inode *inode, struct file *file, char *buf, int count) { int dev; - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); return sound_read_sw (dev, &files[dev], buf, count); } static int -sound_write (struct inode *inode, struct file *file, char *buf, int count) +sound_write (struct inode *inode, struct file *file, const char *buf, int count) { int dev; @@ -74,8 +73,7 @@ sound_write (struct inode *inode, struct file *file, char *buf, int count) #endif - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); return sound_write_sw (dev, &files[dev], buf, count); } @@ -92,8 +90,7 @@ sound_open (struct inode *inode, struct file *file) int dev, retval; struct fileinfo tmp_file; - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS) { @@ -127,8 +124,7 @@ sound_release (struct inode *inode, struct file *file) { int dev; - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); sound_release_sw (dev, &files[dev]); #ifdef MODULE @@ -142,8 +138,7 @@ sound_ioctl (struct inode *inode, struct file *file, { int dev; - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); if (cmd & IOC_INOUT) { @@ -176,8 +171,7 @@ sound_select (struct inode *inode, struct file *file, int sel_type, select_table { int dev; - dev = inode->i_rdev; - dev = MINOR (dev); + dev = MINOR(inode->i_rdev); DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type)); @@ -438,6 +432,7 @@ module_sound_mem_init (void) int dev, ret = 0; unsigned long dma_pagesize; char *start_addr, *end_addr; + int order, size; struct dma_buffparms *dmap; for (dev = 0; dev < num_audiodevs; dev++) @@ -497,8 +492,10 @@ module_sound_mem_init (void) } } #else - start_addr = kmalloc (audio_devs[dev]->buffsize, - GFP_DMA | GFP_KERNEL); + for (order = 0, size = PAGE_SIZE; + size < audio_devs[dev]->buffsize; + order++, size <<= 1); + start_addr = (char *) __get_free_pages(GFP_KERNEL, order, MAX_DMA_ADDRESS); #endif if (start_addr == NULL) ret = -ENOMEM; /* Can't stop the loop in this case, because @@ -545,8 +542,12 @@ module_sound_mem_release (void) } #else int dev, i; + int order, size; - for (dev = 0; dev < num_audiodevs; dev++) + for (dev = 0; dev < num_audiodevs; dev++) { + for (order = 0, size = PAGE_SIZE; + size < audio_devs[dev]->buffsize; + order++, size <<= 1); if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0) { for (i = 0; i < audio_devs[dev]->buffcount; i++) @@ -555,9 +556,11 @@ module_sound_mem_release (void) if (debugmem) printk ("sound: freeing 0x%lx\n", (long) (audio_devs[dev]->dmap->raw_buf[i])); - kfree (audio_devs[dev]->dmap->raw_buf[i]); + free_pages((unsigned long) audio_devs[dev]->dmap->raw_buf[i], + order); } } + } #endif } diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6632cf5b4e32..16ffcb9275f4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -633,6 +633,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) #ifdef LOW_ELF_STACK current->start_stack = p = elf_stack - 4; #endif + current->suid = current->euid = current->fsuid = bprm->e_uid; + current->sgid = current->egid = current->fsgid = bprm->e_gid; bprm->p -= MAX_ARG_PAGES*PAGE_SIZE; bprm->p = (unsigned long) create_elf_tables((char *)bprm->p, @@ -649,8 +651,6 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->start_code = start_code; current->mm->end_data = end_data; current->mm->start_stack = bprm->p; - current->suid = current->euid = current->fsuid = bprm->e_uid; - current->sgid = current->egid = current->fsgid = bprm->e_gid; /* Calling sys_brk effectively mmaps the pages that we need for the bss and break sections */ diff --git a/fs/block_dev.c b/fs/block_dev.c index 8705ec203468..af96fdf78b99 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -31,7 +31,7 @@ int block_write(struct inode * inode, struct file * filp, const char * buf, int struct buffer_head * bhlist[NBUF]; int blocks_per_cluster; unsigned int size; - unsigned int dev; + kdev_t dev; struct buffer_head * bh, *bufferlist[NBUF]; register char * p; int excess; @@ -172,7 +172,7 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count) struct buffer_head * bhreq[NBUF]; unsigned int chars; loff_t size; - unsigned int dev; + kdev_t dev; int read; int excess; diff --git a/fs/buffer.c b/fs/buffer.c index 8c2a03ab4ea8..757f188bc0f6 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -134,7 +134,7 @@ repeat: We will ultimately want to put these in a separate list, but for now we search all of the lists for dirty buffers */ -static int sync_buffers(dev_t dev, int wait) +static int sync_buffers(kdev_t dev, int wait) { int i, retry, pass = 0, err = 0; int nlist, ncount; @@ -177,7 +177,9 @@ static int sync_buffers(dev_t dev, int wait) if (wait && bh->b_req && !bh->b_lock && !bh->b_dirt && !bh->b_uptodate) { err = 1; - printk("Weird - unlocked, clean and not uptodate buffer on list %d %x %lu\n", nlist, bh->b_dev, bh->b_blocknr); + printk("Weird - unlocked, clean and not " + "uptodate buffer on list %d %s %lu\n", + nlist, kdevname(bh->b_dev), bh->b_blocknr); continue; } /* Don't write clean buffers. Don't write ANY buffers @@ -192,14 +194,16 @@ static int sync_buffers(dev_t dev, int wait) ll_rw_block(WRITE, 1, &bh); if(nlist != BUF_DIRTY) { - printk("[%d %x %ld] ", nlist, bh->b_dev, bh->b_blocknr); + printk("[%d %s %ld] ", nlist, + kdevname(bh->b_dev), bh->b_blocknr); ncount++; }; bh->b_count--; retry = 1; } } - if (ncount) printk("sys_sync: %d dirty buffers not on dirty list\n", ncount); + if (ncount) + printk("sys_sync: %d dirty buffers not on dirty list\n", ncount); /* If we are waiting for the sync to succeed, and if any dirty blocks were written, then repeat; on the second pass, only @@ -210,7 +214,7 @@ static int sync_buffers(dev_t dev, int wait) return err; } -void sync_dev(dev_t dev) +void sync_dev(kdev_t dev) { sync_buffers(dev, 0); sync_supers(dev); @@ -218,7 +222,7 @@ void sync_dev(dev_t dev) sync_buffers(dev, 0); } -int fsync_dev(dev_t dev) +int fsync_dev(kdev_t dev) { sync_buffers(dev, 0); sync_supers(dev); @@ -251,7 +255,7 @@ asmlinkage int sys_fsync(unsigned int fd) return 0; } -void invalidate_buffers(dev_t dev) +void invalidate_buffers(kdev_t dev) { int i; int nlist; @@ -273,7 +277,7 @@ void invalidate_buffers(dev_t dev) } } -#define _hashfn(dev,block) (((unsigned)(dev^block))%nr_hash) +#define _hashfn(dev,block) (((unsigned)(HASHDEV(dev)^block))%nr_hash) #define hash(dev,block) hash_table[_hashfn(dev,block)] static inline void remove_from_hash_queue(struct buffer_head * bh) @@ -291,7 +295,8 @@ static inline void remove_from_lru_list(struct buffer_head * bh) { if (!(bh->b_prev_free) || !(bh->b_next_free)) panic("VFS: LRU block list corrupted"); - if (bh->b_dev == 0xffff) panic("LRU list corrupted"); + if (bh->b_dev == B_FREE) + panic("LRU list corrupted"); bh->b_prev_free->b_next_free = bh->b_next_free; bh->b_next_free->b_prev_free = bh->b_prev_free; @@ -307,9 +312,10 @@ static inline void remove_from_free_list(struct buffer_head * bh) int isize = BUFSIZE_INDEX(bh->b_size); if (!(bh->b_prev_free) || !(bh->b_next_free)) panic("VFS: Free block list corrupted"); - if(bh->b_dev != 0xffff) panic("Free list corrupted"); + if(bh->b_dev != B_FREE) + panic("Free list corrupted"); if(!free_list[isize]) - panic("Free list empty"); + panic("Free list empty"); nr_free[isize]--; if(bh->b_next_free == bh) free_list[isize] = NULL; @@ -324,7 +330,7 @@ static inline void remove_from_free_list(struct buffer_head * bh) static inline void remove_from_queues(struct buffer_head * bh) { - if(bh->b_dev == 0xffff) { + if(bh->b_dev == B_FREE) { remove_from_free_list(bh); /* Free list entries should not be in the hash queue */ return; @@ -343,7 +349,8 @@ static inline void put_last_lru(struct buffer_head * bh) lru_list[bh->b_list] = bh->b_next_free; return; } - if(bh->b_dev == 0xffff) panic("Wrong block for lru list"); + if(bh->b_dev == B_FREE) + panic("Wrong block for lru list"); remove_from_lru_list(bh); /* add to back of free list */ @@ -365,7 +372,7 @@ static inline void put_last_free(struct buffer_head * bh) return; isize = BUFSIZE_INDEX(bh->b_size); - bh->b_dev = 0xffff; /* So it is obvious we are on the free list */ + bh->b_dev = B_FREE; /* So it is obvious we are on the free list */ /* add to back of free list */ if(!free_list[isize]) { @@ -384,7 +391,7 @@ static inline void insert_into_queues(struct buffer_head * bh) { /* put at end of free list */ - if(bh->b_dev == 0xffff) { + if(bh->b_dev == B_FREE) { put_last_free(bh); return; }; @@ -402,7 +409,7 @@ static inline void insert_into_queues(struct buffer_head * bh) /* put the buffer in new hash-queue if it has a device */ bh->b_prev = NULL; bh->b_next = NULL; - if (!bh->b_dev) + if (!(bh->b_dev)) return; bh->b_next = hash(bh->b_dev,bh->b_blocknr); hash(bh->b_dev,bh->b_blocknr) = bh; @@ -410,17 +417,17 @@ static inline void insert_into_queues(struct buffer_head * bh) bh->b_next->b_prev = bh; } -static struct buffer_head * find_buffer(dev_t dev, int block, int size) +static struct buffer_head * find_buffer(kdev_t dev, int block, int size) { struct buffer_head * tmp; for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next) - if (tmp->b_dev==dev && tmp->b_blocknr==block) + if (tmp->b_dev == dev && tmp->b_blocknr == block) if (tmp->b_size == size) return tmp; else { - printk("VFS: Wrong blocksize on device %d/%d\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: Wrong blocksize on device %s\n", + kdevname(dev)); return NULL; } return NULL; @@ -433,7 +440,7 @@ static struct buffer_head * find_buffer(dev_t dev, int block, int size) * will force it bad). This shouldn't really happen currently, but * the code is ready. */ -struct buffer_head * get_hash_table(dev_t dev, int block, int size) +struct buffer_head * get_hash_table(kdev_t dev, int block, int size) { struct buffer_head * bh; @@ -443,13 +450,14 @@ struct buffer_head * get_hash_table(dev_t dev, int block, int size) bh->b_reuse=0; bh->b_count++; wait_on_buffer(bh); - if (bh->b_dev == dev && bh->b_blocknr == block && bh->b_size == size) + if (bh->b_dev == dev && bh->b_blocknr == block + && bh->b_size == size) return bh; bh->b_count--; } } -void set_blocksize(dev_t dev, int size) +void set_blocksize(kdev_t dev, int size) { int i, nlist; struct buffer_head * bh, *bhnext; @@ -610,9 +618,10 @@ repeat0: panic("Shared buffer in candidate list\n"); if (BADNESS(bh)) panic("Buffer in candidate list with BADNESS != 0\n"); - if(bh->b_dev == 0xffff) panic("Wrong list"); + if(bh->b_dev == B_FREE) + panic("Wrong list"); remove_from_queues(bh); - bh->b_dev = 0xffff; + bh->b_dev = B_FREE; put_last_free(bh); needed -= bh->b_size; buffers[i]--; @@ -687,7 +696,7 @@ repeat0: * 14.02.92: changed it to sync dirty buffers a bit: better performance * when the filesystem starts to get full of dirty blocks (I hope). */ -struct buffer_head * getblk(dev_t dev, int block, int size) +struct buffer_head * getblk(kdev_t dev, int block, int size) { struct buffer_head * bh; int isize = BUFSIZE_INDEX(size); @@ -748,7 +757,8 @@ void set_writetime(struct buffer_head * buf, int flag) void refile_buffer(struct buffer_head * buf){ int dispose; - if(buf->b_dev == 0xffff) panic("Attempt to refile free buffer\n"); + if(buf->b_dev == B_FREE) + panic("Attempt to refile free buffer\n"); if (buf->b_dirt) dispose = BUF_DIRTY; else if (mem_map[MAP_NR((unsigned long) buf->b_data)] > 1) @@ -794,9 +804,10 @@ void brelse(struct buffer_head * buf) if (buf->b_reuse) { buf->b_reuse = 0; if (!buf->b_lock && !buf->b_dirt && !buf->b_wait) { - if(buf->b_dev == 0xffff) panic("brelse: Wrong list"); + if(buf->b_dev == B_FREE) + panic("brelse: Wrong list"); remove_from_queues(buf); - buf->b_dev = 0xffff; + buf->b_dev = B_FREE; put_last_free(buf); } } @@ -810,13 +821,13 @@ void brelse(struct buffer_head * buf) * bread() reads a specified block and returns the buffer that contains * it. It returns NULL if the block was unreadable. */ -struct buffer_head * bread(dev_t dev, int block, int size) +struct buffer_head * bread(kdev_t dev, int block, int size) { struct buffer_head * bh; if (!(bh = getblk(dev, block, size))) { - printk("VFS: bread: READ error on device %d/%d\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: bread: READ error on device %s\n", + kdevname(dev)); return NULL; } if (bh->b_uptodate) @@ -837,7 +848,7 @@ struct buffer_head * bread(dev_t dev, int block, int size) #define NBUF 16 -struct buffer_head * breada(dev_t dev, int block, int bufsize, +struct buffer_head * breada(kdev_t dev, int block, int bufsize, unsigned int pos, unsigned int filesize) { struct buffer_head * bhlist[NBUF]; @@ -958,7 +969,7 @@ static struct buffer_head * create_buffers(unsigned long page, unsigned long siz head = bh; bh->b_data = (char *) (page+offset); bh->b_size = size; - bh->b_dev = 0xffff; /* Flag as unused */ + bh->b_dev = B_FREE; /* Flag as unused */ } return head; /* @@ -1010,7 +1021,7 @@ static unsigned long try_to_align(struct buffer_head ** bh, int nrbuf, } static unsigned long check_aligned(struct buffer_head * first, unsigned long address, - dev_t dev, int *b, int size) + kdev_t dev, int *b, int size) { struct buffer_head * bh[MAX_BUF_PER_PAGE]; unsigned long page; @@ -1051,7 +1062,7 @@ no_go: } static unsigned long try_to_load_aligned(unsigned long address, - dev_t dev, int b[], int size) + kdev_t dev, int b[], int size) { struct buffer_head * bh, * tmp, * arr[MAX_BUF_PER_PAGE]; unsigned long offset; @@ -1122,7 +1133,7 @@ not_aligned: * demand-loadable executables). */ static inline unsigned long try_to_share_buffers(unsigned long address, - dev_t dev, int *b, int size) + kdev_t dev, int *b, int size) { struct buffer_head * bh; int block; @@ -1143,7 +1154,7 @@ static inline unsigned long try_to_share_buffers(unsigned long address, * etc. This also allows us to optimize memory usage by sharing code pages * and filesystem buffers.. */ -unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int no_share) +unsigned long bread_page(unsigned long address, kdev_t dev, int b[], int size, int no_share) { struct buffer_head * bh[MAX_BUF_PER_PAGE]; unsigned long where; @@ -1178,7 +1189,7 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in * bwrite_page writes a page out to the buffer cache and/or the physical device. * It's used for mmap writes (the same way bread_page() is used for mmap reads). */ -void bwrite_page(unsigned long address, dev_t dev, int b[], int size) +void bwrite_page(unsigned long address, kdev_t dev, int b[], int size) { struct buffer_head * bh[MAX_BUF_PER_PAGE]; int i, j; @@ -1486,7 +1497,7 @@ void show_buffers(void) * are unused, and reassign to a new cluster them if this is true. */ static inline int try_to_reassign(struct buffer_head * bh, struct buffer_head ** bhp, - dev_t dev, unsigned int starting_block) + kdev_t dev, unsigned int starting_block) { unsigned long page; struct buffer_head * tmp, * p; @@ -1515,10 +1526,10 @@ static inline int try_to_reassign(struct buffer_head * bh, struct buffer_head ** p = tmp; tmp = tmp->b_this_page; remove_from_queues(p); - p->b_dev=dev; + p->b_dev = dev; p->b_uptodate = 0; p->b_req = 0; - p->b_blocknr=starting_block++; + p->b_blocknr = starting_block++; insert_into_queues(p); } while (tmp != bh); return 1; @@ -1538,7 +1549,7 @@ static inline int try_to_reassign(struct buffer_head * bh, struct buffer_head ** * be expiring data prematurely. For now we only cannibalize buffers * of the same size to keep the code simpler. */ -static int reassign_cluster(dev_t dev, +static int reassign_cluster(kdev_t dev, unsigned int starting_block, int size) { struct buffer_head *bh; @@ -1565,7 +1576,7 @@ static int reassign_cluster(dev_t dev, * from a new page in memory. We should only do this if we have * not expanded the buffer cache to the maximum size that we allow. */ -static unsigned long try_to_generate_cluster(dev_t dev, int block, int size) +static unsigned long try_to_generate_cluster(kdev_t dev, int block, int size) { struct buffer_head * bh, * tmp, * arr[MAX_BUF_PER_PAGE]; int isize = BUFSIZE_INDEX(size); @@ -1622,7 +1633,7 @@ not_aligned: return 0; } -unsigned long generate_cluster(dev_t dev, int b[], int size) +unsigned long generate_cluster(kdev_t dev, int b[], int size) { int i, offset; diff --git a/fs/dcache.c b/fs/dcache.c index 0b37923f91bc..3a232088a0dd 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -41,7 +41,7 @@ struct hash_list { */ struct dir_cache_entry { struct hash_list h; - unsigned long dev; + kdev_t dc_dev; unsigned long dir; unsigned long version; unsigned long ino; @@ -52,8 +52,8 @@ struct dir_cache_entry { }; #define COPYDATA(de, newde) \ -memcpy((void *) &newde->dev, (void *) &de->dev, \ -4*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN) +memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, \ +sizeof(kdev_t) + 3*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN) static struct dir_cache_entry level1_cache[DCACHE_SIZE]; static struct dir_cache_entry level2_cache[DCACHE_SIZE]; @@ -70,7 +70,7 @@ static struct dir_cache_entry * level2_head; * itself on the doubly-linked list, not just a pointer to the first entry. */ #define DCACHE_HASH_QUEUES 19 -#define hash_fn(dev,dir,namehash) (((dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES) +#define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES) static struct hash_list hash_table[DCACHE_HASH_QUEUES]; @@ -135,7 +135,7 @@ static struct dir_cache_entry * find_entry(struct inode * dir, const char * name struct dir_cache_entry * de = hash->next; for (de = hash->next ; de != (struct dir_cache_entry *) hash ; de = de->h.next) { - if (de->dev != dir->i_dev) + if (de->dc_dev != dir->i_dev) continue; if (de->dir != dir->i_ino) continue; @@ -201,7 +201,7 @@ void dcache_add(struct inode * dir, const char * name, int len, unsigned long in de = level1_head; level1_head = de->next_lru; remove_hash(de); - de->dev = dir->i_dev; + de->dc_dev = dir->i_dev; de->dir = dir->i_ino; de->version = dir->i_version; de->ino = ino; diff --git a/fs/devices.c b/fs/devices.c index b07253ad3541..1172526e1aa2 100644 --- a/fs/devices.c +++ b/fs/devices.c @@ -139,7 +139,7 @@ int unregister_blkdev(unsigned int major, const char * name) * People changing diskettes in the middle of an operation deserve * to loose :-) */ -int check_disk_change(dev_t dev) +int check_disk_change(kdev_t dev) { int i; struct file_operations * fops; @@ -152,8 +152,8 @@ int check_disk_change(dev_t dev) if (!fops->check_media_change(dev)) return 0; - printk(KERN_DEBUG "VFS: Disk change detected on device %d/%d\n", - MAJOR(dev), MINOR(dev)); + printk(KERN_DEBUG "VFS: Disk change detected on device %s\n", + kdevname(dev)); for (i=0 ; irec_len < de->name_len + 8 || (de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) { printk ("ext_readdir: bad dir entry, skipping\n"); - printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n", - inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len); + printk ("dev=%s, dir=%ld, " + "offset=%ld, rec_len=%d, name_len=%d\n", + kdevname(inode->i_dev), inode->i_ino, + offset, de->rec_len, de->name_len); filp->f_pos += 1024-offset; if (filp->f_pos > inode->i_size) filp->f_pos = inode->i_size; diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c index 29c4c4289fd5..6b2ca164c359 100644 --- a/fs/ext/freelists.c +++ b/fs/ext/freelists.c @@ -179,7 +179,7 @@ void ext_free_inode(struct inode * inode) struct super_block * sb; unsigned long block; unsigned long ino; - dev_t dev; + kdev_t dev; if (!inode) return; diff --git a/fs/ext/inode.c b/fs/ext/inode.c index 34c57efc09b3..2c107b2b46bc 100644 --- a/fs/ext/inode.c +++ b/fs/ext/inode.c @@ -68,13 +68,14 @@ struct super_block *ext_read_super(struct super_block *s,void *data, { struct buffer_head *bh; struct ext_super_block *es; - int dev = s->s_dev,block; + kdev_t dev = s->s_dev; + int block; MOD_INC_USE_COUNT; lock_super(s); set_blocksize(dev, BLOCK_SIZE); if (!(bh = bread(dev, 1, BLOCK_SIZE))) { - s->s_dev=0; + s->s_dev = 0; unlock_super(s); printk("EXT-fs: unable to read superblock\n"); MOD_DEC_USE_COUNT; @@ -98,8 +99,8 @@ struct super_block *ext_read_super(struct super_block *s,void *data, s->s_dev = 0; unlock_super(s); if (!silent) - printk("VFS: Can't find an extfs filesystem on dev 0x%04x.\n", - dev); + printk("VFS: Can't find an extfs filesystem on dev " + "%s.\n", kdevname(dev)); MOD_DEC_USE_COUNT; return NULL; } @@ -132,7 +133,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data, s->s_dev = dev; s->s_op = &ext_sops; if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) { - s->s_dev=0; + s->s_dev = 0; printk("EXT-fs: get root inode failed\n"); MOD_DEC_USE_COUNT; return NULL; @@ -380,7 +381,7 @@ void ext_read_inode(struct inode * inode) inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; inode->i_blocks = inode->i_blksize = 0; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = raw_inode->i_zone[0]; + inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]); else for (block = 0; block < 12; block++) inode->u.ext_i.i_data[block] = raw_inode->i_zone[block]; brelse(bh); @@ -417,7 +418,7 @@ static struct buffer_head * ext_update_inode(struct inode * inode) raw_inode->i_size = inode->i_size; raw_inode->i_time = inode->i_mtime; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = inode->i_rdev; + raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); else for (block = 0; block < 12; block++) raw_inode->i_zone[block] = inode->u.ext_i.i_data[block]; mark_buffer_dirty(bh, 1); @@ -444,8 +445,9 @@ int ext_sync_inode (struct inode *inode) wait_on_buffer(bh); if (bh->b_req && !bh->b_uptodate) { - printk ("IO error syncing ext inode [%04x:%08lx]\n", - inode->i_dev, inode->i_ino); + printk ("IO error syncing ext inode [" + "%s:%08lx]\n", + kdevname(inode->i_dev), inode->i_ino); err = -1; } } diff --git a/fs/ext/namei.c b/fs/ext/namei.c index f9e4b8499436..ca757987de30 100644 --- a/fs/ext/namei.c +++ b/fs/ext/namei.c @@ -118,8 +118,10 @@ static struct buffer_head * ext_find_entry(struct inode * dir, de->rec_len < de->name_len + 8 || (((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) { printk ("ext_find_entry: bad dir entry\n"); - printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n", - dir->i_dev, dir->i_ino, offset, de->rec_len, de->name_len); + printk ("dev=%s, dir=%ld, offset=%ld, " + "rec_len=%d, name_len=%d\n", + kdevname(dir->i_dev), dir->i_ino, offset, + de->rec_len, de->name_len); de = (struct ext_dir_entry *) (bh->b_data+BLOCK_SIZE); offset = ((offset / BLOCK_SIZE) + 1) * BLOCK_SIZE; continue; @@ -266,8 +268,10 @@ printk ("ext_add_entry : creating next block\n"); de->rec_len < de->name_len + 8 || (((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) { printk ("ext_addr_entry: bad dir entry\n"); - printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n", - dir->i_dev, dir->i_ino, offset, de->rec_len, de->name_len); + printk ("dev=%s, dir=%ld, offset=%ld, " + "rec_len=%d, name_len=%d\n", + kdevname(dir->i_dev), dir->i_ino, offset, + de->rec_len, de->name_len); brelse (bh); return NULL; } @@ -372,7 +376,7 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; + inode->i_rdev = to_kdev_t(rdev); #if 0 inode->i_mtime = inode->i_atime = CURRENT_TIME; #endif @@ -471,14 +475,16 @@ static int empty_dir(struct inode * inode) struct ext_dir_entry * de, * de1; if (inode->i_size < 2 * 12 || !(bh = ext_bread(inode,0,0))) { - printk("warning - bad directory on dev %04x\n",inode->i_dev); + printk("warning - bad directory on dev %s\n", + kdevname(inode->i_dev)); return 1; } de = (struct ext_dir_entry *) bh->b_data; de1 = (struct ext_dir_entry *) ((char *) de + de->rec_len); if (de->inode != inode->i_ino || !de1->inode || strcmp(".",de->name) || strcmp("..",de1->name)) { - printk("warning - bad directory on dev %04x\n",inode->i_dev); + printk("warning - bad directory on dev %s\n", + kdevname(inode->i_dev)); return 1; } offset = de->rec_len + de1->rec_len; @@ -496,8 +502,10 @@ static int empty_dir(struct inode * inode) if (de->rec_len < 8 || de->rec_len %4 != 0 || de->rec_len < de->name_len + 8) { printk ("empty_dir: bad dir entry\n"); - printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n", - inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len); + printk ("dev=%s, dir=%ld, offset=%ld, " + "rec_len=%d, name_len=%d\n", + kdevname(inode->i_dev), inode->i_ino, + offset, de->rec_len, de->name_len); brelse (bh); return 1; } @@ -597,8 +605,9 @@ int ext_unlink(struct inode * dir, const char * name, int len) if (S_ISDIR(inode->i_mode)) goto end_unlink; if (!inode->i_nlink) { - printk("Deleting nonexistent file (%04x:%ld), %d\n", - inode->i_dev,inode->i_ino,inode->i_nlink); + printk("Deleting nonexistent file (%s:%ld), %d\n", + kdevname(inode->i_dev), inode->i_ino, + inode->i_nlink); inode->i_nlink=1; } de->inode = 0; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 59cc319cc33c..f50282ff64ce 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -552,7 +552,7 @@ void ext2_read_inode (struct inode * inode) ext2_error (inode->i_sb, "ext2_read_inode", "New inode has non-zero prealloc count!"); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = raw_inode->i_block[0]; + inode->i_rdev = to_kdev_t(raw_inode->i_block[0]); else for (block = 0; block < EXT2_N_BLOCKS; block++) inode->u.ext2_i.i_data[block] = raw_inode->i_block[block]; brelse (bh); @@ -634,7 +634,7 @@ static struct buffer_head * ext2_update_inode (struct inode * inode) raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl; raw_inode->i_version = inode->u.ext2_i.i_version; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_block[0] = inode->i_rdev; + raw_inode->i_block[0] = kdev_t_to_nr(inode->i_rdev); else for (block = 0; block < EXT2_N_BLOCKS; block++) raw_inode->i_block[block] = inode->u.ext2_i.i_data[block]; mark_buffer_dirty(bh, 1); @@ -661,8 +661,9 @@ int ext2_sync_inode (struct inode *inode) wait_on_buffer (bh); if (bh->b_req && !bh->b_uptodate) { - printk ("IO error syncing ext2 inode [%04x:%08lx]\n", - inode->i_dev, inode->i_ino); + printk ("IO error syncing ext2 inode [" + "%s:%08lx]\n", + kdevname(inode->i_dev), inode->i_ino); err = -1; } } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 0b36a6a35ed5..086f7c63222b 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -445,7 +445,7 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode, else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; + inode->i_rdev = to_kdev_t(rdev); inode->i_dirt = 1; bh = ext2_add_entry (dir, name, len, &de, &err); if (!bh) { diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 9feaa8f03c5d..e2c68e65571e 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -55,10 +55,10 @@ void ext2_error (struct super_block * sb, const char * function, if (test_opt (sb, ERRORS_PANIC) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_PANIC && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO))) - panic ("EXT2-fs panic (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); - printk (KERN_CRIT "EXT2-fs error (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); + panic ("EXT2-fs panic (device %s): %s: %s\n", + kdevname(sb->s_dev), function, error_buf); + printk (KERN_CRIT "EXT2-fs error (device %s): %s: %s\n", + kdevname(sb->s_dev), function, error_buf); if (test_opt (sb, ERRORS_RO) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_RO && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) { @@ -81,8 +81,8 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function, va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - panic ("EXT2-fs panic (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); + panic ("EXT2-fs panic (device %s): %s: %s\n", + kdevname(sb->s_dev), function, error_buf); } void ext2_warning (struct super_block * sb, const char * function, @@ -93,8 +93,8 @@ void ext2_warning (struct super_block * sb, const char * function, va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - printk (KERN_WARNING "EXT2-fs warning (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); + printk (KERN_WARNING "EXT2-fs warning (device %s): %s: %s\n", + kdevname(sb->s_dev), function, error_buf); } void ext2_put_super (struct super_block * sb) @@ -367,7 +367,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, unsigned short resuid = EXT2_DEF_RESUID; unsigned short resgid = EXT2_DEF_RESGID; unsigned long logic_sb_block = 1; - int dev = sb->s_dev; + kdev_t dev = sb->s_dev; int db_count; int i, j; @@ -400,8 +400,8 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, unlock_super (sb); brelse (bh); if (!silent) - printk ("VFS: Can't find an ext2 filesystem on dev %d/%d.\n", - MAJOR(dev), MINOR(dev)); + printk ("VFS: Can't find an ext2 filesystem on dev " + "%s.\n", kdevname(dev)); return NULL; } sb->s_blocksize_bits = sb->u.ext2_sb.s_es->s_log_block_size + 10; @@ -470,9 +470,9 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, unlock_super (sb); brelse (bh); if (!silent) - printk ("VFS: Can't find an ext2 filesystem on dev %d/%d.\n", - MAJOR(dev), MINOR(dev)); - + printk ("VFS: Can't find an ext2 filesystem on dev " + "%s.\n", + kdevname(dev)); MOD_DEC_USE_COUNT; return NULL; } @@ -481,8 +481,8 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, unlock_super (sb); brelse (bh); if (!silent) - printk ("VFS: Unsupported blocksize on dev 0x%04x.\n", - dev); + printk ("VFS: Unsupported blocksize on dev " + "%s.\n", kdevname(dev)); MOD_DEC_USE_COUNT; return NULL; } diff --git a/fs/hpfs/hpfs_fs.c b/fs/hpfs/hpfs_fs.c index ad30f9b5d09d..5eab178b542e 100644 --- a/fs/hpfs/hpfs_fs.c +++ b/fs/hpfs/hpfs_fs.c @@ -245,7 +245,7 @@ static int zerop(void *addr, unsigned len); static void count_dnodes(struct inode *inode, dnode_secno dno, unsigned *n_dnodes, unsigned *n_subdirs); static unsigned count_bitmap(struct super_block *s); -static unsigned count_one_bitmap(dev_t dev, secno secno); +static unsigned count_one_bitmap(kdev_t dev, secno secno); static secno bplus_lookup(struct inode *inode, struct bplus_header *b, secno file_secno, struct buffer_head **bhp); static struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, @@ -254,21 +254,21 @@ static struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, static struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, struct quad_buffer_head *qbh); static dnode_secno dir_subdno(struct inode *inode, unsigned pos); -static struct hpfs_dirent *map_nth_dirent(dev_t dev, dnode_secno dno, +static struct hpfs_dirent *map_nth_dirent(kdev_t dev, dnode_secno dno, int n, struct quad_buffer_head *qbh); static unsigned choose_conv(unsigned char *p, unsigned len); static unsigned convcpy_tofs(unsigned char *out, unsigned char *in, unsigned len); -static dnode_secno fnode_dno(dev_t dev, ino_t ino); -static struct fnode *map_fnode(dev_t dev, ino_t ino, +static dnode_secno fnode_dno(kdev_t dev, ino_t ino); +static struct fnode *map_fnode(kdev_t dev, ino_t ino, struct buffer_head **bhp); -static struct anode *map_anode(dev_t dev, unsigned secno, +static struct anode *map_anode(kdev_t dev, unsigned secno, struct buffer_head **bhp); -static struct dnode *map_dnode(dev_t dev, unsigned secno, +static struct dnode *map_dnode(kdev_t dev, unsigned secno, struct quad_buffer_head *qbh); -static void *map_sector(dev_t dev, unsigned secno, struct buffer_head **bhp); -static void *map_4sectors(dev_t dev, unsigned secno, +static void *map_sector(kdev_t dev, unsigned secno, struct buffer_head **bhp); +static void *map_4sectors(kdev_t dev, unsigned secno, struct quad_buffer_head *qbh); static void brelse4(struct quad_buffer_head *qbh); @@ -343,7 +343,7 @@ struct super_block *hpfs_read_super(struct super_block *s, struct buffer_head *bh0, *bh1, *bh2; struct quad_buffer_head qbh; dnode_secno root_dno; - dev_t dev; + kdev_t dev; uid_t uid; gid_t gid; umode_t umask; @@ -850,7 +850,7 @@ static unsigned count_bitmap(struct super_block *s) * Read in one bit map, count the bits, return the count. */ -static unsigned count_one_bitmap(dev_t dev, secno secno) +static unsigned count_one_bitmap(kdev_t dev, secno secno) { struct quad_buffer_head qbh; char *bits; @@ -1554,7 +1554,7 @@ static dnode_secno dir_subdno(struct inode *inode, unsigned pos) * Return the dir entry at index n in dnode dno, or 0 if there isn't one */ -static struct hpfs_dirent *map_nth_dirent(dev_t dev, dnode_secno dno, +static struct hpfs_dirent *map_nth_dirent(kdev_t dev, dnode_secno dno, int n, struct quad_buffer_head *qbh) { @@ -1584,7 +1584,7 @@ static int hpfs_dir_read(struct inode *inode, struct file *filp, /* Return the dnode pointer in a directory fnode */ -static dnode_secno fnode_dno(dev_t dev, ino_t ino) +static dnode_secno fnode_dno(kdev_t dev, ino_t ino) { struct buffer_head *bh; struct fnode *fnode; @@ -1601,7 +1601,7 @@ static dnode_secno fnode_dno(dev_t dev, ino_t ino) /* Map an fnode into a buffer and return pointers to it and to the buffer. */ -static struct fnode *map_fnode(dev_t dev, ino_t ino, struct buffer_head **bhp) +static struct fnode *map_fnode(kdev_t dev, ino_t ino, struct buffer_head **bhp) { struct fnode *fnode; @@ -1622,7 +1622,7 @@ static struct fnode *map_fnode(dev_t dev, ino_t ino, struct buffer_head **bhp) /* Map an anode into a buffer and return pointers to it and to the buffer. */ -static struct anode *map_anode(dev_t dev, unsigned secno, +static struct anode *map_anode(kdev_t dev, unsigned secno, struct buffer_head **bhp) { struct anode *anode; @@ -1644,7 +1644,7 @@ static struct anode *map_anode(dev_t dev, unsigned secno, /* Map a dnode into a buffer and return pointers to it and to the buffer. */ -static struct dnode *map_dnode(dev_t dev, unsigned secno, +static struct dnode *map_dnode(kdev_t dev, unsigned secno, struct quad_buffer_head *qbh) { struct dnode *dnode; @@ -1666,7 +1666,7 @@ static struct dnode *map_dnode(dev_t dev, unsigned secno, /* Map a sector into a buffer and return pointers to it and to the buffer. */ -static void *map_sector(dev_t dev, unsigned secno, struct buffer_head **bhp) +static void *map_sector(kdev_t dev, unsigned secno, struct buffer_head **bhp) { struct buffer_head *bh; @@ -1680,7 +1680,7 @@ static void *map_sector(dev_t dev, unsigned secno, struct buffer_head **bhp) /* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */ -static void *map_4sectors(dev_t dev, unsigned secno, +static void *map_4sectors(kdev_t dev, unsigned secno, struct quad_buffer_head *qbh) { struct buffer_head *bh; diff --git a/fs/inode.c b/fs/inode.c index f32714aca5a9..6992b68d207a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -21,12 +21,12 @@ static struct inode * first_inode; static struct wait_queue * inode_wait = NULL; static int nr_inodes = 0, nr_free_inodes = 0; -static inline int const hashfn(dev_t dev, unsigned int i) +static inline int const hashfn(kdev_t dev, unsigned int i) { - return (dev ^ i) % NR_IHASH; + return (HASHDEV(dev) ^ i) % NR_IHASH; } -static inline struct inode_hash_entry * const hash(dev_t dev, int i) +static inline struct inode_hash_entry * const hash(kdev_t dev, int i) { return hash_table + hashfn(dev, i); } @@ -159,7 +159,7 @@ void clear_inode(struct inode * inode) insert_inode_free(inode); } -int fs_may_mount(dev_t dev) +int fs_may_mount(kdev_t dev) { struct inode * inode, * next; int i; @@ -177,7 +177,7 @@ int fs_may_mount(dev_t dev) return 1; } -int fs_may_umount(dev_t dev, struct inode * mount_root) +int fs_may_umount(kdev_t dev, struct inode * mount_root) { struct inode * inode; int i; @@ -193,7 +193,7 @@ int fs_may_umount(dev_t dev, struct inode * mount_root) return 1; } -int fs_may_remount_ro(dev_t dev) +int fs_may_remount_ro(kdev_t dev) { struct file * file; int i; @@ -336,7 +336,7 @@ int bmap(struct inode * inode, int block) return 0; } -void invalidate_inodes(dev_t dev) +void invalidate_inodes(kdev_t dev) { struct inode * inode, * next; int i; @@ -348,14 +348,15 @@ void invalidate_inodes(dev_t dev) if (inode->i_dev != dev) continue; if (inode->i_count || inode->i_dirt || inode->i_lock) { - printk("VFS: inode busy on removed device %d/%d\n", MAJOR(dev), MINOR(dev)); + printk("VFS: inode busy on removed device %s\n", + kdevname(dev)); continue; } clear_inode(inode); } } -void sync_inodes(dev_t dev) +void sync_inodes(kdev_t dev) { int i; struct inode * inode; @@ -377,9 +378,8 @@ void iput(struct inode * inode) wait_on_inode(inode); if (!inode->i_count) { printk("VFS: iput: trying to free free inode\n"); - printk("VFS: device %d/%d, inode %lu, mode=0%07o\n", - MAJOR(inode->i_rdev), MINOR(inode->i_rdev), - inode->i_ino, inode->i_mode); + printk("VFS: device %s, inode %lu, mode=0%07o\n", + kdevname(inode->i_rdev), inode->i_ino, inode->i_mode); return; } if (inode->i_pipe) @@ -407,8 +407,8 @@ repeat: } inode->i_count--; if (inode->i_mmap) { - printk("iput: inode %lu on device %d/%d still has mappings.\n", - inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev)); + printk("iput: inode %lu on device %s still has mappings.\n", + inode->i_ino, kdevname(inode->i_dev)); inode->i_mmap = NULL; } nr_free_inodes++; @@ -463,7 +463,7 @@ repeat: inode->i_version = ++event; inode->i_sem.count = 1; inode->i_ino = ++ino; - inode->i_dev = -1; + inode->i_dev = 0; nr_free_inodes--; if (nr_free_inodes < 0) { printk ("VFS: get_empty_inode: bad free inode count.\n"); diff --git a/fs/ioctl.c b/fs/ioctl.c index 8931cd60c29b..aabab2e38458 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -50,7 +50,7 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) return 0; } if (filp->f_op && filp->f_op->ioctl) - return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); + return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg); return -EINVAL; } @@ -72,7 +72,7 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) return 0; case FIONBIO: - on = get_fs_long((unsigned long *) arg); + on = get_user((unsigned int *) arg); if (on) filp->f_flags |= O_NONBLOCK; else @@ -81,7 +81,7 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) case FIOASYNC: /* O_SYNC is not yet implemented, but it's here for completeness. */ - on = get_fs_long ((unsigned long *) arg); + on = get_user ((unsigned int *) arg); if (on) filp->f_flags |= O_SYNC; else @@ -90,10 +90,10 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) default: if (filp->f_inode && S_ISREG(filp->f_inode->i_mode)) - return file_ioctl(filp,cmd,arg); + return file_ioctl(filp, cmd, arg); if (filp->f_op && filp->f_op->ioctl) - return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); + return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg); return -EINVAL; } diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index cc00e341d2a0..d48248bdc559 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -156,7 +156,7 @@ static int parse_options(char *options, struct iso9660_options * popt) /* * look if the driver can tell the multi session redirection value */ -static unsigned int isofs_get_last_session(int dev) +static unsigned int isofs_get_last_session(kdev_t dev) { struct cdrom_multisession ms_info; unsigned int vol_desc_start; @@ -195,7 +195,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, int iso_blknum; unsigned int blocksize_bits; int high_sierra; - int dev=s->s_dev; + kdev_t dev = s->s_dev; unsigned int vol_desc_start; struct iso_volume_descriptor *vdp; @@ -248,9 +248,10 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, printk("isofs.inode: iso_blknum=%d\n", iso_blknum); #endif 0 if (!(bh = bread(dev, iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits), opt.blocksize))) { - s->s_dev=0; - printk("isofs_read_super: bread failed, dev 0x%x iso_blknum %d\n", - dev, iso_blknum); + s->s_dev = 0; + printk("isofs_read_super: bread failed, dev " + "%s iso_blknum %d\n", + kdevname(dev), iso_blknum); unlock_super(s); MOD_DEC_USE_COUNT; return NULL; @@ -374,7 +375,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, unlock_super(s); if (!(s->s_mounted)) { - s->s_dev=0; + s->s_dev = 0; printk("get root inode failed\n"); MOD_DEC_USE_COUNT; return NULL; diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index b902d8f24303..dd2e8ec25364 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -306,14 +306,14 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, high = isonum_733(rr->u.PN.dev_high); low = isonum_733(rr->u.PN.dev_low); /* - * The Rock Ridge standard specifies that if sizeof(dev_t) <=4, + * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, * then the high field is unused, and the device number is completely * stored in the low field. Some writers may ignore this subtlety, * and as a result we test to see if the entire device number is * stored in the low field, and use that. */ - if(MINOR(low) != low && high == 0) { - inode->i_rdev = low; + if((low & ~0xff) && high == 0) { + inode->i_rdev = MKDEV(low >> 8, low & 0xff); } else { inode->i_rdev = MKDEV(high, low); } diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index ac97cb84e0bb..d557f06e7cc9 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -74,7 +74,8 @@ void minix_free_block(struct super_block * sb, int block) return; } if (!clear_bit(bit,bh->b_data)) - printk("free_block (%04x:%d): bit already cleared\n",sb->s_dev,block); + printk("free_block (%s:%d): bit already cleared\n", + kdevname(sb->s_dev), block); mark_buffer_dirty(bh, 1); return; } diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1a19c573e2b5..b99e714b30bb 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -126,7 +126,8 @@ struct super_block *minix_read_super(struct super_block *s,void *data, { struct buffer_head *bh; struct minix_super_block *ms; - int i,dev=s->s_dev,block; + int i, block; + kdev_t dev = s->s_dev; if (32 != sizeof (struct minix_inode)) panic("bad i-node size"); @@ -134,7 +135,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data, lock_super(s); set_blocksize(dev, BLOCK_SIZE); if (!(bh = bread(dev,1,BLOCK_SIZE))) { - s->s_dev=0; + s->s_dev = 0; unlock_super(s); printk("MINIX-fs: unable to read superblock\n"); MOD_DEC_USE_COUNT; @@ -165,7 +166,8 @@ struct super_block *minix_read_super(struct super_block *s,void *data, unlock_super(s); brelse(bh); if (!silent) - printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n", dev); + printk("VFS: Can't find a minix filesystem on dev " + "%s.\n", kdevname(dev)); MOD_DEC_USE_COUNT; return NULL; } @@ -189,7 +191,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data, brelse(s->u.minix_sb.s_imap[i]); for(i=0;iu.minix_sb.s_zmap[i]); - s->s_dev=0; + s->s_dev = 0; unlock_super(s); brelse(bh); printk("MINIX-fs: bad superblock or unable to read bitmaps\n"); @@ -416,16 +418,17 @@ void minix_read_inode(struct inode * inode) inode->i_op = NULL; inode->i_mode = 0; if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { - printk("Bad inode number on dev 0x%04x: %d is out of range\n", - inode->i_dev, ino); + printk("Bad inode number on dev %s" + ": %d is out of range\n", + kdevname(inode->i_dev), ino); return; } block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks + (ino-1)/MINIX_INODES_PER_BLOCK; if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) { - printk("Major problem: unable to read inode from dev 0x%04x\n", - inode->i_dev); + printk("Major problem: unable to read inode from dev " + "%s\n", kdevname(inode->i_dev)); return; } raw_inode = ((struct minix_inode *) bh->b_data) + @@ -438,7 +441,7 @@ void minix_read_inode(struct inode * inode) inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; inode->i_blocks = inode->i_blksize = 0; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = raw_inode->i_zone[0]; + inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]); else for (block = 0; block < 9; block++) inode->u.minix_i.i_data[block] = raw_inode->i_zone[block]; brelse(bh); @@ -464,8 +467,9 @@ static struct buffer_head * minix_update_inode(struct inode * inode) ino = inode->i_ino; if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { - printk("Bad inode number on dev 0x%04x: %d is out of range\n", - inode->i_dev, ino); + printk("Bad inode number on dev %s" + ": %d is out of range\n", + kdevname(inode->i_dev), ino); inode->i_dirt = 0; return 0; } @@ -485,7 +489,7 @@ static struct buffer_head * minix_update_inode(struct inode * inode) raw_inode->i_size = inode->i_size; raw_inode->i_time = inode->i_mtime; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = inode->i_rdev; + raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); else for (block = 0; block < 9; block++) raw_inode->i_zone[block] = inode->u.minix_i.i_data[block]; inode->i_dirt=0; @@ -512,8 +516,9 @@ int minix_sync_inode(struct inode * inode) wait_on_buffer(bh); if (bh->b_req && !bh->b_uptodate) { - printk ("IO error syncing minix inode [%04x:%08lx]\n", - inode->i_dev, inode->i_ino); + printk ("IO error syncing minix inode [" + "%s:%08lx]\n", + kdevname(inode->i_dev), inode->i_ino); err = -1; } } diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 995008c92d63..f1bee443428a 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -286,7 +286,7 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; + inode->i_rdev = to_kdev_t(rdev); inode->i_dirt = 1; error = minix_add_entry(dir, name, len, &bh, &de); if (error) { @@ -426,7 +426,8 @@ static int empty_dir(struct inode * inode) return 1; bad_dir: brelse(bh); - printk("Bad directory on device %04x\n",inode->i_dev); + printk("Bad directory on device %s\n", + kdevname(inode->i_dev)); return 1; } @@ -521,8 +522,9 @@ repeat: goto end_unlink; } if (!inode->i_nlink) { - printk("Deleting nonexistent file (%04x:%lu), %d\n", - inode->i_dev,inode->i_ino,inode->i_nlink); + printk("Deleting nonexistent file (%s:%lu), %d\n", + kdevname(inode->i_dev), + inode->i_ino, inode->i_nlink); inode->i_nlink=1; } de->inode = 0; diff --git a/fs/msdos/fat.c b/fs/msdos/fat.c index 6059ec7bcfbe..6c2fcca941f5 100644 --- a/fs/msdos/fat.c +++ b/fs/msdos/fat.c @@ -125,13 +125,14 @@ void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu) struct fat_cache *walk; #ifdef DEBUG -printk("cache lookup: <%d,%d> %d (%d,%d) -> ",inode->i_dev,inode->i_ino,cluster, - *f_clu,*d_clu); +printk("cache lookup: <%s,%d> %d (%d,%d) -> ", kdevname(inode->i_dev), + inode->i_ino, cluster, *f_clu, *d_clu); #endif for (walk = fat_cache; walk; walk = walk->next) - if (inode->i_dev == walk->device && walk->ino == inode->i_ino && - walk->file_cluster <= cluster && walk->file_cluster > - *f_clu) { + if (inode->i_dev == walk->device + && walk->ino == inode->i_ino + && walk->file_cluster <= cluster + && walk->file_cluster > *f_clu) { *d_clu = walk->disk_cluster; #ifdef DEBUG printk("cache hit: %d (%d)\n",walk->file_cluster,*d_clu); @@ -151,8 +152,8 @@ static void list_cache(void) for (walk = fat_cache; walk; walk = walk->next) { if (walk->device) - printk("<%d,%d>(%d,%d) ",walk->device,walk->ino, - walk->file_cluster,walk->disk_cluster); + printk("<%s,%d>(%d,%d) ", kdevname(walk->device), + walk->ino, walk->file_cluster, walk->disk_cluster); else printk("-- "); } printk("\n"); @@ -165,12 +166,14 @@ void cache_add(struct inode *inode,int f_clu,int d_clu) struct fat_cache *walk,*last; #ifdef DEBUG -printk("cache add: <%d,%d> %d (%d)\n",inode->i_dev,inode->i_ino,f_clu,d_clu); +printk("cache add: <%s,%d> %d (%d)\n", kdevname(inode->i_dev), + inode->i_ino, f_clu, d_clu); #endif last = NULL; for (walk = fat_cache; walk->next; walk = (last = walk)->next) - if (inode->i_dev == walk->device && walk->ino == inode->i_ino && - walk->file_cluster == f_clu) { + if (inode->i_dev == walk->device + && walk->ino == inode->i_ino + && walk->file_cluster == f_clu) { if (walk->disk_cluster != d_clu) { printk("FAT cache corruption"); cache_inval_inode(inode); @@ -207,17 +210,19 @@ void cache_inval_inode(struct inode *inode) struct fat_cache *walk; for (walk = fat_cache; walk; walk = walk->next) - if (walk->device == inode->i_dev && walk->ino == inode->i_ino) + if (walk->device == inode->i_dev + && walk->ino == inode->i_ino) walk->device = 0; } -void cache_inval_dev(int device) +void cache_inval_dev(kdev_t device) { struct fat_cache *walk; for (walk = fat_cache; walk; walk = walk->next) - if (walk->device == device) walk->device = 0; + if (walk->device == device) + walk->device = 0; } diff --git a/fs/msdos/inode.c b/fs/msdos/inode.c index d878c4ad51a6..c8f32fb6910c 100644 --- a/fs/msdos/inode.c +++ b/fs/msdos/inode.c @@ -168,7 +168,7 @@ struct super_block *msdos_read_super(struct super_block *sb,void *data, { struct buffer_head *bh; struct msdos_boot_sector *b; - int data_sectors,logical_sector_size,sector_mult; + int data_sectors,logical_sector_size,sector_mult,fat_clusters=0; int debug,error,fat,quiet; char check,conversion; uid_t uid; @@ -246,11 +246,12 @@ struct super_block *msdos_read_super(struct super_block *sb,void *data, b->cluster_size/sector_mult : 0; MSDOS_SB(sb)->fat_bits = fat ? fat : MSDOS_SB(sb)->clusters > MSDOS_FAT12 ? 16 : 12; + fat_clusters = MSDOS_SB(sb)->fat_length*SECTOR_SIZE*8/ + MSDOS_SB(sb)->fat_bits; error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries & - (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > MSDOS_SB(sb)-> - fat_length*SECTOR_SIZE*8/MSDOS_SB(sb)->fat_bits || - (logical_sector_size & (SECTOR_SIZE-1)) || !b->secs_track || - !b->heads; + (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > fat_clusters+ + MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1)) + || !b->secs_track || !b->heads; } brelse(bh); /* @@ -276,10 +277,12 @@ struct super_block *msdos_read_super(struct super_block *sb,void *data, sectors),(unsigned long)b->total_sect,logical_sector_size); printk ("Transaction block size = %d\n",blksize); } + if (MSDOS_SB(sb)->clusters+2 > fat_clusters) + MSDOS_SB(sb)->clusters = fat_clusters-2; if (error) { if (!silent) - printk("VFS: Can't find a valid MSDOS filesystem on dev 0x%04x.\n", - sb->s_dev); + printk("VFS: Can't find a valid MSDOS filesystem on dev " + "%s.\n", kdevname(sb->s_dev)); sb->s_dev = 0; MOD_DEC_USE_COUNT; return NULL; @@ -382,7 +385,8 @@ void msdos_read_inode(struct inode *inode) } if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, SECTOR_SIZE))) { - printk("dev = 0x%04X, ino = %ld\n",inode->i_dev,inode->i_ino); + printk("dev = %s, ino = %ld\n", + kdevname(inode->i_dev), inode->i_ino); panic("msdos_read_inode: unable to read i-node block"); } raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) @@ -446,7 +450,8 @@ void msdos_write_inode(struct inode *inode) if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return; if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, SECTOR_SIZE))) { - printk("dev = 0x%04X, ino = %ld\n",inode->i_dev,inode->i_ino); + printk("dev = %s, ino = %ld\n", + kdevname(inode->i_dev), inode->i_ino); panic("msdos_write_inode: unable to read i-node block"); } raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) diff --git a/fs/msdos/misc.c b/fs/msdos/misc.c index 3e2c8238e96f..0fc2ea9e6cec 100644 --- a/fs/msdos/misc.c +++ b/fs/msdos/misc.c @@ -20,15 +20,16 @@ #define PRINTK(x) #define Printk(x) printk x -/* Well-known binary file extensions */ + +/* Well-known binary file extensions - of course there are many more */ static char bin_extensions[] = - "EXECOMBINAPPSYSDRVOVLOVROBJLIBDLLPIF" /* program code */ - "ARCZIPLHALZHZOOTARZ ARJ" /* common archivers */ - "TZ TAZTZPTPZ" /* abbreviations of tar.Z and tar.zip */ - "GZ TGZDEB" /* .gz, .tar.gz and Debian packages */ - "GIFBMPTIFGL JPGPCX" /* graphics */ - "TFMVF GF PK PXLDVI"; /* TeX */ + "EXE" "COM" "BIN" "APP" "SYS" "DRV" "OVL" "OVR" "OBJ" "LIB" "DLL" "PIF" /* program code */ + "ARC" "ZIP" "LHA" "LZH" "ZOO" "TAR" "Z " "ARJ" /* common archivers */ + "TZ " "TAZ" "TZP" "TPZ" /* abbreviations of tar.Z and tar.zip */ + "GZ " "TGZ" "DEB" /* .gz, .tar.gz and Debian packages */ + "GIF" "BMP" "TIF" "GL " "JPG" "PCX" /* graphics */ + "TFM" "VF " "GF " "PK " "PXL" "DVI"; /* TeX */ /* @@ -42,8 +43,9 @@ void fs_panic(struct super_block *s,const char *msg) not_ro = !(s->s_flags & MS_RDONLY); if (not_ro) s->s_flags |= MS_RDONLY; - printk("Filesystem panic (dev 0x%04X, mounted on 0x%04X:%ld)\n %s\n", - s->s_dev,s->s_covered->i_dev,s->s_covered->i_ino,msg); + printk("Filesystem panic (dev %s, ", kdevname(s->s_dev)); + printk("mounted on %s:%ld)\n %s\n", /* note: kdevname returns & static char[] */ + kdevname(s->s_covered->i_dev), s->s_covered->i_ino, msg); if (not_ro) printk(" File system has been set read-only\n"); } diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index bcad000df701..4b23f30ad873 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -368,7 +368,8 @@ int msdos_rmdir(struct inode *dir,const char *name,int len) res = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) goto rmdir_done; res = -EBUSY; - if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done; + if (dir->i_dev != inode->i_dev || dir == inode) + goto rmdir_done; res = msdos_empty(inode); if (res) goto rmdir_done; diff --git a/fs/namei.c b/fs/namei.c index 523d6df671bf..ed1139780d2b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -122,14 +122,14 @@ int permission(struct inode * inode,int mask) */ int get_write_access(struct inode * inode) { - struct task_struct ** p; + struct task_struct * p; if ((inode->i_count > 1) && S_ISREG(inode->i_mode)) /* shortcut */ - for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + for_each_task(p) { struct vm_area_struct * mpnt; - if (!*p) + if (!p->mm) continue; - for(mpnt = (*p)->mm->mmap; mpnt; mpnt = mpnt->vm_next) { + for(mpnt = p->mm->mmap; mpnt; mpnt = mpnt->vm_next) { if (inode != mpnt->vm_inode) continue; if (mpnt->vm_flags & VM_DENYWRITE) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index aaf1c4147107..591feff4b88b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -92,7 +92,7 @@ static struct nfs_entry *c_entry = NULL; static int nfs_readdir(struct inode *inode, struct file *filp, void *dirent, filldir_t filldir) { - static int c_dev = 0; + static kdev_t c_dev = 0; static int c_ino; static int c_size; @@ -215,7 +215,7 @@ void nfs_kfree_cache(void) */ static struct nfs_lookup_cache_entry { - int dev; + kdev_t dev; int inode; char filename[NFS_MAXNAMLEN + 1]; struct nfs_fh fhandle; @@ -231,7 +231,8 @@ static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir, for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) { entry = nfs_lookup_cache + i; - if (entry->dev == dir->i_dev && entry->inode == dir->i_ino + if (entry->dev == dir->i_dev + && entry->inode == dir->i_ino && !strncmp(filename, entry->filename, NFS_MAXNAMLEN)) return entry; } @@ -291,7 +292,7 @@ static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode, const char *filename) { struct nfs_lookup_cache_entry *entry; - int dev; + kdev_t dev; int fileid; int i; @@ -316,7 +317,7 @@ static void nfs_lookup_cache_refresh(struct inode *file, struct nfs_fattr *fattr) { struct nfs_lookup_cache_entry *entry; - int dev = file->i_dev; + kdev_t dev = file->i_dev; int fileid = file->i_ino; int i; @@ -621,7 +622,7 @@ void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) inode->i_size = fattr->size; inode->i_blksize = fattr->blocksize; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = fattr->rdev; + inode->i_rdev = to_kdev_t(fattr->rdev); else inode->i_rdev = 0; inode->i_blocks = fattr->blocks; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e62cdc5ad800..b043455bbe85 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -81,7 +81,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data, unsigned int fd; struct file *filp; - dev_t dev = sb->s_dev; + kdev_t dev = sb->s_dev; MOD_INC_USE_COUNT; if (!data) { diff --git a/fs/proc/array.c b/fs/proc/array.c index c9e90c4bda31..80bbb310ee5d 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -185,7 +185,7 @@ static int get_kstat(char * buffer) int i, len; unsigned sum = 0; - for (i = 0 ; i < 16 ; i++) + for (i = 0 ; i < NR_IRQS ; i++) sum += kstat.interrupts[i]; len = sprintf(buffer, "cpu %u %u %u %lu\n" @@ -206,7 +206,7 @@ static int get_kstat(char * buffer) kstat.pswpin, kstat.pswpout, sum); - for (i = 0 ; i < 16 ; i++) + for (i = 0 ; i < NR_IRQS ; i++) len += sprintf(buffer + len, " %u", kstat.interrupts[i]); len += sprintf(buffer + len, "\nctxt %u\n" @@ -446,7 +446,7 @@ static int get_stat(int pid, char * buffer) tsk->p_pptr->pid, tsk->pgrp, tsk->session, - tsk->tty ? tsk->tty->device : 0, + tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0, tty_pgrp, tsk->flags, tsk->min_flt, @@ -641,7 +641,7 @@ static int read_maps (int pid, struct file * file, char * buf, int count) char line[MAPS_LINE_MAX+1]; char str[5], *cp = str; int flags; - dev_t dev; + kdev_t dev; unsigned long ino; int len; diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 581cde4ccb96..429df5d88831 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -150,6 +150,8 @@ static int proc_readfd(struct inode * inode, struct file * filp, } for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) { + if (!p->files) + break; if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode) continue; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 0618a1384b9e..6871ca5d1526 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -162,35 +162,6 @@ void proc_read_inode(struct inode * inode) return; } - if (ino == PROC_SCSI_SCSI) { - inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; - inode->i_op = &proc_scsi_inode_operations; - return; - } - /* - * Special hook used when scsi is not present. - */ - if (ino == PROC_SCSI_NOT_PRESENT) { - inode->i_mode = S_IFREG | S_IRUGO | S_IXUGO; - inode->i_op = &proc_scsi_inode_operations; - return; - } - - /* files within /proc/scsi */ - if ((ino > PROC_SCSI_SCSI) && (ino < PROC_SCSI_FILE)) { - inode->i_nlink = 2; - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; - inode->i_op = &proc_scsi_inode_operations; - return; - } - - /* files within /proc/scsi// */ - if ((ino >= PROC_SCSI_FILE) && (ino <= PROC_SCSI_LAST)) { - inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; - inode->i_op = &proc_scsi_inode_operations; - return; - } - if (!pid) { switch (ino) { case PROC_KMSG: diff --git a/fs/proc/link.c b/fs/proc/link.c index ffd12b7aa0f6..599ac1da5277 100644 --- a/fs/proc/link.c +++ b/fs/proc/link.c @@ -128,13 +128,20 @@ static int proc_follow_link(struct inode * dir, struct inode * inode, new_inode = NULL; switch (ino) { case PROC_PID_CWD: + if (!p->fs) + break; new_inode = p->fs->pwd; break; case PROC_PID_ROOT: + if (!p->fs) + break; new_inode = p->fs->root; break; case PROC_PID_EXE: { - struct vm_area_struct * vma = p->mm->mmap; + struct vm_area_struct * vma; + if (!p->mm) + break; + vma = p->mm->mmap; while (vma) { if (vma->vm_flags & VM_EXECUTABLE) { new_inode = vma->vm_inode; @@ -147,6 +154,8 @@ static int proc_follow_link(struct inode * dir, struct inode * inode, default: switch (ino >> 8) { case PROC_PID_FD_DIR: + if (!p->files) + break; ino &= 0xff; if (ino < NR_OPEN && p->files->fd[ino]) { #ifdef PLAN9_SEMANTICS @@ -183,7 +192,7 @@ static int proc_readlink(struct inode * inode, char * buffer, int buflen) return i; if (!inode) return -EIO; - dev = inode->i_dev; + dev = kdev_t_to_nr(inode->i_dev); ino = inode->i_ino; iput(inode); i = sprintf(buf,"[%04x]:%u", dev, ino); diff --git a/fs/proc/root.c b/fs/proc/root.c index c879a918e966..283eaaef8188 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -129,8 +129,7 @@ struct proc_dir_entry proc_scsi = { S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, &proc_dir_inode_operations, NULL, NULL, - NULL, - &proc_root, NULL + NULL, &proc_root, NULL }; int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) @@ -249,7 +248,9 @@ void proc_root_init(void) 64, &proc_self_inode_operations, }); proc_register(&proc_root, &proc_net); + proc_register(&proc_root, &proc_scsi); + #ifdef CONFIG_DEBUG_MALLOC proc_register(&proc_root, &(struct proc_dir_entry) { PROC_MALLOC, 6, "malloc", diff --git a/fs/proc/scsi.c b/fs/proc/scsi.c index 8f3d0f529f7d..10d96cb037e3 100644 --- a/fs/proc/scsi.c +++ b/fs/proc/scsi.c @@ -15,9 +15,9 @@ * registered HBA as a single file. * 95/05/30 Added rudimentary write support for parameter passing * 95/07/04 Fixed bugs in directory handling + * 95/09/13 Update to support the new proc-dir tree * * TODO: Improve support to write to the driver files - * Optimize directory handling * Add some more comments */ #include @@ -34,10 +34,8 @@ static int proc_readscsi(struct inode * inode, struct file * file, char * buf, int count); static int proc_writescsi(struct inode * inode, struct file * file, const char * buf, int count); -static int proc_lookupscsi(struct inode *,const char *,int,struct inode **); static int proc_scsilseek(struct inode *, struct file *, off_t, int); -extern uint count_templates(void); extern void build_proc_dir_hba_entries(uint); /* the *_get_info() functions are in the respective scsi driver code */ @@ -48,7 +46,7 @@ static struct file_operations proc_scsi_operations = { proc_scsilseek, /* lseek */ proc_readscsi, /* read */ proc_writescsi, /* write */ - NULL, /* readdir */ + proc_readdir, /* readdir */ NULL, /* select */ NULL, /* ioctl */ NULL, /* mmap */ @@ -63,7 +61,7 @@ static struct file_operations proc_scsi_operations = { struct inode_operations proc_scsi_inode_operations = { &proc_scsi_operations, /* default scsi directory file-ops */ NULL, /* create */ - proc_lookupscsi,/* lookup */ + proc_lookup, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ @@ -78,94 +76,6 @@ struct inode_operations proc_scsi_inode_operations = { NULL /* permission */ }; -struct proc_dir_entry scsi_dir[PROC_SCSI_FILE - PROC_SCSI_SCSI + 3]; -struct proc_dir_entry scsi_hba_dir[(PROC_SCSI_LAST - PROC_SCSI_FILE) * 4]; - -static struct proc_dir_entry scsi_dir2[] = { - { PROC_SCSI, 1, "." }, - { PROC_ROOT_INO, 2, ".." }, - { PROC_SCSI_NOT_PRESENT, 11, "not.present" }, - { 0, 0, NULL } -}; - -inline static uint count_dir_entries(uint inode, uint *num) -{ - struct proc_dir_entry *dir; - uint index, flag; - - (uint) *num = flag = index = 0; - - if(dispatch_scsi_info_ptr) { - if (inode == PROC_SCSI) { - dir = scsi_dir; - while(dir[(uint)*num].low_ino) - (*num)++; - } else { - /* Here we do not simply count the entries. Since the array - * contains the directories of all drivers, we need to return - * a pointer to the beginning of the directory information - * and its length. - */ - dir = scsi_hba_dir; - while(dir[index].low_ino || dir[index].low_ino <= PROC_SCSI_LAST) { - if(dir[index].low_ino == inode) - flag = 1; - if(dir[index].low_ino == 0) { - if(flag == 1) - break; - else - *num = 0; - } else { - (*num)++; - } - index++; - } - return(index - (*num)); - } - } - else { - dir = scsi_dir2; - while(dir[(uint)*num].low_ino) - (*num)++; - } - return(0); -} - -static int proc_lookupscsi(struct inode * dir, const char * name, int len, - struct inode ** result) -{ - struct proc_dir_entry *de = NULL; - - *result = NULL; - if (!dir) - return(-ENOENT); - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return(-ENOENT); - } - if (dispatch_scsi_info_ptr != NULL) { - if (dir->i_ino <= PROC_SCSI_SCSI) - de = scsi_dir; - else { - de = &scsi_hba_dir[dispatch_scsi_info_ptr(dir->i_ino, 0, 0, 0, 0, 2)]; - } - } - else - de = scsi_dir2; - - for (; de->name ; de++) { - if (!proc_match(len, name, de)) - continue; - *result = proc_get_inode(dir->i_sb, de->low_ino, de); - iput(dir); - if (!*result) - return(-ENOENT); - return(0); - } - iput(dir); - return(-ENOENT); -} - int get_not_present_info(char *buffer, char **start, off_t offset, int length) { int len, pos, begin; @@ -255,20 +165,17 @@ static int proc_writescsi(struct inode * inode, struct file * file, int ret = 0; char * page; - if (!(page = (char *) __get_free_page(GFP_KERNEL))) - return(-ENOMEM); - if(count > PROC_BLOCK_SIZE) { return(-EOVERFLOW); } if(dispatch_scsi_info_ptr != NULL) { + if (!(page = (char *) __get_free_page(GFP_KERNEL))) + return(-ENOMEM); memcpy_fromfs(page, buf, count); ret = dispatch_scsi_info_ptr(inode->i_ino, page, 0, 0, count, 1); - } else { - free_page((ulong) page); + } else return(-ENOPKG); /* Nothing here */ - } free_page((ulong) page); return(ret); diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 2352f677c7e1..6ae4c8e3c009 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -184,7 +184,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) struct smb_sb_info *smb_sb; unsigned int fd; struct file *filp; - dev_t dev = sb->s_dev; + kdev_t dev = sb->s_dev; int error; if (!data) { diff --git a/fs/stat.c b/fs/stat.c index dfd44c1699c4..d163ea72078e 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -20,13 +20,13 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf) printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n", current->comm); - tmp.st_dev = inode->i_dev; + tmp.st_dev = kdev_t_to_nr(inode->i_dev); tmp.st_ino = inode->i_ino; tmp.st_mode = inode->i_mode; tmp.st_nlink = inode->i_nlink; tmp.st_uid = inode->i_uid; tmp.st_gid = inode->i_gid; - tmp.st_rdev = inode->i_rdev; + tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); tmp.st_size = inode->i_size; if (inode->i_pipe) tmp.st_size = PIPE_SIZE(*inode); @@ -42,13 +42,13 @@ static void cp_new_stat(struct inode * inode, struct new_stat * statbuf) unsigned int blocks, indirect; memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = inode->i_dev; + tmp.st_dev = kdev_t_to_nr(inode->i_dev); tmp.st_ino = inode->i_ino; tmp.st_mode = inode->i_mode; tmp.st_nlink = inode->i_nlink; tmp.st_uid = inode->i_uid; tmp.st_gid = inode->i_gid; - tmp.st_rdev = inode->i_rdev; + tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); tmp.st_size = inode->i_size; if (inode->i_pipe) tmp.st_size = PIPE_SIZE(*inode); diff --git a/fs/super.c b/fs/super.c index b04e3c3e46b8..e6ae81ec451d 100644 --- a/fs/super.c +++ b/fs/super.c @@ -35,7 +35,7 @@ struct super_block super_blocks[NR_SUPER]; static int do_remount_sb(struct super_block *sb, int flags, char * data); /* this is initialized in init/main.c */ -dev_t ROOT_DEV = 0; +kdev_t ROOT_DEV; static struct file_system_type * file_systems = NULL; @@ -197,7 +197,7 @@ repeat: current->state = TASK_RUNNING; } -void sync_supers(dev_t dev) +void sync_supers(kdev_t dev) { struct super_block * sb; @@ -216,7 +216,7 @@ void sync_supers(dev_t dev) } } -static struct super_block * get_super(dev_t dev) +static struct super_block * get_super(kdev_t dev) { struct super_block * s; @@ -234,20 +234,20 @@ static struct super_block * get_super(dev_t dev) return NULL; } -void put_super(dev_t dev) +void put_super(kdev_t dev) { struct super_block * sb; if (dev == ROOT_DEV) { - printk("VFS: Root device %d/%d: prepare for armageddon\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: Root device %s: prepare for armageddon\n", + kdevname(dev)); return; } if (!(sb = get_super(dev))) return; if (sb->s_covered) { - printk("VFS: Mounted device %d/%d - tssk, tssk\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: Mounted device %s - tssk, tssk\n", + kdevname(dev)); return; } if (sb->s_op && sb->s_op->put_super) @@ -262,7 +262,7 @@ asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf) unsigned long old_fs; int error; - s = get_super(dev); + s = get_super(to_kdev_t(dev)); if (s == NULL) return -EINVAL; @@ -286,7 +286,7 @@ asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf) return 0; } -static struct super_block * read_super(dev_t dev,const char *name,int flags, +static struct super_block * read_super(kdev_t dev,const char *name,int flags, void *data, int silent) { struct super_block * s; @@ -299,14 +299,14 @@ static struct super_block * read_super(dev_t dev,const char *name,int flags, if (s) return s; if (!(type = get_fs_type(name))) { - printk("VFS: on device %d/%d: get_fs_type(%s) failed\n", - MAJOR(dev), MINOR(dev), name); + printk("VFS: on device %s: get_fs_type(%s) failed\n", + kdevname(dev), name); return NULL; } for (s = 0+super_blocks ;; s++) { if (s >= NR_SUPER+super_blocks) return NULL; - if (!s->s_dev) + if (!(s->s_dev)) break; } s->s_dev = dev; @@ -330,29 +330,29 @@ static struct super_block * read_super(dev_t dev,const char *name,int flags, static char unnamed_dev_in_use[256/8] = { 0, }; -dev_t get_unnamed_dev(void) +kdev_t get_unnamed_dev(void) { int i; for (i = 1; i < 256; i++) { if (!set_bit(i,unnamed_dev_in_use)) - return (UNNAMED_MAJOR << 8) | i; + return MKDEV(UNNAMED_MAJOR, i); } return 0; } -void put_unnamed_dev(dev_t dev) +void put_unnamed_dev(kdev_t dev) { if (!dev) return; if (MAJOR(dev) == UNNAMED_MAJOR && clear_bit(MINOR(dev), unnamed_dev_in_use)) return; - printk("VFS: put_unnamed_dev: freeing unused device %d/%d\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: put_unnamed_dev: freeing unused device %s\n", + kdevname(dev)); } -static int do_umount(dev_t dev) +static int do_umount(kdev_t dev) { struct super_block * sb; int retval; @@ -373,8 +373,8 @@ static int do_umount(dev_t dev) if (!(sb=get_super(dev)) || !(sb->s_covered)) return -ENOENT; if (!sb->s_covered->i_mount) - printk("VFS: umount(%d/%d): mounted inode has i_mount=NULL\n", - MAJOR(dev), MINOR(dev)); + printk("VFS: umount(%s): mounted inode has i_mount=NULL\n", + kdevname(dev)); if (!fs_may_umount(dev, sb->s_mounted)) return -EBUSY; sb->s_covered->i_mount = NULL; @@ -402,7 +402,7 @@ static int do_umount(dev_t dev) asmlinkage int sys_umount(char * name) { struct inode * inode; - dev_t dev; + kdev_t dev; int retval; struct inode dummy_inode; struct file_operations * fops; @@ -460,7 +460,7 @@ asmlinkage int sys_umount(char * name) * We also have to flush all inode-data for this device, as the new mount * might need new info. */ -int do_mount(dev_t dev, const char * dir, const char * type, int flags, void * data) +int do_mount(kdev_t dev, const char * dir, const char * type, int flags, void * data) { struct inode * dir_i; struct super_block * sb; @@ -506,7 +506,7 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data) { int retval; - if (!(flags & MS_RDONLY ) && sb->s_dev && is_read_only(sb->s_dev)) + if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev)) return -EACCES; /*flags |= MS_RDONLY;*/ /* If we are remounting RDONLY, make sure there are no rw files open */ @@ -584,7 +584,7 @@ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type, struct file_system_type * fstype; struct inode * inode; struct file_operations * fops; - dev_t dev; + kdev_t dev; int retval; const char * t; unsigned long flags = 0; @@ -718,6 +718,6 @@ void mount_root(void) return; } } - panic("VFS: Unable to mount root fs on %02x:%02x", - MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); + panic("VFS: Unable to mount root fs on %s", + kdevname(ROOT_DEV)); } diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 3e97711424c6..2af026b5cc0d 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c @@ -96,8 +96,10 @@ static int sysv_readdir(struct inode * inode, struct file * filp, memcpy(&sde, de, sizeof(struct sysv_dir_entry)); if (sde.inode > inode->i_sb->sv_ninodes) - printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n", - inode->i_dev, inode->i_ino, (off_t) filp->f_pos, sde.inode); + printk("sysv_readdir: Bad inode number on dev " + "%s, ino %ld, offset 0x%04lx: %d is out of range\n", + kdevname(inode->i_dev), + inode->i_ino, (off_t) filp->f_pos, sde.inode); i = strnlen(sde.name, SYSV_NAMELEN); if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode) < 0) { diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index 98883c22cb22..dcbd3af9c1a4 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c @@ -84,7 +84,8 @@ void sysv_free_inode(struct inode * inode) return; } if (!(bh = sv_bread(sb, inode->i_dev, sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits)))) { - printk("sysv_free_inode: unable to read inode block on device %d/%d\n",MAJOR(inode->i_dev),MINOR(inode->i_dev)); + printk("sysv_free_inode: unable to read inode block on device " + "%s\n", kdevname(inode->i_dev)); clear_inode(inode); return; } diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 4aa0932cb3a8..e26e0db0b636 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -347,7 +347,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, { struct buffer_head *bh; const char *found; - int dev = sb->s_dev; + kdev_t dev = sb->s_dev; if (1024 != sizeof (struct xenix_super_block)) panic("Xenix FS: bad super-block size"); @@ -397,10 +397,11 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, brelse(bh); } } - sb->s_dev=0; + sb->s_dev = 0; unlock_super(sb); if (!silent) - printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device %d/%d\n",MAJOR(dev),MINOR(dev)); + printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device " + "%s\n", kdevname(dev)); failed: MOD_DEC_USE_COUNT; return NULL; @@ -477,7 +478,8 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, } sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits; if (!silent) - printk("VFS: Found a %s FS (block size = %d) on device %d/%d\n",found,sb->sv_block_size,MAJOR(dev),MINOR(dev)); + printk("VFS: Found a %s FS (block size = %d) on device %s\n", + found, sb->sv_block_size, kdevname(dev)); sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type; /* The buffer code now supports block size 512 as well as 1024. */ sb->s_blocksize = sb->sv_block_size; @@ -811,14 +813,16 @@ void sysv_read_inode(struct inode * inode) inode->i_op = NULL; inode->i_mode = 0; if (!ino || ino > sb->sv_ninodes) { - printk("Bad inode number on dev 0x%04x: %d is out of range\n", - inode->i_dev, ino); + printk("Bad inode number on dev %s" + ": %d is out of range\n", + kdevname(inode->i_dev), ino); return; } block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits); if (!(bh = sv_bread(sb,inode->i_dev,block))) { - printk("Major problem: unable to read inode from dev 0x%04x\n", - inode->i_dev); + printk("Major problem: unable to read inode from dev " + "%s\n", + kdevname(inode->i_dev)); return; } raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1); @@ -843,7 +847,7 @@ void sysv_read_inode(struct inode * inode) } inode->i_blocks = inode->i_blksize = 0; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = raw_inode->i_a.i_rdev; + inode->i_rdev = to_kdev_t(raw_inode->i_a.i_rdev); else if (sb->sv_convert) for (block = 0; block < 10+1+1+1; block++) @@ -896,8 +900,9 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) ino = inode->i_ino; if (!ino || ino > sb->sv_ninodes) { - printk("Bad inode number on dev 0x%04x: %d is out of range\n", - inode->i_dev, ino); + printk("Bad inode number on dev %s" + ": %d is out of range\n", + kdevname(inode->i_dev), ino); inode->i_dirt = 0; return 0; } @@ -927,7 +932,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) raw_inode->i_ctime = inode->i_ctime; } if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_a.i_rdev = inode->i_rdev; /* write 2 or 3 bytes ?? */ + raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */ else if (sb->sv_convert) for (block = 0; block < 10+1+1+1; block++) @@ -958,8 +963,9 @@ int sysv_sync_inode(struct inode * inode) wait_on_buffer(bh); if (bh->b_req && !bh->b_uptodate) { - printk ("IO error syncing sysv inode [%04x:%08lx]\n", - inode->i_dev, inode->i_ino); + printk ("IO error syncing sysv inode [" + "%s:%08lx]\n", + kdevname(inode->i_dev), inode->i_ino); err = -1; } } diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 8d245d38e2a2..e7c3fd16b32b 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -279,7 +279,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; + inode->i_rdev = to_kdev_t(rdev); inode->i_dirt = 1; error = sysv_add_entry(dir, name, len, &bh, &de); if (error) { @@ -418,7 +418,8 @@ static int empty_dir(struct inode * inode) return 1; bad_dir: brelse(bh); - printk("Bad directory on device %04x\n",inode->i_dev); + printk("Bad directory on device %s\n", + kdevname(inode->i_dev)); return 1; } @@ -512,8 +513,9 @@ repeat: goto end_unlink; } if (!inode->i_nlink) { - printk("Deleting nonexistent file (%04x:%lu), %d\n", - inode->i_dev,inode->i_ino,inode->i_nlink); + printk("Deleting nonexistent file (%s:%lu), %d\n", + kdevname(inode->i_dev), + inode->i_ino, inode->i_nlink); inode->i_nlink=1; } de->inode = 0; diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c index 404a64cb6f89..44f4472d9ade 100644 --- a/fs/umsdos/dir.c +++ b/fs/umsdos/dir.c @@ -346,7 +346,7 @@ void umsdos_lookup_patch ( */ if (S_ISREG(entry->mode)) entry->mtime = inode->i_mtime; inode->i_mode = entry->mode; - inode->i_rdev = entry->rdev; + inode->i_rdev = to_kdev_t(entry->rdev); inode->i_atime = entry->atime; inode->i_ctime = entry->ctime; inode->i_mtime = entry->mtime; diff --git a/fs/xiafs/bitmap.c b/fs/xiafs/bitmap.c index bca7e4367a9c..38a66d375672 100644 --- a/fs/xiafs/bitmap.c +++ b/fs/xiafs/bitmap.c @@ -239,9 +239,9 @@ void xiafs_free_zone(struct super_block * sb, int d_addr) return; offset = bit & (XIAFS_BITS_PER_Z(sb) -1); if (!clear_bit(offset, bh->b_data)) - printk("XIA-FS: dev %04x" + printk("XIA-FS: dev %s" " block bit %u (0x%x) already cleared (%s %d)\n", - sb->s_dev, bit, bit, WHERE_ERR); + kdevname(sb->s_dev), bit, bit, WHERE_ERR); mark_buffer_dirty(bh, 1); xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached); } @@ -287,8 +287,9 @@ void xiafs_free_inode(struct inode * inode) if (!inode) return; - if (!inode->i_dev || inode->i_count!=1 || inode->i_nlink || !inode->i_sb || - inode->i_ino < 3 || inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) { + if (!inode->i_dev || inode->i_count!=1 + || inode->i_nlink || !inode->i_sb || inode->i_ino < 3 + || inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) { printk("XIA-FS: bad inode (%s %d)\n", WHERE_ERR); return; } @@ -299,9 +300,9 @@ void xiafs_free_inode(struct inode * inode) return; clear_inode(inode); if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data)) - printk("XIA-FS: dev %04x" + printk("XIA-FS: dev %s" "inode bit %ld (0x%lx) already cleared (%s %d)\n", - inode->i_dev, ino, ino, WHERE_ERR); + kdevname(inode->i_dev), ino, ino, WHERE_ERR); mark_buffer_dirty(bh, 1); xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached); } diff --git a/fs/xiafs/inode.c b/fs/xiafs/inode.c index 5f9fc833ae93..a6914132c9c4 100644 --- a/fs/xiafs/inode.c +++ b/fs/xiafs/inode.c @@ -70,16 +70,17 @@ struct super_block *xiafs_read_super(struct super_block *s, void *data, { struct buffer_head *bh; struct xiafs_super_block *sp; - int i, z, dev; + int i, z; + kdev_t dev; MOD_INC_USE_COUNT; - dev=s->s_dev; + dev = s->s_dev; lock_super(s); set_blocksize(dev, BLOCK_SIZE); if (!(bh = bread(dev, 0, BLOCK_SIZE))) { - s->s_dev=0; + s->s_dev = 0; unlock_super(s); printk("XIA-FS: read super_block failed (%s %d)\n", WHERE_ERR); MOD_DEC_USE_COUNT; @@ -92,8 +93,8 @@ struct super_block *xiafs_read_super(struct super_block *s, void *data, unlock_super(s); brelse(bh); if (!silent) - printk("VFS: Can't find a xiafs filesystem on dev 0x%04x.\n", - dev); + printk("VFS: Can't find a xiafs filesystem on dev " + "%s.\n", kdevname(dev)); MOD_DEC_USE_COUNT; return NULL; } @@ -164,7 +165,7 @@ xiafs_read_super_fail: brelse(s->u.xiafs_sb.s_imap_buf[i]); for(i=0; i < _XIAFS_ZMAP_SLOTS; i++) brelse(s->u.xiafs_sb.s_zmap_buf[i]); - s->s_dev=0; + s->s_dev = 0; unlock_super(s); printk("XIA-FS: read bitmaps failed (%s %d)\n", WHERE_ERR); MOD_DEC_USE_COUNT; @@ -408,7 +409,7 @@ void xiafs_read_inode(struct inode * inode) inode->i_blksize = XIAFS_ZSIZE(inode->i_sb); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { inode->i_blocks=0; - inode->i_rdev = raw_inode->i_zone[0]; + inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]); } else { XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks); for (zone = 0; zone < 8; zone++) @@ -469,7 +470,7 @@ static struct buffer_head * xiafs_update_inode(struct inode * inode) raw_inode->i_ctime = inode->i_ctime; raw_inode->i_mtime = inode->i_mtime; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = inode->i_rdev; + raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); else { XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks); for (zone = 0; zone < 8; zone++) @@ -505,8 +506,8 @@ int xiafs_sync_inode (struct inode *inode) wait_on_buffer(bh); if (bh->b_req && !bh->b_uptodate) { - printk ("IO error syncing xiafs inode [%04X:%lu]\n", - inode->i_dev, inode->i_ino); + printk ("IO error syncing xiafs inode [%s:%lu]\n", + kdevname(inode->i_dev), inode->i_ino); err = -1; } } diff --git a/fs/xiafs/namei.c b/fs/xiafs/namei.c index 46b3590b2b93..0d66a3e6bc89 100644 --- a/fs/xiafs/namei.c +++ b/fs/xiafs/namei.c @@ -317,7 +317,7 @@ int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; + inode->i_rdev = to_kdev_t(rdev); inode->i_atime = inode->i_ctime = inode->i_atime = CURRENT_TIME; inode->i_dirt = 1; bh = xiafs_add_entry(dir, name, len, &de, NULL); diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index 2a7421aef00a..97663c59ccf2 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h @@ -8,6 +8,16 @@ */ #include +#include + +#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) +# define NR_IRQS 33 +#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) +# define NR_IRQS 32 +#else +# define NR_IRQS 16 +#endif + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index a54548ddef4a..46893166ed6d 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h @@ -10,6 +10,8 @@ #include #include +#define NR_IRQS 16 + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1e0b17c8168a..ba4d08afd886 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -12,7 +12,14 @@ * for read/write completion. */ struct request { - int dev; /* -1 if no request */ + volatile int rq_status; /* should split this into a few status bits */ +#define RQ_INACTIVE (-1) +#define RQ_ACTIVE 1 +#define RQ_SCSI_BUSY 0xffff +#define RQ_SCSI_DONE 0xfffe +#define RQ_SCSI_DISCONNECTING 0xffe0 + + kdev_t rq_dev; int cmd; /* READ or WRITE */ int errors; unsigned long sector; diff --git a/include/linux/fd.h b/include/linux/fd.h index f6b1d13a2a9d..1c4deb05be4e 100644 --- a/include/linux/fd.h +++ b/include/linux/fd.h @@ -184,7 +184,7 @@ struct floppy_drive_struct { /* Prevent "aliased" accesses. */ int fd_ref; - int fd_device; + int fd_device; /* should be a kdev_t but is externally visible */ int last_checked; /* when was the drive last checked for a disk change? */ char *dmabuf; diff --git a/include/linux/fs.h b/include/linux/fs.h index b06d45c7c50a..b63d493c2f9d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -12,6 +12,7 @@ #include #include #include +#include /* * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix @@ -40,16 +41,6 @@ #define READA 2 /* read-ahead - don't pause */ #define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */ -extern void buffer_init(void); -extern unsigned long inode_init(unsigned long start, unsigned long end); -extern unsigned long file_table_init(unsigned long start, unsigned long end); -extern unsigned long name_cache_init(unsigned long start, unsigned long end); - -#define MAJOR(a) (int)((unsigned short)(a) >> 8) -#define MINOR(a) (int)((unsigned short)(a) & 0xFF) -#define MKDEV(a,b) ((int)((((a) & 0xff) << 8) | ((b) & 0xff))) -#define NODEV MKDEV(0,0) - #ifndef NULL #define NULL ((void *) 0) #endif @@ -115,13 +106,20 @@ extern unsigned long name_cache_init(unsigned long start, unsigned long end); #define FIBMAP 1 /* bmap access */ #define FIGETBSZ 2 /* get the block size used for bmap */ +#ifdef __KERNEL__ +extern void buffer_init(void); +extern unsigned long inode_init(unsigned long start, unsigned long end); +extern unsigned long file_table_init(unsigned long start, unsigned long end); +extern unsigned long name_cache_init(unsigned long start, unsigned long end); + typedef char buffer_block[BLOCK_SIZE]; struct buffer_head { char * b_data; /* pointer to data block (1024 bytes) */ unsigned long b_size; /* block size */ unsigned long b_blocknr; /* block number */ - dev_t b_dev; /* device (0 = free) */ + kdev_t b_dev; /* device (B_FREE = free) */ + unsigned short b_count; /* users using this block */ unsigned char b_uptodate; unsigned char b_dirt; /* 0-clean,1-dirty */ @@ -152,8 +150,6 @@ struct buffer_head { #include #include -#ifdef __KERNEL__ - /* * Attribute flags. These should be or-ed together to figure out what * has been changed! @@ -189,13 +185,13 @@ struct iattr { }; struct inode { - dev_t i_dev; + kdev_t i_dev; unsigned long i_ino; umode_t i_mode; nlink_t i_nlink; uid_t i_uid; gid_t i_gid; - dev_t i_rdev; + kdev_t i_rdev; off_t i_size; time_t i_atime; time_t i_mtime; @@ -288,7 +284,7 @@ extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struc #include struct super_block { - dev_t s_dev; + kdev_t s_dev; unsigned long s_blocksize; unsigned char s_blocksize_bits; unsigned char s_lock; @@ -336,8 +332,8 @@ struct file_operations { void (*release) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *); int (*fasync) (struct inode *, struct file *, int); - int (*check_media_change) (dev_t dev); - int (*revalidate) (dev_t dev); + int (*check_media_change) (kdev_t dev); + int (*revalidate) (kdev_t dev); }; struct inode_operations { @@ -412,9 +408,9 @@ extern struct file_operations rdwr_pipe_fops; extern struct file_system_type *get_fs_type(const char *name); -extern int fs_may_mount(dev_t dev); -extern int fs_may_umount(dev_t dev, struct inode * mount_root); -extern int fs_may_remount_ro(dev_t dev); +extern int fs_may_mount(kdev_t dev); +extern int fs_may_umount(kdev_t dev, struct inode * mount_root); +extern int fs_may_remount_ro(kdev_t dev); extern struct file *first_file; extern int nr_files; @@ -456,14 +452,14 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag) } -extern int check_disk_change(dev_t dev); -extern void invalidate_inodes(dev_t dev); -extern void invalidate_buffers(dev_t dev); +extern int check_disk_change(kdev_t dev); +extern void invalidate_inodes(kdev_t dev); +extern void invalidate_buffers(kdev_t dev); extern int floppy_is_wp(int minor); -extern void sync_inodes(dev_t dev); -extern void sync_dev(dev_t dev); -extern int fsync_dev(dev_t dev); -extern void sync_supers(dev_t dev); +extern void sync_inodes(kdev_t dev); +extern void sync_dev(kdev_t dev); +extern int fsync_dev(kdev_t dev); +extern void sync_supers(kdev_t dev); extern int bmap(struct inode * inode,int block); extern int notify_change(struct inode *, struct iattr *); extern int namei(const char * pathname, struct inode ** res_inode); @@ -483,22 +479,22 @@ extern void clear_inode(struct inode *); extern struct inode * get_pipe_inode(void); extern struct file * get_empty_filp(void); extern int close_fp(struct file *filp); -extern struct buffer_head * get_hash_table(dev_t dev, int block, int size); -extern struct buffer_head * getblk(dev_t dev, int block, int size); +extern struct buffer_head * get_hash_table(kdev_t dev, int block, int size); +extern struct buffer_head * getblk(kdev_t dev, int block, int size); extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]); -extern void ll_rw_page(int rw, int dev, unsigned long nr, char * buffer); -extern void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buffer); -extern int is_read_only(int dev); +extern void ll_rw_page(int rw, kdev_t dev, unsigned long nr, char * buffer); +extern void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buffer); +extern int is_read_only(kdev_t dev); extern void brelse(struct buffer_head * buf); -extern void set_blocksize(dev_t dev, int size); -extern struct buffer_head * bread(dev_t dev, int block, int size); -extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share); -extern void bwrite_page(unsigned long addr,dev_t dev,int b[],int size); -extern struct buffer_head * breada(dev_t dev,int block, int size, +extern void set_blocksize(kdev_t dev, int size); +extern struct buffer_head * bread(kdev_t dev, int block, int size); +extern unsigned long bread_page(unsigned long addr,kdev_t dev,int b[],int size,int no_share); +extern void bwrite_page(unsigned long addr,kdev_t dev,int b[],int size); +extern struct buffer_head * breada(kdev_t dev,int block, int size, unsigned int pos, unsigned int filesize); -extern void put_super(dev_t dev); -unsigned long generate_cluster(dev_t dev, int b[], int size); -extern dev_t ROOT_DEV; +extern void put_super(kdev_t dev); +unsigned long generate_cluster(kdev_t dev, int b[], int size); +extern kdev_t ROOT_DEV; extern void show_buffers(void); extern void mount_root(void); diff --git a/include/linux/kd.h b/include/linux/kd.h index 5af1271cb0f3..d10deaa975ed 100644 --- a/include/linux/kd.h +++ b/include/linux/kd.h @@ -15,6 +15,8 @@ struct consolefontdesc { char *chardata; /* font data in expanded form */ }; +#define PIO_FONTRESET 0x4B6D /* reset to default font */ + #define GIO_CMAP 0x4B70 /* gets colour palette on VGA+ */ #define PIO_CMAP 0x4B71 /* sets colour palette on VGA+ */ @@ -132,6 +134,6 @@ struct kbkeycode { /* note: 0x4B00-0x4B4E all have had a value at some time; don't reuse for the time being */ -/* note: 0x4B60-0x4B6C, 0x4B70, 0x4B71 used above */ +/* note: 0x4B60-0x4B6D, 0x4B70, 0x4B71 used above */ #endif /* _LINUX_KD_H */ diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h new file mode 100644 index 000000000000..b08cd38174e3 --- /dev/null +++ b/include/linux/kdev_t.h @@ -0,0 +1,114 @@ +#ifndef _LINUX_KDEV_T_H +#define _LINUX_KDEV_T_H +#ifdef __KERNEL__ +/* +As a preparation for the introduction of larger device numbers, +we introduce a type kdev_t to hold them. No information about +this type is known outside of this include file. + +Objects of type kdev_t designate a device. Outside of the kernel +the corresponding things are objects of type dev_t - usually an +integral type with the device major and minor in the high and low +bits, respectively. Conversion is done by + +extern kdev_t to_kdev_t(int); + +It is up to the various file systems to decide how objects of type +dev_t are stored on disk. +The only other point of contact between kernel and outside world +are the system calls stat and mknod, new versions of which will +eventually have to be used in libc. + +[Unfortunately, the floppy control ioctls fail to hide the internal +kernel structures, and the fd_device field of a struct floppy_drive_struct +is user-visible. So, it remains a dev_t for the moment, with some ugly +conversions in floppy.c.] + +Inside the kernel, we aim for a kdev_t type that is a pointer +to a structure with information about the device (like major, +minor, size, blocksize, sectorsize, name, read-only flag, +struct file_operations etc.). + +However, for the time being we let kdev_t be almost the same as dev_t: + +typedef struct { unsigned short major, minor; } kdev_t; + +Admissible operations on an object of type kdev_t: +- passing it along +- comparing it for equality with another such object +- storing it in ROOT_DEV, inode->i_dev, inode->i_rdev, sb->s_dev, + bh->b_dev, req->rq_dev, de->dc_dev, tty->device +- using its bit pattern as argument in a hash function +- finding its major and minor +- complaining about it + +An object of type kdev_t is created only by the function MKDEV(), +with the single exception of the constant 0 (no device). + +Right now the other information mentioned above is usually found +in static arrays indexed by major or major,minor. + +An obstacle to immediately using + typedef struct { ... (* lots of information *) } *kdev_t +is the case of mknod used to create a block device that the +kernel doesn't know about at present (but first learns about +when some module is inserted). + +aeb - 950811 +*/ + +/* Since MINOR(dev) is used as index in static arrays, + the kernel is not quite ready yet for larger minors. + However, everything runs fine with an arbitrary kdev_t type. */ + +#define MINORBITS 8 +#define MINORMASK ((1<> MINORBITS) +#define MINOR(dev) ((dev) & MINORMASK) +#define HASHDEV(dev) (dev) +#define NODEV 0 +#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) +#define B_FREE 0xffff /* yuk */ + +extern char * kdevname(kdev_t); /* note: returns pointer to static data! */ + +/* +As long as device numbers in the outside world have 16 bits only, +we use these conversions. +*/ + +static inline unsigned int kdev_t_to_nr(kdev_t dev) { + return (MAJOR(dev)<<8) | MINOR(dev); +} + +static inline kdev_t to_kdev_t(int dev) +{ + int major, minor; +#if 0 + major = (dev >> 16); + if (!major) { + major = (dev >> 8); + minor = (dev & 0xff); + } else + minor = (dev & 0xffff); +#else + major = (dev >> 8); + minor = (dev & 0xff); +#endif + return MKDEV(major, minor); +} + +#else /* __KERNEL__ */ + +/* +Some unfortunate programs want their definitions of MAJOR and MINOR +from the kernel sources. +*/ +#define MAJOR(dev) ((dev)>>8) +#define MINOR(dev) ((dev) & 0xff) + +#endif /* __KERNEL__ */ +#endif diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 4d3f3e941a08..27614973c498 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -1,6 +1,8 @@ #ifndef _LINUX_KERNEL_STAT_H #define _LINUX_KERNEL_STAT_H +#include + /* * 'kernel_stat.h' contains the definitions needed for doing * some kernel statistics (cpu usage, context switches ...), @@ -14,7 +16,7 @@ struct kernel_stat { unsigned int dk_drive[DK_NDRIVE]; unsigned int pgpgin, pgpgout; unsigned int pswpin, pswpout; - unsigned int interrupts[16]; + unsigned int interrupts[NR_IRQS]; unsigned int ipackets, opackets; unsigned int ierrors, oerrors; unsigned int collisions; diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h index 5f22761fdd8f..d2e709a1adae 100644 --- a/include/linux/mc146818rtc.h +++ b/include/linux/mc146818rtc.h @@ -14,17 +14,16 @@ #ifndef RTC_PORT #define RTC_PORT(x) (0x70 + (x)) -#define RTC_ADDR(x) (0x80 | (x)) #define RTC_ALWAYS_BCD 1 #endif #define CMOS_READ(addr) ({ \ -outb_p(RTC_ADDR(addr),RTC_PORT(0)); \ +outb_p((addr),RTC_PORT(0)); \ inb_p(RTC_PORT(1)); \ }) #define CMOS_WRITE(val, addr) ({ \ -outb_p(RTC_ADDR(addr),RTC_PORT(0)); \ -outb_p(val,RTC_PORT(1)); \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ }) /********************************************************************** diff --git a/include/linux/module.h b/include/linux/module.h index a9612cea970d..f283e3a0ba5c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -90,7 +90,7 @@ extern int register_symtab(struct symbol_table *); * define the count variable, and usage macros. */ -extern int mod_use_count_; +extern long mod_use_count_; #if defined(CONFIG_MODVERSIONS) && defined(MODULE) && !defined(__GENKSYMS__) int Using_Versions; /* gcc will handle this global (used as a flag) correctly */ #endif diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index f439026442c4..1e24d9a85dc0 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -21,6 +21,9 @@ #define FAT_CACHE 8 /* FAT cache size */ +#define MSDOS_MAX_EXTRA 3 /* tolerate up to that number of clusters which are + inaccessible because the FAT is too short */ + #define ATTR_RO 1 /* read-only */ #define ATTR_HIDDEN 2 /* hidden */ #define ATTR_SYS 4 /* system */ @@ -88,7 +91,7 @@ struct msdos_dir_entry { }; struct fat_cache { - int device; /* device number. 0 means unused. */ + kdev_t device; /* device number. 0 means unused. */ int ino; /* inode number. */ int file_cluster; /* cluster number in the file. */ int disk_cluster; /* cluster number on disk. */ @@ -137,7 +140,7 @@ extern void cache_init(void); void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu); void cache_add(struct inode *inode,int f_clu,int d_clu); void cache_inval_inode(struct inode *inode); -void cache_inval_dev(int device); +void cache_inval_dev(kdev_t device); int get_cluster(struct inode *inode,int cluster); /* namei.c */ diff --git a/include/linux/optcd.h b/include/linux/optcd.h index 20ef07189a62..036d4a3da921 100644 --- a/include/linux/optcd.h +++ b/include/linux/optcd.h @@ -170,7 +170,7 @@ struct opt_Toc { #define CURRENT_VALID \ - (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR \ + (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR \ && CURRENT -> cmd == READ && CURRENT -> sector != -1) diff --git a/include/linux/pci.h b/include/linux/pci.h index 7a25b31bb50d..31c1b2fde915 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -422,8 +422,8 @@ #define PCI_DEVICE_ID_INTEL_7116 0x1223 #define PCI_DEVICE_ID_INTEL_82865 0x1227 #define PCI_DEVICE_ID_INTEL_82437 0x122d -#define PCI_DEVICE_ID_INTEL_82371 0x122e -#define PCI_DEVICE_ID_INTEL_82438 0x1230 +#define PCI_DEVICE_ID_INTEL_82371_0 0x122e +#define PCI_DEVICE_ID_INTEL_82371_1 0x1230 #define PCI_DEVICE_ID_INTEL_P6 0x84c4 #define PCI_VENDOR_ID_ADAPTEC 0x9004 diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index c9a30fe277e0..a5558b217abc 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -3,6 +3,7 @@ #include #include +#include /* * The proc filesystem constants/structures @@ -97,7 +98,7 @@ enum scsi_directory_inos { PROC_SCSI_AIC7XXX, PROC_SCSI_BUSLOGIC, PROC_SCSI_U14_34F, - PROC_SCSI_FUTURE_DOMAIN, + PROC_SCSI_FDOMAIN, PROC_SCSI_GENERIC_NCR5380, PROC_SCSI_IN2000, PROC_SCSI_PAS16, @@ -152,6 +153,8 @@ extern struct proc_dir_entry proc_scsi; extern struct proc_dir_entry proc_pid; extern struct proc_dir_entry proc_pid_fd; +extern struct inode_operations proc_scsi_inode_operations; + extern void proc_root_init(void); extern void proc_base_init(void); extern void proc_net_init(void); @@ -169,6 +172,38 @@ static inline int proc_net_unregister(int x) return proc_unregister(&proc_net, x); } +static inline int proc_scsi_register(struct proc_dir_entry *driver, + struct proc_dir_entry *x) +{ + x->ops = &proc_scsi_inode_operations; + if(x->low_ino < PROC_SCSI_FILE){ + return(proc_register(&proc_scsi, x)); + }else{ + return(proc_register(driver, x)); + } +} + +static inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x) +{ + extern void scsi_init_free(char *ptr, unsigned int size); + + if(x <= PROC_SCSI_FILE) + return(proc_unregister(&proc_scsi, x)); + else { + struct proc_dir_entry **p = &driver->subdir, *dp; + int ret; + + while ((dp = *p) != NULL) { + if (dp->low_ino == x) + break; + p = &dp->next; + } + ret = proc_unregister(driver, x); + scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4); + return(ret); + } +} + extern struct super_block *proc_read_super(struct super_block *,void *,int); extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *); extern void proc_statfs(struct super_block *, struct statfs *, int); diff --git a/include/linux/scsicam.h b/include/linux/scsicam.h index d78dc71c4c02..954e1407ee54 100644 --- a/include/linux/scsicam.h +++ b/include/linux/scsicam.h @@ -12,5 +12,6 @@ #ifndef SCSICAM_H #define SCSICAM_H -extern int scsicam_bios_param (Disk *disk, int dev, int *ip); +#include +extern int scsicam_bios_param (Disk *disk, kdev_t dev, int *ip); #endif /* def SCSICAM_H */ diff --git a/include/linux/sysv_fs.h b/include/linux/sysv_fs.h index 984be6b1cdab..f96f32676648 100644 --- a/include/linux/sysv_fs.h +++ b/include/linux/sysv_fs.h @@ -337,21 +337,21 @@ struct sysv_dir_entry { /* sv_get_hash_table(sb,dev,block) is equivalent to get_hash_table(dev,block,block_size) */ static inline struct buffer_head * -sv_get_hash_table (struct super_block *sb, int dev, unsigned int block) +sv_get_hash_table (struct super_block *sb, kdev_t dev, unsigned int block) { return get_hash_table (dev, block + sb->sv_block_base, sb->sv_block_size); } /* sv_getblk(sb,dev,block) is equivalent to getblk(dev,block,block_size) */ static inline struct buffer_head * -sv_getblk (struct super_block *sb, int dev, unsigned int block) +sv_getblk (struct super_block *sb, kdev_t dev, unsigned int block) { return getblk (dev, block + sb->sv_block_base, sb->sv_block_size); } /* sv_bread(sb,dev,block) is equivalent to bread(dev,block,block_size) */ static inline struct buffer_head * -sv_bread (struct super_block *sb, int dev, unsigned int block) +sv_bread (struct super_block *sb, kdev_t dev, unsigned int block) { return bread (dev, block + sb->sv_block_base, sb->sv_block_size); } diff --git a/include/linux/timex.h b/include/linux/timex.h index f27c2804b0f5..660599274536 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -16,18 +16,20 @@ /* * Modification history timex.h - * + * * 17 Sep 93 David L. Mills * Created file $NTP/include/sys/timex.h * 07 Oct 93 Torsten Duwe * Derived linux/timex.h + * 1995-08-13 Torsten Duwe + * kernel PLL updated to 1994-12-13 specs (rfc-1489) */ #ifndef _LINUX_TIMEX_H #define _LINUX_TIMEX_H /* * The following defines establish the engineering parameters of the PLL - * model. The HZ variable establishes the timer interrupt frequency, 100 Hz + * model. The HZ variable establishes the timer interrupt frequency, 100 Hz * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the * nearest power of two in order to avoid hardware multiply operations. @@ -39,14 +41,19 @@ #endif /* - * The SHIFT_KG and SHIFT_KF defines establish the damping of the PLL - * and are chosen by analysis for a slightly underdamped convergence - * characteristic. The MAXTC define establishes the maximum time constant - * of the PLL. With the parameters given and the default time constant of - * zero, the PLL will converge in about 15 minutes. + * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen + * for a slightly underdamped convergence characteristic. SHIFT_KH + * establishes the damping of the FLL and is chosen by wisdom and black + * art. + * + * MAXTC establishes the maximum time constant of the PLL. With the + * SHIFT_KG and SHIFT_KF values given and a time constant range from + * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, + * respectively. */ -#define SHIFT_KG 8 /* shift for phase increment */ -#define SHIFT_KF 20 /* shift for frequency increment */ +#define SHIFT_KG 6 /* phase factor (shift) */ +#define SHIFT_KF 16 /* PLL frequency factor (shift) */ +#define SHIFT_KH 2 /* FLL frequency factor (shift) */ #define MAXTC 6 /* maximum time constant (shift) */ /* @@ -56,15 +63,47 @@ * point of the time_offset variable which represents the current offset * with respect to standard time. The FINEUSEC define represents 1 usec in * scaled units. + * + * SHIFT_USEC defines the scaling (shift) of the time_freq and + * time_tolerance variables, which represent the current frequency + * offset and maximum frequency tolerance. */ -#define SHIFT_SCALE 24 /* shift for phase scale factor */ +#define SHIFT_SCALE 22 /* shift for phase scale factor */ #define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* shift for offset scale factor */ -#define FINEUSEC (1 << SHIFT_SCALE) /* 1 us in scaled units */ +#define SHIFT_USEC 16 /* frequency offset scale (shift) */ +#define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */ -#define MAXPHASE 128000 /* max phase error (us) */ -#define MAXFREQ 100 /* max frequency error (ppm) */ -#define MINSEC 16 /* min interval between updates (s) */ -#define MAXSEC 1200 /* max interval between updates (s) */ +#define MAXPHASE 512000L /* max phase error (us) */ +#define MAXFREQ (512000L << SHIFT_USEC) /* max frequency error (ppm) */ +#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */ +#define MINSEC 16L /* min interval between updates (s) */ +#define MAXSEC 1200L /* max interval between updates (s) */ + +/* + * The following defines are used only if a pulse-per-second (PPS) + * signal is available and connected via a modem control lead, such as + * produced by the optional ppsclock feature incorporated in the Sun + * asynch driver. They establish the design parameters of the frequency- + * lock loop used to discipline the CPU clock oscillator to the PPS + * signal. + * + * PPS_AVG is the averaging factor for the frequency loop, as well as + * the time and frequency dispersion. + * + * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum + * calibration intervals, respectively, in seconds as a power of two. + * + * PPS_VALID is the maximum interval before the PPS signal is considered + * invalid and protocol updates used directly instead. + * + * MAXGLITCH is the maximum interval before a time offset of more than + * MAXTIME is believed. + */ +#define PPS_AVG 2 /* pps averaging constant (shift) */ +#define PPS_SHIFT 2 /* min interval duration (s) (shift) */ +#define PPS_SHIFTMAX 8 /* max interval duration (s) (shift) */ +#define PPS_VALID 120 /* pps signal watchdog max (s) */ +#define MAXGLITCH 30 /* pps signal glitch max (s) */ #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ @@ -79,13 +118,13 @@ * to discipline kernel clock oscillator */ struct timex { - int mode; /* mode selector */ + unsigned int modes; /* mode selector */ long offset; /* time offset (usec) */ - long frequency; /* frequency offset (scaled ppm) */ + long freq; /* frequency offset (scaled ppm) */ long maxerror; /* maximum error (usec) */ long esterror; /* estimated error (usec) */ int status; /* clock command/status */ - long time_constant; /* pll time constant */ + long constant; /* pll time constant */ long precision; /* clock precision (usec) (read only) */ long tolerance; /* clock frequency tolerance (ppm) * (read only) @@ -108,7 +147,7 @@ struct timex { }; /* - * Mode codes (timex.mode) + * Mode codes (timex.mode) */ #define ADJ_OFFSET 0x0001 /* time offset */ #define ADJ_FREQUENCY 0x0002 /* frequency offset */ @@ -119,14 +158,47 @@ struct timex { #define ADJ_TICK 0x4000 /* tick value */ #define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */ +/* xntp 3.4 compatibility names */ +#define MOD_OFFSET ADJ_OFFSET +#define MOD_FREQUENCY ADJ_FREQUENCY +#define MOD_MAXERROR ADJ_MAXERROR +#define MOD_ESTERROR ADJ_ESTERROR +#define MOD_STATUS ADJ_STATUS +#define MOD_TIMECONST ADJ_TIMECONST + /* - * Clock command/status codes (timex.status) + * Status codes (timex.status) + */ +#define STA_PLL 0x0001 /* enable PLL updates (rw) */ +#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */ +#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */ +#define STA_FLL 0x0008 /* select frequency-lock mode (rw) */ + +#define STA_INS 0x0010 /* insert leap (rw) */ +#define STA_DEL 0x0020 /* delete leap (rw) */ +#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */ +#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */ + +#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */ +#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */ +#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */ +#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ + +#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ + +#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ + STA_PPSERROR | STA_CLOCKERR) /* read-only bits */ + +/* + * Clock states (time_state) */ #define TIME_OK 0 /* clock synchronized */ #define TIME_INS 1 /* insert leap second */ #define TIME_DEL 2 /* delete leap second */ #define TIME_OOP 3 /* leap second in progress */ -#define TIME_BAD 4 /* clock not synchronized */ +#define TIME_WAIT 4 /* leap second has occured */ +#define TIME_ERROR 5 /* clock not synchronized */ +#define TIME_BAD TIME_ERROR /* bw compat */ #ifdef __KERNEL__ /* @@ -138,19 +210,36 @@ extern int tickadj; /* amount of adjustment per tick */ /* * phase-lock loop variables */ -extern int time_status; /* clock synchronization status */ +extern int time_state; /* clock status */ +extern int time_status; /* clock synchronization status bits */ extern long time_offset; /* time adjustment (us) */ extern long time_constant; /* pll time constant */ extern long time_tolerance; /* frequency tolerance (ppm) */ extern long time_precision; /* clock precision (us) */ extern long time_maxerror; /* maximum error */ extern long time_esterror; /* estimated error */ + extern long time_phase; /* phase offset (scaled us) */ extern long time_freq; /* frequency offset (scaled ppm) */ extern long time_adj; /* tick adjust (scaled 1 / HZ) */ extern long time_reftime; /* time at last adjustment (s) */ extern long time_adjust; /* The amount of adjtime left */ + +/* interface variables pps->timer interrupt */ +extern long pps_offset; /* pps time offset (us) */ +extern long pps_jitter; /* time dispersion (jitter) (us) */ +extern long pps_freq; /* frequency offset (scaled ppm) */ +extern long pps_stabil; /* frequency dispersion (scaled ppm) */ +extern long pps_valid; /* pps signal watchdog counter */ + +/* interface variables pps->adjtimex */ +extern int pps_shift; /* interval duration (s) (shift) */ +extern long pps_jitcnt; /* jitter limit exceeded */ +extern long pps_calcnt; /* calibration intervals */ +extern long pps_errcnt; /* calibration errors */ +extern long pps_stbcnt; /* stability limit exceeded */ + #endif /* KERNEL */ #endif /* LINUX_TIMEX_H */ diff --git a/include/linux/tty.h b/include/linux/tty.h index d4bb47a3b534..79c59aa56770 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -203,7 +203,7 @@ struct tty_struct { struct termios *termios, *termios_locked; int pgrp; int session; - dev_t device; + kdev_t device; unsigned long flags; int count; struct winsize winsize; @@ -288,7 +288,7 @@ extern long stl_init(long); extern long stli_init(long); #endif -extern int tty_paranoia_check(struct tty_struct *tty, dev_t device, +extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device, const char *routine); extern char *_tty_name(struct tty_struct *tty, char *buf); extern char *tty_name(struct tty_struct *tty); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index a5debb6ef886..3468fa2d73f6 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -18,7 +18,7 @@ * This routine is called when a particular tty device is closed. * * int (*write)(struct tty_struct * tty, int from_user, - * unsigned char *buf, int count); + * const unsigned char *buf, int count); * * This routine is called by the kernel to write a series of * characters to the tty device. The characters may come from diff --git a/include/linux/user.h b/include/linux/user.h index 94df3abf4ac5..2c8da3cbb488 100644 --- a/include/linux/user.h +++ b/include/linux/user.h @@ -1,6 +1,7 @@ #ifndef _LINUX_USER_H #define _LINUX_USER_H +#include #include /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under diff --git a/include/linux/xd.h b/include/linux/xd.h index ddca8bf095d2..4222fcb71aed 100644 --- a/include/linux/xd.h +++ b/include/linux/xd.h @@ -113,7 +113,7 @@ static int xd_open (struct inode *inode,struct file *file); static void do_xd_request (void); static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); static void xd_release (struct inode *inode,struct file *file); -static int xd_reread_partitions (int dev); +static int xd_reread_partitions (kdev_t dev); static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); diff --git a/init/main.c b/init/main.c index 7946decf9fcc..23ad6adc4226 100644 --- a/init/main.c +++ b/init/main.c @@ -62,6 +62,7 @@ extern void aha152x_setup(char *str, int *ints); extern void aha1542_setup(char *str, int *ints); extern void aic7xxx_setup(char *str, int *ints); extern void buslogic_setup(char *str, int *ints); +extern void fdomain_setup(char *str, int *ints); extern void scsi_luns_setup(char *str, int *ints); extern void sound_setup(char *str, int *ints); #ifdef CONFIG_CDU31A @@ -205,6 +206,9 @@ struct { #ifdef CONFIG_SCSI_BUSLOGIC { "buslogic=", buslogic_setup}, #endif +#ifdef CONFIG_SCSI_FUTURE_DOMAIN + { "fdomain=", fdomain_setup}, +#endif #ifdef CONFIG_BLK_DEV_XD { "xd=", xd_setup }, #endif @@ -359,14 +363,16 @@ static void parse_options(char *line) int n; line += 5; if (strncmp(line,"/dev/",5)) { - ROOT_DEV = simple_strtoul(line,NULL,16); + ROOT_DEV = to_kdev_t( + simple_strtoul(line,NULL,16)); continue; } line += 5; for (n = 0 ; devnames[n] ; n++) { int len = strlen(devnames[n]); if (!strncmp(line,devnames[n],len)) { - ROOT_DEV = devnums[n]+simple_strtoul(line+len,NULL,0); + ROOT_DEV = to_kdev_t(devnums[n]+ + simple_strtoul(line+len,NULL,0)); break; } } diff --git a/kernel/exit.c b/kernel/exit.c index 08fb1ac92466..8acab682b52f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -63,8 +63,7 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv) p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); } - /* Depends on order SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU */ - if ((sig >= SIGSTOP) && (sig <= SIGTTOU)) + if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) p->signal &= ~(1<<(SIGCONT-1)); /* Actually generate the signal */ generate(sig,p); diff --git a/kernel/fork.c b/kernel/fork.c index 1d5cb66b97ec..d204dccdd430 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -31,34 +31,34 @@ long last_pid=0; static int find_empty_process(void) { - int free_task; - int i, tasks_free; + int i; int this_user_tasks; + struct task_struct *p; + if (nr_tasks >= NR_TASKS - MIN_TASKS_LEFT_FOR_ROOT) { + if (current->uid) + return -EAGAIN; + } repeat: if ((++last_pid) & 0xffff8000) last_pid=1; this_user_tasks = 0; - tasks_free = 0; - free_task = -EAGAIN; - i = NR_TASKS; - while (--i > 0) { - if (!task[i]) { - free_task = i; - tasks_free++; - continue; - } - if (task[i]->uid == current->uid) + for_each_task (p) { + if (p->uid == current->uid) this_user_tasks++; - if (task[i]->pid == last_pid || task[i]->pgrp == last_pid || - task[i]->session == last_pid) + if (p->pid == last_pid || + p->pgrp == last_pid || + p->session == last_pid) goto repeat; } - if (tasks_free <= MIN_TASKS_LEFT_FOR_ROOT || - this_user_tasks > current->rlim[RLIMIT_NPROC].rlim_cur) + if (this_user_tasks > current->rlim[RLIMIT_NPROC].rlim_cur) if (current->uid) return -EAGAIN; - return free_task; + for (i = 0 ; i < NR_TASKS ; i++) { + if (!task[i]) + return i; + } + return -EAGAIN; } static int dup_mmap(struct mm_struct * mm) diff --git a/kernel/info.c b/kernel/info.c index c7b2b9a8cb4e..929f1e20f73c 100644 --- a/kernel/info.c +++ b/kernel/info.c @@ -18,7 +18,6 @@ asmlinkage int sys_sysinfo(struct sysinfo *info) { int error; struct sysinfo val; - struct task_struct **p; error = verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo)); if (error) @@ -31,8 +30,7 @@ asmlinkage int sys_sysinfo(struct sysinfo *info) val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); - for (p = &LAST_TASK; p > &FIRST_TASK; p--) - if (*p) val.procs++; + val.procs = nr_tasks-1; si_meminfo(&val); si_swapinfo(&val); diff --git a/kernel/sched.c b/kernel/sched.c index cf39500489bf..89444e5b94a6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -50,7 +50,8 @@ DECLARE_TASK_QUEUE(tq_scheduler); /* * phase-lock loop variables */ -int time_status = TIME_BAD; /* clock synchronization status */ +int time_state = TIME_BAD; /* clock synchronization status */ +int time_status = STA_UNSYNC; /* clock status bits */ long time_offset = 0; /* time adjustment (us) */ long time_constant = 0; /* pll time constant */ long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */ @@ -474,57 +475,117 @@ static inline void calc_load(void) * They were originally developed for SUN and DEC kernels. * All the kudos should go to Dave for this stuff. * - * These were ported to Linux by Philip Gladstone. */ static void second_overflow(void) { - long ltemp; - - /* Bump the maxerror field */ - time_maxerror = (0x70000000-time_maxerror < time_tolerance) ? - 0x70000000 : (time_maxerror + time_tolerance); - - /* Run the PLL */ - if (time_offset < 0) { - ltemp = (-(time_offset+1) >> (SHIFT_KG + time_constant)) + 1; - time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE); - time_offset += (time_adj * HZ) >> (SHIFT_SCALE - SHIFT_UPDATE); - time_adj = - time_adj; - } else if (time_offset > 0) { - ltemp = ((time_offset-1) >> (SHIFT_KG + time_constant)) + 1; - time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE); - time_offset -= (time_adj * HZ) >> (SHIFT_SCALE - SHIFT_UPDATE); - } else { - time_adj = 0; + long ltemp; + + /* Bump the maxerror field */ + time_maxerror = (0x70000000-time_maxerror < + time_tolerance >> SHIFT_USEC) ? + 0x70000000 : (time_maxerror + (time_tolerance >> SHIFT_USEC)); + + /* + * Leap second processing. If in leap-insert state at + * the end of the day, the system clock is set back one + * second; if in leap-delete state, the system clock is + * set ahead one second. The microtime() routine or + * external clock driver will insure that reported time + * is always monotonic. The ugly divides should be + * replaced. + */ + switch (time_state) { + + case TIME_OK: + if (time_status & STA_INS) + time_state = TIME_INS; + else if (time_status & STA_DEL) + time_state = TIME_DEL; + break; + + case TIME_INS: + if (xtime.tv_sec % 86400 == 0) { + xtime.tv_sec--; + time_state = TIME_OOP; + printk("Clock: inserting leap second 23:59:60 UTC\n"); } + break; - time_adj += (time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE)) - + FINETUNE; - - /* Handle the leap second stuff */ - switch (time_status) { - case TIME_INS: - /* ugly divide should be replaced */ - if (xtime.tv_sec % 86400 == 0) { - xtime.tv_sec--; /* !! */ - time_status = TIME_OOP; - printk("Clock: inserting leap second 23:59:60 UTC\n"); - } - break; - - case TIME_DEL: - /* ugly divide should be replaced */ - if (xtime.tv_sec % 86400 == 86399) { - xtime.tv_sec++; - time_status = TIME_OK; - printk("Clock: deleting leap second 23:59:59 UTC\n"); - } - break; - - case TIME_OOP: - time_status = TIME_OK; - break; + case TIME_DEL: + if ((xtime.tv_sec + 1) % 86400 == 0) { + xtime.tv_sec++; + time_state = TIME_WAIT; + printk("Clock: deleting leap second 23:59:59 UTC\n"); } + break; + + case TIME_OOP: + time_state = TIME_WAIT; + break; + + case TIME_WAIT: + if (!(time_status & (STA_INS | STA_DEL))) + time_state = TIME_OK; + } + + /* + * Compute the phase adjustment for the next second. In + * PLL mode, the offset is reduced by a fixed factor + * times the time constant. In FLL mode the offset is + * used directly. In either mode, the maximum phase + * adjustment for each second is clamped so as to spread + * the adjustment over not more than the number of + * seconds between updates. + */ + if (time_offset < 0) { + ltemp = -time_offset; + if (!(time_status & STA_FLL)) + ltemp >>= SHIFT_KG + time_constant; + if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE) + ltemp = (MAXPHASE / MINSEC) << + SHIFT_UPDATE; + time_offset += ltemp; + time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - + SHIFT_UPDATE); + } else { + ltemp = time_offset; + if (!(time_status & STA_FLL)) + ltemp >>= SHIFT_KG + time_constant; + if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE) + ltemp = (MAXPHASE / MINSEC) << + SHIFT_UPDATE; + time_offset -= ltemp; + time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - + SHIFT_UPDATE); + } + + /* + * Compute the frequency estimate and additional phase + * adjustment due to frequency error for the next + * second. When the PPS signal is engaged, gnaw on the + * watchdog counter and update the frequency computed by + * the pll and the PPS signal. + */ + pps_valid++; + if (pps_valid == PPS_VALID) { + pps_jitter = MAXTIME; + pps_stabil = MAXFREQ; + time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | + STA_PPSWANDER | STA_PPSERROR); + } + ltemp = time_freq + pps_freq; + if (ltemp < 0) + time_adj -= -ltemp >> + (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE); + else + time_adj += ltemp >> + (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE); + + /* compensate for (HZ==100) != 128. Add 25% to get 125; => only 3% error */ + if (time_adj < 0) + time_adj -= -time_adj >> 2; + else + time_adj += time_adj >> 2; } /* @@ -592,12 +653,12 @@ static void do_timer(int irq, struct pt_regs * regs) * advance the tick more. */ time_phase += time_adj; - if (time_phase < -FINEUSEC) { + if (time_phase <= -FINEUSEC) { ltemp = -time_phase >> SHIFT_SCALE; time_phase += ltemp << SHIFT_SCALE; xtime.tv_usec += tick + time_adjust_step - ltemp; } - else if (time_phase > FINEUSEC) { + else if (time_phase >= FINEUSEC) { ltemp = time_phase >> SHIFT_SCALE; time_phase -= ltemp << SHIFT_SCALE; xtime.tv_usec += tick + time_adjust_step + ltemp; @@ -638,7 +699,7 @@ static void do_timer(int irq, struct pt_regs * regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if (time_status != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && + if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec > 500000 - (tick >> 1) && xtime.tv_usec < 500000 + (tick >> 1)) if (set_rtc_mmss(xtime.tv_sec) == 0) diff --git a/kernel/sys.c b/kernel/sys.c index 1dccd2eb1789..5de77041140b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -56,7 +56,7 @@ static int proc_sel(struct task_struct *p, int which, int who) asmlinkage int sys_setpriority(int which, int who, int niceval) { - struct task_struct **p; + struct task_struct *p; int error = ESRCH; int priority; @@ -66,39 +66,39 @@ asmlinkage int sys_setpriority(int which, int who, int niceval) if ((priority = PZERO - niceval) <= 0) priority = 1; - for(p = &LAST_TASK; p > &FIRST_TASK; --p) { - if (!*p || !proc_sel(*p, which, who)) + for_each_task(p) { + if (!proc_sel(p, which, who)) continue; - if ((*p)->uid != current->euid && - (*p)->uid != current->uid && !suser()) { + if (p->uid != current->euid && + p->uid != current->uid && !suser()) { error = EPERM; continue; } if (error == ESRCH) error = 0; - if (priority > (*p)->priority && !suser()) + if (priority > p->priority && !suser()) error = EACCES; else - (*p)->priority = priority; + p->priority = priority; } return -error; } asmlinkage int sys_getpriority(int which, int who) { - struct task_struct **p; - int max_prio = 0; + struct task_struct *p; + int max_prio = -ESRCH; if (which > 2 || which < 0) return -EINVAL; - for(p = &LAST_TASK; p > &FIRST_TASK; --p) { - if (!*p || !proc_sel(*p, which, who)) + for_each_task (p) { + if (!proc_sel(p, which, who)) continue; - if ((*p)->priority > max_prio) - max_prio = (*p)->priority; + if (p->priority > max_prio) + max_prio = p->priority; } - return(max_prio ? max_prio : -ESRCH); + return max_prio; } asmlinkage int sys_profil(void) diff --git a/kernel/time.c b/kernel/time.c index c78a819ecdb4..4c3076e07732 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -19,10 +19,8 @@ * 1995-03-26 Markus Kuhn * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887 * precision CMOS clock update - * - * to do: adjtimex() has to be updated to recent (1994-12-13) revision - * of David Mill's kernel clock model. For more information, check - * . + * 1995-08-13 Torsten Duwe + * kernel PLL updated to 1994-12-13 specs (rfc-1489) */ #include @@ -150,7 +148,7 @@ asmlinkage int sys_stime(int * tptr) cli(); xtime.tv_sec = value; xtime.tv_usec = 0; - time_status = TIME_BAD; + time_state = TIME_BAD; time_maxerror = 0x70000000; time_esterror = 0x70000000; sti(); @@ -330,7 +328,7 @@ asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz) } xtime = new_tv; - time_status = TIME_BAD; + time_state = TIME_BAD; time_maxerror = 0x70000000; time_esterror = 0x70000000; sti(); @@ -338,6 +336,24 @@ asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz) return 0; } +long pps_offset = 0; /* pps time offset (us) */ +long pps_jitter = MAXTIME; /* time dispersion (jitter) (us) */ + +long pps_freq = 0; /* frequency offset (scaled ppm) */ +long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */ + +long pps_valid = PPS_VALID; /* pps signal watchdog counter */ + +int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */ + +long pps_jitcnt = 0; /* jitter limit exceeded */ +long pps_calcnt = 0; /* calibration intervals */ +long pps_errcnt = 0; /* calibration errors */ +long pps_stbcnt = 0; /* stability limit exceeded */ + +/* hook for a loadable hardpps kernel module */ +void (*hardpps_ptr)(struct timeval *) = (void (*)(struct timeval *))0; + /* adjtimex mainly allows reading (and writing, if superuser) of * kernel time-keeping variables. used by xntpd. */ @@ -360,25 +376,19 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) memcpy_fromfs(&txc, txc_p, sizeof(struct timex)); /* In order to modify anything, you gotta be super-user! */ - if (txc.mode && !suser()) + if (txc.modes && !suser()) return -EPERM; /* Now we validate the data before disabling interrupts */ - if (txc.mode != ADJ_OFFSET_SINGLESHOT && (txc.mode & ADJ_OFFSET)) - /* Microsec field limited to -131000 .. 131000 usecs */ - if (txc.offset <= -(1 << (31 - SHIFT_UPDATE)) - || txc.offset >= (1 << (31 - SHIFT_UPDATE))) - return -EINVAL; - - /* time_status must be in a fairly small range */ - if (txc.mode & ADJ_STATUS) - if (txc.status < TIME_OK || txc.status > TIME_BAD) + if (txc.modes != ADJ_OFFSET_SINGLESHOT && (txc.modes & ADJ_OFFSET)) + /* adjustment Offset limited to +- .512 seconds */ + if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE ) return -EINVAL; /* if the quartz is off by more than 10% something is VERY wrong ! */ - if (txc.mode & ADJ_TICK) + if (txc.modes & ADJ_TICK) if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) return -EINVAL; @@ -388,72 +398,118 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) save_adjust = time_adjust; /* If there are input parameters, then process them */ - if (txc.mode) + if (txc.modes) { - if (time_status == TIME_BAD) - time_status = TIME_OK; + if (time_state == TIME_BAD) + time_state = TIME_OK; - if (txc.mode & ADJ_STATUS) + if (txc.modes & ADJ_STATUS) time_status = txc.status; - if (txc.mode & ADJ_FREQUENCY) - time_freq = txc.frequency << (SHIFT_KF - 16); + if (txc.modes & ADJ_FREQUENCY) + time_freq = txc.freq; - if (txc.mode & ADJ_MAXERROR) + if (txc.modes & ADJ_MAXERROR) time_maxerror = txc.maxerror; - if (txc.mode & ADJ_ESTERROR) + if (txc.modes & ADJ_ESTERROR) time_esterror = txc.esterror; - if (txc.mode & ADJ_TIMECONST) - time_constant = txc.time_constant; + if (txc.modes & ADJ_TIMECONST) + time_constant = txc.constant; - if (txc.mode & ADJ_OFFSET) - if (txc.mode == ADJ_OFFSET_SINGLESHOT) + if (txc.modes & ADJ_OFFSET) + if ((txc.modes == ADJ_OFFSET_SINGLESHOT) + || !(time_status & STA_PLL)) { time_adjust = txc.offset; } - else /* XXX should give an error if other bits set */ + else if ((time_status & STA_PLL)||(time_status & STA_PPSTIME)) { - time_offset = txc.offset << SHIFT_UPDATE; - mtemp = xtime.tv_sec - time_reftime; - time_reftime = xtime.tv_sec; - if (mtemp > (MAXSEC+2) || mtemp < 0) - mtemp = 0; - - if (txc.offset < 0) - time_freq -= (-txc.offset * mtemp) >> - (time_constant + time_constant); + ltemp = (time_status & STA_PPSTIME && + time_status & STA_PPSSIGNAL) ? + pps_offset : txc.offset; + + /* + * Scale the phase adjustment and + * clamp to the operating range. + */ + if (ltemp > MAXPHASE) + time_offset = MAXPHASE << SHIFT_UPDATE; + else if (ltemp < -MAXPHASE) + time_offset = -(MAXPHASE << SHIFT_UPDATE); else - time_freq += (txc.offset * mtemp) >> - (time_constant + time_constant); + time_offset = ltemp << SHIFT_UPDATE; - ltemp = time_tolerance << SHIFT_KF; + /* + * Select whether the frequency is to be controlled and in which + * mode (PLL or FLL). Clamp to the operating range. Ugly + * multiply/divide should be replaced someday. + */ - if (time_freq > ltemp) - time_freq = ltemp; - else if (time_freq < -ltemp) - time_freq = -ltemp; + if (time_status & STA_FREQHOLD || time_reftime == 0) + time_reftime = xtime.tv_sec; + mtemp = xtime.tv_sec - time_reftime; + time_reftime = xtime.tv_sec; + if (time_status & STA_FLL) + { + if (mtemp >= MINSEC) + { + ltemp = ((time_offset / mtemp) << (SHIFT_USEC - + SHIFT_UPDATE)); + if (ltemp < 0) + time_freq -= -ltemp >> SHIFT_KH; + else + time_freq += ltemp >> SHIFT_KH; + } + } + else + { + if (mtemp < MAXSEC) + { + ltemp *= mtemp; + if (ltemp < 0) + time_freq -= -ltemp >> (time_constant + + time_constant + SHIFT_KF - + SHIFT_USEC); + else + time_freq += ltemp >> (time_constant + + time_constant + SHIFT_KF - + SHIFT_USEC); + } + } + if (time_freq > time_tolerance) + time_freq = time_tolerance; + else if (time_freq < -time_tolerance) + time_freq = -time_tolerance; } - if (txc.mode & ADJ_TICK) + if (txc.modes & ADJ_TICK) tick = txc.tick; } txc.offset = save_adjust; - txc.frequency = ((time_freq+1) >> (SHIFT_KF - 16)); + txc.freq = time_freq; txc.maxerror = time_maxerror; txc.esterror = time_esterror; txc.status = time_status; - txc.time_constant = time_constant; + txc.constant = time_constant; txc.precision = time_precision; txc.tolerance = time_tolerance; txc.time = xtime; txc.tick = tick; + txc.ppsfreq = pps_freq; + txc.jitter = pps_jitter; + txc.shift = pps_shift; + txc.stabil = pps_stabil; + txc.jitcnt = pps_jitcnt; + txc.calcnt = pps_calcnt; + txc.errcnt = pps_errcnt; + txc.stbcnt = pps_stbcnt; sti(); memcpy_tofs(txc_p, &txc, sizeof(struct timex)); - return time_status; + return time_state; } /* diff --git a/mm/kmalloc.c b/mm/kmalloc.c index ec810867cd14..2e73a927d58b 100644 --- a/mm/kmalloc.c +++ b/mm/kmalloc.c @@ -87,7 +87,7 @@ struct size_descriptor { }; /* - * For now it is unsafe to allocate bucket sizes between n & n=16 where n is + * For now it is unsafe to allocate bucket sizes between n and n-16 where n is * 4096 * any power of two */ #if PAGE_SIZE == 4096 @@ -293,7 +293,7 @@ void kfree(void *ptr) } if ((order < 0) || - (order > sizeof(sizes) / sizeof(sizes[0])) || + (order >= sizeof(sizes) / sizeof(sizes[0])) || (((long) (page->next)) & ~PAGE_MASK) || (p->bh_flags != MF_USED)) { printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n", diff --git a/mm/swap.c b/mm/swap.c index fe74f8073562..c952bf1c3959 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -41,7 +41,7 @@ static struct { static struct swap_info_struct { unsigned int flags; - unsigned int swap_device; + kdev_t swap_device; struct inode * swap_file; unsigned char * swap_map; unsigned char * swap_lockmap; @@ -707,7 +707,8 @@ static inline void check_free_buffers(unsigned long addr) if (bh) { struct buffer_head *tmp = bh; do { - if (tmp->b_list == BUF_SHARED && tmp->b_dev != 0xffff) + if (tmp->b_list == BUF_SHARED + && tmp->b_dev != B_FREE) refile_buffer(tmp); tmp = tmp->b_this_page; } while (tmp != bh); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index a1482fea8fa0..3ae6d882303b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -31,8 +31,11 @@ static inline void set_pgdir(unsigned long address, pgd_t entry) { struct task_struct * p; - for_each_task(p) + for_each_task(p) { + if (!p->mm) + continue; *pgd_offset(p->mm,address) = entry; + } } static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 639f29122b3f..282f5f2ecd68 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5137,7 +5137,10 @@ static void tcp_write_wakeup(struct sock *sk) struct iphdr *iph; struct tcphdr *th; struct tcphdr *nth; - unsigned long win_size, ow_size; + unsigned long win_size; +#if 0 + unsigned long ow_size; +#endif void * tcp_data_start; /* diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index f41d5107d7ba..35b0ec31d1be 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -29,6 +29,7 @@ #include #include #include /* For the statistics structure. */ +#include #include #include @@ -41,7 +42,6 @@ #include #include -#include #include #include diff --git a/scripts/Configure b/scripts/Configure index 9a1b8be380a7..6eb7153de541 100644 --- a/scripts/Configure +++ b/scripts/Configure @@ -124,6 +124,36 @@ function tristate () { define_bool "$2" "$ans" } +# +# dep_tristate processes a tristate argument +# +# tristate question define default that depends upon +# another option. If the option we depend upon is a module, +# then the only allowable options are M or N. If Y, then +# this is a normal tristate. This is used in cases where modules +# are nested, and one module requires the presence of something +# else in the kernel. +# +function dep_tristate () { + if [ "$4" != "m" ]; then + tristate "$1" "$2" "$3" + else + ans="" + def=$(eval echo "\${$2:-$3}") + case "$def" in + "y" | "m") defprompt="M/n" + def="m" + ;; + "n") defprompt="N/m" + ;; + esac + while [ "$ans" != "n" -a "$ans" != "m" ]; do + readln "$1 ($2) [$defprompt] " "$def" + done + define_bool "$2" "$ans" + fi +} + # # define_int sets the value of a integer argument # @@ -248,9 +278,9 @@ if [ -f ./.config ] ; then fi . $CONFIG_IN -if [ "$CONFIG_SOUND" = "y" ] ; then - $MAKE -C drivers/sound config || exit 1 -fi +case "$CONFIG_SOUND" in + [YyMm] ) $MAKE -C drivers/sound config || exit 1 ;; +esac rm -f .config.old if [ -f .config ]; then -- 2.39.5