Commit 86c19b05 authored by Ben Avison's avatar Ben Avison
Browse files

LBA28 support

Detail:
  LBA28 is still useful for some small capacity Micro SATA SSDs in particular.
  Also a bugfix to reading the drive capacity (the only effect would have
  been that we didn't correctly fault DiscOps beyond the end of the media).
Admin:
  Tested on IGEPv5

Version 4.01. Tagged as 'ADFS-4_01'
parent 120aa298
/* (4.00)
/* (4.01)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 4.00
#define Module_MajorVersion_CMHG 4.01
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 12 Oct 2015
#define Module_Date_CMHG 13 Mar 2016
#define Module_MajorVersion "4.00"
#define Module_Version 400
#define Module_MajorVersion "4.01"
#define Module_Version 401
#define Module_MinorVersion ""
#define Module_Date "12 Oct 2015"
#define Module_Date "13 Mar 2016"
#define Module_ApplicationDate "12-Oct-15"
#define Module_ApplicationDate "13-Mar-16"
#define Module_ComponentName "ADFS"
#define Module_ComponentPath "cddl/RiscOS/Sources/FileSys/ADFS/ADFS"
#define Module_FullVersion "4.00"
#define Module_HelpVersion "4.00 (12 Oct 2015)"
#define Module_LibraryVersionInfo "4:0"
#define Module_FullVersion "4.01"
#define Module_HelpVersion "4.01 (13 Mar 2016)"
#define Module_LibraryVersionInfo "4:1"
......@@ -123,8 +123,14 @@ static low_level_error_t transfer_with_retries(uint32_t reason,
.lba4 = (uint8_t) (*disc_address >> (LOG2_SECTOR_SIZE + 32)),
.lba5 = (uint8_t) (*disc_address >> (LOG2_SECTOR_SIZE + 36)),
.device = DEVICE_MAGIC | DEVICE_LBA,
.command = command[reason][1][1]
.command = command[reason][dr->lba48][1]
};
if (!dr->lba48)
{
p.sector_count1 = 0;
p.lba3 = 0;
p.device |= (uint8_t) (*disc_address >> (LOG2_SECTOR_SIZE + 24)) & 0xF;
}
flags |= ATAOp_DMA |
(dr->deviceid << ATAOp_DeviceIDShift) |
(dr->cpid << ATAOp_CPIDShift) |
......@@ -332,7 +338,7 @@ low_level_error_t discop(uint32_t reason,
{ /* remove warnings about jump past initialisation of variables */
uint64_t end_down = ROUND_DOWN_64(*disc_address + *fg_length, LOG2_SECTOR_SIZE);
uint64_t end_up = ROUND_UP_64(*disc_address + *fg_length, LOG2_SECTOR_SIZE);
uint32_t chunk_size = 65536 << LOG2_SECTOR_SIZE; // TODO 256 sectors for non-LBA48
uint32_t chunk_size = dr->lba48 ? 65536 << LOG2_SECTOR_SIZE : 256 << LOG2_SECTOR_SIZE;
dprintf("%016llX/%016llX/%016llX, chunk=%08X\n", *disc_address, end_down, end_up, chunk_size);
block_or_scatter_t ptr_for_verify_ops;
if (reason == DiscOp_Verify)
......
......@@ -58,7 +58,7 @@ void drive_attached(uint32_t cpid, uint32_t deviceid, bool packet_device)
(cpid << ADFSIDEUserOp_CPIDShift) |
ADFSIDEUserOp_TransRead,
(uint8_t *) &params,
dr->identify_info,
(uint8_t *) dr->identify_info,
sizeof dr->identify_info,
0, &status, &remain);
if (e != NULL || status != 0)
......@@ -114,8 +114,15 @@ void drive_attached(uint32_t cpid, uint32_t deviceid, bool packet_device)
}
}
}
/* Assume 48-bit LBA support for now. Fortunately, value is little-endian */
dr->capacity = SECTOR_SIZE * *(uint64_t *)&dr->identify_info[OFFSET_MAX_LBA48];
/* Interpret identify blocks. Fortunately, sector count values are little-endian */
dr->lba48 = (dr->identify_info[OFFSET_COMMAND_SET] &
(COMMAND_SET_MBZ | COMMAND_SET_MBO | COMMAND_SET_LBA48)) ==
(COMMAND_SET_MBO | COMMAND_SET_LBA48);
if (dr->lba48)
dr->capacity = SECTOR_SIZE * *(uint64_t *)&dr->identify_info[OFFSET_MAX_LBA48];
else
dr->capacity = SECTOR_SIZE * (uint64_t) *(uint32_t *)&dr->identify_info[OFFSET_MAX_LBA];
dprintf("assigned to drive %u\n", dr->drive);
}
else
......
......@@ -142,8 +142,14 @@ enum
};
/* Locations in identify block */
#define OFFSET_MAX_LBA (60)
#define OFFSET_COMMAND_SET (83)
#define OFFSET_MAX_LBA48 (100)
#define COMMAND_SET_MBZ (1u<<15)
#define COMMAND_SET_MBO (1u<<14)
#define COMMAND_SET_LBA48 (1u<<10)
/* Types */
/** Parameter blocks for device control commands */
......@@ -275,13 +281,14 @@ typedef struct drive
struct drive *next; /**< Linked list link */
uint32_t drive; /**< ADFS drive number, or -1 if none (eg if an ATAPI device, or if > NUM_WINNIES found) */
bool packet_device; /**< Device type (maybe extend to an enum to include floppies in future) */
bool lba48; /**< Device supports 48-bit LBA */
uint8_t cpid; /**< ATADriver controller/port ID */
uint8_t deviceid; /**< ATADriver device ID */
uint8_t standby_timer; /**< Automatic standby timer period - meaning defined by ATA IDLE command (0 = off, 1-240 = timeout / 5 seconds, etc) */
new_disc_error_t disc_error; /**< Most recent disc error */
uint8_t *block_buffer; /**< Sector-size buffer to handle misaligned reads/writes, allocated from RMA */
uint64_t capacity; /**< Disc size, in sectors */
uint8_t identify_info[512]; /**< Result of ATA IDENTIFY DEVICE or IDENTIFY PACKET DEVICE */
uint16_t identify_info[256]; /**< Result of ATA IDENTIFY DEVICE or IDENTIFY PACKET DEVICE */
} drive_t;
/** Retries state */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment