Commit 579d0d6f authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.10

parent d75df542
......@@ -713,6 +713,10 @@ S: 2a, rue de l'Acier
S: L-4505 Differdange
S: Luxembourg
N: Gerd Knorr
E: kraxel@cs.tu-berlin.de
D: SCSI CD-ROM driver hacking, minor bug fixes
N: Harald Koenig
E: koenig@tat.physik.uni-tuebingen.de
D: XFree86 (S3), DCF77, some kernel hacks and fixes
......
This diff is collapsed.
......@@ -1243,6 +1243,13 @@ CONFIG_BLK_DEV_SR
say M here and read Documentation/modules.txt and
Documentation/scsi.txt .
Enable vendor-specific extentions (for SCSI CDROM)
CONFIG_BLK_DEV_SR_VENDOR
This enables the usage of vendor specific SCSI commands. This is
required for some stuff which is newer than the SCSI-II standard,
most important is the multisession CD support. You'll probably want
to say y here, unless you have a _real old_ CD-ROM drive.
SCSI generic support
CONFIG_CHR_DEV_SG
If you want to use SCSI scanners, synthesizers or CD-writers or just
......
......@@ -42,7 +42,7 @@ foo \kill}%
%
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$}
\date{Last revised: July 9, 1996}
\date{Last revised: November 13, 1996}
\maketitle
%
\noindent
......@@ -179,7 +179,11 @@ reply.
\major{52}{}{char }{Spellcaster DataComm/BRI ISDN card}
\major{53}{}{char }{BDM interface for remote debugging MC683xx microcontrollers}
\major{54}{}{char }{Electrocardiognosis Holter serial card}
\major{55}{--59}{}{Unallocated}
\major{55}{}{char }{DSP56001 digital signal processor}
\major{56}{}{char }{Apple Desktop Bus}
\major{57}{}{char }{Hayes ESP serial card}
\major{58}{}{char }{Hayes ESP serial card -- alternate devices}
\major{59}{}{}{Unallocated}
\major{60}{--63}{}{Local/experimental use}
\major{64}{--119}{}{Unallocated}
\major{120}{--127}{}{Local/experimental use}
......@@ -453,6 +457,7 @@ physical disks.
\minor{5}{/dev/atarimouse}{Atari mouse}
\minor{6}{/dev/sunmouse}{Sun mouse}
\minor{7}{/dev/amigamouse1}{Second Amiga mouse}
\minor{8}{/dev/smouse}{Simple serial mouse driver}
\minor{128}{/dev/beep}{Fancy beep device}
\minor{129}{/dev/modreq}{Kernel module load request}
\minor{130}{/dev/watchdog}{Watchdog timer port}
......@@ -1116,7 +1121,35 @@ $<$mseritan@ottonel.pub.ro$>$ to transfer data from Holter 24-hour
heart monitoring equipment.
\begin{devicelist}
\major{55}{--59}{}{Unallocated}
\major{55}{}{char }{DSP56001 digital signal processor}
\minor{0}{/dev/dsp56k}{First DSP56001}
\end{devicelist}
\begin{devicelist}
\major{56}{}{char }{Apple Desktop Bus}
\minor{0}{/dev/adb}{ADB bus control}
\end{devicelist}
\noindent
Additional devices will be added to this number, all starting with
{\file /dev/adb}.
\begin{devicelist}
\major{57}{}{char }{Hayes ESP serial card}
\minor{0}{/dev/ttyP0}{First ESP port}
\minor{1}{/dev/ttyP1}{Second ESP port}
\minordots
\end{devicelist}
\begin{devicelist}
\major{58}{}{char }{Hayes ESP serial card -- alternate devices}
\minor{0}{/dev/cup0}{Callout device corresponding to {\file ttyP0}}
\minor{1}{/dev/cup1}{Callout device corresponding to {\file ttyP1}}
\minordots
\end{devicelist}
\begin{devicelist}
\major{59}{}{}{Unallocated}
\end{devicelist}
\begin{devicelist}
......@@ -1182,9 +1215,9 @@ It is recommended that these links exist on all systems:
\link{/dev/ramdisk}{ram0}{symbolic}{Backward compatibility}
\link{/dev/ftape}{rft0}{symbolic}{Backward compatibility}
\link{/dev/scd?}{sr?}{hard}{Alternate name for CD-ROMs}
%\link{/dev/fd?H*}{fd?D*}{hard}{Compatible floppy formats}
%\link{/dev/fd?E*}{fd?D*}{hard}{Compatible floppy formats}
%\link{/dev/fd?E*}{fd?H*}{hard}{Compatible floppy formats}
\link{/dev/fd?D*}{fd?u*}{hard}{Backward compatibility}
\link{/dev/fd?H*}{fd?u*}{hard}{Backward compatibility}
\link{/dev/fd?E*}{fd?u*}{hard}{Backward compatibility}
\end{nodelist}
\subsection{Locally defined links}
......
......@@ -2,7 +2,7 @@
Maintained by H. Peter Anvin <hpa@zytor.com>
Last revised: July 9, 1996
Last revised: November 13, 1996
This list is the successor to Rick Miller's Linux Device List, which
he stopped maintaining when he got busy with other things in 1993. It
......@@ -269,6 +269,7 @@ reply.
5 = /dev/atarimouse Atari mouse
6 = /dev/sunmouse Sun mouse
7 = /dev/amigamouse1 Second Amiga mouse
8 = /dev/smouse Simple serial mouse driver
128 = /dev/beep Fancy beep device
129 = /dev/modreq Kernel module load request
130 = /dev/watchdog Watchdog timer port
......@@ -785,7 +786,26 @@ reply.
<mseritan@ottonel.pub.ro> to transfer data from Holter
24-hour heart monitoring equipment.
55-59 UNALLOCATED
55 char DSP56001 digital signal processor
0 = /dev/dsp56k First DSP56001
56 char Apple Desktop Bus
0 = /dev/adb ADB bus control
Additional devices will be added to this number, all
starting with /dev/adb.
57 char Hayes ESP serial card
0 = /dev/ttyP0 First ESP port
1 = /dev/ttyP1 Second ESP port
...
58 char Hayes ESP serial card - alternate devices
0 = /dev/cup0 Callout device corresponding to ttyP0
1 = /dev/cup1 Callout device corresponding to ttyP1
...
59 UNALLOCATED
60-63 LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not
......
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 9
SUBLEVEL = 10
ARCH = i386
......@@ -285,6 +285,7 @@ modules_install:
if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
if [ -f NET_MODULES ]; then inst_mod NET_MODULES net; fi; \
if [ -f IPV4_MODULES ]; then inst_mod IPV4_MODULES ipv4; fi; \
if [ -f IPV6_MODULES ]; then inst_mod IPV6_MODULES ipv6; fi; \
if [ -f SCSI_MODULES ]; then inst_mod SCSI_MODULES scsi; fi; \
if [ -f FS_MODULES ]; then inst_mod FS_MODULES fs; fi; \
if [ -f CDROM_MODULES ]; then inst_mod CDROM_MODULES cdrom; fi; \
......
......@@ -102,6 +102,7 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
# CONFIG_CHR_DEV_SG is not set
#
......@@ -123,9 +124,9 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_NCR53C406A is not set
......@@ -193,6 +194,7 @@ CONFIG_NFS_FS=y
CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_UFS_FS is not set
#
......
/*
* arch/alpha/lib/strlen_user.S
* arch/alpha/lib/__strlen_user.S
*
* Just like strlen except returns -EFAULT if an exception occurs
* before the terminator is found.
......@@ -13,7 +13,7 @@
99: x,##y; \
.section __ex_table,"a"; \
.gprel32 99b; \
lda zero, $exception-99b(v0); \
lda zero, $exception-99b(zero); \
.text
......@@ -21,12 +21,12 @@
.set noat
.text
.globl strlen_user
.ent strlen_user
.globl __strlen_user
.ent __strlen_user
.frame sp, 0, ra
.align 3
strlen_user:
__strlen_user:
.prologue 0
EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned)
......@@ -34,7 +34,7 @@ strlen_user:
insqh t1, a0, t1
andnot a0, 7, v0
or t1, t0, t0
nop # dual issue the next two on ev5
subq a0, 1, a0 # return "1+strlen" (0 for exception)
cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
bne t1, $found
......@@ -58,8 +58,10 @@ $found: negq t1, t2 # clear all but least set bit
nop # dual issue next two on ev4 and ev5
subq v0, a0, v0
ret
$exception:
mov zero, v0
ret
.end strlen_user
.end __strlen_user
......@@ -25,7 +25,7 @@ zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
if hash $(ENCAPS) 2> /dev/null; then \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(BZIMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
else \
$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
fi
......
......@@ -20,6 +20,7 @@ static struct symbol_table arch_symbol_table = {
X(dump_thread),
X(dump_fpu),
X(ioremap),
X(iounmap),
XNOVERS(__down_failed),
XNOVERS(__up_wakeup),
#ifdef __SMP__
......
......@@ -1013,7 +1013,7 @@ static void setup_DMA(void)
FDCS->reset = 1;
return;
}
if ((long) raw_cmd->kernel_data % 512){
if (((unsigned long) raw_cmd->kernel_data) % 512){
printk("non aligned address: %p\n", raw_cmd->kernel_data);
cont->done(0);
FDCS->reset=1;
......@@ -2541,7 +2541,8 @@ static int make_raw_rw_request(void)
}
/* 64 kb boundaries */
if (CROSS_64KB(CURRENT->buffer, max_size << 9))
max_size = (K_64 - ((long) CURRENT->buffer) % K_64)>>9;
max_size = (K_64 -
((unsigned long)CURRENT->buffer) % K_64)>>9;
direct = transfer_size(ssize,max_sector,max_size) - sector_t;
/*
* We try to read tracks, but if we get too many errors, we
......
......@@ -2647,8 +2647,8 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
return nslots;
}
void ide_cdrom_setup (ide_drive_t *drive)
static
int ide_cdrom_setup (ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
int nslots;
......@@ -2750,8 +2750,12 @@ void ide_cdrom_setup (ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities (drive);
if (ide_cdrom_register (drive, nslots))
printk ("%s: Can't register\n", drive->name);
if (ide_cdrom_register (drive, nslots)) {
printk ("%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
info->devinfo.handle = NULL;
return 1;
}
return 0;
}
/* Forwarding functions to generic routines. */
......@@ -2765,13 +2769,22 @@ int ide_cdrom_ioctl (ide_drive_t *drive,
int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
{
return cdrom_fops.open (ip, fp);
int rc;
MOD_INC_USE_COUNT;
rc = cdrom_fops.open (ip, fp);
if (rc) {
drive->usage--;
MOD_DEC_USE_COUNT;
}
return rc;
}
void ide_cdrom_release (struct inode *inode, struct file *file,
ide_drive_t *drive)
{
cdrom_fops.release (inode, file);
MOD_DEC_USE_COUNT;
}
int ide_cdrom_check_media_change (ide_drive_t *drive)
......@@ -2785,6 +2798,7 @@ int ide_cdrom_check_media_change (ide_drive_t *drive)
int ide_cdrom_cleanup(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
if (ide_unregister_subdriver (drive))
return 1;
......@@ -2792,6 +2806,8 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
kfree (info->sector_buffer);
if (info->toc != NULL)
kfree (info->toc);
if (devinfo->handle == drive && unregister_cdrom (devinfo))
printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
kfree (info);
drive->driver_data = NULL;
return 0;
......@@ -2860,10 +2876,17 @@ int ide_cdrom_init (void)
kfree (info);
continue;
}
failed--;
memset (info, 0, sizeof (struct cdrom_info));
drive->driver_data = info;
ide_cdrom_setup (drive);
DRIVER(drive)->busy++;
if (ide_cdrom_setup (drive)) {
DRIVER(drive)->busy--;
if (ide_cdrom_cleanup (drive))
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
continue;
}
DRIVER(drive)->busy--;
failed--;
}
ide_register_module(&ide_cdrom_module);
MOD_DEC_USE_COUNT;
......
......@@ -90,11 +90,11 @@ endif #CONFIG_GSCD
ifeq ($(CONFIG_CM206),y)
L_OBJS += cm206.o
C = 1
USE_GENERIC_CD=1
else
ifeq ($(CONFIG_CM206),m)
M_OBJS += cm206.o
CM = 1
USE_MODULAR_GENERIC_CD=1
endif
endif #CONFIG_CM206
......@@ -128,6 +128,14 @@ else
endif
endif #CONFIG_ISP16_CDI
ifeq ($(CONFIG_BLK_DEV_SR),y)
USE_GENERIC_CD=1
else
ifeq ($(CONFIG_BLK_DEV_SR),m)
USE_MODULAR_GENERIC_CD=1
endif
endif #SCSI CDROM DRIVER
ifeq ($(CONFIG_BLK_DEV_IDECD),y)
USE_GENERIC_CD=1
else
......
......@@ -268,13 +268,11 @@ int cdrom_media_changed(kdev_t dev)
meaningful format indicated above.
*/
#undef current /* set in sched.h */
static
void sanitize_format(union cdrom_addr *addr,
u_char * current, u_char requested)
u_char * curr, u_char requested)
{
if (*current == requested)
if (*curr == requested)
return; /* nothing to be done! */
if (requested == CDROM_LBA) {
addr->lba = (int) addr->msf.frame +
......@@ -287,7 +285,7 @@ void sanitize_format(union cdrom_addr *addr,
addr->msf.second = lba % 60;
addr->msf.minute = lba / 60;
}
*current = requested;
*curr = requested;
}
/* All checking and format change makes this code really hard to read!
......
......@@ -61,6 +61,10 @@
07 July 1995 Modifications by Andrew J. Kroll
Bjorn Ekwall <bj0rn@blox.se> added unregister_blkdev to mcd_init()
Michael K. Johnson <johnsonm@redhat.com> added retries on open
for slow drives which take a while to recognize that they contain
a CD.
*/
#include <linux/module.h>
......@@ -1095,6 +1099,7 @@ int
mcd_open(struct inode *ip, struct file *fp)
{
int st;
int count = 0;
if (mcdPresent == 0)
return -ENXIO; /* no hardware */
......@@ -1106,9 +1111,16 @@ mcd_open(struct inode *ip, struct file *fp)
mcd_invalidate_buffers();
st = statusCmd(); /* check drive status */
if (st == -1)
return -EIO; /* drive doesn't respond */
do {
st = statusCmd(); /* check drive status */
if (st == -1)
return -EIO; /* drive doesn't respond */
if ((st & MST_READY) == 0) { /* no disk? wait a sec... */
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + HZ;
schedule();
}
} while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
if ((st & MST_READY) == 0) /* no disk in drive */
{
......
Thu Nov 14 00:06:09 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (autoconfig): Fix autoconfiguration problems;
info->flags wasn't getting initialized from the state
structure. Put in more paranoid test for the 16750.
Fri Nov 8 20:19:50 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* n_tty.c (n_tty_flush_buffer): Only call driver->unthrottle() if
......
......@@ -50,7 +50,7 @@
#include <asm/bitops.h>
static char *serial_name = "Serial driver";
static char *serial_version = "4.20";
static char *serial_version = "4.21";
DECLARE_TASK_QUEUE(tq_serial);
......@@ -2687,7 +2687,7 @@ static int get_auto_irq(struct async_struct *info)
(void)serial_inp(info, UART_IIR);
(void)serial_inp(info, UART_MSR);
timeout = jiffies+2*HZ/100;
timeout = jiffies+ ((2*HZ)/100);
while (timeout >= jiffies) {
if (rs_irq_triggered)
break;
......@@ -2758,7 +2758,9 @@ static void autoconfig(struct serial_state * state)
if (!state->port)
return;
info = &scr_info; /* This is just for serial_{in,out} */
info->port = state->port;
info->magic = SERIAL_MAGIC;
info->port = state->port;
info->flags = state->flags;
save_flags(flags); cli();
......@@ -2848,8 +2850,13 @@ static void autoconfig(struct serial_state * state)
serial_outp(info, UART_FCR,
UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
scratch = serial_in(info, UART_IIR) >> 5;
if (scratch == 7)
state->type = PORT_16750;
if (scratch == 7) {
serial_outp(info, UART_LCR, 0);
serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
scratch = serial_in(info, UART_IIR) >> 5;
if (scratch == 7)
state->type = PORT_16750;
}
serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
}
serial_outp(info, UART_LCR, scratch2);
......
/* $Id: proto.h,v 1.1 1996/09/23 01:53:52 fritz Exp $
*
* not much now - just the l3 proto discriminator
*
* $Log: proto.h,v $
* Revision 1.1 1996/09/23 01:53:52 fritz
* Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
*
*/
#ifndef PROTO_H
#define PROTO_H
#define PROTO_EURO 0x08
#define PROTO_DIS_N0 0x40
#define PROTO_DIS_N1 0x41
#endif
......@@ -17,7 +17,8 @@
static char *version =
"tulip.c:v0.10 8/11/95 becker@cesdis.gsfc.nasa.gov\n"
" +0.72 4/17/96 "
"http://www.dsl.tutics.tut.ac.jp/~linux/tulip\n";
"http://www.dsl.tutics.tut.ac.jp/~linux/tulip\n"
" +0.01 10/24/96 mjacob@feral.com (2.1.7)\n";
/* A few user-configurable values. */
......@@ -334,6 +335,7 @@ struct tulip_private {
int setup_frame[48]; /* Pseudo-Tx frame to init address table. */
void (*port_select)(struct device *dev);
int (*port_fail)(struct device *dev);
struct device *next_module;
char *signature;
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
......@@ -367,7 +369,6 @@ static int tulip_rx(struct device *dev);
static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int tulip_close(struct device *dev);
static struct enet_statistics *tulip_get_stats(struct device *dev);
static struct device *tulip_alloc(struct device *dev);
static void set_multicast_list(struct device *dev);
#define generic21140_fail NULL
......@@ -379,6 +380,11 @@ static void cogent21140_select(struct device *dev);
static int generic21040_fail(struct device *dev);
static int generic21041_fail(struct device *dev);
#ifdef MODULE
/* A list of all installed Tulip devices, for removing the driver module. */
static struct device *root_tulip_dev = NULL;
#endif
static struct {
void (*port_select)(struct device *dev);
int (*port_fail)(struct device *dev);
......@@ -436,7 +442,6 @@ static struct {
#ifdef MODULE
static int if_port=TULIP_AUTO_PORT;
static size_t alloc_size;
#ifdef TULIP_FULL_DUPLEX
static int full_duplex=1;
#else
......@@ -1132,6 +1137,7 @@ static void set_multicast_list(struct device *dev)
*setup_frm++ = eaddrs[2];
} while (++i < 15);
#ifndef __alpha__
/* Now add this frame to the Tx list. */
{
unsigned long flags;
......@@ -1152,46 +1158,8 @@ static void set_multicast_list(struct device *dev)
/* Trigger an immediate transmit demand. */
tio_write(TPOLL_TRIGGER, CSR1);
}
}
}
static struct device *tulip_alloc(struct device *dev)
{
struct tulip_private *tp;
char *buff;
#ifndef MODULE
size_t alloc_size;
#endif
if (!dev || dev->priv) {
struct device *olddev = dev;
alloc_size = sizeof(struct device)
+ sizeof(struct tulip_private)
+ ETHNAMSIZ;
alloc_size = ROUND_UP(alloc_size, 8);
buff = (char *)kmalloc(alloc_size, GFP_KERNEL);
dev = (struct device *)buff;
if (dev == NULL) {
printk("tulip_alloc: kmalloc failed.\n");
return(NULL);
}
tp = (struct tulip_private *)(buff + sizeof(struct device));
memset(buff, 0, alloc_size);
dev->priv = (void *)tp;
dev->name = (char *)(buff + sizeof(struct device)
+ sizeof(struct tulip_private));
if (olddev) {
dev->next = olddev->next;
olddev->next = dev;
}
} else {
alloc_size = ROUND_UP(sizeof(struct tulip_private), 8);
tp = (struct tulip_private *)kmalloc(alloc_size, GFP_KERNEL);
memset((void *)tp, 0, alloc_size);
dev->priv = (void *)tp;
}
return(dev);
}
int
......@@ -1200,6 +1168,7 @@ tulip_hwinit(struct device *dev, int ioaddr,
{
/* See note below on the Znyx 315 etherarray. */
static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
static int last_irq;
char detect_mesg[80], *mesgp=detect_mesg;
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int i;
......@@ -1269,11 +1238,13 @@ tulip_hwinit(struct device *dev, int ioaddr,
for (i = 0; i < ETH_ALEN - 1; i++)
dev->dev_addr[i] = last_phys_addr[i];
dev->dev_addr[i] = last_phys_addr[i] + 1;
irq = last_irq;
}
for (i = 0; i < ETH_ALEN - 1; i++)
mesgp += sprintf(mesgp, "%2.2x:", dev->dev_addr[i]);
mesgp += sprintf(mesgp, "%2.2x, IRQ %d\n",
last_phys_addr[i] = dev->dev_addr[i], irq);
last_irq = irq;
/* copy ethernet address */
if (card_type(tp, device_id,
......@@ -1295,21 +1266,20 @@ tulip_hwinit(struct device *dev, int ioaddr,
dev->set_multicast_list = &set_multicast_list;
#ifdef MODULE
ether_setup(dev);
if (if_port == TULIP_AUTO_PORT)
if_port = TULIP_PORT;
else
tp->port_fix = 1;
dev->if_port = if_port;
tp->full_duplex = full_duplex;
tp->next_module = root_tulip_dev;
root_tulip_dev = dev;
#else
#ifdef TULIP_FULL_DUPLEX
tp->full_duplex = 1;
#endif
init_etherdev(dev, 0);
dev->if_port = TULIP_PORT;
#endif
#ifdef TULIP_FIX_PORT
tp->port_fix = 1;
#endif
......@@ -1340,14 +1310,13 @@ int tulip_probe(struct device *dev)
if (!pcibios_present()) return(-ENODEV);
for (pci_index = 0; pci_index < 8; pci_index++) {
for (pci_index = 0; pci_index < 0xff; pci_index++) {
/* Search for the PCI_DEVICE_ID_DEV_TULIP* chips */
for (cno = 0; pci_chips[cno] != PCI_DEVICE_ID_NONE; cno ++)
for (cno = 0; pci_chips[cno] != PCI_DEVICE_ID_NONE; cno++) {
if (pcibios_find_device(PCI_VENDOR_ID_DEC,
pci_chips[cno],
pci_index, &pci_bus,
&pci_device_fn) == 0) {
struct device *dp;
/* get IO address */
pcibios_read_config_dword(pci_bus, pci_device_fn,
......@@ -1355,19 +1324,14 @@ int tulip_probe(struct device *dev)
&pci_ioaddr);
/* Remove I/O space marker in bit 0. */
pci_ioaddr &= ~3;
for (dp = tulip_head; dp != NULL; dp = dp->next)
if (dp->base_addr == pci_ioaddr) break;
if (dp) continue;
/* get IRQ */
pcibios_read_config_byte(pci_bus, pci_device_fn,
PCI_INTERRUPT_LINE, &pci_irq);
#ifdef MODULE
/* compare requested IRQ/IO address */
if (dev && dev->base_addr &&
dev->base_addr != pci_ioaddr) continue;
#else
if ((dev = tulip_alloc(dev)) == NULL) break;
#endif
pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pci_irq);
dev = init_etherdev(NULL,
ROUND_UP(sizeof(struct device) +
sizeof (struct tulip_private) +
ETHNAMSIZ, 8));
if (dev == NULL) break;
if (!tulip_head) {
printk(version);
tulip_head = dev;
......@@ -1394,56 +1358,48 @@ int tulip_probe(struct device *dev)
PCI_LATENCY_TIMER, 100);
}
if (tulip_hwinit(dev, pci_ioaddr, pci_irq,
pci_chips[cno]) < 0) continue;
num ++;
#ifdef MODULE
return(0);
#endif
pci_chips[cno]) < 0) {
continue;
}
num++;
#ifdef TULIP_MAX_CARDS
if (num >= TULIP_MAX_CARDS) return(0);
#endif
}
}
}
return(num > 0 ? 0: -ENODEV);
}
#ifdef MODULE
#ifdef __alpha__
#if 1
static int io = 0xb000;
#else
static int io = 0x10400;
#endif
#else
static int io = 0xfc80;
#endif
static struct device *mod_dev;
/* The parameters that may be passed in... */
/* This driver does nothing with options yet. It will later be used to
pass the full-duplex flag, etc. */
int debug = -1;
int init_module(void)
int
init_module(void)
{
if ((mod_dev = tulip_alloc(0)) == NULL) return(-EIO);
mod_dev->base_addr = io;
mod_dev->irq = 0;
mod_dev->init = &tulip_probe;
if (register_netdev(mod_dev)) {
printk("tulip: register_netdev() returned non-zero.\n");
kfree_s(mod_dev, alloc_size);
return -EIO;
}
return(0);
root_tulip_dev = NULL;
return tulip_probe(NULL);
}
void
cleanup_module(void)
{
release_region(mod_dev->base_addr, TULIP_TOTAL_SIZE);
unregister_netdev(mod_dev);
kfree_s(mod_dev, alloc_size);
struct device *next_dev;
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
while (root_tulip_dev) {
next_dev =
((struct tulip_private *) root_tulip_dev->priv)->next_module;
unregister_netdev(root_tulip_dev);
release_region(root_tulip_dev->base_addr, TULIP_TOTAL_SIZE);
kfree(root_tulip_dev);
root_tulip_dev = next_dev;
}
}
#endif /* MODULE */
......
......@@ -3,6 +3,9 @@ comment 'SCSI support type (disk, tape, CD-ROM)'
dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
dep_tristate 'SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
bool ' Enable vendor-specific extentions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
fi
dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
......
......@@ -58,8 +58,12 @@ else
endif
endif
ifeq ($(CONFIG_BLK_DEV_SR_VENDOR),y)
SR_VENDOR = sr_vendor.o
endif
ifeq ($(CONFIG_BLK_DEV_SR),y)
L_OBJS += sr.o sr_ioctl.o
L_OBJS += sr.o sr_ioctl.o $(SR_VENDOR)
else
ifeq ($(CONFIG_BLK_DEV_SR),m)
M_OBJS += sr_mod.o
......@@ -376,8 +380,8 @@ scsi_mod.o: $(MX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o \
scsicam.o scsi_proc.o
$(LD) $(LD_RFLAG) -r -o $@ $(MX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o
sr_mod.o: sr.o sr_ioctl.o
$(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o
sr_mod.o: sr.o sr_ioctl.o $(SR_VENDOR)
$(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o $(SR_VENDOR)
sd_mod.o: sd.o sd_ioctl.o
$(LD) $(LD_RFLAG) -r -o $@ sd.o sd_ioctl.o
This diff is collapsed.
......@@ -642,26 +642,6 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
scsi_result[1] |= 0x80; /* removable */
}
if (!strncmp (scsi_result + 8, "NEC", 3)) {
if (!strncmp (scsi_result + 16, "CD-ROM DRIVE:84 ", 16) ||
!strncmp (scsi_result + 16, "CD-ROM DRIVE:25", 15))
SDpnt->manufacturer = SCSI_MAN_NEC_OLDCDR;
else
SDpnt->manufacturer = SCSI_MAN_NEC;
}
else if (!strncmp (scsi_result + 8, "TOSHIBA", 7))
SDpnt->manufacturer = SCSI_MAN_TOSHIBA;
else if (!strncmp (scsi_result + 8, "SONY", 4))
SDpnt->manufacturer = SCSI_MAN_SONY;
else if (!strncmp (scsi_result + 8, "PIONEER", 7))
SDpnt->manufacturer = SCSI_MAN_PIONEER;
else if (!strncmp (scsi_result + 8, "MATSHITA", 8))
SDpnt->manufacturer = SCSI_MAN_MATSHITA;
else if (!strncmp (scsi_result + 8, "HP", 2))
SDpnt->manufacturer = SCSI_MAN_HP;
else
SDpnt->manufacturer = SCSI_MAN_UNKNOWN;
memcpy (SDpnt->vendor, scsi_result + 8, 8);
memcpy (SDpnt->model, scsi_result + 16, 16);
memcpy (SDpnt->rev, scsi_result + 32, 4);
......
......@@ -122,19 +122,6 @@ extern const unsigned char scsi_command_size[8];
* as the LUN.
*/
/*
* Manufacturers list
*/
#define SCSI_MAN_UNKNOWN 0
#define SCSI_MAN_NEC 1
#define SCSI_MAN_TOSHIBA 2
#define SCSI_MAN_NEC_OLDCDR 3
#define SCSI_MAN_SONY 4
#define SCSI_MAN_PIONEER 5
#define SCSI_MAN_MATSHITA 6
#define SCSI_MAN_HP 7
/*
* As the scsi do command functions are intelligent, and may need to
* redo a command, we need to keep track of the last command
......
......@@ -37,6 +37,7 @@
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
#define MAJOR_NR SCSI_DISK_MAJOR
#include <linux/blk.h>
......@@ -660,10 +661,10 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
* a bounce buffer if we are straddling the 16Mb line
*/
if (contiguous && SCpnt->request.bh &&
((long) SCpnt->request.bh->b_data)
virt_to_phys(SCpnt->request.bh->b_data)
+ (SCpnt->request.nr_sectors << 9) - 1 > ISA_DMA_THRESHOLD
&& SCpnt->host->unchecked_isa_dma) {
if(((long) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
if(virt_to_phys(SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
bounce_buffer = (char *) scsi_malloc(bounce_size);
if(!bounce_buffer) contiguous = 0;
}
......@@ -720,7 +721,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) ||
!CLUSTERABLE_DEVICE(SCpnt) ||
(SCpnt->host->unchecked_isa_dma &&
((unsigned long) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
virt_to_phys(bh->b_data-1) == ISA_DMA_THRESHOLD)) {
if (count < SCpnt->host->sg_tablesize) count++;
else break;
}
......@@ -730,7 +731,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
}
#if 0
if(SCpnt->host->unchecked_isa_dma &&
((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
virt_to_phys(SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
#endif
SCpnt->use_sg = count; /* Number of chains */
/* scsi_malloc can only allocate in chunks of 512 bytes */
......@@ -762,7 +763,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
sgpnt[count].length += bh->b_size;
counted += bh->b_size >> 9;
if (((long) sgpnt[count].address) + sgpnt[count].length - 1 >
if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length - 1 >
ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
!sgpnt[count].alt_address) {
sgpnt[count].alt_address = sgpnt[count].address;
......@@ -809,7 +810,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
&& CLUSTERABLE_DEVICE(SCpnt)) {
char * tmp;
if (((long) sgpnt[count].address) + sgpnt[count].length +
if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length +
bhp->b_size - 1 > ISA_DMA_THRESHOLD &&
(SCpnt->host->unchecked_isa_dma) &&
!sgpnt[count].alt_address) continue;
......@@ -871,7 +872,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
/* Now handle the possibility of DMA to addresses > 16Mb */
if(SCpnt->use_sg == 0){
if (((long) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD &&
if (virt_to_phys(buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD &&
(SCpnt->host->unchecked_isa_dma)) {
if(bounce_buffer)
buff = bounce_buffer;
......
This diff is collapsed.
......@@ -17,24 +17,45 @@
#ifndef _SR_H
#define _SR_H
#include <linux/config.h>
#include "scsi.h"
typedef struct
{
unsigned capacity; /* size in blocks */
unsigned sector_size; /* size in bytes */
Scsi_Device *device;
unsigned long mpcd_sector; /* for reading multisession-CD's */
char xa_flags; /* some flags for handling XA-CD's */
Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
unsigned long ms_offset; /* for reading multisession-CD's */
unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */
unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift*/
unsigned needs_sector_size:1; /* needs to get sector size */
unsigned ten:1; /* support ten byte commands */
unsigned remap:1; /* support remapping */
unsigned use:1; /* is this device still supportable */
unsigned auto_eject:1; /* auto-eject medium on last release. */
unsigned xa_flag:1; /* CD has XA sectors */
struct cdrom_device_info cdi;
} Scsi_CD;
extern Scsi_CD * scsi_CDs;
int sr_do_ioctl(int, unsigned char*, void*, unsigned);
int sr_lock_door(struct cdrom_device_info*, int);
int sr_tray_move(struct cdrom_device_info*, int);
int sr_drive_status(struct cdrom_device_info*, int);
int sr_disk_status(struct cdrom_device_info*);
int sr_get_last_session(struct cdrom_device_info*, struct cdrom_multisession*);
int sr_get_mcn(struct cdrom_device_info*, struct cdrom_mcn*);
int sr_reset(struct cdrom_device_info*);
int sr_audio_ioctl(struct cdrom_device_info*, unsigned int, void*);
int sr_dev_ioctl(struct cdrom_device_info*, unsigned int, unsigned long);
/* vendor-specific */
#ifdef CONFIG_BLK_DEV_SR_VENDOR
void sr_vendor_init(int minor);
int sr_cd_check(struct cdrom_device_info*);
#endif
#endif
This diff is collapsed.
/* -*-linux-c-*-
*
* vendor-specific code for SCSI CD-ROM's goes here.
*
* This is needed becauce most of the new features (multisession and
* the like) are to new to be included into the SCSI-II standard (to
* be exact: there is'nt anything in my draft copy).
*
* Gerd Knorr <kraxel@cs.tu-berlin.de>
*/
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/blk.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_ioctl.h>
#include <linux/cdrom.h>
#include <linux/ucdrom.h>
#include "sr.h"
/* here are some constants to sort the vendors into groups */
#define VENDOR_CAN_NOT_HANDLE 1 /* don't know how to handle */
#define VENDOR_NEC 2
#define VENDOR_TOSHIBA 3
#define VENDOR_SONY_LIKE 4 /* much drives are Sony compatible */
#define VENDOR_HP 5
#define DEBUG
void
sr_vendor_init(int minor)
{
char *vendor = scsi_CDs[minor].device->vendor;
char *model = scsi_CDs[minor].device->model;
if (!strncmp (vendor, "NEC", 3)) {
scsi_CDs[minor].vendor = VENDOR_NEC;
if (!strncmp (model,"CD-ROM DRIVE:25", 15) ||
!strncmp (model,"CD-ROM DRIVE:36", 15) ||
!strncmp (model,"CD-ROM DRIVE:83", 15) ||
!strncmp (model,"CD-ROM DRIVE:84 ",16))
/* these can't handle multisession, may hang */
scsi_CDs[minor].cdi.mask |= CDC_MULTI_SESSION;
} else if (!strncmp (vendor, "TOSHIBA", 7)) {
scsi_CDs[minor].vendor = VENDOR_TOSHIBA;
} else if (!strncmp (vendor, "HP", 2)) {
scsi_CDs[minor].vendor = VENDOR_HP;
} else {
/* most drives can handled like sony ones, so we take
* it as default */
scsi_CDs[minor].vendor = VENDOR_SONY_LIKE;
}
}
/*
* support for XA/multisession-CD's
*
* - NEC: Detection and support of multisession CD's.
*
* - TOSHIBA: Detection and support of multisession CD's.
* Some XA-Sector tweaking, required for older drives.
*
* - SONY: Detection and support of multisession CD's.
* added by Thomas Quinot <operator@melchior.cuivre.fdn.fr>
*
* - PIONEER, HITACHI, PLEXTOR, MATSHITA: known to work with SONY code.
*
* - HP: Much like SONY, but a little different... (Thomas)
* HP-Writers only ???
*/
#define BCD_TO_BIN(x) ((((int)x & 0xf0) >> 4)*10 + ((int)x & 0x0f))
int sr_cd_check(struct cdrom_device_info *cdi)
{
unsigned long sector,min,sec,frame;
unsigned char *buffer; /* the buffer for the ioctl */
unsigned char cmd[12]; /* the scsi-command */
int rc,is_xa,no_multi,minor;
minor = MINOR(cdi->dev);
buffer = (unsigned char *) scsi_malloc(512);
if(!buffer) return -ENOMEM;
sector = 0; /* the multisession sector offset goes here */
is_xa = 0; /* flag: the CD uses XA-Sectors */
no_multi = 0; /* flag: the drive can't handle multisession */
rc = 0;
switch(scsi_CDs[minor].vendor) {
case VENDOR_NEC:
memset(cmd,0,12);
cmd[0] = 0xde;
cmd[1] = (scsi_CDs[minor].device->lun << 5) | 0x03;
cmd[2] = 0xb0;
rc = sr_do_ioctl(minor, cmd, buffer, 0x16);
if (rc != 0)
break;
if (buffer[14] != 0 && buffer[14] != 0xb0) {
printk(KERN_INFO "sr (nec): Hmm, seems the cdrom doesn't support multisession CD's\n");
no_multi = 1;
break;
}
min = BCD_TO_BIN(buffer[15]);
sec = BCD_TO_BIN(buffer[16]);
frame = BCD_TO_BIN(buffer[17]);
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
is_xa = (buffer[14] == 0xb0);
break;
case VENDOR_TOSHIBA:
/* we request some disc information (is it a XA-CD ?,
* where starts the last session ?) */
memset(cmd,0,12);
cmd[0] = 0xc7;
cmd[1] = (scsi_CDs[minor].device->lun << 5) | 3;
rc = sr_do_ioctl(minor, cmd, buffer, 4);
if (rc == 0x28000002 &&
!scsi_ioctl(scsi_CDs[minor].device,
SCSI_IOCTL_TEST_UNIT_READY, NULL)) {
printk(KERN_INFO "sr (toshiba): Hmm, seems the drive doesn't support multisession CD's\n");
no_multi = 1;
break;
}
if (rc != 0)
break;
min = BCD_TO_BIN(buffer[1]);
sec = BCD_TO_BIN(buffer[2]);
frame = BCD_TO_BIN(buffer[3]);
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
if (sector)
sector -= CD_BLOCK_OFFSET;
is_xa = (buffer[0] == 0x20);
#if 0
/* this is required for some CD's:
* - Enhanced-CD (Hardware tells wrong XA-flag)
* - these broken non-XA multisession CD's
*/
if (is_xa == 0 && sector != 0) {
printk(KERN_WARNING "Warning: multisession offset "
"found, setting XA-flag\n");
is_xa = 1;
}
#endif
/* now the XA-Sector tweaking: set_density... */
memset(cmd,0,12);
cmd[0] = MODE_SELECT;
cmd[1] = (scsi_CDs[minor].device->lun << 5)
| (1 << 4);
cmd[4] = 12;
memset(buffer,0,12);
buffer[ 3] = 0x08;
buffer[ 4] = 0x83;
buffer[10] = 0x08;
rc = sr_do_ioctl(minor, cmd, buffer, 12);
if (rc != 0) {
break;
}
#if 0
/* shoult'nt be required any more */
scsi_CDs[minor].needs_sector_size = 1;
#endif
break;
case VENDOR_HP:
cmd[0] = READ_TOC;
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[8] = 0x04;
cmd[9] = 0x40;
rc = sr_do_ioctl(minor, cmd, buffer, 12);
if (rc != 0) {
break;
}
if ((rc = buffer[2]) == 0) {
printk (KERN_WARNING
"sr (hp): No finished session\n");
break;
}
cmd[0] = READ_TOC; /* Read TOC */
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[6] = rc & 0x7f; /* number of last session */
cmd[8] = 0x0c;
cmd[9] = 0x40;
rc = sr_do_ioctl(minor, cmd, buffer, 12);
if (rc != 0) {
break;
}
#undef STRICT_HP
#ifdef STRICT_HP
sector = buffer[11] + (buffer[10] << 8) + (buffer[9] << 16);
/* HP documentation states that Logical Start Address is
returned as three (!) bytes, and that buffer[8] is
reserved. This is strange, because a LBA usually is
4 bytes long. */
#else
sector = buffer[11] + (buffer[10] << 8) +
(buffer[9] << 16) + (buffer[8] << 24);
#endif
is_xa = !!sector;
break;
case VENDOR_SONY_LIKE:
/* Thomas QUINOT <thomas@melchior.cuivre.fdn.fr> */
#ifdef DEBUG
printk(KERN_DEBUG
"sr: use \"Sony group\" multisession code\n");
#endif
memset(cmd,0,12);
cmd[0] = READ_TOC;
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[8] = 12;
cmd[9] = 0x40;
rc = sr_do_ioctl(minor, cmd, buffer, 12);
if (rc != 0) {
break;
}
if ((buffer[0] << 8) + buffer[1] != 0x0a) {
printk(KERN_INFO "sr (sony): Hmm, seems the drive doesn't support multisession CD's\n");
no_multi = 1;
break;
}
sector = buffer[11] + (buffer[10] << 8) +
(buffer[9] << 16) + (buffer[8] << 24);
if (buffer[6] <= 1) {
/* ignore sector offsets from first track */
sector = 0;
}
is_xa = !!sector;
break;
case VENDOR_CAN_NOT_HANDLE:
sector = 0;
no_multi = 1;
break;
default:
/* should not happen */
printk(KERN_WARNING
"sr: unknown vendor code (%i), not initialized ?\n",
scsi_CDs[minor].vendor);
sector = 0;
no_multi = 1;
break;
}
#ifdef DEBUG
if (sector)
printk(KERN_DEBUG
"sr: multisession CD detected, offset: %lu\n",sector);
#endif
scsi_CDs[minor].ms_offset = sector;
scsi_CDs[minor].xa_flag = is_xa;
if (no_multi)
cdi->mask |= CDC_MULTI_SESSION;
scsi_free(buffer, 512);
return rc;
}
......@@ -144,20 +144,14 @@ unsigned long * create_elf_tables(char *p, int argc, int envc,
__put_user((unsigned long)argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
char c;
__put_user(p,argv++);
do {
get_user(c,p++);
} while (c);
p += strlen_user(p);
}
__put_user(NULL, argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
char c;
__put_user(p,envp++);
do {
get_user(c,p++);
} while (c);
p += strlen_user(p);
}
__put_user(NULL, envp);
current->mm->env_end = (unsigned long) p;
......
......@@ -35,6 +35,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/bitops.h>
#define NR_SIZES 5
static char buffersize_index[17] =
......@@ -169,7 +170,7 @@ static int sync_buffers(kdev_t dev, int wait)
there to be dirty buffers on any of the other lists. */
bh = lru_list[BUF_DIRTY];
if (!bh)
break;
goto repeat2;
for (i = nr_buffers_type[BUF_DIRTY]*2 ; i-- > 0 ; bh = next) {
if (bh->b_list != BUF_DIRTY)
goto repeat;
......@@ -1865,6 +1866,32 @@ unsigned long generate_cluster(kdev_t dev, int b[], int size)
return reassign_cluster(dev, b[0], size);
}
unsigned long generate_cluster_swab32(kdev_t dev, int b[], int size)
{
int i, offset;
for (i = 0, offset = 0 ; offset < PAGE_SIZE ; i++, offset += size) {
if(i && le32_to_cpu(b[i])-1 !=
le32_to_cpu(b[i-1])) return 0; /* No need to cluster */
if(find_buffer(dev, le32_to_cpu(b[i]), size)) return 0;
};
/* OK, we have a candidate for a new cluster */
/* See if one size of buffer is over-represented in the buffer cache,
if so reduce the numbers of buffers */
if(maybe_shrink_lav_buffers(size))
{
int retval;
retval = try_to_generate_cluster(dev, le32_to_cpu(b[0]), size);
if(retval) return retval;
};
if (nr_free_pages > min_free_pages*2)
return try_to_generate_cluster(dev, le32_to_cpu(b[0]), size);
else
return reassign_cluster(dev, le32_to_cpu(b[0]), size);
}
/* ===================== Init ======================= */
......
......@@ -178,27 +178,23 @@ asmlinkage int sys_uselib(const char * library)
/*
* count() counts the number of arguments/envelopes
*
* We also do some limited EFAULT checking: this isn't complete, but
* it does cover most cases. I'll have to do this correctly some day..
*/
static int count(char ** argv)
{
int error, i = 0;
char ** tmp, *p;
int i = 0;
if ((tmp = argv) != NULL) {
error = verify_area(VERIFY_READ, tmp, sizeof(char *));
if (error)
return error;
if (argv != NULL) {
for (;;) {
get_user(p,tmp++);
char * p;
int error;
error = get_user(p,argv);
if (error)
return error;
if (!p)
break;
argv++;
i++;
error = verify_area(VERIFY_READ, p, 1);
if (error)
return error;
}
}
return i;
......@@ -224,60 +220,51 @@ static int count(char ** argv)
unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
char *tmp, *tmp1, *pag = NULL;
int len, offset = 0;
unsigned long old_fs, new_fs;
char *str;
unsigned long old_fs;
if (!p)
return 0; /* bullet-proofing */
new_fs = get_ds();
old_fs = get_fs();
if (from_kmem==2)
set_fs(new_fs);
set_fs(KERNEL_DS);
while (argc-- > 0) {
int len;
unsigned long pos;
if (from_kmem == 1)
set_fs(new_fs);
get_user(tmp, argv+argc);
if (!tmp)
set_fs(KERNEL_DS);
get_user(str, argv+argc);
if (!str)
panic("VFS: argc is wrong");
tmp1 = tmp;
if (from_kmem == 1)
set_fs(old_fs);
for (;;) {
char c;
get_user(c,tmp++);
if (!c)
break;
}
len = tmp - tmp1;
len = strlen_user(str); /* includes the '\0' */
if (p < len) { /* this shouldn't happen - 128kB */
set_fs(old_fs);
return 0;
}
p -= len;
pos = p;
while (len) {
--p; --tmp; --len;
if (--offset < 0) {
offset = p % PAGE_SIZE;
char *pag;
int offset, bytes_to_copy;
offset = pos % PAGE_SIZE;
if (!(pag = (char *) page[pos/PAGE_SIZE]) &&
!(pag = (char *) page[pos/PAGE_SIZE] =
(unsigned long *) get_free_page(GFP_USER))) {
if (from_kmem==2)
set_fs(old_fs);
if (!(pag = (char *) page[p/PAGE_SIZE]) &&
!(pag = (char *) page[p/PAGE_SIZE] =
(unsigned long *) get_free_page(GFP_USER)))
return 0;
if (from_kmem==2)
set_fs(new_fs);
}
if (len == 0 || offset == 0)
get_user(*(pag + offset), tmp);
else {
int bytes_to_copy = (len > offset) ? offset : len;
tmp -= bytes_to_copy;
p -= bytes_to_copy;
offset -= bytes_to_copy;
len -= bytes_to_copy;
copy_from_user(pag + offset, tmp, bytes_to_copy + 1);
return 0;
}
bytes_to_copy = PAGE_SIZE - offset;
if (bytes_to_copy > len)
bytes_to_copy = len;
copy_from_user(pag + offset, str, bytes_to_copy);
pos += bytes_to_copy;
str += bytes_to_copy;
len -= bytes_to_copy;
}
}
if (from_kmem==2)
......
This diff is collapsed.
......@@ -13,6 +13,9 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*
* ext2 directory handling functions
*
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
*/
#include <asm/uaccess.h>
......@@ -77,23 +80,24 @@ int ext2_check_dir_entry (const char * function, struct inode * dir,
{
const char * error_msg = NULL;
if (de->rec_len < EXT2_DIR_REC_LEN(1))
if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
error_msg = "rec_len is smaller than minimal";
else if (de->rec_len % 4 != 0)
else if (le16_to_cpu(de->rec_len) % 4 != 0)
error_msg = "rec_len % 4 != 0";
else if (de->rec_len < EXT2_DIR_REC_LEN(de->name_len))
else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(le16_to_cpu(de->name_len)))
error_msg = "rec_len is too small for name_len";
else if (dir && ((char *) de - bh->b_data) + de->rec_len >
else if (dir && ((char *) de - bh->b_data) + le16_to_cpu(de->rec_len) >
dir->i_sb->s_blocksize)
error_msg = "directory entry across blocks";
else if (dir && de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count)
else if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
error_msg = "inode out of bounds";
if (error_msg != NULL)
ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
dir->i_ino, error_msg, offset, (unsigned long) de->inode,
de->rec_len, de->name_len);
dir->i_ino, error_msg, offset,
(unsigned long) le32_to_cpu(de->inode),
le16_to_cpu(de->rec_len), le16_to_cpu(de->name_len));
return error_msg == NULL ? 1 : 0;
}
......@@ -161,9 +165,9 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
* least that it is non-zero. A
* failure will be detected in the
* dirent test below. */
if (de->rec_len < EXT2_DIR_REC_LEN(1))
if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
break;
i += de->rec_len;
i += le16_to_cpu(de->rec_len);
}
offset = i;
filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
......@@ -183,8 +187,8 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
brelse (bh);
return stored;
}
offset += de->rec_len;
if (de->inode) {
offset += le16_to_cpu(de->rec_len);
if (le32_to_cpu(de->inode)) {
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
......@@ -192,16 +196,17 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
* not the directory has been modified
* during the copy operation. */
unsigned long version;
dcache_add(inode, de->name, de->name_len, de->inode);
dcache_add(inode, de->name, le16_to_cpu(de->name_len),
le32_to_cpu(de->inode));
version = inode->i_version;
error = filldir(dirent, de->name, de->name_len, filp->f_pos, de->inode);
error = filldir(dirent, de->name, le16_to_cpu(de->name_len), filp->f_pos, le32_to_cpu(de->inode));
if (error)
break;
if (version != inode->i_version)
goto revalidate;
stored ++;
}
filp->f_pos += de->rec_len;
filp->f_pos += le16_to_cpu(de->rec_len);
}
offset = 0;
brelse (bh);
......
......@@ -10,6 +10,9 @@
* linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds
*
* ext2fs fsync primitive
*
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
*/
#include <asm/uaccess.h>
......@@ -27,7 +30,7 @@
#define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
#define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
static int sync_block (struct inode * inode, u32 * block, int wait)
static __inline__ int sync_block (struct inode * inode, u32 * block, int wait)
{
struct buffer_head * bh;
int tmp;
......@@ -55,7 +58,35 @@ static int sync_block (struct inode * inode, u32 * block, int wait)
return 0;
}
static int sync_iblock (struct inode * inode, u32 * iblock,
static __inline__ int sync_block_swab32 (struct inode * inode, u32 * block, int wait)
{
struct buffer_head * bh;
int tmp;
if (!le32_to_cpu(*block))
return 0;
tmp = le32_to_cpu(*block);
bh = get_hash_table (inode->i_dev, le32_to_cpu(*block), blocksize);
if (!bh)
return 0;
if (le32_to_cpu(*block) != tmp) {
brelse (bh);
return 1;
}
if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
brelse (bh);
return -1;
}
if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
brelse (bh);
return 0;
}
ll_rw_block (WRITE, 1, &bh);
bh->b_count--;
return 0;
}
static __inline__ int sync_iblock (struct inode * inode, u32 * iblock,
struct buffer_head ** bh, int wait)
{
int rc, tmp;
......@@ -78,8 +109,31 @@ static int sync_iblock (struct inode * inode, u32 * iblock,
return 0;
}
static __inline__ int sync_iblock_swab32 (struct inode * inode, u32 * iblock,
struct buffer_head ** bh, int wait)
{
int rc, tmp;
*bh = NULL;
tmp = le32_to_cpu(*iblock);
if (!tmp)
return 0;
rc = sync_block_swab32 (inode, iblock, wait);
if (rc)
return rc;
*bh = bread (inode->i_dev, tmp, blocksize);
if (tmp != le32_to_cpu(*iblock)) {
brelse (*bh);
*bh = NULL;
return 1;
}
if (!*bh)
return -1;
return 0;
}
static int sync_direct (struct inode * inode, int wait)
static __inline__ int sync_direct (struct inode * inode, int wait)
{
int i;
int rc, err = 0;
......@@ -94,7 +148,7 @@ static int sync_direct (struct inode * inode, int wait)
return err;
}
static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
static __inline__ int sync_indirect (struct inode * inode, u32 * iblock, int wait)
{
int i;
struct buffer_head * ind_bh;
......@@ -105,9 +159,9 @@ static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
return rc;
for (i = 0; i < addr_per_block; i++) {
rc = sync_block (inode,
((u32 *) ind_bh->b_data) + i,
wait);
rc = sync_block_swab32 (inode,
((u32 *) ind_bh->b_data) + i,
wait);
if (rc > 0)
break;
if (rc)
......@@ -117,7 +171,30 @@ static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
return err;
}
static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
static __inline__ int sync_indirect_swab32 (struct inode * inode, u32 * iblock, int wait)
{
int i;
struct buffer_head * ind_bh;
int rc, err = 0;
rc = sync_iblock_swab32 (inode, iblock, &ind_bh, wait);
if (rc || !ind_bh)
return rc;
for (i = 0; i < addr_per_block; i++) {
rc = sync_block_swab32 (inode,
((u32 *) ind_bh->b_data) + i,
wait);
if (rc > 0)
break;
if (rc)
err = rc;
}
brelse (ind_bh);
return err;
}
static __inline__ int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
{
int i;
struct buffer_head * dind_bh;
......@@ -128,9 +205,32 @@ static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
return rc;
for (i = 0; i < addr_per_block; i++) {
rc = sync_indirect (inode,
((u32 *) dind_bh->b_data) + i,
wait);
rc = sync_indirect_swab32 (inode,
((u32 *) dind_bh->b_data) + i,
wait);
if (rc > 0)
break;
if (rc)
err = rc;
}
brelse (dind_bh);
return err;
}
static __inline__ int sync_dindirect_swab32 (struct inode * inode, u32 * diblock, int wait)
{
int i;
struct buffer_head * dind_bh;
int rc, err = 0;
rc = sync_iblock_swab32 (inode, diblock, &dind_bh, wait);
if (rc || !dind_bh)
return rc;
for (i = 0; i < addr_per_block; i++) {
rc = sync_indirect_swab32 (inode,
((u32 *) dind_bh->b_data) + i,
wait);
if (rc > 0)
break;
if (rc)
......@@ -140,7 +240,7 @@ static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
return err;
}
static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
static __inline__ int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
{
int i;
struct buffer_head * tind_bh;
......@@ -151,9 +251,9 @@ static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
return rc;
for (i = 0; i < addr_per_block; i++) {
rc = sync_dindirect (inode,
((u32 *) tind_bh->b_data) + i,
wait);
rc = sync_dindirect_swab32 (inode,
((u32 *) tind_bh->b_data) + i,
wait);
if (rc > 0)
break;
if (rc)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -118,6 +118,7 @@ struct sockaddr_in {
#define INADDR_ALLHOSTS_GROUP 0xe0000001 /* 224.0.0.1 */
#define INADDR_MAX_LOCAL_GROUP 0xe00000ff /* 224.0.0.255 */
/* <asm/byteorder.h> contains the htonl type stuff.. */
#include <asm/byteorder.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment