summaryrefslogtreecommitdiff
path: root/sys/dev/ic/mfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/mfi.c')
-rw-r--r--sys/dev/ic/mfi.c91
1 files changed, 42 insertions, 49 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index d588363b0e9..d2d1799d57a 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.113 2010/09/24 01:30:05 dlg Exp $ */
+/* $OpenBSD: mfi.c,v 1.114 2010/12/30 08:53:50 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -63,8 +63,8 @@ struct scsi_adapter mfi_switch = {
mfi_scsi_cmd, mfiminphys, 0, 0, mfi_scsi_ioctl
};
-struct mfi_ccb *mfi_get_ccb(struct mfi_softc *);
-void mfi_put_ccb(struct mfi_ccb *);
+void * mfi_get_ccb(void *);
+void mfi_put_ccb(void *, void *);
int mfi_init_ccb(struct mfi_softc *);
struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t);
@@ -85,6 +85,8 @@ int mfi_scsi_io(struct mfi_ccb *, struct scsi_xfer *, uint64_t,
void mfi_scsi_xs_done(struct mfi_ccb *);
int mfi_mgmt(struct mfi_softc *, uint32_t, uint32_t, uint32_t,
void *, uint8_t *);
+int mfi_do_mgmt(struct mfi_softc *, struct mfi_ccb * , uint32_t,
+ uint32_t, uint32_t, void *, uint8_t *);
void mfi_mgmt_done(struct mfi_ccb *);
#if NBIO > 0
@@ -146,9 +148,10 @@ static const struct mfi_iop_ops mfi_iop_gen2 = {
#define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s))
#define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c)))
-struct mfi_ccb *
-mfi_get_ccb(struct mfi_softc *sc)
+void *
+mfi_get_ccb(void *cookie)
{
+ struct mfi_softc *sc = cookie;
struct mfi_ccb *ccb;
mtx_enter(&sc->sc_ccb_mtx);
@@ -165,9 +168,10 @@ mfi_get_ccb(struct mfi_softc *sc)
}
void
-mfi_put_ccb(struct mfi_ccb *ccb)
+mfi_put_ccb(void *cookie, void *io)
{
- struct mfi_softc *sc = ccb->ccb_sc;
+ struct mfi_softc *sc = cookie;
+ struct mfi_ccb *ccb = io;
struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header;
DNPRINTF(MFI_D_CCB, "%s: mfi_put_ccb: %p\n", DEVNAME(sc), ccb);
@@ -239,7 +243,7 @@ mfi_init_ccb(struct mfi_softc *sc)
ccb->ccb_dmamap);
/* add ccb to queue */
- mfi_put_ccb(ccb);
+ mfi_put_ccb(sc, ccb);
}
return (0);
@@ -436,7 +440,7 @@ mfi_initialize_firmware(struct mfi_softc *sc)
return (1);
}
- mfi_put_ccb(ccb);
+ mfi_put_ccb(sc, ccb);
return (0);
}
@@ -638,6 +642,7 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
SLIST_INIT(&sc->sc_ccb_freeq);
mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, mfi_get_ccb, mfi_put_ccb);
rw_init(&sc->sc_lock, "mfi_lock");
@@ -718,6 +723,7 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
sc->sc_link.adapter = &mfi_switch;
sc->sc_link.adapter_target = MFI_MAX_LD;
sc->sc_link.adapter_buswidth = sc->sc_max_ld;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -931,7 +937,6 @@ mfi_scsi_xs_done(struct mfi_ccb *ccb)
break;
}
- mfi_put_ccb(ccb);
scsi_done(xs);
}
@@ -988,7 +993,7 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
struct scsi_link *link = xs->sc_link;
struct mfi_softc *sc = link->adapter_softc;
struct device *dev = link->device_softc;
- struct mfi_ccb *ccb;
+ struct mfi_ccb *ccb = xs->io;
struct scsi_rw *rw;
struct scsi_rw_big *rwb;
struct scsi_rw_16 *rw16;
@@ -1007,13 +1012,6 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
goto stuffup;
}
- if ((ccb = mfi_get_ccb(sc)) == NULL) {
- DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_cmd no ccb\n", DEVNAME(sc));
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- return;
- }
-
xs->error = XS_NOERROR;
switch (xs->cmd->opcode) {
@@ -1023,10 +1021,8 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
rwb = (struct scsi_rw_big *)xs->cmd;
blockno = (uint64_t)_4btol(rwb->addr);
blockcnt = _2btol(rwb->length);
- if (mfi_scsi_io(ccb, xs, blockno, blockcnt)) {
- mfi_put_ccb(ccb);
+ if (mfi_scsi_io(ccb, xs, blockno, blockcnt))
goto stuffup;
- }
break;
case READ_COMMAND:
@@ -1035,10 +1031,8 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
blockno =
(uint64_t)(_3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff));
blockcnt = rw->length ? rw->length : 0x100;
- if (mfi_scsi_io(ccb, xs, blockno, blockcnt)) {
- mfi_put_ccb(ccb);
+ if (mfi_scsi_io(ccb, xs, blockno, blockcnt))
goto stuffup;
- }
break;
case READ_16:
@@ -1046,18 +1040,14 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
rw16 = (struct scsi_rw_16 *)xs->cmd;
blockno = _8btol(rw16->addr);
blockcnt = _4btol(rw16->length);
- if (mfi_scsi_io(ccb, xs, blockno, blockcnt)) {
- mfi_put_ccb(ccb);
+ if (mfi_scsi_io(ccb, xs, blockno, blockcnt))
goto stuffup;
- }
break;
case SYNCHRONIZE_CACHE:
- mfi_put_ccb(ccb); /* we don't need this */
-
mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
- if (mfi_mgmt(sc, MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE,
- 0, NULL, mbox))
+ if (mfi_do_mgmt(sc, ccb, MR_DCMD_CTRL_CACHE_FLUSH,
+ MFI_DATA_NONE, 0, NULL, mbox))
goto stuffup;
goto complete;
@@ -1072,10 +1062,8 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
/* FALLTHROUGH */
default:
- if (mfi_scsi_ld(ccb, xs)) {
- mfi_put_ccb(ccb);
+ if (mfi_scsi_ld(ccb, xs))
goto stuffup;
- }
break;
}
@@ -1094,7 +1082,6 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
xs->error = XS_SENSE;
}
- mfi_put_ccb(ccb);
scsi_done(xs);
return;
}
@@ -1180,16 +1167,25 @@ int
mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len,
void *buf, uint8_t *mbox)
{
- struct mfi_ccb *ccb;
+ struct mfi_ccb *ccb;
+ int rv;
+
+ ccb = scsi_io_get(&sc->sc_iopool, 0);
+ rv = mfi_do_mgmt(sc, ccb, opc, dir, len, buf, mbox);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
+ return (rv);
+}
+
+int
+mfi_do_mgmt(struct mfi_softc *sc, struct mfi_ccb *ccb, uint32_t opc,
+ uint32_t dir, uint32_t len, void *buf, uint8_t *mbox)
+{
struct mfi_dcmd_frame *dcmd;
- int rv = 1;
int s;
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(sc), opc);
- if ((ccb = mfi_get_ccb(sc)) == NULL)
- return (rv);
-
dcmd = &ccb->ccb_frame->mfr_dcmd;
memset(dcmd->mdf_mbox, 0, MFI_MBOX_SIZE);
dcmd->mdf_header.mfh_cmd = MFI_CMD_DCMD;
@@ -1213,12 +1209,12 @@ mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len,
ccb->ccb_sgl = &dcmd->mdf_sgl;
if (mfi_create_sgl(ccb, BUS_DMA_WAITOK))
- goto done;
+ return (EINVAL);
}
if (cold) {
if (mfi_poll(ccb))
- goto done;
+ return (EIO);
} else {
s = splbio();
mfi_start(sc, ccb);
@@ -1229,14 +1225,10 @@ mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len,
splx(s);
if (ccb->ccb_flags & MFI_CCB_F_ERR)
- goto done;
+ return (EIO);
}
- rv = 0;
-
-done:
- mfi_put_ccb(ccb);
- return (rv);
+ return (0);
}
void
@@ -1351,7 +1343,8 @@ mfi_bio_getitall(struct mfi_softc *sc)
cfg = malloc(sizeof *cfg, M_DEVBUF, M_NOWAIT | M_ZERO);
if (cfg == NULL)
goto done;
- if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL))
+ if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg,
+ NULL))
goto done;
size = cfg->mfc_size;