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