Deleted Added
full compact
if_xl.c (112779) if_xl.c (112872)
1/*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 87 unchanged lines hidden (view full) ---

96 * support the PCI "boomerang" chips even though they work with the
97 * "vortex" driver in order to obtain better performance.
98 *
99 * This driver is in the /sys/pci directory because it only supports
100 * PCI-based NICs.
101 */
102
103#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 87 unchanged lines hidden (view full) ---

96 * support the PCI "boomerang" chips even though they work with the
97 * "vortex" driver in order to obtain better performance.
98 *
99 * This driver is in the /sys/pci directory because it only supports
100 * PCI-based NICs.
101 */
102
103#include <sys/cdefs.h>
104__FBSDID("$FreeBSD: head/sys/pci/if_xl.c 112779 2003-03-29 06:34:25Z silby $");
104__FBSDID("$FreeBSD: head/sys/pci/if_xl.c 112872 2003-03-31 17:29:43Z njl $");
105
106#include <sys/param.h>
107#include <sys/systm.h>
108#include <sys/sockio.h>
109#include <sys/endian.h>
110#include <sys/mbuf.h>
111#include <sys/kernel.h>
112#include <sys/socket.h>

--- 1170 unchanged lines hidden (view full) ---

1283 int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
1284 int unit, error = 0, rid, res;
1285
1286 sc = device_get_softc(dev);
1287 unit = device_get_unit(dev);
1288
1289 mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
1290 MTX_DEF | MTX_RECURSE);
105
106#include <sys/param.h>
107#include <sys/systm.h>
108#include <sys/sockio.h>
109#include <sys/endian.h>
110#include <sys/mbuf.h>
111#include <sys/kernel.h>
112#include <sys/socket.h>

--- 1170 unchanged lines hidden (view full) ---

1283 int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
1284 int unit, error = 0, rid, res;
1285
1286 sc = device_get_softc(dev);
1287 unit = device_get_unit(dev);
1288
1289 mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
1290 MTX_DEF | MTX_RECURSE);
1291 XL_LOCK(sc);
1292
1293 sc->xl_flags = 0;
1294 if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_555)
1295 sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
1296 if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_556 ||
1297 pci_get_device(dev) == TC_DEVICEID_HURRICANE_556B)
1298 sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
1299 XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET |

--- 70 unchanged lines hidden (view full) ---

1370 */
1371 pci_enable_busmaster(dev);
1372 pci_enable_io(dev, SYS_RES_IOPORT);
1373 pci_enable_io(dev, SYS_RES_MEMORY);
1374 command = pci_read_config(dev, PCIR_COMMAND, 4);
1375
1376 if (!(command & PCIM_CMD_PORTEN) && !(command & PCIM_CMD_MEMEN)) {
1377 printf("xl%d: failed to enable I/O ports and memory mappings!\n", unit);
1291
1292 sc->xl_flags = 0;
1293 if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_555)
1294 sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
1295 if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_556 ||
1296 pci_get_device(dev) == TC_DEVICEID_HURRICANE_556B)
1297 sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
1298 XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET |

--- 70 unchanged lines hidden (view full) ---

1369 */
1370 pci_enable_busmaster(dev);
1371 pci_enable_io(dev, SYS_RES_IOPORT);
1372 pci_enable_io(dev, SYS_RES_MEMORY);
1373 command = pci_read_config(dev, PCIR_COMMAND, 4);
1374
1375 if (!(command & PCIM_CMD_PORTEN) && !(command & PCIM_CMD_MEMEN)) {
1376 printf("xl%d: failed to enable I/O ports and memory mappings!\n", unit);
1377 error = ENXIO;
1378 goto fail;
1379 }
1380
1381 rid = XL_PCI_LOMEM;
1382 res = SYS_RES_MEMORY;
1383
1384 sc->xl_res = bus_alloc_resource(dev, res, &rid,
1385 0, ~0, 1, RF_ACTIVE);

--- 4 unchanged lines hidden (view full) ---

1390 printf("xl%d: using memory mapped I/O\n", unit);
1391 } else {
1392 rid = XL_PCI_LOIO;
1393 res = SYS_RES_IOPORT;
1394 sc->xl_res = bus_alloc_resource(dev, res, &rid,
1395 0, ~0, 1, RF_ACTIVE);
1396 if (sc->xl_res == NULL) {
1397 printf ("xl%d: couldn't map ports/memory\n", unit);
1378 goto fail;
1379 }
1380
1381 rid = XL_PCI_LOMEM;
1382 res = SYS_RES_MEMORY;
1383
1384 sc->xl_res = bus_alloc_resource(dev, res, &rid,
1385 0, ~0, 1, RF_ACTIVE);

--- 4 unchanged lines hidden (view full) ---

1390 printf("xl%d: using memory mapped I/O\n", unit);
1391 } else {
1392 rid = XL_PCI_LOIO;
1393 res = SYS_RES_IOPORT;
1394 sc->xl_res = bus_alloc_resource(dev, res, &rid,
1395 0, ~0, 1, RF_ACTIVE);
1396 if (sc->xl_res == NULL) {
1397 printf ("xl%d: couldn't map ports/memory\n", unit);
1398 error = ENXIO;
1398 goto fail;
1399 }
1400 if (bootverbose)
1401 printf("xl%d: using port I/O\n", unit);
1402 }
1403
1404 sc->xl_btag = rman_get_bustag(sc->xl_res);
1405 sc->xl_bhandle = rman_get_bushandle(sc->xl_res);
1406
1407 if (sc->xl_flags & XL_FLAG_FUNCREG) {
1408 rid = XL_PCI_FUNCMEM;
1409 sc->xl_fres = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
1410 0, ~0, 1, RF_ACTIVE);
1411
1412 if (sc->xl_fres == NULL) {
1413 printf ("xl%d: couldn't map ports/memory\n", unit);
1399 goto fail;
1400 }
1401 if (bootverbose)
1402 printf("xl%d: using port I/O\n", unit);
1403 }
1404
1405 sc->xl_btag = rman_get_bustag(sc->xl_res);
1406 sc->xl_bhandle = rman_get_bushandle(sc->xl_res);
1407
1408 if (sc->xl_flags & XL_FLAG_FUNCREG) {
1409 rid = XL_PCI_FUNCMEM;
1410 sc->xl_fres = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
1411 0, ~0, 1, RF_ACTIVE);
1412
1413 if (sc->xl_fres == NULL) {
1414 printf ("xl%d: couldn't map ports/memory\n", unit);
1414 goto fail_res;
1415 error = ENXIO;
1416 goto fail;
1415 }
1416
1417 sc->xl_ftag = rman_get_bustag(sc->xl_fres);
1418 sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
1419 }
1420
1417 }
1418
1419 sc->xl_ftag = rman_get_bustag(sc->xl_fres);
1420 sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
1421 }
1422
1423 /* Allocate interrupt */
1421 rid = 0;
1422 sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
1423 RF_SHAREABLE | RF_ACTIVE);
1424 if (sc->xl_irq == NULL) {
1425 printf("xl%d: couldn't map interrupt\n", unit);
1424 rid = 0;
1425 sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
1426 RF_SHAREABLE | RF_ACTIVE);
1427 if (sc->xl_irq == NULL) {
1428 printf("xl%d: couldn't map interrupt\n", unit);
1426 goto fail_fres;
1429 error = ENXIO;
1430 goto fail;
1427 }
1428
1431 }
1432
1429 error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
1430 xl_intr, sc, &sc->xl_intrhand);
1431 if (error) {
1432 printf("xl%d: couldn't set up irq\n", unit);
1433 goto fail_irq;
1434 }
1435
1436 /* Reset the adapter. */
1437 xl_reset(sc);
1438
1439 /*
1440 * Get station address from the EEPROM.
1441 */
1442 if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) {
1443 printf("xl%d: failed to read station address\n", sc->xl_unit);
1433 /* Reset the adapter. */
1434 xl_reset(sc);
1435
1436 /*
1437 * Get station address from the EEPROM.
1438 */
1439 if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) {
1440 printf("xl%d: failed to read station address\n", sc->xl_unit);
1444 goto fail_irq_setup;
1441 error = ENXIO;
1442 goto fail;
1445 }
1446
1447 /*
1448 * A 3Com chip was detected. Inform the world.
1449 */
1450 printf("xl%d: Ethernet address: %6D\n", unit, eaddr, ":");
1451
1452 sc->xl_unit = unit;
1453 callout_handle_init(&sc->xl_stat_ch);
1454 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
1455
1456 /*
1443 }
1444
1445 /*
1446 * A 3Com chip was detected. Inform the world.
1447 */
1448 printf("xl%d: Ethernet address: %6D\n", unit, eaddr, ":");
1449
1450 sc->xl_unit = unit;
1451 callout_handle_init(&sc->xl_stat_ch);
1452 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
1453
1454 /*
1457 * Now allocate a tag for the DMA descriptor lists.
1455 * Now allocate a tag for the DMA descriptor lists and a chunk
1456 * of DMA-able memory based on the tag. Also obtain the DMA
1457 * addresses of the RX and TX ring, which we'll need later.
1458 * All of our lists are allocated as a contiguous block
1459 * of memory.
1460 */
1461 error = bus_dma_tag_create(NULL, 8, 0,
1462 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
1463 XL_RX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
1464 &sc->xl_ldata.xl_rx_tag);
1465 if (error) {
1458 * All of our lists are allocated as a contiguous block
1459 * of memory.
1460 */
1461 error = bus_dma_tag_create(NULL, 8, 0,
1462 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
1463 XL_RX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
1464 &sc->xl_ldata.xl_rx_tag);
1465 if (error) {
1466 printf("xl%d: failed to allocate dma tag\n", unit);
1467 goto fail_irq_setup;
1466 printf("xl%d: failed to allocate rx dma tag\n", unit);
1467 goto fail;
1468 }
1469
1468 }
1469
1470 error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
1471 (void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
1472 &sc->xl_ldata.xl_rx_dmamap);
1473 if (error) {
1474 printf("xl%d: no memory for rx list buffers!\n", unit);
1475 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1476 sc->xl_ldata.xl_rx_tag = NULL;
1477 goto fail;
1478 }
1479
1480 error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
1481 sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
1482 XL_RX_LIST_SZ, xl_dma_map_addr,
1483 &sc->xl_ldata.xl_rx_dmaaddr, 0);
1484 if (error) {
1485 printf("xl%d: cannot get dma address of the rx ring!\n", unit);
1486 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1487 sc->xl_ldata.xl_rx_dmamap);
1488 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1489 sc->xl_ldata.xl_rx_tag = NULL;
1490 goto fail;
1491 }
1492
1470 error = bus_dma_tag_create(NULL, 8, 0,
1471 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
1472 XL_TX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
1473 &sc->xl_ldata.xl_tx_tag);
1474 if (error) {
1493 error = bus_dma_tag_create(NULL, 8, 0,
1494 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
1495 XL_TX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
1496 &sc->xl_ldata.xl_tx_tag);
1497 if (error) {
1475 printf("xl%d: failed to allocate dma tag\n", unit);
1476 goto fail_rxtag;
1498 printf("xl%d: failed to allocate tx dma tag\n", unit);
1499 goto fail;
1477 }
1478
1500 }
1501
1479 /*
1480 * Allocate a DMA tag for the mapping of mbufs.
1481 */
1482 error = bus_dma_tag_create(NULL, 1, 0,
1483 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
1484 XL_MAXFRAGS, BUS_SPACE_MAXSIZE_32BIT, 0, &sc->xl_mtag);
1485 if (error) {
1486 printf("xl%d: failed to allocate dma tag\n", unit);
1487 goto fail_txtag;
1488 }
1489
1490 /*
1491 * Now allocate a chunk of DMA-able memory based on the
1492 * tag we just created.
1493 */
1494 error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
1495 (void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT,
1496 &sc->xl_ldata.xl_tx_dmamap);
1497 if (error) {
1498 printf("xl%d: no memory for list buffers!\n", unit);
1502 error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
1503 (void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT,
1504 &sc->xl_ldata.xl_tx_dmamap);
1505 if (error) {
1506 printf("xl%d: no memory for list buffers!\n", unit);
1499 goto fail_mtag;
1507 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1508 sc->xl_ldata.xl_tx_tag = NULL;
1509 goto fail;
1500 }
1501
1510 }
1511
1502 error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
1503 (void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
1504 &sc->xl_ldata.xl_rx_dmamap);
1505 if (error) {
1506 printf("xl%d: no memory for list buffers!\n", unit);
1507 goto fail_txmem;
1508 }
1509
1510 bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
1511 bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
1512
1513 /*
1514 * Obtain the DMA address of the RX and TX ring which we'll need later.
1515 */
1516 error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
1517 sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
1518 XL_TX_LIST_SZ, xl_dma_map_addr,
1519 &sc->xl_ldata.xl_tx_dmaaddr, 0);
1520 if (error) {
1521 printf("xl%d: cannot get dma address of the tx ring!\n", unit);
1512 error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
1513 sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
1514 XL_TX_LIST_SZ, xl_dma_map_addr,
1515 &sc->xl_ldata.xl_tx_dmaaddr, 0);
1516 if (error) {
1517 printf("xl%d: cannot get dma address of the tx ring!\n", unit);
1522 goto fail_rxmem;
1518 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1519 sc->xl_ldata.xl_tx_dmamap);
1520 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1521 sc->xl_ldata.xl_tx_tag = NULL;
1522 goto fail;
1523 }
1524
1523 }
1524
1525 error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
1526 sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
1527 XL_RX_LIST_SZ, xl_dma_map_addr,
1528 &sc->xl_ldata.xl_rx_dmaaddr, 0);
1525 /*
1526 * Allocate a DMA tag for the mapping of mbufs.
1527 */
1528 error = bus_dma_tag_create(NULL, 1, 0,
1529 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
1530 XL_MAXFRAGS, BUS_SPACE_MAXSIZE_32BIT, 0, &sc->xl_mtag);
1529 if (error) {
1531 if (error) {
1530 printf("xl%d: cannot get dma address of the rx ring!\n", unit);
1531 goto fail_txmap;
1532 printf("xl%d: failed to allocate mbuf dma tag\n", unit);
1533 goto fail;
1532 }
1533
1534 }
1535
1536 bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
1537 bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
1538
1534 /* We need a spare DMA map for the RX ring. */
1535 error = bus_dmamap_create(sc->xl_mtag, 0, &sc->xl_tmpmap);
1536 if (error)
1539 /* We need a spare DMA map for the RX ring. */
1540 error = bus_dmamap_create(sc->xl_mtag, 0, &sc->xl_tmpmap);
1541 if (error)
1537 return(error);
1542 goto fail;
1538
1539 /*
1540 * Figure out the card type. 3c905B adapters have the
1541 * 'supportsNoTxLength' bit set in the capabilities
1542 * word in the EEPROM.
1543 */
1544 xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
1545 if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)

--- 42 unchanged lines hidden (view full) ---

1588 if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
1589 || sc->xl_media & XL_MEDIAOPT_BT4) {
1590 if (bootverbose)
1591 printf("xl%d: found MII/AUTO\n", sc->xl_unit);
1592 xl_setcfg(sc);
1593 if (mii_phy_probe(dev, &sc->xl_miibus,
1594 xl_ifmedia_upd, xl_ifmedia_sts)) {
1595 printf("xl%d: no PHY found!\n", sc->xl_unit);
1543
1544 /*
1545 * Figure out the card type. 3c905B adapters have the
1546 * 'supportsNoTxLength' bit set in the capabilities
1547 * word in the EEPROM.
1548 */
1549 xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
1550 if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)

--- 42 unchanged lines hidden (view full) ---

1593 if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
1594 || sc->xl_media & XL_MEDIAOPT_BT4) {
1595 if (bootverbose)
1596 printf("xl%d: found MII/AUTO\n", sc->xl_unit);
1597 xl_setcfg(sc);
1598 if (mii_phy_probe(dev, &sc->xl_miibus,
1599 xl_ifmedia_upd, xl_ifmedia_sts)) {
1600 printf("xl%d: no PHY found!\n", sc->xl_unit);
1596 goto fail_rxmap;
1601 error = ENXIO;
1602 goto fail;
1597 }
1598
1599 goto done;
1600 }
1601
1602 /*
1603 * Sanity check. If the user has selected "auto" and this isn't
1604 * a 10/100 card of some kind, we need to force the transceiver

--- 100 unchanged lines hidden (view full) ---

1705 XL_SEL_WIN(0);
1706 CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
1707 }
1708
1709 /*
1710 * Call MI attach routine.
1711 */
1712 ether_ifattach(ifp, eaddr);
1603 }
1604
1605 goto done;
1606 }
1607
1608 /*
1609 * Sanity check. If the user has selected "auto" and this isn't
1610 * a 10/100 card of some kind, we need to force the transceiver

--- 100 unchanged lines hidden (view full) ---

1711 XL_SEL_WIN(0);
1712 CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
1713 }
1714
1715 /*
1716 * Call MI attach routine.
1717 */
1718 ether_ifattach(ifp, eaddr);
1713 XL_UNLOCK(sc);
1714 return(0);
1715
1719
1716fail_rxmap:
1717 bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
1718fail_txmap:
1719 bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
1720fail_rxmem:
1721 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1722 sc->xl_ldata.xl_rx_dmamap);
1723fail_txmem:
1724 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1725 sc->xl_ldata.xl_tx_dmamap);
1726fail_mtag:
1727 bus_dma_tag_destroy(sc->xl_mtag);
1728fail_txtag:
1729 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1730fail_rxtag:
1731 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1732fail_irq_setup:
1733 bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
1734fail_irq:
1735 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
1736fail_fres:
1737 if (sc->xl_fres != NULL)
1738 bus_release_resource(dev, SYS_RES_MEMORY, XL_PCI_FUNCMEM,
1739 sc->xl_fres);
1740fail_res:
1741 if (sc->xl_flags & XL_FLAG_USE_MMIO) {
1742 rid = XL_PCI_LOMEM;
1743 res = SYS_RES_MEMORY;
1744 } else {
1745 rid = XL_PCI_LOIO;
1746 res = SYS_RES_IOPORT;
1720 error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
1721 xl_intr, sc, &sc->xl_intrhand);
1722 if (error) {
1723 printf("xl%d: couldn't set up irq\n", unit);
1724 goto fail;
1747 }
1748
1725 }
1726
1749 bus_release_resource(dev, res, rid, sc->xl_res);
1750fail:
1727fail:
1751 XL_UNLOCK(sc);
1752 mtx_destroy(&sc->xl_mtx);
1728 if (error)
1729 xl_detach(dev);
1753
1730
1754 return(ENXIO);
1731 return(error);
1755}
1756
1757static int
1758xl_detach(dev)
1759 device_t dev;
1760{
1761 struct xl_softc *sc;
1762 struct ifnet *ifp;
1763 int rid, res;
1764
1765 sc = device_get_softc(dev);
1732}
1733
1734static int
1735xl_detach(dev)
1736 device_t dev;
1737{
1738 struct xl_softc *sc;
1739 struct ifnet *ifp;
1740 int rid, res;
1741
1742 sc = device_get_softc(dev);
1743 KASSERT(mtx_initialized(&sc->xl_mtx), "xl mutex not initialized");
1766 XL_LOCK(sc);
1767 ifp = &sc->arpcom.ac_if;
1768
1769 if (sc->xl_flags & XL_FLAG_USE_MMIO) {
1770 rid = XL_PCI_LOMEM;
1771 res = SYS_RES_MEMORY;
1772 } else {
1773 rid = XL_PCI_LOIO;
1774 res = SYS_RES_IOPORT;
1775 }
1776
1744 XL_LOCK(sc);
1745 ifp = &sc->arpcom.ac_if;
1746
1747 if (sc->xl_flags & XL_FLAG_USE_MMIO) {
1748 rid = XL_PCI_LOMEM;
1749 res = SYS_RES_MEMORY;
1750 } else {
1751 rid = XL_PCI_LOIO;
1752 res = SYS_RES_IOPORT;
1753 }
1754
1777 xl_reset(sc);
1778 xl_stop(sc);
1779 ether_ifdetach(ifp);
1780
1781 /* Delete any miibus and phy devices attached to this interface */
1782 if (sc->xl_miibus != NULL) {
1783 bus_generic_detach(dev);
1755 if (device_is_alive(dev)) {
1756 if (bus_child_present(dev)) {
1757 xl_reset(sc);
1758 xl_stop(sc);
1759 }
1760 ether_ifdetach(ifp);
1784 device_delete_child(dev, sc->xl_miibus);
1761 device_delete_child(dev, sc->xl_miibus);
1762 bus_generic_detach(dev);
1763 ifmedia_removeall(&sc->ifmedia);
1785 }
1786
1764 }
1765
1787 bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
1788 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
1766 if (sc->xl_intrhand)
1767 bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
1768 if (sc->xl_irq)
1769 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
1789 if (sc->xl_fres != NULL)
1790 bus_release_resource(dev, SYS_RES_MEMORY,
1791 XL_PCI_FUNCMEM, sc->xl_fres);
1770 if (sc->xl_fres != NULL)
1771 bus_release_resource(dev, SYS_RES_MEMORY,
1772 XL_PCI_FUNCMEM, sc->xl_fres);
1792 bus_release_resource(dev, res, rid, sc->xl_res);
1793 bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
1794 bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
1795 bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
1796 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1797 sc->xl_ldata.xl_rx_dmamap);
1798 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1799 sc->xl_ldata.xl_tx_dmamap);
1800 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1801 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1802 bus_dma_tag_destroy(sc->xl_mtag);
1803 ifmedia_removeall(&sc->ifmedia);
1773 if (sc->xl_res)
1774 bus_release_resource(dev, res, rid, sc->xl_res);
1804
1775
1776 if (sc->xl_mtag) {
1777 bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
1778 bus_dma_tag_destroy(sc->xl_mtag);
1779 }
1780 if (sc->xl_ldata.xl_rx_tag) {
1781 bus_dmamap_unload(sc->xl_ldata.xl_rx_tag,
1782 sc->xl_ldata.xl_rx_dmamap);
1783 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1784 sc->xl_ldata.xl_rx_dmamap);
1785 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1786 }
1787 if (sc->xl_ldata.xl_tx_tag) {
1788 bus_dmamap_unload(sc->xl_ldata.xl_tx_tag,
1789 sc->xl_ldata.xl_tx_dmamap);
1790 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1791 sc->xl_ldata.xl_tx_dmamap);
1792 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1793 }
1794
1805 XL_UNLOCK(sc);
1806 mtx_destroy(&sc->xl_mtx);
1807
1808 return(0);
1809}
1810
1811/*
1812 * Initialize the transmit descriptors.

--- 1448 unchanged lines hidden ---
1795 XL_UNLOCK(sc);
1796 mtx_destroy(&sc->xl_mtx);
1797
1798 return(0);
1799}
1800
1801/*
1802 * Initialize the transmit descriptors.

--- 1448 unchanged lines hidden ---