Messages in this thread Patch in this message | | | Date | Wed, 20 Oct 1999 23:56:38 +0200 (MET DST) | From | Andries.Brouwer@cwi ... | 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/
| |