mirror of
https://github.com/LIV2/lide.device.git
synced 2025-12-06 00:32:45 +00:00
Compare commits
8 Commits
b5db233bf3
...
828bdaa85f
| Author | SHA1 | Date | |
|---|---|---|---|
| 828bdaa85f | |||
| d439ceb016 | |||
| 161f3da34b | |||
| 827b64bff4 | |||
| ced23f8ff7 | |||
| e5bb9a06ce | |||
| 0d78bd0989 | |||
| 4207fb75a4 |
12
Makefile
12
Makefile
@ -56,6 +56,11 @@ CFLAGS+= -DSIMPLE_IDE=1
|
|||||||
.PHONY: $(PROJECT)
|
.PHONY: $(PROJECT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef AMIGAPCI
|
||||||
|
CFLAGS+= -DAMIGAPCI=1
|
||||||
|
.PHONY: $(PROJECT)
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: clean all lideflash disk lha rename/renamelide lidetool/lidetool
|
.PHONY: clean all lideflash disk lha rename/renamelide lidetool/lidetool
|
||||||
|
|
||||||
all: $(ROM) \
|
all: $(ROM) \
|
||||||
@ -63,7 +68,8 @@ all: $(ROM) \
|
|||||||
rename/renamelide \
|
rename/renamelide \
|
||||||
lide-N2630-high.rom \
|
lide-N2630-high.rom \
|
||||||
lide-N2630-low.rom \
|
lide-N2630-low.rom \
|
||||||
AIDE-$(PROJECT)
|
AIDE-$(PROJECT) \
|
||||||
|
amigapci-$(PROJECT)
|
||||||
|
|
||||||
OBJ = device.o \
|
OBJ = device.o \
|
||||||
ata.o \
|
ata.o \
|
||||||
@ -88,6 +94,9 @@ $(ROM): $(PROJECT)
|
|||||||
AIDE-$(PROJECT): $(SRCS)
|
AIDE-$(PROJECT): $(SRCS)
|
||||||
${CC} -o $@ $(CFLAGS) -DSIMPLE_IDE=1 $(SRCS) bootblock.S $(LDFLAGS)
|
${CC} -o $@ $(CFLAGS) -DSIMPLE_IDE=1 $(SRCS) bootblock.S $(LDFLAGS)
|
||||||
|
|
||||||
|
amigapci-$(PROJECT): $(SRCS)
|
||||||
|
${CC} -o $@ $(CFLAGS) -DAMIGAPCI=1 $(SRCS) bootblock.S $(LDFLAGS)
|
||||||
|
|
||||||
lideflash/lideflash:
|
lideflash/lideflash:
|
||||||
make -C lideflash
|
make -C lideflash
|
||||||
|
|
||||||
@ -148,6 +157,7 @@ lide-tk-29F040.rom: lide-tk-29F020.rom
|
|||||||
clean:
|
clean:
|
||||||
-rm -f $(PROJECT)
|
-rm -f $(PROJECT)
|
||||||
-rm -f AIDE-$(PROJECT)
|
-rm -f AIDE-$(PROJECT)
|
||||||
|
-rm -f amigapci-$(PROJECT)
|
||||||
make -C bootrom clean
|
make -C bootrom clean
|
||||||
make -C lideflash clean
|
make -C lideflash clean
|
||||||
make -C lidetool clean
|
make -C lidetool clean
|
||||||
|
|||||||
59
ata.c
59
ata.c
@ -21,9 +21,9 @@
|
|||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "lide_alib.h"
|
#include "lide_alib.h"
|
||||||
|
|
||||||
static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, unsigned long long lba, UBYTE sectorCount, UBYTE features);
|
static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features);
|
||||||
static BYTE write_taskfile_lba48(struct IDEUnit *unit, UBYTE command, unsigned long long, UBYTE sectorCount, UBYTE features);
|
static BYTE write_taskfile_lba48(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features);
|
||||||
static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, unsigned long long lba, UBYTE sectorCount, UBYTE features);
|
static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_status_reg_delay
|
* ata_status_reg_delay
|
||||||
@ -229,14 +229,14 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_bench
|
* ata_bench
|
||||||
*
|
*
|
||||||
* Measure the amount of E Clock ticks taken to transfer 512K from the unit
|
* Measure the amount of E Clock ticks taken to transfer 512K from the unit
|
||||||
*
|
*
|
||||||
* @param unit Pointer to an IDEUnit struct
|
* @param unit Pointer to an IDEUnit struct
|
||||||
* @param xfer_routine Pointer to one of the transfer routines
|
* @param xfer_routine Pointer to one of the transfer routines
|
||||||
* @param buffer pointer to a 512 byte buffer
|
* @param buffer pointer to a 512 byte buffer
|
||||||
* @return tick count
|
* @return tick count
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static ULONG ata_bench(struct IDEUnit *unit, ata_xfer_func xfer_routine, void *buffer) {
|
static ULONG ata_bench(struct IDEUnit *unit, ata_xfer_func xfer_routine, void *buffer) {
|
||||||
struct ExecBase *SysBase = unit->SysBase;
|
struct ExecBase *SysBase = unit->SysBase;
|
||||||
@ -269,9 +269,9 @@ static ULONG ata_bench(struct IDEUnit *unit, ata_xfer_func xfer_routine, void *b
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_autoselect_xfer
|
* ata_autoselect_xfer
|
||||||
*
|
*
|
||||||
* Set the transfer method for the unit based on the CPU, Board type and benchmark result
|
* Set the transfer method for the unit based on the CPU, Board type and benchmark result
|
||||||
*
|
*
|
||||||
* @param unit Pointer to an IDEUnit struct
|
* @param unit Pointer to an IDEUnit struct
|
||||||
* @return transfer method
|
* @return transfer method
|
||||||
*/
|
*/
|
||||||
@ -287,11 +287,11 @@ static enum xfer ata_autoselect_xfer(struct IDEUnit *unit) {
|
|||||||
// longword_movem will always be faster on a standard 68000
|
// longword_movem will always be faster on a standard 68000
|
||||||
if ((SysBase->AttnFlags & (AFF_68020 | AFF_68030 | AFF_68040 | AFF_68060)) == 0)
|
if ((SysBase->AttnFlags & (AFF_68020 | AFF_68030 | AFF_68040 | AFF_68060)) == 0)
|
||||||
return longword_movem;
|
return longword_movem;
|
||||||
|
|
||||||
// ReadEClock needed by ata_bench not supported before Kick 2.0
|
// ReadEClock needed by ata_bench not supported before Kick 2.0
|
||||||
if (SysBase->LibNode.lib_Version < 36)
|
if (SysBase->LibNode.lib_Version < 36)
|
||||||
return longword_movem;
|
return longword_movem;
|
||||||
|
|
||||||
if ((buf = AllocMem(512,MEMF_ANY))) {
|
if ((buf = AllocMem(512,MEMF_ANY))) {
|
||||||
enum xfer method;
|
enum xfer method;
|
||||||
ticks = ata_bench(unit,ata_read_long_movem,buf);
|
ticks = ata_bench(unit,ata_read_long_movem,buf);
|
||||||
@ -309,9 +309,9 @@ static enum xfer ata_autoselect_xfer(struct IDEUnit *unit) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_set_xfer
|
* ata_set_xfer
|
||||||
*
|
*
|
||||||
* Sets the transfer routine for the unit
|
* Sets the transfer routine for the unit
|
||||||
*
|
*
|
||||||
* @param unit Pointer to an IDEUnit strict
|
* @param unit Pointer to an IDEUnit strict
|
||||||
* @param method Transfer routine
|
* @param method Transfer routine
|
||||||
*/
|
*/
|
||||||
@ -357,7 +357,7 @@ bool ata_init_unit(struct IDEUnit *unit, void *base) {
|
|||||||
|
|
||||||
UWORD *buf;
|
UWORD *buf;
|
||||||
bool dev_found = false;
|
bool dev_found = false;
|
||||||
|
|
||||||
unit->drive.data = (UWORD*) (base + ata_reg_data);
|
unit->drive.data = (UWORD*) (base + ata_reg_data);
|
||||||
unit->drive.error_features = (UBYTE*) (base + ata_reg_error);
|
unit->drive.error_features = (UBYTE*) (base + ata_reg_error);
|
||||||
unit->drive.sectorCount = (UBYTE*) (base + ata_reg_sectorCount);
|
unit->drive.sectorCount = (UBYTE*) (base + ata_reg_sectorCount);
|
||||||
@ -416,9 +416,9 @@ bool ata_init_unit(struct IDEUnit *unit, void *base) {
|
|||||||
unit->flags.lba48 = true;
|
unit->flags.lba48 = true;
|
||||||
Info("INIT: Large drive, using LBA48 mode \n");
|
Info("INIT: Large drive, using LBA48 mode \n");
|
||||||
unit->logicalSectors = 0;
|
unit->logicalSectors = 0;
|
||||||
unit->logicalSectors |= ((unsigned long long)buf[ata_identify_lba48_sectors]) << 0;
|
unit->logicalSectors |= ((uint64_t)buf[ata_identify_lba48_sectors]) << 0;
|
||||||
unit->logicalSectors |= ((unsigned long long)buf[ata_identify_lba48_sectors+1]) << 16;
|
unit->logicalSectors |= ((uint64_t)buf[ata_identify_lba48_sectors+1]) << 16;
|
||||||
unit->logicalSectors |= ((unsigned long long)buf[ata_identify_lba48_sectors+2]) << 32;
|
unit->logicalSectors |= ((uint64_t)buf[ata_identify_lba48_sectors+2]) << 32;
|
||||||
|
|
||||||
unit->write_taskfile = &write_taskfile_lba48;
|
unit->write_taskfile = &write_taskfile_lba48;
|
||||||
|
|
||||||
@ -439,15 +439,15 @@ bool ata_init_unit(struct IDEUnit *unit, void *base) {
|
|||||||
|
|
||||||
if (unit->logicalSectors >= 267382800) {
|
if (unit->logicalSectors >= 267382800) {
|
||||||
// For drives larger than 127GB fudge the geometry
|
// For drives larger than 127GB fudge the geometry
|
||||||
unit->heads = 63;
|
unit->heads = 64;
|
||||||
unit->sectorsPerTrack = 255;
|
unit->sectorsPerTrack = 256;
|
||||||
unit->cylinders = (unit->logicalSectors / (63*255));
|
unit->cylinders = unit->logicalSectors >> 14;
|
||||||
} else if (unit->logicalSectors >= 16514064) {
|
} else if (unit->logicalSectors >= 16514064) {
|
||||||
// If a drive is larger than 8GB then the drive will report a geometry of 16383/16/63 (CHS)
|
// If a drive is larger than 8GB then the drive will report a geometry of 16383/16/63 (CHS)
|
||||||
// In this case generate a new Cylinders value
|
// In this case generate a new Cylinders value
|
||||||
unit->heads = 16;
|
unit->heads = 16;
|
||||||
unit->sectorsPerTrack = 255;
|
unit->sectorsPerTrack = 255;
|
||||||
unit->cylinders = (unit->logicalSectors / (16*255));
|
unit->cylinders = ((ULONG)unit->logicalSectors / (16*255));
|
||||||
Info("INIT: Adjusting geometry, new geometry; 16/255/%ld\n",unit->cylinders);
|
Info("INIT: Adjusting geometry, new geometry; 16/255/%ld\n",unit->cylinders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,7 +537,7 @@ bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple) {
|
|||||||
* @param unit Pointer to the unit structure
|
* @param unit Pointer to the unit structure
|
||||||
* @returns error
|
* @returns error
|
||||||
*/
|
*/
|
||||||
BYTE ata_read(void *buffer, unsigned long long lba, ULONG count, struct IDEUnit *unit) {
|
BYTE ata_read(void *buffer, uint64_t lba, ULONG count, struct IDEUnit *unit) {
|
||||||
Trace("ata_read enter\n");
|
Trace("ata_read enter\n");
|
||||||
Trace("ATA: Request sector count: %ld\n",count);
|
Trace("ATA: Request sector count: %ld\n",count);
|
||||||
|
|
||||||
@ -625,7 +625,7 @@ BYTE ata_read(void *buffer, unsigned long long lba, ULONG count, struct IDEUnit
|
|||||||
* @param unit Pointer to the unit structure
|
* @param unit Pointer to the unit structure
|
||||||
* @returns error
|
* @returns error
|
||||||
*/
|
*/
|
||||||
BYTE ata_write(void *buffer, unsigned long long lba, ULONG count, struct IDEUnit *unit) {
|
BYTE ata_write(void *buffer, uint64_t lba, ULONG count, struct IDEUnit *unit) {
|
||||||
Trace("ata_write enter\n");
|
Trace("ata_write enter\n");
|
||||||
Trace("ATA: Request sector count: %ld\n",count);
|
Trace("ATA: Request sector count: %ld\n",count);
|
||||||
|
|
||||||
@ -746,10 +746,11 @@ void ata_write_unaligned_long(void *source asm("a0"), void *destination asm("a1"
|
|||||||
* @param unit Pointer to an IDEUnit struct
|
* @param unit Pointer to an IDEUnit struct
|
||||||
* @param lba Pointer to the LBA variable
|
* @param lba Pointer to the LBA variable
|
||||||
*/
|
*/
|
||||||
static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, unsigned long long lba, UBYTE sectorCount, UBYTE features) {
|
static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features) {
|
||||||
UWORD cylinder = (lba / (unit->heads * unit->sectorsPerTrack));
|
|
||||||
UBYTE head = ((lba / unit->sectorsPerTrack) % unit->heads) & 0xF;
|
UWORD cylinder = ((ULONG)lba / (unit->heads * unit->sectorsPerTrack));
|
||||||
UBYTE sector = (lba % unit->sectorsPerTrack) + 1;
|
UBYTE head = (((ULONG)lba / unit->sectorsPerTrack) % unit->heads) & 0xF;
|
||||||
|
UBYTE sector = ((ULONG)lba % unit->sectorsPerTrack) + 1;
|
||||||
|
|
||||||
BYTE devHead;
|
BYTE devHead;
|
||||||
|
|
||||||
@ -776,7 +777,7 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, unsigned lon
|
|||||||
* @param unit Pointer to an IDEUnit struct
|
* @param unit Pointer to an IDEUnit struct
|
||||||
* @param lba Pointer to the LBA variable
|
* @param lba Pointer to the LBA variable
|
||||||
*/
|
*/
|
||||||
static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, unsigned long long lba, UBYTE sectorCount, UBYTE features) {
|
static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features) {
|
||||||
BYTE devHead;
|
BYTE devHead;
|
||||||
|
|
||||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||||
@ -802,7 +803,7 @@ static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, unsigned lon
|
|||||||
* @param unit Pointer to an IDEUnit struct
|
* @param unit Pointer to an IDEUnit struct
|
||||||
* @param lba Pointer to the LBA variable
|
* @param lba Pointer to the LBA variable
|
||||||
*/
|
*/
|
||||||
static BYTE write_taskfile_lba48(struct IDEUnit *unit, UBYTE command, unsigned long long lba, UBYTE sectorCount, UBYTE features) {
|
static BYTE write_taskfile_lba48(struct IDEUnit *unit, UBYTE command, uint64_t lba, UBYTE sectorCount, UBYTE features) {
|
||||||
|
|
||||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||||
return HFERR_SelTimeout;
|
return HFERR_SelTimeout;
|
||||||
|
|||||||
6
ata.h
6
ata.h
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
#ifdef SIMPLE_IDE
|
#ifdef SIMPLE_IDE
|
||||||
|
|
||||||
#define NO_AUTOCONFIG
|
|
||||||
|
|
||||||
#define BOARD_BASE 0xEF0000
|
#define BOARD_BASE 0xEF0000
|
||||||
#define CHANNEL_0 0x2000
|
#define CHANNEL_0 0x2000
|
||||||
#define CHANNEL_1 0x1000
|
#define CHANNEL_1 0x1000
|
||||||
@ -110,8 +108,8 @@ bool ata_identify(struct IDEUnit *, UWORD *);
|
|||||||
bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple);
|
bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple);
|
||||||
void ata_set_xfer(struct IDEUnit *unit, enum xfer method);
|
void ata_set_xfer(struct IDEUnit *unit, enum xfer method);
|
||||||
|
|
||||||
BYTE ata_read(void *buffer, unsigned long long lba, ULONG count, struct IDEUnit *unit);
|
BYTE ata_read(void *buffer, uint64_t lba, ULONG count, struct IDEUnit *unit);
|
||||||
BYTE ata_write(void *buffer, unsigned long long lba, ULONG count, struct IDEUnit *unit);
|
BYTE ata_write(void *buffer, uint64_t lba, ULONG count, struct IDEUnit *unit);
|
||||||
BYTE ata_set_pio(struct IDEUnit *unit, UBYTE pio);
|
BYTE ata_set_pio(struct IDEUnit *unit, UBYTE pio);
|
||||||
BYTE scsi_ata_passthrough( struct IDEUnit *unit, struct SCSICmd *cmd);
|
BYTE scsi_ata_passthrough( struct IDEUnit *unit, struct SCSICmd *cmd);
|
||||||
|
|
||||||
|
|||||||
16
atapi.c
16
atapi.c
@ -79,7 +79,7 @@ static bool atapi_wait_drq_not_bsy(struct IDEUnit *unit, ULONG tries) {
|
|||||||
*
|
*
|
||||||
* Polls the BSY bit in the status register until cleared, an error occurs, or the timeout is reached.
|
* Polls the BSY bit in the status register until cleared, an error occurs, or the timeout is reached.
|
||||||
*
|
*
|
||||||
* For long-running commands (e.g., FORMAT UNIT, BLANK, up to 30 minutes), uses timer-based waits (1 ms per poll) to yield to other tasks, ensuring AmigaOS multitasking friendliness.
|
* For long-running commands (e.g., FORMAT UNIT, BLANK, up to 30 minutes), uses timer-based waits (1 ms per poll) to yield to other tasks, ensuring AmigaOS multitasking friendliness.
|
||||||
* For faster commands (e.g., READ (10), WRITE (10)), uses a ~1.4 µs delay via CIA register reads for CPU-independent timing and high throughput.
|
* For faster commands (e.g., READ (10), WRITE (10)), uses a ~1.4 µs delay via CIA register reads for CPU-independent timing and high throughput.
|
||||||
*
|
*
|
||||||
* Timeout durations:
|
* Timeout durations:
|
||||||
@ -733,7 +733,7 @@ BYTE atapi_get_capacity(struct IDEUnit *unit) {
|
|||||||
if ((ret = atapi_packet(cmd,unit)) == 0) {
|
if ((ret = atapi_packet(cmd,unit)) == 0) {
|
||||||
unit->logicalSectors = capacity.logicalSectors + 1;
|
unit->logicalSectors = capacity.logicalSectors + 1;
|
||||||
unit->blockSize = capacity.blockSize;
|
unit->blockSize = capacity.blockSize;
|
||||||
|
|
||||||
while ((unit->blockSize >> unit->blockShift) > 1) {
|
while ((unit->blockSize >> unit->blockShift) > 1) {
|
||||||
unit->blockShift++;
|
unit->blockShift++;
|
||||||
}
|
}
|
||||||
@ -848,7 +848,7 @@ BYTE atapi_scsi_mode_sense_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
|||||||
dest[1] = buf[2]; // Medium type
|
dest[1] = buf[2]; // Medium type
|
||||||
dest[2] = buf[3]; // WP/DPOFUA Flags
|
dest[2] = buf[3]; // WP/DPOFUA Flags
|
||||||
dest[3] = buf[7]; // Block descriptor length
|
dest[3] = buf[7]; // Block descriptor length
|
||||||
|
|
||||||
// Copy the mode sense data
|
// Copy the mode sense data
|
||||||
for (int i = 0; i < (cmd_sense->scsi_Actual - 8); i++) {
|
for (int i = 0; i < (cmd_sense->scsi_Actual - 8); i++) {
|
||||||
dest[i+4] = buf[i+8];
|
dest[i+4] = buf[i+8];
|
||||||
@ -923,7 +923,7 @@ BYTE atapi_scsi_mode_select_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
|||||||
dst[2] = src[1]; // Mediun Type
|
dst[2] = src[1]; // Mediun Type
|
||||||
dst[3] = src[2]; // Device specific parameter
|
dst[3] = src[2]; // Device specific parameter
|
||||||
dst[7] = src[3]; // Block descriptor length
|
dst[7] = src[3]; // Block descriptor length
|
||||||
|
|
||||||
// Copy the Mode Parameters
|
// Copy the Mode Parameters
|
||||||
len = bufSize - 8;
|
len = bufSize - 8;
|
||||||
CopyMem(src + 4, dst + 8, len);
|
CopyMem(src + 4, dst + 8, len);
|
||||||
@ -1039,11 +1039,11 @@ BYTE atapi_start_stop_unit(struct IDEUnit *unit, bool start, bool loej, bool imm
|
|||||||
|
|
||||||
if (loej) operation |= (1<<1);
|
if (loej) operation |= (1<<1);
|
||||||
if (start) operation |= (1<<0);
|
if (start) operation |= (1<<0);
|
||||||
|
|
||||||
BYTE cdb[10] = {0};
|
BYTE cdb[10] = {0};
|
||||||
struct SCSI_FIXED_SENSE sense;
|
struct SCSI_FIXED_SENSE sense;
|
||||||
memset(&sense,0,sizeof(struct SCSI_FIXED_SENSE));
|
memset(&sense,0,sizeof(struct SCSI_FIXED_SENSE));
|
||||||
|
|
||||||
struct SCSICmd cmd = {
|
struct SCSICmd cmd = {
|
||||||
.scsi_Command = (APTR)&cdb,
|
.scsi_Command = (APTR)&cdb,
|
||||||
.scsi_CmdActual = 0,
|
.scsi_CmdActual = 0,
|
||||||
@ -1340,7 +1340,7 @@ BYTE atapi_autosense(struct SCSICmd *scsi_command, struct IDEUnit *unit) {
|
|||||||
|
|
||||||
if (scsi_command->scsi_SenseData == NULL || scsi_command->scsi_SenseLength == 0)
|
if (scsi_command->scsi_SenseData == NULL || scsi_command->scsi_SenseLength == 0)
|
||||||
return IOERR_BADADDRESS;
|
return IOERR_BADADDRESS;
|
||||||
|
|
||||||
struct SCSICmd *cmd = MakeSCSICmd(SZ_CDB_12);
|
struct SCSICmd *cmd = MakeSCSICmd(SZ_CDB_12);
|
||||||
|
|
||||||
if (cmd != NULL) {
|
if (cmd != NULL) {
|
||||||
@ -1351,7 +1351,7 @@ BYTE atapi_autosense(struct SCSICmd *scsi_command, struct IDEUnit *unit) {
|
|||||||
cmd->scsi_Length = scsi_command->scsi_SenseLength;
|
cmd->scsi_Length = scsi_command->scsi_SenseLength;
|
||||||
cmd->scsi_Flags = SCSIF_READ;
|
cmd->scsi_Flags = SCSIF_READ;
|
||||||
cmd->scsi_CmdLength = 12;
|
cmd->scsi_CmdLength = 12;
|
||||||
|
|
||||||
ret = atapi_packet(cmd,unit);
|
ret = atapi_packet(cmd,unit);
|
||||||
scsi_command->scsi_SenseActual = cmd->scsi_Actual;
|
scsi_command->scsi_SenseActual = cmd->scsi_Actual;
|
||||||
|
|
||||||
|
|||||||
@ -294,6 +294,7 @@ RomFetch
|
|||||||
|
|
||||||
.RomFetchZ ; access type is Zorro
|
.RomFetchZ ; access type is Zorro
|
||||||
move.l d0,d3
|
move.l d0,d3
|
||||||
|
moveq #0,d0
|
||||||
.nextnip
|
.nextnip
|
||||||
lsl.l #8,d0
|
lsl.l #8,d0
|
||||||
IFND BYTEWIDE
|
IFND BYTEWIDE
|
||||||
|
|||||||
25
device.c
25
device.c
@ -27,7 +27,7 @@
|
|||||||
#include "lide_alib.h"
|
#include "lide_alib.h"
|
||||||
#include "mounter/mounter.h"
|
#include "mounter/mounter.h"
|
||||||
|
|
||||||
#ifdef NO_AUTOCONFIG
|
#ifdef FAKE_CONFIGDEV
|
||||||
extern UBYTE bootblock, bootblock_end;
|
extern UBYTE bootblock, bootblock_end;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ char * set_dev_name(struct DeviceBase *dev) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NO_AUTOCONFIG
|
#ifdef FAKE_CONFIGDEV
|
||||||
/**
|
/**
|
||||||
* CreateFakeConfigDev
|
* CreateFakeConfigDev
|
||||||
* Create fake ConfigDev and DiagArea to support autoboot without requiring real autoconfig device.
|
* Create fake ConfigDev and DiagArea to support autoboot without requiring real autoconfig device.
|
||||||
@ -201,9 +201,9 @@ static BOOL FindCDFS() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ioreq_is_valid
|
* ioreq_is_valid
|
||||||
*
|
*
|
||||||
* Check if the supplied IOReq points to a valid unit
|
* Check if the supplied IOReq points to a valid unit
|
||||||
*
|
*
|
||||||
* @param dev Pointer to DeviceBase
|
* @param dev Pointer to DeviceBase
|
||||||
* @param ior The ioreq to test
|
* @param ior The ioreq to test
|
||||||
* @returns bool
|
* @returns bool
|
||||||
@ -269,6 +269,7 @@ static void Cleanup(struct DeviceBase *dev) {
|
|||||||
FreeMem((char *)dev - dev->lib.lib_NegSize, dev->lib.lib_NegSize + dev->lib.lib_PosSize);
|
FreeMem((char *)dev - dev->lib.lib_NegSize, dev->lib.lib_NegSize + dev->lib.lib_PosSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ATA_CHANNELS
|
||||||
/**
|
/**
|
||||||
* detectChannels
|
* detectChannels
|
||||||
*
|
*
|
||||||
@ -329,6 +330,7 @@ static BYTE detectChannels(struct ConfigDev *cd) {
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_device
|
* init_device
|
||||||
@ -411,12 +413,25 @@ struct Library * init_device(struct ExecBase *SysBase asm("a6"), BPTR seg_list a
|
|||||||
Cleanup(dev);
|
Cleanup(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef BOARD_MANUF_ID
|
||||||
|
struct ConfigDev *realcd;
|
||||||
|
|
||||||
|
if (!(realcd = FindConfigDev(NULL,BOARD_MANUF_ID,BOARD_PROD_ID))) {
|
||||||
|
Info("AmigaPCI IDE not found\n");
|
||||||
|
Cleanup(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
APTR BOARD_BASE = realcd->cd_BoardAddr;
|
||||||
|
#endif
|
||||||
cd->cd_BoardAddr = (APTR)BOARD_BASE;
|
cd->cd_BoardAddr = (APTR)BOARD_BASE;
|
||||||
cd->cd_BoardSize = 0x1000;
|
cd->cd_BoardSize = 0x1000;
|
||||||
numBoards = 1;
|
numBoards = 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ATA_CHANNELS
|
||||||
UBYTE channels = detectChannels(cd);
|
UBYTE channels = detectChannels(cd);
|
||||||
|
#else
|
||||||
|
UBYTE channels = ATA_CHANNELS;
|
||||||
|
#endif
|
||||||
for (int c=0; c < channels; c++) {
|
for (int c=0; c < channels; c++) {
|
||||||
|
|
||||||
Info("Starting IO Task %ld\n",dev->numTasks);
|
Info("Starting IO Task %ld\n",dev->numTasks);
|
||||||
|
|||||||
18
device.h
18
device.h
@ -15,6 +15,20 @@
|
|||||||
|
|
||||||
#define MAX_UNITS 4
|
#define MAX_UNITS 4
|
||||||
|
|
||||||
|
#if AMIGAPCI
|
||||||
|
// #define NO_AUTOCONFIG 1
|
||||||
|
#define BOARD_MANUF_ID 600
|
||||||
|
#define BOARD_PROD_ID 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIMPLE_IDE
|
||||||
|
#define NO_AUTOCONFIG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_AUTOCONFIG
|
||||||
|
#define FAKE_CONFIGDEV 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// VSCode C/C++ extension doesn't like the asm("<reg>") syntax
|
// VSCode C/C++ extension doesn't like the asm("<reg>") syntax
|
||||||
#ifdef __INTELLISENSE__
|
#ifdef __INTELLISENSE__
|
||||||
#define asm(x)
|
#define asm(x)
|
||||||
@ -47,7 +61,7 @@ struct IDEUnit {
|
|||||||
struct ExecBase *SysBase;
|
struct ExecBase *SysBase;
|
||||||
struct IOTask *itask;
|
struct IOTask *itask;
|
||||||
struct Drive drive;
|
struct Drive drive;
|
||||||
BYTE (*write_taskfile)(struct IDEUnit *, UBYTE, unsigned long long, UBYTE, UBYTE);
|
BYTE (*write_taskfile)(struct IDEUnit *, UBYTE, uint64_t, UBYTE, UBYTE);
|
||||||
enum xfer xferMethod;
|
enum xfer xferMethod;
|
||||||
ata_xfer_func read_fast;
|
ata_xfer_func read_fast;
|
||||||
ata_xfer_func write_fast;
|
ata_xfer_func write_fast;
|
||||||
@ -65,7 +79,7 @@ struct IDEUnit {
|
|||||||
UWORD blockSize;
|
UWORD blockSize;
|
||||||
UWORD blockShift;
|
UWORD blockShift;
|
||||||
ULONG cylinders;
|
ULONG cylinders;
|
||||||
unsigned long long logicalSectors;
|
uint64_t logicalSectors;
|
||||||
struct MinList changeInts;
|
struct MinList changeInts;
|
||||||
UBYTE multipleCount;
|
UBYTE multipleCount;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
23
iotask.c
23
iotask.c
@ -111,7 +111,7 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
|||||||
UBYTE *data = (APTR)scsi_command->scsi_Data;
|
UBYTE *data = (APTR)scsi_command->scsi_Data;
|
||||||
UBYTE *command = (APTR)scsi_command->scsi_Command;
|
UBYTE *command = (APTR)scsi_command->scsi_Command;
|
||||||
|
|
||||||
unsigned long long lba;
|
uint64_t lba;
|
||||||
ULONG count;
|
ULONG count;
|
||||||
BYTE error = 0;
|
BYTE error = 0;
|
||||||
scsi_command->scsi_SenseActual = 0;
|
scsi_command->scsi_SenseActual = 0;
|
||||||
@ -169,10 +169,10 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
|||||||
case SCSI_CMD_READ_16:
|
case SCSI_CMD_READ_16:
|
||||||
case SCSI_CMD_WRITE_16:
|
case SCSI_CMD_WRITE_16:
|
||||||
lba = ((struct SCSI_CDB_16 *)command)->lba;
|
lba = ((struct SCSI_CDB_16 *)command)->lba;
|
||||||
count = ((struct SCSI_CDB_16 *)command)->length;
|
count = ((struct SCSI_CDB_16 *)command)->length;
|
||||||
|
|
||||||
do_scsi_transfer:
|
do_scsi_transfer:
|
||||||
if (data == NULL || (lba + count) >= unit->logicalSectors) {
|
if (data == NULL || (lba + count) > unit->logicalSectors) {
|
||||||
error = IOERR_BADADDRESS;
|
error = IOERR_BADADDRESS;
|
||||||
fake_scsi_sense(scsi_command,lba,count,error);
|
fake_scsi_sense(scsi_command,lba,count,error);
|
||||||
break;
|
break;
|
||||||
@ -383,7 +383,8 @@ static void process_ioreq(struct IOTask *itask, struct IOStdReq *ioreq) {
|
|||||||
struct IOExtTD *iotd;
|
struct IOExtTD *iotd;
|
||||||
struct IDEUnit *unit;
|
struct IDEUnit *unit;
|
||||||
UWORD blockShift;
|
UWORD blockShift;
|
||||||
unsigned long long lba;
|
uint64_t lba;
|
||||||
|
ULONG lba_high, lba_low;
|
||||||
ULONG count;
|
ULONG count;
|
||||||
BYTE error = 0;
|
BYTE error = 0;
|
||||||
enum xfer_dir direction = WRITE;
|
enum xfer_dir direction = WRITE;
|
||||||
@ -483,7 +484,15 @@ transfer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockShift = ((struct IDEUnit *)ioreq->io_Unit)->blockShift;
|
blockShift = ((struct IDEUnit *)ioreq->io_Unit)->blockShift;
|
||||||
lba = (((unsigned long long)ioreq->io_Actual << 32 | ioreq->io_Offset) >> blockShift);
|
|
||||||
|
// This looks like a lond-winded way to get the LBA doesn't it?
|
||||||
|
// Splitting up the operation like this results in smaller code size (avoids 64-bit math from libgcc)
|
||||||
|
lba_high = ioreq->io_Actual >> blockShift;
|
||||||
|
lba_low = ioreq->io_Actual << (32 - blockShift);
|
||||||
|
lba_low |= (ioreq->io_Offset >> blockShift);
|
||||||
|
|
||||||
|
lba = ((uint64_t)lba_high << 32 | lba_low);
|
||||||
|
|
||||||
count = (ioreq->io_Length >> blockShift);
|
count = (ioreq->io_Length >> blockShift);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
@ -492,7 +501,7 @@ transfer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((lba + count) > (unit->logicalSectors)) {
|
if ((lba + count) > (unit->logicalSectors)) {
|
||||||
Trace("Read past end of device\n");
|
Trace("Access past end of device\n");
|
||||||
error = IOERR_BADADDRESS;
|
error = IOERR_BADADDRESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -604,7 +613,7 @@ void __attribute__((noreturn)) io_task () {
|
|||||||
RemTask(NULL);
|
RemTask(NULL);
|
||||||
Wait(0);
|
Wait(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
signalMask |= (1 << itask->dcTimerMp->mp_SigBit);
|
signalMask |= (1 << itask->dcTimerMp->mp_SigBit);
|
||||||
|
|
||||||
run_timer(SysBase,itask->dcTimerReq,CHANGEINT_INTERVAL,0);
|
run_timer(SysBase,itask->dcTimerReq,CHANGEINT_INTERVAL,0);
|
||||||
|
|||||||
@ -169,7 +169,7 @@ static void DumpUnit(struct IOStdReq *req) {
|
|||||||
printf("Supports LBA: %s\n", (unit->flags.lba) ? "Yes" : "No");
|
printf("Supports LBA: %s\n", (unit->flags.lba) ? "Yes" : "No");
|
||||||
printf("Supports LBA48: %s\n", (unit->flags.lba48) ? "Yes" : "No");
|
printf("Supports LBA48: %s\n", (unit->flags.lba48) ? "Yes" : "No");
|
||||||
printf("C/H/S: %d/%d/%d\n", unit->cylinders, unit->heads, unit->sectorsPerTrack);
|
printf("C/H/S: %d/%d/%d\n", unit->cylinders, unit->heads, unit->sectorsPerTrack);
|
||||||
printf("Logical Sectors: %llu\n", (unsigned long long)unit->logicalSectors);
|
printf("Logical Sectors: %llu\n", (uint64_t)unit->logicalSectors);
|
||||||
printf("READ/WRITE Multiple: %s\n", (unit->flags.xferMultiple) ? "Yes" : "No");
|
printf("READ/WRITE Multiple: %s\n", (unit->flags.xferMultiple) ? "Yes" : "No");
|
||||||
printf("Multiple count: %d\n", unit->multipleCount);
|
printf("Multiple count: %d\n", unit->multipleCount);
|
||||||
printf("Last Error: ");
|
printf("Last Error: ");
|
||||||
|
|||||||
13
scsi.c
13
scsi.c
@ -225,19 +225,8 @@ BYTE scsi_read_capacity_16_emu(struct IDEUnit *unit, struct SCSICmd *scsi_comman
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SCSI_READ_CAPACITY_16 *cdb = (struct SCSI_READ_CAPACITY_16 *)scsi_command->scsi_Command;
|
|
||||||
|
|
||||||
data->block_size = unit->blockSize;
|
data->block_size = unit->blockSize;
|
||||||
|
data->lba = unit->logicalSectors - 1;
|
||||||
|
|
||||||
if (cdb->flags & 0x01) {
|
|
||||||
// Partial Medium Indicator - Return end of cylinder
|
|
||||||
// Implement this so HDToolbox stops moaning about track size
|
|
||||||
ULONG spc = unit->sectorsPerTrack * unit->heads;
|
|
||||||
data->lba = (((cdb->lba / spc) + 1) * spc) - 1;
|
|
||||||
} else {
|
|
||||||
data->lba = (unit->logicalSectors) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scsi_command->scsi_Actual = 8;
|
scsi_command->scsi_Actual = 8;
|
||||||
|
|
||||||
|
|||||||
30
scsi.h
30
scsi.h
@ -72,12 +72,12 @@ struct __attribute__((packed)) SCSI_CDB_10 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) SCSI_CDB_16 {
|
struct __attribute__((packed)) SCSI_CDB_16 {
|
||||||
UBYTE operation;
|
UBYTE operation;
|
||||||
UBYTE flags;
|
UBYTE flags;
|
||||||
unsigned long long lba;
|
uint64_t lba;
|
||||||
ULONG length;
|
ULONG length;
|
||||||
UBYTE group;
|
UBYTE group;
|
||||||
UBYTE control;
|
UBYTE control;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) SCSI_READ_CAPACITY_10 {
|
struct __attribute__((packed)) SCSI_READ_CAPACITY_10 {
|
||||||
@ -89,12 +89,12 @@ struct __attribute__((packed)) SCSI_READ_CAPACITY_10 {
|
|||||||
UBYTE control;
|
UBYTE control;
|
||||||
};
|
};
|
||||||
struct __attribute__((packed)) SCSI_READ_CAPACITY_16 {
|
struct __attribute__((packed)) SCSI_READ_CAPACITY_16 {
|
||||||
UBYTE operation;
|
UBYTE operation;
|
||||||
UBYTE serviceAction;
|
UBYTE serviceAction;
|
||||||
unsigned long long lba;
|
uint64_t lba;
|
||||||
ULONG allocation;
|
ULONG allocation;
|
||||||
UBYTE flags;
|
UBYTE flags;
|
||||||
UBYTE control;
|
UBYTE control;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) SCSI_CAPACITY_10 {
|
struct __attribute__((packed)) SCSI_CAPACITY_10 {
|
||||||
@ -103,9 +103,9 @@ struct __attribute__((packed)) SCSI_CAPACITY_10 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) SCSI_CAPACITY_16 {
|
struct __attribute__((packed)) SCSI_CAPACITY_16 {
|
||||||
unsigned long long lba;
|
uint64_t lba;
|
||||||
ULONG block_size;
|
ULONG block_size;
|
||||||
char reserved[3];
|
char reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) SCSI_FIXED_SENSE {
|
struct __attribute__((packed)) SCSI_FIXED_SENSE {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user