mirror of
https://github.com/LIV2/lide.device.git
synced 2025-12-06 00:32:45 +00:00
Whitespace fixes
This commit is contained in:
parent
8e253bcc42
commit
f434a797df
124
ata.c
124
ata.c
@ -27,11 +27,11 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
|
||||
/**
|
||||
* ata_status_reg_delay
|
||||
*
|
||||
*
|
||||
* We need a short delay before actually checking the status register to let the drive update the status
|
||||
* To get the right delay we read the status register 4 times but just throw away the result
|
||||
* More info: https://wiki.osdev.org/ATA_PIO_Mode#400ns_delays
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
static void __attribute__((always_inline)) ata_status_reg_delay(struct IDEUnit *unit) {
|
||||
@ -47,9 +47,9 @@ static void __attribute__((always_inline)) ata_status_reg_delay(struct IDEUnit *
|
||||
|
||||
/**
|
||||
* ata_save_error
|
||||
*
|
||||
*
|
||||
* Save the contents of the drive registers so that errors can be reported in sense data
|
||||
*
|
||||
*
|
||||
*/
|
||||
static void ata_save_error(struct IDEUnit *unit) {
|
||||
unit->last_error[0] = *unit->drive->error_features;
|
||||
@ -62,10 +62,10 @@ static void ata_save_error(struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* ata_check_error
|
||||
*
|
||||
*
|
||||
* Check for ATA error / fault
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns True if error is indicated
|
||||
*/
|
||||
static bool __attribute__((always_inline)) ata_check_error(struct IDEUnit *unit) {
|
||||
@ -74,7 +74,7 @@ static bool __attribute__((always_inline)) ata_check_error(struct IDEUnit *unit)
|
||||
|
||||
/**
|
||||
* ata_wait_drq
|
||||
*
|
||||
*
|
||||
* Poll DRQ in the status register until set or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -102,7 +102,7 @@ static bool ata_wait_drq(struct IDEUnit *unit, ULONG tries, bool fast) {
|
||||
|
||||
/**
|
||||
* ata_wait_not_busy
|
||||
*
|
||||
*
|
||||
* Poll BSY in the status register until clear or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -124,7 +124,7 @@ static bool ata_wait_not_busy(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* ata_wait_ready
|
||||
*
|
||||
*
|
||||
* Poll RDY in the status register until set or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -146,10 +146,10 @@ static bool ata_wait_ready(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* ata_select
|
||||
*
|
||||
*
|
||||
* Selects the drive by writing to the dev head register
|
||||
* If the request would not change the drive select then this will be a no-op to save time
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param select the dev head value to set
|
||||
* @param wait whether to wait for the drive to clear BSY after selection
|
||||
@ -159,7 +159,7 @@ bool ata_select(struct IDEUnit *unit, UBYTE select, bool wait)
|
||||
{
|
||||
bool changed = false;
|
||||
volatile UBYTE *shadowDevHead = unit->shadowDevHead;
|
||||
|
||||
|
||||
if (!unit->lba) select &= ~(0x40);
|
||||
|
||||
if (*shadowDevHead == select) {
|
||||
@ -169,7 +169,7 @@ bool ata_select(struct IDEUnit *unit, UBYTE select, bool wait)
|
||||
if ((*shadowDevHead & 0xF0) != (select & 0xF0)) changed = true;
|
||||
|
||||
// Wait for BSY to clear before changing drive unless there's no drive selected
|
||||
if (*shadowDevHead != 0 && changed) ata_wait_not_busy(unit,ATA_BSY_WAIT_COUNT);
|
||||
if (*shadowDevHead != 0 && changed) ata_wait_not_busy(unit,ATA_BSY_WAIT_COUNT);
|
||||
|
||||
*unit->drive->devHead = select;
|
||||
|
||||
@ -185,7 +185,7 @@ bool ata_select(struct IDEUnit *unit, UBYTE select, bool wait)
|
||||
|
||||
/**
|
||||
* ata_identify
|
||||
*
|
||||
*
|
||||
* Send an IDENTIFY command to the device and place the results in the buffer
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param buffer Pointer to the destination buffer
|
||||
@ -194,17 +194,17 @@ bool ata_select(struct IDEUnit *unit, UBYTE select, bool wait)
|
||||
bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
|
||||
{
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
|
||||
ata_select(unit,drvSel,false);
|
||||
|
||||
if (!ata_wait_not_busy(unit,ATA_BSY_WAIT_COUNT)) return false;
|
||||
|
||||
|
||||
*unit->drive->sectorCount = 0;
|
||||
*unit->drive->lbaLow = 0;
|
||||
*unit->drive->lbaMid = 0;
|
||||
*unit->drive->lbaHigh = 0;
|
||||
*unit->drive->error_features = 0;
|
||||
*unit->drive->devHead = drvSel;
|
||||
*unit->drive->devHead = drvSel;
|
||||
*unit->drive->status_command = ATA_CMD_IDENTIFY;
|
||||
|
||||
if (ata_check_error(unit) || !ata_wait_drq(unit,500,false)) {
|
||||
@ -251,7 +251,7 @@ void ata_set_xfer(struct IDEUnit *unit, enum xfer method) {
|
||||
|
||||
/**
|
||||
* ata_init_unit
|
||||
*
|
||||
*
|
||||
* Initialize a unit, check if it is there and responding
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns false on error
|
||||
@ -271,20 +271,20 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
bool dev_found = false;
|
||||
|
||||
offset = (unit->channel == 0) ? CHANNEL_0 : CHANNEL_1;
|
||||
|
||||
if ((unit->drive = AllocMem(sizeof(struct Drive),MEMF_ANY|MEMF_CLEAR)) == NULL) { // Pointerholder for drive base
|
||||
|
||||
if ((unit->drive = AllocMem(sizeof(struct Drive),MEMF_ANY|MEMF_CLEAR)) == NULL) { // Pointerholder for drive base
|
||||
return false;
|
||||
}
|
||||
|
||||
unit->drive->data = (UWORD*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_data);
|
||||
unit->drive->error_features = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_error);
|
||||
unit->drive->sectorCount = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_sectorCount);
|
||||
unit->drive->lbaLow = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaLow);
|
||||
unit->drive->lbaMid = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaMid);
|
||||
unit->drive->lbaHigh = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaHigh);
|
||||
unit->drive->devHead = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_devHead);
|
||||
unit->drive->status_command = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_status);
|
||||
|
||||
|
||||
unit->drive->data = (UWORD*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_data);
|
||||
unit->drive->error_features = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_error);
|
||||
unit->drive->sectorCount = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_sectorCount);
|
||||
unit->drive->lbaLow = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaLow);
|
||||
unit->drive->lbaMid = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaMid);
|
||||
unit->drive->lbaHigh = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaHigh);
|
||||
unit->drive->devHead = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_devHead);
|
||||
unit->drive->status_command = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_status);
|
||||
|
||||
*unit->shadowDevHead = *unit->drive->devHead = (unit->primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
for (int i=0; i<(8*NEXT_REG); i+=NEXT_REG) {
|
||||
@ -295,7 +295,7 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dev_found == false || !ata_wait_not_busy(unit,ATA_BSY_WAIT_COUNT)) {
|
||||
return false;
|
||||
}
|
||||
@ -335,14 +335,14 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
|
||||
unit->lba48 = true;
|
||||
Info("INIT: Drive supports LBA48 mode \n");
|
||||
unit->logicalSectors = (buf[ata_identify_lba48_sectors + 1] << 16 |
|
||||
unit->logicalSectors = (buf[ata_identify_lba48_sectors + 1] << 16 |
|
||||
buf[ata_identify_lba48_sectors]);
|
||||
unit->write_taskfile = &write_taskfile_lba48;
|
||||
|
||||
|
||||
} else if (unit->lba == true) {
|
||||
// LBA-28 up to 127GB
|
||||
unit->write_taskfile = &write_taskfile_lba;
|
||||
|
||||
|
||||
} else {
|
||||
// CHS Mode
|
||||
Warn("INIT: Drive doesn't support LBA mode\n");
|
||||
@ -354,7 +354,7 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
|
||||
if (unit->logicalSectors == 0 || unit->heads == 0 || unit->cylinders == 0) goto ident_failed;
|
||||
|
||||
if (unit->logicalSectors >= 267382800) {
|
||||
if (unit->logicalSectors >= 267382800) {
|
||||
// For drives larger than 127GB fudge the geometry
|
||||
unit->heads = 63;
|
||||
unit->sectorsPerTrack = 255;
|
||||
@ -368,7 +368,7 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
Info("INIT: Adjusting geometry, new geometry; 16/255/%ld\n",unit->cylinders);
|
||||
}
|
||||
|
||||
|
||||
|
||||
while ((unit->blockSize >> unit->blockShift) > 1) {
|
||||
unit->blockShift++;
|
||||
}
|
||||
@ -397,14 +397,14 @@ ident_failed:
|
||||
unit->present = true;
|
||||
|
||||
Info("INIT: LBAs %ld Blocksize: %ld\n",unit->logicalSectors,unit->blockSize);
|
||||
|
||||
|
||||
if (buf) FreeMem(buf,512);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_set_multiple
|
||||
*
|
||||
*
|
||||
* Configure the DRQ block size for READ MULTIPLE and WRITE MULTIPLE
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param multiple DRQ Block size
|
||||
@ -412,7 +412,7 @@ ident_failed:
|
||||
*/
|
||||
bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple) {
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
|
||||
ata_select(unit,drvSel,true);
|
||||
|
||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||
@ -427,7 +427,7 @@ bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple) {
|
||||
|
||||
if (!ata_wait_not_busy(unit,ATA_BSY_WAIT_COUNT))
|
||||
return IOERR_UNITBUSY;
|
||||
|
||||
|
||||
if (ata_check_error(unit)) {
|
||||
if (*unit->drive->error_features & ata_err_flag_aborted) {
|
||||
return IOERR_ABORTED;
|
||||
@ -443,7 +443,7 @@ bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple) {
|
||||
|
||||
/**
|
||||
* ata_read
|
||||
*
|
||||
*
|
||||
* Read blocks from the unit
|
||||
* @param buffer destination buffer
|
||||
* @param lba LBA Address
|
||||
@ -459,12 +459,12 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
ULONG txn_count; // Amount of sectors to transfer in the current READ/WRITE command
|
||||
|
||||
UBYTE command;
|
||||
|
||||
|
||||
if (unit->lba48) {
|
||||
command = ATA_CMD_READ_MULTIPLE_EXT;
|
||||
} else {
|
||||
command = (unit->xferMultiple) ? ATA_CMD_READ_MULTIPLE : ATA_CMD_READ;
|
||||
}
|
||||
}
|
||||
|
||||
void (*ata_xfer)(void *source, void *destination);
|
||||
|
||||
@ -486,7 +486,7 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* Transfer up-to MAX_TRANSFER_SECTORS per ATA command invocation
|
||||
*
|
||||
*
|
||||
* count: Number of sectors to transfer for this io request
|
||||
* txn_count: Number of sectors to transfer to/from the drive in one ATA command transaction
|
||||
* multiple_count: Max number of sectors that can be transferred before polling DRQ
|
||||
@ -498,7 +498,7 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
txn_count = count; // Get any remainders
|
||||
}
|
||||
count -= txn_count;
|
||||
|
||||
|
||||
Trace("ATA: XFER Count: %ld, txn_count: %ld\n",count,txn_count);
|
||||
|
||||
if ((error = unit->write_taskfile(unit,command,lba,txn_count,0)) != 0) {
|
||||
@ -529,7 +529,7 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* ata_write
|
||||
*
|
||||
*
|
||||
* Write blocks to the unit
|
||||
* @param buffer source buffer
|
||||
* @param lba LBA Address
|
||||
@ -546,7 +546,7 @@ BYTE ata_write(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
ULONG txn_count; // Amount of sectors to transfer in the current READ/WRITE command
|
||||
|
||||
UBYTE command;
|
||||
|
||||
|
||||
if (unit->lba48) {
|
||||
command = ATA_CMD_WRITE_MULTIPLE_EXT;
|
||||
} else {
|
||||
@ -573,7 +573,7 @@ BYTE ata_write(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* Transfer up-to MAX_TRANSFER_SECTORS per ATA command invocation
|
||||
*
|
||||
*
|
||||
* count: Number of sectors to transfer for this io request
|
||||
* txn_count: Number of sectors to transfer to/from the drive in one ATA command transaction
|
||||
* multiple_count: Max number of sectors that can be transferred before polling DRQ
|
||||
@ -616,7 +616,7 @@ BYTE ata_write(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* ata_read_unaligned_long
|
||||
*
|
||||
*
|
||||
* Read data to an unaligned buffer
|
||||
* @param source Pointer to the drive data port
|
||||
* @param destination Pointer to the data buffer
|
||||
@ -637,7 +637,7 @@ void ata_read_unaligned_long(void *source, void *destination) {
|
||||
|
||||
/**
|
||||
* ata_write_unaligned_long
|
||||
*
|
||||
*
|
||||
* Write data from an unaligned buffer
|
||||
* @param source Pointer to the data buffer
|
||||
* @param destination Pointer to the drive data port
|
||||
@ -652,7 +652,7 @@ void ata_write_unaligned_long(void *source, void *destination) {
|
||||
|
||||
/**
|
||||
* write_taskfile_chs
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param lba Pointer to the LBA variable
|
||||
*/
|
||||
@ -662,12 +662,12 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
UBYTE sector = (lba % unit->sectorsPerTrack) + 1;
|
||||
|
||||
BYTE devHead;
|
||||
|
||||
|
||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||
return HFERR_SelTimeout;
|
||||
|
||||
devHead = ((unit->primary) ? 0xA0 : 0xB0) | (head & 0x0F);
|
||||
|
||||
|
||||
*unit->shadowDevHead = devHead;
|
||||
*unit->drive->devHead = devHead;
|
||||
*unit->drive->sectorCount = sectorCount; // Count value of 0 indicates to transfer 256 sectors
|
||||
@ -682,7 +682,7 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
|
||||
/**
|
||||
* write_taskfile_lba
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param lba Pointer to the LBA variable
|
||||
*/
|
||||
@ -708,7 +708,7 @@ static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
|
||||
/**
|
||||
* write_taskfile_lba48
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param lba Pointer to the LBA variable
|
||||
*/
|
||||
@ -734,7 +734,7 @@ static BYTE write_taskfile_lba48(struct IDEUnit *unit, UBYTE command, ULONG lba,
|
||||
|
||||
/**
|
||||
* ata_set_pio
|
||||
*
|
||||
*
|
||||
* @param unit Pointer t oan IDEUnit struct
|
||||
* @param pio pio mode
|
||||
*/
|
||||
@ -742,7 +742,7 @@ BYTE ata_set_pio(struct IDEUnit *unit, UBYTE pio) {
|
||||
BYTE error = 0;
|
||||
|
||||
if (pio > 4) return IOERR_BADADDRESS;
|
||||
|
||||
|
||||
if (pio > 0) pio |= 0x08;
|
||||
|
||||
if ((error = write_taskfile_lba(unit,ATA_CMD_SET_FEATURES,0,pio,0x03)) != 0)
|
||||
@ -758,9 +758,9 @@ BYTE ata_set_pio(struct IDEUnit *unit, UBYTE pio) {
|
||||
|
||||
/**
|
||||
* scsi_ata_passthrough
|
||||
*
|
||||
*
|
||||
* Handle SCSI ATA PASSTHROUGH (12) command to send ATA commands to the drive
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param cmd Pointer to a SCSICmd struct
|
||||
* @return non-zero on error
|
||||
@ -771,11 +771,11 @@ BYTE scsi_ata_passthrough(struct IDEUnit *unit, struct SCSICmd *cmd) {
|
||||
bool byt_blok = (cdb->length & ATA_BYT_BLOK) ? true : false;
|
||||
UBYTE protocol = (cdb->protocol >> 1) & 0x0F;
|
||||
UBYTE t_length = cdb->length & ATA_TLEN_MASK;
|
||||
|
||||
|
||||
ULONG lba = (cdb->lbaHigh << 16 | cdb->lbaMid << 8 | cdb->lbaLow);
|
||||
ULONG count = 0;
|
||||
BYTE error = 0;
|
||||
|
||||
|
||||
UWORD *src = NULL;
|
||||
UWORD *dest = NULL;
|
||||
|
||||
|
||||
2
ata.h
2
ata.h
@ -24,7 +24,7 @@
|
||||
#define ata_reg_error 1*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_features 1*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_sectorCount 2*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_lbaLow 3*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_lbaLow 3*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_lbaMid 4*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_lbaHigh 5*NEXT_REG + IDE_CSMASK
|
||||
#define ata_reg_devHead 6*NEXT_REG + IDE_CSMASK
|
||||
|
||||
154
atapi.c
154
atapi.c
@ -24,11 +24,11 @@
|
||||
|
||||
/**
|
||||
* atapi_status_reg_delay
|
||||
*
|
||||
*
|
||||
* We need a short delay before actually checking the status register to let the drive update the status
|
||||
* Reading a CIA register should ensure a consistent delay regardless of CPU speed
|
||||
* More info: https://wiki.osdev.org/ATA_PIO_Mode#400ns_delays
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
static void __attribute__((always_inline)) atapi_status_reg_delay(struct IDEUnit *unit) {
|
||||
@ -38,7 +38,7 @@ static void __attribute__((always_inline)) atapi_status_reg_delay(struct IDEUni
|
||||
}
|
||||
/**
|
||||
* atapi_wait_drq
|
||||
*
|
||||
*
|
||||
* Poll DRQ in the status register until set or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -57,7 +57,7 @@ static bool atapi_wait_drq(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* atapi_wait_drq_not_bsy
|
||||
*
|
||||
*
|
||||
* Poll the status register until DRQ set and BSY clear or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -75,7 +75,7 @@ static bool atapi_wait_drq_not_bsy(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* atapi_wait_not_bsy
|
||||
*
|
||||
*
|
||||
* Poll BSY in the status register until clear or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -94,7 +94,7 @@ static bool atapi_wait_not_bsy(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* atapi_wait_not_drqbsy
|
||||
*
|
||||
*
|
||||
* Poll DRQ & BSY in the status register until clear or timeout
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param tries Tries, sets the timeout
|
||||
@ -114,9 +114,9 @@ static bool atapi_wait_not_drqbsy(struct IDEUnit *unit, ULONG tries) {
|
||||
|
||||
/**
|
||||
* atapi_check_ir
|
||||
*
|
||||
*
|
||||
* Mask the Interrupt Reason register and check against a value
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param mask Mask
|
||||
* @param value Expected value after masking
|
||||
@ -134,7 +134,7 @@ static bool atapi_check_ir(struct IDEUnit *unit, UBYTE mask, UBYTE value, UWORD
|
||||
|
||||
/**
|
||||
* atapi_dev_reset
|
||||
*
|
||||
*
|
||||
* Resets the device by sending a DEVICE RESET command to it
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
@ -148,12 +148,12 @@ void atapi_dev_reset(struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_check_signature
|
||||
*
|
||||
*
|
||||
* Resets the device then checks the signature in the LBA High and Mid registers to see if an ATAPI device is present
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
bool atapi_check_signature(struct IDEUnit *unit) {
|
||||
|
||||
|
||||
atapi_dev_reset(unit);
|
||||
wait_us(unit->itask->tr,10000);
|
||||
for (int i=0; i<20; i++) {
|
||||
@ -165,9 +165,9 @@ bool atapi_check_signature(struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_identify
|
||||
*
|
||||
*
|
||||
* Send an "IDENTIFY PACKET DEVICE" command and read the results into a buffer
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param buffer Pointer to the destination buffer
|
||||
* @returns True on success, false on failure
|
||||
@ -216,9 +216,9 @@ bool atapi_identify(struct IDEUnit *unit, UWORD *buffer) {
|
||||
|
||||
/**
|
||||
* atapi_translate
|
||||
*
|
||||
*
|
||||
* Translate TD commands to ATAPI and issue them to the device
|
||||
*
|
||||
*
|
||||
* @param io_Data Pointer to the data buffer
|
||||
* @param lba LBA to transfer
|
||||
* @param count Number of LBAs to transfer
|
||||
@ -227,7 +227,7 @@ bool atapi_identify(struct IDEUnit *unit, UWORD *buffer) {
|
||||
* @param direction Transfer direction
|
||||
* @returns error
|
||||
*/
|
||||
BYTE atapi_translate(APTR io_Data, ULONG lba, ULONG count, ULONG *io_Actual, struct IDEUnit *unit, enum xfer_dir direction)
|
||||
BYTE atapi_translate(APTR io_Data, ULONG lba, ULONG count, ULONG *io_Actual, struct IDEUnit *unit, enum xfer_dir direction)
|
||||
{
|
||||
Trace("atapi_translate enter\n");
|
||||
struct SCSICmd *cmd = MakeSCSICmd(SZ_CDB_10);
|
||||
@ -295,7 +295,7 @@ BYTE atapi_translate(APTR io_Data, ULONG lba, ULONG count, ULONG *io_Actual, str
|
||||
case 0x07: // Disk is write protected
|
||||
ret = TDERR_WriteProt;
|
||||
goto done;
|
||||
|
||||
|
||||
default: // Anything else
|
||||
ret = TDERR_NotSpecified;
|
||||
continue; // Try again
|
||||
@ -312,7 +312,7 @@ BYTE atapi_translate(APTR io_Data, ULONG lba, ULONG count, ULONG *io_Actual, str
|
||||
done:
|
||||
Trace("atapi_packet returns %ld\n",ret);
|
||||
*io_Actual = cmd->scsi_Actual;
|
||||
|
||||
|
||||
DeleteSCSICmd(cmd);
|
||||
|
||||
return ret;
|
||||
@ -322,9 +322,9 @@ done:
|
||||
|
||||
/**
|
||||
* atapi_packet
|
||||
*
|
||||
*
|
||||
* Send a SCSICmd to an ATAPI device
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct
|
||||
* @param unit Pointer to the IDEUnit
|
||||
* @returns error, sense key returned in SenseData
|
||||
@ -367,7 +367,7 @@ BYTE atapi_packet(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
byte_count = cmd->scsi_Length;
|
||||
}
|
||||
|
||||
*unit->drive->lbaMid = byte_count & 0xFF;
|
||||
*unit->drive->lbaMid = byte_count & 0xFF;
|
||||
*unit->drive->lbaHigh = byte_count >> 8 & 0xFF;
|
||||
*unit->drive->error_features = 0;
|
||||
*unit->drive->devHead = drvSelHead;
|
||||
@ -378,7 +378,7 @@ BYTE atapi_packet(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
ret = IOERR_UNITBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (!atapi_check_ir(unit,IR_STATUS,IR_COMMAND,10)) {
|
||||
Trace("ATAPI: Failed command phase\n");
|
||||
ret = HFERR_Phase;
|
||||
@ -404,7 +404,7 @@ BYTE atapi_packet(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
if (*status & ata_flag_error) goto ata_error;
|
||||
|
||||
cmd->scsi_CmdActual = cmd->scsi_CmdLength;
|
||||
|
||||
|
||||
ULONG index = 0;
|
||||
|
||||
while (1) {
|
||||
@ -418,7 +418,7 @@ BYTE atapi_packet(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
if (cmd->scsi_Length == 0) break;
|
||||
|
||||
if ((atapi_check_ir(unit,0x03,IR_STATUS,1))) break;
|
||||
|
||||
|
||||
if (!(atapi_wait_drq(unit,10))) break;
|
||||
|
||||
|
||||
@ -501,9 +501,9 @@ end:
|
||||
|
||||
/**
|
||||
* atapi_test_unit_ready
|
||||
*
|
||||
*
|
||||
* Send a TEST UNIT READY to the unit and update the media change count & presence
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns nonzero if there was an error
|
||||
*/
|
||||
@ -572,9 +572,9 @@ done:
|
||||
|
||||
/**
|
||||
* atapi_request_sense
|
||||
*
|
||||
*
|
||||
* Request extended sense data from the ATAPI device
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param senseKey Pointer for the senseKey result
|
||||
* @param asc Pointer for the asc result
|
||||
@ -587,7 +587,7 @@ BYTE atapi_request_sense(struct IDEUnit *unit, UBYTE *errorCode, UBYTE *senseKey
|
||||
UBYTE *cdb = (UBYTE *)cmd->scsi_Command;
|
||||
|
||||
UBYTE *buf;
|
||||
|
||||
|
||||
if ((buf = AllocMem(18,MEMF_CLEAR|MEMF_ANY)) == NULL) {
|
||||
DeleteSCSICmd(cmd);
|
||||
return TDERR_NoMem;
|
||||
@ -619,9 +619,9 @@ BYTE atapi_request_sense(struct IDEUnit *unit, UBYTE *errorCode, UBYTE *senseKey
|
||||
|
||||
/**
|
||||
* atapi_get_capacity
|
||||
*
|
||||
*
|
||||
* Send a READ CAPACITY (10) to the ATAPI device then update the unit geometry with the returned values
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @return non-zero on error
|
||||
*/
|
||||
@ -656,23 +656,23 @@ BYTE atapi_get_capacity(struct IDEUnit *unit) {
|
||||
if ((ret = atapi_packet(cmd,unit)) == 0) {
|
||||
unit->logicalSectors = capacity.logicalSectors + 1;
|
||||
unit->blockSize = capacity.blockSize;
|
||||
|
||||
|
||||
while ((unit->blockSize >> unit->blockShift) > 1) {
|
||||
unit->blockShift++;
|
||||
}
|
||||
}
|
||||
Trace("New geometry: %ld %ld\n",unit->logicalSectors, unit->blockSize);
|
||||
|
||||
|
||||
DeleteSCSICmd(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* atapi_mode_sense
|
||||
*
|
||||
*
|
||||
* Send a MODE SENSE (10) request to the ATAPI device
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param page_code Page code to request
|
||||
* @param buffer Pointer to a buffer for the mode sense data response
|
||||
@ -714,9 +714,9 @@ BYTE atapi_mode_sense(struct IDEUnit *unit, BYTE page_code, BYTE subpage_code, U
|
||||
|
||||
/**
|
||||
* atapi_scsi_mode_sense_6
|
||||
*
|
||||
*
|
||||
* ATAPI devices do not support MODE SENSE (6) so translate to a MODE SENSE (10)
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct containing a MODE SENSE (6) request
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error, mode-sense data in cmd->scsi_Data
|
||||
@ -727,7 +727,7 @@ BYTE atapi_scsi_mode_sense_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
BYTE ret;
|
||||
UBYTE *buf = NULL;
|
||||
UBYTE *dest = (UBYTE *)cmd->scsi_Data;
|
||||
UBYTE *dest = (UBYTE *)cmd->scsi_Data;
|
||||
ULONG len = cmd->scsi_Command[4] + 4; // Original allocation length
|
||||
|
||||
struct SCSICmd *cmd_sense = NULL;
|
||||
@ -783,9 +783,9 @@ BYTE atapi_scsi_mode_sense_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_scsi_mode_select_6
|
||||
*
|
||||
*
|
||||
* ATAPI devices do not support MODE SELECT (6) so translate to a MODE SELECT (10)
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct containing a MODE SENSE (6) request
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error, mode-sense data in cmd->scsi_Data
|
||||
@ -817,7 +817,7 @@ BYTE atapi_scsi_mode_select_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
}
|
||||
|
||||
cmd_select->scsi_Command[0] = SCSI_CMD_MODE_SELECT_10;
|
||||
cmd_select->scsi_Command[1] = cmd->scsi_Command[1]; // PF / SP
|
||||
cmd_select->scsi_Command[1] = cmd->scsi_Command[1]; // PF / SP
|
||||
cmd_select->scsi_Command[7] = (bufSize >> 8) & 0xFF; // Parameter list length
|
||||
cmd_select->scsi_Command[8] = bufSize; // Parameter list length
|
||||
|
||||
@ -852,10 +852,10 @@ BYTE atapi_scsi_mode_select_6(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_scsi_read_write_6
|
||||
*
|
||||
*
|
||||
* ATAPI devices do not support READ (6) or WRITE (6)
|
||||
* Translate these calls to READ (10) / WRITE (10);
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error
|
||||
@ -870,7 +870,7 @@ BYTE atapi_scsi_read_write_6 (struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
cdb->operation = oldcdb->operation | 0x20;
|
||||
cdb->length = oldcdb->length;
|
||||
cdb->lba = oldcdb->lba_high << 16 |
|
||||
oldcdb->lba_mid << 8 |
|
||||
oldcdb->lba_mid << 8 |
|
||||
oldcdb->lba_low;
|
||||
|
||||
if (cdb->length == 0) cdb->length = 256; // for SCSI READ/WRITE 6 a transfer length of 0 specifies that 256 blocks will be transferred
|
||||
@ -892,12 +892,12 @@ BYTE atapi_scsi_read_write_6 (struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_packet_unaligned
|
||||
*
|
||||
*
|
||||
* In the unlikely event that someone has allocated an unaligned data buffer, align the data first by making a copy
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on exit
|
||||
* @returns non-zero on exit
|
||||
*/
|
||||
BYTE atapi_packet_unaligned(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
BYTE error = 0;
|
||||
@ -926,9 +926,9 @@ BYTE atapi_packet_unaligned(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_start_stop_unit
|
||||
*
|
||||
*
|
||||
* send START STOP command to ATAPI drive e.g to eject the disc
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param start Start bit of START STOP
|
||||
* @param loej loej bit of START STOP
|
||||
@ -943,7 +943,7 @@ BYTE atapi_start_stop_unit(struct IDEUnit *unit, bool start, bool loej) {
|
||||
if (start) operation |= (1<<0);
|
||||
|
||||
if ((cmd = MakeSCSICmd(SZ_CDB_10)) == NULL) return TDERR_NoMem;
|
||||
|
||||
|
||||
cmd->scsi_Command[0] = SCSI_CMD_START_STOP_UNIT;
|
||||
cmd->scsi_Command[1] = (1<<0); // Immediate bit set
|
||||
cmd->scsi_Command[4] = operation;
|
||||
@ -957,9 +957,9 @@ BYTE atapi_start_stop_unit(struct IDEUnit *unit, bool start, bool loej) {
|
||||
|
||||
/**
|
||||
* atapi_check_wp
|
||||
*
|
||||
*
|
||||
* Check write-protect status of the disk
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error
|
||||
*/
|
||||
@ -984,7 +984,7 @@ BYTE atapi_check_wp(struct IDEUnit *unit) {
|
||||
|
||||
/**
|
||||
* atapi_update_presence
|
||||
*
|
||||
*
|
||||
* If the medium has changed state update the unit info, geometry etc
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param present Medium present
|
||||
@ -1010,7 +1010,7 @@ bool atapi_update_presence(struct IDEUnit *unit, bool present) {
|
||||
|
||||
/**
|
||||
* atapi_do_defer_tur
|
||||
*
|
||||
*
|
||||
* If an access to the medium was successful then we know that it is present.
|
||||
* The diskchange task can then skip the next "Test Unit Ready" so it won't interrupt a transfer
|
||||
*
|
||||
@ -1029,11 +1029,11 @@ void atapi_do_defer_tur(struct IDEUnit *unit, UBYTE cmd) {
|
||||
|
||||
/**
|
||||
* atapi_adjust_end_msf
|
||||
*
|
||||
*
|
||||
* Decrement the MSF by one frame.
|
||||
* i.e get the end of the last track by inputting the MSF for the lead-out
|
||||
*
|
||||
* @param msf
|
||||
*
|
||||
* @param msf
|
||||
*/
|
||||
static void atapi_adjust_end_msf(struct SCSI_TRACK_MSF *msf) {
|
||||
if (msf->frame > 0) {
|
||||
@ -1052,9 +1052,9 @@ static void atapi_adjust_end_msf(struct SCSI_TRACK_MSF *msf) {
|
||||
|
||||
/**
|
||||
* atapi_read_toc
|
||||
*
|
||||
*
|
||||
* Reads the CD TOC into the supplied buffer
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param buf Pointer to the buffer
|
||||
* @param bufSize Size of buffer
|
||||
@ -1068,9 +1068,9 @@ BYTE atapi_read_toc(struct IDEUnit *unit, BYTE *buf, ULONG bufSize) {
|
||||
}
|
||||
|
||||
struct SCSICmd *cmd = MakeSCSICmd(SZ_CDB_10);
|
||||
|
||||
|
||||
if (cmd == NULL) return TDERR_NoMem;
|
||||
|
||||
|
||||
cmd->scsi_Data = (UWORD *)buf;
|
||||
cmd->scsi_Length = bufSize;
|
||||
cmd->scsi_Flags = SCSIF_READ;
|
||||
@ -1083,14 +1083,14 @@ BYTE atapi_read_toc(struct IDEUnit *unit, BYTE *buf, ULONG bufSize) {
|
||||
|
||||
DeleteSCSICmd(cmd);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* atapi_get_track_msf
|
||||
*
|
||||
*
|
||||
* Find the M/S/F of a Track
|
||||
*
|
||||
*
|
||||
* @param toc pointer to a SCSI_CD_TOC struct
|
||||
* @param trackNum track number to find
|
||||
* @param msf Pointer to a SCSI_TRACK_MSF struct
|
||||
@ -1116,14 +1116,14 @@ BOOL atapi_get_track_msf(struct SCSI_CD_TOC *toc, int trackNum, struct SCSI_TRAC
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* atapi_play_track_index
|
||||
*
|
||||
*
|
||||
* Find tracks <start> and <end> in TOC and issue a PLAY AUDIO MSF command
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param start Start track number
|
||||
* @param end End track number
|
||||
* @param end End track number
|
||||
* @returns non-zero on error
|
||||
*/
|
||||
BYTE atapi_play_track_index(struct IDEUnit *unit, UBYTE start, UBYTE end) {
|
||||
@ -1135,7 +1135,7 @@ BYTE atapi_play_track_index(struct IDEUnit *unit, UBYTE start, UBYTE end) {
|
||||
if (toc == NULL) return TDERR_NoMem;
|
||||
|
||||
ret = atapi_read_toc(unit,(BYTE *)toc,SCSI_TOC_SIZE);
|
||||
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
if (end > toc->lastTrack) end = 0xAA; // Lead out
|
||||
@ -1158,9 +1158,9 @@ BYTE atapi_play_track_index(struct IDEUnit *unit, UBYTE start, UBYTE end) {
|
||||
|
||||
/**
|
||||
* atapi_play_audio_msf
|
||||
*
|
||||
*
|
||||
* Issue a PLAY AUDIO MSF command to the drive
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param start Pointer to a SCSI_TRACK_MSF struct for the starting position
|
||||
* @param end Pointer to a SCSI_TRACK_MSF struct for the ending position
|
||||
@ -1170,7 +1170,7 @@ BYTE atapi_play_audio_msf(struct IDEUnit *unit, struct SCSI_TRACK_MSF *start, st
|
||||
BYTE ret = 0;
|
||||
|
||||
struct SCSICmd *cmd = MakeSCSICmd(SZ_CDB_10);
|
||||
|
||||
|
||||
if (cmd == NULL) return TDERR_NoMem;
|
||||
|
||||
cmd->scsi_Command[0] = SCSI_CMD_PLAY_AUDIO_MSF;
|
||||
@ -1195,10 +1195,10 @@ BYTE atapi_play_audio_msf(struct IDEUnit *unit, struct SCSI_TRACK_MSF *start, st
|
||||
|
||||
/**
|
||||
* atapi_translate_play_audio_index
|
||||
*
|
||||
*
|
||||
* PLAY AUDIO INDEX was deprecated with SCSI-3 and is not supported by ATAPI drives
|
||||
* Some software makes use of this, so we translate it to a PLAY AUDIO MSF command
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct for a PLAY AUDIO INDEX command
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error
|
||||
@ -1219,9 +1219,9 @@ BYTE atapi_translate_play_audio_index(struct SCSICmd *cmd, struct IDEUnit *unit)
|
||||
|
||||
/**
|
||||
* atapi_autosense
|
||||
*
|
||||
*
|
||||
* Perform a REQUEST SENSE and put the result into scsi_SenseData of a supplied SCSICmd
|
||||
*
|
||||
*
|
||||
* @param scsi_command Pointer to a SCSICmd struct
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns non-zero on error
|
||||
|
||||
20
blockcopy.h
20
blockcopy.h
@ -3,17 +3,17 @@
|
||||
#pragma GCC optimize ("-fomit-frame-pointer")
|
||||
/**
|
||||
* ata_read_long_movem
|
||||
*
|
||||
*
|
||||
* Fast copy of a 512-byte sector using movem
|
||||
* Adapted from the open source at_apollo_device by Frédéric REQUIN
|
||||
* https://github.com/fredrequin/at_apollo_device
|
||||
*
|
||||
*
|
||||
* NOTE!
|
||||
* The 68000 does an extra memory access at the end of a movem instruction!
|
||||
* Source: https://github.com/prb28/m68k-instructions-documentation/blob/master/instructions/movem.md
|
||||
*
|
||||
*
|
||||
* With the src of end-52 the error reg will be harmlessly read instead.
|
||||
*
|
||||
*
|
||||
* @param source Pointer to drive data port
|
||||
* @param destination Pointer to source buffer
|
||||
*/
|
||||
@ -37,11 +37,11 @@ static inline void ata_read_long_movem (void *source, void *destination) {
|
||||
|
||||
/**
|
||||
* ata_write_long_movem
|
||||
*
|
||||
*
|
||||
* Fast copy of a 512-byte sector using movem
|
||||
* Adapted from the open source at_apollo_device by Frédéric REQUIN
|
||||
* https://github.com/fredrequin/at_apollo_device
|
||||
*
|
||||
*
|
||||
* @param source Pointer to source buffer
|
||||
* @param destination Pointer to drive data port
|
||||
*/
|
||||
@ -62,9 +62,9 @@ static inline void ata_write_long_movem (void *source, void *destination) {
|
||||
|
||||
/**
|
||||
* ata_read_long_move
|
||||
*
|
||||
*
|
||||
* Read a sector using move - faster than movem on 68020+
|
||||
*
|
||||
*
|
||||
*/
|
||||
static inline void ata_read_long_move (void *source, void *destination) {
|
||||
asm volatile (
|
||||
@ -82,9 +82,9 @@ static inline void ata_read_long_move (void *source, void *destination) {
|
||||
|
||||
/**
|
||||
* ata_write_long_move
|
||||
*
|
||||
*
|
||||
* Write a sector using move - faster than movem on 68020+
|
||||
*
|
||||
*
|
||||
*/
|
||||
static inline void ata_write_long_move (void *source, void *destination) {
|
||||
asm volatile (
|
||||
|
||||
16
debug.c
16
debug.c
@ -17,11 +17,11 @@ void traceCommand(struct IOStdReq *req) {
|
||||
case CMD_CLEAR:
|
||||
commandName = "CMD_CLEAR";
|
||||
break;
|
||||
|
||||
|
||||
case CMD_UPDATE:
|
||||
commandName = "CMD_UPDATE";
|
||||
break;
|
||||
|
||||
|
||||
case CMD_READ:
|
||||
commandName = "CMD_READ";
|
||||
break;
|
||||
@ -29,23 +29,23 @@ void traceCommand(struct IOStdReq *req) {
|
||||
case CMD_WRITE:
|
||||
commandName = "CMD_WRITE";
|
||||
break;
|
||||
|
||||
|
||||
case TD_REMCHANGEINT:
|
||||
commandName = "TD_REMCHANGEINT";
|
||||
break;
|
||||
|
||||
|
||||
case TD_PROTSTATUS:
|
||||
commandName = "TD_PROTSTATUS";
|
||||
break;
|
||||
|
||||
|
||||
case TD_CHANGENUM:
|
||||
commandName = "TD_CHANGENUM";
|
||||
break;
|
||||
|
||||
|
||||
case TD_CHANGESTATE:
|
||||
commandName = "TD_CHANGESTATE";
|
||||
break;
|
||||
|
||||
|
||||
case TD_EJECT:
|
||||
commandName = "TD_EJECT";
|
||||
break;
|
||||
@ -223,7 +223,7 @@ void traceCommand(struct IOStdReq *req) {
|
||||
case TDERR_PostReset:
|
||||
err = "TDERR_PostReset";
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
err = "UNKNOWN";
|
||||
|
||||
|
||||
4
device.h
4
device.h
@ -22,7 +22,7 @@ enum xfer {
|
||||
|
||||
/**
|
||||
* Drive struct
|
||||
*
|
||||
*
|
||||
* Each register spaced 512 bytes apart
|
||||
* To use this code with other boards you may need to adjust these sizes
|
||||
*/
|
||||
@ -120,7 +120,7 @@ struct IDETask {
|
||||
|
||||
#define DEVICE_ID_STRING "lide " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " (" XSTR(BUILD_DATE) ") " XSTR(GIT_REF)
|
||||
#define DEVICE_VERSION 40
|
||||
#define DEVICE_REVISION 10
|
||||
#define DEVICE_REVISION 9
|
||||
#define DEVICE_PRIORITY 0 /* Most people will not need a priority and should leave it at zero. */
|
||||
|
||||
#endif
|
||||
|
||||
42
driver.c
42
driver.c
@ -91,7 +91,7 @@ char * set_dev_name(struct DeviceBase *dev) {
|
||||
|
||||
/**
|
||||
* L_CreateTask
|
||||
*
|
||||
*
|
||||
* Create a task with tc_UserData populated before it starts
|
||||
* @param taskName Pointer to a null-terminated string
|
||||
* @param priority Task Priority between -128 and 127
|
||||
@ -101,9 +101,9 @@ char * set_dev_name(struct DeviceBase *dev) {
|
||||
*/
|
||||
struct Task *L_CreateTask(char * taskName, LONG priority, APTR funcEntry, ULONG stackSize, APTR userData) {
|
||||
stackSize = (stackSize + 3UL) & ~3UL;
|
||||
|
||||
|
||||
struct Task *task;
|
||||
|
||||
|
||||
struct {
|
||||
struct Node ml_Node;
|
||||
UWORD ml_NumEntries;
|
||||
@ -142,12 +142,12 @@ struct Task *L_CreateTask(char * taskName, LONG priority, APTR funcEntry, ULONG
|
||||
|
||||
/**
|
||||
* sleep
|
||||
*
|
||||
*
|
||||
* @param seconds Seconds to wait
|
||||
* @param microseconds Microseconds to wait
|
||||
*/
|
||||
static void sleep(ULONG seconds, ULONG microseconds) {
|
||||
|
||||
|
||||
struct timerequest *tr = NULL;
|
||||
struct MsgPort *iomp = NULL;
|
||||
|
||||
@ -170,9 +170,9 @@ static void sleep(ULONG seconds, ULONG microseconds) {
|
||||
#if CDBOOT
|
||||
/**
|
||||
* FindCDFS
|
||||
*
|
||||
*
|
||||
* Look for a CD Filesystem in FileSystem.resource
|
||||
*
|
||||
*
|
||||
* @return BOOL True if CDFS found
|
||||
*/
|
||||
static BOOL FindCDFS() {
|
||||
@ -228,7 +228,7 @@ static void Cleanup(struct DeviceBase *dev) {
|
||||
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
|
||||
|
||||
struct IDEUnit *unit;
|
||||
|
||||
|
||||
if (SysBase->SoftVer >= 36) {
|
||||
ObtainSemaphoreShared(&dev->ulSem);
|
||||
} else {
|
||||
@ -260,7 +260,7 @@ static void Cleanup(struct DeviceBase *dev) {
|
||||
|
||||
/**
|
||||
* detectChannels
|
||||
*
|
||||
*
|
||||
* Detect how many IDE Channels this board has
|
||||
* @param cd Pointer to the ConfigDev struct for this board
|
||||
* @returns number of channels
|
||||
@ -283,7 +283,7 @@ static BYTE detectChannels(struct ConfigDev *cd) {
|
||||
// On a Matze TK the ROM goes away and the board can do 2 channels
|
||||
ULONG signature = 0;
|
||||
char *romFooter = (char *)cd->cd_BoardAddr + 0xFFF8;
|
||||
|
||||
|
||||
if (cd->cd_Rom.er_InitDiagVec & 1 || // If the board has an odd offset then add it
|
||||
cd->cd_Rom.er_InitDiagVec == 0x100) { // WinUAE AT-Bus 2008 has DiagVec @ 0x100 but Driver is on odd offset
|
||||
romFooter++;
|
||||
@ -301,8 +301,8 @@ static BYTE detectChannels(struct ConfigDev *cd) {
|
||||
}
|
||||
}
|
||||
|
||||
// Detect if there are 1 or 2 IDE channels on this board
|
||||
// 2 channel boards use the CS2 decode for the second channel
|
||||
// Detect if there are 1 or 2 IDE channels on this board
|
||||
// 2 channel boards use the CS2 decode for the second channel
|
||||
volatile UBYTE *status = cd->cd_BoardAddr + CHANNEL_0 + ata_reg_status;
|
||||
volatile UBYTE *alt_status = cd->cd_BoardAddr + CHANNEL_1 + ata_reg_altStatus;
|
||||
|
||||
@ -348,7 +348,7 @@ struct Library __attribute__((used, saveds)) * init_device(struct ExecBase *SysB
|
||||
dev->isOpen = FALSE;
|
||||
dev->numUnits = 0;
|
||||
dev->numTasks = 0;
|
||||
|
||||
|
||||
NewList((struct List *)&dev->units);
|
||||
InitSemaphore(&dev->ulSem);
|
||||
|
||||
@ -388,7 +388,7 @@ struct Library __attribute__((used, saveds)) * init_device(struct ExecBase *SysB
|
||||
Trace("Claiming board %08lx\n",(ULONG)cd->cd_BoardAddr);
|
||||
cd->cd_Flags &= ~(CDF_CONFIGME); // Claim the board
|
||||
cd->cd_Driver = dev;
|
||||
|
||||
|
||||
numBoards++;
|
||||
UBYTE channels = detectChannels(cd);
|
||||
|
||||
@ -457,12 +457,12 @@ will execute your Expunge at a time. */
|
||||
static BPTR __attribute__((used, saveds)) expunge(struct DeviceBase *dev asm("a6"))
|
||||
{
|
||||
Trace((CONST_STRPTR) "running expunge()\n");
|
||||
|
||||
|
||||
/**
|
||||
* Don't expunge
|
||||
*
|
||||
*
|
||||
* If expunged the driver will be gone until reboot
|
||||
*
|
||||
*
|
||||
* Also need to figure out how to kill the disk change int task cleanly before this can be enabled
|
||||
*/
|
||||
|
||||
@ -523,7 +523,7 @@ static void __attribute__((used, saveds)) open(struct DeviceBase *dev asm("a6"),
|
||||
*/
|
||||
UBYTE lun = unitnum / 10;
|
||||
unitnum = (unitnum % 10);
|
||||
|
||||
|
||||
if (lun != 0) {
|
||||
// No LUNs for IDE drives
|
||||
error = TDERR_BadUnitNum;
|
||||
@ -557,7 +557,7 @@ static void __attribute__((used, saveds)) open(struct DeviceBase *dev asm("a6"),
|
||||
error = TDERR_BadUnitNum;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
if (unit->itask->task == NULL || unit->itask->active == false) {
|
||||
error = IOERR_OPENFAIL;
|
||||
goto exit;
|
||||
@ -606,7 +606,7 @@ static void td_get_geometry(struct IOStdReq *ioreq) {
|
||||
// ioreq->io_Error = TDERR_DiskChanged;
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// Clear the geometry struct beforehand to make sure reserved / unused parts are zero
|
||||
memset(geometry,0,sizeof(struct DriveGeometry));
|
||||
|
||||
@ -690,7 +690,7 @@ static UWORD supported_commands[] =
|
||||
static void __attribute__((used, saveds)) begin_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
|
||||
{
|
||||
BYTE error = TDERR_NotSpecified;
|
||||
|
||||
|
||||
// Check that the IOReq has a sane Device / Unit pointer first
|
||||
if (ioreq_is_valid(dev,(struct IORequest *)ioreq)) {
|
||||
/* This makes sure that WaitIO() is guaranteed to work and
|
||||
|
||||
44
idetask.c
44
idetask.c
@ -22,9 +22,9 @@
|
||||
|
||||
/**
|
||||
* scsi_inquiry_ata
|
||||
*
|
||||
*
|
||||
* Handle SCSI-Direct INQUIRY commands for ATA devices
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param scsi_command Pointer to a SCSICmd struct
|
||||
*/
|
||||
@ -61,9 +61,9 @@ static BYTE scsi_inquiry_ata(struct IDEUnit *unit, struct SCSICmd *scsi_command)
|
||||
|
||||
/**
|
||||
* scsi_read_capaity_ata
|
||||
*
|
||||
*
|
||||
* Handle SCSI-Direct READ CAPACITY commands for ATA devices
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param scsi_command Pointer to a SCSICmd struct
|
||||
*/
|
||||
@ -98,9 +98,9 @@ static BYTE scsi_read_capaity_ata(struct IDEUnit *unit, struct SCSICmd *scsi_com
|
||||
|
||||
/**
|
||||
* scsi_mode_sense_ata
|
||||
*
|
||||
*
|
||||
* Handle SCSI-Direct MODE SENSE (6) commands for ATA devices
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param scsi_command Pointer to a SCSICmd struct
|
||||
*/
|
||||
@ -259,14 +259,14 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
}
|
||||
} else {
|
||||
// SCSI command handling for ATAPI Drives
|
||||
|
||||
|
||||
switch (scsi_command->scsi_Command[0]) {
|
||||
|
||||
case SCSI_CMD_INQUIRY:
|
||||
// Fudge the SCSI version number for CD/DVDs
|
||||
// Some software expects version 2 but ATAPI returns version 0
|
||||
error = atapi_packet(scsi_command,unit);
|
||||
|
||||
|
||||
if (error == 0 && unit->deviceType == DG_CDROM) {
|
||||
if ((scsi_command->scsi_Command[1] & 1) == 0) {
|
||||
((struct SCSI_Inquiry *)scsi_command->scsi_Data)->version = 2;
|
||||
@ -314,7 +314,7 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
Trace("Auto sense requested\n");
|
||||
// Request sense with retries
|
||||
for (int retry = 0; retry < 3; retry++) {
|
||||
if ((atapi_autosense(scsi_command,unit)) == 0)
|
||||
if ((atapi_autosense(scsi_command,unit)) == 0)
|
||||
break;
|
||||
|
||||
wait_us(unit->itask->tr,250000); // Wait 250ms before retrying
|
||||
@ -326,7 +326,7 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
// SCSI Command complete, handle any errors
|
||||
|
||||
Trace("SCSI: return: %02lx\n",error);
|
||||
|
||||
|
||||
scsi_command->scsi_CmdActual = scsi_command->scsi_CmdLength;
|
||||
|
||||
if (error != 0) {
|
||||
@ -342,7 +342,7 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
/**
|
||||
* diskchange_task
|
||||
*
|
||||
* This task periodically polls all removable devices for media changes and updates
|
||||
* This task periodically polls all removable devices for media changes and updates
|
||||
*/
|
||||
void __attribute__((noreturn)) diskchange_task () {
|
||||
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
|
||||
@ -386,7 +386,7 @@ void __attribute__((noreturn)) diskchange_task () {
|
||||
PutMsg(unit->itask->iomp,(struct Message *)ioreq); // Send request dirßsectly to the ide task
|
||||
WaitPort(iomp);
|
||||
GetMsg(iomp);
|
||||
|
||||
|
||||
present = (ioreq->io_Actual == 0); // Get current state
|
||||
|
||||
if (present != unit->mediumPresentPrev) {
|
||||
@ -398,7 +398,7 @@ void __attribute__((noreturn)) diskchange_task () {
|
||||
for (intreq = (struct IOStdReq *)unit->changeInts.mlh_Head;
|
||||
intreq->io_Message.mn_Node.ln_Succ != NULL;
|
||||
intreq = (struct IOStdReq *)intreq->io_Message.mn_Node.ln_Succ) {
|
||||
|
||||
|
||||
if (intreq->io_Data) {
|
||||
Cause(intreq->io_Data);
|
||||
}
|
||||
@ -424,7 +424,7 @@ die:
|
||||
if (TimerReq && TimerReq->tr_node.io_Device) CloseDevice((struct IORequest *)TimerReq);
|
||||
if (TimerReq) DeleteExtIO((struct IORequest *)TimerReq);
|
||||
if (TimerMP) DeletePort(TimerMP);
|
||||
|
||||
|
||||
RemTask(NULL);
|
||||
Wait(0);
|
||||
while (1);
|
||||
@ -432,16 +432,16 @@ die:
|
||||
|
||||
/**
|
||||
* init_units
|
||||
*
|
||||
*
|
||||
* Initialize the IDE Drives and add them to the dev->units list
|
||||
*
|
||||
*
|
||||
* @param itask Pointer to an IDETask struct
|
||||
* @returns number of drives foun
|
||||
*/
|
||||
static BYTE init_units(struct IDETask *itask) {
|
||||
UBYTE num_units = 0;
|
||||
struct DeviceBase *dev = itask->dev;
|
||||
|
||||
|
||||
for (BYTE i=0; i < 2; i++) {
|
||||
struct IDEUnit *unit = AllocMem(sizeof(struct IDEUnit),MEMF_ANY|MEMF_CLEAR);
|
||||
if (unit != NULL) {
|
||||
@ -500,9 +500,9 @@ static BYTE init_units(struct IDETask *itask) {
|
||||
return num_units;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* cleanup
|
||||
*
|
||||
*
|
||||
* Clean up after the task, freeing resources etc back to the system
|
||||
*/
|
||||
static void cleanup(struct IDETask *itask) {
|
||||
@ -673,7 +673,7 @@ transfer:
|
||||
error = TDERR_DiskChanged;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
blockShift = ((struct IDEUnit *)ioreq->io_Unit)->blockShift;
|
||||
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) >> blockShift);
|
||||
count = (ioreq->io_Length >> blockShift);
|
||||
@ -750,10 +750,10 @@ transfer:
|
||||
|
||||
/**
|
||||
* direct_changestate
|
||||
*
|
||||
*
|
||||
* Send a TD_CHANGESTATE request directly to the IDE Task
|
||||
* This will have the side-effect of updating the presence status and geometry of the unit if the status changed
|
||||
*
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param dev Pointer to DeviceBase
|
||||
* @returns -1 on error, 0 if disk present, >0 if no disk
|
||||
|
||||
@ -172,7 +172,7 @@ bool CheckPVD(struct IOStdReq *ior) {
|
||||
if (ior->io_Actual < 2048) break;
|
||||
|
||||
// Check ISO ID String & for PVD Version & Type code
|
||||
if ((strncmp(iso_id,id_string,5) == 0) && buf[0] == 1 && buf[6] == 1) {
|
||||
if ((strncmp(iso_id,id_string,5) == 0) && buf[0] == 1 && buf[6] == 1) {
|
||||
if (strncmp(sys_id_1,system_id,strlen(sys_id_1)) == 0 || strncmp(sys_id_2,system_id,strlen(sys_id_2) == 0)) {
|
||||
ret = true; // CDTV or AMIGA BOOT
|
||||
} else {
|
||||
@ -616,7 +616,7 @@ static struct FileSysEntry *FSHDProcess(struct FileSysHeaderBlock *fshb, ULONG d
|
||||
const char resourceName[] = "FileSystem.resource";
|
||||
|
||||
Forbid();
|
||||
|
||||
|
||||
struct FileSysResource *fsr = NULL;
|
||||
fsr = OpenResource(FSRNAME);
|
||||
if (!fsr) {
|
||||
|
||||
16
scsi.c
16
scsi.c
@ -19,14 +19,14 @@
|
||||
|
||||
/**
|
||||
* scsi_sense
|
||||
*
|
||||
*
|
||||
* Populate sense data based on the error returned by the ATA functions
|
||||
*
|
||||
*
|
||||
* @param command A pointer to a SCSICmd
|
||||
* @param info Sense data Info long
|
||||
* @param specific Sense data Specific long
|
||||
* @param error Error code returned from ata_transfer
|
||||
*
|
||||
*
|
||||
*/
|
||||
void scsi_sense(struct SCSICmd* command, ULONG info, ULONG specific, BYTE error)
|
||||
{
|
||||
@ -77,11 +77,11 @@ void scsi_sense(struct SCSICmd* command, ULONG info, ULONG specific, BYTE error)
|
||||
|
||||
/**
|
||||
* MakeSCSICmd
|
||||
*
|
||||
*
|
||||
* Creates an new SCSICmd struct and CDB
|
||||
*
|
||||
*
|
||||
* @param cdbSize Size of CDB to create
|
||||
* @returns Pointer to an initialized SCSICmd struct
|
||||
* @returns Pointer to an initialized SCSICmd struct
|
||||
*/
|
||||
struct SCSICmd * MakeSCSICmd(ULONG cdbSize) {
|
||||
UBYTE *cdb = NULL;
|
||||
@ -107,9 +107,9 @@ struct SCSICmd * MakeSCSICmd(ULONG cdbSize) {
|
||||
|
||||
/**
|
||||
* DeleteSCSICmd
|
||||
*
|
||||
*
|
||||
* Delete a SCSICmd and its CDB
|
||||
*
|
||||
*
|
||||
* @param cmd Pointer to a SCSICmd struct to be deleted
|
||||
*/
|
||||
void DeleteSCSICmd(struct SCSICmd *cmd) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user