📄 cpia_usb.c
字号:
return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), packet[1] + (packet[0] << 8), USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, packet[2] + (packet[3] << 8), packet[4] + (packet[5] << 8), buf, size, HZ);}static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data){ int err = 0; int databytes; struct usb_cpia *ucpia = (struct usb_cpia *)privdata; struct usb_device *udev = ucpia->dev; if (!udev) { DBG("Internal driver error: udev is NULL\n"); return -EINVAL; } if (!command) { DBG("Internal driver error: command is NULL\n"); return -EINVAL; } databytes = (((int)command[7])<<8) | command[6]; if (command[0] == DATA_IN) { u8 buffer[8]; if (!data) { DBG("Internal driver error: data is NULL\n"); return -EINVAL; } err = ReadPacket(udev, command, buffer, 8); if (err < 0) return err; memcpy(data, buffer, databytes); } else if(command[0] == DATA_OUT) WritePacket(udev, command, data, databytes); else { DBG("Unexpected first byte of command: %x\n", command[0]); err = -EINVAL; } return 0;}static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata), void *cbdata){ return -ENODEV;}static int cpia_usb_streamStart(void *privdata){ return -ENODEV;}static int cpia_usb_streamStop(void *privdata){ return -ENODEV;}static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock){ struct usb_cpia *ucpia = (struct usb_cpia *) privdata; struct framebuf *mybuff; if (!ucpia || !ucpia->present) return -1; if (ucpia->curbuff->status != FRAME_READY) interruptible_sleep_on(&ucpia->wq_stream); else DBG("Frame already waiting!\n"); mybuff = ucpia->curbuff; if (!mybuff) return -1; if (mybuff->status != FRAME_READY || mybuff->length < 4) { DBG("Something went wrong!\n"); return -1; } memcpy(frame, mybuff->data, mybuff->length); mybuff->status = FRAME_EMPTY; /* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", *//* mybuff->length, frame[0], frame[1], *//* frame[mybuff->length-4], frame[mybuff->length-3], *//* frame[mybuff->length-2], frame[mybuff->length-1]); */ return mybuff->length;}static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try){ if (!ucpia->streaming) return; ucpia->streaming = 0; /* Set packet size to 0 */ if (try) { int ret; ret = usb_set_interface(ucpia->dev, ucpia->iface, 0); if (ret < 0) { printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret); return; } ucpia->alt = 0; } /* Unschedule all of the iso td's */ if (ucpia->sbuf[1].urb) { usb_unlink_urb(ucpia->sbuf[1].urb); usb_free_urb(ucpia->sbuf[1].urb); ucpia->sbuf[1].urb = NULL; } if (ucpia->sbuf[1].data) { kfree(ucpia->sbuf[1].data); ucpia->sbuf[1].data = NULL; } if (ucpia->sbuf[0].urb) { usb_unlink_urb(ucpia->sbuf[0].urb); usb_free_urb(ucpia->sbuf[0].urb); ucpia->sbuf[0].urb = NULL; } if (ucpia->sbuf[0].data) { kfree(ucpia->sbuf[0].data); ucpia->sbuf[0].data = NULL; }}static int cpia_usb_close(void *privdata){ struct usb_cpia *ucpia = (struct usb_cpia *) privdata; if(!ucpia) return -ENODEV; ucpia->open = 0; /* ucpia->present = 0 protects against trying to reset the * alt setting if camera is physically disconnected while open */ cpia_usb_free_resources(ucpia, ucpia->present); return 0;}int cpia_usb_init(void){ /* return -ENODEV; */ return 0;}/* Probing and initializing */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void *cpia_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id){ struct usb_interface_descriptor *interface;#elsestatic int cpia_probe(struct usb_interface *intf, const struct usb_device_id *id){ struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_interface *interface;#endif struct usb_cpia *ucpia; struct cam_data *cam; int ret; /* A multi-config CPiA camera? */ if (udev->descriptor.bNumConfigurations != 1)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) return NULL;#else return -ENODEV;#endif#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) interface = &udev->actconfig->interface[ifnum].altsetting[0];#else interface = &intf->altsetting[0];#endif printk(KERN_INFO "USB CPiA camera found\n"); ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL); if (!ucpia) { printk(KERN_ERR "couldn't kmalloc cpia struct\n");#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) return NULL;#else return -ENOMEM;#endif } memset(ucpia, 0, sizeof(*ucpia)); ucpia->dev = udev;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) ucpia->iface = interface->bInterfaceNumber;#else ucpia->iface = interface->desc.bInterfaceNumber;#endif init_waitqueue_head(&ucpia->wq_stream); ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0])); if (!ucpia->buffers[0]) { printk(KERN_ERR "couldn't vmalloc frame buffer 0\n"); goto fail_alloc_0; } ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1])); if (!ucpia->buffers[1]) { printk(KERN_ERR "couldn't vmalloc frame buffer 1\n"); goto fail_alloc_1; } ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2])); if (!ucpia->buffers[2]) { printk(KERN_ERR "couldn't vmalloc frame buffer 2\n"); goto fail_alloc_2; } ucpia->buffers[0]->next = ucpia->buffers[1]; ucpia->buffers[1]->next = ucpia->buffers[2]; ucpia->buffers[2]->next = ucpia->buffers[0]; ret = usb_set_interface(udev, ucpia->iface, 0); if (ret < 0) { printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret); /* goto fail_all; */ } ucpia->alt = 0; /* Before register_camera, important */ ucpia->present = 1; cam = cpia_register_camera(&cpia_usb_ops, ucpia); if (!cam) { LOG("failed to cpia_register_camera\n"); goto fail_all; } spin_lock( &cam_list_lock_usb ); list_add( &cam->cam_data_list, &cam_list ); spin_unlock( &cam_list_lock_usb );#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) return cam;#else usb_set_intfdata(intf, cam); return 0;#endiffail_all: vfree(ucpia->buffers[2]); ucpia->buffers[2] = NULL;fail_alloc_2: vfree(ucpia->buffers[1]); ucpia->buffers[1] = NULL;fail_alloc_1: vfree(ucpia->buffers[0]); ucpia->buffers[0] = NULL;fail_alloc_0: kfree(ucpia);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) return NULL;#else return -EIO;#endif}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void cpia_disconnect(struct usb_device *dev, void *ptr);#elsestatic void cpia_disconnect(struct usb_interface *intf);#endifstatic struct usb_device_id cpia_id_table [] = { { USB_DEVICE(0x0553, 0x0002) }, { USB_DEVICE(0x0813, 0x0001) }, { } /* Terminating entry */};MODULE_DEVICE_TABLE (usb, cpia_id_table);#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10))MODULE_LICENSE("GPL");#endifstatic struct usb_driver cpia_driver = {#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) name: "cpia", probe: cpia_probe, disconnect: cpia_disconnect, id_table: cpia_id_table,#else#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,70)) .owner = THIS_MODULE,#endif .name = "cpia", .probe = cpia_probe, .disconnect = cpia_disconnect, .id_table = cpia_id_table,#endif};#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void cpia_disconnect(struct usb_device *udev, void *ptr){ struct cam_data *cam = (struct cam_data *) ptr;#elsestatic void cpia_disconnect(struct usb_interface *intf){ struct cam_data *cam = usb_get_intfdata(intf); struct usb_device *udev;#endif struct usb_cpia *ucpia; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) usb_set_intfdata(intf, NULL);#endif if (!cam) return; ucpia = (struct usb_cpia *) cam->lowlevel_data; spin_lock( &cam_list_lock_usb ); list_del(&cam->cam_data_list); spin_unlock( &cam_list_lock_usb ); ucpia->present = 0; cpia_unregister_camera(cam); if(ucpia->open) cpia_usb_close(cam->lowlevel_data); ucpia->curbuff->status = FRAME_ERROR; if (waitqueue_active(&ucpia->wq_stream)) wake_up_interruptible(&ucpia->wq_stream);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75)) udev = interface_to_usbdev(intf); usb_driver_release_interface(&cpia_driver, udev->actconfig->interface[0]);#else usb_driver_release_interface(&cpia_driver, &udev->actconfig->interface[0]);#endif ucpia->curbuff = ucpia->workbuff = NULL; if (ucpia->buffers[2]) { vfree(ucpia->buffers[2]); ucpia->buffers[2] = NULL; } if (ucpia->buffers[1]) { vfree(ucpia->buffers[1]); ucpia->buffers[1] = NULL; } if (ucpia->buffers[0]) { vfree(ucpia->buffers[0]); ucpia->buffers[0] = NULL; } cam->lowlevel_data = NULL; kfree(ucpia);}static int __init usb_cpia_init(void){ printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER); spin_lock_init(&cam_list_lock_usb); return usb_register(&cpia_driver);}static void __exit usb_cpia_cleanup(void){ usb_deregister(&cpia_driver);}module_init (usb_cpia_init);module_exit (usb_cpia_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -