IDE-CD driver documentation
Originally by scott snyder <snyder@fnald0.fnal.gov> (19 May 1996)
Carrying on the torch is: Erik Andersen <andersee@debian.org>
+New maintainers (19 Oct 1998): Jens Axboe <axboe@image.dk>
+ Chris Zwilling <chris@cloudnet.com>
1. Introduction
---------------
S: Odd Fixes
IDE/ATAPI CDROM DRIVER
-P: Erik Andersen
-M: andersee@debian.org
+P: Jens Axboe
+M: axboe@image.dk
+P: Chris Zwilling
+M: chris@cloudnet.com
L: linux-kernel@vger.rutgers.edu
S: Maintained
S: Maintained
UNIFORM CDROM DRIVER
-P: Erik Andersen
-M: andersee@debian.org
+P: Jens Axboe
+M: axboe@image.dk
+P: Chris Zwilling
+M: chris@cloudnet.com
L: linux-kernel@vger.rutgers.edu
S: Maintained
VERSION = 2
PATCHLEVEL = 1
-SUBLEVEL = 126
+SUBLEVEL = 127
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
* linux/drivers/block/ide-cd.c
* Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1998 Jens Axboe and Chris Zwilling
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
* 4.15 Aug 25, 1998 -- Updated ide-cd.h to respect mechine endianess,
* patch thanks to "Eddie C. Dost" <ecd@skynet.be>
*
+ * 4.50 Oct 19, 1998 -- New maintainers!
+ * Jens Axboe <axboe@image.dk>
+ * Chris Zwilling <chris@cloudnet.com>
+ *
*************************************************************************/
-#define IDECD_VERSION "4.15"
+#define IDECD_VERSION "4.50"
#include <linux/module.h>
#include <linux/types.h>
if (was_locked)
(void) cdrom_lockdoor (drive, 1, NULL);
- return stat;
+ return slot;
}
}
* linux/drivers/block/ide_modes.h
*
* Copyright (C) 1996 Erik Andersen
+ * Copyright (C) 1998 Jens Axboe and Chris Zwilling
*/
#include <asm/byteorder.h>
/* linux/drivers/cdrom/cdrom.c.
Copyright (c) 1996, 1997 David A. van Leeuwen.
Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
+ Copyright (c) 1998 Jens Axboe and Chris Zwilling
May be copied or modified under the terms of the GNU General Public
License. See linux/COPYING for more information.
Thanks to Grant R. Guenther <grant@torque.net> for spotting this bug.
-- Made a few things more pedanticly correct.
+ 2.50 Oct 19, 1998 - Jens Axboe <axboe@image.dk>
+ -- New maintainers! Erik was too busy to continue the work on the driver,
+ so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
+ will do their best to follow in his footsteps
+
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 2.14"
-#define VERSION "Id: cdrom.c 2.14 1998/08/17 erik"
+#define REVISION "Revision: 2.50"
+#define VERSION "Id: cdrom.c 2.50 1998/10/19"
/* I use an error-log mask to give fine grain control over the type of
messages dumped to the system logs. The available masks include: */
static void srom_repair(struct device *dev, int card);
static int test_bad_enet(struct device *dev, int status);
static int an_exception(struct bus_type *lp);
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
static void eisa_probe(struct device *dev, u_long iobase);
#endif
static void pci_probe(struct device *dev, u_long iobase);
#endif /* MODULE */
static char name[DE4X5_NAME_LENGTH + 1];
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
static int lastEISA = 0;
#else
{
u_long iobase = dev->base_addr;
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
eisa_probe(dev, iobase);
#endif
if (lastEISA == MAX_EISA_SLOTS) {
return;
}
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
/*
** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
** the motherboard. Upto 15 EISA devices are supported.
return;
}
-#endif /* !(__sparc_v9__) && !(__powerpc__) */
+#endif /* !(__sparc_v9__) && !(__powerpc__) && !defined(__alpha__) */
/*
** PCI bus I/O device probe
u_int class = DE4X5_CLASS_CODE;
u_int device;
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
char name[DE4X5_STRLEN];
u_long iobase = 0x1000;
data[3] = mdio_read(ioaddr, data[0], data[1]);
return 0;
case SIOCDEVPRIVATE+2: /* Write the specified MII register */
- if (!suser())
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
mdio_write(ioaddr, data[0], data[1], data[2]);
return 0;
* 1994, 1995 Eberhard Moenkeberg, emoenke@gwdg.de
* 1996 David van Leeuwen, david@tm.tno.nl
* 1997, 1998 Erik Andersen, andersee@debian.org
+ * 1998 Jens Axboe, axboe@image.dk and
+ * Chris Zwilling, chris@cloudnet.com
*/
#ifndef _LINUX_CDROM_H
/* memory.c & swap.c*/
-/*
- * Decide if we should try to do some swapout..
- */
-extern int free_memory_available(void);
-extern struct wait_queue * kswapd_wait;
-
#define free_page(addr) free_pages((addr),0)
extern void FASTCALL(free_pages(unsigned long addr, unsigned long order));
extern void FASTCALL(__free_page(struct page *));
#define GFP_DMA __GFP_DMA
+/*
+ * Decide if we should try to do some swapout..
+ */
+extern int free_memory_available(void);
+extern struct task_struct * kswapd_task;
+
+extern inline void kswapd_notify(unsigned int gfp_mask)
+{
+ if (kswapd_task) {
+ wake_up_process(kswapd_task);
+ if (gfp_mask & __GFP_WAIT) {
+ current->policy |= SCHED_YIELD;
+ schedule();
+ }
+ }
+}
+
/* vma is the first one with address < vma->vm_end,
* and even address < vma->vm_start. Have to extend vma. */
static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
return vma;
}
-extern __inline__ void kswapd_wakeup(void)
-{
- wake_up(&kswapd_wait);
-}
-
#define buffer_under_min() ((buffermem >> PAGE_SHIFT) * 100 < \
buffer_mem.min_percent * num_physpages)
#define buffer_under_borrow() ((buffermem >> PAGE_SHIFT) * 100 < \
#define SOUND_MIXER_CAPS 0xfc
# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */
#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
+#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */
+#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */
/* Device mask bits */
if (!acct_file || !acct_needcheck)
return;
- sb = acct_file->f_dentry->f_inode->i_sb;
+ sb = acct_file->f_dentry->d_inode->i_sb;
if (!sb->s_op || !sb->s_op->statfs)
return;
{
spin_lock(&scheduler_lock);
spin_lock_irq(&runqueue_lock);
- current->policy |= SCHED_YIELD;
+ if (current->policy == SCHED_OTHER)
+ current->policy |= SCHED_YIELD;
current->need_resched = 1;
move_last_runqueue(current);
spin_unlock_irq(&runqueue_lock);
/*
* If we failed to find anything, we'll return NULL, but we'll
- * wake up kswapd _now_ ad even wait for it synchronously if
+ * wake up kswapd _now_ and even wait for it synchronously if
* we can.. This way we'll at least make some forward progress
* over time.
*/
- wake_up(&kswapd_wait);
- if (gfp_mask & __GFP_WAIT)
- schedule();
+ kswapd_notify(gfp_mask);
nopage:
return 0;
}
cachep->c_dflags = SLAB_CFLGS_GROWN;
cachep->c_growing++;
-re_try:
spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
/* A series of memory allocations for a new slab.
kmem_freepages(cachep, objp);
failed:
spin_lock_irq(&cachep->c_spinlock);
- if (local_flags != SLAB_ATOMIC && cachep->c_gfporder) {
- /* For large order (>0) slabs, we try again.
- * Needed because the gfp() functions are not good at giving
- * out contiguous pages unless pushed (but do not push too hard).
- */
- if (cachep->c_failures++ < 4 && cachep->c_freep == kmem_slab_end(cachep))
- goto re_try;
- cachep->c_failures = 1; /* Memory is low, don't try as hard next time. */
- }
cachep->c_growing--;
spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
return 0;
#include <asm/bitops.h>
#include <asm/pgtable.h>
-/*
- * When are we next due for a page scan?
- */
-static unsigned long next_swap_jiffies = 0;
-
/*
* How often do we do a pageout scan during normal conditions?
* Default is four times a second.
/*
* The wait queue for waking up the pageout daemon:
*/
-struct wait_queue * kswapd_wait = NULL;
+struct task_struct * kswapd_task = NULL;
static void init_swap_timer(void);
*/
int kswapd(void *unused)
{
- struct wait_queue wait = { current, NULL };
-
current->session = 1;
current->pgrp = 1;
strcpy(current->comm, "kswapd");
*/
lock_kernel();
- /* Give kswapd a realtime priority. */
- current->policy = SCHED_FIFO;
- current->rt_priority = 32; /* Fixme --- we need to standardise our
- namings for POSIX.4 realtime scheduling
- priorities. */
+ /*
+ * Set the base priority to something smaller than a
+ * regular process. We will scale up the priority
+ * dynamically depending on how much memory we need.
+ */
+ current->priority = (DEF_PRIORITY * 2) / 3;
/*
* Tell the memory management that we're a "memory allocator",
current->flags |= PF_MEMALLOC;
init_swap_timer();
- add_wait_queue(&kswapd_wait, &wait);
+ kswapd_task = current;
while (1) {
int tries;
} while (--tries > 0);
}
/* As if we could ever get here - maybe we want to make this killable */
- remove_wait_queue(&kswapd_wait, &wait);
+ kswapd_task = NULL;
unlock_kernel();
return 0;
}
return retval;
}
+/*
+ * Wake up kswapd according to the priority
+ * 0 - no wakeup
+ * 1 - wake up as a low-priority process
+ * 2 - wake up as a normal process
+ * 3 - wake up as an almost real-time process
+ *
+ * This plays mind-games with the "goodness()"
+ * function in kernel/sched.c.
+ */
+static inline void kswapd_wakeup(int priority)
+{
+ if (priority) {
+ struct task_struct *p = kswapd_task;
+ if (p) {
+ p->counter = p->priority << priority;
+ wake_up_process(p);
+ }
+ }
+}
+
/*
* The swap_tick function gets called on every clock tick.
*/
void swap_tick(void)
{
- unsigned long now, want;
- int want_wakeup = 0;
-
- want = next_swap_jiffies;
- now = jiffies;
+ unsigned int pages;
+ int want_wakeup;
/*
- * Examine the memory queues. Mark memory low
- * if there is nothing available in the three
- * highest queues.
- *
* Schedule for wakeup if there isn't lots
- * of free memory.
+ * of free memory or if there is too much
+ * of it used for buffers or pgcache.
+ *
+ * "want_wakeup" is our priority: 0 means
+ * not to wake anything up, while 3 means
+ * that we'd better give kswapd a realtime
+ * priority.
*/
- switch (free_memory_available()) {
- case 0:
- want = now;
- /* Fall through */
- case 1:
+ want_wakeup = 0;
+ if (buffer_over_max() || pgcache_over_max())
want_wakeup = 1;
- default:
- }
-
- if ((long) (now - want) >= 0) {
- if (want_wakeup || buffer_over_max() || pgcache_over_max()) {
- /* Set the next wake-up time */
- next_swap_jiffies = now + swapout_interval;
- kswapd_wakeup();
- }
- }
+ pages = nr_free_pages;
+ if (pages < freepages.high)
+ want_wakeup = 1;
+ if (pages < freepages.low)
+ want_wakeup = 2;
+ if (pages < freepages.min)
+ want_wakeup = 3;
+
+ kswapd_wakeup(want_wakeup);
+
timer_active |= (1<<SWAP_TIMER);
}