Add support to aic for pccard attachments. Reports from testers have

been so positive that I'm going to go ahead and commit this now rather
than do another round of patches.

My Adaptec 1460D works great with these changes.
This commit is contained in:
imp 2000-01-14 23:42:36 +00:00
parent ca5b317836
commit 7ec55590c7
3 changed files with 185 additions and 1 deletions

View File

@ -70,6 +70,8 @@ static void aic_scsi_reset __P((struct aic_softc *aic));
static void aic_chip_reset __P((struct aic_softc *aic));
static void aic_reset __P((struct aic_softc *aic, int initiate_reset));
devclass_t aic_devclass;
static struct aic_scb *free_scbs;
static struct aic_scb *

View File

@ -223,6 +223,6 @@ static driver_t aic_isa_driver = {
aic_isa_methods, sizeof(struct aic_isa_softc),
};
static devclass_t aic_devclass;
extern devclass_t aic_devclass;
DRIVER_MODULE(aic, isa, aic_isa_driver, aic_devclass, 0, 0);

182
sys/dev/aic/aic_pccard.c Normal file
View File

@ -0,0 +1,182 @@
/*-
* Copyright (c) 1999 Luoqi Chen.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#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 <dev/aic/aic6360reg.h>
#include <dev/aic/aicvar.h>
struct aic_pccard_softc {
struct aic_softc sc_aic;
struct resource *sc_port;
struct resource *sc_irq;
void *sc_ih;
};
static int aic_pccard_alloc_resources __P((device_t));
static void aic_pccard_release_resources __P((device_t));
static int aic_pccard_probe __P((device_t));
static int aic_pccard_attach __P((device_t));
#define AIC_PCCARD_PORTSIZE 0x20
static int
aic_pccard_alloc_resources(device_t dev)
{
struct aic_pccard_softc *sc = device_get_softc(dev);
int rid;
sc->sc_port = sc->sc_irq = 0;
rid = 0;
sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0ul, ~0ul, AIC_PCCARD_PORTSIZE, RF_ACTIVE);
if (!sc->sc_port)
return (ENOMEM);
rid = 0;
sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
0ul, ~0ul, 1, RF_ACTIVE);
if (!sc->sc_irq) {
aic_pccard_release_resources(dev);
return (ENOMEM);
}
sc->sc_aic.unit = device_get_unit(dev);
sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
return (0);
}
static void
aic_pccard_release_resources(device_t dev)
{
struct aic_pccard_softc *sc = device_get_softc(dev);
if (sc->sc_port)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port);
if (sc->sc_irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
sc->sc_port = sc->sc_irq = 0;
}
static int
aic_pccard_probe(device_t dev)
{
struct aic_pccard_softc *sc = device_get_softc(dev);
struct aic_softc *aic = &sc->sc_aic;
if (aic_pccard_alloc_resources(dev))
return (ENXIO);
if (aic_probe(aic)) {
aic_pccard_release_resources(dev);
return (ENXIO);
}
aic_pccard_release_resources(dev);
device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
return (0);
}
static int
aic_pccard_attach(device_t dev)
{
struct aic_pccard_softc *sc = device_get_softc(dev);
struct aic_softc *aic = &sc->sc_aic;
int error;
error = aic_pccard_alloc_resources(dev);
if (error) {
device_printf(dev, "resource allocation failed\n");
return (error);
}
error = aic_attach(aic);
if (error) {
device_printf(dev, "attach failed\n");
aic_pccard_release_resources(dev);
return (error);
}
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM, aic_intr,
aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_pccard_release_resources(dev);
return (error);
}
return (0);
}
static int
aic_pccard_detach(device_t dev)
{
struct aic_pccard_softc *sc = device_get_softc(dev);
struct aic_softc *aic = &sc->sc_aic;
int error;
error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
if (error) {
device_printf(dev, "failed to unregister interrupt handler\n");
}
error = aic_detach(aic);
if (error) {
device_printf(dev, "detach failed\n");
return (error);
}
aic_pccard_release_resources(dev);
return (0);
}
static device_method_t aic_pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, aic_pccard_probe),
DEVMETHOD(device_attach, aic_pccard_attach),
DEVMETHOD(device_detach, aic_pccard_detach),
{ 0, 0 }
};
static driver_t aic_pccard_driver = {
"aic",
aic_pccard_methods, sizeof(struct aic_pccard_softc),
};
extern devclass_t aic_devclass;
DRIVER_MODULE(aic, pccard, aic_pccard_driver, aic_devclass, 0, 0);