2 Copyright © 2013-2019, The AROS Development Team. All rights reserved.
5 Desc: A600/A1200/A4000 ATA HIDD
10 #include <aros/debug.h>
12 #include <hardware/ata.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
)
31 volatile UBYTE
*irqbase
= bus
->gayleirqbase
;
32 UBYTE irqmask
= *irqbase
;
33 if (irqmask
& GAYLE_IRQ_IDE
) {
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
43 *irqbase
= 0x7c | (*irqbase
& 3);
44 if (status
& ATAF_BUSY
) {
45 bug("[ATA:Gayle] ATA interrupt but BUSY flag set!?\n");
48 bus
->ata_HandleIRQ(status
, bus
->irqData
);
56 AROS_INTH1(IDE_Handler_A4000
, struct ATA_BusData
*, bus
)
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)) {
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");
73 bus
->ata_HandleIRQ(status
, bus
->irqData
);
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
;
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";
96 AddIntServer(INTB_PORTS
, irq
);
98 if (bus
->gayleintbase
) {
99 volatile UBYTE
*gayleintbase
= bus
->gayleintbase
;
100 *gayleintbase
|= GAYLE_INT_IDE
;
102 bus
->ideintadded
= TRUE
;
107 static void ata_RemoveGayleInterrupt(struct ATA_BusData
*bus
)
109 struct Interrupt
*irq
= &bus
->ideint
;
111 if (!bus
->ideintadded
)
113 bus
->ideintadded
= FALSE
;
114 if (bus
->gayleintbase
) {
115 volatile UBYTE
*gayleintbase
= bus
->gayleintbase
;
116 *gayleintbase
&= ~GAYLE_INT_IDE
;
118 RemIntServer(INTB_PORTS
, irq
);
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__
);)
133 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
136 struct ATA_BusData
*data
= OOP_INST_DATA(cl
, o
);
137 //OOP_MethodID mDispose;
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
);)
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
);
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);
172 D(bug("[ATA:Gayle] %s()\n", __func__
);)
174 Hidd_ATABus_Switch(msg
->attrID
, idx
)
176 case aoHidd_ATABus_Use80Wire
:
177 *msg
->storage
= FALSE
;
180 case aoHidd_ATABus_UseDMA
:
181 *msg
->storage
= FALSE
;
184 case aoHidd_ATABus_Use32Bit
:
185 *msg
->storage
= TRUE
;
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
;
199 D(bug("[ATA:Gayle] %s()\n", __func__
);)
201 while ((tag
= NextTagItem(&tstate
)))
205 Hidd_Bus_Switch(tag
->ti_Tag
, idx
)
207 case aoHidd_Bus_IRQHandler
:
208 data
->ata_HandleIRQ
= (APTR
)tag
->ti_Data
;
211 case aoHidd_Bus_IRQData
:
212 data
->irqData
= (APTR
)tag
->ti_Data
;
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
);
230 pio
->port
= data
->bus
->port
;
231 pio
->altport
= data
->bus
->altport
;
232 pio
->dataport
= (UBYTE
*)(((ULONG
)pio
->port
) & ~3);
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
);