static int __devinit iguanair_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct iguanair *ir; struct rc_dev *rc; int ret, pipein, pipeout; struct usb_host_interface *idesc; ir = kzalloc(sizeof(*ir), GFP_KERNEL); rc = rc_allocate_device(); if (!ir || !rc) { ret = -ENOMEM; goto out; } ir->buf_in = usb_alloc_coherent(udev, MAX_IN_PACKET, GFP_KERNEL, &ir->dma_in); ir->packet = usb_alloc_coherent(udev, MAX_OUT_PACKET, GFP_KERNEL, &ir->dma_out); ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); ir->urb_out = usb_alloc_urb(0, GFP_KERNEL); if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) { ret = -ENOMEM; goto out; } idesc = intf->altsetting; if (idesc->desc.bNumEndpoints < 2) { ret = -ENODEV; goto out; } ir->rc = rc; ir->dev = &intf->dev; ir->udev = udev; mutex_init(&ir->lock); init_completion(&ir->completion); pipeout = usb_sndintpipe(udev, idesc->endpoint[1].desc.bEndpointAddress); usb_fill_int_urb(ir->urb_out, udev, pipeout, ir->packet, MAX_OUT_PACKET, iguanair_irq_out, ir, 1); ir->urb_out->transfer_dma = ir->dma_out; ir->urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress); usb_fill_int_urb(ir->urb_in, udev, pipein, ir->buf_in, MAX_IN_PACKET, iguanair_rx, ir, 1); ir->urb_in->transfer_dma = ir->dma_in; ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ret = usb_submit_urb(ir->urb_in, GFP_KERNEL); if (ret) { dev_warn(&intf->dev, "failed to submit urb: %d\n", ret); goto out; } ret = iguanair_get_features(ir); if (ret) goto out2; snprintf(ir->name, sizeof(ir->name), "IguanaWorks USB IR Transceiver version 0x%04x", ir->version); usb_make_path(ir->udev, ir->phys, sizeof(ir->phys)); rc->input_name = ir->name; rc->input_phys = ir->phys; usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protos = RC_BIT_ALL; rc->priv = ir; rc->open = iguanair_open; rc->close = iguanair_close; rc->s_tx_mask = iguanair_set_tx_mask; rc->s_tx_carrier = iguanair_set_tx_carrier; rc->tx_ir = iguanair_tx; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_RC6_MCE; rc->timeout = MS_TO_NS(100); rc->rx_resolution = RX_RESOLUTION; iguanair_set_tx_carrier(rc, 38000); ret = rc_register_device(rc); if (ret < 0) { dev_err(&intf->dev, "failed to register rc device %d", ret); goto out2; } usb_set_intfdata(intf, ir); return 0; out2: usb_kill_urb(ir->urb_in); usb_kill_urb(ir->urb_out); out: if (ir) { usb_free_urb(ir->urb_in); usb_free_urb(ir->urb_out); usb_free_coherent(udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in); usb_free_coherent(udev, MAX_OUT_PACKET, ir->packet, ir->dma_out); } rc_free_device(rc); kfree(ir); return ret; }
static int __devinit iguanair_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct iguanair *ir; struct rc_dev *rc; int ret; struct usb_host_interface *idesc; ir = kzalloc(sizeof(*ir), GFP_KERNEL); rc = rc_allocate_device(); if (!ir || !rc) { ret = ENOMEM; goto out; } ir->buf_in = usb_alloc_coherent(udev, MAX_PACKET_SIZE, GFP_ATOMIC, &ir->dma_in); ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); if (!ir->buf_in || !ir->urb_in) { ret = ENOMEM; goto out; } idesc = intf->altsetting; if (idesc->desc.bNumEndpoints < 2) { ret = -ENODEV; goto out; } ir->rc = rc; ir->dev = &intf->dev; ir->udev = udev; ir->pipe_in = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress); ir->pipe_out = usb_sndintpipe(udev, idesc->endpoint[1].desc.bEndpointAddress); mutex_init(&ir->lock); init_completion(&ir->completion); ret = iguanair_get_features(ir); if (ret) { dev_warn(&intf->dev, "failed to get device features"); goto out; } usb_fill_int_urb(ir->urb_in, ir->udev, ir->pipe_in, ir->buf_in, MAX_PACKET_SIZE, iguanair_rx, ir, idesc->endpoint[0].desc.bInterval); ir->urb_in->transfer_dma = ir->dma_in; ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; snprintf(ir->name, sizeof(ir->name), "IguanaWorks USB IR Transceiver version %d.%d", ir->version[0], ir->version[1]); usb_make_path(ir->udev, ir->phys, sizeof(ir->phys)); rc->input_name = ir->name; rc->input_phys = ir->phys; usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protos = RC_TYPE_ALL; rc->priv = ir; rc->open = iguanair_open; rc->close = iguanair_close; rc->s_tx_mask = iguanair_set_tx_mask; rc->s_tx_carrier = iguanair_set_tx_carrier; rc->tx_ir = iguanair_tx; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_EMPTY; iguanair_set_tx_carrier(rc, 38000); ret = rc_register_device(rc); if (ret < 0) { dev_err(&intf->dev, "failed to register rc device %d", ret); goto out; } usb_set_intfdata(intf, ir); dev_info(&intf->dev, "Registered %s", ir->name); return 0; out: if (ir) { usb_free_urb(ir->urb_in); usb_free_coherent(udev, MAX_PACKET_SIZE, ir->buf_in, ir->dma_in); } rc_free_device(rc); kfree(ir); return ret; }