Port-amiga archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
IDE-doubler support (patch, testers wanted)
Attached is a patch to add support for 'standard' IDE-doublers to
NetBSD-current. Testers (both with IDE-doubler hardware and without) are
very much wanted, especially people with A4000s.
Please note that I don't know of a way to determine if IDE-doubler is
present or not on runtime - DO NOT TRY TO BOOT MISCONFIGURED KERNEL as
it will most probably hang, crash, burn and eat your breakfast.
Should probably add a boot flag to enable/disable this, as it would be
good if we could ship INSTALL/GENERIC kernels with the code in but
disabled by default. Of course if anyone can come up with a way to
determine if an IDE-doubler is present, that is even better.
There are some issues with this (because IDE-doubling on amiga is such
an *ugly* hack), I've seen my CD-ROM not get detected after a soft
reboot (probably left in somekinda interesting state and since we can't
reset the bus...).
I haven't really stresstested this more than checking that I can mount
CDs and md5sums match on the data read from CD, but I believe it should
work pretty reliably as long as you don't get a bus hang (we still can't
reset the bus).
Here's a dmesg for showoff purposes:
NetBSD 1.6L (FOOBAR) #0: Mon Jan 13 22:26:21 EET 2003
lonewolf%omoikane.cs-intra.net@localhost:/scratch/nb/idedoubler/src/sys/arch/amiga/compile/FOOBAR
Amiga 1200 (68060 rev.1 CPU/MMU/FPU)
total memory = 65536 KB
avail memory = 59496 KB
using 422 buffers containing 3376 KB of memory
memory segment 0 at 78000000 size 04000000
memory segment 1 at 00000000 size 00200000
mainbus0 (root)
clock0 at mainbus0: CIA B system hz 100 hardware hz 709379
Calibrating delay loop... 21/1024 us
a2kbbc0 at mainbus0
ser0 at mainbus0: input fifo 512 output fifo 32
par0 at mainbus0
kbd0 at mainbus0: CIA A type Amiga
ms0 at mainbus0
grfcc0 at mainbus0
grf0 at grfcc0: width 640 height 400 colors 4
ite0 at grf0: rows 50 cols 80 repeat at (30/100)s next at (10/100)s has keyboard
fdc0 at mainbus0: dmabuf pa 0x1de874: dmabuf ka 0x8d98874
fd0 at fdc0 unit 0: 3.5dd 80 cyl, 2 head, 11 sec [9 sec], 512 bytes/sec
wdc0 at mainbus0: Gayle IDE (A1200 style) with IDE-doubler
wd0 at wdc0 channel 0 drive 0: <Maxtor 2B020H1>
wd0: drive supports 16-sector PIO transfers, LBA addressing
wd0: 19541 MB, 16383 cyl, 16 head, 63 sec, 512 bytes/sect x 40020624 sectors
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wdc0: unable to reset (no aux registers)
atapibus0 at wdc0 channel 1: 2 targets
cd0 at atapibus0 drive 1: <MEMOREX CD-MAXX52, MT1198 B Firmware, MB1.0> cdrom
removable
cd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 2 (Ultra/33)
wdc0: unable to reset (no aux registers)
zbus0 at mainbus0
bzivsc at zbus0: pa 0xea0000 man/pro 8512/17 not configured
4 views configured
root on wd0a dumps on wd0b
root file system type: ffs
--
Ilpo Ruotsalainen - <lonewolf%iki.fi@localhost> - http://www.iki.fi/lonewolf/
Index: sys/dev/ic/wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.120
diff --unified -r1.120 wdc.c
--- sys/dev/ic/wdc.c 2003/01/01 00:10:19 1.120
+++ sys/dev/ic/wdc.c 2003/01/13 20:36:05
@@ -228,29 +228,35 @@
if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
chp->wdc->select(chp,0);
- /* assert SRST, wait for reset to complete */
- bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
- WDSD_IBM);
- delay(10);
- bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
- WDCTL_RST | WDCTL_IDS);
- DELAY(1000);
- bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
- WDCTL_IDS);
- delay(1000);
- (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
- bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
- delay(10);
-
- ret_value = __wdcwait_reset(chp, ret_value);
- WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
- chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
- ret_value), DEBUG_PROBE);
-
- /* if reset failed, there's nothing here */
- if (ret_value == 0)
- return 0;
+ if (chp->wdc && ((chp->wdc->cap & WDC_CAPABILITY_NO_AUX) == 0))
+ {
+ /* assert SRST, wait for reset to complete */
+ bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
+ WDSD_IBM);
+ delay(10);
+ bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
+ WDCTL_RST | WDCTL_IDS);
+ DELAY(1000);
+ bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
+ WDCTL_IDS);
+ delay(1000);
+ (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
+ bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
+ WDCTL_4BIT);
+ delay(10);
+
+ ret_value = __wdcwait_reset(chp, ret_value);
+ WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
+ chp->wdc ? chp->wdc->sc_dev.dv_xname :
+ "wdcprobe",
+ chp->channel, ret_value), DEBUG_PROBE);
+
+ /* if reset failed, there's nothing here */
+ if (ret_value == 0)
+ return 0;
+ }
+
/*
* Test presence of drives. First test register signatures looking for
* ATAPI devices. If it's not an ATAPI and reset said there may be
@@ -759,6 +765,13 @@
int verb;
{
int drv_mask1, drv_mask2;
+
+ if (chp->wdc->cap & WDC_CAPABILITY_NO_AUX)
+ {
+ printf("%s: unable to reset (no aux registers)\n",
+ chp->wdc->sc_dev.dv_xname);
+ return 1;
+ }
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,0);
Index: sys/dev/ic/wdcvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdcvar.h,v
retrieving revision 1.34
diff --unified -r1.34 wdcvar.h
--- sys/dev/ic/wdcvar.h 2002/01/13 17:24:29 1.34
+++ sys/dev/ic/wdcvar.h 2003/01/13 20:36:05
@@ -103,6 +103,7 @@
#define WDC_CAPABILITY_SINGLE_DRIVE 0x0800 /* Don't probe second drive */
#define WDC_CAPABILITY_NOIRQ 0x1000 /* Controller never interrupts */
#define WDC_CAPABILITY_SELECT 0x2000 /* Controller selects target */
+#define WDC_CAPABILITY_NO_AUX 0x4000 /* Controller doesn't have aux ports */
u_int8_t PIO_cap; /* highest PIO mode supported */
u_int8_t DMA_cap; /* highest DMA mode supported */
u_int8_t UDMA_cap; /* highest UDMA mode supported */
Index: sys/arch/amiga/dev/wdc_amiga.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/wdc_amiga.c,v
retrieving revision 1.10
diff --unified -r1.10 wdc_amiga.c
--- sys/arch/amiga/dev/wdc_amiga.c 2002/10/02 04:55:53 1.10
+++ sys/arch/amiga/dev/wdc_amiga.c 2003/01/13 20:36:05
@@ -59,14 +59,21 @@
#include <dev/ata/atavar.h>
#include <dev/ic/wdcvar.h>
+#include "opt_idedoubler.h"
+
+#ifdef IDEDOUBLER
+#define NUM_CHANNELS 2
+#else
+#define NUM_CHANNELS 1
+#endif
+
struct wdc_amiga_softc {
- struct wdc_softc sc_wdcdev;
- struct channel_softc *wdc_chanptr;
- struct channel_softc wdc_channel;
- struct isr sc_isr;
+ struct wdc_softc sc_wdcdev;
+ struct channel_softc *wdc_chanptrs[NUM_CHANNELS];
+ struct channel_softc wdc_channels[NUM_CHANNELS];
+ struct isr sc_isr;
volatile u_char *sc_intreg;
- struct bus_space_tag cmd_iot;
- struct bus_space_tag ctl_iot;
+ struct bus_space_tag sc_iot;
char sc_a1200;
};
@@ -89,51 +96,83 @@
wdc_amiga_attach(struct device *parent, struct device *self, void *aux)
{
struct wdc_amiga_softc *sc = (void *)self;
+ int i;
- printf("\n");
+ printf(": Gayle IDE");
if (is_a4000()) {
- sc->cmd_iot.base = (u_long)ztwomap(0xdd2020 + 2);
+ printf(" (A4000 style)");
+ sc->sc_iot.base = (u_long)ztwomap(0xdd2020 + 2);
sc->sc_intreg = (u_char *)ztwomap(0xdd2020 + 0x1000);
sc->sc_a1200 = 0;
} else {
- sc->cmd_iot.base = (u_long) ztwomap(0xda0000 + 2);
- sc->ctl_iot.base = (u_long) ztwomap(0xda4000);
+ printf(" (A1200 style)");
+ sc->sc_iot.base = (u_long) ztwomap(0xda0000 + 2);
gayle_init();
sc->sc_intreg = &gayle.intreq;
sc->sc_a1200 = 1;
}
- sc->cmd_iot.absm = sc->ctl_iot.absm = &amiga_bus_stride_4swap;
- sc->wdc_channel.cmd_iot = &sc->cmd_iot;
- sc->wdc_channel.ctl_iot = &sc->ctl_iot;
-
- if (bus_space_map(sc->wdc_channel.cmd_iot, 0, 0x40, 0,
- &sc->wdc_channel.cmd_ioh)) {
- printf("%s: couldn't map registers\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
+ sc->sc_iot.absm = &amiga_bus_stride_4swap;
+
+ if (bus_space_map(&sc->sc_iot,
+ 0, 0x40, 0, &sc->wdc_channels[0].cmd_ioh))
+ {
+ printf("%s: could not map registers\n",
+ sc->sc_wdcdev.sc_dev.dv_xname);
return;
}
- if (sc->sc_a1200)
- sc->wdc_channel.ctl_ioh = sc->ctl_iot.base;
- else if (bus_space_subregion(sc->wdc_channel.cmd_iot,
- sc->wdc_channel.cmd_ioh, 0x406, 1, &sc->wdc_channel.ctl_ioh))
+#ifndef IDEDOUBLER
+ printf("\n");
+
+ sc->wdc_channels[0].cmd_iot = sc->wdc_channels[0].ctl_iot = &sc->sc_iot;
+
+ if (bus_space_subregion(sc->wdc_channels[0].cmd_iot,
+ sc->wdc_channels[0].cmd_ioh,
+ 0x406, 1, &sc->wdc_channels[0].ctl_ioh))
+ {
+ printf("%s: could not map registers\n",
+ sc->sc_wdcdev.sc_dev.dv_xname);
return;
+ }
sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16;
+#else
+ printf(" with IDE-doubler\n");
+
+ sc->wdc_channels[0].cmd_iot = sc->wdc_channels[1].cmd_iot = &sc->sc_iot;
+
+ if (bus_space_subregion(sc->wdc_channels[0].cmd_iot,
+ sc->wdc_channels[0].cmd_ioh,
+ 0x400, 0x40, &sc->wdc_channels[1].cmd_ioh))
+ {
+ printf("%s: could not map registers\n",
+ sc->sc_wdcdev.sc_dev.dv_xname);
+ return;
+ }
+
+ sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_NO_AUX;
+#endif
+
sc->sc_wdcdev.PIO_cap = 0;
- sc->wdc_chanptr = &sc->wdc_channel;
- sc->sc_wdcdev.channels = &sc->wdc_chanptr;
- sc->sc_wdcdev.nchannels = 1;
- sc->wdc_channel.channel = 0;
- sc->wdc_channel.wdc = &sc->sc_wdcdev;
- sc->wdc_channel.ch_queue = malloc(sizeof(struct channel_queue),
- M_DEVBUF, M_NOWAIT);
- if (sc->wdc_channel.ch_queue == NULL) {
- printf("%s: can't allocate memory for command queue",
- sc->sc_wdcdev.sc_dev.dv_xname);
- return;
+ sc->sc_wdcdev.channels = sc->wdc_chanptrs;
+ sc->sc_wdcdev.nchannels = NUM_CHANNELS;
+
+ for (i=0; i<NUM_CHANNELS; i++)
+ {
+ sc->wdc_channels[i].channel = i;
+ sc->wdc_channels[i].wdc = &sc->sc_wdcdev;
+ sc->wdc_channels[i].ch_queue = malloc(
+ sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
+ if (sc->wdc_channels[i].ch_queue == NULL) {
+ printf("%s: can't allocate memory for command queue",
+ sc->sc_wdcdev.sc_dev.dv_xname);
+ return;
+ }
+
+ sc->wdc_chanptrs[i] = &sc->wdc_channels[i];
}
+
sc->sc_isr.isr_intr = wdc_amiga_intr;
sc->sc_isr.isr_arg = sc;
sc->sc_isr.isr_ipl = 2;
@@ -142,7 +181,8 @@
if (sc->sc_a1200)
gayle.intena |= GAYLE_INT_IDE;
- wdcattach(&sc->wdc_channel);
+ for (i=0; i<NUM_CHANNELS; i++)
+ wdcattach(&sc->wdc_channels[i]);
}
int
@@ -150,12 +190,24 @@
{
struct wdc_amiga_softc *sc = (struct wdc_amiga_softc *)arg;
u_char intreq = *sc->sc_intreg;
- int ret = 0;
+ int i;
+ int ret = 0, chanret;
if (intreq & GAYLE_INT_IDE) {
if (sc->sc_a1200)
gayle.intreq = 0x7c | (intreq & 0x03);
- ret = wdcintr(&sc->wdc_channel);
+
+ for (i=0; i<NUM_CHANNELS; i++)
+ {
+ chanret = wdcintr(&sc->wdc_channels[i]);
+
+ if (chanret == 0)
+ ;
+ else if (chanret == 1)
+ ret = 1;
+ else if (ret == 0)
+ ret = chanret;
+ }
}
return ret;
Index: sys/arch/amiga/conf/files.amiga
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/conf/files.amiga,v
retrieving revision 1.127
diff --unified -r1.127 files.amiga
--- sys/arch/amiga/conf/files.amiga 2002/11/03 02:29:38 1.127
+++ sys/arch/amiga/conf/files.amiga 2003/01/13 20:36:06
@@ -29,6 +29,8 @@
defflag P5PPC68KBOARD
defflag LEV6_DEFER
+defflag IDEDOUBLER
+
defparam IOBZCLOCK
device mainbus {}
Home |
Main Index |
Thread Index |
Old Index