lkml.org 
[lkml]   [1999]   [Oct]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] 34 GB disks under 2.2.*
    Lots of people are buying these large Maxtor and IBM disks
    these days, and many do not regard 2.3.21 and later stable
    enough (for myself, I do not regard 2.2.* very stable either -
    2.0.3x is clearly better), so there is a large demand for
    a patch on 2.2.12 or so. It follows below.

    [By mistake I did this on a not entirely clean tree,
    so there are a few tiny other improvements as well.]

    Andries


    ---------------------------------------------------------------
    diff -u --recursive --new-file ../linux-2.2.12/linux/drivers/block/genhd.c ./linux/drivers/block/genhd.c
    --- ../linux-2.2.12/linux/drivers/block/genhd.c Wed Aug 25 01:08:35 1999
    +++ ./linux/drivers/block/genhd.c Wed Oct 20 21:35:40 1999
    @@ -784,8 +784,11 @@
    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;
    }
    @@ -856,8 +859,11 @@
    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;
    }
    diff -u --recursive --new-file ../linux-2.2.12/linux/drivers/block/ide-disk.c ./linux/drivers/block/ide-disk.c
    --- ../linux-2.2.12/linux/drivers/block/ide-disk.c Wed Mar 24 20:07:58 1999
    +++ ./linux/drivers/block/ide-disk.c Wed Oct 20 22:07:30 1999
    @@ -88,30 +88,35 @@
    */
    static int lba_capacity_is_ok (struct hd_driveid *id)
    {
    - unsigned long lba_sects = id->lba_capacity;
    - unsigned long chs_sects = id->cyls * id->heads * id->sectors;
    - unsigned long _10_percent = chs_sects / 10;
    + unsigned long lba_sects, chs_sects, head, tail;

    /*
    - * very large drives (8GB+) may lie about the number of cylinders
    - * This is a split test for drives 8 Gig and Bigger only.
    + * The ATA spec tells large drives to return
    + * C/H/S = 16383/16/63 independent of their size.
    + * Some drives can be jumpered to use 15 heads instead of 16.
    */
    - if ((id->lba_capacity >= 16514064) && (id->cyls == 0x3fff) &&
    - (id->heads == 16) && (id->sectors == 63)) {
    - id->cyls = lba_sects / (16 * 63); /* correct cyls */
    - return 1; /* lba_capacity is our only option */
    - }
    + if (id->cyls == 16383 && id->sectors == 63 &&
    + (id->heads == 15 || id->heads == 16) &&
    + id->lba_capacity >= 16383*63*id->heads)
    + return 1;
    +
    + lba_sects = id->lba_capacity;
    + chs_sects = id->cyls * id->heads * id->sectors;
    +
    /* perform a rough sanity check on lba_sects: within 10% is "okay" */
    - if ((lba_sects - chs_sects) < _10_percent) {
    - return 1; /* lba_capacity is good */
    - }
    + if ((lba_sects - chs_sects) < chs_sects/10)
    + return 1;
    +
    /* some drives have the word order reversed */
    - lba_sects = (lba_sects << 16) | (lba_sects >> 16);
    - if ((lba_sects - chs_sects) < _10_percent) {
    - id->lba_capacity = lba_sects; /* fix it */
    + head = ((lba_sects >> 16) & 0xffff);
    + tail = (lba_sects & 0xffff);
    + lba_sects = (head | (tail << 16));
    + if ((lba_sects - chs_sects) < chs_sects/10) {
    + id->lba_capacity = lba_sects;
    return 1; /* lba_capacity is (now) good */
    }
    - return 0; /* lba_capacity value is bad */
    +
    + return 0; /* lba_capacity value may be bad */
    }

    /*
    @@ -446,7 +451,6 @@
    /* Determine capacity, and use LBA if the drive properly supports it */
    if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) {
    if (id->lba_capacity >= capacity) {
    - drive->cyl = id->lba_capacity / (drive->head * drive->sect);
    capacity = id->lba_capacity;
    drive->select.b.lba = 1;
    }
    @@ -721,9 +725,9 @@
    if ((id->lba_capacity > 16514064) || (id->cyls == 0x3fff)) {
    id->cyls = ((int)(id->lba_capacity/(id->heads * id->sectors)));
    }
    - drive->cyl = id->cur_cyls = id->cyls;
    - drive->head = id->cur_heads = id->heads;
    - drive->sect = id->cur_sectors = id->sectors;
    + drive->cyl = id->cyls;
    + drive->head = id->heads;
    + drive->sect = id->sectors;
    }

    /* calculate drive capacity, and select LBA if possible */
    @@ -733,21 +737,19 @@
    * if possible, give fdisk access to more of the drive,
    * by correcting bios_cyls:
    */
    - if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
    - (!drive->forced_geom) && drive->bios_sect && drive->bios_head) {
    - drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
    -#ifdef DEBUG
    - printk("Fixing Geometry :: CHS=%d/%d/%d to CHS=%d/%d/%d\n",
    - drive->id->cur_cyls,
    - drive->id->cur_heads,
    - drive->id->cur_sectors,
    - drive->bios_cyl,
    - drive->bios_head,
    - drive->bios_sect);
    -#endif
    - drive->id->cur_cyls = drive->bios_cyl;
    - drive->id->cur_heads = drive->bios_head;
    - drive->id->cur_sectors = drive->bios_sect;
    + if (!drive->forced_geom &&
    + capacity > drive->bios_cyl * drive->bios_sect * drive->bios_head) {
    + unsigned long cylsize;
    + cylsize = drive->bios_sect * drive->bios_head;
    + if (cylsize == 0 || capacity/cylsize > 65535) {
    + drive->bios_sect = 63;
    + drive->bios_head = 255;
    + cylsize = 63*255;
    + }
    + if (capacity/cylsize > 65535)
    + drive->bios_cyl = 65535;
    + else
    + drive->bios_cyl = capacity/cylsize;
    }

    #if 0 /* done instead for entire identify block in arch/ide.h stuff */
    @@ -770,19 +772,6 @@
    }
    }
    printk("\n");
    -
    - if (drive->select.b.lba) {
    - if (*(int *)&id->cur_capacity0 < id->lba_capacity) {
    -#ifdef DEBUG
    - printk(" CurSects=%d, LBASects=%d, ",
    - *(int *)&id->cur_capacity0, id->lba_capacity);
    -#endif
    - *(int *)&id->cur_capacity0 = id->lba_capacity;
    -#ifdef DEBUG
    - printk( "Fixed CurSects=%d\n", *(int *)&id->cur_capacity0);
    -#endif
    - }
    - }

    drive->mult_count = 0;
    if (id->max_multsect) {
    diff -u --recursive --new-file ../linux-2.2.12/linux/drivers/block/ide-proc.c ./linux/drivers/block/ide-proc.c
    --- ../linux-2.2.12/linux/drivers/block/ide-proc.c Wed May 6 23:42:53 1998
    +++ ./linux/drivers/block/ide-proc.c Thu Oct 14 18:18:31 1999
    @@ -516,8 +516,10 @@
    char *out = page;
    int len;

    - out += sprintf(out,"physical %hi/%hi/%hi\n", drive->cyl, drive->head, drive->sect);
    - out += sprintf(out,"logical %hi/%hi/%hi\n", drive->bios_cyl, drive->bios_head, drive->bios_sect);
    + out += sprintf(out,"physical %d/%d/%d\n",
    + drive->cyl, drive->head, drive->sect);
    + out += sprintf(out,"logical %d/%d/%d\n",
    + drive->bios_cyl, drive->bios_head, drive->bios_sect);
    len = out - page;
    PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
    }
    diff -u --recursive --new-file ../linux-2.2.12/linux/drivers/net/8390.c ./linux/drivers/net/8390.c
    --- ../linux-2.2.12/linux/drivers/net/8390.c Thu May 13 00:23:32 1999
    +++ ./linux/drivers/net/8390.c Thu Oct 14 14:49:27 1999
    @@ -1089,7 +1089,9 @@
    int start_page)
    {
    int e8390_base = dev->base_addr;
    +#ifdef EI_LOCAL_NEEDED_FOR_EI_SHIFT
    struct ei_device *ei_local = (struct ei_device *) dev->priv;
    +#endif

    outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);

    diff -u --recursive --new-file ../linux-2.2.12/linux/drivers/net/8390.h ./linux/drivers/net/8390.h
    --- ../linux-2.2.12/linux/drivers/net/8390.h Mon Dec 28 20:04:21 1998
    +++ ./linux/drivers/net/8390.h Wed Oct 20 22:19:04 1999
    @@ -215,6 +215,7 @@
    #if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \
    defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE)
    #define EI_SHIFT(x) (ei_local->reg_offset[x])
    +#define EI_LOCAL_NEEDED_FOR_EI_SHIFT
    #else
    #define EI_SHIFT(x) (x)
    #endif
    diff -u --recursive --new-file ../linux-2.2.12/linux/fs/devices.c ./linux/fs/devices.c
    --- ../linux-2.2.12/linux/fs/devices.c Wed Dec 23 20:39:49 1998
    +++ ./linux/fs/devices.c Fri Feb 19 23:46:56 1999
    @@ -228,7 +228,7 @@
    */
    int blkdev_open(struct inode * inode, struct file * filp)
    {
    - int ret = -ENODEV;
    + int ret = -ENXIO;
    filp->f_op = get_blkfops(MAJOR(inode->i_rdev));
    if (filp->f_op != NULL){
    ret = 0;
    diff -u --recursive --new-file ../linux-2.2.12/linux/fs/namei.c ./linux/fs/namei.c
    --- ../linux-2.2.12/linux/fs/namei.c Thu May 13 00:23:36 1999
    +++ ./linux/fs/namei.c Sun Oct 3 18:48:00 1999
    @@ -555,6 +555,8 @@
    * on removing (or moving) the same entry: the
    * parent lock will serialize them, but the
    * other process will be too late..
    + *
    + * Note that check_parent will fail for mount points.
    */
    #define check_parent(dir, dentry) \
    ((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash))
    @@ -974,6 +976,10 @@

    error = -ENOENT;
    if (!dentry->d_inode)
    + goto exit_dput;
    +
    + error = -EBUSY;
    + if (dentry->d_covers != dentry)
    goto exit_dput;

    dir = dget(dentry->d_parent);
    diff -u --recursive --new-file ../linux-2.2.12/linux/include/linux/genhd.h ./linux/include/linux/genhd.h
    --- ../linux-2.2.12/linux/include/linux/genhd.h Wed Aug 25 01:08:49 1999
    +++ ./linux/include/linux/genhd.h Wed Oct 20 22:18:01 1999
    @@ -42,7 +42,7 @@
    #endif

    #define DM6_PARTITION 0x54 /* has DDO: use xlated geom & offset */
    -#define EZD_PARTITION 0x55 /* EZ-DRIVE: same as DM6 (we think) */
    +#define EZD_PARTITION 0x55 /* EZ-DRIVE: remap sector 1 to 0 */
    #define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */
    #define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */

    diff -u --recursive --new-file ../linux-2.2.12/linux/ipc/sem.c ./linux/ipc/sem.c
    --- ../linux-2.2.12/linux/ipc/sem.c Sun Jan 10 04:16:44 1999
    +++ ./linux/ipc/sem.c Thu Oct 14 15:10:49 1999
    @@ -694,7 +694,7 @@
    interruptible_sleep_on(&queue.sleeper);

    /*
    - * If queue.status == 1 we where woken up and
    + * If queue.status == 1 we were woken up and
    * have to retry else we simply return.
    * If an interrupt occurred we have to clean up the
    * queue
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:54    [W:0.034 / U:29.896 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site