[hatari-devel] Patch for ACSI/SCSI drives with block sizes > 512 bytes

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


Hi all,

I attached a patch which adds support for drives with block sizes >
512 bytes (currently ACSI/SCSI only). By default (i.e. without explicit
configuration) the block size is 512 bytes, so there should not be any
compatibility issues.

I hope that you will accept this patch. I know it's quite special, but
on the other hand, devices with 2048 and 4096 physical bytes per sector
are real (optical media, 4KN SATA drives) and can be used with the Atari,
so the patch is not that exotic. If the patch is accepted I will most likely
also provide the required changes for IDE.

The additional configuration property for ACSI/SCSI is called
ConfigureParams.nBlockSize.

@Thomas Please check your configuration setup for SCSI ID 7 in
configuration.c. Looks as if the initialization for SCSI ID 7 was missing.
I added the missing part in the attached patch.

Best regards

Uwe
diff -r bdfce9ffb31b src/configuration.c
--- a/src/configuration.c	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/configuration.c	Thu Oct 11 14:58:51 2018 +0200
@@ -460,20 +460,28 @@
 {
 	{ "bUseDevice0", Bool_Tag, &ConfigureParams.Acsi[0].bUseDevice },
 	{ "sDeviceFile0", String_Tag, ConfigureParams.Acsi[0].sDeviceFile },
+	{ "nBlockSize0", Int_Tag, &ConfigureParams.Acsi[0].nBlockSize },
 	{ "bUseDevice1", Bool_Tag, &ConfigureParams.Acsi[1].bUseDevice },
 	{ "sDeviceFile1", String_Tag, ConfigureParams.Acsi[1].sDeviceFile },
+	{ "nBlockSize1", Int_Tag, &ConfigureParams.Acsi[1].nBlockSize },
 	{ "bUseDevice2", Bool_Tag, &ConfigureParams.Acsi[2].bUseDevice },
-	{ "sDeviceFile2", String_Tag, ConfigureParams.Acsi[2].sDeviceFile },
+	{ "sDeviceFile2", String_Tag, &ConfigureParams.Acsi[2].sDeviceFile },
+	{ "nBlockSize2", Int_Tag, &ConfigureParams.Acsi[2].nBlockSize },
 	{ "bUseDevice3", Bool_Tag, &ConfigureParams.Acsi[3].bUseDevice },
 	{ "sDeviceFile3", String_Tag, ConfigureParams.Acsi[3].sDeviceFile },
+	{ "nBlockSize3", Int_Tag, &ConfigureParams.Acsi[3].nBlockSize },
 	{ "bUseDevice4", Bool_Tag, &ConfigureParams.Acsi[4].bUseDevice },
 	{ "sDeviceFile4", String_Tag, ConfigureParams.Acsi[4].sDeviceFile },
+	{ "nBlockSize4", Int_Tag, &ConfigureParams.Acsi[4].nBlockSize },
 	{ "bUseDevice5", Bool_Tag, &ConfigureParams.Acsi[5].bUseDevice },
 	{ "sDeviceFile5", String_Tag, ConfigureParams.Acsi[5].sDeviceFile },
+	{ "nBlockSize5", Int_Tag, &ConfigureParams.Acsi[5].nBlockSize },
 	{ "bUseDevice6", Bool_Tag, &ConfigureParams.Acsi[6].bUseDevice },
 	{ "sDeviceFile6", String_Tag, ConfigureParams.Acsi[6].sDeviceFile },
+	{ "nBlockSize6", Int_Tag, &ConfigureParams.Acsi[6].nBlockSize },
 	{ "bUseDevice7", Bool_Tag, &ConfigureParams.Acsi[7].bUseDevice },
 	{ "sDeviceFile7", String_Tag, ConfigureParams.Acsi[7].sDeviceFile },
+	{ "nBlockSize7", Int_Tag, &ConfigureParams.Acsi[7].nBlockSize },
 	{ NULL , Error_Tag, NULL }
 };
 
@@ -482,18 +490,28 @@
 {
 	{ "bUseDevice0", Bool_Tag, &ConfigureParams.Scsi[0].bUseDevice },
 	{ "sDeviceFile0", String_Tag, ConfigureParams.Scsi[0].sDeviceFile },
+	{ "nBlockSize0", Int_Tag, &ConfigureParams.Scsi[0].nBlockSize },
 	{ "bUseDevice1", Bool_Tag, &ConfigureParams.Scsi[1].bUseDevice },
 	{ "sDeviceFile1", String_Tag, ConfigureParams.Scsi[1].sDeviceFile },
+	{ "nBlockSize1", Int_Tag, &ConfigureParams.Scsi[1].nBlockSize },
 	{ "bUseDevice2", Bool_Tag, &ConfigureParams.Scsi[2].bUseDevice },
 	{ "sDeviceFile2", String_Tag, ConfigureParams.Scsi[2].sDeviceFile },
+	{ "nBlockSize2", Int_Tag, &ConfigureParams.Scsi[2].nBlockSize },
 	{ "bUseDevice3", Bool_Tag, &ConfigureParams.Scsi[3].bUseDevice },
 	{ "sDeviceFile3", String_Tag, ConfigureParams.Scsi[3].sDeviceFile },
+	{ "nBlockSize3", Int_Tag, &ConfigureParams.Scsi[3].nBlockSize },
 	{ "bUseDevice4", Bool_Tag, &ConfigureParams.Scsi[4].bUseDevice },
 	{ "sDeviceFile4", String_Tag, ConfigureParams.Scsi[4].sDeviceFile },
+	{ "nBlockSize4", Int_Tag, &ConfigureParams.Scsi[4].nBlockSize },
 	{ "bUseDevice5", Bool_Tag, &ConfigureParams.Scsi[5].bUseDevice },
 	{ "sDeviceFile5", String_Tag, ConfigureParams.Scsi[5].sDeviceFile },
+	{ "nBlockSize5", Int_Tag, &ConfigureParams.Scsi[5].nBlockSize },
 	{ "bUseDevice6", Bool_Tag, &ConfigureParams.Scsi[6].bUseDevice },
 	{ "sDeviceFile6", String_Tag, ConfigureParams.Scsi[6].sDeviceFile },
+	{ "nBlockSize6", Int_Tag, &ConfigureParams.Scsi[6].nBlockSize },
+	{ "bUseDevice7", Bool_Tag, &ConfigureParams.Scsi[7].bUseDevice },
+	{ "sDeviceFile7", String_Tag, ConfigureParams.Scsi[7].sDeviceFile },
+	{ "nBlockSize7", Int_Tag, &ConfigureParams.Scsi[7].nBlockSize },
 	{ NULL , Error_Tag, NULL }
 };
 
@@ -669,12 +687,14 @@
 	{
 		ConfigureParams.Acsi[i].bUseDevice = false;
 		strcpy(ConfigureParams.Acsi[i].sDeviceFile, psWorkingDir);
+                ConfigureParams.Acsi[i].nBlockSize = 512;
 	}
 	/* SCSI */
 	for (i = 0; i < MAX_SCSI_DEVS; i++)
 	{
 		ConfigureParams.Scsi[i].bUseDevice = false;
 		strcpy(ConfigureParams.Scsi[i].sDeviceFile, psWorkingDir);
+                ConfigureParams.Scsi[i].nBlockSize = 512;
 	}
 	/* IDE */
 	for (i = 0; i < MAX_IDE_DEVS; i++)
diff -r bdfce9ffb31b src/hdc.c
--- a/src/hdc.c	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/hdc.c	Thu Oct 11 14:58:51 2018 +0200
@@ -90,7 +90,7 @@
  */
 static unsigned long HDC_GetLBA(SCSI_CTRLR *ctr)
 {
-	/* offset = logical block address * 512 */
+	/* offset = logical block address * physical sector size */
 	if (ctr->opcode < 0x20)				/* Class 0? */
 		return HDC_ReadInt24(ctr->command, 1) & 0x1FFFFF;
 	else
@@ -166,7 +166,7 @@
 	          HDC_CmdInfoStr(ctr), dev->nLastBlockAddr);
 
 	if (dev->nLastBlockAddr < dev->hdSize &&
-	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * 512L, SEEK_SET) == 0)
+	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * dev->blockSize, SEEK_SET) == 0)
 	{
 		LOG_TRACE(TRACE_SCSI_CMD, " -> OK\n");
 		ctr->status = HD_STATUS_OK;
@@ -438,11 +438,11 @@
 	buf[0] = (nSectors >> 24) & 0xFF;
 	buf[1] = (nSectors >> 16) & 0xFF;
 	buf[2] = (nSectors >> 8) & 0xFF;
-	buf[3] = (nSectors) & 0xFF;
-	buf[4] = 0x00;
-	buf[5] = 0x00;
-	buf[6] = 0x02;
-	buf[7] = 0x00;
+	buf[3] = nSectors & 0xFF;
+	buf[4] = (dev->blockSize >> 24) & 0xFF;
+	buf[5] = (dev->blockSize >> 16) & 0xFF;
+	buf[6] = (dev->blockSize >> 8) & 0xFF;
+	buf[7] = dev->blockSize & 0xFF;
 
 	ctr->status = HD_STATUS_OK;
 	dev->nLastError = HD_REQSENS_OK;
@@ -464,14 +464,14 @@
 
 	/* seek to the position */
 	if (dev->nLastBlockAddr >= dev->hdSize ||
-	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * 512L, SEEK_SET) != 0)
+	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * dev->blockSize, SEEK_SET) != 0)
 	{
 		ctr->status = HD_STATUS_ERROR;
 		dev->nLastError = HD_REQSENS_INVADDR;
 	}
 	else
 	{
-		ctr->data_len = HDC_GetCount(ctr) * 512;
+		ctr->data_len = HDC_GetCount(ctr) * dev->blockSize;
 		if (ctr->data_len)
 		{
 			HDC_PrepRespBuf(ctr, ctr->data_len);
@@ -509,15 +509,15 @@
 
 	/* seek to the position */
 	if (dev->nLastBlockAddr >= dev->hdSize ||
-	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * 512L, SEEK_SET) != 0)
+	    fseeko(dev->image_file, (off_t)dev->nLastBlockAddr * dev->blockSize, SEEK_SET) != 0)
 	{
 		ctr->status = HD_STATUS_ERROR;
 		dev->nLastError = HD_REQSENS_INVADDR;
 	}
 	else
 	{
-		buf = HDC_PrepRespBuf(ctr, 512 * HDC_GetCount(ctr));
-		n = fread(buf, 512, HDC_GetCount(ctr), dev->image_file);
+		buf = HDC_PrepRespBuf(ctr, dev->blockSize * HDC_GetCount(ctr));
+		n = fread(buf, dev->blockSize, HDC_GetCount(ctr), dev->image_file);
 		if (n == HDC_GetCount(ctr))
 		{
 			ctr->status = HD_STATUS_OK;
@@ -751,7 +751,7 @@
  * Check file size for sane values (non-zero, multiple of 512),
  * and return the size
  */
-off_t HDC_CheckAndGetSize(const char *filename)
+off_t HDC_CheckAndGetSize(const char *filename, unsigned long blockSize)
 {
 	off_t filesize;
 	char shortname[48];
@@ -778,12 +778,12 @@
 		             shortname);
 		return -EINVAL;
 	}
-	if ((filesize & 0x1ff) != 0)
+	if ((filesize & (blockSize - 1)) != 0)
 	{
 		Log_AlertDlg(LOG_ERROR, "Can not use the hard disk image file\n"
 		                        "'%s'\nsince its size is not a multiple"
-		                        " of 512.",
-		            shortname);
+		                        " of %ld.",
+                            shortname, blockSize);
 		return -EINVAL;
 	}
 
@@ -793,7 +793,7 @@
 /**
  * Open a disk image file
  */
-int HDC_InitDevice(SCSI_DEV *dev, char *filename)
+int HDC_InitDevice(SCSI_DEV *dev, char *filename, unsigned long blockSize)
 {
 	off_t filesize;
 	FILE *fp;
@@ -802,7 +802,7 @@
 	Log_Printf(LOG_INFO, "Mounting hard drive image '%s'\n", filename);
 
 	/* Check size for sanity */
-	filesize = HDC_CheckAndGetSize(filename);
+	filesize = HDC_CheckAndGetSize(filename, blockSize);
 	if (filesize < 0)
 		return filesize;
 
@@ -819,7 +819,8 @@
 		return -ENOLCK;
 	}
 
-	dev->hdSize = filesize / 512;
+        dev->blockSize = blockSize;
+	dev->hdSize = filesize / dev->blockSize;
 	dev->image_file = fp;
 	dev->enabled = true;
 
@@ -849,7 +850,7 @@
 	{
 		if (!ConfigureParams.Acsi[i].bUseDevice)
 			continue;
-		if (HDC_InitDevice(&AcsiBus.devs[i], ConfigureParams.Acsi[i].sDeviceFile) == 0)
+		if (HDC_InitDevice(&AcsiBus.devs[i], ConfigureParams.Acsi[i].sDeviceFile, ConfigureParams.Acsi[i].nBlockSize) == 0)
 		{
 			bAcsiEmuOn = true;
 			nAcsiPartitions += HDC_PartitionCount(AcsiBus.devs[i].image_file, TRACE_SCSI_CMD, NULL);
diff -r bdfce9ffb31b src/ide.c
--- a/src/ide.c	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/ide.c	Thu Oct 11 14:58:51 2018 +0200
@@ -541,12 +541,12 @@
 }
 
 
-static int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
+static int bdrv_open(BlockDriverState *bs, const char *filename, unsigned long blockSize, int flags)
 {
 	Log_Printf(LOG_INFO, "Mounting IDE hard drive image %s\n", filename);
 
 	bs->read_only = 0;
-	bs->file_size = HDC_CheckAndGetSize(filename);
+	bs->file_size = HDC_CheckAndGetSize(filename, blockSize);
 	if (bs->file_size <= 0)
 		return -1;
 	if (bs->file_size < 2 * 16 * 63 * SECTOR_SIZE)
@@ -2698,7 +2698,7 @@
 		if (ConfigureParams.Ide[i].bUseDevice)
 		{
 			int is_byteswap;
-			bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, 0);
+			bdrv_open(hd_table[i], ConfigureParams.Ide[i].sDeviceFile, 512, 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! */
diff -r bdfce9ffb31b src/includes/configuration.h
--- a/src/includes/configuration.h	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/includes/configuration.h	Thu Oct 11 14:58:51 2018 +0200
@@ -228,6 +228,7 @@
 {
   bool bUseDevice;
   char sDeviceFile[FILENAME_MAX];
+  int nBlockSize;
 } CNF_SCSIDEV;
 
 typedef enum
diff -r bdfce9ffb31b src/includes/hdc.h
--- a/src/includes/hdc.h	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/includes/hdc.h	Thu Oct 11 14:58:51 2018 +0200
@@ -57,6 +57,7 @@
 	bool bSetLastBlockAddr;
 	Uint8 nLastError;
 	unsigned long hdSize;       /* Size of the hard disk in sectors */
+        unsigned long blockSize;    /* Size of a sector in bytes */
 	/* For NCR5380 emulation: */
 	int direction;
 	Uint8 msgout[4];
@@ -93,12 +94,12 @@
  */
 extern bool HDC_Init(void);
 extern void HDC_UnInit(void);
-extern int HDC_InitDevice(SCSI_DEV *dev, char *filename);
+extern int HDC_InitDevice(SCSI_DEV *dev, char *filename, unsigned long blockSize);
 extern void HDC_ResetCommandStatus(void);
 extern short int HDC_ReadCommandByte(int addr);
 extern void HDC_WriteCommandByte(int addr, Uint8 byte);
 extern int HDC_PartitionCount(FILE *fp, const Uint64 tracelevel, int *pIsByteSwapped);
-extern off_t HDC_CheckAndGetSize(const char *filename);
+extern off_t HDC_CheckAndGetSize(const char *filename, unsigned long blockSize);
 extern bool HDC_WriteCommandPacket(SCSI_CTRLR *ctr, Uint8 b);
 extern void HDC_DmaTransfer(void);
 
diff -r bdfce9ffb31b src/ncr5380.c
--- a/src/ncr5380.c	Wed Oct 10 07:14:25 2018 +0200
+++ b/src/ncr5380.c	Thu Oct 11 14:58:51 2018 +0200
@@ -1019,7 +1019,7 @@
 	{
 		if (!ConfigureParams.Scsi[i].bUseDevice)
 			continue;
-		if (HDC_InitDevice(&ScsiBus.devs[i], ConfigureParams.Scsi[i].sDeviceFile) == 0)
+		if (HDC_InitDevice(&ScsiBus.devs[i], ConfigureParams.Scsi[i].sDeviceFile, ConfigureParams.Scsi[i].nBlockSize) == 0)
 			partitions += HDC_PartitionCount(ScsiBus.devs[i].image_file, TRACE_SCSI_CMD, NULL);
 	}
 	return partitions;


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