summaryrefslogtreecommitdiffstats
path: root/sys/i386/eisa
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-04-18 15:50:35 +0000
committerpeter <peter@FreeBSD.org>1999-04-18 15:50:35 +0000
commitd31d6be6f69b97664f49ea66dc3e371f78b96da7 (patch)
tree1e02bc4ef3b26a4288796ff2f42370aa037dfed9 /sys/i386/eisa
parentdfb16d4177a39907c05c263200214aca2caaa824 (diff)
downloadFreeBSD-src-d31d6be6f69b97664f49ea66dc3e371f78b96da7.zip
FreeBSD-src-d31d6be6f69b97664f49ea66dc3e371f78b96da7.tar.gz
Implement an EISA new-bus framework. The old driver probe mechanism
had a quirk that made a shim rather hard to implement properly and it was just easier to convert the drivers in one go. The changes to the buslogic driver go beyond just this - the whole driver was new-bus'ed including pci and isa. I have only tested the EISA part of this so far. Submitted by: Doug Rabson <dfr@nlsystems.com>
Diffstat (limited to 'sys/i386/eisa')
-rw-r--r--sys/i386/eisa/3c5x9.c251
-rw-r--r--sys/i386/eisa/adv_eisa.c191
-rw-r--r--sys/i386/eisa/ahb.c188
-rw-r--r--sys/i386/eisa/ahc_eisa.c191
-rw-r--r--sys/i386/eisa/bt_eisa.c356
-rw-r--r--sys/i386/eisa/dpt_eisa.c192
-rw-r--r--sys/i386/eisa/eisaconf.c490
-rw-r--r--sys/i386/eisa/eisaconf.h101
-rw-r--r--sys/i386/eisa/if_vx_eisa.c154
9 files changed, 1141 insertions, 973 deletions
diff --git a/sys/i386/eisa/3c5x9.c b/sys/i386/eisa/3c5x9.c
index 35b9ca0..8a96166 100644
--- a/sys/i386/eisa/3c5x9.c
+++ b/sys/i386/eisa/3c5x9.c
@@ -19,7 +19,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: 3c5x9.c,v 1.9 1997/02/22 09:31:52 peter Exp $
+ * $Id: 3c5x9.c,v 1.10 1997/09/21 21:35:21 gibbs Exp $
*/
#include "eisa.h"
@@ -29,8 +29,13 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/clock.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <net/if.h>
@@ -66,24 +71,10 @@
#define TRANS_AUI 0x4000
#define TRANS_BNC 0xc000
-static int ep_eisa_probe __P((void));
-static int ep_eisa_attach __P((struct eisa_device *e_dev));
-
-static struct eisa_driver ep_eisa_driver = {
- "ep",
- ep_eisa_probe,
- ep_eisa_attach,
- /*shutdown*/NULL,
- &ep_unit
- };
-
-DATA_SET (eisadriver_set, ep_eisa_driver);
-
static const char *ep_match __P((eisa_id_t type));
static const char*
-ep_match(type)
- eisa_id_t type;
+ep_match(eisa_id_t type)
{
switch(type) {
case EISA_DEVICE_ID_3COM_3C509_TP:
@@ -111,122 +102,116 @@ ep_match(type)
}
static int
-ep_eisa_probe(void)
+ep_eisa_probe(device_t dev)
{
+ const char *desc;
u_long iobase;
- struct eisa_device *e_dev = NULL;
- int count;
-
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, ep_match))) {
- u_short conf;
- u_long port;
- int irq;
-
- port = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
- iobase = port + EP_EISA_SLOT_OFFSET;
-
- /* We must be in EISA configuration mode */
- if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
- continue;
-
- eisa_add_iospace(e_dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
- eisa_add_iospace(e_dev, port, EP_IOSIZE, RESVADDR_NONE);
-
- conf = inw(iobase + EISA_IOCONF);
- /* Determine our IRQ */
- switch (conf & IRQ_CHANNEL) {
- case INT_3:
- irq = 3;
- break;
- case INT_5:
- irq = 5;
- break;
- case INT_7:
- irq = 7;
- break;
- case INT_9:
- irq = 9;
- break;
- case INT_10:
- irq = 10;
- break;
- case INT_11:
- irq = 11;
- break;
- case INT_12:
- irq = 12;
- break;
- case INT_15:
- irq = 15;
- break;
- default:
+ u_short conf;
+ u_long port;
+ int irq;
+
+ desc = ep_match(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
+
+ port = (eisa_get_slot(dev) * EISA_SLOT_SIZE);
+ iobase = port + EP_EISA_SLOT_OFFSET;
+
+ /* We must be in EISA configuration mode */
+ if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
+ return ENXIO;
+
+ eisa_add_iospace(dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
+ eisa_add_iospace(dev, port, EP_IOSIZE, RESVADDR_NONE);
+
+ conf = inw(iobase + EISA_IOCONF);
+ /* Determine our IRQ */
+ switch (conf & IRQ_CHANNEL) {
+ case INT_3:
+ irq = 3;
+ break;
+ case INT_5:
+ irq = 5;
+ break;
+ case INT_7:
+ irq = 7;
+ break;
+ case INT_9:
+ irq = 9;
+ break;
+ case INT_10:
+ irq = 10;
+ break;
+ case INT_11:
+ irq = 11;
+ break;
+ case INT_12:
+ irq = 12;
+ break;
+ case INT_15:
+ irq = 15;
+ break;
+ default:
/* Disabled */
- printf("ep: 3COM Network Adapter at "
- "slot %d has its IRQ disabled. "
- "Probe failed.\n",
- e_dev->ioconf.slot);
- continue;
- }
- eisa_add_intr(e_dev, irq);
- eisa_registerdev(e_dev, &ep_eisa_driver);
- count++;
+ printf("ep: 3COM Network Adapter at "
+ "slot %d has its IRQ disabled. "
+ "Probe failed.\n",
+ eisa_get_slot(dev));
+ return ENXIO;
}
- return count;
+ eisa_add_intr(dev, irq);
+
+ return 0;
}
static int
-ep_eisa_attach(e_dev)
- struct eisa_device *e_dev;
+ep_eisa_attach(device_t dev)
{
struct ep_softc *sc;
struct ep_board *epb;
- int unit = e_dev->unit;
- int irq;
- resvaddr_t *ioport;
- resvaddr_t *eisa_ioport;
+ struct resource *io = 0;
+ struct resource *eisa_io = 0;
+ struct resource *irq = 0;
+ int unit = device_get_unit(dev);
u_char level_intr;
- int i;
-
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return -1;
+ int i, rid, shared;
+ void *ih;
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
/*
* The addresses are sorted in increasing order
* so we know the port to pass to the core ep
* driver comes first.
*/
- ioport = e_dev->ioconf.ioaddrs.lh_first;
-
- if(!ioport)
- return -1;
-
- eisa_ioport = ioport->links.le_next;
-
- if(!eisa_ioport)
- return -1;
-
- eisa_reg_start(e_dev);
- if(eisa_reg_iospace(e_dev, ioport))
- return -1;
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ goto bad;
+ }
- if(eisa_reg_iospace(e_dev, eisa_ioport))
- return -1;
+ rid = 1;
+ eisa_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!eisa_io) {
+ device_printf(dev, "No I/O space?!\n");
+ goto bad;
+ }
epb = &ep_board[ep_boards];
- epb->epb_addr = ioport->addr;
+ epb->epb_addr = rman_get_start(io);
epb->epb_used = 1;
if(!(sc = ep_alloc(unit, epb)))
- return -1;
+ goto bad;
ep_boards++;
sc->stat = 0;
level_intr = FALSE;
- switch(e_dev->id) {
+ switch(eisa_get_id(dev)) {
case EISA_DEVICE_ID_3COM_3C509_TP:
sc->ep_connectors = UTP|AUI;
break;
@@ -255,45 +240,71 @@ ep_eisa_attach(e_dev)
/*
* Set the eisa config selected media type
*/
- sc->ep_connector = inw(eisa_ioport->addr + EISA_BPROM_MEDIA_CONF)
+ sc->ep_connector = inw(rman_get_start(eisa_io) + EISA_BPROM_MEDIA_CONF)
>> ACF_CONNECTOR_BITS;
- if(eisa_reg_intr(e_dev, irq, ep_intr, (void *)sc, &net_imask,
- /*shared ==*/level_intr)) {
- ep_free(sc);
- return -1;
+ shared = level_intr ? RF_SHAREABLE : 0;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, shared | RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "No irq?!\n");
+ goto bad;
}
- eisa_reg_end(e_dev);
/* Reset and Enable the card */
- outb(eisa_ioport->addr + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
+ outb(rman_get_start(eisa_io) + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
DELAY(1000); /* we must wait at least 1 ms */
- outb(eisa_ioport->addr + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
+ outb(rman_get_start(eisa_io) + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
/* Now the registers are availible through the lower ioport */
/*
* Retrieve our ethernet address
*/
- GO_WINDOW(0);
+ GO_WINDOW(0);
for(i = 0; i < 3; i++)
sc->epb->eth_addr[i] = get_e(sc, i);
/* Even we get irq number from board, we should tell him..
Otherwise we never get a H/W interrupt anymore...*/
- if ( irq == 9 )
- irq = 2;
- SET_IRQ(eisa_ioport->addr, irq);
+ if ( rman_get_start(irq) == 9 )
+ rman_get_start(irq) = 2;
+ SET_IRQ(rman_get_start(eisa_io), rman_get_start(irq));
ep_attach(sc);
- if(eisa_enable_intr(e_dev, irq)) {
- ep_free(sc);
- eisa_release_intr(e_dev, irq, ep_intr);
- return -1;
- }
+ bus_setup_intr(dev, irq, ep_intr, sc, &ih);
return 0;
+
+ bad:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ if (eisa_io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io);
+ if (irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ return -1;
}
+static device_method_t ep_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ep_eisa_probe),
+ DEVMETHOD(device_attach, ep_eisa_attach),
+
+ { 0, 0 }
+};
+
+static driver_t ep_eisa_driver = {
+ "ep",
+ ep_eisa_methods,
+ DRIVER_TYPE_NET,
+ 1, /* unused */
+};
+
+static devclass_t ep_devclass;
+
+DRIVER_MODULE(ep, eisa, ep_eisa_driver, ep_devclass, 0, 0);
+
#endif /* NEISA > 0 */
diff --git a/sys/i386/eisa/adv_eisa.c b/sys/i386/eisa/adv_eisa.c
index 87ff8dd..465f675 100644
--- a/sys/i386/eisa/adv_eisa.c
+++ b/sys/i386/eisa/adv_eisa.c
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: adv_eisa.c,v 1.1 1998/09/15 07:05:39 gibbs Exp $
+ * $Id: adv_eisa.c,v 1.2 1998/12/22 18:14:09 gibbs Exp $
*/
#include "eisa.h"
@@ -41,9 +41,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <i386/eisa/eisaconf.h>
@@ -69,9 +73,6 @@
#define ADV_EISA_MAX_DMA_ADDR (0x07FFFFFFL)
#define ADV_EISA_MAX_DMA_COUNT (0x07FFFFFFL)
-static int adveisaprobe(void);
-static int adveisaattach(struct eisa_device *e_dev);
-
/*
* The overrun buffer shared amongst all EISA adapters.
*/
@@ -80,22 +81,10 @@ static bus_dma_tag_t overrun_dmat;
static bus_dmamap_t overrun_dmamap;
static bus_addr_t overrun_physbase;
-static struct eisa_driver adv_eisa_driver =
-{
- "adv",
- adveisaprobe,
- adveisaattach,
- /*shutdown*/NULL,
- &adv_unit
-};
-
-DATA_SET (eisadriver_set, adv_eisa_driver);
-
static const char *adveisamatch(eisa_id_t type);
static const char*
-adveisamatch(type)
- eisa_id_t type;
+adveisamatch(eisa_id_t type)
{
switch (type & ~0xF) {
case EISA_DEVICE_ID_ADVANSYS_740:
@@ -111,69 +100,78 @@ adveisamatch(type)
}
static int
-adveisaprobe(void)
+adveisaprobe(device_t dev)
{
+ const char *desc;
u_int32_t iobase;
u_int8_t irq;
- struct eisa_device *e_dev = NULL;
- int count;
-
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, adveisamatch))) {
- iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE)
- + ADV_EISA_SLOT_OFFSET;
-
- eisa_add_iospace(e_dev, iobase, ADV_EISA_IOSIZE, RESVADDR_NONE);
- irq = inb(iobase + ADV_EISA_IRQ_BURST_LEN_REG);
- irq &= ADV_EISA_IRQ_MASK;
- switch (irq) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 5:
- break;
- default:
- printf("adv at slot %d: illegal "
- "irq setting %d\n", e_dev->ioconf.slot,
- irq);
- continue;
- }
- eisa_add_intr(e_dev, irq + 10);
- eisa_registerdev(e_dev, &adv_eisa_driver);
- count++;
+
+ desc = adveisamatch(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
+
+ iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE)
+ + ADV_EISA_SLOT_OFFSET;
+
+ eisa_add_iospace(dev, iobase, ADV_EISA_IOSIZE, RESVADDR_NONE);
+ irq = inb(iobase + ADV_EISA_IRQ_BURST_LEN_REG);
+ irq &= ADV_EISA_IRQ_MASK;
+ switch (irq) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ break;
+ default:
+ printf("adv at slot %d: illegal "
+ "irq setting %d\n", eisa_get_slot(dev),
+ irq);
+ return ENXIO;
}
- return count;
+ eisa_add_intr(dev, irq + 10);
+
+ return 0;
}
static int
-adveisaattach(struct eisa_device *e_dev)
+adveisaattach(device_t dev)
{
struct adv_softc *adv;
struct adv_softc *adv_b;
- resvaddr_t *iospace;
- int unit;
- int irq;
- int error;
+ struct resource *io;
+ struct resource *irq;
+ int unit = device_get_unit(dev);
+ int rid, error;
+ void *ih;
adv_b = NULL;
- unit = e_dev->unit;
- iospace = e_dev->ioconf.ioaddrs.lh_first;
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return (-1);
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ return ENOMEM;
+ }
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "No irq?!\n");
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ return ENOMEM;
- if (!iospace)
- return (-1);
+ }
- switch (e_dev->id & ~0xF) {
+ switch (eisa_get_id(dev) & ~0xF) {
case EISA_DEVICE_ID_ADVANSYS_750:
- adv_b = adv_alloc(unit, I386_BUS_SPACE_IO,
- iospace->addr + ADV_EISA_OFFSET_CHAN2);
+ adv_b = adv_alloc(unit, rman_get_bustag(io),
+ rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN2);
if (adv_b == NULL)
- return (-1);
+ goto bad;
/*
* Allocate a parent dmatag for all tags created
@@ -195,19 +193,19 @@ adveisaattach(struct eisa_device *e_dev)
printf("%s: Could not allocate DMA tag - error %d\n",
adv_name(adv_b), error);
adv_free(adv_b);
- return (-1);
+ goto bad;
}
adv_b->init_level++;
/* FALLTHROUGH */
case EISA_DEVICE_ID_ADVANSYS_740:
- adv = adv_alloc(unit, I386_BUS_SPACE_IO,
- iospace->addr + ADV_EISA_OFFSET_CHAN1);
+ adv = adv_alloc(unit, rman_get_bustag(io),
+ rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN1);
if (adv == NULL) {
if (adv_b != NULL)
adv_free(adv_b);
- return (-1);
+ goto bad;
}
/*
@@ -230,14 +228,14 @@ adveisaattach(struct eisa_device *e_dev)
printf("%s: Could not allocate DMA tag - error %d\n",
adv_name(adv), error);
adv_free(adv);
- return (-1);
+ goto bad;
}
adv->init_level++;
break;
default:
printf("adveisaattach: Unknown device type!\n");
- return (-1);
+ goto bad;
break;
}
@@ -256,7 +254,7 @@ adveisaattach(struct eisa_device *e_dev)
/*flags*/0,
&overrun_dmat) != 0) {
adv_free(adv);
- return (-1);
+ goto bad;
}
if (bus_dmamem_alloc(overrun_dmat,
(void **)&overrun_buf,
@@ -264,7 +262,7 @@ adveisaattach(struct eisa_device *e_dev)
&overrun_dmamap) != 0) {
bus_dma_tag_destroy(overrun_dmat);
adv_free(adv);
- return (-1);
+ goto bad;
}
/* And permanently map it in */
bus_dmamap_load(overrun_dmat, overrun_dmamap,
@@ -273,23 +271,6 @@ adveisaattach(struct eisa_device *e_dev)
/*flags*/0);
}
- eisa_reg_start(e_dev);
- if (eisa_reg_iospace(e_dev, iospace)) {
- adv_free(adv);
- if (adv_b != NULL)
- adv_free(adv_b);
- return (-1);
- }
-
- if (eisa_reg_intr(e_dev, irq, adv_intr, (void *)adv, &cam_imask,
- /*shared ==*/TRUE)) {
- adv_free(adv);
- if (adv_b != NULL)
- adv_free(adv_b);
- return (-1);
- }
- eisa_reg_end(e_dev);
-
/*
* Now that we know we own the resources we need, do the
* card initialization.
@@ -301,7 +282,7 @@ adveisaattach(struct eisa_device *e_dev)
ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
- adv->chip_version = EISA_REVISION_ID(e_dev->id)
+ adv->chip_version = EISA_REVISION_ID(eisa_get_id(dev))
+ ADV_CHIP_MIN_VER_EISA - 1;
if (adv_init(adv) != 0) {
@@ -321,7 +302,7 @@ adveisaattach(struct eisa_device *e_dev)
ADV_OUTB(adv_b, ADV_CHIP_CTRL, ADV_CC_HALT);
ADV_OUTW(adv_b, ADV_CHIP_STATUS, 0);
- adv_b->chip_version = EISA_REVISION_ID(e_dev->id)
+ adv_b->chip_version = EISA_REVISION_ID(eisa_get_id(dev))
+ ADV_CHIP_MIN_VER_EISA - 1;
if (adv_init(adv_b) != 0) {
@@ -335,13 +316,7 @@ adveisaattach(struct eisa_device *e_dev)
/*
* Enable our interrupt handler.
*/
- if (eisa_enable_intr(e_dev, irq)) {
- adv_free(adv);
- if (adv_b != NULL)
- adv_free(adv_b);
- eisa_release_intr(e_dev, irq, adv_intr);
- return (-1);
- }
+ bus_setup_intr(dev, irq, adv_intr, adv, &ih);
/* Attach sub-devices - always succeeds */
adv_attach(adv);
@@ -349,6 +324,30 @@ adveisaattach(struct eisa_device *e_dev)
adv_attach(adv_b);
return 0;
+
+ bad:
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ return -1;
}
+static device_method_t adv_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, adveisaprobe),
+ DEVMETHOD(device_attach, adveisaattach),
+
+ { 0, 0 }
+};
+
+static driver_t adv_eisa_driver = {
+ "adv",
+ adv_eisa_methods,
+ DRIVER_TYPE_CAM,
+ 1, /* unused */
+};
+
+static devclass_t adv_devclass;
+
+DRIVER_MODULE(adv, eisa, adv_eisa_driver, adv_devclass, 0, 0);
+
#endif /* NEISA > 0 */
diff --git a/sys/i386/eisa/ahb.c b/sys/i386/eisa/ahb.c
index 46c7b56..6d294ee 100644
--- a/sys/i386/eisa/ahb.c
+++ b/sys/i386/eisa/ahb.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ahb.c,v 1.7 1999/03/05 23:37:07 gibbs Exp $
+ * $Id: ahb.c,v 1.8 1999/04/11 03:06:05 eivind Exp $
*/
#include "eisa.h"
@@ -36,10 +36,14 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -71,9 +75,7 @@
bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value)
static const char *ahbmatch(eisa_id_t type);
-static int ahbprobe(void);
-static int ahbattach(struct eisa_device *dev);
-static struct ahb_softc *ahballoc(u_long unit, u_int iobase, u_int irq);
+static struct ahb_softc *ahballoc(u_long unit, u_int iobase);
static void ahbfree(struct ahb_softc *ahb);
static int ahbreset(struct ahb_softc *ahb);
static void ahbmapecbs(void *arg, bus_dma_segment_t *segs,
@@ -184,19 +186,6 @@ ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code)
ahb_outb(ahb, ATTN, attn_code);
}
-static u_long ahbunit;
-
-static struct eisa_driver ahb_eisa_driver =
-{
- "ahb",
- ahbprobe,
- ahbattach,
- /*shutdown*/NULL,
- &ahbunit
-};
-
-DATA_SET (eisadriver_set, ahb_eisa_driver);
-
static const char *
ahbmatch(eisa_id_t type)
{
@@ -211,98 +200,93 @@ ahbmatch(eisa_id_t type)
}
static int
-ahbprobe(void)
+ahbprobe(device_t dev)
{
- struct eisa_device *e_dev = NULL;
+ const char *desc;
u_int32_t iobase;
u_int32_t irq;
- int count;
+ u_int8_t intdef;
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, ahbmatch))) {
- u_int8_t intdef;
+ desc = ahbmatch(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
- iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE) +
- AHB_EISA_SLOT_OFFSET;
+ iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
+ AHB_EISA_SLOT_OFFSET;
- eisa_add_iospace(e_dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE);
+ eisa_add_iospace(dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE);
- intdef = inb(INTDEF + iobase);
- switch (intdef & 0x7) {
- case INT9:
- irq = 9;
- break;
- case INT10:
- irq = 10;
- break;
- case INT11:
- irq = 11;
- break;
- case INT12:
- irq = 12;
- break;
- case INT14:
- irq = 14;
- break;
- case INT15:
- irq = 15;
- break;
- default:
- printf("Adaptec 174X at slot %d: illegal "
- "irq setting %d\n", e_dev->ioconf.slot,
- (intdef & 0x7));
- irq = 0;
- break;
- }
- if (irq == 0)
- continue;
- eisa_add_intr(e_dev, irq);
- eisa_registerdev(e_dev, &ahb_eisa_driver);
- count++;
+ intdef = inb(INTDEF + iobase);
+ switch (intdef & 0x7) {
+ case INT9:
+ irq = 9;
+ break;
+ case INT10:
+ irq = 10;
+ break;
+ case INT11:
+ irq = 11;
+ break;
+ case INT12:
+ irq = 12;
+ break;
+ case INT14:
+ irq = 14;
+ break;
+ case INT15:
+ irq = 15;
+ break;
+ default:
+ printf("Adaptec 174X at slot %d: illegal "
+ "irq setting %d\n", eisa_get_slot(dev),
+ (intdef & 0x7));
+ irq = 0;
+ break;
}
- return count;
+ if (irq == 0)
+ return ENXIO;
+
+ eisa_add_intr(dev, irq);
+
+ return 0;
}
static int
-ahbattach(struct eisa_device *e_dev)
+ahbattach(device_t dev)
{
/*
* find unit and check we have that many defined
*/
struct ahb_softc *ahb;
struct ecb* next_ecb;
- resvaddr_t *iospace;
- u_int irq;
-
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return (-1);
-
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
-
- iospace = e_dev->ioconf.ioaddrs.lh_first;
-
- if (iospace == NULL)
- return (-1);
-
- eisa_reg_start(e_dev);
- if (eisa_reg_iospace(e_dev, iospace)) {
- eisa_reg_end(e_dev);
- return (-1);
+ struct resource *io = 0;
+ struct resource *irq = 0;
+ int shared, rid;
+ void *ih;
+
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ return ENOMEM;
}
- if ((ahb = ahballoc(e_dev->unit, iospace->addr, irq)) == NULL) {
- eisa_reg_end(e_dev);
- return (-1);
+ if ((ahb = ahballoc(device_get_unit(dev), rman_get_start(io))) == NULL) {
+ goto error_exit2;
}
if (ahbreset(ahb) != 0)
- return (-1);
+ goto error_exit;
- if (eisa_reg_intr(e_dev, irq, ahbintr, (void *)ahb, &cam_imask,
- (ahb_inb(ahb, INTDEF) & INTLEVEL) ? TRUE : FALSE)) {
- eisa_reg_end(e_dev);
- ahbfree(ahb);
- return (-1);
+ shared = (ahb_inb(ahb, INTDEF) & INTLEVEL) ? RF_SHAREABLE : 0;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, shared | RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "Can't allocate interrupt\n");
+ goto error_exit;
}
/*
@@ -377,8 +361,6 @@ ahbattach(struct eisa_device *e_dev)
ahb->init_level++;
- eisa_reg_end(e_dev);
-
/*
* Now that we know we own the resources we need, register
* our bus with the XPT.
@@ -387,21 +369,26 @@ ahbattach(struct eisa_device *e_dev)
goto error_exit;
/* Enable our interrupt */
- eisa_enable_intr(e_dev, irq);
+ bus_setup_intr(dev, irq, ahbintr, ahb, &ih);
return (0);
+
error_exit:
/*
* The board's IRQ line will not be left enabled
* if we can't intialize correctly, so its safe
* to release the irq.
*/
- eisa_release_intr(e_dev, irq, ahbintr);
ahbfree(ahb);
+error_exit2:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ if (irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
return (-1);
}
static struct ahb_softc *
-ahballoc(u_long unit, u_int iobase, u_int irq)
+ahballoc(u_long unit, u_int iobase)
{
struct ahb_softc *ahb;
@@ -1348,4 +1335,23 @@ ahbtimeout(void *arg)
splx(s);
}
+static device_method_t ahb_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ahbprobe),
+ DEVMETHOD(device_attach, ahbattach),
+
+ { 0, 0 }
+};
+
+static driver_t ahb_eisa_driver = {
+ "ahb",
+ ahb_eisa_methods,
+ DRIVER_TYPE_CAM,
+ 1, /* unused */
+};
+
+static devclass_t ahb_devclass;
+
+DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0);
+
#endif /* NEISA */
diff --git a/sys/i386/eisa/ahc_eisa.c b/sys/i386/eisa/ahc_eisa.c
index cdfd7b9..f01a13d 100644
--- a/sys/i386/eisa/ahc_eisa.c
+++ b/sys/i386/eisa/ahc_eisa.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ahc_eisa.c,v 1.4 1998/12/15 08:24:45 gibbs Exp $
+ * $Id: ahc_eisa.c,v 1.5 1999/03/05 23:28:42 gibbs Exp $
*/
#include "eisa.h"
@@ -35,9 +35,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <i386/eisa/eisaconf.h>
@@ -61,26 +65,12 @@
#define AHC_EISA_IOSIZE 0x100
#define INTDEF 0x5cul /* Interrupt Definition Register */
-static int aic7770probe(void);
-static int aic7770_attach(struct eisa_device *e_dev);
static void aha2840_load_seeprom(struct ahc_softc *ahc);
-static struct eisa_driver ahc_eisa_driver =
-{
- "ahc",
- aic7770probe,
- aic7770_attach,
- /*shutdown*/NULL,
- &ahc_unit
-};
-
-DATA_SET (eisadriver_set, ahc_eisa_driver);
-
static const char *aic7770_match(eisa_id_t type);
static const char*
-aic7770_match(type)
- eisa_id_t type;
+aic7770_match(eisa_id_t type)
{
switch (type) {
case EISA_DEVICE_ID_ADAPTEC_AIC7770:
@@ -100,75 +90,75 @@ aic7770_match(type)
}
static int
-aic7770probe(void)
+aic7770_probe(device_t dev)
{
+ const char *desc;
u_int32_t iobase;
u_int32_t irq;
u_int8_t intdef;
u_int8_t hcntrl;
- struct eisa_device *e_dev;
- int count;
- e_dev = NULL;
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, aic7770_match))) {
- iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE)
- + AHC_EISA_SLOT_OFFSET;
+ desc = aic7770_match(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
+
+ iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE)
+ + AHC_EISA_SLOT_OFFSET;
/* Pause the card preseving the IRQ type */
- hcntrl = inb(iobase + HCNTRL) & IRQMS;
-
- outb(iobase + HCNTRL, hcntrl | PAUSE);
-
- eisa_add_iospace(e_dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE);
- intdef = inb(INTDEF + iobase);
- irq = intdef & 0xf;
- switch (irq) {
- case 9:
- case 10:
- case 11:
- case 12:
- case 14:
- case 15:
- break;
- default:
- printf("aic7770 at slot %d: illegal "
- "irq setting %d\n", e_dev->ioconf.slot,
- intdef);
- irq = 0;
- break;
- }
- if (irq == 0)
- continue;
- eisa_add_intr(e_dev, irq);
- eisa_registerdev(e_dev, &ahc_eisa_driver);
- count++;
+ hcntrl = inb(iobase + HCNTRL) & IRQMS;
+
+ outb(iobase + HCNTRL, hcntrl | PAUSE);
+
+ eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE);
+ intdef = inb(INTDEF + iobase);
+ irq = intdef & 0xf;
+ switch (irq) {
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 14:
+ case 15:
+ break;
+ default:
+ printf("aic7770 at slot %d: illegal "
+ "irq setting %d\n", eisa_get_slot(dev),
+ intdef);
+ irq = 0;
+ break;
}
- return count;
+ if (irq == 0)
+ return ENXIO;
+
+ eisa_add_intr(dev, irq);
+
+ return 0;
}
static int
-aic7770_attach(struct eisa_device *e_dev)
+aic7770_attach(device_t dev)
{
ahc_chip chip;
struct ahc_softc *ahc;
- resvaddr_t *iospace;
- int unit = e_dev->unit;
- int irq;
- int error;
-
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return (-1);
-
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
-
- iospace = e_dev->ioconf.ioaddrs.lh_first;
-
- if (!iospace)
- return -1;
+ struct resource *io = 0;
+ struct resource *irq = 0;
+ int unit = device_get_unit(dev);
+ int error, rid;
+ int shared;
+ void *ih;
+
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ return ENOMEM;
+ }
- switch (e_dev->id) {
+ switch (eisa_get_id(dev)) {
case EISA_DEVICE_ID_ADAPTEC_274x:
case EISA_DEVICE_ID_ADAPTEC_AIC7770:
chip = AHC_AIC7770|AHC_EISA;
@@ -179,13 +169,12 @@ aic7770_attach(struct eisa_device *e_dev)
break;
default:
printf("aic7770_attach: Unknown device type!\n");
- return -1;
- break;
+ goto bad;
}
- if (!(ahc = ahc_alloc(unit, iospace->addr, NULL,
+ if (!(ahc = ahc_alloc(unit, rman_get_start(io), NULL,
chip, AHC_AIC7770_FE, AHC_FNONE, NULL)))
- return -1;
+ goto bad;
ahc->channel = 'A';
ahc->channel_b = 'B';
@@ -204,31 +193,27 @@ aic7770_attach(struct eisa_device *e_dev)
printf("%s: Could not allocate DMA tag - error %d\n",
ahc_name(ahc), error);
ahc_free(ahc);
- return -1;
+ goto bad;
}
- eisa_reg_start(e_dev);
- if (eisa_reg_iospace(e_dev, iospace)) {
- ahc_free(ahc);
- return -1;
- }
-
if (ahc_reset(ahc) != 0) {
ahc_free(ahc);
- return -1;
+ goto bad;
}
/*
* The IRQMS bit enables level sensitive interrupts. Only allow
* IRQ sharing if it's set.
*/
- if (eisa_reg_intr(e_dev, irq, ahc_intr, (void *)ahc, &cam_imask,
- /*shared ==*/ahc->pause & IRQMS)) {
- ahc_free(ahc);
- return -1;
+ shared = (ahc->pause & IRQMS) ? RF_SHAREABLE : 0;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, shared | RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "Can't allocate interrupt\n");
+ goto bad;
}
- eisa_reg_end(e_dev);
/*
* Tell the user what type of interrupts we're using.
@@ -355,8 +340,7 @@ aic7770_attach(struct eisa_device *e_dev)
* The board's IRQ line is not yet enabled so it's safe
* to release the irq.
*/
- eisa_release_intr(e_dev, irq, ahc_intr);
- return -1;
+ goto bad;
}
/*
@@ -367,16 +351,20 @@ aic7770_attach(struct eisa_device *e_dev)
/*
* Enable our interrupt handler.
*/
- if (eisa_enable_intr(e_dev, irq)) {
- ahc_free(ahc);
- eisa_release_intr(e_dev, irq, ahc_intr);
- return -1;
- }
+ if (bus_setup_intr(dev, irq, ahc_intr, ahc, &ih))
+ goto bad;
/* Attach sub-devices - always succeeds */
ahc_attach(ahc);
return 0;
+
+ bad:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ if (irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ return -1;
}
/*
@@ -474,4 +462,23 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
}
}
+static device_method_t ahc_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, aic7770_probe),
+ DEVMETHOD(device_attach, aic7770_attach),
+
+ { 0, 0 }
+};
+
+static driver_t ahc_eisa_driver = {
+ "ahc",
+ ahc_eisa_methods,
+ DRIVER_TYPE_CAM,
+ 1, /* unused */
+};
+
+static devclass_t ahc_devclass;
+
+DRIVER_MODULE(ahc, eisa, ahc_eisa_driver, ahc_devclass, 0, 0);
+
#endif /* NEISA > 0 */
diff --git a/sys/i386/eisa/bt_eisa.c b/sys/i386/eisa/bt_eisa.c
index 9272d3d..84ca778 100644
--- a/sys/i386/eisa/bt_eisa.c
+++ b/sys/i386/eisa/bt_eisa.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bt_eisa.c,v 1.2 1999/03/08 21:35:03 gibbs Exp $
+ * $Id: bt_eisa.c,v 1.3 1999/03/23 07:27:38 gibbs Exp $
*/
#include "eisa.h"
@@ -35,9 +35,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <i386/eisa/eisaconf.h>
@@ -99,20 +103,58 @@
#define AMI_MISC2_OPTIONS 0x49E
#define AMI_ENABLE_ISA_DMA 0x08
-static int bt_eisa_probe(void);
-static int bt_eisa_attach(struct eisa_device *e_dev);
+static const char *bt_match(eisa_id_t type);
-static struct eisa_driver bt_eisa_driver = {
- "bt",
- bt_eisa_probe,
- bt_eisa_attach,
- /*shutdown*/NULL,
- &bt_unit
-};
+static int
+bt_eisa_alloc_resources(device_t dev)
+{
+ struct bt_softc *bt = device_get_softc(dev);
+ int rid;
+ struct resource *port;
+ struct resource *irq;
+ int shared;
-DATA_SET (eisadriver_set, bt_eisa_driver);
+ /*
+ * XXX assumes that the iospace ranges are sorted in increasing
+ * order.
+ */
+ rid = 1;
+ port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!port)
+ return (ENOMEM);
+
+ bt_init_softc(dev, port, 0, 0);
+
+ if (eisa_get_irq(dev) != -1) {
+ shared = bt->level_trigger_ints ? RF_SHAREABLE : 0;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, shared | RF_ACTIVE);
+ if (!irq) {
+ if (port)
+ bus_release_resource(dev, SYS_RES_IOPORT,
+ 0, port);
+ return (ENOMEM);
+ }
+ } else
+ irq = 0;
+ bt->irq = irq;
-static const char *bt_match(eisa_id_t type);
+ return (0);
+}
+
+static void
+bt_eisa_release_resources(device_t dev)
+{
+ struct bt_softc *bt = device_get_softc(dev);
+
+ if (bt->port)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->port);
+ if (bt->irq)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->irq);
+ bt_free_softc(dev);
+}
static const char*
bt_match(eisa_id_t type)
@@ -137,155 +179,119 @@ bt_match(eisa_id_t type)
}
static int
-bt_eisa_probe(void)
+bt_eisa_probe(device_t dev)
{
+ const char *desc;
u_long iobase;
- struct eisa_device *e_dev = NULL;
- int count;
-
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, bt_match))) {
- struct bt_softc *bt;
- struct bt_probe_info info;
- u_long port;
- u_long iosize;
- u_int ioconf;
-
- iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
- if (e_dev->id == EISA_DEVICE_ID_AMI_4801) {
- u_int ioconf1;
-
- iobase += AMI_EISA_SLOT_OFFSET;
- iosize = AMI_EISA_IOSIZE;
- ioconf1 = inb(iobase + AMI_EISA_IOCONF1);
- /* Determine "ISA" I/O port */
- switch (ioconf1 & AMI_PORTADDR) {
- case AMI_PORT_330:
- port = 0x330;
- break;
- case AMI_PORT_334:
- port = 0x334;
- break;
- case AMI_PORT_230:
- port = 0x230;
- break;
- case AMI_PORT_234:
- port = 0x234;
- break;
- case AMI_PORT_134:
- port = 0x134;
- break;
- case AMI_PORT_130:
- port = 0x130;
- break;
- default:
- /* Disabled */
- printf("bt: AMI EISA Adapter at "
- "slot %d has a disabled I/O "
- "port. Cannot attach.\n",
- e_dev->ioconf.slot);
- continue;
- }
- } else {
- iobase += BT_EISA_SLOT_OFFSET;
- iosize = BT_EISA_IOSIZE;
-
- ioconf = inb(iobase + EISA_IOCONF);
- /* Determine "ISA" I/O port */
- switch (ioconf & PORTADDR) {
- case PORT_330:
- port = 0x330;
- break;
- case PORT_334:
- port = 0x334;
- break;
- case PORT_230:
- port = 0x230;
- break;
- case PORT_234:
- port = 0x234;
- break;
- case PORT_130:
- port = 0x130;
- break;
- case PORT_134:
- port = 0x134;
- break;
- default:
- /* Disabled */
- printf("bt: Buslogic EISA Adapter at "
- "slot %d has a disabled I/O "
- "port. Cannot attach.\n",
- e_dev->ioconf.slot);
- continue;
- }
- }
- bt_mark_probed_iop(port);
-
- /* Allocate a softc for use during probing */
- bt = bt_alloc(BT_TEMP_UNIT, I386_BUS_SPACE_IO, port);
-
- if (bt == NULL) {
- printf("bt_eisa_probe: Could not allocate softc for "
- "card at slot 0x%x\n", e_dev->ioconf.slot);
- continue;
+ struct bt_probe_info info;
+ u_long port;
+ u_long iosize;
+ u_int ioconf;
+ int result;
+
+ desc = bt_match(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
+
+ iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE);
+ if (eisa_get_id(dev) == EISA_DEVICE_ID_AMI_4801) {
+ u_int ioconf1;
+
+ iobase += AMI_EISA_SLOT_OFFSET;
+ iosize = AMI_EISA_IOSIZE;
+ ioconf1 = inb(iobase + AMI_EISA_IOCONF1);
+ /* Determine "ISA" I/O port */
+ switch (ioconf1 & AMI_PORTADDR) {
+ case AMI_PORT_330:
+ port = 0x330;
+ break;
+ case AMI_PORT_334:
+ port = 0x334;
+ break;
+ case AMI_PORT_230:
+ port = 0x230;
+ break;
+ case AMI_PORT_234:
+ port = 0x234;
+ break;
+ case AMI_PORT_134:
+ port = 0x134;
+ break;
+ case AMI_PORT_130:
+ port = 0x130;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: AMI EISA Adapter at "
+ "slot %d has a disabled I/O "
+ "port. Cannot attach.\n",
+ eisa_get_slot(dev));
+ return (ENXIO);
}
-
- if (bt_port_probe(bt, &info) != 0) {
- printf("bt_eisa_probe: Probe failed for "
- "card at slot 0x%x\n", e_dev->ioconf.slot);
- } else {
- eisa_add_iospace(e_dev, iobase, iosize, RESVADDR_NONE);
- eisa_add_iospace(e_dev, port, BT_IOSIZE, RESVADDR_NONE);
- eisa_add_intr(e_dev, info.irq);
-
- eisa_registerdev(e_dev, &bt_eisa_driver);
-
- count++;
+ } else {
+ iobase += BT_EISA_SLOT_OFFSET;
+ iosize = BT_EISA_IOSIZE;
+
+ ioconf = inb(iobase + EISA_IOCONF);
+ /* Determine "ISA" I/O port */
+ switch (ioconf & PORTADDR) {
+ case PORT_330:
+ port = 0x330;
+ break;
+ case PORT_334:
+ port = 0x334;
+ break;
+ case PORT_230:
+ port = 0x230;
+ break;
+ case PORT_234:
+ port = 0x234;
+ break;
+ case PORT_130:
+ port = 0x130;
+ break;
+ case PORT_134:
+ port = 0x134;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: Buslogic EISA Adapter at "
+ "slot %d has a disabled I/O "
+ "port. Cannot attach.\n",
+ eisa_get_slot(dev));
+ return (ENXIO);
}
- bt_free(bt);
}
- return count;
+ bt_mark_probed_iop(port);
+
+ /* Tell parent where our resources are going to be */
+ eisa_add_iospace(dev, iobase, iosize, RESVADDR_NONE);
+ eisa_add_iospace(dev, port, BT_IOSIZE, RESVADDR_NONE);
+
+ /* And allocate them */
+ bt_eisa_alloc_resources(dev);
+
+ if (bt_port_probe(dev, &info) != 0) {
+ printf("bt_eisa_probe: Probe failed for "
+ "card at slot 0x%x\n", eisa_get_slot(dev));
+ result = ENXIO;
+ } else {
+ eisa_add_intr(dev, info.irq);
+ result = 0;
+ }
+ bt_eisa_release_resources(dev);
+
+ return (result);
}
static int
-bt_eisa_attach(struct eisa_device *e_dev)
+bt_eisa_attach(device_t dev)
{
- struct bt_softc *bt;
- int unit = e_dev->unit;
- int irq;
- resvaddr_t *ioport;
- resvaddr_t *eisa_ioport;
-
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return (-1);
-
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
-
- /*
- * The addresses are sorted in increasing order
- * so we know the port to pass to the core bt
- * driver comes first.
- */
- ioport = e_dev->ioconf.ioaddrs.lh_first;
-
- if (ioport == NULL)
- return -1;
-
- eisa_ioport = ioport->links.le_next;
-
- if (eisa_ioport == NULL)
- return -1;
-
- eisa_reg_start(e_dev);
- if (eisa_reg_iospace(e_dev, ioport))
- return -1;
-
- if (eisa_reg_iospace(e_dev, eisa_ioport))
- return -1;
+ struct bt_softc *bt = device_get_softc(dev);
- if ((bt = bt_alloc(unit, I386_BUS_SPACE_IO, ioport->addr)) == NULL)
- return -1;
+ /* Allocate resources */
+ bt_eisa_alloc_resources(dev);
/* Allocate a dmatag for our SCB DMA maps */
/* XXX Should be a child of the PCI bus dma tag */
@@ -297,42 +303,42 @@ bt_eisa_attach(struct eisa_device *e_dev)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
- bt_free(bt);
- return -1;
- }
-
- if (eisa_reg_intr(e_dev, irq, bt_intr, (void *)bt, &cam_imask,
- /*shared ==*/bt->level_trigger_ints ? 1 : 0)) {
- bt_free(bt);
+ bt_eisa_release_resources(dev);
return -1;
}
- eisa_reg_end(e_dev);
/*
* Now that we know we own the resources we need, do the full
* card initialization.
*/
- if (bt_probe(bt) || bt_fetch_adapter_info(bt) || bt_init(bt)) {
- bt_free(bt);
- /*
- * The board's IRQ line will not be left enabled
- * if we can't intialize correctly, so its safe
- * to release the irq.
- */
- eisa_release_intr(e_dev, irq, bt_intr);
+ if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) {
+ bt_eisa_release_resources(dev);
return -1;
}
- /* Attach sub-devices - always succeeds */
- bt_attach(bt);
-
- if (eisa_enable_intr(e_dev, irq)) {
- bt_free(bt);
- eisa_release_intr(e_dev, irq, bt_intr);
- return -1;
- }
+ /* Attach sub-devices - always succeeds (sets up intr) */
+ bt_attach(dev);
return 0;
}
+static device_method_t bt_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bt_eisa_probe),
+ DEVMETHOD(device_attach, bt_eisa_attach),
+
+ { 0, 0 }
+};
+
+static driver_t bt_eisa_driver = {
+ "bt",
+ bt_eisa_methods,
+ DRIVER_TYPE_CAM,
+ sizeof(struct bt_softc),
+};
+
+static devclass_t bt_devclass;
+
+DRIVER_MODULE(bt, eisa, bt_eisa_driver, bt_devclass, 0, 0);
+
#endif /* NEISA > 0 */
diff --git a/sys/i386/eisa/dpt_eisa.c b/sys/i386/eisa/dpt_eisa.c
index 65eefc9..a8b2448 100644
--- a/sys/i386/eisa/dpt_eisa.c
+++ b/sys/i386/eisa/dpt_eisa.c
@@ -33,7 +33,7 @@
*/
/*
- * $Id: dpt_eisa.c,v 1.3 1998/08/09 02:22:34 jkh Exp $
+ * $Id: dpt_eisa.c,v 1.4 1998/09/15 08:33:35 gibbs Exp $
*/
#include "eisa.h"
@@ -46,9 +46,13 @@
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <cam/scsi/scsi_all.h>
@@ -65,100 +69,80 @@
/* Function Prototypes */
-static int dpt_eisa_probe(void);
-static int dpt_eisa_attach(struct eisa_device*);
-
static const char *dpt_eisa_match(eisa_id_t);
-static struct eisa_driver dpt_eisa_driver =
-{
- "dpt",
- dpt_eisa_probe,
- dpt_eisa_attach,
- NULL,
- &dpt_unit
-};
-
-DATA_SET (eisadriver_set, dpt_eisa_driver);
-
static int
-dpt_eisa_probe(void)
+dpt_eisa_probe(device_t dev)
{
- struct eisa_device *e_dev = NULL;
- int count;
+ const char *desc;
u_int32_t io_base;
u_int intdef;
u_int irq;
- e_dev = NULL;
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, dpt_eisa_match))) {
- io_base = (e_dev->ioconf.slot * EISA_SLOT_SIZE)
- + DPT_EISA_SLOT_OFFSET;
+ desc = dpt_eisa_match(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
- eisa_add_iospace(e_dev, io_base,
- DPT_EISA_IOSIZE, RESVADDR_NONE);
+ io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE)
+ + DPT_EISA_SLOT_OFFSET;
+
+ eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
- intdef = inb(DPT_EISA_INTDEF + io_base);
+ intdef = inb(DPT_EISA_INTDEF + io_base);
+
+ irq = intdef & DPT_EISA_INT_NUM_MASK;
+ switch (irq) {
+ case DPT_EISA_INT_NUM_11:
+ irq = 11;
+ break;
+ case DPT_EISA_INT_NUM_15:
+ irq = 15;
+ break;
+ case DPT_EISA_INT_NUM_14:
+ irq = 14;
+ break;
+ default:
+ printf("dpt at slot %d: illegal irq setting %d\n",
+ eisa_get_slot(dev), irq);
+ irq = 0;
+ break;
+ }
+ if (irq == 0)
+ return ENXIO;
- irq = intdef & DPT_EISA_INT_NUM_MASK;
- switch (irq) {
- case DPT_EISA_INT_NUM_11:
- irq = 11;
- break;
- case DPT_EISA_INT_NUM_15:
- irq = 15;
- break;
- case DPT_EISA_INT_NUM_14:
- irq = 14;
- break;
- default:
- printf("dpt at slot %d: illegal irq setting %d\n",
- e_dev->ioconf.slot, irq);
- irq = 0;
- break;
- }
- if (irq == 0)
- continue;
+ eisa_add_intr(dev, irq);
- eisa_add_intr(e_dev, irq);
- eisa_registerdev(e_dev, &dpt_eisa_driver);
- count++;
- }
- return count;
+ return 0;
}
-int
-dpt_eisa_attach(e_dev)
- struct eisa_device *e_dev;
+static int
+dpt_eisa_attach(device_t dev)
{
dpt_softc_t *dpt;
- resvaddr_t *io_space;
- int unit = e_dev->unit;
- int irq;
+ struct resource *io = 0;
+ struct resource *irq = 0;
+ int unit = device_get_unit(dev);
int shared;
int s;
-
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL) {
- printf("dpt%d: Can't retrieve irq from EISA config struct.\n",
- unit);
- return -1;
- }
-
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
- io_space = e_dev->ioconf.ioaddrs.lh_first;
-
- if (!io_space) {
- printf("dpt%d: No I/O space?!\n", unit);
- return -1;
+ int rid;
+ void *ih;
+
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ return ENOMEM;
}
- shared = inb(DPT_EISA_INTDEF + io_space->addr) & DPT_EISA_INT_LEVEL;
+ shared = (inb(DPT_EISA_INTDEF + rman_get_start(io))
+ & DPT_EISA_INT_LEVEL) ? RF_SHAREABLE : 0;
- dpt = dpt_alloc(unit, I386_BUS_SPACE_IO,
- io_space->addr + DPT_EISA_EATA_REG_OFFSET);
+ dpt = dpt_alloc(unit, rman_get_bustag(io),
+ rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET);
if (dpt == NULL)
- return -1;
+ goto bad;
/* Allocate a dmatag representing the capabilities of this attachment */
/* XXX Should be a child of the EISA bus dma tag */
@@ -171,46 +155,37 @@ dpt_eisa_attach(e_dev)
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &dpt->parent_dmat) != 0) {
dpt_free(dpt);
- return -1;
+ goto bad;
}
- if (eisa_reg_intr(e_dev, irq, dpt_intr, (void *)dpt, &cam_imask,
- shared)) {
- printf("dpt%d: eisa_reg_intr() failed.\n", unit);
- dpt_free(dpt);
- return -1;
- }
- eisa_reg_end(e_dev);
-
- /* Enable our interrupt handler. */
- if (eisa_enable_intr(e_dev, irq)) {
-#ifdef DPT_DEBUG_ERROR
- printf("dpt%d: eisa_enable_intr() failed.\n", unit);
-#endif
- free(dpt, M_DEVBUF);
- eisa_release_intr(e_dev, irq, dpt_intr);
- return -1;
- }
- /*
- * Enable our interrupt handler.
- */
- if (eisa_enable_intr(e_dev, irq)) {
- dpt_free(dpt);
- eisa_release_intr(e_dev, irq, dpt_intr);
- return -1;
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, shared | RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "No irq?!\n");
+ goto bad;
}
s = splcam();
if (dpt_init(dpt) != 0) {
dpt_free(dpt);
- return -1;
+ goto bad;
}
/* Register with the XPT */
dpt_attach(dpt);
+ bus_setup_intr(dev, irq, dpt_intr, dpt, &ih);
+
splx(s);
return 0;
+
+ bad:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ if (irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ return -1;
}
static const char *
@@ -264,4 +239,23 @@ dpt_eisa_match(type)
return (NULL);
}
+static device_method_t dpt_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dpt_eisa_probe),
+ DEVMETHOD(device_attach, dpt_eisa_attach),
+
+ { 0, 0 }
+};
+
+static driver_t dpt_eisa_driver = {
+ "dpt",
+ dpt_eisa_methods,
+ DRIVER_TYPE_CAM,
+ 1, /* unused */
+};
+
+static devclass_t dpt_devclass;
+
+DRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
+
#endif /* NEISA > 0 */
diff --git a/sys/i386/eisa/eisaconf.c b/sys/i386/eisa/eisaconf.c
index e1eee61..d7781d9 100644
--- a/sys/i386/eisa/eisaconf.c
+++ b/sys/i386/eisa/eisaconf.c
@@ -28,55 +28,64 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: eisaconf.c,v 1.36 1998/12/04 22:54:46 archie Exp $
+ * $Id: eisaconf.c,v 1.37 1999/01/14 06:22:03 jdp Exp $
*/
#include "opt_eisa.h"
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/linker_set.h>
+#include <sys/queue.h>
#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/limits.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <i386/eisa/eisaconf.h>
#include <sys/interrupt.h>
-struct eisa_device_node{
- struct eisa_device dev;
- struct eisa_device_node *next;
+typedef struct resvaddr {
+ u_long addr; /* start address */
+ u_long size; /* size of reserved area */
+ int flags;
+ struct resource *res; /* resource manager handle */
+ LIST_ENTRY(resvaddr) links; /* List links */
+} resvaddr_t;
+
+LIST_HEAD(resvlist, resvaddr);
+
+struct irq_node {
+ int irq_no;
+ void *idesc;
+ TAILQ_ENTRY(irq_node) links;
};
-/*
- * This should probably be a list of "struct device" once it exists.
- * A struct device will incorperate ioconf and driver entry point data
- * regardless of how its attached to the system (via unions) as well
- * as more generic information that all device types should support (unit
- * number, if its installed, etc).
- */
-static struct eisa_device_node *eisa_dev_list;
-static struct eisa_device_node **eisa_dev_list_tail = &eisa_dev_list;
-static u_long eisa_unit;
-
-static struct eisa_driver mainboard_drv = {
- "eisa",
- NULL,
- NULL,
- NULL,
- &eisa_unit
- };
+TAILQ_HEAD(irqlist, irq_node);
+
+struct eisa_ioconf {
+ int slot;
+ struct resvlist ioaddrs; /* list of reserved I/O ranges */
+ struct resvlist maddrs; /* list of reserved memory ranges */
+ struct irqlist irqs; /* list of reserved irqs */
+};
+
+/* To be replaced by the "super device" generic device structure... */
+struct eisa_device {
+ eisa_id_t id;
+ struct eisa_ioconf ioconf;
+};
-/*
- * Add the mainboard_drv to the eisa driver linkerset so that it is
- * defined even if no EISA drivers are linked into the kernel.
- */
-DATA_SET (eisadriver_set, mainboard_drv);
/*
* Local function declarations and static variables
*/
+#if 0
static void eisa_reg_print __P((struct eisa_device *e_dev,
char *string, char *separator));
static int eisa_add_resvaddr __P((struct eisa_device *e_dev,
@@ -85,7 +94,9 @@ static int eisa_add_resvaddr __P((struct eisa_device *e_dev,
static int eisa_reg_resvaddr __P((struct eisa_device *e_dev,
struct resvlist *head, resvaddr_t *resvaddr,
int *reg_count));
+#endif
+#if 0
/*
* Keep some state about what we've printed so far
* to make probe output pretty.
@@ -98,29 +109,77 @@ static struct {
int column; /* How much we have output so far. */
#define MAX_COL 80
} reg_state;
+#endif
/* Global variable, so UserConfig can change it. */
#ifndef EISA_SLOTS
#define EISA_SLOTS 10 /* PCI clashes with higher ones.. fix later */
#endif
int num_eisa_slots = EISA_SLOTS;
+
+static devclass_t eisa_devclass;
+
+static int
+mainboard_probe(device_t dev)
+{
+ char *idstring;
+ eisa_id_t id = eisa_get_id(dev);
+
+ if (eisa_get_slot(dev) != 0)
+ return (ENXIO);
+
+ idstring = (char *)malloc(8 + sizeof(" (System Board)") + 1,
+ M_DEVBUF, M_NOWAIT);
+ if (idstring == NULL) {
+ panic("Eisa probe unable to malloc");
+ }
+ sprintf(idstring, "%c%c%c%x%x (System Board)",
+ EISA_MFCTR_CHAR0(id),
+ EISA_MFCTR_CHAR1(id),
+ EISA_MFCTR_CHAR2(id),
+ EISA_PRODUCT_ID(id),
+ EISA_REVISION_ID(id));
+ device_set_desc(dev, idstring);
+
+ return (0);
+}
+
+static int
+mainboard_attach(device_t dev)
+{
+ return (0);
+}
+
+static device_method_t mainboard_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, mainboard_probe),
+ DEVMETHOD(device_attach, mainboard_attach),
+
+ { 0, 0 }
+};
+
+static driver_t mainboard_driver = {
+ "mainboard",
+ mainboard_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+static devclass_t mainboard_devclass;
+
+DRIVER_MODULE(mainboard, eisa, mainboard_driver, mainboard_devclass, 0, 0);
/*
** probe for EISA devices
*/
-void
-eisa_configure()
+static int
+eisa_probe(device_t dev)
{
int i,slot;
- struct eisa_device_node *dev_node;
- struct eisa_driver **e_drvp;
- struct eisa_driver *e_drv;
struct eisa_device *e_dev;
int eisaBase = 0xc80;
eisa_id_t eisa_id;
- e_drvp = (struct eisa_driver**)eisadriver_set.ls_items;
-
for (slot = 0; slot < num_eisa_slots; eisaBase+=0x1000, slot++) {
int id_size = sizeof(eisa_id);
eisa_id = 0;
@@ -132,19 +191,16 @@ eisa_configure()
continue; /* no EISA card in slot */
/* Prepare an eisa_device_node for this slot */
- dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node),
- M_DEVBUF, M_NOWAIT);
- if (!dev_node) {
- printf("eisa0: cannot malloc eisa_device_node");
+ e_dev = (struct eisa_device *)malloc(sizeof(*e_dev),
+ M_DEVBUF, M_NOWAIT);
+ if (!e_dev) {
+ printf("eisa0: cannot malloc eisa_device");
break; /* Try to attach what we have already */
}
- bzero(dev_node, sizeof(*dev_node));
- e_dev = &(dev_node->dev);
+ bzero(e_dev, sizeof(*e_dev));
e_dev->id = eisa_id;
- e_dev->full_name = "Unattached Device";
-
e_dev->ioconf.slot = slot;
/* Initialize our lists of reserved addresses */
@@ -152,134 +208,202 @@ eisa_configure()
LIST_INIT(&(e_dev->ioconf.maddrs));
TAILQ_INIT(&(e_dev->ioconf.irqs));
- *eisa_dev_list_tail = dev_node;
- eisa_dev_list_tail = &dev_node->next;
+ device_add_child(dev, NULL, -1, e_dev);
}
- dev_node = eisa_dev_list;
+ return 0;
+}
- /*
- * "Attach" the system board
- */
+static void
+eisa_print_child(device_t dev, device_t child)
+{
+ /* XXX print resource descriptions? */
+ printf(" at slot %d", eisa_get_slot(child));
+ printf(" on %s", device_get_nameunit(dev));
+}
- /* The first will be the motherboard in a true EISA system */
- if (dev_node && (dev_node->dev.ioconf.slot == 0)) {
- char *idstring;
-
- e_dev = &dev_node->dev;
- e_dev->driver = &mainboard_drv;
- e_dev->unit = (*e_dev->driver->unit)++;
- idstring = (char *)malloc(8 + sizeof(" (System Board)") + 1,
- M_DEVBUF, M_NOWAIT);
- if (idstring == NULL) {
- panic("Eisa probe unable to malloc");
- }
- sprintf(idstring, "%c%c%c%x%x (System Board)",
- EISA_MFCTR_CHAR0(e_dev->id),
- EISA_MFCTR_CHAR1(e_dev->id),
- EISA_MFCTR_CHAR2(e_dev->id),
- EISA_PRODUCT_ID(e_dev->id),
- EISA_REVISION_ID(e_dev->id));
- e_dev->full_name = idstring;
-
- printf("%s%ld: <%s>\n",
- e_dev->driver->name,
- e_dev->unit,
- e_dev->full_name);
-
- /* Should set the iosize, but I don't have a spec handy */
- printf("Probing for devices on the EISA bus\n");
- dev_node = dev_node->next;
- }
+static int
+eisa_find_irq(struct eisa_device *e_dev, int rid)
+{
+ int i;
+ struct irq_node *irq;
- if (!eisa_dev_list) {
- /*
- * No devices.
- */
- return;
- }
- /*
- * See what devices we recognize.
- */
- while((e_drv = *e_drvp++)) {
- if (e_drv->probe)
- (*e_drv->probe)();
+ for (i = 0, irq = TAILQ_FIRST(&e_dev->ioconf.irqs);
+ i < rid && irq;
+ i++, irq = TAILQ_NEXT(irq, links))
+ ;
+
+ if (irq)
+ return irq->irq_no;
+ else
+ return -1;
+}
+
+static struct resvaddr *
+eisa_find_maddr(struct eisa_device *e_dev, int rid)
+{
+ int i;
+ struct resvaddr *resv;
+
+ for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.maddrs);
+ i < rid && resv;
+ i++, resv = LIST_NEXT(resv, links))
+ ;
+
+ return resv;
+}
+
+static struct resvaddr *
+eisa_find_ioaddr(struct eisa_device *e_dev, int rid)
+{
+ int i;
+ struct resvaddr *resv;
+
+ for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.ioaddrs);
+ i < rid && resv;
+ i++, resv = LIST_NEXT(resv, links))
+ ;
+
+ return resv;
+}
+
+static int
+eisa_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ struct eisa_device *e_dev = device_get_ivars(child);
+
+ switch (which) {
+ case EISA_IVAR_SLOT:
+ *result = e_dev->ioconf.slot;
+ break;
+
+ case EISA_IVAR_ID:
+ *result = e_dev->id;
+ break;
+
+ case EISA_IVAR_IRQ:
+ /* XXX only first irq */
+ *result = eisa_find_irq(e_dev, 0);
+ break;
+
+ default:
+ return (ENOENT);
}
- /*
- * Attach the devices we found in slot order
- */
- for (; dev_node; dev_node=dev_node->next) {
- e_dev = &dev_node->dev;
- e_drv = e_dev->driver;
-
- if (e_drv) {
- /*
- * Determine the proper unit number for this device.
- * Here we should look in the device table generated
- * by config to see if this type of device is enabled
- * either generically or for this particular address
- * as well as determine if a reserved unit number
- * should be used. We should also ensure that the
- * "next availible unit number" skips over "wired" unit
- * numbers. This will be done after config is fixed or
- * some other configuration method is chosen.
- */
- e_dev->unit = (*e_drv->unit)++;
- if ((*e_drv->attach)(e_dev) < 0) {
- /* Ensure registration has ended */
- reg_state.in_registration = 0;
- printf("\n%s0:%d <%s> attach failed\n",
- mainboard_drv.name,
- e_dev->ioconf.slot,
- e_dev->full_name);
- continue;
- }
- /* Ensure registration has ended */
- reg_state.in_registration = 0;
+ return (0);
+}
+
+static int
+eisa_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ return (EINVAL);
+}
+
+static struct resource *
+eisa_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ int isdefault;
+ struct eisa_device *e_dev = device_get_ivars(child);
+ struct resource *rv, **rvp = 0;
+
+ isdefault = (device_get_parent(child) == dev
+ && start == 0UL && end == ~0UL && count == 1);
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (isdefault) {
+ int irq = eisa_find_irq(e_dev, *rid);
+ if (irq == -1)
+ return 0;
+ start = end = irq;
+ count = 1;
+ }
+ break;
+
+ case SYS_RES_MEMORY:
+ if (isdefault) {
+ struct resvaddr *resv;
+
+ resv = eisa_find_maddr(e_dev, *rid);
+ if (!resv)
+ return 0;
+
+ start = resv->addr;
+ end = resv->size - 1;
+ count = resv->size;
+ rvp = &resv->res;
}
- else {
- /* Announce unattached device */
- printf("%s0:%d <%c%c%c%x%x=0x%x> unknown device\n",
- mainboard_drv.name,
- e_dev->ioconf.slot,
- EISA_MFCTR_CHAR0(e_dev->id),
- EISA_MFCTR_CHAR1(e_dev->id),
- EISA_MFCTR_CHAR2(e_dev->id),
- EISA_PRODUCT_ID(e_dev->id),
- EISA_REVISION_ID(e_dev->id),
- e_dev->id);
+ break;
+
+ case SYS_RES_IOPORT:
+ if (isdefault) {
+ struct resvaddr *resv;
+
+ resv = eisa_find_ioaddr(e_dev, *rid);
+ if (!resv)
+ return 0;
+
+ start = resv->addr;
+ end = resv->size - 1;
+ count = resv->size;
+ rvp = &resv->res;
}
+ break;
+
+ default:
+ return 0;
}
+
+ rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags);
+ if (rvp)
+ *rvp = rv;
+
+ return rv;
}
-struct eisa_device *
-eisa_match_dev(e_dev, match_func)
- struct eisa_device *e_dev;
- const char* (*match_func)(eisa_id_t);
+static int
+eisa_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
{
- struct eisa_device_node *e_node = eisa_dev_list;
+ int rv;
+ struct eisa_device *e_dev = device_get_ivars(child);
+ struct resvaddr *resv = 0;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (eisa_find_irq(e_dev, rid) == -1)
+ return EINVAL;
+ break;
- if (e_dev) {
- /* Start our search from the last successful match */
- e_node = ((struct eisa_device_node *)e_dev)->next;
+ case SYS_RES_MEMORY:
+ if (device_get_parent(child) == dev)
+ resv = eisa_find_maddr(e_dev, rid);
+ break;
+
+
+ case SYS_RES_IOPORT:
+ if (device_get_parent(child) == dev)
+ resv = eisa_find_ioaddr(e_dev, rid);
+ break;
+
+ default:
+ return (ENOENT);
}
- for(; e_node; e_node = e_node->next) {
- const char *result;
- if (e_node->dev.driver) {
- /* Already claimed */
- continue;
- }
- result = (*match_func)(e_node->dev.id);
- if (result) {
- e_node->dev.full_name = result;
- return (&(e_node->dev));
- }
+ rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
+
+ if (rv == 0) {
+ if (resv)
+ resv->res = 0;
}
- return NULL;
+
+ return rv;
}
+#if 0
+
/* Interrupt and I/O space registration facitlities */
void
eisa_reg_start(e_dev)
@@ -362,11 +486,14 @@ eisa_reg_end(e_dev)
"registration session\n");
}
+#endif /* 0 */
+
int
-eisa_add_intr(e_dev, irq)
- struct eisa_device *e_dev;
+eisa_add_intr(dev, irq)
+ device_t dev;
int irq;
{
+ struct eisa_device *e_dev = device_get_ivars(dev);
struct irq_node *irq_info;
irq_info = (struct irq_node *)malloc(sizeof(*irq_info), M_DEVBUF,
@@ -380,6 +507,8 @@ eisa_add_intr(e_dev, irq)
return 0;
}
+#if 0
+
int
eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared)
struct eisa_device *e_dev;
@@ -494,6 +623,8 @@ eisa_enable_intr(e_dev, irq)
return (result);
}
+#endif /* 0 */
+
static int
eisa_add_resvaddr(e_dev, head, base, size, flags)
struct eisa_device *e_dev;
@@ -548,27 +679,31 @@ eisa_add_resvaddr(e_dev, head, base, size, flags)
}
int
-eisa_add_mspace(e_dev, mbase, msize, flags)
- struct eisa_device *e_dev;
+eisa_add_mspace(dev, mbase, msize, flags)
+ device_t dev;
u_long mbase;
u_long msize;
int flags;
{
+ struct eisa_device *e_dev = device_get_ivars(dev);
return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.maddrs), mbase, msize,
flags);
}
int
-eisa_add_iospace(e_dev, iobase, iosize, flags)
- struct eisa_device *e_dev;
+eisa_add_iospace(dev, iobase, iosize, flags)
+ device_t dev;
u_long iobase;
u_long iosize;
int flags;
{
+ struct eisa_device *e_dev = device_get_ivars(dev);
return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), iobase,
iosize, flags);
}
+#if 0
+
static int
eisa_reg_resvaddr(e_dev, head, resvaddr, reg_count)
struct eisa_device *e_dev;
@@ -650,12 +785,35 @@ eisa_reg_iospace(e_dev, resvaddr)
&(reg_state.num_ioaddrs)));
}
-int
-eisa_registerdev(e_dev, driver)
- struct eisa_device *e_dev;
- struct eisa_driver *driver;
-{
- e_dev->driver = driver; /* Driver now owns this device */
- return (0);
-}
+#endif
+
+static device_method_t eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, eisa_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, eisa_print_child),
+ DEVMETHOD(bus_read_ivar, eisa_read_ivar),
+ DEVMETHOD(bus_write_ivar, eisa_write_ivar),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(bus_alloc_resource, eisa_alloc_resource),
+ DEVMETHOD(bus_release_resource, eisa_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t eisa_driver = {
+ "eisa",
+ eisa_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
+DRIVER_MODULE(eisa, isab, eisa_driver, eisa_devclass, 0, 0);
diff --git a/sys/i386/eisa/eisaconf.h b/sys/i386/eisa/eisaconf.h
index 2b2ff2d..cb950c8 100644
--- a/sys/i386/eisa/eisaconf.h
+++ b/sys/i386/eisa/eisaconf.h
@@ -28,14 +28,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: eisaconf.h,v 1.16 1997/03/13 18:04:05 joerg Exp $
+ * $Id: eisaconf.h,v 1.17 1997/09/21 21:35:23 gibbs Exp $
*/
#ifndef _I386_EISA_EISACONF_H_
#define _I386_EISA_EISACONF_H_ 1
-#include <sys/queue.h>
-
#define EISA_SLOT_SIZE 0x1000
#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
@@ -45,79 +43,46 @@
#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */
#define EISA_REVISION_ID(ID) (u_char)(ID & 0x0F) /* Bits 0-3 */
-extern struct linker_set eisadriver_set;
extern int num_eisa_slots;
typedef u_int32_t eisa_id_t;
-typedef struct resvaddr {
- u_long addr; /* start address */
- u_long size; /* size of reserved area */
- int flags;
+enum eisa_device_ivars {
+ EISA_IVAR_SLOT,
+ EISA_IVAR_ID,
+ EISA_IVAR_IRQ
+};
+
+/*
+ * Simplified accessors for isa devices
+ */
+#define EISA_ACCESSOR(A, B, T) \
+ \
+static __inline T eisa_get_ ## A(device_t dev) \
+{ \
+ uintptr_t v; \
+ BUS_READ_IVAR(device_get_parent(dev), dev, EISA_IVAR_ ## B, &v); \
+ return (T) v; \
+} \
+ \
+static __inline void eisa_set_ ## A(device_t dev, T t) \
+{ \
+ u_long v = (u_long) t; \
+ BUS_WRITE_IVAR(device_get_parent(dev), dev, EISA_IVAR_ ## B, v); \
+}
+
+EISA_ACCESSOR(slot, SLOT, int)
+EISA_ACCESSOR(id, ID, eisa_id_t)
+EISA_ACCESSOR(irq, IRQ, eisa_id_t)
+
+int eisa_add_intr __P((device_t, int));
+
#define RESVADDR_NONE 0x00
#define RESVADDR_BITMASK 0x01 /* size is a mask of reserved
* bits at addr
*/
#define RESVADDR_RELOCATABLE 0x02
- LIST_ENTRY(resvaddr) links; /* List links */
-} resvaddr_t;
-
-LIST_HEAD(resvlist, resvaddr);
-
-struct irq_node {
- int irq_no;
- void *idesc;
- TAILQ_ENTRY(irq_node) links;
-};
-
-TAILQ_HEAD(irqlist, irq_node);
-
-struct eisa_ioconf {
- int slot;
- struct resvlist ioaddrs; /* list of reserved I/O ranges */
- struct resvlist maddrs; /* list of reserved memory ranges */
- struct irqlist irqs; /* list of reserved irqs */
-};
-
-struct eisa_device;
-
-struct eisa_driver {
- char* name; /* device name */
- int (*probe) __P((void));
- /* test whether device is present */
- int (*attach) __P((struct eisa_device *));
- /* setup driver for a device */
- int (*shutdown) __P((int));
- /* Return the device to a safe
- * state before shutdown
- */
- u_long *unit; /* Next available unit */
-};
-
-/* To be replaced by the "super device" generic device structure... */
-struct eisa_device {
- eisa_id_t id;
- u_long unit;
- const char* full_name; /* for use in the probe message */
- struct eisa_ioconf ioconf;
- struct eisa_driver* driver;
-};
-
-void eisa_configure __P((void));
-struct eisa_device *eisa_match_dev __P((struct eisa_device *,
- const char * (*)(eisa_id_t)));
-
-void eisa_reg_start __P((struct eisa_device *));
-void eisa_reg_end __P((struct eisa_device *));
-int eisa_add_intr __P((struct eisa_device *, int));
-int eisa_reg_intr __P((struct eisa_device *, int, void (*)(void *),
- void *, u_int *, int));
-int eisa_release_intr __P((struct eisa_device *, int, void (*)(void *)));
-int eisa_enable_intr __P((struct eisa_device *, int));
-int eisa_add_iospace __P((struct eisa_device *, u_long, u_long, int));
-int eisa_reg_iospace __P((struct eisa_device *, resvaddr_t *));
-int eisa_add_mspace __P((struct eisa_device *, u_long, u_long, int));
-int eisa_reg_mspace __P((struct eisa_device *, resvaddr_t *));
-int eisa_registerdev __P((struct eisa_device *, struct eisa_driver *));
+int eisa_add_iospace __P((device_t, u_long, u_long, int));
+int eisa_add_mspace __P((device_t, u_long, u_long, int));
#endif /* _I386_EISA_EISACONF_H_ */
diff --git a/sys/i386/eisa/if_vx_eisa.c b/sys/i386/eisa/if_vx_eisa.c
index b46fc75..808e369 100644
--- a/sys/i386/eisa/if_vx_eisa.c
+++ b/sys/i386/eisa/if_vx_eisa.c
@@ -38,6 +38,12 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -58,22 +64,9 @@
static const char *vx_match __P((eisa_id_t type));
-static int vx_eisa_probe __P((void));
-static int vx_eisa_attach __P((struct eisa_device *));
-
-static struct eisa_driver vx_eisa_driver = {
- "vx",
- vx_eisa_probe,
- vx_eisa_attach,
- /* shutdown */ NULL,
- &vx_count
-};
-
-DATA_SET(eisadriver_set, vx_eisa_driver);
static const char*
-vx_match(type)
- eisa_id_t type;
+vx_match(eisa_id_t type)
{
switch (type) {
case EISA_DEVICE_ID_3COM_3C592:
@@ -95,88 +88,117 @@ vx_match(type)
}
static int
-vx_eisa_probe(void)
+vx_eisa_probe(device_t dev)
{
+ const char *desc;
u_long iobase;
- struct eisa_device *e_dev = NULL;
- int count;
+ u_long port;
- count = 0;
- while ((e_dev = eisa_match_dev(e_dev, vx_match))) {
- u_long port;
+ desc = vx_match(eisa_get_id(dev));
+ if (!desc)
+ return (ENXIO);
+ device_set_desc(dev, desc);
- port = e_dev->ioconf.slot * EISA_SLOT_SIZE;
- iobase = port + VX_EISA_SLOT_OFFSET;
+ port = eisa_get_slot(dev) * EISA_SLOT_SIZE;
+ iobase = port + VX_EISA_SLOT_OFFSET;
- eisa_add_iospace(e_dev, iobase, VX_EISA_IOSIZE, RESVADDR_NONE);
- eisa_add_iospace(e_dev, port, VX_IOSIZE, RESVADDR_NONE);
+ eisa_add_iospace(dev, iobase, VX_EISA_IOSIZE, RESVADDR_NONE);
+ eisa_add_iospace(dev, port, VX_IOSIZE, RESVADDR_NONE);
- /* Set irq */
- eisa_add_intr(e_dev, inw(iobase + VX_RESOURCE_CONFIG) >> 12);
- eisa_registerdev(e_dev, &vx_eisa_driver);
- count++;
- }
- return count;
+ /* Set irq */
+ eisa_add_intr(dev, inw(iobase + VX_RESOURCE_CONFIG) >> 12);
+
+ return (0);
}
static int
-vx_eisa_attach(e_dev)
- struct eisa_device *e_dev;
+vx_eisa_attach(device_t dev)
{
struct vx_softc *sc;
- int unit = e_dev->unit;
- int irq;
- resvaddr_t *ioport;
- resvaddr_t *eisa_ioport;
+ int unit = device_get_unit(dev);
+ struct resource *io = 0;
+ struct resource *eisa_io = 0;
+ struct resource *irq = 0;
u_char level_intr;
+ int rid;
+ void *ih;
+
+ /*
+ * The addresses are sorted in increasing order
+ * so we know the port to pass to the core ep
+ * driver comes first.
+ */
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!io) {
+ device_printf(dev, "No I/O space?!\n");
+ goto bad;
+ }
- if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
- return (-1);
-
- irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
-
- ioport = e_dev->ioconf.ioaddrs.lh_first;
-
- if (!ioport)
- return -1;
-
- eisa_ioport = ioport->links.le_next;
-
- if (!eisa_ioport)
- return -1;
-
- eisa_reg_start(e_dev);
- if (eisa_reg_iospace(e_dev, ioport))
- return -1;
-
- if (eisa_reg_iospace(e_dev, eisa_ioport))
- return -1;
+ rid = 1;
+ eisa_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!eisa_io) {
+ device_printf(dev, "No I/O space?!\n");
+ goto bad;
+ }
if ((sc = vxalloc(unit)) == NULL)
- return -1;
+ goto bad;
- sc->vx_io_addr = ioport->addr;
+ sc->vx_io_addr = rman_get_start(io);
level_intr = FALSE;
- if (eisa_reg_intr(e_dev, irq, vxintr, (void *) sc, &net_imask,
- /* shared == */ level_intr)) {
+ rid = 0;
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!irq) {
+ device_printf(dev, "No irq?!\n");
vxfree(sc);
- return -1;
+ goto bad;
}
- eisa_reg_end(e_dev);
/* Now the registers are availible through the lower ioport */
vxattach(sc);
- if (eisa_enable_intr(e_dev, irq)) {
+ if (bus_setup_intr(dev, irq, vxintr, sc, &ih)) {
vxfree(sc);
- eisa_release_intr(e_dev, irq, vxintr);
- return -1;
+ goto bad;
}
+
return 0;
+
+ bad:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
+ if (eisa_io)
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io);
+ if (irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ return -1;
}
+static device_method_t vx_eisa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, vx_eisa_probe),
+ DEVMETHOD(device_attach, vx_eisa_attach),
+
+ { 0, 0 }
+};
+
+static driver_t vx_eisa_driver = {
+ "vx",
+ vx_eisa_methods,
+ DRIVER_TYPE_NET,
+ 1, /* unused */
+};
+
+static devclass_t vx_devclass;
+
+DRIVER_MODULE(vx, eisa, vx_eisa_driver, vx_devclass, 0, 0);
+
#endif /* NVX > 0 */
#endif /* NEISA > 0 */
OpenPOWER on IntegriCloud