On Mon, 27 Jan 1997, Linus Torvalds wrote:
> The select->poll changes make the source compile, but do not actually do
> quite the right thing. The poll changes weren't only a matter of naming
> changes, but also changed semantics somewhat (I don't do naming changes
> just to change names usually: there is a reason why I didn't want
> unmodified code to compile - it needs to get subtly fixed first).
>
> Anyway, I should have made the changes clear in my announcement of 2.1.23,
> but I was too lazy. The changes in the poll behaviour can be broken down
> into four different sub-areas:
[snip]
Thanks, Linus, the explanation made it all clear - I had seen in the other
drivers that poll_wait was being called unconditionally, but I didn't know
why. The attached patch attempts to do the Right Thing with the sound
driver, I hope I got it all right. There is plenty of goto's in one of the
files, simply because they were there before, masked by returns, and I was
afraid I might lose some cases if I converted them to some more structured
code.
Hannu will probably come up with his own version in a week or two, in the
meanwhile this patch should do it for the rest of us. :-)
The other changes are also here (floppy, softdog, binfmt_script and
/proc/swap).
Ionut
--
It is better to keep your mouth shut and be thought a fool,
than to open it and remove all doubt.
--- linux-2.1.23/fs/proc/array.c.old Sun Jan 26 05:07:45 1997
+++ linux-2.1.23/fs/proc/array.c Sun Jan 26 17:25:47 1997
@@ -1011,6 +1011,7 @@
extern int get_md_status (char *);
extern int get_rtc_status (char *);
extern int get_locks_status (char *);
+extern int get_swaparea_info (char *);
#ifdef __SMP_PROF__
extern int get_smp_prof_list(char *);
#endif
@@ -1088,6 +1089,9 @@
case PROC_MTAB:
return get_filesystem_info( page );
+
+ case PROC_SWAP:
+ return get_swaparea_info(page);
#ifdef CONFIG_RTC
case PROC_RTC:
return get_rtc_status(page);
--- linux-2.1.23/fs/proc/root.c.old Sun Jan 26 05:07:45 1997
+++ linux-2.1.23/fs/proc/root.c Sun Jan 26 17:27:59 1997
@@ -510,6 +510,10 @@
PROC_MTAB, 6, "mounts",
S_IFREG | S_IRUGO, 1, 0, 0,
};
+static struct proc_dir_entry proc_root_swaps = {
+ PROC_MTAB, 5, "swaps",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+};
static struct proc_dir_entry proc_root_profile = {
PROC_PROFILE, 7, "profile",
S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
@@ -572,6 +576,7 @@
proc_register(&proc_root, &proc_root_locks);
proc_register(&proc_root, &proc_root_mounts);
+ proc_register(&proc_root, &proc_root_swaps);
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
#ifdef CONFIG_SUN_OPENPROMFS
--- linux-2.1.23/fs/binfmt_script.c.old Sun Jan 26 05:07:30 1997
+++ linux-2.1.23/fs/binfmt_script.c Sun Jan 26 17:06:41 1997
@@ -76,7 +76,6 @@
/*
* OK, now restart the process with the interpreter's inode.
*/
- bprm->filename = interp;
retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
if (retval)
return retval;
--- linux-2.1.23/mm/swapfile.c.old Sun Jan 26 05:07:49 1997
+++ linux-2.1.23/mm/swapfile.c Sun Jan 26 17:29:04 1997
@@ -18,6 +18,7 @@
#include <linux/swap.h>
#include <linux/fs.h>
#include <linux/swapctl.h>
+#include <linux/malloc.h>
#include <linux/blkdev.h> /* for blk_size */
#include <linux/vmalloc.h>
@@ -393,6 +394,8 @@
nr_swap_pages -= p->pages;
iput(p->swap_file);
+ if (p->swap_filename)
+ kfree(p->swap_filename);
p->swap_file = NULL;
p->swap_device = 0;
vfree(p->swap_map);
@@ -406,6 +409,37 @@
return err;
}
+int get_swaparea_info(char *buf)
+{
+ struct swap_info_struct *ptr = swap_info;
+ int i, j, len = 0, usedswap;
+
+ len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+ for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
+ if (ptr->flags & SWP_USED) {
+ if (ptr->swap_filename)
+ len += sprintf(buf + len, "%-31s ", ptr->swap_filename);
+ else
+ len += sprintf(buf + len, "(null)\t\t\t");
+ if (ptr->swap_file)
+ len += sprintf(buf + len, "file\t\t");
+ else
+ len += sprintf(buf + len, "partition\t");
+ usedswap = 0;
+ for (j = 0; j < ptr->max; ++j)
+ switch (ptr->swap_map[j]) {
+ case 128:
+ case 0:
+ continue;
+ default:
+ usedswap++;
+ }
+ len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10),
+ usedswap << (PAGE_SHIFT - 10), ptr->prio);
+ }
+ return len;
+}
+
/*
* Written 01/25/92 by Simmule Turner, heavily changed by Linus.
*
@@ -418,6 +452,7 @@
unsigned int type;
int i, j, prev;
int error = -EPERM;
+ char *tmp;
struct file filp;
static int least_priority = 0;
@@ -434,6 +469,7 @@
if (type >= nr_swapfiles)
nr_swapfiles = type+1;
p->flags = SWP_USED;
+ p->swap_filename = NULL;
p->swap_file = NULL;
p->swap_device = 0;
p->swap_map = NULL;
@@ -541,6 +577,12 @@
prev = i;
}
p->next = i;
+ if (!getname(specialfile, &tmp)) {
+ if ((p->swap_filename =
+ (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
+ strcpy(p->swap_filename, tmp);
+ putname(tmp);
+ }
if (prev < 0) {
swap_list.head = swap_list.next = p - swap_info;
} else {
--- linux-2.1.23/include/linux/swap.h.old Sat Nov 23 05:29:04 1996
+++ linux-2.1.23/include/linux/swap.h Sun Jan 26 17:25:47 1997
@@ -19,6 +19,7 @@
struct swap_info_struct {
unsigned int flags;
kdev_t swap_device;
+ char *swap_filename;
struct inode * swap_file;
unsigned char * swap_map;
unsigned char * swap_lockmap;
--- linux-2.1.23/include/linux/proc_fs.h.old Sun Jan 26 05:21:20 1997
+++ linux-2.1.23/include/linux/proc_fs.h Sun Jan 26 17:25:47 1997
@@ -43,6 +43,7 @@
PROC_CMDLINE,
PROC_SYS,
PROC_MTAB,
+ PROC_SWAP,
PROC_MD,
PROC_RTC,
PROC_LOCKS,
--- linux-2.1.23/drivers/block/floppy.c.old Sun Jan 26 05:07:10 1997
+++ linux-2.1.23/drivers/block/floppy.c Sun Jan 26 18:56:58 1997
@@ -4128,7 +4128,6 @@
extern char *get_options(char *str, int *ints);
char *floppy=NULL;
-MODULE_PARM(floppy, "s");
static void parse_floppy_cfg_string(char *cfg)
{
--- linux-2.1.23/drivers/char/softdog.c.old Thu Dec 12 09:51:09 1996
+++ linux-2.1.23/drivers/char/softdog.c Sun Jan 26 17:37:29 1997
@@ -46,6 +46,7 @@
struct timer_list watchdog_ticktock;
static int timer_alive = 0;
+static int in_use = 0;
/*
@@ -70,8 +71,9 @@
static int softdog_open(struct inode *inode, struct file *file)
{
- if(timer_alive)
+ if(in_use)
return -EBUSY;
+ in_use = 1;
MOD_INC_USE_COUNT;
/*
* Activate timer
@@ -94,6 +96,7 @@
MOD_DEC_USE_COUNT;
timer_alive=0;
#endif
+ in_use = 0;
}
static void softdog_ping(void)
--- linux-2.1.23/drivers/sound/dmabuf.c.old Sun Nov 24 09:32:06 1996
+++ linux-2.1.23/drivers/sound/dmabuf.c Tue Jan 28 01:39:25 1997
@@ -11,7 +11,7 @@
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/poll.h>
#include "sound_config.h"
@@ -1834,109 +1834,70 @@
{
}
-int
-DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+DMAbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
+ unsigned int mask = 0;
struct dma_buffparms *dmap;
unsigned long flags;
- switch (sel_type)
- {
- case SEL_IN:
- if (!(audio_devs[dev]->open_mode))
- return 0;
-
- dmap = audio_devs[dev]->dmap_in;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
-
- save_flags (flags);
- cli ();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&in_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
-
- if (dmap->dma_mode != DMODE_INPUT)
- {
- if (dmap->dma_mode == DMODE_NONE &&
- audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
- !dmap->qlen &&
- audio_devs[dev]->go)
- {
- unsigned long flags;
-
- save_flags (flags);
- cli ();
- activate_recording (dev, dmap);
- restore_flags (flags);
- }
- return 0;
- }
-
- if (!dmap->qlen)
- {
- save_flags (flags);
- cli ();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&in_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- dmap = audio_devs[dev]->dmap_out;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
+ save_flags (flags);
+ cli ();
- save_flags (flags);
- cli ();
+ in_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&in_sleeper[dev], wait);
+ out_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&out_sleeper[dev], wait);
- out_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&out_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
-
- if (dmap->dma_mode == DMODE_INPUT)
- {
- return 0;
- }
+ restore_flags (flags);
- if (dmap->dma_mode == DMODE_NONE)
- {
- return 1;
- }
+/* sel_in */
+ dmap = audio_devs[dev]->dmap_in;
+ if (!(audio_devs[dev]->open_mode))
+ goto sel_out;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ if (dmap->qlen)
+ mask |= POLLIN | POLLRDNORM;
+ goto sel_out;
+ }
+ if (dmap->dma_mode != DMODE_INPUT) {
+ if (dmap->dma_mode == DMODE_NONE &&
+ audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
+ !dmap->qlen &&
+ audio_devs[dev]->go) {
+ unsigned long flags;
- if (!space_in_queue (dev))
- {
- save_flags (flags);
- cli ();
+ save_flags (flags);
+ cli ();
+ activate_recording (dev, dmap);
+ restore_flags (flags);
+ }
+ goto sel_out;
+ }
+ if (!dmap->qlen)
+ goto sel_out;
+ mask |= POLLIN | POLLRDNORM;
- out_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&out_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
- return 1;
- break;
+ sel_out:
+ dmap = audio_devs[dev]->dmap_out;
- case SEL_EX:
- return 0;
- }
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ if (dmap->qlen)
+ mask |= POLLOUT | POLLWRNORM;
+ goto sel_ex;
+ }
+ if (dmap->dma_mode == DMODE_INPUT)
+ goto sel_ex;
+ if (dmap->dma_mode == DMODE_NONE) {
+ mask |= POLLOUT | POLLWRNORM;
+ goto sel_ex;
+ }
+ if (!space_in_queue (dev))
+ goto sel_ex;
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+sel_ex:
+ return mask;
}
--- linux-2.1.23/drivers/sound/sound_calls.h.old Fri Nov 15 03:14:55 1996
+++ linux-2.1.23/drivers/sound/sound_calls.h Tue Jan 28 01:37:43 1997
@@ -18,7 +18,7 @@
void DMAbuf_reset_dma (int dev);
void DMAbuf_inputintr(int dev);
void DMAbuf_outputintr(int dev, int underflow_flag);
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int DMAbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
void DMAbuf_start_device(int dev);
void DMAbuf_start_devices(unsigned int devmask);
void DMAbuf_reset (int dev);
@@ -36,7 +36,7 @@
unsigned int cmd, caddr_t arg);
void audio_init_devices (void);
-int audio_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int audio_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
* System calls for the /dev/sequencer
@@ -56,7 +56,7 @@
void seq_input_event(unsigned char *event, int len);
void seq_copy_to_input (unsigned char *event, int len);
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int sequencer_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
* System calls for the /dev/midi
@@ -72,7 +72,7 @@
void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
void MIDIbuf_init(void);
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int MIDIbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
*
--- linux-2.1.23/drivers/sound/audio.c.old Sun Jan 26 19:13:45 1997
+++ linux-2.1.23/drivers/sound/audio.c Tue Jan 28 01:39:00 1997
@@ -12,7 +12,7 @@
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/poll.h>
#include "sound_config.h"
@@ -542,44 +542,31 @@
*/
}
-int
-audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+audio_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
char *dma_buf;
+ unsigned int mask = 0;
int buf_no, buf_ptr, buf_size;
dev = dev >> 4;
- switch (sel_type)
- {
- case SEL_IN:
- if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- return 0; /* Not recording */
- }
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
-
- case SEL_OUT:
- if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- return 0; /* Wrong direction */
- }
-
- if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
- {
- return 1; /* There is space in the current buffer */
- }
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
+ mask = DMAbuf_poll (dev, file, wait);
- case SEL_EX:
- return 0;
- }
+/* sel_in */
+ if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ mask &= ~(POLLIN | POLLRDNORM); /* Wrong direction */
+
+/* sel_out */
+ if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX)) {
+ mask &= ~(POLLOUT | POLLWRNORM); /* Wrong direction */
+ goto sel_ex;
+ }
+ if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+ sel_ex:
+ return mask;
}
--- linux-2.1.23/drivers/sound/midibuf.c.old Fri Nov 15 03:15:25 1996
+++ linux-2.1.23/drivers/sound/midibuf.c Tue Jan 28 01:39:39 1997
@@ -11,6 +11,7 @@
* for more info.
*/
#include <linux/config.h>
+#include <linux/poll.h>
#include "sound_config.h"
@@ -497,40 +498,21 @@
}
}
-int
-MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+MIDIbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (!DATA_AVAIL (midi_in_buf[dev]))
- {
-
- input_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&input_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- if (SPACE_AVAIL (midi_out_buf[dev]))
- {
-
- midi_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&midi_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
+ unsigned int mask = 0;
- return 0;
+ input_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&input_sleeper[dev], wait);
+ midi_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&midi_sleeper[dev], wait);
+
+ if (DATA_AVAIL (midi_in_buf[dev]))
+ mask |= POLLIN | POLLRDNORM;
+ if (!SPACE_AVAIL (midi_out_buf[dev]))
+ mask |= POLLOUT | POLLWRNORM;
+ return mask;
}
--- linux-2.1.23/drivers/sound/sequencer.c.old Fri Nov 15 03:15:37 1996
+++ linux-2.1.23/drivers/sound/sequencer.c Tue Jan 28 01:39:49 1997
@@ -11,6 +11,7 @@
* for more info.
*/
#include <linux/config.h>
+#include <linux/poll.h>
#define SEQUENCER_C
@@ -1768,50 +1769,28 @@
return -EINVAL;
}
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+sequencer_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
+ unsigned int mask = 0;
unsigned long flags;
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- save_flags (flags);
- cli ();
- if (!iqlen)
- {
-
- midi_sleep_flag.opts = WK_SLEEP;
- select_wait (&midi_sleeper, wait);
- restore_flags (flags);
- return 0;
- }
- restore_flags (flags);
- return 1;
- break;
+ save_flags (flags);
+ cli ();
- case SEL_OUT:
- save_flags (flags);
- cli ();
- if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
- {
+ midi_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&midi_sleeper, wait);
+ seq_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&seq_sleeper, wait);
- seq_sleep_flag.opts = WK_SLEEP;
- select_wait (&seq_sleeper, wait);
- restore_flags (flags);
- return 0;
- }
- restore_flags (flags);
- return 1;
- break;
+ restore_flags (flags);
- case SEL_EX:
- return 0;
- }
+ if (iqlen)
+ mask |= POLLIN | POLLRDNORM;
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+ return mask;
}
--- linux-2.1.23/drivers/sound/soundcard.c.old Sun Jan 26 05:07:24 1997
+++ linux-2.1.23/drivers/sound/soundcard.c Tue Jan 28 01:34:47 1997
@@ -192,29 +192,29 @@
return err;
}
-static int
-sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
+static unsigned int
+sound_poll (struct file *file, poll_table * wait)
{
int dev;
- dev = MINOR (inode->i_rdev);
+ dev = MINOR (file->f_inode->i_rdev);
files[dev].flags = file->f_flags;
- DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
+ DEB (printk ("sound_poll(dev=%d)\n", dev));
switch (dev & 0x0f)
{
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_select (dev, &files[dev], sel_type, wait);
+ return sequencer_poll (dev, &files[dev], wait);
break;
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- return MIDIbuf_select (dev, &files[dev], sel_type, wait);
+ return MIDIbuf_poll (dev, &files[dev], wait);
break;
#endif
@@ -222,7 +222,7 @@
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return audio_select (dev, &files[dev], sel_type, wait);
+ return audio_poll (dev, &files[dev], wait);
break;
#endif
@@ -327,7 +327,7 @@
sound_read,
sound_write,
NULL, /* sound_readdir */
- sound_select,
+ sound_poll,
sound_ioctl,
sound_mmap,
sound_open,