FreeBSD Bugzilla – Attachment 9090 Details for
Bug 18756
[PATCH] fxp device causes lockups after suspend/resume
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 7.34 KB, created by
mike+fbsd
on 2000-05-22 21:30:01 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
mike+fbsd
Created:
2000-05-22 21:30:01 UTC
Size:
7.34 KB
patch
obsolete
>Index: sys/pci/if_fxp.c >=================================================================== >RCS file: /usr/local/src/FREEBSD/src/sys/pci/if_fxp.c,v >retrieving revision 1.77.2.1 >diff -c -r1.77.2.1 if_fxp.c >*** sys/pci/if_fxp.c 2000/03/29 02:02:38 1.77.2.1 >--- sys/pci/if_fxp.c 2000/05/22 20:01:22 >*************** >*** 222,227 **** >--- 222,228 ---- > static void fxp_mediastatus __P((struct ifnet *, struct ifmediareq *)); > static void fxp_set_media __P((struct fxp_softc *, int)); > static __inline void fxp_scb_wait __P((struct fxp_softc *)); >+ static __inline void fxp_dma_wait __P((volatile u_int16_t *, struct fxp_softc *sc)); > static FXP_INTR_TYPE fxp_intr __P((void *)); > static void fxp_start __P((struct ifnet *)); > static int fxp_ioctl __P((struct ifnet *, >*************** >*** 291,299 **** > { > int i = 10000; > >! while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i); > } > > /************************************************************* > * Operating system-specific autoconfiguration glue > *************************************************************/ >--- 292,316 ---- > { > int i = 10000; > >! while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i) >! DELAY(2); >! if (i == 0) >! printf(FXP_FORMAT ": SCB timeout\n", FXP_ARGS(sc)); > } > >+ static __inline void >+ fxp_dma_wait(status, sc) >+ volatile u_int16_t *status; >+ struct fxp_softc *sc; >+ { >+ int i = 10000; >+ >+ while (!(*status & FXP_CB_STATUS_C) && --i) >+ DELAY(2); >+ if (i == 0) >+ printf(FXP_FORMAT ": DMA timeout\n", FXP_ARGS(sc)); >+ } >+ > /************************************************************* > * Operating system-specific autoconfiguration glue > *************************************************************/ >*************** >*** 680,691 **** >--- 697,773 ---- > return 0; > } > >+ /* >+ * Device suspend routine. Stop the interface and save some PCI >+ * settings in case the BIOS doesn't restore them properly on >+ * resume. >+ */ >+ static int >+ fxp_suspend(device_t dev) >+ { >+ struct fxp_softc *sc = device_get_softc(dev); >+ int i, s = splimp(); >+ >+ fxp_stop(sc); >+ >+ for (i=0; i<5; i++) >+ sc->saved_maps[i] = pci_read_config(dev, PCIR_MAPS + i*4, 4); >+ sc->saved_biosaddr = pci_read_config(dev, PCIR_BIOS, 4); >+ sc->saved_intline = pci_read_config(dev, PCIR_INTLINE, 1); >+ sc->saved_cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1); >+ sc->saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1); >+ >+ splx(s); >+ >+ return 0; >+ } >+ >+ /* >+ * Device resume routine. Restore some PCI settings in case the BIOS >+ * doesn't, re-enable busmastering, and restart the interface if >+ * appropriate. >+ */ >+ static int >+ fxp_resume(device_t dev) >+ { >+ struct fxp_softc *sc = device_get_softc(dev); >+ struct ifnet *ifp = &sc->sc_if; >+ u_int16_t pci_command; >+ int i, s = splimp(); >+ >+ /* better way to do this? */ >+ for (i=0; i<5; i++) >+ pci_write_config(dev, PCIR_MAPS + i*4, sc->saved_maps[i], 4); >+ pci_write_config(dev, PCIR_BIOS, sc->saved_biosaddr, 4); >+ pci_write_config(dev, PCIR_INTLINE, sc->saved_intline, 1); >+ pci_write_config(dev, PCIR_CACHELNSZ, sc->saved_cachelnsz, 1); >+ pci_write_config(dev, PCIR_LATTIMER, sc->saved_lattimer, 1); >+ >+ /* reenable busmastering */ >+ pci_command = pci_read_config(dev, PCIR_COMMAND, 2); >+ pci_command |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); >+ pci_write_config(dev, PCIR_COMMAND, pci_command, 2); >+ >+ CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); >+ DELAY(10); >+ >+ /* reinitialize interface if necessary */ >+ if (ifp->if_flags & IFF_UP) >+ fxp_init(sc); >+ >+ splx(s); >+ >+ return 0; >+ } >+ > static device_method_t fxp_methods[] = { > /* Device interface */ > DEVMETHOD(device_probe, fxp_probe), > DEVMETHOD(device_attach, fxp_attach), > DEVMETHOD(device_detach, fxp_detach), > DEVMETHOD(device_shutdown, fxp_shutdown), >+ DEVMETHOD(device_suspend, fxp_suspend), >+ DEVMETHOD(device_resume, fxp_resume), > > { 0, 0 } > }; >*************** >*** 1096,1101 **** >--- 1178,1188 ---- > int claimed = 0; > #endif > >+ /* don't try to service interrupts when the interface isn't running */ >+ if ((ifp->if_flags & IFF_RUNNING) == 0) { >+ return; >+ } >+ > while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) { > #if defined(__NetBSD__) > claimed = 1; >*************** >*** 1358,1363 **** >--- 1445,1453 ---- > struct fxp_cb_tx *txp; > int i; > >+ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); >+ ifp->if_timer = 0; >+ > /* > * Cancel stats updater. > */ >*************** >*** 1400,1408 **** > panic("fxp_stop: no buffers!"); > } > } >- >- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); >- ifp->if_timer = 0; > } > > /* >--- 1490,1495 ---- >*************** >*** 1515,1521 **** > CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status)); > CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); > /* ...and wait for it to complete. */ >! while (!(cbp->cb_status & FXP_CB_STATUS_C)); > > /* > * Now initialize the station address. Temporarily use the TxCB >--- 1602,1608 ---- > CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status)); > CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); > /* ...and wait for it to complete. */ >! fxp_dma_wait(&cbp->cb_status, sc); > > /* > * Now initialize the station address. Temporarily use the TxCB >*************** >*** 1538,1544 **** > fxp_scb_wait(sc); > CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); > /* ...and wait for it to complete. */ >! while (!(cb_ias->cb_status & FXP_CB_STATUS_C)); > > /* > * Initialize transmit control block (TxCB) list. >--- 1625,1631 ---- > fxp_scb_wait(sc); > CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); > /* ...and wait for it to complete. */ >! fxp_dma_wait(&cb_ias->cb_status, sc); > > /* > * Initialize transmit control block (TxCB) list. >*************** >*** 1977,1982 **** >--- 2064,2070 ---- > struct ifnet *ifp = &sc->sc_if; > struct ifmultiaddr *ifma; > int nmcasts; >+ int count; > > /* > * If there are queued commands, we must wait until they are all >*************** >*** 2058,2065 **** > * Wait until command unit is not active. This should never > * be the case when nothing is queued, but make sure anyway. > */ > while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) == >! FXP_SCB_CUS_ACTIVE) ; > > /* > * Start the multicast setup command. >--- 2146,2159 ---- > * Wait until command unit is not active. This should never > * be the case when nothing is queued, but make sure anyway. > */ >+ count = 100; > while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) == >! FXP_SCB_CUS_ACTIVE && --count) >! DELAY(10); >! if (count == 0) { >! printf(FXP_FORMAT ": command queue timeout\n", FXP_ARGS(sc)); >! return; >! } > > /* > * Start the multicast setup command. >Index: sys/pci/if_fxpvar.h >=================================================================== >RCS file: /usr/local/src/FREEBSD/src/sys/pci/if_fxpvar.h,v >retrieving revision 1.9.2.1 >diff -c -r1.9.2.1 if_fxpvar.h >*** sys/pci/if_fxpvar.h 2000/03/29 02:02:39 1.9.2.1 >--- sys/pci/if_fxpvar.h 2000/05/22 19:58:05 >*************** >*** 68,73 **** >--- 68,78 ---- > int phy_primary_device; /* device type of primary PHY */ > int phy_10Mbps_only; /* PHY is 10Mbps-only device */ > int eeprom_size; /* size of serial EEPROM */ >+ u_int32_t saved_maps[5]; /* pci data */ >+ u_int32_t saved_biosaddr; >+ u_int8_t saved_intline; >+ u_int8_t saved_cachelnsz; >+ u_int8_t saved_lattimer; > }; > > /* Macros to ease CSR access. */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 18756
: 9090