mirror of
https://github.com/LIV2/lide.device.git
synced 2025-12-06 00:32:45 +00:00
Compare commits
4 Commits
7a3fbbd49f
...
c7f8340f5a
| Author | SHA1 | Date | |
|---|---|---|---|
| c7f8340f5a | |||
| e5fad0b4fd | |||
| c32aeef94c | |||
| 83f74a8cb1 |
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@ -17,7 +17,6 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
submodules: true
|
||||
|
||||
- name: Build
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "mounter"]
|
||||
path = mounter
|
||||
url = https://github.com/LIV2/mounter
|
||||
4
Makefile
4
Makefile
@ -11,7 +11,7 @@ export BUILD_DATE
|
||||
export GIT_REF
|
||||
|
||||
CC=m68k-amigaos-gcc
|
||||
CFLAGS+=-nostartfiles -nostdlib -mcpu=68000 -Wall -Wno-multichar -Wno-pointer-sign -Wno-attributes -Wno-unused-value -s -Os -fomit-frame-pointer -DCDBOOT=1 -DNO_RDBLAST=1
|
||||
CFLAGS+=-nostartfiles -nostdlib -mcpu=68000 -Wall -Wno-multichar -Wno-pointer-sign -Wno-unused-value -s -Os -fomit-frame-pointer -DCDBOOT=1 -DNO_RDBLAST=1
|
||||
CFLAGS+=-DGIT_REF=$(GIT_REF) -DBUILD_DATE=$(BUILD_DATE)
|
||||
LDFLAGS=-lgcc -lc
|
||||
AS=m68k-amigaos-as
|
||||
@ -71,7 +71,7 @@ OBJ = device.o \
|
||||
scsi.o \
|
||||
idetask.o \
|
||||
lide_alib.o \
|
||||
mounter.o \
|
||||
mounter/mounter.o \
|
||||
debug.o
|
||||
|
||||
ASMOBJ = endskip.o
|
||||
|
||||
76
ata.c
76
ata.c
@ -34,7 +34,7 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
static void __attribute__((always_inline)) ata_status_reg_delay(struct IDEUnit *unit) {
|
||||
static void ata_status_reg_delay(struct IDEUnit *unit) {
|
||||
asm volatile (
|
||||
".rep 4 \n\t"
|
||||
"tst.l (%0) \n\t" // Use tst.l so we don't need to save/restore some other register
|
||||
@ -68,7 +68,7 @@ static void ata_save_error(struct IDEUnit *unit) {
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns True if error is indicated
|
||||
*/
|
||||
static bool __attribute__((always_inline)) ata_check_error(struct IDEUnit *unit) {
|
||||
static bool ata_check_error(struct IDEUnit *unit) {
|
||||
return (*unit->drive.status_command & (ata_flag_error | ata_flag_df));
|
||||
}
|
||||
|
||||
@ -160,7 +160,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 (!unit->flags.lba) select &= ~(0x40);
|
||||
|
||||
if (*shadowDevHead == select) {
|
||||
return false;
|
||||
@ -193,7 +193,7 @@ 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
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
ata_select(unit,drvSel,false);
|
||||
|
||||
@ -342,41 +342,39 @@ void ata_set_xfer(struct IDEUnit *unit, enum xfer method) {
|
||||
*
|
||||
* Initialize a unit, check if it is there and responding
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @param base Base address of the drive registers
|
||||
* @returns false on error
|
||||
*/
|
||||
bool ata_init_unit(struct IDEUnit *unit) {
|
||||
bool ata_init_unit(struct IDEUnit *unit, void *base) {
|
||||
struct ExecBase *SysBase = unit->SysBase;
|
||||
|
||||
unit->cylinders = 0;
|
||||
unit->heads = 0;
|
||||
unit->sectorsPerTrack = 0;
|
||||
unit->blockSize = 0;
|
||||
unit->present = false;
|
||||
unit->mediumPresent = false;
|
||||
unit->flags.present = false;
|
||||
unit->flags.mediumPresent = false;
|
||||
|
||||
ULONG offset;
|
||||
UWORD *buf;
|
||||
bool dev_found = false;
|
||||
|
||||
offset = (unit->channel == 0) ? CHANNEL_0 : CHANNEL_1;
|
||||
unit->drive.data = (UWORD*) (base + ata_reg_data);
|
||||
unit->drive.error_features = (UBYTE*) (base + ata_reg_error);
|
||||
unit->drive.sectorCount = (UBYTE*) (base + ata_reg_sectorCount);
|
||||
unit->drive.lbaLow = (UBYTE*) (base + ata_reg_lbaLow);
|
||||
unit->drive.lbaMid = (UBYTE*) (base + ata_reg_lbaMid);
|
||||
unit->drive.lbaHigh = (UBYTE*) (base + ata_reg_lbaHigh);
|
||||
unit->drive.devHead = (UBYTE*) (base + ata_reg_devHead);
|
||||
unit->drive.status_command = (UBYTE*) (base + 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
|
||||
*unit->shadowDevHead = *unit->drive.devHead = (unit->flags.primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
enum xfer method = ata_autoselect_xfer(unit);
|
||||
ata_set_xfer(unit,method);
|
||||
|
||||
for (int i=0; i<(8*NEXT_REG); i+=NEXT_REG) {
|
||||
// Check if the bus is floating (D7/6 pulled-up with resistors)
|
||||
if ((i != ata_reg_devHead) && (*((volatile UBYTE *)unit->cd->cd_BoardAddr + offset + i) & 0xC0) != 0xC0) {
|
||||
if ((i != ata_reg_devHead) && (*((volatile UBYTE *)base + i) & 0xC0) != 0xC0) {
|
||||
dev_found = true;
|
||||
Trace("INIT: Unit base: %08lx; Drive base %08lx\n",unit, unit->drive);
|
||||
break;
|
||||
@ -395,20 +393,20 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
if (ata_identify(unit,buf) == true) {
|
||||
Info("INIT: ATA Drive found!\n");
|
||||
|
||||
unit->lba = (buf[ata_identify_capabilities] & ata_capability_lba) != 0;
|
||||
unit->flags.lba = (buf[ata_identify_capabilities] & ata_capability_lba) != 0;
|
||||
unit->cylinders = buf[ata_identify_cylinders];
|
||||
unit->heads = buf[ata_identify_heads];
|
||||
unit->sectorsPerTrack = buf[ata_identify_sectors];
|
||||
unit->blockSize = 512;
|
||||
unit->logicalSectors = buf[ata_identify_logical_sectors+1] << 16 | buf[ata_identify_logical_sectors];
|
||||
unit->blockShift = 0;
|
||||
unit->mediumPresent = true;
|
||||
unit->flags.mediumPresent = true;
|
||||
unit->multipleCount = buf[ata_identify_multiple] & 0xFF;
|
||||
|
||||
if (unit->multipleCount > 0 && (ata_set_multiple(unit,unit->multipleCount) == 0)) {
|
||||
unit->xferMultiple = true;
|
||||
unit->flags.xferMultiple = true;
|
||||
} else {
|
||||
unit->xferMultiple = false;
|
||||
unit->flags.xferMultiple = false;
|
||||
unit->multipleCount = 1;
|
||||
}
|
||||
|
||||
@ -420,13 +418,13 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
goto ident_failed;
|
||||
}
|
||||
|
||||
unit->lba48 = true;
|
||||
unit->flags.lba48 = true;
|
||||
Info("INIT: Drive supports LBA48 mode \n");
|
||||
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) {
|
||||
} else if (unit->flags.lba == true) {
|
||||
// LBA-28 up to 127GB
|
||||
unit->write_taskfile = &write_taskfile_lba;
|
||||
|
||||
@ -464,7 +462,7 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
Info("INIT: ATAPI Drive found!\n");
|
||||
|
||||
unit->deviceType = (buf[0] >> 8) & 0x1F;
|
||||
unit->atapi = true;
|
||||
unit->flags.atapi = true;
|
||||
|
||||
atapi_test_unit_ready(unit,true); // Clear the Unit attention check condition
|
||||
} else {
|
||||
@ -476,14 +474,14 @@ ident_failed:
|
||||
}
|
||||
}
|
||||
|
||||
if (unit->atapi == false && unit->blockSize == 0) {
|
||||
if (unit->flags.atapi == false && unit->blockSize == 0) {
|
||||
Warn("INIT: Error! blockSize is 0\n");
|
||||
if (buf) FreeMem(buf,512);
|
||||
return false;
|
||||
}
|
||||
|
||||
Info("INIT: Blockshift: %ld\n",unit->blockShift);
|
||||
unit->present = true;
|
||||
unit->flags.present = true;
|
||||
|
||||
Info("INIT: LBAs %ld Blocksize: %ld\n",unit->logicalSectors,unit->blockSize);
|
||||
|
||||
@ -500,7 +498,7 @@ ident_failed:
|
||||
* @return non-zero on error
|
||||
*/
|
||||
bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple) {
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0; // Select drive
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
ata_select(unit,drvSel,true);
|
||||
|
||||
@ -552,10 +550,10 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
UBYTE multipleCount = unit->multipleCount;
|
||||
volatile void *dataRegister = unit->drive.data;
|
||||
|
||||
if (unit->lba48) {
|
||||
if (unit->flags.lba48) {
|
||||
command = ATA_CMD_READ_MULTIPLE_EXT;
|
||||
} else {
|
||||
command = (unit->xferMultiple) ? ATA_CMD_READ_MULTIPLE : ATA_CMD_READ;
|
||||
command = (unit->flags.xferMultiple) ? ATA_CMD_READ_MULTIPLE : ATA_CMD_READ;
|
||||
}
|
||||
|
||||
ata_xfer_func ata_xfer;
|
||||
@ -567,7 +565,7 @@ BYTE ata_read(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
ata_xfer = unit->read_fast;
|
||||
}
|
||||
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0;
|
||||
|
||||
ata_select(unit,drvSel,true);
|
||||
|
||||
@ -641,10 +639,10 @@ BYTE ata_write(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
UBYTE multipleCount = unit->multipleCount;
|
||||
volatile void *dataRegister = unit->drive.data;
|
||||
|
||||
if (unit->lba48) {
|
||||
if (unit->flags.lba48) {
|
||||
command = ATA_CMD_WRITE_MULTIPLE_EXT;
|
||||
} else {
|
||||
command = (unit->xferMultiple) ? ATA_CMD_WRITE_MULTIPLE : ATA_CMD_WRITE;
|
||||
command = (unit->flags.xferMultiple) ? ATA_CMD_WRITE_MULTIPLE : ATA_CMD_WRITE;
|
||||
}
|
||||
|
||||
ata_xfer_func ata_xfer;
|
||||
@ -656,7 +654,7 @@ BYTE ata_write(void *buffer, ULONG lba, ULONG count, struct IDEUnit *unit) {
|
||||
ata_xfer = unit->write_fast;
|
||||
}
|
||||
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0;
|
||||
|
||||
ata_select(unit,drvSel,true);
|
||||
|
||||
@ -760,7 +758,7 @@ static BYTE write_taskfile_chs(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||
return HFERR_SelTimeout;
|
||||
|
||||
devHead = ((unit->primary) ? 0xA0 : 0xB0) | (head & 0x0F);
|
||||
devHead = ((unit->flags.primary) ? 0xA0 : 0xB0) | (head & 0x0F);
|
||||
|
||||
*unit->shadowDevHead = devHead;
|
||||
*unit->drive.devHead = devHead;
|
||||
@ -786,7 +784,7 @@ static BYTE write_taskfile_lba(struct IDEUnit *unit, UBYTE command, ULONG lba, U
|
||||
if (!ata_wait_ready(unit,ATA_RDY_WAIT_COUNT))
|
||||
return HFERR_SelTimeout;
|
||||
|
||||
devHead = ((unit->primary) ? 0xE0 : 0xF0) | ((lba >> 24) & 0x0F);
|
||||
devHead = ((unit->flags.primary) ? 0xE0 : 0xF0) | ((lba >> 24) & 0x0F);
|
||||
|
||||
*unit->shadowDevHead = devHead;
|
||||
*unit->drive.devHead = devHead;
|
||||
@ -920,7 +918,7 @@ BYTE scsi_ata_passthrough(struct IDEUnit *unit, struct SCSICmd *cmd) {
|
||||
|
||||
count += (count & 1); // Ensure byte count is even
|
||||
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0;
|
||||
|
||||
ata_select(unit,drvSel,true);
|
||||
|
||||
|
||||
2
ata.h
2
ata.h
@ -104,7 +104,7 @@ enum xfer_dir {
|
||||
#define ATA_RDY_WAIT_COUNT (ATA_RDY_WAIT_S * 1000 * (1000 / ATA_RDY_WAIT_LOOP_US))
|
||||
|
||||
|
||||
bool ata_init_unit(struct IDEUnit *);
|
||||
bool ata_init_unit(struct IDEUnit *unit, void *base);
|
||||
bool ata_select(struct IDEUnit *unit, UBYTE select, bool wait);
|
||||
bool ata_identify(struct IDEUnit *, UWORD *);
|
||||
bool ata_set_multiple(struct IDEUnit *unit, BYTE multiple);
|
||||
|
||||
16
atapi.c
16
atapi.c
@ -31,7 +31,7 @@
|
||||
*
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
*/
|
||||
static void __attribute__((always_inline)) atapi_status_reg_delay() {
|
||||
static void atapi_status_reg_delay() {
|
||||
asm volatile (
|
||||
"tst.b 0xBFE001"
|
||||
);
|
||||
@ -158,7 +158,7 @@ static bool atapi_check_ir(struct IDEUnit *unit, UBYTE mask, UBYTE value, UWORD
|
||||
* @param unit Pointer to an IDEUnit struct
|
||||
* @returns True if error is indicated
|
||||
*/
|
||||
static bool __attribute__((always_inline)) atapi_check_error(struct IDEUnit *unit) {
|
||||
static bool atapi_check_error(struct IDEUnit *unit) {
|
||||
atapi_status_reg_delay();
|
||||
return (*unit->drive.status_command & (ata_flag_error | ata_flag_df));
|
||||
}
|
||||
@ -206,7 +206,7 @@ bool atapi_check_signature(struct IDEUnit *unit) {
|
||||
*/
|
||||
bool atapi_identify(struct IDEUnit *unit, UWORD *buffer) {
|
||||
|
||||
UBYTE drvSel = (unit->primary) ? 0xE0 : 0xF0; // Select drive
|
||||
UBYTE drvSel = (unit->flags.primary) ? 0xE0 : 0xF0; // Select drive
|
||||
|
||||
// Only update the devHead register if absolutely necessary to save time
|
||||
ata_select(unit,drvSel,false);
|
||||
@ -410,7 +410,7 @@ BYTE atapi_packet(struct SCSICmd *cmd, struct IDEUnit *unit) {
|
||||
|
||||
cmd->scsi_Actual = 0;
|
||||
|
||||
UBYTE drvSelHead = ((unit->primary) ? 0xE0 : 0xF0);
|
||||
UBYTE drvSelHead = ((unit->flags.primary) ? 0xE0 : 0xF0);
|
||||
|
||||
// Only update the devHead register if absolutely necessary to save time
|
||||
ata_select(unit,drvSelHead,true);
|
||||
@ -1119,14 +1119,14 @@ BYTE atapi_check_wp(struct IDEUnit *unit) {
|
||||
*/
|
||||
bool atapi_update_presence(struct IDEUnit *unit, bool present) {
|
||||
bool ret = false;
|
||||
if (present && unit->mediumPresent == false) {
|
||||
if (present && unit->flags.mediumPresent == false) {
|
||||
unit->changeCount++;
|
||||
unit->mediumPresent = true;
|
||||
unit->flags.mediumPresent = true;
|
||||
atapi_get_capacity(unit);
|
||||
ret = true;
|
||||
} else if (!present && unit->mediumPresent == true) {
|
||||
} else if (!present && unit->flags.mediumPresent == true) {
|
||||
unit->changeCount++;
|
||||
unit->mediumPresent = false;
|
||||
unit->flags.mediumPresent = false;
|
||||
unit->logicalSectors = 0;
|
||||
unit->blockShift = 0;
|
||||
unit->blockSize = 0;
|
||||
|
||||
96
device.c
96
device.c
@ -22,9 +22,9 @@
|
||||
#include "idetask.h"
|
||||
#include "newstyle.h"
|
||||
#include "td64.h"
|
||||
#include "mounter.h"
|
||||
#include "debug.h"
|
||||
#include "lide_alib.h"
|
||||
#include "mounter/mounter.h"
|
||||
|
||||
#ifdef NO_AUTOCONFIG
|
||||
extern UBYTE bootblock, bootblock_end;
|
||||
@ -236,22 +236,6 @@ static void Cleanup(struct DeviceBase *dev) {
|
||||
Info("Cleaning up...\n");
|
||||
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
|
||||
char *devName = dev->lib.lib_Node.ln_Name;
|
||||
struct IDEUnit *unit;
|
||||
|
||||
if (SysBase->LibNode.lib_Version >= 36) {
|
||||
ObtainSemaphoreShared(&dev->ulSem);
|
||||
} else {
|
||||
ObtainSemaphore(&dev->ulSem);
|
||||
}
|
||||
|
||||
for (unit = (struct IDEUnit *)dev->units.mlh_Head;
|
||||
unit->mn_Node.mln_Succ != NULL;
|
||||
unit = (struct IDEUnit *)unit->mn_Node.mln_Succ)
|
||||
{
|
||||
unit->cd->cd_Flags |= CDF_CONFIGME;
|
||||
}
|
||||
|
||||
ReleaseSemaphore(&dev->ulSem);
|
||||
|
||||
if (dev->ExpansionBase) CloseLibrary((struct Library *)dev->ExpansionBase);
|
||||
|
||||
@ -261,6 +245,7 @@ static void Cleanup(struct DeviceBase *dev) {
|
||||
itask->mn_Node.mln_Succ != NULL;
|
||||
itask = (struct IDETask *)itask->mn_Node.mln_Succ)
|
||||
{
|
||||
itask->cd->cd_Flags |= CDF_CONFIGME;
|
||||
FreeMem(itask,sizeof(struct IDETask));
|
||||
}
|
||||
|
||||
@ -339,7 +324,7 @@ static BYTE detectChannels(struct ConfigDev *cd) {
|
||||
*
|
||||
* Scan for drives and initialize the driver if any are found
|
||||
*/
|
||||
struct Library __attribute__((used, saveds)) * init_device(struct ExecBase *SysBase asm("a6"), BPTR seg_list asm("a0"), struct DeviceBase *dev asm("d0"))
|
||||
struct Library * init_device(struct ExecBase *SysBase asm("a6"), BPTR seg_list asm("a0"), struct DeviceBase *dev asm("d0"))
|
||||
{
|
||||
dev->SysBase = SysBase;
|
||||
Trace("Init dev, base: %08lx\n",dev);
|
||||
@ -495,7 +480,7 @@ struct Library __attribute__((used, saveds)) * init_device(struct ExecBase *SysB
|
||||
* IMPORTANT: because Expunge is called from the memory allocator,
|
||||
* it may NEVER Wait() or otherwise take long time to complete.
|
||||
*/
|
||||
static BPTR __attribute__((used, saveds)) expunge(struct DeviceBase *dev asm("a6"))
|
||||
static BPTR expunge(struct DeviceBase *dev asm("a6"))
|
||||
{
|
||||
Trace((CONST_STRPTR) "running expunge()\n");
|
||||
|
||||
@ -516,7 +501,7 @@ static BPTR __attribute__((used, saveds)) expunge(struct DeviceBase *dev asm("a6
|
||||
* This call is guaranteed to be single-threaded; only one task
|
||||
* will execute your Open at a time.
|
||||
*/
|
||||
static void __attribute__((used, saveds)) open(struct DeviceBase *dev asm("a6"), struct IORequest *ioreq asm("a1"), ULONG unitnum asm("d0"), ULONG flags asm("d1"))
|
||||
static void open(struct DeviceBase *dev asm("a6"), struct IORequest *ioreq asm("a1"), ULONG unitnum asm("d0"), ULONG flags asm("d1"))
|
||||
{
|
||||
struct ExecBase *SysBase = dev->SysBase;
|
||||
struct IDEUnit *unit = NULL;
|
||||
@ -564,7 +549,7 @@ static void __attribute__((used, saveds)) open(struct DeviceBase *dev asm("a6"),
|
||||
|
||||
ReleaseSemaphore(&dev->ulSem);
|
||||
|
||||
if (found == false || unit->present == false) {
|
||||
if (found == false || unit->flags.present == false) {
|
||||
error = TDERR_BadUnitNum;
|
||||
goto exit;
|
||||
}
|
||||
@ -623,7 +608,7 @@ static void td_get_geometry(struct IOStdReq *ioreq) {
|
||||
geometry->dg_TrackSectors = unit->sectorsPerTrack;
|
||||
geometry->dg_BufMemType = MEMF_PUBLIC;
|
||||
geometry->dg_DeviceType = unit->deviceType;
|
||||
geometry->dg_Flags = (unit->atapi) ? DGF_REMOVABLE : 0;
|
||||
geometry->dg_Flags = (unit->flags.atapi) ? DGF_REMOVABLE : 0;
|
||||
|
||||
ioreq->io_Actual = sizeof(struct DriveGeometry);
|
||||
}
|
||||
@ -635,7 +620,7 @@ static void td_get_geometry(struct IOStdReq *ioreq) {
|
||||
* This call is guaranteed to be single-threaded; only one task
|
||||
* will execute your Close at a time.
|
||||
*/
|
||||
static BPTR __attribute__((used, saveds)) close(struct DeviceBase *dev asm("a6"), struct IORequest *ioreq asm("a1"))
|
||||
static BPTR close(struct DeviceBase *dev asm("a6"), struct IORequest *ioreq asm("a1"))
|
||||
{
|
||||
if (ioreq_is_valid(dev,ioreq)) {
|
||||
struct IDEUnit *unit = (struct IDEUnit *)ioreq->io_Unit;
|
||||
@ -696,7 +681,7 @@ const UWORD supported_commands[] =
|
||||
*
|
||||
* Handle immediate requests and send any others to ide_task
|
||||
*/
|
||||
static void __attribute__((used, saveds)) begin_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
|
||||
static void begin_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
|
||||
{
|
||||
struct ExecBase *SysBase = dev->SysBase;
|
||||
|
||||
@ -806,7 +791,7 @@ static void __attribute__((used, saveds)) begin_io(struct DeviceBase *dev asm("a
|
||||
case CMD_START:
|
||||
case CMD_STOP:
|
||||
// Don't pass it to the task if it's not an atapi device
|
||||
if (!unit->atapi) {
|
||||
if (!unit->flags.atapi) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
@ -879,7 +864,7 @@ sendToTask:
|
||||
*
|
||||
* Abort io request
|
||||
*/
|
||||
static ULONG __attribute__((used, saveds)) abort_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
|
||||
static ULONG abort_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
|
||||
{
|
||||
struct ExecBase *SysBase = dev->SysBase;
|
||||
|
||||
@ -1002,68 +987,41 @@ void TweakBootList(struct ExecBase *SysBase) {
|
||||
*
|
||||
* Create the device and add it to the system if init_device succeeds
|
||||
*/
|
||||
static struct Library __attribute__((used)) * init(BPTR seg_list asm("a0"))
|
||||
static struct Library * init(BPTR seg_list asm("a0"))
|
||||
{
|
||||
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
|
||||
Info("Init driver.\n");
|
||||
struct MountStruct *ms = NULL;
|
||||
struct DeviceBase *mydev = (struct DeviceBase *)MakeLibrary((ULONG *)&device_vectors, // Vectors
|
||||
NULL, // InitStruct data
|
||||
(APTR)init_device, // Init function
|
||||
sizeof(struct DeviceBase), // Library data size
|
||||
seg_list); // Segment list
|
||||
|
||||
BOOL CDBoot = FindCDFS();
|
||||
|
||||
if (mydev != NULL) {
|
||||
ULONG ms_size = (sizeof(struct MountStruct) + (MAX_UNITS * sizeof(struct UnitStruct)));
|
||||
Info("Add Device.\n");
|
||||
AddDevice((struct Device *)mydev);
|
||||
|
||||
if ((ms = AllocMem(ms_size,MEMF_ANY|MEMF_PUBLIC)) == NULL) goto done;
|
||||
struct IDETask *itask = (struct IDETask *)mydev->ideTasks.mlh_Head;
|
||||
|
||||
ms->deviceName = mydev->lib.lib_Node.ln_Name;
|
||||
ms->creatorName = NULL;
|
||||
ms->numUnits = 0;
|
||||
ms->SysBase = SysBase;
|
||||
if (!itask->mn_Node.mln_Succ) goto done;
|
||||
|
||||
UWORD index = 0;
|
||||
#if CDBOOT
|
||||
BOOL CDBoot = FindCDFS();
|
||||
#endif
|
||||
struct IDEUnit *unit;
|
||||
struct MountStruct ms = {
|
||||
.deviceName = mydev->lib.lib_Node.ln_Name,
|
||||
.creatorName = mydev->lib.lib_Node.ln_Name,
|
||||
.SysBase = SysBase,
|
||||
.cdBoot = CDBoot,
|
||||
.luns = false,
|
||||
.slowSpinup = false,
|
||||
.ignoreLast = true,
|
||||
.configDev = itask->cd
|
||||
};
|
||||
|
||||
if (SysBase->LibNode.lib_Version >= 36) {
|
||||
ObtainSemaphoreShared(&mydev->ulSem);
|
||||
} else {
|
||||
ObtainSemaphore(&mydev->ulSem);
|
||||
}
|
||||
|
||||
for (unit = (struct IDEUnit *)mydev->units.mlh_Head;
|
||||
unit->mn_Node.mln_Succ != NULL;
|
||||
unit = (struct IDEUnit *)unit->mn_Node.mln_Succ)
|
||||
{
|
||||
if (unit->present == true) {
|
||||
#if CDBOOT
|
||||
// If CDFS not resident don't bother adding the CDROM to the mountlist
|
||||
if (unit->deviceType == DG_CDROM && !CDBoot) continue;
|
||||
#endif
|
||||
ms->Units[index].unitNum = unit->unitNum;
|
||||
ms->Units[index].configDev = unit->cd;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
ms->numUnits = index;
|
||||
|
||||
ReleaseSemaphore(&mydev->ulSem);
|
||||
if (ms->numUnits > 0) {
|
||||
MountDrive(ms);
|
||||
}
|
||||
|
||||
FreeMem(ms,ms_size);
|
||||
MountDrive(&ms);
|
||||
|
||||
if (!seg_list) // Only tweak if we're in boot
|
||||
TweakBootList(SysBase);
|
||||
|
||||
}
|
||||
done:
|
||||
return (struct Library *)mydev;
|
||||
|
||||
21
device.h
21
device.h
@ -44,8 +44,6 @@ struct Drive {
|
||||
|
||||
struct IDEUnit {
|
||||
struct MinNode mn_Node;
|
||||
struct Unit io_unit;
|
||||
struct ConfigDev *cd;
|
||||
struct ExecBase *SysBase;
|
||||
struct IDETask *itask;
|
||||
struct Drive drive;
|
||||
@ -58,17 +56,8 @@ struct IDEUnit {
|
||||
volatile UBYTE *shadowDevHead;
|
||||
volatile void *changeInt;
|
||||
UBYTE unitNum;
|
||||
UBYTE channel;
|
||||
UBYTE deviceType;
|
||||
UBYTE last_error[6];
|
||||
bool primary;
|
||||
bool present;
|
||||
bool atapi;
|
||||
bool mediumPresent;
|
||||
bool mediumPresentPrev;
|
||||
bool xferMultiple;
|
||||
bool lba;
|
||||
bool lba48;
|
||||
UWORD openCount;
|
||||
UWORD changeCount;
|
||||
UWORD heads;
|
||||
@ -79,6 +68,16 @@ struct IDEUnit {
|
||||
ULONG logicalSectors;
|
||||
struct MinList changeInts;
|
||||
UBYTE multipleCount;
|
||||
struct {
|
||||
unsigned char primary : 1;
|
||||
unsigned char present : 1;
|
||||
unsigned char atapi : 1;
|
||||
unsigned char mediumPresent : 1;
|
||||
unsigned char mediumPresentPrev : 1;
|
||||
unsigned char xferMultiple : 1;
|
||||
unsigned char lba : 1;
|
||||
unsigned char lba48 : 1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
struct DeviceBase {
|
||||
|
||||
46
idetask.c
46
idetask.c
@ -267,7 +267,7 @@ static BYTE handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
|
||||
Trace("SCSI: Command %lx\n",*scsi_command->scsi_Command);
|
||||
|
||||
if (unit->atapi == false)
|
||||
if (unit->flags.atapi == false)
|
||||
{
|
||||
// Non-ATAPI drives - Translate SCSI CMD to ATA
|
||||
switch (scsi_command->scsi_Command[0]) {
|
||||
@ -422,22 +422,21 @@ static BYTE init_units(struct IDETask *itask) {
|
||||
|
||||
for (BYTE i=0; i < 2; i++) {
|
||||
struct IDEUnit *unit = AllocMem(sizeof(struct IDEUnit),MEMF_ANY|MEMF_CLEAR);
|
||||
|
||||
if (unit != NULL) {
|
||||
// Setup each unit structure
|
||||
unit->itask = itask;
|
||||
unit->unitNum = ((itask->boardNum * 4) + (itask->channel << 1) + i);
|
||||
unit->SysBase = SysBase;
|
||||
unit->cd = itask->cd;
|
||||
unit->primary = ((i%2) == 1) ? false : true;
|
||||
unit->channel = itask->channel;
|
||||
unit->flags.primary = ((i%2) == 1) ? false : true;
|
||||
unit->openCount = 0;
|
||||
unit->changeCount = 1;
|
||||
unit->deviceType = DG_DIRECT_ACCESS;
|
||||
unit->mediumPresent = false;
|
||||
unit->mediumPresentPrev = false;
|
||||
unit->present = false;
|
||||
unit->atapi = false;
|
||||
unit->xferMultiple = false;
|
||||
unit->flags.mediumPresent = false;
|
||||
unit->flags.mediumPresentPrev = false;
|
||||
unit->flags.present = false;
|
||||
unit->flags.atapi = false;
|
||||
unit->flags.xferMultiple = false;
|
||||
unit->multipleCount = 0;
|
||||
unit->shadowDevHead = &itask->shadowDevHead;
|
||||
*unit->shadowDevHead = 0;
|
||||
@ -449,8 +448,11 @@ static BYTE init_units(struct IDETask *itask) {
|
||||
|
||||
Warn("testing unit %ld\n",unit->unitNum);
|
||||
|
||||
if (ata_init_unit(unit)) {
|
||||
if (unit->atapi) itask->hasRemovables = true;
|
||||
void *base = itask->cd->cd_BoardAddr;
|
||||
base += (itask->channel == 0) ? CHANNEL_0 : CHANNEL_1;
|
||||
|
||||
if (ata_init_unit(unit,base)) {
|
||||
if (unit->flags.atapi) itask->hasRemovables = true;
|
||||
num_units++;
|
||||
itask->dev->numUnits++;
|
||||
dev->highestUnit = unit->unitNum;
|
||||
@ -524,11 +526,11 @@ static void diskchange_check(struct IDETask *itask) {
|
||||
unit->mn_Node.mln_Succ != NULL;
|
||||
unit = (struct IDEUnit *)unit->mn_Node.mln_Succ)
|
||||
{
|
||||
if (unit->present && unit->atapi) {
|
||||
if (unit->flags.present && unit->flags.atapi) {
|
||||
|
||||
present = (atapi_test_unit_ready(unit,true) == 0) ? true : false;
|
||||
|
||||
if (present != unit->mediumPresentPrev) {
|
||||
if (present != unit->flags.mediumPresentPrev) {
|
||||
|
||||
Forbid();
|
||||
if (unit->changeInt != NULL)
|
||||
@ -545,7 +547,7 @@ static void diskchange_check(struct IDETask *itask) {
|
||||
Permit();
|
||||
}
|
||||
|
||||
unit->mediumPresentPrev = present;
|
||||
unit->flags.mediumPresentPrev = present;
|
||||
|
||||
|
||||
}
|
||||
@ -585,23 +587,23 @@ static void process_ioreq(struct IDETask *itask, struct IOStdReq *ioreq) {
|
||||
return;
|
||||
|
||||
case CMD_START:
|
||||
if (unit->atapi) {
|
||||
if (unit->flags.atapi) {
|
||||
error = atapi_start_stop_unit(unit,true,false,false);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STOP:
|
||||
if (unit->atapi) {
|
||||
if (unit->flags.atapi) {
|
||||
error = atapi_start_stop_unit(unit,false,false,false);
|
||||
}
|
||||
break;
|
||||
|
||||
case TD_EJECT:
|
||||
if (!unit->atapi) {
|
||||
if (!unit->flags.atapi) {
|
||||
error = IOERR_NOCMD;
|
||||
break;
|
||||
}
|
||||
ioreq->io_Actual = (unit->mediumPresent) ? 0 : 1; // io_Actual reflects the previous state
|
||||
ioreq->io_Actual = (unit->flags.mediumPresent) ? 0 : 1; // io_Actual reflects the previous state
|
||||
|
||||
bool insert = (ioreq->io_Length == 0) ? true : false;
|
||||
|
||||
@ -611,7 +613,7 @@ static void process_ioreq(struct IDETask *itask, struct IOStdReq *ioreq) {
|
||||
case TD_CHANGESTATE:
|
||||
error = 0;
|
||||
ioreq->io_Actual = 0;
|
||||
if (unit->atapi) {
|
||||
if (unit->flags.atapi) {
|
||||
ioreq->io_Actual = (atapi_test_unit_ready(unit,false) != 0);
|
||||
break;
|
||||
}
|
||||
@ -619,7 +621,7 @@ static void process_ioreq(struct IDETask *itask, struct IOStdReq *ioreq) {
|
||||
|
||||
case TD_PROTSTATUS:
|
||||
error = 0;
|
||||
if (unit->atapi) {
|
||||
if (unit->flags.atapi) {
|
||||
if ((error = atapi_check_wp(unit)) == TDERR_WriteProt) {
|
||||
error = 0;
|
||||
ioreq->io_Actual = 1;
|
||||
@ -660,7 +662,7 @@ validate_etd:
|
||||
case NSCMD_TD_FORMAT64:
|
||||
direction = WRITE;
|
||||
transfer:
|
||||
if (unit->atapi == true && unit->mediumPresent == false) {
|
||||
if (unit->flags.atapi == true && unit->flags.mediumPresent == false) {
|
||||
Trace("Access attempt without media\n");
|
||||
error = TDERR_DiskChanged;
|
||||
break;
|
||||
@ -681,7 +683,7 @@ transfer:
|
||||
break;
|
||||
}
|
||||
|
||||
if (unit->atapi == true) {
|
||||
if (unit->flags.atapi == true) {
|
||||
error = atapi_translate(ioreq->io_Data, lba, count, &ioreq->io_Actual, unit, direction);
|
||||
} else {
|
||||
if (direction == READ) {
|
||||
|
||||
@ -161,14 +161,14 @@ static void DumpUnit(struct IOStdReq *req) {
|
||||
|
||||
printf("Device Type: %d\n", unit->deviceType);
|
||||
printf("Transfer method: %d\n", unit->xferMethod);
|
||||
printf("Primary: %s\n", (unit->primary) ? "Yes" : "No");
|
||||
printf("ATAPI: %s\n", (unit->atapi) ? "Yes" : "No");
|
||||
printf("Medium Present: %s\n", (unit->mediumPresent) ? "Yes" : "No");
|
||||
printf("Supports LBA: %s\n", (unit->lba) ? "Yes" : "No");
|
||||
printf("Supports LBA48: %s\n", (unit->lba48) ? "Yes" : "No");
|
||||
printf("Primary: %s\n", (unit->flags.primary) ? "Yes" : "No");
|
||||
printf("ATAPI: %s\n", (unit->flags.atapi) ? "Yes" : "No");
|
||||
printf("Medium Present: %s\n", (unit->flags.mediumPresent) ? "Yes" : "No");
|
||||
printf("Supports LBA: %s\n", (unit->flags.lba) ? "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("Logical Sectors: %ld\n", (long int)unit->logicalSectors);
|
||||
printf("READ/WRITE Multiple: %s\n", (unit->xferMultiple) ? "Yes" : "No");
|
||||
printf("READ/WRITE Multiple: %s\n", (unit->flags.xferMultiple) ? "Yes" : "No");
|
||||
printf("Multiple count: %d\n", unit->multipleCount);
|
||||
printf("Last Error: ");
|
||||
for (int i=0; i<6; i++) {
|
||||
@ -298,12 +298,12 @@ static void setMultiple(struct IOStdReq *req, int multiple) {
|
||||
struct IDEUnit *unit = (struct IDEUnit *)req->io_Unit;
|
||||
|
||||
if (multiple > 0) {
|
||||
unit->xferMultiple = true;
|
||||
unit->flags.xferMultiple = true;
|
||||
unit->multipleCount = multiple;
|
||||
printf("set multiple transfer: %d\n",multiple);
|
||||
} else {
|
||||
printf("Transfer multiple disabled.\n");
|
||||
unit->xferMultiple = false;
|
||||
unit->flags.xferMultiple = false;
|
||||
unit->multipleCount = 1;
|
||||
}
|
||||
|
||||
|
||||
1
mounter
Submodule
1
mounter
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8ffa8ef7b3b00c4e9129e576ca304e0523a41707
|
||||
41
mounter.h
41
mounter.h
@ -1,41 +0,0 @@
|
||||
#ifndef MOUNTER_H
|
||||
#define MOUNTER_H
|
||||
|
||||
struct UnitStruct
|
||||
{
|
||||
ULONG unitNum;
|
||||
struct ConfigDev *configDev;
|
||||
};
|
||||
|
||||
struct MountStruct
|
||||
{
|
||||
// Device name. ("myhddriver.device")
|
||||
// Offset 0.
|
||||
UBYTE *deviceName;
|
||||
// Number of units
|
||||
UWORD numUnits;
|
||||
// Name string used to set Creator field in FileSystem.resource (if KS 1.3) and in FileSystem.resource entries.
|
||||
// If NULL: use device name.
|
||||
// Offset 8.
|
||||
const UBYTE *creatorName;
|
||||
// ConfigDev: set if autoconfig board autoboot support is wanted.
|
||||
// If NULL and bootable partition found: fake ConfigDev is automatically created.
|
||||
// Offset 12.
|
||||
struct ConfigDev *configDev;
|
||||
// SysBase.
|
||||
// Offset 16.
|
||||
struct ExecBase *SysBase;
|
||||
// Array of UnitStructs
|
||||
struct UnitStruct Units[];
|
||||
};
|
||||
|
||||
|
||||
APTR W_CreateIORequest(struct MsgPort *ioReplyPort, ULONG size, struct ExecBase *SysBase);
|
||||
void W_DeleteIORequest(APTR iorequest, struct ExecBase *SysBase);
|
||||
struct MsgPort *W_CreateMsgPort(struct ExecBase *SysBase);
|
||||
void W_DeleteMsgPort(struct MsgPort *port, struct ExecBase *SysBase);
|
||||
|
||||
int mount_drives(struct ConfigDev *cd, char *devName, struct MountStruct *ms);
|
||||
LONG MountDrive(struct MountStruct *ms);
|
||||
|
||||
#endif
|
||||
18
ndkcompat.h
18
ndkcompat.h
@ -1,18 +0,0 @@
|
||||
#ifndef __NDK_COMPAT_H
|
||||
#define __NDK_COMPAT_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/* ULONG has changed from NDK 3.9 to NDK 3.2.
|
||||
* However, PRI*32 did not. What is the right way to implement this?
|
||||
*/
|
||||
#if INCLUDE_VERSION < 47
|
||||
#undef PRIu32
|
||||
#define PRIu32 "lu"
|
||||
#undef PRId32
|
||||
#define PRId32 "ld"
|
||||
#undef PRIx32
|
||||
#define PRIx32 "lx"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user