revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-amiga / devs / ata / ata_amiga.c
blobdf46acfcb245e5ab2c5a376d094722aaa3a8c8f5
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #define IDE_DEBUG 0
8 #define PCMCIA_DEBUG 0
10 #include <aros/debug.h>
11 #include <exec/types.h>
12 #include <exec/exec.h>
13 #include <proto/exec.h>
14 #include <proto/cardres.h>
15 #include <graphics/gfxbase.h>
16 #include <hardware/custom.h>
17 #include <hardware/intbits.h>
18 #include <resources/card.h>
19 #include <libraries/pccard.h>
20 #include <aros/symbolsets.h>
22 #include "ata.h"
23 #include "timer.h"
25 #define GAYLE_BASE_4000 0xdd2022 /* 0xdd2020.W, 0xdd2026.B, 0xdd202a.B ... (argh!) */
26 #define GAYLE_IRQ_4000 0xdd3020
28 #define GAYLE_BASE_1200 0xda0000 /* 0xda0000.W, 0xda0004.B, 0xda0008.B ... */
29 #define GAYLE_IRQ_1200 0xda9000
30 #define GAYLE_INT_1200 0xdaa000
32 #define GAYLE_IRQ_IDE 0x80
33 #define GAYLE_INT_IDE 0x80
35 struct amiga_driverdata
37 struct amiga_busdata *bus[2];
38 struct Interrupt ideint;
39 BOOL ideintdone;
40 UBYTE *gaylebase;
41 UBYTE *gayleirqbase;
42 BOOL a4000;
43 UBYTE doubler;
46 struct amiga_pcmcia_driverdata
48 struct amiga_busdata *bus[1];
49 struct CardHandle cardhandle;
50 struct Interrupt statusint;
51 struct Interrupt insertint;
52 struct Interrupt removalint;
53 struct CardResource *CardResource;
54 BOOL intena;
55 ULONG configbase, configmask;
56 struct DeviceTData dtd;
57 struct CardMemoryMap *cmm;
61 struct amiga_busdata
63 void *ddata;
64 struct ata_Bus *bus;
65 UBYTE *port;
66 BOOL reset;
69 static void ata_insw(APTR address, UWORD port, ULONG count, void *data)
71 struct amiga_busdata *bdata = data;
72 volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3));
73 ULONG *dst = address;
75 count /= 4;
76 while (count-- != 0)
77 *dst++ = *addr;
80 static void ata_outsw(APTR address, UWORD port, ULONG count, APTR data)
82 struct amiga_busdata *bdata = data;
83 volatile ULONG *addr = (ULONG*)(bdata->port + (port & ~3));
84 ULONG *dst = address;
86 count /= 4;
87 while (count-- != 0)
88 *addr = *dst++;
91 static void ata_pcmcia_insw(APTR address, UWORD port, ULONG count, void *data)
93 struct amiga_busdata *bdata = data;
94 volatile UWORD *addr = (UWORD*)(bdata->port + port);
95 UWORD *dst = address;
97 count /= 2;
98 while (count-- != 0)
99 *dst++ = *addr;
102 static void ata_pcmcia_outsw(APTR address, UWORD port, ULONG count, APTR data)
104 struct amiga_busdata *bdata = data;
105 volatile UWORD *addr = (UWORD*)(bdata->port + port);
106 UWORD *dst = address;
108 count /= 2;
109 while (count-- != 0)
110 *addr = *dst++;
114 static void ata_outl(ULONG val, UWORD offset, IPTR port, APTR data)
118 static void ata_out(UBYTE val, UWORD offset, IPTR port, APTR data)
120 struct amiga_busdata *bdata = data;
121 volatile UBYTE *addr;
123 #if IDE_DEBUG
124 bug("ata_out(%x,%x)=%x:%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4, val);
125 #endif
126 /* IDE doubler hides Alternate Status/Device Control register */
127 if (port == -1) {
128 if (bdata->reset == 0 && (val & 4)) {
129 ata_out(0x40, ata_DevHead, 0, bdata);
130 D(bug("[ATA] Emulating reset\n"));
131 ata_out(ATA_EXECUTE_DIAG, ata_Command, 0, bdata);
133 bdata->reset = (val & 4) != 0;
134 return;
136 addr = (UBYTE*)(bdata->port + port);
137 addr[offset * 4] = val;
140 static UBYTE ata_in(UWORD offset, IPTR port, APTR data)
142 struct amiga_busdata *bdata = data;
143 volatile UBYTE *addr;
144 UBYTE v;
146 #if IDE_DEBUG
147 bug("ata_in(%x,%x)=%x\n", offset, port, (UBYTE*)(bdata->port + port) + offset * 4);
148 #endif
149 if (port == -1) {
150 port = 0;
151 offset = ata_Status;
153 addr = (UBYTE*)(bdata->port + port);
154 v = addr[offset * 4];
155 #if IDE_DEBUG
156 bug("=%x\n", v);
157 #endif
158 return v;
161 static void gayledebug(void)
163 #if 0
164 volatile UBYTE *g = (UBYTE*)0xa00200;
165 volatile UBYTE *gstatus = (UBYTE*)0xda8000;
166 volatile UBYTE *gintreq = (UBYTE*)0xda9000;
167 volatile UBYTE *gintena = (UBYTE*)0xdaa000;
168 volatile UBYTE *gconfig = (UBYTE*)0xdab000;
169 bug ("%02x %02x %02x %02x %02x\n",
170 *g, *gstatus, *gintreq, *gintena, *gconfig);
171 #endif
174 static void ata_pcmcia_out(UBYTE val, UWORD offset, IPTR port, APTR data)
176 volatile UBYTE *addr;
178 addr = (UBYTE*)port;
179 if (offset == 1) {
180 /* Error / Feature not available when using Amiga PCMCIA */
181 return;
182 } else if (offset & 1) {
183 addr += 0x10000;
185 addr[offset] = val;
187 #if PCMCIA_DEBUG
188 bug("pcmcia_ata_out(%x,%x)=%p=%x\n", offset, port, &addr[offset], val);
189 #endif
192 static UBYTE ata_pcmcia_in(UWORD offset, IPTR port, APTR data)
194 volatile UBYTE *addr;
195 UBYTE v;
197 gayledebug();
199 addr = (UBYTE*)port;
200 if (offset == 1) {
201 /* Error / Feature not available when using Amiga PCMCIA */
202 return 1;
203 } else if (offset & 1) {
204 addr += 0x10000;
206 v = addr[offset];
208 #if PCMCIA_DEBUG
209 bug("pcmcia_ata_in(%x,%x)=%p=%x (%02X)\n", offset, port, &addr[offset], v);
210 #endif
212 gayledebug();
214 return v;
218 static BOOL custom_check(APTR addr)
220 volatile struct Custom *custom = (struct Custom*)0xdff000;
221 volatile struct Custom *maybe_custom = (struct Custom*)addr;
222 UWORD intena;
223 BOOL iscustom = TRUE;
225 intena = custom->intenar;
226 custom->intena = 0x7fff;
227 custom->intena = 0xc000;
228 maybe_custom->intena = 0x7fff;
229 if (custom->intenar == 0x4000) {
230 maybe_custom->intena = 0x7fff;
231 if (custom->intenar == 0x4000)
232 iscustom = FALSE;
234 custom->intena = 0x7fff;
235 custom->intena = intena | 0x8000;
236 return iscustom;
239 static UBYTE *getport(struct amiga_driverdata *ddata)
241 UBYTE id, status1, status2;
242 volatile UBYTE *port, *altport;
243 struct GfxBase *gfx;
245 port = NULL;
246 gfx = (struct GfxBase*)TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS);
247 Disable();
248 id = ReadGayle();
249 if (id) {
250 port = (UBYTE*)GAYLE_BASE_1200;
251 ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200;
252 } else {
253 // in AGA this area is never custom mirror but lets make sure..
254 if (!custom_check((APTR)0xdd4000) && (gfx->ChipRevBits0 & GFXF_AA_ALICE)) {
255 port = (UBYTE*)GAYLE_BASE_4000;
256 ddata->a4000 = TRUE;
257 ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_4000;
260 Enable();
261 CloseLibrary((struct Library*)gfx);
263 D(bug("[ATA] Gayle ID=%02x. Possible IDE port=%08x.\n", id, (ULONG)port & ~3));
264 if (port == NULL)
265 return NULL;
267 altport = port + 0x1010;
268 Disable();
269 port[ata_DevHead * 4] = ATAF_ERROR;
270 /* If nothing connected, we get back what we wrote, ATAF_ERROR set */
271 status1 = port[ata_Status * 4];
272 port[ata_DevHead * 4] = ATAF_DATAREQ;
273 status2 = port[ata_Status * 4];
274 port[ata_DevHead * 4] = 0;
275 Enable();
276 D(bug("[ATA] Status=%02x,%02x\n", status1, status2));
277 // BUSY and DRDY both active or ERROR/DATAREQ = no drive(s) = do not install driver
278 if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY))
279 || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ)))
281 D(bug("[ATA] Drives not detected\n"));
282 return NULL;
284 if (ddata->doubler) {
285 UBYTE v1, v2;
286 /* check if AltControl is both readable and writable
287 * It is either floating or DevHead if IDE doubler is connected.
288 * AltControl = DevHead (R)
289 * Device Control = DevHead (W)
291 Disable();
292 altport[ata_AltControl * 4] = 0;
293 port[ata_DevHead * 4] = 1;
294 v1 = altport[ata_AltControl * 4];
295 altport[ata_AltControl * 4] = 2;
296 port[ata_DevHead * 4] = 4;
297 v2 = altport[ata_AltControl * 4];
298 altport[ata_AltControl * 4] = 0;
299 port[ata_DevHead * 4] = 0;
300 Enable();
301 if ((v1 == 0 && v2 == 2) || (v1 == 1 && v2 == 4) || (v1 == 0xff && v2 == 0xff)) {
302 ddata->doubler = 2;
303 } else {
304 ddata->doubler = 0;
306 D(bug("[ATA] IDE doubler check (%02X, %02X) = %d\n", v1, v2, ddata->doubler));
308 /* we may have connected drives */
309 return (UBYTE*)port;
311 static void ackint(struct amiga_driverdata *ddata)
313 if (ddata->a4000)
314 return;
315 /* Clear A600/A1200 IDE interrupt. (Stupid Gayle hardware) */
316 *ddata->gayleirqbase = 0x7c | (*ddata->gayleirqbase & 3);
318 static void ata_AckInterrupt(struct ata_Bus *bus)
320 struct amiga_busdata *bdata = bus->ab_DriverData;
321 struct amiga_driverdata *ddata = bdata->ddata;
322 ackint(ddata);
325 static void callbusirq(struct amiga_driverdata *ddata)
327 volatile UBYTE *port;
328 UBYTE status1, status2;
329 BOOL handled = FALSE;
331 if (ddata->bus[0])
332 handled |= ata_HandleIRQ(ddata->bus[0]->bus);
333 if (ddata->bus[1])
334 handled |= ata_HandleIRQ(ddata->bus[1]->bus);
335 if (handled)
336 return;
338 /* Handle spurious interrupt */
339 port = ddata->gaylebase;
340 status1 = port[ata_Status * 4];
341 status2 = 0;
342 if (ddata->doubler == 2)
343 status2 = port[0x1000 + ata_Status * 4];
344 ackint(ddata);
345 bug("[ATA] Spurious interrupt: %02X %02X\n", status1, status2);
348 AROS_INTH1(IDE_Handler_A1200, struct amiga_driverdata *, ddata)
350 AROS_INTFUNC_INIT
352 UBYTE irqmask = *ddata->gayleirqbase;
353 if (irqmask & GAYLE_IRQ_IDE) {
354 callbusirq(ddata);
356 return FALSE;
358 AROS_INTFUNC_EXIT
361 AROS_INTH1(IDE_Handler_A4000, struct amiga_driverdata *, ddata)
363 AROS_INTFUNC_INIT
365 /* A4000 interrupt clears when register is read */
366 UWORD irqmask = *((UWORD*)ddata->gayleirqbase);
367 if (irqmask & (GAYLE_IRQ_IDE << 8)) {
368 callbusirq(ddata);
370 return FALSE;
372 AROS_INTFUNC_EXIT
375 static AROS_CARDH(IDE_PCMCIA_Handler, void *, data, status)
377 AROS_CARDFUNC_INIT
379 struct amiga_pcmcia_driverdata *ddata = data;
380 if (!status) {
381 if (ddata->intena)
382 ata_HandleIRQ(ddata->bus[0]->bus);
384 return status;
386 AROS_CARDFUNC_EXIT
389 static BOOL ata_CreateInterrupt(struct ata_Bus *bus, UBYTE num)
391 struct amiga_busdata *bdata = bus->ab_DriverData;
392 struct amiga_driverdata *ddata = bdata->ddata;
393 struct Interrupt *irq = &ddata->ideint;
394 volatile UBYTE *gayleintbase = NULL;
396 bdata->bus = bus;
397 ddata->bus[num] = bdata;
399 if (ddata->ideintdone)
400 return TRUE;
401 ddata->ideintdone = TRUE;
403 if (ddata->a4000) {
404 irq->is_Code = (APTR)IDE_Handler_A4000;
405 } else {
406 gayleintbase = (UBYTE*)GAYLE_INT_1200;
407 irq->is_Code = (APTR)IDE_Handler_A1200;
410 irq->is_Node.ln_Pri = 20;
411 irq->is_Node.ln_Type = NT_INTERRUPT;
412 irq->is_Node.ln_Name = "AT-IDE";
413 irq->is_Data = ddata;
414 AddIntServer(INTB_PORTS, irq);
416 if (gayleintbase)
417 *gayleintbase |= GAYLE_INT_IDE;
419 return TRUE;
421 static BOOL ata_CreateInterrupt0(struct ata_Bus *bus)
423 return ata_CreateInterrupt(bus, 0);
425 static BOOL ata_CreateInterrupt1(struct ata_Bus *bus)
427 return ata_CreateInterrupt(bus, 1);
429 static BOOL ata_CreateInterrupt_pcmcia(struct ata_Bus *bus)
431 struct amiga_busdata *bdata = bus->ab_DriverData;
432 struct amiga_pcmcia_driverdata *ddata = bdata->ddata;
434 bdata->bus = bus;
435 ddata->bus[0] = bdata;
437 ddata->intena = 1;
438 return TRUE;
441 static const struct ata_BusDriver amiga_driver0 =
443 ata_out,
444 ata_in,
445 ata_outl,
446 ata_insw,
447 ata_outsw,
448 ata_insw, /* These are intentionally the same as 16-bit routines */
449 ata_outsw,
450 ata_CreateInterrupt0,
451 ata_AckInterrupt
453 static const struct ata_BusDriver amiga_driver1 =
455 ata_out,
456 ata_in,
457 ata_outl,
458 ata_insw,
459 ata_outsw,
460 ata_insw, /* These are intentionally the same as 16-bit routines */
461 ata_outsw,
462 ata_CreateInterrupt1,
463 ata_AckInterrupt
465 static const struct ata_BusDriver amiga_driver_pcmcia =
467 ata_pcmcia_out,
468 ata_pcmcia_in,
469 ata_outl,
470 ata_pcmcia_insw,
471 ata_pcmcia_outsw,
472 ata_pcmcia_insw,
473 ata_pcmcia_outsw,
474 ata_CreateInterrupt_pcmcia,
475 NULL
478 static BOOL ata_amiga_ide_init(struct ataBase *LIBBASE)
480 struct amiga_driverdata *ddata;
481 struct amiga_busdata *bdata;
483 ddata = AllocVec(sizeof(struct amiga_driverdata), MEMF_CLEAR | MEMF_PUBLIC);
484 if (!ddata)
485 return FALSE;
486 ddata->doubler = 1;
488 ddata->gaylebase = getport(ddata);
489 bdata = AllocVec(sizeof(struct amiga_busdata) * (ddata->doubler == 2 ? 2 : 1), MEMF_CLEAR | MEMF_PUBLIC);
490 if (bdata && ddata->gaylebase) {
491 LIBBASE->ata_NoDMA = TRUE;
492 bdata->ddata = ddata;
493 bdata->port = ddata->gaylebase;
494 ata_RegisterBus(0, ddata->doubler ? -1 : 0x1010, 2, 0, ARBF_EarlyInterrupt, &amiga_driver0, bdata, LIBBASE);
495 if (ddata->doubler == 2) {
496 D(bug("[ATA] Adding secondary bus\n"));
497 bdata++;
498 bdata->ddata = ddata;
499 bdata->port = ddata->gaylebase + 0x1000;
500 ata_RegisterBus(0, -1, 2, 0, ARBF_EarlyInterrupt, &amiga_driver1, bdata, LIBBASE);
502 return TRUE;
504 FreeVec(bdata);
505 FreeVec(ddata);
506 return FALSE;
509 static BOOL detectcard(struct amiga_pcmcia_driverdata *ddata)
511 APTR CardResource;
512 struct CardHandle *ch;
513 UBYTE tuple[256 + 2];
514 WORD cnt1, cnt2;
515 UBYTE *tp;
516 BOOL got;
518 ch = &ddata->cardhandle;
519 CardResource = ddata->CardResource;
521 CardResetCard(ch);
522 /* Some cards refuse to work if CARD_ENABLEF_DIGAUDIO is enabled at this point */
523 CardMiscControl(ch, CARD_DISABLEF_WP);
525 got = FALSE;
526 for (;;) {
527 if (!CopyTuple(ch, tuple, PCCARD_TPL_DEVICE, sizeof(tuple) - 2))
528 break;
529 if (!DeviceTuple(tuple, &ddata->dtd))
530 break;
531 if (ddata->dtd.dtd_DTtype != PCCARD_DTYPE_FUNCSPEC)
532 break;
533 tuple[2] = 0;
534 if (!CopyTuple(ch, tuple, PCCARD_TPL_FUNCID, sizeof(tuple) - 2))
535 break;
536 if (tuple[2] != PCCARD_FUNC_FIXED)
537 break;
538 got = FALSE;
539 for (cnt1 = 0; TRUE; cnt1++) {
540 if (!CopyTuple(ch, tuple, PCCARD_TPL_FUNCE | (cnt1 << 16), sizeof(tuple) - 2))
541 break;
542 if (tuple[2] != 1 || tuple[3] != 1)
543 break;
544 got = TRUE;
545 break;
547 if (!got)
548 break;
549 got = FALSE;
550 if (!CopyTuple(ch, tuple, PCCARD_TPL_CONFIG, sizeof(tuple) - 2))
551 break;
552 if (tuple[1] < 5)
553 break;
554 //lastindex = tuple[3] & 0x3f;
555 tp = &tuple[4];
556 cnt2 = (tuple[2] & 3) + 1;
557 for (cnt1 = 0; cnt1 < cnt2; cnt1++) {
558 ddata->configbase |= (*tp) << (cnt1 * 8);
559 tp++;
561 cnt2 = ((tuple[2] >> 3) & 15) + 1;
562 for (cnt1 = 0; cnt1 < cnt2 && cnt1 < 4; cnt1++) {
563 ddata->configmask |= (*tp) << (cnt1 * 8);
564 tp++;
566 return TRUE;
568 return FALSE;
571 static void pcmcia_config_write(struct amiga_pcmcia_driverdata *ddata, UBYTE reg, UBYTE data)
573 volatile UBYTE *attrbase = ddata->cmm->cmm_AttributeMemory;
574 volatile UBYTE *gstatus = (UBYTE*)0xda8000;
575 APTR CardResource;
576 struct CardHandle *ch;
578 CardResource = ddata->CardResource;
579 ch = &ddata->cardhandle;
580 if (!(ddata->configmask & (1 << reg)))
581 return;
582 bug("%02x -> %p\n", data, &attrbase[ddata->configbase + 2 * reg]);
583 gayledebug();
584 gayledebug();
585 gayledebug();
586 for(;;) {
587 UBYTE status = *gstatus;
588 if (!(status & CARD_STATUSF_BSY) || !(status & CARD_STATUSF_CCDET))
589 break;
591 CardMiscControl(ch, CARD_DISABLEF_WP);
592 attrbase[ddata->configbase + 2 * reg] = data;
593 CardMiscControl(ch, 0);
594 for(;;) {
595 UBYTE status = *gstatus;
596 if (!(status & CARD_STATUSF_BSY) || !(status & CARD_STATUSF_CCDET))
597 break;
599 data = attrbase[ddata->configbase + 2 * reg];
600 bug("=%02X\n", data);
601 gayledebug();
602 gayledebug();
603 gayledebug();
606 static void initializecard(struct ataBase *LIBBASE, struct amiga_pcmcia_driverdata *ddata)
608 struct CardHandle *ch;
609 UBYTE tuple[256 + 2];
610 UBYTE *tp;
611 APTR CardResource;
612 struct IORequest *req;
614 ch = &ddata->cardhandle;
615 CardResource = ddata->CardResource;
617 D(bug("Detected PCMCIA IDE. ConfigBase=%08x RMask=%08x\n", ddata->configbase, ddata->configmask);
618 memset(tuple, 0, sizeof tuple);
619 if (CopyTuple(ch, tuple, PCCARD_TPL_VERS1, sizeof(tuple) - 2)) {
620 if (tuple[2] == 4) {
621 tp = &tuple[4];
622 while (*tp != 0xff) {
623 bug("%s ", tp);
624 tp += strlen(tp) + 1;
626 D(bug("\n"));
629 req = ata_OpenTimer(LIBBASE);
630 CardAccessSpeed(ch, ddata->dtd.dtd_DTspeed);
631 #if 0
632 pcmcia_config_write(ddata, 3, 0); /* Socket and copy. Must be written first. */
633 pcmcia_config_write(ddata, 0, 0x80);
634 if (req)
635 ata_WaitTO(req, 0, 20000, 0);
636 pcmcia_config_write(ddata, 0, 0x00);
637 if (req)
638 ata_WaitTO(req, 0, 20000, 0);
639 for(;;) {
640 UBYTE status = ReadCardStatus();
641 if (!(status & CARD_STATUSF_BSY) || !(status & CARD_STATUSF_CCDET))
642 break;
644 #endif
645 Disable();
646 pcmcia_config_write(ddata, 3, 0); /* Socket and copy. Must be written first. */
647 pcmcia_config_write(ddata, 2, 0); /* Pin replacement. */
648 pcmcia_config_write(ddata, 1, 0); /* Configuration and Status. */
649 /* NOTE: We must use index #2 because some buggy cards won't work properly if using config index #1 */
650 pcmcia_config_write(ddata, 0, 0x42); /* Configure option. Level interrupt (0x40) + config index (2). */
651 Enable();
652 if (req)
653 ata_WaitTO(req, 0, 50000, 0);
654 pcmcia_config_write(ddata, 1, 0); /* Configuration and Status. */
655 CardMiscControl(ch, CARD_ENABLEF_DIGAUDIO | CARD_DISABLEF_WP);
656 ata_CloseTimer(req);
657 /* Now we have IDE registers at iobase + 0x1f0 to 0x1f7 and 0x3f6 to 0x3f7 */
658 /* CARD_ENABLEF_DIGAUDIO must be enabled now */
661 static BOOL ata_amiga_pcmcia_init(struct ataBase *LIBBASE)
663 struct CardResource *CardResource;
664 struct amiga_pcmcia_driverdata *ddata;
665 struct amiga_busdata *bdata;
666 struct CardHandle *ch;
668 CardResource = OpenResource("card.resource");
669 if (!CardResource)
670 return FALSE;
671 if (CardInterface() != CARD_INTERFACE_AMIGA_0)
672 return FALSE;
674 ddata = AllocVec(sizeof(struct amiga_pcmcia_driverdata) + sizeof(struct amiga_busdata), MEMF_CLEAR | MEMF_PUBLIC);
675 if (!ddata)
676 return FALSE;
677 bdata = (struct amiga_busdata*)(ddata + 1);
679 ch = &ddata->cardhandle;
680 ddata->CardResource = CardResource;
681 ddata->cmm = GetCardMap();
683 ch->cah_CardFlags = CARDF_IFAVAILABLE | CARDF_POSTSTATUS;
684 ch->cah_CardNode.ln_Name = LIBBASE->ata_Device.dd_Library.lib_Node.ln_Name;
685 ch->cah_CardStatus = &ddata->statusint;
686 ch->cah_CardRemoved = &ddata->removalint;
687 ch->cah_CardInserted = &ddata->insertint;
688 ch->cah_CardStatus->is_Data = ddata;
689 ch->cah_CardStatus->is_Code = (VOID_FUNC)IDE_PCMCIA_Handler;
690 #if 0
691 ch->cah_CardRemoved->is_Data = ddata;
692 ch->cah_CardRemoved->is_Code = (void*)IDE_PCMCIA_Removed;
693 ch->cah_CardInserted->is_Data = ddata;
694 ch->cah_CardInserted->is_Code = (void*)IDE_PCMCIA_Inserted
695 #endif
697 if (!OwnCard(ch)) {
698 BeginCardAccess(ch);
700 if (detectcard(ddata)) {
701 initializecard(LIBBASE, ddata);
702 bdata->ddata = ddata;
703 bdata->port = (UBYTE*)ddata->cmm->cmm_IOMemory;
705 LIBBASE->ata_NoDMA = TRUE;
706 ata_RegisterBus((IPTR)ddata->cmm->cmm_IOMemory + 0x1f0, (IPTR)(ddata->cmm->cmm_IOMemory + 0x3f6 - ata_AltControl), 2, 0, ARBF_EarlyInterrupt, &amiga_driver_pcmcia, bdata, LIBBASE);
707 return TRUE;
710 EndCardAccess(ch);
711 ReleaseCard(ch, CARDF_REMOVEHANDLE);
714 FreeVec(ddata);
716 return FALSE;
719 static int ata_amiga_init(struct ataBase *LIBBASE)
721 BOOL r_ide, r_pcmcia;
723 r_ide = ata_amiga_ide_init(LIBBASE);
724 r_pcmcia = ata_amiga_pcmcia_init(LIBBASE);
725 return (r_ide || r_pcmcia) ? 1 : 0;
728 ADD2INITLIB(ata_amiga_init, 20)