Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Feb 2011 02:14:53 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r218787 - head/sys/dev/dc
Message-ID:  <201102180214.p1I2ErOJ038791@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Fri Feb 18 02:14:53 2011
New Revision: 218787
URL: http://svn.freebsd.org/changeset/base/218787

Log:
  When driver have to use base softc due to lack of SROM on second
  port, copy SROM information from base softc as well and run SROM
  parser again.  This change is necessary for some dual port
  controllers to make dc(4) correctly detect PHY media based on first
  port configuration table.
  While I'm here add a check for validity of the base softc before
  duplicating SROM contents from base softc. If driver failed to
  attach to the first port it can access invalid area.
  
  PR:		kern/79262
  Reviewed by:	marius

Modified:
  head/sys/dev/dc/if_dc.c

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c	Fri Feb 18 01:56:25 2011	(r218786)
+++ head/sys/dev/dc/if_dc.c	Fri Feb 18 02:14:53 2011	(r218787)
@@ -1815,6 +1815,7 @@ dc_attach(device_t dev)
 	u_int32_t command;
 	struct dc_softc *sc;
 	struct ifnet *ifp;
+	struct dc_mediainfo *m;
 	u_int32_t reg, revision;
 	int error, i, mac_offset, phy, rid, tmp;
 	u_int8_t *mac;
@@ -2108,8 +2109,24 @@ dc_attach(device_t dev)
 	if ((sc->dc_eaddr[0] == 0 && (sc->dc_eaddr[1] & ~0xffff) == 0) ||
 	    (sc->dc_eaddr[0] == 0xffffffff &&
 	    (sc->dc_eaddr[1] & 0xffff) == 0xffff)) {
-		if (dc_check_multiport(sc) == 0)
+		error = dc_check_multiport(sc);
+		if (error == 0) {
 			bcopy(sc->dc_eaddr, eaddr, sizeof(eaddr));
+			/* Extract media information. */
+			if (DC_IS_INTEL(sc) && sc->dc_srom != NULL) {
+				while (sc->dc_mi != NULL) {
+					m = sc->dc_mi->dc_next;
+					free(sc->dc_mi, M_DEVBUF);
+					sc->dc_mi = m;
+				}
+				error = dc_parse_21143_srom(sc);
+				if (error != 0)
+					goto fail;
+			}
+		} else if (error == ENOMEM)
+			goto fail;
+		else
+			error = 0;
 	}
 
 	/* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */
@@ -3875,12 +3892,30 @@ dc_check_multiport(struct dc_softc *sc)
 			continue;
 		if (unit > device_get_unit(sc->dc_dev))
 			continue;
+		if (device_is_attached(child) == 0)
+			continue;
 		dsc = device_get_softc(child);
-		device_printf(sc->dc_dev, "Using station address of %s as base",
+		device_printf(sc->dc_dev,
+		    "Using station address of %s as base\n",
 		    device_get_nameunit(child));
 		bcopy(dsc->dc_eaddr, sc->dc_eaddr, ETHER_ADDR_LEN);
 		eaddr = (uint8_t *)sc->dc_eaddr;
 		eaddr[5]++;
+		/* Prepare SROM to parse again. */
+		if (DC_IS_INTEL(sc) && dsc->dc_srom != NULL &&
+		    sc->dc_romwidth != 0) {
+			free(sc->dc_srom, M_DEVBUF);
+			sc->dc_romwidth = dsc->dc_romwidth;
+			sc->dc_srom = malloc(DC_ROM_SIZE(sc->dc_romwidth),
+			    M_DEVBUF, M_NOWAIT);
+			if (sc->dc_srom == NULL) {
+				device_printf(sc->dc_dev,
+				    "Could not allocate SROM buffer\n");
+				return (ENOMEM);
+			}
+			bcopy(dsc->dc_srom, sc->dc_srom,
+			    DC_ROM_SIZE(sc->dc_romwidth));
+		}
 		return (0);
 	}
 	return (ENOENT);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102180214.p1I2ErOJ038791>