package/boot/uboot-oxnas/src/drivers/block/plxsata_ide.c
/**
 * Ref bug-6320
 *
 * This code is a work around for a DMA hardware bug that will repeat the
 * penultimate 8-bytes on some reads. This code will check that the amount
 * of data transferred is a multiple of 512 bytes, if not the in it will
 * fetch the correct data from a buffer in the SATA core and copy it into
 * memory.
 *
 */
Ref bug-6320
This code is a work around for a DMA hardware bug that will repeat the
penultimate 8-bytes on some reads. This code will check that the amount
of data transferred is a multiple of 512 bytes, if not the in it will
fetch the correct data from a buffer in the SATA core and copy it into
memory.
Ref bug - 6320 This code is a work around for a DMA hardware bug that will repeat the penultimate 8 - bytes on some reads . This code will check that the amount of data transferred is a multiple of 512 bytes if not the in it will fetch the correct data from a buffer in the SATA core and copy it into memory .
static void sata_bug_6320_workaround(int port, ulong *candidate)
{
	int is_read;
	int quads_transferred;
	int remainder;
	int sector_quads_remaining;
	is_read = !(*((unsigned long*) SATA_DM_DBG1)
		& (port ? SATA_CORE_PORT1_DATA_DIR : SATA_CORE_PORT0_DATA_DIR));
	quads_transferred = *((unsigned long*) (
		port ? SATA_DATACOUNT_PORT1 : SATA_DATACOUNT_PORT0));
	remainder = quads_transferred & 0x7f;
	sector_quads_remaining = remainder ? (0x80 - remainder) : 0;
	if (is_read && (sector_quads_remaining == 2)) {
		debug("SATA read fixup, only transfered %d quads, "
			"sector_quads_remaining %d, port %d\n",
			quads_transferred, sector_quads_remaining, port);
		int total_len = ATA_SECT_SIZE;
		ulong *sata_data_ptr = (void*) (
			port ? SATA_DATA_MUX_RAM1 : SATA_DATA_MUX_RAM0)
			+ ((total_len - 8) % 2048);
		*candidate = *sata_data_ptr;
		*(candidate + 1) = *(sata_data_ptr + 1);
	}
}
static void sata_bug_6320_workaround ( int port , ulong * candidate ) { int is_read ; int quads_transferred ; int remainder ; int sector_quads_remaining ; is_read = ! ( * ( ( unsigned long * ) SATA_DM_DBG1 ) & ( port ? SATA_CORE_PORT1_DATA_DIR : SATA_CORE_PORT0_DATA_DIR ) ) ; quads_transferred = * ( ( unsigned long * ) ( port ? SATA_DATACOUNT_PORT1 : SATA_DATACOUNT_PORT0 ) ) ; remainder = quads_transferred & 0x7f ; sector_quads_remaining = remainder ? ( 0x80 - remainder ) : 0 ; if ( is_read && ( sector_quads_remaining == 2 ) ) { debug ( " " " \n " , quads_transferred , sector_quads_remaining , port ) ; int total_len = ATA_SECT_SIZE ; ulong * sata_data_ptr = ( void * ) ( port ? SATA_DATA_MUX_RAM1 : SATA_DATA_MUX_RAM0 ) + ( ( total_len - 8 ) % 2048 ) ; * candidate = * sata_data_ptr ; * ( candidate + 1 ) = * ( sata_data_ptr + 1 ) ; } }
Ref bug-6320
 This code is a work around for a DMA hardware bug that will repeat the
 penultimate 8-bytes on some reads.
Ref bug - 6320 This code is a work around for a DMA hardware bug that will repeat the penultimate 8 - bytes on some reads .
/* Only want to apply fix to reads */ /* Check for an incomplete transfer, i.e. not a multiple of 512 bytes
	 transferred (datacount_port register counts quads transferred) */