\documentstyle{article}
-% $Id: devices.tex,v 1.12 1998/08/06 04:52:01 hpa Exp $
+% $Id: devices.tex,v 1.14 1998/08/10 22:39:24 hpa Exp $
% ---------------------------------------------------------------------------
% Adopt somewhat reasonable margins, so it doesn't take a million
% pages to print... :-) If you're actually putting this in print, you
%
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$}
-\date{Last revised: August 5, 1998}
+\date{Last revised: August 10, 1998}
\maketitle
%
\noindent
\major{78}{}{char }{PAM Software's multimodem boards}
\major{79}{}{char }{PAM Software's multimodem boards -- alternate devices}
\major{80}{}{char }{Photometrics AT200 CCD camera}
-\major{81}{}{char }{Brooktree Bt848 frame grabbers}
+\major{81}{}{char }{video4linux}
\major{82}{}{char }{WiNRADiO communications receiver card}
\major{83}{}{char }{Teletext/videotext interfaces}
\major{84}{}{char }{Ikon 1011[57] Versatec Greensheet Interface}
\major{107}{}{char }{3Dfx Voodoo Graphics device}
\major{108}{}{char }{Device independent PPP interface}
\major{109}{}{char }{Reserved for logical volume manager}
-\major{110}{--119}{}{Unallocated}
+\major{110}{}{char }{miroMEDIA Surround board}
+\major{111}{--119}{}{Unallocated}
\major{120}{--127}{}{Local/experimental use}
\major{128}{--135}{char }{Unix98 PTY masters}
\major{136}{--143}{char }{Unix98 PTY slaves}
\minor{64}{/dev/ttyS0}{First serial port}
\minordots
\minor{127}{/dev/ttyS63}{64th serial port}
- \minor{128}{/dev/ptyp0}{First old pseudo-tty master}
+ \minor{128}{/dev/ptyp0}{OBSOLETE}
\minordots
- \minor{191}{/dev/ptysf}{64th old pseudo-tty master}
- \minor{192}{/dev/ttyp0}{First old pseudo-tty slave}
+ \minor{191}{/dev/ptysf}{OBSOLETE}
+ \minor{192}{/dev/ttyp0}{OBSOLETE}
\minordots
- \minor{255}{/dev/ttysf}{64th old pseudo-tty slave}
+ \minor{255}{/dev/ttysf}{OBSOLETE}
\end{devicelist}
\noindent
-For compatibility with previous versions of Linux, the first 64 PTYs
-are replicated under this device number. This use is deprecated with
-the release of Linux 2.0 and may be removed in a future version of
-Linux. To ensure proper operation, do not mix old and new PTY devices.
+Older versions of the Linux kernel used this major number for BSD PTY
+devices. As of Linux 2.1.115, this is no longer supported. Use major
+numbers 2 and 3.
\begin{devicelist}
\major{ 5}{}{char }{Alternate TTY devices}
\minor{133}{/dev/exttrp}{External device trap}
\minor{134}{/dev/apm\_bios}{Advanced Power Management BIOS}
\minor{135}{/dev/rtc}{Real Time Clock}
- \minor{136}{/dev/qcam0}{QuickCam on {\file lp0}}
- \minor{137}{/dev/qcam1}{QuickCam on {\file lp1}}
- \minor{138}{/dev/qcam2}{QuickCam on {\file lp2}}
\minor{139}{/dev/openprom}{SPARC OpenBoot PROM}
\minor{140}{/dev/relay8}{Berkshire Products Octal relay card}
\minor{141}{/dev/relay16}{Berkshire Products ISO-16 relay card}
\minor{149}{/dev/input/mouse}{Linux/SGI Irix emulation mouse}
\minor{150}{/dev/input/keyboard}{Linux/SGI Irix emulation keyboard}
\minor{151}{/dev/led}{Front panel LEDs}
- \minor{152}{/dev/radio}{Radio card (type?)}
\minor{153}{/dev/mergemem}{Memory merge device}
+ \minor{154}{/dev/pmu}{Macintosh PowerBook power manager}
\end{devicelist}
\begin{devicelist}
\end{devicelist}
\begin{devicelist}
-\major{81}{}{char }{Brooktree Bt848 frame grabbers}
- \minor{0}{/dev/bttv0}{First Bt848 card}
- \minor{0}{/dev/bttv1}{Second Bt848 card}
- \minordots
- \minor{16}{/dev/bttvc0}{Control for first Bt848 card}
- \minor{17}{/dev/bttvc1}{Control for second Bt848 card}
- \minordots
- \minor{32}{/dev/bttv-vbi0}{VBI data of first Bt848 card}
- \minor{33}{/dev/bttv-vbi1}{VBI data of second Bt848 card}
- \minordots
+\major{81}{}{char }{video4linux}
+ \minor{0}{/dev/video0}{Video capture/overlay device}
+ \minordots
+ \minor{63}{/dev/video63}{Video capture/overlay device}
+ \minor{64}{/dev/radio0}{Radio device}
+ \minordots
+ \minor{127}{/dev/radio63}{Radio device}
+ \minor{192}{/dev/vtx0}{Teletext device}
+ \minordots
+ \minor{223}{/dev/vtx31}{Teletext device}
+ \minor{224}{/dev/vbi0}{Vertical blank interupt}
+ \minordots
+ \minor{255}{/dev/vbi31}{Vertical blank interupt}
\end{devicelist}
\begin{devicelist}
\end{devicelist}
\begin{devicelist}
-\major{110}{--119}{}{Unallocated}
+\major{110}{}{char }{miroMEDIA Surround board}
+ \minor{0}{/dev/srnd0}{First miroMEDIA Surround board}
+ \minor{1}{/dev/srnd1}{First miroMEDIA Surround board}
+ \minordots
+\end{devicelist}
+
+\begin{devicelist}
+\major{111}{--119}{}{Unallocated}
\end{devicelist}
\begin{devicelist}
\link{/dev/core}{/proc/kcore}{symbolic}{Backward compatibility}
\link{/dev/ramdisk}{ram0}{symbolic}{Backward compatibility}
\link{/dev/ftape}{qft0}{symbolic}{Backward compatibility}
+\link{/dev/bttv0}{video0}{symbolic}{Backward compatibility}
+\link{/dev/radio}{radio0}{symbolic}{Backward compatibility}
\link{/dev/scd?}{sr?}{hard}{Alternate name for CD-ROMs}
\end{nodelist}
LINUX ALLOCATED DEVICES
Maintained by H. Peter Anvin <hpa@zytor.com>
- Last revised: August 5, 1998
+ Last revised: August 10, 1998
This list is the Linux Device List, the official registry of allocated
device numbers and /dev directory nodes for the Linux operating
64 = /dev/ttyS0 First serial port
...
127 = /dev/ttyS63 64th serial port
- 128 = /dev/ptyp0 First old pseudo-tty master
+ 128 = /dev/ptyp0 OBSOLETE
...
- 191 = /dev/ptysf 64th old pseudo-tty master
- 192 = /dev/ttyp0 First old pseudo-tty slave
+ 191 = /dev/ptysf OBSOLETE
+ 192 = /dev/ttyp0 OBSOLETE
...
- 255 = /dev/ttysf 64th old pseudo-tty slave
+ 255 = /dev/ttysf OBSOLETE
- For compatibility with previous versions of Linux, the
- first 64 PTYs are replicated under this device number.
- This use is deprecated with the release of Linux 2.0
- and may be removed in a future version of Linux. To
- ensure proper operation, do not mix old and new PTY
- devices.
+ Older versions of the Linux kernel used this major
+ number for BSD PTY devices. As of Linux 2.1.115, this
+ is no longer supported. Use major numbers 2 and 3.
5 char Alternate TTY devices
0 = /dev/tty Current TTY device
133 = /dev/exttrp External device trap
134 = /dev/apm_bios Advanced Power Management BIOS
135 = /dev/rtc Real Time Clock
- 136 = /dev/qcam0 QuickCam on lp0
- 137 = /dev/qcam1 QuickCam on lp1
- 138 = /dev/qcam2 QuickCam on lp2
139 = /dev/openprom SPARC OpenBoot PROM
140 = /dev/relay8 Berkshire Products Octal relay card
141 = /dev/relay16 Berkshire Products ISO-16 relay card
149 = /dev/input/mouse Linux/SGI Irix emulation mouse
150 = /dev/input/keyboard Linux/SGI Irix emulation keyboard
151 = /dev/led Front panel LEDs
- 152 = /dev/radio Radio card (type?)
153 = /dev/mergemem Memory merge device
+ 154 = /dev/pmu Macintosh PowerBook power manager
11 char Raw keyboard device
0 = /dev/kbd Raw keyboard device
80 char Photometrics AT200 CCD camera
0 = /dev/at200 Photometrics AT200 CCD camera
- 81 char Brooktree Bt848 frame grabbers
- 0 = /dev/bttv0 First Bt848 card
- 1 = /dev/bttv1 Second Bt848 card
+ 81 char video4linux
+ 0 = /dev/video0 Video capture/overlay device
+ ...
+ 63 = /dev/video63 Video capture/overlay device
+ 64 = /dev/radio0 Radio device
...
- 16 = /dev/bttvc0 Control for first Bt848 card
- 17 = /dev/bttvc1 Control for second Bt848 card
+ 127 = /dev/radio63 Radio device
+ 192 = /dev/vtx0 Teletext device
...
- 32 = /dev/bttv-vbi0 VBI data of first Bt848 card
- 33 = /dev/bttv-vbi1 VBI data of second Bt848 card
+ 223 = /dev/vtx31 Teletext device
+ 224 = /dev/vbi0 Vertical blank interrupt
...
+ 255 = /dev/vbi31 Vertical blank interrupt
82 char WiNRADiO communications receiver card
0 = /dev/winradio0 First WiNRADiO card
109 char Reserved for logical volume manager
-108-119 UNALLOCATED
+110 char miroMEDIA Surround board
+ 0 = /dev/srnd0 First miroMEDIA Surround board
+ 1 = /dev/srnd1 Second miroMEDIA Surround board
+ ...
+
+111-119 UNALLOCATED
120-127 LOCAL/EXPERIMENTAL USE
/dev/core /proc/kcore symbolic Backward compatibility
/dev/ramdisk ram0 symbolic Backward compatibility
/dev/ftape qft0 symbolic Backward compatibility
+/dev/bttv0 video0 symbolic Backward compatibility
+/dev/radio radio0 symbolic Backward compatibility
/dev/scd? sr? hard Alternate SCSI CD-ROM name
Locally defined links
scripts/split-include include/linux/autoconf.h include/config; \
fi
-linuxsubdirs: dummy
- set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
+linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
+
+$(patsubst %, _dir_%, $(SUBDIRS)) : dummy
+ $(MAKE) -C $(patsubst _dir_%, %, $@)
$(TOPDIR)/include/linux/version.h: include/linux/version.h
$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
init/main.o: init/main.c
$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
-fs: dummy
- $(MAKE) linuxsubdirs SUBDIRS=fs
-
-lib: dummy
- $(MAKE) linuxsubdirs SUBDIRS=lib
-
-mm: dummy
- $(MAKE) linuxsubdirs SUBDIRS=mm
-
-ipc: dummy
- $(MAKE) linuxsubdirs SUBDIRS=ipc
-
-kernel: dummy
- $(MAKE) linuxsubdirs SUBDIRS=kernel
-
-drivers: dummy
- $(MAKE) linuxsubdirs SUBDIRS=drivers
-
-net: dummy
- $(MAKE) linuxsubdirs SUBDIRS=net
+fs lib mm ipc kernel drivers net: dummy
+ $(MAKE) $(subst $@, _dir_$@, $@)
MODFLAGS = -DMODULE
ifdef CONFIG_MODULES
MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h
endif
-modules: include/linux/version.h
- @set -e; \
- for i in $(SUBDIRS); \
- do $(MAKE) -C $$i CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules; \
- done
+modules: $(patsubst %, _mod_%, $(SUBDIRS))
+
+$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h
+ $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules
modules_install:
@( \
dep-files: scripts/mkdep archdep include/linux/version.h
scripts/mkdep init/*.c > .depend
scripts/mkdep `find $(FINDHPATH) -follow -name \*.h ! -name modversions.h -print` > .hdepend
- set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done
+# set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep ;done
+# let this be made through the fastdep rule in Rules.make
+ $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
MODVERFILE :=
fastdep: dummy
$(TOPDIR)/scripts/mkdep $(wildcard *.[chS] local.h.master) > .depend
ifdef ALL_SUB_DIRS
- set -e; for i in $(ALL_SUB_DIRS); do $(MAKE) -C $$i fastdep; done
+ $(MAKE) $(patsubst %,_sfdep_%,$(ALL_SUB_DIRS)) _FASTDEP_ALL_SUB_DIRS="$(ALL_SUB_DIRS)"
endif
+ifdef _FASTDEP_ALL_SUB_DIRS
+$(patsubst %,_sfdep_%,$(_FASTDEP_ALL_SUB_DIRS)):
+ $(MAKE) -C $(patsubst _sfdep_%,%,$@) fastdep
+endif
+
+
#
# A rule to make subdirectories
#
-sub_dirs: dummy
+sub_dirs: dummy $(patsubst %,_subdir_%,$(SUB_DIRS))
+
ifdef SUB_DIRS
- set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done
+$(patsubst %,_subdir_%,$(SUB_DIRS)) : dummy
+ $(MAKE) -C $(patsubst _subdir_%,%,$@)
endif
#
ifneq "$(strip $(ALL_MOBJS))" ""
PDWN=$(shell $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh)
endif
-modules: $(ALL_MOBJS) $(MIX_OBJS) $(MI_OBJS) dummy
+
ifdef MOD_SUB_DIRS
- set -e; for i in $(MOD_SUB_DIRS); do $(MAKE) -C $$i modules; done
+$(patsubst %,_modsubdir_%,$(MOD_SUB_DIRS)) : dummy
+ $(MAKE) -C $(patsubst _modsubdir_%,%,$@) modules
endif
+
ifdef MOD_IN_SUB_DIRS
- set -e; for i in $(MOD_IN_SUB_DIRS); do $(MAKE) -C $$i modules; done
+$(patsubst %,_modinsubdir_%,$(MOD_IN_SUB_DIRS)) : dummy
+ $(MAKE) -C $(patsubst _modinsubdir_%,%,$@) modules
endif
+
+modules: $(ALL_MOBJS) $(MIX_OBJS) $(MI_OBJS) dummy \
+ $(patsubst %,_modsubdir_%,$(MOD_SUB_DIRS)) \
+ $(patsubst %,_modinsubdir_%,$(MOD_IN_SUB_DIRS))
ifneq "$(strip $(MOD_LIST_NAME))" ""
rm -f $$TOPDIR/modules/$(MOD_LIST_NAME)
ifdef MOD_SUB_DIRS
.globl ret_from_smpfork
ret_from_smpfork:
GET_CURRENT(%ebx)
-call __putlock
btrl $0, SYMBOL_NAME(scheduler_lock)
jmp ret_from_sys_call
#endif /* __SMP__ */
$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
L_TARGET = lib.a
-L_OBJS = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o lock.o lock_check.o
+L_OBJS = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o
include $(TOPDIR)/Rules.make
+++ /dev/null
-.globl __getlock
-__getlock:
- pushl %eax
-
- movl $-8192,%eax
- andl %esp,%eax
- movl 36(%eax),%eax
- incl spinlocks(,%eax,4)
-
- popl %eax
- ret
-
-.globl __putlock
-__putlock:
- pushl %eax
-
- movl $-8192,%eax
- andl %esp,%eax
- movl 36(%eax),%eax
- decl spinlocks(,%eax,4)
- js __bad_put
-
- popl %eax
- ret
-
-__bad_put:
- pushl %edx
- pushl %ecx
- call __putlock_negative
- popl %ecx
- popl %edx
- popl %eax
- ret
+++ /dev/null
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-unsigned int spinlocks[32];
-
-static void show_stack(unsigned int *stack)
-{
- int i;
-
- for (i = 0; i < 40; i++) {
- extern int get_options, __start_fixup;
- unsigned int p = stack[i];
- if (p >= (unsigned int) &get_options && p < (unsigned int)&__start_fixup)
- printk("[<%08x>] ", p);
- }
-}
-
-void __putlock_negative(
- unsigned int ecx,
- unsigned int edx,
- unsigned int eax,
- unsigned int from_where)
-{
- static int count = 0;
-
- spinlocks[current->processor] = 0;
-
- if (count < 5) {
- count++;
- printk("negative putlock from %x\n", from_where);
- show_stack(&ecx);
- }
-}
-
-void __check_locks(unsigned int type)
-{
- static int warned = 0;
-
- if (warned < 5) {
- unsigned int from_where = (&type)[-1];
- unsigned int this_cpu = current->processor;
- int bad_irq = 0;
-
- if (type) {
- unsigned long flags;
- __save_flags(flags);
- if (!(flags & 0x200) || (global_irq_holder == this_cpu))
- bad_irq = 1;
- }
-
- if (spinlocks[this_cpu] ||
- local_irq_count[this_cpu] ||
- local_bh_count[this_cpu] ||
- bad_irq) {
- warned++;
- printk("scheduling with spinlocks=%d at %x\n", spinlocks[this_cpu], from_where);
- show_stack(&type);
- }
- }
-}
-
-
inline unsigned long
__generic_copy_to_user(void *to, const void *from, unsigned long n)
{
- if ((unsigned long) to < TASK_SIZE)
- __check_locks(1);
if (access_ok(VERIFY_WRITE, to, n))
__copy_user(to,from,n);
return n;
inline unsigned long
__generic_copy_from_user(void *to, const void *from, unsigned long n)
{
- if ((unsigned long) from < TASK_SIZE)
- __check_locks(1);
if (access_ok(VERIFY_READ, from, n))
__copy_user(to,from,n);
return n;
__strncpy_from_user(char *dst, const char *src, long count)
{
long res;
- __check_locks(1);
__do_strncpy_from_user(dst, src, count, res);
return res;
}
strncpy_from_user(char *dst, const char *src, long count)
{
long res = -EFAULT;
- __check_locks(1);
if (access_ok(VERIFY_READ, src, 1))
__do_strncpy_from_user(dst, src, count, res);
return res;
unsigned long
clear_user(void *to, unsigned long n)
{
- __check_locks(1);
if (access_ok(VERIFY_WRITE, to, n))
__do_clear_user(to, n);
return n;
unsigned long
__clear_user(void *to, unsigned long n)
{
- __check_locks(1);
__do_clear_user(to, n);
return n;
}
{
unsigned long res;
- __check_locks(1);
__asm__ __volatile__(
"0: repne; scasb\n"
" notl %0\n"
* This is necessary for drives for situations where
* the translated geometry is unavailable from the BIOS.
*/
- for (i = 0; i < 4 ; i++) {
+ int xlate_done = 0;
+ for (i = 0; i < 4 && !xlate_done; i++) {
struct partition *q = &p[i];
if (NR_SECTS(q)
&& (q->sector & 63) == 1
if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
(void) ide_xlate_1024(dev, heads, " [PTBL]");
- break;
+ xlate_done = 1;
}
}
}
+ if (!xlate_done) {
+ /*
+ * Default translation is equivalent of "BIOS LBA":
+ */
+ ide_xlate_1024(dev, -2, " [LBA]");
+ }
}
}
#endif /* CONFIG_BLK_DEV_IDE */
/*
- * linux/drivers/block/ide.c Version 6.17 March 29, 1998
+ * linux/drivers/block/ide.c Version 6.18 August 16, 1998
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/
* Version 6.15 added SMP awareness to IDE drivers
* Version 6.16 fixed various bugs; even more SMP friendly
* Version 6.17 fix for newest EZ-Drive problem
+ * Version 6.18 default unpartitioned-disk translation now "BIOS LBA"
*
* Some additional driver compile-time options are in ide.h
*
printk("%s ", msg);
- if (xparm == -1 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63))
+ if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63))
return 0; /* small disk: no translation needed */
if (drive->id) {
#if FAKE_FDISK_FOR_EZDRIVE
if (xparm == -1) {
drive->remap_0_to_1 = 1;
- msg = "0->1";
+ printk("[remap 0->1] ");
} else
#endif /* FAKE_FDISK_FOR_EZDRIVE */
if (xparm == 1) {
drive->sect0 = 63;
drive->bios_cyl = (tracks - 1) / drive->bios_head;
- msg = "+63";
+ printk("[remap +63] ");
}
- printk("[remap %s] ", msg);
}
drive->part[0].nr_sects = current_capacity(drive);
printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
* once to be processed
* 97-4-11 Making protocol independent of endianity etc.
* 97-9-13 Cosmetic changes
+ * 98-5-13 Attempt to make 64-bit-clean on 64-bit machines
*
* possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
* why not: would need verify_area and friends, would share yet another
#define PARANOIA
#include <linux/major.h>
-#define MAJOR_NR NBD_MAJOR
-#include <linux/nbd.h>
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/file.h>
+#include <linux/ioctl.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
+#include <asm/types.h>
+
+#define MAJOR_NR NBD_MAJOR
+#include <linux/nbd.h>
+
+#define LO_MAGIC 0x68797548
static int nbd_blksizes[MAX_NBD] = {1024, 1024,};
static int nbd_sizes[MAX_NBD] = {0x7fffffff, 0x7fffffff,};
/*
* Send or receive packet.
*/
-static
-int nbd_xmit(int send, struct socket *sock, char *buf, int size)
+static int nbd_xmit(int send, struct socket *sock, char *buf, int size)
{
mm_segment_t oldfs;
int result;
DEBUG("NBD: sending control, ");
request.magic = htonl(NBD_REQUEST_MAGIC);
request.type = htonl(req->cmd);
- request.from = htonl(req->sector * 512);
+ request.from = cpu_to_be64( (u64) req->sector * (u64) 512);
request.len = htonl(req->current_nr_sectors << 9);
memcpy(request.handle, &req, sizeof(req));
}
#define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; }
-struct request * /* NULL returned = something went wrong, inform userspace */
- nbd_read_stat(struct nbd_device *lo)
+struct request *nbd_read_stat(struct nbd_device *lo)
+ /* NULL returned = something went wrong, inform userspace */
{
int result;
struct nbd_reply reply;
{
int i;
- if (sizeof(struct nbd_request) != 24) {
- printk(KERN_CRIT "Sizeof nbd_request needs to be 24 in order to work!\n" );
+ if (sizeof(struct nbd_request) != 28) {
+ printk(KERN_CRIT "Sizeof nbd_request needs to be 28 in order to work!\n" );
return -EIO;
}
if (tty->driver.subtype == PTY_TYPE_MASTER) {
tty_hangup(tty->link);
set_bit(TTY_OTHER_CLOSED, &tty->flags);
- devpts_pty_kill(MINOR(tty->device) - tty->driver.minor_start);
+#ifdef CONFIG_UNIX98_PTYS
+ {
+ unsigned int major = MAJOR(tty->device) - UNIX98_PTY_MASTER_MAJOR;
+ if ( major < UNIX98_NR_MAJORS ) {
+ devpts_pty_kill( MINOR(tty->device)
+ - tty->driver.minor_start + tty->driver.name_base );
+ }
+ }
+#endif
}
}
return ((count < N_TTY_BUF_SIZE/2) ? 0 : count);
}
-/*
- * Return the minor device number of a given pty. This lets us
- * open a master pty with the multi-headed ptmx device, then
- * find out which one we got after it is open, with an ioctl.
+/*
+ * Return the device number of a Unix98 PTY (only!). This lets us open a
+ * master pty with the multi-headed ptmx device, then find out which
+ * one we got after it is open, with an ioctl.
*/
-static int pty_get_device_minor(struct tty_struct *tty, unsigned int *value)
+#ifdef CONFIG_UNIX98_PTYS
+static int pty_get_device_number(struct tty_struct *tty, unsigned int *value)
{
- unsigned int result = MINOR(tty->device);
+ unsigned int result = MINOR(tty->device)
+ - tty->driver.minor_start + tty->driver.name_base;
return put_user(result, value);
}
+#endif
+
/* Set the lock flag on a pty */
static int pty_set_lock(struct tty_struct *tty, int * arg)
{
return 0;
}
-static int pty_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
if (!tty) {
printk("pty_ioctl called with NULL tty!\n");
return -EIO;
}
switch(cmd) {
- case TIOCGPTN: /* Get PT Number */
- return pty_get_device_minor(tty, (unsigned int *)arg);
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
return pty_set_lock(tty, (int *) arg);
}
return -ENOIOCTLCMD;
}
+#ifdef CONFIG_UNIX98_PTYS
+static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ if (!tty) {
+ printk("pty_unix98_ioctl called with NULL tty!\n");
+ return -EIO;
+ }
+ switch(cmd) {
+ case TIOCGPTN: /* Get PT Number */
+ return pty_get_device_number(tty, (unsigned int *)arg);
+ }
+
+ return pty_bsd_ioctl(tty,file,cmd,arg);
+}
+#endif
+
static void pty_flush_buffer(struct tty_struct *tty)
{
struct tty_struct *to = tty->link;
* assign it here, instead of up with the rest of the
* pty_driver initialization. <cananian@alumni.princeton.edu>
*/
- pty_driver.ioctl = pty_ioctl;
+ pty_driver.ioctl = pty_bsd_ioctl;
/* Unix98 devices */
#ifdef CONFIG_UNIX98_PTYS
ptm_driver[i].proc_entry = 0;
ptm_driver[i].major = UNIX98_PTY_MASTER_MAJOR+i;
ptm_driver[i].minor_start = 0;
+ ptm_driver[i].name_base = i*NR_PTYS;
ptm_driver[i].num = NR_PTYS;
ptm_driver[i].other = &pts_driver[i];
ptm_driver[i].table = ptm_table[i];
pts_driver[i].proc_entry = 0;
pts_driver[i].major = UNIX98_PTY_SLAVE_MAJOR+i;
pts_driver[i].minor_start = 0;
+ pts_driver[i].name_base = i*NR_PTYS;
pts_driver[i].num = ptm_driver[i].num;
pts_driver[i].other = &ptm_driver[i];
pts_driver[i].table = pts_table[i];
pts_driver[i].termios_locked = pts_termios_locked[i];
pts_driver[i].driver_state = ptm_state[i];
- ptm_driver[i].ioctl = pty_ioctl;
+ ptm_driver[i].ioctl = pty_unix98_ioctl;
if (tty_register_driver(&ptm_driver[i]))
panic("Couldn't register Unix98 ptm driver major %d",
#ifdef CONFIG_UNIX98_PTYS
if (device == PTMX_DEV) {
/* find a free pty. */
- int major, minor, line;
+ int major, minor;
struct tty_driver *driver;
/* find a device that is not in use. */
return -EIO; /* no free ptys */
ptmx_found:
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
- line = minor - driver->minor_start;
- devpts_pty_new(line + major*NR_PTYS, MKDEV(driver->other->major,
- line+driver->other->minor_start));
+ minor -= driver->minor_start;
+ devpts_pty_new(driver->other->name_base + minor, MKDEV(driver->other->major, minor + driver->other->minor_start));
noctty = 1;
goto init_dev_done;
}
*/
-#define BusLogic_DriverVersion "2.1.13"
-#define BusLogic_DriverDate "17 April 1998"
+#define BusLogic_DriverVersion "2.1.15"
+#define BusLogic_DriverDate "17 August 1998"
#include <linux/version.h>
#include <linux/module.h>
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/types.h>
#include <linux/blk.h>
#include <linux/blkdev.h>
BusLogic_ProbeInfoCount - FlashPointCount;
memcpy(SavedProbeInfo,
BusLogic_ProbeInfoList,
- sizeof(BusLogic_ProbeInfoList));
+ BusLogic_ProbeInfoCount
+ * sizeof(BusLogic_ProbeInfo_T));
memcpy(&BusLogic_ProbeInfoList[0],
&SavedProbeInfo[FlashPointCount],
MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
HostAdapter->TargetStatistics[CCB->TargetID]
.CommandsCompleted++;
if (BusLogic_GlobalOptions.TraceErrors)
- {
- int i;
- BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
- "Adapter Status %02X "
- "Target Status %02X\n",
- HostAdapter, CCB->SerialNumber,
- CCB->TargetID, Command->result,
- CCB->HostAdapterStatus,
- CCB->TargetDeviceStatus);
- BusLogic_Notice("CDB ", HostAdapter);
- for (i = 0; i < CCB->CDB_Length; i++)
- BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
- BusLogic_Notice("\n", HostAdapter);
- BusLogic_Notice("Sense ", HostAdapter);
- for (i = 0; i < CCB->SenseDataLength; i++)
- BusLogic_Notice(" %02X", HostAdapter,
- Command->sense_buffer[i]);
- BusLogic_Notice("\n", HostAdapter);
- }
+ {
+ int i;
+ BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
+ "Adapter Status %02X "
+ "Target Status %02X\n",
+ HostAdapter, CCB->SerialNumber,
+ CCB->TargetID, Command->result,
+ CCB->HostAdapterStatus,
+ CCB->TargetDeviceStatus);
+ BusLogic_Notice("CDB ", HostAdapter);
+ for (i = 0; i < CCB->CDB_Length; i++)
+ BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
+ BusLogic_Notice("\n", HostAdapter);
+ BusLogic_Notice("Sense ", HostAdapter);
+ for (i = 0; i < CCB->SenseDataLength; i++)
+ BusLogic_Notice(" %02X", HostAdapter,
+ Command->sense_buffer[i]);
+ BusLogic_Notice("\n", HostAdapter);
+ }
}
break;
}
BusLogic_TargetStatistics_T *TargetStatistics;
int TargetID, Length;
char *Buffer;
- if (WriteFlag) return 0;
for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
HostAdapter != NULL;
HostAdapter = HostAdapter->Next)
return 0;
}
TargetStatistics = HostAdapter->TargetStatistics;
+ if (WriteFlag)
+ {
+ HostAdapter->ExternalHostAdapterResets = 0;
+ HostAdapter->HostAdapterInternalErrors = 0;
+ memset(TargetStatistics, 0,
+ BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
+ return 0;
+ }
Buffer = HostAdapter->MessageBuffer;
Length = HostAdapter->MessageBufferLength;
Length += sprintf(&Buffer[Length], "\n\
static void BusLogic_ParseDriverOptions(char *);
+/*
+ Declare the Initialization Functions.
+*/
+
+static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *) __init;
+static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T) __init;
+static void
+BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *, int) __init;
+static int
+BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T *) __init;
+static int
+BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T *) __init;
+static boolean BusLogic_Failure(BusLogic_HostAdapter_T *, char *) __init;
+static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *) __init;
+static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *) __init;
+static boolean
+BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init;
+static boolean
+BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init;
+static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *) __init;
+static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T *) __init;
+static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T *,
+ SCSI_Host_T *) __init;
+static void BusLogic_SelectQueueDepths(SCSI_Host_T *, SCSI_Device_T *) __init;
+int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *) __init;
+int BusLogic_ReleaseHostAdapter(SCSI_Host_T *) __init;
+static boolean BusLogic_ParseKeyword(char **, char *) __init;
+static void BusLogic_ParseDriverOptions(char *) __init;
+void BusLogic_Setup(char *, int *) __init;
+
+
#endif /* BusLogic_DriverVersion */
if(RD_HARPOON(ioport + hp_page_ctrl) & BIOS_SHADOW)
{
- pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k Rom */
+ pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k ROM */
}
else
{
- pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k Rom */
+ pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k ROM */
}
pAdapterInfo->ai_stateinfo |= (FAST20_ENA | TAG_QUEUE_ENA);
*
* Function: Sccb_bad_isr
*
- * Description: Some type of interrupt has occured which is slightly
+ * Description: Some type of interrupt has occurred which is slightly
* out of the ordinary. We will now decode it fully, in
* this routine. This is broken up in an attempt to save
* processing time.
*
* Function: sssyncv
*
- * Description: Write the desired value to the Sync Regisiter for the
+ * Description: Write the desired value to the Sync Register for the
* ID specified.
*
*---------------------------------------------------------------------*/
BusLogic MultiMaster and FlashPoint SCSI Driver for Linux
- Version 2.0.12 for Linux 2.0
+ Version 2.0.15 for Linux 2.0
+ Version 2.1.15 for Linux 2.1
PRODUCTION RELEASE
- 29 March 1998
+ 17 August 1998
Leonard N. Zubkoff
Dandelion Digital
lnz@dandelion.com
- Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>
+ Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
INTRODUCTION
Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont, California
94555, USA and can be reached at 510/796-6100 or on the World Wide Web at
-http://www.mylex.com. Mylex Technical Support can be reached by electronic
+http://www.mylex.com. Mylex HBA Technical Support can be reached by electronic
mail at techsup@mylex.com, by Voice at 510/608-2400, or by FAX at 510/745-7715.
Contact information for offices in Europe and Japan is available on the Web
site.
DRIVER INSTALLATION
-This distribution was prepared for Linux kernel version 2.0.33, but should be
+This distribution was prepared for Linux kernel version 2.0.35, but should be
compatible with 2.0.4 or any later 2.0 series kernel.
To install the new BusLogic SCSI driver, you may use the following commands,
replacing "/usr/src" with wherever you keep your Linux kernel source tree:
cd /usr/src
- tar -xvzf BusLogic-2.0.12.tar.gz
+ tar -xvzf BusLogic-2.0.15.tar.gz
mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi
- patch -p < BusLogic.patch
+ patch -p0 < BusLogic.patch (only for 2.0.33 and below)
cd linux
make config
make depend
Please see the file README.BusLogic for information about Linux support for
Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters.
-The Mylex DAC960 PCI RAID Controllers are not supported at the present time,
-but work on a Linux driver for the DAC960 is in progress. Please consult
+The Mylex DAC960 PCI RAID Controllers are now supported. Please consult
http://www.dandelion.com/Linux/ for further information on the DAC960 driver.
/* Expiration-handling functions */
void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *);
-struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *,unsigned long);
+struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *);
/* Operations structures */
autofs_init_usage(dh,ent); /* Relink at queue tail */
}
-struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *dh,
- unsigned long timeout)
+struct autofs_dir_ent *autofs_expire(struct super_block *sb,
+ struct autofs_sb_info *sbi)
{
+ struct autofs_dirhash *dh = &sbi->dirhash;
struct autofs_dir_ent *ent;
+ struct dentry *dentry;
+ unsigned long timeout = sbi->exp_timeout;
ent = dh->expiry_head.exp_next;
- if ( ent == &(dh->expiry_head) ) return NULL;
- return (jiffies - ent->last_usage >= timeout) ? ent : NULL;
+ if ( ent == &(dh->expiry_head) )
+ return NULL; /* No entries */
+
+ while ( jiffies - ent->last_usage >= timeout ) {
+ /* Move to end of list in case expiry isn't desirable */
+ autofs_update_usage(dh, ent);
+
+ /* Check to see that entry is expirable */
+ if ( ent->ino < AUTOFS_FIRST_DIR_INO )
+ return ent; /* Symlinks are always expirable */
+
+ /* Get the dentry for the autofs subdirectory */
+ dentry = lookup_dentry(ent->name, dget(sb->s_root), 0);
+
+ if ( IS_ERR(dentry) ) {
+ printk("autofs: no such dentry on expiry queue: %s\n",
+ ent->name);
+ autofs_delete_usage(ent);
+ continue;
+ }
+
+ if ( !dentry->d_inode ) {
+ dput(dentry);
+ printk("autofs: negative dentry on expiry queue: %s\n",
+ ent->name);
+ autofs_delete_usage(ent);
+ continue;
+ }
+
+ /* Make sure entry is mounted and unused; note that dentry will
+ point to the mounted-on-top root. */
+ if ( !S_ISDIR(dentry->d_inode->i_mode)
+ || dentry->d_covers == dentry ) {
+ dput(dentry);
+ DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
+ continue;
+ }
+
+ /*
+ * Now, this is known to be a mount point; therefore the dentry
+ * will be held by the superblock. is_root_busy() will break if
+ * we hold a use count here, so we have to dput() it before calling
+ * is_root_busy(). However, since it is a mount point (already
+ * verified), dput() will be a nonblocking operation and the use
+ * count will not go to zero; therefore the call to is_root_busy()
+ * here is legal.
+ */
+ dput(dentry);
+
+ if ( !is_root_busy(dentry) ) {
+ DPRINTK(("autofs: signaling expire on %s\n", ent->name));
+ return ent; /* Expirable! */
+ }
+ DPRINTK(("autofs: didn't expire due to is_root_busy: %s\n", ent->name));
+ }
+ return NULL; /* No expirable entries */
}
void autofs_initialize_hash(struct autofs_dirhash *dh) {
return -ENOSPC;
}
- ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL);
+ ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
if ( !ent->name ) {
kfree(sl->data);
kfree(ent);
ent->ino = AUTOFS_FIRST_SYMLINK + n;
ent->hash = dentry->d_name.hash;
- memcpy(ent->name, dentry->d_name.name,ent->len = dentry->d_name.len);
+ memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
autofs_hash_insert(dh,ent);
d_instantiate(dentry, iget(dir->i_sb,ent->ino));
if ( !ent )
return -ENOSPC;
- ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL);
+ ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
if ( !ent->name ) {
kfree(ent);
return -ENOSPC;
}
ent->hash = dentry->d_name.hash;
- memcpy(ent->name, dentry->d_name.name, ent->len = dentry->d_name.len);
+ memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
ent->ino = sbi->next_dir_ino++;
autofs_hash_insert(dh,ent);
dir->i_nlink++;
}
/* Perform an expiry operation */
-static inline int autofs_expire_run(struct autofs_sb_info *sbi,
+static inline int autofs_expire_run(struct super_block *sb,
+ struct autofs_sb_info *sbi,
struct autofs_packet_expire *pkt_p)
{
struct autofs_dir_ent *ent;
struct autofs_packet_expire pkt;
- struct autofs_dirhash *dh = &(sbi->dirhash);
-
+
memset(&pkt,0,sizeof pkt);
pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
pkt.hdr.type = autofs_ptype_expire;
if ( !sbi->exp_timeout ||
- !(ent = autofs_expire(dh,sbi->exp_timeout)) )
+ !(ent = autofs_expire(sb,sbi)) )
return -EAGAIN;
pkt.len = ent->len;
if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
return -EFAULT;
-
- autofs_update_usage(dh,ent);
return 0;
}
case AUTOFS_IOC_SETTIMEOUT:
return autofs_get_set_timeout(sbi,(unsigned long *)arg);
case AUTOFS_IOC_EXPIRE:
- return autofs_expire_run(sbi,(struct autofs_packet_expire *)arg);
+ return autofs_expire_run(inode->i_sb,sbi,
+ (struct autofs_packet_expire *)arg);
default:
return -ENOSYS;
}
struct vm_area_struct *vma;
struct elfhdr elf;
off_t offset = 0, dataoff;
- long limit = current->rlim[RLIMIT_CORE].rlim_cur;
+ unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
int numnote = 4;
struct memelfnote notes[4];
struct elf_prstatus prstatus; /* NT_PRSTATUS */
for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
if (maydump(vma))
{
- int sz = vma->vm_end-vma->vm_start;
+ unsigned long sz = vma->vm_end-vma->vm_start;
if (size+sz >= limit)
break;
this_parent = this_parent->d_parent;
goto resume;
}
- return (count == 1); /* one remaining use count? */
+ return (count > 1); /* remaining users? */
}
/*
int ntfs_fixup_record(ntfs_volume *vol, char *record, char *magic, int size)
{
int start, count, offset;
- short fixup;
+ unsigned short fixup;
if(!IS_MAGIC(record,magic))
return 0;
#include <linux/linkage.h>
-#ifdef __SMP__
-extern void __check_locks(unsigned int);
-#else
-#define __check_locks(x) do { } while (0)
-#endif
-
/*
* SMP- and interrupt-safe semaphores..
*
*/
extern inline void down(struct semaphore * sem)
{
- __check_locks(0);
__asm__ __volatile__(
"# atomic down operation\n\t"
#ifdef __SMP__
{
int result;
- __check_locks(0);
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
#ifdef __SMP__
extern spinlock_t kernel_flag;
-#ifdef __SMP__
-extern void __check_locks(unsigned int);
-#else
-#define __check_locks(x) do { } while (0)
-#endif
-
/*
* Release global kernel lock and global interrupt lock
*/
#define release_kernel_lock(task, cpu) \
do { \
if (task->lock_depth >= 0) \
- __asm__ __volatile__(spin_unlock_string \
- :"=m" (__dummy_lock(&kernel_flag))); \
+ spin_unlock(&kernel_flag); \
release_irqlock(cpu); \
__sti(); \
} while (0)
#define reacquire_kernel_lock(task) \
do { \
if (task->lock_depth >= 0) \
- __asm__ __volatile__(spin_lock_string \
- :"=m" (__dummy_lock(&kernel_flag))); \
+ spin_lock(&kernel_flag); \
} while (0)
*/
extern __inline__ void lock_kernel(void)
{
- __check_locks(1);
__asm__ __volatile__(
"incl %1\n\t"
"jne 9f"
#define spin_lock(lock) \
__asm__ __volatile__( \
spin_lock_string \
-"\n\tcall __getlock" \
:"=m" (__dummy_lock(lock)))
#define spin_unlock(lock) \
__asm__ __volatile__( \
-"call __putlock\n\t" \
spin_unlock_string \
:"=m" (__dummy_lock(lock)))
asm volatile("\n1:\t" \
"lock ; incl %0\n\t" \
"js 2f\n" \
-"call __getlock\n" \
".section .text.lock,\"ax\"\n" \
"2:\tlock ; decl %0\n" \
"3:\tcmpl $0,%0\n\t" \
:"=m" (__dummy_lock(&(rw)->lock)))
#define read_unlock(rw) \
- asm volatile( \
-"call __putlock\n" \
- "lock ; decl %0" \
+ asm volatile("lock ; decl %0" \
:"=m" (__dummy_lock(&(rw)->lock)))
#define write_lock(rw) \
"jc 4f\n" \
"2:\ttestl $0x7fffffff,%0\n\t" \
"jne 3f\n" \
-"call __getlock\n" \
".section .text.lock,\"ax\"\n" \
"3:\tlock ; btrl $31,%0\n" \
"4:\tcmp $0,%0\n\t" \
:"=m" (__dummy_lock(&(rw)->lock)))
#define write_unlock(rw) \
- asm volatile( \
-"call __putlock\n" \
- "lock ; btrl $31,%0": \
- "=m" (__dummy_lock(&(rw)->lock)))
+ asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock)))
#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0)
#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0)
#include <linux/sched.h>
#include <asm/page.h>
-#ifdef __SMP__
-extern void __check_locks(unsigned int);
-#else
-#define __check_locks(x) do { } while (0)
-#endif
-
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/* Careful: we have to cast the result to the type of the pointer for sign reasons */
#define get_user(x,ptr) \
({ int __ret_gu,__val_gu; \
- __check_locks(1); \
switch(sizeof (*(ptr))) { \
case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \
#define put_user(x,ptr) \
({ int __ret_pu; \
- __check_locks(1); \
switch(sizeof (*(ptr))) { \
case 1: __put_user_x(1,__ret_pu,(__typeof__(*(ptr)))(x),ptr); break; \
case 2: __put_user_x(2,__ret_pu,(__typeof__(*(ptr)))(x),ptr); break; \
#define __put_user_nocheck(x,ptr,size) \
({ \
long __pu_err; \
- __check_locks(1); \
__put_user_size((x),(ptr),(size),__pu_err); \
__pu_err; \
})
#define __get_user_nocheck(x,ptr,size) \
({ \
long __gu_err, __gu_val; \
- __check_locks(1); \
__get_user_size(__gu_val,(ptr),(size),__gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
static inline unsigned long
__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
__copy_user(to,from,n);
return n;
}
static inline unsigned long
__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
__copy_user(to,from,n);
return n;
}
static inline unsigned long
__constant_copy_to_user(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
if (access_ok(VERIFY_WRITE, to, n))
__constant_copy_user(to,from,n);
return n;
static inline unsigned long
__constant_copy_from_user(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
if (access_ok(VERIFY_READ, from, n))
__constant_copy_user(to,from,n);
return n;
static inline unsigned long
__constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
__constant_copy_user(to,from,n);
return n;
}
static inline unsigned long
__constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
{
- __check_locks(1);
__constant_copy_user(to,from,n);
return n;
}
* Decide if we should try to do some swapout..
*/
extern int free_memory_available(void);
+extern struct wait_queue * kswapd_wait;
#define free_page(addr) free_pages((addr),0)
extern void FASTCALL(free_pages(unsigned long addr, unsigned long order));
* GFP bitmasks..
*/
#define __GFP_WAIT 0x01
-#define __GFP_IO 0x02
-#define __GFP_LOW 0x00
+#define __GFP_LOW 0x02
#define __GFP_MED 0x04
#define __GFP_HIGH 0x08
#define GFP_BUFFER (__GFP_LOW | __GFP_WAIT)
#define GFP_ATOMIC (__GFP_HIGH)
-#define GFP_USER (__GFP_LOW | __GFP_WAIT | __GFP_IO)
-#define GFP_KERNEL (__GFP_MED | __GFP_WAIT | __GFP_IO)
-#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
+#define GFP_USER (__GFP_LOW | __GFP_WAIT)
+#define GFP_KERNEL (__GFP_MED | __GFP_WAIT)
+#define GFP_NFS (__GFP_HIGH | __GFP_WAIT)
/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
platforms, used as appropriate on others */
#ifndef LINUX_NBD_H
#define LINUX_NBD_H
-#include <linux/ioctl.h>
-#include <asm/types.h>
-
-#define NBD_SET_SOCK _IO( 0xab, 0 )
-#define NBD_SET_BLKSIZE _IO( 0xab, 1 )
-#define NBD_SET_SIZE _IO( 0xab, 2 )
-#define NBD_DO_IT _IO( 0xab, 3 )
-#define NBD_CLEAR_SOCK _IO( 0xab, 4 )
-#define NBD_CLEAR_QUE _IO( 0xab, 5 )
-#define NBD_PRINT_DEBUG _IO( 0xab, 6 )
+#define NBD_SET_SOCK _IO( 0xab, 0 )
+#define NBD_SET_BLKSIZE _IO( 0xab, 1 )
+#define NBD_SET_SIZE _IO( 0xab, 2 )
+#define NBD_DO_IT _IO( 0xab, 3 )
+#define NBD_CLEAR_SOCK _IO( 0xab, 4 )
+#define NBD_CLEAR_QUE _IO( 0xab, 5 )
+#define NBD_PRINT_DEBUG _IO( 0xab, 6 )
#ifdef MAJOR_NR
/* This now IS in some kind of include file... */
-#define NBD_REQUEST_MAGIC 0x12560953
-#define NBD_REPLY_MAGIC 0x96744668
-#define LO_MAGIC 0x68797548
+/* These are send over network in request/reply magic field */
+
+#define NBD_REQUEST_MAGIC 0x25609513
+#define NBD_REPLY_MAGIC 0x67446698
+/* Do *not* use magics: 0x12560953 0x96744668. */
struct nbd_request {
- __u32 magic;
- __u32 from;
- __u32 len;
+ u32 magic;
+ u32 type; /* == READ || == WRITE */
char handle[8];
- __u32 type; /* == READ || == WRITE */
+ u64 from;
+ u32 len;
};
struct nbd_reply {
- __u32 magic;
+ u32 magic;
+ u32 error; /* 0 = ok, else error */
char handle[8]; /* handle you got from request */
- __u32 error; /* 0 = ok, else error */
};
#endif
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
#define PF_SIGNALED 0x00000400 /* killed by a signal */
+#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
#define PF_DTRACE 0x00200000 /* delayed trace (used on m68k) */
if (target != current)
read_unlock(&tasklist_lock);
- spin_unlock(&task_capacibility_lock);
+ spin_unlock(&task_capability_lock);
if (!error) {
if (copy_to_user(dataptr, &data, sizeof data))
#define UIDHASH_SZ (PIDHASH_SZ >> 2)
static struct user_struct {
+ atomic_t count;
struct user_struct *next, **pprev;
unsigned int uid;
- int task_count;
} *uidhash[UIDHASH_SZ];
spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
if (up) {
p->user = NULL;
- lock_kernel();
- if (!--up->task_count) {
+ if (atomic_dec_and_test(&up->count)) {
uid_hash_remove(up);
kmem_cache_free(uid_cachep, up);
}
- unlock_kernel();
}
}
return -EAGAIN;
p->user = up;
up->uid = p->uid;
- up->task_count = 0;
+ atomic_set(&up->count, 0);
uid_hash_insert(up, hashent);
}
- up->task_count++;
+ atomic_inc(&up->count);
return 0;
}
lock_kernel();
if (p->user) {
- if (p->user->task_count >= p->rlim[RLIMIT_NPROC].rlim_cur)
+ if (atomic_read(&p->user->count) >= p->rlim[RLIMIT_NPROC].rlim_cur)
goto bad_fork_free;
}
nr_tasks++;
if (p->user)
- p->user->task_count++;
+ atomic_inc(&p->user->count);
retval = -ENOMEM;
/* copy all the process information */
}
if (p->user)
- p->user->task_count++;
+ atomic_dec(&p->user->count);
nr_tasks--;
add_free_taskslot(p->tarray_ptr);
bad_fork_free:
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/smp_lock.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
modprobe_path is set via /proc/sys.
*/
char modprobe_path[256] = "/sbin/modprobe";
-static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
/*
exec_modprobe is spawned from a kernel-mode user process,
/* don't use the user's root, use init's root instead */
exit_fs(current); /* current->fs->count--; */
current->fs = task_init->fs;
- current->fs->count++;
+ atomic_inc(¤t->fs->count);
unlock_kernel();
}
static int exec_modprobe(void * module_name)
{
- char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL};
+ static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+ char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
int i;
use_init_file_context();
{
int pid;
int waitpid_result;
+ sigset_t tmpsig;
/* Don't allow request_module() before the root fs is mounted! */
if ( ! current->fs->root ) {
pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
if (pid < 0) {
- printk(KERN_ERR "kmod: fork failed, errno %d\n", -pid);
+ printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
return pid;
}
+
+ /* Block everything but SIGKILL/SIGSTOP */
+ spin_lock_irq(¤t->sigmask_lock);
+ tmpsig = current->blocked;
+ siginitset(¤t->blocked, ~(sigmask(SIGKILL)|sigmask(SIGSTOP)));
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
waitpid_result = waitpid(pid, NULL, __WCLONE);
+
+ /* Allow signals again.. */
+ spin_lock_irq(¤t->sigmask_lock);
+ current->blocked = tmpsig;
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
if (waitpid_result != pid) {
printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
pid, waitpid_result);
goto scheduling_in_interrupt;
release_kernel_lock(prev, this_cpu);
- __check_locks(1);
-
/* Do "administrative" work here while we don't hold any locks */
if (bh_active & bh_mask)
do_bottom_half();
break;
}
age_page(page);
+#if 0
if (page->age)
break;
if (page_cache_size * 100 < (page_cache.min_percent * num_physpages))
break;
+#endif
if (PageSwapCache(page)) {
delete_from_swap_cache(page);
return 1;
break;
/* is it a buffer cache page? */
- if ((gfp_mask & __GFP_IO) && bh && try_to_free_buffer(bh, &bh, 6))
+ if (bh && try_to_free_buffer(bh, &bh, 6))
return 1;
break;
struct page * page;
int count_max, count_min;
- count_max = (limit<<2) >> (priority>>1);
- count_min = (limit<<2) >> (priority);
+ count_max = (limit<<1) >> (priority>>1);
+ count_min = (limit<<1) >> (priority);
page = mem_map + clock;
do {
*/
page = mem_map + MAP_NR(page_cache);
add_to_page_cache(page, inode, offset, hash);
+ set_bit(PG_referenced, &page->flags);
inode->i_op->readpage(file, page);
page_cache = 0;
}
goto nopage;
if (gfp_mask & __GFP_WAIT) {
- __check_locks(1);
if (in_interrupt()) {
static int count = 0;
if (++count < 5) {
spin_lock_irqsave(&page_alloc_lock, flags);
RMQUEUE(order, (gfp_mask & GFP_DMA));
spin_unlock_irqrestore(&page_alloc_lock, flags);
+
+ /*
+ * If we failed to find anything, we'll return NULL, but we'll
+ * wake up kswapd _now_ ad even wait for it synchronously if
+ * we can.. This way we'll at least make some forward progress
+ * over time.
+ */
+ wake_up(&kswapd_wait);
+ if (gfp_mask & __GFP_WAIT)
+ schedule();
nopage:
return 0;
}
/*
* The wait queue for waking up the pageout daemon:
*/
-static struct wait_queue * kswapd_wait = NULL;
+struct wait_queue * kswapd_wait = NULL;
static void init_swap_timer(void);
return 1;
state = 1;
case 1:
- if ((gfp_mask & __GFP_IO) && shm_swap(i, gfp_mask))
+ if (shm_swap(i, gfp_mask))
return 1;
state = 2;
case 2:
/* Give kswapd a realtime priority. */
current->policy = SCHED_FIFO;
- current->priority = 32; /* Fixme --- we need to standardise our
+ current->rt_priority = 32; /* Fixme --- we need to standardise our
namings for POSIX.4 realtime scheduling
priorities. */
*/
tries = pager_daemon.tries_base;
tries >>= 4*free_memory_available();
-
- while (tries--) {
- int gfp_mask;
- if (free_memory_available() > 1)
- break;
- gfp_mask = __GFP_IO;
- do_try_to_free_page(gfp_mask);
+ do {
+ do_try_to_free_page(0);
/*
* Syncing large chunks is faster than swapping
* synchronously (less head movement). -- Rik.
*/
if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
run_task_queue(&tq_disk);
-
- }
+ if (free_memory_available() > 1)
+ break;
+ } while (--tries > 0);
}
/* As if we could ever get here - maybe we want to make this killable */
remove_wait_queue(&kswapd_wait, &wait);
}
/*
- * This is REALLY ugly.
- *
* We need to make the locks finer granularity, but right
* now we need this so that we can do page allocations
* without holding the kernel lock etc.
+ *
+ * The "PF_MEMALLOC" flag protects us against recursion:
+ * if we need more memory as part of a swap-out effort we
+ * will just silently return "success" to tell the page
+ * allocator to accept the allocation.
*/
int try_to_free_pages(unsigned int gfp_mask, int count)
{
- int retval;
+ int retval = 1;
lock_kernel();
- do {
- retval = do_try_to_free_page(gfp_mask);
- if (!retval)
- break;
- count--;
- } while (count > 0);
+ if (current->flags & PF_MEMALLOC) {
+ current->flags |= PF_MEMALLOC;
+ do {
+ retval = do_try_to_free_page(gfp_mask);
+ if (!retval)
+ break;
+ count--;
+ } while (count > 0);
+ current->flags &= PF_MEMALLOC;
+ }
unlock_kernel();
return retval;
}
atomic_add(skb->truesize, &sk->wmem_alloc);
skb->destructor = sock_wfree;
skb->sk = sk;
+ return skb;
}
- return skb;
}
return NULL;
}
atomic_add(skb->truesize, &sk->rmem_alloc);
skb->destructor = sock_rfree;
skb->sk = sk;
+ return skb;
}
- return skb;
}
return NULL;
}
skb->pkt_type = qp->fragments->skb->pkt_type;
skb->protocol = qp->fragments->skb->protocol;
+ /*
+ * Clearly bogus, because security markings of the individual
+ * fragments should have been checked for consistency before
+ * gluing, and intermediate coalescing of fragments may have
+ * taken place in ip_defrag() before ip_glue() ever got called.
+ * If we're not going to do the consistency checking, we might
+ * as well take the value associated with the first fragment.
+ * --rct
+ */
+ skb->security = qp->fragments->skb->security;
/* Done with all fragments. Fixup the new IP header. */
iph = skb->nh.iph;
* Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0
* Apr 20, 1998 Alan Cox Fixed 2.1 symbols
* May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate
+* Aug 15, 1998 Arnaldo C. Melo Fixed device_setup return value
*****************************************************************************/
#include <linux/stddef.h> /* offsetof(), etc. */
if(!copy_from_user(data, conf->data, conf->data_size))
{
conf->data=data;
- wandev->setup(wandev,conf);
+ err = wandev->setup(wandev,conf);
}
else
err = -ENOBUFS;