if_tl.c (111119) | if_tl.c (112872) |
---|---|
1/* 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * | 1/* 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * |
32 * $FreeBSD: head/sys/pci/if_tl.c 111119 2003-02-19 05:47:46Z imp $ | 32 * $FreeBSD: head/sys/pci/if_tl.c 112872 2003-03-31 17:29:43Z njl $ |
33 */ 34 35/* 36 * Texas Instruments ThunderLAN driver for FreeBSD 2.2.6 and 3.x. 37 * Supports many Compaq PCI NICs based on the ThunderLAN ethernet controller, 38 * the National Semiconductor DP83840A physical interface and the 39 * Microchip Technology 24Cxx series serial EEPROM. 40 * --- 179 unchanged lines hidden (view full) --- 220 221MODULE_DEPEND(tl, miibus, 1, 1, 1); 222 223/* "controller miibus0" required. See GENERIC if you get errors here. */ 224#include "miibus_if.h" 225 226#if !defined(lint) 227static const char rcsid[] = | 33 */ 34 35/* 36 * Texas Instruments ThunderLAN driver for FreeBSD 2.2.6 and 3.x. 37 * Supports many Compaq PCI NICs based on the ThunderLAN ethernet controller, 38 * the National Semiconductor DP83840A physical interface and the 39 * Microchip Technology 24Cxx series serial EEPROM. 40 * --- 179 unchanged lines hidden (view full) --- 220 221MODULE_DEPEND(tl, miibus, 1, 1, 1); 222 223/* "controller miibus0" required. See GENERIC if you get errors here. */ 224#include "miibus_if.h" 225 226#if !defined(lint) 227static const char rcsid[] = |
228 "$FreeBSD: head/sys/pci/if_tl.c 111119 2003-02-19 05:47:46Z imp $"; | 228 "$FreeBSD: head/sys/pci/if_tl.c 112872 2003-03-31 17:29:43Z njl $"; |
229#endif 230 231/* 232 * Various supported device vendors/types and their names. 233 */ 234 235static struct tl_type tl_devs[] = { 236 { TI_VENDORID, TI_DEVICEID_THUNDERLAN, --- 885 unchanged lines hidden (view full) --- 1122 struct ifnet *ifp; 1123 struct tl_softc *sc; 1124 int unit, error = 0, rid; 1125 1126 vid = pci_get_vendor(dev); 1127 did = pci_get_device(dev); 1128 sc = device_get_softc(dev); 1129 unit = device_get_unit(dev); | 229#endif 230 231/* 232 * Various supported device vendors/types and their names. 233 */ 234 235static struct tl_type tl_devs[] = { 236 { TI_VENDORID, TI_DEVICEID_THUNDERLAN, --- 885 unchanged lines hidden (view full) --- 1122 struct ifnet *ifp; 1123 struct tl_softc *sc; 1124 int unit, error = 0, rid; 1125 1126 vid = pci_get_vendor(dev); 1127 did = pci_get_device(dev); 1128 sc = device_get_softc(dev); 1129 unit = device_get_unit(dev); |
1130 bzero(sc, sizeof(struct tl_softc)); | |
1131 1132 t = tl_devs; 1133 while(t->tl_name != NULL) { 1134 if (vid == t->tl_vid && did == t->tl_did) 1135 break; 1136 t++; 1137 } 1138 1139 if (t->tl_name == NULL) { 1140 device_printf(dev, "unknown device!?\n"); | 1130 1131 t = tl_devs; 1132 while(t->tl_name != NULL) { 1133 if (vid == t->tl_vid && did == t->tl_did) 1134 break; 1135 t++; 1136 } 1137 1138 if (t->tl_name == NULL) { 1139 device_printf(dev, "unknown device!?\n"); |
1140 error = ENXIO; |
|
1141 goto fail; 1142 } 1143 1144 mtx_init(&sc->tl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 1145 MTX_DEF | MTX_RECURSE); | 1141 goto fail; 1142 } 1143 1144 mtx_init(&sc->tl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 1145 MTX_DEF | MTX_RECURSE); |
1146 TL_LOCK(sc); | |
1147 1148 /* 1149 * Map control/status registers. 1150 */ 1151 pci_enable_busmaster(dev); 1152 pci_enable_io(dev, SYS_RES_IOPORT); 1153 pci_enable_io(dev, SYS_RES_MEMORY); 1154 command = pci_read_config(dev, PCIR_COMMAND, 4); --- 57 unchanged lines hidden (view full) --- 1212#endif 1213 1214 /* Allocate interrupt */ 1215 rid = 0; 1216 sc->tl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 1217 RF_SHAREABLE | RF_ACTIVE); 1218 1219 if (sc->tl_irq == NULL) { | 1146 1147 /* 1148 * Map control/status registers. 1149 */ 1150 pci_enable_busmaster(dev); 1151 pci_enable_io(dev, SYS_RES_IOPORT); 1152 pci_enable_io(dev, SYS_RES_MEMORY); 1153 command = pci_read_config(dev, PCIR_COMMAND, 4); --- 57 unchanged lines hidden (view full) --- 1211#endif 1212 1213 /* Allocate interrupt */ 1214 rid = 0; 1215 sc->tl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 1216 RF_SHAREABLE | RF_ACTIVE); 1217 1218 if (sc->tl_irq == NULL) { |
1220 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); | |
1221 device_printf(dev, "couldn't map interrupt\n"); 1222 error = ENXIO; 1223 goto fail; 1224 } 1225 | 1219 device_printf(dev, "couldn't map interrupt\n"); 1220 error = ENXIO; 1221 goto fail; 1222 } 1223 |
1226 error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET, 1227 tl_intr, sc, &sc->tl_intrhand); 1228 1229 if (error) { 1230 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); 1231 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); 1232 device_printf(dev, "couldn't set up irq\n"); 1233 goto fail; 1234 } 1235 | |
1236 /* 1237 * Now allocate memory for the TX and RX lists. 1238 */ 1239 sc->tl_ldata = contigmalloc(sizeof(struct tl_list_data), M_DEVBUF, 1240 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 1241 1242 if (sc->tl_ldata == NULL) { | 1224 /* 1225 * Now allocate memory for the TX and RX lists. 1226 */ 1227 sc->tl_ldata = contigmalloc(sizeof(struct tl_list_data), M_DEVBUF, 1228 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 1229 1230 if (sc->tl_ldata == NULL) { |
1243 bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand); 1244 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); 1245 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); | |
1246 device_printf(dev, "no memory for list buffers!\n"); 1247 error = ENXIO; 1248 goto fail; 1249 } 1250 1251 bzero(sc->tl_ldata, sizeof(struct tl_list_data)); 1252 1253 sc->tl_dinfo = t; --- 7 unchanged lines hidden (view full) --- 1261 tl_hardreset(dev); 1262 tl_softreset(sc, 1); 1263 1264 /* 1265 * Get station address from the EEPROM. 1266 */ 1267 if (tl_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, 1268 sc->tl_eeaddr, ETHER_ADDR_LEN)) { | 1231 device_printf(dev, "no memory for list buffers!\n"); 1232 error = ENXIO; 1233 goto fail; 1234 } 1235 1236 bzero(sc->tl_ldata, sizeof(struct tl_list_data)); 1237 1238 sc->tl_dinfo = t; --- 7 unchanged lines hidden (view full) --- 1246 tl_hardreset(dev); 1247 tl_softreset(sc, 1); 1248 1249 /* 1250 * Get station address from the EEPROM. 1251 */ 1252 if (tl_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, 1253 sc->tl_eeaddr, ETHER_ADDR_LEN)) { |
1269 bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand); 1270 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); 1271 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); 1272 contigfree(sc->tl_ldata, 1273 sizeof(struct tl_list_data), M_DEVBUF); | |
1274 device_printf(dev, "failed to read station address\n"); 1275 error = ENXIO; 1276 goto fail; 1277 } 1278 1279 /* 1280 * XXX Olicom, in its desire to be different from the 1281 * rest of the world, has done strange things with the --- 62 unchanged lines hidden (view full) --- 1344 ifm->ifm_media = ifm->ifm_cur->ifm_media; 1345 tl_ifmedia_upd(ifp); 1346 } 1347 1348 /* 1349 * Call MI attach routine. 1350 */ 1351 ether_ifattach(ifp, sc->arpcom.ac_enaddr); | 1254 device_printf(dev, "failed to read station address\n"); 1255 error = ENXIO; 1256 goto fail; 1257 } 1258 1259 /* 1260 * XXX Olicom, in its desire to be different from the 1261 * rest of the world, has done strange things with the --- 62 unchanged lines hidden (view full) --- 1324 ifm->ifm_media = ifm->ifm_cur->ifm_media; 1325 tl_ifmedia_upd(ifp); 1326 } 1327 1328 /* 1329 * Call MI attach routine. 1330 */ 1331 ether_ifattach(ifp, sc->arpcom.ac_enaddr); |
1352 TL_UNLOCK(sc); 1353 return(0); | |
1354 | 1332 |
1333 error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET, 1334 tl_intr, sc, &sc->tl_intrhand); 1335 1336 if (error) { 1337 device_printf(dev, "couldn't set up irq\n"); 1338 goto fail; 1339 } 1340 |
|
1355fail: | 1341fail: |
1356 TL_UNLOCK(sc); 1357 mtx_destroy(&sc->tl_mtx); | 1342 if (error) 1343 tl_detach(dev); 1344 |
1358 return(error); 1359} 1360 1361static int 1362tl_detach(dev) 1363 device_t dev; 1364{ 1365 struct tl_softc *sc; 1366 struct ifnet *ifp; 1367 1368 sc = device_get_softc(dev); | 1345 return(error); 1346} 1347 1348static int 1349tl_detach(dev) 1350 device_t dev; 1351{ 1352 struct tl_softc *sc; 1353 struct ifnet *ifp; 1354 1355 sc = device_get_softc(dev); |
1356 KASSERT(mtx_initialized(&sc->tl_mtx), "tl mutex not initialized"); |
|
1369 TL_LOCK(sc); 1370 ifp = &sc->arpcom.ac_if; 1371 | 1357 TL_LOCK(sc); 1358 ifp = &sc->arpcom.ac_if; 1359 |
1372 tl_stop(sc); 1373 ether_ifdetach(ifp); | 1360 if (device_is_alive(dev)) { 1361 if (bus_child_present(dev)) 1362 tl_stop(sc); 1363 ether_ifdetach(ifp); 1364 device_delete_child(dev, sc->tl_miibus); 1365 bus_generic_detach(dev); 1366 } |
1374 | 1367 |
1375 bus_generic_detach(dev); 1376 device_delete_child(dev, sc->tl_miibus); 1377 1378 contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF); | 1368 if (sc->tl_ldata) 1369 contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF); |
1379 if (sc->tl_bitrate) 1380 ifmedia_removeall(&sc->ifmedia); 1381 | 1370 if (sc->tl_bitrate) 1371 ifmedia_removeall(&sc->ifmedia); 1372 |
1382 bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand); 1383 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); 1384 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); | 1373 if (sc->tl_intrhand) 1374 bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand); 1375 if (sc->tl_irq) 1376 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); 1377 if (sc->tl_res) 1378 bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); |
1385 1386 TL_UNLOCK(sc); 1387 mtx_destroy(&sc->tl_mtx); 1388 1389 return(0); 1390} 1391 1392/* --- 973 unchanged lines hidden --- | 1379 1380 TL_UNLOCK(sc); 1381 mtx_destroy(&sc->tl_mtx); 1382 1383 return(0); 1384} 1385 1386/* --- 973 unchanged lines hidden --- |