Always check memory allocation failure. If driver encounter memory

allocation error, do not attach driver.

Reviewed by:	marius
This commit is contained in:
Pyun YongHyeon 2011-02-18 01:56:25 +00:00
parent b2983d3006
commit abe4e86598
2 changed files with 60 additions and 21 deletions

View File

@ -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 media)
}
}
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, struct dc_eblock_sia *l)
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, struct dc_eblock_sym *l)
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, struct dc_eblock_mii *l)
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

View File

@ -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