Re: [hatari-devel] Patch: IDE support for sector sizes > 512 bytes |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [hatari-devel] Patch: IDE support for sector sizes > 512 bytes
- From: Uwe Seimet <Uwe.Seimet@xxxxxxxxx>
- Date: Wed, 17 Oct 2018 19:40:43 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1539798044; s=strato-dkim-0002; d=seimet.de; h=In-Reply-To:References:Message-ID:Subject:To:From:Date: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=GQ+OR3AAMm2gPUSLw95X04rY2jhkcqTmTgRk9RobFQU=; b=Gt5te62UXyAEpq9yz+KoMRr7bgEfDsNsOr2oRFHO+P9FbHhlL+PUMgzmmCU14px+4V VBtqQ7ItoR0UepFRU43+uqA9iqlsLdr9r2SkGTNCoBk6I5SFEcSAJQHJWmZfhWYmx44x D7fNwt3I8IPYxom53zZgBPW3X45dscULi7m2qPOmYgeRtjgJUdFEKDnzdI0UU8N4g23N lih77ak8RpKmHeQ7q8oCUka4ANANXKfsEn93y8whziRIQ23hIac1YqOvR8rDXmmNEcxn QynA+OKEqKPRDaym+ibUgE89CXYJwAsa1/S4lX5w1QXEs0ZGDqcjRSSODxJnD9lQO17+ RhxA==
Hi,
There was still a problem with calculating the capacity of IDE drives
with sectors > 512 bytes. The updated attached patch completely replaces
the previous patch and fixes this issue.
Best regards
Uwe
> Hi,
>
> The attached patch adds support for IDE/SATA hard disks with physical
> sector sizes of up to 4096 bytes.
> Just like with ACSI/SCSI there is a new configuration property nBlockSize.
>
> The patch was successfully tested with emulated drives with 512 and 4096
> physical bytes per sector. No backwards compatibility issues were found.
>
> Notes:
>
> - With 4096 bytes per physical sector a real Atari blocks the IDE port
> when trying to boot from such a drive. This is because the TOS boot
> code does not support sectors > 512 bytes.
> - A hard disk driver with support for IDE/SATA drives with 4096 bytes per
> sector (4KN) is required to make use of this feature with Hatari.
>
> Best regards
>
> Uwe
> diff -r 4f4871bb49f0 src/configuration.c
> --- a/src/configuration.c Tue Oct 16 06:49:32 2018 +0200
> +++ b/src/configuration.c Tue Oct 16 19:41:40 2018 +0200
> @@ -521,9 +521,11 @@
> { "bUseDevice0", Bool_Tag, &ConfigureParams.Ide[0].bUseDevice },
> { "nByteSwap0", Int_Tag, &ConfigureParams.Ide[0].nByteSwap },
> { "sDeviceFile0", String_Tag, ConfigureParams.Ide[0].sDeviceFile },
> + { "nBlockSize0", Int_Tag, &ConfigureParams.Ide[0].nBlockSize },
> { "bUseDevice1", Bool_Tag, &ConfigureParams.Ide[1].bUseDevice },
> { "nByteSwap1", Int_Tag, &ConfigureParams.Ide[1].nByteSwap },
> { "sDeviceFile1", String_Tag, ConfigureParams.Ide[1].sDeviceFile },
> + { "nBlockSize1", Int_Tag, &ConfigureParams.Ide[1].nBlockSize },
> { NULL , Error_Tag, NULL }
> };
>
> @@ -702,6 +704,7 @@
> ConfigureParams.Ide[i].bUseDevice = false;
> ConfigureParams.Ide[i].nByteSwap = BYTESWAP_AUTO;
> strcpy(ConfigureParams.Ide[i].sDeviceFile, psWorkingDir);
> + ConfigureParams.Ide[i].nBlockSize = 512;
> }
>
> /* Set defaults for Joysticks */
> diff -r 4f4871bb49f0 src/ide.c
> --- a/src/ide.c Tue Oct 16 06:49:32 2018 +0200
> +++ b/src/ide.c Tue Oct 16 19:41:40 2018 +0200
> @@ -334,6 +334,7 @@
> off_t file_size;
> int media_changed;
> int byteswap;
> + int sector_size;
>
> /* I/O stats (display with "info blockstats"). */
> uint64_t rd_bytes;
> @@ -366,7 +367,6 @@
> #define MIN(a, b) (((a) < (b)) ? (a) : (b))
>
> #define SECTOR_BITS 9
> -#define SECTOR_SIZE (1 << SECTOR_BITS)
>
>
> /**
> @@ -455,9 +455,9 @@
> if (!bs->fhndl)
> return -ENOMEDIUM;
>
> - len = nb_sectors * SECTOR_SIZE;
> + len = nb_sectors * bs->sector_size;
>
> - if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
> + if (fseeko(bs->fhndl, sector_num * bs->sector_size, SEEK_SET) != 0)
> {
> perror("bdrv_read");
> return -errno;
> @@ -503,9 +503,9 @@
> if (bs->read_only)
> return -EACCES;
>
> - len = nb_sectors * SECTOR_SIZE;
> + len = nb_sectors * bs->sector_size;
>
> - if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
> + if (fseeko(bs->fhndl, sector_num * bs->sector_size, SEEK_SET) != 0)
> {
> perror("bdrv_write");
> return -errno;
> @@ -549,7 +549,7 @@
> bs->file_size = HDC_CheckAndGetSize(filename, blockSize);
> if (bs->file_size <= 0)
> return -1;
> - if (bs->file_size < 2 * 16 * 63 * SECTOR_SIZE)
> + if (bs->file_size < 2 * 16 * 63 * bs->sector_size)
> {
> Log_AlertDlg(LOG_ERROR, "IDE disk image size (%"PRId64" bytes) is "
> "too small for an IDE disk image "
> @@ -768,6 +768,9 @@
> /* set to 1 set disable mult support */
> #define MAX_MULT_SECTORS 16
>
> +/* maximum physical IDE hard disk drive sector size */
> +#define MAX_SECTOR_SIZE 4096
> +
> /* ATAPI defines */
>
> #define ATAPI_PACKET_SIZE 12
> @@ -1031,8 +1034,8 @@
> /* ratio logical/physical: 0, logicalSectorSizeSupported */
> put_le16(p + 106, 1 << 12);
> /* words per logical sector */
> - put_le16(p + 117, 512 >> 1);
> - put_le16(p + 118, 512 >> 17);
> + put_le16(p + 117, s->bs->sector_size >> 1);
> + put_le16(p + 118, s->bs->sector_size >> 17);
>
> memcpy(s->identify_data, p, sizeof(s->identify_data));
> s->identify_set = 1;
> @@ -1234,7 +1237,7 @@
> ide_set_irq(s);
> return;
> }
> - ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
> + ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_read);
> ide_set_irq(s);
> ide_set_sector(s, sector_num + n);
> s->nsector -= n;
> @@ -1272,7 +1275,7 @@
> n1 = s->nsector;
> if (n1 > s->req_nb_sectors)
> n1 = s->req_nb_sectors;
> - ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
> + ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n1, ide_sector_write);
> }
> ide_set_sector(s, sector_num + n);
>
> @@ -2086,7 +2089,7 @@
> n = s->nsector;
> if (n > s->req_nb_sectors)
> n = s->req_nb_sectors;
> - ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
> + ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_write);
> s->media_changed = 1;
> break;
> case WIN_READ_EXT:
> @@ -2111,7 +2114,7 @@
> s->error = 0;
> s->status = SEEK_STAT | READY_STAT;
> s->req_nb_sectors = 1;
> - ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
> + ide_transfer_start(s, s->io_buffer, s->bs->sector_size, ide_sector_write);
> s->media_changed = 1;
> break;
> case WIN_MULTREAD_EXT:
> @@ -2138,7 +2141,7 @@
> n = s->nsector;
> if (n > s->req_nb_sectors)
> n = s->req_nb_sectors;
> - ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
> + ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_write);
> s->media_changed = 1;
> break;
> case WIN_READDMA_EXT:
> @@ -2537,7 +2540,7 @@
> struct partition *p;
> uint32_t nr_sects;
>
> - buf = malloc(SECTOR_SIZE);
> + buf = malloc(MAX_SECTOR_SIZE);
> if (buf == NULL)
> return -1;
> ret = bdrv_read(s->bs, 0, buf, 1);
> @@ -2591,7 +2594,7 @@
> for (i = 0; i < 2; i++)
> {
> s = ide_state + i;
> - s->io_buffer = malloc(MAX_MULT_SECTORS * 512 + 4);
> + s->io_buffer = malloc(MAX_MULT_SECTORS * MAX_SECTOR_SIZE + 4);
> assert(s->io_buffer);
> if (i == 0)
> s->bs = hd0;
> @@ -2704,7 +2707,7 @@
> if (ConfigureParams.Ide[i].bUseDevice)
> {
> int is_byteswap;
> - bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, 512, 0);
> + bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, ConfigureParams.Ide[i].nBlockSize, 0);
> nIDEPartitions += HDC_PartitionCount(hd_table[i]->fhndl, TRACE_IDE, &is_byteswap);
> /* Our IDE implementation is little endian by default,
> * so we need to byteswap if the image is not swapped! */
> @@ -2712,6 +2715,8 @@
> hd_table[i]->byteswap = !is_byteswap;
> else
> hd_table[i]->byteswap = !ConfigureParams.Ide[i].nByteSwap;
> +
> + hd_table[i]->sector_size = ConfigureParams.Ide[i].nBlockSize;
> }
> }
>
> diff -r 4f4871bb49f0 src/includes/configuration.h
> --- a/src/includes/configuration.h Tue Oct 16 06:49:32 2018 +0200
> +++ b/src/includes/configuration.h Tue Oct 16 19:41:40 2018 +0200
> @@ -243,6 +243,7 @@
> bool bUseDevice;
> BYTESWAPPING nByteSwap;
> char sDeviceFile[FILENAME_MAX];
> + int nBlockSize;
> } CNF_IDEDEV;
>
> /* Falcon register $FFFF8006 bits 6 & 7 (mirrored in $FFFF82C0 bits 0 & 1):
diff -r 4f4871bb49f0 src/configuration.c
--- a/src/configuration.c Tue Oct 16 06:49:32 2018 +0200
+++ b/src/configuration.c Wed Oct 17 19:33:24 2018 +0200
@@ -521,9 +521,11 @@
{ "bUseDevice0", Bool_Tag, &ConfigureParams.Ide[0].bUseDevice },
{ "nByteSwap0", Int_Tag, &ConfigureParams.Ide[0].nByteSwap },
{ "sDeviceFile0", String_Tag, ConfigureParams.Ide[0].sDeviceFile },
+ { "nBlockSize0", Int_Tag, &ConfigureParams.Ide[0].nBlockSize },
{ "bUseDevice1", Bool_Tag, &ConfigureParams.Ide[1].bUseDevice },
{ "nByteSwap1", Int_Tag, &ConfigureParams.Ide[1].nByteSwap },
{ "sDeviceFile1", String_Tag, ConfigureParams.Ide[1].sDeviceFile },
+ { "nBlockSize1", Int_Tag, &ConfigureParams.Ide[1].nBlockSize },
{ NULL , Error_Tag, NULL }
};
@@ -702,6 +704,7 @@
ConfigureParams.Ide[i].bUseDevice = false;
ConfigureParams.Ide[i].nByteSwap = BYTESWAP_AUTO;
strcpy(ConfigureParams.Ide[i].sDeviceFile, psWorkingDir);
+ ConfigureParams.Ide[i].nBlockSize = 512;
}
/* Set defaults for Joysticks */
diff -r 4f4871bb49f0 src/ide.c
--- a/src/ide.c Tue Oct 16 06:49:32 2018 +0200
+++ b/src/ide.c Wed Oct 17 19:33:24 2018 +0200
@@ -334,6 +334,7 @@
off_t file_size;
int media_changed;
int byteswap;
+ int sector_size;
/* I/O stats (display with "info blockstats"). */
uint64_t rd_bytes;
@@ -365,9 +366,6 @@
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define SECTOR_BITS 9
-#define SECTOR_SIZE (1 << SECTOR_BITS)
-
/**
* return 0 as number of sectors if no device present or error
@@ -379,7 +377,7 @@
if (length < 0)
length = 0;
else
- length = length >> SECTOR_BITS;
+ length = length / bs->sector_size;
*nb_sectors_ptr = length;
}
@@ -455,9 +453,9 @@
if (!bs->fhndl)
return -ENOMEDIUM;
- len = nb_sectors * SECTOR_SIZE;
+ len = nb_sectors * bs->sector_size;
- if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
+ if (fseeko(bs->fhndl, sector_num * bs->sector_size, SEEK_SET) != 0)
{
perror("bdrv_read");
return -errno;
@@ -503,9 +501,9 @@
if (bs->read_only)
return -EACCES;
- len = nb_sectors * SECTOR_SIZE;
+ len = nb_sectors * bs->sector_size;
- if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
+ if (fseeko(bs->fhndl, sector_num * bs->sector_size, SEEK_SET) != 0)
{
perror("bdrv_write");
return -errno;
@@ -549,7 +547,7 @@
bs->file_size = HDC_CheckAndGetSize(filename, blockSize);
if (bs->file_size <= 0)
return -1;
- if (bs->file_size < 2 * 16 * 63 * SECTOR_SIZE)
+ if (bs->file_size < 2 * 16 * 63 * bs->sector_size)
{
Log_AlertDlg(LOG_ERROR, "IDE disk image size (%"PRId64" bytes) is "
"too small for an IDE disk image "
@@ -768,6 +766,9 @@
/* set to 1 set disable mult support */
#define MAX_MULT_SECTORS 16
+/* maximum physical IDE hard disk drive sector size */
+#define MAX_SECTOR_SIZE 4096
+
/* ATAPI defines */
#define ATAPI_PACKET_SIZE 12
@@ -1031,8 +1032,8 @@
/* ratio logical/physical: 0, logicalSectorSizeSupported */
put_le16(p + 106, 1 << 12);
/* words per logical sector */
- put_le16(p + 117, 512 >> 1);
- put_le16(p + 118, 512 >> 17);
+ put_le16(p + 117, s->bs->sector_size >> 1);
+ put_le16(p + 118, s->bs->sector_size >> 17);
memcpy(s->identify_data, p, sizeof(s->identify_data));
s->identify_set = 1;
@@ -1234,7 +1235,7 @@
ide_set_irq(s);
return;
}
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
+ ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_read);
ide_set_irq(s);
ide_set_sector(s, sector_num + n);
s->nsector -= n;
@@ -1272,7 +1273,7 @@
n1 = s->nsector;
if (n1 > s->req_nb_sectors)
n1 = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
+ ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n1, ide_sector_write);
}
ide_set_sector(s, sector_num + n);
@@ -2086,7 +2087,7 @@
n = s->nsector;
if (n > s->req_nb_sectors)
n = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
+ ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_write);
s->media_changed = 1;
break;
case WIN_READ_EXT:
@@ -2111,7 +2112,7 @@
s->error = 0;
s->status = SEEK_STAT | READY_STAT;
s->req_nb_sectors = 1;
- ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
+ ide_transfer_start(s, s->io_buffer, s->bs->sector_size, ide_sector_write);
s->media_changed = 1;
break;
case WIN_MULTREAD_EXT:
@@ -2138,7 +2139,7 @@
n = s->nsector;
if (n > s->req_nb_sectors)
n = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
+ ide_transfer_start(s, s->io_buffer, s->bs->sector_size * n, ide_sector_write);
s->media_changed = 1;
break;
case WIN_READDMA_EXT:
@@ -2537,7 +2538,7 @@
struct partition *p;
uint32_t nr_sects;
- buf = malloc(SECTOR_SIZE);
+ buf = malloc(MAX_SECTOR_SIZE);
if (buf == NULL)
return -1;
ret = bdrv_read(s->bs, 0, buf, 1);
@@ -2591,7 +2592,7 @@
for (i = 0; i < 2; i++)
{
s = ide_state + i;
- s->io_buffer = malloc(MAX_MULT_SECTORS * 512 + 4);
+ s->io_buffer = malloc(MAX_MULT_SECTORS * MAX_SECTOR_SIZE + 4);
assert(s->io_buffer);
if (i == 0)
s->bs = hd0;
@@ -2704,7 +2705,7 @@
if (ConfigureParams.Ide[i].bUseDevice)
{
int is_byteswap;
- bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, 512, 0);
+ bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, ConfigureParams.Ide[i].nBlockSize, 0);
nIDEPartitions += HDC_PartitionCount(hd_table[i]->fhndl, TRACE_IDE, &is_byteswap);
/* Our IDE implementation is little endian by default,
* so we need to byteswap if the image is not swapped! */
@@ -2712,6 +2713,8 @@
hd_table[i]->byteswap = !is_byteswap;
else
hd_table[i]->byteswap = !ConfigureParams.Ide[i].nByteSwap;
+
+ hd_table[i]->sector_size = ConfigureParams.Ide[i].nBlockSize;
}
}
diff -r 4f4871bb49f0 src/includes/configuration.h
--- a/src/includes/configuration.h Tue Oct 16 06:49:32 2018 +0200
+++ b/src/includes/configuration.h Wed Oct 17 19:33:24 2018 +0200
@@ -243,6 +243,7 @@
bool bUseDevice;
BYTESWAPPING nByteSwap;
char sDeviceFile[FILENAME_MAX];
+ int nBlockSize;
} CNF_IDEDEV;
/* Falcon register $FFFF8006 bits 6 & 7 (mirrored in $FFFF82C0 bits 0 & 1):