diff options
author | Achim Gottinger <achim@gentoo.org> | 2000-11-19 15:37:42 +0000 |
---|---|---|
committer | Achim Gottinger <achim@gentoo.org> | 2000-11-19 15:37:42 +0000 |
commit | d722abffdd16e3d0b7b5bb2324281f9016e71165 (patch) | |
tree | 830898094f24355add50d46ad4df87d38edc5e04 /sys-kernel | |
parent | *** empty log message *** (diff) | |
download | gentoo-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.c | 1733 | ||||
-rw-r--r-- | sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.autoconf | 1737 | ||||
-rw-r--r-- | sys-kernel/linux-UP-2.2.17/files/linux-UP-2.2.17-r5.config | 1320 | ||||
-rw-r--r-- | sys-kernel/linux-UP-2.2.17/files/ll_rw_blk.c | 1196 | ||||
-rw-r--r-- | sys-kernel/linux-UP-2.2.17/files/md.c | 4030 | ||||
-rw-r--r-- | sys-kernel/linux-UP-2.2.17/linux-UP-2.2.17-r5.ebuild | 189 |
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(¶m, (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 +} + + + + + + + + + + + + + + + + |