patch-1.3.14 linux/drivers/block/ide.c
Next file: linux/drivers/block/sbpcd.c
Previous file: linux/drivers/block/genhd.c
Back to the patch index
Back to the overall index
- Lines: 171
- Date:
Mon Jul 31 14:30:15 1995
- Orig file:
v1.3.13/linux/drivers/block/ide.c
- Orig date:
Tue Jul 18 16:28:56 1995
diff -u --recursive --new-file v1.3.13/linux/drivers/block/ide.c linux/drivers/block/ide.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide.c Version 4.00 Jul 10, 1995
+ * linux/drivers/block/ide.c Version 4.11 Jul 29, 1995
*
* Copyright (C) 1994, 1995 Linus Torvalds & authors (see below)
*/
@@ -91,6 +91,10 @@
* add transparent support for DiskManager-6.0x "Dynamic
* Disk Overlay" (DDO), most of this in in genhd.c
* eliminate "multiple mode turned off" message at boot
+ * Version 4.10 fix bug in ioctl for "hdparm -c3"
+ * fix DM6:DDO support -- now works with LILO, fdisk, ...
+ * don't treat some naughty WD drives as removeable
+ * Version 4.11 updated DM6 support using info provided by OnTrack
*
* To do:
* - add support for alternative IDE port addresses
@@ -278,6 +282,8 @@
* For fast indexing, sizeof(ide_dev_t) = 32 = power_of_2;
* Everything is carefully aligned on appropriate boundaries,
* and several fields are placed for optimal (gcc) access.
+ *
+ * Ugh. Actually, we're two bytes over (34 bytes).. gotta fix this someday.
*/
typedef enum {disk, cdrom} dev_type;
@@ -322,6 +328,7 @@
const char *name;
struct hd_driveid *id;
struct wait_queue *wqueue;
+ byte sect0, removeable;
} ide_dev_t;
/*
@@ -1153,7 +1160,7 @@
end_request(0, HWIF);
goto repeat;
}
- block += ide_hd[HWIF][minor].start_sect;
+ block += ide_hd[HWIF][minor].start_sect + dev->sect0;
#if (DISK_RECOVERY_TIME > 0)
while ((read_timer() - ide_lastreq[HWIF]) < DISK_RECOVERY_TIME);
#endif
@@ -1334,9 +1341,11 @@
if (drive < MAX_DRIVES) {
switch (MAJOR(i_rdev)) {
+#ifndef CONFIG_BLK_DEV_HD
case IDE0_MAJOR: dev = &ide_dev[0][drive];
if (dev->present) return dev;
break;
+#endif /* CONFIG_BLK_DEV_HD */
case IDE1_MAJOR: dev = &ide_dev[1][drive];
if (dev->present) return dev;
break;
@@ -1358,12 +1367,12 @@
sleep_on(&dev->wqueue);
dev->usage++;
restore_flags(flags);
- if (dev->id && (dev->id->config & (1<<7))) /* for removeable disks */
- check_disk_change(inode->i_rdev);
#ifdef CONFIG_BLK_DEV_IDECD
if (dev->type == cdrom)
return cdrom_open (inode, filp, dev);
#endif /* CONFIG_BLK_DEV_IDECD */
+ if (dev->removeable) /* for disks */
+ check_disk_change(inode->i_rdev);
return 0;
}
@@ -1567,9 +1576,12 @@
case HDIO_SET_KEEPSETTINGS:
case HDIO_SET_UNMASKINTR:
case HDIO_SET_NOWERR:
+ if (arg > 1)
+ return -EINVAL;
case HDIO_SET_CHIPSET:
- if (!suser()) return -EACCES;
- if ((arg > 1) || (MINOR(inode->i_rdev) & PARTN_MASK))
+ if (!suser())
+ return -EACCES;
+ if ((MINOR(inode->i_rdev) & PARTN_MASK))
return -EINVAL;
save_flags(flags);
cli();
@@ -1654,7 +1666,7 @@
if (dev->type == cdrom)
return cdrom_check_media_change (dev);
#endif /* CONFIG_BLK_DEV_IDECD */
- if (dev->id && (dev->id->config & (1<<7))) /* for removeable disks */
+ if (dev->removeable) /* for disks */
return 1; /* always assume it was changed */
return 0;
}
@@ -1763,12 +1775,19 @@
printk(" UNKNOWN device\n");
dev->type = cdrom; /* until we do it "correctly" above */
dev->present = 1;
+ dev->removeable = 1;
#else
printk(unsupported);
#endif /* CONFIG_BLK_DEV_IDECD */
return;
}
+ /* check for removeable disks (eg. SYQUEST), ignore 'WD' drives */
+ if (id->config & (1<<7)) { /* removeable disk ? */
+ if (id->model[0] != 'W' || id->model[1] != 'D')
+ dev->removeable = 1;
+ }
+
dev->type = disk;
/* Extract geometry if we did not already have one for the drive */
if (!dev->present) {
@@ -2159,20 +2178,36 @@
ide_setup (str, ints);
}
-
-void ide_xlate_1024 (dev_t full_dev)
+int ide_xlate_1024 (dev_t full_dev, int need_offset, char *msg)
{
ide_dev_t *dev;
+ byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}, *heads = head_vals;
+ unsigned long capacity;
- if ((dev = get_info_ptr(full_dev)) != NULL) {
- dev->bios_cyl -= 1; /* keeps fdisk sane */
- while (dev->bios_cyl > 1024) {
- if (dev->bios_head > 32)
- return;
- dev->bios_head *= 2;
- dev->bios_cyl /= 2;
- }
+ if ((dev = get_info_ptr(full_dev)) == NULL && dev->id == NULL)
+ return 0;
+
+ dev->cyl = dev->bios_cyl = dev->id->cyls;
+ dev->head = dev->bios_head = dev->id->heads;
+ dev->sect = dev->bios_sect = dev->id->sectors;
+ dev->special.b.set_geometry = 1;
+
+ capacity = dev->bios_cyl * dev->bios_head * dev->bios_sect / 63;
+ dev->bios_sect = 63;
+ do {
+ dev->bios_head = *heads;
+ dev->bios_cyl = capacity / dev->bios_head;
+ } while (dev->bios_cyl >= 1024 && *++heads);
+ if (need_offset) {
+ dev->sect0 = 63;
+ capacity -= 1;
+ dev->bios_cyl = capacity / dev->bios_head;
}
+ capacity = dev->bios_cyl * dev->bios_head * dev->bios_sect;
+ ide_capacity[DEV_HWIF][dev->select.b.drive] = capacity;
+ ide_hd[DEV_HWIF][MINOR(full_dev)].nr_sects = capacity;
+ printk("%s [+%d,%d/%d/%d]", msg, dev->sect0, dev->bios_cyl, dev->bios_head, dev->bios_sect);
+ return 1;
}
#ifndef CONFIG_BLK_DEV_HD
@@ -2243,6 +2278,8 @@
dev->special.b.recalibrate = 1;
dev->special.b.set_geometry = 1;
dev->keep_settings = 0;
+ dev->sect0 = 0;
+ dev->removeable = 0;
ide_hd[hwif][drive<<PARTN_BITS].start_sect = 0;
dev->name = ide_devname[hwif][drive];
if (!dev->bad_wstat)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this