Fix several problems related to resume:
- Initialize fc->status to process bus reset correctly after resume. - Initialize AT ring buffer pointer. - Requeue stdma to stfree for active IR buffer. - Stop DMA before suspend for safe. - Set powerstate after resume.
This commit is contained in:
parent
a772047bc6
commit
630529ad1e
@ -84,6 +84,7 @@ devclass_t firewire_devclass;
|
||||
static int firewire_match __P((device_t));
|
||||
static int firewire_attach __P((device_t));
|
||||
static int firewire_detach __P((device_t));
|
||||
static int firewire_resume __P((device_t));
|
||||
#if 0
|
||||
static int firewire_shutdown __P((device_t));
|
||||
#endif
|
||||
@ -109,7 +110,7 @@ static device_method_t firewire_methods[] = {
|
||||
DEVMETHOD(device_attach, firewire_attach),
|
||||
DEVMETHOD(device_detach, firewire_detach),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
DEVMETHOD(device_resume, firewire_resume),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
/* Bus interface */
|
||||
@ -367,7 +368,7 @@ firewire_attach( device_t dev )
|
||||
|
||||
fc = (struct firewire_comm *)device_get_softc(pa);
|
||||
sc->fc = fc;
|
||||
fc->status = -1;
|
||||
fc->status = FWBUSNOTREADY;
|
||||
|
||||
unitmask = UNIT2MIN(device_get_unit(dev));
|
||||
|
||||
@ -434,6 +435,19 @@ firewire_add_child(device_t dev, int order, const char *name, int unit)
|
||||
return child;
|
||||
}
|
||||
|
||||
static int
|
||||
firewire_resume(device_t dev)
|
||||
{
|
||||
struct firewire_softc *sc;
|
||||
|
||||
sc = (struct firewire_softc *)device_get_softc(dev);
|
||||
sc->fc->status = FWBUSNOTREADY;
|
||||
|
||||
bus_generic_resume(dev);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dettach it.
|
||||
*/
|
||||
|
@ -121,6 +121,7 @@ struct firewire_comm{
|
||||
SLIST_HEAD(, csrdir) ongocsr;
|
||||
SLIST_HEAD(, csrdir) csrfree;
|
||||
u_int32_t status;
|
||||
#define FWBUSNOTREADY (-1)
|
||||
#define FWBUSRESET 0
|
||||
#define FWBUSINIT 1
|
||||
#define FWBUSCYMELECT 2
|
||||
|
@ -549,10 +549,17 @@ fwohci_reset(struct fwohci_softc *sc, device_t dev)
|
||||
/* Initialize async TX */
|
||||
OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
|
||||
OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
|
||||
|
||||
/* AT Retries */
|
||||
OWRITE(sc, FWOHCI_RETRY,
|
||||
/* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
|
||||
(0xffff << 16 ) | (0x0f << 8) | (0x0f << 4) | 0x0f) ;
|
||||
|
||||
sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
|
||||
sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
|
||||
sc->atrq.bottom = sc->atrq.top;
|
||||
sc->atrs.bottom = sc->atrs.top;
|
||||
|
||||
for( i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb ;
|
||||
i ++, db_tr = STAILQ_NEXT(db_tr, link)){
|
||||
db_tr->xfer = NULL;
|
||||
@ -1681,6 +1688,9 @@ fwohci_stop(struct fwohci_softc *sc, device_t dev)
|
||||
| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
|
||||
| OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
|
||||
| OHCI_INT_PHY_BUS_R);
|
||||
|
||||
fw_drain_txq(&sc->fc);
|
||||
|
||||
/* XXX Link down? Bus reset? */
|
||||
return 0;
|
||||
}
|
||||
@ -1689,14 +1699,22 @@ int
|
||||
fwohci_resume(struct fwohci_softc *sc, device_t dev)
|
||||
{
|
||||
int i;
|
||||
struct fw_xferq *ir;
|
||||
struct fw_bulkxfer *chunk;
|
||||
|
||||
fwohci_reset(sc, dev);
|
||||
/* XXX resume isochronus receive automatically. (how about TX?) */
|
||||
for(i = 0; i < sc->fc.nisodma; i ++) {
|
||||
if((sc->ir[i].xferq.flag & FWXFERQ_RUNNING) != 0) {
|
||||
ir = &sc->ir[i].xferq;
|
||||
if((ir->flag & FWXFERQ_RUNNING) != 0) {
|
||||
device_printf(sc->fc.dev,
|
||||
"resume iso receive ch: %d\n", i);
|
||||
sc->ir[i].xferq.flag &= ~FWXFERQ_RUNNING;
|
||||
ir->flag &= ~FWXFERQ_RUNNING;
|
||||
/* requeue stdma to stfree */
|
||||
while((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&ir->stdma, link);
|
||||
STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
|
||||
}
|
||||
sc->fc.irx_enable(&sc->fc, i);
|
||||
}
|
||||
}
|
||||
|
@ -380,13 +380,14 @@ fwohci_pci_detach(device_t self)
|
||||
static int
|
||||
fwohci_pci_suspend(device_t dev)
|
||||
{
|
||||
fwohci_softc_t *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
device_printf(dev, "fwohci_pci_suspend\n");
|
||||
err = bus_generic_suspend(dev);
|
||||
if (err)
|
||||
return err;
|
||||
/* fwohci_stop(dev); */
|
||||
fwohci_stop(sc, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -397,6 +398,7 @@ fwohci_pci_resume(device_t dev)
|
||||
|
||||
device_printf(dev, "fwohci_pci_resume: power_state = 0x%08x\n",
|
||||
pci_get_powerstate(dev));
|
||||
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
|
||||
fwohci_pci_init(dev);
|
||||
fwohci_resume(sc, dev);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user