Patch by JiSheng Zhang:

* Combine the many small areas created by the Firewire bus manager
  into one larger one. Needs further testing. Supposed to fix #1519.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29396 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-03-04 12:41:05 +00:00
parent 847af0079c
commit 6acf774d2d
3 changed files with 54 additions and 53 deletions

View File

@ -134,7 +134,7 @@ static int fwohci_itx_disable (struct firewire_comm *, int);
static void fwohci_timeout (void *); static void fwohci_timeout (void *);
static void fwohci_set_intr (struct firewire_comm *, int); static void fwohci_set_intr (struct firewire_comm *, int);
static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *); static inline void fwohci_set_rx_buf(struct fw_xferq *, struct fwohcidb_tr *, bus_addr_t dbuf[], int dsiz[]);
static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int); static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
static void dump_db (struct fwohci_softc *, uint32_t); static void dump_db (struct fwohci_softc *, uint32_t);
static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t); static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
@ -1217,26 +1217,26 @@ static void
fwohci_db_free(struct fwohci_dbch *dbch) fwohci_db_free(struct fwohci_dbch *dbch)
{ {
struct fwohcidb_tr *db_tr; struct fwohcidb_tr *db_tr;
int idb; // int idb;
if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
return; return;
for(db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb; /* for(db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
db_tr = STAILQ_NEXT(db_tr, link), idb++){ db_tr = STAILQ_NEXT(db_tr, link), idb++){
/* if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 && if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
db_tr->buf != NULL) { db_tr->buf != NULL) {
fwdma_free_size(dbch->dmat, db_tr->dma_map, fwdma_free_size(dbch->dmat, db_tr->dma_map,
db_tr->buf, dbch->xferq.psize); db_tr->buf, dbch->xferq.psize);
db_tr->buf = NULL;*/ db_tr->buf = NULL;
if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 && else if (db_tr->dma_map != NULL)
db_tr->Area > B_OK) { bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
delete_area(db_tr->Area); }*/
db_tr->Area = -1; if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
dbch->Area > B_OK) {
delete_area(dbch->Area);
dbch->Area = -1;
}
/* else if (db_tr->dma_map != NULL)
bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);*/
} }
dbch->ndb = 0; dbch->ndb = 0;
db_tr = STAILQ_FIRST(&dbch->db_trq); db_tr = STAILQ_FIRST(&dbch->db_trq);
@ -1438,6 +1438,10 @@ fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
uint32_t off = 0; uint32_t off = 0;
struct fwohcidb_tr *db_tr; struct fwohcidb_tr *db_tr;
struct fwohcidb *db; struct fwohcidb *db;
void *buf_virt, *buf_phy;
struct fw_xferq *ir;
bus_addr_t dbuf[2];
int dsiz[2];
z = dbch->ndesc; z = dbch->ndesc;
if(&sc->arrq == dbch){ if(&sc->arrq == dbch){
@ -1471,8 +1475,39 @@ fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
dbch->bottom = STAILQ_NEXT(dbch->bottom, link); dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
} }
db_tr = dbch->top; db_tr = dbch->top;
ir = &dbch->xferq;
if(ir->buf == NULL && (ir->flag & FWXFERQ_EXTBUF) == 0) {
dbch->Area = alloc_mem(&buf_virt, &buf_phy,
ir->psize * dbch->ndb, 0, "fw rx Area");
if(dbch->Area < B_OK)
return(ENOMEM);
}
for (idb = 0; idb < dbch->ndb; idb ++) { for (idb = 0; idb < dbch->ndb; idb ++) {
fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma); //fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
if(ir->buf == NULL && (ir->flag & FWXFERQ_EXTBUF) == 0) {
db_tr->buf = (caddr_t)buf_virt;
dbuf[0] = (bus_addr_t)buf_phy;
db_tr->dbcnt = 1;
dsiz[0] = ir->psize;
buf_virt += ir->psize;
buf_phy += ir->psize;
} else {
db_tr->dbcnt = 0;
dsiz[db_tr->dbcnt] = sizeof(uint32_t);
dbuf[db_tr->dbcnt++] = sc->dummy_dma.bus_addr;
dsiz[db_tr->dbcnt] = ir->psize;
if (ir->buf != NULL) {
db_tr->buf = fwdma_v_addr(ir->buf, idb);
dbuf[db_tr->dbcnt] = fwdma_bus_addr(
ir->buf, idb);
}
db_tr->dbcnt++;
}
fwohci_set_rx_buf(ir, db_tr, dbuf, dsiz);
if (STAILQ_NEXT(db_tr, link) == NULL) if (STAILQ_NEXT(db_tr, link) == NULL)
break; break;
db = db_tr->db; db = db_tr->db;
@ -2566,47 +2601,13 @@ fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
return 0; return 0;
} }
int static inline void
fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, fwohci_set_rx_buf(struct fw_xferq *ir, struct fwohcidb_tr *db_tr,
int poffset, struct fwdma_alloc *dummy_dma) bus_addr_t dbuf[], int dsiz[])
{ {
struct fwohcidb *db = db_tr->db;
struct fw_xferq *ir;
int i, ldesc; int i, ldesc;
bus_addr_t dbuf[2]; struct fwohcidb *db = db_tr->db;
int dsiz[2];
void * buf_virt, *buf_phy;
ir = &dbch->xferq;
if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
/* db_tr->buf = fwdma_malloc_size(dbch->dmat, &db_tr->dma_map,
ir->psize, &dbuf[0], BUS_DMA_NOWAIT);
if (db_tr->buf == NULL)
return(ENOMEM);*/
db_tr->Area = alloc_mem(&buf_virt, &buf_phy,
MIN(ir->psize, MAX_REQCOUNT), 0, "fw ir Area");
if(db_tr->Area < B_OK)
return(ENOMEM);
db_tr->buf = (caddr_t)buf_virt;
dbuf[0] = (bus_addr_t)buf_phy;
db_tr->dbcnt = 1;
dsiz[0] = ir->psize;
/* bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
BUS_DMASYNC_PREREAD);*/
} else {
db_tr->dbcnt = 0;
if (dummy_dma != NULL) {
dsiz[db_tr->dbcnt] = sizeof(uint32_t);
dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
}
dsiz[db_tr->dbcnt] = ir->psize;
if (ir->buf != NULL) {
db_tr->buf = fwdma_v_addr(ir->buf, poffset);
dbuf[db_tr->dbcnt] = fwdma_bus_addr( ir->buf, poffset);
}
db_tr->dbcnt++;
}
for(i = 0 ; i < db_tr->dbcnt ; i++){ for(i = 0 ; i < db_tr->dbcnt ; i++){
FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]); FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]); FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
@ -2620,7 +2621,6 @@ fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST); FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
} }
FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS); FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
return 0;
} }

View File

@ -340,7 +340,6 @@ struct fwohcidb_tr{
caddr_t buf; caddr_t buf;
bus_addr_t bus_addr; bus_addr_t bus_addr;
int dbcnt; int dbcnt;
area_id Area;
}; };
/* /*

View File

@ -57,6 +57,8 @@ typedef struct fwohci_softc {
struct fwdma_alloc_multi *am; struct fwdma_alloc_multi *am;
#ifndef __HAIKU__ #ifndef __HAIKU__
bus_dma_tag_t dmat; bus_dma_tag_t dmat;
#else
area_id Area;
#endif #endif
} arrq, arrs, atrq, atrs, it[OHCI_DMA_ITCH], ir[OHCI_DMA_IRCH]; } arrq, arrs, atrq, atrs, it[OHCI_DMA_ITCH], ir[OHCI_DMA_IRCH];
u_int maxrec; u_int maxrec;