summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-01-01 04:23:54 +0000
committersimokawa <simokawa@FreeBSD.org>2003-01-01 04:23:54 +0000
commit230497406eb86bfe10e8082d585e0fdafe68baf6 (patch)
tree63d5bda907d9025b3bfb9aa3e58badbc3e7a6fae /sys
parent47963ec0410e42bb2a947f880e0b8d97f50cdee9 (diff)
downloadFreeBSD-src-230497406eb86bfe10e8082d585e0fdafe68baf6.zip
FreeBSD-src-230497406eb86bfe10e8082d585e0fdafe68baf6.tar.gz
- Retry phy access when the wait-loop count is exhausted.
- Free allocated memory when detaching. - Detect contigmalloc failure.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/firewire/fwohci.c65
-rw-r--r--sys/dev/firewire/fwohci_pci.c2
-rw-r--r--sys/dev/firewire/fwohcivar.h2
3 files changed, 64 insertions, 5 deletions
diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c
index 095ded7..2aa0020 100644
--- a/sys/dev/firewire/fwohci.c
+++ b/sys/dev/firewire/fwohci.c
@@ -321,7 +321,14 @@ again:
}
if(i >= MAX_RETRY) {
device_printf(sc->fc.dev, "cannot read phy\n");
+#if 0
return 0; /* XXX */
+#else
+ if (++retry < MAX_RETRY) {
+ DELAY(1000);
+ goto again;
+ }
+#endif
}
/* Make sure that SCLK is started */
stat = OREAD(sc, FWOHCI_INTSTAT);
@@ -457,6 +464,7 @@ fwohci_init(struct fwohci_softc *sc, device_t dev)
contigmalloc(CROMSIZE * 2, M_DEVBUF, M_NOWAIT, 0, ~0, 1<<10, 0);
if(sc->cromptr == NULL){
+ device_printf(dev, "cromptr alloc failed.");
return ENOMEM;
}
sc->fc.dev = dev;
@@ -591,15 +599,30 @@ fwohci_init(struct fwohci_softc *sc, device_t dev)
#define OHCI_SIDSIZE (1 << 11)
sc->fc.sid_buf = (u_int32_t *) vm_page_alloc_contig( OHCI_SIDSIZE,
0x10000, 0xffffffff, OHCI_SIDSIZE);
+ if (sc->fc.sid_buf == NULL) {
+ device_printf(dev, "sid_buf alloc failed.\n");
+ return ENOMEM;
+ }
+
OWRITE(sc, OHCI_SID_BUF, vtophys(sc->fc.sid_buf));
sc->fc.sid_buf++;
OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
fwohci_db_init(&sc->arrq);
+ if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
fwohci_db_init(&sc->arrs);
+ if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
fwohci_db_init(&sc->atrq);
+ if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
fwohci_db_init(&sc->atrs);
+ if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
reg = OREAD(sc, FWOHCIGUID_H);
for( i = 0 ; i < 4 ; i ++){
@@ -643,7 +666,6 @@ fwohci_init(struct fwohci_softc *sc, device_t dev)
i ++, db_tr = STAILQ_NEXT(db_tr, link)){
db_tr->xfer = NULL;
}
- sc->atrq.flags = sc->atrs.flags = 0;
OWRITE(sc, FWOHCI_RETRY,
(0xffff << 16 )| (0x0f << 8) | (0x0f << 4) | 0x0f) ;
@@ -683,6 +705,31 @@ fwohci_cyctimer(struct firewire_comm *fc)
db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
} while (0)
+int
+fwohci_detach(struct fwohci_softc *sc, device_t dev)
+{
+ int i;
+
+ if (sc->fc.sid_buf != NULL)
+ contigfree((void *)(uintptr_t)sc->fc.sid_buf,
+ OHCI_SIDSIZE, M_DEVBUF);
+ if (sc->cromptr != NULL)
+ contigfree((void *)sc->cromptr, CROMSIZE * 2, M_DEVBUF);
+
+ fwohci_db_free(&sc->arrq);
+ fwohci_db_free(&sc->arrs);
+
+ fwohci_db_free(&sc->atrq);
+ fwohci_db_free(&sc->atrs);
+
+ for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
+ fwohci_db_free(&sc->it[i]);
+ fwohci_db_free(&sc->ir[i]);
+ }
+
+ return 0;
+}
+
static void
fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
@@ -1015,21 +1062,26 @@ fwohci_db_free(struct fwohci_dbch *dbch)
struct fwohcidb_tr *db_tr;
int idb;
+ if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
+ return;
+
if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){
for(db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0;
idb < dbch->ndb;
db_tr = STAILQ_NEXT(db_tr, link), idb++){
- free(db_tr->buf, M_DEVBUF);
- db_tr->buf = NULL;
+ if (db_tr->buf != NULL) {
+ free(db_tr->buf, M_DEVBUF);
+ db_tr->buf = NULL;
+ }
}
}
dbch->ndb = 0;
db_tr = STAILQ_FIRST(&dbch->db_trq);
contigfree((void *)(uintptr_t)(volatile void *)db_tr->db,
sizeof(struct fwohcidb) * dbch->ndesc * dbch->ndb, M_DEVBUF);
- /* Attach DB to DMA ch. */
free(db_tr, M_DEVBUF);
STAILQ_INIT(&dbch->db_trq);
+ dbch->flags &= ~FWOHCI_DBCH_INIT;
}
static void
@@ -1049,8 +1101,9 @@ fwohci_db_init(struct fwohci_dbch *dbch)
STAILQ_INIT(&dbch->db_trq);
db_tr = (struct fwohcidb_tr *)
malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
- M_DEVBUF, M_DONTWAIT);
+ M_DEVBUF, M_DONTWAIT | M_ZERO);
if(db_tr == NULL){
+ printf("fwochi_db_init: malloc failed\n");
return;
}
db = (struct fwohcidb *)
@@ -1058,6 +1111,7 @@ fwohci_db_init(struct fwohci_dbch *dbch)
M_DEVBUF, M_DONTWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
if(db == NULL){
printf("fwochi_db_init: contigmalloc failed\n");
+ free(db_tr, M_DEVBUF);
return;
}
bzero(db, sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb);
@@ -1082,6 +1136,7 @@ fwohci_db_init(struct fwohci_dbch *dbch)
= STAILQ_FIRST(&dbch->db_trq);
dbch->top = STAILQ_FIRST(&dbch->db_trq);
dbch->bottom = dbch->top;
+ dbch->flags = FWOHCI_DBCH_INIT;
}
static int
diff --git a/sys/dev/firewire/fwohci_pci.c b/sys/dev/firewire/fwohci_pci.c
index ff96c28..3d5f011 100644
--- a/sys/dev/firewire/fwohci_pci.c
+++ b/sys/dev/firewire/fwohci_pci.c
@@ -288,6 +288,8 @@ fwohci_pci_detach(device_t self)
sc->bst = 0;
sc->bsh = 0;
}
+
+ fwohci_detach(sc, self);
splx(s);
return 0;
diff --git a/sys/dev/firewire/fwohcivar.h b/sys/dev/firewire/fwohcivar.h
index 6b7c954..0a77c7e 100644
--- a/sys/dev/firewire/fwohcivar.h
+++ b/sys/dev/firewire/fwohcivar.h
@@ -58,6 +58,7 @@ typedef struct fwohci_softc {
caddr_t buf;
} frag;
int flags;
+#define FWOHCI_DBCH_INIT (1<<0)
#define FWOHCI_DBCH_FULL (1<<1)
int buf_offset;
} arrq, arrs, atrq, atrs, it[OHCI_DMA_ITCH], ir[OHCI_DMA_IRCH];
@@ -67,4 +68,5 @@ typedef struct fwohci_softc {
} fwohci_softc_t;
void fwohci_intr __P((void *arg));
int fwohci_init __P((struct fwohci_softc *, device_t));
+int fwohci_detach __P((struct fwohci_softc *, device_t));
int fwohci_shutdown __P((device_t dev));
OpenPOWER on IntegriCloud