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>
This commit is contained in:
Peter Wemm 1999-04-18 15:50:35 +00:00
parent a7375c7225
commit a49a3d4433
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=45791
29 changed files with 2988 additions and 2416 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.112 1999/04/15 14:52:24 bde Exp $
* $Id: autoconf.c,v 1.113 1999/04/16 21:22:11 peter Exp $
*/
/*
@ -232,10 +232,6 @@ configure(dummy)
INTREN(IRQ_SLAVE);
#endif /* APIC_IO */
#if NEISA > 0
eisa_configure();
#endif
#if NPNP > 0
pnp_configure();
#endif

View File

@ -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;
desc = adveisamatch(eisa_get_id(dev));
if (!desc)
return (ENXIO);
device_set_desc(dev, desc);
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++;
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 */

View File

@ -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;
struct resource *io = 0;
struct resource *irq = 0;
int shared, rid;
void *ih;
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);
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 */

View File

@ -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;
hcntrl = inb(iobase + HCNTRL) & IRQMS;
outb(iobase + HCNTRL, hcntrl | PAUSE);
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++;
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;
struct resource *io = 0;
struct resource *irq = 0;
int unit = device_get_unit(dev);
int error, rid;
int shared;
void *ih;
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;
iospace = e_dev->ioconf.ioaddrs.lh_first;
if (!iospace)
return -1;
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 */

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt.c,v 1.14 1999/03/08 21:36:33 gibbs Exp $
* $Id: bt.c,v 1.15 1999/04/07 23:01:43 gibbs Exp $
*/
/*
@ -46,6 +46,7 @@
#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
/*
* XXX It appears that BusLogic PCI adapters go out to lunch if you
@ -60,6 +61,7 @@
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
#include <sys/rman.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@ -208,48 +210,29 @@ u_int16_t bt_board_ports[] =
};
/* Exported functions */
struct bt_softc *
bt_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh)
void
bt_init_softc(device_t dev, struct resource *port,
struct resource *irq, struct resource *drq)
{
struct bt_softc *bt;
struct bt_softc *bt = device_get_softc(dev);
if (unit != BT_TEMP_UNIT) {
if (unit >= NBT) {
printf("bt: unit number (%d) too high\n", unit);
return NULL;
}
/*
* Allocate a storage area for us
*/
if (bt_softcs[unit]) {
printf("bt%d: memory already allocated\n", unit);
return NULL;
}
}
bt = malloc(sizeof(struct bt_softc), M_DEVBUF, M_NOWAIT);
if (!bt) {
printf("bt%d: cannot malloc!\n", unit);
return NULL;
}
bzero(bt, sizeof(struct bt_softc));
SLIST_INIT(&bt->free_bt_ccbs);
LIST_INIT(&bt->pending_ccbs);
SLIST_INIT(&bt->sg_maps);
bt->unit = unit;
bt->tag = tag;
bt->bsh = bsh;
if (bt->unit != BT_TEMP_UNIT) {
bt_softcs[unit] = bt;
}
return (bt);
bt->dev = dev;
bt->unit = device_get_unit(dev);
bt->port = port;
bt->irq = irq;
bt->drq = drq;
bt->tag = rman_get_bustag(port);
bt->bsh = rman_get_bushandle(port);
}
void
bt_free(struct bt_softc *bt)
bt_free_softc(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
switch (bt->init_level) {
default:
case 11:
@ -294,20 +277,17 @@ bt_free(struct bt_softc *bt)
case 0:
break;
}
if (bt->unit != BT_TEMP_UNIT) {
bt_softcs[bt->unit] = NULL;
}
free(bt, M_DEVBUF);
}
int
bt_port_probe(struct bt_softc *bt, struct bt_probe_info *info)
bt_port_probe(device_t dev, struct bt_probe_info *info)
{
struct bt_softc *bt = device_get_softc(dev);
config_data_t config_data;
int error;
/* See if there is really a card present */
if (bt_probe(bt) || bt_fetch_adapter_info(bt))
if (bt_probe(dev) || bt_fetch_adapter_info(dev))
return(1);
/*
@ -365,8 +345,9 @@ bt_port_probe(struct bt_softc *bt, struct bt_probe_info *info)
* Probe the adapter and verify that the card is a BusLogic.
*/
int
bt_probe(struct bt_softc* bt)
bt_probe(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
esetup_info_data_t esetup_info;
u_int status;
u_int intstat;
@ -384,21 +365,21 @@ bt_probe(struct bt_softc* bt)
|| (status & (DIAG_ACTIVE|CMD_REG_BUSY|
STATUS_REG_RSVD|CMD_INVALID)) != 0) {
if (bootverbose)
printf("%s: Failed Status Reg Test - %x\n", bt_name(bt),
device_printf(dev, "Failed Status Reg Test - %x\n",
status);
return (ENXIO);
}
intstat = bt_inb(bt, INTSTAT_REG);
if ((intstat & INTSTAT_REG_RSVD) != 0) {
printf("%s: Failed Intstat Reg Test\n", bt_name(bt));
device_printf(dev, "Failed Intstat Reg Test\n");
return (ENXIO);
}
geometry = bt_inb(bt, GEOMETRY_REG);
if (geometry == 0xFF) {
if (bootverbose)
printf("%s: Failed Geometry Reg Test\n", bt_name(bt));
device_printf(dev, "Failed Geometry Reg Test\n");
return (ENXIO);
}
@ -409,7 +390,7 @@ bt_probe(struct bt_softc* bt)
*/
if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) {
if (bootverbose)
printf("%s: Failed Reset\n", bt_name(bt));
device_printf(dev, "Failed Reset\n");
return (ENXIO);
}
@ -428,8 +409,9 @@ bt_probe(struct bt_softc* bt)
* Pull the boards setup information and record it in our softc.
*/
int
bt_fetch_adapter_info(struct bt_softc *bt)
bt_fetch_adapter_info(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
board_id_data_t board_id;
esetup_info_data_t esetup_info;
config_data_t config_data;
@ -441,8 +423,7 @@ bt_fetch_adapter_info(struct bt_softc *bt)
(u_int8_t*)&board_id, sizeof(board_id),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed Get Board Info\n",
bt_name(bt));
device_printf(dev, "bt_fetch_adapter_info - Failed Get Board Info\n");
return (error);
}
bt->firmware_ver[0] = board_id.firmware_rev_major;
@ -460,8 +441,9 @@ bt_fetch_adapter_info(struct bt_softc *bt)
(u_int8_t*)&bt->firmware_ver[3], 1,
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed Get "
"Firmware 3rd Digit\n", bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed Get "
"Firmware 3rd Digit\n");
return (error);
}
if (bt->firmware_ver[3] == ' ')
@ -475,8 +457,9 @@ bt_fetch_adapter_info(struct bt_softc *bt)
(u_int8_t*)&bt->firmware_ver[4], 1,
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed Get "
"Firmware 4th Digit\n", bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed Get "
"Firmware 4th Digit\n");
return (error);
}
if (bt->firmware_ver[4] == ' ')
@ -532,8 +515,9 @@ bt_fetch_adapter_info(struct bt_softc *bt)
(u_int8_t*)&model_data, sizeof(model_data),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed Inquire "
"Model Number\n", bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed Inquire "
"Model Number\n");
return (error);
}
for (i = 0; i < sizeof(model_data.ascii_model); i++) {
@ -617,8 +601,9 @@ bt_fetch_adapter_info(struct bt_softc *bt)
sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed "
"Get Auto SCSI Info\n", bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed "
"Get Auto SCSI Info\n");
return (error);
}
@ -651,8 +636,9 @@ bt_fetch_adapter_info(struct bt_softc *bt)
sizeof(setup_info), DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed "
"Get Setup Info\n", bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed "
"Get Setup Info\n");
return (error);
}
@ -678,8 +664,8 @@ bt_fetch_adapter_info(struct bt_softc *bt)
(u_int8_t*)&config_data, sizeof(config_data),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
printf("%s: bt_fetch_adapter_info - Failed Get Config\n",
bt_name(bt));
device_printf(dev,
"bt_fetch_adapter_info - Failed Get Config\n");
return (error);
}
bt->scsi_id = config_data.scsi_id;
@ -691,11 +677,12 @@ bt_fetch_adapter_info(struct bt_softc *bt)
* Start the board, ready for normal operation
*/
int
bt_init(struct bt_softc* bt)
bt_init(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
/* Announce the Adapter */
printf("%s: BT-%s FW Rev. %s ", bt_name(bt),
bt->model, bt->firmware_ver);
device_printf(dev, "BT-%s FW Rev. %s ", bt->model, bt->firmware_ver);
if (bt->ultra_scsi != 0)
printf("Ultra ");
@ -818,8 +805,8 @@ bt_init(struct bt_softc* bt)
btallocccbs(bt);
if (bt->num_ccbs == 0) {
printf("%s: bt_init - Unable to allocate initial ccbs\n",
bt_name(bt));
device_printf(dev,
"bt_init - Unable to allocate initial ccbs\n");
goto error_exit;
}
@ -834,8 +821,9 @@ bt_init(struct bt_softc* bt)
}
int
bt_attach(struct bt_softc *bt)
bt_attach(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
int tagged_dev_openings;
struct cam_devq *devq;
@ -878,18 +866,14 @@ bt_attach(struct bt_softc *bt)
return (ENXIO);
}
/*
* Setup interrupt.
*/
bus_setup_intr(dev, bt->irq, bt_intr, bt, &bt->ih);
return (0);
}
char *
bt_name(struct bt_softc *bt)
{
static char name[10];
snprintf(name, sizeof(name), "bt%d", bt->unit);
return (name);
}
int
bt_check_probed_iop(u_int ioport)
{
@ -1055,7 +1039,7 @@ btgetccb(struct bt_softc *bt)
btallocccbs(bt);
bccb = SLIST_FIRST(&bt->free_bt_ccbs);
if (bccb == NULL)
printf("%s: Can't malloc BCCB\n", bt_name(bt));
device_printf(bt->dev, "Can't malloc BCCB\n");
else {
SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
bt->active_ccbs++;
@ -1388,8 +1372,9 @@ btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
if (error != 0) {
if (error != EFBIG)
printf("%s: Unexepected error 0x%x returned from "
"bus_dmamap_load\n", bt_name(bt), error);
device_printf(bt->dev,
"Unexepected error 0x%x returned from "
"bus_dmamap_load\n", error);
if (ccb->ccb_h.status == CAM_REQ_INPROG) {
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
@ -1470,9 +1455,10 @@ btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* hung, one of the pending transactions will
* timeout causing us to start recovery operations.
*/
printf("%s: Encountered busy mailbox with %d out of %d "
"commands active!!!\n", bt_name(bt), bt->active_ccbs,
bt->max_ccbs);
device_printf(bt->dev,
"Encountered busy mailbox with %d out of %d "
"commands active!!!\n", bt->active_ccbs,
bt->max_ccbs);
untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch);
if (nseg != 0)
bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
@ -1531,8 +1517,9 @@ btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code)
csio = &bccb->ccb->csio;
if ((bccb->flags & BCCB_ACTIVE) == 0) {
printf("%s: btdone - Attempt to free non-active BCCB %p\n",
bt_name(bt), (void *)bccb);
device_printf(bt->dev,
"btdone - Attempt to free non-active BCCB %p\n",
(void *)bccb);
return;
}
@ -1586,7 +1573,7 @@ btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code)
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
printf("%s: No longer in timeout\n", bt_name(bt));
device_printf(bt->dev, "No longer in timeout\n");
return;
}
@ -1594,12 +1581,12 @@ btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code)
switch (comp_code) {
case BMBI_FREE:
printf("%s: btdone - CCB completed with free status!\n",
bt_name(bt));
device_printf(bt->dev,
"btdone - CCB completed with free status!\n");
break;
case BMBI_NOT_FOUND:
printf("%s: btdone - CCB Abort failed to find CCB\n",
bt_name(bt));
device_printf(bt->dev,
"btdone - CCB Abort failed to find CCB\n");
break;
case BMBI_ABORT:
case BMBI_ERROR:

View File

@ -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,21 +103,59 @@
#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 struct eisa_driver bt_eisa_driver = {
"bt",
bt_eisa_probe,
bt_eisa_attach,
/*shutdown*/NULL,
&bt_unit
};
DATA_SET (eisadriver_set, bt_eisa_driver);
static const char *bt_match(eisa_id_t type);
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;
/*
* 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;
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;
struct bt_probe_info info;
u_long port;
u_long iosize;
u_int ioconf;
int result;
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;
desc = bt_match(eisa_get_id(dev));
if (!desc)
return (ENXIO);
device_set_desc(dev, desc);
iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
if (e_dev->id == EISA_DEVICE_ID_AMI_4801) {
u_int ioconf1;
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",
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;
}
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);
}
bt_mark_probed_iop(port);
} else {
iobase += BT_EISA_SLOT_OFFSET;
iosize = BT_EISA_IOSIZE;
/* 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;
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);
}
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++;
}
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;
struct bt_softc *bt = device_get_softc(dev);
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;
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);
bt_eisa_release_resources(dev);
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);
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 */

View File

@ -26,33 +26,90 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt_isa.c,v 1.6 1999/03/08 21:32:59 gibbs Exp $
* $Id: bt_isa.c,v 1.7 1999/04/06 21:15:18 phk Exp $
*/
#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/isa/isa_device.h>
#include <isa/isavar.h>
#include <i386/isa/isa_dma.h>
#include <dev/buslogic/btreg.h>
#include <cam/scsi/scsi_all.h>
static int bt_isa_probe __P((struct isa_device *dev));
static int bt_isa_attach __P((struct isa_device *dev));
static void bt_isa_intr __P((void *unit));
static bus_dma_filter_t btvlbouncefilter;
static bus_dmamap_callback_t btmapsensebuffers;
struct isa_driver btdriver =
static int
bt_isa_alloc_resources(device_t dev)
{
bt_isa_probe,
bt_isa_attach,
"bt"
};
int rid;
struct resource *port;
struct resource *irq;
struct resource *drq;
rid = 0;
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, 1, RF_ACTIVE);
if (!port)
return (ENOMEM);
if (isa_get_irq(dev) != -1) {
rid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!irq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
return (ENOMEM);
}
} else
irq = 0;
if (isa_get_drq(dev) != -1) {
rid = 0;
drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!drq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
if (irq)
bus_release_resource(dev, SYS_RES_IRQ,
0, irq);
return (ENOMEM);
}
} else
drq = 0;
bt_init_softc(dev, port, irq, drq);
return (0);
}
static void
bt_isa_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);
if (bt->drq)
bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->drq);
bt_free_softc(dev);
}
/*
* Check if the device can be found at the port given
@ -61,35 +118,24 @@ struct isa_driver btdriver =
* autoconf.c
*/
static int
bt_isa_probe(dev)
struct isa_device *dev;
bt_isa_probe(device_t dev)
{
/*
* find unit and check we have that many defined
*/
struct bt_softc *bt;
int port_index;
int max_port_index;
/*
* We ignore the unit number assigned by config to allow
* consistant numbering between PCI/EISA/ISA devices.
* This is a total kludge until we have a configuration
* manager.
*/
dev->id_unit = bt_unit;
bt = NULL;
port_index = 0;
max_port_index = BT_NUM_ISAPORTS - 1;
/*
* Bound our board search if the user has
* specified an exact port.
*/
bt_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
bt_find_probe_range(isa_get_port(dev), &port_index, &max_port_index);
if (port_index < 0)
return 0;
return (ENXIO);
/* Attempt to find an adapter */
for (;port_index <= max_port_index; port_index++) {
@ -97,6 +143,8 @@ bt_isa_probe(dev)
u_int ioport;
ioport = bt_iop_from_bio(port_index);
isa_set_port(dev, ioport);
isa_set_portsize(dev, BT_NREGS);
/*
* Ensure this port has not already been claimed already
@ -104,52 +152,50 @@ bt_isa_probe(dev)
*/
if (bt_check_probed_iop(ioport) != 0)
continue;
dev->id_iobase = ioport;
if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
/* Initialise the softc for use during probing */
if (bt_isa_alloc_resources(dev) != 0)
continue;
/* Allocate a softc for use during probing */
bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
if (bt == NULL)
break;
/* We're going to attempt to probe it now, so mark it probed */
bt_mark_probed_bio(port_index);
if (bt_port_probe(bt, &info) != 0) {
if (bt_port_probe(dev, &info) != 0) {
printf("bt_isa_probe: Probe failed for card at 0x%x\n",
ioport);
bt_free(bt);
bt_isa_release_resources(dev);
continue;
}
dev->id_drq = info.drq;
dev->id_irq = 0x1 << info.irq;
dev->id_intr = bt_isa_intr;
bt_isa_release_resources(dev);
bt_unit++;
return (BT_NREGS);
isa_set_drq(dev, info.drq);
isa_set_irq(dev, info.irq);
return (0);
}
return (0);
return (ENXIO);
}
/*
* Attach all the sub-devices we can find
*/
static int
bt_isa_attach(dev)
struct isa_device *dev;
bt_isa_attach(device_t dev)
{
struct bt_softc *bt;
struct bt_softc *bt = device_get_softc(dev);
bus_dma_filter_t *filter;
void *filter_arg;
bus_addr_t lowaddr;
int error;
bt = bt_softcs[dev->id_unit];
if (dev->id_drq != -1)
isa_dmacascade(dev->id_drq);
/* Initialise softc */
error = bt_isa_alloc_resources(dev);
if (error) {
device_printf(dev, "can't allocate resources in bt_isa_attach\n");
return error;
}
/* Allocate our parent dmatag */
filter = NULL;
@ -186,13 +232,13 @@ bt_isa_attach(dev)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (bt_init(bt)) {
bt_free(bt);
return (-1);
if (bt_init(dev)) {
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
@ -207,8 +253,8 @@ bt_isa_attach(dev)
/*nsegments*/1,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->sense_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -217,8 +263,8 @@ bt_isa_attach(dev)
if (bus_dmamem_alloc(bt->sense_dmat,
(void **)&bt->sense_buffers,
BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -232,19 +278,13 @@ bt_isa_attach(dev)
bt->init_level++;
}
return (bt_attach(bt));
}
error = bt_attach(dev);
if (error) {
bt_isa_release_resources(dev);
return (error);
}
/*
* Handle an ISA interrupt.
* XXX should go away as soon as ISA interrupt handlers
* take a (void *) arg.
*/
static void
bt_isa_intr(void *unit)
{
struct bt_softc* arg = bt_softcs[(int)unit];
bt_intr((void *)arg);
return (0);
}
#define BIOS_MAP_SIZE (16 * 1024)
@ -273,3 +313,22 @@ btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
bt = (struct bt_softc*)arg;
bt->sense_buffers_physbase = segs->ds_addr;
}
static device_method_t bt_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bt_isa_probe),
DEVMETHOD(device_attach, bt_isa_attach),
{ 0, 0 }
};
static driver_t bt_isa_driver = {
"bt",
bt_isa_methods,
DRIVER_TYPE_CAM,
sizeof(struct bt_softc),
};
static devclass_t bt_devclass;
DRIVER_MODULE(bt, isa, bt_isa_driver, bt_devclass, 0, 0);

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt_pci.c,v 1.3 1998/11/10 06:45:14 gibbs Exp $
* $Id: bt_pci.c,v 1.4 1998/12/14 06:32:54 dillon Exp $
*/
#include "pci.h"
@ -34,6 +34,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@ -41,6 +42,8 @@
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/buslogic/btreg.h>
@ -51,72 +54,74 @@
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140104Bul
#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130104Bul
static int btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp,
bus_space_handle_t* bshp);
static const char* bt_pci_probe(pcici_t tag, pcidi_t type);
static void bt_pci_attach(pcici_t config_id, int unit);
static struct pci_device bt_pci_driver = {
"bt",
bt_pci_probe,
bt_pci_attach,
&bt_unit,
NULL
};
DATA_SET (pcidevice_set, bt_pci_driver);
static int
btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp,
bus_space_handle_t* bshp)
bt_pci_alloc_resources(device_t dev)
{
vm_offset_t vaddr;
vm_offset_t paddr;
u_int16_t io_port;
int command;
int command, type = 0, rid, zero;
struct resource *regs = 0;
struct resource *irq = 0;
vaddr = 0;
paddr = 0;
command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
/* XXX Memory Mapped I/O seems to cause problems */
command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
#if 0
if ((command & PCIM_CMD_MEMEN) == 0
|| (pci_map_mem(config_id, BT_PCI_MEMADDR, &vaddr, &paddr)) == 0)
#endif
if ((command & PCIM_CMD_PORTEN) == 0
|| (pci_map_port(config_id, BT_PCI_IOADDR, &io_port)) == 0)
return (-1);
if (vaddr != 0) {
*tagp = I386_BUS_SPACE_MEM;
*bshp = vaddr;
} else {
*tagp = I386_BUS_SPACE_IO;
*bshp = io_port;
/* XXX Memory Mapped I/O seems to cause problems */
if (command & PCIM_CMD_MEMEN) {
type = SYS_RES_MEMORY;
rid = BT_PCI_MEMADDR;
regs = bus_alloc_resource(dev, type, &rid,
0, ~0, 1, RF_ACTIVE);
}
#else
if (!regs && (command & PCIM_CMD_PORTEN)) {
type = SYS_RES_IOPORT;
rid = BT_PCI_IOADDR;
regs = bus_alloc_resource(dev, type, &rid,
0, ~0, 1, RF_ACTIVE);
}
#endif
if (!regs)
return (ENOMEM);
zero = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (!irq) {
bus_release_resource(dev, type, rid, regs);
return (ENOMEM);
}
bt_init_softc(dev, regs, irq, 0);
return (0);
}
static const char*
bt_pci_probe (pcici_t config_id, pcidi_t type)
static void
bt_pci_release_resources(device_t dev)
{
switch(type) {
struct bt_softc *bt = device_get_softc(dev);
if (bt->port)
/* XXX can't cope with memory registers anyway */
bus_release_resource(dev, SYS_RES_IOPORT,
BT_PCI_IOADDR, bt->port);
if (bt->irq)
bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->irq);
bt_free_softc(dev);
}
static int
bt_pci_probe(device_t dev)
{
switch (pci_get_devid(dev)) {
case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER:
case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC:
{
struct bt_softc *bt;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct bt_softc *bt = device_get_softc(dev);
pci_info_data_t pci_info;
int error;
if (btpcideterminebusspace(config_id, &tag, &bsh) != 0)
break;
bt = bt_alloc(BT_TEMP_UNIT, tag, bsh);
if (bt == NULL)
break;
error = bt_pci_alloc_resources(dev);
if (error)
return (error);
/*
* Determine if an ISA compatible I/O port has been
@ -131,7 +136,7 @@ bt_pci_probe (pcici_t config_id, pcidi_t type)
if (error == 0
&& pci_info.io_port < BIO_DISABLED) {
bt_mark_probed_bio(pci_info.io_port);
if (bsh != bt_iop_from_bio(pci_info.io_port)) {
if (bt->bsh != bt_iop_from_bio(pci_info.io_port)) {
u_int8_t new_addr;
new_addr = BIO_DISABLED;
@ -142,30 +147,30 @@ bt_pci_probe (pcici_t config_id, pcidi_t type)
DEFAULT_CMD_TIMEOUT);
}
}
bt_free(bt);
return ("Buslogic Multi-Master SCSI Host Adapter");
break;
bt_pci_release_resources(dev);
device_set_desc(dev, "Buslogic Multi-Master SCSI Host Adapter");
return (0);
}
default:
break;
}
return (NULL);
return (ENXIO);
}
static void
bt_pci_attach(pcici_t config_id, int unit)
static int
bt_pci_attach(device_t dev)
{
struct bt_softc *bt;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct bt_softc *bt = device_get_softc(dev);
int opri;
int error;
if (btpcideterminebusspace(config_id, &tag, &bsh) != 0)
return;
if ((bt = bt_alloc(unit, tag, bsh)) == NULL)
return; /* XXX PCI code should take return status */
/* Initialise softc */
error = bt_pci_alloc_resources(dev);
if (error) {
device_printf(dev, "can't allocate resources in bt_pci_attach\n");
return error;
}
/* Allocate a dmatag for our CCB DMA maps */
/* XXX Should be a child of the PCI bus dma tag */
@ -177,14 +182,10 @@ bt_pci_attach(pcici_t config_id, int unit)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
bt_free(bt);
return;
bt_pci_release_resources(dev);
return (ENOMEM);
}
if ((pci_map_int(config_id, bt_intr, (void *)bt, &cam_imask)) == 0) {
bt_free(bt);
return;
}
/*
* Protect ourself from spurrious interrupts during
* intialization and attach. We should really rely
@ -195,16 +196,40 @@ bt_pci_attach(pcici_t config_id, int unit)
*/
opri = splcam();
if (bt_probe(bt) || bt_fetch_adapter_info(bt) || bt_init(bt)) {
bt_free(bt);
if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) {
bt_pci_release_resources(dev);
splx(opri);
return; /* XXX PCI code should take return status */
return (ENXIO);
}
bt_attach(bt);
error = bt_attach(dev);
splx(opri);
return;
if (error) {
bt_pci_release_resources(dev);
return (error);
}
return (0);
}
static device_method_t bt_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bt_pci_probe),
DEVMETHOD(device_attach, bt_pci_attach),
{ 0, 0 }
};
static driver_t bt_pci_driver = {
"bt",
bt_pci_methods,
DRIVER_TYPE_CAM,
sizeof(struct bt_softc),
};
static devclass_t bt_devclass;
DRIVER_MODULE(bt, pci, bt_pci_driver, bt_devclass, 0, 0);
#endif /* NPCI > 0 */

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: btreg.h,v 1.4 1999/03/08 21:36:34 gibbs Exp $
* $Id: btreg.h,v 1.5 1999/04/07 23:01:43 gibbs Exp $
*/
#ifndef _BTREG_H_
@ -595,6 +595,11 @@ struct sg_map_node {
};
struct bt_softc {
struct device *dev;
struct resource *port;
struct resource *irq;
struct resource *drq;
void *ih;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct cam_sim *sim;
@ -663,17 +668,18 @@ extern struct bt_softc *bt_softcs[]; /* XXX Config should handle this */
extern u_long bt_unit;
#define BT_TEMP_UNIT 0xFF /* Unit for probes */
struct bt_softc* bt_alloc(int unit, bus_space_tag_t tag,
bus_space_handle_t bsh);
void bt_free(struct bt_softc *bt);
int bt_port_probe(struct bt_softc *bt,
void bt_init_softc(device_t dev,
struct resource *port,
struct resource *irq,
struct resource *drq);
void bt_free_softc(device_t dev);
int bt_port_probe(device_t dev,
struct bt_probe_info *info);
int bt_probe(struct bt_softc *bt);
int bt_fetch_adapter_info(struct bt_softc *bt);
int bt_init(struct bt_softc *bt);
int bt_attach(struct bt_softc *bt);
int bt_probe(device_t dev);
int bt_fetch_adapter_info(device_t dev);
int bt_init(device_t dev);
int bt_attach(device_t dev);
void bt_intr(void *arg);
char * bt_name(struct bt_softc *bt);
int bt_check_probed_iop(u_int ioport);
void bt_mark_probed_bio(isa_compat_io_t port);
void bt_mark_probed_iop(u_int ioport);
@ -689,6 +695,8 @@ int bt_cmd(struct bt_softc *bt, bt_op_t opcode,
u_int8_t *reply_data, u_int reply_len,
u_int cmd_timeout);
#define bt_name(bt) device_get_nameunit(bt->dev)
#define bt_inb(bt, port) \
bus_space_read_1((bt)->tag, (bt)->bsh, port)

View File

@ -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",
e_dev->ioconf.slot, irq);
irq = 0;
break;
}
if (irq == 0)
continue;
eisa_add_intr(e_dev, irq);
eisa_registerdev(e_dev, &dpt_eisa_driver);
count++;
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;
}
return count;
if (irq == 0)
return ENXIO;
eisa_add_intr(dev, irq);
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;
int rid;
void *ih;
if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL) {
printf("dpt%d: Can't retrieve irq from EISA config struct.\n",
unit);
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;
io_space = e_dev->ioconf.ioaddrs.lh_first;
shared = (inb(DPT_EISA_INTDEF + rman_get_start(io))
& DPT_EISA_INT_LEVEL) ? RF_SHAREABLE : 0;
if (!io_space) {
printf("dpt%d: No I/O space?!\n", unit);
return -1;
}
shared = inb(DPT_EISA_INTDEF + io_space->addr) & DPT_EISA_INT_LEVEL;
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 */

View File

@ -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;
TAILQ_HEAD(irqlist, irq_node);
static struct eisa_driver mainboard_drv = {
"eisa",
NULL,
NULL,
NULL,
&eisa_unit
};
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;
/*
* "Attach" the system board
*/
/* 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;
}
if (!eisa_dev_list) {
/*
* No devices.
*/
return;
}
/*
* See what devices we recognize.
*/
while((e_drv = *e_drvp++)) {
if (e_drv->probe)
(*e_drv->probe)();
}
/*
* 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;
}
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);
}
}
return 0;
}
struct eisa_device *
eisa_match_dev(e_dev, match_func)
struct eisa_device *e_dev;
const char* (*match_func)(eisa_id_t);
static void
eisa_print_child(device_t dev, device_t child)
{
struct eisa_device_node *e_node = eisa_dev_list;
if (e_dev) {
/* Start our search from the last successful match */
e_node = ((struct eisa_device_node *)e_dev)->next;
}
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));
}
}
return NULL;
/* XXX print resource descriptions? */
printf(" at slot %d", eisa_get_slot(child));
printf(" on %s", device_get_nameunit(dev));
}
static int
eisa_find_irq(struct eisa_device *e_dev, int rid)
{
int i;
struct irq_node *irq;
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);
}
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;
}
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;
}
static int
eisa_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
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;
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);
}
rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
if (rv == 0) {
if (resv)
resv->res = 0;
}
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);

View File

@ -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_ */

View File

@ -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;
u_short conf;
u_long port;
int irq;
count = 0;
while ((e_dev = eisa_match_dev(e_dev, ep_match))) {
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 = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
iobase = port + EP_EISA_SLOT_OFFSET;
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)
continue;
/* We must be in EISA configuration mode */
if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
return ENXIO;
eisa_add_iospace(e_dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
eisa_add_iospace(e_dev, port, EP_IOSIZE, RESVADDR_NONE);
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:
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;
int i, rid, shared;
void *ih;
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 ep
* driver comes first.
*/
ioport = e_dev->ioconf.ioaddrs.lh_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(!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;
}
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 */

View File

@ -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;
if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
return (-1);
/*
* 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;
}
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 */

View File

@ -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;
u_short conf;
u_long port;
int irq;
count = 0;
while ((e_dev = eisa_match_dev(e_dev, ep_match))) {
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 = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
iobase = port + EP_EISA_SLOT_OFFSET;
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)
continue;
/* We must be in EISA configuration mode */
if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
return ENXIO;
eisa_add_iospace(e_dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
eisa_add_iospace(e_dev, port, EP_IOSIZE, RESVADDR_NONE);
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:
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;
int i, rid, shared;
void *ih;
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 ep
* driver comes first.
*/
ioport = e_dev->ioconf.ioaddrs.lh_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(!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;
}
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 */

View File

@ -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;
desc = adveisamatch(eisa_get_id(dev));
if (!desc)
return (ENXIO);
device_set_desc(dev, desc);
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++;
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 */

View File

@ -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;
struct resource *io = 0;
struct resource *irq = 0;
int shared, rid;
void *ih;
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);
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 */

View File

@ -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;
hcntrl = inb(iobase + HCNTRL) & IRQMS;
outb(iobase + HCNTRL, hcntrl | PAUSE);
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++;
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;
struct resource *io = 0;
struct resource *irq = 0;
int unit = device_get_unit(dev);
int error, rid;
int shared;
void *ih;
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;
iospace = e_dev->ioconf.ioaddrs.lh_first;
if (!iospace)
return -1;
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 */

View File

@ -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,21 +103,59 @@
#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 struct eisa_driver bt_eisa_driver = {
"bt",
bt_eisa_probe,
bt_eisa_attach,
/*shutdown*/NULL,
&bt_unit
};
DATA_SET (eisadriver_set, bt_eisa_driver);
static const char *bt_match(eisa_id_t type);
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;
/*
* 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;
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;
struct bt_probe_info info;
u_long port;
u_long iosize;
u_int ioconf;
int result;
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;
desc = bt_match(eisa_get_id(dev));
if (!desc)
return (ENXIO);
device_set_desc(dev, desc);
iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
if (e_dev->id == EISA_DEVICE_ID_AMI_4801) {
u_int ioconf1;
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",
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;
}
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);
}
bt_mark_probed_iop(port);
} else {
iobase += BT_EISA_SLOT_OFFSET;
iosize = BT_EISA_IOSIZE;
/* 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;
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);
}
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++;
}
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;
struct bt_softc *bt = device_get_softc(dev);
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;
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);
bt_eisa_release_resources(dev);
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);
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 */

View File

@ -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",
e_dev->ioconf.slot, irq);
irq = 0;
break;
}
if (irq == 0)
continue;
eisa_add_intr(e_dev, irq);
eisa_registerdev(e_dev, &dpt_eisa_driver);
count++;
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;
}
return count;
if (irq == 0)
return ENXIO;
eisa_add_intr(dev, irq);
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;
int rid;
void *ih;
if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL) {
printf("dpt%d: Can't retrieve irq from EISA config struct.\n",
unit);
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;
io_space = e_dev->ioconf.ioaddrs.lh_first;
shared = (inb(DPT_EISA_INTDEF + rman_get_start(io))
& DPT_EISA_INT_LEVEL) ? RF_SHAREABLE : 0;
if (!io_space) {
printf("dpt%d: No I/O space?!\n", unit);
return -1;
}
shared = inb(DPT_EISA_INTDEF + io_space->addr) & DPT_EISA_INT_LEVEL;
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 */

View File

@ -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;
TAILQ_HEAD(irqlist, irq_node);
static struct eisa_driver mainboard_drv = {
"eisa",
NULL,
NULL,
NULL,
&eisa_unit
};
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;
/*
* "Attach" the system board
*/
/* 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;
}
if (!eisa_dev_list) {
/*
* No devices.
*/
return;
}
/*
* See what devices we recognize.
*/
while((e_drv = *e_drvp++)) {
if (e_drv->probe)
(*e_drv->probe)();
}
/*
* 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;
}
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);
}
}
return 0;
}
struct eisa_device *
eisa_match_dev(e_dev, match_func)
struct eisa_device *e_dev;
const char* (*match_func)(eisa_id_t);
static void
eisa_print_child(device_t dev, device_t child)
{
struct eisa_device_node *e_node = eisa_dev_list;
if (e_dev) {
/* Start our search from the last successful match */
e_node = ((struct eisa_device_node *)e_dev)->next;
}
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));
}
}
return NULL;
/* XXX print resource descriptions? */
printf(" at slot %d", eisa_get_slot(child));
printf(" on %s", device_get_nameunit(dev));
}
static int
eisa_find_irq(struct eisa_device *e_dev, int rid)
{
int i;
struct irq_node *irq;
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);
}
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;
}
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;
}
static int
eisa_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
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;
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);
}
rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
if (rv == 0) {
if (resv)
resv->res = 0;
}
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);

View File

@ -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_ */

View File

@ -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;
if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
return (-1);
/*
* 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;
}
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 */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.112 1999/04/15 14:52:24 bde Exp $
* $Id: autoconf.c,v 1.113 1999/04/16 21:22:11 peter Exp $
*/
/*
@ -232,10 +232,6 @@ configure(dummy)
INTREN(IRQ_SLAVE);
#endif /* APIC_IO */
#if NEISA > 0
eisa_configure();
#endif
#if NPNP > 0
pnp_configure();
#endif

View File

@ -26,33 +26,90 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt_isa.c,v 1.6 1999/03/08 21:32:59 gibbs Exp $
* $Id: bt_isa.c,v 1.7 1999/04/06 21:15:18 phk Exp $
*/
#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/isa/isa_device.h>
#include <isa/isavar.h>
#include <i386/isa/isa_dma.h>
#include <dev/buslogic/btreg.h>
#include <cam/scsi/scsi_all.h>
static int bt_isa_probe __P((struct isa_device *dev));
static int bt_isa_attach __P((struct isa_device *dev));
static void bt_isa_intr __P((void *unit));
static bus_dma_filter_t btvlbouncefilter;
static bus_dmamap_callback_t btmapsensebuffers;
struct isa_driver btdriver =
static int
bt_isa_alloc_resources(device_t dev)
{
bt_isa_probe,
bt_isa_attach,
"bt"
};
int rid;
struct resource *port;
struct resource *irq;
struct resource *drq;
rid = 0;
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, 1, RF_ACTIVE);
if (!port)
return (ENOMEM);
if (isa_get_irq(dev) != -1) {
rid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!irq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
return (ENOMEM);
}
} else
irq = 0;
if (isa_get_drq(dev) != -1) {
rid = 0;
drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!drq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
if (irq)
bus_release_resource(dev, SYS_RES_IRQ,
0, irq);
return (ENOMEM);
}
} else
drq = 0;
bt_init_softc(dev, port, irq, drq);
return (0);
}
static void
bt_isa_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);
if (bt->drq)
bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->drq);
bt_free_softc(dev);
}
/*
* Check if the device can be found at the port given
@ -61,35 +118,24 @@ struct isa_driver btdriver =
* autoconf.c
*/
static int
bt_isa_probe(dev)
struct isa_device *dev;
bt_isa_probe(device_t dev)
{
/*
* find unit and check we have that many defined
*/
struct bt_softc *bt;
int port_index;
int max_port_index;
/*
* We ignore the unit number assigned by config to allow
* consistant numbering between PCI/EISA/ISA devices.
* This is a total kludge until we have a configuration
* manager.
*/
dev->id_unit = bt_unit;
bt = NULL;
port_index = 0;
max_port_index = BT_NUM_ISAPORTS - 1;
/*
* Bound our board search if the user has
* specified an exact port.
*/
bt_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
bt_find_probe_range(isa_get_port(dev), &port_index, &max_port_index);
if (port_index < 0)
return 0;
return (ENXIO);
/* Attempt to find an adapter */
for (;port_index <= max_port_index; port_index++) {
@ -97,6 +143,8 @@ bt_isa_probe(dev)
u_int ioport;
ioport = bt_iop_from_bio(port_index);
isa_set_port(dev, ioport);
isa_set_portsize(dev, BT_NREGS);
/*
* Ensure this port has not already been claimed already
@ -104,52 +152,50 @@ bt_isa_probe(dev)
*/
if (bt_check_probed_iop(ioport) != 0)
continue;
dev->id_iobase = ioport;
if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
/* Initialise the softc for use during probing */
if (bt_isa_alloc_resources(dev) != 0)
continue;
/* Allocate a softc for use during probing */
bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
if (bt == NULL)
break;
/* We're going to attempt to probe it now, so mark it probed */
bt_mark_probed_bio(port_index);
if (bt_port_probe(bt, &info) != 0) {
if (bt_port_probe(dev, &info) != 0) {
printf("bt_isa_probe: Probe failed for card at 0x%x\n",
ioport);
bt_free(bt);
bt_isa_release_resources(dev);
continue;
}
dev->id_drq = info.drq;
dev->id_irq = 0x1 << info.irq;
dev->id_intr = bt_isa_intr;
bt_isa_release_resources(dev);
bt_unit++;
return (BT_NREGS);
isa_set_drq(dev, info.drq);
isa_set_irq(dev, info.irq);
return (0);
}
return (0);
return (ENXIO);
}
/*
* Attach all the sub-devices we can find
*/
static int
bt_isa_attach(dev)
struct isa_device *dev;
bt_isa_attach(device_t dev)
{
struct bt_softc *bt;
struct bt_softc *bt = device_get_softc(dev);
bus_dma_filter_t *filter;
void *filter_arg;
bus_addr_t lowaddr;
int error;
bt = bt_softcs[dev->id_unit];
if (dev->id_drq != -1)
isa_dmacascade(dev->id_drq);
/* Initialise softc */
error = bt_isa_alloc_resources(dev);
if (error) {
device_printf(dev, "can't allocate resources in bt_isa_attach\n");
return error;
}
/* Allocate our parent dmatag */
filter = NULL;
@ -186,13 +232,13 @@ bt_isa_attach(dev)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (bt_init(bt)) {
bt_free(bt);
return (-1);
if (bt_init(dev)) {
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
@ -207,8 +253,8 @@ bt_isa_attach(dev)
/*nsegments*/1,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->sense_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -217,8 +263,8 @@ bt_isa_attach(dev)
if (bus_dmamem_alloc(bt->sense_dmat,
(void **)&bt->sense_buffers,
BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -232,19 +278,13 @@ bt_isa_attach(dev)
bt->init_level++;
}
return (bt_attach(bt));
}
error = bt_attach(dev);
if (error) {
bt_isa_release_resources(dev);
return (error);
}
/*
* Handle an ISA interrupt.
* XXX should go away as soon as ISA interrupt handlers
* take a (void *) arg.
*/
static void
bt_isa_intr(void *unit)
{
struct bt_softc* arg = bt_softcs[(int)unit];
bt_intr((void *)arg);
return (0);
}
#define BIOS_MAP_SIZE (16 * 1024)
@ -273,3 +313,22 @@ btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
bt = (struct bt_softc*)arg;
bt->sense_buffers_physbase = segs->ds_addr;
}
static device_method_t bt_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bt_isa_probe),
DEVMETHOD(device_attach, bt_isa_attach),
{ 0, 0 }
};
static driver_t bt_isa_driver = {
"bt",
bt_isa_methods,
DRIVER_TYPE_CAM,
sizeof(struct bt_softc),
};
static devclass_t bt_devclass;
DRIVER_MODULE(bt, isa, bt_isa_driver, bt_devclass, 0, 0);

View File

@ -23,11 +23,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: isa_compat.h,v 1.1 1999/04/16 21:22:23 peter Exp $
* $Id: isa_compat.h,v 1.2 1999/04/17 19:38:38 peter Exp $
*/
#include "vt.h"
#include "bt.h"
#include "adv.h"
#include "aha.h"
#include "wdc.h"
@ -96,7 +95,6 @@ struct old_isa_driver {
};
extern struct isa_driver vtdriver;
extern struct isa_driver btdriver;
extern struct isa_driver advdriver;
extern struct isa_driver ahadriver;
extern struct isa_driver wdcdriver;
@ -308,9 +306,6 @@ static struct old_isa_driver old_drivers[] = {
/* CAM */
#if NBT > 0
{ DRIVER_TYPE_CAM, &btdriver },
#endif
#if NADV > 0
{ DRIVER_TYPE_CAM, &advdriver },
#endif

View File

@ -26,33 +26,90 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt_isa.c,v 1.6 1999/03/08 21:32:59 gibbs Exp $
* $Id: bt_isa.c,v 1.7 1999/04/06 21:15:18 phk Exp $
*/
#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/isa/isa_device.h>
#include <isa/isavar.h>
#include <i386/isa/isa_dma.h>
#include <dev/buslogic/btreg.h>
#include <cam/scsi/scsi_all.h>
static int bt_isa_probe __P((struct isa_device *dev));
static int bt_isa_attach __P((struct isa_device *dev));
static void bt_isa_intr __P((void *unit));
static bus_dma_filter_t btvlbouncefilter;
static bus_dmamap_callback_t btmapsensebuffers;
struct isa_driver btdriver =
static int
bt_isa_alloc_resources(device_t dev)
{
bt_isa_probe,
bt_isa_attach,
"bt"
};
int rid;
struct resource *port;
struct resource *irq;
struct resource *drq;
rid = 0;
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, 1, RF_ACTIVE);
if (!port)
return (ENOMEM);
if (isa_get_irq(dev) != -1) {
rid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!irq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
return (ENOMEM);
}
} else
irq = 0;
if (isa_get_drq(dev) != -1) {
rid = 0;
drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
0, ~0, 1, RF_ACTIVE);
if (!drq) {
if (port)
bus_release_resource(dev, SYS_RES_IOPORT,
0, port);
if (irq)
bus_release_resource(dev, SYS_RES_IRQ,
0, irq);
return (ENOMEM);
}
} else
drq = 0;
bt_init_softc(dev, port, irq, drq);
return (0);
}
static void
bt_isa_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);
if (bt->drq)
bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->drq);
bt_free_softc(dev);
}
/*
* Check if the device can be found at the port given
@ -61,35 +118,24 @@ struct isa_driver btdriver =
* autoconf.c
*/
static int
bt_isa_probe(dev)
struct isa_device *dev;
bt_isa_probe(device_t dev)
{
/*
* find unit and check we have that many defined
*/
struct bt_softc *bt;
int port_index;
int max_port_index;
/*
* We ignore the unit number assigned by config to allow
* consistant numbering between PCI/EISA/ISA devices.
* This is a total kludge until we have a configuration
* manager.
*/
dev->id_unit = bt_unit;
bt = NULL;
port_index = 0;
max_port_index = BT_NUM_ISAPORTS - 1;
/*
* Bound our board search if the user has
* specified an exact port.
*/
bt_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
bt_find_probe_range(isa_get_port(dev), &port_index, &max_port_index);
if (port_index < 0)
return 0;
return (ENXIO);
/* Attempt to find an adapter */
for (;port_index <= max_port_index; port_index++) {
@ -97,6 +143,8 @@ bt_isa_probe(dev)
u_int ioport;
ioport = bt_iop_from_bio(port_index);
isa_set_port(dev, ioport);
isa_set_portsize(dev, BT_NREGS);
/*
* Ensure this port has not already been claimed already
@ -104,52 +152,50 @@ bt_isa_probe(dev)
*/
if (bt_check_probed_iop(ioport) != 0)
continue;
dev->id_iobase = ioport;
if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
/* Initialise the softc for use during probing */
if (bt_isa_alloc_resources(dev) != 0)
continue;
/* Allocate a softc for use during probing */
bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
if (bt == NULL)
break;
/* We're going to attempt to probe it now, so mark it probed */
bt_mark_probed_bio(port_index);
if (bt_port_probe(bt, &info) != 0) {
if (bt_port_probe(dev, &info) != 0) {
printf("bt_isa_probe: Probe failed for card at 0x%x\n",
ioport);
bt_free(bt);
bt_isa_release_resources(dev);
continue;
}
dev->id_drq = info.drq;
dev->id_irq = 0x1 << info.irq;
dev->id_intr = bt_isa_intr;
bt_isa_release_resources(dev);
bt_unit++;
return (BT_NREGS);
isa_set_drq(dev, info.drq);
isa_set_irq(dev, info.irq);
return (0);
}
return (0);
return (ENXIO);
}
/*
* Attach all the sub-devices we can find
*/
static int
bt_isa_attach(dev)
struct isa_device *dev;
bt_isa_attach(device_t dev)
{
struct bt_softc *bt;
struct bt_softc *bt = device_get_softc(dev);
bus_dma_filter_t *filter;
void *filter_arg;
bus_addr_t lowaddr;
int error;
bt = bt_softcs[dev->id_unit];
if (dev->id_drq != -1)
isa_dmacascade(dev->id_drq);
/* Initialise softc */
error = bt_isa_alloc_resources(dev);
if (error) {
device_printf(dev, "can't allocate resources in bt_isa_attach\n");
return error;
}
/* Allocate our parent dmatag */
filter = NULL;
@ -186,13 +232,13 @@ bt_isa_attach(dev)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (bt_init(bt)) {
bt_free(bt);
return (-1);
if (bt_init(dev)) {
bt_isa_release_resources(dev);
return (ENOMEM);
}
if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
@ -207,8 +253,8 @@ bt_isa_attach(dev)
/*nsegments*/1,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->sense_dmat) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -217,8 +263,8 @@ bt_isa_attach(dev)
if (bus_dmamem_alloc(bt->sense_dmat,
(void **)&bt->sense_buffers,
BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
bt_free(bt);
return (-1);
bt_isa_release_resources(dev);
return (ENOMEM);
}
bt->init_level++;
@ -232,19 +278,13 @@ bt_isa_attach(dev)
bt->init_level++;
}
return (bt_attach(bt));
}
error = bt_attach(dev);
if (error) {
bt_isa_release_resources(dev);
return (error);
}
/*
* Handle an ISA interrupt.
* XXX should go away as soon as ISA interrupt handlers
* take a (void *) arg.
*/
static void
bt_isa_intr(void *unit)
{
struct bt_softc* arg = bt_softcs[(int)unit];
bt_intr((void *)arg);
return (0);
}
#define BIOS_MAP_SIZE (16 * 1024)
@ -273,3 +313,22 @@ btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
bt = (struct bt_softc*)arg;
bt->sense_buffers_physbase = segs->ds_addr;
}
static device_method_t bt_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bt_isa_probe),
DEVMETHOD(device_attach, bt_isa_attach),
{ 0, 0 }
};
static driver_t bt_isa_driver = {
"bt",
bt_isa_methods,
DRIVER_TYPE_CAM,
sizeof(struct bt_softc),
};
static devclass_t bt_devclass;
DRIVER_MODULE(bt, isa, bt_isa_driver, bt_devclass, 0, 0);

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bt_pci.c,v 1.3 1998/11/10 06:45:14 gibbs Exp $
* $Id: bt_pci.c,v 1.4 1998/12/14 06:32:54 dillon Exp $
*/
#include "pci.h"
@ -34,6 +34,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@ -41,6 +42,8 @@
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/buslogic/btreg.h>
@ -51,72 +54,74 @@
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140104Bul
#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130104Bul
static int btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp,
bus_space_handle_t* bshp);
static const char* bt_pci_probe(pcici_t tag, pcidi_t type);
static void bt_pci_attach(pcici_t config_id, int unit);
static struct pci_device bt_pci_driver = {
"bt",
bt_pci_probe,
bt_pci_attach,
&bt_unit,
NULL
};
DATA_SET (pcidevice_set, bt_pci_driver);
static int
btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp,
bus_space_handle_t* bshp)
bt_pci_alloc_resources(device_t dev)
{
vm_offset_t vaddr;
vm_offset_t paddr;
u_int16_t io_port;
int command;
int command, type = 0, rid, zero;
struct resource *regs = 0;
struct resource *irq = 0;
vaddr = 0;
paddr = 0;
command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
/* XXX Memory Mapped I/O seems to cause problems */
command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
#if 0
if ((command & PCIM_CMD_MEMEN) == 0
|| (pci_map_mem(config_id, BT_PCI_MEMADDR, &vaddr, &paddr)) == 0)
#endif
if ((command & PCIM_CMD_PORTEN) == 0
|| (pci_map_port(config_id, BT_PCI_IOADDR, &io_port)) == 0)
return (-1);
if (vaddr != 0) {
*tagp = I386_BUS_SPACE_MEM;
*bshp = vaddr;
} else {
*tagp = I386_BUS_SPACE_IO;
*bshp = io_port;
/* XXX Memory Mapped I/O seems to cause problems */
if (command & PCIM_CMD_MEMEN) {
type = SYS_RES_MEMORY;
rid = BT_PCI_MEMADDR;
regs = bus_alloc_resource(dev, type, &rid,
0, ~0, 1, RF_ACTIVE);
}
#else
if (!regs && (command & PCIM_CMD_PORTEN)) {
type = SYS_RES_IOPORT;
rid = BT_PCI_IOADDR;
regs = bus_alloc_resource(dev, type, &rid,
0, ~0, 1, RF_ACTIVE);
}
#endif
if (!regs)
return (ENOMEM);
zero = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (!irq) {
bus_release_resource(dev, type, rid, regs);
return (ENOMEM);
}
bt_init_softc(dev, regs, irq, 0);
return (0);
}
static const char*
bt_pci_probe (pcici_t config_id, pcidi_t type)
static void
bt_pci_release_resources(device_t dev)
{
switch(type) {
struct bt_softc *bt = device_get_softc(dev);
if (bt->port)
/* XXX can't cope with memory registers anyway */
bus_release_resource(dev, SYS_RES_IOPORT,
BT_PCI_IOADDR, bt->port);
if (bt->irq)
bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->irq);
bt_free_softc(dev);
}
static int
bt_pci_probe(device_t dev)
{
switch (pci_get_devid(dev)) {
case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER:
case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC:
{
struct bt_softc *bt;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct bt_softc *bt = device_get_softc(dev);
pci_info_data_t pci_info;
int error;
if (btpcideterminebusspace(config_id, &tag, &bsh) != 0)
break;
bt = bt_alloc(BT_TEMP_UNIT, tag, bsh);
if (bt == NULL)
break;
error = bt_pci_alloc_resources(dev);
if (error)
return (error);
/*
* Determine if an ISA compatible I/O port has been
@ -131,7 +136,7 @@ bt_pci_probe (pcici_t config_id, pcidi_t type)
if (error == 0
&& pci_info.io_port < BIO_DISABLED) {
bt_mark_probed_bio(pci_info.io_port);
if (bsh != bt_iop_from_bio(pci_info.io_port)) {
if (bt->bsh != bt_iop_from_bio(pci_info.io_port)) {
u_int8_t new_addr;
new_addr = BIO_DISABLED;
@ -142,30 +147,30 @@ bt_pci_probe (pcici_t config_id, pcidi_t type)
DEFAULT_CMD_TIMEOUT);
}
}
bt_free(bt);
return ("Buslogic Multi-Master SCSI Host Adapter");
break;
bt_pci_release_resources(dev);
device_set_desc(dev, "Buslogic Multi-Master SCSI Host Adapter");
return (0);
}
default:
break;
}
return (NULL);
return (ENXIO);
}
static void
bt_pci_attach(pcici_t config_id, int unit)
static int
bt_pci_attach(device_t dev)
{
struct bt_softc *bt;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct bt_softc *bt = device_get_softc(dev);
int opri;
int error;
if (btpcideterminebusspace(config_id, &tag, &bsh) != 0)
return;
if ((bt = bt_alloc(unit, tag, bsh)) == NULL)
return; /* XXX PCI code should take return status */
/* Initialise softc */
error = bt_pci_alloc_resources(dev);
if (error) {
device_printf(dev, "can't allocate resources in bt_pci_attach\n");
return error;
}
/* Allocate a dmatag for our CCB DMA maps */
/* XXX Should be a child of the PCI bus dma tag */
@ -177,14 +182,10 @@ bt_pci_attach(pcici_t config_id, int unit)
/*nsegments*/BUS_SPACE_UNRESTRICTED,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, &bt->parent_dmat) != 0) {
bt_free(bt);
return;
bt_pci_release_resources(dev);
return (ENOMEM);
}
if ((pci_map_int(config_id, bt_intr, (void *)bt, &cam_imask)) == 0) {
bt_free(bt);
return;
}
/*
* Protect ourself from spurrious interrupts during
* intialization and attach. We should really rely
@ -195,16 +196,40 @@ bt_pci_attach(pcici_t config_id, int unit)
*/
opri = splcam();
if (bt_probe(bt) || bt_fetch_adapter_info(bt) || bt_init(bt)) {
bt_free(bt);
if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) {
bt_pci_release_resources(dev);
splx(opri);
return; /* XXX PCI code should take return status */
return (ENXIO);
}
bt_attach(bt);
error = bt_attach(dev);
splx(opri);
return;
if (error) {
bt_pci_release_resources(dev);
return (error);
}
return (0);
}
static device_method_t bt_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bt_pci_probe),
DEVMETHOD(device_attach, bt_pci_attach),
{ 0, 0 }
};
static driver_t bt_pci_driver = {
"bt",
bt_pci_methods,
DRIVER_TYPE_CAM,
sizeof(struct bt_softc),
};
static devclass_t bt_devclass;
DRIVER_MODULE(bt, pci, bt_pci_driver, bt_devclass, 0, 0);
#endif /* NPCI > 0 */

View File

@ -1,6 +1,6 @@
/**************************************************************************
**
** $Id: pcisupport.c,v 1.96 1999/04/16 21:22:52 peter Exp $
** $Id: pcisupport.c,v 1.97 1999/04/17 19:48:45 dfr Exp $
**
** Device driver for DEC/INTEL PCI chipsets.
**
@ -890,6 +890,19 @@ static devclass_t pcib_devclass;
DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
static const char *
eisab_match(device_t dev)
{
switch (pci_get_devid(dev)) {
case 0x04828086:
/* Recognize this specifically, it has PCI-HOST class (!) */
return ("Intel 82375EB PCI-EISA bridge");
}
return NULL;
}
static const char *
isab_match(device_t dev)
{
@ -901,8 +914,6 @@ isab_match(device_t dev)
if (rev == 3)
return ("Intel 82378ZB PCI to ISA bridge");
return ("Intel 82378IB PCI to ISA bridge");
case 0x04828086:
return ("Intel 82375EB PCI-EISA bridge");
case 0x122e8086:
return ("Intel 82371FB PCI to ISA bridge");
case 0x70008086:
@ -947,10 +958,26 @@ static int
isab_probe(device_t dev)
{
const char *desc;
int is_eisa;
desc = isab_match(dev);
is_eisa = 0;
desc = eisab_match(dev);
if (desc)
is_eisa = 1;
else
desc = isab_match(dev);
if (desc) {
device_set_desc_copy(dev, desc);
/* In case of a generic EISA bridge */
if (pci_get_subclass(dev) == PCIS_BRIDGE_EISA)
is_eisa = 1;
/* For PCI-EISA bridge, add both eisa and isa */
/* Don't bother adding more than one EISA bus */
if (is_eisa && !devclass_get_device(devclass_find("isa"), 0))
device_add_child(dev, "eisa", -1, 0);
/* Don't bother adding more than one ISA bus */
if (!devclass_get_device(devclass_find("isa"), 0))
device_add_child(dev, "isa", -1, 0);