Commit ec010c86 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.19

parent 893c4d2f
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 18
SUBLEVEL = 19
all: Version zImage
......
......@@ -468,7 +468,7 @@ static void lastcons(void)
static void send_intr(void)
{
if (tty->termios && I_IGNBRK(tty))
if (!tty || (tty->termios && I_IGNBRK(tty)))
return;
tty_insert_flip_char(tty, 0, TTY_BREAK);
}
......
......@@ -20,6 +20,7 @@
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/major.h>
#include <linux/mm.h>
#include <asm/segment.h>
#include <asm/system.h>
......@@ -32,9 +33,19 @@ struct pty_struct {
#define PTY_MAGIC 0x5001
#define PTY_BUF_SIZE 1024
#define PTY_BUF_SIZE PAGE_SIZE/2
static unsigned char tmp_buf[PTY_BUF_SIZE];
/*
* tmp_buf is used as a temporary buffer by pty_write. We need to
* lock it in case the memcpy_fromfs blocks while swapping in a page,
* and some other program tries to do a pty write at the same time.
* Since the lock will only come under contention when the system is
* swapping and available memory is low, it makes sense to share one
* buffer across all the PTY's, since it significantly saves memory if
* large numbers of PTY's are open.
*/
static unsigned char *tmp_buf;
static struct semaphore tmp_buf_sem = MUTEX;
struct tty_driver pty_driver, pty_slave_driver;
static int pty_refcount;
......@@ -78,24 +89,34 @@ static int pty_write(struct tty_struct * tty, int from_user,
unsigned char *buf, int count)
{
struct tty_struct *to = tty->link;
int c, n;
int c=0, n, r;
char *temp_buffer;
if (!to || tty->stopped)
return 0;
count = MIN(count, to->ldisc.receive_room(to));
if (from_user) {
for (c = count; c > 0; c -= n) {
n = MIN(c, PTY_BUF_SIZE);
memcpy_fromfs(tmp_buf, buf, n);
to->ldisc.receive_buf(to, tmp_buf, 0, n);
buf += n;
down(&tmp_buf_sem);
temp_buffer = tmp_buf +
((tty->driver.subtype-1) * PTY_BUF_SIZE);
while (count > 0) {
n = MIN(count, PTY_BUF_SIZE);
memcpy_fromfs(temp_buffer, buf, n);
r = to->ldisc.receive_room(to);
if (r <= 0)
break;
n = MIN(n, r);
to->ldisc.receive_buf(to, temp_buffer, 0, n);
buf += n; c+= n;
count -= n;
}
} else
to->ldisc.receive_buf(to, buf, 0, count);
up(&tmp_buf_sem);
} else {
c = MIN(count, to->ldisc.receive_room(to));
to->ldisc.receive_buf(to, buf, 0, c);
}
return count;
return c;
}
static int pty_write_room(struct tty_struct *tty)
......@@ -146,7 +167,13 @@ int pty_open(struct tty_struct *tty, struct file * filp)
return -ENODEV;
pty = pty_state + line;
tty->driver_data = pty;
if (!tmp_buf) {
tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
if (!tmp_buf)
return -ENOMEM;
}
if (tty->driver.subtype == PTY_TYPE_SLAVE)
clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
wake_up_interruptible(&pty->open_wait);
......@@ -199,12 +226,12 @@ long pty_init(long kmem_start)
pty_slave_driver.termios_locked = ttyp_termios_locked;
pty_slave_driver.other = &pty_driver;
tmp_buf = 0;
if (tty_register_driver(&pty_driver))
panic("Couldn't register pty driver\n");
panic("Couldn't register pty driver");
if (tty_register_driver(&pty_slave_driver))
panic("Couldn't register pty slave driver\n");
panic("Couldn't register pty slave driver");
return kmem_start;
}
......@@ -499,6 +499,10 @@ static void rs_interrupt(int irq)
int pass_counter = 0;
struct async_struct *end_mark = 0;
#ifdef SERIAL_DEBUG_INTR
printk("rs_interrupt(%d)...", irq);
#endif
info = IRQ_ports[irq];
if (!info)
return;
......@@ -512,6 +516,8 @@ static void rs_interrupt(int irq)
}
end_mark = 0;
info->last_active = jiffies;
status = serial_inp(info, UART_LSR);
if (status & UART_LSR_DR)
receive_chars(info, &status);
......@@ -543,6 +549,10 @@ static void rs_interrupt_single(int irq)
int pass_counter = 0;
struct async_struct * info;
#ifdef SERIAL_DEBUG_INTR
printk("rs_interrupt_single(%d)...", irq);
#endif
info = IRQ_ports[irq];
if (!info || !info->tty)
return;
......@@ -561,6 +571,7 @@ static void rs_interrupt_single(int irq)
break;
}
} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
info->last_active = jiffies;
}
#else /* CONFIG_SERIAL_NEW_ISR */
......@@ -574,6 +585,11 @@ static void rs_interrupt(int irq)
struct async_struct * info;
int done = 1, pass_counter = 0;
#ifdef SERIAL_DEBUG_INTR
printk("rs_interrupt(%d)...", irq);
#endif
info = IRQ_ports[irq];
if (!info)
return;
......@@ -625,6 +641,11 @@ static void rs_interrupt_single(int irq)
int status;
struct async_struct * info;
#ifdef SERIAL_DEBUG_INTR
printk("rs_interrupt_single(%d)...", irq);
#endif
info = IRQ_ports[irq];
if (!info || !info->tty)
return;
......@@ -697,13 +718,39 @@ static void do_softint(void *private)
*/
static void rs_timer(void)
{
static unsigned long last_strobe = 0;
struct async_struct *info;
unsigned int i;
if ((jiffies - last_strobe) >= 60*HZ) {
for (i=1; i < 16; i++) {
info = IRQ_ports[i];
if (!info)
continue;
cli();
if (info->next_port) {
do {
serial_out(info, UART_IER, 0);
info->IER |= UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
info = info->next_port;
} while (info);
rs_interrupt(i);
} else
rs_interrupt_single(i);
sti();
}
}
last_strobe = jiffies;
timer_table[RS_TIMER].expires = jiffies + 60 * HZ;
timer_active |= 1 << RS_TIMER;
if (IRQ_ports[0]) {
cli();
rs_interrupt(0);
sti();
timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0] - 2;
timer_active |= 1 << RS_TIMER;
}
}
......@@ -757,7 +804,7 @@ static void free_all_interrupts(int irq_lines)
/*
* This routine figures out the correct timeout for a particular IRQ.
* It uses the smallest timeout of all of the serial ports in a
* particular interrupt chain.
* particular interrupt chain. Now only used for IRQ 0....
*/
static void figure_IRQ_timeout(int irq)
{
......@@ -908,10 +955,8 @@ static int startup(struct async_struct * info)
/*
* Set up serial timers...
*/
if (info->irq == 0) {
timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0];
timer_active |= 1 << RS_TIMER;
}
timer_table[RS_TIMER].expires = jiffies + 2;
timer_active |= 1 << RS_TIMER;
/*
* and set the speed of the serial port
......@@ -1633,6 +1678,15 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
rs_wild_int_mask = check_wild_interrupts(0);
return 0;
case TIOCSERGSTRUCT:
error = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct async_struct));
if (error)
return error;
memcpy_tofs((struct async_struct *) arg,
info, sizeof(struct async_struct));
return 0;
default:
return -ENOIOCTLCMD;
}
......
......@@ -146,6 +146,7 @@ static int ppp_open(struct tty_struct *);
static void ppp_close(struct tty_struct *);
#ifdef NEW_TTY_DRIVERS
static int ppp_receive_room(struct tty_struct *tty);
static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
char *fp, int count);
static void ppp_write_wakeup(struct tty_struct *tty);
......@@ -239,6 +240,7 @@ ppp_init(struct device *dev)
#ifdef NEW_TTY_DRIVERS
ppp_ldisc.magic = TTY_LDISC_MAGIC;
ppp_ldisc.receive_room = ppp_receive_room;
ppp_ldisc.receive_buf = ppp_receive_buf;
ppp_ldisc.write_wakeup = ppp_write_wakeup;
#else
......@@ -891,6 +893,12 @@ ppp_unesc(struct ppp *ppp, unsigned char *c, int n)
}
#else
static int ppp_receive_room(struct tty_struct *tty)
{
return 65536; /* We can handle an infinite amount of data. :-) */
}
static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
char *fp, int count)
{
......
......@@ -656,6 +656,10 @@ sl_close(struct device *dev)
return(0);
}
static int slip_receive_room(struct tty_struct *tty)
{
return 65536; /* We can handle an infinite amount of data. :-) */
}
/*
* Handle the 'receiver data ready' interrupt.
......@@ -680,7 +684,7 @@ static void slip_receive_buf(struct tty_struct *tty, unsigned char *cp,
/* Read the characters out of the buffer */
while (count--) {
if (*fp++) {
if (fp && *fp++) {
sl->flags |= SLF_ERROR;
cp++;
continue;
......@@ -1048,6 +1052,7 @@ slip_init(struct device *dev)
unsigned int, unsigned long)) slip_ioctl;
sl_ldisc.select = NULL;
sl_ldisc.receive_buf = slip_receive_buf;
sl_ldisc.receive_room = slip_receive_room;
sl_ldisc.write_wakeup = slip_write_wakeup;
if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
printk("ERROR: %d\n", i);
......
Wed Jun 1 21:12:13 1994 Eric Youngdale (eric@esp22)
* scsi.h: Add new return code for reset() function:
SCSI_RESET_PUNT.
* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
now.
* aha1542.c: If the command responsible for the reset is not
pending, return SCSI_RESET_PUNT.
* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
Tue May 31 19:36:01 1994 Eric Youngdale (eric@esp22)
* buslogic.c: Do not print out message about "must be Adaptec"
if we have detected a buslogic card. Print out a warning message
if we are configuring for >16Mb, since the 445S at board level
D or earlier does not work right. The "D" level board can be made
to work by flipping an undocumented switch, but this is too subtle.
Changes based upon patches in Yggdrasil distribution.
* sg.c, sg.h: Return sense data to user.
* aha1542.c, aha1740.c, buslogic.c: Do not panic if
sense buffer is wrong size.
* hosts.c: Test for ultrastor card before any of the others.
* scsi.c: Allow boot-time option for max_scsi_luns=? so that
buggy firmware has an easy work-around.
Sun May 15 20:24:34 1994 Eric Youngdale (eric@esp22)
* Linux 1.1.15 released.
Post-codefreeze thaw...
* buslogic.[c,h]: New driver from David Gentzel.
......
......@@ -460,7 +460,6 @@ int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
#ifndef DEBUG
if (bufflen != sizeof(SCpnt->sense_buffer)) {
printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
panic("aha1542.c");
};
#endif
SCpnt->result = 0;
......@@ -1058,7 +1057,10 @@ int aha1542_reset(Scsi_Cmnd * SCpnt)
}
#endif
return SCSI_RESET_PENDING;
/* No active command at this time, so this means that each time we got
some kind of response the last time through. Tell the mid-level code
to request sense information in order to decide what to do next. */
return SCSI_RESET_PUNT;
}
#ifdef CONFIG_BLK_DEV_SD
......
......@@ -251,7 +251,6 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
if (bufflen != sizeof(SCpnt->sense_buffer))
{
printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
panic("aha1740.c");
}
SCpnt->result = 0;
done(SCpnt);
......@@ -487,7 +486,7 @@ int aha1740_abort(Scsi_Cmnd * SCpnt)
int aha1740_reset(Scsi_Cmnd * SCpnt)
{
DEB(printk("aha1740_reset called\n"));
return SCSI_RESET_SNOOZE;
return SCSI_RESET_PUNT;
}
int aha1740_biosparam(int size, int dev, int* ip)
......
......@@ -1178,7 +1178,7 @@ int buslogic_reset(Scsi_Cmnd *SCpnt)
#if BUSLOGIC_DEBUG
buslogic_printk("buslogic_reset\n");
#endif
return SCSI_RESET_SNOOZE;
return SCSI_RESET_PUNT;
}
int buslogic_biosparam(int size, int dev, int *ip)
......
......@@ -110,6 +110,9 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hos
Scsi_Host_Template scsi_hosts[] =
{
#ifdef CONFIG_SCSI_ULTRASTOR
ULTRASTOR_14F,
#endif
#ifdef CONFIG_SCSI_AHA152X
AHA152X,
#endif
......@@ -141,9 +144,6 @@ Scsi_Host_Template scsi_hosts[] =
#ifdef CONFIG_SCSI_T128
TRANTOR_T128,
#endif
#ifdef CONFIG_SCSI_ULTRASTOR
ULTRASTOR_14F,
#endif
#ifdef CONFIG_SCSI_7000FASST
WD7000,
#endif
......
......@@ -192,6 +192,20 @@ static void scan_scsis_done (Scsi_Cmnd * SCpnt)
#endif
SCpnt->request.dev = 0xfffe;
}
#ifdef NO_MULTI_LUN
static int max_scsi_luns = 1;
#else
static int max_scsi_luns = 8;
#endif
void scsi_luns_setup(char *str, int *ints) {
if (ints[0] != 1)
printk("scsi_luns_setup : usage max_scsi_luns=n (n should be between 1 and 8)\n");
else
max_scsi_luns = ints[1];
}
/*
* Detecting SCSI devices :
* We scan all present host adapter's busses, from ID 0 to ID 6.
......@@ -223,11 +237,7 @@ static void scan_scsis (void)
* We need the for so our continue, etc. work fine.
*/
#ifdef NO_MULTI_LUN
for (lun = 0; lun < 1; ++lun)
#else
for (lun = 0; lun < 8; ++lun)
#endif
for (lun = 0; lun < max_scsi_luns; ++lun)
{
scsi_devices[NR_SCSI_DEVICES].host = shpnt;
scsi_devices[NR_SCSI_DEVICES].id = dev;
......@@ -1491,6 +1501,7 @@ int scsi_reset (Scsi_Cmnd * SCpnt)
return 0;
case SCSI_RESET_PENDING:
return 0;
case SCSI_RESET_PUNT:
case SCSI_RESET_WAKEUP:
SCpnt->internal_timeout &= ~IN_RESET;
scsi_request_sense (SCpnt);
......
......@@ -351,27 +351,34 @@ struct scatterlist {
/* We do not know how to reset the bus, or we do not want to. Bummer.
Anyway, just wait a little more for the command in question, and hope that
it eventually finishes */
it eventually finishes. If it never finishes, the SCSI device could
hang, so use this with caution. */
#define SCSI_RESET_SNOOZE 0
/* We do not know how to reset the bus, or we do not want to. Bummer.
We have given up on this ever completing. The mid-level code will
request sense information to decide how to proceed from here. */
#define SCSI_RESET_PUNT 1
/* This means that we were able to reset the bus. We have restarted all of
the commands that should be restarted, and we should be able to continue
on normally from here. We do not expect any interrupts that will return
DID_RESET to any of the other commands in the host_queue. */
#define SCSI_RESET_SUCCESS 1
DID_RESET to any of the other commands in the host_queue, and the mid-level
code does not need to do anything special to keep the commands alive. */
#define SCSI_RESET_SUCCESS 2
/* We called for an reset of this bus, and we should get an interrupt
when this succeeds. Each command should get it's own status
passed up to scsi_done, but this has not happened yet. */
#define SCSI_RESET_PENDING 2
#define SCSI_RESET_PENDING 3
/* We did a reset, but do not expect an interrupt to signal DID_RESET.
This tells the upper level code to request the sense info, and this
should keep the command alive. */
#define SCSI_RESET_WAKEUP 3
#define SCSI_RESET_WAKEUP 4
/* Something went wrong, and we do not know how to fix it. */
#define SCSI_RESET_ERROR 4
#define SCSI_RESET_ERROR 5
void * scsi_malloc(unsigned int);
int scsi_free(void *, unsigned int);
......
......@@ -173,7 +173,9 @@ static int sg_read(struct inode *inode,struct file *filp,char *buf,int count)
buf+=sizeof(struct sg_header);
if (count>device->header.pack_len)
count=device->header.pack_len;
memcpy_tofs(buf,device->buff,count-sizeof(struct sg_header));
if (count > sizeof(struct sg_header)) {
memcpy_tofs(buf,device->buff,count-sizeof(struct sg_header));
}
}
else
count=0;
......@@ -193,6 +195,7 @@ static void sg_command_done(Scsi_Cmnd * SCpnt)
SCpnt->request.dev=-1;
return;
}
memcpy(device->header.sense_buffer, SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
if (SCpnt->sense_buffer[0])
{
device->header.result=EIO;
......@@ -211,6 +214,7 @@ static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
int bsize,size,amt,i;
unsigned char cmnd[MAX_COMMAND_SIZE];
struct scsi_generic *device=&scsi_generics[dev];
if ((i=verify_area(VERIFY_READ,buf,count)))
return i;
if (count<sizeof(struct sg_header))
......
......@@ -17,6 +17,8 @@ struct sg_header
int reply_len; /* maximum length <4096 of expected reply */
int pack_id; /* id number of packet */
int result; /* 0==ok, otherwise refer to errno codes */
int flags; /* for future use */
unsigned char sense_buffer[16]; /* used only by reads */
/* command follows then data for command */
};
......
......@@ -927,7 +927,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt)
#endif
if(config.slot)
return SCSI_RESET_SNOOZE; /* Do not attempt a reset for the 24f */
return SCSI_RESET_PUNT; /* Do not attempt a reset for the 24f */
save_flags(flags);
cli();
......
......@@ -1204,7 +1204,7 @@ int wd7000_abort(Scsi_Cmnd * SCpnt)
*/
int wd7000_reset(Scsi_Cmnd * SCpnt)
{
return SCSI_RESET_SNOOZE;
return SCSI_RESET_PUNT;
}
......
......@@ -99,6 +99,7 @@ struct async_struct {
int MCR; /* Modem control register */
int MCR_noint; /* MCR with interrupts off */
int event;
unsigned long last_active;
int line;
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
......
......@@ -51,6 +51,7 @@
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
/* Used for packet mode */
#define TIOCPKT_DATA 0
......
......@@ -90,6 +90,7 @@ extern void tmc8xx_setup(char *str, int *ints);
extern void t128_setup(char *str, int *ints);
extern void generic_NCR5380_setup(char *str, int *intr);
extern void aha152x_setup(char *str, int *ints);
extern void scsi_luns_setup(char *str, int *ints);
extern void sound_setup(char *str, int *ints);
#ifdef CONFIG_SBPCD
extern void sbpcd_setup(char *str, int *ints);
......@@ -174,6 +175,9 @@ struct {
#ifdef CONFIG_INET
{ "ether=", eth_setup },
#endif
#ifdef CONFIG_SCSI
{ "max_scsi_luns=", scsi_luns_setup },
#endif
#ifdef CONFIG_BLK_DEV_HD
{ "hd=", hd_setup },
#endif
......
......@@ -476,6 +476,7 @@ void kfree_skb(struct sk_buff *skb, int rw)
skb->link3 = NULL;
skb->sk = NULL;
skb->stamp.tv_sec=0; /* No idea about time */
skb->localroute = 0;
net_memory += size;
net_skbcount++;
#if CONFIG_SKB_CHECK
......
......@@ -938,10 +938,11 @@ sock_init(void)
/* Initialize the protocols module. */
proto_init();
#ifdef CONFIG_NET
/* Initialize the DEV module. */
dev_init();
/* And the bottom half handler */
bh_base[NET_BH].routine= net_bh;
#endif
}
......@@ -358,12 +358,13 @@ unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
old_fs = get_fs();
set_fs(get_ds());
i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
if (i == 0) i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
if (i == -EEXIST)
i = -EADDRINUSE;
if (i == 0)
i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
set_fs(old_fs);
if (i < 0) {
printk("UNIX: bind: can't open socket %s\n", fname);
return(i);
}
if (i < 0)
return i;
upd->sockaddr_len = sockaddr_len; /* now its legal */
return(0);
......
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