static void virtio_net_check_queues(void) { struct packet *p; size_t len; /* Put the received packets into the recv list */ while (virtio_from_queue(net_dev, RX_Q, (void **)&p, &len) == 0) { p->len = len; STAILQ_INSERT_TAIL(&recv_list, p, next); in_rx--; virtio_net_stats.ets_packetR++; } /* * Packets from the TX queue just indicated they are free to * be reused now. inet already knows about them as being sent. */ while (virtio_from_queue(net_dev, TX_Q, (void **)&p, NULL) == 0) { memset(p->vhdr, 0, sizeof(*p->vhdr)); memset(p->vdata, 0, MAX_PACK_SIZE); STAILQ_INSERT_HEAD(&free_list, p, next); virtio_net_stats.ets_packetT++; } }
cursor_t * cursor_create(store_t *store) { cursor_t *cursor; cursor = nc_alloc(sizeof(*cursor)); if (cursor == NULL) { return NULL; } cursor->iter = leveldb_create_iterator(store->db, store->roptions); if (cursor->iter == NULL) { nc_free(cursor); return NULL; } leveldb_iter_seek_to_first(cursor->iter); cursor->id = g_cursor_id++; cursor->owner = store; ncursor++; STAILQ_INSERT_HEAD(&cursorq, cursor, next); return cursor; }
/** * mutt_list_insert_head - Insert a string at the beginning of a List * @param h Head of the List * @param s String to insert * @retval ptr Newly inserted ListNode containing the string */ struct ListNode *mutt_list_insert_head(struct ListHead *h, char *s) { struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode)); np->data = s; STAILQ_INSERT_HEAD(h, np, entries); return np; }
/*! \fn int io_device_read(uint16_t procnum) * \brief Richiede un accesso al dispositivo di I/O * \details La funzione si occupa di accodare la richiesta d'accesso al * dispositivo di I/O da parte di uno dei processi. Qualora l'MMU abbia * gia terminato la propria esecuzione, la funzione non accetta * ulteriori richieste. * \param procnum ID del processo * \return Restituisce l'esito dell'operazione: * 1 la richiesta e' stata accodata * 0 quando non sono piu' ammesse richieste */ int io_device_read(uint16_t procnum) { io_entry_t *req; int ret; pthread_mutex_lock(&request_lock); if (!io_device_should_exit) { pthread_mutex_lock(&wait_lock); req = XMALLOC(io_entry_t, 1); req->pid = proc_table[procnum]->pid; req->procnum = procnum; pthread_mutex_lock(&fifo_lock); if (STAILQ_EMPTY(&io_request_head)) STAILQ_INSERT_HEAD(&io_request_head, req, entries); else STAILQ_INSERT_TAIL(&io_request_head, req, entries); ioreq_count++; pthread_mutex_unlock(&fifo_lock); fprintf(LOG_FILE(procnum), "\nRichiesta d'accesso a dispositivo I/O accodata\n"); pthread_mutex_unlock(&wait_lock); pthread_cond_signal(&wait_cond); ret = 1; } else ret = 0; pthread_mutex_unlock(&request_lock); return ret; }
void mbuf_recycle(struct context *ctx, struct mbuf *mbuf) { ctx->stats.buffers--; STAILQ_NEXT(mbuf, next) = NULL; STAILQ_INSERT_HEAD(&ctx->free_mbufq, mbuf, next); ctx->nfree_mbufq++; }
/* Async. stream output */ static void fwe_as_output(struct fwe_softc *fwe, struct ifnet *ifp) { struct mbuf *m; struct fw_xfer *xfer; struct fw_xferq *xferq; struct fw_pkt *fp; int i = 0; xfer = NULL; xferq = fwe->fd.fc->atq; while ((xferq->queued < xferq->maxq - 1) && (ifp->if_snd.ifq_head != NULL)) { FWE_LOCK(fwe); xfer = STAILQ_FIRST(&fwe->xferlist); if (xfer == NULL) { #if 0 printf("if_fwe: lack of xfer\n"); #endif FWE_UNLOCK(fwe); break; } STAILQ_REMOVE_HEAD(&fwe->xferlist, link); FWE_UNLOCK(fwe); IF_DEQUEUE(&ifp->if_snd, m); if (m == NULL) { FWE_LOCK(fwe); STAILQ_INSERT_HEAD(&fwe->xferlist, xfer, link); FWE_UNLOCK(fwe); break; } BPF_MTAP(ifp, m); /* keep ip packet alignment for alpha */ M_PREPEND(m, ETHER_ALIGN, M_NOWAIT); fp = &xfer->send.hdr; *(uint32_t *)&xfer->send.hdr = *(int32_t *)&fwe->pkt_hdr; fp->mode.stream.len = m->m_pkthdr.len; xfer->mbuf = m; xfer->send.pay_len = m->m_pkthdr.len; if (fw_asyreq(fwe->fd.fc, -1, xfer) != 0) { /* error */ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* XXX set error code */ fwe_output_callback(xfer); } else { if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); i++; } } #if 0 if (i > 1) printf("%d queued\n", i); #endif if (i > 0) xferq->start(fwe->fd.fc); }
static void virtio_net_check_queues(void) { struct packet *p; size_t len; /* Put the received packets into the recv list */ while (virtio_from_queue(to_virtio_dev_t(&pci_vn), RX_Q, (void **)&p, &len) == 0) { pci_d("virtio_from_queue:%lx,len:%x\n", p, len); p->len = len; pci_d("vhdr:%lx,phdr:%lx,vdata:%lx,pdata:%lx,len:%d\n", p->vhdr, p->phdr, p->vdata, p->pdata, p->len); struct virtio_net_hdr { u8 flags; u8 gso_type; u16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ u16 gso_size; /* Bytes to append to hdr_len per frame */ u16 csum_start; /* Position to start checksumming from */ u16 csum_offset; /* Offset after that to place checksum */ }; pci_d ("flags:%x,gso_type:%x,hdr_len:%x,gso_size:%x,csum_start:%x,csum_offset:%x\n", p->vhdr->flags, p->vhdr->gso_type, p->vhdr->hdr_len, p->vhdr->gso_size, p->vhdr->csum_start, p->vhdr->csum_offset); ulong *pl = (ulong *) p->vdata; pci_d("%lx,%lx,%lx,%lx,%lx,%lx,%lx\n", pl[0], pl[1], pl[2], pl[3], pl[4], pl[5], pl[6]); u16 *pw = (u16 *) p->vdata; pci_d("%lx,%lx,%lx\n", pw[5], pw[6], pw[7]); uchar *pc = (uchar *) p->vdata+8; pci_d("To:%x:%x:%x:%x:%x:%x,From:%x:%x:%x:%x:%x:%x: len:%x,type:%x\n", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5], pc[6], pc[7], pc[8], pc[9], pc[10], pc[11],pw[10],pw[11]); STAILQ_INSERT_TAIL(&recv_list, p, next); in_rx--; virtio_net_stats.ets_packetR++; } /* * Packets from the TX queue just indicated they are free to * be reused now. inet already knows about them as being sent. */ while (virtio_from_queue(to_virtio_dev_t(&pci_vn), TX_Q, (void **)&p, NULL) == 0) { pci_d("virtio_from_queue:%lx,len:%x\n", p, len); ulong *pl = (ulong *) p; pci_d("%lx,%lx,%lx,%lx,%lx,%lx,%lx\n", pl[0], pl[1], pl[2], pl[3], pl[4], pl[5], pl[6]); memset(p->vhdr, 0, sizeof(*p->vhdr)); memset(p->vdata, 0, MAX_PACK_SIZE); STAILQ_INSERT_HEAD(&free_list, p, next); virtio_net_stats.ets_packetT++; } }
void mbuf_put(struct mbuf *mbuf) { log_debug(LOG_VVERB, "put mbuf %p len %d", mbuf, mbuf->last - mbuf->pos); ASSERT(STAILQ_NEXT(mbuf, next) == NULL); ASSERT(mbuf->magic == MBUF_MAGIC); nfree_mbufq++; STAILQ_INSERT_HEAD(&free_mbufq, mbuf, next); }
void flowadv_add_entry(struct flowadv_fcentry *fce) { lck_mtx_lock_spin(&fadv_lock); STAILQ_INSERT_HEAD(&fadv_list, fce, fce_link); VERIFY(!STAILQ_EMPTY(&fadv_list)); if (!fadv_active && fadv_thread != THREAD_NULL) wakeup_one((caddr_t)&fadv_list); lck_mtx_unlock(&fadv_lock); }
int taskqueue_enqueue(struct taskqueue *queue, struct task *task) { struct task *ins; struct task *prev; int s = splhigh(); /* * Don't allow new tasks on a queue which is being freed. */ if (queue->tq_draining) { splx(s); return EPIPE; } /* * Count multiple enqueues. */ if (task->ta_pending) { task->ta_pending++; splx(s); return 0; } /* * Optimise the case when all tasks have the same priority. */ prev = STAILQ_LAST(&queue->tq_queue); if (!prev || prev->ta_priority >= task->ta_priority) { STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link); } else { prev = 0; for (ins = STAILQ_FIRST(&queue->tq_queue); ins; prev = ins, ins = STAILQ_NEXT(ins, ta_link)) if (ins->ta_priority < task->ta_priority) break; if (prev) STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); else STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); } task->ta_pending = 1; if (queue->tq_enqueue) queue->tq_enqueue(queue->tq_context); splx(s); return 0; }
void buf_time_free(struct buf_time *t) { t->ctx->mstats.buf_times--; if (t->ctx->mstats.free_buf_times > BUF_TIME_LIMIT) { cv_free(t); return; } STAILQ_NEXT(t, next) = NULL; STAILQ_INSERT_HEAD(&t->ctx->free_buf_timeq, t, next); t->ctx->mstats.free_buf_times++; }
static void ktrace_init(void *dummy) { struct ktr_request *req; int i; mtx_init(&ktrace_mtx, "ktrace", NULL, MTX_DEF | MTX_QUIET); sx_init(&ktrace_sx, "ktrace_sx"); STAILQ_INIT(&ktr_free); for (i = 0; i < ktr_requestpool; i++) { req = malloc(sizeof(struct ktr_request), M_KTRACE, M_WAITOK); STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); } }
/*===========================================================================* * mq_init * *===========================================================================*/ void mq_init(void) { /* Initialize the message queues and message cells. */ int i; STAILQ_INIT(&free_list); for (i = 0; i < MAX_DEVICES; i++) STAILQ_INIT(&queue[i]); for (i = 0; i < MQ_SIZE; i++) STAILQ_INSERT_HEAD(&free_list, &pool[i], next); }
void ath_txfrag_cleanup(struct ath_softc *sc, ath_bufhead *frags, struct ieee80211_node *ni) { struct ath_buf *bf, *next; ATH_TXBUF_LOCK_ASSERT(sc); STAILQ_FOREACH_SAFE(bf, frags, bf_list, next) { /* NB: bf assumed clean */ STAILQ_REMOVE_HEAD(frags, bf_list); STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list); ieee80211_node_decref(ni); }
static void virtio_net_init_queues(void) { int i; STAILQ_INIT(&free_list); STAILQ_INIT(&recv_list); for (i = 0; i < BUF_PACKETS; i++) { packets[i].idx = i; packets[i].vhdr = &hdrs_vir[i]; packets[i].phdr = hdrs_phys + i * sizeof(hdrs_vir[i]); packets[i].vdata = data_vir + i * MAX_PACK_SIZE; packets[i].pdata = data_phys + i * MAX_PACK_SIZE; STAILQ_INSERT_HEAD(&free_list, &packets[i], next); } }
EP_STAT gdp_event_free(gdp_event_t *gev) { EP_ASSERT_POINTER_VALID(gev); ep_dbg_cprintf(Dbg, 48, "gdp_event_free(%p)\n", gev); if (gev->datum != NULL) gdp_datum_free(gev->datum); gev->datum = NULL; gev->type = _GDP_EVENT_FREE; ep_thr_mutex_lock(&FreeListMutex); STAILQ_INSERT_HEAD(&FreeList, gev, queue); ep_thr_mutex_unlock(&FreeListMutex); return EP_STAT_OK; }
static int virtio_net_cpy_to_user(message *m) { /* Hmm, this looks so similar to cpy_from_user... TODO */ int i, r, size, ivsz; int left = MAX_PACK_SIZE; /* Try copying the whole packet */ int bytes = 0; iovec_s_t iovec[NR_IOREQS]; struct packet *p; /* This should only be called if recv_list has some entries */ assert(!STAILQ_EMPTY(&recv_list)); p = STAILQ_FIRST(&recv_list); STAILQ_REMOVE_HEAD(&recv_list, next); virtio_net_fetch_iovec(iovec, m, m->m_net_netdrv_dl_readv_s.grant, m->m_net_netdrv_dl_readv_s.count); for (i = 0; i < m->m_net_netdrv_dl_readv_s.count && left > 0; i++) { ivsz = iovec[i].iov_size; size = left > ivsz ? ivsz : left; r = sys_safecopyto(m->m_source, iovec[i].iov_grant, 0, (vir_bytes) p->vdata + bytes, size); if (r != OK) panic("%s: copy to %d failed (%d)", name, m->m_source, r); left -= size; bytes += size; } if (left != 0) dput(("Uhm... left=%d", left)); /* Clean the packet */ memset(p->vhdr, 0, sizeof(*p->vhdr)); memset(p->vdata, 0, MAX_PACK_SIZE); STAILQ_INSERT_HEAD(&free_list, p, next); return bytes; }
void mpc_url_put(mpc_url_t *mpc_url) { pthread_mutex_lock(&mutex_free); ASSERT(mpc_url->no_put == 0); ASSERT(STAILQ_NEXT(mpc_url, next) == NULL); ASSERT(mpc_url->magic == MPC_URL_MAGIC); if (mpc_url_max_nfree != 0 && mpc_url_nfree + 1 > mpc_url_max_nfree) { mpc_url_free(mpc_url); } else { mpc_url_nfree++; STAILQ_INSERT_HEAD(&mpc_url_free_queue, mpc_url, next); } pthread_mutex_unlock(&mutex_free); }
static int rtwn_usb_alloc_rx_list(struct rtwn_softc *sc) { struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc); int error, i; error = rtwn_usb_alloc_list(sc, uc->uc_rx, RTWN_USB_RX_LIST_COUNT, uc->uc_rx_buf_size * RTWN_USB_RXBUFSZ_UNIT); if (error != 0) return (error); STAILQ_INIT(&uc->uc_rx_active); STAILQ_INIT(&uc->uc_rx_inactive); for (i = 0; i < RTWN_USB_RX_LIST_COUNT; i++) STAILQ_INSERT_HEAD(&uc->uc_rx_inactive, &uc->uc_rx[i], next); return (0); }
/* Push a new entry into the slow log. * This function will make sure to trim the slow log accordingly to the * configured max length. * The unit of duration is microseconds */ void slowlog_push_entry_if_needed(struct msg *r, long long duration) { if (slowlog_log_slower_than < 0) return; /* Slowlog disabled */ if (duration >= slowlog_log_slower_than) { slowlog_entry *se = slowlog_create_entry(r,duration); pthread_rwlock_wrlock(&rwlocker); se->id = slowlog_entry_id++; STAILQ_INSERT_HEAD(&slowlog, se, next); if (slowlog_len >= slowlog_max_len) { se = STAILQ_LAST(&slowlog, slowlog_entry, next); STAILQ_REMOVE(&slowlog, se, slowlog_entry, next); slowlog_free_entry(se); } else { slowlog_len ++; } pthread_rwlock_unlock(&rwlocker); slowlog_statistics_input(); } }
void mbuf_block_put(struct mbuf_block *mbuf_block) { #ifdef MBUF_DEBUG printf("[%p] mbuf_block put %p\n", oxt::thread_signature, mbuf_block); #endif assert(STAILQ_NEXT(mbuf_block, next) == NULL); assert(mbuf_block->magic == MBUF_BLOCK_MAGIC); assert(mbuf_block->refcount == 0); assert(mbuf_block->pool->nactive_mbuf_blockq > 0); mbuf_block->refcount = 1; mbuf_block->pool->nfree_mbuf_blockq++; mbuf_block->pool->nactive_mbuf_blockq--; STAILQ_INSERT_HEAD(&mbuf_block->pool->free_mbuf_blockq, mbuf_block, next); #ifdef MBUF_ENABLE_DEBUGGING TAILQ_REMOVE(&mbuf_block->pool->active_mbuf_blockq, mbuf_block, active_q); #endif }
/*===========================================================================* * mq_dequeue * *===========================================================================*/ int mq_dequeue(device_id_t device_id, message *mess, int *ipc_status) { /* Return and remove a message, including its IPC status, from the message * queue of a thread. Return TRUE iff a message was available. */ struct mq_cell *cell; assert(device_id >= 0 && device_id < MAX_DEVICES); if (STAILQ_EMPTY(&queue[device_id])) return FALSE; cell = STAILQ_FIRST(&queue[device_id]); STAILQ_REMOVE_HEAD(&queue[device_id], next); *mess = cell->mess; *ipc_status = cell->ipc_status; STAILQ_INSERT_HEAD(&free_list, cell, next); return TRUE; }
/* * Put a packet receive from the RX queue into a user buffer, and return the * packet length. If there are no received packets, return SUSPEND. */ static ssize_t virtio_net_recv(struct netdriver_data * data, size_t max) { struct packet *p; ssize_t len; /* Get the first received packet, if any. */ if (STAILQ_EMPTY(&recv_list)) return SUSPEND; p = STAILQ_FIRST(&recv_list); STAILQ_REMOVE_HEAD(&recv_list, next); /* Copy out the packet contents. */ len = p->len - sizeof(struct virtio_net_hdr); if (len > max) len = max; /* * HACK: due to lack of padding, received packets may in fact be * smaller than the minimum ethernet packet size. Inet will accept the * packets just fine if we increase the length to its minimum. We * already zeroed out the rest of the packet data, so this is safe. */ if (len < ETH_MIN_PACK_SIZE) len = ETH_MIN_PACK_SIZE; netdriver_copyout(data, 0, p->vdata, len); /* Clean the packet. */ memset(p->vhdr, 0, sizeof(*p->vhdr)); memset(p->vdata, 0, MAX_PACK_SIZE); STAILQ_INSERT_HEAD(&free_list, p, next); /* Readd packets to the receive queue as necessary. */ virtio_net_refill_rx_queue(); return len; }
void mbuf_insert_head(struct mhdr *mhdr, struct mbuf *mbuf) { STAILQ_INSERT_HEAD(mhdr, mbuf, next); log_debug(LOG_VVERB, "insert head mbuf %p len %d", mbuf, mbuf->last - mbuf->pos); }
void mbuf_recycle(struct context *ctx, struct mbuf *mbuf) { STAILQ_INSERT_HEAD(&ctx->free_mbufq, mbuf, next); ctx->nfree_mbufq++; }
void ath_cont_data(struct ath_softc *sc ,int val,ath_callback ath_draintxq, ath_callback ath_stoprecv) { static struct sk_buff *skb = NULL; struct ieee80211_frame *hdr; static struct ieee80211com *ic; static struct ath_buf *bf,*prev,*first; static struct ath_desc *ds; static struct ath_hal *ah; static STAILQ_HEAD(tpc_buf,ath_buf) tmp_q; static int is_inited=0; struct ath_txq *txq; const HAL_RATE_TABLE *rt; u_int8_t *p; u_int32_t flags, txrate, r,i; u_int16_t hdrlen, framelen, dmalen,delay=0; #define MIN(a,b) ((a) < (b) ? (a) : (b)) if(ath_hal_getdiagstate(sc->sc_ah, 19,0,10,NULL,NULL) == AH_FALSE) { printk("HAL does not support TX99 mode \n"); printk("compile HAL with AH_PRIVATE_DIAG turned on \n"); return; } if(is_inited == 0) { STAILQ_INIT(&tmp_q); is_inited=1; } /* enter CONT_DATA mode */ if (val && skb==NULL) { skb = ath_alloc_skb(4096, 32); if (skb == NULL) goto out; /* build output packet */ hdr = (struct ieee80211_frame *)skb_put(skb, sizeof(*hdr)); IEEE80211_ADDR_COPY(&hdr->i_addr1, test_addr); IEEE80211_ADDR_COPY(&hdr->i_addr2, test_addr); IEEE80211_ADDR_COPY(&hdr->i_addr3, test_addr); hdr->i_dur[0] = 0x0; hdr->i_dur[1] = 0x0; hdr->i_seq[0] = 0x5a; hdr->i_seq[1] = 0x5a; hdr->i_fc[0] = IEEE80211_FC0_TYPE_DATA; hdr->i_fc[1] = 0; hdrlen = sizeof(*hdr); for(r=0; r<2000; ) { p = skb_put(skb, sizeof(PN9Data)); memcpy(p, PN9Data, sizeof(PN9Data)); r += sizeof(PN9Data); } framelen = hdrlen + r + IEEE80211_CRC_LEN; ic = &sc->sc_ic; ah = sc->sc_ah; rt = sc->sc_currates; if (rt==NULL) { printk("no rate table\n"); goto out; } txrate = rt->info[rt->rateCount-1].rateCode; /* send at highest rate */ { int rix; if (sc->sc_txrx99.txrate==0) sc->sc_txrx99.txrate = 6000; for(rix=0; rix<rt->rateCount; rix++) { if (rt->info[rix].rateKbps==sc->sc_txrx99.txrate) { txrate = rt->info[rix].rateCode; printk("txrate set to %dKbps\n", sc->sc_txrx99.txrate); break; } } } ath_draintxq(sc); prev=first=NULL; printk("txpower set to %d\n", sc->sc_txrx99.txpower); /* send 20 frames for the Power Amp to settle down */ for(i=0;i<20;++i) { ATH_TXBUF_LOCK_BH(sc); bf = STAILQ_FIRST(&sc->sc_txbuf); if (bf != NULL) { STAILQ_REMOVE_HEAD(&sc->sc_txbuf,bf_list); } ATH_TXBUF_UNLOCK_BH(sc); if (bf==NULL) { printk("no tx buf\n"); goto out; } if(!i) first=bf; framelen = skb->len + IEEE80211_CRC_LEN; dmalen = skb->len; txq = sc->sc_ac2q[WME_AC_VO]; bf->bf_skbaddr = bus_map_single(sc->sc_bdev, skb->data, framelen, BUS_DMA_TODEVICE); bf->bf_skb = skb; bf->bf_node = 0; flags = HAL_TXDESC_CLRDMASK; ds = bf->bf_desc; if(prev) prev->bf_desc->ds_link = bf->bf_daddr; /* link from prev desc */ ds->ds_data = bf->bf_skbaddr; r = ath_hal_setuptxdesc(ah, ds, framelen, hdrlen, HAL_PKT_TYPE_NORMAL, sc->sc_txrx99.txpower, txrate, /* tx rate */ 1, /* max retries */ HAL_TXKEYIX_INVALID, /* no WEP */ 1, /* select Omni Antenna 0 */ flags, 0, /* rts/cts rate */ 0 /* rts/cts duration */ ); if (r==AH_FALSE) { printk("fail setuptxdesc r(%d)\n", r); goto out; } r = ath_hal_filltxdesc(ah, ds, skb->len, AH_TRUE, AH_TRUE,ds); if (r==AH_FALSE) { printk("fail fill tx desc r(%d)\n", r); goto out; } ath_hal_setupxtxdesc(ah, ds , txrate, 15 /* series 1 */ , txrate, 15 /* series 2 */ , txrate, 15 /* series 3 */ ); /* insert the buffers in to tmp_q */ STAILQ_INSERT_HEAD(&tmp_q,bf,bf_list); prev=bf; } ath_hal_intrset(ah, 0); /* disable interrupts */ //sc->sc_imask = HAL_INT_RX | HAL_INT_TX // | HAL_INT_RXEOL | HAL_INT_RXORN // | HAL_INT_FATAL | HAL_INT_GLOBAL; sc->sc_imask = 0; //ath_hal_intrset(ah, sc->sc_imask); bf->bf_desc->ds_link = 0; r = ath_hal_puttxbuf(ah, txq->axq_qnum, first->bf_daddr); ath_hal_txstart(ah, txq->axq_qnum); while(ath_hal_txprocdesc(ah,bf->bf_desc) == HAL_EINPROGRESS) { udelay(2000); ++delay; } /* sleep for 20ms */ udelay(20000); printk("took %d msec to transmit the 20 frames \n",2*delay); /* start TX99 mode */ ath_stoprecv(sc); /* stop recv side */ bf->bf_desc->ds_link = first->bf_daddr; /* link to self */ ath_hal_getdiagstate(ah, 19,(void *) sc->sc_txrx99.prefetch,9,NULL,NULL); ath_hal_getdiagstate(ah, 19, (void *)txq->axq_qnum, val,NULL,NULL); r = ath_hal_puttxbuf(ah, txq->axq_qnum, first->bf_daddr); ath_hal_txstart(ah, txq->axq_qnum); } /* leave CONT_DATA mode, reset the chip */ if (val==0 && skb) { int j=0; ath_hal_getdiagstate(ah, 19, 0, 0,NULL,NULL); /* insert the buffers back into txbuf list */ ATH_TXBUF_LOCK_BH(sc); bf = STAILQ_FIRST(&tmp_q); while(bf) { bf->bf_skb=NULL; STAILQ_REMOVE_HEAD(&tmp_q,bf_list); STAILQ_INSERT_HEAD(&sc->sc_txbuf,bf,bf_list); bf = STAILQ_FIRST(&tmp_q); ++j; } ATH_TXBUF_UNLOCK_BH(sc); printk("inserted back %d buffers \n",j); ic->ic_reset(ic->ic_dev); skb = NULL; bf = NULL; } if (val==7 && skb) { ath_hal_getdiagstate(ah, 19, ds, 7,NULL,NULL); } sc->sc_txrx99.tx99mode=val; out: return; #undef MIN }