public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Andries Brouwer <aeb@veritas.com>
To: Taisuke Yamada <tai@imasy.or.jp>
Cc: andre@linux-ide.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Large "clipped" IDE disk support for 2.4 when using old BIOS
Date: Sun, 19 Nov 2000 18:24:31 +0100	[thread overview]
Message-ID: <20001119182431.A1226@veritas.com> (raw)
In-Reply-To: <200011181930.eAIJUYA01883@research.imasy.or.jp>
In-Reply-To: <200011181930.eAIJUYA01883@research.imasy.or.jp>; from tai@imasy.or.jp on Sun, Nov 19, 2000 at 04:30:34AM +0900

On Sun, Nov 19, 2000 at 04:30:34AM +0900, Taisuke Yamada wrote:

> 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.

Hi Taisuke,

I suppose you know that no kernel patch is required
(since setmax.c does the same from user space).
Did you try setmax?
I would like to see the results - am still in the information
gathering stage - I have two largish Maxtor disks myself, one
40 GB and one 60 GB, and their behaviour is different, so
to me it seems a bit too early to come with kernel patches.

I think I already sent you setmax.c, but in case my memory
is confused let me include it here again. This is for 2.4.

Andries

-----
/* setmax.c - aeb, 000326 */
#include <stdio.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/hdreg.h>

#ifndef HDIO_DRIVE_CMD_AEB
#define HDIO_DRIVE_CMD_AEB	0x031e
#endif

#define INITIALIZE_DRIVE_PARAMETERS 0x91
#define READ_NATIVE_MAX_ADDRESS 0xf8
#define CHECK_POWER_MODE	0xe5
#define SET_MAX			0xf9

#define LBA	0x40
#define VV	1		/* if set in sectorct then NOT volatile */

struct idecmdin {
	unsigned char cmd;
	unsigned char feature;
	unsigned char nsect;
	unsigned char sect, lcyl, hcyl;
	unsigned char select;
};

struct idecmdout {
	unsigned char status;
	unsigned char error;
	unsigned char nsect;
	unsigned char sect, lcyl, hcyl;
	unsigned char select;
};

unsigned int
tolba(unsigned char *args) {
	return ((args[6] & 0xf) << 24) + (args[5] << 16) + (args[4] << 8) + args[3];
}

void
fromlba(unsigned char *args, unsigned int lba) {
	args[3] = (lba & 0xff);
	lba >>= 8;
	args[4] = (lba & 0xff);
	lba >>= 8;
	args[5] = (lba & 0xff);
	lba >>= 8;
	args[6] = (args[6] & 0xf0) | (lba & 0xf);
}

int
get_identity(int fd) {
	unsigned char args[4+512] = {WIN_IDENTIFY,0,0,1,};
	struct hd_driveid *id = (struct hd_driveid *)&args[4];

	if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
		perror("HDIO_DRIVE_CMD");
		fprintf(stderr,
			"WIN_IDENTIFY failed - trying WIN_PIDENTIFY\n");
		args[0] = WIN_PIDENTIFY;
		if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
			perror("HDIO_DRIVE_CMD");
			fprintf(stderr,
			       "WIN_PIDENTIFY also failed - giving up\n");
			exit(1);
		}
	}

	printf("lba capacity: %d sectors (%lld bytes)\n",
	       id->lba_capacity,
	       (long long) id->lba_capacity * 512);
}

/*
 * result: in LBA mode precisely what is expected
 *         in CHS mode the correct H and S, and C mod 65536.
 */
unsigned int
get_native_max(int fd, int slave) {
	unsigned char args[7];
	int i, max;

	for (i=0; i<7; i++)
		args[i] = 0;
	args[0] = READ_NATIVE_MAX_ADDRESS;
	args[6] = (slave ? 0x10 : 0) | LBA;
	if (ioctl(fd, HDIO_DRIVE_CMD_AEB, &args)) {
		perror("HDIO_DRIVE_CMD_AEB failed READ_NATIVE_MAX_ADDRESS");
		for (i=0; i<7; i++)
			printf("%d = 0x%x\n", args[i], args[i]);
		exit(1);
	}
	return tolba(args);
}

/*
 * SET_MAX_ADDRESS requires immediately preceding READ_NATIVE_MAX_ADDRESS
 *
 * Results: this fails for delta <= 254, succeeds for delta >= 255.
 * So, in order to get the last 255*512=130560 bytes back one has to reboot.
 * Side effect: reset to CurCHS=16383/16/63, CurSects=16514064.
 */
void
set_max_address(int fd, int slave, int delta) {
	unsigned char args[7];
	int i, nativemax;

	nativemax = get_native_max(fd, slave);
	printf("nativemax=%d (0x%x)\n", nativemax, nativemax);

	for (i=0; i<7; i++)
		args[i] = 0;
	args[0] = SET_MAX;
	args[1] = 0;
	fromlba(args, nativemax-delta);
	args[6] |= LBA;

	if (ioctl(fd, HDIO_DRIVE_CMD_AEB, &args)) {
		perror("HDIO_DRIVE_CMD_AEB failed SET_MAX");
		for (i=0; i<7; i++)
			printf("%d = 0x%x\n", args[i], args[i]);
		exit(1);
	}
}

static char short_opts[] = "d:";
static const struct option long_opts[] = {
	{ "delta",	required_argument,	NULL,	'd' },
        { NULL, 0, NULL, 0 }
};

static char *usage_txt =
"Call: setmax [-d D] DEVICE\n"
"\n"
"The call  \"setmax --delta D DEVICE\"  will do a SET_MAX command\n"
"to set the maximum accessible sector number D sectors\n"
"below end-of-disk.\n"
"\n"
"The call  \"setmax DEVICE\"  will do a READ_NATIVE_MAX_ADDRESS\n"
"command, and report the maximum accessible sector number.\n"
"\n"
"This is IDE-only. Probably DEVICE is /dev/hdx for some x.\n\n";

main(int argc, char **argv){
	int fd, c;
	int delta;

	/* If you modify device, also update slave, if necessary. */
	/* master: hda, hdc, hde; slave: hdb, hdd, hdf */
	char *device = NULL;	/* e.g. "/dev/hda" */
	int slave = 0;

	delta = -1;
	while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != -1) {
		switch(c) {
		case 'd':
			delta = atoi(optarg);
			break;
		case '?':
		default:
			fprintf(stderr, "unknown option\n");
			fprintf(stderr, usage_txt);
			exit(1);
		}
	}

	if (optind < argc)
		device = argv[optind];
	if (!device) {
		fprintf(stderr, "no device specified - "
			"use e.g. \"setmax /dev/hdb\"\n");
		fprintf(stderr, usage_txt);
		exit(1);
	}
	printf("Using device %s\n", device);

	fd = open(device, O_RDONLY);
	if (fd == -1) {
		perror("open");
		exit(1);
	}

	if (delta != -1) {
		printf("setting delta=%d\n", delta);
		set_max_address(fd, slave, delta);
	} else {
		int mad = get_native_max(fd, slave);
		long long bytes = (long long) (mad+1) * 512;
		int hMB = (bytes+50000000)/100000000;

		printf("native max address: %d\n", mad);
		printf("that is %lld bytes, %d.%d GB\n",
		       bytes, hMB/10, hMB%10);
	}
	get_identity(fd);

	return 0;
}

/* READ_NATIVE_MAX_ADDRESS:
 Inputs:
	features, sectorct, sectornr, cyllow, cylhi: NA
	device/head: 8 bits: obs LBA obs DEV na na na na
	command: F8
 Outputs:
 	error: 8 bits: na na na na na ABRT na na
 	sectorct: NA
	sectornr, cyllo, cylhi: native max address
	device/head: 8 bits: obs na obs DEV; 4bits native max address
	status: BSY DRDY DF na DRQ na na ERR  [010x0xx0]

SET_MAX_ADDRESS (obsolete?):
 Error: ABRT=4: command not supported, max requested exceeds
 	device capacity, CYL > 16383, command not preceded by
	READ_NATIVE_MAX_ADDRESS.
	Also error if the device is in Set_Max_Locked or Set_Max_Frozen state.
*/
-
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/

  parent reply	other threads:[~2000-11-19 17:54 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

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=20001119182431.A1226@veritas.com \
    --to=aeb@veritas.com \
    --cc=andre@linux-ide.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tai@imasy.or.jp \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox