1/* $NetBSD: if_en_pci.c,v 1.1 1996/06/22 02:00:31 chuck Exp $ */ 2/*- 3 * Copyright (c) 1996 Charles D. Cranor and Washington University. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles D. Cranor and 17 * Washington University. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34#include <sys/cdefs.h>
| 1/* $NetBSD: if_en_pci.c,v 1.1 1996/06/22 02:00:31 chuck Exp $ */ 2/*- 3 * Copyright (c) 1996 Charles D. Cranor and Washington University. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles D. Cranor and 17 * Washington University. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34#include <sys/cdefs.h>
|
217 218 /* 219 * Map control/status registers. 220 */ 221 rid = PCI_CBMA; 222 scp->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 223 RF_ACTIVE); 224 if (scp->res == NULL) { 225 device_printf(dev, "could not map memory\n"); 226 if_free(sc->ifp); 227 error = ENXIO; 228 goto fail; 229 } 230 231 sc->dev = dev; 232 sc->en_memt = rman_get_bustag(scp->res); 233 sc->en_base = rman_get_bushandle(scp->res); 234 235 /* 236 * Allocate our interrupt. 237 */ 238 rid = 0; 239 scp->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 240 RF_SHAREABLE | RF_ACTIVE); 241 if (scp->irq == NULL) { 242 device_printf(dev, "could not map interrupt\n"); 243 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 244 if_free(sc->ifp); 245 error = ENXIO; 246 goto fail; 247 } 248 249 sc->ipl = 1; /* XXX (required to enable interrupt on midway) */ 250 251 /* figure out if we are an adaptec card or not */ 252 sc->is_adaptec = (pci_get_vendor(dev) == PCI_VENDOR_ADP) ? 1 : 0; 253 254 /* 255 * set up pci bridge 256 */ 257 if (sc->is_adaptec) { 258 adp_get_macaddr(scp); 259 sc->en_busreset = adp_busreset; 260 adp_busreset(sc); 261 } else { 262 eni_get_macaddr(dev, scp); 263 sc->en_busreset = NULL; 264 pci_write_config(dev, EN_TONGA, TONGA_SWAP_DMA | TONGA_READ_IVAN, 4); 265 } 266 267 /* 268 * Common attach stuff 269 */ 270 if ((error = en_attach(sc)) != 0) { 271 device_printf(dev, "attach failed\n"); 272 bus_teardown_intr(dev, scp->irq, scp->ih); 273 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 274 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 275 if_free(sc->ifp); 276 goto fail; 277 } 278 279 /* 280 * Do the interrupt SETUP last just before returning 281 */ 282 error = bus_setup_intr(dev, scp->irq, INTR_TYPE_NET, 283 en_intr, sc, &scp->ih); 284 if (error) { 285 en_reset(sc); 286 atm_ifdetach(sc->ifp);
| 214 215 /* 216 * Map control/status registers. 217 */ 218 rid = PCI_CBMA; 219 scp->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 220 RF_ACTIVE); 221 if (scp->res == NULL) { 222 device_printf(dev, "could not map memory\n"); 223 if_free(sc->ifp); 224 error = ENXIO; 225 goto fail; 226 } 227 228 sc->dev = dev; 229 sc->en_memt = rman_get_bustag(scp->res); 230 sc->en_base = rman_get_bushandle(scp->res); 231 232 /* 233 * Allocate our interrupt. 234 */ 235 rid = 0; 236 scp->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 237 RF_SHAREABLE | RF_ACTIVE); 238 if (scp->irq == NULL) { 239 device_printf(dev, "could not map interrupt\n"); 240 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 241 if_free(sc->ifp); 242 error = ENXIO; 243 goto fail; 244 } 245 246 sc->ipl = 1; /* XXX (required to enable interrupt on midway) */ 247 248 /* figure out if we are an adaptec card or not */ 249 sc->is_adaptec = (pci_get_vendor(dev) == PCI_VENDOR_ADP) ? 1 : 0; 250 251 /* 252 * set up pci bridge 253 */ 254 if (sc->is_adaptec) { 255 adp_get_macaddr(scp); 256 sc->en_busreset = adp_busreset; 257 adp_busreset(sc); 258 } else { 259 eni_get_macaddr(dev, scp); 260 sc->en_busreset = NULL; 261 pci_write_config(dev, EN_TONGA, TONGA_SWAP_DMA | TONGA_READ_IVAN, 4); 262 } 263 264 /* 265 * Common attach stuff 266 */ 267 if ((error = en_attach(sc)) != 0) { 268 device_printf(dev, "attach failed\n"); 269 bus_teardown_intr(dev, scp->irq, scp->ih); 270 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 271 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 272 if_free(sc->ifp); 273 goto fail; 274 } 275 276 /* 277 * Do the interrupt SETUP last just before returning 278 */ 279 error = bus_setup_intr(dev, scp->irq, INTR_TYPE_NET, 280 en_intr, sc, &scp->ih); 281 if (error) { 282 en_reset(sc); 283 atm_ifdetach(sc->ifp);
|
288 device_printf(dev, "could not setup irq\n"); 289 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 290 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 291 en_destroy(sc); 292 if_free(sc->ifp); 293 goto fail; 294 } 295 296 return (0); 297 298 fail: 299 return (error); 300} 301 302/* 303 * Detach the adapter 304 */ 305static int 306en_pci_detach(device_t dev) 307{ 308 struct en_softc *sc = device_get_softc(dev); 309 struct en_pci_softc *scp = (struct en_pci_softc *)sc; 310 311 /* 312 * Stop DMA and drop transmit queue. 313 */ 314 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) { 315 if_printf(sc->ifp, "still running\n"); 316 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 317 } 318 319 /* 320 * Close down routes etc. 321 */ 322 en_reset(sc); 323 atm_ifdetach(sc->ifp); 324 325 /* 326 * Deallocate resources. 327 */ 328 bus_teardown_intr(dev, scp->irq, scp->ih); 329 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 330 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 331 332 /* 333 * Free all the driver internal resources 334 */ 335 en_destroy(sc); 336 if_free(sc->ifp); 337 338 return (0); 339} 340 341static int 342en_pci_shutdown(device_t dev) 343{ 344 struct en_pci_softc *psc = device_get_softc(dev); 345 346 en_reset(&psc->esc); 347 DELAY(10); /* is this necessary? */ 348 349 return (0); 350} 351 352/* 353 * Get the MAC address from an Adaptec board. No idea how to get 354 * serial number or other stuff, because I have no documentation for that 355 * card. 356 */ 357static void 358adp_get_macaddr(struct en_pci_softc *scp) 359{ 360 struct en_softc * sc = (struct en_softc *)scp; 361 int lcv; 362 363 for (lcv = 0; lcv < sizeof(IFP2IFATM(sc->ifp)->mib.esi); lcv++) 364 IFP2IFATM(sc->ifp)->mib.esi[lcv] = bus_space_read_1(sc->en_memt, 365 sc->en_base, MID_ADPMACOFF + lcv); 366} 367 368/* 369 * Read station (MAC) address from serial EEPROM. 370 * derived from linux drivers/atm/eni.c by Werner Almesberger, EPFL LRC. 371 */ 372#define EN_PROM_MAGIC 0x0c 373#define EN_PROM_DATA 0x02 374#define EN_PROM_CLK 0x01 375#define EN_ESI 64 376#define EN_SERIAL 112 377 378/* 379 * Read a byte from the given address in the EEPROM 380 */ 381static uint8_t 382eni_get_byte(device_t dev, uint32_t *data, u_int address) 383{ 384 int j; 385 uint8_t tmp; 386 387 address = (address << 1) + 1; 388 389 /* start operation */ 390 *data |= EN_PROM_DATA ; 391 pci_write_config(dev, EN_TONGA, *data, 4); 392 *data |= EN_PROM_CLK ; 393 pci_write_config(dev, EN_TONGA, *data, 4); 394 *data &= ~EN_PROM_DATA ; 395 pci_write_config(dev, EN_TONGA, *data, 4); 396 *data &= ~EN_PROM_CLK ; 397 pci_write_config(dev, EN_TONGA, *data, 4); 398 /* send address with serial line */ 399 for ( j = 7 ; j >= 0 ; j --) { 400 *data = ((address >> j) & 1) ? (*data | EN_PROM_DATA) : 401 (*data & ~EN_PROM_DATA); 402 pci_write_config(dev, EN_TONGA, *data, 4); 403 *data |= EN_PROM_CLK ; 404 pci_write_config(dev, EN_TONGA, *data, 4); 405 *data &= ~EN_PROM_CLK ; 406 pci_write_config(dev, EN_TONGA, *data, 4); 407 } 408 /* get ack */ 409 *data |= EN_PROM_DATA ; 410 pci_write_config(dev, EN_TONGA, *data, 4); 411 *data |= EN_PROM_CLK ; 412 pci_write_config(dev, EN_TONGA, *data, 4); 413 *data = pci_read_config(dev, EN_TONGA, 4); 414 *data &= ~EN_PROM_CLK ; 415 pci_write_config(dev, EN_TONGA, *data, 4); 416 *data |= EN_PROM_DATA ; 417 pci_write_config(dev, EN_TONGA, *data, 4); 418 419 tmp = 0; 420 421 for ( j = 7 ; j >= 0 ; j --) { 422 tmp <<= 1; 423 *data |= EN_PROM_DATA ; 424 pci_write_config(dev, EN_TONGA, *data, 4); 425 *data |= EN_PROM_CLK ; 426 pci_write_config(dev, EN_TONGA, *data, 4); 427 *data = pci_read_config(dev, EN_TONGA, 4); 428 if(*data & EN_PROM_DATA) tmp |= 1; 429 *data &= ~EN_PROM_CLK ; 430 pci_write_config(dev, EN_TONGA, *data, 4); 431 *data |= EN_PROM_DATA ; 432 pci_write_config(dev, EN_TONGA, *data, 4); 433 } 434 /* get ack */ 435 *data |= EN_PROM_DATA ; 436 pci_write_config(dev, EN_TONGA, *data, 4); 437 *data |= EN_PROM_CLK ; 438 pci_write_config(dev, EN_TONGA, *data, 4); 439 *data = pci_read_config(dev, EN_TONGA, 4); 440 *data &= ~EN_PROM_CLK ; 441 pci_write_config(dev, EN_TONGA, *data, 4); 442 *data |= EN_PROM_DATA ; 443 pci_write_config(dev, EN_TONGA, *data, 4); 444 445 return (tmp); 446} 447 448/* 449 * Get MAC address and other stuff from the EEPROM 450 */ 451static void 452eni_get_macaddr(device_t dev, struct en_pci_softc *scp) 453{ 454 struct en_softc * sc = (struct en_softc *)scp; 455 int i; 456 uint32_t data, t_data; 457 458 t_data = pci_read_config(dev, EN_TONGA, 4) & 0xffffff00; 459 460 data = EN_PROM_MAGIC | EN_PROM_DATA | EN_PROM_CLK; 461 pci_write_config(dev, EN_TONGA, data, 4); 462 463 for (i = 0; i < sizeof(IFP2IFATM(sc->ifp)->mib.esi); i ++) 464 IFP2IFATM(sc->ifp)->mib.esi[i] = eni_get_byte(dev, &data, i + EN_ESI); 465 466 IFP2IFATM(sc->ifp)->mib.serial = 0; 467 for (i = 0; i < 4; i++) { 468 IFP2IFATM(sc->ifp)->mib.serial <<= 8; 469 IFP2IFATM(sc->ifp)->mib.serial |= eni_get_byte(dev, &data, i + EN_SERIAL); 470 } 471 /* stop operation */ 472 data &= ~EN_PROM_DATA; 473 pci_write_config(dev, EN_TONGA, data, 4); 474 data |= EN_PROM_CLK; 475 pci_write_config(dev, EN_TONGA, data, 4); 476 data |= EN_PROM_DATA; 477 pci_write_config(dev, EN_TONGA, data, 4); 478 pci_write_config(dev, EN_TONGA, t_data, 4); 479} 480 481/* 482 * Driver infrastructure 483 */ 484static device_method_t en_methods[] = { 485 /* Device interface */ 486 DEVMETHOD(device_probe, en_pci_probe), 487 DEVMETHOD(device_attach, en_pci_attach), 488 DEVMETHOD(device_detach, en_pci_detach), 489 DEVMETHOD(device_shutdown, en_pci_shutdown), 490 491 { 0, 0 } 492}; 493 494static driver_t en_driver = { 495 "en", 496 en_methods, 497 sizeof(struct en_pci_softc), 498}; 499 500static devclass_t en_devclass; 501 502DRIVER_MODULE(en, pci, en_driver, en_devclass, en_modevent, 0);
| 284 device_printf(dev, "could not setup irq\n"); 285 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 286 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 287 en_destroy(sc); 288 if_free(sc->ifp); 289 goto fail; 290 } 291 292 return (0); 293 294 fail: 295 return (error); 296} 297 298/* 299 * Detach the adapter 300 */ 301static int 302en_pci_detach(device_t dev) 303{ 304 struct en_softc *sc = device_get_softc(dev); 305 struct en_pci_softc *scp = (struct en_pci_softc *)sc; 306 307 /* 308 * Stop DMA and drop transmit queue. 309 */ 310 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) { 311 if_printf(sc->ifp, "still running\n"); 312 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 313 } 314 315 /* 316 * Close down routes etc. 317 */ 318 en_reset(sc); 319 atm_ifdetach(sc->ifp); 320 321 /* 322 * Deallocate resources. 323 */ 324 bus_teardown_intr(dev, scp->irq, scp->ih); 325 bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); 326 bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); 327 328 /* 329 * Free all the driver internal resources 330 */ 331 en_destroy(sc); 332 if_free(sc->ifp); 333 334 return (0); 335} 336 337static int 338en_pci_shutdown(device_t dev) 339{ 340 struct en_pci_softc *psc = device_get_softc(dev); 341 342 en_reset(&psc->esc); 343 DELAY(10); /* is this necessary? */ 344 345 return (0); 346} 347 348/* 349 * Get the MAC address from an Adaptec board. No idea how to get 350 * serial number or other stuff, because I have no documentation for that 351 * card. 352 */ 353static void 354adp_get_macaddr(struct en_pci_softc *scp) 355{ 356 struct en_softc * sc = (struct en_softc *)scp; 357 int lcv; 358 359 for (lcv = 0; lcv < sizeof(IFP2IFATM(sc->ifp)->mib.esi); lcv++) 360 IFP2IFATM(sc->ifp)->mib.esi[lcv] = bus_space_read_1(sc->en_memt, 361 sc->en_base, MID_ADPMACOFF + lcv); 362} 363 364/* 365 * Read station (MAC) address from serial EEPROM. 366 * derived from linux drivers/atm/eni.c by Werner Almesberger, EPFL LRC. 367 */ 368#define EN_PROM_MAGIC 0x0c 369#define EN_PROM_DATA 0x02 370#define EN_PROM_CLK 0x01 371#define EN_ESI 64 372#define EN_SERIAL 112 373 374/* 375 * Read a byte from the given address in the EEPROM 376 */ 377static uint8_t 378eni_get_byte(device_t dev, uint32_t *data, u_int address) 379{ 380 int j; 381 uint8_t tmp; 382 383 address = (address << 1) + 1; 384 385 /* start operation */ 386 *data |= EN_PROM_DATA ; 387 pci_write_config(dev, EN_TONGA, *data, 4); 388 *data |= EN_PROM_CLK ; 389 pci_write_config(dev, EN_TONGA, *data, 4); 390 *data &= ~EN_PROM_DATA ; 391 pci_write_config(dev, EN_TONGA, *data, 4); 392 *data &= ~EN_PROM_CLK ; 393 pci_write_config(dev, EN_TONGA, *data, 4); 394 /* send address with serial line */ 395 for ( j = 7 ; j >= 0 ; j --) { 396 *data = ((address >> j) & 1) ? (*data | EN_PROM_DATA) : 397 (*data & ~EN_PROM_DATA); 398 pci_write_config(dev, EN_TONGA, *data, 4); 399 *data |= EN_PROM_CLK ; 400 pci_write_config(dev, EN_TONGA, *data, 4); 401 *data &= ~EN_PROM_CLK ; 402 pci_write_config(dev, EN_TONGA, *data, 4); 403 } 404 /* get ack */ 405 *data |= EN_PROM_DATA ; 406 pci_write_config(dev, EN_TONGA, *data, 4); 407 *data |= EN_PROM_CLK ; 408 pci_write_config(dev, EN_TONGA, *data, 4); 409 *data = pci_read_config(dev, EN_TONGA, 4); 410 *data &= ~EN_PROM_CLK ; 411 pci_write_config(dev, EN_TONGA, *data, 4); 412 *data |= EN_PROM_DATA ; 413 pci_write_config(dev, EN_TONGA, *data, 4); 414 415 tmp = 0; 416 417 for ( j = 7 ; j >= 0 ; j --) { 418 tmp <<= 1; 419 *data |= EN_PROM_DATA ; 420 pci_write_config(dev, EN_TONGA, *data, 4); 421 *data |= EN_PROM_CLK ; 422 pci_write_config(dev, EN_TONGA, *data, 4); 423 *data = pci_read_config(dev, EN_TONGA, 4); 424 if(*data & EN_PROM_DATA) tmp |= 1; 425 *data &= ~EN_PROM_CLK ; 426 pci_write_config(dev, EN_TONGA, *data, 4); 427 *data |= EN_PROM_DATA ; 428 pci_write_config(dev, EN_TONGA, *data, 4); 429 } 430 /* get ack */ 431 *data |= EN_PROM_DATA ; 432 pci_write_config(dev, EN_TONGA, *data, 4); 433 *data |= EN_PROM_CLK ; 434 pci_write_config(dev, EN_TONGA, *data, 4); 435 *data = pci_read_config(dev, EN_TONGA, 4); 436 *data &= ~EN_PROM_CLK ; 437 pci_write_config(dev, EN_TONGA, *data, 4); 438 *data |= EN_PROM_DATA ; 439 pci_write_config(dev, EN_TONGA, *data, 4); 440 441 return (tmp); 442} 443 444/* 445 * Get MAC address and other stuff from the EEPROM 446 */ 447static void 448eni_get_macaddr(device_t dev, struct en_pci_softc *scp) 449{ 450 struct en_softc * sc = (struct en_softc *)scp; 451 int i; 452 uint32_t data, t_data; 453 454 t_data = pci_read_config(dev, EN_TONGA, 4) & 0xffffff00; 455 456 data = EN_PROM_MAGIC | EN_PROM_DATA | EN_PROM_CLK; 457 pci_write_config(dev, EN_TONGA, data, 4); 458 459 for (i = 0; i < sizeof(IFP2IFATM(sc->ifp)->mib.esi); i ++) 460 IFP2IFATM(sc->ifp)->mib.esi[i] = eni_get_byte(dev, &data, i + EN_ESI); 461 462 IFP2IFATM(sc->ifp)->mib.serial = 0; 463 for (i = 0; i < 4; i++) { 464 IFP2IFATM(sc->ifp)->mib.serial <<= 8; 465 IFP2IFATM(sc->ifp)->mib.serial |= eni_get_byte(dev, &data, i + EN_SERIAL); 466 } 467 /* stop operation */ 468 data &= ~EN_PROM_DATA; 469 pci_write_config(dev, EN_TONGA, data, 4); 470 data |= EN_PROM_CLK; 471 pci_write_config(dev, EN_TONGA, data, 4); 472 data |= EN_PROM_DATA; 473 pci_write_config(dev, EN_TONGA, data, 4); 474 pci_write_config(dev, EN_TONGA, t_data, 4); 475} 476 477/* 478 * Driver infrastructure 479 */ 480static device_method_t en_methods[] = { 481 /* Device interface */ 482 DEVMETHOD(device_probe, en_pci_probe), 483 DEVMETHOD(device_attach, en_pci_attach), 484 DEVMETHOD(device_detach, en_pci_detach), 485 DEVMETHOD(device_shutdown, en_pci_shutdown), 486 487 { 0, 0 } 488}; 489 490static driver_t en_driver = { 491 "en", 492 en_methods, 493 sizeof(struct en_pci_softc), 494}; 495 496static devclass_t en_devclass; 497 498DRIVER_MODULE(en, pci, en_driver, en_devclass, en_modevent, 0);
|