summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2014-03-24 04:05:11 +0000
committerdlg <dlg@openbsd.org>2014-03-24 04:05:11 +0000
commit3480c703a2fd86ec5cd61efd81fed4e6aa3d135d (patch)
tree0aeaa16909280e93a041ab5f5134530995f99e09
parentThe kernel isn't involved in times(3); <sys/times.h> should never be (diff)
downloadwireguard-openbsd-3480c703a2fd86ec5cd61efd81fed4e6aa3d135d.tar.xz
wireguard-openbsd-3480c703a2fd86ec5cd61efd81fed4e6aa3d135d.zip
mpi scatter gather lists are 24 bytes long and next to each other in
memory. that means you cant do 8 byte loads and stores on the sg_addr member cos it wont be 8 byte aligned half the time which makes strict alignment archs (ie, the fun ones ones) upset. annotate the sge as being 4 byte aligned. replace the sg_addr member with sg_addr_lo and sg_addr_hi. replace htole64 assignment of the sg addr with a wrapper that does the right thing with a couple of htolem32 calls. generated code shrinks again.
-rw-r--r--sys/dev/ic/mpi.c47
-rw-r--r--sys/dev/ic/mpireg.h7
2 files changed, 24 insertions, 30 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index 5da74b18f15..50f595b5859 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.186 2014/03/24 02:59:11 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.187 2014/03/24 04:05:11 dlg Exp $ */
/*
* Copyright (c) 2005, 2006, 2009 David Gwynne <dlg@openbsd.org>
@@ -206,6 +206,13 @@ void mpi_refresh_sensors(void *);
mpi_req_cfg_page((_s), (_a), MPI_PG_POLL|MPI_PG_EXTENDED, \
(_h), (_r), (_p), (_l))
+static inline void
+mpi_dvatosge(struct mpi_sge *sge, u_int64_t dva)
+{
+ htolem32(&sge->sg_addr_lo, dva);
+ htolem32(&sge->sg_addr_hi, dva >> 32);
+}
+
int
mpi_attach(struct mpi_softc *sc)
{
@@ -757,7 +764,6 @@ mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk)
} __packed *bundle;
struct mpi_msg_scsi_io *io;
struct mpi_sge *sge;
- u_int64_t addr;
DNPRINTF(MPI_D_PPR, "%s: mpi_inq\n", DEVNAME(sc));
@@ -806,9 +812,8 @@ mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk)
MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
(u_int32_t)sizeof(inq));
- addr = ccb->ccb_cmd_dva +
- ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle);
- sge->sg_addr = htole64(addr);
+ mpi_dvatosge(sge, ccb->ccb_cmd_dva +
+ ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle));
if (mpi_poll(sc, ccb, 5000) != 0)
return (1);
@@ -1515,7 +1520,6 @@ mpi_load_xs(struct mpi_ccb *ccb)
struct mpi_msg_scsi_io *io = &mcb->mcb_io;
struct mpi_sge *sge, *nsge = &mcb->mcb_sgl[0];
struct mpi_sge *ce = NULL, *nce;
- u_int64_t ce_dva;
bus_dmamap_t dmap = ccb->ccb_dmamap;
u_int32_t addr, flags;
int i, error;
@@ -1540,7 +1544,7 @@ mpi_load_xs(struct mpi_ccb *ccb)
if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
- io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
+ io->chain_offset = (u_int32_t *)ce - (u_int32_t *)io;
}
for (i = 0; i < dmap->dm_nsegs; i++) {
@@ -1549,13 +1553,9 @@ mpi_load_xs(struct mpi_ccb *ccb)
nsge++;
sge->sg_hdr |= htole32(MPI_SGE_FL_LAST);
- DNPRINTF(MPI_D_DMA, "%s: - 0x%08x 0x%016llx\n",
- DEVNAME(sc), sge->sg_hdr,
- sge->sg_addr);
-
if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
nce = &nsge[sc->sc_chain_len - 1];
- addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
+ addr = (u_int32_t *)nce - (u_int32_t *)nsge;
addr = addr << 16 |
sizeof(struct mpi_sge) * sc->sc_chain_len;
} else {
@@ -1567,13 +1567,8 @@ mpi_load_xs(struct mpi_ccb *ccb)
ce->sg_hdr = htole32(MPI_SGE_FL_TYPE_CHAIN |
MPI_SGE_FL_SIZE_64 | addr);
- ce_dva = ccb->ccb_cmd_dva +
- ((u_int8_t *)nsge - (u_int8_t *)mcb);
-
- ce->sg_addr = htole64(ce_dva);
-
- DNPRINTF(MPI_D_DMA, "%s: ce: 0x%08x 0x%016llx\n",
- DEVNAME(sc), ce->sg_hdr, ce->sg_addr);
+ mpi_dvatosge(ce, ccb->ccb_cmd_dva +
+ ((u_int8_t *)nsge - (u_int8_t *)mcb));
ce = nce;
}
@@ -1585,10 +1580,7 @@ mpi_load_xs(struct mpi_ccb *ccb)
sge = nsge;
sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
- sge->sg_addr = htole64(dmap->dm_segs[i].ds_addr);
-
- DNPRINTF(MPI_D_DMA, "%s: %d: 0x%08x 0x%016llx\n",
- DEVNAME(sc), i, sge->sg_hdr, sge->sg_addr);
+ mpi_dvatosge(sge, dmap->dm_segs[i].ds_addr);
nsge = sge + 1;
}
@@ -2037,9 +2029,10 @@ mpi_iocfacts(struct mpi_softc *sc)
DNPRINTF(MPI_D_MISC, "%s: hi_priority_queue_depth: 0x%04x\n",
DEVNAME(sc), letoh16(ifp.hi_priority_queue_depth));
DNPRINTF(MPI_D_MISC, "%s: host_page_buffer_sge: hdr: 0x%08x "
- "addr 0x%016llx\n", DEVNAME(sc),
+ "addr 0x%08lx%08lx\n", DEVNAME(sc),
letoh32(ifp.host_page_buffer_sge.sg_hdr),
- letoh64(ifp.host_page_buffer_sge.sg_addr));
+ letoh32(ifp.host_page_buffer_sge.sg_addr_hi),
+ letoh32(ifp.host_page_buffer_sge.sg_addr_lo));
sc->sc_maxcmds = letoh16(ifp.global_credits);
sc->sc_maxchdepth = ifp.max_chain_depth;
sc->sc_ioc_number = ifp.ioc_number;
@@ -2664,7 +2657,7 @@ mpi_fwupload(struct mpi_softc *sc)
bundle->sge.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
MPI_SGE_FL_SIZE_64 | MPI_SGE_FL_LAST | MPI_SGE_FL_EOB |
MPI_SGE_FL_EOL | (u_int32_t)sc->sc_fw_len);
- bundle->sge.sg_addr = htole64(MPI_DMA_DVA(sc->sc_fw));
+ mpi_dvatosge(&bundle->sge, MPI_DMA_DVA(sc->sc_fw));
if (mpi_poll(sc, ccb, 50000) != 0) {
DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc));
@@ -2886,7 +2879,7 @@ mpi_req_cfg_page(struct mpi_softc *sc, u_int32_t address, int flags,
(read ? MPI_SGE_FL_DIR_IN : MPI_SGE_FL_DIR_OUT));
/* bounce the page via the request space to avoid more bus_dma games */
- cq->page_buffer.sg_addr = htole64(ccb->ccb_cmd_dva +
+ mpi_dvatosge(&cq->page_buffer, ccb->ccb_cmd_dva +
sizeof(struct mpi_msg_config_request));
kva = ccb->ccb_cmd;
diff --git a/sys/dev/ic/mpireg.h b/sys/dev/ic/mpireg.h
index 011bb6bc500..f8425cf0496 100644
--- a/sys/dev/ic/mpireg.h
+++ b/sys/dev/ic/mpireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpireg.h,v 1.42 2012/08/26 11:33:44 dlg Exp $ */
+/* $OpenBSD: mpireg.h,v 1.43 2014/03/24 04:05:11 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -126,8 +126,9 @@
struct mpi_sge {
u_int32_t sg_hdr;
- u_int64_t sg_addr;
-} __packed;
+ u_int32_t sg_addr_lo;
+ u_int32_t sg_addr_hi;
+} __packed __aligned(4);
struct mpi_fw_tce {
u_int8_t reserved1;