Linux Kernel Patch v2.3, patch-2.3.3 (0/4)

7 views
Skip to first unread message

Thomas...@ciw.uni-karlsruhe.de

unread,
May 18, 1999, 3:00:00 AM5/18/99
to
Archive-name: v2.3/patch-2.3.3/part0

lines added deleted
linux/CREDITS : 24 10 1
linux/Documentation/Configure.help : 29 15 5
linux/Documentation/filesystems/hpfs.txt : 39 8 7
linux/Documentation/mtrr.txt : 30 7 3
linux/MAINTAINERS : 12 6 0
linux/arch/i386/Makefile : 30 8 3
linux/arch/i386/lib/checksum.S : 32 8 4
linux/arch/m68k/atari/stdma.c : 8 1 1
linux/arch/m68k/mac/adb-bus.c : 29 4 4
linux/arch/mips/kernel/irixsig.c : 8 1 1
linux/arch/ppc/8xx_io/uart.c : 19 3 3
linux/arch/sparc/defconfig : 7 1 0
linux/arch/sparc64/defconfig : 7 1 0
linux/arch/sparc64/kernel/sys_sparc32.c : 128 100 4
linux/arch/sparc64/solaris/fs.c : 5 1 1
linux/arch/sparc64/solaris/ipc.c : 13 2 1
linux/drivers/acorn/block/fd1772.c : 8 1 1
linux/drivers/acorn/block/mfmhd.c : 8 1 1
linux/drivers/ap1000/ap.c : 8 1 1
linux/drivers/ap1000/ddv.c : 17 2 2
linux/drivers/block/Makefile : 8 1 1
linux/drivers/block/acsi.c : 44 9 9
linux/drivers/block/ataflop.c : 44 7 17
linux/drivers/block/blkpg.c : 288 288 0
linux/drivers/block/cmd646.c : 5 1 1
linux/drivers/block/floppy.c : 50 8 15
linux/drivers/block/genhd.c : 114 19 29
linux/drivers/block/hd.c : 58 11 17
linux/drivers/block/ide.c : 169 7 124
linux/drivers/block/md.c : 91 7 49
linux/drivers/block/paride/pd.c : 59 9 20
linux/drivers/block/paride/pf.c : 45 7 19
linux/drivers/block/ps2esdi.c : 53 10 18
linux/drivers/block/rd.c : 32 6 6
linux/drivers/block/xd.c : 46 10 13
linux/drivers/cdrom/gscd.c : 8 1 1
linux/drivers/cdrom/sbpcd.c : 8 1 1
linux/drivers/char/cyclades.c : 8 1 1
linux/drivers/char/dn_keyb.c : 8 1 1
linux/drivers/char/h8.c : 17 2 2
linux/drivers/char/keyboard.c : 50 11 2
linux/drivers/char/pcxx.c : 8 1 1
linux/drivers/char/pcxx.h : 10 2 2
linux/drivers/char/planb.c : 8 1 1
linux/drivers/char/planb.h : 24 3 3
linux/drivers/char/serial167.c : 8 1 1
linux/drivers/isdn/avmb1/capidev.h : 8 1 1
linux/drivers/isdn/pcbit/pcbit.h : 8 1 1
linux/drivers/macintosh/adb.c : 17 2 2
linux/drivers/macintosh/mac_keyb.c : 8 1 1
linux/drivers/macintosh/macserial.c : 8 1 1
linux/drivers/macintosh/macserial.h : 10 2 2
linux/drivers/misc/parport_init.c : 21 3 2
linux/drivers/misc/parport_pc.c : 396 63 50
linux/drivers/net/cosa.c : 27 4 3
linux/drivers/net/de620.c : 8 1 1
linux/drivers/net/sunhme.c : 8 1 1
linux/drivers/net/z85230.h : 10 2 2
linux/drivers/sbus/char/pcikbd.c : 14 3 1
linux/drivers/scsi/sd_ioctl.c : 55 7 28
linux/drivers/scsi/sr_ioctl.c : 62 7 32
linux/drivers/scsi/st.h : 8 1 1
linux/drivers/sgi/char/sgiserial.c : 17 2 2
linux/drivers/sgi/char/sgiserial.h : 10 2 2
linux/drivers/sgi/char/shmiq.c : 8 1 1
linux/drivers/sgi/char/usema.c : 8 1 1
linux/drivers/sound/lowlevel/awe_compat.h : 8 1 1
linux/drivers/sound/lowlevel/awe_wave.c : 8 1 1
linux/drivers/sound/msnd.h : 11 3 2
linux/drivers/usb/Config.in : 12 5 0
linux/drivers/usb/README.ohci : 31 28 0
linux/drivers/usb/ohci-debug.c : 48 11 8
linux/drivers/usb/ohci.c : 1247 486 226
linux/drivers/usb/ohci.h : 127 38 16
linux/fs/ChangeLog : 33 0 17
linux/fs/Config.in : 8 1 1
linux/fs/affs/namei.c : 8 1 1
linux/fs/devices.c : 8 1 1
linux/fs/ext2/namei.c : 8 1 1
linux/fs/ext2/truncate.c : 17 2 2
linux/fs/hfs/bnode.c : 8 1 1
linux/fs/hfs/catalog.c : 17 2 2
linux/fs/hpfs/alloc.c : 34 9 3
linux/fs/hpfs/dentry.c : 38 8 8
linux/fs/hpfs/dir.c : 159 31 60
linux/fs/hpfs/dnode.c : 114 15 23
linux/fs/hpfs/file.c : 7 0 1
linux/fs/hpfs/hpfs_fn.h : 34 6 2
linux/fs/hpfs/inode.c : 52 10 9
linux/fs/hpfs/name.c : 29 8 6
linux/fs/hpfs/namei.c : 334 61 96
linux/fs/hpfs/super.c : 53 7 5
linux/fs/minix/namei.c : 8 1 1
linux/fs/namei.c : 19 1 5
linux/fs/nfsd/vfs.c : 8 2 0
linux/fs/super.c : 9 2 1
linux/fs/sysv/namei.c : 8 1 1
linux/fs/ufs/namei.c : 8 1 1
linux/include/asm-alpha/processor.h : 8 1 1
linux/include/asm-alpha/semaphore.h : 8 1 1
linux/include/asm-arm/semaphore.h : 8 1 1
linux/include/asm-m68k/adb_mouse.h : 8 1 1
linux/include/asm-m68k/atari_joystick.h : 8 1 1
linux/include/asm-m68k/mac_mouse.h : 8 1 1
linux/include/asm-m68k/semaphore.h : 8 1 1
linux/include/asm-mips/semaphore.h : 8 1 1
linux/include/asm-ppc/adb_mouse.h : 8 1 1
linux/include/asm-ppc/semaphore.h : 8 1 1
linux/include/asm-sparc/io.h : 5 1 1
linux/include/asm-sparc64/hdreg.h : 5 1 1
linux/include/asm-sparc64/ide.h : 14 3 1
linux/include/asm-sparc64/io.h : 5 1 1
linux/include/linux/blk.h : 12 0 6
linux/include/linux/blkpg.h : 64 64 0
linux/include/linux/fs.h : 30 8 2
linux/include/linux/genhd.h : 38 7 9
linux/include/linux/hpfs_fs_sb.h : 24 3 3
linux/include/linux/istallion.h : 12 3 3
linux/include/linux/lp_m68k.h : 8 1 1
linux/include/linux/netdevice.h : 8 1 1
linux/include/linux/parport.h : 7 1 0
linux/include/linux/parport_pc.h : 126 24 24
linux/include/linux/rpcsock.h : 19 3 3
linux/include/linux/serial167.h : 10 2 2
linux/include/linux/stallion.h : 10 2 2
linux/include/linux/swap.h : 7 1 0
linux/include/linux/umsdos_fs_i.h : 8 1 1
linux/kernel/ksyms.c : 15 2 0
linux/mm/mlock.c : 14 4 3
linux/mm/swapfile.c : 18 12 0
linux/net/core/filter.c : 8 1 1
linux/net/ipv4/tcp_timer.c : 19 1 5
linux/net/ipv6/exthdrs.c : 8 1 1
linux/net/netlink/af_netlink.c : 8 1 1
--
Thomas Koenig, Thomas...@ciw.uni-karlsruhe.de, ig...@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.

Thomas...@ciw.uni-karlsruhe.de

unread,
May 18, 1999, 3:00:00 AM5/18/99
to
Archive-name: v2.3/patch-2.3.3/part2

#!/bin/sh
# this is part 2 of a 4 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.3 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 2; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.3.3'
else
echo 'x - continuing with patch-2.3.3'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.3' &&
@@ -279,7 +279,8 @@
X u_char type;
X
X /* the XOR below used to be an OR */
- int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
+ int shift_final = (shift_state | kbd->slockstate) ^
+ kbd->lockstate;
X ushort *key_map = key_maps[shift_final];
X
X if (key_map != NULL) {
@@ -311,6 +312,7 @@
X /* we have at least to update shift_state */
X #if 1 /* how? two almost equivalent choices follow */
X compute_shiftstate();
+ kbd->slockstate = 0; /* play it safe */
X #else
X keysym = U(plain_map[keycode]);
X type = KTYP(keysym);
@@ -472,6 +474,7 @@
X
X static void boot_it(void)
X {
+ if (kbd->slockstate & ~shift_state) return;
X ctrl_alt_del();
X }
X
@@ -741,7 +744,7 @@
X for(j=0; j<BITS_PER_LONG; j++,k++)
X if(test_bit(k, key_down)) {
X sym = U(plain_map[k]);
- if(KTYP(sym) == KT_SHIFT) {
+ if(KTYP(sym) == KT_SHIFT || KTYP(sym) == KT_SLOCK) {
X val = KVAL(sym);
X if (val == KVAL(K_CAPSSHIFT))
X val = KVAL(K_SHIFT);
@@ -793,9 +796,15 @@
X
X static void do_slock(unsigned char value, char up_flag)
X {
+ do_shift(value,up_flag);
X if (up_flag || rep)
X return;
X chg_vc_kbd_slock(kbd, value);
+ /* try to make Alt, oops, AltGr and such work */
+ if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
+ kbd->slockstate = 0;
+ chg_vc_kbd_slock(kbd, value);
+ }
X }
X
X /*
diff -u --recursive --new-file v2.3.2/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c
--- v2.3.2/linux/drivers/char/pcxx.c Wed Mar 10 16:51:35 1999
+++ linux/drivers/char/pcxx.c Sat May 15 15:05:36 1999
@@ -326,7 +326,7 @@
X
X static int pcxx_waitcarrier(struct tty_struct *tty,struct file *filp,struct channel *info)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X int retval = 0;
X int do_clocal = 0;
X
diff -u --recursive --new-file v2.3.2/linux/drivers/char/pcxx.h linux/drivers/char/pcxx.h
--- v2.3.2/linux/drivers/char/pcxx.h Sun Apr 13 10:18:20 1997
+++ linux/drivers/char/pcxx.h Sat May 15 15:05:36 1999
@@ -88,8 +88,8 @@
X int blocked_open;
X int close_delay;
X int event;
- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;
X struct tq_struct tqueue;
X /* ------------ Async control data ------------- */
X unchar modemfake; /* Modem values to be forced */
diff -u --recursive --new-file v2.3.2/linux/drivers/char/planb.c linux/drivers/char/planb.c
--- v2.3.2/linux/drivers/char/planb.c Mon May 10 10:17:28 1999
+++ linux/drivers/char/planb.c Sat May 15 15:05:36 1999
@@ -379,7 +379,7 @@
X
X static void __planb_wait(struct planb *pb)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X
X add_wait_queue(&pb->lockq, &wait);
X repeat:
diff -u --recursive --new-file v2.3.2/linux/drivers/char/planb.h linux/drivers/char/planb.h
--- v2.3.2/linux/drivers/char/planb.h Fri May 7 11:05:30 1999
+++ linux/drivers/char/planb.h Sat May 15 15:05:36 1999
@@ -175,7 +175,7 @@
X unsigned int tab_size;
X int maxlines;
X int lock;
- struct wait_queue *lockq;
+ wait_queue_head_t lockq;
X unsigned int irq; /* interrupt number */
X volatile unsigned int intr_mask;
X
@@ -190,13 +190,13 @@
X unsigned long ch1_cmd_phys;
X volatile unsigned char *mask; /* Clipmask buffer */
X int suspend;
- struct wait_queue *suspendq;
+ wait_queue_head_t suspendq;
X struct planb_suspend suspended;
X int cmd_buff_inited; /* cmd buffer inited? */
X
X int grabbing;
X unsigned int gcount;
- struct wait_queue *capq;
+ wait_queue_head_t capq;
X int last_fr;
X int prev_last_fr;
X unsigned char *fbuffer;
diff -u --recursive --new-file v2.3.2/linux/drivers/char/serial167.c linux/drivers/char/serial167.c
--- v2.3.2/linux/drivers/char/serial167.c Thu Nov 5 09:58:43 1998
+++ linux/drivers/char/serial167.c Sat May 15 15:05:36 1999
@@ -2007,7 +2007,7 @@
X block_til_ready(struct tty_struct *tty, struct file * filp,
X struct cyclades_port *info)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X unsigned long flags;
X int channel;
X int retval;
diff -u --recursive --new-file v2.3.2/linux/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- v2.3.2/linux/drivers/isdn/avmb1/capidev.h Thu May 29 21:53:05 1997
+++ linux/drivers/isdn/avmb1/capidev.h Sat May 15 15:05:36 1999
@@ -22,7 +22,7 @@
X int is_registered;
X __u16 applid;
X struct sk_buff_head recv_queue;
- struct wait_queue *recv_wait;
+ wait_queue_head_t recv_wait;
X __u16 errcode;
X };
X
diff -u --recursive --new-file v2.3.2/linux/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h
--- v2.3.2/linux/drivers/isdn/pcbit/pcbit.h Tue Aug 4 10:31:59 1998
+++ linux/drivers/isdn/pcbit/pcbit.h Sat May 15 15:05:36 1999
@@ -68,7 +68,7 @@
X struct frame_buf *write_queue;
X
X /* Protocol start */
- struct wait_queue *set_running_wq;
+ wait_queue_head_t set_running_wq;
X struct timer_list set_running_timer;
X
X struct timer_list error_recover_timer;
diff -u --recursive --new-file v2.3.2/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c
--- v2.3.2/linux/drivers/macintosh/adb.c Thu Apr 29 12:53:48 1999
+++ linux/drivers/macintosh/adb.c Sat May 15 15:05:36 1999
@@ -375,7 +375,7 @@
X spinlock_t lock;
X atomic_t n_pending;
X struct adb_request *completed;
- struct wait_queue *wait_queue;
+ wait_queue_head_t wait_queue;
X int inuse;
X };
X
@@ -458,7 +458,7 @@
X int ret;
X struct adbdev_state *state = file->private_data;
X struct adb_request *req;
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X unsigned long flags;
X
X if (count < 2)
diff -u --recursive --new-file v2.3.2/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
--- v2.3.2/linux/drivers/macintosh/mac_keyb.c Thu Apr 29 12:53:48 1999
+++ linux/drivers/macintosh/mac_keyb.c Sat May 15 15:05:36 1999
@@ -251,7 +251,7 @@
X extern int console_loglevel;
X
X extern struct kbd_struct kbd_table[];
-extern struct wait_queue * keypress_wait;
+extern struct wait_queue_head_t keypress_wait;
X
X extern void handle_scancode(unsigned char, int);
X
diff -u --recursive --new-file v2.3.2/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.3.2/linux/drivers/macintosh/macserial.c Thu Apr 29 12:53:48 1999
+++ linux/drivers/macintosh/macserial.c Sat May 15 15:05:36 1999
@@ -1595,7 +1595,7 @@
X static int block_til_ready(struct tty_struct *tty, struct file * filp,
X struct mac_serial *info)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait,current);
X int retval;
X int do_clocal = 0;
X
diff -u --recursive --new-file v2.3.2/linux/drivers/macintosh/macserial.h linux/drivers/macintosh/macserial.h
--- v2.3.2/linux/drivers/macintosh/macserial.h Wed Mar 10 21:48:46 1999
+++ linux/drivers/macintosh/macserial.h Sat May 15 15:05:36 1999
@@ -153,8 +153,8 @@
X struct tq_struct tqueue_hangup;
X struct termios normal_termios;
X struct termios callout_termios;
- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;
X };
X
X
diff -u --recursive --new-file v2.3.2/linux/drivers/misc/parport_init.c linux/drivers/misc/parport_init.c
--- v2.3.2/linux/drivers/misc/parport_init.c Tue May 11 09:55:49 1999
+++ linux/drivers/misc/parport_init.c Sun May 16 10:55:21 1999
@@ -20,10 +20,11 @@
X
X #ifndef MODULE
X static int io[PARPORT_MAX+1] __initdata = { [0 ... PARPORT_MAX] = 0 };
+static int io_hi[PARPORT_MAX+1] __initdata = { [0 ... PARPORT_MAX] = 0 };
X static int irq[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_IRQ_PROBEONLY };
X static int dma[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_DMA_NONE };
X
-extern int parport_pc_init(int *io, int *irq, int *dma);
+extern int parport_pc_init(int *io, int *io_hi, int *irq, int *dma);
X extern int parport_ax_init(void);
X
X static int parport_setup_ptr __initdata = 0;
@@ -121,7 +122,7 @@
X parport_proc_init();
X #endif
X #ifdef CONFIG_PARPORT_PC
- parport_pc_init(io, irq, dma);
+ parport_pc_init(io, io_hi, irq, dma);
X #endif
X #ifdef CONFIG_PARPORT_AX
X parport_ax_init();
diff -u --recursive --new-file v2.3.2/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- v2.3.2/linux/drivers/misc/parport_pc.c Mon May 10 10:26:31 1999
+++ linux/drivers/misc/parport_pc.c Sun May 16 10:10:00 1999
@@ -36,6 +36,7 @@
X
X #include <linux/config.h>
X #include <linux/module.h>
+#include <linux/init.h>
X #include <linux/sched.h>
X #include <linux/delay.h>
X #include <linux/errno.h>
@@ -53,7 +54,7 @@
X than PARPORT_MAX (in <linux/parport.h>). */
X #define PARPORT_PC_MAX_PORTS 8
X
-static int user_specified = 0;
+static int user_specified __initdata = 0;
X
X static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
X {
@@ -62,27 +63,27 @@
X
X void parport_pc_write_epp(struct parport *p, unsigned char d)
X {
- outb(d, p->base+EPPDATA);
+ outb(d, EPPDATA(p));
X }
X
X unsigned char parport_pc_read_epp(struct parport *p)
X {
- return inb(p->base+EPPDATA);
+ return inb(EPPDATA(p));
X }
X
X void parport_pc_write_epp_addr(struct parport *p, unsigned char d)
X {
- outb(d, p->base+EPPADDR);
+ outb(d, EPPADDR(p));
X }
X
X unsigned char parport_pc_read_epp_addr(struct parport *p)
X {
- return inb(p->base+EPPADDR);
+ return inb(EPPADDR(p));
X }
X
X int parport_pc_check_epp_timeout(struct parport *p)
X {
- if (!(inb(p->base+STATUS) & 1))
+ if (!(inb(STATUS(p)) & 1))
X return 0;
X parport_pc_epp_clear_timeout(p);
X return 1;
@@ -90,24 +91,24 @@
X
X unsigned char parport_pc_read_configb(struct parport *p)
X {
- return inb(p->base+CONFIGB);
+ return inb(CONFIGB(p));
X }
X
X void parport_pc_write_data(struct parport *p, unsigned char d)
X {
- outb(d, p->base+DATA);
+ outb(d, DATA(p));
X }
X
X unsigned char parport_pc_read_data(struct parport *p)
X {
- return inb(p->base+DATA);
+ return inb(DATA(p));
X }
X
X void parport_pc_write_control(struct parport *p, unsigned char d)
X {
X struct parport_pc_private *priv = p->private_data;
X priv->ctr = d;/* update soft copy */
- outb(d, p->base+CONTROL);
+ outb(d, CONTROL(p));
X }
X
X unsigned char parport_pc_read_control(struct parport *p)
@@ -121,34 +122,34 @@
X struct parport_pc_private *priv = p->private_data;
X unsigned char ctr = priv->ctr;
X ctr = (ctr & ~mask) ^ val;
- outb (ctr, p->base+CONTROL);
+ outb (ctr, CONTROL(p));
X return priv->ctr = ctr; /* update soft copy */
X }
X
X void parport_pc_write_status(struct parport *p, unsigned char d)
X {
- outb(d, p->base+STATUS);
+ outb(d, STATUS(p));
X }
X
X unsigned char parport_pc_read_status(struct parport *p)
X {
- return inb(p->base+STATUS);
+ return inb(STATUS(p));
X }
X
X void parport_pc_write_econtrol(struct parport *p, unsigned char d)
X {
- outb(d, p->base+ECONTROL);
+ outb(d, ECONTROL(p));
X }
X
X unsigned char parport_pc_read_econtrol(struct parport *p)
X {
- return inb(p->base+ECONTROL);
+ return inb(ECONTROL(p));
X }
X
X unsigned char parport_pc_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val)
X {
- unsigned char old = inb(p->base+ECONTROL);
- outb(((old & ~mask) ^ val), p->base+ECONTROL);
+ unsigned char old = inb(ECONTROL(p));
+ outb(((old & ~mask) ^ val), ECONTROL(p));
X return old;
X }
X
@@ -159,12 +160,12 @@
X
X void parport_pc_write_fifo(struct parport *p, unsigned char v)
X {
- outb (v, p->base+CONFIGA);
+ outb (v, CONFIGA(p));
X }
X
X unsigned char parport_pc_read_fifo(struct parport *p)
X {
- return inb (p->base+CONFIGA);
+ return inb (CONFIGA(p));
X }
X
X void parport_pc_disable_irq(struct parport *p)
@@ -183,7 +184,7 @@
X free_irq(p->irq, p);
X release_region(p->base, p->size);
X if (p->modes & PARPORT_MODE_PCECR)
- release_region(p->base+0x400, 3);
+ release_region(p->base_hi, 3);
X }
X
X int parport_pc_claim_resources(struct parport *p)
@@ -195,7 +196,7 @@
X return err;
X request_region(p->base, p->size, p->name);
X if (p->modes & PARPORT_MODE_PCECR)
- request_region(p->base+0x400, 3, p->name);
+ request_region(p->base_hi, 3, p->name);
X return 0;
X }
X
@@ -223,8 +224,8 @@
X {
X size_t got = 0;
X for (; got < length; got++) {
- *((char*)buf)++ = inb (p->base+EPPDATA);
- if (inb (p->base+STATUS) & 0x01)
+ *((char*)buf)++ = inb (EPPDATA(p));
+ if (inb (STATUS(p)) & 0x01)
X break;
X }
X return got;
@@ -234,8 +235,8 @@
X {
X size_t written = 0;
X for (; written < length; written++) {
- outb (*((char*)buf)++, p->base+EPPDATA);
- if (inb (p->base+STATUS) & 0x01)
+ outb (*((char*)buf)++, EPPDATA(p));
+ if (inb (STATUS(p)) & 0x01)
X break;
X }
X return written;
@@ -350,7 +351,7 @@
X /*
X * Checks for port existence, all ports support SPP MODE
X */
-static int parport_SPP_supported(struct parport *pb)
+static int __init parport_SPP_supported(struct parport *pb)
X {
X unsigned char r, w;
X
@@ -370,11 +371,11 @@
X * allow reads, so read_control just returns a software
X * copy. Some ports _do_ allow reads, so bypass the software
X * copy here. In addition, some bits aren't writable. */
- r = inb (pb->base+CONTROL);
+ r = inb (CONTROL (pb));
X if ((r & 0x3f) == w) {
X w = 0xe;
X parport_pc_write_control (pb, w);
- r = inb (pb->base+CONTROL);
+ r = inb (CONTROL(pb));
X parport_pc_write_control (pb, 0xc);
X if ((r & 0x3f) == w)
X return PARPORT_MODE_PCSPP;
@@ -425,7 +426,7 @@
X * We will write 0x2c to ECR and 0xcc to CTR since both of these
X * values are "safe" on the CTR since bits 6-7 of CTR are unused.
X */
-static int parport_ECR_present(struct parport *pb)
+static int __init parport_ECR_present(struct parport *pb)
X {
X unsigned char r;
X
@@ -458,7 +459,7 @@
X return 0;
X }
X
-static int parport_ECP_supported(struct parport *pb)
+static int __init parport_ECP_supported(struct parport *pb)
X {
X int i;
X unsigned char oecr;
@@ -493,7 +494,7 @@
X * or writing a 1 to the bit (SMC, UMC, WinBond), others ???
X * This bit is always high in non EPP modes.
X */
-static int parport_EPP_supported(struct parport *pb)
+static int __init parport_EPP_supported(struct parport *pb)
X {
X /* If EPP timeout bit clear then EPP available */
X if (!parport_pc_epp_clear_timeout(pb))
@@ -514,7 +515,7 @@
X return 0;
X }
X
-static int parport_ECPEPP_supported(struct parport *pb)
+static int __init parport_ECPEPP_supported(struct parport *pb)
X {
X int mode;
X unsigned char oecr;
@@ -550,7 +551,7 @@
X * be misdetected here is rather academic.
X */
X
-static int parport_PS2_supported(struct parport *pb)
+static int __init parport_PS2_supported(struct parport *pb)
X {
X int ok = 0;
X unsigned char octr = parport_pc_read_control(pb);
@@ -570,7 +571,7 @@
X return ok?PARPORT_MODE_PCPS2:0;
X }
X
-static int parport_ECPPS2_supported(struct parport *pb)
+static int __init parport_ECPPS2_supported(struct parport *pb)
X {
X int mode;
X unsigned char oecr;
@@ -590,7 +591,7 @@
X /* --- IRQ detection -------------------------------------- */
X
X /* Only if supports ECP mode */
-static int programmable_irq_support(struct parport *pb)
+static int __init programmable_irq_support(struct parport *pb)
X {
X int irq, intrLine;
X unsigned char oecr = parport_pc_read_econtrol(pb);
@@ -607,7 +608,7 @@
X return irq;
X }
X
-static int irq_probe_ECP(struct parport *pb)
+static int __init irq_probe_ECP(struct parport *pb)
X {
X int irqs, i;
X
@@ -634,7 +635,7 @@
X * This detection seems that only works in National Semiconductors
X * This doesn't work in SMC, LGS, and Winbond
X */
-static int irq_probe_EPP(struct parport *pb)
+static int __init irq_probe_EPP(struct parport *pb)
X {
X int irqs;
X unsigned char octr = parport_pc_read_control(pb);
@@ -675,7 +676,7 @@
X return pb->irq;
X }
X
-static int irq_probe_SPP(struct parport *pb)
+static int __init irq_probe_SPP(struct parport *pb)
X {
X int irqs;
X unsigned char octr = parport_pc_read_control(pb);
@@ -723,7 +724,7 @@
X * When ECP is available we can autoprobe for IRQs.
X * NOTE: If we can autoprobe it, we can register the IRQ.
X */
-static int parport_irq_probe(struct parport *pb)
+static int __init parport_irq_probe(struct parport *pb)
X {
X if (pb->modes & PARPORT_MODE_PCECR) {
X pb->irq = programmable_irq_support(pb);
@@ -754,7 +755,9 @@
X
X /* --- Initialisation code -------------------------------- */
X
-static int probe_one_port(unsigned long int base, int irq, int dma)
+static int __init probe_one_port(unsigned long int base,
+ unsigned long int base_hi,
+ int irq, int dma)
X {
X struct parport *p;
X int probedirq = PARPORT_IRQ_NONE;
@@ -770,8 +773,9 @@
X return 0;
X }
X ((struct parport_pc_private *) (p->private_data))->ctr = 0xc;
+ p->base_hi = base_hi;
X if (p->base != 0x3bc) {
- if (!check_region(base+0x400,3)) {
+ if (base_hi && !check_region(base_hi,3)) {
X p->modes |= parport_ECR_present(p);
X p->modes |= parport_ECP_supported(p);
X p->modes |= parport_ECPPS2_supported(p);
@@ -791,6 +795,8 @@
X p->size = (p->modes & (PARPORT_MODE_PCEPP
X | PARPORT_MODE_PCECPEPP))?8:3;
X printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
+ if (p->base_hi && (p->modes & PARPORT_MODE_PCECR))
+ printk (" (0x%lx)", p->base_hi);
X if (p->irq == PARPORT_IRQ_AUTO) {
X p->irq = PARPORT_IRQ_NONE;
X parport_irq_probe(p);
@@ -829,11 +835,14 @@
X /* Done probing. Now put the port into a sensible start-up state. */
X if (p->modes & PARPORT_MODE_PCECR)
X /*
- * Put the ECP detected port in the more SPP like mode.
+ * Put the ECP detected port in PS2 mode.
X */
- parport_pc_write_econtrol(p, 0x0);
- parport_pc_write_control(p, 0xc);
+ parport_pc_write_econtrol(p, 0x24);
X parport_pc_write_data(p, 0);
+ parport_pc_write_control(p, 0x8);
+ udelay (50);
+ parport_pc_write_control(p, 0xc);
+ udelay (50);
X
X if (parport_probe_hook)
X (*parport_probe_hook)(p);
@@ -841,20 +850,22 @@
X return 1;
X }
X
-int parport_pc_init(int *io, int *irq, int *dma)
+int __init parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
X {
X int count = 0, i = 0;
X if (io && *io) {
X /* Only probe the ports we were given. */
X user_specified = 1;
X do {
- count += probe_one_port(*(io++), *(irq++), *(dma++));
+ if (!*io_hi) *io_hi = 0x400 + *io;
+ count += probe_one_port(*(io++), *(io_hi++),
+ *(irq++), *(dma++));
X } while (*io && (++i < PARPORT_PC_MAX_PORTS));
X } else {
X /* Probe all the likely ports. */
- count += probe_one_port(0x3bc, irq[0], dma[0]);
- count += probe_one_port(0x378, irq[0], dma[0]);
- count += probe_one_port(0x278, irq[0], dma[0]);
+ count += probe_one_port(0x3bc, 0x7bc, irq[0], dma[0]);
+ count += probe_one_port(0x378, 0x778, irq[0], dma[0]);
+ count += probe_one_port(0x278, 0x678, irq[0], dma[0]);
X }
X
X return count;
@@ -862,10 +873,12 @@
X
X #ifdef MODULE
X static int io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
+static int io_hi[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
X static int dma[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_DMA_NONE };
X static int irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY };
X static const char *irq[PARPORT_PC_MAX_PORTS] = { NULL, };
X MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
+MODULE_PARM(io_hi, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
X MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
X MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
X
@@ -877,7 +890,7 @@
X for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++);
X parport_parse_irqs(i, irq, irqval);
X
- return (parport_pc_init(io, irqval, dma)?0:1);
+ return (parport_pc_init(io, io_hi, irqval, dma)?0:1);
X }
X
X void cleanup_module(void)
diff -u --recursive --new-file v2.3.2/linux/drivers/net/cosa.c linux/drivers/net/cosa.c
--- v2.3.2/linux/drivers/net/cosa.c Sun Mar 7 15:47:46 1999
+++ linux/drivers/net/cosa.c Sat May 15 15:05:36 1999
@@ -126,7 +126,8 @@
X struct semaphore rsem, wsem;
X char *rxdata;
X int rxsize;
- struct wait_queue *txwaitq, *rxwaitq;
+ wait_queue_head_t txwaitq;
+ wait_queue_head_t rxwaitq;
X int tx_status, rx_status;
X
X /* SPPP/HDLC device parts */
@@ -762,7 +763,7 @@
X static ssize_t cosa_read(struct file *file,
X char *buf, size_t count, loff_t *ppos)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X int flags;
X struct channel_data *chan = (struct channel_data *)file->private_data;
X struct cosa_data *cosa = chan->cosa;
@@ -833,7 +834,7 @@
X const char *buf, size_t count, loff_t *ppos)
X {
X struct channel_data *chan = (struct channel_data *)file->private_data;
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X struct cosa_data *cosa = chan->cosa;
X unsigned int flags;
X char *kbuf;
diff -u --recursive --new-file v2.3.2/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.3.2/linux/drivers/net/de620.c Mon Mar 2 11:55:41 1998
+++ linux/drivers/net/de620.c Sat May 15 23:43:04 1999
@@ -664,7 +664,7 @@
X if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
X /* Ouch... Forget it! Skip all and start afresh... */
X printk("%s: Ring overrun? Restoring...\n", dev->name);
- /* You win some, you loose some. And sometimes plenty... */
+ /* You win some, you lose some. And sometimes plenty... */
X adapter_init(dev);
X ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
X return 0;
diff -u --recursive --new-file v2.3.2/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- v2.3.2/linux/drivers/net/sunhme.c Mon Mar 15 16:11:30 1999
+++ linux/drivers/net/sunhme.c Sat May 15 11:12:09 1999
@@ -1834,7 +1834,7 @@
X #define RXD(x)
X #endif
X
-/* Originally I use to handle the allocation failure by just giving back just
+/* Originally I used to handle the allocation failure by just giving back just
X * that one ring buffer to the happy meal. Problem is that usually when that
X * condition is triggered, the happy meal expects you to do something reasonable
X * with all of the packets it has DMA'd in. So now I just drop the entire
diff -u --recursive --new-file v2.3.2/linux/drivers/net/z85230.h linux/drivers/net/z85230.h
--- v2.3.2/linux/drivers/net/z85230.h Sat Oct 17 15:33:45 1998
+++ linux/drivers/net/z85230.h Sat May 15 15:05:36 1999
@@ -331,8 +331,8 @@
X int line; /* Minor number */
X struct termios normal_termios; /* Terminal settings */
X struct termios callout_termios;
- struct wait_queue *open_wait; /* Tasks waiting to open */
- struct wait_queue *close_wait; /* and for close to end */
+ wait_queue_head_t open_wait; /* Tasks waiting to open */
+ wait_queue_head_t close_wait; /* and for close to end */
X unsigned long event; /* Pending events */
X int fdcount; /* # of fd on device */
X int blocked_open; /* # of blocked opens */
diff -u --recursive --new-file v2.3.2/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- v2.3.2/linux/drivers/sbus/char/pcikbd.c Fri May 14 18:55:21 1999
+++ linux/drivers/sbus/char/pcikbd.c Sun May 16 19:15:57 1999
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.28 1999/05/12 11:15:05 davem Exp $
+/* $Id: pcikbd.c,v 1.29 1999/05/16 13:47:53 ecd Exp $
X * pcikbd.c: Ultra/AX PC keyboard support.
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -982,6 +982,8 @@
X return -ENOMEM;
X }
X memset(queue, 0, sizeof(*queue));
+
+ init_waitqueue_head(&queue->proc_list);
X
X if (request_irq(pcimouse_irq, &pcimouse_interrupt,
X SA_SHIRQ, "mouse", (void *)pcimouse_iobase)) {
diff -u --recursive --new-file v2.3.2/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v2.3.2/linux/drivers/scsi/sd_ioctl.c Wed Feb 24 16:27:54 1999
+++ linux/drivers/scsi/sd_ioctl.c Sat May 15 23:43:04 1999
@@ -15,6 +15,7 @@
X
X #define MAJOR_NR SCSI_DISK0_MAJOR
X #include <linux/blk.h>
+#include <linux/blkpg.h>
X #include "scsi.h"
X #include <scsi/scsi_ioctl.h>
X #include "hosts.h"
@@ -79,41 +80,19 @@
X (long *) arg);
X return 0;
X
+ case BLKROSET:
+ case BLKROGET:
X case BLKRASET:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;
-
X case BLKRAGET:
- if (!arg)
- return -EINVAL;
- error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
- if (error)
- return error;
- put_user(read_ahead[MAJOR(inode->i_rdev)], (long *) arg);
- return 0;
-
X case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;
-
+ case BLKSSZGET:
+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
+
X case BLKRRPART: /* Re-read partition tables */
X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;
X return revalidate_scsidisk(dev, 1);
-
- case BLKSSZGET:
- /* Block size of media */
- return put_user(blksize_size[MAJOR(dev)][MINOR(dev)&0x0F],
- (int *)arg);
-
- RO_IOCTLS(dev, arg);
X
X default:
X return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg);
diff -u --recursive --new-file v2.3.2/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.3.2/linux/drivers/scsi/sr_ioctl.c Sat May 15 23:46:03 1999
+++ linux/drivers/scsi/sr_ioctl.c Sat May 15 23:43:04 1999
@@ -7,6 +7,7 @@
X #include <linux/string.h>
X
X #include <linux/blk.h>
+#include <linux/blkpg.h>
X #include "scsi.h"
X #include "hosts.h"
X #include <scsi/scsi_ioctl.h>
@@ -768,7 +769,7 @@
X int sr_dev_ioctl(struct cdrom_device_info *cdi,
X unsigned int cmd, unsigned long arg)
X {
- int target, err;
+ int target;
X
X target = MINOR(cdi->dev);
X
@@ -855,40 +856,14 @@
X spin_unlock_irqrestore(&io_request_lock, flags);
X return rc;
X }
- case BLKRAGET:
- if (!arg)
- return -EINVAL;
- err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
- if (err)
- return err;
- put_user(read_ahead[MAJOR(cdi->dev)], (long *) arg);
- return 0;
X
+ case BLKROSET:
+ case BLKROGET:
X case BLKRASET:
- if(!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if(!(cdi->dev))
- return -EINVAL;
- if(arg > 0xff)
- return -EINVAL;
- read_ahead[MAJOR(cdi->dev)] = arg;
- return 0;
-
- case BLKSSZGET:
- /* Block size of media */
- return put_user(blksize_size[MAJOR(cdi->dev)][MINOR(cdi->dev)],
- (int *)arg);
-
- RO_IOCTLS(cdi->dev,arg);
-
+ case BLKRAGET:
X case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if(!(cdi->dev))
- return -EINVAL;
- fsync_dev(cdi->dev);
- invalidate_buffers(cdi->dev);
- return 0;
+ case BLKSSZGET:
+ return blk_ioctl(cdi->dev, cmd, arg);
X
X default:
X return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
diff -u --recursive --new-file v2.3.2/linux/drivers/scsi/st.h linux/drivers/scsi/st.h
--- v2.3.2/linux/drivers/scsi/st.h Sun Sep 6 09:48:30 1998
+++ linux/drivers/scsi/st.h Sat May 15 15:05:36 1999
@@ -65,7 +65,7 @@
X typedef struct {
X kdev_t devt;
X unsigned capacity;
- struct wait_queue * waiting;
+ wait_queue_head_t waiting;
X Scsi_Device* device;
X struct semaphore sem;
X ST_buffer * buffer;
diff -u --recursive --new-file v2.3.2/linux/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- v2.3.2/linux/drivers/sgi/char/sgiserial.c Thu Nov 5 09:58:44 1998
+++ linux/drivers/sgi/char/sgiserial.c Sat May 15 15:05:36 1999
@@ -33,7 +33,7 @@
X #define NUM_SERIAL 1 /* One chip on board. */
X #define NUM_CHANNELS (NUM_SERIAL * 2)
X
-extern struct wait_queue * keypress_wait;
+extern struct wait_queue_head_t keypress_wait;
X
X struct sgi_zslayout *zs_chips[NUM_SERIAL] = { 0, };
X struct sgi_zschannel *zs_channels[NUM_CHANNELS] = { 0, 0, };
@@ -1519,7 +1519,7 @@
X static int block_til_ready(struct tty_struct *tty, struct file * filp,
X struct sgi_serial *info)
X {
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X int retval;
X int do_clocal = 0;
X
diff -u --recursive --new-file v2.3.2/linux/drivers/sgi/char/sgiserial.h linux/drivers/sgi/char/sgiserial.h
--- v2.3.2/linux/drivers/sgi/char/sgiserial.h Wed Dec 10 10:31:11 1997
+++ linux/drivers/sgi/char/sgiserial.h Sat May 15 15:05:36 1999
@@ -158,8 +158,8 @@
X struct tq_struct tqueue_hangup;
X struct termios normal_termios;
X struct termios callout_termios;
- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;
X };
X
X
diff -u --recursive --new-file v2.3.2/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.3.2/linux/drivers/sgi/char/shmiq.c Mon Aug 24 13:14:10 1998
+++ linux/drivers/sgi/char/shmiq.c Sat May 15 15:05:36 1999
@@ -82,7 +82,7 @@
X int events;
X int mapped;
X
- struct wait_queue *proc_list;
+ wait_queue_head_t proc_list;
X struct fasync_struct *fasync;
X } shmiqs [MAX_SHMI_QUEUES];
X
diff -u --recursive --new-file v2.3.2/linux/drivers/sgi/char/usema.c linux/drivers/sgi/char/usema.c
--- v2.3.2/linux/drivers/sgi/char/usema.c Mon Aug 24 13:02:44 1998
+++ linux/drivers/sgi/char/usema.c Sat May 15 15:05:36 1999
@@ -39,7 +39,7 @@
X
X struct irix_usema {
X struct file *filp;
- struct wait_queue *proc_list;
+ wait_queue_head_t proc_list;
X };
X
X static int
diff -u --recursive --new-file v2.3.2/linux/drivers/sound/lowlevel/awe_compat.h linux/drivers/sound/lowlevel/awe_compat.h
--- v2.3.2/linux/drivers/sound/lowlevel/awe_compat.h Sun Mar 7 15:22:06 1999
+++ linux/drivers/sound/lowlevel/awe_compat.h Sat May 15 15:05:36 1999
@@ -245,7 +245,7 @@
X #endif /* AWE_MODULE_SUPPORT */
X
X #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
-inline static void interruptible_sleep_on_timeout(struct wait_queue **q, unsigned long timeout)
+inline static void interruptible_sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout)
X {
X current->timeout = jiffies + timeout;
X interruptible_sleep_on(q);
diff -u --recursive --new-file v2.3.2/linux/drivers/sound/lowlevel/awe_wave.c linux/drivers/sound/lowlevel/awe_wave.c
--- v2.3.2/linux/drivers/sound/lowlevel/awe_wave.c Sun Mar 7 15:22:06 1999
+++ linux/drivers/sound/lowlevel/awe_wave.c Sat May 15 15:05:36 1999
@@ -979,7 +979,7 @@
X }
X #else
X
-static struct wait_queue *awe_sleeper = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(awe_sleeper);
X static void awe_wait(unsigned short delay)
X {
X interruptible_sleep_on_timeout(&awe_sleeper, (HZ * (unsigned long)delay + 44099) / 44100);
diff -u --recursive --new-file v2.3.2/linux/drivers/sound/msnd.h linux/drivers/sound/msnd.h
--- v2.3.2/linux/drivers/sound/msnd.h Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/msnd.h Sat May 15 15:05:37 1999
@@ -231,8 +231,9 @@
X #define F_EXT_MIDI_INUSE 9
X #define F_INT_MIDI_INUSE 10
X #define F_DISABLE_WRITE_NDELAY 11
- struct wait_queue *writeblock, *readblock;
- struct wait_queue *writeflush;
+ wait_queue_head_t writeblock;
+ wait_queue_head_t readblock;
+ wait_queue_head_t writeflush;
X #ifndef LINUX20
X spinlock_t lock;
X #endif
diff -u --recursive --new-file v2.3.2/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.3.2/linux/drivers/usb/Config.in Sat May 15 23:46:03 1999
+++ linux/drivers/usb/Config.in Sun May 16 22:23:31 1999
@@ -14,7 +14,12 @@
X tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB
X if [ ! "$CONFIG_USB" = "n" ]; then
X bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI
+
X bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI
+ if [ "$CONFIG_USB_OHCI" = "y" ]; then
+ bool ' Enable tons of OHCI debugging output?' CONFIG_USB_OHCI_DEBUG
+ fi
+
X bool 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support?' CONFIG_USB_OHCI_HCD
X if [ "$CONFIG_USB_OHCI_HCD" = "y" ]; then
X bool 'OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB
diff -u --recursive --new-file v2.3.2/linux/drivers/usb/README.ohci linux/drivers/usb/README.ohci
--- v2.3.2/linux/drivers/usb/README.ohci Tue May 11 10:04:03 1999
+++ linux/drivers/usb/README.ohci Sun May 16 22:23:31 1999
@@ -1,3 +1,31 @@
+May 16, 1999 16:20:54
+
+EDs are now allocated dynamically from their device's pool. Root hub
+status changes should stop the infinite "no device connected" messages
+that occurred after removing a device.
+
+TODO:
+
+~ Add the concept of a td_group to lump TDs associated with a single
+ data transfer request from the higher layers. This will be needed
+ for bulk and all larger transfers that will span multiple TDs but
+ which need to allocate/free them as a group as things happen. I
+ am thinking about create_td_group and free_td_group functions...
+~ Add bulk transfer support.
+~ Add Isochronous transfer support. These have their own special
+ format TDs to allow for several DMA data pointers. Kinda neat, but
+ likely harder to use through a generic interface in practice.
+~ Support dynamic allocation & growth of the TD/ED pools. Merge them
+ into global pools rather than a today's static per device allocation.
+
+KNOWN BUGS:
+
+~ Unplugging a hub causes khubd to Oops. I don't think this is
+ directly related to OHCI, but due to the fact that the interrupt TD
+ for the hub is never stopped. We need a usb_release_irq() that gets
+ called using the "IRQ handle" that should be returned by
+ usb_request_irq().
+
X May 09, 1999 16:25:58
X
X Cool, things are working "well" now. (I'm not getting oops's from the
diff -u --recursive --new-file v2.3.2/linux/drivers/usb/ohci-debug.c linux/drivers/usb/ohci-debug.c
--- v2.3.2/linux/drivers/usb/ohci-debug.c Tue May 11 10:04:03 1999
+++ linux/drivers/usb/ohci-debug.c Sun May 16 22:23:31 1999
@@ -80,17 +80,18 @@
X
X printk(KERN_DEBUG " ohci ED:\n");
X printk(KERN_DEBUG " status = 0x%x\n", stat);
- printk(KERN_DEBUG " %sMPS %d%s%s%s%s tc%d e%d fa%d\n",
+ printk(KERN_DEBUG " %sMPS %d%s%s%s%s tc%d e%d fa%d%s\n",
X skip ? "Skip " : "",
X mps,
- isoc ? "Isoc. " : "",
+ isoc ? " Isoc." : "",
X low_speed ? " LowSpd" : "",
X (dir == OHCI_ED_D_IN) ? " Input" :
X (dir == OHCI_ED_D_OUT) ? " Output" : "",
X halted ? " Halted" : "",
X toggle,
X endnum,
- funcaddr);
+ funcaddr,
+ (stat & ED_ALLOCATED) ? " Allocated" : "");
X printk(KERN_DEBUG " tail_td = 0x%x\n", ed->tail_td);
X printk(KERN_DEBUG " head_td = 0x%x\n", ed_head_td(ed));
X printk(KERN_DEBUG " next_ed = 0x%x\n", ed->next_ed);
@@ -108,19 +109,21 @@
X
X printk(KERN_DEBUG " ohci TD hardware fields:\n");
X printk(KERN_DEBUG " info = 0x%x\n", td->info);
- printk(KERN_DEBUG " %s%s%s%d %s\n",
+ printk(KERN_DEBUG " %s%s%s%d %s %s%d\n",
X td_round ? "Rounding " : "",
X (td_dir == OHCI_TD_D_IN) ? "Input " :
X (td_dir == OHCI_TD_D_OUT) ? "Output " :
X (td_dir == OHCI_TD_D_SETUP) ? "Setup " : "",
X "IntDelay ", td_int_delay,
X (td_toggle < 2) ? " " :
- (td_toggle & 1) ? "Data1 " : "Data0 ");
- printk(KERN_DEBUG " %s%d %s0x%x, %sAccessed, %sActive\n",
- "ErrorCnt ", td_errcnt,
- "ComplCode ", td_cc,
+ (td_toggle & 1) ? "Data1" : "Data0",
+ "ErrorCnt ", td_errcnt);
+ printk(KERN_DEBUG " ComplCode 0x%x, %sAccessed, %sActive\n",
+ td_cc,
X td_cc_accessed(*td) ? "" : "Not ",
X td_active(*td) ? "" : "Not ");
+
+ printk(KERN_DEBUG " %s\n", td_allocated(*td) ? "Allocated" : "Free");
X
X printk(KERN_DEBUG " cur_buf = 0x%x\n", td->cur_buf);
X printk(KERN_DEBUG " next_td = 0x%x\n", td->next_td);
diff -u --recursive --new-file v2.3.2/linux/drivers/usb/ohci.c linux/drivers/usb/ohci.c
--- v2.3.2/linux/drivers/usb/ohci.c Sat May 15 23:46:03 1999
+++ linux/drivers/usb/ohci.c Sun May 16 22:23:31 1999
@@ -29,7 +29,7 @@
X *
X * No filesystems were harmed in the development of this code.
X *
- * $Id: ohci.c,v 1.26 1999/05/11 07:34:47 greg Exp $
+ * $Id: ohci.c,v 1.43 1999/05/16 22:35:24 greg Exp $
X */
X
X #include <linux/config.h>
@@ -59,31 +59,30 @@
X
X static DECLARE_WAIT_QUEUE_HEAD(ohci_configure);
X
-#ifdef OHCI_TIMER
-static struct timer_list ohci_timer; /* timer for root hub polling */
+#ifdef CONFIG_USB_OHCI_DEBUG
+#define OHCI_DEBUG /* to make typing it easier.. */
X #endif
X
+#ifdef OHCI_DEBUG
+int MegaDebug = 0; /* SIGUSR2 to the control thread toggles this */
+#endif
X
-static int ohci_td_result(struct ohci_device *dev, struct ohci_td *td)
-{
- unsigned int status;
-
- status = td->info & OHCI_TD_CC;
-
- /* TODO Debugging code for TD failures goes here */
-
- return status;
-} /* ohci_td_result() */
X
+#ifdef OHCI_TIMER
+static struct timer_list ohci_timer; /* timer for root hub polling */
+#endif
X
X static spinlock_t ohci_edtd_lock = SPIN_LOCK_UNLOCKED;
X
X /*
- * Add a TD to the end of the TD list on a given ED. If td->next_td
- * points to any more TDs, they will be added as well (naturally).
- * Otherwise td->next_td must be 0.
+ * Add a TD to the end of the TD list on a given ED. This function
+ * does NOT advance the ED's tail_td pointer beyond the given TD. To
+ * add multiple TDs, call this function once for each TD. Do not
+ * "simply" update tail_td yourself... This function does more than
+ * that.
X *
- * The SKIP flag will be cleared after this function.
+ * If this ED is on the controller, you MUST set its SKIP flag before
+ * calling this function.
X *
X * Important! This function needs locking and atomicity as it works
X * in parallel with the HC's DMA. Locking ohci_edtd_lock while using
@@ -93,54 +92,62 @@
X */
X static void ohci_add_td_to_ed(struct ohci_td *td, struct ohci_ed *ed)
X {
- /* don't let the HC pull anything from underneath us */
- ed->status |= OHCI_ED_SKIP;
+ struct ohci_td *dummy_td, *prev_td;
+
+ if (ed->tail_td == 0) {
+ printk("eek! an ED without a dummy_td\n");
+ }
+
+ /* The ED's tail_td is constant, always pointing to the
+ * dummy_td. The reason the ED never processes the dummy is
+ * that it stops processing TDs as soon as head_td == tail_td.
+ * When it advances to this last dummy TD it conveniently stops. */
+ dummy_td = bus_to_virt(ed->tail_td);
X
- if (ed_head_td(ed) == 0) { /* empty list, put it on the head */
- set_ed_head_td(ed, virt_to_bus(td));
- ed->tail_td = 0;
+ /* Dummy's data pointer is used to point to the previous TD */
+ if (ed_head_td(ed) != ed->tail_td) {
+ prev_td = (struct ohci_td *) dummy_td->data;
X } else {
- struct ohci_td *tail, *head;
- head = (ed_head_td(ed) == 0) ? NULL : bus_to_virt(ed_head_td(ed));
- tail = (ed->tail_td == 0) ? NULL : bus_to_virt(ed->tail_td);
- if (!tail) { /* no tail, single element list */
- td->next_td = head->next_td;
- head->next_td = virt_to_bus(td);
- ed->tail_td = virt_to_bus(td);
- } else { /* append to the list */
- td->next_td = tail->next_td;
- tail->next_td = virt_to_bus(td);
- ed->tail_td = virt_to_bus(td);
- }
+ /* if the ED is empty, previous is meaningless */
+ /* We'll be inserting into the head of the list */
+ prev_td = NULL;
X }
X
- /* save the ED link in each of the TDs added */
+ /* Store the new back pointer and set up this TD's next */
+ dummy_td->data = td;
+ td->next_td = ed->tail_td;
+
+ /* Store the TD pointer back to the ED */
X td->ed = ed;
- while (td->next_td != 0) {
- td = bus_to_virt(td->next_td);
- td->ed = ed;
- }
X
- /* turn off the SKIP flag */
- ed->status &= ~OHCI_ED_SKIP;
+ if (!prev_td) { /* No previous TD? then insert us at the head */
+ if (ed_head_td(ed) != ed->tail_td)
+ printk(KERN_DEBUG "Suspicious ED...\n");
+ set_ed_head_td(ed, virt_to_bus(td)); /* put it on the ED */
+ } else {
+ /* add the TD to the end */
+ prev_td->next_td = virt_to_bus(td);
+ }
X } /* ohci_add_td_to_ed() */
X
X
X inline void ohci_start_control(struct ohci *ohci)
X {
X /* tell the HC to start processing the control list */
- writel(OHCI_CMDSTAT_CLF, &ohci->regs->cmdstatus);
+ writel_set(OHCI_USB_CLE, &ohci->regs->control);
+ writel_set(OHCI_CMDSTAT_CLF, &ohci->regs->cmdstatus);
X }
X
X inline void ohci_start_bulk(struct ohci *ohci)
X {
X /* tell the HC to start processing the bulk list */
- writel(OHCI_CMDSTAT_BLF, &ohci->regs->cmdstatus);
+ writel_set(OHCI_USB_BLE, &ohci->regs->control);
+ writel_set(OHCI_CMDSTAT_BLF, &ohci->regs->cmdstatus);
X }
X
X inline void ohci_start_periodic(struct ohci *ohci)
X {
- /* enable processing periodc transfers starting next frame */
+ /* enable processing periodic (intr) transfers starting next frame */
X writel_set(OHCI_USB_PLE, &ohci->regs->control);
X }
X
@@ -152,6 +159,7 @@
X
X /*
X * Add an ED to the hardware register ED list pointed to by hw_listhead_p
+ * This function only makes sense for Control and Bulk EDs.
X */
X static void ohci_add_ed_to_hw(struct ohci_ed *ed, void* hw_listhead_p)
X {
@@ -172,11 +180,11 @@
X writel(virt_to_bus(ed), hw_listhead_p);
X
X spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-} /* ohci_add_ed() */
+} /* ohci_add_ed_to_hw() */
X
X
X /*
- * Put another control ED on the controller's list
+ * Put a control ED on the controller's list
X */
X void ohci_add_control_ed(struct ohci *ohci, struct ohci_ed *ed)
X {
@@ -184,37 +192,146 @@
X ohci_start_control(ohci);
X } /* ohci_add_control_ed() */
X
+/*
+ * Put a bulk ED on the controller's list
+ */
+void ohci_add_bulk_ed(struct ohci *ohci, struct ohci_ed *ed)
+{
+ ohci_add_ed_to_hw(ed, &ohci->regs->ed_bulkhead);
+ ohci_start_bulk(ohci);
+} /* ohci_add_bulk_ed() */
X
-#if 0
X /*
- * Put another control ED on the controller's list
+ * Put a periodic ED on the appropriate list given the period.
X */
X void ohci_add_periodic_ed(struct ohci *ohci, struct ohci_ed *ed, int period)
X {
- ohci_add_ed_to_hw(ed, /* XXX */);
+ struct ohci_ed *int_ed;
+ unsigned long flags;
+
+ /*
+ * Pick a good frequency endpoint based on the requested period
+ */
+ int_ed = &ohci->root_hub->ed[ms_to_ed_int(period)];
+#ifdef OHCI_DEBUG
+ printk("usb-ohci: Using INT ED queue %d for %dms period\n",
+ ms_to_ed_int(period), period);
+#endif
+
+ spin_lock_irqsave(&ohci_edtd_lock, flags);
+ /*
+ * Insert this ED at the front of the list.
+ */
+ ed->next_ed = int_ed->next_ed;
+ int_ed->next_ed = virt_to_bus(ed);
+
+ spin_unlock_irqrestore(&ohci_edtd_lock, flags);
+
X ohci_start_periodic(ohci);
-} /* ohci_add_control_ed() */
+} /* ohci_add_periodic_ed() */
+
+/*
+ * Put an isochronous ED on the controller's list
+ */
+inline void ohci_add_isoc_ed(struct ohci *ohci, struct ohci_ed *ed)
+{
+ ohci_add_periodic_ed(ohci, ed, 1);
+}
+
+
+/*
+ * This will be used for the interrupt to wake us up on the next SOF
+ */
+DECLARE_WAIT_QUEUE_HEAD(start_of_frame_wakeup);
+
+/*
+ * Guarantee that an ED is safe to be modified by the HCD (us).
+ *
+ * This function can NOT be called from an interrupt.
+ */
+void ohci_wait_for_ed_safe(struct ohci_regs *regs, struct ohci_ed *ed, int ed_type)
+{
+ __u32 hw_listcurrent;
+
+ /* tell the controller to skip this ED */
+ ed->status |= OHCI_ED_SKIP;
+
+ switch (ed_type) {
+ case HCD_ED_CONTROL:
+ hw_listcurrent = readl(regs->ed_controlcurrent);
+ break;
+ case HCD_ED_BULK:
+ hw_listcurrent = readl(regs->ed_bulkcurrent);
+ break;
+ case HCD_ED_ISOC:
+ case HCD_ED_INT:
+ hw_listcurrent = readl(regs->ed_periodcurrent);
+ break;
+ default:
+ return;
+ }
+
+ /*
+ * If the HC is processing this ED we need to wait until the
+ * at least the next frame.
+ */
+ if (virt_to_bus(ed) == hw_listcurrent) {
+ DECLARE_WAITQUEUE(wait, current);
+
+#ifdef OHCI_DEBUG
+ printk("Waiting a frame for OHC to finish with ED %p\n", ed);
X #endif
X
+ add_wait_queue(&start_of_frame_wakeup, &wait);
+
+ /* clear the SOF interrupt status and enable it */
+ writel(OHCI_INTR_SF, &regs->intrstatus);
+ writel(OHCI_INTR_SF, &regs->intrenable);
+
+ schedule_timeout(HZ/10);
+
+ remove_wait_queue(&start_of_frame_wakeup, &wait);
+ }
+
+ return; /* The ED is now safe */
+} /* ohci_wait_for_ed_safe() */
+
X
X /*
- * Remove an ED from the HC list whos bus headpointer is pointed to
- * by hw_listhead_p
+ * Remove an ED from the HC's list.
+ * This function can ONLY be used for Control or Bulk EDs.
X *
X * Note that the SKIP bit is left on in the removed ED.
X */
-void ohci_remove_ed_from_hw(struct ohci_ed *ed, __u32* hw_listhead_p)
+void ohci_remove_norm_ed_from_hw(struct ohci *ohci, struct ohci_ed *ed, int ed_type)
X {
X unsigned long flags;
+ struct ohci_regs *regs = ohci->regs;
X struct ohci_ed *cur;
X __u32 bus_ed = virt_to_bus(ed);
X __u32 bus_cur;
+ __u32 *hw_listhead_p;
X
X if (ed == NULL || !bus_ed)
X return;
X
- /* tell the controller this skip ED */
- ed->status |= OHCI_ED_SKIP;
+ switch (ed_type) {
+ case HCD_ED_CONTROL:
+ hw_listhead_p = &regs->ed_controlhead;
+ break;
+ case HCD_ED_BULK:
+ hw_listhead_p = &regs->ed_bulkhead;
+ break;
+ default:
+ printk("Unknown HCD ED type %d.\n", ed_type);
+ return;
+ }
+
+ /*
+ * Tell the controller to this skip ED and make sure it is not the
+ * being accessed by the HC as we speak.
+ */
+ ohci_wait_for_ed_safe(regs, ed, ed_type);
X
X bus_cur = readl(hw_listhead_p);
X
@@ -232,7 +349,7 @@
X struct ohci_ed *prev;
X
X /* walk the list and unlink the ED if found */
- for (;;) {
+ do {
X prev = cur;
X cur = bus_to_virt(cur->next_ed);
X
@@ -241,17 +358,14 @@
X prev->next_ed = cur->next_ed;
X break;
X }
-
- if (cur->next_ed == 0)
- break;
- }
+ } while (cur->next_ed != 0);
X }
X
X /* clear any links from the ED for safety */
X ed->next_ed = 0;
X
X spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-} /* ohci_remove_ed_from_hw() */
+} /* ohci_remove_norm_ed_from_hw() */
X
X /*
X * Remove an ED from the controller's control list. Note that the SKIP bit
@@ -259,7 +373,7 @@
X */
X inline void ohci_remove_control_ed(struct ohci *ohci, struct ohci_ed *ed)
X {
- ohci_remove_ed_from_hw(ed, &ohci->regs->ed_controlhead);
+ ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_CONTROL);
X }
X
X /*
@@ -268,7 +382,7 @@
X */
X inline void ohci_remove_bulk_ed(struct ohci *ohci, struct ohci_ed *ed)
X {
- ohci_remove_ed_from_hw(ed, &ohci->regs->ed_bulkhead);
+ ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_BULK);
X }
X
X
@@ -321,7 +435,8 @@
X td->next_td = 0; /* remove the TDs links */
X td->ed = NULL;
X
- /* TODO return this TD to the pool of free TDs */
+ /* return this TD to the pool of free TDs */
+ ohci_free_td(td);
X
X /* unset the "skip me bit" in this ED */
X ed->status &= ~OHCI_ED_SKIP;
@@ -332,15 +447,21 @@
X
X /*
X * Get a pointer (virtual) to an available TD from the given device's
- * pool.
- *
- * Return NULL if none are left.
+ * pool. Return NULL if none are left.
X */
X static struct ohci_td *ohci_get_free_td(struct ohci_device *dev)
X {
X int idx;
X
+#if 0
+ printk(KERN_DEBUG "in ohci_get_free_td()\n");
+#endif
+
+ /* FIXME: this is horribly inefficient */
X for (idx=0; idx < NUM_TDS; idx++) {
+#if 0
+ show_ohci_td(&dev->td[idx]);
+#endif
X if (!td_allocated(dev->td[idx])) {
X struct ohci_td *new_td = &dev->td[idx];
X /* zero out the TD */
@@ -353,12 +474,53 @@
X }
X }
X
- printk("usb-ohci error: unable to allocate a TD\n");
+ printk("usb-ohci: unable to allocate a TD\n");
X return NULL;
X } /* ohci_get_free_td() */
X
X
X /*
+ * Get a pointer (virtual) to an available TD from the given device's
+ * pool. Return NULL if none are left.
+ */
+static struct ohci_ed *ohci_get_free_ed(struct ohci_device *dev)
+{
+ int idx;
+
+ /* FIXME: this is horribly inefficient */
+ for (idx=0; idx < NUM_EDS; idx++) {
+ if (!ed_allocated(dev->ed[idx])) {
+ struct ohci_ed *new_ed = &dev->ed[idx];
+ /* zero out the ED */
+ memset(new_ed, 0, sizeof(*new_ed));
+ /* all new EDs start with the SKIP bit set */
+ new_ed->status |= OHCI_ED_SKIP;
+ /* mark it as allocated */
+ allocate_ed(new_ed);
+ return new_ed;
+ }
+ }
+
+ printk("usb-ohci: unable to allocate an ED\n");
+ return NULL;
+} /* ohci_get_free_ed() */
+
+
+void ohci_free_ed(struct ohci_ed *ed)
+{
+ if (!ed)
+ return;
+
+ if (ed->tail_td == 0) {
+ printk("yikes! an ED without a dummy_td\n");
+ } else
+ ohci_free_td((struct ohci_td *)bus_to_virt(ed->tail_td));
+
+ ed->status &= ~(__u32)ED_ALLOCATED;
+} /* ohci_free_ed() */
+
+
+/*
X * Initialize a TD
X *
X * dir = OHCI_TD_D_IN, OHCI_TD_D_OUT, or OHCI_TD_D_SETUP
@@ -379,10 +541,58 @@
X td->dev_id = dev_id;
X td->completed = completed;
X
+#if 0
+ printk(KERN_DEBUG "ohci_fill_new_td created:\n");
+ show_ohci_td(td);
+#endif
+
X return td;
X } /* ohci_fill_new_td() */
X
X
+/*
+ * Initialize a new ED on device dev, including allocating and putting the
+ * dummy tail_td on its queue if it doesn't already have one. Any
+ * TDs on this ED other than the dummy will be lost (so there better
+ * not be any!). This assumes that the ED is Allocated and will
+ * force the Allocated bit on.
+ */
+struct ohci_ed *ohci_fill_ed(struct ohci_device *dev, struct ohci_ed *ed, int maxpacketsize, int lowspeed, int endp_id, int isoc_tds)
+{
+ struct ohci_td *dummy_td;
+
+ if (ed_head_td(ed) != ed->tail_td)
+ printk("Reusing a non-empty ED %p!\n", ed);
+
+ if (!ed->tail_td) {
+ dummy_td = ohci_get_free_td(dev);
+ if (dummy_td == NULL) {
+ printk("Error allocating dummy TD for ED %p\n", ed);
+ return NULL; /* no dummy available! */
+ }
+ make_dumb_td(dummy_td); /* flag it as a dummy */
+ ed->tail_td = virt_to_bus(dummy_td);
+ } else {
+ dummy_td = bus_to_virt(ed->tail_td);
+ if (!td_dummy(*dummy_td))
+ printk("ED %p's dummy %p is screwy\n", ed, dummy_td);
+ }
+
+ /* set the head TD to the dummy and clear the Carry & Halted bits */
+ ed->_head_td = ed->tail_td;
+
+ ed->status = \
+ ed_set_maxpacket(maxpacketsize) |
+ ed_set_speed(lowspeed) |
+ (endp_id & 0x7ff) |
+ ((isoc_tds == 0) ? OHCI_ED_F_NORM : OHCI_ED_F_ISOC);
+ allocate_ed(ed);
+ ed->next_ed = 0;
+
+ return ed;
+} /* ohci_fill_ed() */
+
+
X /**********************************
X * OHCI interrupt list operations *
X **********************************/
@@ -404,26 +614,26 @@
X struct ohci_td *td;
X struct ohci_ed *interrupt_ed; /* endpoint descriptor for this irq */
X
- /*
- * Pick a good frequency endpoint based on the requested period
- */
- interrupt_ed = &dev->ohci->root_hub->ed[ms_to_ed_int(period)];
+ /* Get an ED and TD */
+ interrupt_ed = ohci_get_free_ed(dev);
+ if (!interrupt_ed) {
+ printk("Out of EDs on device %p in ohci_request_irq\n", dev);
+ return -1;
+ }
+
+ td = ohci_get_free_td(dev);
+ if (!td) {
+ printk("Out of TDs in ohci_request_irq\n");
+ ohci_free_ed(interrupt_ed);
+ return -1;
+ }
X
X /*
X * Set the max packet size, device speed, endpoint number, usb
X * device number (function address), and type of TD.
- *
- * FIXME: Isochronous transfers need a pool of special 32 byte
- * TDs (32 byte aligned) in order to be supported.
X */
- interrupt_ed->status = \
- ed_set_maxpacket(usb_maxpacket(pipe)) |
- ed_set_speed(usb_pipeslow(pipe)) |
- usb_pipe_endpdev(pipe) |
- OHCI_ED_F_NORM;
-
- td = ohci_get_free_td(dev);
- /* FIXME: check for NULL */
+ ohci_fill_ed(dev, interrupt_ed, usb_maxpacket(pipe), usb_pipeslow(pipe),
+ usb_pipe_endpdev(pipe), 0 /* normal TDs */);
X
X /* Fill in the TD */
X ohci_fill_new_td(td, td_set_dir_out(usb_pipeout(pipe)),
@@ -432,42 +642,23 @@
X &dev->data, DATA_BUF_LEN,
X dev_id, handler);
X /*
- * TODO: be aware that OHCI won't advance out of the 4kb
- * page cur_buf started in. It'll wrap around to the start
- * of the page... annoying or useful? you decide.
- *
- * We should make sure dev->data doesn't cross a page...
+ * TODO: be aware of how the OHCI controller deals with DMA
+ * spanning more than one page.
X */
X
- /* FIXME: this just guarantees that its the end of the list */
- td->next_td = 0;
+ /*
+ * Put the TD onto our ED and make sure its ready to run
+ */
+ ohci_add_td_to_ed(td, interrupt_ed);
+ interrupt_ed->status &= ~OHCI_ED_SKIP;
+ ohci_unhalt_ed(interrupt_ed);
X
X /* Linus did this. see asm/system.h; scary concept... I don't
X * know if its needed here or not but it won't hurt. */
X wmb();
X
- /*
- * Put the TD onto our ED
- */
- {
- unsigned long flags;
- spin_lock_irqsave(&ohci_edtd_lock, flags);
- ohci_add_td_to_ed(td, interrupt_ed);
- spin_unlock_irqrestore(&ohci_edtd_lock, flags);
- }
-
-#if 0
X /* Assimilate the new ED into the collective */
- /*
- * When dynamic ED allocation is done, this call will be
- * useful. For now, the correct ED already on the
- * controller's proper periodic ED lists was chosen above.
- */
X ohci_add_periodic_ed(dev->ohci, interrupt_ed, period);
-#else
- /* enable periodic (interrupt) transfers on the HC */
- ohci_start_periodic(dev->ohci);
-#endif
X
X return 0;
X } /* ohci_request_irq() */
@@ -486,6 +677,12 @@
X */
X static int ohci_control_completed(int stats, void *buffer, void *dev_id)
X {
+ /* pass the TDs completion status back to control_msg */
+ if (dev_id) {
+ int *completion_status = (int *)dev_id;
+ *completion_status = stats;
+ }
+
X wake_up(&control_wakeup);
X return 0;
X } /* ohci_control_completed() */
@@ -502,44 +699,46 @@
X * - The command itself
X * - An optional data phase (if len > 0)
X * - Status complete phase
+ *
+ * This function can NOT be called from an interrupt.
X */
X static int ohci_control_msg(struct usb_device *usb, unsigned int pipe, void *cmd, void *data, int len)
X {
X struct ohci_device *dev = usb_to_ohci(usb);
- /*
- * ideally dev->ed should be linked into the root hub's
- * control_ed list and used instead of just using it directly.
- * This could present a problem as is with more than one
- * device. (but who wants to use a keyboard AND a mouse
- * anyways? ;)
- */
- struct ohci_ed *control_ed = &dev->ohci->root_hub->ed[ED_CONTROL];
+ struct ohci_ed *control_ed = ohci_get_free_ed(dev);
X struct ohci_td *setup_td, *data_td, *status_td;
X DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ int completion_status = -1;
X
-#if 0
- printk(KERN_DEBUG "entering ohci_control_msg %p (ohci_dev: %p) pipe 0x%x, cmd %p, data %p, len %d\n", usb, dev, pipe, cmd, data, len);
+#ifdef OHCI_DEBUG
+ printk(KERN_DEBUG "ohci_control_msg %p (ohci_dev: %p) pipe %x, cmd %p, data %p, len %d\n", usb, dev, pipe, cmd, data, len);
X #endif
+ if (!control_ed) {
+ printk("usb-ohci: couldn't get ED for dev %p\n", dev);
+ return -1;
+ }
+
+ /* get a TD to send this control message with */
+ setup_td = ohci_get_free_td(dev);
+ if (!setup_td) {
+ printk("usb-ohci: couldn't get TD for dev %p [cntl setup]\n", dev);
+ ohci_free_ed(control_ed);
+ return -1;
+ }
X
X /*
X * Set the max packet size, device speed, endpoint number, usb
X * device number (function address), and type of TD.
X *
X */
- control_ed->status = \
- ed_set_maxpacket(usb_maxpacket(pipe)) |
- ed_set_speed(usb_pipeslow(pipe)) |
- usb_pipe_endpdev(pipe) |
- OHCI_ED_F_NORM;
+ ohci_fill_ed(dev, control_ed, usb_maxpacket(pipe), usb_pipeslow(pipe),
+ usb_pipe_endpdev(pipe), 0 /* normal TDs */);
X
X /*
X * Build the control TD
X */
X
- /* get a TD to send this control message with */
- setup_td = ohci_get_free_td(dev);
- /* TODO check for NULL */
-
X /*
X * Set the not accessed condition code, allow odd sized data,
X * and set the data transfer type to SETUP. Setup DATA always
@@ -555,7 +754,13 @@
X NULL, NULL);
X
X /* allocate the next TD */
- data_td = ohci_get_free_td(dev); /* TODO check for NULL */
+ data_td = ohci_get_free_td(dev);
+ if (!data_td) {
+ printk("usb-ohci: couldn't get TD for dev %p [cntl data]\n", dev);
+ ohci_free_td(setup_td);
+ ohci_free_ed(control_ed);
+ return -1;
+ }
X
X /* link to the next TD */
X setup_td->next_td = virt_to_bus(data_td);
@@ -570,48 +775,59 @@
X NULL, NULL);
X
X /*
- * XXX we should check that the data buffer doesn't
- * cross a 4096 byte boundary. If so, it needs to be
- * copied into a single 4096 byte aligned area for the
- * OHCI's TD logic to see it all, or multiple TDs need
- * to be made for each page.
+ * TODO: Normal TDs can transfer up to 8192 bytes on OHCI.
+ * However, for that to happen, the data must -start-
+ * on a nice 4kb page. We need to check for data
+ * sizes > 4096 and, if they cross more than two 4096
+ * byte pages of memory one or more additional TDs
+ * will need to be created. (repeat doing this in a
+ * loop until all of the DATA is on a TD)
X *
- * It's not likely a control transfer will run into
- * this problem.. (famous last words)
+ * Control transfers are -highly unlikely- to need to
+ * transfer this much data.. but who knows.. sadistic
+ * hardware is sure to exist.
X */
X
X status_td = ohci_get_free_td(dev); /* TODO check for NULL */
+ if (!status_td) {
+ printk("usb-ohci: couldn't get TD for dev %p [cntl status]\n", dev);
+ ohci_free_td(setup_td);
+ ohci_free_td(data_td);
+ ohci_free_ed(control_ed);
+ return -1;
+ }
+
X data_td->next_td = virt_to_bus(status_td);
X } else {
X status_td = data_td; /* no data_td, use it for status */
X }
X
- /* The control status packet always uses a DATA1 */
+ /* The control status packet always uses a DATA1
+ * Give "dev_id" the address of completion_status so that the
+ * TDs status can be passed back to us from the IRQ. */
X ohci_fill_new_td(status_td,
X td_set_dir_in(usb_pipeout(pipe) | (len == 0)),
X TOGGLE_DATA1,
- 0,
- NULL, 0,
- NULL, ohci_control_completed);
+ 0 /* flags */,
+ NULL /* data */, 0 /* data len */,
+ &completion_status, ohci_control_completed);
X status_td->next_td = 0; /* end of TDs */
X
X /*
- * Start the control transaction..
- */
- current->state = TASK_UNINTERRUPTIBLE;
- add_wait_queue(&control_wakeup, &wait);
-
- /*
X * Add the chain of 2-3 control TDs to the control ED's TD list
X */
SHAR_EOF
true || echo 'restore of patch-2.3.3 failed'
fi
echo 'End of part 2'
echo 'File patch-2.3.3 is continued in part 3'
echo 3 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
May 18, 1999, 3:00:00 AM5/18/99
to
Archive-name: v2.3/patch-2.3.3/part1

#!/bin/sh
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a 4 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
#

if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= patch-2.3.3 ==============
if test -f 'patch-2.3.3' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.3.3 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.3.3 (Text)'


sed 's/^X//' << 'SHAR_EOF' > 'patch-2.3.3' &&

diff -u --recursive --new-file v2.3.2/linux/CREDITS linux/CREDITS
--- v2.3.2/linux/CREDITS Sat May 15 23:46:02 1999
+++ linux/CREDITS Sun May 16 10:26:44 1999
@@ -1534,6 +1534,15 @@
X E: o...@pell.chi.il.us
X D: improved memory detection code.
X
+N: Mikulas Patocka
+E: mik...@artax.karlin.mff.cuni.cz
+W: http://artax.karlin.mff.cuni.cz/~mikulas/
+P: 1024/BB11D2D5 A0 F1 28 4A C4 14 1E CF 92 58 7A 8F 69 BC A4 D3
+D: Read/write HPFS filesystem
+S: Weissova 8
+S: 644 00 Brno
+S: Czech Republic
+
X N: Vojtech Pavlik
X E: voj...@ucw.cz
X D: Joystick driver
@@ -1839,7 +1848,7 @@
X
X N: Chris Smith
X E: csm...@convex.com
-D: HPFS filesystem
+D: Read only HPFS filesystem
X S: Richardson, Texas
X S: USA
X
diff -u --recursive --new-file v2.3.2/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.2/linux/Documentation/Configure.help Sat May 15 23:46:02 1999
+++ linux/Documentation/Configure.help Sun May 16 10:26:44 1999
@@ -7322,14 +7322,24 @@
X directories that are mount points on the local filesystem (this is
X how nfsd behaves on Sun systems), say yes here. If unsure, say N.
X
-OS/2 HPFS filesystem support (read only)
+OS/2 HPFS filesystem support (read/write)
X CONFIG_HPFS_FS
X OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
X is the filesystem used for organizing files on OS/2 hard disk
- partitions. Say Y if you want to be able to read files from an OS/2
- HPFS partition of your hard drive. OS/2 floppies however are in
- regular MSDOS format, so you don't need this option in order to be
- able to read them. Read Documentation/filesystems/hpfs.txt.
+ partitions. Say Y if you want to be able to read and write files
+ on an OS/2 HPFS partition of your hard drive. OS/2 floppies however
+ are in regular MSDOS format, so you don't need this option in order
+ to be able to read them. Read Documentation/filesystems/hpfs.txt.
+
+ Write support is new and experimental. I don't think it's so
+ "experimental" that it corrupts disks. (but you know: "There's no
+ warranty") There are many checks and filesystem is remounted read-only
+ if any inconsistency found. I use it quite long time and it works.
+
+ This driver may not be able to write to HPFS386 disks on Warp server.
+ HPFS386 on Warp client seems to work ok. If some unknown HPFS386
+ structures are deteced, they are not destroyed and filesystem is
+ remounted read-only.
X
X This filesystem is also available as a module ( = code which can be
X inserted in and removed from the running kernel whenever you want).
diff -u --recursive --new-file v2.3.2/linux/Documentation/filesystems/hpfs.txt linux/Documentation/filesystems/hpfs.txt
--- v2.3.2/linux/Documentation/filesystems/hpfs.txt Sat May 15 23:46:02 1999
+++ linux/Documentation/filesystems/hpfs.txt Sun May 16 10:26:44 1999
@@ -1,4 +1,4 @@
-Read/Write HPFS 1.98b
+Read/Write HPFS 1.99b
X 1998-1999, Mikulas Patocka
X
X email: mik...@artax.karlin.mff.cuni.cz
@@ -58,9 +58,9 @@
X because kernel creates different files with names like bootsect.S and
X bootsect.s. When searching for file thats name has characters >= 128, codepages
X are used - see below.
-OS/2 ignores dots and spaces at the end of file name, so this driver does. If
-you create 'a. ...', the file 'a' will be created, but you can still access it
-under names 'a.', 'a..', 'a . . . ' etc.
+OS/2 ignores dots and spaces at the end of file name, so this driver does as
+well. If you create 'a. ...', the file 'a' will be created, but you can still
+access it under names 'a.', 'a..', 'a . . . ' etc.
X
X
X Extended attributes
@@ -162,9 +162,6 @@
X Renaming files so that only case changes doesn't work. This driver supports it
X but vfs doesn't. Something like 'mv file FILE' won't work.
X
-When you try to create file with bad filename (too long or containing forbidden
-characters), you get ENOENT error instead of EINVAL or ENAMETOOLONG.
-
X All atimes and directory mtimes are not updated. That's because of performance
X reasons. If you extremely wish to update them, let me know, I'll write it (but
X it will be slow).
@@ -266,6 +263,10 @@
X Fixed a bug when chmoding or chowning root directory
X 1.98 Fixed a deadlock when using old_readdir
X Better directory handling; workaround for "unbalanced tree" bug in OS/2
+1.99 Corrected a possible problem when there's not enough space while deleting
+ file
+ Now it tries to truncate the file if there's not enough space when deleting
+ Removed a lot of redundat code
X
X
X vim: set textwidth=80:
diff -u --recursive --new-file v2.3.2/linux/Documentation/mtrr.txt linux/Documentation/mtrr.txt
--- v2.3.2/linux/Documentation/mtrr.txt Mon May 10 10:32:45 1999
+++ linux/Documentation/mtrr.txt Sun May 16 10:13:20 1999
@@ -1,5 +1,5 @@
X MTRR (Memory Type Range Register) control
-2 May 1998
+16 May 1999
X Richard Gooch
X <rgo...@atnf.csiro.au>
X
@@ -31,8 +31,10 @@
X reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
X reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1
X ===============================================================================
-Creating MTRRs from the shell:
+Creating MTRRs from the C-shell:
X # echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
+or if you use bash:
+# echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
X
X And the result thereof:
X % cat /proc/mtrr
@@ -79,8 +81,10 @@
X NOTE: You can only create type=uncachable region, if the first
X region that you created is type=write-combining.
X ===============================================================================
-Removing MTRRs from the shell:
+Removing MTRRs from the C-shell:
X % echo "disable=2" >! /proc/mtrr
+or using bash:
+% echo "disable=2" >| /proc/mtrr
X ===============================================================================
X Reading MTRRs from a C programme using ioctl()'s:
X
diff -u --recursive --new-file v2.3.2/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.2/linux/MAINTAINERS Sat May 8 12:49:46 1999
+++ linux/MAINTAINERS Sun May 16 10:26:44 1999
@@ -361,6 +361,12 @@
X W: http://www.uni-mainz.de/~langm000/linux.html
X S: Maintained
X
+HPFS FILESYSTEM
+P: Mikulas Patocka
+M: mik...@artax.karlin.mff.cuni.cz
+W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
+S: Maintained
+
X IDE DRIVER [GENERAL]
X P: Andre Hedrick
X M: hed...@astro.dyer.vanderbilt.edu
diff -u --recursive --new-file v2.3.2/linux/arch/i386/Makefile linux/arch/i386/Makefile
--- v2.3.2/linux/arch/i386/Makefile Wed Dec 30 14:17:25 1998
+++ linux/arch/i386/Makefile Sun May 16 13:17:22 1999
@@ -25,22 +25,27 @@
X
X ifdef CONFIG_M386
X CFLAGS := $(CFLAGS) -m386 -DCPU=386
+AFLAGS := $(AFLAGS) -DCPU=386
X endif
X
X ifdef CONFIG_M486
X CFLAGS := $(CFLAGS) -m486 -DCPU=486
+AFLAGS := $(AFLAGS) -DCPU=486
X endif
X
X ifdef CONFIG_M586
-CFLAGS := $(CFLAGS) -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=586
+CFLAGS := $(CFLAGS) -DCPU=586
+AFLAGS := $(AFLAGS) -DCPU=586
X endif
X
X ifdef CONFIG_M586TSC
-CFLAGS := $(CFLAGS) -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=586
+CFLAGS := $(CFLAGS) -DCPU=586
+AFLAGS := $(AFLAGS) -DCPU=586
X endif
X
X ifdef CONFIG_M686
-CFLAGS := $(CFLAGS) -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686
+CFLAGS := $(CFLAGS) -DCPU=686
+AFLAGS := $(AFLAGS) -DCPU=686
X endif
X
X HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
diff -u --recursive --new-file v2.3.2/linux/arch/i386/lib/checksum.S linux/arch/i386/lib/checksum.S
--- v2.3.2/linux/arch/i386/lib/checksum.S Fri Jan 15 14:36:20 1999
+++ linux/arch/i386/lib/checksum.S Sun May 16 13:17:22 1999
@@ -117,9 +117,11 @@
X #else /* CPU==686 */
X
X csum_partial:
- movl 12(%esp),%eax # Function arg: unsigned int sum
- movl 8(%esp),%ecx # Function arg: int len
- movl 4(%esp),%esi # Function arg: const unsigned char *buf
+ pushl %esi
+ pushl %ebx
+ movl 20(%esp),%eax # Function arg: unsigned int sum
+ movl 16(%esp),%ecx # Function arg: int len
+ movl 12(%esp),%esi # Function arg: const unsigned char *buf
X
X testl $2, %esi
X jnz 30f
@@ -204,6 +206,8 @@
X addl %ebx,%eax
X adcl $0,%eax
X 80:
+ popl %ebx
+ popl %esi
X ret
X
X #endif /* CPU==686 */
@@ -369,7 +373,7 @@
X
X #define ROUND1(x) \
X SRC(movl x(%esi), %ebx ) ; \
- addl %ebx, %eax\n ; \
+ addl %ebx, %eax ; \
X DST(movl %ebx, x(%edi) ) ;
X
X #define ROUND(x) \
diff -u --recursive --new-file v2.3.2/linux/arch/m68k/atari/stdma.c linux/arch/m68k/atari/stdma.c
--- v2.3.2/linux/arch/m68k/atari/stdma.c Thu Feb 12 16:30:12 1998
+++ linux/arch/m68k/atari/stdma.c Sat May 15 15:05:35 1999
@@ -43,7 +43,7 @@
X /* int func to be called */
X static void (*stdma_isr)(int, void *, struct pt_regs *) = NULL;
X static void *stdma_isr_data = NULL; /* data passed to isr */
-static struct wait_queue *stdma_wait = NULL; /* wait queue for ST-DMA */
+static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */
X
X
X
diff -u --recursive --new-file v2.3.2/linux/arch/m68k/mac/adb-bus.c linux/arch/m68k/mac/adb-bus.c
--- v2.3.2/linux/arch/m68k/mac/adb-bus.c Mon Oct 5 13:54:39 1998
+++ linux/arch/m68k/mac/adb-bus.c Sat May 15 15:05:35 1999
@@ -2328,12 +2328,12 @@
X struct adb_request req;
X };
X
-static struct wait_queue *adb_wait;
+static DECLARE_WAIT_QUEUE_HEAD(adb_wait);
X
X static int adb_wait_reply(struct adbdev_state *state, struct file *file)
X {
X int ret = 0;


- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait,current);
X

X add_wait_queue(&adb_wait, &wait);
X current->state = TASK_INTERRUPTIBLE;
@@ -2552,12 +2552,12 @@
X struct adb_request req;
X };
X
-static struct wait_queue *adb_wait;
+static DECLARE_WAIT_QUEUE_HEAD(adb_wait);
X
X static int adb_wait_reply(struct adbdev_state *state, struct file *file)
X {
X int ret = 0;


- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);
X

X #if (ADBDEBUG & ADBDEBUG_DEVICE)
X printk("ADB request: wait_reply (blocking ... \n");
diff -u --recursive --new-file v2.3.2/linux/arch/mips/kernel/irixsig.c linux/arch/mips/kernel/irixsig.c
--- v2.3.2/linux/arch/mips/kernel/irixsig.c Thu Nov 5 09:58:29 1998
+++ linux/arch/mips/kernel/irixsig.c Sat May 15 15:05:35 1999
@@ -666,7 +666,7 @@
X int options, struct rusage *ru)
X {
X int flag, retval;


- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait,current);

X struct task_struct *p;
X
X lock_kernel();
diff -u --recursive --new-file v2.3.2/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c
--- v2.3.2/linux/arch/ppc/8xx_io/uart.c Wed Dec 23 09:44:40 1998
+++ linux/arch/ppc/8xx_io/uart.c Sat May 15 15:05:35 1999
@@ -155,8 +155,8 @@
X long pgrp; /* pgrp of opening process */
X struct tq_struct tqueue;
X struct tq_struct tqueue_hangup;


- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;
X

X /* CPM Buffer Descriptor pointers.
X */
@@ -1733,7 +1733,7 @@
X ser_info_t *info)
X {
X #ifdef DO_THIS_LATER


- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait, current);

X #endif
X struct serial_state *state = info->state;
X int retval;
diff -u --recursive --new-file v2.3.2/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.3.2/linux/arch/sparc/defconfig Thu Apr 22 19:24:51 1999
+++ linux/arch/sparc/defconfig Sat May 15 11:12:09 1999
@@ -229,6 +229,7 @@
X CONFIG_MSDOS_FS=m
X # CONFIG_UMSDOS_FS is not set
X CONFIG_VFAT_FS=m
+CONFIG_EFS_FS=m
X CONFIG_ISO9660_FS=m
X # CONFIG_JOLIET is not set
X CONFIG_MINIX_FS=m
diff -u --recursive --new-file v2.3.2/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.3.2/linux/arch/sparc64/defconfig Thu Apr 22 19:24:51 1999
+++ linux/arch/sparc64/defconfig Sat May 15 11:12:09 1999
@@ -267,6 +267,7 @@
X CONFIG_MSDOS_FS=m
X # CONFIG_UMSDOS_FS is not set
X CONFIG_VFAT_FS=m
+CONFIG_EFS_FS=m
X CONFIG_ISO9660_FS=m
X # CONFIG_JOLIET is not set
X CONFIG_MINIX_FS=m
diff -u --recursive --new-file v2.3.2/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.3.2/linux/arch/sparc64/kernel/sys_sparc32.c Wed Mar 10 16:53:37 1999
+++ linux/arch/sparc64/kernel/sys_sparc32.c Sun May 16 10:39:51 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.107 1999/03/05 13:21:02 davem Exp $
+/* $Id: sys_sparc32.c,v 1.108 1999/05/16 10:50:32 davem Exp $
X * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -2363,6 +2363,94 @@
X __scm_destroy(scm);
X }
X
+/* In these cases we (currently) can just copy to data over verbatim
+ * because all CMSGs created by the kernel have well defined types which
+ * have the same layout in both the 32-bit and 64-bit API. One must add
+ * some special cased conversions here if we start sending control messages
+ * with incompatible types.
+ *
+ * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
+ * we do our work. The remaining cases are:
+ *
+ * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
+ * IP_TTL int 32-bit clean
+ * IP_TOS __u8 32-bit clean
+ * IP_RECVOPTS variable length 32-bit clean
+ * IP_RETOPTS variable length 32-bit clean
+ * (these last two are clean because the types are defined
+ * by the IPv4 protocol)
+ * IP_RECVERR struct sock_extended_err +
+ * struct sockaddr_in 32-bit clean
+ * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
+ * struct sockaddr_in6 32-bit clean
+ * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
+ * IPV6_HOPLIMIT int 32-bit clean
+ * IPV6_FLOWINFO u32 32-bit clean
+ * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
+ * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
+ * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
+ * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
+ */
+static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
+{
+ unsigned char *workbuf, *wp;
+ unsigned long bufsz, space_avail;
+ struct cmsghdr *ucmsg;
+
+ bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
+ space_avail = kmsg->msg_controllen + bufsz;
+ wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
+ if(workbuf == NULL)
+ goto fail;
+
+ /* To make this more sane we assume the kernel sends back properly
+ * formatted control messages. Because of how the kernel will truncate
+ * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
+ */
+ ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
+ while(((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
+ struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
+ int clen64, clen32;
+
+ /* UCMSG is the 64-bit format CMSG entry in user-space.
+ * KCMSG32 is within the kernel space temporary buffer
+ * we use to convert into a 32-bit style CMSG.
+ */
+ __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
+ __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
+ __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
+
+ clen64 = kcmsg32->cmsg_len;
+ copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
+ clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
+ clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
+ CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+ kcmsg32->cmsg_len = clen32;
+
+ ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
+ wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
+ }
+
+ /* Copy back fixed up data, and adjust pointers. */
+ bufsz = (wp - workbuf);
+ copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
+
+ kmsg->msg_control = (struct cmsghdr *)
+ (((char *)orig_cmsg_uptr) + bufsz);
+ kmsg->msg_controllen = space_avail - bufsz;
+
+ kfree(workbuf);
+ return;
+
+fail:
+ /* If we leave the 64-bit format CMSG chunks in there,
+ * the application could get confused and crash. So to
+ * ensure greater recovery, we report no CMSGs.
+ */
+ kmsg->msg_controllen += bufsz;
+ kmsg->msg_control = (void *) orig_cmsg_uptr;
+}
+
X asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
X {
X struct socket *sock;
@@ -2455,6 +2543,14 @@
X if(scm.fp)
X __scm_destroy(&scm);
X } else {
+ /* If recvmsg processing itself placed some
+ * control messages into user space, it's is
+ * using 64-bit CMSG processing, so we need
+ * to fix it up before we tack on more stuff.
+ */
+ if((unsigned long) kern_msg.msg_control != cmsg_ptr)
+ cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
+
X /* Wheee... */
X if(sock->passcred)
X put_cmsg32(&kern_msg,
@@ -2471,9 +2567,9 @@
X if(uaddr != NULL && err >= 0)
X err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
X if(cmsg_ptr != 0 && err >= 0) {
- u32 ucmsg_ptr = ((u32)(unsigned long)kern_msg.msg_control);
- err = __put_user(ucmsg_ptr, &user_msg->msg_control);
- err |= __put_user(kern_msg.msg_controllen, &user_msg->msg_controllen);
+ unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
+ __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+ err |= __put_user(uclen, &user_msg->msg_controllen);
X }
X if(err >= 0)
X err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
diff -u --recursive --new-file v2.3.2/linux/arch/sparc64/solaris/fs.c linux/arch/sparc64/solaris/fs.c
--- v2.3.2/linux/arch/sparc64/solaris/fs.c Fri May 14 18:55:13 1999
+++ linux/arch/sparc64/solaris/fs.c Sat May 15 11:12:09 1999
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.12 1999/01/02 16:46:06 davem Exp $
+/* $Id: fs.c,v 1.13 1999/05/14 07:24:37 davem Exp $
X * fs.c: fs related syscall emulation for Solaris
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
diff -u --recursive --new-file v2.3.2/linux/arch/sparc64/solaris/ipc.c linux/arch/sparc64/solaris/ipc.c
--- v2.3.2/linux/arch/sparc64/solaris/ipc.c Tue Aug 4 16:03:35 1998
+++ linux/arch/sparc64/solaris/ipc.c Sat May 15 11:12:09 1999
@@ -1,4 +1,4 @@
-/* $Id: ipc.c,v 1.3 1998/07/30 11:29:47 davem Exp $
+/* $Id: ipc.c,v 1.4 1999/05/13 07:11:37 jj Exp $
X * ipc.c: Solaris IPC emulation
X *
X * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -7,6 +7,7 @@
X #include <linux/kernel.h>
X #include <linux/types.h>
X #include <linux/smp_lock.h>
+#include <linux/wait.h>
X #include <linux/shm.h>
X #include <linux/sem.h>
X #include <linux/msg.h>
diff -u --recursive --new-file v2.3.2/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- v2.3.2/linux/drivers/acorn/block/fd1772.c Thu Jan 7 08:46:58 1999
+++ linux/drivers/acorn/block/fd1772.c Sat May 15 15:05:35 1999
@@ -267,7 +267,7 @@
X
X /* Synchronization of FDC1772 access. */
X static volatile int fdc_busy = 0;
-static struct wait_queue *fdc_wait = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
X
X
X static unsigned int changed_floppies = 0xff, fake_change = 0;
diff -u --recursive --new-file v2.3.2/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.3.2/linux/drivers/acorn/block/mfmhd.c Mon Aug 24 13:14:09 1998
+++ linux/drivers/acorn/block/mfmhd.c Sat May 15 15:05:35 1999
@@ -195,7 +195,7 @@
X static int mfm_sizes[MFM_MAXDRIVES << 6];
X static int mfm_blocksizes[MFM_MAXDRIVES << 6];
X static int mfm_sectsizes[MFM_MAXDRIVES << 6];
-static struct wait_queue *mfm_wait_open = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(mfm_wait_open);
X
X /* Stuff from the assembly routines */
X extern unsigned int hdc63463_baseaddress; /* Controller base address */
diff -u --recursive --new-file v2.3.2/linux/drivers/ap1000/ap.c linux/drivers/ap1000/ap.c
--- v2.3.2/linux/drivers/ap1000/ap.c Mon Aug 24 13:45:51 1998
+++ linux/drivers/ap1000/ap.c Sat May 15 15:05:35 1999
@@ -36,7 +36,7 @@
X #define NUM_APDEVS 8
X #define MAX_REQUESTS 1
X
-static struct wait_queue * busy_wait = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(busy_wait);
X
X static int ap_blocksizes[NUM_APDEVS];
X static int ap_length[NUM_APDEVS];
diff -u --recursive --new-file v2.3.2/linux/drivers/ap1000/ddv.c linux/drivers/ap1000/ddv.c
--- v2.3.2/linux/drivers/ap1000/ddv.c Mon Aug 24 13:02:44 1998
+++ linux/drivers/ap1000/ddv.c Sat May 15 15:05:35 1999
@@ -84,7 +84,7 @@
X static char *ddv_opcodep = NULL;
X static struct request *next_request = NULL;
X
-static struct wait_queue * busy_wait = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(busy_wait);
X
X static int ddv_blocksizes[NUM_DDVDEVS]; /* in bytes */
X int ddv_sect_length[NUM_DDVDEVS]; /* in sectors */
@@ -93,7 +93,7 @@
X /* these are used by the ddv_daemon, which services remote disk requests */
X static struct remote_request *rem_queue = NULL;
X static struct remote_request *rem_queue_end;
-static struct wait_queue *ddv_daemon_wait = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(ddv_daemon_wait);
X
X static int opiu_kernel_loaded = 0;
X
diff -u --recursive --new-file v2.3.2/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.3.2/linux/drivers/block/Makefile Fri May 14 18:55:13 1999
+++ linux/drivers/block/Makefile Sat May 15 23:43:04 1999
@@ -20,7 +20,7 @@
X
X
X L_TARGET := block.a
-L_OBJS := genhd.o
+L_OBJS := genhd.o blkpg.o
X M_OBJS :=
X MOD_LIST_NAME := BLOCK_MODULES
X LX_OBJS := ll_rw_blk.o
diff -u --recursive --new-file v2.3.2/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.3.2/linux/drivers/block/acsi.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/acsi.c Sat May 15 23:43:04 1999
@@ -64,6 +64,7 @@
X typedef void Scsi_Device; /* hack to avoid including scsi.h */
X #include <scsi/scsi_ioctl.h>
X #include <linux/hdreg.h> /* for HDIO_GETGEO */
+#include <linux/blkpg.h>
X
X #include <asm/setup.h>
X #include <asm/pgtable.h>
@@ -1125,8 +1126,8 @@
X return -EINVAL;
X switch (cmd) {
X case HDIO_GETGEO:
- /* HDIO_GETGEO is supported more for getting the partition's start
- * sector... */
+ /* HDIO_GETGEO is supported more for getting the partition's
+ * start sector... */
X { struct hd_geometry *geo = (struct hd_geometry *)arg;
X /* just fake some geometry here, it's nonsense anyway; to make it
X * easy, use Adaptec's usual 64/32 mapping */
@@ -1147,19 +1148,18 @@
X case BLKGETSIZE: /* Return device size */
X return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects,
X (long *) arg);
-
+


+ case BLKROSET:
+ case BLKROGET:

X case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;

- if(!inode->i_rdev) return -EINVAL;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);

X

X case BLKRRPART: /* Re-read partition tables */
X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;

X return revalidate_acsidisk(inode->i_rdev, 1);
- RO_IOCTLS(inode->i_rdev,arg);
+
X default:
X return -EINVAL;
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c
--- v2.3.2/linux/drivers/block/ataflop.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/ataflop.c Sat May 15 23:43:04 1999
@@ -93,6 +93,7 @@
X
X #define MAJOR_NR FLOPPY_MAJOR


X #include <linux/blk.h>
+#include <linux/blkpg.h>
X

X #define FD_MAX_UNITS 2
X
@@ -1584,7 +1585,12 @@
X
X device = inode->i_rdev;
X switch (cmd) {
- RO_IOCTLS (device, param);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:
+ return blk_ioctl(device, cmd, param);
X }
X drive = MINOR (device);
X type = drive >> 2;
@@ -1620,22 +1626,6 @@
X getprm.stretch = dtp->stretch;
X if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
X return -EFAULT;
- return 0;
- case BLKRASET:


- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;

- if (param > 0xff)
- return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = param;
- return 0;
- case BLKRAGET:
- return put_user(read_ahead[MAJOR(inode->i_rdev)],
- (int *) param);
- case BLKFLSBUF:


- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;

- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);

X return 0;
X }
X if (!IOCTL_ALLOWED)
diff -u --recursive --new-file v2.3.2/linux/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- v2.3.2/linux/drivers/block/blkpg.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/blkpg.c Sat May 15 23:43:04 1999
@@ -0,0 +1,288 @@
+/*
+ * Partition table and disk geometry handling
+ *
+ * This obsoletes the partition-handling code in genhd.c:
+ * Userspace can look at a disk in arbitrary format and tell
+ * the kernel what partitions there are on the disk, and how
+ * these should be numbered.
+ * It also allows one to repartition a disk that is being used.
+ *
+ * A single ioctl with lots of subfunctions:
+ *
+ * Device number stuff:
+ * get_whole_disk() (given the device number of a partition, find
+ * the device number of the encompassing disk)
+ * get_all_partitions() (given the device number of a disk, return the
+ * device numbers of all its known partitions)
+ *
+ * Partition stuff:
+ * add_partition()
+ * delete_partition()
+ * test_partition_in_use() (also for test_disk_in_use)
+ *
+ * Geometry stuff:
+ * get_geometry()
+ * set_geometry()
+ * get_bios_drivedata()
+ *
+ * For today, only the partition stuff - aeb, 990515
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h> /* for BLKRASET, ... */
+#include <linux/sched.h> /* for capable() */
+#include <linux/blk.h> /* for set_device_ro() */
+#include <linux/blkpg.h>
+#include <linux/genhd.h>
+#include <linux/swap.h> /* for is_swap_partition() */
+
+#include <asm/uaccess.h>
+
+/*
+ * What is the data describing a partition?
+ *
+ * 1. a device number (kdev_t)
+ * 2. a starting sector and number of sectors (hd_struct)
+ * given in the part[] array of the gendisk structure for the drive.
+ *
+ * The number of sectors is replicated in the sizes[] array of
+ * the gendisk structure for the major, which again is copied to
+ * the blk_size[][] array.
+ * (However, hd_struct has the number of 512-byte sectors,
+ * g->sizes[] and blk_size[][] have the number of 1024-byte blocks.)
+ * Note that several drives may have the same major.
+ */
+
+/* a linear search, superfluous when dev is a pointer */
+static struct gendisk *get_gendisk(kdev_t dev) {
+ struct gendisk *g;
+ int m = MAJOR(dev);
+
+ for (g = gendisk_head; g; g = g->next)
+ if (g->major == m)
+ break;
+ return g;
+}
+
+/* moved here from md.c - will be discarded later */
+char *partition_name (kdev_t dev) {
+ static char name[40]; /* kdevname returns 32 bytes */
+ /* disk_name requires 32 bytes */
+ struct gendisk *hd = get_gendisk (dev);
+
+ if (!hd) {
+ sprintf (name, "[dev %s]", kdevname(dev));
+ return (name);
+ }
+
+ return disk_name (hd, MINOR(dev), name); /* routine in genhd.c */
+}
+
+/*
+ * Add a partition.
+ *
+ * returns: EINVAL: bad parameters
+ * ENXIO: cannot find drive
+ * EBUSY: proposed partition overlaps an existing one
+ * or has the same number as an existing one
+ * 0: all OK.
+ */
+int add_partition(kdev_t dev, struct blkpg_partition *p) {
+ struct gendisk *g;
+ long long ppstart, pplength;
+ long pstart, plength;
+ int i, drive, first_minor, end_minor, minor;
+
+ /* convert bytes to sectors, check for fit in a hd_struct */
+ ppstart = (p->start >> 9);
+ pplength = (p->length >> 9);
+ pstart = ppstart;
+ plength = pplength;
+ if (pstart != ppstart || plength != pplength
+ || pstart < 0 || plength < 0)
+ return -EINVAL;
+
+ /* find the drive major */
+ g = get_gendisk(dev);
+ if (!g)
+ return -ENXIO;
+
+ /* existing drive? */
+ drive = (MINOR(dev) >> g->minor_shift);
+ first_minor = (drive << g->minor_shift);
+ end_minor = first_minor + g->max_p;
+ if (drive >= g->nr_real)
+ return -ENXIO;
+
+ /* drive and partition number OK? */
+ if (first_minor != MINOR(dev) || p->pno <= 0 || p->pno >= g->max_p)
+ return -EINVAL;
+
+ /* partition number in use? */
+ minor = first_minor + p->pno;
+ if (g->part[minor].nr_sects != 0)
+ return -EBUSY;
+
+ /* overlap? */
+ for (i=first_minor+1; i<end_minor; i++)
+ if (!(pstart+plength <= g->part[i].start_sect ||
+ pstart >= g->part[i].start_sect + g->part[i].nr_sects))
+ return -EBUSY;
+
+ /* all seems OK */
+ g->part[minor].start_sect = pstart;
+ g->part[minor].nr_sects = plength;
+ if (g->sizes)
+ g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9));
+ return 0;
+}
+
+/*
+ * Delete a partition given by partition number
+ *
+ * returns: EINVAL: bad parameters
+ * ENXIO: cannot find partition
+ * EBUSY: partition is busy
+ * 0: all OK.
+ *
+ * Note that the dev argument refers to the entire disk, not the partition.
+ */
+int del_partition(kdev_t dev, struct blkpg_partition *p) {
+ struct gendisk *g;
+ kdev_t devp;
+ int drive, first_minor, minor;
+
+ /* find the drive major */
+ g = get_gendisk(dev);
+ if (!g)
+ return -ENXIO;
+
+ /* drive and partition number OK? */
+ drive = (MINOR(dev) >> g->minor_shift);
+ first_minor = (drive << g->minor_shift);
+ if (first_minor != MINOR(dev) || p->pno <= 0 || p->pno >= g->max_p)
+ return -EINVAL;
+
+ /* existing drive and partition? */
+ minor = first_minor + p->pno;
+ if (drive >= g->nr_real || g->part[minor].nr_sects == 0)
+ return -ENXIO;
+
+ /* partition in use? Incomplete check for now. */
+ devp = MKDEV(MAJOR(dev), minor);
+ if (get_super(devp) || /* mounted? */
+ is_swap_partition(devp))
+ return -EBUSY;
+
+ /* all seems OK */
+ fsync_dev(devp);
+ invalidate_buffers(devp);
+
+ g->part[minor].start_sect = 0;
+ g->part[minor].nr_sects = 0;
+ if (g->sizes)
+ g->sizes[minor] = 0;
+
+ return 0;
+}
+
+int blkpg_ioctl(kdev_t dev, struct blkpg_ioctl_arg *arg)
+{
+ struct blkpg_ioctl_arg a;
+ struct blkpg_partition p;
+ int len;
+
+ if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
+ return -EFAULT;
+
+ switch (a.op) {
+ case BLKPG_ADD_PARTITION:
+ case BLKPG_DEL_PARTITION:
+ len = a.datalen;
+ if (len < sizeof(struct blkpg_partition))
+ return -EINVAL;
+ if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+ return -EFAULT;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (a.op == BLKPG_ADD_PARTITION)
+ return add_partition(dev, &p);
+ else
+ return del_partition(dev, &p);
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Common ioctl's for block devices
+ */
+
+int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
+{
+ int intval;
+
+ switch (cmd) {
+ case BLKROSET:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (get_user(intval, (int *)(arg)))
+ return -EFAULT;
+ set_device_ro(dev, intval);
+ return 0;
+ case BLKROGET:
+ intval = (is_read_only(dev) != 0);
+ return put_user(intval, (int *)(arg));
+
+ case BLKRASET:
+ if(!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if(!dev || arg > 0xff)
+ return -EINVAL;
+ read_ahead[MAJOR(dev)] = arg;
+ return 0;
+ case BLKRAGET:
+ if (!arg)
+ return -EINVAL;
+ return put_user(read_ahead[MAJOR(dev)], (long *) arg);
+
+ case BLKFLSBUF:
+ if(!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (!dev)
+ return -EINVAL;
+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ return 0;
+
+ case BLKSSZGET:
+ /* get block device sector size as needed e.g. by fdisk */
+ intval = get_hardsect_size(dev);
+ return put_user(intval, (int *) arg);
+
+#if 0
+ case BLKGETSIZE:
+ /* Today get_gendisk() requires a linear scan;
+ add this when dev has pointer type. */
+ g = get_gendisk(dev);
+ if (!g)
+ longval = 0;
+ else
+ longval = g->part[MINOR(dev)].nr_sects;
+ return put_user(longval, (long *) arg);
+#endif
+#if 0
+ case BLKRRPART: /* Re-read partition tables */
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ return reread_partitions(dev, 1);
+#endif
+
+ case BLKPG:
+ return blkpg_ioctl(dev, (struct blkpg_ioctl_arg *) arg);
+
+ default:
+ return -EINVAL;
+ }
+}
+
diff -u --recursive --new-file v2.3.2/linux/drivers/block/cmd646.c linux/drivers/block/cmd646.c
--- v2.3.2/linux/drivers/block/cmd646.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/cmd646.c Sat May 15 11:12:09 1999
@@ -1,4 +1,4 @@
-/* $Id: cmd646.c,v 1.11 1998/12/13 08:36:54 davem Exp $
+/* $Id: cmd646.c,v 1.12 1999/05/14 07:21:01 davem Exp $
X * cmd646.c: Enable interrupts at initialization time on Ultra/PCI machines.
X * Note, this driver is not used at all on other systems because
X * there the "BIOS" has done all of the following already.
diff -u --recursive --new-file v2.3.2/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.3.2/linux/drivers/block/floppy.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/floppy.c Sat May 15 23:43:04 1999
@@ -198,6 +198,7 @@
X #define MAJOR_NR FLOPPY_MAJOR


X
X #include <linux/blk.h>
+#include <linux/blkpg.h>

X #include <linux/cdrom.h> /* for the compatibility eject ioctl */
X
X #ifndef fd_get_dma_residue
@@ -3293,7 +3294,7 @@
X LOCK_FDC(drive,1);
X if (cmd != FDDEFPRM)
X /* notice a disk change immediately, else
- * we loose our settings immediately*/
+ * we lose our settings immediately*/
X CALL(poll_drive(1, FD_RAW_NEED_DISK));
X user_params[drive] = *g;
X if (buffer_drive == drive)
@@ -3402,7 +3403,12 @@
X
X device = inode->i_rdev;
X switch (cmd) {
- RO_IOCTLS(device,param);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:
+ return blk_ioctl(device, cmd, param);
X }
X type = TYPE(device);
X drive = DRIVE(device);
@@ -3432,19 +3438,6 @@
X loc.start = 0;
X return _COPYOUT(loc);
X }
- case BLKRASET:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(param > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = param;
- return 0;
- case BLKRAGET:
- return put_user(read_ahead[MAJOR(inode->i_rdev)],
- (long *) param);
- case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X
X case BLKGETSIZE:
X ECALL(get_floppy_geometry(drive, type, &g));
diff -u --recursive --new-file v2.3.2/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.3.2/linux/drivers/block/genhd.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/genhd.c Sat May 15 23:43:04 1999
@@ -66,10 +66,10 @@
X #endif
X
X /*
- * disk_name() is used by genhd.c and md.c.
- * It formats the devicename of the indicated disk
- * into the supplied buffer, and returns a pointer
- * to that same buffer (for convenience).
+ * disk_name() is used by genhd.c and blkpg.c.
+ * It formats the devicename of the indicated disk into
+ * the supplied buffer (of size at least 32), and returns
+ * a pointer to that same buffer (for convenience).
X */
X char *disk_name (struct gendisk *hd, int minor, char *buf)
X {
@@ -121,7 +121,7 @@
X
X static void add_partition (struct gendisk *hd, int minor, int start, int size)
X {
- char buf[8];
+ char buf[32];
X hd->part[minor].start_sect = start;
X hd->part[minor].nr_sects = size;
X printk(" %s", disk_name(hd, minor, buf));
@@ -134,12 +134,12 @@
X SYS_IND(p) == LINUX_EXTENDED_PARTITION);
X }
X
-static int sector_partition_scale(kdev_t dev)
+int get_hardsect_size(kdev_t dev)
X {
- if (hardsect_size[MAJOR(dev)] != NULL)
- return (hardsect_size[MAJOR(dev)][MINOR(dev)]/512);
- else
- return (1);
+ if (hardsect_size[MAJOR(dev)] != NULL)
+ return hardsect_size[MAJOR(dev)][MINOR(dev)];
+ else
+ return 512;
X }
X
X static unsigned int get_ptable_blocksize(kdev_t dev)
@@ -209,7 +209,7 @@
X struct partition *p;
X unsigned long first_sector, first_size, this_sector, this_size;
X int mask = (1 << hd->minor_shift) - 1;
- int sector_size = sector_partition_scale(dev);
+ int sector_size = get_hardsect_size(dev) / 512;
X int i;
X
X first_sector = hd->part[MINOR(dev)].start_sect;
@@ -453,7 +453,7 @@
X struct partition *p;
X unsigned char *data;
X int mask = (1 << hd->minor_shift) - 1;
- int sector_size = sector_partition_scale(dev);
+ int sector_size = get_hardsect_size(dev) / 512;
X #ifdef CONFIG_BSD_DISKLABEL
X /* no bsd disklabel as a default */
X kdev_t bsd_kdev = 0;
@@ -883,10 +883,7 @@
X int blocksize;
X
X old_blocksize = get_ptable_blocksize(dev);
- if (hardsect_size[MAJOR(dev)] != NULL)
- blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
- else
- blocksize = 512;
+ blocksize = get_hardsect_size(dev);
X
X set_blocksize(dev,blocksize);
X res = 0;
@@ -1223,7 +1220,7 @@
X {
X static int first_time = 1;
X unsigned long first_sector;
- char buf[8];
+ char buf[32];
X
X if (first_time)
X printk("Partition check:\n");
@@ -1307,28 +1304,21 @@
X int end_minor = dev->max_nr * dev->max_p;
X
X blk_size[dev->major] = NULL;
- for (i = 0 ; i < end_minor; i++) {
+ for (i = 0; i < end_minor; i++) {
X dev->part[i].start_sect = 0;
X dev->part[i].nr_sects = 0;
+ dev->sizes[i] = 0;
X }
X dev->init(dev);
- for (drive = 0 ; drive < dev->nr_real ; drive++) {
- int first_minor = drive << dev->minor_shift;
- current_minor = 1 + 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++)
- dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
- blk_size[dev->major] = dev->sizes;
- }
+ for (drive = 0; drive < dev->nr_real; drive++)
+ resetup_one_dev(dev, drive);
X }
X
X __initfunc(void device_setup(void))
X {
X extern void console_map_init(void);
X #ifdef CONFIG_PARPORT
- extern int parport_init(void);
+ extern int parport_init(void) __init;
X #endif
X #ifdef CONFIG_MD_BOOT
X extern void md_setup_drive(void) __init;
diff -u --recursive --new-file v2.3.2/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v2.3.2/linux/drivers/block/hd.c Fri May 14 18:55:13 1999
+++ linux/drivers/block/hd.c Sat May 15 23:43:04 1999
@@ -604,31 +604,25 @@
X g.start = hd[MINOR(inode->i_rdev)].start_sect;
X return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
X }
- case BLKRASET:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;


- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

- case BLKRAGET:
- if (!arg) return -EINVAL;
- return put_user(read_ahead[MAJOR(inode->i_rdev)],
- (long *) arg);
+
X case BLKGETSIZE: /* Return device size */
X if (!arg) return -EINVAL;
X return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
X (long *) arg);
- case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X

X case BLKRRPART: /* Re-read partition tables */
X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;

X return revalidate_hddisk(inode->i_rdev, 1);
X
- RO_IOCTLS(inode->i_rdev,arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:


+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
+

X default:
X return -EINVAL;
X }
@@ -836,7 +830,7 @@
X if (DEVICE_BUSY || USAGE > maxusage) {
X restore_flags(flags);
X return -EBUSY;
- };
+ }
X DEVICE_BUSY = 1;
X restore_flags(flags);
X
@@ -854,7 +848,7 @@
X invalidate_buffers(devi);
X gdev->part[minor].start_sect = 0;
X gdev->part[minor].nr_sects = 0;
- };
+ }
X
X #ifdef MAYBE_REINIT
X MAYBE_REINIT;
diff -u --recursive --new-file v2.3.2/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.3.2/linux/drivers/block/ide.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/ide.c Sun May 16 10:56:16 1999
@@ -122,6 +122,7 @@
X #include <linux/major.h>
X #include <linux/errno.h>
X #include <linux/genhd.h>
+#include <linux/blkpg.h>
X #include <linux/malloc.h>
X #include <linux/pci.h>
X #include <linux/delay.h>
@@ -2232,17 +2233,6 @@
X (unsigned long *) &loc->start)) return -EFAULT;
X return 0;
X }


- case BLKSSZGET:
- /* Block size of media */

- return put_user(blksize_size[HWIF(drive)->major]
- [minor&PARTN_MASK],
- (int *)arg);
-
- case BLKFLSBUF:
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X
X case BLKGETSIZE: /* Return device size */
X return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (long *) arg);
@@ -2383,7 +2373,12 @@
X drive->nice1 = (arg >> IDE_NICE_1) & 1;
X return 0;
X
- RO_IOCTLS(inode->i_rdev, arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKFLSBUF:


+ case BLKSSZGET:
+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);

X
X default:
X if (drive->driver != NULL)
@@ -2917,121 +2912,10 @@
X * Returns 1 if the geometry translation was successful.
X */
X
-#define ANDRIES_GEOMETRY 0
-
X int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg)
X {
X ide_drive_t *drive;
X
-#if ANDRIES_GEOMETRY
- /*
- * This is the documented list of values (some version of)
- * OnTrack DM uses.
- */
-
- static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
-
- /*
- * This is a pure phantasy list - known to be incorrect.
- *
- * In fact it seems that EZD does not do anything to the CHS
- * values in the partition table, so whether EZD is present
- * or not should probably not influence the geometry.
- */
-
- static const byte ez_head_vals[] = {4, 8, 16, 32, 64, 128, 240, 255, 0}; const byte *heads;
- unsigned long tracks;
-
- drive = get_info_ptr(i_rdev);
- if (!drive)
- return 0;
-
- if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63) {
- /*
- * Update the current 3D drive values.
- */
- drive->id->cur_cyls = drive->bios_cyl;
- drive->id->cur_heads = drive->bios_head;
- drive->id->cur_sectors = drive->bios_sect;
- return 0; /* we already have a translation */
- }
-
- if (xparm == -1) {
- int ret = 0;
-#if FAKE_FDISK_FOR_EZDRIVE
- if (drive->remap_0_to_1 == 0) {
- drive->remap_0_to_1 = 1;
- printk("%s [remap 0->1]", msg);
- msg = NULL;
- ret = 1;
- }
- if (drive->bios_head > 16)
-#endif /* FAKE_FDISK_FOR_EZDRIVE */
- {
- /*
- * Update the current 3D drive values.
- */
- drive->id->cur_cyls = drive->bios_cyl;
- drive->id->cur_heads = drive->bios_head;
- drive->id->cur_sectors = drive->bios_sect;
- return ret; /* we already have a translation */
- }
- }
-
- if (msg)
- printk("%s ", msg);
-
- if (drive->forced_geom) {
- /*
- * Update the current 3D drive values.
- */
- drive->id->cur_cyls = drive->bios_cyl;
- drive->id->cur_heads = drive->bios_head;
- drive->id->cur_sectors = drive->bios_sect;


- return 0;
- }
-

-#if 1
- /* There used to be code here that assigned drive->id->CHS
- to drive->CHS and that to drive->bios_CHS. However,
- some disks have id->C/H/S = 4092/16/63 but are larger than 2.1 GB.
- In such cases that code was wrong. Moreover,
- there seems to be no reason to do any of these things. */
-#else
- if (drive->id) {
- drive->cyl = drive->id->cyls;
- drive->head = drive->id->heads;
- drive->sect = drive->id->sectors;
- }
- drive->bios_cyl = drive->cyl;
- drive->bios_head = drive->head;
- drive->bios_sect = drive->sect;
- drive->special.b.set_geometry = 1;
-
-#endif
-
- tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
- drive->bios_sect = 63;
- if (xparm > 1) {
- drive->bios_head = xparm;
- drive->bios_cyl = tracks / drive->bios_head;
- } else {
- heads = (xparm == -1) ? ez_head_vals : dm_head_vals;
- while (drive->bios_cyl >= 1024) {
- drive->bios_head = *heads;
- drive->bios_cyl = tracks / drive->bios_head;
- if (0 == *++heads)
- break;
- }
- if (xparm == 1) {
- drive->sect0 = 63;
- drive->bios_cyl = (tracks - 1) / drive->bios_head;
- printk("[remap +63] ");
- }
- }
-
-#else /* ANDRIES_GEOMETRY */
-
X static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
X const byte *heads = head_vals;
X unsigned long tracks;
@@ -3106,7 +2990,6 @@
X printk("[remap +63] ");
X }
X }
-#endif /* ANDRIES_GEOMETRY */
X
X drive->part[0].nr_sects = current_capacity(drive);
X printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
diff -u --recursive --new-file v2.3.2/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.3.2/linux/drivers/block/md.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/md.c Sat May 15 23:43:04 1999
@@ -59,6 +59,7 @@
X #define MD_DRIVER


X
X #include <linux/blk.h>
+#include <linux/blkpg.h>

X #include <asm/uaccess.h>
X #include <asm/bitops.h>
X #include <asm/atomic.h>
@@ -98,36 +99,6 @@
X
X int md_thread(void * arg);
X
-static struct gendisk *find_gendisk (kdev_t dev)
-{
- struct gendisk *tmp=gendisk_head;
-
- while (tmp != NULL)
- {
- if (tmp->major==MAJOR(dev))
- return (tmp);
-
- tmp=tmp->next;
- }
-
- return (NULL);
-}
-
-char *partition_name (kdev_t dev)
-{
- static char name[40]; /* This should be long
- enough for a device name ! */
- struct gendisk *hd = find_gendisk (dev);
-
- if (!hd)
- {
- sprintf (name, "[dev %s]", kdevname(dev));
- return (name);
- }
-
- return disk_name (hd, MINOR(dev), name); /* routine in genhd.c */
-}
-
X static int legacy_raid_sb (int minor, int pnum)
X {
X int i, factor;
@@ -653,24 +624,7 @@
X return err;
X break;
X
- case BLKFLSBUF:
- fsync_dev (inode->i_rdev);
- invalidate_buffers (inode->i_rdev);
- break;
-
- case BLKRASET:
- if (arg > 0xff)
- return -EINVAL;


- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

X
- case BLKRAGET:
- if (!arg) return -EINVAL;
- err = put_user (read_ahead[MAJOR(inode->i_rdev)], (long *) arg);


- if (err)
- return err;

- break;
-
X /* We have a problem here : there is no easy way to give a CHS
X virtual geometry. We currently pretend that we have a 2 heads
X 4 sectors (with a BIG number of cylinders...). This drives dosfs
@@ -693,7 +647,12 @@
X return err;
X break;
X
- RO_IOCTLS(inode->i_rdev,arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRAGET:
+ case BLKRASET:
+ case BLKFLSBUF:


+ return blk_ioctl(inode->i_rdev, cmd, arg);

X
X default:
X return -EINVAL;
@@ -901,7 +860,6 @@
X EXPORT_SYMBOL(md_maxreadahead);
X EXPORT_SYMBOL(register_md_personality);
X EXPORT_SYMBOL(unregister_md_personality);
-EXPORT_SYMBOL(partition_name);
X EXPORT_SYMBOL(md_dev);
X EXPORT_SYMBOL(md_error);
X EXPORT_SYMBOL(md_register_thread);
diff -u --recursive --new-file v2.3.2/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.3.2/linux/drivers/block/paride/pd.c Mon Sep 28 10:51:16 1998
+++ linux/drivers/block/paride/pd.c Sat May 15 23:43:04 1999
@@ -208,6 +208,7 @@
X #define DEVICE_OFF(device)


X
X #include <linux/blk.h>
+#include <linux/blkpg.h>
X

X #include "pseudo.h"
X
@@ -331,7 +332,7 @@
X static int pd_poffs; /* partition offset of current minor */
X static char * pd_buf; /* buffer for request in progress */
X
-static struct wait_queue *pd_wait_open = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open);
X
X static char *pd_errs[17] = { "ERR","INDEX","ECC","DRQ","SEEK","WRERR",
X "READY","BUSY","AMNF","TK0NF","ABRT","MCR",
@@ -483,35 +484,23 @@
X }
X put_user(pd_hd[dev].start_sect,(long *)&geo->start);
X return 0;
- case BLKRASET:


- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;

- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

- case BLKRAGET:
- if (!arg) return -EINVAL;


- err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));

- if (err) return (err);
- put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
- return (0);
X case BLKGETSIZE:
X if (!arg) return -EINVAL;
X err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
X if (err) return (err);
X put_user(pd_hd[dev].nr_sects,(long *) arg);
X return (0);
- case BLKFLSBUF:


- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X case BLKRRPART:


X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;

X return pd_revalidate(inode->i_rdev);
- RO_IOCTLS(inode->i_rdev,arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:


+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);

X default:
X return -EINVAL;
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- v2.3.2/linux/drivers/block/paride/pf.c Wed Nov 4 10:04:43 1998
+++ linux/drivers/block/paride/pf.c Sat May 15 23:43:04 1999
@@ -205,6 +205,7 @@
X #define DEVICE_OFF(device)


X
X #include <linux/blk.h>
+#include <linux/blkpg.h>
X

X #include "pseudo.h"
X
@@ -433,31 +434,18 @@
X }
X put_user(0,(long *)&geo->start);
X return 0;
- case BLKRASET:


- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;

- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

- case BLKRAGET:
- if (!arg) return -EINVAL;


- err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));

- if (err) return (err);
- put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
- return (0);
X case BLKGETSIZE:
X if (!arg) return -EINVAL;
X err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
X if (err) return (err);
X put_user(PF.capacity,(long *) arg);
X return (0);
- case BLKFLSBUF:


- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

- RO_IOCTLS(inode->i_rdev,arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:


+ return blk_ioctl(inode->i_rdev, cmd, arg);

X default:
X return -EINVAL;
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.3.2/linux/drivers/block/ps2esdi.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/ps2esdi.c Sat May 15 23:43:04 1999
@@ -42,6 +42,7 @@
X #include <linux/genhd.h>
X #include <linux/ps2esdi.h>


X #include <linux/blk.h>
+#include <linux/blkpg.h>

X #include <linux/mca.h>
X #include <linux/init.h>
X #include <linux/ioport.h>
@@ -1140,15 +1141,7 @@
X return (0);
X }
X break;
- case BLKRASET:


- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;

- if (!inode->i_rdev)
- return -EINVAL;
- if (arg > 0xff)
- return -EINVAL;


- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

+
X case BLKGETSIZE:
X if (arg) {
X if ((err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long))))
@@ -1158,20 +1151,19 @@
X return (0);
X }
X break;
- case BLKFLSBUF:


- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;

- if (!inode->i_rdev)
- return -EINVAL;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X
X case BLKRRPART:


X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;

X return (ps2esdi_reread_partitions(inode->i_rdev));
- RO_IOCTLS(inode->i_rdev, arg);
+


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:
+ case BLKFLSBUF:


+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);

X }
X return (-EINVAL);
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.3.2/linux/drivers/block/rd.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/rd.c Sat May 15 23:43:04 1999
@@ -72,6 +72,7 @@
X */
X #define MAJOR_NR RAMDISK_MAJOR


X #include <linux/blk.h>
+#include <linux/blkpg.h>
X

X /*
X * We use a block size of 512 bytes in comparision to BLOCK_SIZE
@@ -198,11 +199,10 @@
X if (!arg) return -EINVAL;
X return put_user(rd_length[minor] >> RDBLK_SIZE_BITS, (long *) arg);
X
- case BLKSSZGET: /* Block size of media */
- if (!arg) return -EINVAL;
- return put_user(rd_blocksizes[minor], (int *)arg);
-
- RO_IOCTLS(inode->i_rdev, arg);


+ case BLKROSET:
+ case BLKROGET:

+ case BLKSSZGET:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
X
X default:
X return -EINVAL;
@@ -519,7 +519,7 @@
X }
X
X if (nblocks > (rd_length[unit] >> RDBLK_SIZE_BITS)) {
- printk("RAMDISK: image too big! (%d/%d blocks)\n",
+ printk("RAMDISK: image too big! (%d/%ld blocks)\n",
X nblocks, rd_length[unit] >> RDBLK_SIZE_BITS);
X goto done;
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.3.2/linux/drivers/block/xd.c Fri May 14 18:55:15 1999
+++ linux/drivers/block/xd.c Sat May 15 23:43:04 1999
@@ -49,6 +49,7 @@
X
X #define MAJOR_NR XT_DISK_MAJOR


X #include <linux/blk.h>
+#include <linux/blkpg.h>
X

X #include "xd.h"
X
@@ -337,21 +338,9 @@
X g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
X return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
X }
- case BLKRASET:
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;


- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;

- case BLKRAGET:
- return put_user(read_ahead[MAJOR(inode->i_rdev)], (long*) arg);
X case BLKGETSIZE:
X if (!arg) return -EINVAL;
X return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
- case BLKFLSBUF: /* Return devices size */
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;


- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;

X case HDIO_SET_DMA:
X if (!capable(CAP_SYS_ADMIN)) return -EACCES;
X if (xdc_busy) return -EBUSY;
@@ -369,7 +358,15 @@


X if (!capable(CAP_SYS_ADMIN))
X return -EACCES;

X return xd_reread_partitions(inode->i_rdev);
- RO_IOCTLS(inode->i_rdev,arg);
+
+ case BLKFLSBUF:


+ case BLKROSET:
+ case BLKROGET:

+ case BLKRASET:
+ case BLKRAGET:


+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
+

X default:
X return -EINVAL;
X }
diff -u --recursive --new-file v2.3.2/linux/drivers/cdrom/gscd.c linux/drivers/cdrom/gscd.c
--- v2.3.2/linux/drivers/cdrom/gscd.c Sat Oct 31 10:28:25 1998
+++ linux/drivers/cdrom/gscd.c Sat May 15 15:05:36 1999
@@ -76,7 +76,7 @@
X MODULE_PARM(gscd, "h");
X
X /* Kommt spaeter vielleicht noch mal dran ...
- * static struct wait_queue *gscd_waitq = NULL;
+ * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
X */
X
X static void gscd_transfer (void);
diff -u --recursive --new-file v2.3.2/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.3.2/linux/drivers/cdrom/sbpcd.c Fri May 14 18:55:15 1999
+++ linux/drivers/cdrom/sbpcd.c Sat May 15 15:05:36 1999
@@ -585,7 +585,7 @@
X /*==========================================================================*/
X
X #if FUTURE
-static struct wait_queue *sbp_waitq = NULL;
+static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
X #endif FUTURE
X
X static int teac=SBP_TEAC_SPEED;
diff -u --recursive --new-file v2.3.2/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.3.2/linux/drivers/char/cyclades.c Fri May 14 18:55:15 1999
+++ linux/drivers/char/cyclades.c Sat May 15 23:43:04 1999
@@ -1264,7 +1264,7 @@
X TTY_OVERRUN;
X *tty->flip.char_buf_ptr++ = 0;
X /* If the flip buffer itself is
- overflowing, we still loose
+ overflowing, we still lose
X the next incoming character.
X */
X if(tty->flip.count
diff -u --recursive --new-file v2.3.2/linux/drivers/char/dn_keyb.c linux/drivers/char/dn_keyb.c
--- v2.3.2/linux/drivers/char/dn_keyb.c Mon Apr 26 13:28:07 1999
+++ linux/drivers/char/dn_keyb.c Sat May 15 15:05:36 1999
@@ -47,7 +47,7 @@
X static unsigned int kbd_mode=APOLLO_KBD_MODE_KEYB;
X static short mouse_dx,mouse_dy,mouse_buttons;
X static int mouse_ready=0,mouse_update_allowed=0,mouse_active=0;
-static struct wait_queue *mouse_wait=NULL;
+static DECLARE_WAIT_QUEUE_HEAD(mouse_wait);
X static struct fasync_struct *mouse_fasyncptr=NULL;
X
X #if 0
diff -u --recursive --new-file v2.3.2/linux/drivers/char/h8.c linux/drivers/char/h8.c
--- v2.3.2/linux/drivers/char/h8.c Mon Aug 24 13:02:44 1998
+++ linux/drivers/char/h8.c Sat May 15 15:05:36 1999
@@ -160,7 +160,7 @@
X */
X int cpu_speed_divisor = -1;
X int h8_event_mask = 0;
-struct wait_queue *h8_monitor_wait = NULL;
+DECLARE_WAIT_QUEUE_HEAD(h8_monitor_wait);
X unsigned int h8_command_mask = 0;
X int h8_uthermal_threshold = DEFAULT_UTHERMAL_THRESHOLD;
X int h8_uthermal_window = UTH_HYSTERESIS;
@@ -170,7 +170,7 @@
X u_char h8_current_temp = 0;
X u_char h8_system_temp = 0;
X int h8_sync_channel = 0;
-struct wait_queue *h8_sync_wait = NULL;
+DECLARE_WAIT_QUEUE_HEAD(h8_sync_wait);
X int h8_init_performed;
X
X /* CPU speeds and clock divisor values */
diff -u --recursive --new-file v2.3.2/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- v2.3.2/linux/drivers/char/keyboard.c Fri May 14 18:55:16 1999
+++ linux/drivers/char/keyboard.c Sun May 16 10:12:38 1999


SHAR_EOF
true || echo 'restore of patch-2.3.3 failed'
fi

echo 'End of part 1'
echo 'File patch-2.3.3 is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
May 18, 1999, 3:00:00 AM5/18/99
to
Archive-name: v2.3/patch-2.3.3/part4

#!/bin/sh
# this is part 4 of a 4 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh

# file patch-2.3.3 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 4; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.3.3'
else
echo 'x - continuing with patch-2.3.3'

sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.3' &&

X inode->i_mode |= S_ISGID;
X mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.2/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v2.3.2/linux/include/asm-alpha/processor.h Mon Jan 18 09:55:30 1999
+++ linux/include/asm-alpha/processor.h Sat May 15 23:43:04 1999
@@ -85,7 +85,7 @@
X * is the frame pointer in schedule() and $15 is saved at offset 48 by
X * entry.S:do_switch_stack).
X *
- * Under heavy swap load I've seen this loose in an ugly way. So do
+ * Under heavy swap load I've seen this lose in an ugly way. So do
X * some extra sanity checking on the ranges we expect these pointers
X * to be in so that we can fail gracefully. This is just for ps after
X * all. -- r~
diff -u --recursive --new-file v2.3.2/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
--- v2.3.2/linux/include/asm-alpha/semaphore.h Fri May 7 10:55:26 1999
+++ linux/include/asm-alpha/semaphore.h Sat May 15 15:05:37 1999
@@ -16,7 +16,7 @@
X /* Careful, inline assembly knows about the position of these two. */
X atomic_t count;
X atomic_t waking; /* biased by -1 */
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X };
X
X #define MUTEX ((struct semaphore) \
diff -u --recursive --new-file v2.3.2/linux/include/asm-arm/semaphore.h linux/include/asm-arm/semaphore.h
--- v2.3.2/linux/include/asm-arm/semaphore.h Fri May 14 18:55:27 1999
+++ linux/include/asm-arm/semaphore.h Sat May 15 15:05:37 1999
@@ -10,7 +10,7 @@
X struct semaphore {
X atomic_t count;
X int waking;
- struct wait_queue * wait;
+ wait_queue_head_t wait;
X };
X
X #define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL })
diff -u --recursive --new-file v2.3.2/linux/include/asm-m68k/adb_mouse.h linux/include/asm-m68k/adb_mouse.h
--- v2.3.2/linux/include/asm-m68k/adb_mouse.h Wed Sep 2 09:39:18 1998
+++ linux/include/asm-m68k/adb_mouse.h Sat May 15 15:05:37 1999
@@ -16,7 +16,7 @@
X short dy;
X int ready;
X int active;
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X struct fasync_struct *fasyncptr;
X };
X
diff -u --recursive --new-file v2.3.2/linux/include/asm-m68k/atari_joystick.h linux/include/asm-m68k/atari_joystick.h
--- v2.3.2/linux/include/asm-m68k/atari_joystick.h Sat Mar 30 04:11:24 1996
+++ linux/include/asm-m68k/atari_joystick.h Sat May 15 15:05:37 1999
@@ -16,7 +16,7 @@
X char dir;
X int ready;
X int active;
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X };
X
X #endif
diff -u --recursive --new-file v2.3.2/linux/include/asm-m68k/mac_mouse.h linux/include/asm-m68k/mac_mouse.h
--- v2.3.2/linux/include/asm-m68k/mac_mouse.h Thu Feb 12 16:30:13 1998
+++ linux/include/asm-m68k/mac_mouse.h Sat May 15 15:05:37 1999
@@ -16,7 +16,7 @@
X short dy;
X int ready;
X int active;
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X struct fasync_struct *fasyncptr;
X };
X
diff -u --recursive --new-file v2.3.2/linux/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h
--- v2.3.2/linux/include/asm-m68k/semaphore.h Fri May 14 18:55:28 1999
+++ linux/include/asm-m68k/semaphore.h Sat May 15 15:05:37 1999
@@ -18,7 +18,7 @@
X struct semaphore {
X atomic_t count;
X atomic_t waking;
- struct wait_queue * wait;
+ wait_queue_head_t wait;
X };
X
X #define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
diff -u --recursive --new-file v2.3.2/linux/include/asm-mips/semaphore.h linux/include/asm-mips/semaphore.h
--- v2.3.2/linux/include/asm-mips/semaphore.h Thu Jan 14 15:53:25 1999
+++ linux/include/asm-mips/semaphore.h Sat May 15 15:05:37 1999
@@ -17,7 +17,7 @@
X struct semaphore {
X atomic_t count;
X atomic_t waking;
- struct wait_queue * wait;
+ wait_queue_head_t wait;
X };
X
X #define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
diff -u --recursive --new-file v2.3.2/linux/include/asm-ppc/adb_mouse.h linux/include/asm-ppc/adb_mouse.h
--- v2.3.2/linux/include/asm-ppc/adb_mouse.h Mon Jan 12 15:18:13 1998
+++ linux/include/asm-ppc/adb_mouse.h Sat May 15 15:05:37 1999
@@ -16,7 +16,7 @@
X short dy;
X int ready;
X int active;
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X struct fasync_struct *fasyncptr;
X };
X
diff -u --recursive --new-file v2.3.2/linux/include/asm-ppc/semaphore.h linux/include/asm-ppc/semaphore.h
--- v2.3.2/linux/include/asm-ppc/semaphore.h Wed Mar 10 21:30:32 1999
+++ linux/include/asm-ppc/semaphore.h Sat May 15 15:05:37 1999
@@ -13,7 +13,7 @@
X struct semaphore {
X atomic_t count;
X atomic_t waking;
- struct wait_queue *wait;
+ wait_queue_head_t wait;
X };
X
X #define sema_init(sem, val) atomic_set(&((sem)->count), (val))
diff -u --recursive --new-file v2.3.2/linux/include/asm-sparc/io.h linux/include/asm-sparc/io.h
--- v2.3.2/linux/include/asm-sparc/io.h Fri May 14 18:55:28 1999
+++ linux/include/asm-sparc/io.h Sat May 15 11:12:09 1999
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.18 1998/09/21 05:07:17 jj Exp $ */
+/* $Id: io.h,v 1.19 1999/05/14 07:26:09 davem Exp $ */
X #ifndef __SPARC_IO_H
X #define __SPARC_IO_H
X
diff -u --recursive --new-file v2.3.2/linux/include/asm-sparc64/hdreg.h linux/include/asm-sparc64/hdreg.h
--- v2.3.2/linux/include/asm-sparc64/hdreg.h Fri May 14 18:55:28 1999
+++ linux/include/asm-sparc64/hdreg.h Sat May 15 11:12:09 1999
@@ -1,4 +1,4 @@
-/* $Id: hdreg.h,v 1.9 1998/05/08 21:05:28 davem Exp $
+/* $Id: hdreg.h,v 1.1 1999/05/14 07:23:13 davem Exp $
X * hdreg.h: Ultra/PCI specific IDE glue.
X *
X * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.3.2/linux/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- v2.3.2/linux/include/asm-sparc64/ide.h Fri May 14 18:55:28 1999
+++ linux/include/asm-sparc64/ide.h Sat May 15 11:12:10 1999
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.12 1999/04/17 14:25:29 davem Exp $
+/* $Id: ide.h,v 1.14 1999/05/15 05:02:35 davem Exp $
X * ide.h: Ultra/PCI specific IDE glue.
X *
X * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -11,6 +11,8 @@
X #ifdef __KERNEL__
X
X #include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/hdreg.h>
X
X #undef MAX_HWIFS
X #define MAX_HWIFS 2
diff -u --recursive --new-file v2.3.2/linux/include/asm-sparc64/io.h linux/include/asm-sparc64/io.h
--- v2.3.2/linux/include/asm-sparc64/io.h Fri May 14 18:55:29 1999
+++ linux/include/asm-sparc64/io.h Sat May 15 11:12:10 1999
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.19 1998/08/23 05:41:46 ecd Exp $ */
+/* $Id: io.h,v 1.20 1999/05/14 07:23:18 davem Exp $ */
X #ifndef __SPARC64_IO_H
X #define __SPARC64_IO_H
X
diff -u --recursive --new-file v2.3.2/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.3.2/linux/include/linux/blk.h Tue May 11 13:05:32 1999
+++ linux/include/linux/blk.h Sun May 16 13:19:06 1999
@@ -85,12 +85,6 @@
X
X #endif
X
-#define RO_IOCTLS(dev,where) \
- case BLKROSET: { int __val; if (!capable(CAP_SYS_ADMIN)) return -EACCES; \
- if (get_user(__val, (int *)(where))) return -EFAULT; \
- set_device_ro((dev),__val); return 0; } \
- case BLKROGET: { int __val = (is_read_only(dev) != 0) ; \
- return put_user(__val,(int *) (where)); }
X
X #if defined(MAJOR_NR) || defined(IDE_DRIVER)
X
diff -u --recursive --new-file v2.3.2/linux/include/linux/blkpg.h linux/include/linux/blkpg.h
--- v2.3.2/linux/include/linux/blkpg.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/blkpg.h Sat May 15 23:43:04 1999
@@ -0,0 +1,64 @@
+#ifndef _LINUX_BLKPG_H
+#define _LINUX_BLKPG_H
+


+/*
+ * Partition table and disk geometry handling
+ *

+ * A single ioctl with lots of subfunctions:
+ *
+ * Device number stuff:
+ * get_whole_disk() (given the device number of a partition,

+ * find the device number of the encompassing disk)


+ * get_all_partitions() (given the device number of a disk, return the
+ * device numbers of all its known partitions)
+ *
+ * Partition stuff:
+ * add_partition()
+ * delete_partition()
+ * test_partition_in_use() (also for test_disk_in_use)
+ *
+ * Geometry stuff:
+ * get_geometry()
+ * set_geometry()
+ * get_bios_drivedata()
+ *
+ * For today, only the partition stuff - aeb, 990515
+ */

+#include <linux/ioctl.h>
+
+#define BLKPG _IO(0x12,105)
+
+/* The argument structure */
+struct blkpg_ioctl_arg {
+ int op;
+ int flags;
+ int datalen;
+ void *data;
+} *p;
+
+/* The subfunctions (for the op field) */
+#define BLKPG_ADD_PARTITION 1
+#define BLKPG_DEL_PARTITION 2
+
+/* Sizes of name fields. Unused at present. */
+#define BLKPG_DEVNAMELTH 64
+#define BLKPG_VOLNAMELTH 64
+
+/* The data structure for ADD_PARTITION and DEL_PARTITION */
+struct blkpg_partition {
+ long long start; /* starting offset in bytes */
+ long long length; /* length in bytes */
+ int pno; /* partition number */
+ char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2,
+ to be used in kernel messages */
+ char volname[BLKPG_VOLNAMELTH]; /* volume label */
+};
+
+#ifdef __KERNEL__
+
+extern char * partition_name(kdev_t dev);
+extern int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_BLKPG_H */
diff -u --recursive --new-file v2.3.2/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.3.2/linux/include/linux/fs.h Sat May 15 23:46:05 1999
+++ linux/include/linux/fs.h Sun May 16 13:18:20 1999
@@ -140,6 +140,7 @@
X #define IS_NOATIME(inode) __IS_FLG(inode, MS_NOATIME)
X #define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
X
+
X /* the read-only stuff doesn't really belong here, but any other place is
X probably as bad and I don't want to create yet another include file. */
X
@@ -154,7 +155,13 @@
X #define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
X #define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
X #define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
-#define BLKSSZGET _IO(0x12,104)/* get block device sector size (reserved for) */
+#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
+#if 0
+#define BLKPG _IO(0x12,105)/* See blkpg.h */
+/* This was here just to show that the number is taken -
+ probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
+#endif
+
X
X #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
X #define FIBMAP _IO(0x00,1) /* bmap access */
@@ -724,7 +731,6 @@
X extern char * cdevname(kdev_t dev);
X extern char * kdevname(kdev_t dev);
X extern void init_special_inode(struct inode *, umode_t, int);
-
X
X extern void init_fifo(struct inode * inode);
X extern struct inode_operations fifo_inode_operations;
diff -u --recursive --new-file v2.3.2/linux/include/linux/genhd.h linux/include/linux/genhd.h
--- v2.3.2/linux/include/linux/genhd.h Sat May 15 23:46:05 1999
+++ linux/include/linux/genhd.h Sun May 16 13:18:19 1999
@@ -39,7 +39,7 @@
X #endif
X
X #define DM6_PARTITION 0x54 /* has DDO: use xlated geom & offset */
-#define EZD_PARTITION 0x55 /* EZ-DRIVE: same as DM6 (we think) */
+#define EZD_PARTITION 0x55 /* EZ-DRIVE */
X #define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */
X #define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */
X
@@ -70,8 +70,8 @@
X int max_nr; /* maximum number of real devices */
X
X void (*init)(struct gendisk *); /* Initialization called before we do our thing */
- struct hd_struct *part; /* partition table */
- int *sizes; /* device size in blocks, copied to blk_size[] */
+ struct hd_struct *part; /* [indexed by minor] */
+ int *sizes; /* [idem], device size in blocks */
X int nr_real; /* number of real devices */
X
X void *real_devices; /* internal use */
@@ -226,14 +226,12 @@
X
X #endif /* CONFIG_UNIXWARE_DISKLABEL */
X
+#ifdef __KERNEL__
X extern struct gendisk *gendisk_head; /* linked list of disks */
X
-/*


- * disk_name() is used by genhd.c and md.c.
- * It formats the devicename of the indicated disk
- * into the supplied buffer, and returns a pointer
- * to that same buffer (for convenience).

- */
X char *disk_name (struct gendisk *hd, int minor, char *buf);
+
+int get_hardsect_size(kdev_t dev);
+#endif
X
X #endif
diff -u --recursive --new-file v2.3.2/linux/include/linux/hpfs_fs_sb.h linux/include/linux/hpfs_fs_sb.h
--- v2.3.2/linux/include/linux/hpfs_fs_sb.h Sat May 15 23:46:05 1999
+++ linux/include/linux/hpfs_fs_sb.h Sun May 16 10:33:30 1999
@@ -24,13 +24,13 @@
X unsigned sb_rd_inode : 2; /* lookup tells read_inode: 1-read fnode
X 2-don't read fnode, file
X 3-don't read fnode, direcotry */
- struct wait_queue *sb_iget_q;
+ wait_queue_head_t sb_iget_q;
X unsigned char *sb_cp_table; /* code page tables: */
X /* 128 bytes uppercasing table & */
X /* 128 bytes lowercasing table */
X unsigned *sb_bmp_dir; /* main bitmap directory */
X unsigned sb_c_bitmap; /* current bitmap */
- struct wait_queue *sb_creation_de;/* when creating dirents, nobody else
+ wait_queue_head_t sb_creation_de;/* when creating dirents, nobody else
X can alloc blocks */
X unsigned sb_creation_de_lock : 1;
X /*unsigned sb_mounting : 1;*/
@@ -55,7 +55,7 @@
X #define s_hpfs_chk u.hpfs_sb.sb_chk
X #define s_hpfs_was_error u.hpfs_sb.sb_was_error
X #define s_hpfs_chkdsk u.hpfs_sb.sb_chkdsk
-#define s_hpfs_rd_fnode u.hpfs_sb.sb_rd_fnode
+/*#define s_hpfs_rd_fnode u.hpfs_sb.sb_rd_fnode*/
X #define s_hpfs_rd_inode u.hpfs_sb.sb_rd_inode
X #define s_hpfs_cp_table u.hpfs_sb.sb_cp_table
X #define s_hpfs_bmp_dir u.hpfs_sb.sb_bmp_dir
diff -u --recursive --new-file v2.3.2/linux/include/linux/istallion.h linux/include/linux/istallion.h
--- v2.3.2/linux/include/linux/istallion.h Wed Feb 4 14:52:16 1998
+++ linux/include/linux/istallion.h Sat May 15 15:05:37 1999
@@ -70,9 +70,9 @@
X long pgrp;
X unsigned int rxmarkmsk;
X struct tty_struct *tty;


- struct wait_queue *open_wait;
- struct wait_queue *close_wait;

- struct wait_queue *raw_wait;


+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;

+ wait_queue_head_t raw_wait;
X struct tq_struct tqhangup;
X struct termios normaltermios;
X struct termios callouttermios;
diff -u --recursive --new-file v2.3.2/linux/include/linux/lp_m68k.h linux/include/linux/lp_m68k.h
--- v2.3.2/linux/include/linux/lp_m68k.h Fri Nov 20 11:44:06 1998
+++ linux/include/linux/lp_m68k.h Sat May 15 15:05:37 1999
@@ -116,7 +116,7 @@
X unsigned int chars; /*busy timeout */
X unsigned int time; /*wait time */
X unsigned int wait;
- struct wait_queue *lp_wait_q; /*strobe wait */
+ struct wait_queue_head_t lp_wait_q; /*strobe wait */
X void *base; /* hardware drivers internal use*/
X enum lp_type type;
X char lp_buffer[LP_BUFFER_SIZE];
diff -u --recursive --new-file v2.3.2/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v2.3.2/linux/include/linux/netdevice.h Tue May 11 13:05:03 1999
+++ linux/include/linux/netdevice.h Sun May 16 18:28:33 1999
@@ -405,7 +405,7 @@
X extern __inline__ void dev_lock_wait(void)
X {
X while (atomic_read(&dev_lockct)) {
- current->counter = 0;
+ current->policy |= SCHED_YIELD;
X schedule();
X }
X }
diff -u --recursive --new-file v2.3.2/linux/include/linux/parport.h linux/include/linux/parport.h
--- v2.3.2/linux/include/linux/parport.h Fri May 14 18:55:29 1999
+++ linux/include/linux/parport.h Sun May 16 13:19:20 1999
@@ -184,6 +184,7 @@
X /* A parallel port */
X struct parport {
X unsigned long base; /* base address */
+ unsigned long base_hi; /* base address (ECR) */
X unsigned int size; /* IO extent */
X const char *name;
X int irq; /* interrupt (or -1 for none) */
diff -u --recursive --new-file v2.3.2/linux/include/linux/parport_pc.h linux/include/linux/parport_pc.h
--- v2.3.2/linux/include/linux/parport_pc.h Tue May 11 13:04:45 1999
+++ linux/include/linux/parport_pc.h Sun May 16 13:18:35 1999
@@ -5,14 +5,14 @@
X
X /* --- register definitions ------------------------------- */
X
-#define ECONTROL 0x402
-#define CONFIGB 0x401
-#define CONFIGA 0x400
-#define EPPDATA 0x4
-#define EPPADDR 0x3
-#define CONTROL 0x2
-#define STATUS 0x1
-#define DATA 0
+#define ECONTROL(p) ((p)->base_hi + 0x02)
+#define CONFIGB(p) ((p)->base_hi + 0x01)
+#define CONFIGA(p) ((p)->base_hi + 0x00)
+#define EPPDATA(p) ((p)->base + 0x04)
+#define EPPADDR(p) ((p)->base + 0x03)
+#define CONTROL(p) ((p)->base + 0x02)
+#define STATUS(p) ((p)->base + 0x01)
+#define DATA(p) ((p)->base + 0x00)
X
X /* Private data for PC low-level driver. */
X struct parport_pc_private {
@@ -26,27 +26,27 @@
X
X extern __inline__ void parport_pc_write_epp(struct parport *p, unsigned char d)


X {
- outb(d, p->base+EPPDATA);
+ outb(d, EPPDATA(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_epp(struct parport *p)


X {
- return inb(p->base+EPPDATA);
+ return inb(EPPDATA(p));
X }
X

X extern __inline__ void parport_pc_write_epp_addr(struct parport *p, unsigned char d)


X {
- outb(d, p->base+EPPADDR);
+ outb(d, EPPADDR(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_epp_addr(struct parport *p)


X {
- return inb(p->base+EPPADDR);
+ return inb(EPPADDR(p));
X }
X

X extern __inline__ int parport_pc_check_epp_timeout(struct parport *p)


X {
- if (!(inb(p->base+STATUS) & 1))
+ if (!(inb(STATUS(p)) & 1))
X return 0;
X parport_pc_epp_clear_timeout(p);
X return 1;

@@ -54,24 +54,24 @@
X
X extern __inline__ unsigned char parport_pc_read_configb(struct parport *p)


X {
- return inb(p->base+CONFIGB);
+ return inb(CONFIGB(p));
X }
X

X extern __inline__ void parport_pc_write_data(struct parport *p, unsigned char d)


X {
- outb(d, p->base+DATA);
+ outb(d, DATA(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_data(struct parport *p)


X {
- return inb(p->base+DATA);
+ return inb(DATA(p));
X }
X

X extern __inline__ void parport_pc_write_control(struct parport *p, unsigned char d)


X {
X struct parport_pc_private *priv = p->private_data;
X priv->ctr = d;/* update soft copy */
- outb(d, p->base+CONTROL);
+ outb(d, CONTROL(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_control(struct parport *p)
@@ -85,34 +85,34 @@


X struct parport_pc_private *priv = p->private_data;
X unsigned char ctr = priv->ctr;
X ctr = (ctr & ~mask) ^ val;
- outb (ctr, p->base+CONTROL);
+ outb (ctr, CONTROL(p));
X return priv->ctr = ctr; /* update soft copy */
X }
X

X extern __inline__ void parport_pc_write_status(struct parport *p, unsigned char d)


X {
- outb(d, p->base+STATUS);
+ outb(d, STATUS(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_status(struct parport *p)


X {
- return inb(p->base+STATUS);
+ return inb(STATUS(p));
X }
X

X extern __inline__ void parport_pc_write_econtrol(struct parport *p, unsigned char d)


X {
- outb(d, p->base+ECONTROL);
+ outb(d, ECONTROL(p));
X }
X

X extern __inline__ unsigned char parport_pc_read_econtrol(struct parport *p)


X {
- return inb(p->base+ECONTROL);
+ return inb(ECONTROL(p));
X }
X

X extern __inline__ unsigned char parport_pc_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val)


X {
- unsigned char old = inb(p->base+ECONTROL);
- outb(((old & ~mask) ^ val), p->base+ECONTROL);
+ unsigned char old = inb(ECONTROL(p));
+ outb(((old & ~mask) ^ val), ECONTROL(p));
X return old;

X }
X
diff -u --recursive --new-file v2.3.2/linux/include/linux/rpcsock.h linux/include/linux/rpcsock.h
--- v2.3.2/linux/include/linux/rpcsock.h Thu Dec 12 06:54:20 1996
+++ linux/include/linux/rpcsock.h Sat May 15 15:05:37 1999
@@ -77,7 +77,7 @@
X struct rpc_wait * w_next;
X struct rpc_ioreq * w_req;
X int w_result;
- struct wait_queue * w_wait;
+ wait_queue_head_t w_wait;
X rpc_callback_fn_t w_handler;
X void * w_cdata;
X char w_queued;
@@ -94,8 +94,8 @@
X unsigned long cwnd;
X struct rpc_wait * pending;
X struct rpc_wait * free;
- struct wait_queue * backlog;
- struct wait_queue * shutwait;
+ wait_queue_head_t backlog;
+ wait_queue_head_t shutwait;
X int shutdown;
X };
X
diff -u --recursive --new-file v2.3.2/linux/include/linux/serial167.h linux/include/linux/serial167.h
--- v2.3.2/linux/include/linux/serial167.h Mon Oct 5 14:12:12 1998
+++ linux/include/linux/serial167.h Sat May 15 15:05:37 1999
@@ -54,8 +54,8 @@
X struct tq_struct tqueue;


X struct termios normal_termios;
X struct termios callout_termios;

- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;

X struct cyclades_monitor mon;
X };
X
diff -u --recursive --new-file v2.3.2/linux/include/linux/stallion.h linux/include/linux/stallion.h
--- v2.3.2/linux/include/linux/stallion.h Wed Feb 4 14:52:16 1998
+++ linux/include/linux/stallion.h Sat May 15 15:05:37 1999
@@ -95,8 +95,8 @@
X unsigned long hwid;
X void *uartp;
X struct tty_struct *tty;


- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;

X struct termios normaltermios;
X struct termios callouttermios;
X struct tq_struct tqueue;
diff -u --recursive --new-file v2.3.2/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.3.2/linux/include/linux/swap.h Tue May 11 13:03:58 1999
+++ linux/include/linux/swap.h Sun May 16 13:18:20 1999
@@ -113,6 +113,7 @@
X /* linux/mm/swapfile.c */
X extern unsigned int nr_swapfiles;
X extern struct swap_info_struct swap_info[];
+extern int is_swap_partition(kdev_t);
X void si_swapinfo(struct sysinfo *);
X unsigned long get_swap_page(void);
X extern void FASTCALL(swap_free(unsigned long));
diff -u --recursive --new-file v2.3.2/linux/include/linux/umsdos_fs_i.h linux/include/linux/umsdos_fs_i.h
--- v2.3.2/linux/include/linux/umsdos_fs_i.h Sun Dec 27 22:18:28 1998
+++ linux/include/linux/umsdos_fs_i.h Sat May 15 15:05:37 1999
@@ -47,7 +47,7 @@
X */
X
X struct dir_locking_info {
- struct wait_queue *p;
+ wait_queue_head_t p;
X short int looking; /* How many process doing a lookup */
X short int creating; /* Is there any creation going on here
X * Only one at a time, although one
diff -u --recursive --new-file v2.3.2/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.3.2/linux/kernel/ksyms.c Sat May 15 23:46:05 1999
+++ linux/kernel/ksyms.c Sat May 15 23:43:04 1999
@@ -32,6 +32,7 @@
X #include <linux/hdreg.h>
X #include <linux/skbuff.h>


X #include <linux/genhd.h>
+#include <linux/blkpg.h>

X #include <linux/swap.h>
X #include <linux/ctype.h>
X #include <linux/file.h>
@@ -327,6 +328,7 @@
X EXPORT_SYMBOL(kdevname);
X EXPORT_SYMBOL(bdevname);
X EXPORT_SYMBOL(cdevname);
+EXPORT_SYMBOL(partition_name); /* md.c only */
X EXPORT_SYMBOL(simple_strtoul);
X EXPORT_SYMBOL(system_utsname); /* UTS data */
X EXPORT_SYMBOL(uts_sem); /* UTS semaphore */
diff -u --recursive --new-file v2.3.2/linux/mm/mlock.c linux/mm/mlock.c
--- v2.3.2/linux/mm/mlock.c Fri Nov 20 11:43:19 1998
+++ linux/mm/mlock.c Sun May 16 21:45:23 1999
@@ -115,10 +115,11 @@
X if (!retval) {
X /* keep track of amount of locked VM */
X pages = (end - start) >> PAGE_SHIFT;
- if (!(newflags & VM_LOCKED))
+ if (newflags & VM_LOCKED) {
X pages = -pages;
- vma->vm_mm->locked_vm += pages;
- make_pages_present(start, end);
+ make_pages_present(start, end);
+ }
+ vma->vm_mm->locked_vm -= pages;
X }
X return retval;
X }
diff -u --recursive --new-file v2.3.2/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.3.2/linux/mm/swapfile.c Sun Mar 7 15:49:14 1999
+++ linux/mm/swapfile.c Sat May 15 23:43:05 1999
@@ -473,6 +473,18 @@
X return len;
X }
X
+int is_swap_partition(kdev_t dev) {
+ struct swap_info_struct *ptr = swap_info;
+ int i;
+
+ for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
+ if (ptr->flags & SWP_USED)
+ if (ptr->swap_device == dev)
+ return 1;


+ }
+ return 0;
+}
+

X /*
X * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
X *
diff -u --recursive --new-file v2.3.2/linux/net/core/filter.c linux/net/core/filter.c
--- v2.3.2/linux/net/core/filter.c Thu Mar 25 09:23:34 1999
+++ linux/net/core/filter.c Sat May 15 17:43:46 1999
@@ -106,7 +106,7 @@
X continue;
X
X case BPF_ALU|BPF_MUL|BPF_K:
- A *= X;
+ A *= fentry->k;
X continue;
X
X case BPF_ALU|BPF_DIV|BPF_X:
diff -u --recursive --new-file v2.3.2/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.3.2/linux/net/ipv4/tcp_timer.c Mon May 10 09:55:25 1999
+++ linux/net/ipv4/tcp_timer.c Sat May 15 16:58:06 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_timer.c,v 1.62 1999/05/08 21:09:55 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.63 1999/05/15 23:02:21 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -541,10 +541,6 @@
X prev = conn;
X continue;
X }
-
- if ((long)(now - conn->expires) <= 0)
- break;
-
X
X tcp_synq_unlink(tp, conn, prev);
X if (conn->retrans >= sysctl_tcp_retries1) {
diff -u --recursive --new-file v2.3.2/linux/net/ipv6/exthdrs.c linux/net/ipv6/exthdrs.c
--- v2.3.2/linux/net/ipv6/exthdrs.c Sun Oct 4 10:19:40 1998
+++ linux/net/ipv6/exthdrs.c Sat May 15 23:43:05 1999
@@ -369,7 +369,7 @@
X Certainly, it is possible only for udp and raw sockets, but not for tcp.
X
X AUTH header has 4byte granular length, which kills all the idea
- behind AUTOMATIC 64bit alignment of IPv6. Now we will loose
+ behind AUTOMATIC 64bit alignment of IPv6. Now we will lose
X cpu ticks, checking that sender did not something stupid
X and opt->hdrlen is even. Shit! --ANK (980730)
X */
diff -u --recursive --new-file v2.3.2/linux/net/netlink/af_netlink.c linux/net/netlink/af_netlink.c
--- v2.3.2/linux/net/netlink/af_netlink.c Fri May 14 18:55:32 1999
+++ linux/net/netlink/af_netlink.c Sun May 16 18:28:33 1999
@@ -203,7 +203,7 @@
X */
X
X while (netlink_locked(sk)) {
- current->counter = 0;
+ current->policy |= SCHED_YIELD;
X schedule();
X }
X

SHAR_EOF
true || echo 'restore of patch-2.3.3 failed'

echo 'File patch-2.3.3 is complete' &&
chmod 644 patch-2.3.3 ||


echo 'restore of patch-2.3.3 failed'

Cksum="`cksum < 'patch-2.3.3'`"
if ! test "2637971809 197362" = "$Cksum"
then
echo 'patch-2.3.3: original Checksum 2637971809 197362, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
May 18, 1999, 3:00:00 AM5/18/99
to
Archive-name: v2.3/patch-2.3.3/part3

#!/bin/sh
# this is part 3 of a 4 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.3 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 3; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.3.3'
else
echo 'x - continuing with patch-2.3.3'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.3' &&

- {
- unsigned long flags;
- spin_lock_irqsave(&ohci_edtd_lock, flags);

- ohci_add_td_to_ed(setup_td, control_ed);
- spin_unlock_irqrestore(&ohci_edtd_lock, flags);
- }
+ spin_lock_irqsave(&ohci_edtd_lock, flags);
+ control_ed->status |= OHCI_ED_SKIP;
+ ohci_add_td_to_ed(setup_td, control_ed);
+ if (data_td != status_td)
+ ohci_add_td_to_ed(data_td, control_ed);
+ ohci_add_td_to_ed(status_td, control_ed);
+ control_ed->status &= ~OHCI_ED_SKIP;
+ ohci_unhalt_ed(control_ed);
+ spin_unlock_irqrestore(&ohci_edtd_lock, flags);
X
-#if 0
+#ifdef OHCI_DEBUG
+ if (MegaDebug) {
X /* complete transaction debugging output (before) */
X printk(KERN_DEBUG " Control ED %lx:\n", virt_to_bus(control_ed));
X show_ohci_ed(control_ed);
@@ -623,48 +839,55 @@
X }
X printk(KERN_DEBUG " Status TD %lx:\n", virt_to_bus(status_td));
X show_ohci_td(status_td);
+ printk(KERN_DEBUG " Controller Status:\n");
+ show_ohci_status(dev->ohci);
+ }
X #endif
X
+ /*
+ * Start the control transaction..
+ */
+ current->state = TASK_UNINTERRUPTIBLE;
+ add_wait_queue(&control_wakeup, &wait);
+
X /* Give the ED to the HC */
X ohci_add_control_ed(dev->ohci, control_ed);
X
- /* FIXME:
- * this should really check to see that the transaction completed.
- */
X schedule_timeout(HZ/10);
X
X remove_wait_queue(&control_wakeup, &wait);
X
-#if 0
+#ifdef OHCI_DEBUG
+ if (MegaDebug) {
X /* complete transaction debugging output (after) */
- printk(KERN_DEBUG " (after) Control ED:\n");
+ printk(KERN_DEBUG " *after* Control ED %lx:\n", virt_to_bus(control_ed));
X show_ohci_ed(control_ed);
- printk(KERN_DEBUG " (after) Setup TD:\n");
+ printk(KERN_DEBUG " *after* Setup TD %lx:\n", virt_to_bus(setup_td));
X show_ohci_td(setup_td);
X if (data_td != status_td) {
- printk(KERN_DEBUG " (after) Data TD:\n");
+ printk(KERN_DEBUG " *after* Data TD %lx:\n", virt_to_bus(data_td));
X show_ohci_td(data_td);
X }
- printk(KERN_DEBUG " (after) Status TD:\n");
+ printk(KERN_DEBUG " *after* Status TD %lx:\n", virt_to_bus(status_td));
X show_ohci_td(status_td);
+ printk(KERN_DEBUG " *after* Controller Status:\n");
+ show_ohci_status(dev->ohci);
+ }
X #endif
X
- /* clean up incase it failed */
- /* XXX only do this if their ed pointer still points to control_ed
- * incase they've been reclaimed and used by something else
- * already. -greg */
- ohci_remove_td_from_ed(setup_td, control_ed);
- ohci_remove_td_from_ed(data_td, control_ed);
- ohci_remove_td_from_ed(status_td, control_ed);
-
- /* remove the control ED */
+ /* clean up */
+ ohci_free_td(setup_td);
+ if (data_td != status_td)
+ ohci_free_td(data_td);
+ ohci_free_td(status_td);
+ /* remove the control ED from the HC */
X ohci_remove_control_ed(dev->ohci, control_ed);
+ ohci_free_ed(control_ed); /* return it to the pool */
X
X #if 0
X printk(KERN_DEBUG "leaving ohci_control_msg\n");
X #endif
-
- return ohci_td_result(dev, status_td);
+ return completion_status;
X } /* ohci_control_msg() */
X
X
@@ -675,6 +898,7 @@
X {
X struct usb_device *usb_dev;
X struct ohci_device *dev;
+ int idx;
X
X /*
X * Allocate the generic USB device
@@ -696,6 +920,12 @@
X
X memset(dev, 0, sizeof(*dev));
X
+ /* Initialize all EDs in a new device with the skip flag so that
+ * they are ignored by the controller until set otherwise. */
+ for (idx = 0; idx < NUM_EDS; ++idx) {
+ dev->ed[idx].status |= OHCI_ED_SKIP;
+ }
+
X /*
X * Link them together
X */
@@ -752,10 +982,10 @@
X */
X static int reset_hc(struct ohci *ohci)
X {
- int timeout = 1000; /* prevent an infinite loop */
+ int timeout = 10000; /* prevent an infinite loop */
X
X #if 0
- printk(KERN_DEBUG "usb-ohci: resetting HC %p\n", ohci);
+ printk(KERN_INFO "usb-ohci: resetting HC %p\n", ohci);
X #endif
X
X writel(~0x0, &ohci->regs->intrdisable); /* Disable HC interrupts */
@@ -770,7 +1000,7 @@
X udelay(1);
X }
X
- printk(KERN_DEBUG "usb-ohci: HC %p reset.\n", ohci);
+ printk(KERN_INFO "usb-ohci: HC %p reset.\n", ohci);
X
X return 0;
X } /* reset_hc() */
@@ -783,6 +1013,7 @@


X {
X int ret = 0;

X int fminterval;
+ __u32 what_to_enable;
X
X fminterval = readl(&ohci->regs->fminterval) & 0x3fff;
X #if 0
@@ -812,9 +1043,13 @@
X * useful for debugging and as a bus heartbeat. -greg
X */
X /* Choose the interrupts we care about */
- writel( OHCI_INTR_MIE | /* OHCI_INTR_RHSC | */
- OHCI_INTR_WDH | OHCI_INTR_FNO,
- &ohci->regs->intrenable);
+ what_to_enable = OHCI_INTR_MIE |
+#ifdef OHCI_RHSC_INT
+ OHCI_INTR_RHSC |
+#endif
+ /* | OHCI_INTR_FNO */
+ OHCI_INTR_WDH;
+ writel( what_to_enable, &ohci->regs->intrenable);
X
X /* Enter the USB Operational state & start the frames a flowing.. */
X writel_set(OHCI_USB_OPER, &ohci->regs->control);
@@ -861,7 +1096,7 @@
X /*
X * Wait for the reset to complete.
X */
- wait_ms(10);
+ wait_ms(20);
X
X /* check port status to see that the reset completed */
X status = readl(&ohci->regs->roothub.portstatus[port]);
@@ -886,10 +1121,12 @@
X struct usb_device *usb_dev;
X struct ohci_device *dev;
X /* memory I/O address of the port status register */
- void *portaddr = &ohci->regs->roothub.portstatus[port];
+ __u32 *portaddr = &ohci->regs->roothub.portstatus[port];
X int portstatus;
X
- printk(KERN_DEBUG "ohci_connect_change(%p, %d)\n", ohci, port);
+#ifdef OHCI_DEBUG
+ printk(KERN_DEBUG "ohci_connect_change on port %d\n", port);
+#endif
X
X /*
X * Because of the status change we have to forget
@@ -903,6 +1140,14 @@
X /* disable the port if nothing is connected */
X if (!(portstatus & PORT_CCS)) {
X writel(PORT_CCS, portaddr);
+ /* We need to reset the CSC bit -after- disabling the
+ * port because it causes the CSC bit to come on
+ * again... */
+ wait_ms(20);
+ writel(PORT_CSC, portaddr);
+#ifdef OHCI_DEBUG
+ printk(KERN_DEBUG "ohci port %d disabled, nothing connected.\n", port);
+#endif
X return;
X }
X
@@ -943,15 +1188,18 @@
X struct ohci_regs *regs = ohci->regs;
X int num = 0;
X int maxport = readl(&ohci->regs->roothub) & 0xff;
+ __u32 rh_change_flags = PORT_CSC | PORT_PESC; /* root hub status changes */
X
-#if 1
+#ifdef OHCI_DEBUG
X printk(KERN_DEBUG "entering ohci_check_configuration %p\n", ohci);
X #endif
X
X do {
- if (readl(&regs->roothub.portstatus[num]) & PORT_CSC) {
- /* reset the connect status change bit */
- writel(PORT_CSC, &regs->roothub.portstatus[num]);
+ __u32 *portstatus_p = &regs->roothub.portstatus[num];
+ if (readl(portstatus_p) & rh_change_flags) {
+ /* acknowledge the root hub status changes */
+ writel_set(rh_change_flags, portstatus_p);
+ /* disable the port if nothing is on it */
X /* check the port for a nifty device */
X ohci_connect_change(ohci, num);
X }
@@ -977,8 +1225,8 @@
X int maxport = ohci->root_hub->usb->maxchild;
X
X do {
- if (readl(&ohci->regs->roothub.portstatus[num]) &
- PORT_CSC) {
+ __u32 *portstatus_p = &ohci->regs->roothub.portstatus[num];
+ if (readl(portstatus_p) & PORT_CSC) {
X if (waitqueue_active(&ohci_configure))
X wake_up(&ohci_configure);
X return;
@@ -1037,6 +1285,9 @@
X while (td != NULL) {
X struct ohci_td *next_td = td->next_dl_td;
X
+ if (td_dummy(*td))
+ printk("yikes! reaping a dummy TD\n");
+
X /* FIXME: munge td->info into a future standard status format */
X /* Check if TD should be re-queued */
X if ((td->completed != NULL) &&
@@ -1044,14 +1295,15 @@
X {
X /* Mark the TD as active again:


X * Set the not accessed condition code

- * FIXME: should this reset OHCI_TD_ERRCNT?
+ * Reset the Error count
+ * [FIXME: report errors to the device's driver]
X */
X td->info |= OHCI_TD_CC_NEW;
+ clear_td_errorcount(td);
X
X /* point it back to the start of the data buffer */
X td->cur_buf = virt_to_bus(td->data);
X
- /* XXX disabled for debugging reasons right now.. */
X /* insert it back on its ED */
X ohci_add_td_to_ed(td, td->ed);
X } else {
@@ -1066,9 +1318,6 @@
X } /* ohci_reap_donelist() */
X
X
-#if 0
-static int in_int = 0;
-#endif
X /*
X * Get annoyed at the controller for bothering us.
X * This pretty much follows the OHCI v1.0a spec, section 5.3.
@@ -1080,19 +1329,10 @@
X struct ohci_hcca *hcca = ohci->root_hub->hcca;
X __u32 status, context;
X
-#if 0
- /* for debugging to keep IRQs from running away. */
- if (in_int >= 2)
- return;
- ++in_int;
- return;
-#endif
-
X /* Save the status of the interrupts that are enabled */
X status = readl(&regs->intrstatus);
X status &= readl(&regs->intrenable);
X
-
X /* make context = the interrupt status bits that we care about */
X if (hcca->donehead != 0) {
X context = OHCI_INTR_WDH; /* hcca donehead needs processing */
@@ -1122,6 +1362,10 @@
X context &= ~OHCI_INTR_WDH; /* mark this as checked */
X }
X
+#ifdef OHCI_RHSC_INT
+ /* NOTE: this is very funky on some USB controllers (ie: it
+ * doesn't work right). Using the ohci_timer instead to poll
+ * the root hub is a much better choice. */
X /* Process any root hub status changes */
X if (context & OHCI_INTR_RHSC) {
X /* Wake the thread to process root hub events */
@@ -1134,10 +1378,17 @@
X * The control thread will re-enable it after it has
X * checked the root hub status.
X */
- } else {
- /* check the root hub status anyways. Some controllers
- * might not generate the interrupt properly. (?) */
- ohci_root_hub_events(ohci);
+ }
+#endif
+
+ /* Start of Frame interrupts, used during safe ED removal */
+ if (context & (OHCI_INTR_SF)) {
+ writel(OHCI_INTR_SF, &regs->intrstatus);
+ if (waitqueue_active(&start_of_frame_wakeup))
+ wake_up(&start_of_frame_wakeup);
+ /* Do NOT mark the frame start interrupt as checked
+ * as we don't want to receive any more of them until
+ * asked. */
X }
X
X /* Check those "other" pesky bits */
@@ -1166,8 +1417,8 @@
X context &= ~OHCI_INTR_OC; /* mark this as checked */
X }
X
- /* Mask out any remaining unprocessed interrupts so we don't
- * get any more of them. */
+ /* Mask out any remaining unprocessed or unmasked interrupts
+ * so that we don't get any more of them. */
X if (context & ~OHCI_INTR_MIE) {
X writel(context, &regs->intrdisable);
X }
@@ -1275,7 +1526,9 @@
X
X /*
X * Initialize the polling table to call interrupts at the
- * intended intervals.
+ * intended intervals. Note that these EDs are just
+ * placeholders. They have their SKIP bit set and are used as
+ * list heads to insert real EDs onto.
X */
X dev->hcca->int_table[0] = virt_to_bus(&dev->ed[ED_INT_1]);
X for (i = 1; i < NUM_INTS; i++) {
@@ -1297,18 +1550,14 @@
X }
X
X /*
- * Tell the controller where the control and bulk lists are
+ * Tell the controller where the control and bulk lists are.
X * The lists start out empty.
X */
X writel(0, &ohci->regs->ed_controlhead);
X writel(0, &ohci->regs->ed_bulkhead);
- /*
- writel(virt_to_bus(&dev->ed[ED_CONTROL]), &ohci->regs->ed_controlhead);
- writel(virt_to_bus(&dev->ed[ED_BULK]), &ohci->regs->ed_bulkhead);
- */
X
-#if 0
- printk(KERN_DEBUG "alloc_ohci(): controller\n");
+#ifdef OHCI_DEBUG
+ printk(KERN_INFO "alloc_ohci(): controller\n");
X show_ohci_status(ohci);
X #endif
X
@@ -1325,7 +1574,7 @@
X */
X static void release_ohci(struct ohci *ohci)
X {
- printk(KERN_DEBUG "entering release_ohci %p\n", ohci);
+ printk(KERN_INFO "Releasing OHCI controller 0x%p\n", ohci);
X
X #ifdef OHCI_TIMER
X /* stop our timer */
@@ -1378,7 +1627,7 @@
X * This thread doesn't need any user-level access,
X * so get rid of all of our resources..
X */
- printk("ohci_control_thread code at %p\n", &ohci_control_thread);
+ printk(KERN_INFO "ohci-control thread code for 0x%p code at 0x%p\n", __ohci, &ohci_control_thread);
X exit_mm(current);
X exit_files(current);
X exit_fs(current);
@@ -1391,7 +1640,7 @@
X if (start_hc(ohci) < 0) {
X printk("usb-ohci: failed to start the controller\n");
X release_ohci(ohci);
- printk(KERN_DEBUG "leaving ohci_control_thread %p\n", __ohci);
+ printk(KERN_INFO "leaving ohci_control_thread %p\n", __ohci);


X return 0;
X }
X

@@ -1405,11 +1654,11 @@
X ohci_check_configuration(ohci);
X
X /* re-enable root hub status change interrupts. */
-#if 0
+#ifdef OHCI_RHSC_INT
X writel(OHCI_INTR_RHSC, &ohci->regs->intrenable);
X #endif
X
- printk(KERN_DEBUG "ohci-control thread sleeping\n");
+ printk(KERN_INFO "ohci-control thread sleeping\n");
X interruptible_sleep_on(&ohci_configure);
X #ifdef CONFIG_APM
X if (apm_resume) {
@@ -1431,9 +1680,14 @@
X spin_unlock_irq(&current->sigmask_lock);
X
X if(signr == SIGUSR1) {
- /* FIXME: have it do a full ed/td queue dump */
+ /* TODO: have it do a full ed/td queue dump? */
X printk(KERN_DEBUG "OHCI status dump:\n");
X show_ohci_status(ohci);
+ } else if (signr == SIGUSR2) {
+ /* toggle mega TD/ED debugging output */
+ MegaDebug = !MegaDebug;
+ printk(KERN_DEBUG "usb-ohci: Mega debugging %sabled.\n",
+ MegaDebug ? "en" : "dis");
X } else {
X /* unknown signal, exit the thread */
X break;
@@ -1444,7 +1698,7 @@
X reset_hc(ohci);
X release_ohci(ohci);
X
- printk(KERN_DEBUG "leaving ohci_control_thread %p\n", __ohci);
+ printk(KERN_INFO "ohci-control thread for 0x%p exiting\n", __ohci);
X
X return 0;
X } /* ohci_control_thread() */
@@ -1538,8 +1792,8 @@
X
X ohci->irq = irq;
X
-#if 0
- printk(KERN_DEBUG "usb-ohci: starting ohci-control thread\n");
+#ifdef OHCI_DEBUG
+ printk(KERN_INFO "usb-ohci: forking ohci-control thread for 0x%p\n", ohci);
X #endif
X
X /* fork off the handler */
@@ -1555,7 +1809,7 @@
X }
X release_ohci(ohci);
X
-#if 0
+#ifdef OHCI_DEBUG
X printk(KERN_DEBUG "leaving found_ohci %d %p\n", irq, mem_base);
X #endif
X
@@ -1597,6 +1851,11 @@
X }
X MOD_INC_USE_COUNT;
X
+#ifdef OHCI_DEBUG
+ printk("usb-ohci: Warning! Gobs of debugging output has been enabled.\n");
+ printk(" Check your kern.debug logs for the bulk of it.\n");
+#endif
+
X if (found_ohci(dev->irq, (void *) mem_base) < 0) {
X MOD_DEC_USE_COUNT;
X return -1;
@@ -1672,6 +1931,7 @@
X }
X return retval;
X } /* ohci_init */
+
X
X /* vim:sw=8
X */
diff -u --recursive --new-file v2.3.2/linux/drivers/usb/ohci.h linux/drivers/usb/ohci.h
--- v2.3.2/linux/drivers/usb/ohci.h Sat May 15 23:46:04 1999
+++ linux/drivers/usb/ohci.h Sun May 16 22:23:31 1999
@@ -6,7 +6,7 @@
X *
X * (C) Copyright 1999 Gregory P. Smith <gr...@electricrain.com>
X *
- * $Id: ohci.h,v 1.15 1999/05/09 23:25:49 greg Exp $
+ * $Id: ohci.h,v 1.24 1999/05/16 10:18:26 greg Exp $
X */
X
X #include <linux/list.h>
@@ -37,7 +37,9 @@
X struct ohci_td *next_dl_td; /* used during donelist processing */
X void *data; /* virt. address of the the buffer */
X usb_device_irq completed; /* Completion handler routine */
- int allocated; /* boolean: is this TD allocated? */
+ int hcd_flags; /* Flags for the HCD: */
+ /* bit0 = boolean: Is this TD allocated? */
+ /* bit1 = boolean: Is this a dummy (end of list) TD? */
X
X /* User or Device class driver specific fields */
X void *dev_id; /* user defined pointer passed to irq handler */
@@ -59,6 +61,7 @@
X #define td_force_toggle(b) (((b) | 2) << 24)
X #define OHCI_TD_ERRCNT (3 << 26) /* error count */
X #define td_errorcount(td) (((td).info >> 26) & 3)
+#define clear_td_errorcount(td) ((td)->info &= ~(__u32)OHCI_TD_ERRCNT)
X #define OHCI_TD_CC (0xf << 28) /* condition code */
X #define OHCI_TD_CC_GET(td_i) (((td_i) >> 28) & 0xf)
X #define OHCI_TD_CC_NEW (OHCI_TD_CC) /* set this on all unaccessed TDs! */
@@ -68,9 +71,16 @@
X #define td_active(td) (!td_cc_noerror((td)) && (td_errorcount((td)) < 3))
X #define td_done(td) (td_cc_noerror((td)) || (td_errorcount((td)) == 3))
X
-#define td_allocated(td) ((td).allocated)
-#define allocate_td(td) ((td)->allocated = 1)
-#define ohci_free_td(td) ((td)->allocated = 0)
+/*
+ * Macros to use the td->hcd_flags field.
+ */
+#define td_allocated(td) ((td).hcd_flags & 1)
+#define allocate_td(td) ((td)->hcd_flags |= 1)
+#define ohci_free_td(td) ((td)->hcd_flags &= ~(__u32)1)
+
+#define td_dummy(td) ((td).hcd_flags & 2)
+#define make_dumb_td(td) ((td)->hcd_flags |= 2)
+#define clear_dumb_td(td) ((td)->hcd_flags &= ~(__u32)2)
X
X
X /*
@@ -114,14 +124,14 @@
X #define OHCI_ED_FA (0x7f)
X
X
-/* NOTE: bits 27-31 of the status dword are reserved for the driver */
+/* NOTE: bits 27-31 of the status dword are reserved for the HCD */
X /*
X * We'll use this status flag for to mark if an ED is in use by the
- * driver or not. If the bit is set, it is used.
- *
- * FIXME: implement this!
+ * driver or not. If the bit is set, it is being used.
X */
-#define ED_USED (1 << 31)
+#define ED_ALLOCATED (1 << 31)
+#define ed_allocated(ed) ((ed).status & ED_ALLOCATED)
+#define allocate_ed(ed) ((ed)->status |= ED_ALLOCATED)
X
X /*
X * The HCCA (Host Controller Communications Area) is a 256 byte
@@ -187,16 +197,17 @@
X
X /* .... */
X
+/*
+ * These are the index of the placeholder EDs for the root hub to
+ * build the interrupt transfer ED tree out of.
+ */
X #define ED_INT_1 0
X #define ED_INT_2 1
X #define ED_INT_4 2
X #define ED_INT_8 3
X #define ED_INT_16 4
X #define ED_INT_32 5
-#define ED_CONTROL 6
-#define ED_BULK 7
X #define ED_ISO ED_INT_1 /* same as 1ms interrupt queue */
-#define ED_FIRST_AVAIL 8 /* first non-reserved ED */
X
X /*
X * Given a period p in ms, convert it to the closest endpoint
@@ -215,7 +226,9 @@
X * This is the maximum number of root hub ports. I don't think we'll
X * ever see more than two as that's the space available on an ATX
X * motherboard's case, but it could happen. The OHCI spec allows for
- * up to 15... (which is insane!)
+ * up to 15... (which is insane given that they each need to supply up
+ * to 500ma; that would be 7.5 amps!). I have seen a PCI card with 4
+ * downstream ports on it.
X *
X * Although I suppose several "ports" could be connected directly to
X * internal laptop devices such as a keyboard, mouse, camera and
@@ -259,6 +272,15 @@
X } roothub;
X } __attribute((aligned(32)));
X
+/*
+ * These are used by internal ED managing functions as a
+ * parameter to state the type of ED to deal with (when it matters).
+ */
+#define HCD_ED_ISOC (0)
+#define HCD_ED_INT (1)
+#define HCD_ED_CONTROL (2)
+#define HCD_ED_BULK (3)
+
X /*
X * Read a MMIO register and re-write it after ANDing with (m)
X */
@@ -352,9 +374,9 @@
X #define OHCI_TIMER /* enable the OHCI timer */
X #define OHCI_TIMER_FREQ (234) /* ms between each root hub status check */
X
-#undef OHCI_RHSC_INT /* don't use root hub status interrupts */
+#undef OHCI_RHSC_INT /* Don't use root hub status interrupts! */
X
-/* Debugging code */
+/* Debugging code [ohci-debug.c] */
X void show_ohci_ed(struct ohci_ed *ed);
X void show_ohci_td(struct ohci_td *td);
X void show_ohci_status(struct ohci *ohci);
diff -u --recursive --new-file v2.3.2/linux/fs/ChangeLog linux/fs/ChangeLog
--- v2.3.2/linux/fs/ChangeLog Fri Dec 18 07:09:35 1998
+++ linux/fs/ChangeLog Sat May 15 23:43:05 1999
@@ -144,24 +144,12 @@
X * rmdir of immutable/append-only directory shouldn't be allowed. Fixed.
X
X Remains unfixed:
- * UMSDOS_rename is broken. Call it with the dest. existing and being an
- empty directory and you've got EBUSY. At least it doesn't do
- any harm, so that will wait several days till rename cleanup.
- Sigh... It will wait a bit more. Problems with fat-derived
- filesystems are much worse than I thought. Idea of changing
- inode under dentry is broken by design - guess where the
- semaphore sits, for one.
- * umsdos: weird. rename() shouldn't return -EEXIST. BTW, manpage
- for rename(2) is obviously bogus - it mentions EEXIST and
- on the next line (correctly) says that EINVAL should be
- returned. Under the same conditions.
X * rename's handling of races is, erm, not optimal. Looks like I know
X what to do, but this thing needs some more cleanup - we can
X take care of almost all races in VFS and be much more graceful
X wrt locking. Moreover, it would give strong lookup atomicity.
X But it's a lot of changes to lookup and dcache code, so it will
X go after the fs drivers' cleanup.
- * hfs allows mknod. Only for regular files ;-/ IMHO it's bogus.
X * affs allows HARD links to directories. VFS is, to put it politely,
X not too ready to cope with _that_. And I'm not sure it should
X be - looks like they are pretty much similar to symlinks.
@@ -169,8 +157,3 @@
X braindead filesystems). I've submitted a patch to Linus, but
X looks like it wasn't applied.
X * msdos: shouldn't we treat SYS as IMMUTABLE? Makes sense, IMHO.
- * minix, qnx and sysv do NOT allow to mkdir sticky directories.
- * {minix,sysv}/namei.c (do_{minix,syv}_{rename,unlink}):
- Stuff related to retries still needs cleanup/fixing.
- Looks like I've found an extremely low-probability race
- there...
diff -u --recursive --new-file v2.3.2/linux/fs/Config.in linux/fs/Config.in
--- v2.3.2/linux/fs/Config.in Sat May 15 23:46:04 1999
+++ linux/fs/Config.in Sun May 16 10:27:40 1999
@@ -36,7 +36,7 @@
X if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
X bool ' NTFS read-write support (DANGEROUS)' CONFIG_NTFS_RW
X fi
-tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
+tristate 'OS/2 HPFS filesystem support (read/write) (NEW)' CONFIG_HPFS_FS
X bool '/proc filesystem support' CONFIG_PROC_FS
X if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
X # It compiles as a module for testing only. It should not be used
diff -u --recursive --new-file v2.3.2/linux/fs/affs/namei.c linux/fs/affs/namei.c
--- v2.3.2/linux/fs/affs/namei.c Fri Apr 23 21:20:37 1999
+++ linux/fs/affs/namei.c Sat May 15 23:43:05 1999
@@ -315,7 +315,7 @@
X error = affs_add_entry(dir,NULL,inode,dentry,ST_USERDIR);
X if (error)
X goto out_iput;
- inode->i_mode = S_IFDIR | S_ISVTX | (mode & 0777 & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | S_ISVTX | mode;
X inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);
X d_instantiate(dentry,inode);
X mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.2/linux/fs/devices.c linux/fs/devices.c
--- v2.3.2/linux/fs/devices.c Fri May 14 18:55:24 1999
+++ linux/fs/devices.c Sat May 15 23:43:04 1999
@@ -193,7 +193,7 @@
X * it. Thus it is called only upon a 'mount' or 'open'. This
X * is the best way of combining speed and utility, I think.
X * People changing diskettes in the middle of an operation deserve
- * to loose :-)
+ * to lose :-)
X */
X int check_disk_change(kdev_t dev)
X {
diff -u --recursive --new-file v2.3.2/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.3.2/linux/fs/ext2/namei.c Fri May 14 18:55:24 1999
+++ linux/fs/ext2/namei.c Sat May 15 23:43:05 1999
@@ -490,7 +490,7 @@
X inode->i_nlink = 2;
X mark_buffer_dirty(dir_block, 1);
X brelse (dir_block);
- inode->i_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
X if (dir->i_mode & S_ISGID)


X inode->i_mode |= S_ISGID;
X mark_inode_dirty(inode);

diff -u --recursive --new-file v2.3.2/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c
--- v2.3.2/linux/fs/ext2/truncate.c Sat May 15 23:46:04 1999
+++ linux/fs/ext2/truncate.c Sun May 16 13:55:46 1999
@@ -384,7 +384,7 @@
X
X void ext2_truncate (struct inode * inode)
X {
- int err, offset, retry;
+ int err, offset;
X
X if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
X S_ISLNK(inode->i_mode)))
@@ -393,7 +393,7 @@
X return;
X ext2_discard_prealloc(inode);
X while (1) {
- retry = trunc_direct(inode);
+ int retry = trunc_direct(inode);
X retry |= trunc_indirect (inode,
X EXT2_IND_BLOCK,
X (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK],
diff -u --recursive --new-file v2.3.2/linux/fs/hfs/bnode.c linux/fs/hfs/bnode.c
--- v2.3.2/linux/fs/hfs/bnode.c Fri May 14 18:55:24 1999
+++ linux/fs/hfs/bnode.c Sat May 15 15:02:50 1999
@@ -228,7 +228,7 @@
X break;
X
X case HFS_LOCK_NONE:
- while (bn->lock || witqueue_active(&bn->wqueue)) {
+ while (bn->lock || waitqueue_active(&bn->wqueue)) {
X hfs_sleep_on(&bn->rqueue);
X }
X ++bn->count;
diff -u --recursive --new-file v2.3.2/linux/fs/hfs/catalog.c linux/fs/hfs/catalog.c
--- v2.3.2/linux/fs/hfs/catalog.c Fri May 14 18:55:24 1999
+++ linux/fs/hfs/catalog.c Sat May 15 15:02:50 1999
@@ -647,7 +647,7 @@
X */
X static inline void start_write(struct hfs_cat_entry *dir)
X {
- if (dir->u.dir.readers || wait_queue_active(&dir->u.dir.read_wait)) {
+ if (dir->u.dir.readers || waitqueue_active(&dir->u.dir.read_wait)) {
X hfs_sleep_on(&dir->u.dir.write_wait);
X }
X ++dir->u.dir.writers;
@@ -658,7 +658,7 @@
X */
X static inline void start_read(struct hfs_cat_entry *dir)
X {
- if (dir->u.dir.writers || wait_queue_active(&dir->u.dir.write_wait)) {
+ if (dir->u.dir.writers || waitqueue_active(&dir->u.dir.write_wait)) {
X hfs_sleep_on(&dir->u.dir.read_wait);
X }
X ++dir->u.dir.readers;
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/alloc.c linux/fs/hpfs/alloc.c
--- v2.3.2/linux/fs/hpfs/alloc.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/alloc.c Sun May 16 10:27:40 1999
@@ -307,6 +307,7 @@
X if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
X for (j = 0; j < 512; j++) {
X unsigned k;
+ if (!bmp[j]) continue;
X for (k = bmp[j]; k; k >>= 1) if (k & 1) if (!--n) {
X hpfs_brelse4(&qbh);
X return 0;
@@ -327,9 +328,9 @@
X if (bmp) {
X for (j = 0; j < 512; j++) {
X unsigned k;
+ if (!bmp[j]) continue;
X for (k = 0xf; k; k <<= 4)
X if ((bmp[j] & k) == k) {
- /*printk("%08x,%08x\n",j,i);*/
X if (!--n) {
X hpfs_brelse4(&qbh);
X return 0;
@@ -372,8 +373,13 @@
X int lock)
X {
X struct dnode *d;
- if (!(*dno = alloc_in_dirband(s, near, lock)))
- if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL;
+ if (hpfs_count_one_bitmap(s, s->s_hpfs_dmap) > FREE_DNODES_ADD) {
+ if (!(*dno = alloc_in_dirband(s, near, lock)))
+ if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL;
+ } else {
+ if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock)))
+ if (!(*dno = alloc_in_dirband(s, near, lock))) return NULL;
+ }
X if (!(d = hpfs_get_4sectors(s, *dno, qbh))) {
X hpfs_free_dnode(s, *dno);
X return NULL;
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/dentry.c linux/fs/hpfs/dentry.c
--- v2.3.2/linux/fs/hpfs/dentry.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/dentry.c Sun May 16 10:27:40 1999
@@ -16,14 +16,14 @@
X {
X unsigned long hash;
X int i;
- int l = qstr->len;
+ unsigned l = qstr->len;
X
X if (l == 1) if (qstr->name[0]=='.') goto x;
X if (l == 2) if (qstr->name[0]=='.' || qstr->name[1]=='.') goto x;
- if (hpfs_chk_name((char *)qstr->name,l))
- /*return -ENAMETOOLONG;*/
- return -ENOENT;
X hpfs_adjust_length((char *)qstr->name, &l);
+ /*if (hpfs_chk_name((char *)qstr->name,&l))*/
+ /*return -ENAMETOOLONG;*/
+ /*return -ENOENT;*/
X x:
X
X hash = init_name_hash();
@@ -36,15 +36,15 @@
X
X int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
X {
- int al=a->len;
- int bl=b->len;
+ unsigned al=a->len;
+ unsigned bl=b->len;
X hpfs_adjust_length((char *)a->name, &al);
- hpfs_adjust_length((char *)b->name, &bl);
+ /*hpfs_adjust_length((char *)b->name, &bl);*/
X /* 'a' is the qstr of an already existing dentry, so the name
X * must be valid. 'b' must be validated first.
X */
X
- if (hpfs_chk_name((char *)b->name, bl)) return 1;
+ if (hpfs_chk_name((char *)b->name, &bl)) return 1;
X if (hpfs_compare_names(dentry->d_sb, (char *)a->name, al, (char *)b->name, bl, 0)) return 1;
X return 0;
X }
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/dir.c linux/fs/hpfs/dir.c
--- v2.3.2/linux/fs/hpfs/dir.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/dir.c Sun May 16 10:27:40 1999
@@ -30,8 +30,6 @@
X char *tempname;
X int c1, c2 = 0;
X
- if (!inode) return -EBADF;
- if (!S_ISDIR(inode->i_mode)) return -EBADF;
X if (inode->i_sb->s_hpfs_chk) {
X if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode"))
X return -EFSERROR;
@@ -150,57 +148,30 @@
X struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct quad_buffer_head qbh;
X struct hpfs_dirent *de;
- struct inode *inode;
X ino_t ino;
-
+ int err;
X struct inode *result = NULL;
- if (dir == 0) return -ENOENT;
- hpfs_adjust_length((char *)name, &len);
+
+ if ((err = hpfs_chk_name((char *)name, &len))) {
+ if (err == -ENAMETOOLONG) return ERR_PTR(-ENAMETOOLONG);
+ goto end_add;
+ }
+
X hpfs_lock_inode(dir);
- if (!S_ISDIR(dir->i_mode)) goto bail;
X /*
- * Read in the directory entry. "." is there under the name ^A^A .
- * Always read the dir even for . and .. in case we need the dates.
- *
- * M.P.: No - we can't read '^A^A' for current directory. In some cases
- * the information under '^A^A' is incomplete (missing ea_size, bad
- * fnode number) - chkdsk ignores such errors and it doesn't seem to
- * matter under OS/2.
- */
- if (name[0] == '.' && len == 1) {
- result = dir;
- dir->i_count++;
- goto end;
- } else if (name[0] == '.' && name[1] == '.' && len == 2) {
- struct buffer_head *bh;
- struct fnode *fnode;
- if (dir->i_ino == dir->i_sb->s_hpfs_root) {
- result = dir;
- dir->i_count++;
- goto end;
- }
- if (dir->i_hpfs_parent_dir == dir->i_sb->s_hpfs_root) {
- result = dir->i_sb->s_root->d_inode;
- result->i_count++;
- goto end;
- }
- if (!(fnode = hpfs_map_fnode(dir->i_sb, dir->i_hpfs_parent_dir, &bh))) goto bail;
- de = map_fnode_dirent(dir->i_sb, dir->i_hpfs_parent_dir, fnode, &qbh);
- brelse(bh);
- } else
- de = map_dirent(dir, dir->i_hpfs_dno, (char *) name, len, NULL, &qbh, NULL);
+ * '.' and '..' will never be passed here.
+ */
+
+ de = map_dirent(dir, dir->i_hpfs_dno, (char *) name, len, NULL, &qbh);
X
X /*
X * This is not really a bailout, just means file not found.
X */
X
- if (!de) {
- result = NULL;
- goto end;
- }
+ if (!de) goto end;
X
X /*
X * Get inode number, what we're after.
@@ -213,18 +184,18 @@
X */
X
X hpfs_lock_iget(dir->i_sb, de->directory || (de->ea_size && dir->i_sb->s_hpfs_eas) ? 1 : 2);
- if (!(inode = iget(dir->i_sb, ino))) {
+ if (!(result = iget(dir->i_sb, ino))) {
X hpfs_unlock_iget(dir->i_sb);
- hpfs_error(inode->i_sb, "hpfs_lookup: can't get inode");
+ hpfs_error(result->i_sb, "hpfs_lookup: can't get inode");
X goto bail1;
X }
- if (!de->directory) inode->i_hpfs_parent_dir = dir->i_ino;
+ if (!de->directory) result->i_hpfs_parent_dir = dir->i_ino;
X hpfs_unlock_iget(dir->i_sb);
X
- hpfs_decide_conv(inode, (char *)name, len);
+ hpfs_decide_conv(result, (char *)name, len);
X
X if (de->has_acl || de->has_xtd_perm) if (!(dir->i_sb->s_flags & MS_RDONLY)) {
- hpfs_error(inode->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
+ hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
X goto bail1;
X }
X
@@ -233,24 +204,24 @@
X * inode.
X */
X
- if (!inode->i_ctime) {
- if (!(inode->i_ctime = local_to_gmt(dir->i_sb, de->creation_date)))
- inode->i_ctime = 1;
- inode->i_mtime = local_to_gmt(dir->i_sb, de->write_date);
- inode->i_atime = local_to_gmt(dir->i_sb, de->read_date);
- inode->i_hpfs_ea_size = de->ea_size;
- if (!inode->i_hpfs_ea_mode && de->read_only)
- inode->i_mode &= ~0222;
+ if (!result->i_ctime) {
+ if (!(result->i_ctime = local_to_gmt(dir->i_sb, de->creation_date)))
+ result->i_ctime = 1;
+ result->i_mtime = local_to_gmt(dir->i_sb, de->write_date);
+ result->i_atime = local_to_gmt(dir->i_sb, de->read_date);
+ result->i_hpfs_ea_size = de->ea_size;
+ if (!result->i_hpfs_ea_mode && de->read_only)
+ result->i_mode &= ~0222;
X if (!de->directory) {
- if (inode->i_size == -1) {
- inode->i_size = de->file_size;
+ if (result->i_size == -1) {
+ result->i_size = de->file_size;
X /*
X * i_blocks should count the fnode and any anodes.
X * We count 1 for the fnode and don't bother about
X * anodes -- the disk heads are on the directory band
X * and we want them to stay there.
X */
- inode->i_blocks = 1 + ((inode->i_size + 511) >> 9);
+ result->i_blocks = 1 + ((result->i_size + 511) >> 9);
X }
X }
X }
@@ -261,9 +232,9 @@
X * Made it.
X */
X
- result = inode;
X end:
X hpfs_unlock_inode(dir);
+ end_add:
X hpfs_set_dentry_operations(dentry);
X d_add(dentry, result);
X return NULL;
@@ -275,7 +246,7 @@
X
X hpfs_brelse4(&qbh);
X
- bail:
+ /*bail:*/
X
X hpfs_unlock_inode(dir);
X return ERR_PTR(-ENOENT);
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/dnode.c linux/fs/hpfs/dnode.c
--- v2.3.2/linux/fs/hpfs/dnode.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/dnode.c Sun May 16 10:27:40 1999
@@ -368,7 +368,6 @@
X struct quad_buffer_head qbh;
X dnode_secno dno;
X int c;
- int depth = cdepth;
X int c1, c2 = 0;
X dno = i->i_hpfs_dno;
X down:
@@ -385,7 +384,6 @@
X if (de->down) {
X dno = de_down_pointer(de);
X hpfs_brelse4(&qbh);
- depth++;
X goto down;
X }
X break;
@@ -393,7 +391,7 @@
X }
X hpfs_brelse4(&qbh);
X if (!cdepth) hpfs_lock_creation(i->i_sb);
- if (hpfs_check_free_dnodes(i->i_sb, depth + 2)) {
+ if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
X c = 1;
X goto ret;
X }
@@ -574,11 +572,6 @@
X goto end;
X }
X
- /*{
- static int cnt_t_ = 0;
- if (cnt_t_++ & 1) goto endm;
- }*/
-
X if (!de->last) {
X struct hpfs_dirent *de_next = de_next_de(de);
X struct hpfs_dirent *de_cp;
@@ -607,7 +600,6 @@
X kfree(de_cp);
X goto try_it_again;
X } else {
- /*printk("HPFS: warning: not balancing tree\n");*/
X struct hpfs_dirent *de_prev = dnode_pre_last_de(dnode);
X struct hpfs_dirent *de_cp;
X struct dnode *d1;
@@ -692,20 +684,21 @@
X {
X struct dnode *dnode = qbh->data;
X dnode_secno down = 0;
+ int lock = 0;
X loff_t t;
X if (de->first || de->last) {
X hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno);
X hpfs_brelse4(qbh);
X return 1;
X }
- if (de->down) {
- if ((down = de_down_pointer(de)) && depth) {
- hpfs_lock_creation(i->i_sb);
- if (hpfs_check_free_dnodes(i->i_sb, depth + 2)) {
- hpfs_brelse4(qbh);
- hpfs_unlock_creation(i->i_sb);
- return 2;
- }
+ if (de->down) down = de_down_pointer(de);
+ if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) {
+ lock = 1;
+ hpfs_lock_creation(i->i_sb);
+ if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
+ hpfs_brelse4(qbh);
+ hpfs_unlock_creation(i->i_sb);
+ return 2;
X }
X }
X i->i_version = ++event;
@@ -716,10 +709,12 @@
X if (down) {
X dnode_secno a = move_to_top(i, down, dno);
X for_all_poss(i, hpfs_pos_subst, 5, t);
- if (depth) hpfs_unlock_creation(i->i_sb);
X if (a) delete_empty_dnode(i, a);
+ if (lock) hpfs_unlock_creation(i->i_sb);
X return !a;
- } else delete_empty_dnode(i, dno);
+ }
+ delete_empty_dnode(i, dno);
+ if (lock) hpfs_unlock_creation(i->i_sb);


X return 0;
X }
X

@@ -888,15 +883,13 @@
X /* Find a dirent in tree */
X
X struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, char *name, unsigned len,
- dnode_secno *dd, struct quad_buffer_head *qbh, int *depth)
+ dnode_secno *dd, struct quad_buffer_head *qbh)
X {
X struct dnode *dnode;
X struct hpfs_dirent *de;
X struct hpfs_dirent *de_end;
X int c1, c2 = 0;
X
- if (depth) *depth = 0;
-
X if (!S_ISDIR(inode->i_mode)) hpfs_error(inode->i_sb, "map_dirent: not a directory\n");
X again:
X if (inode->i_sb->s_hpfs_chk)
@@ -914,7 +907,6 @@
X if (de->down) {
X dno = de_down_pointer(de);
X hpfs_brelse4(qbh);
- if (depth) (*depth)++;
X goto again;
X }
X break;
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/file.c linux/fs/hpfs/file.c
--- v2.3.2/linux/fs/hpfs/file.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/file.c Sun May 16 10:27:40 1999
@@ -54,7 +54,6 @@
X i->i_hpfs_n_secs = 0;
X hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
X i->i_blocks = 1 + ((i->i_size + 511) >> 9);
- /*mark_inode_dirty(i);*/i->i_hpfs_dirty = 1;
X hpfs_write_inode(i);
X }
X
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/hpfs_fn.h linux/fs/hpfs/hpfs_fn.h
--- v2.3.2/linux/fs/hpfs/hpfs_fn.h Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/hpfs_fn.h Sun May 16 10:27:40 1999
@@ -42,6 +42,9 @@
X #define ANODE_RD_AHEAD 16
X #define DNODE_RD_AHEAD 4
X
+#define FREE_DNODES_ADD 58
+#define FREE_DNODES_DEL 29
+
X #define CHKCOND(x,y) if (!(x)) printk y
X
X #ifdef DBG
@@ -237,7 +240,7 @@
X void hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *);
X dnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno);
X struct hpfs_dirent *map_pos_dirent(struct inode *, loff_t *, struct quad_buffer_head *);
-struct hpfs_dirent *map_dirent(struct inode *, dnode_secno, char *, unsigned, dnode_secno *, struct quad_buffer_head *, int *depth);
+struct hpfs_dirent *map_dirent(struct inode *, dnode_secno, char *, unsigned, dnode_secno *, struct quad_buffer_head *);
X void hpfs_remove_dtree(struct super_block *, dnode_secno);
X struct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct fnode *, struct quad_buffer_head *);
X
@@ -285,7 +288,7 @@
X /* name.c */
X
X unsigned char hpfs_upcase(unsigned char *, unsigned char);
-int hpfs_chk_name(unsigned char *, unsigned);
+int hpfs_chk_name(unsigned char *, unsigned *);
X char *hpfs_translate_name(struct super_block *, unsigned char *, unsigned, int, int);
X int hpfs_compare_names(struct super_block *, unsigned char *, unsigned, unsigned char *, unsigned, int);
X int hpfs_is_name_long(unsigned char *, unsigned);
@@ -310,5 +313,6 @@
X int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *);
X int hpfs_remount_fs(struct super_block *, int *, char *);
X void hpfs_put_super(struct super_block *);
+unsigned hpfs_count_one_bitmap(struct super_block *, secno);
X int hpfs_statfs(struct super_block *, struct statfs *, int);
X struct super_block *hpfs_read_super(struct super_block *, void *, int);
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/inode.c linux/fs/hpfs/inode.c
--- v2.3.2/linux/fs/hpfs/inode.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/inode.c Sun May 16 10:27:40 1999
@@ -128,6 +128,7 @@
X unsigned char *ea;
X int ea_size;
X i->i_op = 0;
+ /*i->i_hpfs_sem = MUTEX;*/
X init_MUTEX(&i->i_hpfs_sem);
X i->i_uid = sb->s_hpfs_uid;
X i->i_gid = sb->s_hpfs_gid;
@@ -199,27 +200,27 @@
X return;
X }
X if ((ea = hpfs_get_ea(i->i_sb, fnode, "MODE", &ea_size))) {
+ int rdev = 0;
+ umode_t mode = sb->s_hpfs_mode;
X if (ea_size == 2) {
- i->i_mode = ea[0] + (ea[1] << 8);
+ mode = ea[0] + (ea[1] << 8);
X i->i_hpfs_ea_mode = 1;
X }
X kfree(ea);
- if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) {
+ i->i_mode = mode;
+ if (S_ISBLK(mode) || S_ISCHR(mode)) {
X if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) {
X if (ea_size == 4)
- i->i_rdev = to_kdev_t(ea[0] + (ea[1] << 8) + (ea[2] << 16) + (ea[3] << 24));
+ rdev = ea[0] + (ea[1] << 8) + (ea[2] << 16) + (ea[3] << 24);
X kfree(ea);
X }
X }
- if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode) || S_ISFIFO(i->i_mode) || S_ISSOCK(i->i_mode)) {
+ if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
X brelse(bh);
X i->i_nlink = 1;
X i->i_size = 0;
X i->i_blocks = 1;
- i->i_op = NULL;
- if (S_ISBLK(i->i_mode)) i->i_op = (struct inode_operations *) &blkdev_inode_operations;
- if (S_ISCHR(i->i_mode)) i->i_op = (struct inode_operations *) &chrdev_inode_operations;
- if (S_ISFIFO(i->i_mode)) init_fifo(i);
+ init_special_inode(i, mode, rdev);
X return;
X }
X }
@@ -341,7 +342,7 @@
X hpfs_brelse4(&qbh);
X }
X if (S_ISDIR(i->i_mode)) {
- if ((de = map_dirent(i, i->i_hpfs_dno, "\001\001", 2, NULL, &qbh, NULL))) {
+ if ((de = map_dirent(i, i->i_hpfs_dno, "\001\001", 2, NULL, &qbh))) {
X de->write_date = gmt_to_local(i->i_sb, i->i_mtime);
X de->read_date = gmt_to_local(i->i_sb, i->i_atime);
X de->creation_date = gmt_to_local(i->i_sb, i->i_ctime);
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/name.c linux/fs/hpfs/name.c
--- v2.3.2/linux/fs/hpfs/name.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/name.c Sun May 16 10:27:40 1999
@@ -70,13 +70,15 @@
X return dir[a];
X }
X
-int hpfs_chk_name(unsigned char *name, unsigned len)
+int hpfs_chk_name(unsigned char *name, unsigned *len)
X {
X int i;
- if (!len || len > 254) return 1;
- for (i = 0; i < len; i++) if (not_allowed_char(name[i])) return 1;
- if (len == 1) if (name[0] == '.') return 1;
- if (len == 2) if (name[0] == '.' && name[1] == '.') return 1;
+ if (*len > 254) return -ENAMETOOLONG;
+ hpfs_adjust_length(name, len);
+ if (!*len) return -EINVAL;
+ for (i = 0; i < *len; i++) if (not_allowed_char(name[i])) return -EINVAL;
+ if (*len == 1) if (name[0] == '.') return -EINVAL;
+ if (*len == 2) if (name[0] == '.' && name[1] == '.') return -EINVAL;


X return 0;
X }
X

@@ -101,7 +103,7 @@
X }
X
X int hpfs_compare_names(struct super_block *s, unsigned char *n1, unsigned l1,
- unsigned char *n2, unsigned l2, int last)
+ unsigned char *n2, unsigned l2, int last)
X {
X unsigned l = l1 < l2 ? l1 : l2;
X unsigned i;
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/namei.c linux/fs/hpfs/namei.c
--- v2.3.2/linux/fs/hpfs/namei.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/namei.c Sun May 16 10:27:40 1999
@@ -11,7 +11,7 @@
X int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct quad_buffer_head qbh0;
X struct buffer_head *bh;
X struct hpfs_dirent *de;
@@ -22,14 +22,8 @@
X dnode_secno dno;
X int r;
X struct hpfs_dirent dee;
- if (!dir) return -ENOENT;
- if (!S_ISDIR(dir->i_mode)) {
- return -ENOTDIR;
- }
- hpfs_adjust_length((char *)name, &len);
- if (hpfs_chk_name((char *)name, len)) {
- return -ENAMETOOLONG;
- }
+ int err;
+ if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
X if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
X if (!(dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1))) goto bail1;
X memset(&dee, 0, sizeof dee);
@@ -105,25 +99,15 @@
X int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
- struct inode *result;
+ unsigned len = dentry->d_name.len;
+ struct inode *result = NULL;
X struct buffer_head *bh;
X struct fnode *fnode;
X fnode_secno fno;
X int r;
X struct hpfs_dirent dee;
- result = NULL;
- if (!dir) return -ENOENT;
- if (!S_ISDIR(dir->i_mode)) {
- return -ENOTDIR;
- }
- if (!S_ISREG(mode)) {
- return -EINVAL;
- }
- hpfs_adjust_length((char *)name, &len);
- if (hpfs_chk_name((char *)name, len)) {
- return -ENAMETOOLONG;
- }
+ int err;
+ if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
X if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
X memset(&dee, 0, sizeof dee);
X if (!(mode & 0222)) dee.read_only = 1;
@@ -178,28 +162,16 @@
X int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct buffer_head *bh;
X struct fnode *fnode;
X fnode_secno fno;
X int r;
X struct hpfs_dirent dee;
X struct inode *result = NULL;
- if (!dir) return -ENOENT;
- if (dir->i_sb->s_hpfs_eas < 2) {
- /*iput(dir);*/
- return -EPERM;
- }
- if (!S_ISDIR(dir->i_mode)) {
- return -ENOTDIR;
- }
- if (!S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && !S_ISSOCK(mode)) {
- return -EINVAL;
- }
- hpfs_adjust_length((char *)name, &len);
- if (hpfs_chk_name((char *)name, len)) {
- return -ENAMETOOLONG;
- }
+ int err;
+ if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
+ if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
X if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
X memset(&dee, 0, sizeof dee);
X if (!(mode & 0222)) dee.read_only = 1;
@@ -227,17 +199,12 @@
X result->i_hpfs_ea_size = 0;
X /*if (result->i_blocks == -1) result->i_blocks = 1;
X if (result->i_size == -1) result->i_size = 0;*/
- result->i_mode = mode;
X result->i_uid = current->fsuid;
X result->i_gid = current->fsgid;
- if (!S_ISFIFO(mode)) result->i_rdev = to_kdev_t(rdev);
X result->i_nlink = 1;
X result->i_size = 0;
X result->i_blocks = 1;
- result->i_op = NULL;
- if (S_ISBLK(result->i_mode)) result->i_op = (struct inode_operations *) &blkdev_inode_operations;
- if (S_ISCHR(result->i_mode)) result->i_op = (struct inode_operations *) &chrdev_inode_operations;
- if (S_ISFIFO(result->i_mode)) init_fifo(result);
+ init_special_inode(result, mode, rdev);
X hpfs_write_inode_nolock(result);
X d_instantiate(dentry, result);
X }
@@ -258,24 +225,16 @@
X int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct buffer_head *bh;
X struct fnode *fnode;
X fnode_secno fno;
X int r;
X struct hpfs_dirent dee;
X struct inode *result;
- if (!dir) return -ENOENT;
- if (dir->i_sb->s_hpfs_eas < 2) {
- return -EPERM;
- }
- if (!S_ISDIR(dir->i_mode)) {
- return -ENOTDIR;
- }
- hpfs_adjust_length((char *)name, &len);
- if (hpfs_chk_name((char *)name, len)) {
- return -ENAMETOOLONG;
- }
+ int err;
+ if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
+ if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
X if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
X memset(&dee, 0, sizeof dee);
X dee.archive = 1;
@@ -331,16 +290,18 @@
X int hpfs_unlink(struct inode *dir, struct dentry *dentry)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct quad_buffer_head qbh;
X struct hpfs_dirent *de;
X struct inode *inode = dentry->d_inode;
X dnode_secno dno;
X fnode_secno fno;
- int depth, r;
+ int r;
+ int rep = 0;
X hpfs_adjust_length((char *)name, &len);
+ again:
X hpfs_lock_2inodes(dir, inode);
- if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh, &depth))) {
+ if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
X hpfs_unlock_2inodes(dir, inode);
X return -ENOENT;
X }
@@ -355,29 +316,49 @@
X return -EISDIR;
X }
X fno = de->fnode;
- if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, depth)) == 1) hpfs_error(dir->i_sb, "there was error when removing dirent");
+ if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1) hpfs_error(dir->i_sb, "there was error when removing dirent");
X if (r != 2) {
X inode->i_nlink--;
X hpfs_unlock_2inodes(dir, inode);
X d_delete(dentry);
- } else hpfs_unlock_2inodes(dir, inode);
+ } else { /* no space for deleting, try to truncate file */
+ struct iattr newattrs;
+ hpfs_unlock_2inodes(dir, inode);
+ if (rep || dentry->d_count > 1 || permission(inode, MAY_WRITE) || get_write_access(inode)) goto ret;
+ /*printk("HPFS: truncating file before delete.\n");*/
+ down(&inode->i_sem); /* do_truncate should be called here, but it's */
+ newattrs.ia_size = 0; /* not exported */
+ newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ if (notify_change(dentry, &newattrs)) {
+ up(&inode->i_sem);
+ put_write_access(inode);
+ goto ret;
+ }
+ vmtruncate(inode, 0);
+ if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode);
+ up(&inode->i_sem);
+ put_write_access(inode);
+ rep = 1;
+ goto again;
+ }
+ ret:
X return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
X }
X
X int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
X {
X const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
+ unsigned len = dentry->d_name.len;
X struct quad_buffer_head qbh;
X struct hpfs_dirent *de;
X struct inode *inode = dentry->d_inode;
X dnode_secno dno;
X fnode_secno fno;
X int n_items = 0;
- int depth, r;
+ int r;
X hpfs_adjust_length((char *)name, &len);
X hpfs_lock_2inodes(dir, inode);
- if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh, &depth))) {
+ if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
X hpfs_unlock_2inodes(dir, inode);
X return -ENOENT;
X }
@@ -391,8 +372,6 @@
X hpfs_unlock_2inodes(dir, inode);
X return -ENOTDIR;
X }
- /*shrink_dcache_parent(dentry);
- if (dentry->d_count > 1) {*/
X if (!list_empty(&dentry->d_hash)) {
X hpfs_brelse4(&qbh);
X hpfs_unlock_2inodes(dir, inode);
@@ -405,7 +384,7 @@
X return -ENOTEMPTY;
X }
X fno = de->fnode;
- if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, depth)) == 1)
+ if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1)
X hpfs_error(dir->i_sb, "there was error when removing dirent");
X if (r != 2) {
X dir->i_nlink--;
@@ -445,7 +424,7 @@
X {
X struct inode *inode = dinode->d_inode;
X char *link;
- int len;
+ unsigned len;
X struct buffer_head *bh;
X struct fnode *fnode;
X if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) {
@@ -471,40 +450,29 @@
X int old_len = old_dentry->d_name.len;
X char *new_name = (char *)new_dentry->d_name.name;
X int new_len = new_dentry->d_name.len;
- struct inode *i;
+ struct inode *i = old_dentry->d_inode;
X struct inode *new_inode = new_dentry->d_inode;
X struct quad_buffer_head qbh, qbh1;
X struct hpfs_dirent *dep, *nde;
X struct hpfs_dirent de;
X dnode_secno dno;
- int depth, r;
- int err = 0;
+ int r;
X struct buffer_head *bh;
X struct fnode *fnode;
+ int err;
+ if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
+ err = 0;
X hpfs_adjust_length((char *)old_name, &old_len);
- hpfs_adjust_length((char *)new_name, &new_len);
- if (hpfs_chk_name((char *)new_name, new_len) || hpfs_chk_name((char *)old_name, old_len)) {
- err = -ENAMETOOLONG;
- goto end2;
- }
- if (!(i = old_dentry->d_inode)) {
- hpfs_error(old_dir->i_sb, "hpfs_rename: grrr, could not get inode");
- err = -ENOENT;
- goto end2;
- }
- if (i->i_sb != old_dir->i_sb || i->i_sb != new_dir->i_sb) {
- err = -EINVAL; /* Do not allow to move mount points */
- goto end1_;
- }
X
X hpfs_lock_3inodes(old_dir, new_dir, i);
X
- if (is_subdir(new_dentry, old_dentry) || (new_inode && S_ISDIR(new_inode->i_mode))) {
+ /* Erm? Moving over the empty non-busy directory is perfectly legal */
+ if (new_inode && S_ISDIR(new_inode->i_mode)) {
X err = -EINVAL;
X goto end1;
X }
X
- if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh, &depth))) {
+ if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
X hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
X err = -ENOENT;
X goto end1;
@@ -514,10 +482,10 @@
X
X if (new_inode) {
X hpfs_brelse4(&qbh);
- if ((nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1, NULL))) {
+ if ((nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1))) {
X int r;
- if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, depth)) != 2) {
- if (!(nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1, NULL))) {
+ if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
+ if (!(nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1))) {
X hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent #2");
X goto end1;
X }
@@ -539,7 +507,7 @@
X if (new_dir == old_dir) hpfs_brelse4(&qbh);
X
X hpfs_lock_creation(i->i_sb);
- if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, depth + 2))) {
+ if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
X hpfs_unlock_creation(i->i_sb);
X if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
X err = r == 1 ? -ENOSPC : -EFSERROR;
@@ -548,7 +516,7 @@
X }
X
X if (new_dir == old_dir)
- if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh, &depth))) {
+ if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
X hpfs_unlock_creation(i->i_sb);
X hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
X err = -ENOENT;
@@ -577,12 +545,9 @@
X mark_buffer_dirty(bh, 1);
X brelse(bh);
X }
- d_move(old_dentry, new_dentry);
X i->i_hpfs_conv = i->i_sb->s_hpfs_conv;
X hpfs_decide_conv(i, (char *)new_name, new_len);
X end1:
X hpfs_unlock_3inodes(old_dir, new_dir, i);
- end1_:
- end2:
X return err;
X }
diff -u --recursive --new-file v2.3.2/linux/fs/hpfs/super.c linux/fs/hpfs/super.c
--- v2.3.2/linux/fs/hpfs/super.c Sat May 15 23:46:04 1999
+++ linux/fs/hpfs/super.c Sun May 16 10:27:40 1999
@@ -105,7 +105,7 @@
X MOD_DEC_USE_COUNT;
X }
X
-static unsigned count_one_bitmap(struct super_block *s, secno secno)
+unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
X {
X struct quad_buffer_head qbh;
X unsigned *bits;
@@ -114,6 +114,7 @@
X count = 0;
X for (i = 0; i < 2048 / sizeof(unsigned); i++) {
X unsigned b;
+ if (!bits[i]) continue;
X for (b = bits[i]; b; b>>=1) count += b & 1;
X }
X hpfs_brelse4(&qbh);
@@ -126,7 +127,7 @@
X n_bands = (s->s_hpfs_fs_size + 0x3fff) >> 14;
X count = 0;
X for (n = 0; n < n_bands; n++)
- count += count_one_bitmap(s, s->s_hpfs_bmp_dir[n]);
+ count += hpfs_count_one_bitmap(s, s->s_hpfs_bmp_dir[n]);
X return count;
X }
X
@@ -135,7 +136,7 @@
X struct statfs tmp;
X /*if (s->s_hpfs_n_free == -1) {*/
X s->s_hpfs_n_free = count_bitmaps(s);
- s->s_hpfs_n_free_dnodes = count_one_bitmap(s, s->s_hpfs_dmap);
+ s->s_hpfs_n_free_dnodes = hpfs_count_one_bitmap(s, s->s_hpfs_dmap);
X /*}*/
X tmp.f_type = s->s_magic;
X tmp.f_bsize = 512;
@@ -379,7 +380,8 @@
X s->s_hpfs_cp_table = NULL;
X
X s->s_hpfs_creation_de_lock = s->s_hpfs_rd_inode = 0;
- s->s_hpfs_creation_de = s->s_hpfs_iget_q = NULL;
+ init_waitqueue_head(&s->s_hpfs_creation_de);
+ init_waitqueue_head(&s->s_hpfs_iget_q);
X
X uid = current->uid;
X gid = current->gid;
@@ -540,7 +542,7 @@
X
X root_dno = hpfs_fnode_dno(s, s->s_hpfs_root);
X if (root_dno)
- de = map_dirent(s->s_root->d_inode, root_dno, "\001\001", 2, NULL, &qbh, NULL);
+ de = map_dirent(s->s_root->d_inode, root_dno, "\001\001", 2, NULL, &qbh);
X if (!root_dno || !de) hpfs_error(s, "unable to find root dir");
X else {
X s->s_root->d_inode->i_atime = local_to_gmt(s, de->read_date);
diff -u --recursive --new-file v2.3.2/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.3.2/linux/fs/minix/namei.c Fri May 14 18:55:25 1999
+++ linux/fs/minix/namei.c Sat May 15 23:43:05 1999
@@ -297,7 +297,7 @@
X inode->i_nlink = 2;
X mark_buffer_dirty(dir_block, 1);
X brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
X if (dir->i_mode & S_ISGID)


X inode->i_mode |= S_ISGID;
X mark_inode_dirty(inode);

diff -u --recursive --new-file v2.3.2/linux/fs/namei.c linux/fs/namei.c
--- v2.3.2/linux/fs/namei.c Fri May 14 18:55:25 1999
+++ linux/fs/namei.c Sat May 15 23:43:05 1999
@@ -882,10 +882,6 @@
X return error;
X }
X
-/*
- * Look out: this function may change a normal dentry
- * into a directory dentry (different size)..
- */
X static inline int do_mkdir(const char * pathname, int mode)
X {
X int error;
@@ -919,7 +915,7 @@
X goto exit_lock;
X
X DQUOT_INIT(dir->d_inode);
- mode &= 0777 & ~current->fs->umask;
+ mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask;
X error = dir->d_inode->i_op->mkdir(dir->d_inode, dentry, mode);
X
X exit_lock:
diff -u --recursive --new-file v2.3.2/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.3.2/linux/fs/nfsd/vfs.c Mon Apr 12 10:03:45 1999
+++ linux/fs/nfsd/vfs.c Sat May 15 23:43:05 1999
@@ -691,6 +691,8 @@
X break;
X case S_IFDIR:
X opfunc = (nfsd_dirop_t) dirp->i_op->mkdir;
+ /* Odd, indeed, but filesystems did it anyway */
+ iap->ia_mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask;
X break;
X case S_IFCHR:
X case S_IFBLK:
diff -u --recursive --new-file v2.3.2/linux/fs/super.c linux/fs/super.c
--- v2.3.2/linux/fs/super.c Fri May 14 18:55:26 1999
+++ linux/fs/super.c Sat May 15 23:43:04 1999
@@ -846,7 +846,8 @@
X * Anyone using this new feature must know what he/she is doing.
X */
X
-int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
+int do_mount(kdev_t dev, const char * dev_name, const char * dir_name,
+ const char * type, int flags, void * data)
X {
X struct dentry * dir_d;
X struct super_block * sb;
diff -u --recursive --new-file v2.3.2/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.3.2/linux/fs/sysv/namei.c Fri May 14 18:55:26 1999
+++ linux/fs/sysv/namei.c Sat May 15 23:43:05 1999
@@ -291,7 +291,7 @@
X inode->i_nlink = 2;
X mark_buffer_dirty(dir_block, 1);
X brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
X if (dir->i_mode & S_ISGID)


X inode->i_mode |= S_ISGID;
X mark_inode_dirty(inode);

diff -u --recursive --new-file v2.3.2/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.3.2/linux/fs/ufs/namei.c Fri May 14 18:55:27 1999
+++ linux/fs/ufs/namei.c Sat May 15 23:43:05 1999
@@ -539,7 +539,7 @@
X inode->i_nlink = 2;
X mark_buffer_dirty(dir_block, 1);
X brelse (dir_block);
- inode->i_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
X if (dir->i_mode & S_ISGID)


SHAR_EOF
true || echo 'restore of patch-2.3.3 failed'
fi

echo 'End of part 3'
echo 'File patch-2.3.3 is continued in part 4'
echo 4 > _shar_seq_.tmp

Reply all
Reply to author
Forward
0 new messages