本文整理汇总了C++中bus_dmamap_sync函数的典型用法代码示例。如果您正苦于以下问题:C++ bus_dmamap_sync函数的具体用法?C++ bus_dmamap_sync怎么用?C++ bus_dmamap_sync使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了bus_dmamap_sync函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: pcscp_dma_intr
//.........这里部分代码省略.........
PCSCP_READ_REG(esc, NCR_TCM)));
return 0;
}
resid = 0;
/*
* If a transfer onto the SCSI bus gets interrupted by the device
* (e.g. for a SAVEPOINTER message), the data in the FIFO counts
* as residual since the ESP counter registers get decremented as
* bytes are clocked into the FIFO.
*/
if (!datain &&
(resid = (PCSCP_READ_REG(esc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
NCR_DMA(("%s: empty esp FIFO of %d ", __func__, resid));
}
if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
/*
* `Terminal count' is off, so read the residue
* out of the ESP counter registers.
*/
if (datain) {
resid = PCSCP_READ_REG(esc, NCR_FFLAG) & NCRFIFO_FF;
while (resid > 1)
resid =
PCSCP_READ_REG(esc, NCR_FFLAG) & NCRFIFO_FF;
WRITE_DMAREG(esc, DMA_CMD, DMACMD_BLAST | DMACMD_MDL |
(datain ? DMACMD_DIR : 0));
for (i = 0; i < 1000; i++) { /* XXX */
if (READ_DMAREG(esc, DMA_STAT) & DMASTAT_BCMP)
break;
DELAY(1);
}
/* See the below comments... */
if (resid)
p = *esc->sc_dmaaddr;
}
resid += PCSCP_READ_REG(esc, NCR_TCL) |
(PCSCP_READ_REG(esc, NCR_TCM) << 8) |
(PCSCP_READ_REG(esc, NCR_TCH) << 16);
} else {
while ((dmastat & DMASTAT_DONE) == 0)
dmastat = READ_DMAREG(esc, DMA_STAT);
}
WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE | (datain ? DMACMD_DIR : 0));
/* sync MDL */
bus_dmamap_sync(esc->sc_dmat, esc->sc_mdldmap,
0, sizeof(uint32_t) * dmap->dm_nsegs, BUS_DMASYNC_POSTWRITE);
/* sync transfer buffer */
bus_dmamap_sync(esc->sc_dmat, dmap, 0, dmap->dm_mapsize,
datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(esc->sc_dmat, dmap);
trans = esc->sc_dmasize - resid;
/*
* From the technical manual notes:
*
* `In some odd byte conditions, one residual byte will be left
* in the SCSI FIFO, and the FIFO flags will never count to 0.
* When this happens, the residual byte should be retrieved
* via PIO following completion of the BLAST operation.'
*/
if (p) {
p += trans;
*p = PCSCP_READ_REG(esc, NCR_FIFO);
trans++;
}
if (trans < 0) { /* transferred < 0 ? */
#if 0
/*
* This situation can happen in perfectly normal operation
* if the ESP is reselected while using DMA to select
* another target. As such, don't print the warning.
*/
printf("%s: xfer (%d) > req (%d)\n",
device_xname(sc->sc_dev), trans, esc->sc_dmasize);
#endif
trans = esc->sc_dmasize;
}
NCR_DMA(("%s: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
__func__,
PCSCP_READ_REG(esc, NCR_TCL),
PCSCP_READ_REG(esc, NCR_TCM),
PCSCP_READ_REG(esc, NCR_TCH),
trans, resid));
*esc->sc_dmalen -= trans;
*esc->sc_dmaaddr += trans;
return 0;
}
开发者ID:RyanLucchese,项目名称:rumpkernel-netbsd-src,代码行数:101,代码来源:pcscp.c
示例2: kr_encap
/*
* Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
* pointers to the fragment pointers.
*/
static int
kr_encap(struct kr_softc *sc, struct mbuf **m_head)
{
struct kr_txdesc *txd;
struct kr_desc *desc, *prev_desc;
bus_dma_segment_t txsegs[KR_MAXFRAGS];
uint32_t link_addr;
int error, i, nsegs, prod, si, prev_prod;
KR_LOCK_ASSERT(sc);
prod = sc->kr_cdata.kr_tx_prod;
txd = &sc->kr_cdata.kr_txdesc[prod];
error = bus_dmamap_load_mbuf_sg(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
*m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
if (error == EFBIG) {
panic("EFBIG");
} else if (error != 0)
return (error);
if (nsegs == 0) {
m_freem(*m_head);
*m_head = NULL;
return (EIO);
}
/* Check number of available descriptors. */
if (sc->kr_cdata.kr_tx_cnt + nsegs >= (KR_TX_RING_CNT - 1)) {
bus_dmamap_unload(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap);
return (ENOBUFS);
}
txd->tx_m = *m_head;
bus_dmamap_sync(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
BUS_DMASYNC_PREWRITE);
si = prod;
/*
* Make a list of descriptors for this packet. DMA controller will
* walk through it while kr_link is not zero. The last one should
* have COF flag set, to pickup next chain from NDPTR
*/
prev_prod = prod;
desc = prev_desc = NULL;
for (i = 0; i < nsegs; i++) {
desc = &sc->kr_rdata.kr_tx_ring[prod];
desc->kr_ctl = KR_DMASIZE(txsegs[i].ds_len) | KR_CTL_IOF;
if (i == 0)
desc->kr_devcs = KR_DMATX_DEVCS_FD;
desc->kr_ca = txsegs[i].ds_addr;
desc->kr_link = 0;
/* link with previous descriptor */
if (prev_desc)
prev_desc->kr_link = KR_TX_RING_ADDR(sc, prod);
sc->kr_cdata.kr_tx_cnt++;
prev_desc = desc;
KR_INC(prod, KR_TX_RING_CNT);
}
/*
* Set COF for last descriptor and mark last fragment with LD flag
*/
if (desc) {
desc->kr_ctl |= KR_CTL_COF;
desc->kr_devcs |= KR_DMATX_DEVCS_LD;
}
/* Update producer index. */
sc->kr_cdata.kr_tx_prod = prod;
/* Sync descriptors. */
bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
sc->kr_cdata.kr_tx_ring_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Start transmitting */
/* Check if new list is queued in NDPTR */
if (KR_DMA_READ_REG(KR_DMA_TXCHAN, DMA_NDPTR) == 0) {
/* NDPTR is not busy - start new list */
KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_NDPTR,
KR_TX_RING_ADDR(sc, si));
}
else {
link_addr = KR_TX_RING_ADDR(sc, si);
/* Get previous descriptor */
si = (si + KR_TX_RING_CNT - 1) % KR_TX_RING_CNT;
desc = &sc->kr_rdata.kr_tx_ring[si];
desc->kr_link = link_addr;
}
return (0);
}
开发者ID:edgar-pek,项目名称:PerspicuOS,代码行数:97,代码来源:if_kr.c
示例3: qla_lro_intr
/*
* Name: qla_lro_intr
* Function: Handles normal ethernet frames received
*/
static int
qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx)
{
qla_rx_buf_t *rxb;
struct mbuf *mp = NULL, *mpf = NULL, *mpl = NULL;
struct ifnet *ifp = ha->ifp;
qla_sds_t *sdsp;
struct ether_vlan_header *eh;
uint32_t i, rem_len = 0, pkt_length, iplen;
struct tcphdr *th;
struct ip *ip = NULL;
struct ip6_hdr *ip6 = NULL;
uint16_t etype;
uint32_t r_idx = 0;
qla_rx_ring_t *rx_ring;
if (ha->hw.num_rds_rings > 1)
r_idx = sds_idx;
ha->hw.rds[r_idx].count++;
rx_ring = &ha->rx_ring[r_idx];
ha->lro_pkt_count++;
sdsp = &ha->hw.sds[sds_idx];
pkt_length = sgc->payload_length + sgc->l4_offset;
if (sgc->flags & Q8_LRO_COMP_TS) {
pkt_length += QLA_TCP_HDR_SIZE + QLA_TCP_TS_OPTION_SIZE;
} else {
pkt_length += QLA_TCP_HDR_SIZE;
}
ha->lro_bytes += pkt_length;
for (i = 0; i < sgc->num_handles; i++) {
rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF];
QL_ASSERT(ha, (rxb != NULL),
("%s: [sds_idx]=[%d] rxb != NULL\n", __func__,\
sds_idx));
if ((rxb == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_RXB_INVAL)) {
/* log the error */
device_printf(ha->pci_dev,
"%s invalid rxb[%d, %d, 0x%04x]\n",
__func__, sds_idx, i, sgc->handle[i]);
qla_rcv_error(ha);
return (0);
}
mp = rxb->m_head;
if (i == 0)
mpf = mp;
QL_ASSERT(ha, (mp != NULL),
("%s: [sds_idx]=[%d] mp != NULL\n", __func__,\
sds_idx));
bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_POSTREAD);
rxb->m_head = NULL;
rxb->next = sdsp->rxb_free;
sdsp->rxb_free = rxb;
sdsp->rx_free++;
if ((mp == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_MP_NULL)) {
/* log the error */
device_printf(ha->pci_dev,
"%s mp == NULL [%d, %d, 0x%04x]\n",
__func__, sds_idx, i, sgc->handle[i]);
qla_rcv_error(ha);
return (0);
}
if (i == 0) {
mpl = mpf = mp;
mp->m_flags |= M_PKTHDR;
mp->m_pkthdr.len = pkt_length;
mp->m_pkthdr.rcvif = ifp;
rem_len = mp->m_pkthdr.len;
} else {
mp->m_flags &= ~M_PKTHDR;
mpl->m_next = mp;
mpl = mp;
rem_len = rem_len - mp->m_len;
}
}
mpl->m_len = rem_len;
th = (struct tcphdr *)(mpf->m_data + sgc->l4_offset);
if (sgc->flags & Q8_LRO_COMP_PUSH_BIT)
th->th_flags |= TH_PUSH;
//.........这里部分代码省略.........
开发者ID:Digital-Chaos,项目名称:freebsd,代码行数:101,代码来源:ql_isr.c
示例4: kr_tx
static void
kr_tx(struct kr_softc *sc)
{
struct kr_txdesc *txd;
struct kr_desc *cur_tx;
struct ifnet *ifp;
uint32_t ctl, devcs;
int cons, prod;
KR_LOCK_ASSERT(sc);
cons = sc->kr_cdata.kr_tx_cons;
prod = sc->kr_cdata.kr_tx_prod;
if (cons == prod)
return;
bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
sc->kr_cdata.kr_tx_ring_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
ifp = sc->kr_ifp;
/*
* Go through our tx list and free mbufs for those
* frames that have been transmitted.
*/
for (; cons != prod; KR_INC(cons, KR_TX_RING_CNT)) {
cur_tx = &sc->kr_rdata.kr_tx_ring[cons];
ctl = cur_tx->kr_ctl;
devcs = cur_tx->kr_devcs;
/* Check if descriptor has "finished" flag */
if ((ctl & KR_CTL_F) == 0)
break;
sc->kr_cdata.kr_tx_cnt--;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
txd = &sc->kr_cdata.kr_txdesc[cons];
if (devcs & KR_DMATX_DEVCS_TOK)
ifp->if_opackets++;
else {
ifp->if_oerrors++;
/* collisions: medium busy, late collision */
if ((devcs & KR_DMATX_DEVCS_EC) ||
(devcs & KR_DMATX_DEVCS_LC))
ifp->if_collisions++;
}
bus_dmamap_sync(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap);
/* Free only if it's first descriptor in list */
if (txd->tx_m)
m_freem(txd->tx_m);
txd->tx_m = NULL;
/* reset descriptor */
cur_tx->kr_ctl = KR_CTL_IOF;
cur_tx->kr_devcs = 0;
cur_tx->kr_ca = 0;
cur_tx->kr_link = 0;
}
sc->kr_cdata.kr_tx_cons = cons;
bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
sc->kr_cdata.kr_tx_ring_map, BUS_DMASYNC_PREWRITE);
}
开发者ID:edgar-pek,项目名称:PerspicuOS,代码行数:69,代码来源:if_kr.c
示例5: qlw_handle_resp
struct qlw_ccb *
qlw_handle_resp(struct qlw_softc *sc, u_int16_t id)
{
struct qlw_ccb *ccb;
struct qlw_iocb_hdr *hdr;
struct qlw_iocb_status *status;
struct scsi_xfer *xs;
u_int32_t handle;
int entry_type;
int flags;
int bus;
ccb = NULL;
hdr = QLW_DMA_KVA(sc->sc_responses) + (id * QLW_QUEUE_ENTRY_SIZE);
bus_dmamap_sync(sc->sc_dmat,
QLW_DMA_MAP(sc->sc_responses), id * QLW_QUEUE_ENTRY_SIZE,
QLW_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTREAD);
qlw_get_header(sc, hdr, &entry_type, &flags);
switch (entry_type) {
case QLW_IOCB_STATUS:
status = (struct qlw_iocb_status *)hdr;
handle = qlw_swap32(sc, status->handle);
if (handle > sc->sc_maxccbs) {
panic("bad completed command handle: %d (> %d)",
handle, sc->sc_maxccbs);
}
ccb = &sc->sc_ccbs[handle];
xs = ccb->ccb_xs;
if (xs == NULL) {
DPRINTF(QLW_D_INTR, "%s: got status for inactive"
" ccb %d\n", DEVNAME(sc), handle);
qlw_dump_iocb(sc, hdr, QLW_D_INTR);
ccb = NULL;
break;
}
if (xs->io != ccb) {
panic("completed command handle doesn't match xs "
"(handle %d, ccb %p, xs->io %p)", handle, ccb,
xs->io);
}
if (xs->datalen > 0) {
bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
ccb->ccb_dmamap->dm_mapsize,
(xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
}
bus = qlw_xs_bus(sc, xs);
xs->status = qlw_swap16(sc, status->scsi_status);
switch (qlw_swap16(sc, status->completion)) {
case QLW_IOCB_STATUS_COMPLETE:
if (qlw_swap16(sc, status->scsi_status) &
QLW_SCSI_STATUS_SENSE_VALID) {
memcpy(&xs->sense, status->sense_data,
sizeof(xs->sense));
xs->error = XS_SENSE;
} else {
xs->error = XS_NOERROR;
}
xs->resid = 0;
break;
case QLW_IOCB_STATUS_INCOMPLETE:
if (flags & QLW_STATE_GOT_TARGET) {
xs->error = XS_DRIVER_STUFFUP;
} else {
xs->error = XS_SELTIMEOUT;
}
break;
case QLW_IOCB_STATUS_DMA_ERROR:
DPRINTF(QLW_D_INTR, "%s: dma error\n", DEVNAME(sc));
/* set resid apparently? */
break;
case QLW_IOCB_STATUS_RESET:
DPRINTF(QLW_D_INTR, "%s: reset destroyed command\n",
DEVNAME(sc));
sc->sc_marker_required[bus] = 1;
xs->error = XS_RESET;
break;
case QLW_IOCB_STATUS_ABORTED:
DPRINTF(QLW_D_INTR, "%s: aborted\n", DEVNAME(sc));
sc->sc_marker_required[bus] = 1;
xs->error = XS_DRIVER_STUFFUP;
break;
case QLW_IOCB_STATUS_TIMEOUT:
DPRINTF(QLW_D_INTR, "%s: command timed out\n",
DEVNAME(sc));
xs->error = XS_TIMEOUT;
break;
case QLW_IOCB_STATUS_DATA_OVERRUN:
//.........这里部分代码省略.........
开发者ID:DavidAlphaFox,项目名称:openbsd-kernel,代码行数:101,代码来源:qlw.c
示例6: sq_rxintr
static int
sq_rxintr(struct sq_softc *sc)
{
int count = 0;
struct mbuf* m;
int i, framelen;
u_int8_t pktstat;
u_int32_t status;
int new_end, orig_end;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
for(i = sc->sc_nextrx;; i = SQ_NEXTRX(i)) {
SQ_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/* If this is a CPU-owned buffer, we're at the end of the list */
if (sc->sc_rxdesc[i].hdd_ctl & HDD_CTL_OWN) {
#if 0
u_int32_t reg;
reg = bus_space_read_4(sc->sc_hpct, sc->sc_hpch,
HPC_ENETR_CTL);
printf("%s: rxintr: done at %d (ctl %08x)\n",
sc->sc_dev.dv_xname, i, reg);
#endif
break;
}
count++;
m = sc->sc_rxmbuf[i];
framelen = m->m_ext.ext_size -
HDD_CTL_BYTECNT(sc->sc_rxdesc[i].hdd_ctl) - 3;
/* Now sync the actual packet data */
bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0,
sc->sc_rxmap[i]->dm_mapsize, BUS_DMASYNC_POSTREAD);
pktstat = *((u_int8_t*)m->m_data + framelen + 2);
if ((pktstat & RXSTAT_GOOD) == 0) {
ifp->if_ierrors++;
if (pktstat & RXSTAT_OFLOW)
printf("%s: receive FIFO overflow\n",
sc->sc_dev.dv_xname);
bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0,
sc->sc_rxmap[i]->dm_mapsize,
BUS_DMASYNC_PREREAD);
SQ_INIT_RXDESC(sc, i);
continue;
}
if (sq_add_rxbuf(sc, i) != 0) {
ifp->if_ierrors++;
bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0,
sc->sc_rxmap[i]->dm_mapsize,
BUS_DMASYNC_PREREAD);
SQ_INIT_RXDESC(sc, i);
continue;
}
m->m_data += 2;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = framelen;
ifp->if_ipackets++;
#if 0
printf("%s: sq_rxintr: buf %d len %d\n", sc->sc_dev.dv_xname,
i, framelen);
#endif
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
#endif
(*ifp->if_input)(ifp, m);
}
/* If anything happened, move ring start/end pointers to new spot */
if (i != sc->sc_nextrx) {
new_end = SQ_PREVRX(i);
sc->sc_rxdesc[new_end].hdd_ctl |= HDD_CTL_EOCHAIN;
SQ_CDRXSYNC(sc, new_end, BUS_DMASYNC_PREREAD |
BUS_DMASYNC_PREWRITE);
orig_end = SQ_PREVRX(sc->sc_nextrx);
sc->sc_rxdesc[orig_end].hdd_ctl &= ~HDD_CTL_EOCHAIN;
SQ_CDRXSYNC(sc, orig_end, BUS_DMASYNC_PREREAD |
BUS_DMASYNC_PREWRITE);
sc->sc_nextrx = i;
}
status = bus_space_read_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETR_CTL);
/* If receive channel is stopped, restart it... */
//.........这里部分代码省略.........
开发者ID:MarginC,项目名称:kame,代码行数:101,代码来源:if_sq.c
示例7: sq_txintr
static int
sq_txintr(struct sq_softc *sc)
{
int i;
u_int32_t status;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
status = bus_space_read_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETX_CTL);
SQ_TRACE(SQ_TXINTR_ENTER, sc->sc_prevtx, status, sc->sc_nfreetx);
if ((status & (ENETX_CTL_ACTIVE | TXSTAT_GOOD)) == 0) {
if (status & TXSTAT_COLL)
ifp->if_collisions++;
if (status & TXSTAT_UFLOW) {
printf("%s: transmit underflow\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
}
if (status & TXSTAT_16COLL) {
printf("%s: max collisions reached\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
ifp->if_collisions += 16;
}
}
i = sc->sc_prevtx;
while (sc->sc_nfreetx < SQ_NTXDESC) {
/*
* Check status first so we don't end up with a case of
* the buffer not being finished while the DMA channel
* has gone idle.
*/
status = bus_space_read_4(sc->sc_hpct, sc->sc_hpch,
HPC_ENETX_CTL);
SQ_CDTXSYNC(sc, i, sc->sc_txmap[i]->dm_nsegs,
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
/* If not yet transmitted, try and start DMA engine again */
if ((sc->sc_txdesc[i].hdd_ctl & HDD_CTL_XMITDONE) == 0) {
if ((status & ENETX_CTL_ACTIVE) == 0) {
SQ_TRACE(SQ_RESTART_DMA, i, status,
sc->sc_nfreetx);
bus_space_write_4(sc->sc_hpct, sc->sc_hpch,
HPC_ENETX_NDBP, SQ_CDTXADDR(sc, i));
/* Kick DMA channel into life */
bus_space_write_4(sc->sc_hpct, sc->sc_hpch,
HPC_ENETX_CTL, ENETX_CTL_ACTIVE);
/*
* Set a watchdog timer in case the chip
* flakes out.
*/
ifp->if_timer = 5;
} else {
SQ_TRACE(SQ_TXINTR_BUSY, i, status,
sc->sc_nfreetx);
}
break;
}
/* Sync the packet data, unload DMA map, free mbuf */
bus_dmamap_sync(sc->sc_dmat, sc->sc_txmap[i], 0,
sc->sc_txmap[i]->dm_mapsize,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_dmat, sc->sc_txmap[i]);
m_freem(sc->sc_txmbuf[i]);
sc->sc_txmbuf[i] = NULL;
ifp->if_opackets++;
sc->sc_nfreetx++;
SQ_TRACE(SQ_DONE_DMA, i, status, sc->sc_nfreetx);
i = SQ_NEXTTX(i);
}
/* prevtx now points to next xmit packet not yet finished */
sc->sc_prevtx = i;
/* If we have buffers free, let upper layers know */
if (sc->sc_nfreetx > 0)
ifp->if_flags &= ~IFF_OACTIVE;
/* If all packets have left the coop, cancel watchdog */
if (sc->sc_nfreetx == SQ_NTXDESC)
ifp->if_timer = 0;
SQ_TRACE(SQ_TXINTR_EXIT, sc->sc_prevtx, status, sc->sc_nfreetx);
sq_start(ifp);
return 1;
}
开发者ID:MarginC,项目名称:kame,代码行数:96,代码来源:if_sq.c
示例8: lsi64854_scsi_intr
//.........这里部分代码省略.........
DDMACSR_BITS);
csr &= ~D_EN_DMA; /* Stop DMA. */
/* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
csr |= D_INVALIDATE | D_SLAVE_ERR;
L64854_SCSR(sc, csr);
return (-1);
}
/* This is an "assertion" :) */
if (sc->sc_active == 0)
panic("%s: DMA wasn't active", __func__);
DMA_DRAIN(sc, 0);
/* DMA has stopped */
csr &= ~D_EN_DMA;
L64854_SCSR(sc, csr);
sc->sc_active = 0;
dmasize = sc->sc_dmasize;
if (dmasize == 0) {
/* A "Transfer Pad" operation completed. */
DPRINTF(LDB_SCSI, ("%s: discarded %d bytes (tcl=%d, "
"tcm=%d)\n", __func__, NCR_READ_REG(nsc, NCR_TCL) |
(NCR_READ_REG(nsc, NCR_TCM) << 8),
NCR_READ_REG(nsc, NCR_TCL), NCR_READ_REG(nsc, NCR_TCM)));
return (0);
}
resid = 0;
/*
* If a transfer onto the SCSI bus gets interrupted by the device
* (e.g. for a SAVEPOINTER message), the data in the FIFO counts
* as residual since the NCR53C9X counter registers get decremented
* as bytes are clocked into the FIFO.
*/
if ((csr & D_WRITE) == 0 &&
(resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
DPRINTF(LDB_SCSI, ("%s: empty esp FIFO of %d ", __func__,
resid));
if (nsc->sc_rev == NCR_VARIANT_FAS366 &&
(NCR_READ_REG(nsc, NCR_CFG3) & NCRFASCFG3_EWIDE))
resid <<= 1;
}
if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
lxfer = nsc->sc_features & NCR_F_LARGEXFER;
/*
* "Terminal count" is off, so read the residue
* out of the NCR53C9X counter registers.
*/
resid += (NCR_READ_REG(nsc, NCR_TCL) |
(NCR_READ_REG(nsc, NCR_TCM) << 8) |
(lxfer != 0 ? (NCR_READ_REG(nsc, NCR_TCH) << 16) : 0));
if (resid == 0 && dmasize == 65536 && lxfer == 0)
/* A transfer of 64k is encoded as TCL=TCM=0. */
resid = 65536;
}
trans = dmasize - resid;
if (trans < 0) { /* transferred < 0? */
#if 0
/*
* This situation can happen in perfectly normal operation
* if the ESP is reselected while using DMA to select
* another target. As such, don't print the warning.
*/
device_printf(sc->sc_dev, "xfer (%d) > req (%d)\n", trans,
dmasize);
#endif
trans = dmasize;
}
DPRINTF(LDB_SCSI, ("%s: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
__func__, NCR_READ_REG(nsc, NCR_TCL), NCR_READ_REG(nsc, NCR_TCM),
(nsc->sc_features & NCR_F_LARGEXFER) != 0 ?
NCR_READ_REG(nsc, NCR_TCH) : 0, trans, resid));
if (dmasize != 0) {
dmat = sc->sc_buffer_dmat;
dmam = sc->sc_dmamap;
bus_dmamap_sync(dmat, dmam, (csr & D_WRITE) != 0 ?
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(dmat, dmam);
}
*sc->sc_dmalen -= trans;
*sc->sc_dmaaddr = (char *)*sc->sc_dmaaddr + trans;
#if 0 /* this is not normal operation just yet */
if (*sc->sc_dmalen == 0 || nsc->sc_phase != nsc->sc_prevphase)
return (0);
/* and again */
dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE);
return (1);
#endif
return (0);
}
开发者ID:coyizumi,项目名称:cs111,代码行数:101,代码来源:lsi64854.c
示例9: sq_start
//.........这里部分代码省略.........
/*
* Ensure we have enough descriptors free to describe
* the packet.
*/
if (dmamap->dm_nsegs > sc->sc_nfreetx) {
/*
* Not enough free descriptors to transmit this
* packet. We haven't committed to anything yet,
* so just unload the DMA map, put the packet
* back on the queue, and punt. Notify the upper
* layer that there are no more slots left.
*
* XXX We could allocate an mbuf and copy, but
* XXX it is worth it?
*/
ifp->if_flags |= IFF_OACTIVE;
bus_dmamap_unload(sc->sc_dmat, dmamap);
if (m != NULL)
m_freem(m);
break;
}
IFQ_DEQUEUE(&ifp->if_snd, m0);
if (m != NULL) {
m_freem(m0);
m0 = m;
}
/*
* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
*/
/* Sync the DMA map. */
bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
BUS_DMASYNC_PREWRITE);
/*
* Initialize the transmit descriptors.
*/
for (nexttx = sc->sc_nexttx, seg = 0, totlen = 0;
seg < dmamap->dm_nsegs;
seg++, nexttx = SQ_NEXTTX(nexttx)) {
sc->sc_txdesc[nexttx].hdd_bufptr =
dmamap->dm_segs[seg].ds_addr;
sc->sc_txdesc[nexttx].hdd_ctl =
dmamap->dm_segs[seg].ds_len;
sc->sc_txdesc[nexttx].hdd_descptr=
SQ_CDTXADDR(sc, SQ_NEXTTX(nexttx));
lasttx = nexttx;
totlen += dmamap->dm_segs[seg].ds_len;
}
/* Last descriptor gets end-of-packet */
sc->sc_txdesc[lasttx].hdd_ctl |= HDD_CTL_EOPACKET;
/* XXXrkb: if not EDLC, pad to min len manually */
if (totlen < ETHER_MIN_LEN) {
sc->sc_txdesc[lasttx].hdd_ctl += (ETHER_MIN_LEN - totlen);
totlen = ETHER_MIN_LEN;
}
#if 0
printf("%s: transmit %d-%d, len %d\n", sc->sc_dev.dv_xname,
sc->sc_nexttx, lasttx,
totlen);
#endif
开发者ID:MarginC,项目名称:kame,代码行数:67,代码来源:if_sq.c
示例10: lsi64854_reset
static void
lsi64854_reset(struct lsi64854_softc *sc)
{
bus_dma_tag_t dmat;
bus_dmamap_t dmam;
uint32_t csr;
DMA_FLUSH(sc, 1);
csr = L64854_GCSR(sc);
DPRINTF(LDB_ANY, ("%s: csr 0x%x\n", __func__, csr));
if (sc->sc_dmasize != 0) {
dmat = sc->sc_buffer_dmat;
dmam = sc->sc_dmamap;
bus_dmamap_sync(dmat, dmam, (csr & D_WRITE) != 0 ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
bus_dmamap_unload(dmat, dmam);
}
if (sc->sc_rev == DMAREV_HME)
L64854_SCSR(sc, csr | D_HW_RESET_FAS366);
csr |= L64854_RESET; /* reset DMA */
L64854_SCSR(sc, csr);
DELAY(200); /* > 10 Sbus clocks(?) */
/*DMAWAIT1(sc); why was this here? */
csr = L64854_GCSR(sc);
csr &= ~L64854_RESET; /* de-assert reset line */
L64854_SCSR(sc, csr);
DELAY(5); /* allow a few ticks to settle */
csr = L64854_GCSR(sc);
csr |= L64854_INT_EN; /* enable interrupts */
if (sc->sc_rev > DMAREV_1 && sc->sc_channel == L64854_CHANNEL_SCSI) {
if (sc->sc_rev == DMAREV_HME)
csr |= D_TWO_CYCLE;
else
csr |= D_FASTER;
}
/* Set burst */
switch (sc->sc_rev) {
case DMAREV_HME:
case DMAREV_2:
csr &= ~L64854_BURST_SIZE;
if (sc->sc_burst == 32)
csr |= L64854_BURST_32;
else if (sc->sc_burst == 16)
csr |= L64854_BURST_16;
else
csr |= L64854_BURST_0;
break;
case DMAREV_ESC:
csr |= D_ESC_AUTODRAIN; /* Auto-drain */
if (sc->sc_burst == 32)
csr &= ~D_ESC_BURST;
else
csr |= D_ESC_BURST;
break;
default:
break;
}
L64854_SCSR(sc, csr);
if (sc->sc_rev == DMAREV_HME) {
bus_write_4(sc->sc_res, L64854_REG_ADDR, 0);
sc->sc_dmactl = csr;
}
sc->sc_active = 0;
DPRINTF(LDB_ANY, ("%s: done, csr 0x%x\n", __func__, csr));
}
开发者ID:coyizumi,项目名称:cs111,代码行数:74,代码来源:lsi64854.c
示例11: sata_channel_begin_transaction
static int
sata_channel_begin_transaction(struct ata_request *request)
{
struct sata_softc *sc;
struct ata_channel *ch;
struct sata_crqb *crqb;
uint32_t req_in;
int error, slot;
sc = device_get_softc(device_get_parent(request->parent));
ch = device_get_softc(request->parent);
mtx_assert(&ch->state_mtx, MA_OWNED);
/* Only DMA R/W goes through the EDMA machine. */
if (request->u.ata.command != ATA_READ_DMA &&
request->u.ata.command != ATA_WRITE_DMA &&
request->u.ata.command != ATA_READ_DMA48 &&
request->u.ata.command != ATA_WRITE_DMA48) {
/* Disable EDMA before accessing legacy registers */
if (sata_edma_is_running(request->parent)) {
error = sata_edma_ctrl(request->parent, 0);
if (error) {
request->result = error;
return (ATA_OP_FINISHED);
}
}
return (ata_begin_transaction(request));
}
/* Prepare data for DMA */
if ((error = ch->dma.load(request, NULL, NULL))) {
device_printf(request->parent, "setting up DMA failed!\n");
request->result = error;
return ATA_OP_FINISHED;
}
/* Get next free queue slot */
req_in = SATA_INL(sc, SATA_EDMA_REQIPR(ch->unit));
slot = (req_in & sc->sc_edma_reqis_mask) >> SATA_EDMA_REQIS_OFS;
crqb = (struct sata_crqb *)(ch->dma.work +
(slot << SATA_EDMA_REQIS_OFS));
/* Fill in request */
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
crqb->crqb_prdlo = htole32((uint64_t)request->dma->sg_bus & 0xFFFFFFFF);
crqb->crqb_prdhi = htole32((uint64_t)request->dma->sg_bus >> 32);
crqb->crqb_flags = htole32((request->flags & ATA_R_READ ? 0x01 : 0x00) |
(request->tag << 1));
crqb->crqb_ata_command = request->u.ata.command;
crqb->crqb_ata_feature = request->u.ata.feature;
crqb->crqb_ata_lba_low = request->u.ata.lba;
crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24;
crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32;
crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40;
crqb->crqb_ata_feature_p = request->u.ata.feature >> 8;
crqb->crqb_ata_count = request->u.ata.count;
crqb->crqb_ata_count_p = request->u.ata.count >> 8;
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Enable EDMA if disabled */
if (!sata_edma_is_running(request->parent)) {
error = sata_edma_ctrl(request->parent, 1);
if (error) {
ch->dma.unload(request);
request->result = error;
return (ATA_OP_FINISHED);
}
}
/* Tell EDMA about new request */
req_in = (req_in & ~sc->sc_edma_reqis_mask) | (((slot + 1) <<
SATA_EDMA_REQIS_OFS) & sc->sc_edma_reqis_mask);
SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), req_in);
return (ATA_OP_CONTINUES);
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:88,代码来源:mv_sata.c
示例12: sata_channel_attach
static int
sata_channel_attach(device_t dev)
{
struct sata_softc *sc;
struct ata_channel *ch;
uint64_t work;
int error, i;
sc = device_get_softc(device_get_parent(dev));
ch = device_get_softc(dev);
if (ch->attached)
return (0);
ch->dev = dev;
ch->unit = device_get_unit(dev);
ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA;
/* Set legacy ATA resources. */
for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
ch->r_io[i].res = sc->sc_mem_res;
ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2);
}
ch->r_io[ATA_CONTROL].res = sc->sc_mem_res;
ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit);
ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res;
ata_default_registers(dev);
/* Set SATA resources. */
ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res;
ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit);
ch->r_io[ATA_SERROR].res = sc->sc_mem_res;
ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit);
ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res;
ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit);
ata_generic_hw(dev);
ch->hw.begin_transaction = sata_channel_begin_transaction;
ch->hw.end_transaction = sata_channel_end_transaction;
ch->hw.status = sata_channel_status;
/* Set DMA resources */
ata_dmainit(dev);
ch->dma.setprd = sata_channel_dmasetprd;
/* Clear work area */
KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
sizeof(struct sata_crpb)) <= ch->dma.max_iosize,
("insufficient DMA memory for request/response queues.\n"));
bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
sizeof(struct sata_crpb)));
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Turn off EDMA engine */
error = sata_edma_ctrl(dev, 0);
if (error) {
ata_dmafini(dev);
return (error);
}
/*
* Initialize EDMA engine:
* - Native Command Queuing off,
* - Non-Queued operation,
* - Host Queue Cache enabled.
*/
SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE |
(sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0);
/* Set request queue pointers */
work = ch->dma.work_bus;
SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32);
SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF);
SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF);
/* Set response queue pointers */
work += sc->sc_edma_qlen * sizeof(struct sata_crqb);
SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32);
SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF);
SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF);
/* Clear any outstanding interrupts */
ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
SATA_OUTL(sc, SATA_ICR,
~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit)));
/* Umask channel interrupts */
SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) |
SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
SATA_MICR_ERR(ch->unit));
ch->attached = 1;
return (ata_attach(dev));
//.........这里部分代码省略.........
开发者ID:Alkzndr,项目名称:freebsd,代码行数:101,代码来源:mv_sata.c
示例13: ahadone
static void
ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code)
{
union ccb *ccb;
struct ccb_scsiio *csio;
ccb = accb->ccb;
csio = &accb->ccb->csio;
if ((accb->flags & ACCB_ACTIVE) == 0) {
device_printf(aha->dev,
"ahadone - Attempt to free non-active ACCB %p\n",
(void *)accb);
return;
}
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
op = BUS_DMASYNC_POSTREAD;
else
op = BUS_DMASYNC_POSTWRITE;
bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op);
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
}
if (accb == aha->recovery_accb) {
/*
* The recovery ACCB does not have a CCB associated
* with it, so short circuit the normal error handling.
* We now traverse our list of pending CCBs and process
* any that were terminated by the recovery CCBs action.
* We also reinstate timeouts for all remaining, pending,
* CCBs.
*/
struct cam_path *path;
struct ccb_hdr *ccb_h;
cam_status error;
/* Notify all clients that a BDR occurred */
error = xpt_create_path(&path, /*periph*/NULL,
cam_sim_path(aha->sim), accb->hccb.target,
CAM_LUN_WILDCARD);
if (error == CAM_REQ_CMP) {
xpt_async(AC_SENT_BDR, path, NULL);
xpt_free_path(path);
}
ccb_h = LIST_FIRST(&aha->pending_ccbs);
while (ccb_h != NULL) {
struct aha_ccb *pending_accb;
pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
if (pending_accb->hccb.target == accb->hccb.target) {
pending_accb->hccb.ahastat = AHASTAT_HA_BDR;
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
ahadone(aha, pending_accb, AMBI_ERROR);
} else {
callout_reset_sbt(&pending_accb->timer,
SBT_1MS * ccb_h->timeout, 0, ahatimeout,
pending_accb, 0);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
device_printf(aha->dev, "No longer in timeout\n");
return;
}
callout_stop(&accb->timer);
switch (comp_code) {
case AMBI_FREE:
device_printf(aha->dev,
"ahadone - CCB completed with free status!\n");
break;
case AMBI_NOT_FOUND:
device_printf(aha->dev,
"ahadone - CCB Abort failed to find CCB\n");
break;
case AMBI_ABORT:
case AMBI_ERROR:
/* An error occurred */
if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
csio->resid = 0;
else
csio->resid = aha_a24tou(accb->hccb.data_len);
switch(accb->hccb.ahastat) {
case AHASTAT_DATARUN_ERROR:
{
if (csio->resid <= 0) {
csio->ccb_h.status = CAM_DATA_RUN_ERR;
break;
}
/* FALLTHROUGH */
}
case AHASTAT_NOERROR:
csio->scsi_status = accb->hccb.sdstat;
csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
//.........这里部分代码省略.........
开发者ID:2trill2spill,项目名称:freebsd,代码行数:101,代码来源:aha.c
示例14: ahaexecuteccb
static void
ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
struct aha_ccb *accb;
union ccb *ccb;
struct aha_softc *aha;
uint32_t paddr;
accb = (struct aha_ccb *)arg;
ccb = accb->ccb;
aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
if (error != 0) {
if (error != EFBIG)
device_printf(aha->dev,
"Unexepected error 0x%x returned from "
"bus_dmamap_load\n", error);
if (ccb->ccb_h.status == CAM_REQ_INPROG) {
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
}
ahafreeccb(aha, accb);
xpt_done(ccb);
return;
}
if (nseg != 0) {
aha_sg_t *sg;
bus_dma_segment_t *end_seg;
bus_dmasync_op_t op;
end_seg = dm_segs + nseg;
/* Copy the segments into our SG list */
sg = accb->sg_list;
while (dm_segs < end_seg) {
ahautoa24(dm_segs->ds_len, sg->len);
ahautoa24(dm_segs->ds_addr, sg->addr);
sg++;
dm_segs++;
}
if (nseg > 1) {
accb->hccb.opcode = aha->ccb_sg_opcode;
ahautoa24((sizeof(aha_sg_t) * nseg),
accb->hccb.data_len);
ahautoa24(accb->sg_list_phys, accb->hccb.data_addr);
} else {
bcopy(accb->sg_list->len, accb->hccb.data_len, 3);
bcopy(accb->sg_list->addr, accb->hccb.data_addr, 3);
}
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
op = BUS_DMASYNC_PREREAD;
else
op = BUS_DMASYNC_PREWRITE;
bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op);
} else {
accb->hccb.opcode = INITIATOR_CCB;
ahautoa24(0, accb->hccb.data_len);
ahautoa24(0, accb->hccb.data_addr);
}
/*
* Last time we need to check if this CCB needs to
* be aborted.
*/
if (ccb->ccb_h.status != CAM_REQ_INPROG) {
if (nseg != 0)
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
xpt_done(ccb);
return;
}
accb->flags = ACCB_ACTIVE;
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
callout_reset_sbt(&accb->timer, SBT_1MS * ccb->ccb_h.timeout, 0,
ahatimeout, accb, 0);
/* Tell the adapter about this command */
if (aha->cur_outbox->action_code != AMBO_FREE) {
/*
* We should never encounter a busy mailbox.
* If we do, warn the user, and treat it as
* a resource shortage. If the controller is
* hung, one of the pending transactions will
* timeout causing us to start recovery operations.
*/
device_printf(aha->dev,
"Encountered busy mailbox with %d out of %d "
"commands active!!!", aha->active_ccbs, aha->max_ccbs);
callout_stop(&accb->timer);
if (nseg != 0)
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
//.........这里部分代码省略.........
开发者ID:2trill2spill,项目名称:freebsd,代码行数:101,代码来源:aha.c
示例15: bce_start
/* Start packet transmission on the interface. */
static void
bce_start(struct ifnet *ifp)
{
struct bce_softc *sc = ifp->if_softc;
struct mbuf *m0;
bus_dmamap_t dmamap;
int txstart;
int txsfree;
int newpkts = 0;
int error;
/*
* do not start another if currently transmitting, and more
* descriptors(tx slots) are needed for next packet.
*/
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
/* determine number of descriptors available */
if (sc->bce_txsnext >= sc->bce_txin)
txsfree = BCE_NTXDESC - 1 + sc->bce_txin - sc->bce_txsnext;
else
txsfree = sc->bce_txin - sc->bce_txsnext - 1;
/*
* Loop through the send queue, setting up transmit descriptors
* until we drain the queue, or use up all available transmit
* descriptors.
*/
while (txsfree > 0) {
int seg;
/* Grab a packet off the queue. */
IFQ_POLL(&ifp->if_snd, m0);
if (m0 == NULL)
break;
/* get the transmit slot dma map */
dmamap = sc->bce_cdata.bce_tx_map[sc->bce_txsnext];
/*
* Load the DMA map. If this fails, the packet either
* didn't fit in the alloted number of segments, or we
* were short on resources. If the packet will not fit,
* it will be dropped. If short on resources, it will
* be tried again later.
*/
error = bus_dmamap_load_mbuf(sc->bce_dmatag, dmamap, m0,
BUS_DMA_WRITE | BUS_DMA_NOWAIT);
if (error == EFBIG) {
aprint_error_dev(sc->bce_dev,
"Tx packet consumes too many DMA segments, "
"dropping...\n");
IFQ_DEQUEUE(&ifp->if_snd, m0);
m_freem(m0);
ifp->if_oerrors++;
continue;
} else if (error) {
/* short on resources, come back later */
aprint_error_dev(sc->bce_dev,
"unable to load Tx buffer, error = %d\n",
error);
break;
}
/* If not enough descriptors available, try again later */
if (dmamap->dm_nsegs > txsfree) {
ifp->if_flags |= IFF_OACTIVE;
bus_dmamap_unload(sc->bce_dmatag, dmamap);
break;
}
/* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. */
/* So take it off the queue */
IFQ_DEQUEUE(&ifp->if_snd, m0);
/* save the pointer so it can be freed later */
sc->bce_cdata.bce_tx_chain[sc->bce_txsnext] = m0;
/* Sync the data DMA map. */
bus_dmamap_sync(sc->bce_dmatag, dmamap, 0, dmamap->dm_mapsize,
BUS_DMASYNC_PREWRITE);
/* Initialize the transmit descriptor(s). */
txstart = sc->bce_txsnext;
for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
uint32_t ctrl;
ctrl = dmamap->dm_segs[seg].ds_len & CTRL_BC_MASK;
if (seg == 0)
ctrl |= CTRL_SOF;
if (seg == dmamap->dm_nsegs - 1)
ctrl |= CTRL_EOF;
if (sc->bce_txsnext == BCE_NTXDESC - 1)
ctrl |= CTRL_EOT;
ctrl |= CTRL_IOC;
sc->bce_tx_ring[sc->bce_txsnext].ctrl = htole32(ctrl);
sc->bce_tx_ring[sc->bce_txsnext].addr =
htole32(dmamap->dm_segs[seg].ds_addr + 0x40000000); /* MAGIC */
if (sc->bce_txsnext + 1 > BCE_NTXDESC - 1)
//.........这里部分代码省略.........
开发者ID:eyberg,项目名称:rumpkernel-netbsd-src,代码行数:101,代码来源:if_bce.c
示例16: qlw_scsi_cmd
void
qlw_scsi_cmd(struct scsi_xfer *xs)
{
struct scsi_link *link = xs->sc_link;
struct qlw_softc *sc = link->adapter_softc;
struct qlw_ccb *ccb;
struct qlw_iocb_req0 *iocb;
struct qlw_ccb_list list;
u_int16_t req, rspin;
int offset, error, done;
bus_dmamap_t dmap;
int bus;
int seg;
if (xs->cmdlen > sizeof(iocb->cdb)) {
DPRINTF(QLW_D_IO, "%s: cdb too big (%d)\n", DEVNAME(sc),
xs->cmdlen);
memset(&xs->sense, 0, sizeof(xs->sense));
xs->sense.error_code = SSD_ERRCODE_VALID | SSD_ERRCODE_CURRENT;
xs->sense.flags = SKEY_ILLEGAL_REQUEST;
xs->sense.add_sense_code = 0x20;
xs->error = XS_SENSE;
scsi_done(xs);
return;
}
ccb = xs->io;
dmap = ccb->ccb_dmamap;
if (xs->datalen > 0) {
error = bus_dmamap_load(sc->sc_dmat, dmap, xs->data,
xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ?
BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
if (error) {
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
return;
}
bus_dmamap_sync(sc->sc_dmat, dmap, 0,
dmap->dm_mapsize,
(xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
BUS_DMASYNC_PREWRITE);
}
mtx_enter(&sc->sc_queue_mtx);
/* put in a sync marker if required */
bus = qlw_xs_bus(sc, xs);
if (sc->sc_marker_required[bus]) {
req = sc->sc_next_req_id++;
if (sc->sc_next_req_id == sc->sc_maxrequests)
sc->sc_next_req_id = 0;
DPRINTF(QLW_D_IO, "%s: writing marker at request %d\n",
DEVNAME(sc), req);
offset = (req * QLW_QUEUE_ENTRY_SIZE);
iocb = QLW_DMA_KVA(sc->sc_requests) + offset;
bus_dmamap_sync(sc->sc_dmat, QLW
|
请发表评论