我一直在将自定义供应商类USB驱动程序从WINCE 6.0移植到Linux内核,以用于自定义Android设备 . 此驱动程序具有批量 endpoints ,用于将数据传输到文件 . 请不要向我解释这是一个坏主意 . 我理解这一点 . 在我的bulkout_complete函数中,我将数据复制到写缓冲区,然后调用queue_work来安排工作队列将数据写入文件 . 为了确保主机在写入完成之前不能再次发送数据,我有一个写入状态变量,它被清除为工作队列函数中的最后一个操作 . 主机驱动程序在控制 endpoints 上调用特定于供应商的请求以监视该变量的状态 . 清除变量后,主机会将下一个数据包发送到批量 endpoints . 问题是即使变量已清除,下一次调用queue_work将返回零值,这似乎表明工作已在进行中 .

从我的头文件:

u8 mWriteBuffer[4096];
u32 mWriteLength;
static bool mWriteActive = false;
#define USB_WORKQUEUE_NAME "wqusb"
static struct workqueue_struct *wqUSB;
static struct work_struct writeFile_work;
DECLARE_WORK(writeFile_work,file_write_handler);

创建和清理工作队列

static int __init init(void)
{
    wqUSB = create_workqueue(USB_WORKQUEUE_NAME);
    // other init stuff
}
static void __exit cleanup(void)
{
    flush_workqueue(wqUSB);
    destroy_workqueue(wqUSB);
    //other cleanup stuff
}

批量 endpoints 代码

static void bulkout_complete(struct usb_ep *ep, struct usb_request *req)
{
    struct usb_composite_dev    *cdev;
    struct f_myusb *ss = ep->driver_data;
    int             status = req->status;    

    cdev = ss->function.config->cdev;


    switch (status) 
    {

        case 0:             /* normal completion? */
        mWriteLength = (u32)req->length;
        memcpy(mWriteBuffer,(u8*)req->buf,req->length);
        mWriteActive = true;
        if(queue_work(wqUSB,&writeFile_work)==0)
        {
            printk(KERN_INFO "[USB DRIVER] - failed to queuework \n");
        }
        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(cdev, "%s gone (%d), %d/%d\n", ep->name, status,
            req->actual, req->length);

        free_ep_req(ep, req);
        return;

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

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



        }
    }

写入数据的workqueue函数

void file_write_handler(struct work_struct *pwork)
{
     write_file(mWriteBuffer,mWriteLength);
     mWriteActive = false;
}