@@ -42,7+42,7 @@ foo \kill}% %
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$Peter.Anvin@linux.org$>$}
-\date{Last revised: September 6, 1995}
+\date{Last revised: September 20, 1995}
\maketitle
%
\noindent
@@ -138,8+138,10 @@ an unreasonable effort. \major{ }{}{block}{Third IDE hard disk/CD-ROM interface}
\major{34}{}{char }{Z8530 HDLC driver}
\major{ }{}{block}{Fourth IDE hard disk/CD-ROM interface}
-\major{35}{}{block}{Modular RAM disk}
-\major{36--223}{}{}{Unallocated}
+\major{35}{}{char }{tclmidi MIDI driver}
+\major{ }{}{block}{Modular RAM disk}
+\major{36}{}{block}{MCA ESDI hard disk}
+\major{37--223}{}{}{Unallocated}
\major{224--254}{}{}{Local use}
\major{255}{}{}{Reserved}
\end{devicelist}
@@ -318,9+320,9 @@ NOTE: These devices permit both read and write access. \end{devicelist}
\noindent
-Partitions are handled in the same way as for IDE
-disks (see major number 3) except that the limit on
-logical partitions is 11 rather than 59 per disk.
+Partitions are handled in the same way as for IDE disks (see major
+number 3) except that the limit on logical partitions is 11 rather
+than 59 per disk.
\begin{devicelist}
\major{ 9}{}{char }{SCSI tape devices}
@@ -401,8+403,8 @@ names for these devices, please let me know. \end{devicelist}
\noindent
-Partitions are handled in the same way as IDE disks
-(see major number 3).
+Partitions are handled in the same way as for IDE disks (see major
+number 3).
\begin{devicelist}
\major{14}{}{char }{Sound card}
@@ -430,8+432,8 @@ Partitions are handled in the same way as IDE disks \end{devicelist}
\noindent
-Partitions are handled in the same way as IDE disks
-(see major number 3).
+Partitions are handled in the same way as for IDE disks (see major
+number 3).
\begin{devicelist}
\major{15}{}{char }{Joystick}
@@ -517,8+519,8 @@ See the Double documentation for an explanation of the ``mirror'' devices. \end{devicelist}
\noindent
-Partitions are handled the same way as for the first
-interface (see major number 3).
+Partitions are handled the same way as for the first interface (see
+major number 3).
\begin{devicelist}
\major{23}{}{char }{Digiboard serial card -- alternate devices}
@@ -621,9+623,9 @@ interface (see major number 3). \end{devicelist}
\noindent
-Partitions are handled in the same way as for IDE
-disks (see major number 3) except that the limit on
-logical partitions is 11 rather than 59 per disk.
+Partitions are handled in the same way as for IDE disks (see major
+number 3) except that the limit on logical partitions is 11 rather
+than 59 per disk.
\begin{devicelist}
\major{29}{}{char }{Universal frame buffer}
@@ -702,6+704,7 @@ support reading only. \minor{0}{/dev/ttyX0}{First Specialix port}
\minor{1}{/dev/ttyX1}{Second Specialix port}
\minordots
+\\
\major{ }{}{block}{Philips LMS CM-206 CD-ROM}
\minor{0}{/dev/cm206cd}{Philips LMS CM-206 CD-ROM}
\end{devicelist}
@@ -711,6+714,7 @@ support reading only. \minor{0}{/dev/cux0}{Callout device corresponding to {\file ttyX0}}
\minor{1}{/dev/cux1}{Callout device corresponding to {\file ttyX1}}
\minordots
+\\
\major{ }{}{block}{Third IDE hard disk/CD-ROM interface}
\minor{0}{/dev/hde}{Master: whole disk (or CD-ROM)}
\minor{64}{/dev/hdf}{Slave: whole disk (or CD-ROM)}
@@ -727,6+731,13 @@ major number 3). \minor{2}{/dev/sc3}{Second Z8530, first port}
\minor{3}{/dev/sc4}{Second Z8530, second port}
\minordots
+\end{devicelist}
+
+\noindent
+The author has indicated that the device names will change in a
+subsequent version; {\file /dev/sc1} will become {\file /dev/scc0} etc.
+
+\begin{devicelist}
\major{ }{}{block}{Fourth IDE hard disk/CD-ROM interface}
\minor{0}{/dev/hdg}{Master: whole disk (or CD-ROM)}
\minor{64}{/dev/hdh}{Slave: whole disk (or CD-ROM)}
@@ -737,7+748,21 @@ Partitions are handled the same way as for the first interface (see major number 3).
\begin{devicelist}
-\major{35}{}{block}{Modular RAM disk}
+\major{35}{}{char }{tclmidi MIDI driver}
+ \minor{0}{/dev/midi0}{First MIDI port, kernel timed}
+ \minor{1}{/dev/midi1}{Second MIDI port, kernel timed}
+ \minor{2}{/dev/midi2}{Third MIDI port, kernel timed}
+ \minor{3}{/dev/midi3}{Fourth MIDI port, kernel timed}
+ \minor{64}{/dev/rmidi0}{First MIDI port, untimed}
+ \minor{65}{/dev/rmidi1}{Second MIDI port, untimed}
+ \minor{66}{/dev/rmidi2}{Third MIDI port, untimed}
+ \minor{67}{/dev/rmidi3}{Fourth MIDI port, untimed}
+ \minor{128}{/dev/smpte0}{First MIDI port, SMPTE timed}
+ \minor{129}{/dev/smpte1}{Second MIDI port, SMPTE timed}
+ \minor{130}{/dev/smpte2}{Third MIDI port, SMPTE timed}
+ \minor{131}{/dev/smpte3}{Fourth MIDI port, SMPTE timed}
+\\
+\major{ }{}{block}{Modular RAM disk}
\minor{0}{/dev/ram0}{First modular RAM disk}
\minor{1}{/dev/ram1}{Second modular RAM disk}
\minordots
@@ -745,7+770,18 @@ major number 3). \end{devicelist}
\begin{devicelist}
-\major{36}{--223}{}{Unallocated}
+\major{36}{}{block}{MCA ESDI hard disk}
+ \minor{0}{/dev/eda}{First ESDI disk whole disk}
+ \minor{64}{/dev/edb}{Second ESDI disk whole disk}
+ \minordots
+\end{devicelist}
+
+\noindent
+Partitions are handled the same way as for IDE disks (see major number
+3).
+
+\begin{devicelist}
+\major{37}{--223}{}{Unallocated}
\end{devicelist}
\begin{devicelist}
Maintained by H. Peter Anvin <Peter.Anvin@linux.org>
- Last revised: September 6, 1995
+ Last revised: September 20, 1995
This list is the successor to Rick Miller's Linux Device List, which
he stopped maintaining when he lost network access in 1993. It is a
@@ -503,13+503,34 @@ an unreasonable effort. Partitions are handled the same way as for the first
interface (see major number 3).
- 35 block Modular RAM disk device
+ 35 char tclmidi MIDI driver
+ 0 = /dev/midi0 First MIDI port, kernel timed
+ 1 = /dev/midi1 Second MIDI port, kernel timed
+ 2 = /dev/midi2 Third MIDI port, kernel timed
+ 3 = /dev/midi3 Fourth MIDI port, kernel timed
+ 64 = /dev/rmidi0 First MIDI port, untimed
+ 65 = /dev/rmidi1 Second MIDI port, untimed
+ 66 = /dev/rmidi2 Third MIDI port, untimed
+ 67 = /dev/rmidi3 Fourth MIDI port, untimed
+ 128 = /dev/smpte0 First MIDI port, SMPTE timed
+ 129 = /dev/smpte1 Second MIDI port, SMPTE timed
+ 130 = /dev/smpte2 Third MIDI port, SMPTE timed
+ 131 = /dev/smpte3 Fourth MIDI port, SMPTE timed
+ block Modular RAM disk device
0 = /dev/ram0 First modular RAM disk
1 = /dev/ram1 Second modular RAM disk
...
255 = /dev/ram255 256th modular RAM disk
- 36-223 UNALLOCATED
+ 36 block MCA ESDI hard disk
+ 0 = /dev/eda First ESDI disk whole disk
+ 64 = /dev/edb Second ESDI disk whole disk
+ ...
+
+ Partitions are handled in the same way as IDE disks
+ (see major number 3).
+
+ 37-223 UNALLOCATED
224-254 LOCAL USE
Allocated for local/experimental use
@@ -34,7+34,9 @@ The set of modules is rapidly increasing, but so far these are known: Most filesystems: minix, xiafs, msdos, umsdos, sysv, isofs, hpfs,
smbfs, nfs
- Some SCSI drivers: aha1542, in2000
+ Mid-level SCSI support (required by top and low level scsi drivers).
+ Most low-level SCSI drivers: (i.e. aha1542, in2000)
+ All SCSI high-level drivers: disk, tape, cdrom, generic.
Some ethernet drivers:
plip, slip, dummy,
--- /dev/null
+
+ The scsi support in the linux kernel can be modularized in a
+number of different ways depending upon the needs of the end user. To
+understand your options, we should first define a few terms.
+
+ The scsi-core contains the core of scsi support. Without it
+you can do nothing with any of the other scsi drivers. The scsi core
+support can be a module (scsi_mod.o), or it can be build into the kernel.
+If the core is a module, it must be the first scsi module loaded, and
+if you unload the modules, it will have to be the last one unloaded.
+
+ The individual upper and lower level drivers can be loaded in any
+order once the scsi core is present in the kernel (either compiled in
+or loaded as a module). The disk driver (sd_mod.o), cdrom driver (sr_mod.o),
+tape driver (st.o) and scsi generics driver (sg.o) represent the upper level
+drivers to support the various assorted devices which can be controlled.
+You can for example load the tape driver to use the tape drive, and then
+unload it once you have no further need for the driver (and release the
+associated memory).
+
+ The lower level drivers are the ones that support the
+individual cards that are supported for the hardware platform that you
+are running under. Examples are aha1542.o to drive Adaptec 1542
+cards. Rather than list the drivers which *can* be modularized, it is
+easier to list the ones which cannot, since the list only contains a
+few entries. The drivers which have NOT been modularized are:
+
+ NCR5380 boards of one kind or another including PAS16,
+ Trantor T128/128F/228,
+
VERSION = 1
PATCHLEVEL = 3
-SUBLEVEL = 28
+SUBLEVEL = 29
ARCH = i386
@@ -92,12+92,13 @@ ifdef MOD_SUB_DIRS set -e; for i in $(MOD_SUB_DIRS); do $(MAKE) -C $$i modules; done
endif
ifneq "$(strip $(MOD_LIST_NAME))" ""
-ifndef M_OBJS # Hack for fs subdirectories
rm -f $$TOPDIR/modules/$(MOD_LIST_NAME)
+ifdef MOD_SUB_DIRS
for i in $(MOD_SUB_DIRS); do \
echo `basename $$i`.o >> $$TOPDIR/modules/$(MOD_LIST_NAME); done
-else
- echo $(M_OBJS) > $$TOPDIR/modules/$(MOD_LIST_NAME)
+endif
+ifdef M_OBJS
+ echo $(M_OBJS) >> $$TOPDIR/modules/$(MOD_LIST_NAME)
endif
endif
ifdef M_OBJS
NM := nm -B
# enable this for linking under OSF/1:
-LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
+#LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
# enable this for linking under Linux:
-#LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
+LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
CFLAGS := $(CFLAGS) -mno-fp-regs
#
# enable this for linking under OSF/1:
-LINKFLAGS = -non_shared -T 0x20000000 -N
+#LINKFLAGS = -non_shared -T 0x20000000 -N
# enable this for linking under Linux:
-#LINKFLAGS = -static -T bootloader.lds -N
+LINKFLAGS = -static -T bootloader.lds -N
.S.s:
$(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
@@ -32,9+32,9 @@ vmlinux.gz: vmlinux gzip -fv vmlinux
vmlinux: tools/build $(TOPDIR)/vmlinux
- tools/build -v $(TOPDIR)/vmlinux > vmlinux
-# cp $(TOPDIR)/vmlinux vmlinux
-# quickstrip vmlinux
+# tools/build -v $(TOPDIR)/vmlinux > vmlinux
+ cp $(TOPDIR)/vmlinux vmlinux
+ quickstrip vmlinux
tools/lxboot: tools/build
tools/build > tools/lxboot
comment 'General setup'
tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
-bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 n
+bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y
if [ "$CONFIG_ST506" = "y" ]; then
comment 'Please see drivers/block/README.ide for help/info on IDE drives'
bool ' Use old disk-only driver for primary i/f' CONFIG_BLK_DEV_HD n
@@ -29,7+29,7 @@ choice 'Alpha system type' \ EB66 CONFIG_ALPHA_EB66 \
EB66+ CONFIG_ALPHA_EB66P \
EB64 CONFIG_ALPHA_EB64 \
- EB64+ CONFIG_ALPHA_EB64P" Jensen
+ EB64+ CONFIG_ALPHA_EB64P" Cabriolet
if [ "$CONFIG_ALPHA_NONAME" = "y" ]; then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_LCA y
@@ -110,7+110,7 @@ comment 'SCSI low-level drivers'
dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n $CONFIG_SCSI
dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y $CONFIG_SCSI
+dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n $CONFIG_SCSI
dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI
dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI
dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI
@@ -119,7+119,7 @@ dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n $CONFIG_SCSI dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
if [ "$CONFIG_PCI" = "y" ]; then
- dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n $CONFIG_SCSI
+ dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx y $CONFIG_SCSI
fi
dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI
bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
@@ -176,7+176,7 @@ if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then fi
tristate '3c509/3c579 support' CONFIG_EL3 y
fi
-bool 'Other ISA cards' CONFIG_NET_ISA y
+bool 'Other ISA cards' CONFIG_NET_ISA n
if [ "$CONFIG_NET_ISA" = "y" ]; then
tristate 'Cabletron E21xx support' CONFIG_E2100 n
tristate 'DEPCA support' CONFIG_DEPCA y
@@ -199,17+199,17 @@ if [ "$CONFIG_NET_ISA" = "y" ]; then tristate 'NE2000/NE1000 support' CONFIG_NE2000 n
bool 'SK_G16 support' CONFIG_SK_G16 n
fi
-bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
+bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA y
if [ "$CONFIG_NET_EISA" = "y" ]; then
if [ "$CONFIG_NET_ALPHA" = "y" ]; then
tristate 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
fi
tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
- tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 n
+ tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 y
# tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP n
# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
- bool 'Zenith Z-Note support' CONFIG_ZNET y
+ bool 'Zenith Z-Note support' CONFIG_ZNET n
fi
bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
if [ "$CONFIG_NET_POCKET" = "y" ]; then
@@ -42,9+42,7 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err) for (i = -3; i < 6; i++)
printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');
printk("\n");
- for (i = 0 ; i < 5000000000 ; i++)
- /* pause */;
- halt();
+ do_exit(SIGSEGV);
}
asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
@@ -68,12+68,12 @@ void show_mem(void) i = MAP_NR(high_memory);
while (i-- > 0) {
total++;
- if (mem_map[i] & MAP_PAGE_RESERVED)
+ if (mem_map[i].reserved)
reserved++;
- else if (!mem_map[i])
+ else if (!mem_map[i].count)
free++;
else
- shared += mem_map[i]-1;
+ shared += mem_map[i].count-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
@@ -127,7+127,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) continue;
while (nr--)
- mem_map[pfn++] = 0;
+ mem_map[pfn++].reserved = 0;
}
/* unmap the console stuff: we don't need it, and we don't want it */
@@ -158,7+158,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) */
tmp = KERNEL_START;
while (tmp < start_mem) {
- mem_map[MAP_NR(tmp)] = MAP_PAGE_RESERVED;
+ mem_map[MAP_NR(tmp)].reserved = 1;
tmp += PAGE_SIZE;
}
@@ -171,9+171,9 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) #endif
for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
- if (mem_map[MAP_NR(tmp)])
+ if (mem_map[MAP_NR(tmp)].reserved)
continue;
- mem_map[MAP_NR(tmp)] = 1;
+ mem_map[MAP_NR(tmp)].count = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
@@ -191,12+191,12 @@ void si_meminfo(struct sysinfo *val) val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
- if (mem_map[i] & MAP_PAGE_RESERVED)
+ if (mem_map[i].reserved)
continue;
val->totalram++;
- if (!mem_map[i])
+ if (!mem_map[i].count)
continue;
- val->sharedram += mem_map[i]-1;
+ val->sharedram += mem_map[i].count-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
bool 'System V IPC' CONFIG_SYSVIPC y
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
-bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF n
+bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF y
fi
#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 n
#if [ "$CONFIG_M586" = "n" ]; then
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/delay.h>
+#include <linux/config.h>
#include <asm/segment.h>
#include <asm/system.h>
@@ -73,12+73,12 @@ void show_mem(void) i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
- if (mem_map[i] & MAP_PAGE_RESERVED)
+ if (mem_map[i].reserved)
reserved++;
- else if (!mem_map[i])
+ else if (!mem_map[i].count)
free++;
else
- shared += mem_map[i]-1;
+ shared += mem_map[i].count-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
@@ -192,12+192,12 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) * controller as well..
*/
while (start_low_mem < 0x9f000) {
- mem_map[MAP_NR(start_low_mem)] = 0;
+ mem_map[MAP_NR(start_low_mem)].reserved = 0;
start_low_mem += PAGE_SIZE;
}
while (start_mem < high_memory) {
- mem_map[MAP_NR(start_mem)] = 0;
+ mem_map[MAP_NR(start_mem)].reserved = 0;
start_mem += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
@@ -207,7+207,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) sound_mem_init();
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
- if (mem_map[MAP_NR(tmp)]) {
+ if (mem_map[MAP_NR(tmp)].reserved) {
if (tmp >= 0xA0000 && tmp < 0x100000)
reservedpages++;
else if (tmp < (unsigned long) &_etext)
@@ -216,7+216,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) datapages++;
continue;
}
- mem_map[MAP_NR(tmp)] = 1;
+ mem_map[MAP_NR(tmp)].count = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
@@ -249,12+249,12 @@ void si_meminfo(struct sysinfo *val) val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
- if (mem_map[i] & MAP_PAGE_RESERVED)
+ if (mem_map[i].reserved)
continue;
val->totalram++;
- if (!mem_map[i])
+ if (!mem_map[i].count)
continue;
- val->sharedram += mem_map[i]-1;
+ val->sharedram += mem_map[i].count-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
@@ -79,11+79,12 @@ static void extended_partition(struct gendisk *hd, kdev_t dev) {
struct buffer_head *bh;
struct partition *p;
- unsigned long first_sector, this_sector, this_size;
+ unsigned long first_sector, first_size, this_sector, this_size;
int mask = (1 << hd->minor_shift) - 1;
int i;
first_sector = hd->part[MINOR(dev)].start_sect;
+ first_size = hd->part[MINOR(dev)].nr_sects;
this_sector = first_sector;
while (1) {
@@ -122,7+123,13 @@ static void extended_partition(struct gendisk *hd, kdev_t dev) if (!p->nr_sects || p->sys_ind == EXTENDED_PARTITION)
continue;
- if (p->start_sect + p->nr_sects > this_size)
+ /* Check the 3rd and 4th entries -
+ these sometimes contain random garbage */
+ if (i >= 2
+ && p->start_sect + p->nr_sects > this_size
+ && (this_sector + p->start_sect < first_sector ||
+ this_sector + p->start_sect + p->nr_sects >
+ first_sector + first_size))
continue;
add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
@@ -1163,15+1163,14 @@ slip_init_ctrl_dev(struct device *dummy) }
- /* If not loadable module, a bootstrap Space.c slip_proto dev
- * now needs to be unregistered.
+#ifdef MODULE
+ return status;
+#else
+ /* Return "not found", so that dev_init() will unlink
+ * the placeholder device entry for us.
*/
-#ifndef MODULE
-/* printk("SLIP: Unregistering bootstrap device "
- "'slip_proto' - slip OK\n");*/
- unregister_netdev(dummy);
+ return ENODEV;
#endif
- return status;
}
@@ -83,6+83,8 @@ struct pci_dev_info dev_info[] = { DEVICE( SI, SI_501, "85C501"),
DEVICE( SI, SI_496, "85C496"),
DEVICE( SI, SI_601, "85C601"),
+ DEVICE( SI, SI_5511, "85C5511"),
+ DEVICE( SI, SI_5513, "85C5513"),
DEVICE( HP, HP_J2585A, "J2585A"),
#if 0
DEVICE( SMC, SMC_37C665, "FDC 37C665"), /* 1042 ? */
@@ -110,6+112,7 @@ struct pci_dev_info dev_info[] = { DEVICE( LEADTEK, LEADTEK_805, "S3 805"),
DEVICE( CONTAQ, CONTAQ_82C599, "82C599"),
DEVICE( CMD, CMD_640, "640 (buggy)"),
+ DEVICE( CMD, CMD_646, "646"),
DEVICE( VISION, VISION_QD8500, "QD-8500"),
DEVICE( VISION, VISION_QD8580, "QD-8580"),
DEVICE( WINBOND, WINBOND_83769, "W83769F"),
@@ -123,6+126,7 @@ struct pci_dev_info dev_info[] = { DEVICE( AL, AL_M1461, "M1461"),
DEVICE( AL, AL_M4803, "M4803"),
DEVICE( IMS, IMS_8849, "8849"),
+ DEVICE( REALTEK, REALTEK_8300, "ENW-8300C"),
DEVICE( VIA, VIA_82C505, "VT 82C505"),
DEVICE( VIA, VIA_82C561, "VT 82C561"),
DEVICE( VIA, VIA_82C576, "VT 82C576 3V"),
@@ -994,6+994,8 @@ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) { unsigned char pci_bus, pci_device_fn;
static short pci_index=0; /* Device index to PCI BIOS calls */
+ tpnt->proc_dir = &proc_scsi_ncr53c7xx;
+
for (current_override = count = 0; current_override < OVERRIDE_LIMIT;
++current_override) {
if (overrides[current_override].pci ?
@@ -1120,7+1122,6 @@ NCR53c8x0_init_fixup (struct Scsi_Host *host) { * SCRIPTS.
*/
- tpnt->proc_dir = &proc_scsi_ncr53c7xx;
patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
# Create this before we build anything else.
SCSI_MODULE_VER := scsi_syms.ver
SYMTAB_OBJS := scsi_syms.o
- include ../../versions.mk
endif
M_OBJS += scsi_mod.o
endif
include $(TOPDIR)/Rules.make
+ifeq ($(CONFIG_SCSI),m)
+ ifdef CONFIG_MODVERSIONS
+ include ../../versions.mk
+ endif
+endif
+
aha152x.o: aha152x.c
$(CC) $(CFLAGS) $(AHA152X) -c aha152x.c
* Thanks also to Greg Hosler who did a lot of testing and *
* found quite a number of bugs during the development. *
************************************************************
- * last change: 95/07/18 OS: Linux 1.3.10 *
+ * last change: 95/09/17 OS: Linux 1.3.28 *
************************************************************/
/* Look in eata_dma.h for configuration and revision information */
@@ -504,10+504,11 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) cmd->host_scribble = (char *)&hd->ccb[y];
if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
- cmd->result = DID_ERROR << 16;
- printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR,"
- " done.\n", cmd->target, cmd->pid);
+ cmd->result = DID_BUS_BUSY << 16;
+ printk("eata_queue target %d, pid %ld, HBA busy, returning DID_BUS_BUSY\n",
+ cmd->target, cmd->pid);
done(cmd);
+ cp->status = FREE; /* Hmmm..... */
restore_flags(flags);
return(0);
}
@@ -857,7+858,6 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, "Please use the EATA-PIO driver.\n", base);
return (FALSE);
}
-
if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22)
gc->MAX_CHAN = 0;
@@ -1124,8+1124,8 @@ void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt) (int)pal1, (int)pal2, (int)pal3));
#endif
if (get_conf_PIO(base, buf) == TRUE) {
- DBG(DBG_PROBE && DBG_EISA, print_config(buf));
if (buf->IRQ) {
+ DBG(DBG_EISA, printk("Registering EISA HBA\n"));
register_HBA(base, buf, tpnt, IS_EISA);
} else
printk("eata_dma: No valid IRQ. HBA removed from list\n");
@@ -1151,6+1151,7 @@ void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt) for (i = 0; i < MAXISA; i++) {
if (ISAbases[i]) {
if (get_conf_PIO(ISAbases[i],buf) == TRUE){
+ DBG(DBG_ISA, printk("Registering ISA HBA\n"));
register_HBA(ISAbases[i], buf, tpnt, IS_ISA);
} else {
if (check_blink_state(ISAbases[i]))
@@ -1176,6+1177,7 @@ void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) u16 com_adr;
u16 rev_device;
u32 error, i, x;
+ u8 pal1, pal2, pal3;
if (pcibios_present()) {
for (i = 0; i <= MAXPCI; ++i, ++pci_index) {
@@ -1217,21+1219,26 @@ void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) /* Check if the address is valid */
if (base & 0x01) {
base &= 0xfffffffe;
- /* EISA tag there ? */
- if ((inb(base) == 0x12) && (inb(base + 1) == 0x14))
- continue; /* Jep, it's forced, so move on */
- base += 0x10; /* Now, THIS is the real address */
+ /* EISA tag there ? */
+ pal1 = inb(base);
+ pal2 = inb(base + 1);
+ pal3 = inb(base + 2);
+ if (((pal1 == 0x12) && (pal2 == 0x14)) ||
+ ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) ||
+ ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24)))
+ base += 0x08;
+ else
+ base += 0x10; /* Now, THIS is the real address */
+
if (base != 0x1f8) {
/* We didn't find it in the primary search */
if (get_conf_PIO(base, buf) == TRUE) {
- if (buf->FORCADR) /* If the address is forced */
- continue; /* we'll find it later */
-
+
/* OK. We made it till here, so we can go now
* and register it. We only have to check and
* eventually remove it from the EISA and ISA list
*/
-
+ DBG(DBG_PCI, printk("Registering PCI HBA\n"));
register_HBA(base, buf, tpnt, IS_PCI);
if (base < 0x1000) {
#define VER_MAJOR 2
#define VER_MINOR 5
-#define VER_SUB "7b"
+#define VER_SUB "8"
/************************************************************************
@@ -73,6+73,8 @@ int eata_release(struct Scsi_Host *); #define eata_release NULL
#endif
+#include <linux/scsicam.h>
+
#define EATA_DMA { \
NULL, NULL, \
NULL, /* proc_dir_entry */ \
@@ -369,7+369,7 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, SD(HBA_ptr)->writes[11]);
len += size;
pos = begin + len;
- size = sprintf(buffer+len,"Sum : %12u %12u\n",
+ size = sprintf(buffer+len,"Sum :%12u %12u\n",
SD(HBA_ptr)->reads[12],
SD(HBA_ptr)->writes[12]);
len += size;
@@ -378,11+378,12 @@ int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP))
{
- cmd->result = DID_ERROR << 16;
+ cmd->result = DID_BUS_BUSY << 16;
printk("eata_pio_queue target %d, pid %ld, HBA busy, returning "
- "DID_ERROR, done.\n", cmd->target, cmd->pid);
- restore_flags(flags);
+ "DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
done(cmd);
+ cp->status = FREE;
+ restore_flags(flags);
return (0);
}
while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
@@ -416,7+416,7 @@ void scsi_mem_init(unsigned long memory_end) Low24 += PAGE_SIZE) {
unsigned long ForbiddenAddress = High8 + Low24;
if (ForbiddenAddress >= memory_end) goto next_host;
- mem_map[MAP_NR(ForbiddenAddress)] = MAP_PAGE_RESERVED;
+ mem_map[MAP_NR(ForbiddenAddress)].reserved = 1;
}
}
}
@@ -543,7+543,7 @@ int qltyp; /* type of chip */ struct Scsi_Host *hreg; /* registered host structure */
unsigned long flags;
-tpnt->proc_dir = &proc_scsi_qlogic;
+host->proc_dir = &proc_scsi_qlogic;
/* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the
address - I check 230 first since MIDI cards are typically at 330
@@ -510,37+510,37 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors * that an interrupt may start another request, so we run this with interrupts
* turned off
*/
-#define INIT_SCSI_REQUEST \
- if (!CURRENT) {\
- CLEAR_INTR; \
+#define INIT_SCSI_REQUEST \
+ if (!CURRENT) { \
+ CLEAR_INTR; \
restore_flags(flags); \
- return; \
- } \
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
- panic(DEVICE_NAME ": request list destroyed"); \
- if (CURRENT->bh) { \
- if (!CURRENT->bh->b_lock) \
- panic(DEVICE_NAME ": block not locked"); \
+ return; \
+ } \
+ if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
+ panic(DEVICE_NAME ": request list destroyed");\
+ if (CURRENT->bh) { \
+ if (!CURRENT->bh->b_lock) \
+ panic(DEVICE_NAME ": block not locked"); \
}
#endif
#define SCSI_SLEEP(QUEUE, CONDITION) { \
- if (CONDITION) { \
+ if (CONDITION) { \
struct wait_queue wait = { current, NULL}; \
- add_wait_queue(QUEUE, &wait); \
- for(;;) { \
+ add_wait_queue(QUEUE, &wait); \
+ for(;;) { \
current->state = TASK_UNINTERRUPTIBLE; \
- if (CONDITION) { \
- if (intr_count) \
- panic("scsi: trying to call schedule() in interrupt" \
- ", file %s, line %d.\n", __FILE__, __LINE__); \
- schedule(); \
- } \
- else \
- break; \
- } \
- remove_wait_queue(QUEUE, &wait); \
- current->state = TASK_RUNNING; \
+ if (CONDITION) { \
+ if (intr_count) \
+ panic("scsi: trying to call schedule() in interrupt" \
+ ", file %s, line %d.\n", __FILE__, __LINE__); \
+ schedule(); \
+ } \
+ else \
+ break; \
+ } \
+ remove_wait_queue(QUEUE, &wait);\
+ current->state = TASK_RUNNING; \
}; }
#endif
Copyright 1992, 1993, 1994, 1995 Kai Makisara
email Kai.Makisara@metla.fi
- Last modified: Sun Sep 10 20:33:24 1995 by makisara@kai.makisara.fi
+ Last modified: Tue Sep 19 21:51:41 1995 by root@kai.makisara.fi
Some small formal changes - aeb, 950809
*/
#ifdef MODULE
@@ -74,14+74,16 @@ static int debugging = 1; #define TAPE_NR(x) (MINOR(x) & 127)
static int st_nbr_buffers;
-static int st_req_nbr_buffers;
static ST_buffer **st_buffers;
static int st_buffer_size = ST_BUFFER_SIZE;
static int st_write_threshold = ST_WRITE_THRESHOLD;
static int st_max_buffers = ST_MAX_BUFFERS;
+#define MAX_SCSI_TAPES 8
Scsi_Tape * scsi_tapes = NULL;
+static ST_buffer *new_tape_buffer(int);
+
static int st_init(void);
static int st_attach(Scsi_Device *);
static int st_detect(Scsi_Device *);
@@ -189,7+191,7 @@ st_sleep_done (Scsi_Cmnd * SCpnt) if ((STp->buffer)->writing)
SCpnt->request.rq_status = RQ_INACTIVE;
else
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
+ SCpnt->request.rq_status = RQ_SCSI_DONE;
if (!(STp->buffer)->writing || STp->write_pending)
wake_up( &(STp->waiting) );
STp->write_pending = 0;
@@ -257,13+259,13 @@ back_over_eof(kdev_t devt) unsigned int flags;
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
cmd[0] = SPACE;
cmd[1] = ((SCpnt->lun << 5) & 0xe0) | 0x01; /* Space FileMarks */
cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
cmd[5] = 0;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data, 0,
st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
@@ -271,7+273,7 @@ back_over_eof(kdev_t devt) /* need to do the check with interrupts off. -RAB */
save_flags(flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -336,7+338,7 @@ flush_write_buffer(kdev_t devt) cmd[2] = blks >> 16;
cmd[3] = blks >> 8;
cmd[4] = blks;
- SCpnt->request.rq_status = RQ_ACTIVE;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
SCpnt->request.rq_dev = devt;
scsi_do_cmd (SCpnt,
(void *) cmd, (STp->buffer)->b_data, transfer,
@@ -345,7+347,7 @@ flush_write_buffer(kdev_t devt) /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -388,7+390,6 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next) STp = &(scsi_tapes[dev]);
STbuffer = STp->buffer;
-
/*
* If there was a bus reset, block further access
* to this device.
@@ -455,10+456,14 @@ scsi_tape_open(struct inode * inode, struct file * filp) if (!st_buffers[i]->in_use)
break;
if (i >= st_nbr_buffers) {
- printk("st%d: No free buffers.\n", dev);
- return (-EBUSY);
+ STp->buffer = new_tape_buffer(FALSE);
+ if (STp->buffer == NULL) {
+ printk("st%d: No free buffers.\n", dev);
+ return (-EBUSY);
+ }
}
- STp->buffer = st_buffers[i];
+ else
+ STp->buffer = st_buffers[i];
(STp->buffer)->in_use = 1;
(STp->buffer)->writing = 0;
STp->in_use = 1;
@@ -479,6+484,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) #endif
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
if (!SCpnt) {
printk("st%d: Tape request not allocated", dev);
return (-EBUSY);
@@ -487,8+493,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10);
cmd[0] = TEST_UNIT_READY;
cmd[1] = (SCpnt->lun << 5) & 0xe0;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data,
0, st_sleep_done, ST_LONG_TIMEOUT,
@@ -497,7+502,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */
save_flags (processor_flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(processor_flags);
@@ -507,8+512,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10);
cmd[0] = TEST_UNIT_READY;
cmd[1] = (SCpnt->lun << 5) & 0xe0;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data,
0, st_sleep_done, ST_LONG_TIMEOUT,
@@ -517,7+521,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */
save_flags (processor_flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(processor_flags);
@@ -551,8+555,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) memset ((void *) &cmd[0], 0, 10);
cmd[0] = READ_BLOCK_LIMITS;
cmd[1] = (SCpnt->lun << 5) & 0xe0;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data,
6, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
@@ -560,7+563,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */
save_flags (processor_flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(processor_flags);
@@ -587,8+590,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) cmd[0] = MODE_SENSE;
cmd[1] = (SCpnt->lun << 5) & 0xe0;
cmd[4] = 12;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data,
12, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
@@ -596,7+598,7 @@ scsi_tape_open(struct inode * inode, struct file * filp) /* this must be done with interrupts off */
save_flags (processor_flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(processor_flags);
@@ -714,13+716,13 @@ scsi_tape_close(struct inode * inode, struct file * filp)
if (result == 0 || result == (-ENOSPC)) {
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
memset(cmd, 0, 10);
cmd[0] = WRITE_FILEMARKS;
cmd[1] = (SCpnt->lun << 5) & 0xe0;
cmd[4] = 1 + STp->two_fm;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd( SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data,
0, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
@@ -728,7+730,7 @@ scsi_tape_close(struct inode * inode, struct file * filp) /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -867,6+869,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) write_threshold--;
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
total = count;
@@ -902,8+905,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) cmd[2] = blks >> 16;
cmd[3] = blks >> 8;
cmd[4] = blks;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd (SCpnt,
(void *) cmd, (STp->buffer)->b_data, transfer,
st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
@@ -911,7+913,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -1018,8+1020,7 @@ st_write(struct inode * inode, struct file * filp, const char * buf, int count) cmd[2] = blks >> 16;
cmd[3] = blks >> 8;
cmd[4] = blks;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
STp->write_pending = 1;
scsi_do_cmd (SCpnt,
(void *) cmd, (STp->buffer)->b_data,
@@ -1090,6+1091,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) STp->rw = ST_READING;
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
for (total = 0; total < count; ) {
@@ -1118,8+1120,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) cmd[3] = blks >> 8;
cmd[4] = blks;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd (SCpnt,
(void *) cmd, (STp->buffer)->b_data,
bytes, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
@@ -1127,7+1128,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -1687,9+1688,9 @@ st_int_ioctl(struct inode * inode,struct file * file, }
SCpnt = allocate_device(NULL, STp->device, 1);
- cmd[1] |= (SCpnt->lun << 5) & 0xe0;
- SCpnt->request.rq_status = RQ_ACTIVE;
SCpnt->request.rq_dev = devt;
+ cmd[1] |= (SCpnt->lun << 5) & 0xe0;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) (STp->buffer)->b_data, datalen,
st_sleep_done, timeout, MAX_RETRIES);
@@ -1697,7+1698,7 @@ st_int_ioctl(struct inode * inode,struct file * file, /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -1860,30+1861,38 @@ st_ioctl(struct inode * inode,struct file * file, if (i)
return i;
- /*
- * If there was a bus reset, block further access
- * to this device. If the user wants to rewind the tape,
- * then reset the flag and allow access again.
- */
- if( STp->device->was_reset)
- {
- if(mtc.mt_op != MTREW &&
- mtc.mt_op != MTOFFL &&
- mtc.mt_op != MTRESET &&
- mtc.mt_op != MTRETEN &&
- mtc.mt_op != MTEOM)
- return (-EIO);
- STp->device->was_reset = 0;
- }
-
memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
- i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
- mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
- mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
- mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD);
- if (i < 0)
- return i;
+ if (!(STp->device)->was_reset) {
+ i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
+ mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
+ mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
+ mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD);
+ if (i < 0)
+ return i;
+ }
+ else {
+ /*
+ * If there was a bus reset, block further access
+ * to this device. If the user wants to rewind the tape,
+ * then reset the flag and allow access again.
+ */
+ if(mtc.mt_op != MTREW &&
+ mtc.mt_op != MTOFFL &&
+ mtc.mt_op != MTRETEN &&
+ mtc.mt_op != MTERASE &&
+ mtc.mt_op != MTSEEK &&
+ mtc.mt_op != MTEOM)
+ return (-EIO);
+ STp->device->was_reset = 0;
+ if (STp->door_locked != ST_UNLOCKED) {
+ if (st_int_ioctl(inode, file, MTLOCK, 0)) {
+ printk("st%d: Could not relock door after bus reset.\n", dev);
+ STp->door_locked = ST_UNLOCKED;
+ }
+ }
+ }
+
if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
mtc.mt_op != MTSETDRVBUFFER)
@@ -1970,6+1979,7 @@ st_ioctl(struct inode * inode,struct file * file, return i;
SCpnt = allocate_device(NULL, STp->device, 1);
+ SCpnt->request.rq_dev = devt;
memset (scmd, 0, 10);
if ((STp->device)->scsi_level < SCSI_2) {
@@ -1980,8+1990,7 @@ st_ioctl(struct inode * inode,struct file * file, scmd[0] = READ_POSITION;
scmd[1] = 1;
}
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->request.rq_dev = devt;
+ SCpnt->request.rq_status = RQ_SCSI_BUSY;
scmd[1] |= (SCpnt->lun << 5) & 0xe0;
scsi_do_cmd(SCpnt,
(void *) scmd, (void *) (STp->buffer)->b_data,
@@ -1990,7+1999,7 @@ st_ioctl(struct inode * inode,struct file * file, /* this must be done with interrupts off */
save_flags (flags);
cli();
- if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+ if (SCpnt->request.rq_status != RQ_SCSI_DONE)
sleep_on( &(STp->waiting) );
restore_flags(flags);
@@ -2026,6+2035,44 @@ st_ioctl(struct inode * inode,struct file * file, }
\f
+/* Try to allocate a new tape buffer */
+ static ST_buffer *
+new_tape_buffer( int from_initialization )
+{
+ int priority;
+ ST_buffer *tb;
+
+ if (st_nbr_buffers >= st_template.dev_max)
+ return NULL; /* Should never happen */
+
+ if (from_initialization)
+ priority = GFP_ATOMIC;
+ else
+ priority = GFP_KERNEL;
+ tb = (ST_buffer *)scsi_init_malloc(sizeof(ST_buffer), priority);
+ if (tb) {
+ tb->b_data = (unsigned char *)scsi_init_malloc(st_buffer_size,
+ priority | GFP_DMA);
+ if (!tb->b_data) {
+ scsi_init_free((char *)tb, sizeof(ST_buffer));
+ tb = NULL;
+ }
+ }
+ if (!tb) {
+ printk("st: Can't allocate new tape buffer (nbr %d).\n", st_nbr_buffers);
+ return NULL;
+ }
+
+#if DEBUG
+ printk("st: Allocated tape buffer %d.\n", st_nbr_buffers);
+#endif
+ tb->in_use = 0;
+ tb->writing = 0;
+ st_buffers[st_nbr_buffers++] = tb;
+ return tb;
+}
+
+
/* Set the boot options. Syntax: st=xxx,yyy
where xxx is buffer size in 512 byte blocks and yyy is write threshold
in 512 byte blocks. */
@@ -2120,6+2167,9 @@ static int st_init() {
int i;
Scsi_Tape * STp;
+#if !ST_RUNTIME_BUFFERS
+ int target_nbr;
+#endif
if (st_template.dev_noticed == 0) return 0;
@@ -2132,15+2182,17 @@ static int st_init() }
if (scsi_tapes) return 0;
- scsi_tapes = (Scsi_Tape *) scsi_init_malloc(
- (st_template.dev_noticed + ST_EXTRA_DEVS) *
- sizeof(Scsi_Tape), GFP_ATOMIC);
+ st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
+ if (st_template.dev_max < MAX_SCSI_TAPES)
+ st_template.dev_max = MAX_SCSI_TAPES;
+ scsi_tapes =
+ (Scsi_Tape *) scsi_init_malloc(st_template.dev_max * sizeof(Scsi_Tape),
+ GFP_ATOMIC);
if (scsi_tapes == NULL) {
printk("Unable to allocate descriptors for SCSI tapes.\n");
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
return 1;
}
- st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
#if DEBUG
printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
@@ -2168,62+2220,49 @@ static int st_init() STp->drv_block = 0;
STp->moves_after_eof = 1;
STp->at_sm = 0;
- STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget), GFP_ATOMIC);
+ STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget),
+ GFP_ATOMIC);
/* Initialize status */
memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
}
/* Allocate the buffers */
- st_nbr_buffers = st_template.dev_noticed;
- if (st_nbr_buffers < ST_EXTRA_DEVS)
- st_nbr_buffers = ST_EXTRA_DEVS;
- if (st_nbr_buffers > st_max_buffers)
- st_nbr_buffers = st_max_buffers;
- st_req_nbr_buffers = st_nbr_buffers;
- st_buffers = (ST_buffer **) scsi_init_malloc(st_nbr_buffers *
- sizeof(ST_buffer *),
- GFP_ATOMIC);
+ st_buffers =
+ (ST_buffer **) scsi_init_malloc(st_template.dev_max * sizeof(ST_buffer *),
+ GFP_ATOMIC);
if (st_buffers == NULL) {
printk("Unable to allocate tape buffer pointers.\n");
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
scsi_init_free((char *) scsi_tapes,
- (st_template.dev_noticed + ST_EXTRA_DEVS)
- * sizeof(Scsi_Tape));
+ st_template.dev_max * sizeof(Scsi_Tape));
return 1;
}
- /* FIXME - if we are hitting this because we are loading a tape module
- as a loadable driver, we should not use kmalloc - it will allocate
- a 64Kb region in order to buffer about 32Kb. Try using 31 blocks
- instead. */
-
- for (i=0; i < st_nbr_buffers; i++) {
- st_buffers[i] = (ST_buffer *) scsi_init_malloc(sizeof(ST_buffer) -
- 1 + st_buffer_size,
- GFP_ATOMIC | GFP_DMA);
- if (st_buffers[i] == NULL) {
- printk("Not enough memory for buffer %d.\n", i);
+#if ST_RUNTIME_BUFFERS
+ st_nbr_buffers = 0;
+#else
+ target_nbr = st_template.dev_noticed;
+ if (target_nbr < ST_EXTRA_DEVS)
+ target_nbr = ST_EXTRA_DEVS;
+ if (target_nbr > st_max_buffers)
+ target_nbr = st_max_buffers;
+
+ for (i=st_nbr_buffers=0; i < target_nbr; i++) {
+ if (!new_tape_buffer(TRUE)) {
if (i == 0) {
+ printk("Can't continue without at least one tape buffer.\n");
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
- scsi_init_free((char *) scsi_tapes,
- (st_template.dev_noticed + ST_EXTRA_DEVS)
- * sizeof(Scsi_Tape));
scsi_init_free((char *) st_buffers,
- st_nbr_buffers * sizeof(ST_buffer *));
+ st_template.dev_max * sizeof(ST_buffer *));
+ scsi_init_free((char *) scsi_tapes,
+ st_template.dev_max * sizeof(Scsi_Tape));
return 1;
}
- st_nbr_buffers = i;
printk("Number of tape buffers adjusted.\n");
break;
}
- else {
-#if DEBUG
-/* printk("st: Buffer address: %p\n", st_buffers[i]); */
-#endif
- st_buffers[i]->in_use = 0;
- st_buffers[i]->writing = 0;
- }
}
+#endif
return 0;
}
@@ -2265,18+2304,17 @@ void cleanup_module( void) st_registered--;
if(scsi_tapes != NULL) {
scsi_init_free((char *) scsi_tapes,
- (st_template.dev_noticed + ST_EXTRA_DEVS)
- * sizeof(Scsi_Tape));
+ st_template.dev_max * sizeof(Scsi_Tape));
if (st_buffers != NULL) {
for (i=0; i < st_nbr_buffers; i++)
if (st_buffers[i] != NULL) {
- scsi_init_free((char *) st_buffers[i],
- sizeof(ST_buffer) - 1 + st_buffer_size);
+ scsi_init_free((char *) st_buffers[i]->b_data, st_buffer_size);
+ scsi_init_free((char *) st_buffers[i], sizeof(ST_buffer));
}
scsi_init_free((char *) st_buffers,
- st_req_nbr_buffers * sizeof(ST_buffer *));
+ st_template.dev_max * sizeof(ST_buffer *));
}
}
st_template.dev_max = 0;
@@ -18,7+18,7 @@ typedef struct { int writing;
int last_result;
int last_result_fatal;
- unsigned char b_data[1];
+ unsigned char *b_data;
} ST_buffer;
typedef struct {
Copyright 1995 Kai Makisara.
- Last modified: Sun Sep 10 13:26:02 1995 by root@kai.makisara.fi
+ Last modified: Mon Sep 18 21:00:49 1995 by root@kai.makisara.fi
*/
#ifndef _ST_OPTIONS_H
#define _ST_OPTIONS_H
+/* The driver allocates the tape buffers when needed if ST_RUNTIME_BUFFERS
+ is nonzero. Otherwise a number of buffers are allocated at initialization.
+ The drawback of runtime allocation is that allocation may fail. In any
+ case the driver tries to allocate a new tape buffer when none is free. */
+#define ST_RUNTIME_BUFFERS 0
+
/* The driver does not wait for some operations to finish before returning
to the user program if ST_NOWAIT is non-zero. This helps if the SCSI
adapter does not support multiple outstanding commands. However, the user
SENSE. */
#define ST_DEFAULT_BLOCK 0
-/* The tape driver buffer size in kilobytes. When loading as module, the
- memory block being used is slightly less than a power of two, i.e.,
- a 64 kB block is used for a 32 kB buffer => we may as well use what is
- being allocated! */
-#ifdef MODULE
-#define ST_BUFFER_BLOCKS 63
-#else
+/* The tape driver buffer size in kilobytes. */
#define ST_BUFFER_BLOCKS 32
-#endif
/* The number of kilobytes of data in the buffer that triggers an
asynchronous write in fixed block mode. See also ST_ASYNC_WRITES
@@ -618,10+618,10 @@ sound_mem_init (void)
for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
{
- if (mem_map[i])
+ if (mem_map[i].reserved || mem_map[i].count)
panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
- mem_map[i] = MAP_PAGE_RESERVED;
+ mem_map[i].reserved = 1;
}
}
} /* for dev */
@@ -590,7+590,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) elf_ppnt->p_offset & 0xfffff000);
#ifdef LOW_ELF_STACK
- if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack)
+ if((elf_ppnt->p_vaddr & 0xfffff000) < elf_stack)
elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
#endif
@@ -566,7+566,7 @@ repeat0: tmp = bh->b_next_free;
if (!bh) break;
- if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1 ||
+ if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
bh->b_dirt) {
refile_buffer(bh);
continue;
@@ -614,7+614,7 @@ repeat0: if(candidate[i] == bh) candidate[i] = NULL; /* Got last one */
if (bh->b_count || bh->b_size != size)
panic("Busy buffer in candidate list\n");
- if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1)
+ if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1)
panic("Shared buffer in candidate list\n");
if (BADNESS(bh)) panic("Buffer in candidate list with BADNESS != 0\n");
@@ -638,7+638,7 @@ repeat0: tmp = bh->b_next_free;
if (!bh) break;
- if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1 ||
+ if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
bh->b_dirt) {
refile_buffer(bh);
continue;
@@ -761,7+761,7 @@ void refile_buffer(struct buffer_head * buf){ panic("Attempt to refile free buffer\n");
if (buf->b_dirt)
dispose = BUF_DIRTY;
- else if (mem_map[MAP_NR((unsigned long) buf->b_data)] > 1)
+ else if (mem_map[MAP_NR((unsigned long) buf->b_data)].count > 1)
dispose = BUF_SHARED;
else if (buf->b_lock)
dispose = BUF_LOCKED;
@@ -1048,7+1048,7 @@ static unsigned long check_aligned(struct buffer_head * first, unsigned long add }
if (!aligned)
return try_to_align(bh, nrbuf, address);
- mem_map[MAP_NR(page)]++;
+ mem_map[MAP_NR(page)].count++;
read_buffers(bh,nrbuf); /* make sure they are actually read correctly */
while (nrbuf-- > 0)
brelse(bh[nrbuf]);
@@ -1106,7+1106,7 @@ static unsigned long try_to_load_aligned(unsigned long address, }
buffermem += PAGE_SIZE;
bh->b_this_page = tmp;
- mem_map[MAP_NR(address)]++;
+ mem_map[MAP_NR(address)].count++;
buffer_pages[MAP_NR(address)] = bh;
read_buffers(arr,block);
while (block-- > 0)
@@ -1308,7+1308,7 @@ static int try_to_free(struct buffer_head * bh, struct buffer_head ** bhp) buffermem -= PAGE_SIZE;
buffer_pages[MAP_NR(page)] = NULL;
free_page(page);
- return !mem_map[MAP_NR(page)];
+ return !mem_map[MAP_NR(page)].count;
}
@@ -1471,7+1471,7 @@ void show_buffers(void) locked++;
if (bh->b_dirt)
dirty++;
- if(mem_map[MAP_NR(((unsigned long) bh->b_data))] !=1) shared++;
+ if(mem_map[MAP_NR(((unsigned long) bh->b_data))].count !=1) shared++;
if (bh->b_count)
used++, lastused = found;
bh = bh->b_next_free;
@@ -1505,7+1505,7 @@ static inline int try_to_reassign(struct buffer_head * bh, struct buffer_head ** *bhp = bh;
page = (unsigned long) bh->b_data;
page &= PAGE_MASK;
- if(mem_map[MAP_NR(page)] != 1) return 0;
+ if(mem_map[MAP_NR(page)].count != 1) return 0;
tmp = bh;
do {
if (!tmp)
@@ -512,7+512,7 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned ++*dirty;
if (pte_page(page) >= high_memory)
continue;
- if (mem_map[MAP_NR(pte_page(page))] > 1)
+ if (mem_map[MAP_NR(pte_page(page))].count > 1)
++*shared;
} while (address < end);
}
@@ -61,7+61,7 @@ struct inode_operations proc_link_inode_operations = { * looking up the file structure of the newly opened proc fd file, and
* replacing it with the actual file structure of the process's file
* descriptor. This allows plan 9 semantics, so that the returned
- * file descriptor is an dup of the target file descriptor.
+ * file descriptor is a dup of the target file descriptor.
*/
static int proc_fd_dupf(struct inode * inode, struct file * f)
{
@@ -291,7+291,7 @@ int mem_mmap(struct inode * inode, struct file * file,
set_pte(src_table, pte_mkdirty(*src_table));
set_pte(dest_table, *src_table);
- mem_map[MAP_NR(pte_page(*src_table))]++;
+ mem_map[MAP_NR(pte_page(*src_table))].count++;
stmp += PAGE_SIZE;
dtmp += PAGE_SIZE;
@@ -328,8+328,10 @@ int proc_lookup(struct inode * dir,const char * name, int len, }
de = (struct proc_dir_entry *) dir->u.generic_ip;
- if (!de)
+ if (!de) {
+ iput(dir);
return -EINVAL;
+ }
/* Special case "." and "..": they aren't on the directory list */
*result = dir;
@@ -354,8+356,10 @@ int proc_lookup(struct inode * dir,const char * name, int len, if (proc_match(len, name, de))
break;
}
- if (!de)
+ if (!de) {
+ iput(dir);
return -ENOENT;
+ }
ino = de->low_ino | (dir->i_ino & ~(0xffff));
@@ -371,11+375,14 @@ static int proc_root_lookup(struct inode * dir,const char * name, int len, struct inode ** result)
{
unsigned int pid, c;
- int i, ino;
+ int i, ino, retval;
- int retval = proc_lookup(dir, name, len, result);
- if (retval != -ENOENT)
+ dir->i_count++;
+ retval = proc_lookup(dir, name, len, result);
+ if (retval != -ENOENT) {
+ iput(dir);
return retval;
+ }
pid = 0;
while (len-- > 0) {
@@ -71,9+71,13 @@ __asm__ __volatile__( \
#define PAGE_OFFSET 0xFFFFFC0000000000
#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED (1<<31)
-typedef unsigned int mem_map_t;
+typedef struct {
+ unsigned count:30,
+ dirty:1,
+ reserved:1;
+} mem_map_t;
+
#endif /* __KERNEL__ */
@@ -171,35+171,30 @@ extern inline unsigned long pgd_page(pgd_t pgd)
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
-extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; }
+extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
extern inline void pte_reuse(pte_t * ptep)
{
- if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(ptep)]++;
+ if (!mem_map[MAP_NR(ptep)].reserved)
+ mem_map[MAP_NR(ptep)].count++;
}
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; }
extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; }
-extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] != 1; }
+extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)].reserved || mem_map[MAP_NR(pmdp)].count != 1; }
extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
extern inline void pmd_reuse(pmd_t * pmdp)
{
- if (!(mem_map[MAP_NR(pmdp)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(pmdp)]++;
+ if (!mem_map[MAP_NR(pmdp)].reserved)
+ mem_map[MAP_NR(pmdp)].count++;
}
extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; }
-extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] != 1; }
+extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)].reserved; }
extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
-extern inline void pgd_reuse(pgd_t * pgdp)
-{
- if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(pgdp)]++;
-}
/*
* The following only work if pte_present() is true.
@@ -273,7+268,7 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) */
extern inline void pte_free_kernel(pte_t * pte)
{
- mem_map[MAP_NR(pte)] = 1;
+ mem_map[MAP_NR(pte)].reserved = 0;
free_page((unsigned long) pte);
}
@@ -285,7+280,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) if (pmd_none(*pmd)) {
if (page) {
pmd_set(pmd, page);
- mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+ mem_map[MAP_NR(page)].reserved = 1;
return page + address;
}
pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
@@ -303,7+298,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
extern inline void pmd_free_kernel(pmd_t * pmd)
{
- mem_map[MAP_NR(pmd)] = 1;
+ mem_map[MAP_NR(pmd)].reserved = 0;
free_page((unsigned long) pmd);
}
@@ -315,7+310,7 @@ extern inline pmd_t * pmd_alloc_kernel(pgd_t *pgd, unsigned long address) if (pgd_none(*pgd)) {
if (page) {
pgd_set(pgd, page);
- mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+ mem_map[MAP_NR(page)].reserved = 1;
return page + address;
}
pgd_set(pgd, BAD_PAGETABLE);
@@ -81,9+81,12 @@ do { if ((task)->mm == current->mm) invalidate(); } while (0) /* This handles the memory map.. */
#define PAGE_OFFSET 0
#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED (1<<15)
-typedef unsigned short mem_map_t;
+typedef struct {
+ unsigned count:30,
+ dirty:1,
+ reserved:1;
+} mem_map_t;
#endif /* __KERNEL__ */
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
-extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; }
+extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
extern inline void pte_reuse(pte_t * ptep)
{
- if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(ptep)]++;
+ if (!mem_map[MAP_NR(ptep)].reserved)
+ mem_map[MAP_NR(ptep)].count++;
}
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
@@ -170,13+170,8 @@ extern inline void pmd_reuse(pmd_t * pmdp) { } extern inline int pgd_none(pgd_t pgd) { return 0; }
extern inline int pgd_bad(pgd_t pgd) { return 0; }
extern inline int pgd_present(pgd_t pgd) { return 1; }
-extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; }
+extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)].reserved; }
extern inline void pgd_clear(pgd_t * pgdp) { }
-extern inline void pgd_reuse(pgd_t * pgdp)
-{
- if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(pgdp)]++;
-}
/*
* The following only work if pte_present() is true.
@@ -243,7+238,7 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) */
extern inline void pte_free_kernel(pte_t * pte)
{
- mem_map[MAP_NR(pte)] = 1;
+ mem_map[MAP_NR(pte)].reserved = 0;
free_page((unsigned long) pte);
}
@@ -255,7+250,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) if (pmd_none(*pmd)) {
if (page) {
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
- mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+ mem_map[MAP_NR(page)].reserved = 1;
return page + address;
}
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
@@ -104,11+104,11 @@ static inline kdev_t to_kdev_t(int dev) #else /* __KERNEL__ */
/*
-Some unfortunate programs want their definitions of MAJOR and MINOR
-from the kernel sources.
+Some programs want their definitions of MAJOR and MINOR and MKDEV
+from the kernel sources. These must be the externally visible ones.
*/
#define MAJOR(dev) ((dev)>>8)
#define MINOR(dev) ((dev) & 0xff)
-
+#define MKDEV(ma,mi) ((ma)<<8 | (mi))
#endif /* __KERNEL__ */
#endif
* - your exact hardware description. Try to find out
* which device is unknown. It may be you mainboard chipset.
* PCI-CPU bridge or PCI-ISA bridge.
- * - Send all that to frederic@cao-vlsi.ibp.fr, and I'll add
- * your device to the list as soon as possible
+ * - If you can't find the actual information in your hardware
+ * booklet, try to read the references of the chip on the board.
+ * - Send all that, with the word PCIPROBE in the subject,
+ * to frederic@cao-vlsi.ibp.fr, and I'll add your device to
+ * the list as soon as possible
* fred.
*/
#define PCI_DEVICE_ID_SI_501 0x0406
#define PCI_DEVICE_ID_SI_496 0x0496
#define PCI_DEVICE_ID_SI_601 0x0601
+#define PCI_DEVICE_ID_SI_5511 0x5511
+#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_DEVICE_ID_HP_J2585A 0x1030
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_640 0x0640
+#define PCI_DEVICE_ID_CMD_646 0x0646
#define PCI_VENDOR_ID_VISION 0x1098
#define PCI_DEVICE_ID_VISION_QD8500 0x0001
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
+#define PCI_VENDOR_ID_REALTEK 0x10ec
+#define PCI_DEVICE_ID_REALTEK_8300 0x8029
+
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_82C505 0x0505
#define PCI_DEVICE_ID_VIA_82C561 0x0561
@@ -221,7+221,6 @@ extern int proc_match(int, const char *, struct proc_dir_entry *); extern int proc_readdir(struct inode *, struct file *, void *, filldir_t);
extern int proc_lookup(struct inode *, const char *, int, struct inode **);
-extern struct inode_operations proc_base_inode_operations;
extern struct inode_operations proc_net_inode_operations;
extern struct inode_operations proc_netdir_inode_operations;
extern struct inode_operations proc_scsi_inode_operations;
@@ -664,7+664,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns
done: /* pte_val(pte) == shp->shm_pages[idx] */
current->min_flt++;
- mem_map[MAP_NR(pte_page(pte))]++;
+ mem_map[MAP_NR(pte_page(pte))].count++;
return pte_modify(pte, shmd->vm_page_prot);
}
@@ -764,7+764,7 @@ int shm_swap (int prio, unsigned long limit) printk("shm_swap_out: page and pte mismatch\n");
set_pte(page_table,
__pte(shmd->vm_pte + SWP_ENTRY(0, idx << SHM_IDX_SHIFT)));
- mem_map[MAP_NR(pte_page(pte))]--;
+ mem_map[MAP_NR(pte_page(pte))].count--;
if (shmd->vm_mm->rss > 0)
shmd->vm_mm->rss--;
invalid++;
@@ -774,7+774,7 @@ int shm_swap (int prio, unsigned long limit) break;
}
- if (mem_map[MAP_NR(pte_page(page))] != 1)
+ if (mem_map[MAP_NR(pte_page(page))].count != 1)
goto check_table;
shp->shm_pages[idx] = swap_nr;
if (invalid)
@@ -92,11+92,6 @@ int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, off_t offset, int length,
int inode, int func) = 0; /* Dirty hack */
-#if defined(CONFIG_PROC_FS)
-extern struct proc_dir_entry scsi_dir[];
-extern struct proc_dir_entry scsi_hba_dir[];
-#endif
-
extern int sys_tz;
extern int request_dma(unsigned int dmanr, char * deviceID);
extern void free_dma(unsigned int dmanr);
@@ -290,6+285,7 @@ struct symbol_table symbol_table = { X(printk),
X(sprintf),
X(vsprintf),
+ X(kdevname),
X(simple_strtoul),
X(system_utsname),
X(sys_call_table),
@@ -416,11+412,6 @@ struct symbol_table symbol_table = { */
X(gendisk_head),
X(resetup_one_dev),
-
-#if defined(CONFIG_PROC_FS)
- X(scsi_dir),
- X(scsi_hba_dir),
-#endif
X(dispatch_scsi_info_ptr),
#endif
/* Added to make file system as module */
@@ -153,7+153,7 @@ static pte_t filemap_swapin(struct vm_area_struct * vma, {
unsigned long page = SWP_OFFSET(entry);
- mem_map[page]++;
+ mem_map[page].count++;
page = (page << PAGE_SHIFT) + PAGE_OFFSET;
return mk_pte(page,vma->vm_page_prot);
}
@@ -173,7+173,7 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma, return 0;
set_pte(ptep, pte_mkclean(pte));
page = pte_page(pte);
- mem_map[MAP_NR(page)]++;
+ mem_map[MAP_NR(page)].count++;
} else {
if (pte_none(pte))
return 0;
@@ -207,7+207,7 @@ static inline void copy_one_pte(pte_t * old_pte, pte_t * new_pte) set_pte(new_pte, pte);
return;
}
- if (pte_page(pte) > high_memory || (mem_map[MAP_NR(pte_page(pte))] & MAP_PAGE_RESERVED)) {
+ if (pte_page(pte) > high_memory || mem_map[MAP_NR(pte_page(pte))].reserved) {
set_pte(new_pte, pte);
return;
}
@@ -217,7+217,7 @@ static inline void copy_one_pte(pte_t * old_pte, pte_t * new_pte) pte = pte_mkdirty(pte);
set_pte(new_pte, pte_mkold(pte));
set_pte(old_pte, pte);
- mem_map[MAP_NR(pte_page(pte))]++;
+ mem_map[MAP_NR(pte_page(pte))].count++;
}
static inline int copy_pte_range(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long address, unsigned long size)
@@ -315,7+315,7 @@ static inline void forget_pte(pte_t page) return;
if (pte_present(page)) {
free_page(pte_page(page));
- if (mem_map[MAP_NR(pte_page(page))] & MAP_PAGE_RESERVED)
+ if (mem_map[MAP_NR(pte_page(page))].reserved)
return;
if (current->mm->rss <= 0)
return;
@@ -479,7+479,7 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned do {
pte_t oldpage = *pte;
pte_clear(pte);
- if (offset >= high_memory || (mem_map[MAP_NR(offset)] & MAP_PAGE_RESERVED))
+ if (offset >= high_memory || mem_map[MAP_NR(offset)].reserved)
set_pte(pte, mk_pte(offset, prot));
forget_pte(oldpage);
address += PAGE_SIZE;
@@ -558,7+558,7 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig
if (page >= high_memory)
printk("put_dirty_page: trying to put page %08lx at %08lx\n",page,address);
- if (mem_map[MAP_NR(page)] != 1)
+ if (mem_map[MAP_NR(page)].count != 1)
printk("mem_map disagrees with %08lx at %08lx\n",page,address);
pgd = pgd_offset(tsk->mm,address);
pmd = pmd_alloc(pgd, address);
@@ -632,9+632,9 @@ void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, /*
* Do we need to copy?
*/
- if (mem_map[MAP_NR(old_page)] != 1) {
+ if (mem_map[MAP_NR(old_page)].count != 1) {
if (new_page) {
- if (mem_map[MAP_NR(old_page)] & MAP_PAGE_RESERVED)
+ if (mem_map[MAP_NR(old_page)].reserved)
++vma->vm_mm->rss;
copy_page(old_page,new_page);
set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
@@ -812,7+812,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are /* is the page reasonable at all? */
if (pte_page(from) >= high_memory)
return 0;
- if (mem_map[MAP_NR(pte_page(from))] & MAP_PAGE_RESERVED)
+ if (mem_map[MAP_NR(pte_page(from))].reserved)
return 0;
/* is the destination ok? */
to_dir = pgd_offset(to_area->vm_mm,to_address);
@@ -862,7+862,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are set_pte(from_table, pte_mkdirty(from));
delete_from_swap_cache(pte_page(from));
}
- mem_map[MAP_NR(pte_page(from))]++;
+ mem_map[MAP_NR(pte_page(from))].count++;
set_pte(to_table, mk_pte(pte_page(from), to_area->vm_page_prot));
/* Check if we need to do anything at all to the 'from' field */
if (!pte_write(from))
@@ -966,7+966,7 @@ static inline void do_swap_page(struct task_struct * tsk, free_page(pte_page(page));
return;
}
- if (mem_map[MAP_NR(pte_page(page))] > 1 && !(vma->vm_flags & VM_SHARED))
+ if (mem_map[MAP_NR(pte_page(page))].count > 1 && !(vma->vm_flags & VM_SHARED))
page = pte_wrprotect(page);
++vma->vm_mm->rss;
++tsk->maj_flt;
@@ -1041,7+1041,7 @@ void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, entry = mk_pte(page, vma->vm_page_prot);
if (write_access) {
entry = pte_mkwrite(pte_mkdirty(entry));
- } else if (mem_map[MAP_NR(page)] > 1 && !(vma->vm_flags & VM_SHARED))
+ } else if (mem_map[MAP_NR(page)].count > 1 && !(vma->vm_flags & VM_SHARED))
entry = pte_wrprotect(entry);
put_page(page_table, entry);
}
@@ -367,7+367,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc return 0;
if (page >= limit)
return 0;
- if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
+ if (mem_map[MAP_NR(page)].reserved)
return 0;
if ((pte_dirty(pte) && delete_from_swap_cache(page)) || pte_young(pte)) {
set_pte(page_table, pte_mkold(pte));
@@ -380,7+380,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc if (vma->vm_ops->swapout(vma, address - vma->vm_start + vma->vm_offset, page_table))
kill_proc(pid, SIGBUS, 1);
} else {
- if (mem_map[MAP_NR(page)] != 1)
+ if (mem_map[MAP_NR(page)].count != 1)
return 0;
if (!(entry = get_swap_page()))
return 0;
@@ -393,7+393,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc return 1; /* we slept: the process may not exist any more */
}
if ((entry = find_in_swap_cache(page))) {
- if (mem_map[MAP_NR(page)] != 1) {
+ if (mem_map[MAP_NR(page)].count != 1) {
set_pte(page_table, pte_mkdirty(pte));
printk("Aiee.. duplicated cached swap-cache entry\n");
return 0;
@@ -407,7+407,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc vma->vm_mm->rss--;
pte_clear(page_table);
invalidate();
- entry = mem_map[MAP_NR(page)];
+ entry = mem_map[MAP_NR(page)].count;
free_page(page);
return entry;
}
@@ -717,21+717,21 @@ static inline void check_free_buffers(unsigned long addr)
void free_pages(unsigned long addr, unsigned long order)
{
- if (addr < high_memory) {
+ if (MAP_NR(addr) < MAP_NR(high_memory)) {
unsigned long flag;
mem_map_t * map = mem_map + MAP_NR(addr);
- if (*map) {
- if (!(*map & MAP_PAGE_RESERVED)) {
- save_flags(flag);
- cli();
- if (!--*map) {
- free_pages_ok(addr, order);
- delete_from_swap_cache(addr);
- }
- restore_flags(flag);
- if (*map == 1)
- check_free_buffers(addr);
+ if (map->reserved)
+ return;
+ if (map->count) {
+ save_flags(flag);
+ cli();
+ if (!--map->count) {
+ free_pages_ok(addr, order);
+ delete_from_swap_cache(addr);
}
+ restore_flags(flag);
+ if (map->count == 1)
+ check_free_buffers(addr);
return;
}
printk("Trying to free free memory (%08lx): memory probably corrupted\n",addr);
@@ -775,7+775,7 @@ do { unsigned long size = PAGE_SIZE << high; \ mark_used((unsigned long) addr, high); \
restore_flags(flags); \
addr = (struct mem_list *) (size + (unsigned long) addr); \
- } mem_map[MAP_NR((unsigned long) addr)] = 1; \
+ } mem_map[MAP_NR((unsigned long) addr)].count = 1; \
} while (0)
unsigned long __get_free_pages(int priority, unsigned long order, unsigned long limit)
@@ -956,6+956,8 @@ static int unuse_process(struct task_struct * p, unsigned int type, unsigned lon /*
* Go through process' page directory.
*/
+ if (!p->mm || pgd_inuse(p->mm->pgd))
+ return 0;
vma = p->mm->mmap;
while (vma) {
pgd_t * pgd = pgd_offset(p->mm, vma->vm_start);
@@ -1244,7+1246,7 @@ void si_swapinfo(struct sysinfo *val)
/*
* set up the free-area data structures:
- * - mark all pages MAP_PAGE_RESERVED
+ * - mark all pages reserved
* - mark all memory queues empty
* - clear the memory bitmaps
*/
@@ -1266,8+1268,12 @@ unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem) mem_map = (mem_map_t *) start_mem;
p = mem_map + MAP_NR(end_mem);
start_mem = LONG_ALIGN((unsigned long) p);
- while (p > mem_map)
- *--p = MAP_PAGE_RESERVED;
+ while (p > mem_map) {
+ --p;
+ p->count = 0;
+ p->dirty = 0;
+ p->reserved = 1;
+ }
for (i = 0 ; i < NR_MEM_LISTS ; i++) {
unsigned long bitmap_size;