add place-holder directory for the a3000 wd533c93 scsi controller implementation.
[AROS.git] / arch / m68k-amiga / hidd / gayle_ata / gayleata_busclass.c
blob3e48f7ee9243dc3cb73784d58885bbf665a35e8e
1 /*
2 Copyright © 2013-2019, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: A600/A1200/A4000 ATA HIDD
6 Lang: English
7 */
9 #define DEBUG 1
10 #include <aros/debug.h>
12 #include <hardware/ata.h>
13 #include <hidd/bus.h>
14 #include <hidd/ata.h>
15 #include <hidd/pci.h>
16 #include <oop/oop.h>
17 #include <utility/tagitem.h>
18 #include <proto/exec.h>
19 #include <proto/kernel.h>
20 #include <proto/oop.h>
21 #include <proto/utility.h>
22 #include <hardware/intbits.h>
24 #include "bus_class.h"
25 #include "interface_pio.h"
27 AROS_INTH1(IDE_Handler_A1200, struct ATA_BusData *, bus)
29 AROS_INTFUNC_INIT
31 volatile UBYTE *irqbase = bus->gayleirqbase;
32 UBYTE irqmask = *irqbase;
33 if (irqmask & GAYLE_IRQ_IDE) {
34 volatile UBYTE *port;
35 UBYTE status;
37 port = bus->gaylebase;
38 status = port[ata_Status * 4];
39 /* Clear A600/A1200 IDE interrupt. (Stupid Gayle hardware)
40 * Technically this should be done while interrupts are
41 * disabled
43 *irqbase = 0x7c | (*irqbase & 3);
44 if (status & ATAF_BUSY) {
45 bug("[ATA:Gayle] ATA interrupt but BUSY flag set!?\n");
46 return FALSE;
48 bus->ata_HandleIRQ(status, bus->irqData);
49 return TRUE;
51 return FALSE;
53 AROS_INTFUNC_EXIT
56 AROS_INTH1(IDE_Handler_A4000, struct ATA_BusData *, bus)
58 AROS_INTFUNC_INIT
60 /* A4000 interrupt clears when register is read */
61 volatile UWORD *irqbase = (UWORD*)bus->gayleirqbase;
62 UWORD irqmask = *irqbase;
63 if (irqmask & (GAYLE_IRQ_IDE << 8)) {
64 volatile UBYTE *port;
65 UBYTE status;
67 port = bus->gaylebase;
68 status = port[ata_Status * 4];
69 if (status & ATAF_BUSY) {
70 bug("[ATA:Gayle] ATA interrupt but BUSY flag set!?\n");
71 return FALSE;
73 bus->ata_HandleIRQ(status, bus->irqData);
74 return TRUE;
76 return FALSE;
78 AROS_INTFUNC_EXIT
81 static BOOL ata_CreateGayleInterrupt(struct ATA_BusData *bus, UBYTE num)
83 struct Interrupt *irq = &bus->ideint;
85 if (bus->bus->a4000) {
86 irq->is_Code = (APTR)IDE_Handler_A4000;
87 } else {
88 bus->gayleintbase = (UBYTE*)GAYLE_INT_1200;
89 irq->is_Code = (APTR)IDE_Handler_A1200;
92 irq->is_Node.ln_Pri = 20;
93 irq->is_Node.ln_Type = NT_INTERRUPT;
94 irq->is_Node.ln_Name = "AT-IDE";
95 irq->is_Data = bus;
96 AddIntServer(INTB_PORTS, irq);
98 if (bus->gayleintbase) {
99 volatile UBYTE *gayleintbase = bus->gayleintbase;
100 *gayleintbase |= GAYLE_INT_IDE;
102 bus->ideintadded = TRUE;
104 return TRUE;
107 static void ata_RemoveGayleInterrupt(struct ATA_BusData *bus)
109 struct Interrupt *irq = &bus->ideint;
111 if (!bus->ideintadded)
112 return;
113 bus->ideintadded = FALSE;
114 if (bus->gayleintbase) {
115 volatile UBYTE *gayleintbase = bus->gayleintbase;
116 *gayleintbase &= ~GAYLE_INT_IDE;
118 RemIntServer(INTB_PORTS, irq);
121 /* Class Methods */
123 OOP_Object *GAYLEATA__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
125 struct ataBase *base = cl->UserData;
126 struct ata_ProbedBus *bus = (struct ata_ProbedBus *)GetTagData(aHidd_DriverData, 0, msg->attrList);
128 D(bug("[ATA:Gayle] %s()\n", __func__);)
130 if (!bus)
131 return NULL;
133 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, &msg->mID);
134 if (o)
136 struct ATA_BusData *data = OOP_INST_DATA(cl, o);
137 //OOP_MethodID mDispose;
139 data->bus = bus;
140 /* Signal structure ownership */
141 data->bus->atapb_Node.ln_Succ = (struct Node *)-1;
142 data->gaylebase = data->bus->port;
143 data->gayleirqbase = data->bus->gayleirqbase;
144 ata_CreateGayleInterrupt(data, 0);
146 //mDispose = msg->mID - moRoot_New + moRoot_Dispose;
147 //OOP_DoSuperMethod(cl, o, &mDispose);
149 D(bug("[ATA:Gayle] %s: Instance @ %p\n", __func__, o);)
150 return o;
153 void GAYLEATA__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
155 //struct ataBase *base = cl->UserData;
156 struct ATA_BusData *data = OOP_INST_DATA(cl, o);
158 D(bug("[ATA:Gayle] %s()\n", __func__);)
160 ata_RemoveGayleInterrupt(data);
161 FreeVec(data->bus);
163 OOP_DoSuperMethod(cl, o, msg);
166 void GAYLEATA__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
168 struct ataBase *base = cl->UserData;
169 //struct ATA_BusData *data = OOP_INST_DATA(cl, o);
170 ULONG idx;
172 D(bug("[ATA:Gayle] %s()\n", __func__);)
174 Hidd_ATABus_Switch(msg->attrID, idx)
176 case aoHidd_ATABus_Use80Wire:
177 *msg->storage = FALSE;
178 return;
180 case aoHidd_ATABus_UseDMA:
181 *msg->storage = FALSE;
182 return;
184 case aoHidd_ATABus_Use32Bit:
185 *msg->storage = TRUE;
186 return;
189 OOP_DoSuperMethod(cl, o, &msg->mID);
192 void GAYLEATA__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
194 struct ataBase *base = cl->UserData;
195 struct ATA_BusData *data = OOP_INST_DATA(cl, o);
196 struct TagItem *tstate = msg->attrList;
197 struct TagItem *tag;
199 D(bug("[ATA:Gayle] %s()\n", __func__);)
201 while ((tag = NextTagItem(&tstate)))
203 ULONG idx;
205 Hidd_Bus_Switch(tag->ti_Tag, idx)
207 case aoHidd_Bus_IRQHandler:
208 data->ata_HandleIRQ = (APTR)tag->ti_Data;
209 break;
211 case aoHidd_Bus_IRQData:
212 data->irqData = (APTR)tag->ti_Data;
213 break;
217 OOP_DoSuperMethod(cl, o, &msg->mID);
220 APTR GAYLEATA__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
222 struct ATA_BusData *data = OOP_INST_DATA(cl, o);
223 struct pio_data *pio;
225 D(bug("[ATA:Gayle] %s()\n", __func__);)
227 pio = (struct pio_data *)OOP_DoSuperMethod(cl, o, msg);
228 if (pio)
230 pio->port = data->bus->port;
231 pio->altport = data->bus->altport;
232 pio->dataport = (UBYTE*)(((ULONG)pio->port) & ~3);
235 return pio;
238 void GAYLEATA__Hidd_ATABus__Shutdown(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
240 //struct ATA_BusData *data = OOP_INST_DATA(cl, o);
242 OOP_DoSuperMethod(cl, o, msg);