Clean up locking and resource management for pci/if_*
- Remove locking of the softc in the attach method, instead depending on bus_setup_intr being at the end of attach (delaying interrupt enable until after ether_ifattach is called) - Call *_detach directly in the error case of attach, depending on checking in detach to only free resources that were allocated. This puts all resource freeing in one place, avoiding thinkos that lead to memory leaks. - Add bus_child_present check to calls to *_stop in the detach method to be sure hw is present before touching its registers. - Remove bzero softc calls since device_t should do this for us. - dc: move interrupt allocation back where it was before. It was unnecessary to move it. This reverts part of 1.88 - rl: move irq allocation before ether_ifattach. Problems might have been caused by allocating the irq after enabling interrupts on the card. - rl: call rl_stop before ether_ifdetach - sf: call sf_stop before ether_ifdetach - sis: add missed free of sis_tag - sis: check errors from tag creation - sis: move dmamem_alloc and dmamap_load to happen at same time as tag creation - sk: remove duplicate initialization of sk_dev - ste: add missed bus_generic_detach - ti: call ti_stop before ether_ifdetach - ti: add missed error setting in ti_rdata alloc failure - vr: add missed error setting in I/O, memory mapping cases - xl: add missed error setting in I/O, memory mapping cases - xl: remove multi-level goto on attach failure - xl: move dmamem_alloc and dmamap_load to happen at same time as tag creation - Calls to free(9) are unconditional because it is valid to call free with a null pointer. Reviewed by: imp, mdodd
This commit is contained in:
parent
6391ac5ac4
commit
4d18978dc6
@ -1905,7 +1905,6 @@ dc_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct dc_softc));
|
||||
|
||||
mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -1950,6 +1949,17 @@ dc_attach(dev)
|
||||
sc->dc_btag = rman_get_bustag(sc->dc_res);
|
||||
sc->dc_bhandle = rman_get_bushandle(sc->dc_res);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->dc_irq == NULL) {
|
||||
printf("dc%d: couldn't map interrupt\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Need this info to decide on a chip type. */
|
||||
sc->dc_info = dc_devtype(dev);
|
||||
revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF;
|
||||
@ -2141,7 +2151,6 @@ dc_attach(dev)
|
||||
mac = pci_get_ether(dev);
|
||||
if (!mac) {
|
||||
device_printf(dev, "No station address in CIS!\n");
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2165,7 +2174,6 @@ dc_attach(dev)
|
||||
|
||||
if (sc->dc_ldata == NULL) {
|
||||
printf("dc%d: no memory for list buffers!\n", unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2224,8 +2232,6 @@ dc_attach(dev)
|
||||
|
||||
if (error) {
|
||||
printf("dc%d: MII without any PHY!\n", sc->dc_unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -2288,31 +2294,19 @@ dc_attach(dev)
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->dc_irq == NULL) {
|
||||
printf("dc%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Hook interrupt last to avoid having to lock softc */
|
||||
error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
|
||||
(IS_MPSAFE ? INTR_MPSAFE : 0),
|
||||
dc_intr, sc, &sc->dc_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
printf("dc%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (error != 0)
|
||||
mtx_destroy(&sc->dc_mtx);
|
||||
if (error)
|
||||
dc_detach(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2325,24 +2319,29 @@ dc_detach(dev)
|
||||
struct dc_mediainfo *m;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
KASSERT(mtx_initialized(&sc->dc_mtx), "dc mutex not initialized");
|
||||
DC_LOCK(sc);
|
||||
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
dc_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
dc_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->dc_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->dc_miibus);
|
||||
if (sc->dc_intrhand)
|
||||
bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
|
||||
if (sc->dc_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
if (sc->dc_res)
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
|
||||
contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
|
||||
if (sc->dc_pnic_rx_buf != NULL)
|
||||
free(sc->dc_pnic_rx_buf, M_DEVBUF);
|
||||
if (sc->dc_ldata)
|
||||
contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
|
||||
free(sc->dc_pnic_rx_buf, M_DEVBUF);
|
||||
|
||||
while(sc->dc_mi != NULL) {
|
||||
m = sc->dc_mi->dc_next;
|
||||
|
@ -681,11 +681,10 @@ sf_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct sf_softc));
|
||||
|
||||
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
SF_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
*/
|
||||
@ -751,21 +750,10 @@ sf_attach(dev)
|
||||
|
||||
if (sc->sf_irq == NULL) {
|
||||
printf("sf%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
|
||||
sf_intr, sc, &sc->sf_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_res);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
printf("sf%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->sf_stat_ch);
|
||||
/* Reset the adapter. */
|
||||
sf_reset(sc);
|
||||
@ -791,9 +779,6 @@ sf_attach(dev)
|
||||
|
||||
if (sc->sf_ldata == NULL) {
|
||||
printf("sf%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -804,10 +789,6 @@ sf_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->sf_miibus,
|
||||
sf_ifmedia_upd, sf_ifmedia_sts)) {
|
||||
printf("sf%d: MII without any phy!\n", sc->sf_unit);
|
||||
contigfree(sc->sf_ldata,sizeof(struct sf_list_data),M_DEVBUF);
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -830,12 +811,19 @@ sf_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
|
||||
SF_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
|
||||
sf_intr, sc, &sc->sf_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("sf%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
SF_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sf_mtx);
|
||||
if (error)
|
||||
sf_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -847,20 +835,27 @@ sf_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->sf_mtx), "sf mutex not initialized");
|
||||
SF_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
sf_stop(sc);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
sf_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->sf_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->sf_miibus);
|
||||
if (sc->sf_intrhand)
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
if (sc->sf_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
if (sc->sf_res)
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
|
||||
contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
|
||||
if (sc->sf_ldata)
|
||||
contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
|
||||
|
||||
SF_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sf_mtx);
|
||||
|
@ -1039,20 +1039,18 @@ sk_attach_xmac(dev)
|
||||
struct sk_softc *sc;
|
||||
struct sk_if_softc *sc_if;
|
||||
struct ifnet *ifp;
|
||||
int i, port;
|
||||
int i, port, error;
|
||||
|
||||
if (dev == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
error = 0;
|
||||
sc_if = device_get_softc(dev);
|
||||
sc = device_get_softc(device_get_parent(dev));
|
||||
SK_LOCK(sc);
|
||||
port = *(int *)device_get_ivars(dev);
|
||||
free(device_get_ivars(dev), M_DEVBUF);
|
||||
device_set_ivars(dev, NULL);
|
||||
sc_if->sk_dev = dev;
|
||||
|
||||
bzero((char *)sc_if, sizeof(struct sk_if_softc));
|
||||
|
||||
sc_if->sk_dev = dev;
|
||||
sc_if->sk_unit = device_get_unit(dev);
|
||||
@ -1125,8 +1123,8 @@ sk_attach_xmac(dev)
|
||||
default:
|
||||
printf("skc%d: unsupported PHY type: %d\n",
|
||||
sc->sk_unit, sc_if->sk_phytype);
|
||||
SK_UNLOCK(sc);
|
||||
return(ENODEV);
|
||||
error = ENODEV;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
/* Allocate the descriptor queues. */
|
||||
@ -1135,9 +1133,8 @@ sk_attach_xmac(dev)
|
||||
|
||||
if (sc_if->sk_rdata == NULL) {
|
||||
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
|
||||
sc->sk_if[port] = NULL;
|
||||
SK_UNLOCK(sc);
|
||||
return(ENOMEM);
|
||||
error = ENOMEM;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
|
||||
@ -1146,11 +1143,8 @@ sk_attach_xmac(dev)
|
||||
if (sk_alloc_jumbo_mem(sc_if)) {
|
||||
printf("sk%d: jumbo buffer allocation failed\n",
|
||||
sc_if->sk_unit);
|
||||
contigfree(sc_if->sk_rdata,
|
||||
sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
sc->sk_if[port] = NULL;
|
||||
SK_UNLOCK(sc);
|
||||
return(ENOMEM);
|
||||
error = ENOMEM;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
ifp = &sc_if->arpcom.ac_if;
|
||||
@ -1167,11 +1161,12 @@ sk_attach_xmac(dev)
|
||||
ifp->if_baudrate = 1000000000;
|
||||
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
|
||||
|
||||
callout_handle_init(&sc_if->sk_tick_ch);
|
||||
|
||||
/*
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
|
||||
callout_handle_init(&sc_if->sk_tick_ch);
|
||||
|
||||
/*
|
||||
* Do miibus setup.
|
||||
@ -1180,16 +1175,19 @@ sk_attach_xmac(dev)
|
||||
if (mii_phy_probe(dev, &sc_if->sk_miibus,
|
||||
sk_ifmedia_upd, sk_ifmedia_sts)) {
|
||||
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
|
||||
contigfree(sc_if->sk_rdata,
|
||||
sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
ether_ifdetach(ifp);
|
||||
SK_UNLOCK(sc);
|
||||
return(ENXIO);
|
||||
error = ENXIO;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
fail_xmac:
|
||||
SK_UNLOCK(sc);
|
||||
if (error) {
|
||||
/* Access should be ok even though lock has been dropped */
|
||||
sc->sk_if[port] = NULL;
|
||||
sk_detach_xmac(dev);
|
||||
}
|
||||
|
||||
return(0);
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1206,11 +1204,9 @@ sk_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct sk_softc));
|
||||
|
||||
mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
SK_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -1277,21 +1273,10 @@ sk_attach(dev)
|
||||
|
||||
if (sc->sk_irq == NULL) {
|
||||
printf("skc%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
|
||||
sk_intr, sc, &sc->sk_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("skc%d: couldn't set up irq\n", unit);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
sk_reset(sc);
|
||||
|
||||
@ -1321,12 +1306,8 @@ sk_attach(dev)
|
||||
default:
|
||||
printf("skc%d: unknown ram size: %d\n",
|
||||
sc->sk_unit, sk_win_read_1(sc, SK_EPROM0));
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read and save physical media type */
|
||||
@ -1346,9 +1327,6 @@ sk_attach(dev)
|
||||
default:
|
||||
printf("skc%d: unknown media type: 0x%x\n",
|
||||
sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE));
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1371,12 +1349,19 @@ sk_attach(dev)
|
||||
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
SK_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
|
||||
sk_intr, sc, &sc->sk_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("skc%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
SK_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sk_mtx);
|
||||
if (error)
|
||||
sk_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1390,16 +1375,24 @@ sk_detach_xmac(dev)
|
||||
|
||||
sc = device_get_softc(device_get_parent(dev));
|
||||
sc_if = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx),
|
||||
"sk mutex not initialized in sk_detach_xmac");
|
||||
SK_IF_LOCK(sc_if);
|
||||
|
||||
ifp = &sc_if->arpcom.ac_if;
|
||||
sk_stop(sc_if);
|
||||
ether_ifdetach(ifp);
|
||||
bus_generic_detach(dev);
|
||||
if (sc_if->sk_miibus != NULL)
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
sk_stop(sc_if);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc_if->sk_miibus);
|
||||
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
|
||||
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
if (sc_if->sk_cdata.sk_jumbo_buf)
|
||||
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
|
||||
if (sc_if->sk_rdata) {
|
||||
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
|
||||
M_DEVBUF);
|
||||
}
|
||||
SK_IF_UNLOCK(sc_if);
|
||||
|
||||
return(0);
|
||||
@ -1412,17 +1405,23 @@ sk_detach(dev)
|
||||
struct sk_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->sk_mtx), "sk mutex not initialized");
|
||||
SK_LOCK(sc);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (sc->sk_devs[SK_PORT_A] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
|
||||
if (sc->sk_devs[SK_PORT_B] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
|
||||
if (device_is_alive(dev)) {
|
||||
if (sc->sk_devs[SK_PORT_A] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
|
||||
if (sc->sk_devs[SK_PORT_B] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
if (sc->sk_intrhand)
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
if (sc->sk_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
if (sc->sk_res)
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
|
||||
SK_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sk_mtx);
|
||||
|
@ -2115,7 +2115,6 @@ ti_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct ti_softc));
|
||||
|
||||
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -2161,25 +2160,10 @@ ti_attach(dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
|
||||
ti_intr, sc, &sc->ti_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
printf("ti%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->ti_unit = unit;
|
||||
|
||||
if (ti_chipinit(sc)) {
|
||||
printf("ti%d: chip initialization failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2190,10 +2174,6 @@ ti_attach(dev)
|
||||
/* Init again -- zeroing memory may have clobbered some registers. */
|
||||
if (ti_chipinit(sc)) {
|
||||
printf("ti%d: chip initialization failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2208,10 +2188,6 @@ ti_attach(dev)
|
||||
if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
|
||||
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
|
||||
printf("ti%d: failed to read station address\n", unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2227,12 +2203,8 @@ ti_attach(dev)
|
||||
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
|
||||
|
||||
if (sc->ti_rdata == NULL) {
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
printf("ti%d: no memory for list buffers!\n", sc->ti_unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -2242,23 +2214,12 @@ ti_attach(dev)
|
||||
#ifdef TI_PRIVATE_JUMBOS
|
||||
if (ti_alloc_jumbo_mem(sc)) {
|
||||
printf("ti%d: jumbo buffer allocation failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data),
|
||||
M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!jumbo_vm_init()) {
|
||||
printf("ti%d: VM initialization failed!\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
free(sc->ti_rdata, M_DEVBUF);
|
||||
error = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@ -2359,10 +2320,19 @@ ti_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
|
||||
ti_intr, sc, &sc->ti_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("ti%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
mtx_destroy(&sc->ti_mtx);
|
||||
if (sc && error)
|
||||
ti_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -2405,21 +2375,33 @@ ti_detach(dev)
|
||||
return EBUSY;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->ti_mtx), "ti mutex not initialized");
|
||||
TI_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
ti_stop(sc);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
ti_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
bus_generic_detach(dev);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM, sc->ti_res);
|
||||
if (sc->ti_intrhand)
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
if (sc->ti_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
if (sc->ti_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM,
|
||||
sc->ti_res);
|
||||
}
|
||||
|
||||
#ifdef TI_PRIVATE_JUMBOS
|
||||
contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
|
||||
if (sc->ti_cdata.ti_jumbo_buf)
|
||||
contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
|
||||
#endif
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
if (sc->ti_rdata)
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
|
||||
|
||||
TI_UNLOCK(sc);
|
||||
mtx_destroy(&sc->ti_mtx);
|
||||
|
@ -744,11 +744,9 @@ vr_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct vr_softc *));
|
||||
|
||||
mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
VR_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -785,12 +783,13 @@ vr_attach(dev)
|
||||
#ifdef VR_USEIOSPACE
|
||||
if (!(command & PCIM_CMD_PORTEN)) {
|
||||
printf("vr%d: failed to enable I/O ports!\n", unit);
|
||||
free(sc, M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("vr%d: failed to enable memory mapping!\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
@ -815,21 +814,10 @@ vr_attach(dev)
|
||||
|
||||
if (sc->vr_irq == NULL) {
|
||||
printf("vr%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
|
||||
vr_intr, sc, &sc->vr_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
printf("vr%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows may put the chip in suspend mode when it
|
||||
* shuts down. Be sure to kick it in the head to wake it
|
||||
@ -873,9 +861,6 @@ vr_attach(dev)
|
||||
|
||||
if (sc->vr_ldata == NULL) {
|
||||
printf("vr%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -902,11 +887,6 @@ vr_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->vr_miibus,
|
||||
vr_ifmedia_upd, vr_ifmedia_sts)) {
|
||||
printf("vr%d: MII without any phy!\n", sc->vr_unit);
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
contigfree(sc->vr_ldata,
|
||||
sizeof(struct vr_list_data), M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -917,12 +897,18 @@ vr_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
VR_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
|
||||
vr_intr, sc, &sc->vr_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("vr%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
VR_UNLOCK(sc);
|
||||
mtx_destroy(&sc->vr_mtx);
|
||||
if (error)
|
||||
vr_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
@ -935,20 +921,27 @@ vr_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->vr_mtx), "vr mutex not initialized");
|
||||
VR_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
vr_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
vr_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->vr_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->vr_miibus);
|
||||
if (sc->vr_intrhand)
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
if (sc->vr_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
if (sc->vr_res)
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
|
||||
contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
|
||||
if (sc->vr_ldata)
|
||||
contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
|
||||
|
||||
VR_UNLOCK(sc);
|
||||
mtx_destroy(&sc->vr_mtx);
|
||||
|
@ -1905,7 +1905,6 @@ dc_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct dc_softc));
|
||||
|
||||
mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -1950,6 +1949,17 @@ dc_attach(dev)
|
||||
sc->dc_btag = rman_get_bustag(sc->dc_res);
|
||||
sc->dc_bhandle = rman_get_bushandle(sc->dc_res);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->dc_irq == NULL) {
|
||||
printf("dc%d: couldn't map interrupt\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Need this info to decide on a chip type. */
|
||||
sc->dc_info = dc_devtype(dev);
|
||||
revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF;
|
||||
@ -2141,7 +2151,6 @@ dc_attach(dev)
|
||||
mac = pci_get_ether(dev);
|
||||
if (!mac) {
|
||||
device_printf(dev, "No station address in CIS!\n");
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2165,7 +2174,6 @@ dc_attach(dev)
|
||||
|
||||
if (sc->dc_ldata == NULL) {
|
||||
printf("dc%d: no memory for list buffers!\n", unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2224,8 +2232,6 @@ dc_attach(dev)
|
||||
|
||||
if (error) {
|
||||
printf("dc%d: MII without any PHY!\n", sc->dc_unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -2288,31 +2294,19 @@ dc_attach(dev)
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->dc_irq == NULL) {
|
||||
printf("dc%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Hook interrupt last to avoid having to lock softc */
|
||||
error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
|
||||
(IS_MPSAFE ? INTR_MPSAFE : 0),
|
||||
dc_intr, sc, &sc->dc_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
printf("dc%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (error != 0)
|
||||
mtx_destroy(&sc->dc_mtx);
|
||||
if (error)
|
||||
dc_detach(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2325,24 +2319,29 @@ dc_detach(dev)
|
||||
struct dc_mediainfo *m;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
KASSERT(mtx_initialized(&sc->dc_mtx), "dc mutex not initialized");
|
||||
DC_LOCK(sc);
|
||||
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
dc_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
dc_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->dc_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->dc_miibus);
|
||||
if (sc->dc_intrhand)
|
||||
bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
|
||||
if (sc->dc_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
if (sc->dc_res)
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
|
||||
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
|
||||
|
||||
contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
|
||||
if (sc->dc_pnic_rx_buf != NULL)
|
||||
free(sc->dc_pnic_rx_buf, M_DEVBUF);
|
||||
if (sc->dc_ldata)
|
||||
contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
|
||||
free(sc->dc_pnic_rx_buf, M_DEVBUF);
|
||||
|
||||
while(sc->dc_mi != NULL) {
|
||||
m = sc->dc_mi->dc_next;
|
||||
|
@ -521,7 +521,6 @@ pcn_attach(dev)
|
||||
/* Initialize our mutex. */
|
||||
mtx_init(&sc->pcn_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
PCN_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -557,13 +556,13 @@ pcn_attach(dev)
|
||||
#ifdef PCN_USEIOSPACE
|
||||
if (!(command & PCIM_CMD_PORTEN)) {
|
||||
printf("pcn%d: failed to enable I/O ports!\n", unit);
|
||||
error = ENXIO;;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("pcn%d: failed to enable memory mapping!\n", unit);
|
||||
error = ENXIO;;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
@ -592,14 +591,6 @@ pcn_attach(dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET,
|
||||
pcn_intr, sc, &sc->pcn_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("pcn%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
pcn_reset(sc);
|
||||
|
||||
@ -657,21 +648,18 @@ pcn_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, (u_int8_t *) eaddr);
|
||||
PCN_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET,
|
||||
pcn_intr, sc, &sc->pcn_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("pcn%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
PCN_UNLOCK(sc);
|
||||
|
||||
if (sc->pcn_intrhand)
|
||||
bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
|
||||
if (sc->pcn_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
|
||||
if (sc->pcn_res)
|
||||
bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
|
||||
|
||||
if (mtx_initialized(&sc->pcn_mtx) != 0)
|
||||
mtx_destroy(&sc->pcn_mtx);
|
||||
if (error)
|
||||
pcn_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
@ -686,22 +674,30 @@ pcn_detach(dev)
|
||||
sc = device_get_softc(dev);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
KASSERT(mtx_initialized(&sc->pcn_mtx), "pcn mutex not initialized");
|
||||
PCN_LOCK(sc);
|
||||
|
||||
pcn_reset(sc);
|
||||
pcn_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
|
||||
if (sc->pcn_miibus != NULL) {
|
||||
bus_generic_detach(dev);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev)) {
|
||||
pcn_reset(sc);
|
||||
pcn_stop(sc);
|
||||
}
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->pcn_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
|
||||
bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
|
||||
if (sc->pcn_intrhand)
|
||||
bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
|
||||
if (sc->pcn_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
|
||||
if (sc->pcn_res)
|
||||
bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
|
||||
|
||||
contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), M_DEVBUF);
|
||||
if (sc->pcn_ldata) {
|
||||
contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data),
|
||||
M_DEVBUF);
|
||||
}
|
||||
PCN_UNLOCK(sc);
|
||||
|
||||
mtx_destroy(&sc->pcn_mtx);
|
||||
|
@ -868,7 +868,6 @@ rl_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct rl_softc));
|
||||
|
||||
mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -943,13 +942,13 @@ rl_attach(dev)
|
||||
sc->rl_btag = rman_get_bustag(sc->rl_res);
|
||||
sc->rl_bhandle = rman_get_bushandle(sc->rl_res);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->rl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->rl_irq == NULL) {
|
||||
printf("rl%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -996,8 +995,6 @@ rl_attach(dev)
|
||||
sc->rl_type = RL_8129;
|
||||
else {
|
||||
printf("rl%d: unknown device ID: %x\n", unit, rl_did);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1015,6 +1012,8 @@ rl_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
BUS_DMA_ALLOCNOW, /* flags */
|
||||
&sc->rl_parent_tag);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Now allocate a tag for the DMA descriptor lists.
|
||||
@ -1030,6 +1029,8 @@ rl_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->rl_tag);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Now allocate a chunk of DMA-able memory based on the
|
||||
@ -1039,12 +1040,10 @@ rl_attach(dev)
|
||||
(void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT,
|
||||
&sc->rl_cdata.rl_rx_dmamap);
|
||||
|
||||
if (sc->rl_cdata.rl_rx_buf == NULL) {
|
||||
if (error) {
|
||||
printf("rl%d: no memory for list buffers!\n", unit);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
bus_dma_tag_destroy(sc->rl_tag);
|
||||
error = ENXIO;
|
||||
sc->rl_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1056,11 +1055,6 @@ rl_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->rl_miibus,
|
||||
rl_ifmedia_upd, rl_ifmedia_sts)) {
|
||||
printf("rl%d: MII without any phy!\n", sc->rl_unit);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
bus_dmamem_free(sc->rl_tag,
|
||||
sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->rl_tag);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1079,6 +1073,8 @@ rl_attach(dev)
|
||||
ifp->if_baudrate = 10000000;
|
||||
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
|
||||
|
||||
callout_handle_init(&sc->rl_stat_ch);
|
||||
|
||||
/*
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
@ -1089,18 +1085,13 @@ rl_attach(dev)
|
||||
|
||||
if (error) {
|
||||
printf("rl%d: couldn't set up irq\n", unit);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
bus_dmamem_free(sc->rl_tag,
|
||||
sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->rl_tag);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->rl_stat_ch);
|
||||
fail:
|
||||
if (error != 0)
|
||||
mtx_destroy(&sc->rl_mtx);
|
||||
if (error)
|
||||
rl_detach(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1112,24 +1103,33 @@ rl_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->rl_mtx), "rl mutex not initialized");
|
||||
RL_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
rl_stop(sc);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
rl_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->rl_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->rl_miibus);
|
||||
if (sc->rl_intrhand)
|
||||
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
|
||||
if (sc->rl_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
if (sc->rl_res)
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
|
||||
bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
|
||||
sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->rl_tag);
|
||||
bus_dma_tag_destroy(sc->rl_parent_tag);
|
||||
if (sc->rl_tag) {
|
||||
bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
|
||||
sc->rl_cdata.rl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->rl_tag);
|
||||
}
|
||||
if (sc->rl_parent_tag)
|
||||
bus_dma_tag_destroy(sc->rl_parent_tag);
|
||||
|
||||
RL_UNLOCK(sc);
|
||||
mtx_destroy(&sc->rl_mtx);
|
||||
|
@ -681,11 +681,10 @@ sf_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct sf_softc));
|
||||
|
||||
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
SF_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
*/
|
||||
@ -751,21 +750,10 @@ sf_attach(dev)
|
||||
|
||||
if (sc->sf_irq == NULL) {
|
||||
printf("sf%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
|
||||
sf_intr, sc, &sc->sf_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_res);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
printf("sf%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->sf_stat_ch);
|
||||
/* Reset the adapter. */
|
||||
sf_reset(sc);
|
||||
@ -791,9 +779,6 @@ sf_attach(dev)
|
||||
|
||||
if (sc->sf_ldata == NULL) {
|
||||
printf("sf%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -804,10 +789,6 @@ sf_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->sf_miibus,
|
||||
sf_ifmedia_upd, sf_ifmedia_sts)) {
|
||||
printf("sf%d: MII without any phy!\n", sc->sf_unit);
|
||||
contigfree(sc->sf_ldata,sizeof(struct sf_list_data),M_DEVBUF);
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -830,12 +811,19 @@ sf_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
|
||||
SF_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
|
||||
sf_intr, sc, &sc->sf_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("sf%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
SF_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sf_mtx);
|
||||
if (error)
|
||||
sf_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -847,20 +835,27 @@ sf_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->sf_mtx), "sf mutex not initialized");
|
||||
SF_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
sf_stop(sc);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
sf_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->sf_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->sf_miibus);
|
||||
if (sc->sf_intrhand)
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
if (sc->sf_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
if (sc->sf_res)
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
|
||||
bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
|
||||
|
||||
contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
|
||||
if (sc->sf_ldata)
|
||||
contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
|
||||
|
||||
SF_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sf_mtx);
|
||||
|
200
sys/pci/if_sis.c
200
sys/pci/if_sis.c
@ -1054,7 +1054,6 @@ sis_attach(dev)
|
||||
waittime = 0;
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct sis_softc));
|
||||
|
||||
mtx_init(&sc->sis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -1102,13 +1101,13 @@ sis_attach(dev)
|
||||
#ifdef SIS_USEIOSPACE
|
||||
if (!(command & PCIM_CMD_PORTEN)) {
|
||||
printf("sis%d: failed to enable I/O ports!\n", unit);
|
||||
error = ENXIO;;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("sis%d: failed to enable memory mapping!\n", unit);
|
||||
error = ENXIO;;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
@ -1133,21 +1132,10 @@ sis_attach(dev)
|
||||
|
||||
if (sc->sis_irq == NULL) {
|
||||
printf("sis%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
|
||||
sis_intr, sc, &sc->sis_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
printf("sis%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
sis_reset(sc);
|
||||
|
||||
@ -1276,9 +1264,13 @@ sis_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
BUS_DMA_ALLOCNOW, /* flags */
|
||||
&sc->sis_parent_tag);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Now allocate a tag for the DMA descriptor lists.
|
||||
* Now allocate a tag for the DMA descriptor lists and a chunk
|
||||
* of DMA-able memory based on the tag. Also obtain the physical
|
||||
* addresses of the RX and TX ring, which we'll need later.
|
||||
* All of our lists are allocated as a contiguous block
|
||||
* of memory.
|
||||
*/
|
||||
@ -1291,6 +1283,33 @@ sis_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->sis_ldata.sis_rx_tag);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
|
||||
(void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
|
||||
&sc->sis_ldata.sis_rx_dmamap);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: no memory for rx list buffers!\n", unit);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
sc->sis_ldata.sis_rx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
|
||||
sizeof(struct sis_desc), sis_dma_map_ring,
|
||||
&sc->sis_cdata.sis_rx_paddr, 0);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: cannot get address of the rx ring!\n", unit);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
sc->sis_ldata.sis_rx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
@ -1301,6 +1320,33 @@ sis_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->sis_ldata.sis_tx_tag);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag,
|
||||
(void **)&sc->sis_ldata.sis_tx_list, BUS_DMA_NOWAIT,
|
||||
&sc->sis_ldata.sis_tx_dmamap);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: no memory for tx list buffers!\n", unit);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
sc->sis_ldata.sis_tx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
|
||||
sizeof(struct sis_desc), sis_dma_map_ring,
|
||||
&sc->sis_cdata.sis_tx_paddr, 0);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: cannot get address of the tx ring!\n", unit);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
sc->sis_ldata.sis_tx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
@ -1311,43 +1357,8 @@ sis_attach(dev)
|
||||
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->sis_tag);
|
||||
|
||||
/*
|
||||
* Now allocate a chunk of DMA-able memory based on the
|
||||
* tag we just created.
|
||||
*/
|
||||
error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag,
|
||||
(void **)&sc->sis_ldata.sis_tx_list, BUS_DMA_NOWAIT,
|
||||
&sc->sis_ldata.sis_tx_dmamap);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
error = ENXIO;
|
||||
if (error)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
|
||||
(void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
|
||||
&sc->sis_ldata.sis_rx_dmamap);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
bzero(sc->sis_ldata.sis_tx_list, SIS_TX_LIST_SZ);
|
||||
bzero(sc->sis_ldata.sis_rx_list, SIS_RX_LIST_SZ);
|
||||
@ -1356,14 +1367,6 @@ sis_attach(dev)
|
||||
* Obtain the physical addresses of the RX and TX
|
||||
* rings which we'll need later in the init routine.
|
||||
*/
|
||||
bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
|
||||
sizeof(struct sis_desc), sis_dma_map_ring,
|
||||
&sc->sis_cdata.sis_tx_paddr, 0);
|
||||
bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
|
||||
sizeof(struct sis_desc), sis_dma_map_ring,
|
||||
&sc->sis_cdata.sis_rx_paddr, 0);
|
||||
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
ifp->if_softc = sc;
|
||||
@ -1385,19 +1388,12 @@ sis_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->sis_miibus,
|
||||
sis_ifmedia_upd, sis_ifmedia_sts)) {
|
||||
printf("sis%d: MII without any PHY!\n", sc->sis_unit);
|
||||
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->sis_stat_ch);
|
||||
|
||||
/*
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
@ -1409,11 +1405,18 @@ sis_attach(dev)
|
||||
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
|
||||
ifp->if_capabilities |= IFCAP_VLAN_MTU;
|
||||
|
||||
callout_handle_init(&sc->sis_stat_ch);
|
||||
return(0);
|
||||
error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
|
||||
sis_intr, sc, &sc->sis_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("sis%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
mtx_destroy(&sc->sis_mtx);
|
||||
if (error)
|
||||
sis_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1424,33 +1427,46 @@ sis_detach(dev)
|
||||
struct sis_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->sis_mtx), "sis mutex not initialized");
|
||||
SIS_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
sis_reset(sc);
|
||||
sis_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev)) {
|
||||
sis_reset(sc);
|
||||
sis_stop(sc);
|
||||
}
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->sis_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->sis_miibus);
|
||||
if (sc->sis_intrhand)
|
||||
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
|
||||
if (sc->sis_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
if (sc->sis_res)
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
|
||||
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
|
||||
|
||||
bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
bus_dma_tag_destroy(sc->sis_parent_tag);
|
||||
if (sc->sis_ldata.sis_rx_tag) {
|
||||
bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
|
||||
sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
|
||||
}
|
||||
if (sc->sis_ldata.sis_tx_tag) {
|
||||
bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dmamem_free(sc->sis_ldata.sis_tx_tag,
|
||||
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
|
||||
}
|
||||
if (sc->sis_parent_tag)
|
||||
bus_dma_tag_destroy(sc->sis_parent_tag);
|
||||
if (sc->sis_tag)
|
||||
bus_dma_tag_destroy(sc->sis_tag);
|
||||
|
||||
SIS_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sis_mtx);
|
||||
|
117
sys/pci/if_sk.c
117
sys/pci/if_sk.c
@ -1039,20 +1039,18 @@ sk_attach_xmac(dev)
|
||||
struct sk_softc *sc;
|
||||
struct sk_if_softc *sc_if;
|
||||
struct ifnet *ifp;
|
||||
int i, port;
|
||||
int i, port, error;
|
||||
|
||||
if (dev == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
error = 0;
|
||||
sc_if = device_get_softc(dev);
|
||||
sc = device_get_softc(device_get_parent(dev));
|
||||
SK_LOCK(sc);
|
||||
port = *(int *)device_get_ivars(dev);
|
||||
free(device_get_ivars(dev), M_DEVBUF);
|
||||
device_set_ivars(dev, NULL);
|
||||
sc_if->sk_dev = dev;
|
||||
|
||||
bzero((char *)sc_if, sizeof(struct sk_if_softc));
|
||||
|
||||
sc_if->sk_dev = dev;
|
||||
sc_if->sk_unit = device_get_unit(dev);
|
||||
@ -1125,8 +1123,8 @@ sk_attach_xmac(dev)
|
||||
default:
|
||||
printf("skc%d: unsupported PHY type: %d\n",
|
||||
sc->sk_unit, sc_if->sk_phytype);
|
||||
SK_UNLOCK(sc);
|
||||
return(ENODEV);
|
||||
error = ENODEV;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
/* Allocate the descriptor queues. */
|
||||
@ -1135,9 +1133,8 @@ sk_attach_xmac(dev)
|
||||
|
||||
if (sc_if->sk_rdata == NULL) {
|
||||
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
|
||||
sc->sk_if[port] = NULL;
|
||||
SK_UNLOCK(sc);
|
||||
return(ENOMEM);
|
||||
error = ENOMEM;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
|
||||
@ -1146,11 +1143,8 @@ sk_attach_xmac(dev)
|
||||
if (sk_alloc_jumbo_mem(sc_if)) {
|
||||
printf("sk%d: jumbo buffer allocation failed\n",
|
||||
sc_if->sk_unit);
|
||||
contigfree(sc_if->sk_rdata,
|
||||
sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
sc->sk_if[port] = NULL;
|
||||
SK_UNLOCK(sc);
|
||||
return(ENOMEM);
|
||||
error = ENOMEM;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
ifp = &sc_if->arpcom.ac_if;
|
||||
@ -1167,11 +1161,12 @@ sk_attach_xmac(dev)
|
||||
ifp->if_baudrate = 1000000000;
|
||||
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
|
||||
|
||||
callout_handle_init(&sc_if->sk_tick_ch);
|
||||
|
||||
/*
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
|
||||
callout_handle_init(&sc_if->sk_tick_ch);
|
||||
|
||||
/*
|
||||
* Do miibus setup.
|
||||
@ -1180,16 +1175,19 @@ sk_attach_xmac(dev)
|
||||
if (mii_phy_probe(dev, &sc_if->sk_miibus,
|
||||
sk_ifmedia_upd, sk_ifmedia_sts)) {
|
||||
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
|
||||
contigfree(sc_if->sk_rdata,
|
||||
sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
ether_ifdetach(ifp);
|
||||
SK_UNLOCK(sc);
|
||||
return(ENXIO);
|
||||
error = ENXIO;
|
||||
goto fail_xmac;
|
||||
}
|
||||
|
||||
fail_xmac:
|
||||
SK_UNLOCK(sc);
|
||||
if (error) {
|
||||
/* Access should be ok even though lock has been dropped */
|
||||
sc->sk_if[port] = NULL;
|
||||
sk_detach_xmac(dev);
|
||||
}
|
||||
|
||||
return(0);
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1206,11 +1204,9 @@ sk_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct sk_softc));
|
||||
|
||||
mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
SK_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -1277,21 +1273,10 @@ sk_attach(dev)
|
||||
|
||||
if (sc->sk_irq == NULL) {
|
||||
printf("skc%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
|
||||
sk_intr, sc, &sc->sk_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("skc%d: couldn't set up irq\n", unit);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
sk_reset(sc);
|
||||
|
||||
@ -1321,12 +1306,8 @@ sk_attach(dev)
|
||||
default:
|
||||
printf("skc%d: unknown ram size: %d\n",
|
||||
sc->sk_unit, sk_win_read_1(sc, SK_EPROM0));
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read and save physical media type */
|
||||
@ -1346,9 +1327,6 @@ sk_attach(dev)
|
||||
default:
|
||||
printf("skc%d: unknown media type: 0x%x\n",
|
||||
sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE));
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1371,12 +1349,19 @@ sk_attach(dev)
|
||||
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
SK_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
|
||||
sk_intr, sc, &sc->sk_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("skc%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
SK_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sk_mtx);
|
||||
if (error)
|
||||
sk_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1390,16 +1375,24 @@ sk_detach_xmac(dev)
|
||||
|
||||
sc = device_get_softc(device_get_parent(dev));
|
||||
sc_if = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx),
|
||||
"sk mutex not initialized in sk_detach_xmac");
|
||||
SK_IF_LOCK(sc_if);
|
||||
|
||||
ifp = &sc_if->arpcom.ac_if;
|
||||
sk_stop(sc_if);
|
||||
ether_ifdetach(ifp);
|
||||
bus_generic_detach(dev);
|
||||
if (sc_if->sk_miibus != NULL)
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
sk_stop(sc_if);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc_if->sk_miibus);
|
||||
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
|
||||
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
if (sc_if->sk_cdata.sk_jumbo_buf)
|
||||
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
|
||||
if (sc_if->sk_rdata) {
|
||||
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
|
||||
M_DEVBUF);
|
||||
}
|
||||
SK_IF_UNLOCK(sc_if);
|
||||
|
||||
return(0);
|
||||
@ -1412,17 +1405,23 @@ sk_detach(dev)
|
||||
struct sk_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->sk_mtx), "sk mutex not initialized");
|
||||
SK_LOCK(sc);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (sc->sk_devs[SK_PORT_A] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
|
||||
if (sc->sk_devs[SK_PORT_B] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
|
||||
if (device_is_alive(dev)) {
|
||||
if (sc->sk_devs[SK_PORT_A] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
|
||||
if (sc->sk_devs[SK_PORT_B] != NULL)
|
||||
device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
if (sc->sk_intrhand)
|
||||
bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
|
||||
if (sc->sk_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
|
||||
if (sc->sk_res)
|
||||
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
|
||||
|
||||
SK_UNLOCK(sc);
|
||||
mtx_destroy(&sc->sk_mtx);
|
||||
|
@ -918,7 +918,6 @@ ste_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct ste_softc));
|
||||
sc->ste_dev = dev;
|
||||
|
||||
/*
|
||||
@ -933,7 +932,6 @@ ste_attach(dev)
|
||||
|
||||
mtx_init(&sc->ste_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
STE_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -993,27 +991,17 @@ ste_attach(dev)
|
||||
sc->ste_btag = rman_get_bustag(sc->ste_res);
|
||||
sc->ste_bhandle = rman_get_bushandle(sc->ste_res);
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->ste_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->ste_irq == NULL) {
|
||||
printf("ste%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->ste_irq, INTR_TYPE_NET,
|
||||
ste_intr, sc, &sc->ste_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
printf("ste%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->ste_stat_ch);
|
||||
|
||||
/* Reset the adapter. */
|
||||
@ -1025,9 +1013,6 @@ ste_attach(dev)
|
||||
if (ste_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
|
||||
STE_EEADDR_NODE0, 3, 0)) {
|
||||
printf("ste%d: failed to read station address\n", unit);
|
||||
bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
error = ENXIO;;
|
||||
goto fail;
|
||||
}
|
||||
@ -1046,9 +1031,6 @@ ste_attach(dev)
|
||||
|
||||
if (sc->ste_ldata == NULL) {
|
||||
printf("ste%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1057,13 +1039,8 @@ ste_attach(dev)
|
||||
|
||||
/* Do MII setup. */
|
||||
if (mii_phy_probe(dev, &sc->ste_miibus,
|
||||
ste_ifmedia_upd, ste_ifmedia_sts)) {
|
||||
ste_ifmedia_upd, ste_ifmedia_sts)) {
|
||||
printf("ste%d: MII without any phy!\n", sc->ste_unit);
|
||||
bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
contigfree(sc->ste_ldata,
|
||||
sizeof(struct ste_list_data), M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -1095,12 +1072,18 @@ ste_attach(dev)
|
||||
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
|
||||
ifp->if_capabilities |= IFCAP_VLAN_MTU;
|
||||
|
||||
STE_UNLOCK(sc);
|
||||
return(0);
|
||||
error = bus_setup_intr(dev, sc->ste_irq, INTR_TYPE_NET,
|
||||
ste_intr, sc, &sc->ste_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("ste%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
STE_UNLOCK(sc);
|
||||
mtx_destroy(&sc->ste_mtx);
|
||||
if (error)
|
||||
ste_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1112,20 +1095,29 @@ ste_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->ste_mtx), "ste mutex not initialized");
|
||||
STE_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ste_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
ste_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->ste_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->ste_miibus);
|
||||
if (sc->ste_intrhand)
|
||||
bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
|
||||
if (sc->ste_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
if (sc->ste_res)
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
|
||||
bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
|
||||
|
||||
contigfree(sc->ste_ldata, sizeof(struct ste_list_data), M_DEVBUF);
|
||||
if (sc->ste_ldata) {
|
||||
contigfree(sc->ste_ldata, sizeof(struct ste_list_data),
|
||||
M_DEVBUF);
|
||||
}
|
||||
|
||||
STE_UNLOCK(sc);
|
||||
mtx_destroy(&sc->ste_mtx);
|
||||
|
@ -2115,7 +2115,6 @@ ti_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct ti_softc));
|
||||
|
||||
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
@ -2161,25 +2160,10 @@ ti_attach(dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
|
||||
ti_intr, sc, &sc->ti_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
printf("ti%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->ti_unit = unit;
|
||||
|
||||
if (ti_chipinit(sc)) {
|
||||
printf("ti%d: chip initialization failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2190,10 +2174,6 @@ ti_attach(dev)
|
||||
/* Init again -- zeroing memory may have clobbered some registers. */
|
||||
if (ti_chipinit(sc)) {
|
||||
printf("ti%d: chip initialization failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2208,10 +2188,6 @@ ti_attach(dev)
|
||||
if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
|
||||
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
|
||||
printf("ti%d: failed to read station address\n", unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -2227,12 +2203,8 @@ ti_attach(dev)
|
||||
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
|
||||
|
||||
if (sc->ti_rdata == NULL) {
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
error = ENXIO;
|
||||
printf("ti%d: no memory for list buffers!\n", sc->ti_unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -2242,23 +2214,12 @@ ti_attach(dev)
|
||||
#ifdef TI_PRIVATE_JUMBOS
|
||||
if (ti_alloc_jumbo_mem(sc)) {
|
||||
printf("ti%d: jumbo buffer allocation failed\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data),
|
||||
M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!jumbo_vm_init()) {
|
||||
printf("ti%d: VM initialization failed!\n", sc->ti_unit);
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
TI_PCI_LOMEM, sc->ti_res);
|
||||
free(sc->ti_rdata, M_DEVBUF);
|
||||
error = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@ -2359,10 +2320,19 @@ ti_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
|
||||
ti_intr, sc, &sc->ti_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("ti%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
mtx_destroy(&sc->ti_mtx);
|
||||
if (sc && error)
|
||||
ti_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -2405,21 +2375,33 @@ ti_detach(dev)
|
||||
return EBUSY;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->ti_mtx), "ti mutex not initialized");
|
||||
TI_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
ti_stop(sc);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
ti_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
bus_generic_detach(dev);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM, sc->ti_res);
|
||||
if (sc->ti_intrhand)
|
||||
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
|
||||
if (sc->ti_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
|
||||
if (sc->ti_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM,
|
||||
sc->ti_res);
|
||||
}
|
||||
|
||||
#ifdef TI_PRIVATE_JUMBOS
|
||||
contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
|
||||
if (sc->ti_cdata.ti_jumbo_buf)
|
||||
contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
|
||||
#endif
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
if (sc->ti_rdata)
|
||||
contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
|
||||
|
||||
TI_UNLOCK(sc);
|
||||
mtx_destroy(&sc->ti_mtx);
|
||||
|
@ -1127,7 +1127,6 @@ tl_attach(dev)
|
||||
did = pci_get_device(dev);
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct tl_softc));
|
||||
|
||||
t = tl_devs;
|
||||
while(t->tl_name != NULL) {
|
||||
@ -1138,12 +1137,12 @@ tl_attach(dev)
|
||||
|
||||
if (t->tl_name == NULL) {
|
||||
device_printf(dev, "unknown device!?\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mtx_init(&sc->tl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
TL_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Map control/status registers.
|
||||
@ -1217,22 +1216,11 @@ tl_attach(dev)
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->tl_irq == NULL) {
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
device_printf(dev, "couldn't map interrupt\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET,
|
||||
tl_intr, sc, &sc->tl_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
device_printf(dev, "couldn't set up irq\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate memory for the TX and RX lists.
|
||||
*/
|
||||
@ -1240,9 +1228,6 @@ tl_attach(dev)
|
||||
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
|
||||
|
||||
if (sc->tl_ldata == NULL) {
|
||||
bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
device_printf(dev, "no memory for list buffers!\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
@ -1266,11 +1251,6 @@ tl_attach(dev)
|
||||
*/
|
||||
if (tl_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
|
||||
sc->tl_eeaddr, ETHER_ADDR_LEN)) {
|
||||
bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
contigfree(sc->tl_ldata,
|
||||
sizeof(struct tl_list_data), M_DEVBUF);
|
||||
device_printf(dev, "failed to read station address\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
@ -1349,12 +1329,19 @@ tl_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
|
||||
TL_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET,
|
||||
tl_intr, sc, &sc->tl_intrhand);
|
||||
|
||||
if (error) {
|
||||
device_printf(dev, "couldn't set up irq\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
TL_UNLOCK(sc);
|
||||
mtx_destroy(&sc->tl_mtx);
|
||||
if (error)
|
||||
tl_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1366,22 +1353,29 @@ tl_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->tl_mtx), "tl mutex not initialized");
|
||||
TL_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
tl_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
tl_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->tl_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->tl_miibus);
|
||||
|
||||
contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF);
|
||||
if (sc->tl_ldata)
|
||||
contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF);
|
||||
if (sc->tl_bitrate)
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
|
||||
bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
if (sc->tl_intrhand)
|
||||
bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
|
||||
if (sc->tl_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
|
||||
if (sc->tl_res)
|
||||
bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
|
||||
|
||||
TL_UNLOCK(sc);
|
||||
mtx_destroy(&sc->tl_mtx);
|
||||
|
@ -744,11 +744,9 @@ vr_attach(dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
bzero(sc, sizeof(struct vr_softc *));
|
||||
|
||||
mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
VR_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -785,12 +783,13 @@ vr_attach(dev)
|
||||
#ifdef VR_USEIOSPACE
|
||||
if (!(command & PCIM_CMD_PORTEN)) {
|
||||
printf("vr%d: failed to enable I/O ports!\n", unit);
|
||||
free(sc, M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("vr%d: failed to enable memory mapping!\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
@ -815,21 +814,10 @@ vr_attach(dev)
|
||||
|
||||
if (sc->vr_irq == NULL) {
|
||||
printf("vr%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
|
||||
vr_intr, sc, &sc->vr_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
printf("vr%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows may put the chip in suspend mode when it
|
||||
* shuts down. Be sure to kick it in the head to wake it
|
||||
@ -873,9 +861,6 @@ vr_attach(dev)
|
||||
|
||||
if (sc->vr_ldata == NULL) {
|
||||
printf("vr%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -902,11 +887,6 @@ vr_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->vr_miibus,
|
||||
vr_ifmedia_upd, vr_ifmedia_sts)) {
|
||||
printf("vr%d: MII without any phy!\n", sc->vr_unit);
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
contigfree(sc->vr_ldata,
|
||||
sizeof(struct vr_list_data), M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -917,12 +897,18 @@ vr_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
VR_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
|
||||
vr_intr, sc, &sc->vr_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("vr%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
VR_UNLOCK(sc);
|
||||
mtx_destroy(&sc->vr_mtx);
|
||||
if (error)
|
||||
vr_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
@ -935,20 +921,27 @@ vr_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->vr_mtx), "vr mutex not initialized");
|
||||
VR_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
vr_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
vr_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->vr_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->vr_miibus);
|
||||
if (sc->vr_intrhand)
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
if (sc->vr_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
if (sc->vr_res)
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
|
||||
bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
|
||||
bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
|
||||
|
||||
contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
|
||||
if (sc->vr_ldata)
|
||||
contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
|
||||
|
||||
VR_UNLOCK(sc);
|
||||
mtx_destroy(&sc->vr_mtx);
|
||||
|
@ -832,7 +832,6 @@ wb_attach(dev)
|
||||
|
||||
mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
WB_LOCK(sc);
|
||||
|
||||
/*
|
||||
* Handle power management nonsense.
|
||||
@ -900,21 +899,10 @@ wb_attach(dev)
|
||||
|
||||
if (sc->wb_irq == NULL) {
|
||||
printf("wb%d: couldn't map interrupt\n", unit);
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET,
|
||||
wb_intr, sc, &sc->wb_intrhand);
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
printf("wb%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Save the cache line size. */
|
||||
sc->wb_cachesize = pci_read_config(dev, WB_PCI_CACHELEN, 4) & 0xFF;
|
||||
|
||||
@ -939,9 +927,6 @@ wb_attach(dev)
|
||||
|
||||
if (sc->wb_ldata == NULL) {
|
||||
printf("wb%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -967,10 +952,6 @@ wb_attach(dev)
|
||||
*/
|
||||
if (mii_phy_probe(dev, &sc->wb_miibus,
|
||||
wb_ifmedia_upd, wb_ifmedia_sts)) {
|
||||
bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
free(sc->wb_ldata_ptr, M_DEVBUF);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -979,14 +960,18 @@ wb_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
WB_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET,
|
||||
wb_intr, sc, &sc->wb_intrhand);
|
||||
|
||||
if (error) {
|
||||
printf("wb%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (error)
|
||||
device_delete_child(dev, sc->wb_miibus);
|
||||
WB_UNLOCK(sc);
|
||||
mtx_destroy(&sc->wb_mtx);
|
||||
wb_detach(dev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
@ -999,21 +984,30 @@ wb_detach(dev)
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->wb_mtx), "wb mutex not initialized");
|
||||
WB_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
wb_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
|
||||
/* Delete any miibus and phy devices attached to this interface */
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->wb_miibus);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev))
|
||||
wb_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->wb_miibus);
|
||||
bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
if (sc->wb_intrhand)
|
||||
bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
|
||||
if (sc->wb_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
|
||||
if (sc->wb_res)
|
||||
bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
|
||||
|
||||
free(sc->wb_ldata_ptr, M_DEVBUF);
|
||||
if (sc->wb_ldata) {
|
||||
contigfree(sc->wb_ldata, sizeof(struct wb_list_data) + 8,
|
||||
M_DEVBUF);
|
||||
}
|
||||
|
||||
WB_UNLOCK(sc);
|
||||
mtx_destroy(&sc->wb_mtx);
|
||||
|
228
sys/pci/if_xl.c
228
sys/pci/if_xl.c
@ -1288,7 +1288,6 @@ xl_attach(dev)
|
||||
|
||||
mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
XL_LOCK(sc);
|
||||
|
||||
sc->xl_flags = 0;
|
||||
if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_555)
|
||||
@ -1375,6 +1374,7 @@ xl_attach(dev)
|
||||
|
||||
if (!(command & PCIM_CMD_PORTEN) && !(command & PCIM_CMD_MEMEN)) {
|
||||
printf("xl%d: failed to enable I/O ports and memory mappings!\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1395,6 +1395,7 @@ xl_attach(dev)
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
if (sc->xl_res == NULL) {
|
||||
printf ("xl%d: couldn't map ports/memory\n", unit);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
if (bootverbose)
|
||||
@ -1411,26 +1412,22 @@ xl_attach(dev)
|
||||
|
||||
if (sc->xl_fres == NULL) {
|
||||
printf ("xl%d: couldn't map ports/memory\n", unit);
|
||||
goto fail_res;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->xl_ftag = rman_get_bustag(sc->xl_fres);
|
||||
sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
|
||||
}
|
||||
|
||||
/* Allocate interrupt */
|
||||
rid = 0;
|
||||
sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->xl_irq == NULL) {
|
||||
printf("xl%d: couldn't map interrupt\n", unit);
|
||||
goto fail_fres;
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
|
||||
xl_intr, sc, &sc->xl_intrhand);
|
||||
if (error) {
|
||||
printf("xl%d: couldn't set up irq\n", unit);
|
||||
goto fail_irq;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
@ -1441,7 +1438,8 @@ xl_attach(dev)
|
||||
*/
|
||||
if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) {
|
||||
printf("xl%d: failed to read station address\n", sc->xl_unit);
|
||||
goto fail_irq_setup;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1454,7 +1452,9 @@ xl_attach(dev)
|
||||
bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
|
||||
|
||||
/*
|
||||
* Now allocate a tag for the DMA descriptor lists.
|
||||
* Now allocate a tag for the DMA descriptor lists and a chunk
|
||||
* of DMA-able memory based on the tag. Also obtain the DMA
|
||||
* addresses of the RX and TX ring, which we'll need later.
|
||||
* All of our lists are allocated as a contiguous block
|
||||
* of memory.
|
||||
*/
|
||||
@ -1463,8 +1463,31 @@ xl_attach(dev)
|
||||
XL_RX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
|
||||
&sc->xl_ldata.xl_rx_tag);
|
||||
if (error) {
|
||||
printf("xl%d: failed to allocate dma tag\n", unit);
|
||||
goto fail_irq_setup;
|
||||
printf("xl%d: failed to allocate rx dma tag\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
|
||||
(void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
|
||||
&sc->xl_ldata.xl_rx_dmamap);
|
||||
if (error) {
|
||||
printf("xl%d: no memory for rx list buffers!\n", unit);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
|
||||
sc->xl_ldata.xl_rx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
|
||||
sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
|
||||
XL_RX_LIST_SZ, xl_dma_map_addr,
|
||||
&sc->xl_ldata.xl_rx_dmaaddr, 0);
|
||||
if (error) {
|
||||
printf("xl%d: cannot get dma address of the rx ring!\n", unit);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
|
||||
sc->xl_ldata.xl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
|
||||
sc->xl_ldata.xl_rx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dma_tag_create(NULL, 8, 0,
|
||||
@ -1472,8 +1495,31 @@ xl_attach(dev)
|
||||
XL_TX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
|
||||
&sc->xl_ldata.xl_tx_tag);
|
||||
if (error) {
|
||||
printf("xl%d: failed to allocate dma tag\n", unit);
|
||||
goto fail_rxtag;
|
||||
printf("xl%d: failed to allocate tx dma tag\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
|
||||
(void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT,
|
||||
&sc->xl_ldata.xl_tx_dmamap);
|
||||
if (error) {
|
||||
printf("xl%d: no memory for list buffers!\n", unit);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
|
||||
sc->xl_ldata.xl_tx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
|
||||
sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
|
||||
XL_TX_LIST_SZ, xl_dma_map_addr,
|
||||
&sc->xl_ldata.xl_tx_dmaaddr, 0);
|
||||
if (error) {
|
||||
printf("xl%d: cannot get dma address of the tx ring!\n", unit);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
|
||||
sc->xl_ldata.xl_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
|
||||
sc->xl_ldata.xl_tx_tag = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1483,58 +1529,17 @@ xl_attach(dev)
|
||||
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
|
||||
XL_MAXFRAGS, BUS_SPACE_MAXSIZE_32BIT, 0, &sc->xl_mtag);
|
||||
if (error) {
|
||||
printf("xl%d: failed to allocate dma tag\n", unit);
|
||||
goto fail_txtag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate a chunk of DMA-able memory based on the
|
||||
* tag we just created.
|
||||
*/
|
||||
error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
|
||||
(void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT,
|
||||
&sc->xl_ldata.xl_tx_dmamap);
|
||||
if (error) {
|
||||
printf("xl%d: no memory for list buffers!\n", unit);
|
||||
goto fail_mtag;
|
||||
}
|
||||
|
||||
error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
|
||||
(void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
|
||||
&sc->xl_ldata.xl_rx_dmamap);
|
||||
if (error) {
|
||||
printf("xl%d: no memory for list buffers!\n", unit);
|
||||
goto fail_txmem;
|
||||
printf("xl%d: failed to allocate mbuf dma tag\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
|
||||
bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
|
||||
|
||||
/*
|
||||
* Obtain the DMA address of the RX and TX ring which we'll need later.
|
||||
*/
|
||||
error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
|
||||
sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
|
||||
XL_TX_LIST_SZ, xl_dma_map_addr,
|
||||
&sc->xl_ldata.xl_tx_dmaaddr, 0);
|
||||
if (error) {
|
||||
printf("xl%d: cannot get dma address of the tx ring!\n", unit);
|
||||
goto fail_rxmem;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
|
||||
sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
|
||||
XL_RX_LIST_SZ, xl_dma_map_addr,
|
||||
&sc->xl_ldata.xl_rx_dmaaddr, 0);
|
||||
if (error) {
|
||||
printf("xl%d: cannot get dma address of the rx ring!\n", unit);
|
||||
goto fail_txmap;
|
||||
}
|
||||
|
||||
/* We need a spare DMA map for the RX ring. */
|
||||
error = bus_dmamap_create(sc->xl_mtag, 0, &sc->xl_tmpmap);
|
||||
if (error)
|
||||
return(error);
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Figure out the card type. 3c905B adapters have the
|
||||
@ -1593,7 +1598,8 @@ xl_attach(dev)
|
||||
if (mii_phy_probe(dev, &sc->xl_miibus,
|
||||
xl_ifmedia_upd, xl_ifmedia_sts)) {
|
||||
printf("xl%d: no PHY found!\n", sc->xl_unit);
|
||||
goto fail_rxmap;
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
goto done;
|
||||
@ -1710,48 +1716,19 @@ xl_attach(dev)
|
||||
* Call MI attach routine.
|
||||
*/
|
||||
ether_ifattach(ifp, eaddr);
|
||||
XL_UNLOCK(sc);
|
||||
return(0);
|
||||
|
||||
fail_rxmap:
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
|
||||
fail_txmap:
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
|
||||
fail_rxmem:
|
||||
bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
|
||||
sc->xl_ldata.xl_rx_dmamap);
|
||||
fail_txmem:
|
||||
bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
|
||||
sc->xl_ldata.xl_tx_dmamap);
|
||||
fail_mtag:
|
||||
bus_dma_tag_destroy(sc->xl_mtag);
|
||||
fail_txtag:
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
|
||||
fail_rxtag:
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
|
||||
fail_irq_setup:
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
fail_irq:
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
fail_fres:
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, XL_PCI_FUNCMEM,
|
||||
sc->xl_fres);
|
||||
fail_res:
|
||||
if (sc->xl_flags & XL_FLAG_USE_MMIO) {
|
||||
rid = XL_PCI_LOMEM;
|
||||
res = SYS_RES_MEMORY;
|
||||
} else {
|
||||
rid = XL_PCI_LOIO;
|
||||
res = SYS_RES_IOPORT;
|
||||
error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
|
||||
xl_intr, sc, &sc->xl_intrhand);
|
||||
if (error) {
|
||||
printf("xl%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bus_release_resource(dev, res, rid, sc->xl_res);
|
||||
fail:
|
||||
XL_UNLOCK(sc);
|
||||
mtx_destroy(&sc->xl_mtx);
|
||||
if (error)
|
||||
xl_detach(dev);
|
||||
|
||||
return(ENXIO);
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1763,6 +1740,7 @@ xl_detach(dev)
|
||||
int rid, res;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->xl_mtx), "xl mutex not initialized");
|
||||
XL_LOCK(sc);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
@ -1774,33 +1752,45 @@ xl_detach(dev)
|
||||
res = SYS_RES_IOPORT;
|
||||
}
|
||||
|
||||
xl_reset(sc);
|
||||
xl_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
|
||||
/* Delete any miibus and phy devices attached to this interface */
|
||||
if (sc->xl_miibus != NULL) {
|
||||
bus_generic_detach(dev);
|
||||
if (device_is_alive(dev)) {
|
||||
if (bus_child_present(dev)) {
|
||||
xl_reset(sc);
|
||||
xl_stop(sc);
|
||||
}
|
||||
ether_ifdetach(ifp);
|
||||
device_delete_child(dev, sc->xl_miibus);
|
||||
bus_generic_detach(dev);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
}
|
||||
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_intrhand)
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
if (sc->xl_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, res, rid, sc->xl_res);
|
||||
bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
|
||||
sc->xl_ldata.xl_rx_dmamap);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
|
||||
sc->xl_ldata.xl_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
|
||||
bus_dma_tag_destroy(sc->xl_mtag);
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
if (sc->xl_res)
|
||||
bus_release_resource(dev, res, rid, sc->xl_res);
|
||||
|
||||
if (sc->xl_mtag) {
|
||||
bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
|
||||
bus_dma_tag_destroy(sc->xl_mtag);
|
||||
}
|
||||
if (sc->xl_ldata.xl_rx_tag) {
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_rx_tag,
|
||||
sc->xl_ldata.xl_rx_dmamap);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
|
||||
sc->xl_ldata.xl_rx_dmamap);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
|
||||
}
|
||||
if (sc->xl_ldata.xl_tx_tag) {
|
||||
bus_dmamap_unload(sc->xl_ldata.xl_tx_tag,
|
||||
sc->xl_ldata.xl_tx_dmamap);
|
||||
bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
|
||||
sc->xl_ldata.xl_tx_dmamap);
|
||||
bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
|
||||
}
|
||||
|
||||
XL_UNLOCK(sc);
|
||||
mtx_destroy(&sc->xl_mtx);
|
||||
|
Loading…
Reference in New Issue
Block a user