Author: yongari
Date: Fri Feb 18 01:56:25 2011
New Revision: 218786
URL: http://svn.freebsd.org/changeset/base/218786

Log:
  Always check memory allocation failure. If driver encounter memory
  allocation error, do not attach driver.
  
  Reviewed by:  marius

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

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c     Fri Feb 18 00:02:35 2011        (r218785)
+++ head/sys/dev/dc/if_dc.c     Fri Feb 18 01:56:25 2011        (r218786)
@@ -287,11 +287,11 @@ static void dc_reset(struct dc_softc *);
 static int dc_list_rx_init(struct dc_softc *);
 static int dc_list_tx_init(struct dc_softc *);
 
-static void dc_read_srom(struct dc_softc *, int);
-static void dc_parse_21143_srom(struct dc_softc *);
-static void dc_decode_leaf_sia(struct dc_softc *, struct dc_eblock_sia *);
-static void dc_decode_leaf_mii(struct dc_softc *, struct dc_eblock_mii *);
-static void dc_decode_leaf_sym(struct dc_softc *, struct dc_eblock_sym *);
+static int dc_read_srom(struct dc_softc *, int);
+static int dc_parse_21143_srom(struct dc_softc *);
+static int dc_decode_leaf_sia(struct dc_softc *, struct dc_eblock_sia *);
+static int dc_decode_leaf_mii(struct dc_softc *, struct dc_eblock_mii *);
+static int dc_decode_leaf_sym(struct dc_softc *, struct dc_eblock_sym *);
 static void dc_apply_fixup(struct dc_softc *, int);
 static int dc_check_multiport(struct dc_softc *);
 
@@ -1616,12 +1616,16 @@ dc_apply_fixup(struct dc_softc *sc, int 
        }
 }
 
-static void
+static int
 dc_decode_leaf_sia(struct dc_softc *sc, struct dc_eblock_sia *l)
 {
        struct dc_mediainfo *m;
 
        m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+       if (m == NULL) {
+               device_printf(sc->dc_dev, "Could not allocate mediainfo\n");
+               return (ENOMEM);
+       }
        switch (l->dc_sia_code & ~DC_SIA_CODE_EXT) {
        case DC_SIA_CODE_10BT:
                m->dc_media = IFM_10_T;
@@ -1658,14 +1662,19 @@ dc_decode_leaf_sia(struct dc_softc *sc, 
        sc->dc_mi = m;
 
        sc->dc_pmode = DC_PMODE_SIA;
+       return (0);
 }
 
-static void
+static int
 dc_decode_leaf_sym(struct dc_softc *sc, struct dc_eblock_sym *l)
 {
        struct dc_mediainfo *m;
 
        m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+       if (m == NULL) {
+               device_printf(sc->dc_dev, "Could not allocate mediainfo\n");
+               return (ENOMEM);
+       }
        if (l->dc_sym_code == DC_SYM_CODE_100BT)
                m->dc_media = IFM_100_TX;
 
@@ -1679,15 +1688,20 @@ dc_decode_leaf_sym(struct dc_softc *sc, 
        sc->dc_mi = m;
 
        sc->dc_pmode = DC_PMODE_SYM;
+       return (0);
 }
 
-static void
+static int
 dc_decode_leaf_mii(struct dc_softc *sc, struct dc_eblock_mii *l)
 {
        struct dc_mediainfo *m;
        u_int8_t *p;
 
        m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+       if (m == NULL) {
+               device_printf(sc->dc_dev, "Could not allocate mediainfo\n");
+               return (ENOMEM);
+       }
        /* We abuse IFM_AUTO to represent MII. */
        m->dc_media = IFM_AUTO;
        m->dc_gp_len = l->dc_gpr_len;
@@ -1702,24 +1716,30 @@ dc_decode_leaf_mii(struct dc_softc *sc, 
 
        m->dc_next = sc->dc_mi;
        sc->dc_mi = m;
+       return (0);
 }
 
-static void
+static int
 dc_read_srom(struct dc_softc *sc, int bits)
 {
        int size;
 
-       size = 2 << bits;
+       size = DC_ROM_SIZE(bits);
        sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
+       if (sc->dc_srom == NULL) {
+               device_printf(sc->dc_dev, "Could not allocate SROM buffer\n");
+               return (ENOMEM);
+       }
        dc_read_eeprom(sc, (caddr_t)sc->dc_srom, 0, (size / 2), 0);
+       return (0);
 }
 
-static void
+static int
 dc_parse_21143_srom(struct dc_softc *sc)
 {
        struct dc_leaf_hdr *lhdr;
        struct dc_eblock_hdr *hdr;
-       int have_mii, i, loff;
+       int error, have_mii, i, loff;
        char *ptr;
 
        have_mii = 0;
@@ -1746,20 +1766,21 @@ dc_parse_21143_srom(struct dc_softc *sc)
         */
        ptr = (char *)lhdr;
        ptr += sizeof(struct dc_leaf_hdr) - 1;
+       error = 0;
        for (i = 0; i < lhdr->dc_mcnt; i++) {
                hdr = (struct dc_eblock_hdr *)ptr;
                switch (hdr->dc_type) {
                case DC_EBLOCK_MII:
-                       dc_decode_leaf_mii(sc, (struct dc_eblock_mii *)hdr);
+                       error = dc_decode_leaf_mii(sc, (struct dc_eblock_mii 
*)hdr);
                        break;
                case DC_EBLOCK_SIA:
                        if (! have_mii)
-                               dc_decode_leaf_sia(sc,
+                               error = dc_decode_leaf_sia(sc,
                                    (struct dc_eblock_sia *)hdr);
                        break;
                case DC_EBLOCK_SYM:
                        if (! have_mii)
-                               dc_decode_leaf_sym(sc,
+                               error = dc_decode_leaf_sym(sc,
                                    (struct dc_eblock_sym *)hdr);
                        break;
                default:
@@ -1769,6 +1790,7 @@ dc_parse_21143_srom(struct dc_softc *sc)
                ptr += (hdr->dc_len & 0x7F);
                ptr++;
        }
+       return (error);
 }
 
 static void
@@ -1835,6 +1857,7 @@ dc_attach(device_t dev)
        sc->dc_info = dc_devtype(dev);
        revision = pci_get_revid(dev);
 
+       error = 0;
        /* Get the eeprom width, but PNIC and XIRCOM have diff eeprom */
        if (sc->dc_info->dc_devid !=
            DC_DEVID(DC_VENDORID_LO, DC_DEVICEID_82C168) &&
@@ -1848,7 +1871,9 @@ dc_attach(device_t dev)
                sc->dc_flags |= DC_TX_POLL | DC_TX_USE_TX_INTR;
                sc->dc_flags |= DC_REDUCED_MII_POLL;
                /* Save EEPROM contents so we can parse them later. */
-               dc_read_srom(sc, sc->dc_romwidth);
+               error = dc_read_srom(sc, sc->dc_romwidth);
+               if (error != 0)
+                       goto fail;
                break;
        case DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009):
        case DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9100):
@@ -1867,7 +1892,9 @@ dc_attach(device_t dev)
                sc->dc_flags |= DC_TX_USE_TX_INTR;
                sc->dc_flags |= DC_TX_ADMTEK_WAR;
                sc->dc_pmode = DC_PMODE_MII;
-               dc_read_srom(sc, sc->dc_romwidth);
+               error = dc_read_srom(sc, sc->dc_romwidth);
+               if (error != 0)
+                       goto fail;
                break;
        case DC_DEVID(DC_VENDORID_ADMTEK, DC_DEVICEID_AN983):
        case DC_DEVID(DC_VENDORID_ADMTEK, DC_DEVICEID_AN985):
@@ -1934,6 +1961,12 @@ dc_attach(device_t dev)
                sc->dc_flags |= DC_TX_STORENFWD | DC_TX_INTR_ALWAYS;
                sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
                sc->dc_pnic_rx_buf = malloc(DC_RXLEN * 5, M_DEVBUF, M_NOWAIT);
+               if (sc->dc_pnic_rx_buf == NULL) {
+                       device_printf(sc->dc_dev,
+                           "Could not allocate PNIC RX buffer\n");
+                       error = ENOMEM;
+                       goto fail;
+               }
                if (revision < DC_REVISION_82C169)
                        sc->dc_pmode = DC_PMODE_SYM;
                break;
@@ -1959,7 +1992,9 @@ dc_attach(device_t dev)
                sc->dc_flags |= DC_TX_INTR_ALWAYS;
                sc->dc_flags |= DC_REDUCED_MII_POLL;
                sc->dc_pmode = DC_PMODE_MII;
-               dc_read_srom(sc, sc->dc_romwidth);
+               error = dc_read_srom(sc, sc->dc_romwidth);
+               if (error != 0)
+                       goto fail;
                break;
        default:
                device_printf(dev, "unknown device: %x\n",
@@ -1990,9 +2025,11 @@ dc_attach(device_t dev)
         * The tricky ones are the Macronix/PNIC II and the
         * Intel 21143.
         */
-       if (DC_IS_INTEL(sc))
-               dc_parse_21143_srom(sc);
-       else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
+       if (DC_IS_INTEL(sc)) {
+               error = dc_parse_21143_srom(sc);
+               if (error != 0)
+                       goto fail;
+       } else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
                if (sc->dc_type == DC_TYPE_98713)
                        sc->dc_pmode = DC_PMODE_MII;
                else

Modified: head/sys/dev/dc/if_dcreg.h
==============================================================================
--- head/sys/dev/dc/if_dcreg.h  Fri Feb 18 00:02:35 2011        (r218785)
+++ head/sys/dev/dc/if_dcreg.h  Fri Feb 18 01:56:25 2011        (r218786)
@@ -1064,6 +1064,8 @@ struct dc_softc {
  * SROM nonsense.
  */
 
+#define        DC_ROM_SIZE(bits)       (2 << (bits))
+
 #define DC_IB_CTLRCNT          0x13
 #define DC_IB_LEAF0_CNUM       0x1A
 #define DC_IB_LEAF0_OFFSET     0x1B
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to