public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS
@ 2000-11-18 19:30 Taisuke Yamada
  2000-11-18 20:05 ` Andre Hedrick
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Taisuke Yamada @ 2000-11-18 19:30 UTC (permalink / raw)
  To: andre; +Cc: linux-kernel, tai


Hi.

Earlier this month, I had sent in a patch to 2.2.18pre17 (with
IDE-patch from http://www.linux-ide.org/ applied) to add support
for IDE disk larger than 32GB, even if the disk required "clipping"
to reduce apparent disk size due to BIOS limitation.

BIOS known to have this limitation is Award 4.51 (and before) and
it seems many mainboards with not-so-great vendor support still use it.

Now I'm moving to 2.4-based system, and so ported the patch to
2.4-test10. It also applies cleanly to 2.4-test11.

With this patch, you will be able to use disk capacity above
32GB (or 2GB/8GB depending on how clipping take effect), and
still be able to boot off from the disk because you can leave
the "clipping" turned on.

>From my experience, this patch works with both software and
hardware clipping (or jumpering). This is probably because
hardware jumper works as a flag to the disk to enable software
clipping on hardware reset. But I'm not sure if this applies to
all disks.

By the way, is it safe for me to use IDE_*_OFFSET macro as a index
for IDE task command buffer? I couldn't use IDE_COMMAND_OFFSET (== 7),
and had to specify 0 because that's what ide_cmd function requires.

Anyway, here's the patch. Hope it works well on other systems...

--- cut here --- cut here --- cut here --- cut here --- cut here ---
--- linux/drivers/ide/ide-disk.c.orig    Sun Nov 19 03:17:57 2000
+++ linux/drivers/ide/ide-disk.c    Sun Nov 19 03:22:43 2000
@@ -514,23 +514,147 @@
 }
 
 /*
+ * Tests if the drive supports Host Protected Area feature.
+ * Returns true if supported, false otherwise.
+ */
+static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
+{
+    int flag = (drive->id->command_set_1 & 0x0a) ? 1 : 0;
+    printk("%s: host protected area => %d\n", drive->name, flag);
+    return flag;
+}
+
+/*
+ * Queries for true maximum capacity of the drive.
+ * Returns maximum LBA address (> 0) of the drive, 0 if failed.
+ */
+static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
+{
+    byte args[7];
+    unsigned long addr = 0;
+
+    printk("%s: checking for max native LBA...\n", drive->name);
+
+    /* Create IDE/ATA command request structure
+     *
+     * NOTE: I'm not sure if I can safely use IDE_*_OFFSET macro
+     *       here...For real ATA command structure, offset for IDE
+     *       command is 7, but in IDE driver, it needs to be at 0th
+     *       index (same goes for IDE status offset below). Hmm...
+     */
+    args[0]                  = 0xf8; /* READ_NATIVE_MAX - see ATA spec */
+    args[IDE_FEATURE_OFFSET] = 0x00;
+    args[IDE_NSECTOR_OFFSET] = 0x00;
+    args[IDE_SECTOR_OFFSET]  = 0x00;
+    args[IDE_LCYL_OFFSET]    = 0x00;
+    args[IDE_HCYL_OFFSET]    = 0x00;
+    args[IDE_SELECT_OFFSET]  = 0x40;
+
+    /* submit command request - if OK, read current max LBA value */
+    if (ide_wait_cmd_task(drive, args) == 0) {
+        if ((args[0] & 0x01) == 0) {
+            addr = ((args[IDE_SELECT_OFFSET] & 0x0f) << 24)
+                 | ((args[IDE_HCYL_OFFSET]         ) << 16)
+                 | ((args[IDE_LCYL_OFFSET]         ) <<  8)
+                 | ((args[IDE_SECTOR_OFFSET]       ));
+        }
+    }
+
+    printk("%s: max native LBA is %lu\n", drive->name, addr);
+
+    return addr;
+}
+
+/*
+ * Sets maximum virtual LBA address of the drive.
+ * Returns new maximum virtual LBA address (> 0) or 0 on failure.
+ */
+static unsigned long idedisk_set_max_address(ide_drive_t  *drive,
+                         unsigned long addr_req)
+{
+    byte args[7];
+    unsigned long addr_set = 0;
+
+    printk("%s: (un)clipping max LBA...\n", drive->name);
+
+    /* Create IDE/ATA command request structure
+     *
+     * NOTE: I'm not sure if I can safely use IDE_*_OFFSET macro
+     *       here...For real ATA command structure, offset for IDE
+     *       command is 7, but in IDE driver, it needs to be at 0th
+     *       index (same goes for IDE status offset below). Hmm...
+     */
+    args[0]                  = 0xf9; /* SET_MAX - see ATA spec */
+    args[IDE_FEATURE_OFFSET] = 0x00;
+    args[IDE_NSECTOR_OFFSET] = 0x00;
+    args[IDE_SECTOR_OFFSET]  = ((addr_req      ) & 0xff);
+    args[IDE_LCYL_OFFSET]    = ((addr_req >>  8) & 0xff);
+    args[IDE_HCYL_OFFSET]    = ((addr_req >> 16) & 0xff);
+    args[IDE_SELECT_OFFSET]  = ((addr_req >> 24) & 0x0f) | 0x40;
+
+    /* submit command request - if OK, read new max LBA value */
+    if (ide_wait_cmd_task(drive, args) == 0) {
+        if ((args[0] & 0x01) == 0) {
+            addr_set = ((args[IDE_SELECT_OFFSET] & 0x0f) << 24)
+                 | ((args[IDE_HCYL_OFFSET]         ) << 16)
+                 | ((args[IDE_LCYL_OFFSET]         ) <<  8)
+                 | ((args[IDE_SECTOR_OFFSET]       ));
+        }
+    }
+
+    printk("%s: max LBA (un)clipped to %lu\n", drive->name, addr_set);
+
+    return addr_set;
+}
+
+/*
  * Compute drive->capacity, the full capacity of the drive
  * Called with drive->id != NULL.
+ *
+ * To compute capacity, this uses either of
+ *
+ *    1. CHS value set by user       (whatever user sets will be trusted)
+ *    2. LBA value from target drive (require new ATA feature)
+ *    3. LBA value from system BIOS  (new one is OK, old one may break)
+ *    4. CHS value from system BIOS  (traditional style)
+ *
+ * in above order (i.e., if value of higher priority is available,
+ * rest of the values are ignored).
  */
 static void init_idedisk_capacity (ide_drive_t  *drive)
 {
+    unsigned long      hd_max;
+    unsigned long      hd_cap = drive->cyl * drive->head * drive->sect;
+    int                is_lba = 0;
+
     struct hd_driveid *id = drive->id;
-    unsigned long capacity = drive->cyl * drive->head * drive->sect;
 
-    drive->select.b.lba = 0;
+    /* Unless geometry is given by user, use autodetected value */
+    if (! drive->forced_geom) {
+        /* If BIOS LBA geometry is available, use it */
+        if ((id->capability & 2) && lba_capacity_is_ok(id)) {
+            hd_cap = id->lba_capacity;
+            is_lba = 1;
+        }
 
-    /* Determine capacity, and use LBA if the drive properly supports it */
-    if ((id->capability & 2) && lba_capacity_is_ok(id)) {
-        capacity = id->lba_capacity;
-        drive->cyl = capacity / (drive->head * drive->sect);
-        drive->select.b.lba = 1;
+        /* If new ATA feature is supported, try using it */
+        if (idedisk_supports_host_protected_area(drive)) {
+            hd_max = idedisk_read_native_max_address(drive);
+            hd_max = idedisk_set_max_address(drive, hd_max);
+
+            if (hd_max > 0) {
+                hd_cap = hd_max;
+                is_lba = 1;
+            }
+        }
     }
-    drive->capacity = capacity;
+
+    printk("%s: lba = %d, cap = %lu\n", drive->name, is_lba, hd_cap);
+
+    /* update parameters with fetched results */
+    drive->select.b.lba = is_lba;
+    drive->capacity     = hd_cap;
+    drive->cyl          = hd_cap / (drive->head * drive->sect);
 }
 
 static unsigned long idedisk_capacity (ide_drive_t  *drive)
--- cut here --- cut here --- cut here --- cut here --- cut here ---

--
Taisuke Yamada <tai@imasy.or.jp>
PGP fingerprint = 6B 57 1B ED 65 4C 7D AE  57 1B 49 A7 F7 C8 23 46
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 17+ messages in thread
* Re: [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS
@ 2000-11-20 14:19 Andries.Brouwer
  0 siblings, 0 replies; 17+ messages in thread
From: Andries.Brouwer @ 2000-11-20 14:19 UTC (permalink / raw)
  To: aeb, andre; +Cc: linux-kernel, tai

    From andre@linux-ide.org Mon Nov 20 12:29:59 2000

    Andries,

    Don't you mean

    (drive->id->cfs_enable_1 & 0x0400)        word85
    and not
    (drive->id->command_set_1 & 0x0400)        word82

    Because when bit 10 of word 85 is not set then clip or HPArea is not enabled.

I saw no reason to complain about that part.

As far as I can see, ATA4 and ATA5 both require these two bits
to be identical. (Note that ATA4 has "supported" both in text
and table in both places, while ATA5 has "supported" in three
places and "enabled" in one. My preliminary ATA6 drafts do not differ.
And for example, there is no Set Features subcommand to enable/disable
the Host Protected Area feature. Maybe you have more recent drafts that
do allow disabling this feature?)

A small detail that might be improved is that one is only allowed to look
at this bit when words 83 and 84 have bit 15 equal to 0 and bit 14 equal to 1.
(Or, in case you prefer looking at word 85, bit 15 of word 87
must be 0 and bit 14 must be 1.)

Andries
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2000-12-30 17:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-18 19:30 [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS Taisuke Yamada
2000-11-18 20:05 ` Andre Hedrick
2000-11-19 16:41 ` Dan Aloni
2000-11-19 16:51   ` Andre Hedrick
2000-11-19 22:13   ` [PATCH] Large "clipped" IDE disk support for 2.4 when using oldBIOS Taisuke Yamada
2000-11-19 22:41     ` Dan Aloni
2000-11-19 23:11       ` [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS Taisuke Yamada
2000-11-19 23:38         ` Dan Aloni
2000-11-20  0:01           ` Andre Hedrick
2000-11-20  0:17             ` Dan Aloni
2000-11-19 17:24 ` Andries Brouwer
2000-11-19 22:30   ` Taisuke Yamada
     [not found]     ` <20001120032615.A1540@veritas.com>
2000-11-20 11:28       ` Andre Hedrick
2000-11-20 11:59       ` T. Yamada
2000-11-20 12:02         ` Andre Hedrick
2000-12-30 17:06 ` [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS (fixed patch) Tommi Virtanen
  -- strict thread matches above, loose matches on Subject: below --
2000-11-20 14:19 [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS Andries.Brouwer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox