mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
- Propagate suspend/resume to child devices.
- Restore pci config registers after resume. - Reinitialize and start rx buffers after resume. - Don't reallocate memory in fwohci_db_init() if the dbch is already initialized. - Fix typo. - Some clean up.
This commit is contained in:
parent
fe634ca75f
commit
9339321d89
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=108642
@ -95,6 +95,8 @@ static device_method_t firewire_methods[] = {
|
|||||||
DEVMETHOD(device_probe, firewire_match),
|
DEVMETHOD(device_probe, firewire_match),
|
||||||
DEVMETHOD(device_attach, firewire_attach),
|
DEVMETHOD(device_attach, firewire_attach),
|
||||||
DEVMETHOD(device_detach, firewire_detach),
|
DEVMETHOD(device_detach, firewire_detach),
|
||||||
|
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||||
|
DEVMETHOD(device_resume, bus_generic_resume),
|
||||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||||
|
|
||||||
/* Bus interface */
|
/* Bus interface */
|
||||||
|
@ -527,12 +527,16 @@ fwohci_reset(struct fwohci_softc *sc, device_t dev)
|
|||||||
|
|
||||||
fwohci_probe_phy(sc, dev);
|
fwohci_probe_phy(sc, dev);
|
||||||
|
|
||||||
OWRITE(sc, OHCI_SID_BUF, vtophys(sc->fc.sid_buf));
|
OWRITE(sc, OHCI_SID_BUF, vtophys(sc->fc.sid_buf));
|
||||||
OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
|
OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
|
||||||
|
|
||||||
/* enable link */
|
/* enable link */
|
||||||
OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
|
OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
|
||||||
fw_busreset(&sc->fc);
|
fw_busreset(&sc->fc);
|
||||||
|
|
||||||
|
/* force to start rx dma */
|
||||||
|
sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
|
||||||
|
sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
|
||||||
fwohci_rx_enable(sc, &sc->arrq);
|
fwohci_rx_enable(sc, &sc->arrq);
|
||||||
fwohci_rx_enable(sc, &sc->arrs);
|
fwohci_rx_enable(sc, &sc->arrs);
|
||||||
|
|
||||||
@ -1106,27 +1110,26 @@ fwohci_db_init(struct fwohci_dbch *dbch)
|
|||||||
int idb;
|
int idb;
|
||||||
struct fwohcidb *db;
|
struct fwohcidb *db;
|
||||||
struct fwohcidb_tr *db_tr;
|
struct fwohcidb_tr *db_tr;
|
||||||
|
|
||||||
|
|
||||||
|
if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* allocate DB entries and attach one to each DMA channels */
|
/* allocate DB entries and attach one to each DMA channels */
|
||||||
/* DB entry must start at 16 bytes bounary. */
|
/* DB entry must start at 16 bytes bounary. */
|
||||||
dbch->frag.buf = NULL;
|
|
||||||
dbch->frag.len = 0;
|
|
||||||
dbch->frag.plen = 0;
|
|
||||||
dbch->xferq.queued = 0;
|
|
||||||
dbch->pdb_tr = NULL;
|
|
||||||
|
|
||||||
STAILQ_INIT(&dbch->db_trq);
|
STAILQ_INIT(&dbch->db_trq);
|
||||||
db_tr = (struct fwohcidb_tr *)
|
db_tr = (struct fwohcidb_tr *)
|
||||||
malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
|
malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
|
||||||
M_DEVBUF, M_DONTWAIT | M_ZERO);
|
M_DEVBUF, M_DONTWAIT | M_ZERO);
|
||||||
if(db_tr == NULL){
|
if(db_tr == NULL){
|
||||||
printf("fwochi_db_init: malloc failed\n");
|
printf("fwohci_db_init: malloc failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
db = (struct fwohcidb *)
|
db = (struct fwohcidb *)
|
||||||
contigmalloc(sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb,
|
contigmalloc(sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb,
|
||||||
M_DEVBUF, M_DONTWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
|
M_DEVBUF, M_DONTWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
|
||||||
if(db == NULL){
|
if(db == NULL){
|
||||||
printf("fwochi_db_init: contigmalloc failed\n");
|
printf("fwohci_db_init: contigmalloc failed\n");
|
||||||
free(db_tr, M_DEVBUF);
|
free(db_tr, M_DEVBUF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1150,6 +1153,12 @@ fwohci_db_init(struct fwohci_dbch *dbch)
|
|||||||
}
|
}
|
||||||
STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
|
STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
|
||||||
= STAILQ_FIRST(&dbch->db_trq);
|
= STAILQ_FIRST(&dbch->db_trq);
|
||||||
|
out:
|
||||||
|
dbch->frag.buf = NULL;
|
||||||
|
dbch->frag.len = 0;
|
||||||
|
dbch->frag.plen = 0;
|
||||||
|
dbch->xferq.queued = 0;
|
||||||
|
dbch->pdb_tr = NULL;
|
||||||
dbch->top = STAILQ_FIRST(&dbch->db_trq);
|
dbch->top = STAILQ_FIRST(&dbch->db_trq);
|
||||||
dbch->bottom = dbch->top;
|
dbch->bottom = dbch->top;
|
||||||
dbch->flags = FWOHCI_DBCH_INIT;
|
dbch->flags = FWOHCI_DBCH_INIT;
|
||||||
@ -1327,6 +1336,7 @@ fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbch->xferq.flag |= FWXFERQ_RUNNING;
|
dbch->xferq.flag |= FWXFERQ_RUNNING;
|
||||||
|
dbch->top = STAILQ_FIRST(&dbch->db_trq);
|
||||||
for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
|
for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
|
||||||
dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
|
dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
|
||||||
}
|
}
|
||||||
@ -1526,10 +1536,9 @@ fwohci_irx_enable(struct firewire_comm *fc, int dmach)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fwohci_shutdown(device_t dev)
|
fwohci_shutdown(struct fwohci_softc *sc, device_t dev)
|
||||||
{
|
{
|
||||||
u_int i;
|
u_int i;
|
||||||
struct fwohci_softc *sc = device_get_softc(dev);
|
|
||||||
|
|
||||||
/* Now stopping all DMA channel */
|
/* Now stopping all DMA channel */
|
||||||
OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
|
OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
|
||||||
@ -1553,6 +1562,28 @@ fwohci_shutdown(device_t dev)
|
|||||||
| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
|
| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
|
||||||
| OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
|
| OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
|
||||||
| OHCI_INT_PHY_BUS_R);
|
| OHCI_INT_PHY_BUS_R);
|
||||||
|
/* XXX Link down? Bus reset? */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fwohci_resume(struct fwohci_softc *sc, device_t dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
device_printf(sc->fc.dev,
|
||||||
|
"resume iso receive ch: %d\n", i);
|
||||||
|
sc->ir[i].xferq.flag &= ~FWXFERQ_RUNNING;
|
||||||
|
sc->fc.irx_enable(&sc->fc, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bus_generic_resume(dev);
|
||||||
|
sc->fc.ibr(&sc->fc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1814,7 +1845,7 @@ fwohci_set_intr(struct firewire_comm *fc, int enable)
|
|||||||
|
|
||||||
sc = (struct fwohci_softc *)fc;
|
sc = (struct fwohci_softc *)fc;
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(sc->fc.dev, "fwochi_set_intr: %d\n", enable);
|
device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
sc->intmask |= OHCI_INT_EN;
|
sc->intmask |= OHCI_INT_EN;
|
||||||
OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
|
OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
|
||||||
|
@ -144,27 +144,10 @@ fwohci_dummy_intr(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fwohci_pci_attach(device_t self)
|
fwohci_pci_init(device_t self)
|
||||||
{
|
{
|
||||||
fwohci_softc_t *sc = device_get_softc(self);
|
|
||||||
int err;
|
|
||||||
int rid;
|
|
||||||
int latency, cache_line;
|
int latency, cache_line;
|
||||||
u_int16_t cmd;
|
u_int16_t cmd;
|
||||||
#if __FreeBSD_version < 500000
|
|
||||||
int intr;
|
|
||||||
/* For the moment, put in a message stating what is wrong */
|
|
||||||
intr = pci_read_config(self, PCIR_INTLINE, 1);
|
|
||||||
if (intr == 0 || intr == 255) {
|
|
||||||
device_printf(self, "Invalid irq %d\n", intr);
|
|
||||||
#ifdef __i386__
|
|
||||||
device_printf(self, "Please switch PNP-OS to 'No' in BIOS\n");
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
return ENXIO;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cmd = pci_read_config(self, PCIR_COMMAND, 2);
|
cmd = pci_read_config(self, PCIR_COMMAND, 2);
|
||||||
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
|
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
|
||||||
@ -189,7 +172,33 @@ fwohci_pci_attach(device_t self)
|
|||||||
#endif
|
#endif
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(self, "cache size %d.\n", (int) cache_line);
|
device_printf(self, "cache size %d.\n", (int) cache_line);
|
||||||
/**/
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
fwohci_pci_attach(device_t self)
|
||||||
|
{
|
||||||
|
fwohci_softc_t *sc = device_get_softc(self);
|
||||||
|
int err;
|
||||||
|
int rid;
|
||||||
|
#if __FreeBSD_version < 500000
|
||||||
|
int intr;
|
||||||
|
/* For the moment, put in a message stating what is wrong */
|
||||||
|
intr = pci_read_config(self, PCIR_INTLINE, 1);
|
||||||
|
if (intr == 0 || intr == 255) {
|
||||||
|
device_printf(self, "Invalid irq %d\n", intr);
|
||||||
|
#ifdef __i386__
|
||||||
|
device_printf(self, "Please switch PNP-OS to 'No' in BIOS\n");
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
return ENXIO;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fwohci_pci_init(self);
|
||||||
|
|
||||||
rid = PCI_CBMEM;
|
rid = PCI_CBMEM;
|
||||||
sc->bsr = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
|
sc->bsr = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
|
||||||
0, ~0, 1, RF_ACTIVE);
|
0, ~0, 1, RF_ACTIVE);
|
||||||
@ -254,7 +263,7 @@ fwohci_pci_detach(device_t self)
|
|||||||
|
|
||||||
s = splfw();
|
s = splfw();
|
||||||
|
|
||||||
fwohci_shutdown(self);
|
fwohci_shutdown(sc, self);
|
||||||
bus_generic_detach(self);
|
bus_generic_detach(self);
|
||||||
|
|
||||||
/* disable interrupts that might have been switched on */
|
/* disable interrupts that might have been switched on */
|
||||||
@ -300,7 +309,12 @@ fwohci_pci_detach(device_t self)
|
|||||||
static int
|
static int
|
||||||
fwohci_pci_suspend(device_t dev)
|
fwohci_pci_suspend(device_t dev)
|
||||||
{
|
{
|
||||||
device_printf(dev, "fwoch_pci_suspend\n");
|
device_printf(dev, "fwohci_pci_suspend\n");
|
||||||
|
int err;
|
||||||
|
err = bus_generic_suspend(dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
/* fwohci_shutdown(dev); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +323,19 @@ fwohci_pci_resume(device_t dev)
|
|||||||
{
|
{
|
||||||
fwohci_softc_t *sc = device_get_softc(dev);
|
fwohci_softc_t *sc = device_get_softc(dev);
|
||||||
|
|
||||||
device_printf(dev, "fwoch_pci_resume\n");
|
device_printf(dev, "fwohci_pci_resume: power_state = 0x%08x\n",
|
||||||
fwohci_reset(sc, dev);
|
pci_get_powerstate(dev));
|
||||||
|
fwohci_pci_init(dev);
|
||||||
|
fwohci_resume(sc, dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
fwohci_pci_shutdown(device_t dev)
|
||||||
|
{
|
||||||
|
fwohci_softc_t *sc = device_get_softc(dev);
|
||||||
|
|
||||||
|
fwohci_shutdown(sc, dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,9 +344,9 @@ static device_method_t fwohci_methods[] = {
|
|||||||
DEVMETHOD(device_probe, fwohci_pci_probe),
|
DEVMETHOD(device_probe, fwohci_pci_probe),
|
||||||
DEVMETHOD(device_attach, fwohci_pci_attach),
|
DEVMETHOD(device_attach, fwohci_pci_attach),
|
||||||
DEVMETHOD(device_detach, fwohci_pci_detach),
|
DEVMETHOD(device_detach, fwohci_pci_detach),
|
||||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
|
||||||
DEVMETHOD(device_suspend, fwohci_pci_suspend),
|
DEVMETHOD(device_suspend, fwohci_pci_suspend),
|
||||||
DEVMETHOD(device_resume, fwohci_pci_resume),
|
DEVMETHOD(device_resume, fwohci_pci_resume),
|
||||||
|
DEVMETHOD(device_shutdown, fwohci_pci_shutdown),
|
||||||
|
|
||||||
/* Bus interface */
|
/* Bus interface */
|
||||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||||
|
@ -70,4 +70,5 @@ void fwohci_intr __P((void *arg));
|
|||||||
int fwohci_init __P((struct fwohci_softc *, device_t));
|
int fwohci_init __P((struct fwohci_softc *, device_t));
|
||||||
void fwohci_reset __P((struct fwohci_softc *, device_t));
|
void fwohci_reset __P((struct fwohci_softc *, device_t));
|
||||||
int fwohci_detach __P((struct fwohci_softc *, device_t));
|
int fwohci_detach __P((struct fwohci_softc *, device_t));
|
||||||
int fwohci_shutdown __P((device_t dev));
|
int fwohci_resume __P((struct fwohci_softc *, device_t));
|
||||||
|
int fwohci_shutdown __P((struct fwohci_softc *, device_t dev));
|
||||||
|
@ -458,7 +458,9 @@ END_DEBUG
|
|||||||
if (reg == NULL)
|
if (reg == NULL)
|
||||||
break;
|
break;
|
||||||
lun = reg->val & 0xff;
|
lun = reg->val & 0xff;
|
||||||
printf("lun %d found\n", lun);
|
SBP_DEBUG(0)
|
||||||
|
printf("target %d lun %d found\n", target->target_id, lun);
|
||||||
|
END_DEBUG
|
||||||
if (maxlun < lun)
|
if (maxlun < lun)
|
||||||
maxlun = lun;
|
maxlun = lun;
|
||||||
crom_next(&cc);
|
crom_next(&cc);
|
||||||
|
Loading…
Reference in New Issue
Block a user