summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchim Gottinger <achim@gentoo.org>2000-11-19 15:37:42 +0000
committerAchim Gottinger <achim@gentoo.org>2000-11-19 15:37:42 +0000
commitd722abffdd16e3d0b7b5bb2324281f9016e71165 (patch)
tree830898094f24355add50d46ad4df87d38edc5e04 /sys-kernel
parent*** empty log message *** (diff)
downloadgentoo-2-d722abffdd16e3d0b7b5bb2324281f9016e71165.tar.gz
gentoo-2-d722abffdd16e3d0b7b5bb2324281f9016e71165.tar.bz2
gentoo-2-d722abffdd16e3d0b7b5bb2324281f9016e71165.zip
This version has lvm support
Diffstat (limited to 'sys-kernel')
-rw-r--r--sys-kernel/linux-UP-2.2.17/files/genhd.c1733
-rw-r--r--sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.autoconf1737
-rw-r--r--sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.config1320
-rw-r--r--sys-kernel/linux-UP-2.2.17/files/ll_rw_blk.c1196
-rw-r--r--sys-kernel/linux-UP-2.2.17/files/md.c4030
-rw-r--r--sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild189
6 files changed, 10205 insertions, 0 deletions
diff --git a/sys-kernel/linux-UP-2.2.17/files/genhd.c b/sys-kernel/linux-UP-2.2.17/files/genhd.c
new file mode 100644
index 000000000000..4609819b59ea
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/files/genhd.c
@@ -0,0 +1,1733 @@
+/*
+ * Code extracted from
+ * linux/kernel/hd.c
+ *
+ * Copyright (C) 1991-1998 Linus Torvalds
+ *
+ *
+ * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
+ * in the early extended-partition checks and added DM partitions
+ *
+ * Support for DiskManager v6.0x added by Mark Lord,
+ * with information provided by OnTrack. This now works for linux fdisk
+ * and LILO, as well as loadlin and bootln. Note that disks other than
+ * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
+ *
+ * More flexible handling of extended partitions - aeb, 950831
+ *
+ * Check partition table on IDE disks for common CHS translations
+ *
+ * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl}
+ *
+ *
+ * Added LVM extensions - Heinz Mauelshagen 03/07/1999
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/raid/md.h>
+
+#include <asm/system.h>
+#include <asm/byteorder.h>
+
+/*
+ * Many architectures don't like unaligned accesses, which is
+ * frequently the case with the nr_sects and start_sect partition
+ * table entries.
+ */
+#include <asm/unaligned.h>
+
+#define SYS_IND(p) (get_unaligned(&p->sys_ind))
+#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \
+ get_unaligned(&p->nr_sects); \
+ le32_to_cpu(__a); \
+ })
+
+#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \
+ get_unaligned(&p->start_sect); \
+ le32_to_cpu(__a); \
+ })
+
+struct gendisk *gendisk_head = NULL;
+
+static int current_minor = 0;
+extern int *blk_size[];
+extern void rd_load(void);
+extern void initrd_load(void);
+
+extern int chr_dev_init(void);
+extern int blk_dev_init(void);
+extern int i2o_init(void);
+#ifdef CONFIG_BLK_DEV_DAC960
+extern void DAC960_Initialize(void);
+#endif
+extern int scsi_dev_init(void);
+extern int net_dev_init(void);
+
+#ifdef CONFIG_PPC
+extern void note_bootable_part(kdev_t dev, int part);
+#endif
+
+static char *raid_name (struct gendisk *hd, int minor, int major_base,
+ char *buf)
+{
+ int ctlr = hd->major - major_base;
+ int disk = minor >> hd->minor_shift;
+ int part = minor & (( 1 << hd->minor_shift) - 1);
+ if (part == 0)
+ sprintf(buf, "%s/c%dd%d", hd->major_name, ctlr, disk);
+ else
+ sprintf(buf, "%s/c%dd%dp%d", hd->major_name, ctlr, disk,
+ part);
+ return buf;
+}
+
+#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
+#include <linux/lvm.h>
+void ( *lvm_hd_name_ptr) ( char *, int) = NULL;
+#endif
+
+/*
+ * disk_name() is used by genhd.c and md.c.
+ * It formats the devicename of the indicated disk
+ * into the supplied buffer, and returns a pointer
+ * to that same buffer (for convenience).
+ */
+char *disk_name (struct gendisk *hd, int minor, char *buf)
+{
+ unsigned int part;
+ const char *maj = hd->major_name;
+ int unit = (minor >> hd->minor_shift) + 'a';
+
+ /*
+ * IDE devices use multiple major numbers, but the drives
+ * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
+ * This requires special handling here.
+ *
+ * MD devices are named md0, md1, ... md15, fix it up here.
+ */
+ switch (hd->major) {
+#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
+ /*
+ * LVM specific handling
+ */
+ case LVM_BLOCK_MAJOR:
+ *buf = 0;
+ if ( lvm_hd_name_ptr != NULL)
+ ( lvm_hd_name_ptr) ( buf, minor);
+ return buf;
+#endif
+ case IDE9_MAJOR:
+ unit += 2;
+ case IDE8_MAJOR:
+ unit += 2;
+ case IDE7_MAJOR:
+ unit += 2;
+ case IDE6_MAJOR:
+ unit += 2;
+ case IDE5_MAJOR:
+ unit += 2;
+ case IDE4_MAJOR:
+ unit += 2;
+ case IDE3_MAJOR:
+ unit += 2;
+ case IDE2_MAJOR:
+ unit += 2;
+ case IDE1_MAJOR:
+ unit += 2;
+ case IDE0_MAJOR:
+ maj = "hd";
+ break;
+ case MD_MAJOR:
+ unit -= 'a'-'0';
+ }
+ part = minor & ((1 << hd->minor_shift) - 1);
+ if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
+ unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
+ if (unit > 'z') {
+ unit -= 'z' + 1;
+ sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
+ if (part)
+ sprintf(buf + 4, "%d", part);
+ return buf;
+ }
+ }
+ if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <=
+ COMPAQ_SMART2_MAJOR+7) {
+ return raid_name (hd, minor, COMPAQ_SMART2_MAJOR, buf);
+ }
+ if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
+ return raid_name (hd, minor, DAC960_MAJOR, buf);
+ }
+ if (part)
+ sprintf(buf, "%s%c%d", maj, unit, part);
+ else
+ sprintf(buf, "%s%c", maj, unit);
+ return buf;
+}
+
+static void add_partition (struct gendisk *hd, int minor,
+ int start, int size, int type)
+{
+ char buf[MAX_DISKNAME_LEN];
+ struct hd_struct *p = hd->part+minor;
+
+ p->start_sect = start;
+ p->nr_sects = size;
+ p->type = type;
+
+ printk(" %s", disk_name(hd, minor, buf));
+}
+
+static inline int is_extended_partition(struct partition *p)
+{
+ return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
+ SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
+ SYS_IND(p) == LINUX_EXTENDED_PARTITION);
+}
+
+static unsigned int get_ptable_blocksize(kdev_t dev)
+{
+ int ret = 1024;
+
+ /*
+ * See whether the low-level driver has given us a minumum blocksize.
+ * If so, check to see whether it is larger than the default of 1024.
+ */
+ if (!blksize_size[MAJOR(dev)])
+ return ret;
+
+ /*
+ * Check for certain special power of two sizes that we allow.
+ * With anything larger than 1024, we must force the blocksize up to
+ * the natural blocksize for the device so that we don't have to try
+ * and read partial sectors. Anything smaller should be just fine.
+ */
+
+ switch( blksize_size[MAJOR(dev)][MINOR(dev)] ) {
+ case 2048:
+ ret = 2048;
+ break;
+
+ case 4096:
+ ret = 4096;
+ break;
+
+ case 8192:
+ ret = 8192;
+ break;
+
+ case 1024:
+ case 512:
+ case 256:
+ case 0:
+ /*
+ * These are all OK.
+ */
+ break;
+
+ default:
+ panic("Strange blocksize for partition table\n");
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_MSDOS_PARTITION
+/*
+ * Create devices for each logical partition in an extended partition.
+ * The logical partitions form a linked list, with each entry being
+ * a partition table with two entries. The first entry
+ * is the real data partition (with a start relative to the partition
+ * table start). The second is a pointer to the next logical partition
+ * (with a start relative to the entire extended partition).
+ * We do not create a Linux partition for the partition tables, but
+ * only for the actual data partitions.
+ */
+
+#define MSDOS_LABEL_MAGIC 0xAA55
+
+static void extended_partition(struct gendisk *hd, kdev_t dev, int sector_size)
+{
+ struct buffer_head *bh;
+ struct partition *p;
+ unsigned long first_sector, first_size, this_sector, this_size;
+ int mask = (1 << hd->minor_shift) - 1;
+ int i;
+ int loopct = 0; /* number of links followed
+ without finding a data partition */
+
+ first_sector = hd->part[MINOR(dev)].start_sect;
+ first_size = hd->part[MINOR(dev)].nr_sects;
+ this_sector = first_sector;
+
+ while (1) {
+ if (++loopct > 100)
+ return;
+ if ((current_minor & mask) == 0)
+ return;
+ if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+ return;
+ /*
+ * This block is from a device that we're about to stomp on.
+ * So make sure nobody thinks this block is usable.
+ */
+ bh->b_state = 0;
+
+ if ((*(unsigned short *) (bh->b_data+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC))
+ goto done;
+
+ p = (struct partition *) (0x1BE + bh->b_data);
+
+ this_size = hd->part[MINOR(dev)].nr_sects;
+
+ /*
+ * Usually, the first entry is the real data partition,
+ * the 2nd entry is the next extended partition, or empty,
+ * and the 3rd and 4th entries are unused.
+ * However, DRDOS sometimes has the extended partition as
+ * the first entry (when the data partition is empty),
+ * and OS/2 seems to use all four entries.
+ */
+
+ /*
+ * First process the data partition(s)
+ */
+ for (i=0; i<4; i++, p++) {
+ if (!NR_SECTS(p) || is_extended_partition(p))
+ continue;
+
+ /* Check the 3rd and 4th entries -
+ these sometimes contain random garbage */
+ if (i >= 2
+ && START_SECT(p) + NR_SECTS(p) > this_size
+ && (this_sector + START_SECT(p) < first_sector ||
+ this_sector + START_SECT(p) + NR_SECTS(p) >
+ first_sector + first_size))
+ continue;
+
+ add_partition(hd, current_minor,
+ this_sector+START_SECT(p)*sector_size,
+ NR_SECTS(p)*sector_size,
+ ptype(SYS_IND(p)));
+ current_minor++;
+ if ((current_minor & mask) == 0)
+ goto done;
+ loopct = 0;
+ }
+ /*
+ * Next, process the (first) extended partition, if present.
+ * (So far, there seems to be no reason to make
+ * extended_partition() recursive and allow a tree
+ * of extended partitions.)
+ * It should be a link to the next logical partition.
+ * Create a minor for this just long enough to get the next
+ * partition table. The minor will be reused for the next
+ * data partition.
+ */
+ p -= 4;
+ for (i=0; i<4; i++, p++)
+ if(NR_SECTS(p) && is_extended_partition(p))
+ break;
+ if (i == 4)
+ goto done; /* nothing left to do */
+
+ hd->part[current_minor].nr_sects = NR_SECTS(p) * sector_size; /* JSt */
+ hd->part[current_minor].start_sect = first_sector + START_SECT(p) * sector_size;
+ this_sector = first_sector + START_SECT(p) * sector_size;
+ dev = MKDEV(hd->major, current_minor);
+ /* Use bforget(), as we have changed the disk geometry */
+ bforget(bh); /* brelse(bh); */
+ }
+done:
+ bforget(bh); /* brelse(bh); */
+}
+
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+static void
+solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
+
+ struct buffer_head *bh;
+ struct solaris_x86_vtoc *v;
+ struct solaris_x86_slice *s;
+ int mask = (1 << hd->minor_shift) - 1;
+ int i;
+
+ if(!(bh = bread(dev, 0, get_ptable_blocksize(dev))))
+ return;
+ v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
+ if(v->v_sanity != SOLARIS_X86_VTOC_SANE) {
+ brelse(bh);
+ return;
+ }
+ printk(" <solaris:");
+ if(v->v_version != 1) {
+ printk(" cannot handle version %ld vtoc>", v->v_version);
+ brelse(bh);
+ return;
+ }
+ for(i=0; i<SOLARIS_X86_NUMSLICE; i++) {
+ if ((current_minor & mask) == 0)
+ break;
+
+ s = &v->v_slice[i];
+
+ if (s->s_size == 0)
+ continue;
+
+ printk(" [s%d]", i);
+ /* solaris partitions are relative to current MS-DOS
+ * one but add_partition starts relative to sector
+ * zero of the disk. Therefore, must add the offset
+ * of the current partition */
+ add_partition(hd, current_minor,
+ s->s_start+offset, s->s_size, 0);
+ current_minor++;
+ }
+ brelse(bh);
+ printk(" >");
+}
+#endif
+
+#ifdef CONFIG_BSD_DISKLABEL
+static void check_and_add_bsd_partition(struct gendisk *hd,
+ struct bsd_partition *bsd_p, kdev_t dev)
+{
+ struct hd_struct *lin_p;
+ /* check relative position of partitions. */
+ for (lin_p = hd->part + 1 + MINOR(dev);
+ lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) {
+ /* no relationship -> try again */
+ if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset
+ || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
+ continue;
+ /* equal -> no need to add */
+ if (lin_p->start_sect == bsd_p->p_offset &&
+ lin_p->nr_sects == bsd_p->p_size)
+ return;
+ /* bsd living within dos partition */
+ if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect
+ + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) {
+#ifdef DEBUG_BSD_DISKLABEL
+ printk("w: %d %ld+%ld,%d+%d",
+ lin_p - hd->part,
+ lin_p->start_sect, lin_p->nr_sects,
+ bsd_p->p_offset, bsd_p->p_size);
+#endif
+ break;
+ }
+ /* ouch: bsd and linux overlap. Don't even try for that partition */
+#ifdef DEBUG_BSD_DISKLABEL
+ printk("???: %d %ld+%ld,%d+%d",
+ lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects,
+ bsd_p->p_offset, bsd_p->p_size);
+#endif
+ printk("???");
+ return;
+ } /* if the bsd partition is not currently known to linux, we end
+ * up here
+ */
+ add_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size, 0);
+ current_minor++;
+}
+/*
+ * Create devices for BSD partitions listed in a disklabel, under a
+ * dos-like partition. See extended_partition() for more information.
+ */
+static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev,
+ int max_partitions)
+{
+ struct buffer_head *bh;
+ struct bsd_disklabel *l;
+ struct bsd_partition *p;
+ int mask = (1 << hd->minor_shift) - 1;
+
+ if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+ return;
+ bh->b_state = 0;
+ l = (struct bsd_disklabel *) (bh->b_data+512);
+ if (l->d_magic != BSD_DISKMAGIC) {
+ brelse(bh);
+ return;
+ }
+
+ if (l->d_npartitions < max_partitions)
+ max_partitions = l->d_npartitions;
+ for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
+ if ((current_minor & mask) >= (4 + hd->max_p))
+ break;
+
+ if (p->p_fstype != BSD_FS_UNUSED)
+ check_and_add_bsd_partition(hd, p, dev);
+ }
+
+ /* Use bforget(), as we have changed the disk setup */
+ bforget(bh); /* brelse(bh); */
+
+}
+#endif
+
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+/*
+ * Create devices for Unixware partitions listed in a disklabel, under a
+ * dos-like partition. See extended_partition() for more information.
+ */
+static void unixware_partition(struct gendisk *hd, kdev_t dev)
+{
+ struct buffer_head *bh;
+ struct unixware_disklabel *l;
+ struct unixware_slice *p;
+ int mask = (1 << hd->minor_shift) - 1;
+
+ if (!(bh = bread(dev, 14, get_ptable_blocksize(dev))))
+ return;
+ bh->b_state = 0;
+ l = (struct unixware_disklabel *) (bh->b_data+512);
+ if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
+ le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
+ brelse(bh);
+ return;
+ }
+ printk(" <unixware:");
+ p = &l->vtoc.v_slice[1];
+ /* I omit the 0th slice as it is the same as whole disk. */
+ while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
+ if ((current_minor & mask) == 0)
+ break;
+
+ if (p->s_label != UNIXWARE_FS_UNUSED) {
+ add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p), 0);
+ current_minor++;
+ }
+ p++;
+ }
+ /* Use bforget, as we have changed the disk setup */
+ bforget(bh); /* brelse(bh); */
+ printk(" >");
+}
+#endif
+
+static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+ int i, minor = current_minor;
+ struct buffer_head *bh;
+ struct partition *p;
+ unsigned char *data;
+ int mask = (1 << hd->minor_shift) - 1;
+ int sector_size;
+ int disk_number_of_sects;
+#ifdef CONFIG_BSD_DISKLABEL
+ /* no bsd disklabel as a default */
+ kdev_t bsd_kdev = 0;
+ int bsd_maxpart = BSD_MAXPARTITIONS;
+#endif
+#ifdef CONFIG_BLK_DEV_IDE
+ int tested_for_xlate = 0;
+
+read_mbr:
+#endif
+ if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
+ printk(" unable to read partition table\n");
+ return -1;
+ }
+
+ /* in some cases (backwards compatibility) we'll adjust the
+ * sector_size below
+ */
+ if (hardsect_size[MAJOR(dev)] != NULL)
+ sector_size=hardsect_size[MAJOR(dev)][MINOR(dev)]/512;
+ else
+ sector_size=1;
+
+ data = bh->b_data;
+ /* In some cases we modify the geometry */
+ /* of the drive (below), so ensure that */
+ /* nobody else tries to re-use this data. */
+ bh->b_state = 0;
+#ifdef CONFIG_BLK_DEV_IDE
+check_table:
+#endif
+ /* Use bforget(), because we have potentially changed the disk geometry */
+ if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
+ bforget(bh); /* brelse(bh); */
+ return 0;
+ }
+ p = (struct partition *) (0x1be + data);
+
+#ifdef CONFIG_BLK_DEV_IDE
+ if (!tested_for_xlate++) { /* Do this only once per disk */
+ /*
+ * Look for various forms of IDE disk geometry translation
+ */
+ extern int ide_xlate_1024(kdev_t, int, int, const char *);
+ unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
+ int heads = 0;
+
+ /*
+ * The i386 partition handling programs very often
+ * make partitions end on cylinder boundaries.
+ * There is no need to do so, and Linux fdisk doesnt always
+ * do this, and Windows NT on Alpha doesnt do this either,
+ * but still, this helps to guess #heads.
+ */
+ for (i = 0; i < 4; i++) {
+ struct partition *q = &p[i];
+ if (NR_SECTS(q)) {
+ if ((q->sector & 63) == 1 &&
+ (q->end_sector & 63) == 63)
+ heads = q->end_head + 1;
+ break;
+ }
+ }
+ if (SYS_IND(p) == EZD_PARTITION) {
+ /*
+ * Accesses to sector 0 must go to sector 1 instead.
+ */
+ if (ide_xlate_1024(dev, -1, heads, " [EZD]")) {
+ data += 512;
+ goto check_table;
+ }
+ } else if (SYS_IND(p) == DM6_PARTITION) {
+
+ /*
+ * Everything on the disk is offset by 63 sectors,
+ * including a "new" MBR with its own partition table.
+ */
+ if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) {
+ bforget(bh); /* brelse(bh); */
+ goto read_mbr; /* start over with new MBR */
+ }
+ } else if (sig <= 0x1ae &&
+#if 0
+ *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) &&
+ (1 & *(unsigned char *)(data + sig + 2))) {
+#else
+ data[sig] == 0xAA && data[sig+1] == 0x55 &&
+ (data[sig+2] & 1)) {
+#endif
+ /* DM6 signature in MBR, courtesy of OnTrack */
+ (void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]");
+ } else if (SYS_IND(p) == DM6_AUX1PARTITION ||
+ SYS_IND(p) == DM6_AUX3PARTITION) {
+ /*
+ * DM6 on other than the first (boot) drive
+ */
+ (void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]");
+ } else {
+ (void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
+ }
+ }
+#endif /* CONFIG_BLK_DEV_IDE */
+
+ /*
+ * The Linux code now honours the rules the MO people set and
+ * is 'DOS compatible' - sizes are scaled by the media block
+ * size not 512 bytes. The following is a backwards
+ * compatibility check. If a 1k or greater sectorsize disk
+ * (1024, 2048, etc) was created under a pre 2.2 kernel,
+ * the partition table wrongly used units of 512 instead of
+ * units of sectorsize (1024, 2048, etc.) The below check attempts
+ * to detect a partition table created under the older kernel, and
+ * if so detected, it will reset the a sector scale factor to 1 (i.e.
+ * no scaling).
+ */
+ disk_number_of_sects = NR_SECTS((&hd->part[MINOR(dev)]));
+ for (i = 0; i < 4; i++) {
+ struct partition *q = &p[i];
+ if (NR_SECTS(q)) {
+ if (((first_sector+(START_SECT(q)+NR_SECTS(q))*sector_size) >
+ (disk_number_of_sects+1)) &&
+ ((first_sector+(START_SECT(q)+NR_SECTS(q)) <=
+ disk_number_of_sects))) {
+ char buf[MAX_DISKNAME_LEN];
+ printk(" %s: RESETTINGING SECTOR SCALE from %d to 1",
+ disk_name(hd, MINOR(dev), buf), sector_size);
+ sector_size=1;
+ break;
+ }
+ }
+ }
+
+ current_minor += 4; /* first "extra" minor (for extended partitions) */
+ for (i=1 ; i<=4 ; minor++,i++,p++) {
+ if (!NR_SECTS(p))
+ continue;
+ add_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size,
+ ptype(SYS_IND(p)));
+ if (is_extended_partition(p)) {
+ printk(" <");
+ /*
+ * If we are rereading the partition table, we need
+ * to set the size of the partition so that we will
+ * be able to bread the block containing the extended
+ * partition info.
+ */
+ hd->sizes[minor] = hd->part[minor].nr_sects
+ >> (BLOCK_SIZE_BITS - 9);
+ extended_partition(hd, MKDEV(hd->major, minor), sector_size);
+ printk(" >");
+ /* prevent someone doing mkfs or mkswap on an
+ extended partition, but leave room for LILO */
+ if (hd->part[minor].nr_sects > 2)
+ hd->part[minor].nr_sects = 2;
+ }
+#ifdef CONFIG_BSD_DISKLABEL
+ /* tag first disklabel for late recognition */
+ if (SYS_IND(p) == BSD_PARTITION || SYS_IND(p) == NETBSD_PARTITION) {
+ printk("!");
+ if (!bsd_kdev)
+ bsd_kdev = MKDEV(hd->major, minor);
+ } else if (SYS_IND(p) == OPENBSD_PARTITION) {
+ printk("!");
+ if (!bsd_kdev) {
+ bsd_kdev = MKDEV(hd->major, minor);
+ bsd_maxpart = OPENBSD_MAXPARTITIONS;
+ }
+ }
+#endif
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+ if (SYS_IND(p) == UNIXWARE_PARTITION)
+ unixware_partition(hd, MKDEV(hd->major, minor));
+#endif
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+
+ /* james@bpgc.com: Solaris has a nasty indicator: 0x82
+ * which also means linux swap. For that reason, all
+ * of the prints are done inside the
+ * solaris_x86_partition routine */
+
+ if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
+ solaris_x86_partition(hd, MKDEV(hd->major, minor),
+ first_sector+START_SECT(p));
+ }
+#endif
+ }
+#ifdef CONFIG_BSD_DISKLABEL
+ if (bsd_kdev) {
+ printk(" <");
+ bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart);
+ printk(" >");
+ }
+#endif
+ /*
+ * Check for old-style Disk Manager partition table
+ */
+ if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
+ p = (struct partition *) (0x1be + data);
+ for (i = 4 ; i < 16 ; i++, current_minor++) {
+ p--;
+ if ((current_minor & mask) == 0)
+ break;
+ if (!(START_SECT(p) && NR_SECTS(p)))
+ continue;
+ add_partition(hd, current_minor, START_SECT(p),
+ NR_SECTS(p), 0);
+ }
+ }
+ printk("\n");
+ bforget(bh); /* brelse(bh); */
+ return 1;
+}
+
+#endif /* CONFIG_MSDOS_PARTITION */
+
+#ifdef CONFIG_OSF_PARTITION
+
+static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
+{
+ int i;
+ int mask = (1 << hd->minor_shift) - 1;
+ struct buffer_head *bh;
+ struct disklabel {
+ u32 d_magic;
+ u16 d_type,d_subtype;
+ u8 d_typename[16];
+ u8 d_packname[16];
+ u32 d_secsize;
+ u32 d_nsectors;
+ u32 d_ntracks;
+ u32 d_ncylinders;
+ u32 d_secpercyl;
+ u32 d_secprtunit;
+ u16 d_sparespertrack;
+ u16 d_sparespercyl;
+ u32 d_acylinders;
+ u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
+ u32 d_headswitch, d_trkseek, d_flags;
+ u32 d_drivedata[5];
+ u32 d_spare[5];
+ u32 d_magic2;
+ u16 d_checksum;
+ u16 d_npartitions;
+ u32 d_bbsize, d_sbsize;
+ struct d_partition {
+ u32 p_size;
+ u32 p_offset;
+ u32 p_fsize;
+ u8 p_fstype;
+ u8 p_frag;
+ u16 p_cpg;
+ } d_partitions[8];
+ } * label;
+ struct d_partition * partition;
+#define DISKLABELMAGIC (0x82564557UL)
+
+ if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
+ printk("unable to read partition table\n");
+ return -1;
+ }
+ label = (struct disklabel *) (bh->b_data+64);
+ partition = label->d_partitions;
+ if (label->d_magic != DISKLABELMAGIC) {
+ brelse(bh);
+ return 0;
+ }
+ if (label->d_magic2 != DISKLABELMAGIC) {
+ brelse(bh);
+ return 0;
+ }
+ for (i = 0 ; i < label->d_npartitions; i++, partition++) {
+ if ((current_minor & mask) == 0)
+ break;
+ if (partition->p_size)
+ add_partition(hd, current_minor,
+ first_sector+partition->p_offset,
+ partition->p_size, 0);
+ current_minor++;
+ }
+ printk("\n");
+ brelse(bh);
+ return 1;
+}
+
+#endif /* CONFIG_OSF_PARTITION */
+
+#ifdef CONFIG_SUN_PARTITION
+
+static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+ int i, csum;
+ unsigned short *ush;
+ struct buffer_head *bh;
+ struct sun_disklabel {
+ unsigned char info[128]; /* Informative text string */
+ unsigned char spare0[14];
+ struct sun_disklabelinfo {
+ unsigned char spare1;
+ unsigned char id;
+ unsigned char spare2;
+ unsigned char flags;
+ } infos[8];
+ unsigned char spare1[246]; /* Boot information etc. */
+ unsigned short rspeed; /* Disk rotational speed */
+ unsigned short pcylcount; /* Physical cylinder count */
+ unsigned short sparecyl; /* extra sects per cylinder */
+ unsigned char spare2[4]; /* More magic... */
+ unsigned short ilfact; /* Interleave factor */
+ unsigned short ncyl; /* Data cylinder count */
+ unsigned short nacyl; /* Alt. cylinder count */
+ unsigned short ntrks; /* Tracks per cylinder */
+ unsigned short nsect; /* Sectors per track */
+ unsigned char spare3[4]; /* Even more magic... */
+ struct sun_partition {
+ __u32 start_cylinder;
+ __u32 num_sectors;
+ } partitions[8];
+ unsigned short magic; /* Magic number */
+ unsigned short csum; /* Label xor'd checksum */
+ } * label;
+ struct sun_partition *p;
+ unsigned long spc;
+#define SUN_LABEL_MAGIC 0xDABE
+
+ if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
+ printk("Dev %s: unable to read partition table\n",
+ kdevname(dev));
+ return -1;
+ }
+ label = (struct sun_disklabel *) bh->b_data;
+ p = label->partitions;
+ if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
+#if 0
+ /* There is no error here - it is just not a sunlabel. */
+ printk("Dev %s Sun disklabel: bad magic %04x\n",
+ kdevname(dev), be16_to_cpu(label->magic));
+#endif
+ brelse(bh);
+ return 0;
+ }
+ /* Look at the checksum */
+ ush = ((unsigned short *) (label+1)) - 1;
+ for(csum = 0; ush >= ((unsigned short *) label);)
+ csum ^= *ush--;
+ if(csum) {
+ printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
+ kdevname(dev));
+ brelse(bh);
+ return 0;
+ }
+ /* All Sun disks have 8 partition entries */
+ spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
+ for(i=0; i < 8; i++, p++) {
+ unsigned long st_sector;
+ int num_sectors;
+
+ st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
+ num_sectors = be32_to_cpu(p->num_sectors);
+ if (num_sectors)
+ add_partition(hd, current_minor, st_sector,
+ num_sectors, ptype(label->infos[i].id));
+ current_minor++;
+ }
+ printk("\n");
+ brelse(bh);
+ return 1;
+}
+
+#endif /* CONFIG_SUN_PARTITION */
+
+#ifdef CONFIG_SGI_PARTITION
+
+static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+ int i, csum, magic;
+ unsigned int *ui, start, blocks, cs;
+ struct buffer_head *bh;
+ struct sgi_disklabel {
+ int magic_mushroom; /* Big fat spliff... */
+ short root_part_num; /* Root partition number */
+ short swap_part_num; /* Swap partition number */
+ char boot_file[16]; /* Name of boot file for ARCS */
+ unsigned char _unused0[48]; /* Device parameter useless crapola.. */
+ struct sgi_volume {
+ char name[8]; /* Name of volume */
+ int block_num; /* Logical block number */
+ int num_bytes; /* How big, in bytes */
+ } volume[15];
+ struct sgi_partition {
+ int num_blocks; /* Size in logical blocks */
+ int first_block; /* First logical block */
+ int type; /* Type of this partition */
+ } partitions[16];
+ int csum; /* Disk label checksum */
+ int _unused1; /* Padding */
+ } *label;
+ struct sgi_partition *p;
+#define SGI_LABEL_MAGIC 0x0be5a941
+
+ if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
+ printk("Dev %s: unable to read partition table\n", kdevname(dev));
+ return -1;
+ }
+ label = (struct sgi_disklabel *) bh->b_data;
+ p = &label->partitions[0];
+ magic = label->magic_mushroom;
+ if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
+#if 0
+ /* There is no error here - it is just not an sgilabel. */
+ printk("Dev %s SGI disklabel: bad magic %08x\n",
+ kdevname(dev), magic);
+#endif
+ brelse(bh);
+ return 0;
+ }
+ ui = ((unsigned int *) (label + 1)) - 1;
+ for(csum = 0; ui >= ((unsigned int *) label);) {
+ cs = *ui--;
+ csum += be32_to_cpu(cs);
+ }
+ if(csum) {
+ printk("Dev %s SGI disklabel: csum bad, label corrupted\n",
+ kdevname(dev));
+ brelse(bh);
+ return 0;
+ }
+ /* All SGI disk labels have 16 partitions, disks under Linux only
+ * have 15 minor's. Luckily there are always a few zero length
+ * partitions which we don't care about so we never overflow the
+ * current_minor.
+ */
+ for(i = 0; i < 16; i++, p++) {
+ blocks = be32_to_cpu(p->num_blocks);
+ start = be32_to_cpu(p->first_block);
+ if(!blocks)
+ continue;
+ add_partition(hd, current_minor, start, blocks, 0);
+ current_minor++;
+ }
+ printk("\n");
+ brelse(bh);
+ return 1;
+}
+
+#endif
+
+#ifdef CONFIG_AMIGA_PARTITION
+#include <linux/affs_hardblocks.h>
+
+static __inline__ u32
+checksum_block(u32 *m, int size)
+{
+ u32 sum = 0;
+
+ while (size--)
+ sum += be32_to_cpu(*m++);
+ return sum;
+}
+
+static int
+amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+ struct buffer_head *bh;
+ struct RigidDiskBlock *rdb;
+ struct PartitionBlock *pb;
+ int start_sect;
+ int nr_sects;
+ int blk;
+ int part, res;
+ int old_blocksize;
+ int blocksize;
+
+ old_blocksize = get_ptable_blocksize(dev);
+ if (hardsect_size[MAJOR(dev)] != NULL)
+ blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
+ else
+ blocksize = 512;
+
+ set_blocksize(dev,blocksize);
+ res = 0;
+
+ for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
+ if(!(bh = bread(dev,blk,blocksize))) {
+ printk("Dev %s: unable to read RDB block %d\n",
+ kdevname(dev),blk);
+ goto rdb_done;
+ }
+ if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
+ rdb = (struct RigidDiskBlock *)bh->b_data;
+ if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
+ /* Try again with 0xdc..0xdf zeroed, Windows might have
+ * trashed it.
+ */
+ *(u32 *)(&bh->b_data[0xdc]) = 0;
+ if (checksum_block((u32 *)bh->b_data,
+ be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
+ brelse(bh);
+ printk("Dev %s: RDB in block %d has bad checksum\n",
+ kdevname(dev),blk);
+ continue;
+ }
+ printk("Warning: Trashed word at 0xd0 in block %d "
+ "ignored in checksum calculation\n",blk);
+ }
+ printk(" RDSK");
+ blk = be32_to_cpu(rdb->rdb_PartitionList);
+ brelse(bh);
+ for (part = 1; blk > 0 && part <= 16; part++) {
+ if (!(bh = bread(dev,blk,blocksize))) {
+ printk("Dev %s: unable to read partition block %d\n",
+ kdevname(dev),blk);
+ goto rdb_done;
+ }
+ pb = (struct PartitionBlock *)bh->b_data;
+ blk = be32_to_cpu(pb->pb_Next);
+ if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
+ (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
+
+ /* Tell Kernel about it */
+
+ if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
+ be32_to_cpu(pb->pb_Environment[9])) *
+ be32_to_cpu(pb->pb_Environment[3]) *
+ be32_to_cpu(pb->pb_Environment[5]))) {
+ brelse(bh);
+ continue;
+ }
+ start_sect = be32_to_cpu(pb->pb_Environment[9]) *
+ be32_to_cpu(pb->pb_Environment[3]) *
+ be32_to_cpu(pb->pb_Environment[5]);
+ add_partition(hd,current_minor,
+ start_sect,nr_sects,0);
+ current_minor++;
+ res = 1;
+ }
+ brelse(bh);
+ }
+ printk("\n");
+ break;
+ }
+ else
+ brelse(bh);
+ }
+
+rdb_done:
+ set_blocksize(dev,old_blocksize);
+ return res;
+}
+#endif /* CONFIG_AMIGA_PARTITION */
+
+#ifdef CONFIG_MAC_PARTITION
+#include <linux/ctype.h>
+
+/*
+ * Code to understand MacOS partition tables.
+ */
+
+#define MAC_PARTITION_MAGIC 0x504d
+
+/* type field value for A/UX or other Unix partitions */
+#define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
+
+struct mac_partition {
+ __u16 signature; /* expected to be MAC_PARTITION_MAGIC */
+ __u16 res1;
+ __u32 map_count; /* # blocks in partition map */
+ __u32 start_block; /* absolute starting block # of partition */
+ __u32 block_count; /* number of blocks in partition */
+ char name[32]; /* partition name */
+ char type[32]; /* string type description */
+ __u32 data_start; /* rel block # of first data block */
+ __u32 data_count; /* number of data blocks */
+ __u32 status; /* partition status bits */
+ __u32 boot_start;
+ __u32 boot_size;
+ __u32 boot_load;
+ __u32 boot_load2;
+ __u32 boot_entry;
+ __u32 boot_entry2;
+ __u32 boot_cksum;
+ char processor[16]; /* identifies ISA of boot */
+ /* there is more stuff after this that we don't need */
+};
+
+#define MAC_STATUS_BOOTABLE 8 /* partition is bootable */
+
+#define MAC_DRIVER_MAGIC 0x4552
+
+/* Driver descriptor structure, in block 0 */
+struct mac_driver_desc {
+ __u16 signature; /* expected to be MAC_DRIVER_MAGIC */
+ __u16 block_size;
+ __u32 block_count;
+ /* ... more stuff */
+};
+
+static inline void mac_fix_string(char *stg, int len)
+{
+ int i;
+
+ for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
+ stg[i] = 0;
+}
+
+static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
+{
+ struct buffer_head *bh;
+ int blk, blocks_in_map;
+ int dev_bsize, dev_pos, pos;
+ unsigned secsize;
+#ifdef CONFIG_PPC
+ int found_root = 0;
+ int found_root_goodness = 0;
+#endif
+ struct mac_partition *part;
+ struct mac_driver_desc *md;
+
+ dev_bsize = get_ptable_blocksize(dev);
+ dev_pos = 0;
+ /* Get 0th block and look at the first partition map entry. */
+ if ((bh = bread(dev, 0, dev_bsize)) == 0) {
+ printk("%s: error reading partition table\n",
+ kdevname(dev));
+ return -1;
+ }
+ md = (struct mac_driver_desc *) bh->b_data;
+ if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
+ brelse(bh);
+ return 0;
+ }
+ secsize = be16_to_cpu(md->block_size);
+ if (secsize >= dev_bsize) {
+ brelse(bh);
+ dev_pos = secsize;
+ if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
+ printk("%s: error reading partition table\n",
+ kdevname(dev));
+ return -1;
+ }
+ }
+ part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
+ if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
+ brelse(bh);
+ return 0; /* not a MacOS disk */
+ }
+ blocks_in_map = be32_to_cpu(part->map_count);
+ for (blk = 1; blk <= blocks_in_map; ++blk) {
+ pos = blk * secsize;
+ if (pos >= dev_pos + dev_bsize) {
+ brelse(bh);
+ dev_pos = pos;
+ if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
+ printk("%s: error reading partition table\n",
+ kdevname(dev));
+ return -1;
+ }
+ }
+ part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
+ if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+ break;
+ blocks_in_map = be32_to_cpu(part->map_count);
+ add_partition(hd, current_minor,
+ fsec + be32_to_cpu(part->start_block) * (secsize/512),
+ be32_to_cpu(part->block_count) * (secsize/512), 0);
+
+#ifdef CONFIG_PPC
+ /*
+ * If this is the first bootable partition, tell the
+ * setup code, in case it wants to make this the root.
+ */
+ if (_machine == _MACH_Pmac) {
+ int goodness = 0;
+
+ mac_fix_string(part->processor, 16);
+ mac_fix_string(part->name, 32);
+ mac_fix_string(part->type, 32);
+
+ if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
+ && strcasecmp(part->processor, "powerpc") == 0)
+ goodness++;
+
+ if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
+ || strcasecmp(part->type, "Linux_PPC") == 0) {
+ int i, l;
+
+ goodness++;
+ l = strlen(part->name);
+ if (strcmp(part->name, "/") == 0)
+ goodness++;
+ for (i = 0; i <= l - 4; ++i) {
+ if (strnicmp(part->name + i, "root",
+ 4) == 0) {
+ goodness += 2;
+ break;
+ }
+ }
+ if (strnicmp(part->name, "swap", 4) == 0)
+ goodness--;
+ }
+
+ if (goodness > found_root_goodness) {
+ found_root = blk;
+ found_root_goodness = goodness;
+ }
+ }
+#endif /* CONFIG_PPC */
+
+ ++current_minor;
+ }
+#ifdef CONFIG_PPC
+ if (found_root_goodness)
+ note_bootable_part(dev, found_root);
+#endif
+ brelse(bh);
+ printk("\n");
+ return 1;
+}
+
+#endif /* CONFIG_MAC_PARTITION */
+
+#ifdef CONFIG_ATARI_PARTITION
+#include <linux/atari_rootsec.h>
+
+/* ++guenther: this should be settable by the user ("make config")?.
+ */
+#define ICD_PARTS
+
+static int atari_partition (struct gendisk *hd, kdev_t dev,
+ unsigned long first_sector)
+{
+ int minor = current_minor, m_lim = current_minor + hd->max_p;
+ struct buffer_head *bh;
+ struct rootsector *rs;
+ struct partition_info *pi;
+ ulong extensect;
+#ifdef ICD_PARTS
+ int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
+#endif
+
+ bh = bread (dev, 0, get_ptable_blocksize(dev));
+ if (!bh)
+ {
+ printk (" unable to read block 0\n");
+ return -1;
+ }
+
+ rs = (struct rootsector *) bh->b_data;
+ pi = &rs->part[0];
+ printk (" AHDI");
+ for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
+ {
+ if (pi->flg & 1)
+ /* active partition */
+ {
+ if (memcmp (pi->id, "XGM", 3) == 0)
+ /* extension partition */
+ {
+ struct rootsector *xrs;
+ struct buffer_head *xbh;
+ ulong partsect;
+
+#ifdef ICD_PARTS
+ part_fmt = 1;
+#endif
+ printk(" XGM<");
+ partsect = extensect = be32_to_cpu(pi->st);
+ while (1)
+ {
+ xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
+ if (!xbh)
+ {
+ printk (" block %ld read failed\n", partsect);
+ brelse(bh);
+ return 0;
+ }
+ if (partsect & 1)
+ xrs = (struct rootsector *) &xbh->b_data[512];
+ else
+ xrs = (struct rootsector *) &xbh->b_data[0];
+
+ /* ++roman: sanity check: bit 0 of flg field must be set */
+ if (!(xrs->part[0].flg & 1)) {
+ printk( "\nFirst sub-partition in extended partition is not valid!\n" );
+ break;
+ }
+
+ add_partition(hd, minor, partsect + be32_to_cpu(xrs->part[0].st),
+ be32_to_cpu(xrs->part[0].siz), 0);
+
+ if (!(xrs->part[1].flg & 1)) {
+ /* end of linked partition list */
+ brelse( xbh );
+ break;
+ }
+ if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
+ printk( "\nID of extended partition is not XGM!\n" );
+ brelse( xbh );
+ break;
+ }
+
+ partsect = be32_to_cpu(xrs->part[1].st) + extensect;
+ brelse (xbh);
+ minor++;
+ if (minor >= m_lim) {
+ printk( "\nMaximum number of partitions reached!\n" );
+ break;
+ }
+ }
+ printk(" >");
+ }
+ else
+ {
+ /* we don't care about other id's */
+ printk(" %c%c%c(%d)", pi->id[0], pi->id[1], pi->id[2], be32_to_cpu(pi->siz)/2048);
+ add_partition (hd, minor, be32_to_cpu(pi->st), be32_to_cpu(pi->siz), 0);
+ }
+ }
+ }
+#ifdef ICD_PARTS
+ if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
+ {
+ pi = &rs->icdpart[0];
+ /* sanity check: no ICD format if first partition invalid */
+ if (memcmp (pi->id, "GEM", 3) == 0 ||
+ memcmp (pi->id, "BGM", 3) == 0 ||
+ memcmp (pi->id, "LNX", 3) == 0 ||
+ memcmp (pi->id, "SWP", 3) == 0 ||
+ memcmp (pi->id, "RAW", 3) == 0 )
+ {
+ printk(" ICD<");
+ for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
+ {
+ /* accept only GEM,BGM,RAW,LNX,SWP partitions */
+ if (pi->flg & 1 &&
+ (memcmp (pi->id, "GEM", 3) == 0 ||
+ memcmp (pi->id, "BGM", 3) == 0 ||
+ memcmp (pi->id, "LNX", 3) == 0 ||
+ memcmp (pi->id, "SWP", 3) == 0 ||
+ memcmp (pi->id, "RAW", 3) == 0) )
+ {
+ part_fmt = 2;
+ add_partition (hd, minor, pi->st, pi->siz, 0);
+ }
+ }
+ printk(" >");
+ }
+ }
+#endif
+ brelse (bh);
+
+ printk ("\n");
+
+ return 1;
+}
+#endif /* CONFIG_ATARI_PARTITION */
+
+#ifdef CONFIG_ULTRIX_PARTITION
+
+static int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+ int i, minor = current_minor;
+ struct buffer_head *bh;
+ struct ultrix_disklabel {
+ long pt_magic; /* magic no. indicating part. info exits */
+ int pt_valid; /* set by driver if pt is current */
+ struct pt_info {
+ int pi_nblocks; /* no. of sectors */
+ unsigned long pi_blkoff; /* block offset for start */
+ } pt_part[8];
+ } *label;
+
+#define PT_MAGIC 0x032957 /* Partition magic number */
+#define PT_VALID 1 /* Indicates if struct is valid */
+
+#define SBLOCK ((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \
+ /get_ptable_blocksize(dev)))
+
+ bh = bread (dev, SBLOCK, get_ptable_blocksize(dev));
+ if (!bh) {
+ printk (" unable to read block 0x%lx\n", SBLOCK);
+ return -1;
+ }
+
+ label = (struct ultrix_disklabel *)(bh->b_data
+ + get_ptable_blocksize(dev)
+ - sizeof(struct ultrix_disklabel));
+
+ if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) {
+ for (i=0; i<8; i++, minor++)
+ if (label->pt_part[i].pi_nblocks)
+ add_partition(hd, minor,
+ label->pt_part[i].pi_blkoff,
+ label->pt_part[i].pi_nblocks);
+ brelse(bh);
+ printk ("\n");
+ return 1;
+ } else {
+ brelse(bh);
+ return 0;
+ }
+}
+
+#endif /* CONFIG_ULTRIX_PARTITION */
+
+#ifdef CONFIG_ARCH_S390
+#include <asm/ebcdic.h>
+#include "../s390/block/dasd_types.h"
+
+dasd_information_t **dasd_information = NULL;
+
+typedef enum {
+ ibm_partition_none = 0,
+ ibm_partition_lnx1 = 1,
+ ibm_partition_vol1 = 3,
+ ibm_partition_cms1 = 4
+} ibm_partition_t;
+
+static ibm_partition_t
+get_partition_type ( char * type )
+{
+ static char lnx[5]="LNX1";
+ static char vol[5]="VOL1";
+ static char cms[5]="CMS1";
+ if ( ! strncmp ( lnx, "LNX1",4 ) ) {
+ ASCEBC(lnx,4);
+ ASCEBC(vol,4);
+ ASCEBC(cms,4);
+ }
+ if ( ! strncmp (type,lnx,4) ||
+ ! strncmp (type,"LNX1",4) )
+ return ibm_partition_lnx1;
+ if ( ! strncmp (type,vol,4) )
+ return ibm_partition_vol1;
+ if ( ! strncmp (type,cms,4) )
+ return ibm_partition_cms1;
+ return ibm_partition_none;
+}
+
+int
+ibm_partition (struct gendisk *hd, kdev_t dev, int first_sector)
+{
+ struct buffer_head *bh;
+ ibm_partition_t partition_type;
+ char type[5] = {0,};
+ char name[7] = {0,};
+ int di = MINOR(dev) >> hd->minor_shift;
+ if ( ! get_ptable_blocksize(dev) )
+ return 0;
+ if ( ! dasd_information )
+ return 0;
+ if ( ( bh = bread( dev,
+ dasd_information[di]->sizes.label_block,
+ dasd_information[di]->sizes.bp_sector ) ) != NULL ) {
+ strncpy ( type,bh -> b_data, 4);
+ strncpy ( name,bh -> b_data + 4, 6);
+ } else {
+ return 0;
+ }
+ if ( (*(char *)bh -> b_data) & 0x80 ) {
+ EBCASC(name,6);
+ }
+ switch ( partition_type = get_partition_type(type) ) {
+ case ibm_partition_lnx1:
+ printk ( "(LNX1)/%6s:",name);
+ add_partition( hd, MINOR(dev) + 1,
+ (dasd_information[di]->sizes.label_block + 1) <<
+ dasd_information[di]->sizes.s2b_shift,
+ (dasd_information [di]->sizes.blocks -
+ dasd_information[di]->sizes.label_block - 1) <<
+ dasd_information[di]->sizes.s2b_shift,0 );
+ break;
+ case ibm_partition_vol1:
+ printk ( "(VOL1)/%6s:",name);
+ break;
+ case ibm_partition_cms1:
+ printk ( "(CMS1)/%6s:",name);
+ if (* (((long *)bh->b_data) + 13) == 0) {
+ /* disk holds a CMS filesystem */
+ add_partition( hd, MINOR(dev) + 1,
+ (dasd_information [di]->sizes.label_block + 1) <<
+ dasd_information [di]->sizes.s2b_shift,
+ (dasd_information [di]->sizes.blocks -
+ dasd_information [di]->sizes.label_block) <<
+ dasd_information [di]->sizes.s2b_shift,0 );
+ printk ("(CMS)");
+ } else {
+ /* disk is reserved minidisk */
+ long *label=(long*)bh->b_data;
+ int offset = label[13];
+ int size = (label[7]-1-label[13])*(label[3]>>9);
+ add_partition( hd, MINOR(dev) + 1,
+ offset << dasd_information [di]->sizes.s2b_shift,
+ size<<dasd_information [di]->sizes.s2b_shift,0 );
+ printk ("(MDSK)");
+ }
+ break;
+ case ibm_partition_none:
+ printk ( "(nonl)/ :");
+ add_partition( hd, MINOR(dev) + 1,
+ (dasd_information [di]->sizes.label_block + 1) <<
+ dasd_information [di]->sizes.s2b_shift,
+ (dasd_information [di]->sizes.blocks -
+ dasd_information [di]->sizes.label_block - 1) <<
+ dasd_information [di]->sizes.s2b_shift,0 );
+ break;
+ }
+ printk ( "\n" );
+ bforget(bh);
+ return 1;
+}
+#endif
+
+static void check_partition(struct gendisk *hd, kdev_t dev)
+{
+ static int first_time = 1;
+ unsigned long first_sector;
+ char buf[MAX_DISKNAME_LEN];
+
+ if (first_time)
+ printk("Partition check:\n");
+ first_time = 0;
+ first_sector = hd->part[MINOR(dev)].start_sect;
+
+ /*
+ * This is a kludge to allow the partition check to be
+ * skipped for specific drives (e.g. IDE CD-ROM drives)
+ */
+ if ((int)first_sector == -1) {
+ hd->part[MINOR(dev)].start_sect = 0;
+ return;
+ }
+
+ printk(" %s:", disk_name(hd, MINOR(dev), buf));
+#ifdef CONFIG_MSDOS_PARTITION
+ if (msdos_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_OSF_PARTITION
+ if (osf_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_SUN_PARTITION
+ if(sun_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_AMIGA_PARTITION
+ if(amiga_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_MAC_PARTITION
+ if (mac_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_SGI_PARTITION
+ if(sgi_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_ULTRIX_PARTITION
+ if(ultrix_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_ATARI_PARTITION
+ if(atari_partition(hd, dev, first_sector))
+ return;
+#endif
+#ifdef CONFIG_ARCH_S390
+ if (ibm_partition (hd, dev, first_sector))
+ return;
+#endif
+ printk(" unknown partition table\n");
+}
+
+/* This function is used to re-read partition tables for removable disks.
+ Much of the cleanup from the old partition tables should have already been
+ done */
+
+/* This function will re-read the partition tables for a given device,
+and set things back up again. There are some important caveats,
+however. You must ensure that no one is using the device, and no one
+can start using the device while this function is being executed. */
+
+void resetup_one_dev(struct gendisk *dev, int drive)
+{
+ int i;
+ int first_minor = drive << dev->minor_shift;
+ int end_minor = first_minor + dev->max_p;
+
+ blk_size[dev->major] = NULL;
+ current_minor = 1 + first_minor;
+ check_partition(dev, MKDEV(dev->major, first_minor));
+
+ /*
+ * We need to set the sizes array before we will be able to access
+ * any of the partitions on this device.
+ */
+ if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
+ for (i = first_minor; i < end_minor; i++)
+ dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
+ blk_size[dev->major] = dev->sizes;
+ }
+}
+
+static inline void setup_dev(struct gendisk *dev)
+{
+ int i, drive;
+ int end_minor = dev->max_nr * dev->max_p;
+
+ blk_size[dev->major] = NULL;
+ for (i = 0 ; i < end_minor; i++) {
+ dev->part[i].start_sect = 0;
+ dev->part[i].nr_sects = 0;
+ }
+ dev->init(dev);
+ for (drive = 0 ; drive < dev->nr_real ; drive++) {
+ int first_minor = drive << dev->minor_shift;
+ current_minor = 1 + first_minor;
+ check_partition(dev, MKDEV(dev->major, first_minor));
+ }
+ if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
+ for (i = 0; i < end_minor; i++)
+ dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
+ blk_size[dev->major] = dev->sizes;
+ }
+}
+
+__initfunc(void device_setup(void))
+{
+ extern void console_map_init(void);
+ extern void cpqarray_init(void);
+#ifdef CONFIG_PARPORT
+ extern int parport_init(void);
+#endif
+#ifdef CONFIG_MD_BOOT
+ extern void md_setup_drive(void) __init;
+#endif
+#ifdef CONFIG_FC4_SOC
+ extern int soc_probe(void);
+#endif
+ struct gendisk *p;
+
+#ifdef CONFIG_PARPORT
+ parport_init();
+#endif
+ chr_dev_init();
+ blk_dev_init();
+ sti();
+#ifdef CONFIG_I2O
+ i2o_init();
+#endif
+#ifdef CONFIG_BLK_DEV_DAC960
+ DAC960_Initialize();
+#endif
+#ifdef CONFIG_FC4_SOC
+ /* This has to be done before scsi_dev_init */
+ soc_probe();
+#endif
+#ifdef CONFIG_SCSI
+ scsi_dev_init();
+#endif
+#ifdef CONFIG_BLK_CPQ_DA
+ cpqarray_init();
+#endif
+#ifdef CONFIG_NET
+ net_dev_init();
+#endif
+#ifdef CONFIG_VT
+ console_map_init();
+#endif
+
+ for (p = gendisk_head ; p ; p=p->next)
+ setup_dev(p);
+
+#ifdef CONFIG_BLK_DEV_RAM
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start && mount_initrd) initrd_load();
+ else
+#endif
+ rd_load();
+#endif
+#ifdef CONFIG_BLK_DEV_MD
+ autodetect_raid();
+#endif
+#ifdef CONFIG_MD_BOOT
+ md_setup_drive();
+#endif
+}
+
+#ifdef CONFIG_PROC_FS
+int get_partition_list(char * page)
+{
+ struct gendisk *p;
+ char buf[MAX_DISKNAME_LEN];
+ int n, len;
+
+ len = sprintf(page, "major minor #blocks name\n\n");
+ for (p = gendisk_head; p; p = p->next) {
+ for (n=0; n < (p->nr_real << p->minor_shift); n++) {
+ if (p->part[n].nr_sects && len < PAGE_SIZE - 80) {
+ len += sprintf(page+len,
+ "%4d %4d %10d %s\n",
+ p->major, n, p->sizes[n],
+ disk_name(p, n, buf));
+ }
+ }
+ }
+ return len;
+}
+#endif
diff --git a/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.autoconf b/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.autoconf
new file mode 100644
index 000000000000..d31cae1d9cc3
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.autoconf
@@ -0,0 +1,1737 @@
+/*
+ * Automatically generated C config: don't edit
+ */
+#define AUTOCONF_INCLUDED
+/*
+ * Code maturity level options
+ */
+#define CONFIG_EXPERIMENTAL 1
+/*
+ * Processor type and features
+ */
+#undef CONFIG_M386
+#undef CONFIG_M486
+#undef CONFIG_M586
+#define CONFIG_M586TSC 1
+#undef CONFIG_M686
+#define CONFIG_X86_WP_WORKS_OK 1
+#define CONFIG_X86_INVLPG 1
+#define CONFIG_X86_BSWAP 1
+#define CONFIG_X86_POPAD_OK 1
+#define CONFIG_X86_TSC 1
+#define CONFIG_1GB 1
+#undef CONFIG_2GB
+#undef CONFIG_MATH_EMULATION
+#define CONFIG_MTRR 1
+#undef CONFIG_SMP
+/*
+ * Loadable module support
+ */
+#define CONFIG_MODULES 1
+#undef CONFIG_MODVERSIONS
+#define CONFIG_KMOD 1
+/*
+ * General setup
+ */
+#define CONFIG_NET 1
+#define CONFIG_PCI 1
+#undef CONFIG_PCI_GOBIOS
+#undef CONFIG_PCI_GODIRECT
+#define CONFIG_PCI_GOANY 1
+#define CONFIG_PCI_BIOS 1
+#define CONFIG_PCI_DIRECT 1
+#define CONFIG_PCI_QUIRKS 1
+#define CONFIG_PCI_OPTIMIZE 1
+#define CONFIG_PCI_OLD_PROC 1
+#undef CONFIG_MCA
+#undef CONFIG_VISWS
+#define CONFIG_SYSVIPC 1
+#define CONFIG_BSD_PROCESS_ACCT 1
+#define CONFIG_SYSCTL 1
+#define CONFIG_BINFMT_AOUT 1
+#define CONFIG_BINFMT_ELF 1
+#define CONFIG_BINFMT_MISC 1
+#undef CONFIG_BINFMT_JAVA
+#undef CONFIG_PARPORT
+#define CONFIG_PARPORT_MODULE 1
+#undef CONFIG_PARPORT_PC
+#define CONFIG_PARPORT_PC_MODULE 1
+#undef CONFIG_PARPORT_OTHER
+#define CONFIG_APM 1
+#undef CONFIG_APM_IGNORE_USER_SUSPEND
+#undef CONFIG_APM_DO_ENABLE
+#undef CONFIG_APM_CPU_IDLE
+#undef CONFIG_APM_DISPLAY_BLANK
+#undef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+#undef CONFIG_APM_RTC_IS_GMT
+#undef CONFIG_APM_ALLOW_INTS
+#undef CONFIG_APM_REAL_MODE_POWER_OFF
+#undef CONFIG_TOSHIBA
+/*
+ * Crypto options
+ */
+#define CONFIG_CRYPTO 1
+#undef CONFIG_CIPHERS
+#define CONFIG_CIPHERS_MODULE 1
+#undef CONFIG_CIPHER_AES
+#define CONFIG_CIPHER_AES_MODULE 1
+#undef CONFIG_CIPHER_RIJNDAEL
+/*
+ * AES Finalist Ciphers (128 bit blocksize)
+ */
+#undef CONFIG_CIPHER_TWOFISH
+#define CONFIG_CIPHER_TWOFISH_MODULE 1
+#undef CONFIG_CIPHER_MARS
+#define CONFIG_CIPHER_MARS_MODULE 1
+#undef CONFIG_CIPHER_RC6
+#define CONFIG_CIPHER_RC6_MODULE 1
+#undef CONFIG_CIPHER_SERPENT
+#define CONFIG_CIPHER_SERPENT_MODULE 1
+/*
+ * Other Ciphers submitted as AES Candidates:
+ */
+#undef CONFIG_CIPHER_DFC
+#define CONFIG_CIPHER_DFC_MODULE 1
+/*
+ * Other ciphers (64 bit blocksize)
+ */
+#undef CONFIG_CIPHER_BLOWFISH
+#define CONFIG_CIPHER_BLOWFISH_MODULE 1
+#undef CONFIG_CIPHER_IDEA
+#define CONFIG_CIPHER_IDEA_MODULE 1
+#undef CONFIG_CIPHER_RC5
+#define CONFIG_CIPHER_RC5_MODULE 1
+#undef CONFIG_CIPHER_DES_EDE3
+#define CONFIG_CIPHER_DES_EDE3_MODULE 1
+#undef CONFIG_CIPHER_DES
+#define CONFIG_CIPHER_DES_MODULE 1
+#undef CONFIG_DIGEST
+#define CONFIG_DIGEST_MODULE 1
+#undef CONFIG_DIGEST_MD5
+#define CONFIG_DIGEST_MD5_MODULE 1
+#undef CONFIG_DIGEST_SHA1
+#define CONFIG_DIGEST_SHA1_MODULE 1
+/*
+ * Plug and Play support
+ */
+#define CONFIG_PNP 1
+#undef CONFIG_PNP_PARPORT
+#define CONFIG_PNP_PARPORT_MODULE 1
+/*
+ * Block devices
+ */
+#define CONFIG_BLK_DEV_FD 1
+#define CONFIG_BLK_DEV_IDE 1
+/*
+ * Please see Documentation/ide.txt for help/info on IDE drives
+ */
+#undef CONFIG_BLK_DEV_HD_IDE
+#define CONFIG_BLK_DEV_IDEDISK 1
+#undef CONFIG_IDEDISK_MULTI_MODE
+#define CONFIG_BLK_DEV_IDECD 1
+#undef CONFIG_BLK_DEV_IDETAPE
+#define CONFIG_BLK_DEV_IDETAPE_MODULE 1
+#undef CONFIG_BLK_DEV_IDEFLOPPY
+#define CONFIG_BLK_DEV_IDEFLOPPY_MODULE 1
+#undef CONFIG_BLK_DEV_IDESCSI
+#define CONFIG_BLK_DEV_IDESCSI_MODULE 1
+#undef CONFIG_IDE_TASK_IOCTL_DEBUG
+#define CONFIG_BLK_DEV_CMD640 1
+#define CONFIG_BLK_DEV_CMD640_ENHANCED 1
+#define CONFIG_BLK_DEV_RZ1000 1
+#define CONFIG_BLK_DEV_IDEPCI 1
+#undef CONFIG_IDEPCI_SHARE_IRQ
+#define CONFIG_BLK_DEV_IDEDMA 1
+#define CONFIG_IDEDMA_AUTO 1
+#undef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
+#define CONFIG_IDEDMA_PCI_EXPERIMENTAL 1
+#undef CONFIG_IDEDMA_PCI_WIP
+#undef CONFIG_BLK_DEV_OFFBOARD
+#define CONFIG_BLK_DEV_AEC62XX 1
+#define CONFIG_BLK_DEV_ALI15X3 1
+#define CONFIG_BLK_DEV_AMD7409 1
+#define CONFIG_BLK_DEV_CMD64X 1
+#define CONFIG_BLK_DEV_CY82C693 1
+#define CONFIG_BLK_DEV_CS5530 1
+#define CONFIG_BLK_DEV_HPT34X 1
+#define CONFIG_BLK_DEV_HPT366 1
+#define CONFIG_BLK_DEV_PIIX 1
+#define CONFIG_PIIX_TUNING 1
+#define CONFIG_BLK_DEV_OPTI621 1
+#define CONFIG_BLK_DEV_PDC202XX 1
+#define CONFIG_PDC202XX_BURST 1
+#define CONFIG_BLK_DEV_SIS5513 1
+#define CONFIG_BLK_DEV_TRM290 1
+#define CONFIG_BLK_DEV_VIA82CXXX 1
+#define CONFIG_IDE_CHIPSETS 1
+/*
+ * Note: most of these also require special kernel boot parameters
+ */
+#define CONFIG_BLK_DEV_4DRIVES 1
+#define CONFIG_BLK_DEV_ALI14XX 1
+#define CONFIG_BLK_DEV_DTC2278 1
+#define CONFIG_BLK_DEV_HT6560B 1
+#define CONFIG_BLK_DEV_PDC4030 1
+#define CONFIG_BLK_DEV_QD6580 1
+#define CONFIG_BLK_DEV_UMC8672 1
+#undef CONFIG_IDEDMA_IVB
+/*
+ * Additional Block Devices
+ */
+#undef CONFIG_BLK_DEV_LVM
+#define CONFIG_BLK_DEV_LVM_MODULE 1
+#define CONFIG_LVM_PROC_FS 1
+#define CONFIG_BLK_DEV_LOOP 1
+#undef CONFIG_BLK_DEV_LOOP_USE_REL_BLOCK
+#define CONFIG_BLK_DEV_LOOP_GEN_SEL "2"
+#undef CONFIG_BLK_DEV_LOOP_GEN
+#define CONFIG_BLK_DEV_LOOP_GEN_MODULE 1
+#undef CONFIG_BLK_DEV_LOOP_CAST
+#undef CONFIG_BLK_DEV_LOOP_FISH2
+#undef CONFIG_BLK_DEV_NBD
+#define CONFIG_BLK_DEV_NBD_MODULE 1
+#define CONFIG_BLK_DEV_MD 1
+#define CONFIG_AUTODETECT_RAID 1
+#undef CONFIG_MD_LINEAR
+#define CONFIG_MD_LINEAR_MODULE 1
+#undef CONFIG_MD_STRIPED
+#define CONFIG_MD_STRIPED_MODULE 1
+#undef CONFIG_MD_MIRRORING
+#define CONFIG_MD_MIRRORING_MODULE 1
+#undef CONFIG_MD_RAID5
+#define CONFIG_MD_RAID5_MODULE 1
+#define CONFIG_MD_TRANSLUCENT 1
+#undef CONFIG_MD_HSM
+#define CONFIG_BLK_DEV_RAM 1
+#define CONFIG_BLK_DEV_RAM_SIZE (4096)
+#define CONFIG_BLK_DEV_INITRD 1
+#undef CONFIG_BLK_DEV_XD
+#define CONFIG_BLK_DEV_XD_MODULE 1
+#undef CONFIG_BLK_DEV_DAC960
+#define CONFIG_BLK_DEV_DAC960_MODULE 1
+#undef CONFIG_PARIDE_PARPORT
+#define CONFIG_PARIDE_PARPORT_MODULE 1
+#undef CONFIG_PARIDE
+#define CONFIG_PARIDE_MODULE 1
+/*
+ * Parallel IDE high-level drivers
+ */
+#undef CONFIG_PARIDE_PD
+#define CONFIG_PARIDE_PD_MODULE 1
+#undef CONFIG_PARIDE_PCD
+#define CONFIG_PARIDE_PCD_MODULE 1
+#undef CONFIG_PARIDE_PF
+#define CONFIG_PARIDE_PF_MODULE 1
+#undef CONFIG_PARIDE_PT
+#define CONFIG_PARIDE_PT_MODULE 1
+#undef CONFIG_PARIDE_PG
+#define CONFIG_PARIDE_PG_MODULE 1
+/*
+ * Parallel IDE protocol modules
+ */
+#undef CONFIG_PARIDE_ATEN
+#define CONFIG_PARIDE_ATEN_MODULE 1
+#undef CONFIG_PARIDE_BPCK
+#define CONFIG_PARIDE_BPCK_MODULE 1
+#undef CONFIG_PARIDE_COMM
+#define CONFIG_PARIDE_COMM_MODULE 1
+#undef CONFIG_PARIDE_DSTR
+#define CONFIG_PARIDE_DSTR_MODULE 1
+#undef CONFIG_PARIDE_FIT2
+#define CONFIG_PARIDE_FIT2_MODULE 1
+#undef CONFIG_PARIDE_FIT3
+#define CONFIG_PARIDE_FIT3_MODULE 1
+#undef CONFIG_PARIDE_EPAT
+#define CONFIG_PARIDE_EPAT_MODULE 1
+#undef CONFIG_PARIDE_EPIA
+#define CONFIG_PARIDE_EPIA_MODULE 1
+#undef CONFIG_PARIDE_FRIQ
+#define CONFIG_PARIDE_FRIQ_MODULE 1
+#undef CONFIG_PARIDE_FRPW
+#define CONFIG_PARIDE_FRPW_MODULE 1
+#undef CONFIG_PARIDE_KBIC
+#define CONFIG_PARIDE_KBIC_MODULE 1
+#undef CONFIG_PARIDE_KTTI
+#define CONFIG_PARIDE_KTTI_MODULE 1
+#undef CONFIG_PARIDE_ON20
+#define CONFIG_PARIDE_ON20_MODULE 1
+#undef CONFIG_PARIDE_ON26
+#define CONFIG_PARIDE_ON26_MODULE 1
+#define CONFIG_BLK_DEV_IDE_MODES 1
+#undef CONFIG_BLK_CPQ_DA
+#define CONFIG_BLK_CPQ_DA_MODULE 1
+#undef CONFIG_BLK_DEV_HD
+/*
+ * Networking options
+ */
+#undef CONFIG_CIPE
+#define CONFIG_PACKET 1
+#define CONFIG_NETLINK 1
+#define CONFIG_RTNETLINK 1
+#define CONFIG_NETLINK_DEV 1
+#define CONFIG_FIREWALL 1
+#undef CONFIG_NET_SECURITY
+#define CONFIG_FILTER 1
+#define CONFIG_UNIX 1
+#define CONFIG_INET 1
+#define CONFIG_IP_MULTICAST 1
+#define CONFIG_IP_ADVANCED_ROUTER 1
+#define CONFIG_RTNETLINK 1
+#define CONFIG_NETLINK 1
+#define CONFIG_IP_MULTIPLE_TABLES 1
+#define CONFIG_IP_ROUTE_MULTIPATH 1
+#define CONFIG_IP_ROUTE_TOS 1
+#define CONFIG_IP_ROUTE_VERBOSE 1
+#define CONFIG_IP_ROUTE_LARGE_TABLES 1
+#define CONFIG_IP_ROUTE_NAT 1
+#define CONFIG_IP_PNP 1
+#define CONFIG_IP_PNP_DHCP 1
+#define CONFIG_IP_PNP_BOOTP 1
+#define CONFIG_IP_PNP_RARP 1
+#define CONFIG_IP_FIREWALL 1
+#define CONFIG_IP_FIREWALL_NETLINK 1
+#define CONFIG_NETLINK_DEV 1
+#define CONFIG_IP_ROUTE_FWMARK 1
+#define CONFIG_IP_TRANSPARENT_PROXY 1
+#define CONFIG_IP_MASQUERADE 1
+/*
+ * Protocol-specific masquerading support will be built as modules.
+ */
+#define CONFIG_IP_MASQUERADE_ICMP 1
+/*
+ * Protocol-specific masquerading support will be built as modules.
+ */
+#define CONFIG_IP_MASQUERADE_MOD 1
+#undef CONFIG_IP_MASQUERADE_IPAUTOFW
+#define CONFIG_IP_MASQUERADE_IPAUTOFW_MODULE 1
+#undef CONFIG_IP_MASQUERADE_IPPORTFW
+#define CONFIG_IP_MASQUERADE_IPPORTFW_MODULE 1
+#undef CONFIG_IP_MASQUERADE_MFW
+#define CONFIG_IP_MASQUERADE_MFW_MODULE 1
+#undef CONFIG_IP_ROUTER
+#undef CONFIG_NET_IPIP
+#define CONFIG_NET_IPIP_MODULE 1
+#undef CONFIG_NET_IPGRE
+#define CONFIG_NET_IPGRE_MODULE 1
+#undef CONFIG_NET_IPGRE_BROADCAST
+#undef CONFIG_IP_MROUTE
+#undef CONFIG_IP_ALIAS
+#define CONFIG_ARPD 1
+#undef CONFIG_SYN_COOKIES
+/*
+ * (it is safe to leave these untouched)
+ */
+#undef CONFIG_INET_RARP
+#define CONFIG_SKB_LARGE 1
+#undef CONFIG_IPV6
+#define CONFIG_IPV6_MODULE 1
+#undef CONFIG_IPV6_EUI64
+/*
+ *
+ */
+#undef CONFIG_IPX
+#define CONFIG_IPX_MODULE 1
+#undef CONFIG_IPX_INTERN
+#undef CONFIG_SPX
+#define CONFIG_SPX_MODULE 1
+#undef CONFIG_ATALK
+#define CONFIG_ATALK_MODULE 1
+#undef CONFIG_X25
+#define CONFIG_X25_MODULE 1
+#undef CONFIG_LAPB
+#define CONFIG_LAPB_MODULE 1
+#undef CONFIG_BRIDGE
+#undef CONFIG_LLC
+#undef CONFIG_ECONET
+#define CONFIG_ECONET_MODULE 1
+#undef CONFIG_ECONET_AUNUDP
+#undef CONFIG_ECONET_NATIVE
+#undef CONFIG_WAN_ROUTER
+#define CONFIG_WAN_ROUTER_MODULE 1
+#undef CONFIG_NET_FASTROUTE
+#undef CONFIG_NET_HW_FLOWCONTROL
+#undef CONFIG_CPU_IS_SLOW
+/*
+ * QoS and/or fair queueing
+ */
+#define CONFIG_NET_SCHED 1
+#define CONFIG_NETLINK 1
+#define CONFIG_RTNETLINK 1
+#undef CONFIG_NET_SCH_CBQ
+#define CONFIG_NET_SCH_CBQ_MODULE 1
+#undef CONFIG_NET_SCH_CSZ
+#define CONFIG_NET_SCH_CSZ_MODULE 1
+#undef CONFIG_NET_SCH_PRIO
+#define CONFIG_NET_SCH_PRIO_MODULE 1
+#undef CONFIG_NET_SCH_RED
+#define CONFIG_NET_SCH_RED_MODULE 1
+#undef CONFIG_NET_SCH_SFQ
+#define CONFIG_NET_SCH_SFQ_MODULE 1
+#undef CONFIG_NET_SCH_TEQL
+#define CONFIG_NET_SCH_TEQL_MODULE 1
+#undef CONFIG_NET_SCH_TBF
+#define CONFIG_NET_SCH_TBF_MODULE 1
+#define CONFIG_NET_QOS 1
+#define CONFIG_NET_ESTIMATOR 1
+#define CONFIG_NET_CLS 1
+#undef CONFIG_NET_CLS_ROUTE4
+#define CONFIG_NET_CLS_ROUTE4_MODULE 1
+#define CONFIG_NET_CLS_ROUTE 1
+#undef CONFIG_NET_CLS_FW
+#define CONFIG_NET_CLS_FW_MODULE 1
+#undef CONFIG_NET_CLS_U32
+#define CONFIG_NET_CLS_U32_MODULE 1
+#undef CONFIG_NET_CLS_RSVP
+#define CONFIG_NET_CLS_RSVP_MODULE 1
+#undef CONFIG_NET_CLS_RSVP6
+#define CONFIG_NET_CLS_RSVP6_MODULE 1
+#define CONFIG_NET_CLS_POLICE 1
+/*
+ * Telephony Support
+ */
+#undef CONFIG_PHONE
+#define CONFIG_PHONE_MODULE 1
+#undef CONFIG_PHONE_IXJ
+#define CONFIG_PHONE_IXJ_MODULE 1
+/*
+ * SCSI support
+ */
+#define CONFIG_SCSI 1
+/*
+ * SCSI support type (disk, tape, CD-ROM)
+ */
+#define CONFIG_BLK_DEV_SD 1
+#undef CONFIG_CHR_DEV_ST
+#define CONFIG_CHR_DEV_ST_MODULE 1
+#undef CONFIG_BLK_DEV_SR
+#define CONFIG_BLK_DEV_SR_MODULE 1
+#undef CONFIG_BLK_DEV_SR_VENDOR
+#undef CONFIG_CHR_DEV_SG
+#define CONFIG_CHR_DEV_SG_MODULE 1
+/*
+ * Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ */
+#define CONFIG_SCSI_MULTI_LUN 1
+#define CONFIG_SCSI_CONSTANTS 1
+#undef CONFIG_SCSI_LOGGING
+/*
+ * SCSI low-level drivers
+ */
+#undef CONFIG_BLK_DEV_3W_XXXX_RAID
+#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1
+#undef CONFIG_SCSI_7000FASST
+#define CONFIG_SCSI_7000FASST_MODULE 1
+#undef CONFIG_SCSI_ACARD
+#define CONFIG_SCSI_ACARD_MODULE 1
+#undef CONFIG_SCSI_AHA152X
+#define CONFIG_SCSI_AHA152X_MODULE 1
+#undef CONFIG_SCSI_AHA1542
+#define CONFIG_SCSI_AHA1542_MODULE 1
+#undef CONFIG_SCSI_AHA1740
+#define CONFIG_SCSI_AHA1740_MODULE 1
+#undef CONFIG_SCSI_AIC7XXX
+#define CONFIG_SCSI_AIC7XXX_MODULE 1
+#undef CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+#define CONFIG_AIC7XXX_CMDS_PER_DEVICE (8)
+#undef CONFIG_AIC7XXX_PROC_STATS
+#define CONFIG_AIC7XXX_RESET_DELAY (5)
+#undef CONFIG_SCSI_IPS
+#define CONFIG_SCSI_IPS_MODULE 1
+#undef CONFIG_SCSI_ADVANSYS
+#define CONFIG_SCSI_ADVANSYS_MODULE 1
+#undef CONFIG_SCSI_IN2000
+#define CONFIG_SCSI_IN2000_MODULE 1
+#undef CONFIG_SCSI_AM53C974
+#define CONFIG_SCSI_AM53C974_MODULE 1
+#undef CONFIG_SCSI_MEGARAID
+#define CONFIG_SCSI_MEGARAID_MODULE 1
+#undef CONFIG_SCSI_BUSLOGIC
+#define CONFIG_SCSI_BUSLOGIC_MODULE 1
+#define CONFIG_SCSI_OMIT_FLASHPOINT 1
+#undef CONFIG_SCSI_DTC3280
+#define CONFIG_SCSI_DTC3280_MODULE 1
+#undef CONFIG_SCSI_EATA
+#define CONFIG_SCSI_EATA_MODULE 1
+#undef CONFIG_SCSI_EATA_TAGGED_QUEUE
+#undef CONFIG_SCSI_EATA_LINKED_COMMANDS
+#define CONFIG_SCSI_EATA_MAX_TAGS (16)
+#undef CONFIG_SCSI_EATA_DMA
+#define CONFIG_SCSI_EATA_DMA_MODULE 1
+#undef CONFIG_SCSI_EATA_PIO
+#define CONFIG_SCSI_EATA_PIO_MODULE 1
+#undef CONFIG_SCSI_FUTURE_DOMAIN
+#define CONFIG_SCSI_FUTURE_DOMAIN_MODULE 1
+#undef CONFIG_SCSI_GDTH
+#define CONFIG_SCSI_GDTH_MODULE 1
+#undef CONFIG_SCSI_GENERIC_NCR5380
+#define CONFIG_SCSI_GENERIC_NCR5380_MODULE 1
+#define CONFIG_SCSI_GENERIC_NCR53C400 1
+#define CONFIG_SCSI_G_NCR5380_PORT 1
+#undef CONFIG_SCSI_G_NCR5380_MEM
+#undef CONFIG_SCSI_INITIO
+#define CONFIG_SCSI_INITIO_MODULE 1
+#undef CONFIG_SCSI_INIA100
+#define CONFIG_SCSI_INIA100_MODULE 1
+#undef CONFIG_SCSI_PPA
+#define CONFIG_SCSI_PPA_MODULE 1
+#undef CONFIG_SCSI_IMM
+#define CONFIG_SCSI_IMM_MODULE 1
+#define CONFIG_SCSI_IZIP_EPP16 1
+#define CONFIG_SCSI_IZIP_SLOW_CTR 1
+#undef CONFIG_SCSI_NCR53C406A
+#define CONFIG_SCSI_NCR53C406A_MODULE 1
+#undef CONFIG_SCSI_SYM53C416
+#define CONFIG_SCSI_SYM53C416_MODULE 1
+#undef CONFIG_SCSI_SIM710
+#define CONFIG_SCSI_SIM710_MODULE 1
+#undef CONFIG_SCSI_NCR53C7xx
+#define CONFIG_SCSI_NCR53C7xx_MODULE 1
+#undef CONFIG_SCSI_NCR53C7xx_sync
+#define CONFIG_SCSI_NCR53C7xx_FAST 1
+#define CONFIG_SCSI_NCR53C7xx_DISCONNECT 1
+#undef CONFIG_SCSI_NCR53C8XX
+#define CONFIG_SCSI_NCR53C8XX_MODULE 1
+#undef CONFIG_SCSI_SYM53C8XX
+#define CONFIG_SCSI_SYM53C8XX_MODULE 1
+#define CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS (4)
+#define CONFIG_SCSI_NCR53C8XX_MAX_TAGS (32)
+#define CONFIG_SCSI_NCR53C8XX_SYNC (20)
+#define CONFIG_SCSI_NCR53C8XX_PROFILE 1
+#define CONFIG_SCSI_NCR53C8XX_IOMAPPED 1
+#define CONFIG_SCSI_NCR53C8XX_PQS_PDS 1
+#define CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 1
+#undef CONFIG_SCSI_PAS16
+#define CONFIG_SCSI_PAS16_MODULE 1
+#undef CONFIG_SCSI_PCI2000
+#define CONFIG_SCSI_PCI2000_MODULE 1
+#undef CONFIG_SCSI_PCI2220I
+#define CONFIG_SCSI_PCI2220I_MODULE 1
+#undef CONFIG_SCSI_PSI240I
+#define CONFIG_SCSI_PSI240I_MODULE 1
+#undef CONFIG_SCSI_QLOGIC_FAS
+#define CONFIG_SCSI_QLOGIC_FAS_MODULE 1
+#undef CONFIG_SCSI_QLOGIC_ISP
+#define CONFIG_SCSI_QLOGIC_ISP_MODULE 1
+#undef CONFIG_SCSI_QLOGIC_FC
+#define CONFIG_SCSI_QLOGIC_FC_MODULE 1
+#undef CONFIG_SCSI_SEAGATE
+#define CONFIG_SCSI_SEAGATE_MODULE 1
+#undef CONFIG_SCSI_DC390T
+#define CONFIG_SCSI_DC390T_MODULE 1
+#define CONFIG_SCSI_DC390T_NOGENSUPP 1
+#undef CONFIG_SCSI_T128
+#define CONFIG_SCSI_T128_MODULE 1
+#undef CONFIG_SCSI_U14_34F
+#define CONFIG_SCSI_U14_34F_MODULE 1
+#define CONFIG_SCSI_U14_34F_LINKED_COMMANDS 1
+#define CONFIG_SCSI_U14_34F_MAX_TAGS (8)
+#undef CONFIG_SCSI_ULTRASTOR
+#define CONFIG_SCSI_ULTRASTOR_MODULE 1
+#undef CONFIG_SCSI_DEBUG
+/*
+ * I2O device support
+ */
+#undef CONFIG_I2O
+#define CONFIG_I2O_MODULE 1
+#undef CONFIG_I2O_PCI
+#define CONFIG_I2O_PCI_MODULE 1
+#undef CONFIG_I2O_BLOCK
+#define CONFIG_I2O_BLOCK_MODULE 1
+#undef CONFIG_I2O_SCSI
+#define CONFIG_I2O_SCSI_MODULE 1
+/*
+ * Network device support
+ */
+#define CONFIG_NETDEVICES 1
+/*
+ * ARCnet devices
+ */
+#undef CONFIG_ARCNET
+#define CONFIG_ARCNET_MODULE 1
+#define CONFIG_ARCNET_ETH 1
+#define CONFIG_ARCNET_1051 1
+#undef CONFIG_ARCNET_COM90xx
+#define CONFIG_ARCNET_COM90xx_MODULE 1
+#undef CONFIG_ARCNET_COM90xxIO
+#define CONFIG_ARCNET_COM90xxIO_MODULE 1
+#undef CONFIG_ARCNET_RIM_I
+#define CONFIG_ARCNET_RIM_I_MODULE 1
+#undef CONFIG_ARCNET_COM20020
+#define CONFIG_ARCNET_COM20020_MODULE 1
+#undef CONFIG_DUMMY
+#define CONFIG_DUMMY_MODULE 1
+#undef CONFIG_BONDING
+#define CONFIG_BONDING_MODULE 1
+#undef CONFIG_EQUALIZER
+#define CONFIG_EQUALIZER_MODULE 1
+#undef CONFIG_ETHERTAP
+#define CONFIG_ETHERTAP_MODULE 1
+#undef CONFIG_NET_SB1000
+#define CONFIG_NET_SB1000_MODULE 1
+#undef CONFIG_PPPOX
+#define CONFIG_PPPOX_MODULE 1
+/*
+ * Ethernet (10 or 100Mbit)
+ */
+#define CONFIG_NET_ETHERNET 1
+#define CONFIG_NET_VENDOR_3COM 1
+#undef CONFIG_EL1
+#define CONFIG_EL1_MODULE 1
+#undef CONFIG_EL2
+#define CONFIG_EL2_MODULE 1
+#undef CONFIG_ELPLUS
+#define CONFIG_ELPLUS_MODULE 1
+#undef CONFIG_EL16
+#define CONFIG_EL16_MODULE 1
+#undef CONFIG_EL3
+#define CONFIG_EL3_MODULE 1
+#undef CONFIG_3C515
+#define CONFIG_3C515_MODULE 1
+#undef CONFIG_VORTEX
+#define CONFIG_VORTEX_MODULE 1
+#undef CONFIG_LANCE
+#define CONFIG_LANCE_MODULE 1
+#define CONFIG_NET_VENDOR_SMC 1
+#undef CONFIG_WD80x3
+#define CONFIG_WD80x3_MODULE 1
+#undef CONFIG_ULTRA
+#define CONFIG_ULTRA_MODULE 1
+#undef CONFIG_ULTRA32
+#define CONFIG_ULTRA32_MODULE 1
+#undef CONFIG_SMC9194
+#define CONFIG_SMC9194_MODULE 1
+#define CONFIG_NET_VENDOR_RACAL 1
+#undef CONFIG_NI5010
+#define CONFIG_NI5010_MODULE 1
+#undef CONFIG_NI52
+#define CONFIG_NI52_MODULE 1
+#undef CONFIG_NI65
+#define CONFIG_NI65_MODULE 1
+#undef CONFIG_RTL8139
+#define CONFIG_RTL8139_MODULE 1
+#define CONFIG_NET_ISA 1
+#undef CONFIG_AT1700
+#define CONFIG_AT1700_MODULE 1
+#undef CONFIG_E2100
+#define CONFIG_E2100_MODULE 1
+#undef CONFIG_DEPCA
+#define CONFIG_DEPCA_MODULE 1
+#undef CONFIG_EWRK3
+#define CONFIG_EWRK3_MODULE 1
+#undef CONFIG_EEXPRESS
+#define CONFIG_EEXPRESS_MODULE 1
+#undef CONFIG_EEXPRESS_PRO
+#define CONFIG_EEXPRESS_PRO_MODULE 1
+#undef CONFIG_FMV18X
+#define CONFIG_FMV18X_MODULE 1
+#undef CONFIG_HPLAN_PLUS
+#define CONFIG_HPLAN_PLUS_MODULE 1
+#undef CONFIG_HPLAN
+#define CONFIG_HPLAN_MODULE 1
+#undef CONFIG_HP100
+#define CONFIG_HP100_MODULE 1
+#undef CONFIG_ETH16I
+#define CONFIG_ETH16I_MODULE 1
+#undef CONFIG_NE2000
+#define CONFIG_NE2000_MODULE 1
+#undef CONFIG_SEEQ8005
+#define CONFIG_SEEQ8005_MODULE 1
+#define CONFIG_SK_G16 1
+#define CONFIG_NET_EISA 1
+#undef CONFIG_PCNET32
+#define CONFIG_PCNET32_MODULE 1
+#undef CONFIG_AC3200
+#define CONFIG_AC3200_MODULE 1
+#undef CONFIG_APRICOT
+#define CONFIG_APRICOT_MODULE 1
+#undef CONFIG_CS89x0
+#define CONFIG_CS89x0_MODULE 1
+#undef CONFIG_DM9102
+#define CONFIG_DM9102_MODULE 1
+#undef CONFIG_DE4X5
+#define CONFIG_DE4X5_MODULE 1
+#undef CONFIG_DEC_ELCP
+#define CONFIG_DEC_ELCP_MODULE 1
+#undef CONFIG_DEC_ELCP_OLD
+#define CONFIG_DEC_ELCP_OLD_MODULE 1
+#undef CONFIG_DGRS
+#define CONFIG_DGRS_MODULE 1
+#define CONFIG_EEXPRESS_PRO100 1
+#undef CONFIG_LNE390
+#define CONFIG_LNE390_MODULE 1
+#undef CONFIG_NE3210
+#define CONFIG_NE3210_MODULE 1
+#undef CONFIG_NE2K_PCI
+#define CONFIG_NE2K_PCI_MODULE 1
+#undef CONFIG_TLAN
+#define CONFIG_TLAN_MODULE 1
+#undef CONFIG_VIA_RHINE
+#define CONFIG_VIA_RHINE_MODULE 1
+#undef CONFIG_SIS900
+#define CONFIG_SIS900_MODULE 1
+#undef CONFIG_ES3210
+#define CONFIG_ES3210_MODULE 1
+#undef CONFIG_EPIC100
+#define CONFIG_EPIC100_MODULE 1
+#define CONFIG_ZNET 1
+#define CONFIG_NET_POCKET 1
+#define CONFIG_ATP 1
+#undef CONFIG_DE600
+#define CONFIG_DE600_MODULE 1
+#undef CONFIG_DE620
+#define CONFIG_DE620_MODULE 1
+/*
+ * Ethernet (1000 Mbit)
+ */
+#undef CONFIG_ACENIC
+#define CONFIG_ACENIC_MODULE 1
+#undef CONFIG_HAMACHI
+#define CONFIG_HAMACHI_MODULE 1
+#undef CONFIG_YELLOWFIN
+#define CONFIG_YELLOWFIN_MODULE 1
+#undef CONFIG_SK98LIN
+#define CONFIG_SK98LIN_MODULE 1
+#define CONFIG_FDDI 1
+#define CONFIG_DEFXX 1
+#define CONFIG_HIPPI 1
+#undef CONFIG_ROADRUNNER
+#define CONFIG_ROADRUNNER_MODULE 1
+#undef CONFIG_ROADRUNNER_LARGE_RINGS
+/*
+ * Appletalk devices
+ */
+#undef CONFIG_LTPC
+#define CONFIG_LTPC_MODULE 1
+#undef CONFIG_COPS
+#define CONFIG_COPS_MODULE 1
+#undef CONFIG_COPS_DAYNA
+#undef CONFIG_COPS_TANGENT
+#undef CONFIG_IPDDP
+#define CONFIG_IPDDP_MODULE 1
+#undef CONFIG_IPDDP_ENCAP
+#undef CONFIG_IPDDP_DECAP
+#undef CONFIG_PLIP
+#define CONFIG_PLIP_MODULE 1
+#undef CONFIG_PPP
+#define CONFIG_PPP_MODULE 1
+#undef CONFIG_SLIP
+#define CONFIG_SLIP_MODULE 1
+#define CONFIG_SLIP_COMPRESSED 1
+#define CONFIG_SLIP_SMART 1
+#define CONFIG_SLIP_MODE_SLIP6 1
+#define CONFIG_NET_RADIO 1
+#undef CONFIG_STRIP
+#define CONFIG_STRIP_MODULE 1
+#undef CONFIG_WAVELAN
+#define CONFIG_WAVELAN_MODULE 1
+#undef CONFIG_ARLAN
+#define CONFIG_ARLAN_MODULE 1
+/*
+ * Token ring devices
+ */
+#define CONFIG_TR 1
+#undef CONFIG_IBMTR
+#define CONFIG_IBMTR_MODULE 1
+#undef CONFIG_IBMLS
+#define CONFIG_IBMLS_MODULE 1
+#undef CONFIG_IBMOL
+#define CONFIG_IBMOL_MODULE 1
+#undef CONFIG_SKTR
+#define CONFIG_SKTR_MODULE 1
+#define CONFIG_NET_FC 1
+#undef CONFIG_IPHASE5526
+#define CONFIG_IPHASE5526_MODULE 1
+#undef CONFIG_RCPCI
+#define CONFIG_RCPCI_MODULE 1
+#undef CONFIG_SHAPER
+#define CONFIG_SHAPER_MODULE 1
+/*
+ * Wan interfaces
+ */
+#undef CONFIG_HOSTESS_SV11
+#define CONFIG_HOSTESS_SV11_MODULE 1
+#undef CONFIG_COSA
+#define CONFIG_COSA_MODULE 1
+#undef CONFIG_SEALEVEL_4021
+#define CONFIG_SEALEVEL_4021_MODULE 1
+#undef CONFIG_SYNCLINK_SYNCPPP
+#define CONFIG_SYNCLINK_SYNCPPP_MODULE 1
+#undef CONFIG_LANMEDIA
+#define CONFIG_LANMEDIA_MODULE 1
+#undef CONFIG_COMX
+#define CONFIG_COMX_MODULE 1
+#undef CONFIG_COMX_HW_COMX
+#define CONFIG_COMX_HW_COMX_MODULE 1
+#undef CONFIG_COMX_HW_LOCOMX
+#define CONFIG_COMX_HW_LOCOMX_MODULE 1
+#undef CONFIG_COMX_HW_MIXCOM
+#define CONFIG_COMX_HW_MIXCOM_MODULE 1
+#undef CONFIG_COMX_PROTO_PPP
+#define CONFIG_COMX_PROTO_PPP_MODULE 1
+#undef CONFIG_COMX_PROTO_LAPB
+#define CONFIG_COMX_PROTO_LAPB_MODULE 1
+#undef CONFIG_COMX_PROTO_FR
+#define CONFIG_COMX_PROTO_FR_MODULE 1
+#undef CONFIG_HDLC
+#define CONFIG_HDLC_MODULE 1
+#undef CONFIG_N2
+#define CONFIG_N2_MODULE 1
+#undef CONFIG_C101
+#define CONFIG_C101_MODULE 1
+#undef CONFIG_WANXL
+#define CONFIG_WANXL_MODULE 1
+#undef CONFIG_PC300
+#define CONFIG_PC300_MODULE 1
+#undef CONFIG_PC300_X25
+#undef CONFIG_DLCI
+#define CONFIG_DLCI_MODULE 1
+#define CONFIG_DLCI_COUNT (24)
+#define CONFIG_DLCI_MAX (8)
+#undef CONFIG_SDLA
+#define CONFIG_SDLA_MODULE 1
+#define CONFIG_WAN_DRIVERS 1
+#undef CONFIG_VENDOR_SANGOMA
+#define CONFIG_VENDOR_SANGOMA_MODULE 1
+#define CONFIG_WANPIPE_CARDS (1)
+#define CONFIG_WANPIPE_FR 1
+#define CONFIG_WANPIPE_PPP 1
+#define CONFIG_WANPIPE_CHDLC 1
+#undef CONFIG_LAPBETHER
+#define CONFIG_LAPBETHER_MODULE 1
+#undef CONFIG_X25_ASY
+#define CONFIG_X25_ASY_MODULE 1
+#undef CONFIG_SBNI
+#define CONFIG_SBNI_MODULE 1
+/*
+ * Amateur Radio support
+ */
+#define CONFIG_HAMRADIO 1
+/*
+ * Packet Radio protocols
+ */
+#undef CONFIG_AX25
+#define CONFIG_AX25_MODULE 1
+#define CONFIG_AX25_DAMA_SLAVE 1
+#undef CONFIG_NETROM
+#define CONFIG_NETROM_MODULE 1
+#undef CONFIG_ROSE
+#define CONFIG_ROSE_MODULE 1
+/*
+ * AX.25 network device drivers
+ */
+#undef CONFIG_MKISS
+#define CONFIG_MKISS_MODULE 1
+#undef CONFIG_6PACK
+#define CONFIG_6PACK_MODULE 1
+#undef CONFIG_BPQETHER
+#define CONFIG_BPQETHER_MODULE 1
+#undef CONFIG_DMASCC
+#define CONFIG_DMASCC_MODULE 1
+#undef CONFIG_SCC
+#define CONFIG_SCC_MODULE 1
+#undef CONFIG_SCC_DELAY
+#undef CONFIG_SCC_TRXECHO
+#undef CONFIG_BAYCOM_SER_FDX
+#define CONFIG_BAYCOM_SER_FDX_MODULE 1
+#undef CONFIG_BAYCOM_SER_HDX
+#define CONFIG_BAYCOM_SER_HDX_MODULE 1
+#undef CONFIG_BAYCOM_PAR
+#define CONFIG_BAYCOM_PAR_MODULE 1
+#undef CONFIG_BAYCOM_EPP
+#define CONFIG_BAYCOM_EPP_MODULE 1
+#undef CONFIG_SOUNDMODEM
+#define CONFIG_SOUNDMODEM_MODULE 1
+#define CONFIG_SOUNDMODEM_SBC 1
+#define CONFIG_SOUNDMODEM_WSS 1
+#define CONFIG_SOUNDMODEM_AFSK1200 1
+#define CONFIG_SOUNDMODEM_AFSK2400_7 1
+#define CONFIG_SOUNDMODEM_AFSK2400_8 1
+#define CONFIG_SOUNDMODEM_AFSK2666 1
+#define CONFIG_SOUNDMODEM_HAPN4800 1
+#define CONFIG_SOUNDMODEM_PSK4800 1
+#define CONFIG_SOUNDMODEM_FSK9600 1
+#undef CONFIG_YAM
+#define CONFIG_YAM_MODULE 1
+/*
+ * Misc. hamradio protocols
+ */
+#undef CONFIG_HFMODEM
+/*
+ * IrDA (infrared) support
+ */
+#undef CONFIG_IRDA
+#define CONFIG_IRDA_MODULE 1
+/*
+ * IrDA protocols
+ */
+#undef CONFIG_IRLAN
+#define CONFIG_IRLAN_MODULE 1
+#undef CONFIG_IRCOMM
+#define CONFIG_IRCOMM_MODULE 1
+#define CONFIG_IRDA_ULTRA 1
+#define CONFIG_IRDA_OPTIONS 1
+/*
+ * IrDA options
+ */
+#define CONFIG_IRDA_CACHE_LAST_LSAP 1
+#define CONFIG_IRDA_FAST_RR 1
+#undef CONFIG_IRDA_DEBUG
+#define CONFIG_IRDA_COMPRESSION 1
+/*
+ * IrDA compressors
+ */
+#undef CONFIG_IRDA_DEFLATE
+#define CONFIG_IRDA_DEFLATE_MODULE 1
+/*
+ * Infrared-port device drivers
+ */
+/*
+ * SIR device drivers
+ */
+#undef CONFIG_IRTTY_SIR
+#define CONFIG_IRTTY_SIR_MODULE 1
+#undef CONFIG_IRPORT_SIR
+#define CONFIG_IRPORT_SIR_MODULE 1
+/*
+ * FIR device drivers
+ */
+#undef CONFIG_NSC_FIR
+#define CONFIG_NSC_FIR_MODULE 1
+#undef CONFIG_WINBOND_FIR
+#define CONFIG_WINBOND_FIR_MODULE 1
+#undef CONFIG_TOSHIBA_FIR
+#define CONFIG_TOSHIBA_FIR_MODULE 1
+#undef CONFIG_SMC_IRCC_FIR
+#define CONFIG_SMC_IRCC_FIR_MODULE 1
+/*
+ * Dongle support
+ */
+#define CONFIG_DONGLE 1
+#undef CONFIG_ESI_DONGLE
+#define CONFIG_ESI_DONGLE_MODULE 1
+#undef CONFIG_ACTISYS_DONGLE
+#define CONFIG_ACTISYS_DONGLE_MODULE 1
+#undef CONFIG_TEKRAM_DONGLE
+#define CONFIG_TEKRAM_DONGLE_MODULE 1
+#undef CONFIG_GIRBIL_DONGLE
+#define CONFIG_GIRBIL_DONGLE_MODULE 1
+#undef CONFIG_LITELINK_DONGLE
+#define CONFIG_LITELINK_DONGLE_MODULE 1
+#undef CONFIG_OLD_BELKIN_DONGLE
+#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1
+/*
+ * ISDN subsystem
+ */
+#undef CONFIG_ISDN
+#define CONFIG_ISDN_MODULE 1
+#define CONFIG_ISDN_PPP 1
+#define CONFIG_ISDN_PPP_VJ 1
+#define CONFIG_ISDN_MPP 1
+#define CONFIG_ISDN_AUDIO 1
+#define CONFIG_ISDN_TTY_FAX 1
+#define CONFIG_ISDN_X25 1
+/*
+ * ISDN feature submodules
+ */
+#undef CONFIG_ISDN_DRV_LOOP
+#define CONFIG_ISDN_DRV_LOOP_MODULE 1
+#define CONFIG_ISDN_DIVERSION 1
+/*
+ * low-level hardware drivers
+ */
+/*
+ * Passive ISDN cards
+ */
+#undef CONFIG_ISDN_DRV_HISAX
+#define CONFIG_ISDN_DRV_HISAX_MODULE 1
+/*
+ * D-channel protocol features
+ */
+#define CONFIG_HISAX_EURO 1
+#define CONFIG_DE_AOC 1
+#undef CONFIG_HISAX_NO_SENDCOMPLETE
+#undef CONFIG_HISAX_NO_LLC
+#undef CONFIG_HISAX_NO_KEYPAD
+#undef CONFIG_HISAX_1TR6
+/*
+ * HiSax supported cards
+ */
+#define CONFIG_HISAX_16_0 1
+#define CONFIG_HISAX_16_3 1
+#define CONFIG_HISAX_TELESPCI 1
+#define CONFIG_HISAX_S0BOX 1
+#define CONFIG_HISAX_AVM_A1 1
+#define CONFIG_HISAX_FRITZPCI 1
+#define CONFIG_HISAX_AVM_A1_PCMCIA 1
+#define CONFIG_HISAX_ELSA 1
+#define CONFIG_HISAX_IX1MICROR2 1
+#define CONFIG_HISAX_DIEHLDIVA 1
+#define CONFIG_HISAX_ASUSCOM 1
+#define CONFIG_HISAX_TELEINT 1
+#define CONFIG_HISAX_HFCS 1
+#define CONFIG_HISAX_SEDLBAUER 1
+#define CONFIG_HISAX_SPORTSTER 1
+#define CONFIG_HISAX_MIC 1
+#define CONFIG_HISAX_NETJET 1
+#define CONFIG_HISAX_NICCY 1
+#define CONFIG_HISAX_ISURF 1
+#define CONFIG_HISAX_HSTSAPHIR 1
+#define CONFIG_HISAX_BKM_A4T 1
+#define CONFIG_HISAX_SCT_QUADRO 1
+#define CONFIG_HISAX_GAZEL 1
+#define CONFIG_HISAX_HFC_PCI 1
+#define CONFIG_HISAX_W6692 1
+#define CONFIG_HISAX_HFC_SX 1
+/*
+ * Active ISDN cards
+ */
+#undef CONFIG_ISDN_DRV_ICN
+#define CONFIG_ISDN_DRV_ICN_MODULE 1
+#undef CONFIG_ISDN_DRV_PCBIT
+#define CONFIG_ISDN_DRV_PCBIT_MODULE 1
+#undef CONFIG_ISDN_DRV_SC
+#define CONFIG_ISDN_DRV_SC_MODULE 1
+#undef CONFIG_ISDN_DRV_ACT2000
+#define CONFIG_ISDN_DRV_ACT2000_MODULE 1
+#undef CONFIG_ISDN_DRV_EICON
+#define CONFIG_ISDN_DRV_EICON_MODULE 1
+#define CONFIG_ISDN_DRV_EICON_ISA 1
+#undef CONFIG_ISDN_DRV_AVMB1
+#define CONFIG_ISDN_DRV_AVMB1_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1ISA 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCI 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCIV4 1
+#define CONFIG_ISDN_DRV_AVMB1_T1ISA 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCMCIA 1
+#define CONFIG_ISDN_DRV_AVMB1_T1PCI 1
+#define CONFIG_ISDN_DRV_AVMB1_C4 1
+#define CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON 1
+/*
+ * Old CD-ROM drivers (not SCSI, not IDE)
+ */
+#define CONFIG_CD_NO_IDESCSI 1
+#undef CONFIG_AZTCD
+#define CONFIG_AZTCD_MODULE 1
+#undef CONFIG_GSCD
+#define CONFIG_GSCD_MODULE 1
+#undef CONFIG_SBPCD
+#define CONFIG_SBPCD_MODULE 1
+#undef CONFIG_MCD
+#define CONFIG_MCD_MODULE 1
+#define CONFIG_MCD_IRQ (11)
+#define CONFIG_MCD_BASE 0x300
+#undef CONFIG_MCDX
+#define CONFIG_MCDX_MODULE 1
+#undef CONFIG_OPTCD
+#define CONFIG_OPTCD_MODULE 1
+#undef CONFIG_CM206
+#define CONFIG_CM206_MODULE 1
+#undef CONFIG_SJCD
+#define CONFIG_SJCD_MODULE 1
+#undef CONFIG_ISP16_CDI
+#define CONFIG_ISP16_CDI_MODULE 1
+#undef CONFIG_CDU31A
+#define CONFIG_CDU31A_MODULE 1
+#undef CONFIG_CDU535
+#define CONFIG_CDU535_MODULE 1
+/*
+ * Character devices
+ */
+#define CONFIG_VT 1
+#define CONFIG_VT_CONSOLE 1
+#define CONFIG_SERIAL 1
+#define CONFIG_SERIAL_CONSOLE 1
+#undef CONFIG_SERIAL_EXTENDED
+#define CONFIG_SERIAL_NONSTANDARD 1
+#undef CONFIG_COMPUTONE
+#define CONFIG_COMPUTONE_MODULE 1
+#undef CONFIG_ROCKETPORT
+#define CONFIG_ROCKETPORT_MODULE 1
+#undef CONFIG_CYCLADES
+#define CONFIG_CYCLADES_MODULE 1
+#undef CONFIG_CYZ_INTR
+#undef CONFIG_DIGIEPCA
+#define CONFIG_DIGIEPCA_MODULE 1
+#undef CONFIG_ESPSERIAL
+#define CONFIG_ESPSERIAL_MODULE 1
+#undef CONFIG_MOXA_INTELLIO
+#define CONFIG_MOXA_INTELLIO_MODULE 1
+#undef CONFIG_MOXA_SMARTIO
+#define CONFIG_MOXA_SMARTIO_MODULE 1
+#undef CONFIG_ISI
+#define CONFIG_ISI_MODULE 1
+#undef CONFIG_RISCOM8
+#define CONFIG_RISCOM8_MODULE 1
+#undef CONFIG_SPECIALIX
+#define CONFIG_SPECIALIX_MODULE 1
+#define CONFIG_SPECIALIX_RTSCTS 1
+#undef CONFIG_SX
+#define CONFIG_SX_MODULE 1
+#undef CONFIG_RIO
+#define CONFIG_RIO_MODULE 1
+#define CONFIG_RIO_OLDPCI 1
+#define CONFIG_STALDRV 1
+#undef CONFIG_STALLION
+#define CONFIG_STALLION_MODULE 1
+#undef CONFIG_ISTALLION
+#define CONFIG_ISTALLION_MODULE 1
+#undef CONFIG_SYNCLINK
+#define CONFIG_SYNCLINK_MODULE 1
+#undef CONFIG_N_HDLC
+#define CONFIG_N_HDLC_MODULE 1
+#define CONFIG_UNIX98_PTYS 1
+#define CONFIG_UNIX98_PTY_COUNT (256)
+#undef CONFIG_PRINTER
+#define CONFIG_PRINTER_MODULE 1
+#define CONFIG_PRINTER_READBACK 1
+#define CONFIG_MOUSE 1
+/*
+ * Mice
+ */
+#undef CONFIG_ATIXL_BUSMOUSE
+#define CONFIG_ATIXL_BUSMOUSE_MODULE 1
+#undef CONFIG_BUSMOUSE
+#define CONFIG_BUSMOUSE_MODULE 1
+#undef CONFIG_MS_BUSMOUSE
+#define CONFIG_MS_BUSMOUSE_MODULE 1
+#define CONFIG_PSMOUSE 1
+#define CONFIG_82C710_MOUSE 1
+#undef CONFIG_PC110_PAD
+#define CONFIG_PC110_PAD_MODULE 1
+/*
+ * Joysticks
+ */
+#undef CONFIG_JOYSTICK
+#define CONFIG_JOYSTICK_MODULE 1
+#undef CONFIG_JOY_ANALOG
+#define CONFIG_JOY_ANALOG_MODULE 1
+#undef CONFIG_JOY_ASSASSIN
+#define CONFIG_JOY_ASSASSIN_MODULE 1
+#undef CONFIG_JOY_GRAVIS
+#define CONFIG_JOY_GRAVIS_MODULE 1
+#undef CONFIG_JOY_LOGITECH
+#define CONFIG_JOY_LOGITECH_MODULE 1
+#undef CONFIG_JOY_SIDEWINDER
+#define CONFIG_JOY_SIDEWINDER_MODULE 1
+#undef CONFIG_JOY_THRUSTMASTER
+#define CONFIG_JOY_THRUSTMASTER_MODULE 1
+#undef CONFIG_JOY_CREATIVE
+#define CONFIG_JOY_CREATIVE_MODULE 1
+#undef CONFIG_JOY_LIGHTNING
+#define CONFIG_JOY_LIGHTNING_MODULE 1
+#undef CONFIG_JOY_PCI
+#define CONFIG_JOY_PCI_MODULE 1
+#undef CONFIG_JOY_MAGELLAN
+#define CONFIG_JOY_MAGELLAN_MODULE 1
+#undef CONFIG_JOY_SPACEORB
+#define CONFIG_JOY_SPACEORB_MODULE 1
+#undef CONFIG_JOY_SPACEBALL
+#define CONFIG_JOY_SPACEBALL_MODULE 1
+#undef CONFIG_JOY_WARRIOR
+#define CONFIG_JOY_WARRIOR_MODULE 1
+#undef CONFIG_JOY_CONSOLE
+#define CONFIG_JOY_CONSOLE_MODULE 1
+#undef CONFIG_JOY_DB9
+#define CONFIG_JOY_DB9_MODULE 1
+#undef CONFIG_JOY_TURBOGRAFX
+#define CONFIG_JOY_TURBOGRAFX_MODULE 1
+#undef CONFIG_QIC02_TAPE
+#define CONFIG_QIC02_TAPE_MODULE 1
+#define CONFIG_QIC02_DYNCONF 1
+/*
+ * Setting runtime QIC-02 configuration is done with qic02conf
+ */
+/*
+ * from the tpqic02-support package. It is available at
+ */
+/*
+ * metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/
+ */
+#undef CONFIG_AGP
+#define CONFIG_AGP_MODULE 1
+#define CONFIG_AGP_INTEL 1
+#define CONFIG_AGP_I810 1
+#define CONFIG_AGP_VIA 1
+#define CONFIG_AGP_AMD 1
+#define CONFIG_AGP_SIS 1
+#define CONFIG_AGP_ALI 1
+#define CONFIG_WATCHDOG 1
+/*
+ * Watchdog Cards
+ */
+#define CONFIG_WATCHDOG_NOWAYOUT 1
+#undef CONFIG_WDT
+#define CONFIG_WDT_MODULE 1
+#define CONFIG_WDT_501 1
+#define CONFIG_WDT_501_FAN 1
+#undef CONFIG_SOFT_WATCHDOG
+#define CONFIG_SOFT_WATCHDOG_MODULE 1
+#undef CONFIG_PCWATCHDOG
+#define CONFIG_PCWATCHDOG_MODULE 1
+#undef CONFIG_ACQUIRE_WDT
+#define CONFIG_ACQUIRE_WDT_MODULE 1
+#undef CONFIG_60XX_WDT
+#define CONFIG_60XX_WDT_MODULE 1
+#undef CONFIG_MIXCOMWD
+#define CONFIG_MIXCOMWD_MODULE 1
+#undef CONFIG_NVRAM
+#define CONFIG_NVRAM_MODULE 1
+#define CONFIG_RTC 1
+/*
+ * I2C support
+ */
+#undef CONFIG_I2C
+#define CONFIG_I2C_MODULE 1
+#undef CONFIG_I2C_ALGOBIT
+#define CONFIG_I2C_ALGOBIT_MODULE 1
+#undef CONFIG_I2C_PHILIPSPAR
+#define CONFIG_I2C_PHILIPSPAR_MODULE 1
+#undef CONFIG_I2C_ELV
+#define CONFIG_I2C_ELV_MODULE 1
+#undef CONFIG_I2C_VELLEMAN
+#define CONFIG_I2C_VELLEMAN_MODULE 1
+#undef CONFIG_I2C_ALGOPCF
+#define CONFIG_I2C_ALGOPCF_MODULE 1
+#undef CONFIG_I2C_ELEKTOR
+#define CONFIG_I2C_ELEKTOR_MODULE 1
+#define CONFIG_I2C_MAINBOARD 1
+#undef CONFIG_I2C_ALI15X3
+#define CONFIG_I2C_ALI15X3_MODULE 1
+#undef CONFIG_I2C_HYDRA
+#define CONFIG_I2C_HYDRA_MODULE 1
+#undef CONFIG_I2C_PIIX4
+#define CONFIG_I2C_PIIX4_MODULE 1
+#undef CONFIG_I2C_VIA
+#define CONFIG_I2C_VIA_MODULE 1
+#undef CONFIG_I2C_ISA
+#define CONFIG_I2C_ISA_MODULE 1
+#undef CONFIG_I2C_CHARDEV
+#define CONFIG_I2C_CHARDEV_MODULE 1
+/*
+ * Hardware sensors support
+ */
+#undef CONFIG_SENSORS
+#define CONFIG_SENSORS_MODULE 1
+#undef CONFIG_SENSORS_ADM1021
+#define CONFIG_SENSORS_ADM1021_MODULE 1
+#undef CONFIG_SENSORS_ADM9240
+#define CONFIG_SENSORS_ADM9240_MODULE 1
+#undef CONFIG_SENSORS_GL518SM
+#define CONFIG_SENSORS_GL518SM_MODULE 1
+#undef CONFIG_SENSORS_LM75
+#define CONFIG_SENSORS_LM75_MODULE 1
+#undef CONFIG_SENSORS_LM78
+#define CONFIG_SENSORS_LM78_MODULE 1
+#undef CONFIG_SENSORS_LM80
+#define CONFIG_SENSORS_LM80_MODULE 1
+#undef CONFIG_SENSORS_SIS5595
+#define CONFIG_SENSORS_SIS5595_MODULE 1
+#undef CONFIG_SENSORS_W83781D
+#define CONFIG_SENSORS_W83781D_MODULE 1
+#define CONFIG_SENSORS_OTHER 1
+#undef CONFIG_SENSORS_EEPROM
+#define CONFIG_SENSORS_EEPROM_MODULE 1
+#undef CONFIG_SENSORS_LTC1710
+#define CONFIG_SENSORS_LTC1710_MODULE 1
+/*
+ * Video For Linux
+ */
+#undef CONFIG_VIDEO_DEV
+#define CONFIG_VIDEO_DEV_MODULE 1
+#undef CONFIG_RADIO_RTRACK
+#define CONFIG_RADIO_RTRACK_MODULE 1
+#undef CONFIG_RADIO_RTRACK2
+#define CONFIG_RADIO_RTRACK2_MODULE 1
+#undef CONFIG_RADIO_AZTECH
+#define CONFIG_RADIO_AZTECH_MODULE 1
+#undef CONFIG_RADIO_CADET
+#define CONFIG_RADIO_CADET_MODULE 1
+#undef CONFIG_RADIO_MIROPCM20
+#define CONFIG_RADIO_MIROPCM20_MODULE 1
+#undef CONFIG_RADIO_GEMTEK
+#define CONFIG_RADIO_GEMTEK_MODULE 1
+#undef CONFIG_RADIO_TRUST
+#define CONFIG_RADIO_TRUST_MODULE 1
+#undef CONFIG_VIDEO_BT848
+#define CONFIG_VIDEO_BT848_MODULE 1
+/*
+ * MSP3400 sound decoder support is in the section "additional
+ */
+/*
+ * low level sound drivers". You may need to enable it there.
+ */
+#undef CONFIG_VIDEO_BWQCAM
+#define CONFIG_VIDEO_BWQCAM_MODULE 1
+#undef CONFIG_VIDEO_CQCAM
+#define CONFIG_VIDEO_CQCAM_MODULE 1
+#undef CONFIG_VIDEO_CPIA
+#define CONFIG_VIDEO_CPIA_MODULE 1
+#undef CONFIG_VIDEO_CPIA_PP
+#define CONFIG_VIDEO_CPIA_PP_MODULE 1
+#undef CONFIG_VIDEO_CPIA_USB
+#define CONFIG_VIDEO_CPIA_USB_MODULE 1
+#undef CONFIG_VIDEO_PMS
+#define CONFIG_VIDEO_PMS_MODULE 1
+#undef CONFIG_VIDEO_SAA5249
+#define CONFIG_VIDEO_SAA5249_MODULE 1
+#undef CONFIG_RADIO_SF16FMI
+#define CONFIG_RADIO_SF16FMI_MODULE 1
+#undef CONFIG_RADIO_TYPHOON
+#define CONFIG_RADIO_TYPHOON_MODULE 1
+#define CONFIG_RADIO_TYPHOON_PROC_FS 1
+#undef CONFIG_RADIO_ZOLTRIX
+#define CONFIG_RADIO_ZOLTRIX_MODULE 1
+#undef CONFIG_VIDEO_ZORAN
+#define CONFIG_VIDEO_ZORAN_MODULE 1
+#undef CONFIG_VIDEO_BUZ
+#define CONFIG_VIDEO_BUZ_MODULE 1
+#undef CONFIG_DTLK
+#define CONFIG_DTLK_MODULE 1
+/*
+ * Ftape, the floppy tape device driver
+ */
+#undef CONFIG_FTAPE
+#define CONFIG_FTAPE_MODULE 1
+#undef CONFIG_ZFTAPE
+#define CONFIG_ZFTAPE_MODULE 1
+#define CONFIG_ZFT_DFLT_BLK_SZ (10240)
+/*
+ * The compressor will be built as a module only!
+ */
+#undef CONFIG_ZFT_COMPRESSOR
+#define CONFIG_ZFT_COMPRESSOR_MODULE 1
+#define CONFIG_FT_NR_BUFFERS (3)
+#define CONFIG_FT_PROC_FS 1
+#define CONFIG_FT_NORMAL_DEBUG 1
+#undef CONFIG_FT_FULL_DEBUG
+#undef CONFIG_FT_NO_TRACE
+#undef CONFIG_FT_NO_TRACE_AT_ALL
+/*
+ * Hardware configuration
+ */
+#define CONFIG_FT_STD_FDC 1
+#undef CONFIG_FT_MACH2
+#undef CONFIG_FT_PROBE_FC10
+#undef CONFIG_FT_ALT_FDC
+#define CONFIG_FT_FDC_THR (8)
+#define CONFIG_FT_FDC_MAX_RATE (2000)
+/*
+ * ONLY for DEC Alpha architectures
+ */
+#define CONFIG_FT_ALPHA_CLOCK (0)
+/*
+ * USB support
+ */
+#undef CONFIG_USB
+#define CONFIG_USB_MODULE 1
+#define CONFIG_USB_DEBUG 1
+/*
+ * Miscellaneous USB options
+ */
+#define CONFIG_USB_DEVICEFS 1
+#undef CONFIG_USB_BANDWIDTH
+/*
+ * USB Controllers
+ */
+#undef CONFIG_USB_UHCI
+#define CONFIG_USB_UHCI_MODULE 1
+#undef CONFIG_USB_UHCI_ALT
+#define CONFIG_USB_UHCI_ALT_MODULE 1
+#undef CONFIG_USB_OHCI
+#define CONFIG_USB_OHCI_MODULE 1
+/*
+ * USB Devices
+ */
+#undef CONFIG_USB_PRINTER
+#define CONFIG_USB_PRINTER_MODULE 1
+#undef CONFIG_USB_SCANNER
+#define CONFIG_USB_SCANNER_MODULE 1
+#undef CONFIG_USB_AUDIO
+#define CONFIG_USB_AUDIO_MODULE 1
+#undef CONFIG_USB_ACM
+#define CONFIG_USB_ACM_MODULE 1
+#undef CONFIG_USB_SERIAL
+#define CONFIG_USB_SERIAL_MODULE 1
+#define CONFIG_USB_SERIAL_GENERIC 1
+#define CONFIG_USB_SERIAL_VISOR 1
+#define CONFIG_USB_SERIAL_WHITEHEAT 1
+#define CONFIG_USB_SERIAL_FTDI_SIO 1
+#define CONFIG_USB_SERIAL_KEYSPAN_PDA 1
+#define CONFIG_USB_SERIAL_DIGI_ACCELEPORT 1
+#define CONFIG_USB_SERIAL_OMNINET 1
+#define CONFIG_USB_SERIAL_DEBUG 1
+#undef CONFIG_USB_IBMCAM
+#define CONFIG_USB_IBMCAM_MODULE 1
+#undef CONFIG_USB_OV511
+#define CONFIG_USB_OV511_MODULE 1
+#undef CONFIG_USB_DC2XX
+#define CONFIG_USB_DC2XX_MODULE 1
+#undef CONFIG_USB_MDC800
+#define CONFIG_USB_MDC800_MODULE 1
+#undef CONFIG_USB_STORAGE
+#define CONFIG_USB_STORAGE_MODULE 1
+#undef CONFIG_USB_STORAGE_DEBUG
+#undef CONFIG_USB_DABUSB
+#define CONFIG_USB_DABUSB_MODULE 1
+#undef CONFIG_USB_PLUSB
+#define CONFIG_USB_PLUSB_MODULE 1
+#undef CONFIG_USB_PEGASUS
+#define CONFIG_USB_PEGASUS_MODULE 1
+#undef CONFIG_USB_RIO500
+#define CONFIG_USB_RIO500_MODULE 1
+#undef CONFIG_USB_DSBR
+#define CONFIG_USB_DSBR_MODULE 1
+#undef CONFIG_USB_MICROTEK
+#define CONFIG_USB_MICROTEK_MODULE 1
+/*
+ * USB HID
+ */
+#undef CONFIG_USB_HID
+#define CONFIG_USB_HID_MODULE 1
+#undef CONFIG_USB_KBD
+#define CONFIG_USB_KBD_MODULE 1
+#undef CONFIG_USB_MOUSE
+#define CONFIG_USB_MOUSE_MODULE 1
+#undef CONFIG_USB_WACOM
+#define CONFIG_USB_WACOM_MODULE 1
+#undef CONFIG_USB_WMFORCE
+#define CONFIG_USB_WMFORCE_MODULE 1
+#undef CONFIG_INPUT_KEYBDEV
+#define CONFIG_INPUT_KEYBDEV_MODULE 1
+#undef CONFIG_INPUT_MOUSEDEV
+#define CONFIG_INPUT_MOUSEDEV_MODULE 1
+#define CONFIG_INPUT_MOUSEDEV_SCREEN_X (1024)
+#define CONFIG_INPUT_MOUSEDEV_SCREEN_Y (768)
+#undef CONFIG_INPUT_JOYDEV
+#define CONFIG_INPUT_JOYDEV_MODULE 1
+#undef CONFIG_INPUT_EVDEV
+#define CONFIG_INPUT_EVDEV_MODULE 1
+/*
+ * Filesystems
+ */
+#define CONFIG_QUOTA 1
+#define CONFIG_AUTOFS_FS 1
+#undef CONFIG_ADFS_FS
+#define CONFIG_ADFS_FS_MODULE 1
+#undef CONFIG_AFFS_FS
+#define CONFIG_AFFS_FS_MODULE 1
+#undef CONFIG_HFS_FS
+#define CONFIG_HFS_FS_MODULE 1
+#undef CONFIG_FAT_FS
+#define CONFIG_FAT_FS_MODULE 1
+#undef CONFIG_MSDOS_FS
+#define CONFIG_MSDOS_FS_MODULE 1
+#undef CONFIG_UMSDOS_FS
+#define CONFIG_UMSDOS_FS_MODULE 1
+#undef CONFIG_VFAT_FS
+#define CONFIG_VFAT_FS_MODULE 1
+#define CONFIG_ISO9660_FS 1
+#define CONFIG_JOLIET 1
+#undef CONFIG_MINIX_FS
+#define CONFIG_MINIX_FS_MODULE 1
+#undef CONFIG_NTFS_FS
+#define CONFIG_NTFS_FS_MODULE 1
+#undef CONFIG_NTFS_RW
+#undef CONFIG_HPFS_FS
+#define CONFIG_HPFS_FS_MODULE 1
+#define CONFIG_PROC_FS 1
+#define CONFIG_DEVPTS_FS 1
+#undef CONFIG_QNX4FS_FS
+#define CONFIG_QNX4FS_FS_MODULE 1
+#undef CONFIG_QNX4FS_RW
+#undef CONFIG_ROMFS_FS
+#define CONFIG_ROMFS_FS_MODULE 1
+#define CONFIG_EXT2_FS 1
+#undef CONFIG_SYSV_FS
+#define CONFIG_SYSV_FS_MODULE 1
+#undef CONFIG_UFS_FS
+#define CONFIG_UFS_FS_MODULE 1
+#undef CONFIG_UFS_FS_WRITE
+#define CONFIG_REISERFS_FS 1
+#undef CONFIG_REISERFS_CHECK
+#undef CONFIG_EFS_FS
+#define CONFIG_EFS_FS_MODULE 1
+#define CONFIG_SGI_PARTITION 1
+/*
+ * Network File Systems
+ */
+#undef CONFIG_CODA_FS
+#define CONFIG_CODA_FS_MODULE 1
+#define CONFIG_NFS_FS 1
+#define CONFIG_ROOT_NFS 1
+#undef CONFIG_NFSD
+#define CONFIG_NFSD_MODULE 1
+#undef CONFIG_NFSD_SUN
+#define CONFIG_SUNRPC 1
+#define CONFIG_LOCKD 1
+#undef CONFIG_SMB_FS
+#define CONFIG_SMB_FS_MODULE 1
+#undef CONFIG_NCP_FS
+#define CONFIG_NCP_FS_MODULE 1
+#define CONFIG_NCPFS_PACKET_SIGNING 1
+#define CONFIG_NCPFS_IOCTL_LOCKING 1
+#define CONFIG_NCPFS_STRONG 1
+#define CONFIG_NCPFS_NFS_NS 1
+#define CONFIG_NCPFS_OS2_NS 1
+#define CONFIG_NCPFS_SMALLDOS 1
+#define CONFIG_NCPFS_MOUNT_SUBDIR 1
+#define CONFIG_NCPFS_NLS 1
+#define CONFIG_NCPFS_EXTRAS 1
+/*
+ * Partition Types
+ */
+#define CONFIG_BSD_DISKLABEL 1
+#define CONFIG_MAC_PARTITION 1
+#define CONFIG_SMD_DISKLABEL 1
+#define CONFIG_SOLARIS_X86_PARTITION 1
+#define CONFIG_UNIXWARE_DISKLABEL 1
+#define CONFIG_AMIGA_PARTITION 1
+#define CONFIG_NLS 1
+/*
+ * Native Language Support
+ */
+#define CONFIG_NLS_DEFAULT "cp437"
+#undef CONFIG_NLS_CODEPAGE_437
+#define CONFIG_NLS_CODEPAGE_437_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_737
+#define CONFIG_NLS_CODEPAGE_737_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_775
+#define CONFIG_NLS_CODEPAGE_775_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_850
+#define CONFIG_NLS_CODEPAGE_850_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_852
+#define CONFIG_NLS_CODEPAGE_852_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_855
+#define CONFIG_NLS_CODEPAGE_855_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_857
+#define CONFIG_NLS_CODEPAGE_857_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_860
+#define CONFIG_NLS_CODEPAGE_860_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_861
+#define CONFIG_NLS_CODEPAGE_861_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_862
+#define CONFIG_NLS_CODEPAGE_862_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_863
+#define CONFIG_NLS_CODEPAGE_863_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_864
+#define CONFIG_NLS_CODEPAGE_864_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_865
+#define CONFIG_NLS_CODEPAGE_865_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_866
+#define CONFIG_NLS_CODEPAGE_866_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_869
+#define CONFIG_NLS_CODEPAGE_869_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_874
+#define CONFIG_NLS_CODEPAGE_874_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_932
+#define CONFIG_NLS_CODEPAGE_932_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_936
+#define CONFIG_NLS_CODEPAGE_936_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_949
+#define CONFIG_NLS_CODEPAGE_949_MODULE 1
+#undef CONFIG_NLS_CODEPAGE_950
+#define CONFIG_NLS_CODEPAGE_950_MODULE 1
+#undef CONFIG_NLS_ISO8859_1
+#define CONFIG_NLS_ISO8859_1_MODULE 1
+#undef CONFIG_NLS_ISO8859_2
+#define CONFIG_NLS_ISO8859_2_MODULE 1
+#undef CONFIG_NLS_ISO8859_3
+#define CONFIG_NLS_ISO8859_3_MODULE 1
+#undef CONFIG_NLS_ISO8859_4
+#define CONFIG_NLS_ISO8859_4_MODULE 1
+#undef CONFIG_NLS_ISO8859_5
+#define CONFIG_NLS_ISO8859_5_MODULE 1
+#undef CONFIG_NLS_ISO8859_6
+#define CONFIG_NLS_ISO8859_6_MODULE 1
+#undef CONFIG_NLS_ISO8859_7
+#define CONFIG_NLS_ISO8859_7_MODULE 1
+#undef CONFIG_NLS_ISO8859_8
+#define CONFIG_NLS_ISO8859_8_MODULE 1
+#undef CONFIG_NLS_ISO8859_9
+#define CONFIG_NLS_ISO8859_9_MODULE 1
+#undef CONFIG_NLS_ISO8859_14
+#define CONFIG_NLS_ISO8859_14_MODULE 1
+#undef CONFIG_NLS_ISO8859_15
+#define CONFIG_NLS_ISO8859_15_MODULE 1
+#undef CONFIG_NLS_KOI8_R
+#define CONFIG_NLS_KOI8_R_MODULE 1
+/*
+ * Console drivers
+ */
+#define CONFIG_VGA_CONSOLE 1
+#define CONFIG_VIDEO_SELECT 1
+#undef CONFIG_MDA_CONSOLE
+#define CONFIG_MDA_CONSOLE_MODULE 1
+#define CONFIG_FB 1
+#define CONFIG_DUMMY_CONSOLE 1
+#define CONFIG_FB_PM2 1
+#undef CONFIG_FB_PM2_FIFO_DISCONNECT
+#undef CONFIG_FB_PM2_PCI
+#define CONFIG_FB_ATY 1
+#define CONFIG_FB_VESA 1
+#undef CONFIG_FB_VGA16
+#define CONFIG_VIDEO_SELECT 1
+#undef CONFIG_FB_MATROX
+#define CONFIG_FB_MATROX_MODULE 1
+#define CONFIG_FB_MATROX_MILLENIUM 1
+#define CONFIG_FB_MATROX_MYSTIQUE 1
+#define CONFIG_FB_MATROX_G100 1
+#define CONFIG_FB_MATROX_MULTIHEAD 1
+#undef CONFIG_FB_ATY128
+#undef CONFIG_FB_VIRTUAL
+#define CONFIG_FB_VIRTUAL_MODULE 1
+#define CONFIG_FBCON_ADVANCED 1
+#define CONFIG_FBCON_MFB 1
+#define CONFIG_FBCON_CFB2 1
+#define CONFIG_FBCON_CFB4 1
+#define CONFIG_FBCON_CFB8 1
+#define CONFIG_FBCON_CFB16 1
+#define CONFIG_FBCON_CFB24 1
+#define CONFIG_FBCON_CFB32 1
+#undef CONFIG_FBCON_AFB
+#undef CONFIG_FBCON_ILBM
+#undef CONFIG_FBCON_IPLAN2P2
+#undef CONFIG_FBCON_IPLAN2P4
+#undef CONFIG_FBCON_IPLAN2P8
+#undef CONFIG_FBCON_MAC
+#undef CONFIG_FBCON_VGA_PLANES
+#undef CONFIG_FBCON_VGA
+#define CONFIG_FBCON_VGA_MODULE 1
+#define CONFIG_FBCON_FONTWIDTH8_ONLY 1
+#define CONFIG_FBCON_FONTS 1
+#define CONFIG_FONT_8x8 1
+#define CONFIG_FONT_8x16 1
+#undef CONFIG_FONT_SUN8x16
+#undef CONFIG_FONT_PEARL_8x8
+#undef CONFIG_FONT_ACORN_8x8
+/*
+ * Sound
+ */
+#undef CONFIG_SOUND
+#define CONFIG_SOUND_MODULE 1
+#undef CONFIG_SOUND_CMPCI
+#define CONFIG_SOUND_CMPCI_MODULE 1
+#define CONFIG_SOUND_CMPCI_FM 1
+#define CONFIG_SOUND_CMPCI_MIDI 1
+#undef CONFIG_SOUND_CS4281
+#define CONFIG_SOUND_CS4281_MODULE 1
+#undef CONFIG_SOUND_FUSION
+#define CONFIG_SOUND_FUSION_MODULE 1
+#undef CONFIG_SOUND_EMU10K1
+#define CONFIG_SOUND_EMU10K1_MODULE 1
+#undef CONFIG_SOUND_ES1370
+#define CONFIG_SOUND_ES1370_MODULE 1
+#undef CONFIG_SOUND_ES1371
+#define CONFIG_SOUND_ES1371_MODULE 1
+#undef CONFIG_SOUND_MAESTRO
+#define CONFIG_SOUND_MAESTRO_MODULE 1
+#undef CONFIG_SOUND_ESSSOLO1
+#define CONFIG_SOUND_ESSSOLO1_MODULE 1
+#undef CONFIG_SOUND_ICH
+#define CONFIG_SOUND_ICH_MODULE 1
+#undef CONFIG_SOUND_SONICVIBES
+#define CONFIG_SOUND_SONICVIBES_MODULE 1
+#undef CONFIG_SOUND_TRIDENT
+#define CONFIG_SOUND_TRIDENT_MODULE 1
+#undef CONFIG_SOUND_MSNDCLAS
+#define CONFIG_SOUND_MSNDCLAS_MODULE 1
+#undef CONFIG_MSNDCLAS_HAVE_BOOT
+#define CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin"
+#define CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin"
+#undef CONFIG_SOUND_MSNDPIN
+#define CONFIG_SOUND_MSNDPIN_MODULE 1
+#undef CONFIG_MSNDPIN_HAVE_BOOT
+#define CONFIG_MSNDPIN_INIT_FILE "/etc/sound/pndspini.bin"
+#define CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin"
+#undef CONFIG_SOUND_OSS
+#define CONFIG_SOUND_OSS_MODULE 1
+#undef CONFIG_SOUND_PAS
+#define CONFIG_SOUND_PAS_MODULE 1
+#undef CONFIG_SOUND_SB
+#define CONFIG_SOUND_SB_MODULE 1
+#undef CONFIG_SOUND_GUS
+#define CONFIG_SOUND_GUS_MODULE 1
+#define CONFIG_GUS16 1
+#define CONFIG_GUSMAX 1
+#undef CONFIG_SOUND_MPU401
+#define CONFIG_SOUND_MPU401_MODULE 1
+#undef CONFIG_SOUND_PSS
+#define CONFIG_SOUND_PSS_MODULE 1
+#define CONFIG_PSS_MIXER 1
+#undef CONFIG_SOUND_MSS
+#define CONFIG_SOUND_MSS_MODULE 1
+#undef CONFIG_SOUND_SSCAPE
+#define CONFIG_SOUND_SSCAPE_MODULE 1
+#undef CONFIG_SOUND_TRIX
+#define CONFIG_SOUND_TRIX_MODULE 1
+#undef CONFIG_SOUND_VIA82CXXX
+#define CONFIG_SOUND_VIA82CXXX_MODULE 1
+#undef CONFIG_SOUND_MAD16
+#define CONFIG_SOUND_MAD16_MODULE 1
+#define CONFIG_MAD16_OLDCARD 1
+#undef CONFIG_SOUND_WAVEFRONT
+#define CONFIG_SOUND_WAVEFRONT_MODULE 1
+#undef CONFIG_SOUND_CS4232
+#define CONFIG_SOUND_CS4232_MODULE 1
+#undef CONFIG_SOUND_OPL3SA2
+#define CONFIG_SOUND_OPL3SA2_MODULE 1
+#undef CONFIG_SOUND_MAUI
+#define CONFIG_SOUND_MAUI_MODULE 1
+#undef CONFIG_SOUND_SGALAXY
+#define CONFIG_SOUND_SGALAXY_MODULE 1
+#undef CONFIG_SOUND_AD1816
+#define CONFIG_SOUND_AD1816_MODULE 1
+#undef CONFIG_SOUND_OPL3SA1
+#define CONFIG_SOUND_OPL3SA1_MODULE 1
+#undef CONFIG_SOUND_SOFTOSS
+#define CONFIG_SOUND_SOFTOSS_MODULE 1
+#undef CONFIG_SOUND_YM3812
+#define CONFIG_SOUND_YM3812_MODULE 1
+#undef CONFIG_SOUND_VMIDI
+#define CONFIG_SOUND_VMIDI_MODULE 1
+#undef CONFIG_SOUND_UART6850
+#define CONFIG_SOUND_UART6850_MODULE 1
+#undef CONFIG_SOUND_NM256
+#define CONFIG_SOUND_NM256_MODULE 1
+#undef CONFIG_SOUND_YMPCI
+#define CONFIG_SOUND_YMPCI_MODULE 1
+/*
+ * Additional low level sound drivers
+ */
+#define CONFIG_LOWLEVEL_SOUND 1
+#undef CONFIG_ACI_MIXER
+#define CONFIG_ACI_MIXER_MODULE 1
+#undef CONFIG_VIDEO_MSP3400
+#define CONFIG_VIDEO_MSP3400_MODULE 1
+#undef CONFIG_AWE32_SYNTH
+#define CONFIG_AWE32_SYNTH_MODULE 1
+#undef CONFIG_AEDSP16
+#define CONFIG_AEDSP16_MODULE 1
+#define CONFIG_AEDSP16_BASE 0x220
+#define CONFIG_MPU_BASE 0x330
+/*
+ * SC-6600 Audio Cards have no jumper switches at all
+ */
+#define CONFIG_SC6600 1
+/*
+ * SC-6600 specific configuration
+ */
+#define CONFIG_SC6600_JOY 1
+#define CONFIG_SC6600_CDROM (4)
+#define CONFIG_SC6600_CDROMBASE 0x0
+#define CONFIG_AEDSP16_SBPRO 1
+/*
+ * Audio Excel DSP 16 [Sound Blaster Pro]
+ */
+#define CONFIG_AEDSP16_BASE 0x220
+#define CONFIG_AEDSP16_SB_IRQ (5)
+#define CONFIG_AEDSP16_SB_DMA (0)
+#define CONFIG_AEDSP16_MPU401 1
+/*
+ * Audio Excel DSP 16 [MPU-401]
+ */
+#define CONFIG_AEDSP16_MPU_IRQ (0)
+/*
+ * Kernel hacking
+ */
+#undef CONFIG_MAGIC_SYSRQ
diff --git a/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.config b/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.config
new file mode 100644
index 000000000000..7b7e64184ea8
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.config
@@ -0,0 +1,1320 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Processor type and features
+#
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+CONFIG_M586TSC=y
+# CONFIG_M686 is not set
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_TSC=y
+CONFIG_1GB=y
+# CONFIG_2GB is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_SMP is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_PCI_OPTIMIZE=y
+CONFIG_PCI_OLD_PROC=y
+# CONFIG_MCA is not set
+# CONFIG_VISWS is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_BINFMT_JAVA is not set
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+# CONFIG_APM_CPU_IDLE is not set
+# CONFIG_APM_DISPLAY_BLANK is not set
+# CONFIG_APM_IGNORE_SUSPEND_BOUNCE is not set
+# CONFIG_APM_RTC_IS_GMT is not set
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+# CONFIG_TOSHIBA is not set
+
+#
+# Crypto options
+#
+CONFIG_CRYPTO=y
+CONFIG_CIPHERS=m
+CONFIG_CIPHER_AES=m
+# CONFIG_CIPHER_RIJNDAEL is not set
+
+#
+# AES Finalist Ciphers (128 bit blocksize)
+#
+CONFIG_CIPHER_TWOFISH=m
+CONFIG_CIPHER_MARS=m
+CONFIG_CIPHER_RC6=m
+CONFIG_CIPHER_SERPENT=m
+
+#
+# Other Ciphers submitted as AES Candidates:
+#
+CONFIG_CIPHER_DFC=m
+
+#
+# Other ciphers (64 bit blocksize)
+#
+CONFIG_CIPHER_BLOWFISH=m
+CONFIG_CIPHER_IDEA=m
+CONFIG_CIPHER_RC5=m
+CONFIG_CIPHER_DES_EDE3=m
+CONFIG_CIPHER_DES=m
+CONFIG_DIGEST=m
+CONFIG_DIGEST_MD5=m
+CONFIG_DIGEST_SHA1=m
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+CONFIG_PNP_PARPORT=m
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL_DEBUG is not set
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+CONFIG_BLK_DEV_AMD7409=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_PIIX_TUNING=y
+CONFIG_BLK_DEV_OPTI621=y
+CONFIG_BLK_DEV_PDC202XX=y
+CONFIG_PDC202XX_BURST=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_TRM290=y
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_IDE_CHIPSETS=y
+
+#
+# Note: most of these also require special kernel boot parameters
+#
+CONFIG_BLK_DEV_4DRIVES=y
+CONFIG_BLK_DEV_ALI14XX=y
+CONFIG_BLK_DEV_DTC2278=y
+CONFIG_BLK_DEV_HT6560B=y
+CONFIG_BLK_DEV_PDC4030=y
+CONFIG_BLK_DEV_QD6580=y
+CONFIG_BLK_DEV_UMC8672=y
+# CONFIG_IDEDMA_IVB is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LVM=m
+CONFIG_LVM_PROC_FS=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_LOOP_USE_REL_BLOCK is not set
+CONFIG_BLK_DEV_LOOP_GEN_SEL="2"
+CONFIG_BLK_DEV_LOOP_GEN=m
+# CONFIG_BLK_DEV_LOOP_CAST is not set
+# CONFIG_BLK_DEV_LOOP_FISH2 is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_MD=y
+CONFIG_AUTODETECT_RAID=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_STRIPED=m
+CONFIG_MD_MIRRORING=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_TRANSLUCENT=y
+# CONFIG_MD_HSM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_XD=m
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_PARIDE_PARPORT=m
+CONFIG_PARIDE=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_IDE_MODES=y
+CONFIG_BLK_CPQ_DA=m
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_CIPE is not set
+CONFIG_PACKET=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_FIREWALL=y
+# CONFIG_NET_SECURITY is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_LARGE_TABLES=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_FIREWALL=y
+CONFIG_IP_FIREWALL_NETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_TRANSPARENT_PROXY=y
+CONFIG_IP_MASQUERADE=y
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+CONFIG_IP_MASQUERADE_ICMP=y
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+CONFIG_IP_MASQUERADE_MOD=y
+CONFIG_IP_MASQUERADE_IPAUTOFW=m
+CONFIG_IP_MASQUERADE_IPPORTFW=m
+CONFIG_IP_MASQUERADE_MFW=m
+# CONFIG_IP_ROUTER is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_IP_ALIAS is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_RARP is not set
+CONFIG_SKB_LARGE=y
+CONFIG_IPV6=m
+# CONFIG_IPV6_EUI64 is not set
+
+#
+#
+#
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_SPX=m
+CONFIG_ATALK=m
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+CONFIG_ECONET=m
+# CONFIG_ECONET_AUNUDP is not set
+# CONFIG_ECONET_NATIVE is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Telephony Support
+#
+CONFIG_PHONE=m
+CONFIG_PHONE_IXJ=m
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_7000FASST=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AHA1740=m
+CONFIG_SCSI_AIC7XXX=m
+# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+# CONFIG_AIC7XXX_PROC_STATS is not set
+CONFIG_AIC7XXX_RESET_DELAY=5
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_AM53C974=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_BUSLOGIC=m
+CONFIG_SCSI_OMIT_FLASHPOINT=y
+CONFIG_SCSI_DTC3280=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_EATA_DMA=m
+CONFIG_SCSI_EATA_PIO=m
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_GENERIC_NCR5380=m
+CONFIG_SCSI_GENERIC_NCR53C400=y
+CONFIG_SCSI_G_NCR5380_PORT=y
+# CONFIG_SCSI_G_NCR5380_MEM is not set
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+CONFIG_SCSI_IZIP_EPP16=y
+CONFIG_SCSI_IZIP_SLOW_CTR=y
+CONFIG_SCSI_NCR53C406A=m
+CONFIG_SCSI_SYM53C416=m
+CONFIG_SCSI_SIM710=m
+CONFIG_SCSI_NCR53C7xx=m
+# CONFIG_SCSI_NCR53C7xx_sync is not set
+CONFIG_SCSI_NCR53C7xx_FAST=y
+CONFIG_SCSI_NCR53C7xx_DISCONNECT=y
+CONFIG_SCSI_NCR53C8XX=m
+CONFIG_SCSI_SYM53C8XX=m
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+CONFIG_SCSI_NCR53C8XX_PROFILE=y
+CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
+CONFIG_SCSI_NCR53C8XX_PQS_PDS=y
+CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT=y
+CONFIG_SCSI_PAS16=m
+CONFIG_SCSI_PCI2000=m
+CONFIG_SCSI_PCI2220I=m
+CONFIG_SCSI_PSI240I=m
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+CONFIG_SCSI_QLOGIC_FC=m
+CONFIG_SCSI_SEAGATE=m
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_DC390T_NOGENSUPP=y
+CONFIG_SCSI_T128=m
+CONFIG_SCSI_U14_34F=m
+CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y
+CONFIG_SCSI_U14_34F_MAX_TAGS=8
+CONFIG_SCSI_ULTRASTOR=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_PCI=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+CONFIG_ARCNET=m
+CONFIG_ARCNET_ETH=y
+CONFIG_ARCNET_1051=y
+CONFIG_ARCNET_COM90xx=m
+CONFIG_ARCNET_COM90xxIO=m
+CONFIG_ARCNET_RIM_I=m
+CONFIG_ARCNET_COM20020=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+CONFIG_PPPOX=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_VORTEX=m
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+CONFIG_ULTRA=m
+CONFIG_ULTRA32=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+CONFIG_NI5010=m
+CONFIG_NI52=m
+CONFIG_NI65=m
+CONFIG_RTL8139=m
+CONFIG_NET_ISA=y
+CONFIG_AT1700=m
+CONFIG_E2100=m
+CONFIG_DEPCA=m
+CONFIG_EWRK3=m
+CONFIG_EEXPRESS=m
+CONFIG_EEXPRESS_PRO=m
+CONFIG_FMV18X=m
+CONFIG_HPLAN_PLUS=m
+CONFIG_HPLAN=m
+CONFIG_HP100=m
+CONFIG_ETH16I=m
+CONFIG_NE2000=m
+CONFIG_SEEQ8005=m
+CONFIG_SK_G16=y
+CONFIG_NET_EISA=y
+CONFIG_PCNET32=m
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_CS89x0=m
+CONFIG_DM9102=m
+CONFIG_DE4X5=m
+CONFIG_DEC_ELCP=m
+CONFIG_DEC_ELCP_OLD=m
+CONFIG_DGRS=m
+CONFIG_EEXPRESS_PRO100=y
+CONFIG_LNE390=m
+CONFIG_NE3210=m
+CONFIG_NE2K_PCI=m
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_SIS900=m
+CONFIG_ES3210=m
+CONFIG_EPIC100=m
+CONFIG_ZNET=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_SK98LIN=m
+CONFIG_FDDI=y
+CONFIG_DEFXX=y
+CONFIG_HIPPI=y
+CONFIG_ROADRUNNER=m
+# CONFIG_ROADRUNNER_LARGE_RINGS is not set
+
+#
+# Appletalk devices
+#
+CONFIG_LTPC=m
+CONFIG_COPS=m
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+CONFIG_IPDDP=m
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_RADIO=y
+CONFIG_STRIP=m
+CONFIG_WAVELAN=m
+CONFIG_ARLAN=m
+
+#
+# Token ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMTR=m
+CONFIG_IBMLS=m
+CONFIG_IBMOL=m
+CONFIG_SKTR=m
+CONFIG_NET_FC=y
+CONFIG_IPHASE5526=m
+CONFIG_RCPCI=m
+CONFIG_SHAPER=m
+
+#
+# Wan interfaces
+#
+CONFIG_HOSTESS_SV11=m
+CONFIG_COSA=m
+CONFIG_SEALEVEL_4021=m
+CONFIG_SYNCLINK_SYNCPPP=m
+CONFIG_LANMEDIA=m
+CONFIG_COMX=m
+CONFIG_COMX_HW_COMX=m
+CONFIG_COMX_HW_LOCOMX=m
+CONFIG_COMX_HW_MIXCOM=m
+CONFIG_COMX_PROTO_PPP=m
+CONFIG_COMX_PROTO_LAPB=m
+CONFIG_COMX_PROTO_FR=m
+CONFIG_HDLC=m
+CONFIG_N2=m
+CONFIG_C101=m
+CONFIG_WANXL=m
+CONFIG_PC300=m
+# CONFIG_PC300_X25 is not set
+CONFIG_DLCI=m
+CONFIG_DLCI_COUNT=24
+CONFIG_DLCI_MAX=8
+CONFIG_SDLA=m
+CONFIG_WAN_DRIVERS=y
+CONFIG_VENDOR_SANGOMA=m
+CONFIG_WANPIPE_CARDS=1
+CONFIG_WANPIPE_FR=y
+CONFIG_WANPIPE_PPP=y
+CONFIG_WANPIPE_CHDLC=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+CONFIG_SBNI=m
+
+#
+# Amateur Radio support
+#
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_DMASCC=m
+CONFIG_SCC=m
+# CONFIG_SCC_DELAY is not set
+# CONFIG_SCC_TRXECHO is not set
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_BAYCOM_PAR=m
+CONFIG_BAYCOM_EPP=m
+CONFIG_SOUNDMODEM=m
+CONFIG_SOUNDMODEM_SBC=y
+CONFIG_SOUNDMODEM_WSS=y
+CONFIG_SOUNDMODEM_AFSK1200=y
+CONFIG_SOUNDMODEM_AFSK2400_7=y
+CONFIG_SOUNDMODEM_AFSK2400_8=y
+CONFIG_SOUNDMODEM_AFSK2666=y
+CONFIG_SOUNDMODEM_HAPN4800=y
+CONFIG_SOUNDMODEM_PSK4800=y
+CONFIG_SOUNDMODEM_FSK9600=y
+CONFIG_YAM=m
+
+#
+# Misc. hamradio protocols
+#
+# CONFIG_HFMODEM is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_OPTIONS=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+CONFIG_IRDA_COMPRESSION=y
+
+#
+# IrDA compressors
+#
+CONFIG_IRDA_DEFLATE=m
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_IRPORT_SIR=m
+
+#
+# FIR device drivers
+#
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+CONFIG_ISDN_X25=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=y
+
+#
+# low-level hardware drivers
+#
+
+#
+# Passive ISDN cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+# CONFIG_HISAX_NO_SENDCOMPLETE is not set
+# CONFIG_HISAX_NO_LLC is not set
+# CONFIG_HISAX_NO_KEYPAD is not set
+# CONFIG_HISAX_1TR6 is not set
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+
+#
+# Active ISDN cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+CONFIG_ISDN_DRV_SC=m
+CONFIG_ISDN_DRV_ACT2000=m
+CONFIG_ISDN_DRV_EICON=m
+CONFIG_ISDN_DRV_EICON_ISA=y
+CONFIG_ISDN_DRV_AVMB1=m
+CONFIG_ISDN_DRV_AVMB1_B1ISA=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=y
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=y
+CONFIG_ISDN_DRV_AVMB1_T1PCI=y
+CONFIG_ISDN_DRV_AVMB1_C4=y
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+CONFIG_CD_NO_IDESCSI=y
+CONFIG_AZTCD=m
+CONFIG_GSCD=m
+CONFIG_SBPCD=m
+CONFIG_MCD=m
+CONFIG_MCD_IRQ=11
+CONFIG_MCD_BASE=300
+CONFIG_MCDX=m
+CONFIG_OPTCD=m
+CONFIG_CM206=m
+CONFIG_SJCD=m
+CONFIG_ISP16_CDI=m
+CONFIG_CDU31A=m
+CONFIG_CDU535=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_COMPUTONE=m
+CONFIG_ROCKETPORT=m
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+CONFIG_DIGIEPCA=m
+CONFIG_ESPSERIAL=m
+CONFIG_MOXA_INTELLIO=m
+CONFIG_MOXA_SMARTIO=m
+CONFIG_ISI=m
+CONFIG_RISCOM8=m
+CONFIG_SPECIALIX=m
+CONFIG_SPECIALIX_RTSCTS=y
+CONFIG_SX=m
+CONFIG_RIO=m
+CONFIG_RIO_OLDPCI=y
+CONFIG_STALDRV=y
+CONFIG_STALLION=m
+CONFIG_ISTALLION=m
+CONFIG_SYNCLINK=m
+CONFIG_N_HDLC=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_PRINTER=m
+CONFIG_PRINTER_READBACK=y
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+CONFIG_ATIXL_BUSMOUSE=m
+CONFIG_BUSMOUSE=m
+CONFIG_MS_BUSMOUSE=m
+CONFIG_PSMOUSE=y
+CONFIG_82C710_MOUSE=y
+CONFIG_PC110_PAD=m
+
+#
+# Joysticks
+#
+CONFIG_JOYSTICK=m
+CONFIG_JOY_ANALOG=m
+CONFIG_JOY_ASSASSIN=m
+CONFIG_JOY_GRAVIS=m
+CONFIG_JOY_LOGITECH=m
+CONFIG_JOY_SIDEWINDER=m
+CONFIG_JOY_THRUSTMASTER=m
+CONFIG_JOY_CREATIVE=m
+CONFIG_JOY_LIGHTNING=m
+CONFIG_JOY_PCI=m
+CONFIG_JOY_MAGELLAN=m
+CONFIG_JOY_SPACEORB=m
+CONFIG_JOY_SPACEBALL=m
+CONFIG_JOY_WARRIOR=m
+CONFIG_JOY_CONSOLE=m
+CONFIG_JOY_DB9=m
+CONFIG_JOY_TURBOGRAFX=m
+CONFIG_QIC02_TAPE=m
+CONFIG_QIC02_DYNCONF=y
+
+#
+# Setting runtime QIC-02 configuration is done with qic02conf
+#
+
+#
+# from the tpqic02-support package. It is available at
+#
+
+#
+# metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/
+#
+CONFIG_AGP=m
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_I810=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_ALI=y
+CONFIG_WATCHDOG=y
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_WDT=m
+CONFIG_WDT_501=y
+CONFIG_WDT_501_FAN=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_PCWATCHDOG=m
+CONFIG_ACQUIRE_WDT=m
+CONFIG_60XX_WDT=m
+CONFIG_MIXCOMWD=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_PHILIPSPAR=m
+CONFIG_I2C_ELV=m
+CONFIG_I2C_VELLEMAN=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ELEKTOR=m
+CONFIG_I2C_MAINBOARD=y
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_HYDRA=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# Hardware sensors support
+#
+CONFIG_SENSORS=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_OTHER=y
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_LTC1710=m
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_MIROPCM20=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_TRUST=m
+CONFIG_VIDEO_BT848=m
+
+#
+# MSP3400 sound decoder support is in the section "additional
+#
+
+#
+# low level sound drivers". You may need to enable it there.
+#
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_BUZ=m
+CONFIG_DTLK=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_FTAPE=m
+CONFIG_ZFTAPE=m
+CONFIG_ZFT_DFLT_BLK_SZ=10240
+
+#
+# The compressor will be built as a module only!
+#
+CONFIG_ZFT_COMPRESSOR=m
+CONFIG_FT_NR_BUFFERS=3
+CONFIG_FT_PROC_FS=y
+CONFIG_FT_NORMAL_DEBUG=y
+# CONFIG_FT_FULL_DEBUG is not set
+# CONFIG_FT_NO_TRACE is not set
+# CONFIG_FT_NO_TRACE_AT_ALL is not set
+
+#
+# Hardware configuration
+#
+CONFIG_FT_STD_FDC=y
+# CONFIG_FT_MACH2 is not set
+# CONFIG_FT_PROBE_FC10 is not set
+# CONFIG_FT_ALT_FDC is not set
+CONFIG_FT_FDC_THR=8
+CONFIG_FT_FDC_MAX_RATE=2000
+
+#
+# ONLY for DEC Alpha architectures
+#
+CONFIG_FT_ALPHA_CLOCK=0
+
+#
+# USB support
+#
+CONFIG_USB=m
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Controllers
+#
+CONFIG_USB_UHCI=m
+CONFIG_USB_UHCI_ALT=m
+CONFIG_USB_OHCI=m
+
+#
+# USB Devices
+#
+CONFIG_USB_PRINTER=m
+CONFIG_USB_SCANNER=m
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ACM=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_VISOR=y
+CONFIG_USB_SERIAL_WHITEHEAT=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_KEYSPAN_PDA=y
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=y
+CONFIG_USB_SERIAL_OMNINET=y
+CONFIG_USB_SERIAL_DEBUG=y
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_OV511=m
+CONFIG_USB_DC2XX=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_DABUSB=m
+CONFIG_USB_PLUSB=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB HID
+#
+CONFIG_USB_HID=m
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_WMFORCE=m
+CONFIG_INPUT_KEYBDEV=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+
+#
+# Filesystems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_UMSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_MINIX_FS=m
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_RW is not set
+CONFIG_HPFS_FS=m
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=m
+CONFIG_EXT2_FS=y
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_EFS_FS=m
+CONFIG_SGI_PARTITION=y
+
+#
+# Network File Systems
+#
+CONFIG_CODA_FS=m
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_SMB_FS=m
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_MOUNT_SUBDIR=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+
+#
+# Partition Types
+#
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MAC_PARTITION=y
+CONFIG_SMD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+
+#
+# Console drivers
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VIDEO_SELECT=y
+CONFIG_MDA_CONSOLE=m
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_PM2=y
+# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
+# CONFIG_FB_PM2_PCI is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_VESA=y
+# CONFIG_FB_VGA16 is not set
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_ATY128 is not set
+CONFIG_FB_VIRTUAL=m
+CONFIG_FBCON_ADVANCED=y
+CONFIG_FBCON_MFB=y
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+CONFIG_FBCON_VGA=m
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+CONFIG_SOUND_CMPCI=m
+CONFIG_SOUND_CMPCI_FM=y
+CONFIG_SOUND_CMPCI_MIDI=y
+CONFIG_SOUND_CS4281=m
+CONFIG_SOUND_FUSION=m
+CONFIG_SOUND_EMU10K1=m
+CONFIG_SOUND_ES1370=m
+CONFIG_SOUND_ES1371=m
+CONFIG_SOUND_MAESTRO=m
+CONFIG_SOUND_ESSSOLO1=m
+CONFIG_SOUND_ICH=m
+CONFIG_SOUND_SONICVIBES=m
+CONFIG_SOUND_TRIDENT=m
+CONFIG_SOUND_MSNDCLAS=m
+# CONFIG_MSNDCLAS_HAVE_BOOT is not set
+CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin"
+CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin"
+CONFIG_SOUND_MSNDPIN=m
+# CONFIG_MSNDPIN_HAVE_BOOT is not set
+CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin"
+CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin"
+CONFIG_SOUND_OSS=m
+CONFIG_SOUND_PAS=m
+CONFIG_SOUND_SB=m
+CONFIG_SOUND_GUS=m
+CONFIG_GUS16=y
+CONFIG_GUSMAX=y
+CONFIG_SOUND_MPU401=m
+CONFIG_SOUND_PSS=m
+CONFIG_PSS_MIXER=y
+CONFIG_SOUND_MSS=m
+CONFIG_SOUND_SSCAPE=m
+CONFIG_SOUND_TRIX=m
+CONFIG_SOUND_VIA82CXXX=m
+CONFIG_SOUND_MAD16=m
+CONFIG_MAD16_OLDCARD=y
+CONFIG_SOUND_WAVEFRONT=m
+CONFIG_SOUND_CS4232=m
+CONFIG_SOUND_OPL3SA2=m
+CONFIG_SOUND_MAUI=m
+CONFIG_SOUND_SGALAXY=m
+CONFIG_SOUND_AD1816=m
+CONFIG_SOUND_OPL3SA1=m
+CONFIG_SOUND_SOFTOSS=m
+CONFIG_SOUND_YM3812=m
+CONFIG_SOUND_VMIDI=m
+CONFIG_SOUND_UART6850=m
+CONFIG_SOUND_NM256=m
+CONFIG_SOUND_YMPCI=m
+
+#
+# Additional low level sound drivers
+#
+CONFIG_LOWLEVEL_SOUND=y
+CONFIG_ACI_MIXER=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_AWE32_SYNTH=m
+CONFIG_AEDSP16=m
+CONFIG_AEDSP16_BASE=220
+CONFIG_MPU_BASE=330
+
+#
+# SC-6600 Audio Cards have no jumper switches at all
+#
+CONFIG_SC6600=y
+
+#
+# SC-6600 specific configuration
+#
+CONFIG_SC6600_JOY=y
+CONFIG_SC6600_CDROM=4
+CONFIG_SC6600_CDROMBASE=0
+CONFIG_AEDSP16_SBPRO=y
+
+#
+# Audio Excel DSP 16 [Sound Blaster Pro]
+#
+CONFIG_AEDSP16_BASE=220
+CONFIG_AEDSP16_SB_IRQ=5
+CONFIG_AEDSP16_SB_DMA=0
+CONFIG_AEDSP16_MPU401=y
+
+#
+# Audio Excel DSP 16 [MPU-401]
+#
+CONFIG_AEDSP16_MPU_IRQ=0
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
diff --git a/sys-kernel/linux-UP-2.2.17/files/ll_rw_blk.c b/sys-kernel/linux-UP-2.2.17/files/ll_rw_blk.c
new file mode 100644
index 000000000000..8e67d7fec034
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/files/ll_rw_blk.c
@@ -0,0 +1,1196 @@
+/*
+ * linux/drivers/block/ll_rw_blk.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994, Karl Keyte: Added support for disk statistics
+ * Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
+ */
+
+/*
+ * This handles all read/write requests to block devices
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/locks.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/blk.h>
+#include <linux/raid/md.h>
+
+#include <linux/module.h>
+
+#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
+#include <linux/lvm.h>
+ int ( *lvm_map_ptr) ( int, kdev_t *, unsigned long *,
+ unsigned long, int) = NULL;
+#endif
+
+/*
+ * The request-struct contains all necessary data
+ * to load a nr of sectors into memory
+ */
+static struct request all_requests[NR_REQUEST];
+
+/*
+ * The "disk" task queue is used to start the actual requests
+ * after a plug
+ */
+DECLARE_TASK_QUEUE(tq_disk);
+
+/*
+ * Protect the request list against multiple users..
+ *
+ * With this spinlock the Linux block IO subsystem is 100% SMP threaded
+ * from the IRQ event side, and almost 100% SMP threaded from the syscall
+ * side (we still have protect against block device array operations, and
+ * the do_request() side is casually still unsafe. The kernel lock protects
+ * this part currently.).
+ *
+ * there is a fair chance that things will work just OK if these functions
+ * are called with no global kernel lock held ...
+ */
+spinlock_t io_request_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * per-major idle-IO detection
+ */
+unsigned long io_events[MAX_BLKDEV] = {0, };
+
+/*
+ * used to wait on when there are no free requests
+ */
+struct wait_queue * wait_for_request;
+
+/* This specifies how many sectors to read ahead on the disk. */
+
+int read_ahead[MAX_BLKDEV];
+
+/* blk_dev_struct is:
+ * *request_fn
+ * *current_request
+ */
+struct blk_dev_struct blk_dev[MAX_BLKDEV]; /* initialized by blk_dev_init() */
+
+/*
+ * blk_size contains the size of all block-devices in units of 1024 byte
+ * sectors:
+ *
+ * blk_size[MAJOR][MINOR]
+ *
+ * if (!blk_size[MAJOR]) then no minor size checking is done.
+ */
+int * blk_size[MAX_BLKDEV];
+
+/*
+ * blksize_size contains the size of all block-devices:
+ *
+ * blksize_size[MAJOR][MINOR]
+ *
+ * if (!blksize_size[MAJOR]) then 1024 bytes is assumed.
+ */
+int * blksize_size[MAX_BLKDEV];
+
+/*
+ * hardsect_size contains the size of the hardware sector of a device.
+ *
+ * hardsect_size[MAJOR][MINOR]
+ *
+ * if (!hardsect_size[MAJOR])
+ * then 512 bytes is assumed.
+ * else
+ * sector_size is hardsect_size[MAJOR][MINOR]
+ * This is currently set by some scsi devices and read by the msdos fs driver.
+ * Other uses may appear later.
+ */
+int * hardsect_size[MAX_BLKDEV];
+
+/*
+ * The following tunes the read-ahead algorithm in mm/filemap.c
+ */
+int * max_readahead[MAX_BLKDEV];
+
+/*
+ * Max number of sectors per request
+ */
+int * max_sectors[MAX_BLKDEV];
+
+/*
+ * Max number of segments per request
+ */
+int * max_segments[MAX_BLKDEV];
+
+static inline int get_max_sectors(kdev_t dev)
+{
+ if (!max_sectors[MAJOR(dev)])
+ return MAX_SECTORS;
+ return max_sectors[MAJOR(dev)][MINOR(dev)];
+}
+
+static inline int get_max_segments(kdev_t dev)
+{
+ if (!max_segments[MAJOR(dev)])
+ return MAX_SEGMENTS;
+ return max_segments[MAJOR(dev)][MINOR(dev)];
+}
+
+/*
+ * Is called with the request spinlock aquired.
+ * NOTE: the device-specific queue() functions
+ * have to be atomic!
+ */
+static inline struct request **get_queue(kdev_t dev)
+{
+ int major = MAJOR(dev);
+ struct blk_dev_struct *bdev = blk_dev + major;
+
+ if (bdev->queue)
+ return bdev->queue(dev);
+ return &blk_dev[major].current_request;
+}
+
+static inline int get_request_latency(elevator_t * elevator, int rw)
+{
+ int latency;
+
+ latency = elevator->read_latency;
+ if (rw != READ)
+ latency = elevator->write_latency;
+
+ return latency;
+}
+
+/*
+ * remove the plug and let it rip..
+ */
+void unplug_device(void * data)
+{
+ struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
+ int queue_new_request=0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock,flags);
+ if (dev->current_request == &dev->plug) {
+ struct request * next = dev->plug.next;
+ dev->current_request = next;
+ if (next || dev->queue) {
+ dev->plug.next = NULL;
+ queue_new_request = 1;
+ }
+ }
+ if (queue_new_request)
+ (dev->request_fn)();
+
+ spin_unlock_irqrestore(&io_request_lock,flags);
+}
+
+/*
+ * "plug" the device if there are no outstanding requests: this will
+ * force the transfer to start only after we have put all the requests
+ * on the list.
+ *
+ * This is called with interrupts off and no requests on the queue.
+ * (and with the request spinlock aquired)
+ */
+static inline void plug_device(struct blk_dev_struct * dev)
+{
+ if (dev->current_request)
+ return;
+ dev->current_request = &dev->plug;
+ queue_task(&dev->plug_tq, &tq_disk);
+}
+
+/*
+ * look for a free request in the first N entries.
+ * NOTE: interrupts must be disabled on the way in (on SMP the request queue
+ * spinlock has to be aquired), and will still be disabled on the way out.
+ */
+static inline struct request * get_request(int n, kdev_t dev)
+{
+ static struct request *prev_found = NULL, *prev_limit = NULL;
+ register struct request *req, *limit;
+
+ if (n <= 0)
+ panic("get_request(%d): impossible!\n", n);
+
+ limit = all_requests + n;
+ if (limit != prev_limit) {
+ prev_limit = limit;
+ prev_found = all_requests;
+ }
+ req = prev_found;
+ for (;;) {
+ req = ((req > all_requests) ? req : limit) - 1;
+ if (req->rq_status == RQ_INACTIVE)
+ break;
+ if (req == prev_found)
+ return NULL;
+ }
+ prev_found = req;
+ req->rq_status = RQ_ACTIVE;
+ req->rq_dev = dev;
+ return req;
+}
+
+/*
+ * wait until a free request in the first N entries is available.
+ */
+static struct request * __get_request_wait(int n, kdev_t dev)
+{
+ register struct request *req;
+ struct wait_queue wait = { current, NULL };
+ unsigned long flags;
+
+ add_wait_queue(&wait_for_request, &wait);
+ for (;;) {
+ current->state = TASK_UNINTERRUPTIBLE;
+ spin_lock_irqsave(&io_request_lock,flags);
+ req = get_request(n, dev);
+ spin_unlock_irqrestore(&io_request_lock,flags);
+ if (req)
+ break;
+ run_task_queue(&tq_disk);
+ schedule();
+ }
+ remove_wait_queue(&wait_for_request, &wait);
+ current->state = TASK_RUNNING;
+ return req;
+}
+
+static inline struct request * get_request_wait(int n, kdev_t dev)
+{
+ register struct request *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock,flags);
+ req = get_request(n, dev);
+ spin_unlock_irqrestore(&io_request_lock,flags);
+ if (req)
+ return req;
+ return __get_request_wait(n, dev);
+}
+
+/* RO fail safe mechanism */
+
+static long ro_bits[MAX_BLKDEV][8];
+
+int is_read_only(kdev_t dev)
+{
+ int minor,major;
+
+ major = MAJOR(dev);
+ minor = MINOR(dev);
+ if (major < 0 || major >= MAX_BLKDEV) return 0;
+ return ro_bits[major][minor >> 5] & (1 << (minor & 31));
+}
+
+void set_device_ro(kdev_t dev,int flag)
+{
+ int minor,major;
+
+ major = MAJOR(dev);
+ minor = MINOR(dev);
+ if (major < 0 || major >= MAX_BLKDEV) return;
+ if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
+ else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
+}
+
+static inline void drive_stat_acct(int cmd, unsigned long nr_sectors,
+ short disk_index)
+{
+ kstat.dk_drive[disk_index]++;
+ if (cmd == READ) {
+ kstat.dk_drive_rio[disk_index]++;
+ kstat.dk_drive_rblk[disk_index] += nr_sectors;
+ } else if (cmd == WRITE) {
+ kstat.dk_drive_wio[disk_index]++;
+ kstat.dk_drive_wblk[disk_index] += nr_sectors;
+ } else
+ printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
+}
+
+static int blkelvget_ioctl(elevator_t * elevator, blkelv_ioctl_arg_t * arg)
+{
+ int ret;
+ blkelv_ioctl_arg_t output;
+
+ output.queue_ID = elevator->queue_ID;
+ output.read_latency = elevator->read_latency;
+ output.write_latency = elevator->write_latency;
+ output.max_bomb_segments = elevator->max_bomb_segments;
+
+ ret = -EFAULT;
+ if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t)))
+ goto out;
+ ret = 0;
+ out:
+ return ret;
+}
+
+static int blkelvset_ioctl(elevator_t * elevator, const blkelv_ioctl_arg_t * arg)
+{
+ blkelv_ioctl_arg_t input;
+ int ret;
+
+ ret = -EFAULT;
+ if (copy_from_user(&input, arg, sizeof(blkelv_ioctl_arg_t)))
+ goto out;
+
+ ret = -EINVAL;
+ if (input.read_latency < 0)
+ goto out;
+ if (input.write_latency < 0)
+ goto out;
+ if (input.max_bomb_segments <= 0)
+ goto out;
+
+ elevator->read_latency = input.read_latency;
+ elevator->write_latency = input.write_latency;
+ elevator->max_bomb_segments = input.max_bomb_segments;
+
+ ret = 0;
+ out:
+ return ret;
+}
+
+int blkelv_ioctl(kdev_t dev, unsigned long cmd, unsigned long arg)
+{
+ elevator_t * elevator = &blk_dev[MAJOR(dev)].elevator;
+ blkelv_ioctl_arg_t * __arg = (blkelv_ioctl_arg_t *) arg;
+
+ switch (cmd) {
+ case BLKELVGET:
+ return blkelvget_ioctl(elevator, __arg);
+ case BLKELVSET:
+ return blkelvset_ioctl(elevator, __arg);
+ }
+ return -EINVAL;
+}
+
+static inline int seek_to_not_starving_chunk(struct request ** req, int * lat)
+{
+ struct request * tmp = *req;
+ int found = 0, pos = 0;
+ int last_pos = 0, __lat = *lat;
+
+ do {
+ if (tmp->elevator_latency <= 0)
+ {
+ *req = tmp;
+ found = 1;
+ last_pos = pos;
+ if (last_pos >= __lat)
+ break;
+ }
+ pos += tmp->nr_segments;
+ } while ((tmp = tmp->next));
+ *lat -= last_pos;
+
+ return found;
+}
+
+#define CASE_COALESCE_BUT_FIRST_REQUEST_MAYBE_BUSY \
+ case IDE0_MAJOR: /* same as HD_MAJOR */ \
+ case IDE1_MAJOR: \
+ case FLOPPY_MAJOR: \
+ case IDE2_MAJOR: \
+ case IDE3_MAJOR: \
+ case IDE4_MAJOR: \
+ case IDE5_MAJOR: \
+ case IDE6_MAJOR: \
+ case IDE7_MAJOR: \
+ case IDE8_MAJOR: \
+ case IDE9_MAJOR: \
+ case ACSI_MAJOR: \
+ case MFM_ACORN_MAJOR: \
+ case MDISK_MAJOR: \
+ case DASD_MAJOR:
+#define CASE_COALESCE_ALSO_FIRST_REQUEST \
+ case SCSI_DISK0_MAJOR: \
+ case SCSI_DISK1_MAJOR: \
+ case SCSI_DISK2_MAJOR: \
+ case SCSI_DISK3_MAJOR: \
+ case SCSI_DISK4_MAJOR: \
+ case SCSI_DISK5_MAJOR: \
+ case SCSI_DISK6_MAJOR: \
+ case SCSI_DISK7_MAJOR: \
+ case SCSI_CDROM_MAJOR: \
+ case DAC960_MAJOR+0: \
+ case DAC960_MAJOR+1: \
+ case DAC960_MAJOR+2: \
+ case DAC960_MAJOR+3: \
+ case DAC960_MAJOR+4: \
+ case DAC960_MAJOR+5: \
+ case DAC960_MAJOR+6: \
+ case DAC960_MAJOR+7: \
+ case COMPAQ_SMART2_MAJOR+0: \
+ case COMPAQ_SMART2_MAJOR+1: \
+ case COMPAQ_SMART2_MAJOR+2: \
+ case COMPAQ_SMART2_MAJOR+3: \
+ case COMPAQ_SMART2_MAJOR+4: \
+ case COMPAQ_SMART2_MAJOR+5: \
+ case COMPAQ_SMART2_MAJOR+6: \
+ case COMPAQ_SMART2_MAJOR+7:
+
+#define elevator_starve_rest_of_queue(req) \
+do { \
+ struct request * tmp = (req); \
+ for ((tmp) = (tmp)->next; (tmp); (tmp) = (tmp)->next) \
+ (tmp)->elevator_latency--; \
+} while (0)
+
+static inline void elevator_queue(struct request * req,
+ struct request * tmp,
+ int latency,
+ struct blk_dev_struct * dev,
+ struct request ** queue_head)
+{
+ struct request * __tmp;
+ int starving, __latency;
+
+ starving = seek_to_not_starving_chunk(&tmp, &latency);
+ __tmp = tmp;
+ __latency = latency;
+
+ for (;; tmp = tmp->next)
+ {
+ if ((latency -= tmp->nr_segments) <= 0)
+ {
+ tmp = __tmp;
+ latency = __latency - tmp->nr_segments;
+
+ if (starving)
+ break;
+
+ switch (MAJOR(req->rq_dev))
+ {
+ CASE_COALESCE_BUT_FIRST_REQUEST_MAYBE_BUSY
+ if (tmp == dev->current_request)
+ default:
+ goto link;
+ CASE_COALESCE_ALSO_FIRST_REQUEST
+ }
+
+ latency += tmp->nr_segments;
+ req->next = tmp;
+ *queue_head = req;
+ goto after_link;
+ }
+
+ if (!tmp->next)
+ break;
+
+ {
+ const int after_current = IN_ORDER(tmp,req);
+ const int before_next = IN_ORDER(req,tmp->next);
+
+ if (!IN_ORDER(tmp,tmp->next)) {
+ if (after_current || before_next)
+ break;
+ } else {
+ if (after_current && before_next)
+ break;
+ }
+ }
+ }
+
+ link:
+ req->next = tmp->next;
+ tmp->next = req;
+
+ after_link:
+ req->elevator_latency = latency;
+
+ elevator_starve_rest_of_queue(req);
+}
+
+/*
+ * add-request adds a request to the linked list.
+ * It disables interrupts (aquires the request spinlock) so that it can muck
+ * with the request-lists in peace. Thus it should be called with no spinlocks
+ * held.
+ *
+ * By this point, req->cmd is always either READ/WRITE, never READA/WRITEA,
+ * which is important for drive_stat_acct() above.
+ */
+
+void add_request(struct blk_dev_struct * dev, struct request * req)
+{
+ int major = MAJOR(req->rq_dev);
+ int minor = MINOR(req->rq_dev);
+ struct request * tmp, **current_request;
+ short disk_index;
+ unsigned long flags;
+ int queue_new_request = 0;
+ int latency;
+
+ switch (major) {
+ case DAC960_MAJOR+0:
+ disk_index = (minor & 0x00f8) >> 3;
+ break;
+ case SCSI_DISK0_MAJOR:
+ case COMPAQ_SMART2_MAJOR+0:
+ case COMPAQ_SMART2_MAJOR+1:
+ case COMPAQ_SMART2_MAJOR+2:
+ case COMPAQ_SMART2_MAJOR+3:
+ case COMPAQ_SMART2_MAJOR+4:
+ case COMPAQ_SMART2_MAJOR+5:
+ case COMPAQ_SMART2_MAJOR+6:
+ case COMPAQ_SMART2_MAJOR+7:
+ disk_index = (minor & 0x00f0) >> 4;
+ break;
+ case IDE0_MAJOR: /* same as HD_MAJOR */
+ case XT_DISK_MAJOR:
+ disk_index = (minor & 0x0040) >> 6;
+ break;
+ case IDE1_MAJOR:
+ disk_index = ((minor & 0x0040) >> 6) + 2;
+ break;
+ default:
+ disk_index = -1;
+ break;
+ }
+ if (disk_index >= 0 && disk_index < 4)
+ drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
+
+ latency = get_request_latency(&dev->elevator, req->cmd);
+
+ /*
+ * We use the goto to reduce locking complexity
+ */
+ spin_lock_irqsave(&io_request_lock,flags);
+ current_request = get_queue(req->rq_dev);
+
+ if (req->bh)
+ mark_buffer_clean(req->bh);
+ if (!(tmp = *current_request)) {
+ req->next = NULL;
+ req->elevator_latency = latency;
+ *current_request = req;
+ if (dev->current_request != &dev->plug)
+ queue_new_request = 1;
+ goto out;
+ }
+ elevator_queue(req, tmp, latency, dev, current_request);
+
+/* for SCSI devices, call request_fn unconditionally */
+ if (scsi_blk_major(major) ||
+ (major >= DAC960_MAJOR+0 && major <= DAC960_MAJOR+7) ||
+ (major >= COMPAQ_SMART2_MAJOR+0 &&
+ major <= COMPAQ_SMART2_MAJOR+7))
+ queue_new_request = 1;
+
+out:
+ if (queue_new_request)
+ (dev->request_fn)();
+ spin_unlock_irqrestore(&io_request_lock,flags);
+}
+
+/*
+ * Has to be called with the request spinlock aquired
+ */
+static inline void attempt_merge (struct request *req,
+ int max_sectors,
+ int max_segments)
+{
+ struct request *next = req->next;
+ int total_segments;
+
+ if (!next)
+ return;
+ if (req->sector + req->nr_sectors != next->sector)
+ return;
+ if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev ||
+ req->nr_sectors + next->nr_sectors > max_sectors)
+ return;
+ total_segments = req->nr_segments + next->nr_segments;
+ if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ total_segments--;
+ if (total_segments > max_segments)
+ return;
+ if (next->elevator_latency < req->elevator_latency)
+ req->elevator_latency = next->elevator_latency;
+ req->bhtail->b_reqnext = next->bh;
+ req->bhtail = next->bhtail;
+ req->nr_sectors += next->nr_sectors;
+ req->nr_segments = total_segments;
+ next->rq_status = RQ_INACTIVE;
+ req->next = next->next;
+ wake_up (&wait_for_request);
+}
+
+#define read_pendings(req) \
+({ \
+ int __ret = 0; \
+ struct request * tmp = (req); \
+ do { \
+ if (tmp->cmd == READ) \
+ { \
+ __ret = 1; \
+ break; \
+ } \
+ tmp = tmp->next; \
+ } while (tmp); \
+ __ret; \
+})
+
+void make_request(int major, int rw, struct buffer_head * bh)
+{
+ unsigned int sector, count;
+ struct request * req, * prev;
+ int rw_ahead, max_req, max_sectors, max_segments;
+ unsigned long flags;
+ int latency, starving;
+
+ count = bh->b_size >> 9;
+ sector = bh->b_rsector;
+
+ /* Uhhuh.. Nasty dead-lock possible here.. */
+ if (buffer_locked(bh))
+ return;
+ /* Maybe the above fixes it, and maybe it doesn't boot. Life is interesting */
+ lock_buffer(bh);
+ if (!buffer_lowprio(bh))
+ io_events[major]++;
+
+ if (blk_size[major]) {
+ unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1;
+
+ if (maxsector < count || maxsector - count < sector) {
+ bh->b_state &= (1 << BH_Lock);
+ /* This may well happen - the kernel calls bread()
+ without checking the size of the device, e.g.,
+ when mounting a device. */
+ printk(KERN_INFO
+ "attempt to access beyond end of device\n");
+ printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n",
+ kdevname(bh->b_rdev), rw,
+ (sector + count)>>1,
+ blk_size[major][MINOR(bh->b_rdev)]);
+ printk(KERN_INFO "dev %s blksize=%d blocknr=%ld sector=%ld size=%ld count=%d\n",
+ kdevname(bh->b_dev),
+ blksize_size[major][MINOR(bh->b_dev)],
+ bh->b_blocknr, bh->b_rsector, bh->b_size, bh->b_count);
+
+ goto end_io;
+ }
+ }
+
+ rw_ahead = 0; /* normal case; gets changed below for READA/WRITEA */
+ switch (rw) {
+ case READA:
+ rw_ahead = 1;
+ rw = READ; /* drop into READ */
+ case READ:
+ if (buffer_uptodate(bh)) /* Hmmph! Already have it */
+ goto end_io;
+ kstat.pgpgin++;
+ max_req = NR_REQUEST; /* reads take precedence */
+ break;
+ case WRITEA:
+ rw_ahead = 1;
+ rw = WRITE; /* drop into WRITE */
+ case WRITE:
+ if (!buffer_dirty(bh)) /* Hmmph! Nothing to write */
+ goto end_io;
+ /* We don't allow the write-requests to fill up the
+ * queue completely: we want some room for reads,
+ * as they take precedence. The last third of the
+ * requests are only for reads.
+ */
+ kstat.pgpgout++;
+ max_req = (NR_REQUEST * 2) / 3;
+ break;
+ default:
+ printk(KERN_ERR "make_request: bad block dev cmd,"
+ " must be R/W/RA/WA\n");
+ goto end_io;
+ }
+
+/* look for a free request. */
+ /* Loop uses two requests, 1 for loop and 1 for the real device.
+ * Cut max_req in half to avoid running out and deadlocking. */
+ if ((major == LOOP_MAJOR) || (major == NBD_MAJOR))
+ max_req >>= 1;
+
+ /*
+ * Try to coalesce the new request with old requests
+ */
+ max_sectors = get_max_sectors(bh->b_rdev);
+ max_segments = get_max_segments(bh->b_rdev);
+
+ latency = get_request_latency(&blk_dev[major].elevator, rw);
+
+ /*
+ * Now we acquire the request spinlock, we have to be mega careful
+ * not to schedule or do something nonatomic
+ */
+ spin_lock_irqsave(&io_request_lock,flags);
+ req = *get_queue(bh->b_rdev);
+ if (!req) {
+ /* MD and loop can't handle plugging without deadlocking */
+ if (major != MD_MAJOR && major != LOOP_MAJOR &&
+#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
+ major != DDV_MAJOR && major != NBD_MAJOR &&
+ major != LVM_BLK_MAJOR)
+#else
+ major != DDV_MAJOR && major != NBD_MAJOR)
+#endif
+ plug_device(blk_dev + major); /* is atomic */
+ } else switch (major) {
+ CASE_COALESCE_BUT_FIRST_REQUEST_MAYBE_BUSY
+ /*
+ * The scsi disk and cdrom drivers completely remove the request
+ * from the queue when they start processing an entry. For this
+ * reason it is safe to continue to add links to the top entry for
+ * those devices.
+ *
+ * All other drivers need to jump over the first entry, as that
+ * entry may be busy being processed and we thus can't change it.
+ */
+ if (req == blk_dev[major].current_request)
+ {
+ if (!(req = req->next))
+ break;
+ latency -= req->nr_segments;
+ }
+ /* fall through */
+ CASE_COALESCE_ALSO_FIRST_REQUEST
+
+ /* avoid write-bombs to not hurt iteractiveness of reads */
+ if (rw != READ && read_pendings(req))
+ max_segments = blk_dev[major].elevator.max_bomb_segments;
+
+ starving = seek_to_not_starving_chunk(&req, &latency);
+ prev = NULL;
+ do {
+ if (req->sem)
+ continue;
+ if (req->cmd != rw)
+ continue;
+ if (req->nr_sectors + count > max_sectors)
+ continue;
+ if (req->rq_dev != bh->b_rdev)
+ continue;
+ /* Can we add it to the end of this request? */
+ if (req->sector + req->nr_sectors == sector) {
+ if (latency - req->nr_segments < 0)
+ break;
+ if (req->bhtail->b_data + req->bhtail->b_size
+ != bh->b_data) {
+ if (req->nr_segments < max_segments)
+ req->nr_segments++;
+ else break;
+ }
+ req->bhtail->b_reqnext = bh;
+ req->bhtail = bh;
+ req->nr_sectors += count;
+
+ /* latency stuff */
+ if ((latency -= req->nr_segments) < req->elevator_latency)
+ req->elevator_latency = latency;
+ elevator_starve_rest_of_queue(req);
+
+ /* Can we now merge this req with the next? */
+ attempt_merge(req, max_sectors, max_segments);
+ /* or to the beginning? */
+ } else if (req->sector - count == sector) {
+ if (!prev && starving)
+ break;
+ if (bh->b_data + bh->b_size
+ != req->bh->b_data) {
+ if (req->nr_segments < max_segments)
+ req->nr_segments++;
+ else break;
+ }
+ bh->b_reqnext = req->bh;
+ req->bh = bh;
+ req->buffer = bh->b_data;
+ req->current_nr_sectors = count;
+ req->sector = sector;
+ req->nr_sectors += count;
+
+ /* latency stuff */
+ if (latency < --req->elevator_latency)
+ req->elevator_latency = latency;
+ elevator_starve_rest_of_queue(req);
+
+ if (prev)
+ attempt_merge(prev, max_sectors, max_segments);
+ } else
+ continue;
+
+ mark_buffer_clean(bh);
+ spin_unlock_irqrestore(&io_request_lock,flags);
+ return;
+
+ } while (prev = req,
+ (latency -= req->nr_segments) >= 0 && (req = req->next) != NULL);
+ }
+
+/* find an unused request. */
+ req = get_request(max_req, bh->b_rdev);
+
+ spin_unlock_irqrestore(&io_request_lock,flags);
+
+/* if no request available: if rw_ahead, forget it; otherwise try again blocking.. */
+ if (!req) {
+ if (rw_ahead)
+ goto end_io;
+ req = __get_request_wait(max_req, bh->b_rdev);
+ }
+
+/* fill up the request-info, and add it to the queue */
+ req->cmd = rw;
+ req->errors = 0;
+ req->sector = sector;
+ req->nr_sectors = count;
+ req->nr_segments = 1;
+ req->current_nr_sectors = count;
+ req->buffer = bh->b_data;
+ req->sem = NULL;
+ req->bh = bh;
+ req->bhtail = bh;
+ add_request(major+blk_dev,req);
+ return;
+
+end_io:
+ bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+}
+
+/* This function can be used to request a number of buffers from a block
+ device. Currently the only restriction is that all buffers must belong to
+ the same device */
+
+void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
+{
+ unsigned int major;
+ int correct_size;
+ struct blk_dev_struct * dev;
+ int i;
+
+ /* Make sure that the first block contains something reasonable */
+ while (!*bh) {
+ bh++;
+ if (--nr <= 0)
+ return;
+ }
+
+ dev = NULL;
+ if ((major = MAJOR(bh[0]->b_dev)) < MAX_BLKDEV)
+ dev = blk_dev + major;
+ if (!dev || !dev->request_fn) {
+ printk(KERN_ERR
+ "ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n",
+ kdevname(bh[0]->b_dev), bh[0]->b_blocknr);
+ goto sorry;
+ }
+ /* Determine correct block size for this device. */
+ correct_size = BLOCK_SIZE;
+ if (blksize_size[major]) {
+ i = blksize_size[major][MINOR(bh[0]->b_dev)];
+ if (i)
+ correct_size = i;
+ }
+
+ /* Verify requested block sizes. */
+ for (i = 0; i < nr; i++) {
+ if (bh[i] && bh[i]->b_size != correct_size) {
+ printk(KERN_NOTICE "ll_rw_block: device %s: "
+ "only %d-char blocks implemented (%lu)\n",
+ kdevname(bh[0]->b_dev),
+ correct_size, bh[i]->b_size);
+ goto sorry;
+ }
+
+ /* Md remaps blocks now */
+ bh[i]->b_rdev = bh[i]->b_dev;
+ bh[i]->b_rsector=bh[i]->b_blocknr*(bh[i]->b_size >> 9);
+#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
+ major = MAJOR(bh[i]->b_dev);
+ if ( major == LVM_BLK_MAJOR) {
+ int ret;
+
+ if ( lvm_map_ptr == NULL) {
+ printk ( KERN_ERR
+ "Bad lvm_map_ptr in ll_rw_block\n");
+ goto sorry;
+ }
+ if ( ( ret = ( lvm_map_ptr) ( MINOR ( bh[i]->b_dev),
+ &bh[i]->b_rdev,
+ &bh[i]->b_rsector,
+ bh[i]->b_size >> 9,
+ rw)) != 0) {
+ printk ( KERN_ERR
+ "Bad lvm_map in ll_rw_block\n");
+ goto sorry;
+ }
+ /* remap major too ... */
+ major = MAJOR(bh[i]->b_rdev);
+ }
+ #endif
+#ifdef CONFIG_BLK_DEV_MD
+ if (major==MD_MAJOR &&
+ /* changed hope this works */
+ md_map (bh[i]->b_rdev, &bh[i]->b_rdev,
+ &bh[i]->b_rsector, bh[i]->b_size >> 9)) {
+ printk (KERN_ERR
+ "Bad md_map in ll_rw_block\n");
+ goto sorry;
+ }
+#endif
+ }
+
+ if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
+ printk(KERN_NOTICE "Can't write to read-only device %s\n",
+ kdevname(bh[0]->b_dev));
+ goto sorry;
+ }
+
+ for (i = 0; i < nr; i++) {
+ if (bh[i]) {
+ set_bit(BH_Req, &bh[i]->b_state);
+#ifdef CONFIG_BLK_DEV_MD
+ /* changed hope it works */
+ if (MAJOR(bh[i]->b_rdev) == MD_MAJOR) {
+ md_make_request(bh[i], rw);
+ continue;
+ }
+#endif
+ make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
+ }
+ }
+ return;
+
+ sorry:
+ for (i = 0; i < nr; i++) {
+ if (bh[i]) {
+ clear_bit(BH_Dirty, &bh[i]->b_state);
+ clear_bit(BH_Uptodate, &bh[i]->b_state);
+ bh[i]->b_end_io(bh[i], 0);
+ }
+ }
+ return;
+}
+
+#ifdef CONFIG_STRAM_SWAP
+extern int stram_device_init( void );
+#endif
+
+/*
+ * First step of what used to be end_request
+ *
+ * 0 means continue with end_that_request_last,
+ * 1 means we are done
+ */
+
+int
+end_that_request_first( struct request *req, int uptodate, char *name )
+{
+ struct buffer_head * bh;
+ int nsect;
+
+ req->errors = 0;
+ if (!uptodate) {
+ printk("end_request: I/O error, dev %s (%s), sector %lu\n",
+ kdevname(req->rq_dev), name, req->sector);
+ if ((bh = req->bh) != NULL) {
+ nsect = bh->b_size >> 9;
+ req->nr_sectors--;
+ req->nr_sectors &= ~(nsect - 1);
+ req->sector += nsect;
+ req->sector &= ~(nsect - 1);
+ }
+ }
+
+ if ((bh = req->bh) != NULL) {
+ req->bh = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ bh->b_end_io(bh, uptodate);
+ if ((bh = req->bh) != NULL) {
+ req->current_nr_sectors = bh->b_size >> 9;
+ if (req->nr_sectors < req->current_nr_sectors) {
+ req->nr_sectors = req->current_nr_sectors;
+ printk("end_request: buffer-list destroyed\n");
+ }
+ req->buffer = bh->b_data;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+end_that_request_last( struct request *req )
+{
+ if (req->sem != NULL)
+ up(req->sem);
+ req->rq_status = RQ_INACTIVE;
+ wake_up(&wait_for_request);
+}
+
+__initfunc(int blk_dev_init(void))
+{
+ struct request * req;
+ struct blk_dev_struct *dev;
+ static unsigned int queue_ID;
+
+ for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
+ dev->request_fn = NULL;
+ dev->queue = NULL;
+ dev->current_request = NULL;
+ dev->plug.rq_status = RQ_INACTIVE;
+ dev->plug.cmd = -1;
+ dev->plug.next = NULL;
+ dev->plug_tq.sync = 0;
+ dev->plug_tq.routine = &unplug_device;
+ dev->plug_tq.data = dev;
+ dev->elevator = ELEVATOR_DEFAULTS;
+ dev->elevator.queue_ID = queue_ID++;
+ }
+
+ req = all_requests + NR_REQUEST;
+ while (--req >= all_requests) {
+ req->rq_status = RQ_INACTIVE;
+ }
+ memset(ro_bits,0,sizeof(ro_bits));
+ memset(max_readahead, 0, sizeof(max_readahead));
+ memset(max_sectors, 0, sizeof(max_sectors));
+#ifdef CONFIG_AMIGA_Z2RAM
+ z2_init();
+#endif
+#ifdef CONFIG_STRAM_SWAP
+ stram_device_init();
+#endif
+#ifdef CONFIG_BLK_DEV_RAM
+ rd_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_GEN
+ loop_gen_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP
+ loop_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_SERPENT
+ loop_serpent_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_CAST
+ loop_cast_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_IDEA
+ loop_idea_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_BLOW
+ loop_blow_init();
+#endif
+#ifdef CONFIG_BLK_DEV_LOOP_FISH2
+ loop_fish2_init();
+#endif
+#ifdef CONFIG_ISP16_CDI
+ isp16_init();
+#endif CONFIG_ISP16_CDI
+#ifdef CONFIG_BLK_DEV_IDE
+ ide_init(); /* this MUST precede hd_init */
+#endif
+#ifdef CONFIG_BLK_DEV_HD
+ hd_init();
+#endif
+#ifdef CONFIG_BLK_DEV_PS2
+ ps2esdi_init();
+#endif
+#ifdef CONFIG_BLK_DEV_XD
+ xd_init();
+#endif
+#ifdef CONFIG_BLK_DEV_MFM
+ mfm_init();
+#endif
+#ifdef CONFIG_PARIDE
+ { extern void paride_init(void); paride_init(); };
+#endif
+#ifdef CONFIG_MAC_FLOPPY
+ swim3_init();
+#endif
+#ifdef CONFIG_AMIGA_FLOPPY
+ amiga_floppy_init();
+#endif
+#ifdef CONFIG_ATARI_FLOPPY
+ atari_floppy_init();
+#endif
+#ifdef CONFIG_BLK_DEV_FD
+ floppy_init();
+#else
+#if !defined (__mc68000__) && !defined(CONFIG_PPC) && !defined(__sparc__)
+ outb_p(0xc, 0x3f2);
+#endif
+#endif
+#ifdef CONFIG_CDU31A
+ cdu31a_init();
+#endif CONFIG_CDU31A
+#ifdef CONFIG_ATARI_ACSI
+ acsi_init();
+#endif CONFIG_ATARI_ACSI
+#ifdef CONFIG_MCD
+ mcd_init();
+#endif CONFIG_MCD
+#ifdef CONFIG_MCDX
+ mcdx_init();
+#endif CONFIG_MCDX
+#ifdef CONFIG_SBPCD
+ sbpcd_init();
+#endif CONFIG_SBPCD
+#ifdef CONFIG_AZTCD
+ aztcd_init();
+#endif CONFIG_AZTCD
+#ifdef CONFIG_CDU535
+ sony535_init();
+#endif CONFIG_CDU535
+#ifdef CONFIG_GSCD
+ gscd_init();
+#endif CONFIG_GSCD
+#ifdef CONFIG_CM206
+ cm206_init();
+#endif
+#ifdef CONFIG_OPTCD
+ optcd_init();
+#endif CONFIG_OPTCD
+#ifdef CONFIG_SJCD
+ sjcd_init();
+#endif CONFIG_SJCD
+#ifdef CONFIG_BLK_DEV_LVM
+ lvm_init();
+#endif
+#ifdef CONFIG_BLK_DEV_MD
+ md_init();
+#endif CONFIG_BLK_DEV_MD
+#ifdef CONFIG_APBLOCK
+ ap_init();
+#endif
+#ifdef CONFIG_DDV
+ ddv_init();
+#endif
+#ifdef CONFIG_BLK_DEV_NBD
+ nbd_init();
+#endif
+#ifdef CONFIG_MDISK
+ mdisk_init();
+#endif
+#ifdef CONFIG_DASD
+ dasd_init();
+#endif
+#ifdef CONFIG_BLK_DEV_XPRAM
+ xpram_init();
+#endif
+ return 0;
+};
+
+EXPORT_SYMBOL(io_request_lock);
+EXPORT_SYMBOL(end_that_request_first);
+EXPORT_SYMBOL(end_that_request_last);
+EXPORT_SYMBOL(blkelv_ioctl);
diff --git a/sys-kernel/linux-UP-2.2.17/files/md.c b/sys-kernel/linux-UP-2.2.17/files/md.c
new file mode 100644
index 000000000000..7c8cc0bae9d7
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/files/md.c
@@ -0,0 +1,4030 @@
+/*
+ md.c : Multiple Devices driver for Linux
+ Copyright (C) 1998, 1999 Ingo Molnar
+
+ completely rewritten, based on the MD driver code from Marc Zyngier
+
+ Changes:
+
+ - RAID-1/RAID-5 extensions by Miguel de Icaza, Gadi Oxman, Ingo Molnar
+ - boot support for linear and striped mode by Harald Hoyer <HarryH@Royal.Net>
+ - kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+ - kmod support by: Cyrus Durgin
+ - RAID0 bugfixes: Mark Anthony Lisher <markal@iname.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/raid/md.h>
+#include <linux/raid/xor.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+
+#include <asm/unaligned.h>
+
+extern asmlinkage int sys_sched_yield(void);
+extern asmlinkage int sys_setsid(void);
+
+extern unsigned long io_events[MAX_BLKDEV];
+
+#define MAJOR_NR MD_MAJOR
+#define MD_DRIVER
+
+#include <linux/blk.h>
+
+#ifdef CONFIG_MD_BOOT
+extern kdev_t name_to_kdev_t(char *line) md__init;
+#endif
+
+static mdk_personality_t *pers[MAX_PERSONALITY] = {NULL, };
+
+/*
+ * these have to be allocated separately because external
+ * subsystems want to have a pre-defined structure
+ */
+struct hd_struct md_hd_struct[MAX_MD_DEVS];
+static int md_blocksizes[MAX_MD_DEVS];
+static int md_maxreadahead[MAX_MD_DEVS];
+static mdk_thread_t *md_recovery_thread = NULL;
+
+int md_size[MAX_MD_DEVS] = {0, };
+
+static void md_geninit (struct gendisk *);
+
+static struct gendisk md_gendisk=
+{
+ MD_MAJOR,
+ "md",
+ 0,
+ 1,
+ MAX_MD_DEVS,
+ md_geninit,
+ md_hd_struct,
+ md_size,
+ MAX_MD_DEVS,
+ NULL,
+ NULL
+};
+
+/*
+ * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
+ * is 100 KB/sec, so the extra system load does not show up that much.
+ * Increase it if you want to have more _guaranteed_ speed. Note that
+ * the RAID driver will use the maximum available bandwith if the IO
+ * subsystem is idle.
+ *
+ * you can change it via /proc/sys/dev/speed-limit
+ */
+
+static int sysctl_speed_limit = 100;
+
+static struct ctl_table_header *md_table_header;
+
+static ctl_table md_table[] = {
+ {DEV_MD_SPEED_LIMIT, "speed-limit",
+ &sysctl_speed_limit, sizeof(int), 0644, NULL, &proc_dointvec},
+ {0}
+};
+
+static ctl_table md_dir_table[] = {
+ {DEV_MD, "md", NULL, 0, 0555, md_table},
+ {0}
+};
+
+static ctl_table md_root_table[] = {
+ {CTL_DEV, "dev", NULL, 0, 0555, md_dir_table},
+ {0}
+};
+
+static void md_register_sysctl(void)
+{
+ md_table_header = register_sysctl_table(md_root_table, 1);
+}
+
+void md_unregister_sysctl(void)
+{
+ unregister_sysctl_table(md_table_header);
+}
+
+/*
+ * The mapping between kdev and mddev is not necessary a simple
+ * one! Eg. HSM uses several sub-devices to implement Logical
+ * Volumes. All these sub-devices map to the same mddev.
+ */
+dev_mapping_t mddev_map [MAX_MD_DEVS] = { {NULL, 0}, };
+
+void add_mddev_mapping (mddev_t * mddev, kdev_t dev, void *data)
+{
+ unsigned int minor = MINOR(dev);
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return;
+ }
+ if (mddev_map[minor].mddev != NULL) {
+ MD_BUG();
+ return;
+ }
+ mddev_map[minor].mddev = mddev;
+ mddev_map[minor].data = data;
+}
+
+void del_mddev_mapping (mddev_t * mddev, kdev_t dev)
+{
+ unsigned int minor = MINOR(dev);
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return;
+ }
+ if (mddev_map[minor].mddev != mddev) {
+ MD_BUG();
+ return;
+ }
+ mddev_map[minor].mddev = NULL;
+ mddev_map[minor].data = NULL;
+}
+
+/*
+ * Enables to iterate over all existing md arrays
+ */
+static MD_LIST_HEAD(all_mddevs);
+
+static mddev_t * alloc_mddev (kdev_t dev)
+{
+ mddev_t * mddev;
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return 0;
+ }
+ mddev = (mddev_t *) kmalloc(sizeof(*mddev), GFP_KERNEL);
+ if (!mddev)
+ return NULL;
+
+ memset(mddev, 0, sizeof(*mddev));
+
+ mddev->__minor = MINOR(dev);
+ mddev->reconfig_sem = MUTEX;
+ mddev->recovery_sem = MUTEX;
+ mddev->resync_sem = MUTEX;
+ MD_INIT_LIST_HEAD(&mddev->disks);
+ /*
+ * The 'base' mddev is the one with data NULL.
+ * personalities can create additional mddevs
+ * if necessary.
+ */
+ add_mddev_mapping(mddev, dev, 0);
+ md_list_add(&mddev->all_mddevs, &all_mddevs);
+
+ return mddev;
+}
+
+static void free_mddev (mddev_t *mddev)
+{
+ if (!mddev) {
+ MD_BUG();
+ return;
+ }
+
+ /*
+ * Make sure nobody else is using this mddev
+ * (careful, we rely on the global kernel lock here)
+ */
+ while (md_atomic_read(&mddev->resync_sem.count) != 1)
+ schedule();
+ while (md_atomic_read(&mddev->recovery_sem.count) != 1)
+ schedule();
+
+ del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
+ md_list_del(&mddev->all_mddevs);
+ MD_INIT_LIST_HEAD(&mddev->all_mddevs);
+ kfree(mddev);
+}
+
+
+struct gendisk * find_gendisk (kdev_t dev)
+{
+ struct gendisk *tmp = gendisk_head;
+
+ while (tmp != NULL) {
+ if (tmp->major == MAJOR(dev))
+ return (tmp);
+ tmp = tmp->next;
+ }
+ return (NULL);
+}
+
+mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
+{
+ mdk_rdev_t * rdev;
+ struct md_list_head *tmp;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == nr)
+ return rdev;
+ }
+ return NULL;
+}
+
+mdk_rdev_t * find_rdev(mddev_t * mddev, kdev_t dev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->dev == dev)
+ return rdev;
+ }
+ return NULL;
+}
+
+static MD_LIST_HEAD(device_names);
+
+char * partition_name (kdev_t dev)
+{
+ struct gendisk *hd;
+ static char nomem [] = "<nomem>";
+ dev_name_t *dname;
+ struct md_list_head *tmp = device_names.next;
+
+ while (tmp != &device_names) {
+ dname = md_list_entry(tmp, dev_name_t, list);
+ if (dname->dev == dev)
+ return dname->name;
+ tmp = tmp->next;
+ }
+
+ dname = (dev_name_t *) kmalloc(sizeof(*dname), GFP_KERNEL);
+
+ if (!dname)
+ return nomem;
+ /*
+ * ok, add this new device name to the list
+ */
+ hd = find_gendisk (dev);
+
+ if (!hd)
+ sprintf (dname->name, "[dev %s]", kdevname(dev));
+ else
+ disk_name (hd, MINOR(dev), dname->name);
+
+ dname->dev = dev;
+ md_list_add(&dname->list, &device_names);
+
+ return dname->name;
+}
+
+static unsigned int calc_dev_sboffset (kdev_t dev, mddev_t *mddev,
+ int persistent)
+{
+ unsigned int size = 0;
+
+ if (blk_size[MAJOR(dev)])
+ size = blk_size[MAJOR(dev)][MINOR(dev)];
+ if (persistent)
+ size = MD_NEW_SIZE_BLOCKS(size);
+ return size;
+}
+
+static unsigned int calc_dev_size (kdev_t dev, mddev_t *mddev, int persistent)
+{
+ unsigned int size;
+
+ size = calc_dev_sboffset(dev, mddev, persistent);
+ if (!mddev->sb) {
+ MD_BUG();
+ return size;
+ }
+ if (mddev->sb->chunk_size)
+ size &= ~(mddev->sb->chunk_size/1024 - 1);
+ return size;
+}
+
+/*
+ * We check wether all devices are numbered from 0 to nb_dev-1. The
+ * order is guaranteed even after device name changes.
+ *
+ * Some personalities (raid0, linear) use this. Personalities that
+ * provide data have to be able to deal with loss of individual
+ * disks, so they do their checking themselves.
+ */
+int md_check_ordering (mddev_t *mddev)
+{
+ int i, c;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+
+ /*
+ * First, all devices must be fully functional
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {
+ printk("md: md%d's device %s faulty, aborting.\n",
+ mdidx(mddev), partition_name(rdev->dev));
+ goto abort;
+ }
+ }
+
+ c = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ c++;
+ }
+ if (c != mddev->nb_dev) {
+ MD_BUG();
+ goto abort;
+ }
+ if (mddev->nb_dev != mddev->sb->raid_disks) {
+ printk("md: md%d, array needs %d disks, has %d, aborting.\n",
+ mdidx(mddev), mddev->sb->raid_disks, mddev->nb_dev);
+ goto abort;
+ }
+ /*
+ * Now the numbering check
+ */
+ for (i = 0; i < mddev->nb_dev; i++) {
+ c = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == i)
+ c++;
+ }
+ if (c == 0) {
+ printk("md: md%d, missing disk #%d, aborting.\n",
+ mdidx(mddev), i);
+ goto abort;
+ }
+ if (c > 1) {
+ printk("md: md%d, too many disks #%d, aborting.\n",
+ mdidx(mddev), i);
+ goto abort;
+ }
+ }
+ return 0;
+abort:
+ return 1;
+}
+
+static unsigned int zoned_raid_size (mddev_t *mddev)
+{
+ unsigned int mask;
+ mdk_rdev_t * rdev;
+ struct md_list_head *tmp;
+
+ if (!mddev->sb) {
+ MD_BUG();
+ return -EINVAL;
+ }
+ /*
+ * do size and offset calculations.
+ */
+ mask = ~(mddev->sb->chunk_size/1024 - 1);
+printk("mask %08x\n", mask);
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+printk(" rdev->size: %d\n", rdev->size);
+ rdev->size &= mask;
+printk(" masked rdev->size: %d\n", rdev->size);
+ md_size[mdidx(mddev)] += rdev->size;
+printk(" new md_size: %d\n", md_size[mdidx(mddev)]);
+ }
+ return 0;
+}
+
+static void remove_descriptor (mdp_disk_t *disk, mdp_super_t *sb)
+{
+ if (disk_active(disk)) {
+ sb->working_disks--;
+ } else {
+ if (disk_spare(disk)) {
+ sb->spare_disks--;
+ sb->working_disks--;
+ } else {
+ sb->failed_disks--;
+ }
+ }
+ sb->nr_disks--;
+ disk->major = 0;
+ disk->minor = 0;
+ mark_disk_removed(disk);
+}
+
+#define BAD_MAGIC KERN_ERR \
+"md: invalid raid superblock magic on %s\n"
+
+#define BAD_MINOR KERN_ERR \
+"md: %s: invalid raid minor (%x)\n"
+
+#define OUT_OF_MEM KERN_ALERT \
+"md: out of memory.\n"
+
+#define NO_SB KERN_ERR \
+"md: disabled device %s, could not read superblock.\n"
+
+#define BAD_CSUM KERN_WARNING \
+"md: invalid superblock checksum on %s\n"
+
+static int alloc_array_sb (mddev_t * mddev)
+{
+ if (mddev->sb) {
+ MD_BUG();
+ return 0;
+ }
+
+ mddev->sb = (mdp_super_t *) __get_free_page (GFP_KERNEL);
+ if (!mddev->sb)
+ return -ENOMEM;
+ md_clear_page((unsigned long)mddev->sb);
+ return 0;
+}
+
+static int alloc_disk_sb (mdk_rdev_t * rdev)
+{
+ if (rdev->sb)
+ MD_BUG();
+
+ rdev->sb = (mdp_super_t *) __get_free_page(GFP_KERNEL);
+ if (!rdev->sb) {
+ printk (OUT_OF_MEM);
+ return -EINVAL;
+ }
+ md_clear_page((unsigned long)rdev->sb);
+
+ return 0;
+}
+
+static void free_disk_sb (mdk_rdev_t * rdev)
+{
+ if (rdev->sb) {
+ free_page((unsigned long) rdev->sb);
+ rdev->sb = NULL;
+ rdev->sb_offset = 0;
+ rdev->size = 0;
+ } else {
+ if (!rdev->faulty)
+ MD_BUG();
+ }
+}
+
+static void mark_rdev_faulty (mdk_rdev_t * rdev)
+{
+ unsigned long flags;
+
+ if (!rdev) {
+ MD_BUG();
+ return;
+ }
+ save_flags(flags);
+ cli();
+ free_disk_sb(rdev);
+ rdev->faulty = 1;
+ restore_flags(flags);
+}
+
+static int read_disk_sb (mdk_rdev_t * rdev)
+{
+ int ret = -EINVAL;
+ struct buffer_head *bh = NULL;
+ kdev_t dev = rdev->dev;
+ mdp_super_t *sb;
+ u32 sb_offset;
+
+ if (!rdev->sb) {
+ MD_BUG();
+ goto abort;
+ }
+
+ /*
+ * Calculate the position of the superblock,
+ * it's at the end of the disk
+ */
+ sb_offset = calc_dev_sboffset(rdev->dev, rdev->mddev, 1);
+ rdev->sb_offset = sb_offset;
+ printk("(read) %s's sb offset: %d", partition_name(dev),
+ sb_offset);
+ fsync_dev(dev);
+ set_blocksize (dev, MD_SB_BYTES);
+ bh = bread (dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
+
+ if (bh) {
+ sb = (mdp_super_t *) bh->b_data;
+ memcpy (rdev->sb, sb, MD_SB_BYTES);
+ } else {
+ printk (NO_SB,partition_name(rdev->dev));
+ goto abort;
+ }
+ printk(" [events: %08lx]\n", (unsigned long)get_unaligned(&rdev->sb->events));
+ ret = 0;
+abort:
+ if (bh)
+ brelse (bh);
+ return ret;
+}
+
+static unsigned int calc_sb_csum (mdp_super_t * sb)
+{
+ unsigned int disk_csum, csum;
+
+ disk_csum = sb->sb_csum;
+ sb->sb_csum = 0;
+ csum = csum_partial((void *)sb, MD_SB_BYTES, 0);
+ sb->sb_csum = disk_csum;
+ return csum;
+}
+
+/*
+ * Check one RAID superblock for generic plausibility
+ */
+
+static int check_disk_sb (mdk_rdev_t * rdev)
+{
+ mdp_super_t *sb;
+ int ret = -EINVAL;
+
+ sb = rdev->sb;
+ if (!sb) {
+ MD_BUG();
+ goto abort;
+ }
+
+ if (sb->md_magic != MD_SB_MAGIC) {
+ printk (BAD_MAGIC, partition_name(rdev->dev));
+ goto abort;
+ }
+
+ if (sb->md_minor >= MAX_MD_DEVS) {
+ printk (BAD_MINOR, partition_name(rdev->dev),
+ sb->md_minor);
+ goto abort;
+ }
+
+ if (calc_sb_csum(sb) != sb->sb_csum)
+ printk(BAD_CSUM, partition_name(rdev->dev));
+ ret = 0;
+abort:
+ return ret;
+}
+
+static kdev_t dev_unit(kdev_t dev)
+{
+ unsigned int mask;
+ struct gendisk *hd = find_gendisk(dev);
+
+ if (!hd)
+ return 0;
+ mask = ~((1 << hd->minor_shift) - 1);
+
+ return MKDEV(MAJOR(dev), MINOR(dev) & mask);
+}
+
+static mdk_rdev_t * match_dev_unit(mddev_t *mddev, kdev_t dev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev,rdev,tmp)
+ if (dev_unit(rdev->dev) == dev_unit(dev))
+ return rdev;
+
+ return NULL;
+}
+
+static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev1,rdev,tmp)
+ if (match_dev_unit(mddev2, rdev->dev))
+ return 1;
+
+ return 0;
+}
+
+static MD_LIST_HEAD(all_raid_disks);
+static MD_LIST_HEAD(pending_raid_disks);
+
+static void bind_rdev_to_array (mdk_rdev_t * rdev, mddev_t * mddev)
+{
+ mdk_rdev_t *same_pdev;
+
+ if (rdev->mddev) {
+ MD_BUG();
+ return;
+ }
+ same_pdev = match_dev_unit(mddev, rdev->dev);
+ if (same_pdev)
+ printk( KERN_WARNING
+"md%d: WARNING: %s appears to be on the same physical disk as %s. True\n"
+" protection against single-disk failure might be compromised.\n",
+ mdidx(mddev), partition_name(rdev->dev),
+ partition_name(same_pdev->dev));
+
+ md_list_add(&rdev->same_set, &mddev->disks);
+ rdev->mddev = mddev;
+ mddev->nb_dev++;
+ printk("bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
+}
+
+static void unbind_rdev_from_array (mdk_rdev_t * rdev)
+{
+ if (!rdev->mddev) {
+ MD_BUG();
+ return;
+ }
+ md_list_del(&rdev->same_set);
+ MD_INIT_LIST_HEAD(&rdev->same_set);
+ rdev->mddev->nb_dev--;
+ printk("unbind<%s,%d>\n", partition_name(rdev->dev),
+ rdev->mddev->nb_dev);
+ rdev->mddev = NULL;
+}
+
+/*
+ * prevent the device from being mounted, repartitioned or
+ * otherwise reused by a RAID array (or any other kernel
+ * subsystem), by opening the device. [simply getting an
+ * inode is not enough, the SCSI module usage code needs
+ * an explicit open() on the device]
+ */
+static int lock_rdev (mdk_rdev_t *rdev)
+{
+ int err = 0;
+
+ /*
+ * First insert a dummy inode.
+ */
+ if (rdev->inode)
+ MD_BUG();
+ rdev->inode = get_empty_inode();
+ /*
+ * we dont care about any other fields
+ */
+ rdev->inode->i_dev = rdev->inode->i_rdev = rdev->dev;
+ insert_inode_hash(rdev->inode);
+
+ memset(&rdev->filp, 0, sizeof(rdev->filp));
+ rdev->filp.f_mode = 3; /* read write */
+ err = blkdev_open(rdev->inode, &rdev->filp);
+ if (err) {
+ printk("blkdev_open() failed: %d\n", err);
+ clear_inode(rdev->inode);
+ rdev->inode = NULL;
+ }
+ return err;
+}
+
+static void unlock_rdev (mdk_rdev_t *rdev)
+{
+ blkdev_release(rdev->inode);
+ if (!rdev->inode)
+ MD_BUG();
+ clear_inode(rdev->inode);
+ rdev->inode = NULL;
+}
+
+static void export_rdev (mdk_rdev_t * rdev)
+{
+ printk("export_rdev(%s)\n",partition_name(rdev->dev));
+ if (rdev->mddev)
+ MD_BUG();
+ unlock_rdev(rdev);
+ free_disk_sb(rdev);
+ md_list_del(&rdev->all);
+ MD_INIT_LIST_HEAD(&rdev->all);
+ if (rdev->pending.next != &rdev->pending) {
+ printk("(%s was pending)\n",partition_name(rdev->dev));
+ md_list_del(&rdev->pending);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+ }
+ rdev->dev = 0;
+ rdev->faulty = 0;
+ kfree(rdev);
+}
+
+static void kick_rdev_from_array (mdk_rdev_t * rdev)
+{
+ unbind_rdev_from_array(rdev);
+ export_rdev(rdev);
+}
+
+static void export_array (mddev_t *mddev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+ mdp_super_t *sb = mddev->sb;
+
+ if (mddev->sb) {
+ mddev->sb = NULL;
+ free_page((unsigned long) sb);
+ }
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (!rdev->mddev) {
+ MD_BUG();
+ continue;
+ }
+ kick_rdev_from_array(rdev);
+ }
+ if (mddev->nb_dev)
+ MD_BUG();
+}
+
+#undef BAD_CSUM
+#undef BAD_MAGIC
+#undef OUT_OF_MEM
+#undef NO_SB
+
+static void print_desc(mdp_disk_t *desc)
+{
+ printk(" DISK<N:%d,%s(%d,%d),R:%d,S:%d>\n", desc->number,
+ partition_name(MKDEV(desc->major,desc->minor)),
+ desc->major,desc->minor,desc->raid_disk,desc->state);
+}
+
+static void print_sb(mdp_super_t *sb)
+{
+ int i;
+
+ printk(" SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
+ sb->major_version, sb->minor_version, sb->patch_version,
+ sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3,
+ sb->ctime);
+ printk(" L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
+ sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor,
+ sb->layout, sb->chunk_size);
+ printk(" UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
+ sb->utime, sb->state, sb->active_disks, sb->working_disks,
+ sb->failed_disks, sb->spare_disks,
+ sb->sb_csum, (unsigned long)get_unaligned(&sb->events));
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+
+ desc = sb->disks + i;
+ printk(" D %2d: ", i);
+ print_desc(desc);
+ }
+ printk(" THIS: ");
+ print_desc(&sb->this_disk);
+
+}
+
+static void print_rdev(mdk_rdev_t *rdev)
+{
+ printk(" rdev %s: O:%s, SZ:%08d F:%d DN:%d ",
+ partition_name(rdev->dev), partition_name(rdev->old_dev),
+ rdev->size, rdev->faulty, rdev->desc_nr);
+ if (rdev->sb) {
+ printk("rdev superblock:\n");
+ print_sb(rdev->sb);
+ } else
+ printk("no rdev superblock!\n");
+}
+
+void md_print_devices (void)
+{
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev;
+ mddev_t *mddev;
+
+ printk("\n");
+ printk(" **********************************\n");
+ printk(" * <COMPLETE RAID STATE PRINTOUT> *\n");
+ printk(" **********************************\n");
+ ITERATE_MDDEV(mddev,tmp) {
+ printk("md%d: ", mdidx(mddev));
+
+ ITERATE_RDEV(mddev,rdev,tmp2)
+ printk("<%s>", partition_name(rdev->dev));
+
+ if (mddev->sb) {
+ printk(" array superblock:\n");
+ print_sb(mddev->sb);
+ } else
+ printk(" no array superblock.\n");
+
+ ITERATE_RDEV(mddev,rdev,tmp2)
+ print_rdev(rdev);
+ }
+ printk(" **********************************\n");
+ printk("\n");
+}
+
+static int sb_equal ( mdp_super_t *sb1, mdp_super_t *sb2)
+{
+ int ret;
+ mdp_super_t *tmp1, *tmp2;
+
+ tmp1 = kmalloc(sizeof(*tmp1),GFP_KERNEL);
+ tmp2 = kmalloc(sizeof(*tmp2),GFP_KERNEL);
+
+ if (!tmp1 || !tmp2) {
+ ret = 0;
+ goto abort;
+ }
+
+ *tmp1 = *sb1;
+ *tmp2 = *sb2;
+
+ /*
+ * nr_disks is not constant
+ */
+ tmp1->nr_disks = 0;
+ tmp2->nr_disks = 0;
+
+ if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4))
+ ret = 0;
+ else
+ ret = 1;
+
+abort:
+ if (tmp1)
+ kfree(tmp1);
+ if (tmp2)
+ kfree(tmp2);
+
+ return ret;
+}
+
+static int uuid_equal(mdk_rdev_t *rdev1, mdk_rdev_t *rdev2)
+{
+ if ( (rdev1->sb->set_uuid0 == rdev2->sb->set_uuid0) &&
+ (rdev1->sb->set_uuid1 == rdev2->sb->set_uuid1) &&
+ (rdev1->sb->set_uuid2 == rdev2->sb->set_uuid2) &&
+ (rdev1->sb->set_uuid3 == rdev2->sb->set_uuid3))
+
+ return 1;
+
+ return 0;
+}
+
+static mdk_rdev_t * find_rdev_all (kdev_t dev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ tmp = all_raid_disks.next;
+ while (tmp != &all_raid_disks) {
+ rdev = md_list_entry(tmp, mdk_rdev_t, all);
+ if (rdev->dev == dev)
+ return rdev;
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+#define GETBLK_FAILED KERN_ERR \
+"md: getblk failed for device %s\n"
+
+static int write_disk_sb(mdk_rdev_t * rdev)
+{
+ struct buffer_head *bh;
+ kdev_t dev;
+ u32 sb_offset, size;
+ mdp_super_t *sb;
+
+ if (!rdev->sb) {
+ MD_BUG();
+ return -1;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ return -1;
+ }
+ if (rdev->sb->md_magic != MD_SB_MAGIC) {
+ MD_BUG();
+ return -1;
+ }
+
+ dev = rdev->dev;
+ sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
+ if (rdev->sb_offset != sb_offset) {
+ printk("%s's sb offset has changed from %d to %d, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
+ goto skip;
+ }
+ /*
+ * If the disk went offline meanwhile and it's just a spare, then
+ * it's size has changed to zero silently, and the MD code does
+ * not yet know that it's faulty.
+ */
+ size = calc_dev_size(dev, rdev->mddev, 1);
+ if (size != rdev->size) {
+ printk("%s's size has changed from %d to %d since import, skipping\n", partition_name(dev), rdev->size, size);
+ goto skip;
+ }
+
+ printk("(write) %s's sb offset: %d\n", partition_name(dev), sb_offset);
+ fsync_dev(dev);
+ set_blocksize(dev, MD_SB_BYTES);
+ bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
+ if (!bh) {
+ printk(GETBLK_FAILED, partition_name(dev));
+ return 1;
+ }
+ memset(bh->b_data,0,bh->b_size);
+ sb = (mdp_super_t *) bh->b_data;
+ memcpy(sb, rdev->sb, MD_SB_BYTES);
+
+ mark_buffer_uptodate(bh, 1);
+ mark_buffer_dirty(bh, 1);
+ ll_rw_block(WRITE, 1, &bh);
+ wait_on_buffer(bh);
+ brelse(bh);
+ fsync_dev(dev);
+skip:
+ return 0;
+}
+#undef GETBLK_FAILED KERN_ERR
+
+static void set_this_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+{
+ int i, ok = 0;
+ mdp_disk_t *desc;
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ desc = mddev->sb->disks + i;
+#if 0
+ if (disk_faulty(desc)) {
+ if (MKDEV(desc->major,desc->minor) == rdev->dev)
+ ok = 1;
+ continue;
+ }
+#endif
+ if (MKDEV(desc->major,desc->minor) == rdev->dev) {
+ rdev->sb->this_disk = *desc;
+ rdev->desc_nr = desc->number;
+ ok = 1;
+ break;
+ }
+ }
+
+ if (!ok) {
+ MD_BUG();
+ }
+}
+
+static int sync_sbs(mddev_t * mddev)
+{
+ mdk_rdev_t *rdev;
+ mdp_super_t *sb;
+ struct md_list_head *tmp;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)
+ continue;
+ sb = rdev->sb;
+ *sb = *mddev->sb;
+ set_this_disk(mddev, rdev);
+ sb->sb_csum = calc_sb_csum(sb);
+ }
+ return 0;
+}
+
+int md_update_sb(mddev_t * mddev)
+{
+ int first, err, count = 100;
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+ __u64 ev;
+
+repeat:
+ mddev->sb->utime = CURRENT_TIME;
+ ev = get_unaligned(&mddev->sb->events);
+ ++ev;
+ put_unaligned(ev,&mddev->sb->events);
+ if (ev == (__u64)0) {
+ /*
+ * oops, this 64-bit counter should never wrap.
+ * Either we are in around ~1 trillion A.C., assuming
+ * 1 reboot per second, or we have a bug:
+ */
+ MD_BUG();
+ --ev;
+ put_unaligned(ev,&mddev->sb->events);
+ }
+ sync_sbs(mddev);
+
+ /*
+ * do not write anything to disk if using
+ * nonpersistent superblocks
+ */
+ if (mddev->sb->not_persistent)
+ return 0;
+
+ printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
+ mdidx(mddev));
+
+ first = 1;
+ err = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (!first) {
+ first = 0;
+ printk(", ");
+ }
+ if (rdev->faulty)
+ printk("(skipping faulty ");
+ printk("%s ", partition_name(rdev->dev));
+ if (!rdev->faulty) {
+ printk("[events: %08lx]",
+ (unsigned long)get_unaligned(&rdev->sb->events));
+ err += write_disk_sb(rdev);
+ } else
+ printk(")\n");
+ }
+ printk(".\n");
+ if (err) {
+ printk("errors occured during superblock update, repeating\n");
+ if (--count)
+ goto repeat;
+ printk("excessive errors occured during superblock update, exiting\n");
+ }
+ return 0;
+}
+
+/*
+ * Import a device. If 'on_disk', then sanity check the superblock
+ *
+ * mark the device faulty if:
+ *
+ * - the device is nonexistent (zero size)
+ * - the device has no valid superblock
+ *
+ * a faulty rdev _never_ has rdev->sb set.
+ */
+static int md_import_device (kdev_t newdev, int on_disk)
+{
+ int err;
+ mdk_rdev_t *rdev;
+ unsigned int size;
+
+ if (find_rdev_all(newdev))
+ return -EEXIST;
+
+ rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
+ if (!rdev) {
+ printk("could not alloc mem for %s!\n", partition_name(newdev));
+ return -ENOMEM;
+ }
+ memset(rdev, 0, sizeof(*rdev));
+
+ if (!fs_may_mount(newdev)) {
+ printk("md: can not import %s, has active inodes!\n",
+ partition_name(newdev));
+ err = -EBUSY;
+ goto abort_free;
+ }
+
+ if ((err = alloc_disk_sb(rdev)))
+ goto abort_free;
+
+ rdev->dev = newdev;
+ if (lock_rdev(rdev)) {
+ printk("md: could not lock %s, zero-size? Marking faulty.\n",
+ partition_name(newdev));
+ err = -EINVAL;
+ goto abort_free;
+ }
+ rdev->desc_nr = -1;
+ rdev->faulty = 0;
+
+ size = 0;
+ if (blk_size[MAJOR(newdev)])
+ size = blk_size[MAJOR(newdev)][MINOR(newdev)];
+ if (!size) {
+ printk("md: %s has zero size, marking faulty!\n",
+ partition_name(newdev));
+ err = -EINVAL;
+ goto abort_free;
+ }
+
+ if (on_disk) {
+ if ((err = read_disk_sb(rdev))) {
+ printk("md: could not read %s's sb, not importing!\n",
+ partition_name(newdev));
+ goto abort_free;
+ }
+ if ((err = check_disk_sb(rdev))) {
+ printk("md: %s has invalid sb, not importing!\n",
+ partition_name(newdev));
+ goto abort_free;
+ }
+
+ rdev->old_dev = MKDEV(rdev->sb->this_disk.major,
+ rdev->sb->this_disk.minor);
+ rdev->desc_nr = rdev->sb->this_disk.number;
+ }
+ md_list_add(&rdev->all, &all_raid_disks);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+
+ if (rdev->faulty && rdev->sb)
+ free_disk_sb(rdev);
+ return 0;
+
+abort_free:
+ if (rdev->sb) {
+ if (rdev->inode)
+ unlock_rdev(rdev);
+ free_disk_sb(rdev);
+ }
+ kfree(rdev);
+ return err;
+}
+
+/*
+ * Check a full RAID array for plausibility
+ */
+
+#define INCONSISTENT KERN_ERR \
+"md: fatal superblock inconsistency in %s -- removing from array\n"
+
+#define OUT_OF_DATE KERN_ERR \
+"md: superblock update time inconsistency -- using the most recent one\n"
+
+#define OLD_VERSION KERN_ALERT \
+"md: md%d: unsupported raid array version %d.%d.%d\n"
+
+#define NOT_CLEAN_IGNORE KERN_ERR \
+"md: md%d: raid array is not clean -- starting background reconstruction\n"
+
+#define UNKNOWN_LEVEL KERN_ERR \
+"md: md%d: unsupported raid level %d\n"
+
+static int analyze_sbs (mddev_t * mddev)
+{
+ int out_of_date = 0, i;
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev, *rdev2, *freshest;
+ mdp_super_t *sb;
+
+ /*
+ * Verify the RAID superblock on each real device
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {
+ MD_BUG();
+ goto abort;
+ }
+ if (!rdev->sb) {
+ MD_BUG();
+ goto abort;
+ }
+ if (check_disk_sb(rdev))
+ goto abort;
+ }
+
+ /*
+ * The superblock constant part has to be the same
+ * for all disks in the array.
+ */
+ sb = NULL;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (!sb) {
+ sb = rdev->sb;
+ continue;
+ }
+ if (!sb_equal(sb, rdev->sb)) {
+ printk (INCONSISTENT, partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ continue;
+ }
+ }
+
+ /*
+ * OK, we have all disks and the array is ready to run. Let's
+ * find the freshest superblock, that one will be the superblock
+ * that represents the whole array.
+ */
+ if (!mddev->sb)
+ if (alloc_array_sb(mddev))
+ goto abort;
+ sb = mddev->sb;
+ freshest = NULL;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ __u64 ev1, ev2;
+ /*
+ * if the checksum is invalid, use the superblock
+ * only as a last resort. (decrease it's age by
+ * one event)
+ */
+ if (calc_sb_csum(rdev->sb) != rdev->sb->sb_csum) {
+ __u64 ev = get_unaligned(&rdev->sb->events);
+ if (ev != (__u64)0) {
+ --ev;
+ put_unaligned(ev,&rdev->sb->events);
+ }
+ }
+
+ printk("%s's event counter: %08lx\n", partition_name(rdev->dev),
+ (unsigned long)get_unaligned(&rdev->sb->events));
+ if (!freshest) {
+ freshest = rdev;
+ continue;
+ }
+ /*
+ * Find the newest superblock version
+ */
+ ev1 = get_unaligned(&rdev->sb->events);
+ ev2 = get_unaligned(&freshest->sb->events);
+ if (ev1 != ev2) {
+ out_of_date = 1;
+ if (ev1 > ev2)
+ freshest = rdev;
+ }
+ }
+ if (out_of_date) {
+ printk(OUT_OF_DATE);
+ printk("freshest: %s\n", partition_name(freshest->dev));
+ }
+ memcpy (sb, freshest->sb, sizeof(*sb));
+
+ /*
+ * at this point we have picked the 'best' superblock
+ * from all available superblocks.
+ * now we validate this superblock and kick out possibly
+ * failed disks.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ /*
+ * Kick all non-fresh devices faulty
+ */
+ __u64 ev1, ev2;
+ ev1 = get_unaligned(&rdev->sb->events);
+ ev2 = get_unaligned(&sb->events);
+ ++ev1;
+ if (ev1 < ev2) {
+ printk("md: kicking non-fresh %s from array!\n",
+ partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ continue;
+ }
+ }
+
+ /*
+ * Fix up changed device names ... but only if this disk has a
+ * recent update time. Use faulty checksum ones too.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ __u64 ev1, ev2, ev3;
+ if (rdev->faulty) { /* REMOVEME */
+ MD_BUG();
+ goto abort;
+ }
+ ev1 = get_unaligned(&rdev->sb->events);
+ ev2 = get_unaligned(&sb->events);
+ ev3 = ev2;
+ --ev3;
+ if ((rdev->dev != rdev->old_dev) &&
+ ((ev1 == ev2) || (ev1 == ev3))) {
+ mdp_disk_t *desc;
+
+ printk("md: device name has changed from %s to %s since last import!\n", partition_name(rdev->old_dev), partition_name(rdev->dev));
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
+ goto abort;
+ }
+ desc = &sb->disks[rdev->desc_nr];
+ if (rdev->old_dev != MKDEV(desc->major, desc->minor)) {
+ MD_BUG();
+ goto abort;
+ }
+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);
+ desc = &rdev->sb->this_disk;
+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);
+ }
+ }
+
+ /*
+ * Remove unavailable and faulty devices ...
+ *
+ * note that if an array becomes completely unrunnable due to
+ * missing devices, we do not write the superblock back, so the
+ * administrator has a chance to fix things up. The removal thus
+ * only happens if it's nonfatal to the contents of the array.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ int found;
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ /*
+ * We kick faulty devices/descriptors immediately.
+ */
+ if (disk_faulty(desc)) {
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr != desc->number)
+ continue;
+ printk("md%d: kicking faulty %s!\n",
+ mdidx(mddev),partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ found = 1;
+ break;
+ }
+ if (!found) {
+ if (dev == MKDEV(0,0))
+ continue;
+ printk("md%d: removing former faulty %s!\n",
+ mdidx(mddev), partition_name(dev));
+ }
+ remove_descriptor(desc, sb);
+ continue;
+ }
+
+ if (dev == MKDEV(0,0))
+ continue;
+ /*
+ * Is this device present in the rdev ring?
+ */
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == desc->number) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ printk("md%d: former device %s is unavailable, removing from array!\n", mdidx(mddev), partition_name(dev));
+ remove_descriptor(desc, sb);
+ }
+
+ /*
+ * Double check wether all devices mentioned in the
+ * superblock are in the rdev ring.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ if (dev == MKDEV(0,0))
+ continue;
+
+ if (disk_faulty(desc)) {
+ MD_BUG();
+ goto abort;
+ }
+
+ rdev = find_rdev(mddev, dev);
+ if (!rdev) {
+ MD_BUG();
+ goto abort;
+ }
+ }
+
+ /*
+ * Do a final reality check.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
+ goto abort;
+ }
+ /*
+ * is the desc_nr unique?
+ */
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
+ if ((rdev2 != rdev) &&
+ (rdev2->desc_nr == rdev->desc_nr)) {
+ MD_BUG();
+ goto abort;
+ }
+ }
+ /*
+ * is the device unique?
+ */
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
+ if ((rdev2 != rdev) &&
+ (rdev2->dev == rdev->dev)) {
+ MD_BUG();
+ goto abort;
+ }
+ }
+ }
+
+ /*
+ * Check if we can support this RAID array
+ */
+ if (sb->major_version != MD_MAJOR_VERSION ||
+ sb->minor_version > MD_MINOR_VERSION) {
+
+ printk (OLD_VERSION, mdidx(mddev), sb->major_version,
+ sb->minor_version, sb->patch_version);
+ goto abort;
+ }
+
+ if ((sb->state != (1 << MD_SB_CLEAN)) && ((sb->level == 1) ||
+ (sb->level == 4) || (sb->level == 5)))
+ printk (NOT_CLEAN_IGNORE, mdidx(mddev));
+
+ return 0;
+abort:
+ return 1;
+}
+
+#undef INCONSISTENT
+#undef OUT_OF_DATE
+#undef OLD_VERSION
+#undef OLD_LEVEL
+
+static int device_size_calculation (mddev_t * mddev)
+{
+ int data_disks = 0, persistent;
+ unsigned int readahead;
+ mdp_super_t *sb = mddev->sb;
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ /*
+ * Do device size calculation. Bail out if too small.
+ * (we have to do this after having validated chunk_size,
+ * because device size has to be modulo chunk_size)
+ */
+ persistent = !mddev->sb->not_persistent;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)
+ continue;
+ if (rdev->size) {
+ MD_BUG();
+ continue;
+ }
+ rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
+ if (rdev->size < sb->chunk_size / 1024) {
+ printk (KERN_WARNING
+ "Dev %s smaller than chunk_size: %dk < %dk\n",
+ partition_name(rdev->dev),
+ rdev->size, sb->chunk_size / 1024);
+ return -EINVAL;
+ }
+ }
+
+ switch (sb->level) {
+ case -3:
+ data_disks = 1;
+ break;
+ case -2:
+ data_disks = 1;
+ break;
+ case -1:
+ zoned_raid_size(mddev);
+ data_disks = 1;
+ break;
+ case 0:
+ zoned_raid_size(mddev);
+ data_disks = sb->raid_disks;
+ break;
+ case 1:
+ data_disks = 1;
+ break;
+ case 4:
+ case 5:
+ data_disks = sb->raid_disks-1;
+ break;
+ default:
+ printk (UNKNOWN_LEVEL, mdidx(mddev), sb->level);
+ goto abort;
+ }
+ if (!md_size[mdidx(mddev)])
+ md_size[mdidx(mddev)] = sb->size * data_disks;
+
+ readahead = MD_READAHEAD;
+ if ((sb->level == 0) || (sb->level == 4) || (sb->level == 5))
+ readahead = mddev->sb->chunk_size * 4 * data_disks;
+ if (readahead < data_disks * MAX_SECTORS*512*2)
+ readahead = data_disks * MAX_SECTORS*512*2;
+ else {
+ if (sb->level == -3)
+ readahead = 0;
+ }
+ md_maxreadahead[mdidx(mddev)] = readahead;
+
+ printk(KERN_INFO "md%d: max total readahead window set to %dk\n",
+ mdidx(mddev), readahead/1024);
+
+ printk(KERN_INFO
+ "md%d: %d data-disks, max readahead per data-disk: %dk\n",
+ mdidx(mddev), data_disks, readahead/data_disks/1024);
+ return 0;
+abort:
+ return 1;
+}
+
+
+#define TOO_BIG_CHUNKSIZE KERN_ERR \
+"too big chunk_size: %d > %d\n"
+
+#define TOO_SMALL_CHUNKSIZE KERN_ERR \
+"too small chunk_size: %d < %ld\n"
+
+#define BAD_CHUNKSIZE KERN_ERR \
+"no chunksize specified, see 'man raidtab'\n"
+
+static int do_md_run (mddev_t * mddev)
+{
+ int pnum, err;
+ int chunk_size;
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+
+ if (!mddev->nb_dev) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ if (mddev->pers)
+ return -EBUSY;
+
+ /*
+ * Resize disks to align partitions size on a given
+ * chunk size.
+ */
+ md_size[mdidx(mddev)] = 0;
+
+ /*
+ * Analyze all RAID superblock(s)
+ */
+ if (analyze_sbs(mddev)) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ chunk_size = mddev->sb->chunk_size;
+ pnum = level_to_pers(mddev->sb->level);
+
+ mddev->param.chunk_size = chunk_size;
+ mddev->param.personality = pnum;
+
+ if (chunk_size > MAX_CHUNK_SIZE) {
+ printk(TOO_BIG_CHUNKSIZE, chunk_size, MAX_CHUNK_SIZE);
+ return -EINVAL;
+ }
+ /*
+ * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
+ */
+ if ( (1 << ffz(~chunk_size)) != chunk_size) {
+ MD_BUG();
+ return -EINVAL;
+ }
+ if (chunk_size < PAGE_SIZE) {
+ printk(TOO_SMALL_CHUNKSIZE, chunk_size, PAGE_SIZE);
+ return -EINVAL;
+ }
+
+ if (pnum >= MAX_PERSONALITY) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ if ((pnum != RAID1) && (pnum != LINEAR) && !chunk_size) {
+ /*
+ * 'default chunksize' in the old md code used to
+ * be PAGE_SIZE, baaad.
+ * we abort here to be on the safe side. We dont
+ * want to continue the bad practice.
+ */
+ printk(BAD_CHUNKSIZE);
+ return -EINVAL;
+ }
+
+ if (!pers[pnum])
+ {
+#ifdef CONFIG_KMOD
+ char module_name[80];
+ sprintf (module_name, "md-personality-%d", pnum);
+ request_module (module_name);
+ if (!pers[pnum])
+#endif
+ return -EINVAL;
+ }
+
+ if (device_size_calculation(mddev))
+ return -EINVAL;
+
+ /*
+ * Drop all container device buffers, from now on
+ * the only valid external interface is through the md
+ * device.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)
+ continue;
+ fsync_dev(rdev->dev);
+ invalidate_buffers(rdev->dev);
+ }
+
+ mddev->pers = pers[pnum];
+
+ err = mddev->pers->run(mddev);
+ if (err) {
+ printk("pers->run() failed ...\n");
+ mddev->pers = NULL;
+ return -EINVAL;
+ }
+
+ mddev->sb->state &= ~(1 << MD_SB_CLEAN);
+ md_update_sb(mddev);
+
+ /*
+ * md_size has units of 1K blocks, which are
+ * twice as large as sectors.
+ */
+ md_hd_struct[mdidx(mddev)].start_sect = 0;
+ md_hd_struct[mdidx(mddev)].nr_sects = md_size[mdidx(mddev)] << 1;
+
+ read_ahead[MD_MAJOR] = 1024;
+ return (0);
+}
+
+#undef TOO_BIG_CHUNKSIZE
+#undef BAD_CHUNKSIZE
+
+#define OUT(x) do { err = (x); goto out; } while (0)
+
+static int restart_array (mddev_t *mddev)
+{
+ int err = 0;
+
+ /*
+ * Complain if it has no devices
+ */
+ if (!mddev->nb_dev)
+ OUT(-ENXIO);
+
+ if (mddev->pers) {
+ if (!mddev->ro)
+ OUT(-EBUSY);
+
+ mddev->ro = 0;
+ set_device_ro(mddev_to_kdev(mddev), 0);
+
+ printk (KERN_INFO
+ "md%d switched to read-write mode.\n", mdidx(mddev));
+ /*
+ * Kick recovery or resync if necessary
+ */
+ md_recover_arrays();
+ if (mddev->pers->restart_resync)
+ mddev->pers->restart_resync(mddev);
+ } else
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
+#define STILL_MOUNTED KERN_WARNING \
+"md: md%d still mounted.\n"
+
+static int do_md_stop (mddev_t * mddev, int ro)
+{
+ int err = 0, resync_interrupted = 0;
+ kdev_t dev = mddev_to_kdev(mddev);
+
+ if (!ro && !fs_may_mount (dev)) {
+ printk (STILL_MOUNTED, mdidx(mddev));
+ OUT(-EBUSY);
+ }
+
+ /*
+ * complain if it's already stopped
+ */
+ if (!mddev->nb_dev)
+ OUT(-ENXIO);
+
+ if (mddev->pers) {
+ /*
+ * It is safe to call stop here, it only frees private
+ * data. Also, it tells us if a device is unstoppable
+ * (eg. resyncing is in progress)
+ */
+ if (mddev->pers->stop_resync)
+ if (mddev->pers->stop_resync(mddev))
+ resync_interrupted = 1;
+
+ if (mddev->recovery_running)
+ md_interrupt_thread(md_recovery_thread);
+
+ /*
+ * This synchronizes with signal delivery to the
+ * resync or reconstruction thread. It also nicely
+ * hangs the process if some reconstruction has not
+ * finished.
+ */
+ down(&mddev->recovery_sem);
+ up(&mddev->recovery_sem);
+
+ /*
+ * sync and invalidate buffers because we cannot kill the
+ * main thread with valid IO transfers still around.
+ * the kernel lock protects us from new requests being
+ * added after invalidate_buffers().
+ */
+ fsync_dev (mddev_to_kdev(mddev));
+ fsync_dev (dev);
+ invalidate_buffers (dev);
+
+ if (ro) {
+ if (mddev->ro)
+ OUT(-ENXIO);
+ mddev->ro = 1;
+ } else {
+ if (mddev->ro)
+ set_device_ro(dev, 0);
+ if (mddev->pers->stop(mddev)) {
+ if (mddev->ro)
+ set_device_ro(dev, 1);
+ OUT(-EBUSY);
+ }
+ if (mddev->ro)
+ mddev->ro = 0;
+ }
+ if (mddev->sb) {
+ /*
+ * mark it clean only if there was no resync
+ * interrupted.
+ */
+ if (!mddev->recovery_running && !resync_interrupted) {
+ printk("marking sb clean...\n");
+ mddev->sb->state |= 1 << MD_SB_CLEAN;
+ }
+ md_update_sb(mddev);
+ }
+ if (ro)
+ set_device_ro(dev, 1);
+ }
+
+ /*
+ * Free resources if final stop
+ */
+ if (!ro) {
+ export_array(mddev);
+ md_size[mdidx(mddev)] = 0;
+ md_hd_struct[mdidx(mddev)].nr_sects = 0;
+ free_mddev(mddev);
+
+ printk (KERN_INFO "md%d stopped.\n", mdidx(mddev));
+ } else
+ printk (KERN_INFO
+ "md%d switched to read-only mode.\n", mdidx(mddev));
+out:
+ return err;
+}
+
+#undef OUT
+
+/*
+ * We have to safely support old arrays too.
+ */
+int detect_old_array (mdp_super_t *sb)
+{
+ if (sb->major_version > 0)
+ return 0;
+ if (sb->minor_version >= 90)
+ return 0;
+
+ return -EINVAL;
+}
+
+
+static void autorun_array (mddev_t *mddev)
+{
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+ int err;
+
+ if (mddev->disks.prev == &mddev->disks) {
+ MD_BUG();
+ return;
+ }
+
+ printk("running: ");
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ printk("<%s>", partition_name(rdev->dev));
+ }
+ printk("\nnow!\n");
+
+ err = do_md_run (mddev);
+ if (err) {
+ printk("do_md_run() returned %d\n", err);
+ /*
+ * prevent the writeback of an unrunnable array
+ */
+ mddev->sb_dirty = 0;
+ do_md_stop (mddev, 0);
+ }
+}
+
+/*
+ * lets try to run arrays based on all disks that have arrived
+ * until now. (those are in the ->pending list)
+ *
+ * the method: pick the first pending disk, collect all disks with
+ * the same UUID, remove all from the pending list and put them into
+ * the 'same_array' list. Then order this list based on superblock
+ * update time (freshest comes first), kick out 'old' disks and
+ * compare superblocks. If everything's fine then run it.
+ */
+static void autorun_devices (void)
+{
+ struct md_list_head candidates;
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev0, *rdev;
+ mddev_t *mddev;
+ kdev_t md_kdev;
+
+
+ printk("autorun ...\n");
+ while (pending_raid_disks.next != &pending_raid_disks) {
+ rdev0 = md_list_entry(pending_raid_disks.next,
+ mdk_rdev_t, pending);
+
+ printk("considering %s ...\n", partition_name(rdev0->dev));
+ MD_INIT_LIST_HEAD(&candidates);
+ ITERATE_RDEV_PENDING(rdev,tmp) {
+ if (uuid_equal(rdev0, rdev)) {
+ if (!sb_equal(rdev0->sb, rdev->sb)) {
+ printk("%s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+ continue;
+ }
+ printk(" adding %s ...\n", partition_name(rdev->dev));
+ md_list_del(&rdev->pending);
+ md_list_add(&rdev->pending, &candidates);
+ }
+ }
+ /*
+ * now we have a set of devices, with all of them having
+ * mostly sane superblocks. It's time to allocate the
+ * mddev.
+ */
+ md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);
+ mddev = kdev_to_mddev(md_kdev);
+ if (mddev) {
+ printk("md%d already running, cannot run %s\n",
+ mdidx(mddev), partition_name(rdev0->dev));
+ ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)
+ export_rdev(rdev);
+ continue;
+ }
+ mddev = alloc_mddev(md_kdev);
+ printk("created md%d\n", mdidx(mddev));
+ ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {
+ bind_rdev_to_array(rdev, mddev);
+ md_list_del(&rdev->pending);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+ }
+ autorun_array(mddev);
+ }
+ printk("... autorun DONE.\n");
+}
+
+/*
+ * import RAID devices based on one partition
+ * if possible, the array gets run as well.
+ */
+
+#define BAD_VERSION KERN_ERR \
+"md: %s has RAID superblock version 0.%d, autodetect needs v0.90 or higher\n"
+
+#define OUT_OF_MEM KERN_ALERT \
+"md: out of memory.\n"
+
+#define NO_DEVICE KERN_ERR \
+"md: disabled device %s\n"
+
+#define AUTOADD_FAILED KERN_ERR \
+"md: auto-adding devices to md%d FAILED (error %d).\n"
+
+#define AUTOADD_FAILED_USED KERN_ERR \
+"md: cannot auto-add device %s to md%d, already used.\n"
+
+#define AUTORUN_FAILED KERN_ERR \
+"md: auto-running md%d FAILED (error %d).\n"
+
+#define MDDEV_BUSY KERN_ERR \
+"md: cannot auto-add to md%d, already running.\n"
+
+#define AUTOADDING KERN_INFO \
+"md: auto-adding devices to md%d, based on %s's superblock.\n"
+
+#define AUTORUNNING KERN_INFO \
+"md: auto-running md%d.\n"
+
+static int autostart_array (kdev_t startdev)
+{
+ int err = -EINVAL, i;
+ mdp_super_t *sb = NULL;
+ mdk_rdev_t *start_rdev = NULL, *rdev;
+
+ if (md_import_device(startdev, 1)) {
+ printk("could not import %s!\n", partition_name(startdev));
+ goto abort;
+ }
+
+ start_rdev = find_rdev_all(startdev);
+ if (!start_rdev) {
+ MD_BUG();
+ goto abort;
+ }
+ if (start_rdev->faulty) {
+ printk("can not autostart based on faulty %s!\n",
+ partition_name(startdev));
+ goto abort;
+ }
+ md_list_add(&start_rdev->pending, &pending_raid_disks);
+
+ sb = start_rdev->sb;
+
+ err = detect_old_array(sb);
+ if (err) {
+ printk("array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");
+ goto abort;
+ }
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ if (dev == MKDEV(0,0))
+ continue;
+ if (dev == startdev)
+ continue;
+ if (md_import_device(dev, 1)) {
+ printk("could not import %s, trying to run array nevertheless.\n", partition_name(dev));
+ continue;
+ }
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ goto abort;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
+ }
+
+ /*
+ * possibly return codes
+ */
+ autorun_devices();
+ return 0;
+
+abort:
+ if (start_rdev)
+ export_rdev(start_rdev);
+ return err;
+}
+
+#undef BAD_VERSION
+#undef OUT_OF_MEM
+#undef NO_DEVICE
+#undef AUTOADD_FAILED_USED
+#undef AUTOADD_FAILED
+#undef AUTORUN_FAILED
+#undef AUTOADDING
+#undef AUTORUNNING
+
+struct {
+ int set;
+ int noautodetect;
+
+} raid_setup_args md__initdata = { 0, 0 };
+
+/*
+ * Searches all registered partitions for autorun RAID arrays
+ * at boot time.
+ */
+md__initfunc(void autodetect_raid(void))
+{
+#ifdef CONFIG_AUTODETECT_RAID
+ struct gendisk *disk;
+ mdk_rdev_t *rdev;
+ int i;
+
+ if (raid_setup_args.noautodetect) {
+ printk(KERN_INFO "skipping autodetection of RAID arrays\n");
+ return;
+ }
+ printk(KERN_INFO "autodetecting RAID arrays\n");
+
+ for (disk = gendisk_head ; disk ; disk = disk->next) {
+ for (i = 0; i < disk->max_p*disk->max_nr; i++) {
+ kdev_t dev = MKDEV(disk->major,i);
+
+ if (disk->part[i].type == LINUX_OLD_RAID_PARTITION) {
+ printk(KERN_ALERT
+"md: %s's partition type has to be changed from type 0x86 to type 0xfd\n"
+" to maintain interoperability with other OSs! Autodetection support for\n"
+" type 0x86 will be deleted after some migration timeout. Sorry.\n",
+ partition_name(dev));
+ disk->part[i].type = LINUX_RAID_PARTITION;
+ }
+ if (disk->part[i].type != LINUX_RAID_PARTITION)
+ continue;
+
+ if (md_import_device(dev,1)) {
+ printk(KERN_ALERT "could not import %s!\n",
+ partition_name(dev));
+ continue;
+ }
+ /*
+ * Sanity checks:
+ */
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ continue;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ continue;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
+ }
+ }
+
+ autorun_devices();
+#endif
+}
+
+static int get_version (void * arg)
+{
+ mdu_version_t ver;
+
+ ver.major = MD_MAJOR_VERSION;
+ ver.minor = MD_MINOR_VERSION;
+ ver.patchlevel = MD_PATCHLEVEL_VERSION;
+
+ if (md_copy_to_user(arg, &ver, sizeof(ver)))
+ return -EFAULT;
+
+ return 0;
+}
+
+#define SET_FROM_SB(x) info.x = mddev->sb->x
+static int get_array_info (mddev_t * mddev, void * arg)
+{
+ mdu_array_info_t info;
+
+ if (!mddev->sb)
+ return -EINVAL;
+
+ SET_FROM_SB(major_version);
+ SET_FROM_SB(minor_version);
+ SET_FROM_SB(patch_version);
+ SET_FROM_SB(ctime);
+ SET_FROM_SB(level);
+ SET_FROM_SB(size);
+ SET_FROM_SB(nr_disks);
+ SET_FROM_SB(raid_disks);
+ SET_FROM_SB(md_minor);
+ SET_FROM_SB(not_persistent);
+
+ SET_FROM_SB(utime);
+ SET_FROM_SB(state);
+ SET_FROM_SB(active_disks);
+ SET_FROM_SB(working_disks);
+ SET_FROM_SB(failed_disks);
+ SET_FROM_SB(spare_disks);
+
+ SET_FROM_SB(layout);
+ SET_FROM_SB(chunk_size);
+
+ if (md_copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+
+ return 0;
+}
+#undef SET_FROM_SB
+
+#define SET_FROM_SB(x) info.x = mddev->sb->disks[nr].x
+static int get_disk_info (mddev_t * mddev, void * arg)
+{
+ mdu_disk_info_t info;
+ unsigned int nr;
+
+ if (!mddev->sb)
+ return -EINVAL;
+
+ if (md_copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ nr = info.number;
+ if (nr >= mddev->sb->nr_disks)
+ return -EINVAL;
+
+ SET_FROM_SB(major);
+ SET_FROM_SB(minor);
+ SET_FROM_SB(raid_disk);
+ SET_FROM_SB(state);
+
+ if (md_copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+
+ return 0;
+}
+#undef SET_FROM_SB
+
+#define SET_SB(x) mddev->sb->disks[nr].x = info.x
+
+static int add_new_disk (mddev_t * mddev, void * arg)
+{
+ int err, size, persistent;
+ mdu_disk_info_t info;
+ mdk_rdev_t *rdev;
+ unsigned int nr;
+ kdev_t dev;
+
+ if (!mddev->sb)
+ return -EINVAL;
+
+ if (md_copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ nr = info.number;
+ if (nr >= mddev->sb->nr_disks)
+ return -EINVAL;
+
+ dev = MKDEV(info.major,info.minor);
+
+ if (find_rdev_all(dev)) {
+ printk("device %s already used in a RAID array!\n",
+ partition_name(dev));
+ return -EBUSY;
+ }
+
+ SET_SB(number);
+ SET_SB(major);
+ SET_SB(minor);
+ SET_SB(raid_disk);
+ SET_SB(state);
+
+ if ((info.state & (1<<MD_DISK_FAULTY))==0) {
+ err = md_import_device (dev, 0);
+ if (err) {
+ printk("md: error, md_import_device() returned %d\n", err);
+ return -EINVAL;
+ }
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ rdev->old_dev = dev;
+ rdev->desc_nr = info.number;
+
+ bind_rdev_to_array(rdev, mddev);
+
+ persistent = !mddev->sb->not_persistent;
+ if (!persistent)
+ printk("nonpersistent superblock ...\n");
+ if (!mddev->sb->chunk_size)
+ printk("no chunksize?\n");
+
+ size = calc_dev_size(dev, mddev, persistent);
+ rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
+
+ if (!mddev->sb->size || (mddev->sb->size > size))
+ mddev->sb->size = size;
+ }
+
+ /*
+ * sync all other superblocks with the main superblock
+ */
+ sync_sbs(mddev);
+
+ return 0;
+}
+#undef SET_SB
+
+static int hot_remove_disk (mddev_t * mddev, kdev_t dev)
+{
+ int err;
+ mdk_rdev_t *rdev;
+ mdp_disk_t *disk;
+
+ if (!mddev->pers)
+ return -ENODEV;
+
+ printk("trying to remove %s from md%d ... \n",
+ partition_name(dev), mdidx(mddev));
+
+ if (!mddev->pers->diskop) {
+ printk("md%d: personality does not support diskops!\n",
+ mdidx(mddev));
+ return -EINVAL;
+ }
+
+ rdev = find_rdev(mddev, dev);
+ if (!rdev)
+ return -ENXIO;
+
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
+ return -EINVAL;
+ }
+ disk = &mddev->sb->disks[rdev->desc_nr];
+ if (disk_active(disk))
+ goto busy;
+ if (disk_removed(disk)) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ err = mddev->pers->diskop(mddev, &disk, DISKOP_HOT_REMOVE_DISK);
+ if (err == -EBUSY)
+ goto busy;
+ if (err) {
+ MD_BUG();
+ return -EINVAL;
+ }
+
+ remove_descriptor(disk, mddev->sb);
+ kick_rdev_from_array(rdev);
+ mddev->sb_dirty = 1;
+ md_update_sb(mddev);
+
+ return 0;
+busy:
+ printk("cannot remove active disk %s from md%d ... \n",
+ partition_name(dev), mdidx(mddev));
+ return -EBUSY;
+}
+
+static int hot_add_disk (mddev_t * mddev, kdev_t dev)
+{
+ int i, err, persistent;
+ unsigned int size;
+ mdk_rdev_t *rdev;
+ mdp_disk_t *disk;
+
+ if (!mddev->pers)
+ return -ENODEV;
+
+ printk("trying to hot-add %s to md%d ... \n",
+ partition_name(dev), mdidx(mddev));
+
+ if (!mddev->pers->diskop) {
+ printk("md%d: personality does not support diskops!\n",
+ mdidx(mddev));
+ return -EINVAL;
+ }
+
+ persistent = !mddev->sb->not_persistent;
+ size = calc_dev_size(dev, mddev, persistent);
+
+ if (size < mddev->sb->size) {
+ printk("md%d: disk size %d blocks < array size %d\n",
+ mdidx(mddev), size, mddev->sb->size);
+ return -ENOSPC;
+ }
+
+ rdev = find_rdev(mddev, dev);
+ if (rdev)
+ return -EBUSY;
+
+ err = md_import_device (dev, 0);
+ if (err) {
+ printk("md: error, md_import_device() returned %d\n", err);
+ return -EINVAL;
+ }
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ return -EINVAL;
+ }
+ if (rdev->faulty) {
+ printk("md: can not hot-add faulty %s disk to md%d!\n",
+ partition_name(dev), mdidx(mddev));
+ err = -EINVAL;
+ goto abort_export;
+ }
+ bind_rdev_to_array(rdev, mddev);
+
+ /*
+ * The rest should better be atomic, we can have disk failures
+ * noticed in interrupt contexts ...
+ */
+ cli();
+ rdev->old_dev = dev;
+ rdev->size = size;
+ rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
+
+ disk = mddev->sb->disks + mddev->sb->raid_disks;
+ for (i = mddev->sb->raid_disks; i < MD_SB_DISKS; i++) {
+ disk = mddev->sb->disks + i;
+
+ if (!disk->major && !disk->minor)
+ break;
+ if (disk_removed(disk))
+ break;
+ }
+ if (i == MD_SB_DISKS) {
+ sti();
+ printk("md%d: can not hot-add to full array!\n", mdidx(mddev));
+ err = -EBUSY;
+ goto abort_unbind_export;
+ }
+
+ if (disk_removed(disk)) {
+ /*
+ * reuse slot
+ */
+ if (disk->number != i) {
+ sti();
+ MD_BUG();
+ err = -EINVAL;
+ goto abort_unbind_export;
+ }
+ } else {
+ disk->number = i;
+ }
+
+ disk->raid_disk = disk->number;
+ disk->major = MAJOR(dev);
+ disk->minor = MINOR(dev);
+
+ if (mddev->pers->diskop(mddev, &disk, DISKOP_HOT_ADD_DISK)) {
+ sti();
+ MD_BUG();
+ err = -EINVAL;
+ goto abort_unbind_export;
+ }
+
+ mark_disk_spare(disk);
+ mddev->sb->nr_disks++;
+ mddev->sb->spare_disks++;
+ mddev->sb->working_disks++;
+
+ mddev->sb_dirty = 1;
+
+ sti();
+ md_update_sb(mddev);
+
+ /*
+ * Kick recovery, maybe this spare has to be added to the
+ * array immediately.
+ */
+ md_recover_arrays();
+
+ return 0;
+
+abort_unbind_export:
+ unbind_rdev_from_array(rdev);
+
+abort_export:
+ export_rdev(rdev);
+ return err;
+}
+
+#define SET_SB(x) mddev->sb->x = info.x
+static int set_array_info (mddev_t * mddev, void * arg)
+{
+ mdu_array_info_t info;
+
+ if (mddev->sb) {
+ printk("array md%d already has a superblock!\n",
+ mdidx(mddev));
+ return -EBUSY;
+ }
+
+ if (md_copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ if (alloc_array_sb(mddev))
+ return -ENOMEM;
+
+ mddev->sb->major_version = MD_MAJOR_VERSION;
+ mddev->sb->minor_version = MD_MINOR_VERSION;
+ mddev->sb->patch_version = MD_PATCHLEVEL_VERSION;
+ mddev->sb->ctime = CURRENT_TIME;
+
+ SET_SB(level);
+ SET_SB(size);
+ SET_SB(nr_disks);
+ SET_SB(raid_disks);
+ SET_SB(md_minor);
+ SET_SB(not_persistent);
+
+ SET_SB(state);
+ SET_SB(active_disks);
+ SET_SB(working_disks);
+ SET_SB(failed_disks);
+ SET_SB(spare_disks);
+
+ SET_SB(layout);
+ SET_SB(chunk_size);
+
+ mddev->sb->md_magic = MD_SB_MAGIC;
+
+ /*
+ * Generate a 128 bit UUID
+ */
+ get_random_bytes(&mddev->sb->set_uuid0, 4);
+ get_random_bytes(&mddev->sb->set_uuid1, 4);
+ get_random_bytes(&mddev->sb->set_uuid2, 4);
+ get_random_bytes(&mddev->sb->set_uuid3, 4);
+
+ return 0;
+}
+#undef SET_SB
+
+static int set_disk_info (mddev_t * mddev, void * arg)
+{
+ printk("not yet");
+ return -EINVAL;
+}
+
+static int clear_array (mddev_t * mddev)
+{
+ printk("not yet");
+ return -EINVAL;
+}
+
+static int write_raid_info (mddev_t * mddev)
+{
+ printk("not yet");
+ return -EINVAL;
+}
+
+static int protect_array (mddev_t * mddev)
+{
+ printk("not yet");
+ return -EINVAL;
+}
+
+static int unprotect_array (mddev_t * mddev)
+{
+ printk("not yet");
+ return -EINVAL;
+}
+
+static int set_disk_faulty (mddev_t *mddev, kdev_t dev)
+{
+ int ret;
+
+ fsync_dev(mddev_to_kdev(mddev));
+ ret = md_error(mddev_to_kdev(mddev), dev);
+ return ret;
+}
+
+static int md_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ unsigned int minor;
+ int err = 0;
+ struct hd_geometry *loc = (struct hd_geometry *) arg;
+ mddev_t *mddev = NULL;
+ kdev_t dev;
+
+ if (!md_capable_admin())
+ return -EACCES;
+
+ dev = inode->i_rdev;
+ minor = MINOR(dev);
+ if (minor >= MAX_MD_DEVS)
+ return -EINVAL;
+
+ /*
+ * Commands dealing with the RAID driver but not any
+ * particular array:
+ */
+ switch (cmd)
+ {
+ case RAID_VERSION:
+ err = get_version((void *)arg);
+ goto done;
+
+ case PRINT_RAID_DEBUG:
+ err = 0;
+ md_print_devices();
+ goto done_unlock;
+
+ case BLKGETSIZE: /* Return device size */
+ if (!arg) {
+ err = -EINVAL;
+ goto abort;
+ }
+ err = md_put_user(md_hd_struct[minor].nr_sects,
+ (long *) arg);
+ goto done;
+
+ case BLKFLSBUF:
+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ goto done;
+
+ case BLKRASET:
+ if (arg > 0xff) {
+ err = -EINVAL;
+ goto abort;
+ }
+ read_ahead[MAJOR(dev)] = arg;
+ goto done;
+
+ case BLKRAGET:
+ if (!arg) {
+ err = -EINVAL;
+ goto abort;
+ }
+ err = md_put_user (read_ahead[
+ MAJOR(dev)], (long *) arg);
+ goto done;
+ default:
+ }
+
+ /*
+ * Commands creating/starting a new array:
+ */
+
+ mddev = kdev_to_mddev(dev);
+
+ switch (cmd)
+ {
+ case SET_ARRAY_INFO:
+ case START_ARRAY:
+ if (mddev) {
+ printk("array md%d already exists!\n",
+ mdidx(mddev));
+ err = -EEXIST;
+ goto abort;
+ }
+ default:
+ }
+
+ switch (cmd)
+ {
+ case SET_ARRAY_INFO:
+ mddev = alloc_mddev(dev);
+ if (!mddev) {
+ err = -ENOMEM;
+ goto abort;
+ }
+ /*
+ * alloc_mddev() should possibly self-lock.
+ */
+ err = lock_mddev(mddev);
+ if (err) {
+ printk("ioctl, reason %d, cmd %d\n", err, cmd);
+ goto abort;
+ }
+ err = set_array_info(mddev, (void *)arg);
+ if (err) {
+ printk("couldnt set array info. %d\n", err);
+ goto abort;
+ }
+ goto done_unlock;
+
+ case START_ARRAY:
+ /*
+ * possibly make it lock the array ...
+ */
+ err = autostart_array((kdev_t)arg);
+ if (err) {
+ printk("autostart %s failed!\n",
+ partition_name((kdev_t)arg));
+ goto abort;
+ }
+ goto done;
+
+ default:
+ }
+
+ /*
+ * Commands querying/configuring an existing array:
+ */
+
+ if (!mddev) {
+ err = -ENODEV;
+ goto abort;
+ }
+ err = lock_mddev(mddev);
+ if (err) {
+ printk("ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
+ goto abort;
+ }
+
+ /*
+ * Commands even a read-only array can execute:
+ */
+ switch (cmd)
+ {
+ case GET_ARRAY_INFO:
+ err = get_array_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case GET_DISK_INFO:
+ err = get_disk_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case RESTART_ARRAY_RW:
+ err = restart_array(mddev);
+ goto done_unlock;
+
+ case STOP_ARRAY:
+ err = do_md_stop (mddev, 0);
+ goto done_unlock;
+
+ case STOP_ARRAY_RO:
+ err = do_md_stop (mddev, 1);
+ goto done_unlock;
+
+ /*
+ * We have a problem here : there is no easy way to give a CHS
+ * virtual geometry. We currently pretend that we have a 2 heads
+ * 4 sectors (with a BIG number of cylinders...). This drives
+ * dosfs just mad... ;-)
+ */
+ case HDIO_GETGEO:
+ if (!loc) {
+ err = -EINVAL;
+ goto abort_unlock;
+ }
+ err = md_put_user (2, (char *) &loc->heads);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (4, (char *) &loc->sectors);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (md_hd_struct[mdidx(mddev)].nr_sects/8,
+ (short *) &loc->cylinders);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (md_hd_struct[minor].start_sect,
+ (long *) &loc->start);
+ goto done_unlock;
+ }
+
+ /*
+ * The remaining ioctls are changing the state of the
+ * superblock, so we do not allow read-only arrays
+ * here:
+ */
+ if (mddev->ro) {
+ err = -EROFS;
+ goto abort_unlock;
+ }
+
+ switch (cmd)
+ {
+ case CLEAR_ARRAY:
+ err = clear_array(mddev);
+ goto done_unlock;
+
+ case ADD_NEW_DISK:
+ err = add_new_disk(mddev, (void *)arg);
+ goto done_unlock;
+
+ case HOT_REMOVE_DISK:
+ err = hot_remove_disk(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case HOT_ADD_DISK:
+ err = hot_add_disk(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case SET_DISK_INFO:
+ err = set_disk_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case WRITE_RAID_INFO:
+ err = write_raid_info(mddev);
+ goto done_unlock;
+
+ case UNPROTECT_ARRAY:
+ err = unprotect_array(mddev);
+ goto done_unlock;
+
+ case PROTECT_ARRAY:
+ err = protect_array(mddev);
+ goto done_unlock;
+
+ case SET_DISK_FAULTY:
+ err = set_disk_faulty(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case RUN_ARRAY:
+ {
+ mdu_param_t param;
+
+ err = md_copy_from_user(&param, (mdu_param_t *)arg,
+ sizeof(param));
+ if (err)
+ goto abort_unlock;
+
+ err = do_md_run (mddev);
+ /*
+ * we have to clean up the mess if
+ * the array cannot be run for some
+ * reason ...
+ */
+ if (err) {
+ mddev->sb_dirty = 0;
+ do_md_stop (mddev, 0);
+ }
+ goto done_unlock;
+ }
+
+ default:
+ printk(KERN_WARNING "%s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
+ err = -EINVAL;
+ goto abort_unlock;
+ }
+
+done_unlock:
+abort_unlock:
+ if (mddev)
+ unlock_mddev(mddev);
+ else
+ printk("huh11?\n");
+
+ return err;
+done:
+ if (err)
+ printk("huh12?\n");
+abort:
+ return err;
+}
+
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,0)
+
+static int md_open (struct inode *inode, struct file *file)
+{
+ /*
+ * Always succeed
+ */
+ return (0);
+}
+
+static void md_release (struct inode *inode, struct file *file)
+{
+ sync_dev(inode->i_rdev);
+}
+
+
+static int md_read (struct inode *inode, struct file *file,
+ char *buf, int count)
+{
+ mddev_t *mddev = kdev_to_mddev(MD_FILE_TO_INODE(file)->i_rdev);
+
+ if (!mddev || !mddev->pers)
+ return -ENXIO;
+
+ return block_read (inode, file, buf, count);
+}
+
+static int md_write (struct inode *inode, struct file *file,
+ const char *buf, int count)
+{
+ mddev_t *mddev = kdev_to_mddev(MD_FILE_TO_INODE(file)->i_rdev);
+
+ if (!mddev || !mddev->pers)
+ return -ENXIO;
+
+ return block_write (inode, file, buf, count);
+}
+
+static struct file_operations md_fops=
+{
+ NULL,
+ md_read,
+ md_write,
+ NULL,
+ NULL,
+ md_ioctl,
+ NULL,
+ md_open,
+ md_release,
+ block_fsync
+};
+
+#else
+
+static int md_open (struct inode *inode, struct file *file)
+{
+ /*
+ * Always succeed
+ */
+ return (0);
+}
+
+static int md_release (struct inode *inode, struct file *file)
+{
+ sync_dev(inode->i_rdev);
+ return 0;
+}
+
+static ssize_t md_read (struct file *file, char *buf, size_t count,
+ loff_t *ppos)
+{
+ mddev_t *mddev = kdev_to_mddev(MD_FILE_TO_INODE(file)->i_rdev);
+
+ if (!mddev || !mddev->pers)
+ return -ENXIO;
+
+ return block_read(file, buf, count, ppos);
+}
+
+static ssize_t md_write (struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
+{
+ mddev_t *mddev = kdev_to_mddev(MD_FILE_TO_INODE(file)->i_rdev);
+
+ if (!mddev || !mddev->pers)
+ return -ENXIO;
+
+ return block_write(file, buf, count, ppos);
+}
+
+static struct file_operations md_fops=
+{
+ NULL,
+ md_read,
+ md_write,
+ NULL,
+ NULL,
+ md_ioctl,
+ NULL,
+ md_open,
+ NULL,
+ md_release,
+ block_fsync
+};
+
+#endif
+
+int md_map (kdev_t dev, kdev_t *rdev,
+ unsigned long *rsector, unsigned long size)
+{
+ int err;
+ mddev_t *mddev = kdev_to_mddev(dev);
+
+ if (!mddev || !mddev->pers) {
+ err = -ENXIO;
+ goto out;
+ }
+
+ err = mddev->pers->map(mddev, dev, rdev, rsector, size);
+out:
+ return err;
+}
+
+int md_make_request (struct buffer_head * bh, int rw)
+{
+ int err;
+ mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
+
+ if (!mddev || !mddev->pers) {
+ err = -ENXIO;
+ goto out;
+ }
+
+ if (mddev->pers->make_request) {
+ if (buffer_locked(bh)) {
+ err = 0;
+ goto out;
+ }
+ set_bit(BH_Lock, &bh->b_state);
+ if (rw == WRITE || rw == WRITEA) {
+ if (!buffer_dirty(bh)) {
+ bh->b_end_io(bh, buffer_uptodate(bh));
+ err = 0;
+ goto out;
+ }
+ }
+ if (rw == READ || rw == READA) {
+ if (buffer_uptodate(bh)) {
+ bh->b_end_io(bh, buffer_uptodate(bh));
+ err = 0;
+ goto out;
+ }
+ }
+ err = mddev->pers->make_request(mddev, rw, bh);
+ } else {
+ make_request (MAJOR(bh->b_rdev), rw, bh);
+ err = 0;
+ }
+out:
+ return err;
+}
+
+static void do_md_request (void)
+{
+ printk(KERN_ALERT "Got md request, not good...");
+ return;
+}
+
+int md_thread(void * arg)
+{
+ mdk_thread_t *thread = arg;
+
+ md_lock_kernel();
+ exit_mm(current);
+ exit_files(current);
+ exit_fs(current);
+
+ /*
+ * Detach thread
+ */
+ sys_setsid();
+ sprintf(current->comm, thread->name);
+ md_init_signals();
+ md_flush_signals();
+ thread->tsk = current;
+
+ /*
+ * md_thread is a 'system-thread', it's priority should be very
+ * high. We avoid resource deadlocks individually in each
+ * raid personality. (RAID5 does preallocation) We also use RR and
+ * the very same RT priority as kswapd, thus we will never get
+ * into a priority inversion deadlock.
+ *
+ * we definitely have to have equal or higher priority than
+ * bdflush, otherwise bdflush will deadlock if there are too
+ * many dirty RAID5 blocks.
+ */
+ current->policy = SCHED_OTHER;
+ current->priority = 40;
+
+ up(thread->sem);
+
+ for (;;) {
+ cli();
+ if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
+ if (!thread->run)
+ break;
+ interruptible_sleep_on(&thread->wqueue);
+ }
+ sti();
+ clear_bit(THREAD_WAKEUP, &thread->flags);
+ if (thread->run) {
+ thread->run(thread->data);
+ run_task_queue(&tq_disk);
+ }
+ if (md_signal_pending(current)) {
+ printk("%8s(%d) flushing signals.\n", current->comm,
+ current->pid);
+ md_flush_signals();
+ }
+ }
+ sti();
+ up(thread->sem);
+ return 0;
+}
+
+void md_wakeup_thread(mdk_thread_t *thread)
+{
+ set_bit(THREAD_WAKEUP, &thread->flags);
+ wake_up(&thread->wqueue);
+}
+
+mdk_thread_t *md_register_thread (void (*run) (void *),
+ void *data, const char *name)
+{
+ mdk_thread_t *thread;
+ int ret;
+ struct semaphore sem = MUTEX_LOCKED;
+
+ thread = (mdk_thread_t *) kmalloc
+ (sizeof(mdk_thread_t), GFP_KERNEL);
+ if (!thread)
+ return NULL;
+
+ memset(thread, 0, sizeof(mdk_thread_t));
+ init_waitqueue(&thread->wqueue);
+
+ thread->sem = &sem;
+ thread->run = run;
+ thread->data = data;
+ thread->name = name;
+ ret = kernel_thread(md_thread, thread, 0);
+ if (ret < 0) {
+ kfree(thread);
+ return NULL;
+ }
+ down(&sem);
+ return thread;
+}
+
+void md_interrupt_thread (mdk_thread_t *thread)
+{
+ if (!thread->tsk) {
+ MD_BUG();
+ return;
+ }
+ printk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+ send_sig(SIGKILL, thread->tsk, 1);
+}
+
+void md_unregister_thread (mdk_thread_t *thread)
+{
+ struct semaphore sem = MUTEX_LOCKED;
+
+ thread->sem = &sem;
+ thread->run = NULL;
+ thread->name = NULL;
+ if (!thread->tsk) {
+ MD_BUG();
+ return;
+ }
+ md_interrupt_thread(thread);
+ down(&sem);
+}
+
+void md_recover_arrays (void)
+{
+ if (!md_recovery_thread) {
+ MD_BUG();
+ return;
+ }
+ md_wakeup_thread(md_recovery_thread);
+}
+
+
+int md_error (kdev_t dev, kdev_t rdev)
+{
+ mddev_t *mddev = kdev_to_mddev(dev);
+ mdk_rdev_t * rrdev;
+ int rc;
+
+ if (!mddev) {
+ MD_BUG();
+ return 0;
+ }
+ rrdev = find_rdev(mddev, rdev);
+ mark_rdev_faulty(rrdev);
+ /*
+ * if recovery was running, stop it now.
+ */
+ if (mddev->pers->stop_resync)
+ mddev->pers->stop_resync(mddev);
+ if (mddev->recovery_running)
+ md_interrupt_thread(md_recovery_thread);
+ if (mddev->pers->error_handler) {
+ rc = mddev->pers->error_handler(mddev, rdev);
+ md_recover_arrays();
+ return rc;
+ }
+#if 0
+ /*
+ * Drop all buffers in the failed array.
+ * _not_. This is called from IRQ handlers ...
+ */
+ invalidate_buffers(rdev);
+#endif
+ return 0;
+}
+
+static int status_unused (char * page)
+{
+ int sz = 0, i = 0;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+
+ sz += sprintf(page + sz, "unused devices: ");
+
+ ITERATE_RDEV_ALL(rdev,tmp) {
+ if (!rdev->same_set.next && !rdev->same_set.prev) {
+ /*
+ * The device is not yet used by any array.
+ */
+ i++;
+ sz += sprintf(page + sz, "%s ",
+ partition_name(rdev->dev));
+ }
+ }
+ if (!i)
+ sz += sprintf(page + sz, "<none>");
+
+ sz += sprintf(page + sz, "\n");
+ return sz;
+}
+
+
+static int status_resync (char * page, mddev_t * mddev)
+{
+ int sz = 0;
+ unsigned int blocksize, max_blocks, resync, res, dt, tt, et;
+
+ resync = mddev->curr_resync;
+ blocksize = blksize_size[MD_MAJOR][mdidx(mddev)];
+ max_blocks = blk_size[MD_MAJOR][mdidx(mddev)] / (blocksize >> 10);
+
+ /*
+ * Should not happen.
+ */
+ if (!max_blocks) {
+ MD_BUG();
+ return 0;
+ }
+ res = resync*100/max_blocks;
+ if (!mddev->recovery_running)
+ /*
+ * true resync
+ */
+ sz += sprintf(page + sz, " resync=%u%%", res);
+ else
+ /*
+ * recovery ...
+ */
+ sz += sprintf(page + sz, " recovery=%u%%", res);
+
+ /*
+ * We do not want to overflow, so the order of operands and
+ * the * 100 / 100 trick are important. We do a +1 to be
+ * safe against division by zero. We only estimate anyway.
+ *
+ * dt: time until now
+ * tt: total time
+ * et: estimated finish time
+ */
+ dt = ((jiffies - mddev->resync_start) / HZ);
+ tt = (dt * (max_blocks / (resync/100+1)))/100;
+ if (tt > dt)
+ et = tt - dt;
+ else
+ /*
+ * ignore rounding effects near finish time
+ */
+ et = 0;
+
+ sz += sprintf(page + sz, " finish=%u.%umin", et / 60, (et % 60)/6);
+
+ return sz;
+}
+
+int get_md_status (char *page)
+{
+ int sz = 0, j, size;
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev;
+ mddev_t *mddev;
+
+ sz += sprintf(page + sz, "Personalities : ");
+ for (j = 0; j < MAX_PERSONALITY; j++)
+ if (pers[j])
+ sz += sprintf(page+sz, "[%s] ", pers[j]->name);
+
+ sz += sprintf(page+sz, "\n");
+
+
+ sz += sprintf(page+sz, "read_ahead ");
+ if (read_ahead[MD_MAJOR] == INT_MAX)
+ sz += sprintf(page+sz, "not set\n");
+ else
+ sz += sprintf(page+sz, "%d sectors\n", read_ahead[MD_MAJOR]);
+
+ ITERATE_MDDEV(mddev,tmp) {
+ sz += sprintf(page + sz, "md%d : %sactive", mdidx(mddev),
+ mddev->pers ? "" : "in");
+ if (mddev->pers) {
+ if (mddev->ro)
+ sz += sprintf(page + sz, " (read-only)");
+ sz += sprintf(page + sz, " %s", mddev->pers->name);
+ }
+
+ size = 0;
+ ITERATE_RDEV(mddev,rdev,tmp2) {
+ sz += sprintf(page + sz, " %s[%d]",
+ partition_name(rdev->dev), rdev->desc_nr);
+ if (rdev->faulty) {
+ sz += sprintf(page + sz, "(F)");
+ continue;
+ }
+ size += rdev->size;
+ }
+
+ if (mddev->nb_dev) {
+ if (mddev->pers)
+ sz += sprintf(page + sz, " %d blocks",
+ md_size[mdidx(mddev)]);
+ else
+ sz += sprintf(page + sz, " %d blocks", size);
+ }
+
+ if (!mddev->pers) {
+ sz += sprintf(page+sz, "\n");
+ continue;
+ }
+
+ sz += mddev->pers->status (page+sz, mddev);
+
+ if (mddev->curr_resync)
+ sz += status_resync (page+sz, mddev);
+ else {
+ if (md_atomic_read(&mddev->resync_sem.count) != 1)
+ sz += sprintf(page + sz, " resync=DELAYED");
+ }
+ sz += sprintf(page + sz, "\n");
+ }
+ sz += status_unused (page + sz);
+
+ return (sz);
+}
+
+int register_md_personality (int pnum, mdk_personality_t *p)
+{
+ if (pnum >= MAX_PERSONALITY)
+ return -EINVAL;
+
+ if (pers[pnum])
+ return -EBUSY;
+
+ pers[pnum] = p;
+ printk(KERN_INFO "%s personality registered\n", p->name);
+ return 0;
+}
+
+int unregister_md_personality (int pnum)
+{
+ if (pnum >= MAX_PERSONALITY)
+ return -EINVAL;
+
+ printk(KERN_INFO "%s personality unregistered\n", pers[pnum]->name);
+ pers[pnum] = NULL;
+ return 0;
+}
+
+static mdp_disk_t *get_spare(mddev_t *mddev)
+{
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *disk;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)
+ continue;
+ if (!rdev->sb) {
+ MD_BUG();
+ continue;
+ }
+ disk = &sb->disks[rdev->desc_nr];
+ if (disk_faulty(disk)) {
+ MD_BUG();
+ continue;
+ }
+ if (disk_active(disk))
+ continue;
+ return disk;
+ }
+ return NULL;
+}
+
+static int is_mddev_idle (mddev_t *mddev)
+{
+ mdk_rdev_t * rdev;
+ struct md_list_head *tmp;
+ int idle;
+ unsigned long curr_events;
+
+ idle = 1;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ curr_events = io_events[MAJOR(rdev->dev)];
+
+ if (curr_events != rdev->last_events) {
+// printk("!I(%d)", curr_events-rdev->last_events);
+ rdev->last_events = curr_events;
+ idle = 0;
+ }
+ }
+ return idle;
+}
+
+/*
+ * parallel resyncing thread.
+ */
+
+/*
+ * Determine correct block size for this device.
+ */
+unsigned int device_bsize (kdev_t dev)
+{
+ unsigned int i, correct_size;
+
+ correct_size = BLOCK_SIZE;
+ if (blksize_size[MAJOR(dev)]) {
+ i = blksize_size[MAJOR(dev)][MINOR(dev)];
+ if (i)
+ correct_size = i;
+ }
+
+ return correct_size;
+}
+
+static struct wait_queue *resync_wait = (struct wait_queue *)NULL;
+
+#define RA_ORDER (1)
+#define RA_PAGE_SIZE (PAGE_SIZE*(1<<RA_ORDER))
+#define MAX_NR_BLOCKS (RA_PAGE_SIZE/sizeof(struct buffer_head *))
+
+int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
+{
+ mddev_t *mddev2;
+ struct buffer_head **bh;
+ unsigned int max_blocks, blocksize, curr_bsize,
+ i, ii, j, k, chunk, window, nr_blocks, err, serialize;
+ kdev_t read_disk = mddev_to_kdev(mddev);
+ int major = MAJOR(read_disk), minor = MINOR(read_disk);
+ unsigned long starttime;
+ int max_read_errors = 2*MAX_NR_BLOCKS,
+ max_write_errors = 2*MAX_NR_BLOCKS;
+ struct md_list_head *tmp;
+
+retry_alloc:
+ bh = (struct buffer_head **) md__get_free_pages(GFP_KERNEL, RA_ORDER);
+ if (!bh) {
+ printk(KERN_ERR
+ "could not alloc bh array for reconstruction ... retrying!\n");
+ goto retry_alloc;
+ }
+
+ err = down_interruptible(&mddev->resync_sem);
+ if (err)
+ goto out_nolock;
+
+recheck:
+ serialize = 0;
+ ITERATE_MDDEV(mddev2,tmp) {
+ if (mddev2 == mddev)
+ continue;
+ if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
+ printk(KERN_INFO "md: serializing resync, md%d has overlapping physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
+ serialize = 1;
+ break;
+ }
+ }
+ if (serialize) {
+ interruptible_sleep_on(&resync_wait);
+ if (md_signal_pending(current)) {
+ md_flush_signals();
+ err = -EINTR;
+ goto out;
+ }
+ goto recheck;
+ }
+
+ mddev->curr_resync = 1;
+
+ blocksize = device_bsize(read_disk);
+ max_blocks = blk_size[major][minor] / (blocksize >> 10);
+
+ printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
+ printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec.\n",
+ sysctl_speed_limit);
+ printk(KERN_INFO "md: using maximum available idle IO bandwith for reconstruction.\n");
+
+ /*
+ * Resync has low priority.
+ */
+ current->priority = 1;
+
+ is_mddev_idle(mddev); /* this also initializes IO event counters */
+ starttime = jiffies;
+ mddev->resync_start = starttime;
+
+ /*
+ * Tune reconstruction:
+ */
+ window = md_maxreadahead[mdidx(mddev)]/1024;
+ nr_blocks = window / (blocksize >> 10);
+ if (!nr_blocks || (nr_blocks > MAX_NR_BLOCKS))
+ nr_blocks = MAX_NR_BLOCKS;
+ printk(KERN_INFO "md: using %dk window.\n",window);
+
+ for (j = 0; j < max_blocks; j += nr_blocks) {
+
+ if (j)
+ mddev->curr_resync = j;
+ /*
+ * B careful. When some1 mounts a non-'blocksize' filesystem
+ * then we get the blocksize changed right under us. Go deal
+ * with it transparently, recalculate 'blocksize', 'j' and
+ * 'max_blocks':
+ */
+ curr_bsize = device_bsize(read_disk);
+ if (curr_bsize != blocksize) {
+ printk(KERN_INFO "md%d: blocksize changed\n",
+ mdidx(mddev));
+retry_read:
+ if (curr_bsize > blocksize)
+ /*
+ * this is safe, rounds downwards.
+ */
+ j /= curr_bsize/blocksize;
+ else
+ j *= blocksize/curr_bsize;
+
+ blocksize = curr_bsize;
+ nr_blocks = window / (blocksize >> 10);
+ if (!nr_blocks || (nr_blocks > MAX_NR_BLOCKS))
+ nr_blocks = MAX_NR_BLOCKS;
+ max_blocks = blk_size[major][minor] / (blocksize >> 10);
+ printk("nr_blocks changed to %d (blocksize %d, j %d, max_blocks %d)\n",
+ nr_blocks, blocksize, j, max_blocks);
+ /*
+ * We will retry the current block-group
+ */
+ }
+
+ /*
+ * Cleanup routines expect this
+ */
+ for (k = 0; k < nr_blocks; k++)
+ bh[k] = NULL;
+
+ chunk = nr_blocks;
+ if (chunk > max_blocks-j)
+ chunk = max_blocks-j;
+
+ /*
+ * request buffer heads ...
+ */
+ for (i = 0; i < chunk; i++) {
+ bh[i] = getblk (read_disk, j+i, blocksize);
+ if (!bh[i])
+ goto read_error;
+ if (!buffer_dirty(bh[i]))
+ mark_buffer_lowprio(bh[i]);
+ }
+
+ /*
+ * read buffer heads ...
+ */
+ ll_rw_block (READ, chunk, bh);
+ run_task_queue(&tq_disk);
+
+ /*
+ * verify that all of them are OK ...
+ */
+ for (i = 0; i < chunk; i++) {
+ ii = chunk-i-1;
+ wait_on_buffer(bh[ii]);
+ if (!buffer_uptodate(bh[ii]))
+ goto read_error;
+ }
+
+retry_write:
+ for (i = 0; i < chunk; i++)
+ mark_buffer_dirty_lowprio(bh[i]);
+
+ ll_rw_block(WRITE, chunk, bh);
+ run_task_queue(&tq_disk);
+
+ for (i = 0; i < chunk; i++) {
+ ii = chunk-i-1;
+ wait_on_buffer(bh[ii]);
+
+ if (spare && disk_faulty(spare)) {
+ for (k = 0; k < chunk; k++)
+ brelse(bh[k]);
+ printk(" <SPARE FAILED!>\n ");
+ err = -EIO;
+ goto out;
+ }
+
+ if (!buffer_uptodate(bh[ii])) {
+ curr_bsize = device_bsize(read_disk);
+ if (curr_bsize != blocksize) {
+ printk(KERN_INFO
+ "md%d: blocksize changed during write\n",
+ mdidx(mddev));
+ for (k = 0; k < chunk; k++)
+ if (bh[k]) {
+ if (buffer_lowprio(bh[k]))
+ mark_buffer_clean(bh[k]);
+ brelse(bh[k]);
+ }
+ goto retry_read;
+ }
+ printk(" BAD WRITE %8d>\n", j);
+ /*
+ * Ouch, write error, retry or bail out.
+ */
+ if (max_write_errors) {
+ max_write_errors--;
+ printk ( KERN_WARNING "md%d: write error while reconstructing, at block %u(%d).\n", mdidx(mddev), j, blocksize);
+ goto retry_write;
+ }
+ printk ( KERN_ALERT
+ "too many write errors, stopping reconstruction.\n");
+ for (k = 0; k < chunk; k++)
+ if (bh[k]) {
+ if (buffer_lowprio(bh[k]))
+ mark_buffer_clean(bh[k]);
+ brelse(bh[k]);
+ }
+ err = -EIO;
+ goto out;
+ }
+ }
+
+ /*
+ * This is the normal 'everything went OK' case
+ * do a 'free-behind' logic, we sure dont need
+ * this buffer if it was the only user.
+ */
+ for (i = 0; i < chunk; i++)
+ if (buffer_dirty(bh[i]))
+ brelse(bh[i]);
+ else
+ bforget(bh[i]);
+
+
+ if (md_signal_pending(current)) {
+ /*
+ * got a signal, exit.
+ */
+ mddev->curr_resync = 0;
+ printk("md_do_sync() got signal ... exiting\n");
+ md_flush_signals();
+ err = -EINTR;
+ goto out;
+ }
+
+ /*
+ * this loop exits only if either when we are slower than
+ * the 'hard' speed limit, or the system was IO-idle for
+ * a jiffy.
+ * the system might be non-idle CPU-wise, but we only care
+ * about not overloading the IO subsystem. (things like an
+ * e2fsck being done on the RAID array should execute fast)
+ */
+repeat:
+ if (md_need_resched(current))
+ schedule();
+
+ if ((blocksize/1024)*j/((jiffies-starttime)/HZ + 1) + 1
+ > sysctl_speed_limit) {
+ current->priority = 1;
+
+ if (!is_mddev_idle(mddev)) {
+ current->state = TASK_INTERRUPTIBLE;
+ md_schedule_timeout(HZ/2);
+ if (!md_signal_pending(current))
+ goto repeat;
+ }
+ } else
+ current->priority = 40;
+ }
+ fsync_dev(read_disk);
+ printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
+ err = 0;
+ /*
+ * this also signals 'finished resyncing' to md_stop
+ */
+out:
+ up(&mddev->resync_sem);
+out_nolock:
+ free_pages((unsigned long)bh, RA_ORDER);
+ mddev->curr_resync = 0;
+ wake_up(&resync_wait);
+ return err;
+
+read_error:
+ /*
+ * set_blocksize() might change the blocksize. This
+ * should not happen often, but it happens when eg.
+ * someone mounts a filesystem that has non-1k
+ * blocksize. set_blocksize() doesnt touch our
+ * buffer, but to avoid aliasing problems we change
+ * our internal blocksize too and retry the read.
+ */
+ curr_bsize = device_bsize(read_disk);
+ if (curr_bsize != blocksize) {
+ printk(KERN_INFO "md%d: blocksize changed during read\n",
+ mdidx(mddev));
+ for (k = 0; k < chunk; k++)
+ if (bh[k]) {
+ if (buffer_lowprio(bh[k]))
+ mark_buffer_clean(bh[k]);
+ brelse(bh[k]);
+ }
+ goto retry_read;
+ }
+
+ /*
+ * It's a real read problem. We retry and bail out
+ * only if it's excessive.
+ */
+ if (max_read_errors) {
+ max_read_errors--;
+ printk ( KERN_WARNING "md%d: read error while reconstructing, at block %u(%d).\n", mdidx(mddev), j, blocksize);
+ for (k = 0; k < chunk; k++)
+ if (bh[k]) {
+ if (buffer_lowprio(bh[k]))
+ mark_buffer_clean(bh[k]);
+ brelse(bh[k]);
+ }
+ goto retry_read;
+ }
+ printk ( KERN_ALERT "too many read errors, stopping reconstruction.\n");
+ for (k = 0; k < chunk; k++)
+ if (bh[k]) {
+ if (buffer_lowprio(bh[k]))
+ mark_buffer_clean(bh[k]);
+ brelse(bh[k]);
+ }
+ err = -EIO;
+ goto out;
+}
+
+#undef MAX_NR_BLOCKS
+
+/*
+ * This is a kernel thread which syncs a spare disk with the active array
+ *
+ * the amount of foolproofing might seem to be a tad excessive, but an
+ * early (not so error-safe) version of raid1syncd synced the first 0.5 gigs
+ * of my root partition with the first 0.5 gigs of my /home partition ... so
+ * i'm a bit nervous ;)
+ */
+void md_do_recovery (void *data)
+{
+ int err;
+ mddev_t *mddev;
+ mdp_super_t *sb;
+ mdp_disk_t *spare;
+ unsigned long flags;
+ struct md_list_head *tmp;
+
+ printk(KERN_INFO "md: recovery thread got woken up ...\n");
+restart:
+ ITERATE_MDDEV(mddev,tmp) {
+ sb = mddev->sb;
+ if (!sb)
+ continue;
+ if (mddev->recovery_running)
+ continue;
+ if (sb->active_disks == sb->raid_disks)
+ continue;
+ if (!sb->spare_disks) {
+ printk(KERN_ERR "md%d: no spare disk to reconstruct array! -- continuing in degraded mode\n", mdidx(mddev));
+ continue;
+ }
+ /*
+ * now here we get the spare and resync it.
+ */
+ if ((spare = get_spare(mddev)) == NULL)
+ continue;
+ printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!mddev->pers->diskop)
+ continue;
+ if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
+ continue;
+ down(&mddev->recovery_sem);
+ mddev->recovery_running = 1;
+ err = md_do_sync(mddev, spare);
+ if (err == -EIO) {
+ printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!disk_faulty(spare)) {
+ mddev->pers->diskop(mddev,&spare,DISKOP_SPARE_INACTIVE);
+ mark_disk_faulty(spare);
+ mark_disk_nonsync(spare);
+ mark_disk_inactive(spare);
+ sb->spare_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ }
+ } else
+ if (disk_faulty(spare))
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ if (err == -EINTR) {
+ /*
+ * Recovery got interrupted ...
+ * signal back that we have finished using the array.
+ */
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ up(&mddev->recovery_sem);
+ mddev->recovery_running = 0;
+ continue;
+ } else {
+ mddev->recovery_running = 0;
+ up(&mddev->recovery_sem);
+ }
+ save_flags(flags);
+ cli();
+ if (!disk_faulty(spare)) {
+ /*
+ * the SPARE_ACTIVE diskop possibly changes the
+ * pointer too
+ */
+ mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_ACTIVE);
+ mark_disk_sync(spare);
+ mark_disk_active(spare);
+ sb->active_disks++;
+ sb->spare_disks--;
+ }
+ restore_flags(flags);
+ mddev->sb_dirty = 1;
+ md_update_sb(mddev);
+ goto restart;
+ }
+ printk(KERN_INFO "md: recovery thread finished ...\n");
+
+}
+
+int md_notify_reboot(struct notifier_block *this,
+ unsigned long code, void *x)
+{
+ struct md_list_head *tmp;
+ mddev_t *mddev;
+
+ if ((code == MD_SYS_DOWN) || (code == MD_SYS_HALT)
+ || (code == MD_SYS_POWER_OFF)) {
+
+ printk(KERN_INFO "stopping all md devices.\n");
+
+ ITERATE_MDDEV(mddev,tmp)
+ do_md_stop (mddev, 1);
+ /*
+ * certain more exotic SCSI devices are known to be
+ * volatile wrt too early system reboots. While the
+ * right place to handle this issue is the given
+ * driver, we do want to have a safe RAID driver ...
+ */
+ md_mdelay(1000*1);
+ }
+ return NOTIFY_DONE;
+}
+
+struct notifier_block md_notifier = {
+ md_notify_reboot,
+ NULL,
+ 0
+};
+
+md__initfunc(void raid_setup(char *str, int *ints))
+{
+ char tmpline[100];
+ int len, pos, nr, i;
+
+ len = strlen(str) + 1;
+ nr = 0;
+ pos = 0;
+
+ for (i = 0; i < len; i++) {
+ char c = str[i];
+
+ if (c == ',' || !c) {
+ tmpline[pos] = 0;
+ if (!strcmp(tmpline,"noautodetect"))
+ raid_setup_args.noautodetect = 1;
+ nr++;
+ pos = 0;
+ continue;
+ }
+ tmpline[pos] = c;
+ pos++;
+ }
+ raid_setup_args.set = 1;
+ return;
+}
+
+#ifdef CONFIG_MD_BOOT
+struct {
+ int set;
+ int ints[100];
+ char str[100];
+} md_setup_args md__initdata = {
+ 0,{0},{0}
+};
+
+/* called from init/main.c */
+md__initfunc(void md_setup(char *str,int *ints))
+{
+ int i;
+ for(i=0;i<=ints[0];i++) {
+ md_setup_args.ints[i] = ints[i];
+ strcpy(md_setup_args.str, str);
+/* printk ("md: ints[%d]=%d.\n", i, ints[i]);*/
+ }
+ md_setup_args.set=1;
+ return;
+}
+
+md__initfunc(void do_md_setup(char *str,int *ints))
+{
+#if 0
+ int minor, pers, chunk_size, fault;
+ kdev_t dev;
+ int i=1;
+
+ printk("i plan to phase this out --mingo\n");
+
+ if(ints[0] < 4) {
+ printk (KERN_WARNING "md: Too few Arguments (%d).\n", ints[0]);
+ return;
+ }
+
+ minor=ints[i++];
+
+ if ((unsigned int)minor >= MAX_MD_DEVS) {
+ printk (KERN_WARNING "md: Minor device number too high.\n");
+ return;
+ }
+
+ pers = 0;
+
+ switch(ints[i++]) { /* Raidlevel */
+ case -1:
+#ifdef CONFIG_MD_LINEAR
+ pers = LINEAR;
+ printk (KERN_INFO "md: Setting up md%d as linear device.\n",
+ minor);
+#else
+ printk (KERN_WARNING "md: Linear mode not configured."
+ "Recompile the kernel with linear mode enabled!\n");
+#endif
+ break;
+ case 0:
+ pers = STRIPED;
+#ifdef CONFIG_MD_STRIPED
+ printk (KERN_INFO "md: Setting up md%d as a striped device.\n",
+ minor);
+#else
+ printk (KERN_WARNING "md: Striped mode not configured."
+ "Recompile the kernel with striped mode enabled!\n");
+#endif
+ break;
+/* not supported yet
+ case 1:
+ pers = RAID1;
+ printk ("md: Setting up md%d as a raid1 device.\n",minor);
+ break;
+ case 5:
+ pers = RAID5;
+ printk ("md: Setting up md%d as a raid5 device.\n",minor);
+ break;
+*/
+ default:
+ printk (KERN_WARNING "md: Unknown or not supported raid level %d.\n", ints[--i]);
+ return;
+ }
+
+ if (pers) {
+
+ chunk_size = ints[i++]; /* Chunksize */
+ fault = ints[i++]; /* Faultlevel */
+
+ pers = pers | chunk_size | (fault << FAULT_SHIFT);
+
+ while( str && (dev = name_to_kdev_t(str))) {
+ do_md_add (minor, dev);
+ if((str = strchr (str, ',')) != NULL)
+ str++;
+ }
+
+ do_md_run (minor, pers);
+ printk (KERN_INFO "md: Loading md%d.\n",minor);
+ }
+#endif
+}
+#endif
+
+void hsm_init (void);
+void translucent_init (void);
+void linear_init (void);
+void raid0_init (void);
+void raid1_init (void);
+void raid5_init (void);
+
+md__initfunc(int md_init (void))
+{
+ static char * name = "mdrecoveryd";
+
+ printk (KERN_INFO "md driver %d.%d.%d MAX_MD_DEVS=%d, MAX_REAL=%d\n",
+ MD_MAJOR_VERSION, MD_MINOR_VERSION,
+ MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MAX_REAL);
+
+ if (register_blkdev (MD_MAJOR, "md", &md_fops))
+ {
+ printk (KERN_ALERT "Unable to get major %d for md\n", MD_MAJOR);
+ return (-1);
+ }
+
+ blk_dev[MD_MAJOR].request_fn = DEVICE_REQUEST;
+ blk_dev[MD_MAJOR].current_request = NULL;
+ read_ahead[MD_MAJOR] = INT_MAX;
+ md_gendisk.next = gendisk_head;
+
+ gendisk_head = &md_gendisk;
+
+ md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
+ if (!md_recovery_thread)
+ printk(KERN_ALERT "bug: couldn't allocate md_recovery_thread\n");
+
+ md_register_reboot_notifier(&md_notifier);
+ md_register_sysctl();
+
+#ifdef CONFIG_MD_HSM
+ hsm_init ();
+#endif
+#ifdef CONFIG_MD_TRANSLUCENT
+ translucent_init ();
+#endif
+#ifdef CONFIG_MD_LINEAR
+ linear_init ();
+#endif
+#ifdef CONFIG_MD_STRIPED
+ raid0_init ();
+#endif
+#ifdef CONFIG_MD_MIRRORING
+ raid1_init ();
+#endif
+#ifdef CONFIG_MD_RAID5
+ raid5_init ();
+#endif
+#if defined(CONFIG_MD_RAID5) || defined(CONFIG_MD_RAID5_MODULE)
+ /*
+ * pick a XOR routine, runtime.
+ */
+ calibrate_xor_block();
+#endif
+
+ return (0);
+}
+
+#ifdef CONFIG_MD_BOOT
+md__initfunc(void md_setup_drive(void))
+{
+ if(md_setup_args.set)
+ do_md_setup(md_setup_args.str, md_setup_args.ints);
+}
+#endif
+
+MD_EXPORT_SYMBOL(md_size);
+MD_EXPORT_SYMBOL(register_md_personality);
+MD_EXPORT_SYMBOL(unregister_md_personality);
+MD_EXPORT_SYMBOL(partition_name);
+MD_EXPORT_SYMBOL(md_error);
+MD_EXPORT_SYMBOL(md_recover_arrays);
+MD_EXPORT_SYMBOL(md_register_thread);
+MD_EXPORT_SYMBOL(md_unregister_thread);
+MD_EXPORT_SYMBOL(md_update_sb);
+MD_EXPORT_SYMBOL(md_map);
+MD_EXPORT_SYMBOL(md_wakeup_thread);
+MD_EXPORT_SYMBOL(md_do_sync);
+MD_EXPORT_SYMBOL(md_print_devices);
+MD_EXPORT_SYMBOL(find_rdev_nr);
+MD_EXPORT_SYMBOL(md_check_ordering);
+MD_EXPORT_SYMBOL(md_interrupt_thread);
+MD_EXPORT_SYMBOL(mddev_map);
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry proc_md = {
+ PROC_MD, 6, "mdstat",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations,
+};
+#endif
+
+static void md_geninit (struct gendisk *gdisk)
+{
+ int i;
+
+ for(i = 0; i < MAX_MD_DEVS; i++) {
+ md_blocksizes[i] = 1024;
+ md_maxreadahead[i] = MD_READAHEAD;
+ md_gendisk.part[i].start_sect = -1; /* avoid partition check */
+ md_gendisk.part[i].nr_sects = 0;
+ }
+
+ printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
+
+ blksize_size[MD_MAJOR] = md_blocksizes;
+ md_set_global_readahead(md_maxreadahead);
+
+#ifdef CONFIG_PROC_FS
+ proc_register(&proc_root, &proc_md);
+#endif
+}
+
diff --git a/sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild b/sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild
new file mode 100644
index 000000000000..bcfcaa17da28
--- /dev/null
+++ b/sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild
@@ -0,0 +1,189 @@
+# Copyright 1999-2000 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License, v2 or later
+# Author Achim Gottinger <achim@gentoo.org>
+# $Header: /var/cvsroot/gentoo-x86/sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild,v 1.1 2000/11/19 15:37:42 achim Exp $
+
+P=linux-UP-2.2.17
+A="linux-2.2.17.tar.bz2 i2c-2.5.2.tar.gz lm_sensors-2.5.2.tar.gz
+ linux-2.2.17-reiserfs-3.5.26-patch.gz
+ ide.2.2.17.all.20000904.patch.bz2
+ raid-2.2.17-A0 patch-2.2.16-agpgart.bz2 pppoed0.47.tgz
+ patch-int-2.2.17.9.gz patch-2.2.13-LVM-0.8i.gz"
+
+
+S=${WORKDIR}/linux
+DESCRIPTION="Linux kernel for UP systems with reiserfs,usb,sensors,raid,udma,nfs3 and pppoe support"
+SRC_URI="ftp://ftp.uk.kernel.org/pub/linux/kernel/v2.2/linux-2.2.17.tar.bz2
+ ftp://ftp.de.kernel.org/pub/linux/kernel/v2.2/linux-2.2.17.tar.bz2
+ http://www.netroedge.com/~lm78/archive/lm_sensors-2.5.2.tar.gz
+ http://www.netroedge.com/~lm78/archive/i2c-2.5.2.tar.gz
+ http://devlinux.com/pub/namesys/linux-2.2.17-reiserfs-3.5.26-patch.gz
+ http://people.redhat.com/mingo/raid-patches/raid-2.2.17-A0
+ http://ishmael.nmh.northfield.ma.us/~zander/nv-agpgart/patch-2.2.16-agpgart.bz2
+ ftp://ftp.kernel.org/pub/linux/kernel/people/hedrick/ide-2.2.17/ide.2.2.17.all.20000904.patch.bz2
+ ftp://ftp.uk.kernel.org/pub/linux/kernel/people/hedrick/ide-2.2.17/ide.2.2.17.all.20000904.patch.bz2
+ ftp://ftp.de.kernel.org/pub/linux/kernel/people/hedrick/ide-2.2.17/ide.2.2.17.all.20000904.patch.bz2
+ http://www.davin.ottawa.on.ca/pppoe/pppoed0.47.tgz
+ ftp://ftp.uk.kernel.org/pub/linux/kernel/crypto/v2.2/patch-int-2.2.17.9.gz
+ ftp://linux.msede.com/lvm/v0.8/patch-2.2.13-LVM-0.8i.gz"
+
+HOMEPAGE="http://www.kernel.org/
+ http://www.netroedge.com/~lm78/
+ http://devlinux.com/projects/reiserfs/
+ http://www.linux-usb.org/
+ http://www.kerneli.org
+ http://www.scyld.com/software/lfs.html
+ http://linux.msede.com/lvm/index.html"
+
+
+src_compile() {
+ cd ${S}
+ unset CFLAGS
+ unset CXXFLAGS
+ try make dep
+ cd ${S}/arch/i386/lib
+ cp Makefile Makefile.orig
+ sed -e "s:-traditional::" Makefile.orig > Makefile
+ cd ${S}
+ try make bzImage
+ try make modules
+ cd ${S}/fs/reiserfs/utils
+ try make
+ cd ${S}/lm_sensors-2.5.2
+ try make
+}
+
+src_unpack() {
+
+ unpack linux-2.2.17.tar.bz2
+
+ cd ${S}
+
+ echo "Applying Crypto-patch..."
+ gzip -dc ${DISTDIR}/patch-int-2.2.17.9.gz | patch -p1
+
+
+
+ echo "Applying UDMA patch..."
+ bzip2 -dc ${DISTDIR}/ide.2.2.17.all.20000904.patch.bz2 | patch -p1
+
+ echo "Applying reiserfs-patch..."
+ gzip -dc ${DISTDIR}/linux-2.2.17-reiserfs-3.5.26-patch.gz | patch -p1
+
+ echo "Applying reiserfs-knfsd-patch..."
+ gzip -dc ${FILESDIR}/reiserfs-3.5.22-knfsd-8.gz | patch -p1
+
+ echo "Applying usb-patch..."
+ gzip -dc ${FILESDIR}/usb-2.4.0-test2-pre2-for-2.2.17p6-reiserfs.diff.gz | patch -p1 -N
+
+ echo "Applyling lfs-patch..."
+ patch -p1 < ${FILESDIR}/lfs-2.2.16.patch
+
+ echo "Applying pppoe-patch..."
+ unpack pppoed0.47.tgz
+ patch -p1 < pppoed-0.47/kernel-patches/2214-pppox
+
+ echo "Creating i2c-patch..."
+ unpack i2c-2.5.2.tar.gz
+ cd i2c-2.5.2
+ mkpatch/mkpatch.pl . ${S} > ${S}/i2c-patch
+ cd ${S}
+ echo "Applying i2c-patch..."
+ patch -p1 < i2c-patch
+
+ echo "Creating lm-sensors-patch..."
+ unpack lm_sensors-2.5.2.tar.gz
+ cd lm_sensors-2.5.2
+ mkpatch/mkpatch.pl . ${S} > ${S}/sensors.patch
+ cd ${S}
+ echo "Applying lm_sensors-patch..."
+ patch -p1 < sensors.patch
+
+ echo "Applying raid-patch..."
+ patch -p1 < ${DISTDIR}/raid-2.2.17-A0
+
+ echo "Applying agp-patch..."
+ bzip2 -dc ${DISTDIR}/patch-2.2.16-agpgart.bz2 | patch -p1
+
+ echo "Applying lvm-patch..."
+ gzip -dc ${DISTDIR}/patch-2.2.13-LVM-0.8i.gz | patch -p1
+ echo "Fixing rejects..."
+ cp ${FILESDIR}/genhd.c ${S}/drivers/block
+ cp ${FILESDIR}/ll_rw_blk.c ${S}/drivers/block
+ cp ${FILESDIR}/md.c ${S}/drivers/block
+
+ echo "Prepare for compilation..."
+ cd ${S}/arch/i386
+# cp Makefile Makefile.orig
+## sed -e "s/-DCPU=686/-DCPU=586/" -e "s/\-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=586/${CFLAGS}/" Makefile.orig > Makefile
+ cd ${S}
+# cp Makefile Makefile.orig
+## sed -e 's:-O2:${CFLAGS}:g' Makefile.orig > Makefile
+ try make include/linux/version.h
+ try make symlinks
+ cp ${O}/files/${PF}.config .config
+ cp ${O}/files/${PF}.autoconf include/linux/autoconf.h
+ cp ${O}/files/gentoolinux_logo.h include/linux/linux_logo.h
+
+ cd ${S}/lm_sensors-2.5.2
+
+ cp Makefile Makefile.orig
+ sed -e "s:^LINUX=.*:LINUX=${S}:" \
+ -e "s/^COMPILE_KERNEL.*/COMPILE_KERNEL := 0/" \
+ -e "s:^I2C_HEADERS.*:I2C_HEADERS=${S}/i2c-2.5.2/kernel:" \
+ -e "s/^SMP/#SMP/" \
+ -e "s/^#SMP := 0/SMP := 0/" \
+ -e "s:^DESTDIR.*:DESTDIR \:= ${D}:" \
+ -e "s:^PREFIX \:= .*:PREFIX \:= /usr:" \
+ Makefile.orig > Makefile
+
+}
+
+src_install() {
+ dodir /usr/src/linux
+ dodir /usr/src/linux/include/linux
+ dodir /usr/src/linux/include/asm-i386
+ cp -ax ${S}/include ${D}/usr/src/linux
+ dodir /usr/src/linux/Documentation
+ cp -ax ${S}/Documentation ${D}/usr/src/linux
+ cd ${S}/Documentation
+ find . -type f -exec gzip {} \;
+ dodir /usr/include
+ dosym /usr/src/linux/include/linux /usr/include/linux
+ dosym /usr/src/linux/include/asm-i386 /usr/include/asm
+ insinto /
+ cd ${S}
+ doins arch/i386/boot/bzImage
+ try make INSTALL_MOD_PATH=${D} modules_install
+ cd ${D}/lib/modules
+ ln -sf 2.2.17-RAID current
+ into /
+ cd ${S}/fs/reiserfs/utils/bin
+ dosbin mkreiserfs resize_reiserfs reiserfsck dumpreiserfs
+ cd ..
+ into /usr
+ doman fsck/reiserfsck.8
+ doman mkreiserfs/mkreiserfs.8
+ cp dumpreiserfs/README README.dumpreiserfs
+ cp README README.reiserfs
+ dodoc README.reiserfs README.dumpreiserfs
+ cd ${S}/lm_sensors-2.5.2
+ try make install
+ preplib /usr
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+