?? mouse.c
字號:
unsigned long flags; spin_lock_irqsave(&mouse_private->lock, flags); if (!mouse_private->data_valid) { spin_unlock_irqrestore(&mouse_private->lock, flags); return 0; } if ((urb = usbd_alloc_urb(mouse_private->device, (mouse_private->device->function_instance_array+port), CONFIG_USBD_MOUSE_INT_ENDPOINT | IN, MOUSE_PACKET_SIZE))==NULL) { dbg_tx(0, "failed to alloc urb"); spin_unlock_irqrestore(&mouse_private->lock, flags); return -EINVAL; } memcpy(urb->buffer, mouse_private->data, MOUSE_PACKET_SIZE); urb->actual_length = MOUSE_PACKET_SIZE; mouse_private->data_valid = 0; spin_unlock_irqrestore(&mouse_private->lock, flags); dbgPRINTmem(dbgflg_usbdfd_tx,3,urb->buffer,MOUSE_PACKET_SIZE); // push it down into the usb-device layer return usbd_send_urb(urb);}/* mouse_urb_sent - called to indicate URB transmit finished * @urb: pointer to struct urb * @rc: result */int mouse_urb_sent (struct urb *urb, int status){ int port = 0; // XXX compound device struct usb_device_instance *device = urb->device; struct usb_mouse_private *mouse_private = (device->function_instance_array+port)->privdata; dbg_tx(2,"%s length: %d status : %x",urb->device->name, urb->actual_length, status); usbd_dealloc_urb(urb); /* send next urb */ return mouse_send(mouse_private);}/** * mouse_recv_setup - called with a control URB * @urb - pointer to struct urb * * Check if this is a setup packet, process the device request, put results * back into the urb and return zero or non-zero to indicate success (DATA) * or failure (STALL). * * This routine IS called at interrupt time. Please use the usual precautions. * */int mouse_recv_setup (struct urb * urb){ struct usb_device_request *request; struct usb_device_instance *device = urb->device; int port = 0; struct usb_mouse_private *mouse_private = (device->function_instance_array+port)->privdata; request = &urb->device_request; // handle HID Class-Specific Request (c.f. HID 7.2) if ((request->bmRequestType&USB_REQ_TYPE_MASK)!=USB_REQ_TYPE_CLASS) { dbg_ep0(1, "not class request: %x %x", request->bmRequestType, request->bmRequestType&USB_REQ_TYPE_MASK); return 0; // XXX } if ((request->bmRequestType&USB_REQ_DIRECTION_MASK)) { dbg_ep0(1, "Device-to-Host"); switch (request->bRequest) { case USB_REQ_SET_IDLE: mouse_private->duration = le16_to_cpu (request->wValue) >> 8; break; case USB_REQ_SET_REPORT: /* ignore */ break; } } else { dbg_ep0(1, "Host-to-Device"); switch (request->bRequest) { case USB_REQ_GET_IDLE: /* FIXME */ break; case USB_REQ_GET_REPORT: /* FIXME */ break; } } return 0;}/* USB Device Functions ************************************************************************ *//* proc interface */static int mouse_write_proc(struct file *file, const char *buffer, unsigned long count, void *data){ char str[128]; int val[MOUSE_PACKET_SIZE]; unsigned long flags; struct usb_mouse_private *mouse_private = data; memset(str, 0, sizeof(str)); if (copy_from_user(str, buffer, min_t(unsigned long, count, sizeof(str)))) return -EFAULT; if (sscanf(str, "%d %d %d", &val[0], &val[1], &val[2]) != 3) return -EINVAL; spin_lock_irqsave(&mouse_private->lock, flags); if (mouse_private->device->device_state == STATE_CONFIGURED && !mouse_private->data_valid) { int i; for (i = 0; i < MOUSE_PACKET_SIZE; i++) mouse_private->data[i] = val[i]; mouse_private->data_valid = 1; mouse_send(mouse_private); } spin_unlock_irqrestore(&mouse_private->lock, flags); return count;}/* mouse_event - process a device event * */void mouse_event(struct usb_device_instance *device, usb_device_event_t event, int data){ int port = 0; // XXX compound device struct usb_function_instance *function; dbg_usbe(5,"%d",event); if ((function = device->function_instance_array+port)==NULL){ dbg_usbe(1,"no function"); return; } dbg_usbe(3,"---> %s %d", device->name, event); switch (event) { case DEVICE_UNKNOWN: case DEVICE_INIT: dbg_usbe(1,"---> INIT %s %d", device->name, event); break; case DEVICE_CREATE: dbg_usbe(1,"---> CREATE %s %d", device->name, event); { struct usb_mouse_private *mouse_private; struct proc_dir_entry *pentry; // There is no way to indicate error, so make this unconditional // and undo it in the DESTROY event unconditionally as well. // It the responsibility of the USBD core and the bus interface // to see that there is a matching DESTROY for every CREATE. if ((mouse_private = kmalloc(sizeof(struct usb_mouse_private),GFP_ATOMIC))==NULL) { dbg_usbe(1,"---> CREATE malloc failed %s",device->name); return; } mouse_private->device = device; mouse_private->duration = 0; /* infinite */ mouse_private->data_valid = 0; spin_lock_init(&mouse_private->lock); pentry = create_proc_entry(MOUSE_PROC_NAME, 0200, NULL); if (pentry) { pentry->write_proc = mouse_write_proc; pentry->data = mouse_private; } function->privdata = mouse_private; dbg_usbe(1,"---> START %s privdata assigned: %p", device->name, mouse_private); return; } break; case DEVICE_HUB_CONFIGURED: break; case DEVICE_RESET: break; case DEVICE_ADDRESS_ASSIGNED: break; case DEVICE_CONFIGURED: dbg_usbe(1,"---> CONFIGURED %s %d", device->name, event); break; case DEVICE_SET_INTERFACE: break; case DEVICE_SET_FEATURE: break; case DEVICE_CLEAR_FEATURE: break; case DEVICE_DE_CONFIGURED: dbg_usbe(1,"---> DECONFIGURED %s %d", device->name, event); break; case DEVICE_BUS_INACTIVE: break; case DEVICE_BUS_ACTIVITY: break; case DEVICE_POWER_INTERRUPTION: break; case DEVICE_HUB_RESET: break; case DEVICE_DESTROY: dbg_usbe(1, "---> DESTROY %s %d", device->name, event); { struct usb_mouse_private *mouse_private; if ((mouse_private = (device->function_instance_array+port)->privdata) == NULL) { dbg_usbe(1, "---> DESTROY %s mouse_private null", device->name); return; } dbg_usbe(1, "---> DESTROY %s mouse_private %p", device->name, mouse_private); kfree(mouse_private); remove_proc_entry(MOUSE_PROC_NAME, NULL); dbg_usbe(1,"---> STOP %s",device->name); return; } break; case DEVICE_FUNCTION_PRIVATE: dbg_usbe(3, "%s", usbd_device_events[DEVICE_FUNCTION_PRIVATE]); break; }}static void mouse_function_exit(struct usb_device_instance *device){ dbg_init(1, "CLOSING **************************"); /* DEVICE_DESTROY will not called when bi driver unloaded. Call here. */ mouse_event(device, DEVICE_DESTROY, 0);}struct usb_function_operations function_ops = { event: mouse_event, urb_sent: mouse_urb_sent, recv_setup:mouse_recv_setup, function_exit: mouse_function_exit,};struct usb_function_driver function_driver = { name: "usbd mouse", ops: &function_ops, device_description: &mouse_device_description, configurations: sizeof(mouse_description)/sizeof(struct usb_configuration_description), configuration_description: mouse_description, this_module: THIS_MODULE,};/* * mouse_modinit - module init * */static int __init mouse_modinit(void){ printk(KERN_INFO "%s (dbg=\"%s\")\n", __usbd_module_info, dbg?dbg:""); if (vendor_id) { mouse_device_description.idVendor = vendor_id; } if (product_id) { mouse_device_description.idProduct = product_id; } printk(KERN_INFO "vendor_id: %04x product_id: %04x\n", mouse_device_description.idVendor, mouse_device_description.idProduct); if (0 != scan_debug_options("mouse_fd",dbg_table,dbg)) { return(-EINVAL); } // register us with the usb device support layer // if (usbd_register_function(&function_driver)) { return -EINVAL; } // return return 0;}/* mouse_modexit - module cleanup */static void __exit mouse_modexit(void){ // de-register us with the usb device support layer // usbd_deregister_function(&function_driver);}module_init(mouse_modinit);module_exit(mouse_modexit);/* * Local variables: * c-basic-offset: 4 * End: */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -