summaryrefslogtreecommitdiff
path: root/sys/dev/pci/yds.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/yds.c')
-rw-r--r--sys/dev/pci/yds.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/sys/dev/pci/yds.c b/sys/dev/pci/yds.c
index c42d9177a47..ce7c862c4dd 100644
--- a/sys/dev/pci/yds.c
+++ b/sys/dev/pci/yds.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: yds.c,v 1.27 2005/08/09 04:10:13 mickey Exp $ */
+/* $OpenBSD: yds.c,v 1.28 2007/01/06 02:48:40 deraadt Exp $ */
/* $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $ */
/*
@@ -91,6 +91,8 @@ int yds_match(struct device *, void *, void *);
void yds_attach(struct device *, struct device *, void *);
int yds_intr(void *);
+static void nswaph(u_int32_t *p, int wcount);
+
#define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
#define KERNADDR(p) ((void *)((p)->addr))
@@ -334,6 +336,15 @@ yds_get_dstype(id)
return -1;
}
+static void
+nswaph(u_int32_t *p, int wcount)
+{
+ for (; wcount; wcount -=4) {
+ *p = ntohl(*p);
+ p++;
+ }
+}
+
static int
yds_download_mcode(sc)
struct yds_softc *sc;
@@ -352,16 +363,23 @@ yds_download_mcode(sc)
yf = (struct yds_firmware *)buf;
if (sc->sc_flags & YDS_CAP_MCODE_1) {
- p = (u_int32_t *)&yf->data[yf->dsplen];
- size = yf->ds1len;
+ p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)];
+ size = ntohl(yf->ds1len);
} else if (sc->sc_flags & YDS_CAP_MCODE_1E) {
- p = (u_int32_t *)&yf->data[yf->dsplen + yf->ds1len];
- size = yf->ds1elen;
+ p = (u_int32_t *)&yf->data[ntohl(yf->dsplen) + ntohl(yf->ds1len)];
+ size = ntohl(yf->ds1elen);
} else {
free(buf, M_DEVBUF);
return 1; /* unknown */
}
+ if (size > buflen) {
+ printf("%s: old firmware file, update please\n",
+ sc->sc_dev.dv_xname);
+ free(buf, M_DEVBUF);
+ return 1;
+ }
+
if (yds_disable_dsp(sc)) {
free(buf, M_DEVBUF);
return 1;
@@ -382,9 +400,12 @@ yds_download_mcode(sc)
YWRITE2(sc, YDS_GLOBAL_CONTROL, ctrl & ~0x0007);
/* Download DSP microcode. */
- YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0], yf->dsplen);
+ nswaph((u_int32_t *)&yf->data[0], ntohl(yf->dsplen));
+ YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0],
+ ntohl(yf->dsplen));
/* Download CONTROL microcode. */
+ nswaph((u_int32_t *)p, size);
YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size);
yds_enable_dsp(sc);