Commit 6d58893f authored by Linus Torvalds's avatar Linus Torvalds

Import 2.0.16

parent 36513793
......@@ -20,20 +20,21 @@ prefer a HTML-ized shopping list.
Para aquellos que prefieran una version en castellano de este
documento, consultad la traduccion de Alfredo Sanjuan en
http://slug.ctv.es/~alfredo/Cambios.html.
http://slug.ctv.es/~alfredo/Cambios.html (Spanish translation).
Akik magyarul szeretnenek olvasni az uj kernellel kapcsolatos
valtozasokrol, az alabbi cimen megtalaljak Nyitrai Tamas forditasat:
http://www.datanet.hu/generations/linux/newkernel.html.
http://www.datanet.hu/generations/linux/newkernel.html (Hungarian
translation).
Tamas also maintains a version of this file in English at
http://www.datanet.hu/generations/linux/Changes.html.
Tamas also maintains a version of this file at
http://www.datanet.hu/generations/linux/Changes.html (English).
For people who prefer Japanese (thanks to Mitsuhiro Kojima): Kono
bunshou no nihongo ban wa
http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu.
Last updated: August 18, 1996.
Last updated: August 29, 1996.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Releases
......@@ -152,7 +153,7 @@ the sig11 FAQ.
On the other hand, if you're using a gcc patched for Pentium
optimization and are getting these errors, downgrade to a standard GNU
gcc before assuming your hardware (or the kernel) is to blame..
gcc before assuming your hardware (or the kernel) is to blame.
On a related note, if you get random OOPses that don't seem to be
related to anything and you have a motherboard with APM support, try
......@@ -678,11 +679,14 @@ upgrade to install. Almost everything you need is available in
ftp://ftp.redhat.com/pub/current/i386/updates/2.0-kernel/ and its
mirrors.
For others, especially those of you running Slackware 3.0, David
Bourgin has put together a Slackware-compatible package of everything
For others, David Bourgin has put together a package of everything
necessary to quickly and easily upgrade to 2.0.x. See
ftp://ftp.wsc.com/pub/freeware/linux/update.linux/ for more information
and the files.
and the files. This package also includes many bug-fixes, including
one for a recently discovered bug in sendmail-8.7.5 (just look at
/pub/freeware/linux/update.linux/updat2-0.addon1/sendmail-8.7.5a.tar.gz
if you only need the bug fix). There's also an alternate lightweight
termcap in the same directory that works well for many people.
Please send info about any other packages that 2.0.x "broke" or about
any new features of 2.0.x that require extra or new packages for use to
......
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 15
SUBLEVEL = 16
ARCH = i386
......
......@@ -966,7 +966,7 @@ static int wait_for_completion(int delay, timeout_fn function)
return 1;
}
if (jiffies - delay < 0){
if ((signed) (jiffies - delay) < 0){
del_timer(&fd_timer);
fd_timer.function = function;
fd_timer.expires = delay;
......@@ -1415,7 +1415,7 @@ static void setup_rw_floppy(void)
* again just before spinup completion. Beware that
* after scandrives, we must again wait for selection.
*/
if (ready_date - jiffies > DP->select_delay){
if ((signed) (ready_date - jiffies) > DP->select_delay){
ready_date -= DP->select_delay;
function = (timeout_fn) floppy_start;
} else
......
/* $Id: icn.c,v 1.28 1996/06/28 17:02:53 fritz Exp $
/* $Id: icn.c,v 1.29 1996/08/29 20:34:54 fritz Exp $
*
* ISDN low-level module for the ICN active ISDN-Card.
*
......@@ -19,6 +19,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: icn.c,v $
* Revision 1.29 1996/08/29 20:34:54 fritz
* Bugfix in send queue management:
* sndcount was not updated correctly.
* Minor Bugfixes.
*
* Revision 1.28 1996/06/28 17:02:53 fritz
* replaced memcpy_fromfs_toio.
*
......@@ -136,7 +141,7 @@
#undef MAP_DEBUG
static char
*revision = "$Revision: 1.28 $";
*revision = "$Revision: 1.29 $";
static int icn_addcard(int, char *, char *);
......@@ -675,9 +680,7 @@ static void icn_polldchan(unsigned long data)
/* Append a packet to the transmit buffer-queue.
* Parameters:
* channel = Number of B-channel
* buffer = pointer to packet
* len = size of packet (max 4000)
* user = 1 = call from userproc, 0 = call from kernel
* skb = pointer to sk_buff
* card = pointer to card-struct
* Return:
* Number of bytes transferred, -E??? on error
......@@ -701,19 +704,25 @@ static int icn_sendbuf(int channel, struct sk_buff *skb, icn_card * card)
return 0;
save_flags(flags);
cli();
card->sndcount[channel] += len;
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
skb_queue_tail(&card->spqueue[channel], nskb);
dev_kfree_skb(skb, FREE_WRITE);
}
skb_queue_tail(&card->spqueue[channel], nskb);
dev_kfree_skb(skb, FREE_WRITE);
} else
len = 0;
card->sndcount[channel] += len;
restore_flags(flags);
if (!nskb)
return 0;
}
return len;
}
/*
* Check card's status after starting the bootstrap loader.
* On entry, the card's shared memory has already to be mapped.
* Return:
* 0 on success (Boot loader ready)
* -EIO on failure (timeout)
*/
static int icn_check_loader(int cardnumber)
{
int timer = 0;
......@@ -1162,7 +1171,19 @@ static int icn_command(isdn_ctrl * c, icn_card * card)
case ICN_IOCTL_GETDOUBLE:
return (int) card->doubleS0;
case ICN_IOCTL_DEBUGVAR:
return (ulong) card;
if ((i = verify_area(VERIFY_WRITE,
(void *) a,
sizeof(ulong) * 2)))
return i;
memcpy_tofs((char *)a,
(char *)&card, sizeof(ulong));
a += sizeof(ulong);
{
ulong l = (ulong)&dev;
memcpy_tofs((char *)a,
(char *)&l, sizeof(ulong));
}
return 0;
case ICN_IOCTL_LOADBOOT:
icn_stopcard(card);
return (icn_loadboot((u_char *) a, card));
......@@ -1630,7 +1651,7 @@ void cleanup_module(void)
}
card = card->next;
}
card = card;
card = cards;
while (card) {
last = card;
card = card->next;
......
/* $Id: icn.h,v 1.20 1996/06/24 17:20:37 fritz Exp $
/* $Id: icn.h,v 1.21 1996/08/29 20:35:57 fritz Exp $
*
* ISDN lowlevel-module for the ICN active ISDN-Card.
*
......@@ -19,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: icn.h,v $
* Revision 1.21 1996/08/29 20:35:57 fritz
* Speed up B-Channel polling interval.
*
* Revision 1.20 1996/06/24 17:20:37 fritz
* Bugfixes in pollbchan_send():
* - Using lock field of skbuff breaks networking.
......@@ -156,7 +159,7 @@ typedef struct icn_cdef {
#define ICN_BOOT_TIMEOUT1 100 /* Delay for Boot-download (jiffies) */
#define ICN_CHANLOCK_DELAY 10 /* Delay for Channel-mapping (jiffies) */
#define ICN_TIMER_BCREAD 3 /* B-Channel poll-cycle */
#define ICN_TIMER_BCREAD 1 /* B-Channel poll-cycle */
#define ICN_TIMER_DCREAD 50 /* D-Channel poll-cycle */
#define ICN_CODE_STAGE1 4096 /* Size of bootcode */
......
/* $Id: isdn_net.c,v 1.18 1996/07/03 13:48:51 hipp Exp $
/* $Id: isdn_net.c,v 1.20 1996/08/29 20:06:03 fritz Exp $
*
* Linux ISDN subsystem, network interfaces and related functions (linklevel).
*
......@@ -21,6 +21,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_net.c,v $
* Revision 1.20 1996/08/29 20:06:03 fritz
* Bugfix: Transmission timeout had been much to low.
*
* Revision 1.19 1996/08/12 16:24:32 hipp
* removed some (now) obsolete functions for syncPPP in rebuild_header etc.
*
* Revision 1.18 1996/07/03 13:48:51 hipp
* bugfix: Call dev_purge_queues() only for master device
*
......@@ -124,7 +130,7 @@ static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
extern void dev_purge_queues(struct device *dev); /* move this to net/core/dev.c */
char *isdn_net_revision = "$Revision: 1.18 $";
char *isdn_net_revision = "$Revision: 1.20 $";
/*
* Code for raw-networking over ISDN
......@@ -369,6 +375,10 @@ isdn_net_stat_callback(int idx, int cmd)
*/
lp->chargetime = jiffies;
/* Immediately send first skb to speed up arp */
#ifdef CONFIG_ISDN_PPP
if(lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
isdn_ppp_wakeup_daemon(lp);
#endif
if (lp->first_skb) {
if (!(isdn_net_xmit(&p->dev,lp,lp->first_skb)))
lp->first_skb = NULL;
......@@ -658,7 +668,6 @@ isdn_net_log_packet(u_char * buf, isdn_net_local * lp)
u_char *p = buf;
unsigned short proto = ETH_P_IP;
int data_ofs;
int len;
ip_ports *ipp;
char addinfo[100];
......@@ -676,22 +685,6 @@ isdn_net_log_packet(u_char * buf, isdn_net_local * lp)
proto = ntohs(*(unsigned short *)&buf[2]);
p = &buf[4];
break;
case ISDN_NET_ENCAP_SYNCPPP:
len = 4;
#ifdef CONFIG_ISDN_MPP
if (lp->ppp_minor!=-1) {
if (ippp_table[lp->ppp_minor]->mpppcfg &
SC_MP_PROT) {
if (ippp_table[lp->ppp_minor]->mpppcfg &
SC_OUT_SHORT_SEQ)
len = 7;
else
len = 9;
}
}
#endif
p = &buf[len];
break;
}
data_ofs = ((p[0] & 15) * 4);
switch (proto) {
......@@ -851,7 +844,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
if (ndev->tbusy) {
if (jiffies - ndev->trans_start < 20)
if (jiffies - ndev->trans_start < (2 * HZ))
return 1;
if (!lp->dialstate)
lp->stats.tx_errors++;
......@@ -1248,29 +1241,6 @@ isdn_net_header(struct sk_buff *skb, struct device *dev, unsigned short type,
*((ushort*)&skb->data[2]) = htons(type);
len = 4;
break;
#ifdef CONFIG_ISDN_PPP
case ISDN_NET_ENCAP_SYNCPPP:
/* reserve space to be filled in isdn_ppp_xmit */
len = 4;
#ifdef CONFIG_ISDN_MPP
if (lp->ppp_minor!=-1) {
if (ippp_table[lp->ppp_minor]->mpppcfg &
SC_MP_PROT) {
if (ippp_table[lp->ppp_minor]->mpppcfg &
SC_OUT_SHORT_SEQ)
len = 7;
else
len = 9;
}
}
#endif
/* Initialize first 4 bytes to a value, which is
* guaranteed to be invalid. Need that to check
* for already compressed packets in isdn_ppp_xmit().
*/
*((u32 *)skb_push(skb, len)) = 0;
break;
#endif
}
return len;
}
......@@ -1756,7 +1726,7 @@ isdn_net_find_icall(int di, int ch, int idx, char *num)
dev->st_netdev[idx] = lp->netdev;
p->local.isdn_device = di;
p->local.isdn_channel = ch;
p->local.ppp_minor = -1;
p->local.ppp_slot = -1;
p->local.pppbind = -1;
p->local.flags |= ISDN_NET_CONNECTED;
p->local.dialstate = 7;
......@@ -1927,7 +1897,7 @@ isdn_net_new(char *name, struct device *master)
netdev->local.pre_device = -1;
netdev->local.pre_channel = -1;
netdev->local.exclusive = -1;
netdev->local.ppp_minor = -1;
netdev->local.ppp_slot = -1;
netdev->local.pppbind = -1;
netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
......@@ -2443,8 +2413,7 @@ void dev_purge_queues(struct device *dev)
for(i=0;i<DEV_NUMBUFFS;i++) {
struct sk_buff *skb;
while((skb=skb_dequeue(&dev->buffs[i])))
if(skb->free)
kfree_skb(skb,FREE_WRITE);
dev_kfree_skb(skb,FREE_WRITE);
}
}
......
This diff is collapsed.
......@@ -51,5 +51,6 @@ extern int isdn_ppp_select(int, struct file *, int, select_table *);
extern int isdn_ppp_ioctl(int, struct file *, unsigned int, unsigned long);
extern void isdn_ppp_release(int, struct file *);
extern int isdn_ppp_dial_slave(char *);
extern void isdn_ppp_wakeup_daemon(isdn_net_local *);
extern struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
/* $Id: card.c,v 1.12 1996/06/24 17:16:52 fritz Exp $
/* $Id: card.c,v 1.13 1996/07/18 11:21:24 jdenoud Exp $
*
* card.c low level stuff for the Teles S0 isdn card
*
......@@ -7,6 +7,9 @@
* Beat Doebeli log all D channel traffic
*
* $Log: card.c,v $
* Revision 1.13 1996/07/18 11:21:24 jdenoud
* Use small buffers for incoming audio data
*
* Revision 1.12 1996/06/24 17:16:52 fritz
* Added check for misconfigured membase.
*
......@@ -424,7 +427,7 @@ hscx_interrupt(struct IsdnCardState *sp, byte val, byte hscx)
{
byte r;
struct HscxState *hsp = sp->hs + hscx;
int count;
int count, err;
if (!hsp->init)
return;
......@@ -471,9 +474,15 @@ hscx_interrupt(struct IsdnCardState *sp, byte val, byte hscx)
}
afterRME:
if (val & 0x40) { /* RPF */
if (!hsp->rcvibh)
if (BufPoolGet(&hsp->rcvibh, &hsp->rbufpool,
GFP_ATOMIC, (void *) 1, 2)) {
if (!hsp->rcvibh) {
if (hsp->mode == 1)
err=BufPoolGet(&hsp->rcvibh, &hsp->smallpool,
GFP_ATOMIC, (void *)1, 2);
else
err=BufPoolGet(&hsp->rcvibh, &hsp->rbufpool,
GFP_ATOMIC, (void *)1, 2);
if (err) {
printk(KERN_WARNING
"HSCX RPF out of buffers at %ld\n",
jiffies);
......@@ -482,7 +491,8 @@ hscx_interrupt(struct IsdnCardState *sp, byte val, byte hscx)
goto afterRPF;
} else
hsp->rcvptr = 0;
}
hscx_empty_fifo(hsp, 32);
if (hsp->mode == 1) {
/* receive audio data */
......
Fri Aug 30 10:00 1996 Gerard Roudier (groudier@club-internet.fr)
* ncr53c8xx.c - Version 1.12c
Incorporate the changes of FreeBSD/ncr.c revision 1.76.
The changes add support for the 53c860 and 53c875,
but without taking advantage of the new features.
Those chips are used exactly as the old 53c810.
Sun Jul 21 00:00 1996 Gerard Roudier (groudier@club-internet.fr)
* ncr53c8xx.c, README.ncr53c8xx
Add the ncr53c8xx_select_queue_depths() function.
......
......@@ -40,7 +40,7 @@
*/
/*
** 21 July 1996, version 1.12b
** 30 August 1996, version 1.12c
**
** Supported SCSI-II features:
** Synchronous negotiation
......@@ -55,6 +55,8 @@
** 53C815 (~53C810 with on board rom BIOS)
** 53C820 (Wide, NCR BIOS in flash bios required)
** 53C825 (Wide, ~53C820 with on board rom BIOS)
** 53C860 (not yet tested)
** 53C875 (not yet tested)
**
** Other features:
** Memory mapped IO (linux-1.3.X only)
......@@ -1492,7 +1494,7 @@ static void ncr_alloc_ccb (ncb_p np, u_long t, u_long l);
static void ncr_complete (ncb_p np, ccb_p cp);
static void ncr_exception (ncb_p np);
static void ncr_free_ccb (ncb_p np, ccb_p cp);
static void ncr_getclock (ncb_p np);
static void ncr_getclock (ncb_p np, u_char scntl3);
static ccb_p ncr_get_ccb (ncb_p np, u_long t,u_long l);
static void ncr_init (ncb_p np, char * msg, u_long code);
static int ncr_intr (ncb_p np);
......@@ -3540,7 +3542,7 @@ printf("ncr_attach: unit=%d chip=%d base=%x, io_port=%x, irq=%d\n", unit, chip,
** Find the right value for scntl3.
*/
ncr_getclock (np);
ncr_getclock (np, INB(nc_scntl3));
/*
** Reset chip.
......@@ -4816,8 +4818,8 @@ void ncr_init (ncb_p np, char * msg, u_long code)
if ((ChipDevice == PCI_DEVICE_ID_NCR_53C825 && ChipVersion >= 0x10) ||
ChipDevice == PCI_DEVICE_ID_NCR_53C875) {
OUTB(nc_dmode, 0xc0); /* Set 16-transfer burst */
OUTB(nc_ctest5, 0x04); /* Set DMA FIFO to 88 */
#if 0
OUTB(nc_ctest5, 0x04); /* Set DMA FIFO to 88 */
OUTB(nc_ctest5, 0x24); /* Set DMA FIFO to 536 */
OUTB(nc_dmode, 0x40); /* Set 64-transfer burst */
OUTB(nc_ctest3, 0x01); /* Set write and invalidate */
......@@ -6278,9 +6280,18 @@ void ncr_int_sir (ncb_p np)
/*
** Check against controller limits.
*/
fak = (4ul * per - 1) / np->ns_sync - 3;
if (ofs && (fak>7)) {chg = 1; ofs = 0;}
if (!ofs) fak=7;
if (ofs != 0) {
fak = (4ul * per - 1) / np->ns_sync - 3;
if (fak>7) {
chg = 1;
ofs = 0;
}
}
if (ofs == 0) {
fak = 7;
per = 0;
tp->minsync = 0;
}
if (DEBUG_FLAGS & DEBUG_NEGO) {
PRINT_ADDR(cp->cmd);
......@@ -7311,8 +7322,9 @@ static u_long ncr_lookup(char * id)
#endif /* NCR_CLOCK */
static void ncr_getclock (ncb_p np)
static void ncr_getclock (ncb_p np, u_char scntl3)
{
#if 0
u_char tbl[5] = {6,2,3,4,6};
u_char f;
u_char ns_clock = (1000/NCR_CLOCK);
......@@ -7335,6 +7347,25 @@ static void ncr_getclock (ncb_p np)
if (DEBUG_FLAGS & DEBUG_TIMING)
printf ("%s: sclk=%d async=%d sync=%d (ns) scntl3=0x%x\n",
ncr_name (np), ns_clock, np->ns_async, np->ns_sync, np->rv_scntl3);
#else
/*
* For now just preserve the BIOS setting ...
*/
if ((scntl3 & 7) < 3) {
printf ("%s: assuming 40MHz clock", ncr_name(np));
scntl3 = 3; /* assume 40MHz if no value supplied by BIOS */
}
np->ns_sync = 25;
np->ns_async = 50;
np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7);
if (bootverbose) {
printf ("%s: initial value of SCNTL3 = %02x, final = %02x\n",
ncr_name(np), scntl3, np->rv_scntl3);
}
#endif
}
/*===================== LINUX ENTRY POINTS SECTION ==========================*/
......
......@@ -196,7 +196,7 @@ int ncr53c8xx_release(struct Scsi_Host *);
#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
#define NCR53C8XX {NULL,NULL,NULL,NULL,"ncr53c8xx (rel 1.12b)", ncr53c8xx_detect,\
#define NCR53C8XX {NULL,NULL,NULL,NULL,"ncr53c8xx (rel 1.12c)", ncr53c8xx_detect,\
ncr53c8xx_release, /* info */ NULL, /* command, deprecated */ NULL, \
ncr53c8xx_queue_command, ncr53c8xx_abort, ncr53c8xx_reset, \
NULL /* slave attach */, scsicam_bios_param, /* can queue */ SCSI_NCR_CAN_QUEUE,\
......@@ -207,7 +207,7 @@ int ncr53c8xx_release(struct Scsi_Host *);
#else
#define NCR53C8XX {NULL, NULL, "ncr53c8xx (rel 1.12b)", ncr53c8xx_detect,\
#define NCR53C8XX {NULL, NULL, "ncr53c8xx (rel 1.12c)", ncr53c8xx_detect,\
ncr53c8xx_release, /* info */ NULL, /* command, deprecated */ NULL, \
ncr53c8xx_queue_command, ncr53c8xx_abort, ncr53c8xx_reset, \
NULL /* slave attach */, scsicam_bios_param, /* can queue */ SCSI_NCR_CAN_QUEUE,\
......
......@@ -275,8 +275,39 @@ static void sg_command_done(Scsi_Cmnd * SCpnt)
* See if the command completed normally, or whether something went
* wrong.
*/
memcpy(device->header.sense_buffer, SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
device->header.result = (SCpnt->sense_buffer[0] == 0 ? 0 : EIO);
memcpy(device->header.sense_buffer, SCpnt->sense_buffer,
sizeof(SCpnt->sense_buffer));
switch (host_byte(SCpnt->result)) {
case DID_OK:
device->header.result = 0;
break;
case DID_NO_CONNECT:
case DID_BUS_BUSY:
case DID_TIME_OUT:
device->header.result = EBUSY;
break;
case DID_BAD_TARGET:
case DID_ABORT:
case DID_PARITY:
case DID_RESET:
case DID_BAD_INTR:
device->header.result = EIO;
break;
case DID_ERROR:
/*
* There really should be DID_UNDERRUN and DID_OVERRUN error values,
* and a means for callers of scsi_do_cmd to indicate whether an
* underrun or overrun should signal an error. Until that can be
* implemented, this kludge allows for returning useful error values
* except in cases that return DID_ERROR that might be due to an
* underrun.
*/
if (SCpnt->sense_buffer[0] == 0 &&
status_byte(SCpnt->result) == GOOD)
device->header.result = 0;
else device->header.result = EIO;
break;
}
/*
* Now wake up the process that is waiting for the
......
This diff is collapsed.
......@@ -1182,7 +1182,7 @@ DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
if (!audio_devs[dev]->go)
tmout = 0;
else
tmout = 2 * HZ;
tmout = 10 * HZ;
{
......
......@@ -968,11 +968,6 @@ struct buffer_head * breada(kdev_t dev, int block, int bufsize,
*/
static void put_unused_buffer_head(struct buffer_head * bh)
{
struct wait_queue * wait;
wait = ((volatile struct buffer_head *) bh)->b_wait;
memset(bh,0,sizeof(*bh));
((volatile struct buffer_head *) bh)->b_wait = wait;
bh->b_next_free = unused_list;
unused_list = bh;
wake_up(&buffer_wait);
......@@ -1402,6 +1397,11 @@ static int grow_buffers(int pri, int size)
/* =========== Reduce the buffer memory ============= */
static inline int buffer_waiting(struct buffer_head * bh)
{
return waitqueue_active(&bh->b_wait);
}
/*
* try_to_free_buffer() checks if all the buffers on this particular page
* are unused, and free's the page if so.
......@@ -1421,7 +1421,8 @@ int try_to_free_buffer(struct buffer_head * bh, struct buffer_head ** bhp,
if (!tmp)
return 0;
if (tmp->b_count || buffer_protected(tmp) ||
buffer_dirty(tmp) || buffer_locked(tmp) || tmp->b_wait)
buffer_dirty(tmp) || buffer_locked(tmp) ||
buffer_waiting(bh))
return 0;
if (priority && buffer_touched(tmp))
return 0;
......
......@@ -132,6 +132,15 @@ static struct file_lock *file_lock_table = NULL;
/* Free lock not inserted in any queue */
static inline void locks_free_lock(struct file_lock *fl)
{
/*
* CAREFUL! We can't free it until everybody waiting for
* this block have removed themselves from the wait queue
*/
if (fl->fl_wait) {
struct wait_queue *head = WAIT_QUEUE_HEAD(&fl->fl_wait);
while (fl->fl_wait != head)
schedule();
}
kfree(fl);
return;
}
......@@ -636,10 +645,12 @@ static int posix_locks_deadlock(struct task_struct *my_task,
if (my_task == blocked_task)
return (1);
for (fl = file_lock_table; fl != NULL; fl = fl->fl_nextlink) {
struct wait_queue *head;
if (fl->fl_owner == NULL || fl->fl_wait == NULL)
continue;
head = WAIT_QUEUE_HEAD(&fl->fl_wait);
dlock_wait = fl->fl_wait;
do {
while (dlock_wait != head) {
if (dlock_wait->task == blocked_task) {
if (fl->fl_owner == my_task) {
return (1);
......@@ -648,7 +659,7 @@ static int posix_locks_deadlock(struct task_struct *my_task,
goto next_task;
}
dlock_wait = dlock_wait->next;
} while (dlock_wait != fl->fl_wait);
}
}
return (0);
}
......@@ -979,7 +990,7 @@ static void locks_delete_lock(struct file_lock **fl_p, unsigned int wait)
}
wake_up(&fl->fl_wait);
kfree(fl);
locks_free_lock(fl);
return;
}
......@@ -1014,10 +1025,11 @@ static char *lock_get_status(struct file_lock *fl, char *p, int id, char *pfx)
(long)fl, (long)fl->fl_prevlink, (long)fl->fl_nextlink,
(long)fl->fl_next, (long)fl->fl_block, id, pfx);
if ((wt = fl->fl_wait) != NULL) {
do {
struct wait_queue *head = WAIT_QUEUE_HEAD(&fl->fl_wait);
while (wt != head) {
p += sprintf(p, " %d", wt->task->pid);
wt = wt->next;
} while (wt != fl->fl_wait);
}
}
p += sprintf(p, "\n");
return (p);
......
/* $Id: isdn.h,v 1.15 1996/06/15 14:56:57 fritz Exp $
/* $Id: isdn.h,v 1.16 1996/08/12 16:20:56 hipp Exp $
*
* Main header for the Linux ISDN subsystem (linklevel).
*
......@@ -21,6 +21,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn.h,v $
* Revision 1.16 1996/08/12 16:20:56 hipp
* renamed ppp_minor to ppp_slot
*
* Revision 1.15 1996/06/15 14:56:57 fritz
* Added version signatures for data structures used
* by userlevel programs.
......@@ -319,7 +322,7 @@ typedef struct isdn_net_local_s {
struct enet_statistics stats; /* Ethernet Statistics */
int isdn_device; /* Index to isdn-device */
int isdn_channel; /* Index to isdn-channel */
int ppp_minor; /* PPPD device minor number */
int ppp_slot; /* PPPD device slot number */
int pre_device; /* Preselected isdn-device */
int pre_channel; /* Preselected isdn-channel */
int exclusive; /* If non-zero idx to reserved chan.*/
......@@ -549,6 +552,7 @@ struct ippp_struct {
unsigned int maxcid;
isdn_net_local *lp;
int unit;
int minor;
long last_link_seqno;
long mp_seqno;
long range;
......
......@@ -401,12 +401,10 @@ extern inline struct file *file_from_fd(const unsigned int fd)
extern inline void __add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
struct wait_queue *head = *p;
struct wait_queue *next = wait;
struct wait_queue *next = WAIT_QUEUE_HEAD(p);
if (head) {
next = head->next;
p = &head->next;
}
if (head)
next = head;
*p = wait;
wait->next = next;
}
......@@ -424,22 +422,15 @@ extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wa
extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
struct wait_queue * next = wait->next;
struct wait_queue * head = next;
if (wait == next) {
*p = NULL;
} else {
struct wait_queue *head = *p;
if (head == wait)
*p = next;
for (;;) {
struct wait_queue *nextlist = head->next;
if (nextlist == wait)
break;
head = nextlist;
}
head->next = next;
for (;;) {
struct wait_queue * nextlist = head->next;
if (nextlist == wait)
break;
head = nextlist;
}
wait->next = NULL;
head->next = next;
}
extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
......
......@@ -742,15 +742,13 @@ typedef struct copr_msg {
/* Note! Number 31 cannot be used since the sign bit is reserved */
#ifdef NO_LONGER_AVAILABLE
/*
* The following unsupported macros will be removed from the API in near
* future.
* The following unsupported macros are no longer functional.
* Use SOUND_MIXER_PRIVATE# macros in future.
*/
#define SOUND_MIXER_ENHANCE 29 /* Enhanced stereo (0, 40, 60 or 80) */
#define SOUND_MIXER_MUTE 28 /* 0 or 1 */
#define SOUND_MIXER_LOUD 30 /* 0 or 1 */
#endif
#define SOUND_MIXER_ENHANCE 31
#define SOUND_MIXER_MUTE 31
#define SOUND_MIXER_LOUD 31
#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \
......@@ -790,11 +788,10 @@ typedef struct copr_msg {
#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2)
#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3)
#ifdef NO_LONGER_AVAILABLE
/* Obsolete macros */
#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
#endif
#define MIXER_READ(dev) _IOR('M', dev, int)
#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
......@@ -814,11 +811,11 @@ typedef struct copr_msg {
#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1)
#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2)
#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3)
#ifdef NO_LONGER_AVAILABLE
/* Obsolete macros */
#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
#endif
#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
......@@ -844,11 +841,11 @@ typedef struct copr_msg {
#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1)
#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2)
#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3)
#ifdef NO_LONGER_AVAILABLE
/* Obsolete macros */
#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
#endif
#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
......
......@@ -13,6 +13,19 @@ struct wait_queue {
struct wait_queue * next;
};
#define WAIT_QUEUE_HEAD(x) ((struct wait_queue *)((x)-1))
static inline void init_waitqueue(struct wait_queue **q)
{
*q = WAIT_QUEUE_HEAD(q);
}
static inline int waitqueue_active(struct wait_queue **q)
{
struct wait_queue *head = *q;
return head && head != WAIT_QUEUE_HEAD(q);
}
struct semaphore {
int count;
struct wait_queue * wait;
......
......@@ -94,6 +94,7 @@ extern void BusLogic_Setup(char *str, int *ints);
extern void fdomain_setup(char *str, int *ints);
extern void in2000_setup(char *str, int *ints);
extern void NCR53c406a_setup(char *str, int *ints);
extern void wd7000_setup(char *str, int *ints);
extern void ppa_setup(char *str, int *ints);
extern void scsi_luns_setup(char *str, int *ints);
extern void sound_setup(char *str, int *ints);
......@@ -330,6 +331,9 @@ struct {
#ifdef CONFIG_SCSI_IN2000
{ "in2000=", in2000_setup},
#endif
#ifdef CONFIG_SCSI_7000FASST
{ "wd7000=", wd7000_setup},
#endif
#ifdef CONFIG_SCSI_PPA
{ "ppa=", ppa_setup },
#endif
......
......@@ -193,8 +193,7 @@ static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg
msq->msg_lspid = current->pid;
msq->msg_stime = CURRENT_TIME;
restore_flags(flags);
if (msq->rwait)
wake_up (&msq->rwait);
wake_up (&msq->rwait);
return 0;
}
......@@ -350,8 +349,7 @@ static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgty
msghdrs--;
msq->msg_cbytes -= nmsg->msg_ts;
restore_flags(flags);
if (msq->wwait)
wake_up (&msq->wwait);
wake_up (&msq->wwait);
/*
* Calls from kernel level (IPC_KERNELD set)
* wants the message copied to kernel space!
......@@ -438,8 +436,7 @@ static int newque (key_t key, int msgflg)
msq = (struct msqid_ds *) kmalloc (sizeof (*msq), GFP_KERNEL);
if (!msq) {
msgque[id] = (struct msqid_ds *) IPC_UNUSED;
if (msg_lock)
wake_up (&msg_lock);
wake_up (&msg_lock);
return -ENOMEM;
}
ipcp = &msq->msg_perm;
......@@ -459,8 +456,7 @@ static int newque (key_t key, int msgflg)
max_msqid = id;
msgque[id] = msq;
used_queues++;
if (msg_lock)
wake_up (&msg_lock);
wake_up (&msg_lock);
return (unsigned int) msq->msg_perm.seq * MSGMNI + id;
}
......@@ -525,11 +521,9 @@ static void freeque (int id)
while (max_msqid && (msgque[--max_msqid] == IPC_UNUSED));
msgque[id] = (struct msqid_ds *) IPC_UNUSED;
used_queues--;
while (msq->rwait || msq->wwait) {
if (msq->rwait)
wake_up (&msq->rwait);
if (msq->wwait)
wake_up (&msq->wwait);
while (waitqueue_active(&msq->rwait) || waitqueue_active(&msq->wwait)) {
wake_up (&msq->rwait);
wake_up (&msq->wwait);
schedule();
}
for (msgp = msq->msg_first; msgp; msgp = msgh ) {
......
......@@ -103,8 +103,7 @@ static int newary (key_t key, int nsems, int semflg)
if (!sma) {
semary[id] = (struct semid_ds *) IPC_UNUSED;
used_sems -= nsems;
if (sem_lock)
wake_up (&sem_lock);
wake_up (&sem_lock);
return -ENOMEM;
}
memset (sma, 0, size);
......@@ -124,8 +123,7 @@ static int newary (key_t key, int nsems, int semflg)
max_semid = id;
used_semids++;
semary[id] = sma;
if (sem_lock)
wake_up (&sem_lock);
wake_up (&sem_lock);
return (unsigned int) sma->sem_perm.seq * SEMMNI + id;
}
......
......@@ -92,16 +92,14 @@ static int newseg (key_t key, int shmflg, int size)
shp = (struct shmid_ds *) kmalloc (sizeof (*shp), GFP_KERNEL);
if (!shp) {
shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
if (shm_lock)
wake_up (&shm_lock);
wake_up (&shm_lock);
return -ENOMEM;
}
shp->shm_pages = (ulong *) kmalloc (numpages*sizeof(ulong),GFP_KERNEL);
if (!shp->shm_pages) {
shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
if (shm_lock)
wake_up (&shm_lock);
wake_up (&shm_lock);
kfree(shp);
return -ENOMEM;
}
......@@ -125,8 +123,7 @@ static int newseg (key_t key, int shmflg, int size)
max_shmid = id;
shm_segs[id] = shp;
used_segs++;
if (shm_lock)
wake_up (&shm_lock);
wake_up (&shm_lock);
return (unsigned int) shp->shm_perm.seq * SHMMNI + id;
}
......
......@@ -247,6 +247,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->prev_run = NULL;
p->p_pptr = p->p_opptr = current;
p->p_cptr = NULL;
init_waitqueue(&p->wait_chldexit);
p->signal = 0;
p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
......
......@@ -431,51 +431,55 @@ asmlinkage int sys_pause(void)
*/
void wake_up(struct wait_queue **q)
{
struct wait_queue *tmp;
struct task_struct * p;
struct wait_queue *next;
struct wait_queue *head;
if (!q || !(tmp = *q))
if (!q || !(next = *q))
return;
do {
if ((p = tmp->task) != NULL) {
head = WAIT_QUEUE_HEAD(q);
while (next != head) {
struct task_struct *p = next->task;
next = next->next;
if (p != NULL) {
if ((p->state == TASK_UNINTERRUPTIBLE) ||
(p->state == TASK_INTERRUPTIBLE))
wake_up_process(p);
}
if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n",
__builtin_return_address(0));
printk(" q = %p\n",q);
printk(" *q = %p\n",*q);
printk(" tmp = %p\n",tmp);
break;
}
tmp = tmp->next;
} while (tmp != *q);
if (!next)
goto bad;
}
return;
bad:
printk("wait_queue is bad (eip = %p)\n",
__builtin_return_address(0));
printk(" q = %p\n",q);
printk(" *q = %p\n",*q);
}
void wake_up_interruptible(struct wait_queue **q)
{
struct wait_queue *tmp;
struct task_struct * p;
struct wait_queue *next;
struct wait_queue *head;
if (!q || !(tmp = *q))
if (!q || !(next = *q))
return;
do {
if ((p = tmp->task) != NULL) {
head = WAIT_QUEUE_HEAD(q);
while (next != head) {
struct task_struct *p = next->task;
next = next->next;
if (p != NULL) {
if (p->state == TASK_INTERRUPTIBLE)
wake_up_process(p);
}
if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n",
__builtin_return_address(0));
printk(" q = %p\n",q);
printk(" *q = %p\n",*q);
printk(" tmp = %p\n",tmp);
break;
}
tmp = tmp->next;
} while (tmp != *q);
if (!next)
goto bad;
}
return;
bad:
printk("wait_queue is bad (eip = %p)\n",
__builtin_return_address(0));
printk(" q = %p\n",q);
printk(" *q = %p\n",*q);
}
void __down(struct semaphore * sem)
......
......@@ -1298,6 +1298,7 @@ void net_alias_init(void)
*/
#ifndef ALIAS_USER_LAND_DEBUG
#ifdef CONFIG_PROC_FS
proc_net_register(&(struct proc_dir_entry) {
PROC_NET_ALIAS_TYPES, 11, "alias_types",
S_IFREG | S_IRUGO, 1, 0, 0,
......@@ -1311,6 +1312,7 @@ void net_alias_init(void)
net_alias_getinfo
});
#endif
#endif
}
......
......@@ -966,8 +966,10 @@ void tcp_send_ack(struct sock *sk)
sock_wfree(sk, buff);
return;
}
#if 0 /* why does this result in problems? */
#ifndef CONFIG_NO_PATH_MTU_DISCOVERY
buff->ip_hdr->frag_off |= htons(IP_DF);
#endif
#endif
t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
......
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