diff --git a/arch/m68k-amiga/devs/ata/ata_amiga.c b/arch/m68k-amiga/devs/ata/ata_amiga.c index df46acfcb24..f6565a48664 100644 --- a/arch/m68k-amiga/devs/ata/ata_amiga.c +++ b/arch/m68k-amiga/devs/ata/ata_amiga.c @@ -68,46 +68,46 @@ struct amiga_busdata static void ata_insw(APTR address, UWORD port, ULONG count, void *data) { - struct amiga_busdata *bdata = data; - volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3)); - ULONG *dst = address; - - count /= 4; - while (count-- != 0) - *dst++ = *addr; +// struct amiga_busdata *bdata = data; +// volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3)); +// ULONG *dst = address; +// +// count /= 4; +// while (count-- != 0) +// *dst++ = *addr; } static void ata_outsw(APTR address, UWORD port, ULONG count, APTR data) { - struct amiga_busdata *bdata = data; - volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3)); - ULONG *dst = address; - - count /= 4; - while (count-- != 0) - *addr = *dst++; +// struct amiga_busdata *bdata = data; +// volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3)); +// ULONG *dst = address; +// +// count /= 4; +// while (count-- != 0) +// *addr = *dst++; } static void ata_pcmcia_insw(APTR address, UWORD port, ULONG count, void *data) { - struct amiga_busdata *bdata = data; - volatile UWORD *addr = (UWORD*)(bdata->port + port); - UWORD *dst = address; - - count /= 2; - while (count-- != 0) - *dst++ = *addr; +// struct amiga_busdata *bdata = data; +// volatile UWORD *addr = (UWORD*)(bdata->port + port); +// UWORD *dst = address; +// +// count /= 2; +// while (count-- != 0) +// *dst++ = *addr; } static void ata_pcmcia_outsw(APTR address, UWORD port, ULONG count, APTR data) { - struct amiga_busdata *bdata = data; - volatile UWORD *addr = (UWORD*)(bdata->port + port); - UWORD *dst = address; - - count /= 2; - while (count-- != 0) - *addr = *dst++; +// struct amiga_busdata *bdata = data; +// volatile UWORD *addr = (UWORD*)(bdata->port + port); +// UWORD *dst = address; +// +// count /= 2; +// while (count-- != 0) +// *addr = *dst++; } @@ -117,44 +117,44 @@ static void ata_outl(ULONG val, UWORD offset, IPTR port, APTR data) static void ata_out(UBYTE val, UWORD offset, IPTR port, APTR data) { - struct amiga_busdata *bdata = data; - volatile UBYTE *addr; - -#if IDE_DEBUG - bug("ata_out(%x,%x)=%x:%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4, val); -#endif - /* IDE doubler hides Alternate Status/Device Control register */ - if (port == -1) { - if (bdata->reset == 0 && (val & 4)) { - ata_out(0x40, ata_DevHead, 0, bdata); - D(bug("[ATA] Emulating reset\n")); - ata_out(ATA_EXECUTE_DIAG, ata_Command, 0, bdata); - } - bdata->reset = (val & 4) != 0; - return; - } - addr = (UBYTE*)(bdata->port + port); - addr[offset * 4] = val; +// struct amiga_busdata *bdata = data; +// volatile UBYTE *addr; +// +// #if IDE_DEBUG +// bug("ata_out(%x,%x)=%x:%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4, val); +// #endif +// /* IDE doubler hides Alternate Status/Device Control register */ +// if (port == -1) { +// if (bdata->reset == 0 && (val & 4)) { +// ata_out(0x40, ata_DevHead, 0, bdata); +// D(bug("[ATA] Emulating reset\n")); +// ata_out(ATA_EXECUTE_DIAG, ata_Command, 0, bdata); +// } +// bdata->reset = (val & 4) != 0; +// return; +// } +// addr = (UBYTE*)(bdata->port + port); +// addr[offset * 4] = val; } static UBYTE ata_in(UWORD offset, IPTR port, APTR data) { - struct amiga_busdata *bdata = data; - volatile UBYTE *addr; - UBYTE v; - -#if IDE_DEBUG - bug("ata_in(%x,%x)=%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4); -#endif - if (port == -1) { - port = 0; - offset = ata_Status; - } - addr = (UBYTE*)(bdata->port + port); - v = addr[offset * 4]; -#if IDE_DEBUG - bug("=%x\n", v); -#endif +// struct amiga_busdata *bdata = data; +// volatile UBYTE *addr; +// UBYTE v; +// +// #if IDE_DEBUG +// bug("ata_in(%x,%x)=%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4); +// #endif +// if (port == -1) { +// port = 0; +// offset = ata_Status; +// } +// addr = (UBYTE*)(bdata->port + port); +// v = addr[offset * 4]; +// #if IDE_DEBUG +// bug("=%x\n", v); +// #endif return v; } @@ -173,44 +173,44 @@ static void gayledebug(void) static void ata_pcmcia_out(UBYTE val, UWORD offset, IPTR port, APTR data) { - volatile UBYTE *addr; - - addr = (UBYTE*)port; - if (offset == 1) { - /* Error / Feature not available when using Amiga PCMCIA */ - return; - } else if (offset & 1) { - addr += 0x10000; - } - addr[offset] = val; - -#if PCMCIA_DEBUG - bug("pcmcia_ata_out(%x,%x)=%p=%x\n", offset, port, &addr[offset], val); -#endif +// volatile UBYTE *addr; +// +// addr = (UBYTE*)port; +// if (offset == 1) { +// /* Error / Feature not available when using Amiga PCMCIA */ +// return; +// } else if (offset & 1) { +// addr += 0x10000; +// } +// addr[offset] = val; +// +// #if PCMCIA_DEBUG +// bug("pcmcia_ata_out(%x,%x)=%p=%x\n", offset, port, &addr[offset], val); +// #endif } static UBYTE ata_pcmcia_in(UWORD offset, IPTR port, APTR data) { - volatile UBYTE *addr; - UBYTE v; - - gayledebug(); - - addr = (UBYTE*)port; - if (offset == 1) { - /* Error / Feature not available when using Amiga PCMCIA */ - return 1; - } else if (offset & 1) { - addr += 0x10000; - } - v = addr[offset]; - -#if PCMCIA_DEBUG - bug("pcmcia_ata_in(%x,%x)=%p=%x (%02X)\n", offset, port, &addr[offset], v); -#endif - - gayledebug(); - +// volatile UBYTE *addr; +// UBYTE v; +// +// gayledebug(); +// +// addr = (UBYTE*)port; +// if (offset == 1) { +// /* Error / Feature not available when using Amiga PCMCIA */ +// return 1; +// } else if (offset & 1) { +// addr += 0x10000; +// } +// v = addr[offset]; +// +// #if PCMCIA_DEBUG +// bug("pcmcia_ata_in(%x,%x)=%p=%x (%02X)\n", offset, port, &addr[offset], v); +// #endif +// +// gayledebug(); +// return v; } @@ -222,127 +222,127 @@ static BOOL custom_check(APTR addr) UWORD intena; BOOL iscustom = TRUE; - intena = custom->intenar; - custom->intena = 0x7fff; - custom->intena = 0xc000; - maybe_custom->intena = 0x7fff; - if (custom->intenar == 0x4000) { - maybe_custom->intena = 0x7fff; - if (custom->intenar == 0x4000) - iscustom = FALSE; - } - custom->intena = 0x7fff; - custom->intena = intena | 0x8000; +// intena = custom->intenar; +// custom->intena = 0x7fff; +// custom->intena = 0xc000; +// maybe_custom->intena = 0x7fff; +// if (custom->intenar == 0x4000) { +// maybe_custom->intena = 0x7fff; +// if (custom->intenar == 0x4000) +// iscustom = FALSE; +// } +// custom->intena = 0x7fff; +// custom->intena = intena | 0x8000; return iscustom; } static UBYTE *getport(struct amiga_driverdata *ddata) { - UBYTE id, status1, status2; - volatile UBYTE *port, *altport; - struct GfxBase *gfx; - - port = NULL; - gfx = (struct GfxBase*)TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS); - Disable(); - id = ReadGayle(); - if (id) { - port = (UBYTE*)GAYLE_BASE_1200; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; - } else { - // in AGA this area is never custom mirror but lets make sure.. - if (!custom_check((APTR)0xdd4000) && (gfx->ChipRevBits0 & GFXF_AA_ALICE)) { - port = (UBYTE*)GAYLE_BASE_4000; - ddata->a4000 = TRUE; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_4000; - } - } - Enable(); - CloseLibrary((struct Library*)gfx); - - D(bug("[ATA] Gayle ID=%02x. Possible IDE port=%08x.\n", id, (ULONG)port & ~3)); - if (port == NULL) - return NULL; - - altport = port + 0x1010; - Disable(); - port[ata_DevHead * 4] = ATAF_ERROR; - /* If nothing connected, we get back what we wrote, ATAF_ERROR set */ - status1 = port[ata_Status * 4]; - port[ata_DevHead * 4] = ATAF_DATAREQ; - status2 = port[ata_Status * 4]; - port[ata_DevHead * 4] = 0; - Enable(); - D(bug("[ATA] Status=%02x,%02x\n", status1, status2)); - // BUSY and DRDY both active or ERROR/DATAREQ = no drive(s) = do not install driver - if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY)) - || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ))) - { - D(bug("[ATA] Drives not detected\n")); - return NULL; - } - if (ddata->doubler) { - UBYTE v1, v2; - /* check if AltControl is both readable and writable - * It is either floating or DevHead if IDE doubler is connected. - * AltControl = DevHead (R) - * Device Control = DevHead (W) - */ - Disable(); - altport[ata_AltControl * 4] = 0; - port[ata_DevHead * 4] = 1; - v1 = altport[ata_AltControl * 4]; - altport[ata_AltControl * 4] = 2; - port[ata_DevHead * 4] = 4; - v2 = altport[ata_AltControl * 4]; - altport[ata_AltControl * 4] = 0; - port[ata_DevHead * 4] = 0; - Enable(); - if ((v1 == 0 && v2 == 2) || (v1 == 1 && v2 == 4) || (v1 == 0xff && v2 == 0xff)) { - ddata->doubler = 2; - } else { - ddata->doubler = 0; - } - D(bug("[ATA] IDE doubler check (%02X, %02X) = %d\n", v1, v2, ddata->doubler)); - } +// UBYTE id, status1, status2; +// volatile UBYTE *port, *altport; +// struct GfxBase *gfx; +// +// port = NULL; +// gfx = (struct GfxBase*)TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS); +// Disable(); +// id = ReadGayle(); +// if (id) { +// port = (UBYTE*)GAYLE_BASE_1200; +// ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; +// } else { +// // in AGA this area is never custom mirror but lets make sure.. +// if (!custom_check((APTR)0xdd4000) && (gfx->ChipRevBits0 & GFXF_AA_ALICE)) { +// port = (UBYTE*)GAYLE_BASE_4000; +// ddata->a4000 = TRUE; +// ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_4000; +// } +// } +// Enable(); +// CloseLibrary((struct Library*)gfx); +// +// D(bug("[ATA] Gayle ID=%02x. Possible IDE port=%08x.\n", id, (ULONG)port & ~3)); +// if (port == NULL) +// return NULL; +// +// altport = port + 0x1010; +// Disable(); +// port[ata_DevHead * 4] = ATAF_ERROR; +// /* If nothing connected, we get back what we wrote, ATAF_ERROR set */ +// status1 = port[ata_Status * 4]; +// port[ata_DevHead * 4] = ATAF_DATAREQ; +// status2 = port[ata_Status * 4]; +// port[ata_DevHead * 4] = 0; +// Enable(); +// D(bug("[ATA] Status=%02x,%02x\n", status1, status2)); +// // BUSY and DRDY both active or ERROR/DATAREQ = no drive(s) = do not install driver +// if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY)) +// || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ))) +// { +// D(bug("[ATA] Drives not detected\n")); +// return NULL; +// } +// if (ddata->doubler) { +// UBYTE v1, v2; +// /* check if AltControl is both readable and writable +// * It is either floating or DevHead if IDE doubler is connected. +// * AltControl = DevHead (R) +// * Device Control = DevHead (W) +// */ +// Disable(); +// altport[ata_AltControl * 4] = 0; +// port[ata_DevHead * 4] = 1; +// v1 = altport[ata_AltControl * 4]; +// altport[ata_AltControl * 4] = 2; +// port[ata_DevHead * 4] = 4; +// v2 = altport[ata_AltControl * 4]; +// altport[ata_AltControl * 4] = 0; +// port[ata_DevHead * 4] = 0; +// Enable(); +// if ((v1 == 0 && v2 == 2) || (v1 == 1 && v2 == 4) || (v1 == 0xff && v2 == 0xff)) { +// ddata->doubler = 2; +// } else { +// ddata->doubler = 0; +// } +// D(bug("[ATA] IDE doubler check (%02X, %02X) = %d\n", v1, v2, ddata->doubler)); +// } /* we may have connected drives */ return (UBYTE*)port; } static void ackint(struct amiga_driverdata *ddata) { - if (ddata->a4000) - return; - /* Clear A600/A1200 IDE interrupt. (Stupid Gayle hardware) */ - *ddata->gayleirqbase = 0x7c | (*ddata->gayleirqbase & 3); +// if (ddata->a4000) +// return; +// /* Clear A600/A1200 IDE interrupt. (Stupid Gayle hardware) */ +// *ddata->gayleirqbase = 0x7c | (*ddata->gayleirqbase & 3); } static void ata_AckInterrupt(struct ata_Bus *bus) { - struct amiga_busdata *bdata = bus->ab_DriverData; - struct amiga_driverdata *ddata = bdata->ddata; - ackint(ddata); +// struct amiga_busdata *bdata = bus->ab_DriverData; +// struct amiga_driverdata *ddata = bdata->ddata; +// ackint(ddata); } static void callbusirq(struct amiga_driverdata *ddata) { - volatile UBYTE *port; - UBYTE status1, status2; - BOOL handled = FALSE; - - if (ddata->bus[0]) - handled |= ata_HandleIRQ(ddata->bus[0]->bus); - if (ddata->bus[1]) - handled |= ata_HandleIRQ(ddata->bus[1]->bus); - if (handled) - return; - - /* Handle spurious interrupt */ - port = ddata->gaylebase; - status1 = port[ata_Status * 4]; - status2 = 0; - if (ddata->doubler == 2) - status2 = port[0x1000 + ata_Status * 4]; - ackint(ddata); - bug("[ATA] Spurious interrupt: %02X %02X\n", status1, status2); +// volatile UBYTE *port; +// UBYTE status1, status2; +// BOOL handled = FALSE; +// +// if (ddata->bus[0]) +// handled |= ata_HandleIRQ(ddata->bus[0]->bus); +// if (ddata->bus[1]) +// handled |= ata_HandleIRQ(ddata->bus[1]->bus); +// if (handled) +// return; +// +// /* Handle spurious interrupt */ +// port = ddata->gaylebase; +// status1 = port[ata_Status * 4]; +// status2 = 0; +// if (ddata->doubler == 2) +// status2 = port[0x1000 + ata_Status * 4]; +// ackint(ddata); +// bug("[ATA] Spurious interrupt: %02X %02X\n", status1, status2); } AROS_INTH1(IDE_Handler_A1200, struct amiga_driverdata *, ddata) diff --git a/arch/m68k-amiga/devs/ata/waitnano.c b/arch/m68k-amiga/devs/ata/waitnano.c index b3dc8d6c9dc..7353b8d359b 100644 --- a/arch/m68k-amiga/devs/ata/waitnano.c +++ b/arch/m68k-amiga/devs/ata/waitnano.c @@ -19,35 +19,9 @@ BOOL ata_Calibrate(struct IORequest* tmr, struct ataBase *base) static void busywait(UWORD cnt) { - asm volatile ( - "move.w %0,%%d0\n" - "lea 0xbfe001,%%a0\n" - "0:\n" - "tst.b (%%a0)\n" - "tst.b (%%a0)\n" - "tst.b (%%a0)\n" - "tst.b (%%a0)\n" - "dbf %%d0,0b\n" - : : "m" (cnt) : "d0", "a0"); } /* Single CIA access = 1 E-clock */ void ata_WaitNano(ULONG ns, struct ataBase *base) { - /* - We really need to review this code. The WaitNano is supposed to wait given number of *nanoseconds* - Each CIA access takes one E-clock which equals 1400 nanoseconds. It means, on Amiga hardware it is - hardly impossible to do a delay shorter than 1.4 microseconds. - - For how we will shift the nanosecond count by 10 bits, effectively dividing it by 1024. - */ - ns /= 1024; - if (!(SysBase->AttnFlags & AFF_68020)) - ns /= 2; - while (ns >= 65536 * 4) { - busywait(65535); - ns -= 65536 * 4; - } - if (ns >= 4) - busywait(ns / 4); } diff --git a/arch/m68k-amiga/hidd/gayle_ata/ata_gayle.conf b/arch/m68k-amiga/hidd/gayle_ata/ata_gayle.conf index 1a825ea6784..53a9e239983 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/ata_gayle.conf +++ b/arch/m68k-amiga/hidd/gayle_ata/ata_gayle.conf @@ -27,24 +27,3 @@ GetPIOInterface Shutdown ##end methodlist -##begin class -##begin config -basename FASTATA -type hidd -superclass CLID_Hidd_ATABus -classptr_field FastATABusClass -classdatatype struct ATA_BusData -##end config - -##begin methodlist -.interface Root -New -Dispose -Get -Set -.interface Hidd_ATABus -GetPIOInterface -SetXferMode -Shutdown -##end methodlist -##end class \ No newline at end of file diff --git a/arch/m68k-amiga/hidd/gayle_ata/fastata_busclass.c b/arch/m68k-amiga/hidd/gayle_ata/fastata_busclass.c deleted file mode 100644 index 9ad7d87af12..00000000000 --- a/arch/m68k-amiga/hidd/gayle_ata/fastata_busclass.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright © 2017-2019, The AROS Development Team. All rights reserved. - $Id$ - - Desc: Elbox FastATA HIDD - Lang: English -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bus_class.h" -#include "interface_pio.h" - -AROS_INTH1(IDE_Handler_FASTATA, struct ATA_BusData *, bus) -{ - AROS_INTFUNC_INIT - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - return FALSE; - - AROS_INTFUNC_EXIT -} - -static BOOL ata_CreateFastATAInterrupt(struct ATA_BusData *bus, UBYTE num) -{ - D(bug("[ATA:FastATA] %s()\n", __func__);) - return FALSE; -} -static void ata_RemoveFastATAInterrupt(struct ATA_BusData *bus) -{ - D(bug("[ATA:FastATA] %s()\n", __func__);) -} - -OOP_Object *FASTATA__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg) -{ - struct ataBase *base = cl->UserData; - struct ata_ProbedBus *bus = (struct ata_ProbedBus *)GetTagData(aHidd_DriverData, 0, msg->attrList); - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - if (!bus) - return NULL; - - o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg); - if (o) - { - struct ATA_BusData *data = OOP_INST_DATA(cl, o); - - data->bus = bus; - data->gaylebase = data->bus->port; - data->gayleirqbase = data->bus->gayleirqbase; - ata_CreateFastATAInterrupt(data, 0); - } - - D(bug("[ATA:FastATA] %s: Instance @ %p\n", __func__, o);) - return o; -} - -void FASTATA__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) -{ - struct ATA_BusData *data = OOP_INST_DATA(cl, o); - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - ata_RemoveFastATAInterrupt(data); - FreeVec(data->bus); - - OOP_DoSuperMethod(cl, o, msg); -} - -void FASTATA__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg) -{ - struct ataBase *base = cl->UserData; - ULONG idx; - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - Hidd_ATABus_Switch(msg->attrID, idx) - { - case aoHidd_ATABus_Use80Wire: - *msg->storage = FALSE; - return; - - case aoHidd_ATABus_UseDMA: - *msg->storage = FALSE; - return; - - case aoHidd_ATABus_Use32Bit: - *msg->storage = TRUE; - return; - } - - OOP_DoSuperMethod(cl, o, &msg->mID); -} - -void FASTATA__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg) -{ - struct ataBase *base = cl->UserData; - struct ATA_BusData *data = OOP_INST_DATA(cl, o); - struct TagItem *tstate = msg->attrList; - struct TagItem *tag; - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - while ((tag = NextTagItem(&tstate))) - { - ULONG idx; - - Hidd_Bus_Switch(tag->ti_Tag, idx) - { - case aoHidd_Bus_IRQHandler: - data->ata_HandleIRQ = (APTR)tag->ti_Data; - break; - - case aoHidd_Bus_IRQData: - data->irqData = (APTR)tag->ti_Data; - break; - } - } -} - -APTR FASTATA__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) -{ - struct ATA_BusData *data = OOP_INST_DATA(cl, o); - struct pio_data *pio = (struct pio_data *)OOP_DoSuperMethod(cl, o, msg); - - D(bug("[ATA:FastATA] %s()\n", __func__);) - - if (pio) - { - pio->port = data->bus->port; - pio->altport = data->bus->altport; - pio->dataport = (UBYTE*)(((ULONG)pio->port) & ~3); - } - - return pio; -} - -BOOL FASTATA__Hidd_ATABus__SetXferMode(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg) -{ - D(bug("[ATA:FastATA] %s()\n", __func__);) - - return TRUE; -} - -void FASTATA__Hidd_ATABus__Shutdown(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) -{ - D(bug("[ATA:FastATA] %s()\n", __func__);) - - OOP_DoSuperMethod(cl, o, msg); -} diff --git a/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c b/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c index 9f210d0edf6..71bc4d2cd71 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c +++ b/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c @@ -52,41 +52,13 @@ AROS_INTH1(IDE_Handler_A1200, struct ATA_BusData *, bus) AROS_INTFUNC_EXIT } -AROS_INTH1(IDE_Handler_A4000, struct ATA_BusData *, bus) -{ - AROS_INTFUNC_INIT - - /* A4000 interrupt clears when register is read */ - volatile UWORD *irqbase = (UWORD*)bus->gayleirqbase; - UWORD irqmask = *irqbase; - if (irqmask & (GAYLE_IRQ_IDE << 8)) { - volatile UBYTE *port; - UBYTE status; - - port = bus->gaylebase; - status = port[ata_Status * 4]; - if (status & ATAF_BUSY) { - bug("[ATA:Gayle] ATA interrupt but BUSY flag set!?\n"); - return FALSE; - } - bus->ata_HandleIRQ(status, bus->irqData); - return TRUE; - } - return FALSE; - - AROS_INTFUNC_EXIT -} static BOOL ata_CreateGayleInterrupt(struct ATA_BusData *bus, UBYTE num) { struct Interrupt *irq = &bus->ideint; - if (bus->bus->a4000) { - irq->is_Code = (APTR)IDE_Handler_A4000; - } else { bus->gayleintbase = (UBYTE*)GAYLE_INT_1200; irq->is_Code = (APTR)IDE_Handler_A1200; - } irq->is_Node.ln_Pri = 20; irq->is_Node.ln_Type = NT_INTERRUPT; @@ -140,7 +112,7 @@ OOP_Object *GAYLEATA__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New * data->bus->atapb_Node.ln_Succ = (struct Node *)-1; data->gaylebase = data->bus->port; data->gayleirqbase = data->bus->gayleirqbase; - ata_CreateGayleInterrupt(data, 0); + //ata_CreateGayleInterrupt(data, 0); //mDispose = msg->mID - moRoot_New + moRoot_Dispose; //OOP_DoSuperMethod(cl, o, &mDispose); @@ -234,8 +206,7 @@ APTR GAYLEATA__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Ms * This shadow bank is for 16/32-bit data transfers, while the * other one is much slower due to 8-bit transfers, only. */ - if (!data->bus->a4000) - pio->dataport = (UBYTE*)(((ULONG)pio->port) + 0x2000); + pio->dataport = (UBYTE*)(((ULONG)pio->port) + 0x2000); } return pio; diff --git a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c index 02ac4ab8cb3..c6363b44351 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c +++ b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c @@ -16,7 +16,6 @@ static void ata_out(struct pio_data *data, UBYTE val, UWORD offset) { volatile UBYTE *addr; addr = data->port; - DIO(bug("%p REG %d <- %02X\n", addr, offset, val)); addr[offset * 4] = val; } @@ -27,7 +26,6 @@ static UBYTE ata_in(struct pio_data *data, UWORD offset) addr = data->port; v = addr[offset * 4]; - DIO(bug("%p REG %d -> %02X\n", addr, offset, v)); return v; } @@ -36,11 +34,10 @@ static void ata_outsl(struct pio_data *data, APTR address, ULONG count) { volatile ULONG *addr = (ULONG*)data->dataport; - DDATA(bug("LOUT %p %p %d\n", addr, address, count)); asm volatile( -"1: move.l (%[address])+,(%[port]) \n" -" move.l (%[address])+,(%[port]) \n" +"1: move.l (%[address])+,(0xDA2000) \n" +" move.l (%[address])+,(0xDA2000) \n" " subq.l #1,%[count] \n" " bnes 1b \n" ::[count]"d"(count >> 3),[address]"a"(address),[port]"a"(addr)); @@ -51,14 +48,14 @@ static void ata_insl(struct pio_data *data, APTR address, ULONG count) { volatile ULONG *addr = (ULONG*)data->dataport; - DDATA(bug("LIN %p %p %d\n", addr, address, count)); asm volatile( -"1: move.l (%[port]),(%[address])+ \n" -" move.l (%[port]),(%[address])+ \n" -" subq.l #1,%[count] \n" -" bnes 1b \n" - ::[count]"d"(count >> 3),[address]"a"(address),[port]"a"(addr)); +" bra 2f \n" +"1: \n" +" move16 0x00da6000,(%[address])+ \n" +" move16 0x00da6000,(%[address])+ \n" +"2: dbra %[count],1b \n" + ::[count]"d"(count >> 5),[address]"a"(address)); } const APTR bus_FuncTable[] = diff --git a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h index 40327e19960..46ae597de7c 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h +++ b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h @@ -17,37 +17,6 @@ #define GAYLE_IRQ_IDE 0x80 #define GAYLE_INT_IDE 0x80 -/* - * Elbox FastATA Gayle Extensions - */ -#define GAYLE_BASE_FASTATA (GAYLE_BASE_1200 + 0x2000) -#define GAYLE_BASE_FASTATA_PIO0 (0x0) /* the different PIO modes are handled at different .. */ -#define GAYLE_BASE_FASTATA_PIO3 (0x10000) /* .. register offsets - see below for register def's */ -#define GAYLE_BASE_FASTATA_PIO4 (0x14000) -#define GAYLE_BASE_FASTATA_PIO5 (0x12000) -#define GAYLE_IRQ_FASTATA (GAYLE_IRQ_1200) - -#define GAYLE_FASTATA_PORTSIZE 0x1000 - -#define GAYLE_FASTATA_PIO_DATA 0x0 -#define GAYLE_FASTATA_PIO_ERR 0x4 -#define GAYLE_FASTATA_PIO_NSECT 0x8 -#define GAYLE_FASTATA_PIO_SECT 0xC -#define GAYLE_FASTATA_PIO_LOCYL 0x10 -#define GAYLE_FASTATA_PIO_HICYL 0x14 -#define GAYLE_FASTATA_PIO_SEL 0x18 -#define GAYLE_FASTATA_PIO_STAT 0x1C - -#define GAYLE_FASTATA_LONGDATA 0x0 -#define GAYLE_FASTATA_ERR 0x200 -#define GAYLE_FASTATA_DATA 0x208 -#define GAYLE_FASTATA_NSECT 0x400 -#define GAYLE_FASTATA_SECT 0x600 -#define GAYLE_FASTATA_LOCYL 0x800 -#define GAYLE_FASTATA_HICYL 0xA00 -#define GAYLE_FASTATA_SEL 0xC00 -#define GAYLE_FASTATA_STAT 0xE00 - struct pio_data { UBYTE *dataport; diff --git a/arch/m68k-amiga/hidd/gayle_ata/mmakefile.src b/arch/m68k-amiga/hidd/gayle_ata/mmakefile.src index 3fa99bf9a5d..fcd963422fd 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/mmakefile.src +++ b/arch/m68k-amiga/hidd/gayle_ata/mmakefile.src @@ -2,7 +2,7 @@ include $(SRCDIR)/config/aros.cfg -FILES := class_init probe gayleata_busclass fastata_busclass interface_pio +FILES := class_init probe gayleata_busclass interface_pio USER_CPPFLAGS := -D__OOP_NOMETHODBASES__ -D__OOP_NOATTRBASES__ #USER_CPPFLAGS += -DDEBUG diff --git a/arch/m68k-amiga/hidd/gayle_ata/probe.c b/arch/m68k-amiga/hidd/gayle_ata/probe.c index ffb7c9c6c85..3674f6af9b1 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/probe.c +++ b/arch/m68k-amiga/hidd/gayle_ata/probe.c @@ -31,35 +31,7 @@ //#define ENABLE_ATAPOWERFLYER -static BOOL custom_check(APTR addr) -{ - volatile struct Custom *custom = (struct Custom*)0xdff000; - volatile struct Custom *maybe_custom = (struct Custom*)addr; - UWORD intena; - BOOL iscustom = TRUE; - - intena = custom->intenar; - custom->intena = 0x7fff; - custom->intena = 0xc000; - maybe_custom->intena = 0x7fff; - if (custom->intenar == 0x4000) { - maybe_custom->intena = 0x7fff; - if (custom->intenar == 0x4000) - iscustom = FALSE; - } - custom->intena = 0x7fff; - custom->intena = intena | 0x8000; - return iscustom; -} -static BOOL isFastATA(struct ata_ProbedBus *ddata) -{ -#if defined(ENABLE_ATAPOWERFLYER) - if (ddata->gayleirqbase == (UBYTE*)GAYLE_IRQ_FASTATA) - return TRUE; -#endif - return FALSE; -} static UBYTE *getport(struct ata_ProbedBus *ddata) { @@ -71,60 +43,22 @@ static UBYTE *getport(struct ata_ProbedBus *ddata) port = NULL; gfx = (struct GfxBase*)TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS); Disable(); - id = ReadGayle(); - if (id) { - port = (UBYTE*)GAYLE_BASE_1200; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; - } else { - // AGA does not have custom mirror here but lets make sure.. - if (!custom_check((APTR)0xdd4000) && (custom->vposr & 0x7f00) >= 0x2200) { - port = (UBYTE*)GAYLE_BASE_4000; - ddata->a4000 = TRUE; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_4000; - } - } + port = (UBYTE*)GAYLE_BASE_1200; + ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; Enable(); CloseLibrary((struct Library*)gfx); D(bug("[ATA:Gayle] GayleID : %02x\n", id);) -#if defined(ENABLE_ATAPOWERFLYER) - // Detect FastATA... FIXME: the check is flawed for an a4000, disabled for now. - if (ddata->gayleirqbase) - { - altport = (UBYTE*)GAYLE_BASE_FASTATA; - Disable(); - status1 = altport[GAYLE_BASE_FASTATA_PIO0 + GAYLE_FASTATA_PIO_STAT]; - status2 = altport[GAYLE_BASE_FASTATA_PIO3 + GAYLE_FASTATA_STAT]; - Enable(); - D(bug("[ATA:Gayle] (FastATA) Status=%02x,%02x\n", status1, status2);) - if (((status1 != 0x00) && (status1 != 0xFF)) && - ((status1 & 0xfd) == (status2 & 0xfd))) - { - port = (UBYTE*)altport; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_FASTATA; - } - } -#endif - if (port == NULL) - { - D(bug("[ATA:Gayle] No Gayle ATA Detected\n");) - return NULL; - } - ddata->port = (UBYTE*)port; - if ((ddata->port == (UBYTE*)GAYLE_BASE_1200) || (ddata->port == (UBYTE*)GAYLE_BASE_4000)) - { - D(bug("[ATA:Gayle] Possible Gayle IDE port @ %08x\n", (ULONG)port & ~3);) - altport = port + 0x1010; - } - else - { - D(bug("[ATA:Gayle] Possible FastATA IDE port @ %08x\n", (ULONG)port & ~3);) - altport = NULL; - } + + D(bug("[ATA:Gayle] Possible Gayle IDE port @ %08x\n", (ULONG)port & ~3);) + altport = port + 0x1010; + ddata->altport = (UBYTE*)altport; +RETRY: + Disable(); port[ata_DevHead * 4] = ATAF_ERROR; /* If nothing connected, we get back what we wrote, ATAF_ERROR set */ @@ -134,39 +68,17 @@ static UBYTE *getport(struct ata_ProbedBus *ddata) port[ata_DevHead * 4] = 0; Enable(); - D(bug("[ATA:Gayle] Status=%02x,%02x\n", status1, status2);) - // BUSY and DRDY both active or ERROR/DATAREQ = no drive(s) = do not install driver - if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY)) - || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ))) - { - D(bug("[ATA:Gayle] No Devices detected\n");) - return NULL; - } - if (ddata->doubler) { - UBYTE v1, v2; - /* check if AltControl is both readable and writable - * It is either floating or DevHead if IDE doubler is connected. - * AltControl = DevHead (R) - * Device Control = DevHead (W) - */ - Disable(); - altport[ata_AltControl * 4] = 0; - port[ata_DevHead * 4] = 1; - v1 = altport[ata_AltControl * 4]; - altport[ata_AltControl * 4] = 2; - port[ata_DevHead * 4] = 4; - v2 = altport[ata_AltControl * 4]; - altport[ata_AltControl * 4] = 0; - port[ata_DevHead * 4] = 0; - Enable(); - if ((v1 == 0 && v2 == 2) || (v1 == 1 && v2 == 4) || (v1 == 0xff && v2 == 0xff)) { - ddata->doubler = 2; - } else { - ddata->doubler = 0; - } - D(bug("[ATA:Gayle] IDE doubler check (%02X, %02X) = %d\n", v1, v2, ddata->doubler);) - ddata->altport = NULL; - } + D(bug("[ATA:Gayle] Status=%02x,%02x\n", status1, status2);) + // BUSY and DRDY both active or ERROR/DATAREQ = no drive(s) = do not install driver + if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY)) + || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ))) + { +// goto RETRY; + + //D(bug("[ATA:Gayle] No Devices detected\n");) + //return NULL; + } + /* we may have connected drives */ return (UBYTE*)port; } @@ -186,17 +98,11 @@ static int gayle_bus_Scan(struct ataBase *base) probedbus = AllocVec(sizeof(struct ata_ProbedBus), MEMF_ANY | MEMF_CLEAR); if (probedbus && getport(probedbus)) { OOP_Object *ata; - if (isFastATA(probedbus)) - { - ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"PowerFlyer FastATA IDE Controller"; - } - else - { if (probedbus->doubler == 0) ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller"; else ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller + Port Doubler"; - } + ata = HW_AddDriver(base->storageRoot, base->ataClass, ata_tags); if (ata) { struct TagItem attrs[] = @@ -226,15 +132,8 @@ static int gayle_bus_Scan(struct ataBase *base) /* * Check if we have a FastATA adaptor */ - if (isFastATA(probedbus)) - { - busClass = base->FastATABusClass; - attrs[BUS_TAG_HARDWARENAME].ti_Data = (IPTR)"FastATA IDE Channel"; - } - else - { attrs[BUS_TAG_HARDWARENAME].ti_Data = (IPTR)"Gayle IDE Channel"; - } + bus = HIDD_StorageController_AddBus(ata, busClass, attrs); if (bus) diff --git a/rom/devs/ata/ata.c b/rom/devs/ata/ata.c index 6c4491b3d58..4af2b571173 100644 --- a/rom/devs/ata/ata.c +++ b/rom/devs/ata/ata.c @@ -51,12 +51,6 @@ static void cmd_Read32(struct IORequest *io, LIBBASETYPEPTR LIBBASE) { struct ata_Unit *unit = (struct ata_Unit *)IOStdReq(io)->io_Unit; - if (AF_Removable == (unit->au_Flags & (AF_Removable | AF_DiscPresent))) - { - D(bug("[ATA%02ld] %s: USUALLY YOU'D WANT TO CHECK IF DISC IS PRESENT FIRST\n", unit->au_UnitNum, __func__)); - io->io_Error = TDERR_DiskChanged; - return; - } ULONG block = IOStdReq(io)->io_Offset; ULONG count = IOStdReq(io)->io_Length; @@ -87,9 +81,77 @@ static void cmd_Read32(struct IORequest *io, LIBBASETYPEPTR LIBBASE) return; } - /* Call the Unit's access funtion */ - io->io_Error = unit->au_Read32(unit, block, count, - IOStdReq(io)->io_Data, &cnt); + if (unit->au_SectorShift == 9) /* use cache with 512 Byte sectors only */ + { + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + ULONG unitNum = unit->au_UnitNum; + + ULONG start; + ULONG i; + for (start = 0, i = 0; i < count; i++) + { + ULONG blockAdr = (block + i) & CACHE_MASK; + UQUAD blockTag = (block + i) & ~CACHE_MASK; + + if ((unitNum < (1<<9)) && + (base->ata_CacheTags[blockAdr] == (blockTag | unitNum))) /* cache hit */ + { + CopyMem(base->ata_CacheData + blockAdr*512, IOStdReq(io)->io_Data + i*512, 512); + + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read32(unit, block + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + start = i + 1; + } + } + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read32(unit, block + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + ULONG blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + ULONG blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + cnt = count << unit->au_SectorShift; + } + else + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read32(unit, block, count, + IOStdReq(io)->io_Data, &cnt); + } IOStdReq(io)->io_Actual = cnt; } @@ -103,12 +165,6 @@ static void cmd_Read64(struct IORequest *io, LIBBASETYPEPTR LIBBASE) { struct ata_Unit *unit = (struct ata_Unit *)IOStdReq(io)->io_Unit; - if (AF_Removable == (unit->au_Flags & (AF_Removable | AF_DiscPresent))) - { - D(bug("[ATA%02ld] %s: USUALLY YOU'D WANT TO CHECK IF DISC IS PRESENT FIRST\n", unit->au_UnitNum, __func__)); - io->io_Error = TDERR_DiskChanged; - return; - } UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32; ULONG count = IOStdReq(io)->io_Length; @@ -141,7 +197,76 @@ static void cmd_Read64(struct IORequest *io, LIBBASETYPEPTR LIBBASE) io->io_Error = IOERR_BADADDRESS; return; } - io->io_Error = unit->au_Read32(unit, (ULONG)(block & 0x0fffffff), count, IOStdReq(io)->io_Data, &cnt); + + if (unit->au_SectorShift == 9) /* use cache with 512 Byte sectors only */ + { + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + ULONG unitNum = unit->au_UnitNum; + + ULONG start; + ULONG i; + for (start = 0, i = 0; i < count; i++) + { + ULONG blockAdr = (block + i) & CACHE_MASK; + UQUAD blockTag = (block + i) & ~CACHE_MASK; + + if ((unitNum < (1<<9)) && + (base->ata_CacheTags[blockAdr] == (blockTag | unitNum))) /* cache hit */ + { + CopyMem(base->ata_CacheData + blockAdr*512, IOStdReq(io)->io_Data + i*512, 512); + + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read32(unit, (ULONG)(block & 0x0fffffff) + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + start = i + 1; + } + } + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read32(unit, (ULONG)(block & 0x0fffffff) + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + ULONG blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + ULONG blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + cnt = count << unit->au_SectorShift; + } + else + { + io->io_Error = unit->au_Read32(unit, (ULONG)(block & 0x0fffffff), count, IOStdReq(io)->io_Data, &cnt); + } } else { @@ -152,7 +277,75 @@ static void cmd_Read64(struct IORequest *io, LIBBASETYPEPTR LIBBASE) return; } - io->io_Error = unit->au_Read64(unit, block, count, IOStdReq(io)->io_Data, &cnt); + if (unit->au_SectorShift == 9) /* use cache with 512 Byte sectors only */ + { + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + ULONG unitNum = unit->au_UnitNum; + + ULONG start; + ULONG i; + for (start = 0, i = 0; i < count; i++) + { + ULONG blockAdr = (block + i) & CACHE_MASK; + UQUAD blockTag = (block + i) & ~CACHE_MASK; + + if ((unitNum < (1<<9)) && + (base->ata_CacheTags[blockAdr] == (blockTag | unitNum ))) /* cache hit */ + { + CopyMem(base->ata_CacheData + blockAdr*512, IOStdReq(io)->io_Data + i*512, 512); + + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read64(unit, block + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + start = i + 1; + } + } + if (start != i) + { + /* Call the Unit's access funtion */ + io->io_Error = unit->au_Read64(unit, block + start, i - start, + IOStdReq(io)->io_Data + start*512, &cnt); + + if (io->io_Error) + { + IOStdReq(io)->io_Actual = 0; + return; + } + + ULONG blockAdr = (block + start) & CACHE_MASK; + CopyMem(IOStdReq(io)->io_Data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (block + j) & CACHE_MASK; + ULONG blockTag = (block + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + cnt = count << unit->au_SectorShift; + } + else + { + io->io_Error = unit->au_Read64(unit, block, count, IOStdReq(io)->io_Data, &cnt); + } } IOStdReq(io)->io_Actual = cnt; @@ -164,13 +357,6 @@ static void cmd_Write32(struct IORequest *io, LIBBASETYPEPTR LIBBASE) { struct ata_Unit *unit = (struct ata_Unit *)IOStdReq(io)->io_Unit; - if (AF_Removable == (unit->au_Flags & (AF_Removable | AF_DiscPresent))) - { - D(bug("[ATA%02ld] %s: USUALLY YOU'D WANT TO CHECK IF DISC IS PRESENT FIRST\n", unit->au_UnitNum, __func__)); - io->io_Error = TDERR_DiskChanged; - return; - } - ULONG block = IOStdReq(io)->io_Offset; ULONG count = IOStdReq(io)->io_Length; @@ -207,6 +393,14 @@ static void cmd_Write32(struct IORequest *io, LIBBASETYPEPTR LIBBASE) io->io_Error = unit->au_Write32(unit, block, count, IOStdReq(io)->io_Data, &cnt); + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + for (int i = 0; i < count; i++) + { + ULONG blockAdr = (block + i) & CACHE_MASK; + base->ata_CacheTags[blockAdr] = 0xfffffffffffffffful; + } + IOStdReq(io)->io_Actual = cnt; } } @@ -219,13 +413,6 @@ static void cmd_Write64(struct IORequest *io, LIBBASETYPEPTR LIBBASE) { struct ata_Unit *unit = (struct ata_Unit *)IOStdReq(io)->io_Unit; - if (AF_Removable == (unit->au_Flags & (AF_Removable | AF_DiscPresent))) - { - D(bug("[ATA%02ld] %s: USUALLY YOU'D WANT TO CHECK IF DISC IS PRESENT FIRST\n", unit->au_UnitNum, __func__)); - io->io_Error = TDERR_DiskChanged; - return; - } - UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32; ULONG count = IOStdReq(io)->io_Length; @@ -280,8 +467,17 @@ static void cmd_Write64(struct IORequest *io, LIBBASETYPEPTR LIBBASE) io->io_Error = unit->au_Write64(unit, block, count, IOStdReq(io)->io_Data, &cnt); } + + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + for (int i = 0; i < count; i++) + { + ULONG blockAdr = (block + i) & CACHE_MASK; + base->ata_CacheTags[blockAdr] = 0xfffffffffffffffful; + } + IOStdReq(io)->io_Actual = cnt; - } + } } @@ -310,35 +506,6 @@ static void cmd_Flush(struct IORequest *io, LIBBASETYPEPTR LIBBASE) */ static void cmd_TestChanged(struct IORequest *io, LIBBASETYPEPTR LIBBASE) { - struct ata_Unit *unit = (struct ata_Unit *)io->io_Unit; - struct IORequest *msg; - - D(bug("[ATA%02ld] %s()\n", ((struct ata_Unit*)io->io_Unit)->au_UnitNum, __func__)); - - if ((unit->au_XferModes & AF_XFER_PACKET) && (unit->au_Flags & AF_Removable)) - { - atapi_TestUnitOK(unit); - if (unit->au_Flags & AF_DiscChanged) - { - unit->au_ChangeNum++; - - Forbid(); - - /* old-fashioned RemoveInt call first */ - if (unit->au_RemoveInt) - Cause(unit->au_RemoveInt); - - /* And now the whole list of possible calls */ - ForeachNode(&unit->au_SoftList, msg) - { - Cause((struct Interrupt *)IOStdReq(msg)->io_Data); - } - - unit->au_Flags &= ~AF_DiscChanged; - - Permit(); - } - } } static void cmd_Update(struct IORequest *io, LIBBASETYPEPTR LIBBASE) @@ -874,98 +1041,6 @@ AROS_LH1(ULONG, GetBlkSize, * The check is done by sending HD_SCSICMD+1 command (internal testchanged * command). ATAPI units should already handle the command further. */ -void DaemonCode(struct ataBase *ATABase, struct ata_Controller *ataNode) -{ - struct IORequest *timer; // timer - UBYTE b = 0; - ULONG sigs; - - D(bug("[ATA**] ATA DAEMON woke for controller @ 0x%p\n", ataNode)); - - /* - * Prepare message ports and timer.device's request - */ - timer = ata_OpenTimer(ATABase); - if (!timer) - { - D(bug("[ATA++] Failed to open timer!\n")); - - Forbid(); - Signal(ataNode->ac_daemonParent, SIGF_SINGLE); - return; - } - - /* Calibrate 400ns delay */ - if (!ata_Calibrate(timer, ATABase)) - { - ata_CloseTimer(timer); - Forbid(); - Signal(ataNode->ac_daemonParent, SIGF_SINGLE); - return; - } - - /* This also signals that we have initialized successfully */ - ataNode->ac_Daemon = FindTask(NULL); - Signal(ataNode->ac_daemonParent, SIGF_SINGLE); - - D(bug("[ATA++] Starting sweep medium presence detection\n")); - - /* - * Endless loop - */ - do - { - /* - * call separate IORequest for every ATAPI device - * we're calling HD_SCSICMD+1 command here -- anything like test unit ready? - * FIXME: This is not a very nice approach in terms of performance. - * This inserts own command into command queue every 2 seconds, so - * this would give periodic performance drops under high loads. - * It would be much better if unit tasks ping their devices by themselves, - * when idle. This would also save us from lots of headaches with dealing - * with list of these requests. Additionally i start disliking all these - * semaphores. - */ - if (0 == (b & 1)) - { - struct IOStdReq *ios; - - DB2(bug("[ATA++] Detecting media presence\n")); - ObtainSemaphore(&ataNode->DaemonSem); - - ForeachNode(&ataNode->Daemon_ios, ios) - { - /* Using the request will clobber its Node. Save links. */ - struct Node *s = ios->io_Message.mn_Node.ln_Succ; - struct Node *p = ios->io_Message.mn_Node.ln_Pred; - - DoIO((struct IORequest *)ios); - - ios->io_Message.mn_Node.ln_Succ = s; - ios->io_Message.mn_Node.ln_Pred = p; - } - - ReleaseSemaphore(&ataNode->DaemonSem); - } - - /* - * And then hide and wait for 1 second - */ - DB2(bug("[ATA++] 1 second delay, timer 0x%p...\n", timer)); - sigs = ata_WaitTO(timer, 1, 0, SIGBREAKF_CTRL_C); - - DB2(bug("[ATA++] Delay completed\n")); - b++; - } while (!sigs); - - ataNode->ac_Daemon = NULL; - D(bug("[ATA++] Daemon quits\n")); - - ata_CloseTimer(timer); - - Forbid(); - Signal(ataNode->ac_daemonParent, SIGF_SINGLE); -} /* Bus task body. It doesn't really do much. It receives simply all IORequests @@ -983,7 +1058,7 @@ void BusTaskCode(struct ata_Bus *bus, struct ataBase *ATABase) DINIT(bug("[ATA**] Task started (bus: %u)\n", bus->ab_BusNum)); bus->ab_Timer = ata_OpenTimer(ATABase); - bus->ab_BounceBufferPool = CreatePool(MEMF_CLEAR | MEMF_31BIT, 131072, 65536); +// bus->ab_BounceBufferPool = CreatePool(MEMF_CLEAR | MEMF_31BIT, 131072, 65536); /* Get the signal used for sleeping */ bus->ab_Task = FindTask(0); @@ -1020,27 +1095,6 @@ void BusTaskCode(struct ata_Bus *bus, struct ataBase *ATABase) ata_RegisterVolume(0, 0, unit); OOP_GetAttr(bus->ab_Object, aHidd_ATABus_Controller, (IPTR *)&ataNode); - if (ataNode) - { - /* For ATAPI device we also submit media presence detection request */ - unit->DaemonReq = (struct IOStdReq *)CreateIORequest(ataNode->DaemonPort, sizeof(struct IOStdReq)); - if (unit->DaemonReq) - { - /* - * We don't want to keep stalled open count of 1, so we - * don't call OpenDevice() here. Instead we fill in the needed - * fields manually. - */ - unit->DaemonReq->io_Device = &ATABase->ata_Device; - unit->DaemonReq->io_Unit = &unit->au_Unit; - unit->DaemonReq->io_Command = HD_SCSICMD+1; - - ObtainSemaphore(&ataNode->DaemonSem); - AddTail((struct List *)&ataNode->Daemon_ios, - &unit->DaemonReq->io_Message.mn_Node); - ReleaseSemaphore(&ataNode->DaemonSem); - } - } } else { diff --git a/rom/devs/ata/ata.h b/rom/devs/ata/ata.h index ad4897e7acb..54ee6cda4be 100644 --- a/rom/devs/ata/ata.h +++ b/rom/devs/ata/ata.h @@ -38,6 +38,9 @@ #define STACK_SIZE 16384 #define TASK_PRI 10 #define TIMEOUT 30 +#define CACHE_SIZE_BITS 17 /* 2^11 * 512 byte blocks (min 9)*/ +#define CACHE_SIZE (1<ac_Class = cl; data->ac_Object = ataController; - /* Try to setup daemon task looking for diskchanges */ - NEWLIST(&data->Daemon_ios); - InitSemaphore(&data->DaemonSem); - data->ac_daemonParent = FindTask(NULL); - SetSignal(0, SIGF_SINGLE); - - if (!NewCreateTask(TASKTAG_PC, DaemonCode, - TASKTAG_NAME , "ATA.daemon", - TASKTAG_STACKSIZE , STACK_SIZE, - TASKTAG_TASKMSGPORT, &data->DaemonPort, - TASKTAG_PRI , TASK_PRI - 1, /* The daemon should have a little bit lower Pri than handler tasks */ - TASKTAG_ARG1 , ATABase, - TASKTAG_ARG2 , data, - TAG_DONE)) - { - bug("[ATA:Controller] %s: Failed to start up daemon!\n", __func__); - return FALSE; - } - - /* Wait for handshake */ - Wait(SIGF_SINGLE); - D(bug("[ATA:Controller] %s: Daemon task set to 0x%p\n", __func__, data->ata_Daemon)); - AddTail(&ATABase->ata_Controllers, &data->ac_Node); } return ataController; @@ -78,12 +55,6 @@ VOID ATA__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) { if (ataNode->ac_Object == o) { - D(bug("[ATA:Controller] %s: Stopping Daemon...\n", __func__)); - ataNode->ac_daemonParent = FindTask(NULL); - SetSignal(0, SIGF_SINGLE); - Signal(ataNode->ac_Daemon, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - D(bug("[ATA:Controller] %s: Daemon stopped\n", __func__)); D(bug ("[ATA:Controller] %s: Destroying Controller Entry @ 0x%p\n", __func__, ataNode);) Remove(&ataNode->ac_Node); diff --git a/rom/devs/ata/ata_init.c b/rom/devs/ata/ata_init.c index dd060588a2a..cdb54c54b87 100644 --- a/rom/devs/ata/ata_init.c +++ b/rom/devs/ata/ata_init.c @@ -218,6 +218,31 @@ static int ATA_init(struct ataBase *ATABase) D(bug("[ATA--] %s: MemPool @ %p\n", __func__, ATABase->ata_MemPool)); + /* + * ata drive cache memory allocation + */ + ATABase->ata_CacheData = AllocMem(CACHE_SIZE*512, MEMF_CLEAR | MEMF_PUBLIC); + if (ATABase->ata_CacheData == NULL) + { + bug("[ATA--] %s: Failed to Allocate CacheData!\n", __func__); + return FALSE; + } + + D(bug("[ATA--] %s: CacheData @ %p\n", __func__, ATABase->ata_CacheData)); + + ATABase->ata_CacheTags = AllocMem(CACHE_SIZE*8, MEMF_CLEAR | MEMF_PUBLIC); + if (ATABase->ata_CacheTags == NULL) + { + bug("[ATA--] %s: Failed to Allocate CacheTags!\n", __func__); + return FALSE; + } + for (int i = 0; i < CACHE_SIZE; i++) + { + ATABase->ata_CacheTags[i] = 0xfffffffffffffffful; + } + + D(bug("[ATA--] %s: CacheTags @ %p\n", __func__, ATABase->ata_CacheTags)); + #if defined(__OOP_NOATTRBASES__) if (OOP_ObtainAttrBasesArray(&ATABase->unitAttrBase, attrBaseIDs)) { diff --git a/rom/devs/ata/include/hardware/ata.h b/rom/devs/ata/include/hardware/ata.h index 7373c49f77e..52a6aab91ed 100644 --- a/rom/devs/ata/include/hardware/ata.h +++ b/rom/devs/ata/include/hardware/ata.h @@ -42,6 +42,7 @@ #define ATAB_ERROR 0 #define ATAB_BUSY 7 +#define ATAF_DF 0x20 #define ATAF_SLAVE 0x10 #define ATAF_LBA 0x40 #define ATAF_ATAPI 0x80 diff --git a/rom/devs/ata/lowlevel.c b/rom/devs/ata/lowlevel.c index 35c5c849eba..ab709645df9 100644 --- a/rom/devs/ata/lowlevel.c +++ b/rom/devs/ata/lowlevel.c @@ -53,14 +53,10 @@ static BYTE ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); static BYTE ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); static BYTE ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); static BYTE ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); -static BYTE ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); -static BYTE ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); static BYTE ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); static BYTE ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); static BYTE ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); static BYTE ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); -static BYTE ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *); -static BYTE ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *); static void ata_ResetBus(struct ata_Bus *bus); static BYTE ata_Eject(struct ata_Unit *); static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, @@ -181,6 +177,9 @@ static void ata_IRQSetHandler(struct ata_Unit *unit, static void ata_IRQNoData(struct ata_Unit *unit, UBYTE status) { + volatile UBYTE *port=0xDA201C; + status = *port; + if (status & ATAF_BUSY) return; @@ -192,14 +191,46 @@ static void ata_IRQNoData(struct ata_Unit *unit, UBYTE status) ata_IRQSignalTask(unit->au_Bus); } -static void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status) +static void ata_NULL(struct ata_Unit *unit, UBYTE status) { - if (status & ATAF_DATAREQ) - { - DIRQ(bug("[ATA%02ld] IRQ: PIOReadData - DRQ.\n", unit->au_UnitNum)); + return; +} - Unit_InS(unit, unit->au_cmd_data, unit->au_cmd_length); +static void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status) +{ + ULONG count; + APTR address; + volatile UBYTE *port=0xDA201C; + long retrycount; + +AGAIN: + retrycount=100000000; + if (status & ATAF_BUSY){ +WAITBUSY: + status = *port; + retrycount--; + if (retrycount=0){ + unit->au_cmd_error = HFERR_BadStatus; + return; + } + if (status & ATAF_BUSY) goto WAITBUSY; + } + + if (status & ATAF_DATAREQ){ +// Unit_InS(unit, unit->au_cmd_data, unit->au_cmd_length); + + count = (unit->au_cmd_length>>5); + address = unit->au_cmd_data; + + asm volatile( + " bra 2f \n" + "1: move16 (0xDA6000),(%[address])+ \n" + " move16 (0xDA6000),(%[address])+ \n" + "2: dbra %[count],1b \n" + :[count]"+d"(count),[address]"+a"(address)::"cc"); + +// /* * Adjust data pointer and counter. If there's more data left for * this transfer, keep same handler and wait for next interrupt @@ -210,14 +241,21 @@ static void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status) { if (unit->au_cmd_length > unit->au_cmd_total) unit->au_cmd_length = unit->au_cmd_total; - return; + + status = *port; + goto AGAIN; } - DIRQ(bug("[ATA%02ld] IRQ: PIOReadData - transfer completed.\n", - unit->au_UnitNum)); - } - else + + }else{ unit->au_cmd_error = HFERR_BadStatus; + } + ata_IRQNoData(unit, status); + + // if (status & (ATAF_DF | ATAF_ERROR)){ + // unit->au_cmd_error = HFERR_BadStatus; + // } + } static void ata_PIOWriteBlk(struct ata_Unit *unit) @@ -235,43 +273,70 @@ static void ata_PIOWriteBlk(struct ata_Unit *unit) static void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status) { + + volatile UBYTE *port=0xDA201C; + ULONG count; + APTR address; + long retrycount; /* * If there's more data left for this transfer, write it, keep same * handler and wait for next interrupt */ - if (status & ATAF_DATAREQ) { - DIRQ(bug("[ATA%02ld] IRQ: PIOWriteData - DRQ.\n", unit->au_UnitNum)); - ata_PIOWriteBlk(unit); - return; +AGAINW: + retrycount=100000000; + if (status & ATAF_BUSY){ +WAITBUSYW: + status = *port; + retrycount--; + if (retrycount=0){ + unit->au_cmd_error = HFERR_BadStatus; + return; + } + if (status & ATAF_BUSY) goto WAITBUSYW; } - else if (unit->au_cmd_total != 0) + + if (status & ATAF_DATAREQ) { + DIRQ(bug("[ATA%02ld] IRQ: PIOWriteData - DRQ.\n", unit->au_UnitNum)); + +// ata_PIOWriteBlk(unit); + count = unit->au_cmd_length>>3; + address = unit->au_cmd_data; + + asm volatile( + " bra 2f \n" + "1: move.l (%[address])+,(0xDA2000) \n" + " move.l (%[address])+,(0xDA2000) \n" + "2: dbra %[count],1b \n" + :[count]"+d"(count),[address]"+a"(address)::"cc"); + + + unit->au_cmd_data += unit->au_cmd_length; + unit->au_cmd_total -= unit->au_cmd_length; + if (unit->au_cmd_length > unit->au_cmd_total){ + unit->au_cmd_length = unit->au_cmd_total; + } + + if (unit->au_cmd_total != 0){ + status = *port; + goto AGAINW; + } + + }else if (unit->au_cmd_total != 0){ unit->au_cmd_error = HFERR_BadStatus; + } + + + DIRQ(bug("[ATA%02ld] IRQ: PIOWriteData - done.\n", unit->au_UnitNum)); ata_IRQNoData(unit, status); + // if (status & (ATAF_DF | ATAF_ERROR)){ + // unit->au_cmd_error = HFERR_BadStatus; + // } + } -static void ata_IRQDMAReadWrite(struct ata_Unit *unit, UBYTE status) + static void ata_IRQDMAReadWrite(struct ata_Unit *unit, UBYTE status) { - struct ata_Bus *bus = unit->au_Bus; - ULONG stat = DMA_GetResult(bus); - - DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", unit->au_UnitNum, status, stat)); - - if ((status & ATAF_ERROR) || stat) - { - /* This is turned on in order to help Phantom - Pavel Fedin */ - DERROR(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %d\n", unit->au_UnitNum, status, stat)); - DERROR(bug("[ATA%02ld] IRQ: ERROR %02lx\n", unit->au_UnitNum, PIO_In(bus, atapi_Error))); - DERROR(bug("[ATA%02ld] IRQ: DMA Failed.\n", unit->au_UnitNum)); - - unit->au_cmd_error = stat; - ata_IRQNoData(unit, status); - } - else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ))) - { - DIRQ(bug("[ATA%02ld] IRQ: DMA Done.\n", unit->au_UnitNum)); - ata_IRQNoData(unit, status); - } } static void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status) @@ -380,43 +445,43 @@ static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, if (bus->ab_Base->ata_Poll) irq = FALSE; - if (irq) - { - /* Do not read ata_Status in irq mode. It can cause random lost interrupts. */ - if (bus->haveAltIO) - status = PIO_InAlt(bus, ata_AltStatus); - /* - * wait for either IRQ or timeout - */ - DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", - unit->au_UnitNum, status)); - step = ata_WaitTO(unit->au_Bus->ab_Timer, tout, 0, - 1 << bus->ab_SleepySignal); - - if (step == 0) - { - DERROR(bug("[ATA%02ld] Timeout while waiting for device to complete" - " operation\n", unit->au_UnitNum)); - - Disable(); - if (fake_irq) - { - /* fake the interrupt we expected */ - status = PIO_In(bus, ata_Status); - while (unit->au_Bus->ab_HandleIRQ != NULL) - unit->au_Bus->ab_HandleIRQ(unit, status); - } - else - { - /* do nothing if the interrupt eventually arrives */ - ata_IRQSetHandler(unit, NULL, NULL, 0, 0); - res = FALSE; - } - Enable(); - } - } - else - { +// if (irq) +// { +// /* Do not read ata_Status in irq mode. It can cause random lost interrupts. */ +// if (bus->haveAltIO) +// status = PIO_InAlt(bus, ata_AltStatus); +// /* +// * wait for either IRQ or timeout +// */ +// DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", +// unit->au_UnitNum, status)); +// step = ata_WaitTO(unit->au_Bus->ab_Timer, tout, 0, +// 1 << bus->ab_SleepySignal); +// +// if (step == 0) +// { +// DERROR(bug("[ATA%02ld] Timeout while waiting for device to complete" +// " operation\n", unit->au_UnitNum)); +// +// Disable(); +// if (fake_irq) +// { +// /* fake the interrupt we expected */ +// status = PIO_In(bus, ata_Status); +// while (unit->au_Bus->ab_HandleIRQ != NULL) +// unit->au_Bus->ab_HandleIRQ(unit, status); +// } +// else +// { +// /* do nothing if the interrupt eventually arrives */ +// ata_IRQSetHandler(unit, NULL, NULL, 0, 0); +// res = FALSE; +// } +// Enable(); +// } +// } +// else +// { status = PIO_InAlt(bus, ata_AltStatus); while (status & ATAF_BUSY) { @@ -426,6 +491,7 @@ static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, * every 16n rounds do some extra stuff */ if ((step & 15) == 0) + // if (1 == 0) { /* * huhm. so it's been 16n rounds already. any timeout yet? @@ -447,7 +513,7 @@ static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, status = PIO_InAlt(bus, ata_AltStatus); } - } +// } /* * get final status and clear any interrupt (may be neccessary if we @@ -488,6 +554,8 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) BYTE err = 0; APTR mem = block->buffer; UBYTE status; + volatile WORD *irqreg=0xDA9000; + volatile WORD *irqen=0xDAA000; /* * Use a short timeout for Identify commands. This is because some bad @@ -546,6 +614,8 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) if (block->feature != 0) PIO_Out(bus, block->feature, ata_Feature); + ULONG piolen = block->length; + ULONG blklen = block->secmul << unit->au_SectorShift; /* * - set LBA and sector count */ @@ -601,27 +671,17 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) switch (block->method) { case CM_PIOWrite: - ata_IRQSetHandler(unit, &ata_IRQPIOWrite, mem, block->secmul << unit->au_SectorShift, block->length); +// ata_IRQSetHandler(unit, &ata_IRQPIOWrite, mem, block->secmul << unit->au_SectorShift, block->length); break; case CM_PIORead: - ata_IRQSetHandler(unit, &ata_IRQPIORead, mem, block->secmul << unit->au_SectorShift, block->length); + //ata_IRQSetHandler(unit, &ata_IRQPIORead, mem, block->secmul << unit->au_SectorShift, block->length); break; case CM_DMARead: - if (FALSE == DMA_Setup(bus, mem, block->length, TRUE)) - return IOERR_ABORTED; - - ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0); - DMA_Start(bus); break; case CM_DMAWrite: - if (FALSE == DMA_Setup(bus, mem, block->length, FALSE)) - return IOERR_ABORTED; - - ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0); - DMA_Start(bus); break; case CM_NoData: @@ -639,31 +699,65 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) */ DATA(bug("[ATA%02ld] ata_exec_cmd: Sending command\n", unit->au_UnitNum)); - PIO_Out(bus, block->command, ata_Command); - ata_WaitNano(400, bus->ab_Base); - //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0); + if (block->method == CM_PIORead) { + *irqen=0x0000; + PIO_OutAlt(bus, ATACTLF_INT_DISABLE, ata_AltControl); + PIO_Out(bus, block->command, ata_Command); + + ata_WaitNano(400, bus->ab_Base); + + unit->au_cmd_error = 0; + unit->au_cmd_data = mem; + piolen = block->length; + blklen = block->secmul << unit->au_SectorShift; + unit->au_cmd_length = (piolen < blklen) ? piolen : blklen; + unit->au_cmd_total = piolen; + ata_IRQPIORead(unit, ATAF_BUSY); + *irqreg=0x0000; + + }else if (block->method == CM_PIOWrite) { + *irqen=0x0000; + PIO_OutAlt(bus, ATACTLF_INT_DISABLE, ata_AltControl); + PIO_Out(bus, block->command, ata_Command); + + ata_WaitNano(400, bus->ab_Base); + + unit->au_cmd_error = 0; + unit->au_cmd_data = mem; + piolen = block->length; + blklen = block->secmul << unit->au_SectorShift; + unit->au_cmd_length = (piolen < blklen) ? piolen : blklen; + unit->au_cmd_total = piolen; + ata_IRQPIOWrite(unit, ATAF_BUSY); + + }else{ + // *irqen=0x8000; + // PIO_OutAlt(bus, 0x0, ata_AltControl); + PIO_Out(bus, block->command, ata_Command); + + }; /* * In case of PIO write the drive won't issue an IRQ before first * data transfer, so we should poll the status and send the first * block upon request. */ - if (block->method == CM_PIOWrite) - { - if (FALSE == ata_WaitBusyTO(unit, TIMEOUT, FALSE, FALSE, &status)) { - DERROR(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - no response from device. Status %02X\n", unit->au_UnitNum, status)); - return IOERR_UNITBUSY; - } - if (status & ATAF_DATAREQ) { - DATA(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - DRQ.\n", unit->au_UnitNum)); - ata_PIOWriteBlk(unit); - } - else - { - DERROR(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - bad status: %02X\n", status)); - return HFERR_BadStatus; - } - } +// if (block->method == CM_PIOWrite) +// { +// if (FALSE == ata_WaitBusyTO(unit, TIMEOUT, FALSE, FALSE, &status)) { +// DERROR(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - no response from device. Status %02X\n", unit->au_UnitNum, status)); +// return IOERR_UNITBUSY; +// } +// if (status & ATAF_DATAREQ) { +// DATA(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - DRQ.\n", unit->au_UnitNum)); +// ata_PIOWriteBlk(unit); +// } +// else +// { +// DERROR(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - bad status: %02X\n", status)); +// return HFERR_BadStatus; +// } +// } /* * wait for drive to complete what it has to do @@ -678,23 +772,6 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) DATA(bug("[ATA%02ld] ata_exec_cmd: Command done\n", unit->au_UnitNum)); - /* - * clean up DMA - * don't use 'mem' pointer here as it's already invalid. - */ - switch (block->method) - { - case CM_DMARead: - DMA_End(bus, block->buffer, block->length, TRUE); - break; - - case CM_DMAWrite: - DMA_End(bus, block->buffer, block->length, FALSE); - break; - - default: - break; /* Shut up the compiler */ - } D(bug("[ATA%02ld] ata_exec_cmd: return code %ld\n", unit->au_UnitNum, err)); return err; @@ -795,8 +872,6 @@ static BYTE atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, */ if (datalen == 0) ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0); - else if (*dma) - ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0); else if (write) ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, 0, datalen); else @@ -838,41 +913,6 @@ static BYTE atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, static BYTE atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd) { - APTR buffer = cmd->scsi_Data; - ULONG length = cmd->scsi_Length; - BYTE err = 0; - BOOL dma = FALSE; - - cmd->scsi_Actual = 0; - - DATAPI(bug("[DSCSI] Sending packet!\n")); - - /* - * setup DMA & push command - * it does not really mean we will use dma here btw - */ - if ((unit->au_Flags & AF_DMA) && (length !=0) && (buffer != 0)) - { - dma = DMA_Setup(unit->au_Bus, buffer, length, - cmd->scsi_Flags & SCSIF_READ); - } - - err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0); - - DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); }); - - /* - * on check condition - grab sense data - */ - DATAPI(bug("[ATA%02lx] atapi_DirectSCSI: SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err)); - if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE)) - { - DATAPI(bug("[DSCSI] atapi_DirectSCSI: Packet Failed. Calling atapi_RequestSense\n")); - atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength); - DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength)); - } - - return err; } /* @@ -886,22 +926,11 @@ static BYTE ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk) ULONG max=256; ULONG count=blk->sectors; APTR buffer = blk->buffer; - APTR bounce_buffer = NULL; IPTR bounce_buffer_length = 0; if (blk->type == CT_LBA48) max <<= 8; - if (((IPTR)blk->buffer > 0xffffffffULL || ((IPTR)blk->buffer + (count << unit->au_SectorShift)) > 0xffffffffULL) && - (blk->method == CM_DMARead || blk->method == CM_DMAWrite)) - { - DATA(bug("[ATA%02ld] ata_exec_blk: attempt to do DMA transfer outside 32bit address space\n", unit->au_UnitNum)); - DATA(bug("[ATA%02ld] ata_exec_blk: ptr %p, length %d, %s\n", unit->au_UnitNum, blk->buffer, count << unit->au_SectorShift, blk->method == CM_DMARead ? "DMARead" : "DMAWrite")); - - bounce_buffer_length = count << unit->au_SectorShift; - bounce_buffer = AllocPooled(unit->au_Bus->ab_BounceBufferPool, bounce_buffer_length); - blk->buffer = bounce_buffer; - } DATA(bug("[ATA%02ld] ata_exec_blk: Accessing %ld sectors starting from %x%08x\n", unit->au_UnitNum, count, (ULONG)(blk->blk >> 32), (ULONG)blk->blk)); while ((count > 0) && (err == 0)) @@ -912,33 +941,14 @@ static BYTE ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk) DATA(bug("[ATA%02ld] Transfer of %ld sectors from %x%08x\n", unit->au_UnitNum, part, (ULONG)(blk->blk >> 32), (ULONG)blk->blk)); // If bounce buffer is active, - if (bounce_buffer && blk->method == CM_DMAWrite) - { - DATA(bug("[ATA%02ld] Copy %d bytes from source %p to bounce buffer %p\n", unit->au_UnitNum, blk->length, buffer, bounce_buffer)); - CopyMemQuick(buffer, bounce_buffer, blk->length); - buffer = (APTR)((IPTR)buffer + blk->length); - } err = ata_exec_cmd(unit, blk); DATA(bug("[ATA%02ld] ata_exec_blk: ata_exec_cmd returned %lx\n", unit->au_UnitNum, err)); - if (bounce_buffer) - { - if (blk->method == CM_DMARead) - { - DATA(bug("[ATA%02ld] Copy %d bytes from bounce buffer %p to destination %p\n", unit->au_UnitNum, blk->length, bounce_buffer, buffer)); - CopyMemQuick(bounce_buffer, buffer, part << unit->au_SectorShift); - buffer = (APTR)((IPTR)buffer + (part << unit->au_SectorShift)); - } - } - else - { - blk->buffer = (APTR)((IPTR)blk->buffer + (part << unit->au_SectorShift)); - } + blk->buffer = (APTR)((IPTR)blk->buffer + (part << unit->au_SectorShift)); + blk->blk += part; count -= part; } - if (bounce_buffer) - FreePooled(unit->au_Bus->ab_BounceBufferPool, bounce_buffer, bounce_buffer_length); return err; } @@ -1001,7 +1011,7 @@ BOOL ata_setup_unit(struct ata_Bus *bus, struct ata_Unit *unit) } DINIT(bug("[ATA ] ata_setup_unit: Enabling IRQs\n")); - PIO_OutAlt(bus, 0x0, ata_AltControl); +// PIO_OutAlt(bus, 0x0, ata_AltControl); /* * now make unit self diagnose @@ -1065,19 +1075,7 @@ static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode) */ if (0 == (unit->au_XferModes & AF_XFER_PACKET)) { - if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_UDMA6)) - { - /* DMA, both multiword and Ultra */ - unit->au_Read32 = ata_ReadDMA32; - unit->au_Write32 = ata_WriteDMA32; - if (unit->au_XferModes & AF_XFER_48BIT) - { - unit->au_UseModes |= AF_XFER_48BIT; - unit->au_Read64 = ata_ReadDMA64; - unit->au_Write64 = ata_WriteDMA64; - } - } - else if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI)) + if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI)) { /* Multisector PIO */ ata_IRQSetHandler(unit, ata_IRQNoData, NULL, 0, 0); @@ -1161,139 +1159,10 @@ static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode) static void common_SetBestXferMode(struct ata_Unit* unit) { - struct ata_Bus *bus = unit->au_Bus; - struct ataBase *ATABase = bus->ab_Base; - OOP_Object *obj = OOP_OBJECT(ATABase->busClass, bus); - int iter; - int max = AB_XFER_UDMA6; - - if ((!bus->dmaInterface) - || ( !(unit->au_Drive->id_MWDMASupport & 0x0700) - && !(unit->au_Drive->id_UDMASupport & 0x7f00))) - { - /* - * make sure you reduce scan search to pio here! - * otherwise this and above function will fall into infinite loop - */ - DINIT(bug("[ATA%02ld] common_SetBestXferMode: DMA is disabled for" - " this drive.\n", unit->au_UnitNum)); - max = AB_XFER_PIO4; - } - else if (!OOP_GET(obj, aHidd_ATABus_Use80Wire)) - { - DINIT(bug("[ATA%02ld] common_SetBestXferMode: " - "An 80-wire cable has not been detected for this drive. " - "Disabling modes above UDMA2.\n", unit->au_UnitNum)); - max = AB_XFER_UDMA2; - } - - for (iter=max; iter>=AB_XFER_PIO0; --iter) - { - if (unit->au_XferModes & (1<au_UnitNum); - common_SetXferMode(unit, AB_XFER_PIO0); } static void common_DetectXferModes(struct ata_Unit* unit) { - int iter; - - DINIT(bug("[ATA%02ld] common_DetectXferModes: Supports\n", unit->au_UnitNum)); - - if (unit->au_Drive->id_Commands4 & (1 << 4)) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - Packet interface\n", unit->au_UnitNum)); - unit->au_XferModes |= AF_XFER_PACKET; - unit->au_DirectSCSI = atapi_DirectSCSI; - } - else if (unit->au_Drive->id_Commands5 & (1 << 10)) - { - /* ATAPI devices do not use this bit. */ - DINIT(bug("[ATA%02ld] common_DetectXferModes: - 48bit I/O\n", unit->au_UnitNum)); - unit->au_XferModes |= AF_XFER_48BIT; - } - - if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9))) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - LBA Addressing\n", unit->au_UnitNum)); - unit->au_XferModes |= AF_XFER_LBA; - unit->au_UseModes |= AF_XFER_LBA; - } - else - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum)); - unit->au_Flags |= AF_CHSOnly; - } - - if (unit->au_Drive->id_RWMultipleSize & 0xff) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff)); - unit->au_XferModes |= AF_XFER_RWMULTI; - } - - DINIT(bug("[ATA%02ld] common_DetectXferModes: - PIO0 PIO1 PIO2 ", - unit->au_UnitNum)); - unit->au_XferModes |= AF_XFER_PIO(0) | AF_XFER_PIO(1) | AF_XFER_PIO(2); - if (unit->au_Drive->id_ConfigAvailable & (1 << 1)) - { - for (iter = 0; iter < 2; iter++) - { - if (unit->au_Drive->id_PIOSupport & (1 << iter)) - { - DINIT(bug("PIO%ld ", 3 + iter)); - unit->au_XferModes |= AF_XFER_PIO(3 + iter); - } - } - DINIT(bug("\n")); - } - - if ((unit->au_Drive->id_ConfigAvailable & (1 << 1)) && - (unit->au_Drive->id_Capabilities & (1<<8))) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: DMA:\n", unit->au_UnitNum)); - if (unit->au_Drive->id_MWDMASupport & 0xff) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum)); - for (iter = 0; iter < 3; iter++) - { - if (unit->au_Drive->id_MWDMASupport & (1 << iter)) - { - unit->au_XferModes |= AF_XFER_MDMA(iter); - if (unit->au_Drive->id_MWDMASupport & (256 << iter)) - { - unit->au_UseModes |= AF_XFER_MDMA(iter); - DINIT(bug("[MDMA%ld] ", iter)); - } - DINIT(else bug("MDMA%ld ", iter);) - } - } - DINIT(bug("\n")); - } - - if (unit->au_Drive->id_UDMASupport & 0xff) - { - DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum)); - for (iter = 0; iter < 7; iter++) - { - if (unit->au_Drive->id_UDMASupport & (1 << iter)) - { - unit->au_XferModes |= AF_XFER_UDMA(iter); - if (unit->au_Drive->id_UDMASupport & (256 << iter)) - { - unit->au_UseModes |= AF_XFER_UDMA(iter); - DINIT(bug("[UDMA%ld] ", iter)); - } - DINIT(else bug("UDMA%ld ", iter);) - } - } - DINIT(bug("\n")); - } - } } #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x)) @@ -1343,27 +1212,7 @@ static BYTE ata_Identify(struct ata_Unit *unit) unit->au_Bus->ab_Dev[unit->au_UnitNum & 1])); } - /* - * If every second word is zero with 32-bit reads, switch to 16-bit - * accesses for this drive and try again - */ - if (unit->au_Bus->ab_Base->ata_32bit) - { - for (p = (UWORD *)unit->au_Drive, limit = p + 256; p < limit; p++) - n |= *++p; - - if (n == 0) - { - DINIT(bug("[ATA%02ld] Identify data was invalid with 32-bit reads." - " Switching to 16-bit mode.\n", unit->au_UnitNum)); - - Unit_Disable32Bit(unit); - - if (ata_exec_cmd(unit, &acb)) - return IOERR_OPENFAIL; - } - } - +// needed GUNNAR! #if (AROS_BIG_ENDIAN != 0) SWAP_LE_WORD(unit->au_Drive->id_General); SWAP_LE_WORD(unit->au_Drive->id_OldCylinders); @@ -1417,22 +1266,12 @@ static BYTE ata_Identify(struct ata_Unit *unit) SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors); #endif + + + + DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent))); - if (atapi) - { - unit->au_SectorShift = 11; - unit->au_Read32 = atapi_Read; - unit->au_Write32 = atapi_Write; - unit->au_DirectSCSI = atapi_DirectSCSI; - unit->au_Eject = atapi_Eject; - unit->au_Flags |= AF_DiscChanged; - unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f; - unit->au_XferModes = AF_XFER_PACKET; - unit->au_UseModes |= AF_XFER_PACKET; /* OR because this field may already contain AF_XFER_PIO32 */ - } - else - { unit->au_SectorShift = 9; unit->au_DevType = DG_DIRECT_ACCESS; unit->au_Read32 = ata_ReadSector32; @@ -1440,21 +1279,15 @@ static BYTE ata_Identify(struct ata_Unit *unit) unit->au_Eject = ata_Eject; unit->au_XferModes = 0; unit->au_Flags |= AF_DiscPresent | AF_DiscChanged; - } + ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40); ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20); ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8); bug("[ATA%02ld] ata_Identify: Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev); - common_DetectXferModes(unit); - common_SetBestXferMode(unit); - - if (unit->au_Drive->id_General & 0x80) - { - DINIT(bug("[ATA%02ld] ata_Identify: Device is removable.\n", unit->au_UnitNum)); - unit->au_Flags |= AF_Removable; - } + //common_DetectXferModes(unit); + //common_SetBestXferMode(unit); supportLBA = (unit->au_Drive->id_Capabilities & (1 << 9)) != 0; supportLBA48 = supportLBA && (unit->au_Drive->id_Commands5 & (1 << 10)) != 0; @@ -1469,43 +1302,6 @@ static BYTE ata_Identify(struct ata_Unit *unit) unit->au_UnitNum, supportLBA48 ? 48 : (supportLBA ? 28 : 0), unit->au_Capacity, (ULONG)(unit->au_Capacity48 >> 32), (ULONG)(unit->au_Capacity48 & 0xfffffffful))); - if (atapi) - { - /* - * ok, this is not very original, but quite compatible :P - */ - switch (unit->au_DevType) - { - case DG_CDROM: - case DG_WORM: - case DG_OPTICAL_DISK: - unit->au_SectorShift = 11; - unit->au_Heads = 1; - unit->au_Sectors = 75; - unit->au_Cylinders = 4440; - break; - - case DG_DIRECT_ACCESS: - unit->au_SectorShift = 9; - if (!strcmp("LS-120", &unit->au_Model[0])) - { - unit->au_Heads = 2; - unit->au_Sectors = 18; - unit->au_Cylinders = 6848; - } - else if (!strcmp("ZIP 100 ", &unit->au_Model[8])) - { - unit->au_Heads = 1; - unit->au_Sectors = 64; - unit->au_Cylinders = 3072; - } - break; - } - - atapi_TestUnitOK(unit); - } - else - { /* For drive capacities > 8.3GB assume maximal possible layout. It really doesn't matter here, as BIOS will not handle them in @@ -1566,7 +1362,7 @@ static BYTE ata_Identify(struct ata_Unit *unit) unit->au_Capacity48 = unit->au_Capacity; } } - } + DINIT(bug("[ATA%02ld] ata_Identify: Unit CHS: %d/%d/%d\n", unit->au_UnitNum, unit->au_Cylinders, unit->au_Heads, unit->au_Sectors)); @@ -1634,34 +1430,6 @@ static BYTE ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, return 0; } -static BYTE ata_ReadDMA32(struct ata_Unit *unit, ULONG block, - ULONG count, APTR buffer, ULONG *act) -{ - BYTE err; - ata_CommandBlock acb = - { - ATA_READ_DMA, - 0, - 1, - 0, - block, - count, - buffer, - count << unit->au_SectorShift, - 0, - CM_DMARead, - (unit->au_Flags & AF_CHSOnly) ? CT_CHS : CT_LBA28, - }; - - D(bug("[ATA%02ld] ata_ReadDMA32()\n", unit->au_UnitNum)); - - *act = 0; - if (0 != (err = ata_exec_blk(unit, &acb))) - return err; - - *act = count << unit->au_SectorShift; - return 0; -} /* * ata read64 commands @@ -1724,34 +1492,6 @@ static BYTE ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, return 0; } -static BYTE ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, - ULONG count, APTR buffer, ULONG *act) -{ - ata_CommandBlock acb = - { - ATA_READ_DMA64, - 0, - 1, - 0, - block, - count, - buffer, - count << unit->au_SectorShift, - 0, - CM_DMARead, - CT_LBA48 - }; - BYTE err; - - D(bug("[ATA%02ld] ata_ReadDMA64()\n", unit->au_UnitNum)); - - *act = 0; - if (0 != (err = ata_exec_blk(unit, &acb))) - return err; - - *act = count << unit->au_SectorShift; - return 0; -} /* * ata write32 commands @@ -1814,34 +1554,6 @@ static BYTE ata_WriteMultiple32(struct ata_Unit *unit, ULONG block, return 0; } -static BYTE ata_WriteDMA32(struct ata_Unit *unit, ULONG block, - ULONG count, APTR buffer, ULONG *act) -{ - ata_CommandBlock acb = - { - ATA_WRITE_DMA, - 0, - 1, - 0, - block, - count, - buffer, - count << unit->au_SectorShift, - 0, - CM_DMAWrite, - (unit->au_Flags & AF_CHSOnly) ? CT_CHS : CT_LBA28, - }; - BYTE err; - - D(bug("[ATA%02ld] ata_WriteDMA32()\n", unit->au_UnitNum)); - - *act = 0; - if (0 != (err = ata_exec_blk(unit, &acb))) - return err; - - *act = count << unit->au_SectorShift; - return 0; -} /* * ata write64 commands @@ -1904,34 +1616,6 @@ static BYTE ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, return 0; } -static BYTE ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, - ULONG count, APTR buffer, ULONG *act) -{ - ata_CommandBlock acb = - { - ATA_WRITE_DMA64, - 0, - 1, - 0, - block, - count, - buffer, - count << unit->au_SectorShift, - 0, - CM_DMAWrite, - CT_LBA48 - }; - BYTE err; - - D(bug("[ATA%02ld] ata_WriteDMA64()\n", unit->au_UnitNum)); - - *act = 0; - if (0 != (err = ata_exec_blk(unit, &acb))) - return err; - - *act = count << unit->au_SectorShift; - return 0; -} /* * ata miscellaneous commands @@ -2020,93 +1704,20 @@ int atapi_TestUnitOK(struct ata_Unit *unit) static BYTE atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act) { - UBYTE cmd[] = { - SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0 - }; - struct SCSICmd sc = { - 0 - }; - - D(bug("[ATA%02ld] atapi_Read()\n", unit->au_UnitNum)); - - sc.scsi_Command = (void*) &cmd; - sc.scsi_CmdLength = sizeof(cmd); - sc.scsi_Data = buffer; - sc.scsi_Length = count << unit->au_SectorShift; - sc.scsi_Flags = SCSIF_READ; - - return unit->au_DirectSCSI(unit, &sc); } static BYTE atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act) { - UBYTE cmd[] = { - SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0 - }; - struct SCSICmd sc = { - 0 - }; - - D(bug("[ATA%02ld] atapi_Write()\n", unit->au_UnitNum)); - - sc.scsi_Command = (void*) &cmd; - sc.scsi_CmdLength = sizeof(cmd); - sc.scsi_Data = buffer; - sc.scsi_Length = count << unit->au_SectorShift; - sc.scsi_Flags = SCSIF_WRITE; - - return unit->au_DirectSCSI(unit, &sc); } static BYTE atapi_Eject(struct ata_Unit *unit) { - struct atapi_StartStop cmd = { - command: SCSI_STARTSTOP, - immediate: 1, - flags: ATAPI_SS_EJECT, - }; - - struct SCSICmd sc = { - 0 - }; - - D(bug("[ATA%02ld] atapi_Eject()\n", unit->au_UnitNum)); - - sc.scsi_Command = (void*) &cmd; - sc.scsi_CmdLength = sizeof(cmd); - sc.scsi_Flags = SCSIF_READ; - - return unit->au_DirectSCSI(unit, &sc); } static ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen) { - UBYTE cmd[] = { - 3, 0, 0, 0, senselen & 0xfe, 0 - }; - struct SCSICmd sc = { - 0 - }; - - D(bug("[ATA%02ld] atapi_RequestSense()\n", unit->au_UnitNum)); - - if ((senselen == 0) || (sense == 0)) - { - return 0; - } - sc.scsi_Data = (void*)sense; - sc.scsi_Length = senselen & 0xfe; - sc.scsi_Command = (void*)&cmd; - sc.scsi_CmdLength = 6; - sc.scsi_Flags = SCSIF_READ; - - unit->au_DirectSCSI(unit, &sc); - - DATAPI(dump(sense, senselen)); - DATAPI(bug("[SENSE] atapi_RequestSense: sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13])); - return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]); } static ULONG ata_ReadSignature(struct ata_Bus *bus, int unit, @@ -2193,6 +1804,7 @@ static void ata_ResetBus(struct ata_Bus *bus) struct ataBase *ATABase = bus->ab_Base; ULONG TimeOut; BOOL DiagExecuted = FALSE; + volatile UWORD *color0=0xDFF180; /* * Set and then reset the soft reset bit in the Device Control @@ -2204,17 +1816,24 @@ static void ata_ResetBus(struct ata_Bus *bus) ata_WaitNano(400, ATABase); //ata_WaitTO(bus->ab_Timer, 0, 1, 0); - if (bus->haveAltIO) - { +// if (bus->haveAltIO) +// { PIO_OutAlt(bus, ATACTLF_RESET | ATACTLF_INT_DISABLE, ata_AltControl); - ata_WaitTO(bus->ab_Timer, 0, 10, 0); /* sleep 10us; min: 5us */ - + for(int gruen=100000; gruen ; gruen--){ + *color0=0x0030; + *color0=0x0000; + } PIO_OutAlt(bus, ATACTLF_INT_DISABLE, ata_AltControl); - } - else - { - PIO_Out(bus, ATA_EXECUTE_DIAG, ata_Command); - } +// } +// else +// { +// PIO_Out(bus, ATA_EXECUTE_DIAG, ata_Command); +// for(int pink=100000; pink ; pink--){ +// *color0=0x0f99; +// *color0=0x0000; +// } +// } + ata_WaitTO(bus->ab_Timer, 0, 20000, 0); /* sleep 20ms; min: 2ms */ /* If there is a device 0, wait for device 0 to clear BSY */ @@ -2223,17 +1842,19 @@ static void ata_ResetBus(struct ata_Bus *bus) DINIT(bug("[ATA ] ata_ResetBus: Wait for master to clear BSY\n")); TimeOut = 1000; /* Timeout 1s (1ms x 1000) */ - while ( 1 ) + bus->ab_Dev[0] = DEV_NONE; + for(int go=1000000; go ; go--) { - if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0) - break; - ata_WaitTO(bus->ab_Timer, 0, 1000, 0); - if (!(--TimeOut)) { - DINIT(bug("[ATA%02ld] ata_ResetBus: Master device Timed Out!\n")); - bus->ab_Dev[0] = DEV_NONE; + if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0){ + bus->ab_Dev[0] = DEV_UNKNOWN; break; + }else{ + *color0=0x0090; + *color0=0x0000; } } + + DINIT(bug("[ATA ] ata_ResetBus: Wait left after %d ms\n", 1000 - TimeOut)); } @@ -2280,6 +1901,8 @@ static void ata_ResetBus(struct ata_Bus *bus) bus->ab_Dev[0] = ata_ReadSignature(bus, 0, &DiagExecuted); if (DEV_NONE != bus->ab_Dev[1]) bus->ab_Dev[1] = ata_ReadSignature(bus, 1, &DiagExecuted); + + } void ata_InitBus(struct ata_Bus *bus) @@ -2289,6 +1912,9 @@ void ata_InitBus(struct ata_Bus *bus) IPTR haveAltIO; UBYTE tmp1, tmp2; UWORD i; + LONG try; + volatile UWORD *color0=0xDFF180; + /* * initialize timer for the sake of scanning @@ -2308,6 +1934,7 @@ void ata_InitBus(struct ata_Bus *bus) drive will be filtered out later */ for (i = 0; i < MAX_BUSUNITS; i++) { + /* Select device and disable IRQs */ PIO_Out(bus, DEVHEAD_VAL | (i << 4), ata_DevHead); ata_WaitTO(bus->ab_Timer, 0, 400, 0); @@ -2328,11 +1955,15 @@ void ata_InitBus(struct ata_Bus *bus) tmp2 = PIO_In(bus, ata_LBAMid); DB2(bug("[ATA ] ata_InitBus: Reply 0x%02X 0x%02X\n", tmp1, tmp2)); - if ((tmp1 == 0x55) && (tmp2 == 0xaa)) + + if ((tmp1 == 0x55) && (tmp2 == 0xaa)){ bus->ab_Dev[i] = DEV_UNKNOWN; - DINIT(bug("[ATA ] ata_InitBus: Device type = 0x%02X\n", bus->ab_Dev[i])); + DINIT(bug("[ATA ] ata_InitBus: Device type = 0x%02X\n", bus->ab_Dev[i])); + goto exit; + }else{ + } } - +exit: ata_ResetBus(bus); ata_CloseTimer(bus->ab_Timer); DINIT(bug("[ATA ] ata_InitBus: Finished\n")); diff --git a/rom/devs/ata/scsiemu.c b/rom/devs/ata/scsiemu.c index 508148d1c82..94ebf929756 100644 --- a/rom/devs/ata/scsiemu.c +++ b/rom/devs/ata/scsiemu.c @@ -40,11 +40,87 @@ static ULONG rl(UBYTE *p) static UBYTE scsi_read32(struct ata_Unit *unit, APTR data, ULONG offset, ULONG len, ULONG *outlen) { - return unit->au_Read32(unit, offset, len, data, outlen); + if (unit->au_SectorShift == 9) /* use cache with 512 Byte sectors only */ + { + UBYTE io_Error = 0; + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + ULONG unitNum = unit->au_UnitNum; + + ULONG start; + ULONG i; + for (start = 0, i = 0; i < len; i++) + { + ULONG blockAdr = (offset + i) & CACHE_MASK; + UQUAD blockTag = (offset + i) & ~CACHE_MASK; + + if ((unitNum < (1<<9)) && + (base->ata_CacheTags[blockAdr] == (blockTag | unitNum))) /* cache hit */ + { + CopyMem(base->ata_CacheData + blockAdr*512, data + i*512, 512); + + if (start != i) + { + /* Call the Unit's access funtion */ + io_Error = unit->au_Read32(unit, offset + start, i - start, + data + start*512, outlen); + + if (io_Error) + { + return io_Error; + } + + blockAdr = (offset + start) & CACHE_MASK; + CopyMem(data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (offset + j) & CACHE_MASK; + blockTag = (offset + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + start = i + 1; + } + } + if (start != i) + { + /* Call the Unit's access funtion */ + io_Error = unit->au_Read32(unit, offset + start, i - start, + data + start*512, outlen); + + if (io_Error) + { + return io_Error; + } + + ULONG blockAdr = (offset + start) & CACHE_MASK; + CopyMem(data + start*512, base->ata_CacheData + blockAdr*512, (i - start)*512); + for (ULONG j = start; j < i; j++) + { + blockAdr = (offset + j) & CACHE_MASK; + ULONG blockTag = (offset + j) & ~CACHE_MASK; + base->ata_CacheTags[blockAdr] = blockTag | unitNum; + } + } + *outlen = len << unit->au_SectorShift; + return io_Error; + } + else + { + /* Call the Unit's access funtion */ + return unit->au_Read32(unit, offset, len, data, outlen); + } } static UBYTE scsi_write32(struct ata_Unit *unit, APTR data, ULONG offset, ULONG len, ULONG *outlen) { + struct ata_Bus *bus = unit->au_Bus; + struct ataBase *base = bus->ab_Base; + for (int i = 0; i < len; i++) + { + ULONG blockAdr = (offset + i) & CACHE_MASK; + base->ata_CacheTags[blockAdr] = 0xfffffffffffffffful; + } return unit->au_Write32(unit, offset, len, data, outlen); } diff --git a/rom/devs/ata/waitnano.c b/rom/devs/ata/waitnano.c index e2f4c94dce4..192a8428a23 100644 --- a/rom/devs/ata/waitnano.c +++ b/rom/devs/ata/waitnano.c @@ -21,62 +21,9 @@ BOOL ata_Calibrate(struct IORequest* tmr, struct ataBase *base) { - register ULONG x; - register ULONG scale = 0x8000; // min iterations... - volatile register ULONG t = 1; - struct timeval t1, t2; - struct Device *TimerBase = tmr->io_Device; - - D(bug("[ATA ] Calibration started\n")); - - while (scale <= 0x80000000) - { - Forbid(); - GetUpTime(&t1); - for (x = 1; x < scale; x++) - t = (((t + x) * t) - x) / x; // add, mul, sub, div, trivial benchmark. - - GetUpTime(&t2); - Permit(); - SubTime(&t2, &t1); - - // ok, it's going to be totally insane, if secs > 1. - if (t2.tv_secs != 0) - { - bug("[ATA ] micro wait useless.\n"); - return FALSE; - } - - /* - * we expect at least 10000 times longer period, which should be 'achievable' - * unlikely we will cross the magic boundary here of 4 billion instructions in 10 millisecond (yielding 400'000MIPS?) - * on the other side, if we go as low as 1, then 4 iterations of add/sub/mul/div is perfectly fine yielding a bit more than 400ns... - */ - - if (t2.tv_micro >= 10000) - break; - scale <<= 1; - } - - D(bug("[ATA ] Executed %ld ops in %ldus\n", scale, t2.tv_micro)); - - // always round up to the next value.. so 30.9 -> 31, 5.1 -> 6, etc - x = (x + t2.tv_micro - 1) / t2.tv_micro; - x = (x+9) / 10; - - bug("[ATA ] Approximate number of iterations per 100 nanoseconds: %ld\n", x); - base->ata_ItersPer100ns = x; return TRUE; } void ata_WaitNano(register ULONG ns, struct ataBase *base) { - volatile register ULONG t = 1; - ns = (ns + 99) / 100; - ns *= base->ata_ItersPer100ns; - while (ns > 0) - { - t = (((t + ns) * t) - ns) / ns; // add, mul, sub, div, trivial benchmark. - --ns; - } }