summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/firewire/firewire.c2
-rw-r--r--sys/dev/firewire/fwohci.c55
-rw-r--r--sys/dev/firewire/fwohci_pci.c73
-rw-r--r--sys/dev/firewire/fwohcivar.h3
-rw-r--r--sys/dev/firewire/sbp.c4
5 files changed, 99 insertions, 38 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c
index 08f8b61..dedcc61 100644
--- a/sys/dev/firewire/firewire.c
+++ b/sys/dev/firewire/firewire.c
@@ -95,6 +95,8 @@ static device_method_t firewire_methods[] = {
DEVMETHOD(device_probe, firewire_match),
DEVMETHOD(device_attach, firewire_attach),
DEVMETHOD(device_detach, firewire_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
/* Bus interface */
diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c
index 0d72363..e92408d 100644
--- a/sys/dev/firewire/fwohci.c
+++ b/sys/dev/firewire/fwohci.c
@@ -527,12 +527,16 @@ fwohci_reset(struct fwohci_softc *sc, device_t 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);
/* enable link */
OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
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->arrs);
@@ -1106,27 +1110,26 @@ fwohci_db_init(struct fwohci_dbch *dbch)
int idb;
struct fwohcidb *db;
struct fwohcidb_tr *db_tr;
+
+
+ if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
+ goto out;
+
/* allocate DB entries and attach one to each DMA channels */
/* 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);
db_tr = (struct fwohcidb_tr *)
malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
M_DEVBUF, M_DONTWAIT | M_ZERO);
if(db_tr == NULL){
- printf("fwochi_db_init: malloc failed\n");
+ printf("fwohci_db_init: malloc failed\n");
return;
}
db = (struct fwohcidb *)
contigmalloc(sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb,
M_DEVBUF, M_DONTWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
if(db == NULL){
- printf("fwochi_db_init: contigmalloc failed\n");
+ printf("fwohci_db_init: contigmalloc failed\n");
free(db_tr, M_DEVBUF);
return;
}
@@ -1150,6 +1153,12 @@ fwohci_db_init(struct fwohci_dbch *dbch)
}
STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
= 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->bottom = dbch->top;
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->top = STAILQ_FIRST(&dbch->db_trq);
for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
}
@@ -1526,10 +1536,9 @@ fwohci_irx_enable(struct firewire_comm *fc, int dmach)
}
int
-fwohci_shutdown(device_t dev)
+fwohci_shutdown(struct fwohci_softc *sc, device_t dev)
{
u_int i;
- struct fwohci_softc *sc = device_get_softc(dev);
/* Now stopping all DMA channel */
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_ARRQ | OHCI_INT_DMA_ARRS
| 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;
}
@@ -1814,7 +1845,7 @@ fwohci_set_intr(struct firewire_comm *fc, int enable)
sc = (struct fwohci_softc *)fc;
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) {
sc->intmask |= OHCI_INT_EN;
OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
diff --git a/sys/dev/firewire/fwohci_pci.c b/sys/dev/firewire/fwohci_pci.c
index b8e6ac2..d82382e 100644
--- a/sys/dev/firewire/fwohci_pci.c
+++ b/sys/dev/firewire/fwohci_pci.c
@@ -144,27 +144,10 @@ fwohci_dummy_intr(void *arg)
#endif
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;
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 |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
@@ -189,7 +172,33 @@ fwohci_pci_attach(device_t self)
#endif
if (bootverbose)
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;
sc->bsr = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
0, ~0, 1, RF_ACTIVE);
@@ -254,7 +263,7 @@ fwohci_pci_detach(device_t self)
s = splfw();
- fwohci_shutdown(self);
+ fwohci_shutdown(sc, self);
bus_generic_detach(self);
/* disable interrupts that might have been switched on */
@@ -300,7 +309,12 @@ fwohci_pci_detach(device_t self)
static int
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;
}
@@ -309,8 +323,19 @@ fwohci_pci_resume(device_t dev)
{
fwohci_softc_t *sc = device_get_softc(dev);
- device_printf(dev, "fwoch_pci_resume\n");
- fwohci_reset(sc, dev);
+ device_printf(dev, "fwohci_pci_resume: power_state = 0x%08x\n",
+ 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;
}
@@ -319,9 +344,9 @@ static device_method_t fwohci_methods[] = {
DEVMETHOD(device_probe, fwohci_pci_probe),
DEVMETHOD(device_attach, fwohci_pci_attach),
DEVMETHOD(device_detach, fwohci_pci_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, fwohci_pci_suspend),
DEVMETHOD(device_resume, fwohci_pci_resume),
+ DEVMETHOD(device_shutdown, fwohci_pci_shutdown),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
diff --git a/sys/dev/firewire/fwohcivar.h b/sys/dev/firewire/fwohcivar.h
index fcfa26e..5e657cf 100644
--- a/sys/dev/firewire/fwohcivar.h
+++ b/sys/dev/firewire/fwohcivar.h
@@ -70,4 +70,5 @@ void fwohci_intr __P((void *arg));
int fwohci_init __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_shutdown __P((device_t dev));
+int fwohci_resume __P((struct fwohci_softc *, device_t));
+int fwohci_shutdown __P((struct fwohci_softc *, device_t dev));
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index 681442a..ed53d03 100644
--- a/sys/dev/firewire/sbp.c
+++ b/sys/dev/firewire/sbp.c
@@ -458,7 +458,9 @@ END_DEBUG
if (reg == NULL)
break;
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)
maxlun = lun;
crom_next(&cc);
OpenPOWER on IntegriCloud