From owner-freebsd-usb@FreeBSD.ORG Tue Oct 28 03:03:14 2014 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id EA293F3C for ; Tue, 28 Oct 2014 03:03:14 +0000 (UTC) Received: from mail-vc0-x235.google.com (mail-vc0-x235.google.com [IPv6:2607:f8b0:400c:c03::235]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id AC4E7F0B for ; Tue, 28 Oct 2014 03:03:14 +0000 (UTC) Received: by mail-vc0-f181.google.com with SMTP id hy10so1780957vcb.40 for ; Mon, 27 Oct 2014 20:03:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=L4PfGGInAUJTWK3izyAnw/7UQYKCaft0O9u8ndtlkqw=; b=q1y7bHUtM63cYcKwm3D1Y7PdPltE7l1HvfR5tLbhRrRHQMfrCUQfOO8UxemQ+BSAUC S099RC3foJlLg9TKOmMmm/lL4j2ol1ckUKGas0pciFRsSqE+f6xCy7zKRj7yr+sno72Q bt2PBPU64nwcUpQrPej9XVDzycetdlx+FyJKVCxrsksFDnD8C4oz0llCUo0/d8Ie/fpn mAGsmXfzIbcG7tdbZzYtc8J7vvL48DjTRA4yaUYiv42Tr/h6UgaxG5EmW2cLlKFQwI1N eqHO0Qmh/AvuOtVMTeYybIhZ9MsUI/H53iIA2sLJWUy0gLIsCbZluXfQf5FwQyNN4ONf R/6Q== MIME-Version: 1.0 X-Received: by 10.52.138.211 with SMTP id qs19mr210053vdb.13.1414465393691; Mon, 27 Oct 2014 20:03:13 -0700 (PDT) Received: by 10.220.58.136 with HTTP; Mon, 27 Oct 2014 20:03:13 -0700 (PDT) Date: Mon, 27 Oct 2014 20:03:13 -0700 Message-ID: Subject: USB stack driver options for the receive side question From: Nidal Khalil To: freebsd-usb@freebsd.org Content-Type: text/plain; charset=UTF-8 X-Content-Filtered-By: Mailman/MimeDel 2.1.18-1 X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Oct 2014 03:03:15 -0000 Hello All, I am setting up usb to transfer 3 frames on the bulk read descriptor but all I get is one frame transferred? Basically aframe = 1 However if I use .short_frames_ok = 1, then the transfer will pend till the three frames are received. This code is part of a network driver I would like to receive the one buffer it is the only one available and at most three buffers at a time if the transfer is complete. The one frame a time to respond to ping and three frame at time when the transfer load is heavy. Is this a limitation of FreeBSD. I searched all the drivers in the 9.3 release and I can not find a driver that is setup to receive multiple buffers? Below is my sample code: BWL_BULK_RD] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = 2000 * HW_IN_PENDING_FRAMES, .flags = { .pipe_bof = 1, .short_xfer_ok = 1, .ext_buffer = 1 }, .callback = dbus_usbos_recv_callback, .timeout = 0, /* no timeout */ .frames = HW_IN_PENDING_FRAMES }, static void dbus_usbos_recv_callback(CALLBACK_ARGS) { usbos_info_t *usbos_info = usbd_xfer_softc(xfer); struct bwl_rx_data *data; int actlen, sumlen, aframes, nframes, datalen, nr_frames; uint8 *buf; struct timespec tp; DBUSTRACE(("%s(): Enter \n", __FUNCTION__)); usbd_xfer_status(xfer, &actlen, &sumlen, &aframes, &nframes); switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: for (nr_frames = 0; nr_frames != aframes; nr_frames++) { FETCH_LIST_HEAD_ITEM(rx_q_lock, rx_q); if (!data) { DBUSERR(("got xfer frame but the rx_q till end ?? \n")); ASSERT(0); } usbd_xfer_frame_data(xfer, nr_frames, (void**)&buf, &datalen); kern_clock_gettime(curthread, CLOCK_UPTIME_PRECISE, &tp); mylog(&glog, "T %p: %d-%d:%u\n", buf, datalen, tp.tv_sec, tp.tv_nsec); if ((data->rxirb->buf != buf) || (data->rxirb->buf_len < datalen)) { DBUSERR(("the buff or data length not match ?? \n")); ASSERT(0); } MUTEX_UNLOCK(usbos_info); dbus_usbos_recv_complete(data, datalen, DBUS_OK); MUTEX_LOCK(usbos_info); } __transfered += nr_frames; /* no break, FALLTHROUGH */ case USB_ST_SETUP: SET_UP_XFER: nr_frames = 0; mtx_lock(&usbos_info->rx_q_lock); STAILQ_FOREACH(data, &usbos_info->rx_q, next) { if (data->rxirb == NULL) break; kern_clock_gettime(curthread, CLOCK_UPTIME_PRECISE, &tp); mylog(&glog, "S %p:%d-%d:%u\n", data->rxirb->buf, data->rxirb->buf_len, tp.tv_sec, tp.tv_nsec); usbd_xfer_set_frame_data(xfer, nr_frames, data->rxirb->buf, data->rxirb->buf_len); ++nr_frames; if (nr_frames >= BCMWL_HW_IN_PENDING_FRAMES) break; /* break out from STAILQ_FOREACH */ } mtx_unlock(&usbos_info->rx_q_lock); if (nr_frames) { usbd_xfer_set_frames(xfer, nr_frames); usbd_transfer_submit(xfer); } else { printf("%s(): end of rx_q \n", __FUNCTION__); } __setup += nr_frames; break; default: DBUSERR(("%s(): error = %s with %d bytes transfered\n", __FUNCTION__, usbd_errstr(error), actlen)); if (error == USB_ERR_STALLED || error == USB_ERR_IOERROR) { printf("%s(): calling DBUS_STATE_DOWN for %s\n", __FUNCTION__, usbd_errstr(error)); dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN); } if ((error != USB_ERR_CANCELLED) && (error != USB_ERR_STALLED)) { usbd_xfer_set_stall(xfer); goto SET_UP_XFER; } else { /* return all rxirb in the queue */ MUTEX_UNLOCK(usbos_info); mtx_lock(&usbos_info->rx_q_lock); while ((data = STAILQ_FIRST(&usbos_info->rx_q)) != NULL) { STAILQ_REMOVE_HEAD(&usbos_info->rx_q, next); dbus_usbos_recv_complete(data, 0, DBUS_ERR_RXFAIL); } STAILQ_INIT(&usbos_info->rx_q); mtx_unlock(&usbos_info->rx_q_lock); MUTEX_LOCK(usbos_info); } break; } }