Compare commits

...

4 Commits

Author SHA1 Message Date
c7f8340f5a Compact Unit struct some more 2025-07-05 16:46:21 +12:00
e5fad0b4fd Remove unused/unneeded parts of IDEUnit struct 2025-07-05 16:46:21 +12:00
c32aeef94c Mounter: Switch out mounter code with the mounter code upstream from A4091.device
This will make it easier to share improvements to the mounter code
2025-07-05 16:45:52 +12:00
83f74a8cb1 Remove function attributes (used/saveds)
lide doesn't use fbaserel and the used attribute is not needed
2025-07-05 03:28:11 +00:00
14 changed files with 142 additions and 1503 deletions

View File

@ -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
View File

@ -0,0 +1,3 @@
[submodule "mounter"]
path = mounter
url = https://github.com/LIV2/mounter

View File

@ -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

100
ata.c
View File

@ -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->cylinders = 0;
unit->heads = 0;
unit->sectorsPerTrack = 0;
unit->blockSize = 0;
unit->flags.present = false;
unit->flags.mediumPresent = false;
ULONG offset;
UWORD *buf;
bool dev_found = false;
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);
offset = (unit->channel == 0) ? CHANNEL_0 : CHANNEL_1;
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->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->multipleCount = buf[ata_identify_multiple] & 0xFF;
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->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
View File

@ -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
View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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,25 +422,24 @@ 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->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->multipleCount = 0;
unit->shadowDevHead = &itask->shadowDevHead;
*unit->shadowDevHead = 0;
unit->itask = itask;
unit->unitNum = ((itask->boardNum * 4) + (itask->channel << 1) + i);
unit->SysBase = SysBase;
unit->flags.primary = ((i%2) == 1) ? false : true;
unit->openCount = 0;
unit->changeCount = 1;
unit->deviceType = DG_DIRECT_ACCESS;
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;
// Initialize the change int list
unit->changeInts.mlh_Tail = NULL;
@ -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) {

View File

@ -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

@ -0,0 +1 @@
Subproject commit 8ffa8ef7b3b00c4e9129e576ca304e0523a41707

1262
mounter.c

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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