Re: How to handle USB_ENDPOINT_XFER_BULK in gadget API?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

finally did this, but after calling usb_ep_queue has an error
0xFFFFFF8D, whats may be wrong ?
=================BASED on GMIDI code ==================================
=======================================================================
static BYTE RESPONSE_ARRAY[23] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
static int set_myDevice_config(struct myDevice_device *dev, gfp_t gfp_flags)
{
        int err = 0;
        struct usb_request *req;
        struct usb_ep *ep;
        unsigned i;

        dev->in_ep->driver_data = dev;
        dev->out_ep->driver_data = dev;

        err = usb_ep_enable(dev->out_ep, &dongle_endpoint01_descriptor);
        err = usb_ep_enable(dev->in_ep, &dongle_endpoint81_descriptor);

        // for OUT endpoint
        /* allocate a bunch of read buffers and queue them all at once. */
        ep = dev->out_ep;
        for (i = 0; i < qlen && err == 0; i++) {
                req = alloc_ep_req(ep, buflen);
                if (req) {
                        req->complete = myDevice_complete;
                        err = usb_ep_queue(ep, req, GFP_ATOMIC);
                        if (err) {
                                DBG(dev, "OUT %s queue req: %d\n", ep->name, err);
                        }
                } else {
                        err = -ENOMEM;
                }
        }

        // for IN  endpoint
        /* allocate a bunch of read buffers and queue them all at once. */
        ep = dev->in_ep;
        for (i = 0; i < qlen && err == 0; i++) {
                req = alloc_ep_req(ep, buflen);
                if (req) {
                        req->complete = myDevice_complete;
                        err = usb_ep_queue(ep, req, GFP_ATOMIC);
                        
                        if (err) {
                                DBG(dev, "IN %s queue req: %d\n", ep->name, err);
                        }
                } else {
                        err = -ENOMEM;
                }
        }

fail:
        /* caller is responsible for cleanup on error */
        return err;
}



static void myDevice_complete(struct usb_ep *ep, struct usb_request *req)
{
        struct myDevice_device *dev = ep->driver_data;
        int status = req->status;

        switch (status) {
        case 0:                         /* normal completion */
                if (ep == dev->out_ep) {
                        /* we received stuff.  req is queued again, below */
                        // here is correct data passed from host to endpoint 01, working ok
                        myDevice_handle_out_data(ep, req);
                        printk("RECEIVE DATA length = %08X\n",req->actual);
                        req->status = 0;

                } else if (ep == dev->in_ep) {

                    printk("Sending RESPONSE DATA to host len=0x08\n");

                    req->zero   = 0x00;
                    req->actual = 0x08;
                    req->length = 0x17;
                    req->complete=myDevice_complete;
                    // copyin response buffer to transfer buffer
                    memcpy(req->buf,&RESPONSE_ARRAY[0],req->actual);

                    //sending URB request back to host
                    status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); //here i have STATUS_OK, but after calling status in HCD is 0xFFFFFF8D and req->actual=0...
                    
                    return;

                }
                break;

        /* this endpoint is normally active while we're configured */
        case -ECONNABORTED:             /* hardware forced ep reset */
        case -ECONNRESET:               /* request dequeued */
        case -ESHUTDOWN:                /* disconnect from host */
                VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
                                req->actual, req->length);
                if (ep == dev->out_ep) {
                        myDevice_handle_out_data(ep, req);
                }
                free_ep_req(ep, req);
                return;

        case -EOVERFLOW:                /* buffer overrun on read means that
                                         * we didn't provide a big enough
                                         * buffer.
                                         */
        default:
                DBG(dev, "%s complete --> %d, %d/%d\n", ep->name,
                                status, req->actual, req->length);
                break;
        case -EREMOTEIO:                /* short read */
                break;
        }

        status = usb_ep_queue(ep, req, GFP_ATOMIC);
        if (status) {
                ERROR(dev, "kill %s:  resubmit %d bytes --> %d\n",
                                ep->name, req->length, status);
                usb_ep_set_halt(ep);

        }
}

=======================================================================


> Seems, dummy_hcd code uses transfer function() to send/receive all
> transfers, include BULK one.
> The complete() function only holds one endpoint, not all, right?




--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux