Commit f454324e authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.48pre4

parent cb8ca05c
...@@ -1672,20 +1672,62 @@ CONFIG_SCSI_AHA1740 ...@@ -1672,20 +1672,62 @@ CONFIG_SCSI_AHA1740
want to compile it as a module, say M here and read want to compile it as a module, say M here and read
Documentation/modules.txt. Documentation/modules.txt.
Adaptec AHA274X/284X/294X support Adaptec AIC7xxx support (includes 274x/284x/294x)
CONFIG_SCSI_AIC7XXX CONFIG_SCSI_AIC7XXX
Information about this SCSI host adapter is contained in Information about this SCSI host adapter is contained in
drivers/scsi/README.aic7xxx and in the SCSI-HOWTO, available via ftp drivers/scsi/README.aic7xxx and in the SCSI-HOWTO, available via ftp
(user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that
doesn't work out of the box, you may have to change some settings in the AHA2920 SCSI host adapter is *not* supported by this driver; choose
drivers/scsi/aic7xxx.h. It has been reported that the "wide "Future Domain 16xx SCSI support" instead. If you want to compile this
negotiation" on these cards is not quite working and should be driver as module ( = code which can be inserted in and removed from the
disabled. Note that the AHA2920 SCSI host adapter is *not* supported running kernel whenever you want), say M here and read Documentation/
by this driver; choose "Future Domain 16xx SCSI support" instead. If modules.txt. The module will be called aic7xxx.o.
you want to compile this driver a module ( = code which can be
inserted in and removed from the running kernel whenever you want), Enable tagged command queueing
say M here and read Documentation/modules.txt. The module will be CONFIG_AIC7XXX_TAGGED_QUEUEING
called aic7xxx.o. This option allows you to enable tagged command queueing for this
driver. Some scsi devices do not properly support this
feature. Tagged command queueing will improve performance.
Maximum number of commands per LUN
CONFIG_AIC7XXX_CMDS_PER_LUN
This option allows you to set the maximum number of commands queued
per LUN. If tagged queueing is enabled, then you may want to try
increasing AIC7XXX_CMDS_PER_LUN to more than 2. By default, we limit
the SCBs per LUN to 2 with or without tagged queueing enabled. If
tagged queueing is disabled, the sequencer will keep the 2nd SCB in
the input queue until the first one completes - so it is OK to to have
more than 1 SCB queued. If tagged queueing is enabled, then the
sequencer will attempt to send the 2nd SCB to the device while the
first SCB is executing and the device is disconnected. For adapters
limited to 4 SCBs, you may want to actually decrease the commands per
LUN to 1, if you often have more than 2 devices active at the same
time. This will allocate 1 SCB for each device and ensure that there
will always be a free SCB for up to 4 devices active at the same time.
When SCB paging is enabled, set the commands per LUN to 8 or higher
(see SCB paging support below). Note that if AIC7XXX_CMDS_PER_LUN is
not defined and tagged queueing is enabled, the driver will attempt to
set the commands per LUN using its own heuristic based on the number
of available SCBs.
Enable SCB paging
CONFIG_AIC7XXX_PAGE_ENABLE
This option enables SCB paging. This will increase performance when
tagged queueing is enabled. Note that you should increase the
AIC7XXX_CMDS_PER_LUN to 8 as most tagged queueing devices allow at
least this many. Note that EISA and VLB controllers do not support
SCB paging due to chip limitations; enabling it on these controllers
has no effect.
Collect statistics to report in /proc
CONFIG_AIC7XXX_PROC_STATS
This option enables collection of SCSI transfer statistics for the
/proc filesystem. This does affect performance since it has to
maintain statistics.
Delay in seconds after SCSI bus reset
CONFIG_AIC7XXX_RESET_DELAY
This option sets the delay in seconds after a SCSI bus reset.
BusLogic SCSI support BusLogic SCSI support
CONFIG_SCSI_BUSLOGIC CONFIG_SCSI_BUSLOGIC
......
...@@ -335,7 +335,6 @@ clean: archclean ...@@ -335,7 +335,6 @@ clean: archclean
mrproper: clean mrproper: clean
rm -f include/linux/autoconf.h include/linux/version.h rm -f include/linux/autoconf.h include/linux/version.h
rm -f drivers/sound/local.h drivers/sound/.defines rm -f drivers/sound/local.h drivers/sound/.defines
rm -f drivers/scsi/aic7xxx_asm drivers/scsi/aic7xxx_seq.h
rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash
rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h
rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h
......
...@@ -652,19 +652,18 @@ void lp_setup(char *str, int *ints) ...@@ -652,19 +652,18 @@ void lp_setup(char *str, int *ints)
#endif #endif
int lp_wakeup(void *ref) void lp_wakeup(void *ref)
{ {
struct lp_struct *lp_dev = (struct lp_struct *) ref; struct lp_struct *lp_dev = (struct lp_struct *) ref;
if (!lp_dev->lp_wait_q) if (!lp_dev->lp_wait_q)
return 1; /* Wake up whom? */ return; /* Wake up whom? */
/* Claim the Parport */ /* Claim the Parport */
if (parport_claim(lp_dev->dev)) if (parport_claim(lp_dev->dev))
return 1; /* Shouldn't happen */ return; /* Shouldn't happen */
wake_up(&lp_dev->lp_wait_q); wake_up(&lp_dev->lp_wait_q);
return 0;
} }
static int inline lp_searchfor(int list[], int a) static int inline lp_searchfor(int list[], int a)
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
* Major cleanup by Martin Mares, May 1997 * Major cleanup by Martin Mares, May 1997
*/ */
#include <linux/config.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/tty.h> #include <linux/tty.h>
......
...@@ -688,7 +688,6 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty) ...@@ -688,7 +688,6 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty)
return -ENODEV; return -ENODEV;
idx = MINOR(device) - driver->minor_start; idx = MINOR(device) - driver->minor_start;
tty = driver->table[idx];
/* /*
* Check whether we need to acquire the tty semaphore to avoid * Check whether we need to acquire the tty semaphore to avoid
...@@ -697,7 +696,8 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty) ...@@ -697,7 +696,8 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty)
down_tty_sem(idx); down_tty_sem(idx);
/* check whether we're reopening an existing tty */ /* check whether we're reopening an existing tty */
if(tty) goto fast_track; tty = driver->table[idx];
if (tty) goto fast_track;
/* /*
* First time open is complex, especially for PTY devices. * First time open is complex, especially for PTY devices.
......
...@@ -56,6 +56,7 @@ __initfunc(void parport_setup(char *str, int *ints)) ...@@ -56,6 +56,7 @@ __initfunc(void parport_setup(char *str, int *ints))
#ifdef MODULE #ifdef MODULE
int init_module(void) int init_module(void)
{ {
parport_proc_init();
return 0; return 0;
} }
...@@ -80,6 +81,7 @@ __initfunc(int parport_init(void)) ...@@ -80,6 +81,7 @@ __initfunc(int parport_init(void))
struct parport *pb; struct parport *pb;
if (io[0] == PARPORT_DISABLE) return 1; if (io[0] == PARPORT_DISABLE) return 1;
parport_proc_init();
#ifdef CONFIG_PARPORT_PC #ifdef CONFIG_PARPORT_PC
parport_pc_init(io, irq, dma); parport_pc_init(io, irq, dma);
#endif #endif
...@@ -92,12 +94,15 @@ __initfunc(int parport_init(void)) ...@@ -92,12 +94,15 @@ __initfunc(int parport_init(void))
EXPORT_SYMBOL(parport_claim); EXPORT_SYMBOL(parport_claim);
EXPORT_SYMBOL(parport_release); EXPORT_SYMBOL(parport_release);
EXPORT_SYMBOL(parport_register_port); EXPORT_SYMBOL(parport_register_port);
EXPORT_SYMBOL(parport_unregister_port);
EXPORT_SYMBOL(parport_quiesce); EXPORT_SYMBOL(parport_quiesce);
EXPORT_SYMBOL(parport_register_device); EXPORT_SYMBOL(parport_register_device);
EXPORT_SYMBOL(parport_unregister_device); EXPORT_SYMBOL(parport_unregister_device);
EXPORT_SYMBOL(parport_enumerate); EXPORT_SYMBOL(parport_enumerate);
EXPORT_SYMBOL(parport_ieee1284_nibble_mode_ok); EXPORT_SYMBOL(parport_ieee1284_nibble_mode_ok);
EXPORT_SYMBOL(parport_wait_peripheral); EXPORT_SYMBOL(parport_wait_peripheral);
EXPORT_SYMBOL(parport_proc_register);
EXPORT_SYMBOL(parport_proc_unregister);
void inc_parport_count(void) void inc_parport_count(void)
{ {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* and Philip Blundell <Philip.Blundell@pobox.com> * and Philip Blundell <Philip.Blundell@pobox.com>
*/ */
#include <linux/stddef.h>
#include <linux/tasks.h> #include <linux/tasks.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -140,7 +141,7 @@ static void pc_enable_irq(struct parport *p) ...@@ -140,7 +141,7 @@ static void pc_enable_irq(struct parport *p)
static void pc_release_resources(struct parport *p) static void pc_release_resources(struct parport *p)
{ {
if (p->irq != PARPORT_IRQ_NONE) if (p->irq != PARPORT_IRQ_NONE)
free_irq(p->irq, NULL); free_irq(p->irq, p);
release_region(p->base, p->size); release_region(p->base, p->size);
if (p->modes & PARPORT_MODE_PCECR) if (p->modes & PARPORT_MODE_PCECR)
release_region(p->base+0x400, 3); release_region(p->base+0x400, 3);
...@@ -439,9 +440,10 @@ static int parport_SPP_supported(struct parport *pb) ...@@ -439,9 +440,10 @@ static int parport_SPP_supported(struct parport *pb)
*/ */
static int parport_ECR_present(struct parport *pb) static int parport_ECR_present(struct parport *pb)
{ {
int r, octr = pc_read_control(pb), oecr = pc_read_econtrol(pb); unsigned int r, octr = pc_read_control(pb),
oecr = pc_read_econtrol(pb);
r= pc_read_control(pb); r = pc_read_control(pb);
if ((pc_read_econtrol(pb) & 0x03) == (r & 0x03)) { if ((pc_read_econtrol(pb) & 0x03) == (r & 0x03)) {
pc_write_control(pb, r ^ 0x03 ); /* Toggle bits 0-1 */ pc_write_control(pb, r ^ 0x03 ); /* Toggle bits 0-1 */
...@@ -820,7 +822,10 @@ static int probe_one_port(unsigned long int base, int irq, int dma) ...@@ -820,7 +822,10 @@ static int probe_one_port(unsigned long int base, int irq, int dma)
} }
if (p->irq != PARPORT_IRQ_NONE) if (p->irq != PARPORT_IRQ_NONE)
printk(", irq %d", p->irq); printk(", irq %d", p->irq);
if (p->irq != PARPORT_DMA_NONE) if (p->dma == PARPORT_DMA_AUTO)
p->dma = (p->modes & PARPORT_MODE_PCECP)?
parport_dma_probe(p):PARPORT_DMA_NONE;
if (p->dma != PARPORT_DMA_NONE)
printk(", dma %d", p->dma); printk(", dma %d", p->dma);
printk(" ["); printk(" [");
#define printmode(x) {if(p->modes&PARPORT_MODE_PC##x){printk("%s%s",f?",":"",#x);f++;}} #define printmode(x) {if(p->modes&PARPORT_MODE_PC##x){printk("%s%s",f?",":"",#x);f++;}}
...@@ -835,6 +840,7 @@ static int probe_one_port(unsigned long int base, int irq, int dma) ...@@ -835,6 +840,7 @@ static int probe_one_port(unsigned long int base, int irq, int dma)
} }
#undef printmode #undef printmode
printk("]\n"); printk("]\n");
parport_proc_register(p);
return 1; return 1;
} }
...@@ -868,7 +874,7 @@ MODULE_PARM(dma, "1-" __MODULE_STRING(PC_MAX_PORTS) "i"); ...@@ -868,7 +874,7 @@ MODULE_PARM(dma, "1-" __MODULE_STRING(PC_MAX_PORTS) "i");
static int init_module(void) static int init_module(void)
{ {
return (parport_pc_init(NULL, NULL, NULL)?0:1); return (parport_pc_init(io, irq, dma)?0:1);
} }
static void cleanup_module(void) static void cleanup_module(void)
...@@ -878,6 +884,8 @@ static void cleanup_module(void) ...@@ -878,6 +884,8 @@ static void cleanup_module(void)
if (p->modes & PARPORT_MODE_PCSPP) { if (p->modes & PARPORT_MODE_PCSPP) {
if (!(p->flags & PARPORT_FLAG_COMA)) if (!(p->flags & PARPORT_FLAG_COMA))
parport_quiesce(p); parport_quiesce(p);
parport_proc_unregister(p);
parport_unregister_port(p);
} }
p = p->next; p = p->next;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* and Philip Blundell <Philip.Blundell@pobox.com> * and Philip Blundell <Philip.Blundell@pobox.com>
*/ */
#include <linux/stddef.h>
#include <linux/tasks.h> #include <linux/tasks.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -130,6 +131,9 @@ static int hardware_read_proc(char *page, char **start, off_t off, ...@@ -130,6 +131,9 @@ static int hardware_read_proc(char *page, char **start, off_t off,
len += sprintf(page+len, "irq:\tnone\n"); len += sprintf(page+len, "irq:\tnone\n");
else else
len += sprintf(page+len, "irq:\t%d\n",pp->irq); len += sprintf(page+len, "irq:\t%d\n",pp->irq);
if (pp->dma == PARPORT_DMA_NONE)
len += sprintf(page+len, "dma:\tnone\n");
else
len += sprintf(page+len, "dma:\t%d\n",pp->dma); len += sprintf(page+len, "dma:\t%d\n",pp->dma);
......
...@@ -88,6 +88,23 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, ...@@ -88,6 +88,23 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
return tmp; return tmp;
} }
void parport_unregister_port(struct parport *port)
{
struct parport *p;
kfree(port->name);
if (portlist == port) {
portlist = port->next;
} else {
for (p = portlist; (p != NULL) && (p->next != port);
p=p->next);
if (p) {
if ((p->next = port->next) == NULL)
portlist_tail = p;
}
}
kfree(port);
}
void parport_quiesce(struct parport *port) void parport_quiesce(struct parport *port)
{ {
if (port->devices) { if (port->devices) {
...@@ -106,7 +123,7 @@ void parport_quiesce(struct parport *port) ...@@ -106,7 +123,7 @@ void parport_quiesce(struct parport *port)
} }
struct pardevice *parport_register_device(struct parport *port, const char *name, struct pardevice *parport_register_device(struct parport *port, const char *name,
int (*pf)(void *), int (*kf)(void *), int (*pf)(void *), void (*kf)(void *),
void (*irq_func)(int, void *, struct pt_regs *), void (*irq_func)(int, void *, struct pt_regs *),
int flags, void *handle) int flags, void *handle)
{ {
...@@ -223,7 +240,6 @@ int parport_claim(struct pardevice *dev) ...@@ -223,7 +240,6 @@ int parport_claim(struct pardevice *dev)
pd1 = dev->port->cad; pd1 = dev->port->cad;
if (dev->port->cad) { if (dev->port->cad) {
if (dev->port->cad->preempt) { if (dev->port->cad->preempt) {
/* Now try to preempt */
if (dev->port->cad->preempt(dev->port->cad->private)) if (dev->port->cad->preempt(dev->port->cad->private))
return -EAGAIN; return -EAGAIN;
dev->port->ops->save_state(dev->port, dev->state); dev->port->ops->save_state(dev->port, dev->state);
...@@ -301,19 +317,10 @@ void parport_release(struct pardevice *dev) ...@@ -301,19 +317,10 @@ void parport_release(struct pardevice *dev)
} }
/* Now give the lurker a chance. /* Now give the lurker a chance.
* There should be a wakeup callback because we checked for it * There must be a wakeup callback because we checked for it
* at registration. * at registration.
*/ */
if (dev->port->lurker && (dev->port->lurker != dev)) { if (dev->port->lurker && (dev->port->lurker != dev)) {
if (dev->port->lurker->wakeup) {
dev->port->lurker->wakeup(dev->port->lurker->private); dev->port->lurker->wakeup(dev->port->lurker->private);
} }
#ifdef PARPORT_PARANOID
else { /* can't happen */
printk(KERN_DEBUG
"%s (%s): lurker's wakeup callback went away!\n",
dev->port->name, dev->name);
}
#endif
}
} }
...@@ -1045,7 +1045,7 @@ plip_preempt(void *handle) ...@@ -1045,7 +1045,7 @@ plip_preempt(void *handle)
return 0; return 0;
} }
static int static void
plip_wakeup(void *handle) plip_wakeup(void *handle)
{ {
struct device *dev = (struct device *)handle; struct device *dev = (struct device *)handle;
...@@ -1058,12 +1058,12 @@ plip_wakeup(void *handle) ...@@ -1058,12 +1058,12 @@ plip_wakeup(void *handle)
/* bus_owner is already set (but why?) */ /* bus_owner is already set (but why?) */
printk(KERN_DEBUG "%s: I'm broken.\n", dev->name); printk(KERN_DEBUG "%s: I'm broken.\n", dev->name);
else else
return 1; return;
} }
if (!(dev->flags & IFF_UP)) if (!(dev->flags & IFF_UP))
/* Don't need the port when the interface is down */ /* Don't need the port when the interface is down */
return 1; return;
if (!parport_claim(nl->pardev)) { if (!parport_claim(nl->pardev)) {
nl->port_owner = 1; nl->port_owner = 1;
...@@ -1072,7 +1072,7 @@ plip_wakeup(void *handle) ...@@ -1072,7 +1072,7 @@ plip_wakeup(void *handle)
outb (0x00, PAR_DATA(dev)); outb (0x00, PAR_DATA(dev));
} }
return 0; return;
} }
static struct net_device_stats * static struct net_device_stats *
......
...@@ -86,15 +86,15 @@ static long read_polled(struct parport *port, char *buf, ...@@ -86,15 +86,15 @@ static long read_polled(struct parport *port, char *buf,
static struct wait_queue *wait_q = NULL; static struct wait_queue *wait_q = NULL;
static int wakeup(void *ref) static void wakeup(void *ref)
{ {
struct pardevice **dev = (struct pardevice **)ref; struct pardevice **dev = (struct pardevice **)ref;
if (!wait_q || parport_claim(*dev)) if (!wait_q || parport_claim(*dev))
return 1; return;
wake_up(&wait_q); wake_up(&wait_q);
return 0; return;
} }
int parport_probe(struct parport *port, char *buffer, int len) int parport_probe(struct parport *port, char *buffer, int len)
......
...@@ -21,7 +21,14 @@ dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI ...@@ -21,7 +21,14 @@ dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI
dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
bool ' Enable tagged command queueing' CONFIG_AIC7XXX_TAGGED_QUEUEING Y
int ' Maximum number of commands per LUN' CONFIG_AIC7XXX_CMDS_PER_LUN 8
bool ' Enable SCB paging' CONFIG_AIC7XXX_PAGE_ENABLE N
bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
int ' delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 15
fi
dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI
......
This diff is collapsed.
...@@ -210,22 +210,22 @@ static int ppa_sg = SG_ALL; /* enable/disable scatter-gather. */ ...@@ -210,22 +210,22 @@ static int ppa_sg = SG_ALL; /* enable/disable scatter-gather. */
#define w_fifo(x,y) outb(y, PPA_BASE(x)+0x400) #define w_fifo(x,y) outb(y, PPA_BASE(x)+0x400)
#define w_ecr(x,y) outb(y, PPA_BASE(x)+0x402) #define w_ecr(x,y) outb(y, PPA_BASE(x)+0x402)
int ppa_wakeup(void *ref) static void ppa_wakeup(void *ref)
{ {
ppa_struct *ppa_dev = (ppa_struct *) ref; ppa_struct *ppa_dev = (ppa_struct *) ref;
if (!ppa_dev->ppa_wait_q) if (!ppa_dev->ppa_wait_q)
return 1; /* Wake up whom ? */ return; /* Wake up whom ? */
/* Claim the Parport */ /* Claim the Parport */
if (parport_claim(ppa_dev->dev)) if (parport_claim(ppa_dev->dev))
return 1; /* Shouldn't happen */ return; /* Shouldn't happen */
wake_up(&ppa_dev->ppa_wait_q); wake_up(&ppa_dev->ppa_wait_q);
return 0; return;
} }
int ppa_release(struct Scsi_Host *host) static int ppa_release(struct Scsi_Host *host)
{ {
int host_no = host->unique_id; int host_no = host->unique_id;
......
...@@ -52,7 +52,7 @@ int ppa_abort(Scsi_Cmnd *); ...@@ -52,7 +52,7 @@ int ppa_abort(Scsi_Cmnd *);
int ppa_reset(Scsi_Cmnd *, unsigned int); int ppa_reset(Scsi_Cmnd *, unsigned int);
int ppa_proc_info(char *, char **, off_t, int, int, int); int ppa_proc_info(char *, char **, off_t, int, int, int);
int ppa_biosparam(Disk *, kdev_t, int*); int ppa_biosparam(Disk *, kdev_t, int*);
int ppa_release(struct Scsi_Host *); static int ppa_release(struct Scsi_Host *);
#ifndef MODULE #ifndef MODULE
#ifdef PPA_CODE #ifdef PPA_CODE
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
* Fixes: Dmitry Gorodchanin <begemot@bgm.rosprint.net>, 11 Feb 96 * Fixes: Dmitry Gorodchanin <begemot@bgm.rosprint.net>, 11 Feb 96
* removed race conditions in dqput(), dqget() and iput(). * removed race conditions in dqput(), dqget() and iput().
* Andi Kleen removed all verify_area() calls, 31 Dec 96 * Andi Kleen removed all verify_area() calls, 31 Dec 96
* Nick Kralevich <nickkral@cal.alumni.berkeley.edu>, 21 Jul 97
* Fixed a condition where user and group quotas could get mixed up.
* *
* (C) Copyright 1994, 1995 Marco van Wieringen * (C) Copyright 1994, 1995 Marco van Wieringen
* *
...@@ -555,12 +557,14 @@ static struct dquot *dqget(kdev_t dev, unsigned int id, short type) ...@@ -555,12 +557,14 @@ static struct dquot *dqget(kdev_t dev, unsigned int id, short type)
repeat: repeat:
dquot = *(hash(dev, id, type)); dquot = *(hash(dev, id, type));
while (dquot) { while (dquot) {
if (dquot->dq_dev != dev || dquot->dq_id != id) { if (dquot->dq_dev != dev || dquot->dq_id != id ||
dquot->dq_type != type) {
dquot = dquot->dq_hash_next; dquot = dquot->dq_hash_next;
continue; continue;
} }
wait_on_dquot(dquot); wait_on_dquot(dquot);
if (dquot->dq_dev != dev || dquot->dq_id != id) if (dquot->dq_dev != dev || dquot->dq_id != id ||
dquot->dq_type != type)
goto repeat; goto repeat;
if (!dquot->dq_count) if (!dquot->dq_count)
nr_free_dquots--; nr_free_dquots--;
......
...@@ -290,8 +290,18 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err) ...@@ -290,8 +290,18 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)
struct ext2_group_desc * tmp; struct ext2_group_desc * tmp;
struct ext2_super_block * es; struct ext2_super_block * es;
if (!dir || !(inode = get_empty_inode ())) /* Cannot create files in a deleted directory */
if (!dir || !dir->i_nlink) {
*err = -EPERM;
return NULL; return NULL;
}
inode = get_empty_inode ();
if (!inode) {
*err = -ENOMEM;
return NULL;
}
sb = dir->i_sb; sb = dir->i_sb;
inode->i_sb = sb; inode->i_sb = sb;
inode->i_flags = sb->s_flags; inode->i_flags = sb->s_flags;
......
...@@ -905,10 +905,14 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -905,10 +905,14 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
goto end_rename; goto end_rename;
} }
retval = -EPERM; retval = -EPERM;
if (new_inode && (new_dir->i_mode & S_ISVTX) && if (new_inode) {
if ((new_dir->i_mode & S_ISVTX) &&
current->fsuid != new_inode->i_uid && current->fsuid != new_inode->i_uid &&
current->fsuid != new_dir->i_uid && !fsuser()) current->fsuid != new_dir->i_uid && !fsuser())
goto end_rename; goto end_rename;
if (IS_APPEND(new_inode) || IS_IMMUTABLE(new_inode))
goto end_rename;
}
if (S_ISDIR(old_inode->i_mode)) { if (S_ISDIR(old_inode->i_mode)) {
retval = -ENOTDIR; retval = -ENOTDIR;
if (new_inode && !S_ISDIR(new_inode->i_mode)) if (new_inode && !S_ISDIR(new_inode->i_mode))
......
...@@ -1127,13 +1127,14 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -1127,13 +1127,14 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry)
ino_t ino; ino_t ino;
const char *name = dentry->d_name.name; const char *name = dentry->d_name.name;
int len = dentry->d_name.len; int len = dentry->d_name.len;
int retval;
/* In case of madness */ /* In case of madness */
if (dir == 0) if (dir == 0)
return -ENOENT; return -ENOENT;
if (!S_ISDIR(dir->i_mode)) if (!S_ISDIR(dir->i_mode))
goto bail; return -ENOENT;
/* /*
* Read in the directory entry. "." is there under the name ^A^A . * Read in the directory entry. "." is there under the name ^A^A .
...@@ -1153,8 +1154,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -1153,8 +1154,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry)
* This is not really a bailout, just means file not found. * This is not really a bailout, just means file not found.
*/ */
inode = NULL;
if (!de) if (!de)
goto bail; goto add_dentry;
/* /*
* Get inode number, what we're after. * Get inode number, what we're after.
...@@ -1169,8 +1171,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -1169,8 +1171,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry)
* Go find or make an inode. * Go find or make an inode.
*/ */
retval = -EACCES;
if (!(inode = iget(dir->i_sb, ino))) if (!(inode = iget(dir->i_sb, ino)))
goto bail1; goto free4;
/* /*
* Fill in the info from the directory if this is a newly created * Fill in the info from the directory if this is a newly created
...@@ -1195,24 +1198,16 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -1195,24 +1198,16 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry)
} }
} }
brelse4(&qbh);
/* /*
* Made it. * Add the dentry, negative or otherwise.
*/ */
add_dentry:
d_add(dentry, inode);
retval = 0;
d_instantiate(dentry, inode); free4:
iput(dir);
return 0;
/*
* Didn't.
*/
bail1:
brelse4(&qbh); brelse4(&qbh);
bail: return retval;
iput(dir);
return -ENOENT;
} }
/* /*
......
...@@ -224,7 +224,6 @@ static void dispose_list(struct list_head * head) ...@@ -224,7 +224,6 @@ static void dispose_list(struct list_head * head)
break; break;
inode = list_entry(tmp, struct inode, i_list); inode = list_entry(tmp, struct inode, i_list);
truncate_inode_pages(inode, 0); truncate_inode_pages(inode, 0);
list_del(&inode->i_list);
} }
/* Add them all to the unused list in one fell swoop */ /* Add them all to the unused list in one fell swoop */
...@@ -549,7 +548,22 @@ int fs_may_umount(struct super_block *sb, struct dentry * root) ...@@ -549,7 +548,22 @@ int fs_may_umount(struct super_block *sb, struct dentry * root)
return root->d_count == 1; return root->d_count == 1;
} }
/* This belongs in file_table.c, not here... */
int fs_may_remount_ro(struct super_block *sb) int fs_may_remount_ro(struct super_block *sb)
{ {
return 1; struct file *file;
kdev_t dev = sb->s_dev;
/* Check that no files are currently opened for writing. */
for (file = inuse_filps; file; file = file->f_next) {
struct inode *inode;
if (!file->f_dentry)
continue;
inode = file->f_dentry->d_inode;
if (!inode || inode->i_dev != dev)
continue;
if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE)
return 0;
}
return 1; /* Tis' cool bro. */
} }
...@@ -834,6 +834,10 @@ static inline int do_unlink(const char * name) ...@@ -834,6 +834,10 @@ static inline int do_unlink(const char * name)
dir = lock_parent(dentry); dir = lock_parent(dentry);
error = -ENOENT;
if (!dentry->d_inode)
goto exit_lock;
error = -EROFS; error = -EROFS;
if (IS_RDONLY(dir)) if (IS_RDONLY(dir))
goto exit_lock; goto exit_lock;
......
...@@ -417,6 +417,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode) ...@@ -417,6 +417,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode)
if (!inode) if (!inode)
return -EACCES; return -EACCES;
nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -456,6 +457,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde ...@@ -456,6 +457,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
if (!inode) if (!inode)
return -EACCES; return -EACCES;
nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -493,6 +495,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -493,6 +495,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!inode) if (!inode)
return -EACCES; return -EACCES;
nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -516,6 +519,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -516,6 +519,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
if (error) if (error)
return error; return error;
nfs_invalidate_dircache(dir);
d_delete(dentry); d_delete(dentry);
return 0; return 0;
} }
...@@ -543,6 +547,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -543,6 +547,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
if (error) if (error)
return error; return error;
nfs_invalidate_dircache(dir);
d_delete(dentry); d_delete(dentry);
return 0; return 0;
} }
...@@ -583,6 +588,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym ...@@ -583,6 +588,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
if (!inode) if (!inode)
return -EACCES; return -EACCES;
nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -609,6 +615,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr ...@@ -609,6 +615,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
if (error) if (error)
return error; return error;
nfs_invalidate_dircache(dir);
inode->i_count++; inode->i_count++;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
...@@ -652,6 +659,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -652,6 +659,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (error) if (error)
return error; return error;
nfs_invalidate_dircache(old_dir);
nfs_invalidate_dircache(new_dir);
/* Update the dcache */ /* Update the dcache */
d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name); d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name);
d_delete(new_dentry); d_delete(new_dentry);
......
This diff is collapsed.
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/fd.h> #include <linux/fd.h>
#include <linux/config.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
......
...@@ -130,8 +130,7 @@ struct parport_device_info { ...@@ -130,8 +130,7 @@ struct parport_device_info {
* *
* 2) a wake-up function, called by the resource manager to tell drivers * 2) a wake-up function, called by the resource manager to tell drivers
* that the port is available to be claimed. If a driver wants to use * that the port is available to be claimed. If a driver wants to use
* the port, it should call parport_claim() here. The return value from * the port, it should call parport_claim() here.
* this function is ignored.
*/ */
/* A parallel port device */ /* A parallel port device */
...@@ -187,6 +186,9 @@ struct parport { ...@@ -187,6 +186,9 @@ struct parport {
struct parport *parport_register_port(unsigned long base, int irq, int dma, struct parport *parport_register_port(unsigned long base, int irq, int dma,
struct parport_operations *ops); struct parport_operations *ops);
/* Unregister a port. */
void parport_unregister_port(struct parport *port);
/* parport_in_use returns nonzero if there are devices attached to a port. */ /* parport_in_use returns nonzero if there are devices attached to a port. */
#define parport_in_use(x) ((x)->devices != NULL) #define parport_in_use(x) ((x)->devices != NULL)
...@@ -209,7 +211,7 @@ struct parport *parport_enumerate(void); ...@@ -209,7 +211,7 @@ struct parport *parport_enumerate(void);
*/ */
struct pardevice *parport_register_device(struct parport *port, struct pardevice *parport_register_device(struct parport *port,
const char *name, const char *name,
int (*pf)(void *), int (*kf)(void *), int (*pf)(void *), void (*kf)(void *),
void (*irq_func)(int, void *, struct pt_regs *), void (*irq_func)(int, void *, struct pt_regs *),
int flags, void *handle); int flags, void *handle);
......
...@@ -384,33 +384,36 @@ extern spinlock_t pidhash_lock; ...@@ -384,33 +384,36 @@ extern spinlock_t pidhash_lock;
extern __inline__ void hash_pid(struct task_struct *p) extern __inline__ void hash_pid(struct task_struct *p)
{ {
struct task_struct **htable = &pidhash[pid_hashfn(p->pid)]; struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
unsigned long flags;
spin_lock(&pidhash_lock); spin_lock_irqsave(&pidhash_lock, flags);
if((p->pidhash_next = *htable) != NULL) if((p->pidhash_next = *htable) != NULL)
(*htable)->pidhash_pprev = &p->pidhash_next; (*htable)->pidhash_pprev = &p->pidhash_next;
*htable = p; *htable = p;
p->pidhash_pprev = htable; p->pidhash_pprev = htable;
spin_unlock(&pidhash_lock); spin_unlock_irqrestore(&pidhash_lock, flags);
} }
extern __inline__ void unhash_pid(struct task_struct *p) extern __inline__ void unhash_pid(struct task_struct *p)
{ {
spin_lock(&pidhash_lock); unsigned long flags;
spin_lock_irqsave(&pidhash_lock, flags);
if(p->pidhash_next) if(p->pidhash_next)
p->pidhash_next->pidhash_pprev = p->pidhash_pprev; p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
*p->pidhash_pprev = p->pidhash_next; *p->pidhash_pprev = p->pidhash_next;
spin_unlock(&pidhash_lock); spin_unlock_irqrestore(&pidhash_lock, flags);
} }
extern __inline__ struct task_struct *find_task_by_pid(int pid) extern __inline__ struct task_struct *find_task_by_pid(int pid)
{ {
struct task_struct **htable = &pidhash[pid_hashfn(pid)]; struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
struct task_struct *p; unsigned long flags;
spin_lock(&pidhash_lock); spin_lock_irqsave(&pidhash_lock, flags);
for(p = *htable; p && p->pid != pid; p = p->pidhash_next) for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
; ;
spin_unlock(&pidhash_lock); spin_unlock_irqrestore(&pidhash_lock, flags);
return p; return p;
} }
......
...@@ -358,6 +358,9 @@ static struct sk_buff *ip_glue(struct ipq *qp) ...@@ -358,6 +358,9 @@ static struct sk_buff *ip_glue(struct ipq *qp)
fp = fp->next; fp = fp->next;
} }
skb->pkt_type = qp->fragments->skb->pkt_type;
skb->protocol = qp->fragments->skb->protocol;
/* We glued together all fragments, so remove the queue entry. */ /* We glued together all fragments, so remove the queue entry. */
ip_free(qp); ip_free(qp);
......
...@@ -66,6 +66,7 @@ int ipip_rcv(struct sk_buff *skb, unsigned short len) ...@@ -66,6 +66,7 @@ int ipip_rcv(struct sk_buff *skb, unsigned short len)
* Discard the original IP header * Discard the original IP header
*/ */
skb->mac.raw = skb->data;
skb_pull(skb, skb->h.raw - skb->nh.raw); skb_pull(skb, skb->h.raw - skb->nh.raw);
/* /*
......
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