From: Erik Andersen <andersen@codepoet.org>
To: Marcelo Tosatti <marcelo@conectiva.com.br>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
Andries Brouwer <aebr@win.tue.nl>,
Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] 6/8 Backport recent 2.6 IDE updates to 2.4.x
Date: Sun, 17 Aug 2003 00:13:52 -0600 [thread overview]
Message-ID: <20030817061352.GG17621@codepoet.org> (raw)
This patch further refines IDE geometry detection, and takes an
easier path toward detecting when a drive happens to support
things like lba48, making the code more readable and more
consistant.
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
--- linux/drivers/ide/ide-disk.c.orig 2003-08-16 20:51:58.000000000 -0600
+++ linux/drivers/ide/ide-disk.c 2003-08-16 20:56:49.000000000 -0600
@@ -106,11 +106,6 @@
{
unsigned long lba_sects, chs_sects, head, tail;
- if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
- printk("48-bit Drive: %llu \n", id->lba_capacity_2);
- return 1;
- }
-
/*
* The ATA spec tells large drives to return
* C/H/S = 16383/16/63 independent of their size.
@@ -1139,11 +1134,29 @@
return n;
}
+/*
+ * Bits 10 of command_set_1 and cfs_enable_1 must be equal,
+ * so on non-buggy drives we need test only one.
+ * However, we should also check whether these fields are valid.
+ */
+static inline int idedisk_supports_hpa(const struct hd_driveid *id)
+{
+ return (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400);
+}
+
+/*
+ * The same here.
+ */
+static inline int idedisk_supports_lba48(const struct hd_driveid *id)
+{
+ return (id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400);
+}
+
static inline void idedisk_check_hpa_lba28(ide_drive_t *drive)
{
unsigned long capacity, set_max;
- capacity = drive->id->lba_capacity;
+ capacity = drive->capacity;
set_max = idedisk_read_native_max_address(drive);
if (set_max <= capacity)
@@ -1158,7 +1171,7 @@
#ifdef CONFIG_IDEDISK_STROKE
set_max = idedisk_set_max_address(drive, set_max);
if (set_max) {
- drive->id->lba_capacity = set_max;
+ drive->capacity = set_max;
printk(KERN_INFO "%s: Host Protected Area disabled.\n",
drive->name);
}
@@ -1169,7 +1182,7 @@
{
unsigned long long capacity_2, set_max_ext;
- capacity_2 = drive->id->lba_capacity_2;
+ capacity_2 = drive->capacity48;
set_max_ext = idedisk_read_native_max_address_ext(drive);
if (set_max_ext <= capacity_2)
@@ -1184,7 +1197,8 @@
#ifdef CONFIG_IDEDISK_STROKE
set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext);
if (set_max_ext) {
- drive->id->lba_capacity_2 = set_max_ext;
+ drive->capacity48 = set_max_ext;
+ drive->capacity = (unsigned long) set_max_ext;
printk(KERN_INFO "%s: Host Protected Area disabled.\n",
drive->name);
}
@@ -1212,32 +1226,21 @@
* If this drive supports the Host Protected Area feature set,
* then we may need to change our opinion about the drive's capacity.
*/
- int hpa = (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400);
+ int hpa = idedisk_supports_hpa(id);
- if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
+ if (idedisk_supports_lba48(id)) {
/* drive speaks 48-bit LBA */
- unsigned long long capacity_2;
-
drive->select.b.lba = 1;
+ drive->capacity48 = id->lba_capacity_2;
+ drive->capacity = (unsigned long) drive->capacity48;
if (hpa)
idedisk_check_hpa_lba48(drive);
- capacity_2 = id->lba_capacity_2;
- drive->head = drive->bios_head = 255;
- drive->sect = drive->bios_sect = 63;
- drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
- drive->bios_cyl = drive->cyl;
- drive->capacity48 = capacity_2;
- drive->capacity = (unsigned long) capacity_2;
} else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
/* drive speaks 28-bit LBA */
- unsigned long capacity;
-
drive->select.b.lba = 1;
+ drive->capacity = id->lba_capacity;
if (hpa)
idedisk_check_hpa_lba28(drive);
- capacity = id->lba_capacity;
- drive->cyl = capacity / (drive->head * drive->sect);
- drive->capacity = capacity;
} else {
/* drive speaks boring old 28-bit CHS */
drive->capacity = drive->cyl * drive->head * drive->sect;
@@ -1246,7 +1249,7 @@
static u64 idedisk_capacity (ide_drive_t *drive)
{
- if (drive->id->cfs_enable_2 & 0x0400)
+ if (idedisk_supports_lba48(drive->id))
return (drive->capacity48 - drive->sect0);
return (drive->capacity - drive->sect0);
}
@@ -1572,7 +1575,7 @@
if (HWIF(drive)->addressing)
return 0;
- if (!(drive->id->cfs_enable_2 & 0x0400))
+ if (!idedisk_supports_lba48(drive->id))
return -EIO;
drive->addressing = arg;
return 0;
@@ -1696,19 +1699,28 @@
* by correcting bios_cyls:
*/
capacity = idedisk_capacity (drive);
- if (!drive->forced_geom && drive->bios_sect && drive->bios_head) {
- unsigned int cap0 = capacity; /* truncate to 32 bits */
- unsigned int cylsz, cyl;
-
- if (cap0 != capacity)
- drive->bios_cyl = 65535;
- else {
- cylsz = drive->bios_sect * drive->bios_head;
- cyl = cap0 / cylsz;
- if (cyl > 65535)
- cyl = 65535;
- if (cyl > drive->bios_cyl)
- drive->bios_cyl = cyl;
+ if (!drive->forced_geom) {
+
+ if (idedisk_supports_lba48(drive->id)) {
+ /* compatibility */
+ drive->bios_sect = 63;
+ drive->bios_head = 255;
+ }
+
+ if (drive->bios_sect && drive->bios_head) {
+ unsigned int cap0 = capacity; /* truncate to 32 bits */
+ unsigned int cylsz, cyl;
+
+ if (cap0 != capacity)
+ drive->bios_cyl = 65535;
+ else {
+ cylsz = drive->bios_sect * drive->bios_head;
+ cyl = cap0 / cylsz;
+ if (cyl > 65535)
+ cyl = 65535;
+ if (cyl > drive->bios_cyl)
+ drive->bios_cyl = cyl;
+ }
}
}
printk(KERN_INFO "%s: %llu sectors (%llu MB)",
next reply other threads:[~2003-08-17 6:18 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-17 6:13 Erik Andersen [this message]
2003-08-24 16:49 ` [PATCH] 6/8 Backport recent 2.6 IDE updates to 2.4.x Bartlomiej Zolnierkiewicz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030817061352.GG17621@codepoet.org \
--to=andersen@codepoet.org \
--cc=B.Zolnierkiewicz@elka.pw.edu.pl \
--cc=aebr@win.tue.nl \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo@conectiva.com.br \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.