mirror of
https://github.com/LIV2/lide.device.git
synced 2025-12-06 00:32:45 +00:00
Fixups
* Optimizations for size etc * Make endskip actually skip to the end * Save last ATA Error * Remove need for divide by using right shifts
This commit is contained in:
parent
2679269fc6
commit
45db8c4b21
22
Makefile
22
Makefile
@ -1,7 +1,16 @@
|
||||
PROJECT=liv2ride
|
||||
CC=m68k-amigaos-gcc
|
||||
DEBUG=0
|
||||
CFLAGS=-nostartfiles -nostdlib -noixemul -mcpu=68000 -Wall -Wno-multichar -Wno-pointer-sign -DDEBUG=$(DEBUG) -O3 -fomit-frame-pointer -Wno-unused-value -fno-delete-null-pointer-checks
|
||||
CFLAGS=-nostartfiles -nostdlib -noixemul -mcpu=68000 -Wall -Wno-multichar -Wno-pointer-sign -Wno-unused-value -Og -fomit-frame-pointer -fno-delete-null-pointer-checks -msmall-code -s
|
||||
LDFLAGS=-lamiga -lgcc -lc
|
||||
AS=m68k-amigaos-as
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS+= -DDEBUG=$(DEBUG)
|
||||
LDFLAGS+= -ldebug
|
||||
.PHONY: $(PROJECT)
|
||||
endif
|
||||
|
||||
LDFLAGS+= -lnix13
|
||||
|
||||
.PHONY: clean all
|
||||
all: $(PROJECT)
|
||||
@ -11,10 +20,13 @@ OBJ = driver.o \
|
||||
idetask.o \
|
||||
mounter.o
|
||||
|
||||
SRCS = $(OBJ:%.o=%.c)
|
||||
ASMOBJ = endskip.o
|
||||
|
||||
liv2ride: $(SRCS)
|
||||
${CC} -o $@ $(CFLAGS) $(SRCS) -lamiga -lgcc -ldebug -lnix13
|
||||
SRCS = $(OBJ:%.o=%.c)
|
||||
SRCS += $(ASMOBJ:%.o=%.S)
|
||||
|
||||
$(PROJECT): $(SRCS)
|
||||
${CC} -o $@ $(CFLAGS) $(SRCS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
-rm $(PROJECT)
|
||||
|
||||
263
ata.c
263
ata.c
@ -25,7 +25,7 @@
|
||||
*
|
||||
* returns false on timeout
|
||||
*/
|
||||
bool ata_wait_not_busy(struct IDEUnit *unit) {
|
||||
static bool ata_wait_not_busy(struct IDEUnit *unit) {
|
||||
#ifndef NOTIMER
|
||||
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
|
||||
struct timeval now, then;
|
||||
@ -39,7 +39,7 @@ bool ata_wait_not_busy(struct IDEUnit *unit) {
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
if ((*(volatile BYTE *)unit->drive->status_command & ata_busy) == 0) return true;
|
||||
if ((*(volatile BYTE *)unit->drive->status_command & ata_flag_busy) == 0) return true;
|
||||
|
||||
#ifndef NOTIMER
|
||||
GetSysTime(&now);
|
||||
@ -61,7 +61,7 @@ bool ata_wait_not_busy(struct IDEUnit *unit) {
|
||||
*
|
||||
* returns false on timeout
|
||||
*/
|
||||
bool ata_wait_ready(struct IDEUnit *unit) {
|
||||
static bool ata_wait_ready(struct IDEUnit *unit) {
|
||||
#ifndef NOTIMER
|
||||
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
|
||||
struct timeval now, then;
|
||||
@ -74,7 +74,7 @@ bool ata_wait_ready(struct IDEUnit *unit) {
|
||||
KPrintF("wait_ready_enter\n");
|
||||
#endif
|
||||
while (1) {
|
||||
if (*(volatile BYTE *)unit->drive->status_command & ata_ready) return true;
|
||||
if (*(volatile BYTE *)unit->drive->status_command & ata_flag_ready) return true;
|
||||
|
||||
#ifndef NOTIMER
|
||||
GetSysTime(&now);
|
||||
@ -95,7 +95,7 @@ bool ata_wait_ready(struct IDEUnit *unit) {
|
||||
*
|
||||
* returns false on timeout
|
||||
*/
|
||||
bool ata_wait_drq(struct IDEUnit *unit) {
|
||||
static bool ata_wait_drq(struct IDEUnit *unit) {
|
||||
#ifndef NOTIMER
|
||||
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
|
||||
struct timeval now, then;
|
||||
@ -110,7 +110,7 @@ bool ata_wait_drq(struct IDEUnit *unit) {
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
if (*(volatile BYTE *)unit->drive->status_command& ata_drq) return true;
|
||||
if (*(volatile BYTE *)unit->drive->status_command& ata_flag_drq) return true;
|
||||
|
||||
#ifndef NOTIMER
|
||||
GetSysTime(&now);
|
||||
@ -149,11 +149,11 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
|
||||
volatile UBYTE *status = unit->drive->status_command;
|
||||
|
||||
#if DEBUG >= 2
|
||||
KPrintF("Drive Status: %04x%04x %04x%04x\n",status, *status);
|
||||
KPrintF("Drive Status: %08lx %08lx\n",status, *status);
|
||||
#endif
|
||||
if (*status == 0) return false; // No drive there?
|
||||
|
||||
while ((*status & (ata_drq | ata_error)) == 0) {
|
||||
while ((*status & (ata_flag_drq | ata_flag_error)) == 0) {
|
||||
// Wait until ready to transfer or error condition
|
||||
#ifndef NOTIMER
|
||||
GetSysTime(&now);
|
||||
@ -161,10 +161,16 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (*status & ata_error) {
|
||||
if (*status & ata_flag_error) {
|
||||
#if DEBUG >= 1
|
||||
KPrintF("IDENTIFY Status: Error\n");
|
||||
KPrintF("IDENTIFY Status: Error\n");
|
||||
KPrintF("last_error: %08lx\n",&unit->last_error[0]);
|
||||
#endif
|
||||
unit->last_error[0] = *unit->drive->error_features;
|
||||
unit->last_error[1] = *unit->drive->lbaHigh;
|
||||
unit->last_error[2] = *unit->drive->lbaMid;
|
||||
unit->last_error[3] = *unit->drive->lbaLow;
|
||||
unit->last_error[4] = *unit->drive->status_command;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -212,7 +218,7 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
dev_found = true;
|
||||
#if DEBUG >= 1
|
||||
KPrintF("Something there?\n");
|
||||
KPrintF("Unit base: %04x%04x; Drive base %04x%04x\n",unit, unit->drive);
|
||||
KPrintF("Unit base: %08lx; Drive base %08lx\n",unit, unit->drive);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -241,12 +247,150 @@ bool ata_init_unit(struct IDEUnit *unit) {
|
||||
unit->heads = *((UWORD *)buf + ata_identify_heads);
|
||||
unit->sectorsPerTrack = *((UWORD *)buf + ata_identify_sectors);
|
||||
unit->blockSize = *((UWORD *)buf + ata_identify_sectorsize);
|
||||
unit->blockShift = 0;
|
||||
|
||||
// It's faster to shift than divide
|
||||
// Figure out how many shifts are needed for the equivalent divide
|
||||
if (unit->blockSize == 0) {
|
||||
#if DEBUG >= 1
|
||||
KPrintF("Error! blockSize is 0\n");
|
||||
#endif
|
||||
if (buf) FreeMem(buf,512);
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((unit->blockSize >> unit->blockShift) > 1) {
|
||||
unit->blockShift++;
|
||||
}
|
||||
|
||||
unit->present = true;
|
||||
|
||||
if (buf) FreeMem(buf,512);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_transfer
|
||||
*
|
||||
* Read/write a block from/to the unit
|
||||
* @param buffer Source buffer
|
||||
* @param lba LBA Address
|
||||
* @param count Number of blocks to transfer
|
||||
* @param actual Pointer to the io requests io_Actual
|
||||
* @param unit Pointer to the unit structure
|
||||
* @param direction READ/WRITE
|
||||
*/
|
||||
BYTE ata_transfer(void *buffer, ULONG lba, ULONG count, ULONG *actual, struct IDEUnit *unit, enum xfer_dir direction) {
|
||||
#if DEBUG >= 2
|
||||
if (direction == READ) {
|
||||
KPrintF("ata_read");
|
||||
} else {
|
||||
KPrintF("ata_write");
|
||||
}
|
||||
#endif
|
||||
ULONG subcount = 0;
|
||||
ULONG offset = 0;
|
||||
*actual = 0;
|
||||
|
||||
if (count == 0) return TDERR_TooFewSecs;
|
||||
|
||||
BYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
|
||||
*unit->drive->devHead = (UBYTE)(drvSel | ((lba >> 24) & 0x0F));
|
||||
|
||||
#if DEBUG >= 3
|
||||
KPrintF("Request sector count: %ld\n",count);
|
||||
#endif
|
||||
|
||||
// None of this max_transfer 1FE00 nonsense!
|
||||
while (count > 0) {
|
||||
if (count >= MAX_TRANSFER_SECTORS) { // Transfer 256 Sectors at a time
|
||||
subcount = MAX_TRANSFER_SECTORS;
|
||||
} else {
|
||||
subcount = count; // Get any remainders
|
||||
}
|
||||
count -= subcount;
|
||||
|
||||
#if DEBUG >= 3
|
||||
KPrintF("XFER Count: %ld, Subcount: %ld\n",count,subcount);
|
||||
#endif
|
||||
|
||||
if (!ata_wait_not_busy(unit))
|
||||
return HFERR_BadStatus;
|
||||
|
||||
*unit->drive->sectorCount = subcount; // Count value of 0 indicates to transfer 256 sectors
|
||||
*unit->drive->lbaLow = (UBYTE)(lba);
|
||||
*unit->drive->lbaMid = (UBYTE)(lba >> 8);
|
||||
*unit->drive->lbaHigh = (UBYTE)(lba >> 16);
|
||||
*unit->drive->error_features = 0;
|
||||
*unit->drive->status_command = (direction == READ) ? ATA_CMD_READ : ATA_CMD_WRITE;
|
||||
|
||||
for (int block = 0; block < subcount; block++) {
|
||||
if (!ata_wait_drq(unit))
|
||||
return HFERR_BadStatus;
|
||||
|
||||
|
||||
if (direction == READ) {
|
||||
|
||||
//for (int i=0; i<(unit->blockSize / 2); i++) {
|
||||
// ((UWORD *)buffer)[offset] = *(UWORD *)unit->drive->data;
|
||||
// offset++;
|
||||
//}
|
||||
read_fast((void *)(unit->drive->error_features - 48),(buffer + offset));
|
||||
offset += 512;
|
||||
|
||||
} else {
|
||||
//for (int i=0; i<(unit->blockSize / 2); i++) {
|
||||
// *(UWORD *)unit->drive->data = ((UWORD *)buffer)[offset];
|
||||
// offset++;
|
||||
//}
|
||||
write_fast((buffer + offset),(void *)(unit->drive->error_features - 48));
|
||||
offset += 512;
|
||||
|
||||
}
|
||||
|
||||
|
||||
*actual += unit->blockSize;
|
||||
}
|
||||
|
||||
if (*unit->drive->error_features & ata_flag_error) {
|
||||
unit->last_error[0] = unit->drive->error_features[0];
|
||||
unit->last_error[1] = unit->drive->lbaHigh[0];
|
||||
unit->last_error[2] = unit->drive->lbaMid[0];
|
||||
unit->last_error[3] = unit->drive->lbaLow[0];
|
||||
unit->last_error[4] = unit->drive->status_command[0];
|
||||
#if DEBUG
|
||||
KPrintF("ATA ERROR!!!");
|
||||
KPrintF("last_error: %08lx\n",unit->last_error);
|
||||
KPrintF("LBA: %ld, LastLBA: %ld\n",lba,(unit->sectorsPerTrack * unit->cylinders * unit->heads));
|
||||
#endif
|
||||
return TDERR_NotSpecified;
|
||||
}
|
||||
|
||||
lba += subcount;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#pragma GCC optimize ("-fomit-frame-pointer")
|
||||
/**
|
||||
* read_fast
|
||||
*
|
||||
* 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! source needs to be 48 bytes before the end of the data port!
|
||||
* 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-48 the error reg will be harmlessly read instead.
|
||||
*
|
||||
* @param source Pointer to drive data port
|
||||
* @param destination Pointer to source buffer
|
||||
*/
|
||||
void read_fast (void *source, void *destinaton) {
|
||||
asm volatile ("moveq #48,d7\n\t"
|
||||
|
||||
@ -298,6 +442,16 @@ void read_fast (void *source, void *destinaton) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* write_fast
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
void write_fast (void *source, void *destinaton) {
|
||||
asm volatile (
|
||||
"movem.l (%0)+,d0-d6/a1-a4/a6\n\t"
|
||||
@ -338,89 +492,4 @@ void write_fast (void *source, void *destinaton) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_transfer
|
||||
*
|
||||
* Read/write a block from/to the unit
|
||||
* @param buffer Source buffer
|
||||
* @param lba LBA Address
|
||||
* @param count Number of blocks to transfer
|
||||
* @param actual Pointer to the io requests io_Actual
|
||||
* @param unit Pointer to the unit structure
|
||||
* @param direction READ/WRITE
|
||||
*/
|
||||
BYTE ata_transfer(void *buffer, ULONG lba, ULONG count, ULONG *actual, struct IDEUnit *unit, enum xfer_dir direction) {
|
||||
#if DEBUG >= 2
|
||||
if (direction == READ) {
|
||||
KPrintF("ata_read");
|
||||
} else {
|
||||
KPrintF("ata_write");
|
||||
}
|
||||
#endif
|
||||
ULONG subcount;
|
||||
ULONG offset = 0;
|
||||
*actual = 0;
|
||||
|
||||
if (count == 0) return TDERR_TooFewSecs;
|
||||
|
||||
BYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
|
||||
*unit->drive->devHead = (UBYTE)(drvSel | ((lba >> 24) & 0x0F));
|
||||
|
||||
// None of this max_transfer 1FE00 nonsense!
|
||||
while (count > 0) {
|
||||
if (count >= MAX_TRANSFER_SECTORS) { // Transfer 256 Sectors at a time
|
||||
subcount = MAX_TRANSFER_SECTORS;
|
||||
} else {
|
||||
subcount = count; // Get any remainders
|
||||
}
|
||||
|
||||
if (!ata_wait_not_busy(unit))
|
||||
return HFERR_BadStatus;
|
||||
|
||||
*unit->drive->sectorCount = (subcount & 0xFF); // Count value of 0 indicates to transfer 256 sectors
|
||||
*unit->drive->lbaLow = (UBYTE)(lba);
|
||||
*unit->drive->lbaMid = (UBYTE)(lba >> 8);
|
||||
*unit->drive->lbaHigh = (UBYTE)(lba >> 16);
|
||||
*unit->drive->error_features = 0;
|
||||
*unit->drive->status_command = (direction == READ) ? ATA_CMD_READ : ATA_CMD_WRITE;
|
||||
|
||||
|
||||
for (int block = 0; block < subcount; block++) {
|
||||
if (!ata_wait_drq(unit))
|
||||
return HFERR_BadStatus;
|
||||
|
||||
if (*unit->drive->error_features && ata_error) {
|
||||
#if DEBUG >= 1
|
||||
KPrintF("ATA ERROR!!!");
|
||||
#endif
|
||||
return TDERR_NotSpecified;
|
||||
}
|
||||
|
||||
if (direction == READ) {
|
||||
|
||||
// for (int i=0; i<(unit->blockSize / 2); i++) {
|
||||
// ((UWORD *)buffer)[offset] = *(UWORD *)unit->drive->data;
|
||||
// offset++;
|
||||
// }
|
||||
read_fast((void *)(unit->drive->error_features - 48),(buffer + offset));
|
||||
offset += 512;
|
||||
|
||||
} else {
|
||||
//for (int i=0; i<(unit->blockSize / 2); i++) {
|
||||
// *(UWORD *)unit->drive->data = ((UWORD *)buffer)[offset];
|
||||
// offset++;
|
||||
//}
|
||||
write_fast((buffer + offset),(void *)(unit->drive->error_features - 48));
|
||||
offset += 512;
|
||||
|
||||
}
|
||||
|
||||
|
||||
*actual += unit->blockSize;
|
||||
}
|
||||
|
||||
count -= subcount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#pragma GCC reset_options
|
||||
14
ata.h
14
ata.h
@ -27,10 +27,10 @@
|
||||
|
||||
#define drv_sel_secondary (1<<4)
|
||||
|
||||
#define ata_busy (1<<7)
|
||||
#define ata_ready (1<<6)
|
||||
#define ata_drq (1<<3)
|
||||
#define ata_error (1<<0)
|
||||
#define ata_flag_busy (1<<7)
|
||||
#define ata_flag_ready (1<<6)
|
||||
#define ata_flag_drq (1<<3)
|
||||
#define ata_flag_error (1<<0)
|
||||
|
||||
#define ATA_CMD_IDENTIFY 0xEC
|
||||
#define ATA_CMD_READ 0x20
|
||||
@ -56,13 +56,13 @@ enum xfer_dir {
|
||||
WRITE
|
||||
};
|
||||
|
||||
bool ata_wait_busy(struct IDEUnit *);
|
||||
bool ata_wait_ready(struct IDEUnit *);
|
||||
bool ata_wait_drq(struct IDEUnit *);
|
||||
|
||||
bool ata_init_unit(struct IDEUnit *);
|
||||
bool ata_identify(struct IDEUnit *, UWORD *);
|
||||
BYTE ata_transfer(void *buffer, ULONG lba, ULONG count, ULONG *actual, struct IDEUnit *unit, enum xfer_dir);
|
||||
void read_fast (void *, void *);
|
||||
void write_fast (void *, void *);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
4
device.h
4
device.h
@ -33,11 +33,13 @@ struct IDEUnit {
|
||||
BOOL present;
|
||||
UBYTE channel;
|
||||
UBYTE device_type;
|
||||
ULONG change_count;
|
||||
UWORD cylinders;
|
||||
UWORD heads;
|
||||
UWORD sectorsPerTrack;
|
||||
UWORD blockSize;
|
||||
ULONG change_count;
|
||||
UWORD blockShift;
|
||||
UBYTE last_error[5];
|
||||
};
|
||||
|
||||
struct DeviceBase {
|
||||
|
||||
40
driver.c
40
driver.c
@ -37,20 +37,17 @@ int __attribute__((no_reorder)) _start()
|
||||
asm("romtag: \n"
|
||||
" dc.w "XSTR(RTC_MATCHWORD)" \n"
|
||||
" dc.l romtag \n"
|
||||
" dc.l endcode \n"
|
||||
" dc.l _endskip \n"
|
||||
" dc.b "XSTR(RTF_COLDSTART)" \n"
|
||||
" dc.b "XSTR(DEVICE_VERSION)" \n"
|
||||
" dc.b "XSTR(NT_DEVICE)" \n"
|
||||
" dc.b "XSTR(DEVICE_PRIORITY)" \n"
|
||||
" dc.l _device_name+4 \n"
|
||||
" dc.l _device_id_string \n"
|
||||
" dc.l _init \n"
|
||||
"endcode: \n");
|
||||
" dc.l _init \n");
|
||||
|
||||
char device_name[] = DEVICE_NAME;
|
||||
const char device_id_string[] = DEVICE_ID_STRING;
|
||||
const char task_name[] = TASK_NAME;
|
||||
|
||||
char const device_id_string[] = DEVICE_ID_STRING;
|
||||
|
||||
/**
|
||||
* set_dev_name
|
||||
@ -87,7 +84,7 @@ char * set_dev_name(struct DeviceBase *dev) {
|
||||
*
|
||||
* Free used resources back to the system
|
||||
*/
|
||||
void Cleanup(struct DeviceBase *dev) {
|
||||
static void Cleanup(struct DeviceBase *dev) {
|
||||
#if DEBUG > 0
|
||||
KPrintF("Cleaning up...\n");
|
||||
#endif
|
||||
@ -115,14 +112,13 @@ struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm(
|
||||
{
|
||||
dev->SysBase = SysBase;
|
||||
#if DEBUG >= 1
|
||||
KPrintF("Init dev, base: %08x\n",dev);
|
||||
KPrintF("Init dev, base: %08lx\n",dev);
|
||||
#endif
|
||||
struct Library *ExpansionBase = NULL;
|
||||
|
||||
char *devName;
|
||||
|
||||
if (!(devName = set_dev_name(dev))) return NULL;
|
||||
|
||||
/* save pointer to our loaded code (the SegList) */
|
||||
dev->saved_seg_list = seg_list;
|
||||
dev->lib.lib_Node.ln_Type = NT_DEVICE;
|
||||
@ -143,7 +139,7 @@ struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm(
|
||||
if ((dev->units = AllocMem(sizeof(struct IDEUnit)*MAX_UNITS, (MEMF_ANY|MEMF_CLEAR))) == NULL)
|
||||
return NULL;
|
||||
#if DEBUG >=2
|
||||
KPrintF("Dev->Units: %x%x\n",(ULONG)dev->units);
|
||||
KPrintF("Dev->Units: %08lx\n",(ULONG)dev->units);
|
||||
#endif
|
||||
if (!(ExpansionBase = (struct Library *)OpenLibrary("expansion.library",0))) {
|
||||
Cleanup(dev);
|
||||
@ -182,7 +178,7 @@ struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm(
|
||||
cd->cd_Flags &= ~(CDF_CONFIGME); // Claim the board
|
||||
dev->num_boards++;
|
||||
#if DEBUG >= 2
|
||||
KPrintF("Claiming board %04x%04x\n",(ULONG)cd->cd_BoardAddr);
|
||||
KPrintF("Claiming board %08lx\n",(ULONG)cd->cd_BoardAddr);
|
||||
#endif
|
||||
for (BYTE i=0; i<2; i++) {
|
||||
dev->units[i].SysBase = SysBase;
|
||||
@ -192,8 +188,9 @@ struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm(
|
||||
dev->units[i].channel = ((i%4) < 2) ? 0 : 1;
|
||||
dev->units[i].change_count = 1;
|
||||
dev->units[i].device_type = DG_DIRECT_ACCESS;
|
||||
dev->units[i].present = false;
|
||||
#if DEBUG >= 2
|
||||
KPrintF("testing unit %x%x\n",i);
|
||||
KPrintF("testing unit %08lx\n",i);
|
||||
#endif
|
||||
if (ata_init_unit(&dev->units[i])) {
|
||||
dev->num_units++;
|
||||
@ -204,7 +201,7 @@ struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm(
|
||||
}
|
||||
|
||||
#if DEBUG >= 1
|
||||
KPrintF("Detected %x%x drives, %x%x boards\n",dev->num_units, dev->num_boards);
|
||||
KPrintF("Detected %ld drives, %ld boards\n",dev->num_units, dev->num_boards);
|
||||
#endif
|
||||
if (dev->num_units > 0) {
|
||||
#if DEBUG >= 1
|
||||
@ -262,7 +259,7 @@ static BPTR __attribute__((used)) expunge(struct DeviceBase *dev asm("a6"))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->Task != NULL) {
|
||||
if (dev->Task != NULL && dev->TaskActive == true) {
|
||||
// Shut down ide_task
|
||||
|
||||
struct MsgPort *mp = NULL;
|
||||
@ -298,12 +295,13 @@ will execute your Open at a time. */
|
||||
static void __attribute__((used)) open(struct DeviceBase *dev asm("a6"), struct IORequest *ioreq asm("a1"), ULONG unitnum asm("d0"), ULONG flags asm("d1"))
|
||||
{
|
||||
#if DEBUG >= 2
|
||||
KPrintF((CONST_STRPTR) "running open() for unitnum %x%x\n",unitnum);
|
||||
KPrintF((CONST_STRPTR) "running open() for unitnum %ld\n",unitnum);
|
||||
#endif
|
||||
ioreq->io_Error = IOERR_OPENFAIL;
|
||||
|
||||
if (dev->Task == NULL) {
|
||||
if (dev->Task == NULL || dev->TaskActive == false) {
|
||||
ioreq->io_Error = IOERR_OPENFAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -372,6 +370,7 @@ static UWORD supported_commands[] =
|
||||
TD_CHANGESTATE,
|
||||
TD_GETDRIVETYPE,
|
||||
TD_GETGEOMETRY,
|
||||
TD_MOTOR,
|
||||
TD_PROTSTATUS,
|
||||
TD_READ64,
|
||||
TD_WRITE64,
|
||||
@ -396,7 +395,7 @@ static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), str
|
||||
#endif
|
||||
ioreq->io_Error = TDERR_NotSpecified;
|
||||
|
||||
if (dev->Task == NULL) {
|
||||
if (dev->Task == NULL || dev->TaskActive == false) {
|
||||
ioreq->io_Error = IOERR_OPENFAIL;
|
||||
}
|
||||
|
||||
@ -405,6 +404,7 @@ static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), str
|
||||
switch (ioreq->io_Command) {
|
||||
case CMD_CLEAR:
|
||||
case CMD_UPDATE:
|
||||
case TD_MOTOR:
|
||||
ioreq->io_Actual = 0;
|
||||
ioreq->io_Error = 0;
|
||||
break;
|
||||
@ -473,12 +473,12 @@ static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), str
|
||||
|
||||
default:
|
||||
#if DEBUG >= 2
|
||||
KPrintF("Unknown command %x%x\n", ioreq->io_Command);
|
||||
KPrintF("Unknown command %d\n", ioreq->io_Command);
|
||||
#endif
|
||||
ioreq->io_Error = IOERR_NOCMD;
|
||||
}
|
||||
if (!ioreq->io_Flags & IOF_QUICK) {
|
||||
ReplyMsg(&ioreq->io_Message);
|
||||
if (ioreq && !(ioreq->io_Flags & IOF_QUICK)) {
|
||||
ReplyMsg(&ioreq->io_Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
idetask.c
13
idetask.c
@ -35,7 +35,7 @@ static void handle_scsi_command(struct IOStdReq *ioreq) {
|
||||
enum xfer_dir direction = WRITE;
|
||||
|
||||
#if DEBUG >= 2
|
||||
KPrintF("Command %04x%04x\n",*scsi_command->scsi_Command);
|
||||
KPrintF("Command %ld\n",*scsi_command->scsi_Command);
|
||||
#endif
|
||||
switch (scsi_command->scsi_Command[0]) {
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
@ -178,13 +178,13 @@ do_scsi_transfer:
|
||||
* This is a task to complete IO Requests for all units
|
||||
* Requests are sent here from begin_io via the dev->TaskMP Message port
|
||||
*/
|
||||
void ide_task () {
|
||||
void __attribute__((noreturn)) ide_task () {
|
||||
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
|
||||
struct Task volatile *task = FindTask(NULL);
|
||||
struct MsgPort *mp;
|
||||
struct IOStdReq *ioreq;
|
||||
struct IDEUnit *unit;
|
||||
UWORD blocksize;
|
||||
UWORD blockShift;
|
||||
ULONG lba;
|
||||
ULONG count;
|
||||
enum xfer_dir direction = WRITE;
|
||||
@ -230,9 +230,9 @@ void ide_task () {
|
||||
case TD_FORMAT64:
|
||||
case NSCMD_TD_WRITE64:
|
||||
case NSCMD_TD_FORMAT64:
|
||||
blocksize = ((struct IDEUnit *)ioreq->io_Unit)->blockSize;
|
||||
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) / (UWORD)blocksize);
|
||||
count = (ioreq->io_Length/blocksize);
|
||||
blockShift = ((struct IDEUnit *)ioreq->io_Unit)->blockShift;
|
||||
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) >> blockShift);
|
||||
count = (ioreq->io_Length >> blockShift);
|
||||
ioreq->io_Error = ata_transfer(ioreq->io_Data, lba, count, &ioreq->io_Actual, unit, direction);
|
||||
break;
|
||||
|
||||
@ -249,6 +249,7 @@ void ide_task () {
|
||||
DeletePort(mp);
|
||||
dev->TaskMP = NULL;
|
||||
dev->Task = NULL;
|
||||
dev->TaskActive = false;
|
||||
ReplyMsg(&ioreq->io_Message);
|
||||
RemTask(NULL);
|
||||
Wait(0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user