patch-2.3.99-pre1 linux/drivers/block/ide-geometry.c
Next file: linux/drivers/block/ide-pci.c
Previous file: linux/drivers/block/ide-floppy.c
Back to the patch index
Back to the overall index
- Lines: 215
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.3.51/linux/drivers/block/ide-geometry.c
- Orig date:
Fri Mar 10 16:40:42 2000
diff -u --recursive --new-file v2.3.51/linux/drivers/block/ide-geometry.c linux/drivers/block/ide-geometry.c
@@ -1,214 +0,0 @@
-/*
- * linux/drivers/block/ide-geometry.c
- */
-#include <linux/config.h>
-
-#ifdef CONFIG_BLK_DEV_IDE
-#include <linux/ide.h>
-
-#include <asm/io.h>
-
-extern ide_drive_t * get_info_ptr(kdev_t);
-extern unsigned long current_capacity (ide_drive_t *);
-
-/*
- * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
- * controller that is BIOS compatible with ST-506, and thus showing up in our
- * BIOS table, but not register compatible, and therefore not present in CMOS.
- *
- * Furthermore, we will assume that our ST-506 drives <if any> are the primary
- * drives in the system -- the ones reflected as drive 1 or 2. The first
- * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
- * nibble. This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value
- * means we have an AT controller hard disk for that drive.
- *
- * Of course, there is no guarantee that either drive is actually on the
- * "primary" IDE interface, but we don't bother trying to sort that out here.
- * If a drive is not actually on the primary interface, then these parameters
- * will be ignored. This results in the user having to supply the logical
- * drive geometry as a boot parameter for each drive not on the primary i/f.
- */
-/*
- * The only "perfect" way to handle this would be to modify the setup.[cS] code
- * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
- * for us during initialization. I have the necessary docs -- any takers? -ml
- */
-/*
- * I did this, but it doesnt work - there is no reasonable way to find the
- * correspondence between the BIOS numbering of the disks and the Linux
- * numbering. -aeb
- *
- * The code below is bad. One of the problems is that drives 1 and 2
- * may be SCSI disks (even when IDE disks are present), so that
- * the geometry we read here from BIOS is attributed to the wrong disks.
- * Consequently, also the "drive->present = 1" below is a mistake.
- *
- * Eventually the entire routine below should be removed.
- */
-void probe_cmos_for_drives (ide_hwif_t *hwif)
-{
-#ifdef __i386__
- extern struct drive_info_struct drive_info;
- byte cmos_disks, *BIOS = (byte *) &drive_info;
- int unit;
-
-#ifdef CONFIG_BLK_DEV_PDC4030
- if (hwif->chipset == ide_pdc4030 && hwif->channel != 0)
- return;
-#endif /* CONFIG_BLK_DEV_PDC4030 */
- outb_p(0x12,0x70); /* specify CMOS address 0x12 */
- cmos_disks = inb_p(0x71); /* read the data from 0x12 */
- /* Extract drive geometry from CMOS+BIOS if not already setup */
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-
- if ((cmos_disks & (0xf0 >> (unit*4)))
- && !drive->present && !drive->nobios) {
- unsigned short cyl = *(unsigned short *)BIOS;
- unsigned char head = *(BIOS+2);
- unsigned char sect = *(BIOS+14);
- if (cyl > 0 && head > 0 && sect > 0 && sect < 64) {
- drive->cyl = drive->bios_cyl = cyl;
- drive->head = drive->bios_head = head;
- drive->sect = drive->bios_sect = sect;
- drive->ctl = *(BIOS+8);
- } else {
- printk("hd%d: C/H/S=%d/%d/%d from BIOS ignored\n", unit, cyl, head, sect);
- }
- }
-
- BIOS += 16;
- }
-#endif
-}
-
-
-/*
- * If heads is nonzero: find a translation with this many heads and S=63.
- * Otherwise: find out how OnTrack Disk Manager would translate the disk.
- */
-static void
-ontrack(ide_drive_t *drive, int heads, unsigned int *c, int *h, int *s) {
- static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
- const byte *headp = dm_head_vals;
- unsigned long total;
-
- /*
- * The specs say: take geometry as obtained from Identify,
- * compute total capacity C*H*S from that, and truncate to
- * 1024*255*63. Now take S=63, H the first in the sequence
- * 4, 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total.
- * [Please tell aeb@cwi.nl in case this computes a
- * geometry different from what OnTrack uses.]
- */
- total = DRIVER(drive)->capacity(drive);
-
- *s = 63;
-
- if (heads) {
- *h = heads;
- *c = total / (63 * heads);
- return;
- }
-
- while (63 * headp[0] * 1024 < total && headp[1] != 0)
- headp++;
- *h = headp[0];
- *c = total / (63 * headp[0]);
-}
-
-/*
- * This routine is called from the partition-table code in pt/msdos.c.
- * It has two tasks:
- * (i) to handle Ontrack DiskManager by offsetting everything by 63 sectors,
- * or to handle EZdrive by remapping sector 0 to sector 1.
- * (ii) to invent a translated geometry.
- * Part (i) is suppressed if the user specifies the "noremap" option
- * on the command line.
- * Part (ii) is suppressed if the user specifies an explicit geometry.
- *
- * The ptheads parameter is either 0 or tells about the number of
- * heads shown by the end of the first nonempty partition.
- * If this is either 16, 32, 64, 128, 240 or 255 we'll believe it.
- *
- * The xparm parameter has the following meaning:
- * 0 = convert to CHS with fewer than 1024 cyls
- * using the same method as Ontrack DiskManager.
- * 1 = same as "0", plus offset everything by 63 sectors.
- * -1 = similar to "0", plus redirect sector 0 to sector 1.
- * 2 = convert to a CHS geometry with "ptheads" heads.
- *
- * Returns 0 if the translation was not possible, if the device was not
- * an IDE disk drive, or if a geometry was "forced" on the commandline.
- * Returns 1 if the geometry translation was successful.
- */
-int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg)
-{
- ide_drive_t *drive;
- const char *msg1 = "";
- int heads = 0;
- int c, h, s;
- int transl = 1; /* try translation */
- int ret = 0;
-
- drive = get_info_ptr(i_rdev);
- if (!drive)
- return 0;
-
- /* remap? */
- if (drive->remap_0_to_1 != 2) {
- if (xparm == 1) { /* DM */
- drive->sect0 = 63;
- msg1 = " [remap +63]";
- ret = 1;
- } else if (xparm == -1) { /* EZ-Drive */
- if (drive->remap_0_to_1 == 0) {
- drive->remap_0_to_1 = 1;
- msg1 = " [remap 0->1]";
- ret = 1;
- }
- }
- }
-
- /* There used to be code here that assigned drive->id->CHS
- to drive->CHS and that to drive->bios_CHS. However,
- some disks have id->C/H/S = 4092/16/63 but are larger than 2.1 GB.
- In such cases that code was wrong. Moreover,
- there seems to be no reason to do any of these things. */
-
- /* translate? */
- if (drive->forced_geom)
- transl = 0;
-
- /* does ptheads look reasonable? */
- if (ptheads == 32 || ptheads == 64 || ptheads == 128 ||
- ptheads == 240 || ptheads == 255)
- heads = ptheads;
-
- if (xparm == 2) {
- if (!heads ||
- (drive->bios_head >= heads && drive->bios_sect == 63))
- transl = 0;
- }
- if (xparm == -1) {
- if (drive->bios_head > 16)
- transl = 0; /* we already have a translation */
- }
-
- if (transl) {
- ontrack(drive, heads, &c, &h, &s);
- drive->bios_cyl = c;
- drive->bios_head = h;
- drive->bios_sect = s;
- ret = 1;
- }
-
- drive->part[0].nr_sects = current_capacity(drive);
-
- if (ret)
- printk("%s%s [%d/%d/%d]", msg, msg1,
- drive->bios_cyl, drive->bios_head, drive->bios_sect);
- return ret;
-}
-#endif /* CONFIG_BLK_DEV_IDE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)