[hatari-devel] Patch: IDE support for sector sizes > 512 bytes

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


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):


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/