1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-13 10:02:38 +00:00

Add locking to the aic(4) driver and mark it MPSAFE.

- Move 'free_scbs' into the softc rather than having it be a global list
  and convert it to an SLIST instead of a hand-rolled linked-list.
- Use device_printf() and device_get_unit() instead of storing the unit
  number in the softc.
- Remove use of explicit bus space handles and tags.
- Don't call device_set_desc() in the pccard attach routine, instead
  set a default description during the pccard probe if the matching
  product doesn't have a name.

Tested by:	no one
This commit is contained in:
John Baldwin 2012-10-15 16:09:59 +00:00
parent e40cc6afc4
commit 4bb96a7418
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241591
5 changed files with 110 additions and 94 deletions

View File

@ -28,6 +28,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@ -36,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@ -51,6 +53,7 @@ __FBSDID("$FreeBSD$");
static void aic_action(struct cam_sim *sim, union ccb *ccb);
static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs,
int nseg, int error);
static void aic_intr_locked(struct aic_softc *aic);
static void aic_start(struct aic_softc *aic);
static void aic_select(struct aic_softc *aic);
static void aic_selected(struct aic_softc *aic);
@ -71,43 +74,42 @@ static void aic_reset(struct aic_softc *aic, int initiate_reset);
devclass_t aic_devclass;
static struct aic_scb *free_scbs;
static struct aic_scb *
aic_get_scb(struct aic_softc *aic)
{
struct aic_scb *scb;
int s = splcam();
if ((scb = free_scbs) != NULL)
free_scbs = (struct aic_scb *)free_scbs->ccb;
splx(s);
if (!dumping)
mtx_assert(&aic->lock, MA_OWNED);
if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL)
SLIST_REMOVE_HEAD(&aic->free_scbs, link);
return (scb);
}
static void
aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
{
int s = splcam();
if (!dumping)
mtx_assert(&aic->lock, MA_OWNED);
if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
(scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
aic->flags &= ~AIC_RESOURCE_SHORTAGE;
}
scb->flags = 0;
scb->ccb = (union ccb *)free_scbs;
free_scbs = scb;
splx(s);
SLIST_INSERT_HEAD(&aic->free_scbs, scb, link);
}
static void
aic_action(struct cam_sim *sim, union ccb *ccb)
{
struct aic_softc *aic;
int s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n"));
aic = (struct aic_softc *)cam_sim_softc(sim);
mtx_assert(&aic->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO: /* Execute the requested I/O operation */
@ -116,9 +118,7 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
struct aic_scb *scb;
if ((scb = aic_get_scb(aic)) == NULL) {
s = splcam();
aic->flags |= AIC_RESOURCE_SHORTAGE;
splx(s);
xpt_freeze_simq(aic->sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@ -175,8 +175,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
struct ccb_trans_settings_spi *spi =
&cts->xport_specific.spi;
s = splcam();
if ((spi->valid & CTS_SPI_VALID_DISC) != 0 &&
(aic->flags & AIC_DISC_ENABLE) != 0) {
if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
@ -214,7 +212,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
|| (ti->goal.offset != ti->current.offset))
ti->flags |= TINFO_SDTR_NEGO;
splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@ -235,7 +232,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
s = splcam();
if ((ti->flags & TINFO_DISC_ENB) != 0)
spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
if ((ti->flags & TINFO_TAG_ENB) != 0)
@ -248,7 +244,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
spi->sync_period = ti->user.period;
spi->sync_offset = ti->user.offset;
}
splx(s);
spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
spi->valid = CTS_SPI_VALID_SYNC_RATE
@ -311,12 +306,10 @@ aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
struct aic_scb *scb = (struct aic_scb *)arg;
union ccb *ccb = scb->ccb;
struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
int s;
s = splcam();
if (!dumping)
mtx_assert(&aic->lock, MA_OWNED);
if (ccb->ccb_h.status != CAM_REQ_INPROG) {
splx(s);
aic_free_scb(aic, scb);
xpt_done(ccb);
return;
@ -326,11 +319,10 @@ aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
ccb->ccb_h.status |= CAM_SIM_QUEUED;
TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb,
(ccb->ccb_h.timeout * hz) / 1000);
callout_reset(&scb->timer, (ccb->ccb_h.timeout * hz) / 1000,
aic_timeout, scb);
aic_start(aic);
splx(s);
}
/*
@ -1053,7 +1045,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
("aic_done - ccb %p status %x resid %d\n",
ccb, ccb->ccb_h.status, ccb->csio.resid));
untimeout(aic_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch);
callout_stop(&scb->timer);
if ((scb->flags & SCB_DEVICE_RESET) != 0 &&
ccb->ccb_h.func_code != XPT_RESET_DEV) {
@ -1083,9 +1075,9 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
&pending_scb->ccb->ccb_h, sim_links.tqe);
aic_done(aic, pending_scb);
} else {
ccb_h->timeout_ch =
timeout(aic_timeout, (caddr_t)pending_scb,
(ccb_h->timeout * hz) / 1000);
callout_reset(&pending_scb->timer,
(ccb_h->timeout * hz) / 1000, aic_timeout,
pending_scb);
ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
}
}
@ -1102,9 +1094,9 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
&nexus_scb->ccb->ccb_h, sim_links.tqe);
aic_done(aic, nexus_scb);
} else {
ccb_h->timeout_ch =
timeout(aic_timeout, (caddr_t)nexus_scb,
(ccb_h->timeout * hz) / 1000);
callout_reset(&nexus_scb->timer,
(ccb_h->timeout * hz) / 1000, aic_timeout,
nexus_scb);
ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
}
}
@ -1123,7 +1115,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
static void
aic_poll(struct cam_sim *sim)
{
aic_intr(cam_sim_softc(sim));
aic_intr_locked(cam_sim_softc(sim));
}
static void
@ -1132,18 +1124,15 @@ aic_timeout(void *arg)
struct aic_scb *scb = (struct aic_scb *)arg;
union ccb *ccb = scb->ccb;
struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
int s;
mtx_assert(&aic->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("ccb %p - timed out", ccb);
if (aic->nexus && aic->nexus != scb)
printf(", nexus %p", aic->nexus->ccb);
printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state);
s = splcam();
if ((scb->flags & SCB_ACTIVE) == 0) {
splx(s);
xpt_print_path(ccb->ccb_h.path);
printf("ccb %p - timed out already completed\n", ccb);
return;
@ -1151,6 +1140,7 @@ aic_timeout(void *arg)
if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
struct ccb_hdr *ccb_h = &scb->ccb->ccb_h;
struct aic_scb *pending_scb;
if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) {
xpt_freeze_simq(aic->sim, /*count*/1);
@ -1158,18 +1148,17 @@ aic_timeout(void *arg)
}
TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
ccb_h->timeout_ch);
pending_scb = ccb_h->ccb_scb_ptr;
callout_stop(&pending_scb->timer);
}
TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
ccb_h->timeout_ch);
pending_scb = ccb_h->ccb_scb_ptr;
callout_stop(&pending_scb->timer);
}
scb->flags |= SCB_DEVICE_RESET;
ccb->ccb_h.timeout_ch =
timeout(aic_timeout, (caddr_t)scb, 5 * hz);
callout_reset(&scb->timer, 5 * hz, aic_timeout, scb);
aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
} else {
if (aic->nexus == scb) {
@ -1178,14 +1167,21 @@ aic_timeout(void *arg)
}
aic_reset(aic, /*initiate_reset*/TRUE);
}
splx(s);
}
void
aic_intr(void *arg)
{
struct aic_softc *aic = (struct aic_softc *)arg;
mtx_lock(&aic->lock);
aic_intr_locked(aic);
mtx_unlock(&aic->lock);
}
void
aic_intr_locked(struct aic_softc *aic)
{
u_int8_t sstat0, sstat1;
union ccb *ccb;
struct aic_scb *scb;
@ -1434,6 +1430,7 @@ aic_init(struct aic_softc *aic)
TAILQ_INIT(&aic->pending_ccbs);
TAILQ_INIT(&aic->nexus_ccbs);
SLIST_INIT(&aic->free_scbs);
aic->nexus = NULL;
aic->state = AIC_IDLE;
aic->prev_phase = -1;
@ -1481,10 +1478,10 @@ aic_init(struct aic_softc *aic)
aic->max_period = AIC_SYNC_PERIOD;
aic->min_period = AIC_MIN_SYNC_PERIOD;
free_scbs = NULL;
for (i = 255; i >= 0; i--) {
scb = &aic->scbs[i];
scb->tag = i;
callout_init_mtx(&scb->timer, &aic->lock, 0);
aic_free_scb(aic, scb);
}
@ -1543,14 +1540,16 @@ aic_attach(struct aic_softc *aic)
* Construct our SIM entry
*/
aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic,
aic->unit, &Giant, 2, 256, devq);
device_get_unit(aic->dev), &aic->lock, 2, 256, devq);
if (aic->sim == NULL) {
cam_simq_free(devq);
return (ENOMEM);
}
mtx_lock(&aic->lock);
if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) {
cam_sim_free(aic->sim, /*free_devq*/TRUE);
mtx_unlock(&aic->lock);
return (ENXIO);
}
@ -1559,12 +1558,13 @@ aic_attach(struct aic_softc *aic)
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(aic->sim));
cam_sim_free(aic->sim, /*free_devq*/TRUE);
mtx_unlock(&aic->lock);
return (ENXIO);
}
aic_init(aic);
printf("aic%d: %s", aic->unit, aic_chip_names[aic->chip_type]);
device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]);
if (aic->flags & AIC_DMA_ENABLE)
printf(", dma");
if (aic->flags & AIC_DISC_ENABLE)
@ -1574,15 +1574,25 @@ aic_attach(struct aic_softc *aic)
if (aic->flags & AIC_FAST_ENABLE)
printf(", fast SCSI");
printf("\n");
mtx_unlock(&aic->lock);
return (0);
}
int
aic_detach(struct aic_softc *aic)
{
struct aic_scb *scb;
int i;
mtx_lock(&aic->lock);
xpt_async(AC_LOST_DEVICE, aic->path, NULL);
xpt_free_path(aic->path);
xpt_bus_deregister(cam_sim_path(aic->sim));
cam_sim_free(aic->sim, /*free_devq*/TRUE);
mtx_unlock(&aic->lock);
for (i = 255; i >= 0; i--) {
scb = &aic->scbs[i];
callout_drain(&scb->timer);
}
return (0);
}

View File

@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@ -92,7 +95,7 @@ aic_isa_alloc_resources(device_t dev)
else
bs_iat = aicport_generic;
sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
rid = 0;
sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
@ -102,6 +105,7 @@ aic_isa_alloc_resources(device_t dev)
return (ENOMEM);
}
isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE);
mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
if (isa_get_irq(dev) != -1) {
rid = 0;
@ -126,9 +130,7 @@ aic_isa_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
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);
sc->sc_aic.res = sc->sc_port;
return (0);
}
@ -143,7 +145,8 @@ aic_isa_release_resources(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
if (sc->sc_drq)
bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq);
sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
mtx_destroy(&sc->sc_aic.lock);
}
static int
@ -172,10 +175,8 @@ aic_isa_probe(device_t dev)
continue;
if (aic_isa_alloc_resources(dev))
continue;
if (!aic_probe(aic)) {
aic_isa_release_resources(dev);
if (aic_probe(aic) == 0)
break;
}
aic_isa_release_resources(dev);
}
@ -183,6 +184,7 @@ aic_isa_probe(device_t dev)
return (ENXIO);
porta = aic_inb(aic, PORTA);
aic_isa_release_resources(dev);
if (isa_get_irq(dev) == -1)
bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
@ -211,8 +213,8 @@ aic_isa_attach(device_t dev)
return (error);
}
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
NULL, aic_intr, aic, &sc->sc_ih);
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_isa_release_resources(dev);

View File

@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@ -69,7 +72,7 @@ aic_isa_alloc_resources(device_t dev)
struct aic_isa_softc *sc = device_get_softc(dev);
int rid;
sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
rid = 0;
sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@ -102,9 +105,8 @@ aic_isa_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
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);
sc->sc_aic.res = sc->sc_port;
mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
return (0);
}
@ -119,7 +121,8 @@ aic_isa_release_resources(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
if (sc->sc_drq)
bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq);
sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
mtx_destroy(&sc->sc_aic.lock);
}
static int
@ -149,10 +152,8 @@ aic_isa_probe(device_t dev)
continue;
if (aic_isa_alloc_resources(dev))
continue;
if (!aic_probe(aic)) {
aic_isa_release_resources(dev);
if (aic_probe(aic) == 0)
break;
}
aic_isa_release_resources(dev);
}
@ -160,6 +161,7 @@ aic_isa_probe(device_t dev)
return (ENXIO);
porta = aic_inb(aic, PORTA);
aic_isa_release_resources(dev);
if (isa_get_irq(dev) == -1)
bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
@ -188,8 +190,8 @@ aic_isa_attach(device_t dev)
return (error);
}
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
NULL, aic_intr, aic, &sc->sc_ih);
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_isa_release_resources(dev);

View File

@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@ -71,7 +74,7 @@ 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;
sc->sc_port = sc->sc_irq = NULL;
rid = 0;
sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@ -87,9 +90,8 @@ aic_pccard_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
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);
sc->sc_aic.res = sc->sc_port;
mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
return (0);
}
@ -102,7 +104,8 @@ aic_pccard_release_resources(device_t dev)
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;
sc->sc_port = sc->sc_irq = NULL;
mtx_destroy(&sc->sc_aic.lock);
}
static int
@ -114,9 +117,12 @@ aic_pccard_probe(device_t dev)
sizeof(aic_pccard_products[0]), NULL)) != NULL) {
if (pp->pp_name != NULL)
device_set_desc(dev, pp->pp_name);
return 0;
else
device_set_desc(dev,
"Adaptec 6260/6360 SCSI controller");
return (BUS_PROBE_DEFAULT);
}
return EIO;
return (ENXIO);
}
static int
@ -133,8 +139,6 @@ aic_pccard_attach(device_t dev)
return (ENXIO);
}
device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
error = aic_attach(aic);
if (error) {
device_printf(dev, "attach failed\n");
@ -142,8 +146,8 @@ aic_pccard_attach(device_t dev)
return (error);
}
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
NULL, aic_intr, aic, &sc->sc_ih);
error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_pccard_release_resources(dev);

View File

@ -47,6 +47,8 @@ struct aic_tinfo {
struct aic_scb {
union ccb *ccb;
SLIST_ENTRY(aic_scb) link;
struct callout timer;
u_int8_t flags;
u_int8_t tag;
u_int8_t target;
@ -70,14 +72,14 @@ enum { AIC6260, AIC6360, AIC6370, GM82C700 };
struct aic_softc {
device_t dev;
int unit;
bus_space_tag_t tag;
bus_space_handle_t bsh;
struct mtx lock;
struct resource *res;
bus_dma_tag_t dmat;
struct cam_sim *sim;
struct cam_path *path;
TAILQ_HEAD(,ccb_hdr) pending_ccbs, nexus_ccbs;
SLIST_HEAD(,aic_scb) free_scbs;
struct aic_scb *nexus;
u_int32_t flags;
@ -127,32 +129,28 @@ struct aic_softc {
#define AIC_SYNC_OFFSET 8
#define aic_inb(aic, port) \
bus_space_read_1((aic)->tag, (aic)->bsh, (port))
bus_read_1((aic)->res, (port))
#define aic_outb(aic, port, value) \
bus_space_write_1((aic)->tag, (aic)->bsh, (port), (value))
bus_write_1((aic)->res, (port), (value))
#define aic_insb(aic, port, addr, count) \
bus_space_read_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count))
bus_read_multi_1((aic)->res, (port), (addr), (count))
#define aic_outsb(aic, port, addr, count) \
bus_space_write_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count))
bus_write_multi_1((aic)->res, (port), (addr), (count))
#define aic_insw(aic, port, addr, count) \
bus_space_read_multi_2((aic)->tag, (aic)->bsh, (port), \
(u_int16_t *)(addr), (count))
bus_read_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count))
#define aic_outsw(aic, port, addr, count) \
bus_space_write_multi_2((aic)->tag, (aic)->bsh, (port), \
(u_int16_t *)(addr), (count))
bus_write_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count))
#define aic_insl(aic, port, addr, count) \
bus_space_read_multi_4((aic)->tag, (aic)->bsh, (port), \
(u_int32_t *)(addr), (count))
bus_read_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count))
#define aic_outsl(aic, port, addr, count) \
bus_space_write_multi_4((aic)->tag, (aic)->bsh, (port), \
(u_int32_t *)(addr), (count))
bus_write_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count))
extern int aic_probe(struct aic_softc *);
extern int aic_attach(struct aic_softc *);