/** * iowarrior_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int iowarrior_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct iowarrior *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i; int retval = -ENOMEM; /* allocate memory for our device state and intialize it */ dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "Out of memory\n"); return retval; } mutex_init(&dev->mutex); atomic_set(&dev->intr_idx, 0); atomic_set(&dev->read_idx, 0); spin_lock_init(&dev->intr_idx_lock); atomic_set(&dev->overflow_flag, 0); init_waitqueue_head(&dev->read_wait); atomic_set(&dev->write_busy, 0); init_waitqueue_head(&dev->write_wait); dev->udev = udev; dev->interface = interface; iface_desc = interface->cur_altsetting; dev->product_id = le16_to_cpu(udev->descriptor.idProduct); /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->int_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) /* this one will match for the IOWarrior56 only */ dev->int_out_endpoint = endpoint; } /* we have to check the report_size often, so remember it in the endianess suitable for our machine */ dev->report_size = le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize); if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) && (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56)) /* IOWarrior56 has wMaxPacketSize different from report size */ dev->report_size = 7; /* create the urb and buffer for reading */ dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->int_in_urb) { dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL); if (!dev->int_in_buffer) { dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n"); goto error; } usb_fill_int_urb(dev->int_in_urb, dev->udev, usb_rcvintpipe(dev->udev, dev->int_in_endpoint->bEndpointAddress), dev->int_in_buffer, dev->report_size, iowarrior_callback, dev, dev->int_in_endpoint->bInterval); /* create an internal buffer for interrupt data from the device */ dev->read_queue = kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER), GFP_KERNEL); if (!dev->read_queue) { dev_err(&interface->dev, "Couldn't allocate read_queue\n"); goto error; } /* Get the serial-number of the chip */ memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial)); usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial, sizeof(dev->chip_serial)); if (strlen(dev->chip_serial) != 8) memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial)); /* Set the idle timeout to 0, if this is interface 0 */ if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) { usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0A, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); } /* allow device read and ioctl */ dev->present = 1; /* we can register the device now, as it is ready */ usb_set_intfdata(interface, dev); retval = usb_register_dev(interface, &iowarrior_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&interface->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(interface, NULL); goto error; } dev->minor = interface->minor; /* let the user know what node this device is now attached to */ dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d " "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial, iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE); return retval; error: iowarrior_delete(dev); return retval; }
/** * ld_usb_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct ld_usb *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; char *buffer; int i; int retval = -ENOMEM; /* allocate memory for our device state and intialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { dev_err(&intf->dev, "Out of memory\n"); goto exit; } init_MUTEX(&dev->sem); spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); /* workaround for early firmware versions on fast computers */ if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) || (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { buffer = kmalloc(256, GFP_KERNEL); if (buffer == NULL) { dev_err(&intf->dev, "Couldn't allocate string buffer\n"); goto error; } /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ usb_string(udev, 255, buffer, 256); kfree(buffer); } iface_desc = intf->cur_altsetting; /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->interrupt_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) dev->interrupt_out_endpoint = endpoint; } if (dev->interrupt_in_endpoint == NULL) { dev_err(&intf->dev, "Interrupt in endpoint not found\n"); goto error; } if (dev->interrupt_out_endpoint == NULL) dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); if (!dev->ring_buffer) { dev_err(&intf->dev, "Couldn't allocate ring_buffer\n"); goto error; } dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); if (!dev->interrupt_in_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n"); goto error; } dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_in_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) : udev->descriptor.bMaxPacketSize0; dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); if (!dev->interrupt_out_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n"); goto error; } dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_out_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); goto error; } dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; if (dev->interrupt_out_endpoint) dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; /* we can register the device now, as it is ready */ usb_set_intfdata(intf, dev); retval = usb_register_dev(intf, &ld_usb_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&intf->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(intf, NULL); goto error; } /* let the user know what node this device is now attached to */ dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n", (intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor); exit: return retval; error: ld_usb_delete(dev); return retval; }
/* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in * this case start handling it. */ static int ksdazzle_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *dev = interface_to_usbdev(intf); struct ksdazzle_cb *kingsun = NULL; struct net_device *net = NULL; int ret = -ENOMEM; int pipe, maxp_in, maxp_out; __u8 ep_in; __u8 ep_out; /* Check that there really are two interrupt endpoints. Check based on the one in drivers/usb/input/usbmouse.c */ interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 2) { err("ksdazzle: expected 2 endpoints, found %d", interface->desc.bNumEndpoints); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; if (!usb_endpoint_is_int_in(endpoint)) { err("ksdazzle: endpoint 0 is not interrupt IN"); return -ENODEV; } ep_in = endpoint->bEndpointAddress; pipe = usb_rcvintpipe(dev, ep_in); maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp_in > 255 || maxp_in <= 1) { err("ksdazzle: endpoint 0 has max packet size %d not in range [2..255]", maxp_in); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; if (!usb_endpoint_is_int_out(endpoint)) { err("ksdazzle: endpoint 1 is not interrupt OUT"); return -ENODEV; } ep_out = endpoint->bEndpointAddress; pipe = usb_sndintpipe(dev, ep_out); maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); /* Allocate network device container. */ net = alloc_irdadev(sizeof(*kingsun)); if (!net) goto err_out1; SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->netdev = net; kingsun->usbdev = dev; kingsun->ep_in = ep_in; kingsun->ep_out = ep_out; kingsun->irlap = NULL; kingsun->tx_urb = NULL; kingsun->tx_buf_clear = NULL; kingsun->tx_buf_clear_used = 0; kingsun->tx_buf_clear_sent = 0; kingsun->rx_urb = NULL; kingsun->rx_buf = NULL; kingsun->rx_unwrap_buff.in_frame = FALSE; kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; kingsun->rx_unwrap_buff.skb = NULL; kingsun->receiving = 0; spin_lock_init(&kingsun->lock); kingsun->speed_setuprequest = NULL; kingsun->speed_urb = NULL; kingsun->speedparams.baudrate = 0; /* Allocate input buffer */ kingsun->rx_buf = kmalloc(KINGSUN_RCV_MAX, GFP_KERNEL); if (!kingsun->rx_buf) goto free_mem; /* Allocate output buffer */ kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL); if (!kingsun->tx_buf_clear) goto free_mem; /* Allocate and initialize speed setup packet */ kingsun->speed_setuprequest = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!kingsun->speed_setuprequest) goto free_mem; kingsun->speed_setuprequest->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); kingsun->speed_setuprequest->wLength = cpu_to_le16(sizeof(struct ksdazzle_speedparams)); printk(KERN_INFO "KingSun/Dazzle IRDA/USB found at address %d, " "Vendor: %x, Product: %x\n", dev->devnum, le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&kingsun->qos); /* Baud rates known to be supported. Please uncomment if devices (other than a SonyEriccson K300 phone) can be shown to support higher speeds with this dongle. */ kingsun->qos.baud_rate.bits = IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200; kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; irda_qos_bits_to_value(&kingsun->qos); /* Override the network functions we need to use */ net->hard_start_xmit = ksdazzle_hard_xmit; net->open = ksdazzle_net_open; net->stop = ksdazzle_net_close; net->get_stats = ksdazzle_net_get_stats; net->do_ioctl = ksdazzle_net_ioctl; ret = register_netdev(net); if (ret != 0) goto free_mem; dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n", net->name); usb_set_intfdata(intf, kingsun); /* Situation at this point: - all work buffers allocated - setup requests pre-filled - urbs not allocated, set to NULL - max rx packet known (is KINGSUN_FIFO_SIZE) - unwrap state machine (partially) initialized, but skb == NULL */ return 0; free_mem: kfree(kingsun->speed_setuprequest); kfree(kingsun->tx_buf_clear); kfree(kingsun->rx_buf); free_netdev(net); err_out1: return ret; }
/** * usb_alphatrack_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_alphatrack *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i; int true_size; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) goto exit; mutex_init(&dev->mtx); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); iface_desc = intf->cur_altsetting; /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->interrupt_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) dev->interrupt_out_endpoint = endpoint; } if (dev->interrupt_in_endpoint == NULL) { dev_err(&intf->dev, "Interrupt in endpoint not found\n"); goto error; } if (dev->interrupt_out_endpoint == NULL) dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); if (dev->interrupt_in_endpoint_size != 64) dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n"); if (ring_buffer_size == 0) ring_buffer_size = RING_BUFFER_SIZE; true_size = min(ring_buffer_size, RING_BUFFER_SIZE); /* * FIXME - there are more usb_alloc routines for dma correctness. * Needed? */ dev->ring_buffer = kmalloc_array(true_size, sizeof(struct alphatrack_icmd), GFP_KERNEL); if (!dev->ring_buffer) goto error; dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); if (!dev->interrupt_in_buffer) goto error; dev->oldi_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); if (!dev->oldi_buffer) goto error; dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_in_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev-> interrupt_out_endpoint-> wMaxPacketSize) : udev-> descriptor.bMaxPacketSize0; if (dev->interrupt_out_endpoint_size != 64) dev_warn(&intf->dev, "Interrupt out endpoint size is not 64!)\n"); if (write_buffer_size == 0) write_buffer_size = WRITE_BUFFER_SIZE; true_size = min(write_buffer_size, WRITE_BUFFER_SIZE); dev->interrupt_out_buffer = kmalloc_array(true_size, dev->interrupt_out_endpoint_size, GFP_KERNEL); if (!dev->interrupt_out_buffer) goto error; dev->write_buffer = kmalloc_array(true_size, sizeof(struct alphatrack_ocmd), GFP_KERNEL); if (!dev->write_buffer) goto error; dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_out_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); goto error; } dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint-> bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint-> bInterval; if (dev->interrupt_out_endpoint) dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint-> bInterval ? min_interrupt_out_interval : dev-> interrupt_out_endpoint->bInterval; /* we can register the device now, as it is ready */ usb_set_intfdata(intf, dev); atomic_set(&dev->writes_pending, 0); retval = usb_register_dev(intf, &usb_alphatrack_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&intf->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(intf, NULL); goto error; } /* let the user know what node this device is now attached to */ dev_info(&intf->dev, "Alphatrack Device #%d now attached to major %d minor %d\n", (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR, intf->minor); exit: return retval; error: usb_alphatrack_delete(dev); return retval; }
/** * adu_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int adu_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct adu_device *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int retval = -ENODEV; int in_end_size; int out_end_size; int i; dbg(2," %s : enter", __func__); if (udev == NULL) { dev_err(&interface->dev, "udev is NULL.\n"); goto exit; } /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "Out of memory\n"); retval = -ENOMEM; goto exit; } mutex_init(&dev->mtx); spin_lock_init(&dev->buflock); dev->udev = udev; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); iface_desc = &interface->altsetting[0]; /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->interrupt_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) dev->interrupt_out_endpoint = endpoint; } if (dev->interrupt_in_endpoint == NULL) { dev_err(&interface->dev, "interrupt in endpoint not found\n"); goto error; } if (dev->interrupt_out_endpoint == NULL) { dev_err(&interface->dev, "interrupt out endpoint not found\n"); goto error; } in_end_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); out_end_size = le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize); dev->read_buffer_primary = kmalloc((4 * in_end_size), GFP_KERNEL); if (!dev->read_buffer_primary) { dev_err(&interface->dev, "Couldn't allocate read_buffer_primary\n"); retval = -ENOMEM; goto error; } /* debug code prime the buffer */ memset(dev->read_buffer_primary, 'a', in_end_size); memset(dev->read_buffer_primary + in_end_size, 'b', in_end_size); memset(dev->read_buffer_primary + (2 * in_end_size), 'c', in_end_size); memset(dev->read_buffer_primary + (3 * in_end_size), 'd', in_end_size); dev->read_buffer_secondary = kmalloc((4 * in_end_size), GFP_KERNEL); if (!dev->read_buffer_secondary) { dev_err(&interface->dev, "Couldn't allocate read_buffer_secondary\n"); retval = -ENOMEM; goto error; } /* debug code prime the buffer */ memset(dev->read_buffer_secondary, 'e', in_end_size); memset(dev->read_buffer_secondary + in_end_size, 'f', in_end_size); memset(dev->read_buffer_secondary + (2 * in_end_size), 'g', in_end_size); memset(dev->read_buffer_secondary + (3 * in_end_size), 'h', in_end_size); dev->interrupt_in_buffer = kmalloc(in_end_size, GFP_KERNEL); if (!dev->interrupt_in_buffer) { dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n"); goto error; } /* debug code prime the buffer */ memset(dev->interrupt_in_buffer, 'i', in_end_size); dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_in_urb) { dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->interrupt_out_buffer = kmalloc(out_end_size, GFP_KERNEL); if (!dev->interrupt_out_buffer) { dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n"); goto error; } dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_out_urb) { dev_err(&interface->dev, "Couldn't allocate interrupt_out_urb\n"); goto error; } if (!usb_string(udev, udev->descriptor.iSerialNumber, dev->serial_number, sizeof(dev->serial_number))) { dev_err(&interface->dev, "Could not retrieve serial number\n"); goto error; } dbg(2," %s : serial_number=%s", __func__, dev->serial_number); /* we can register the device now, as it is ready */ usb_set_intfdata(interface, dev); retval = usb_register_dev(interface, &adu_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&interface->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(interface, NULL); goto error; } dev->minor = interface->minor; /* let the user know what node this device is now attached to */ dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n", udev->descriptor.idProduct, dev->serial_number, (dev->minor - ADU_MINOR_BASE)); exit: dbg(2," %s : leave, return value %p (dev)", __func__, dev); return retval; error: adu_delete(dev); return retval; }
/* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in * this case start handling it. */ static int kingsun_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *dev = interface_to_usbdev(intf); struct kingsun_cb *kingsun = NULL; struct net_device *net = NULL; int ret = -ENOMEM; int pipe, maxp_in, maxp_out; __u8 ep_in; __u8 ep_out; /* Check that there really are two interrupt endpoints. Check based on the one in drivers/usb/input/usbmouse.c */ interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 2) { err("kingsun-sir: expected 2 endpoints, found %d", interface->desc.bNumEndpoints); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; if (!usb_endpoint_is_int_in(endpoint)) { err("kingsun-sir: endpoint 0 is not interrupt IN"); return -ENODEV; } ep_in = endpoint->bEndpointAddress; pipe = usb_rcvintpipe(dev, ep_in); maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp_in > 255 || maxp_in <= 1) { err("%s: endpoint 0 has max packet size %d not in range", __FILE__, maxp_in); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; if (!usb_endpoint_is_int_out(endpoint)) { err("kingsun-sir: endpoint 1 is not interrupt OUT"); return -ENODEV; } ep_out = endpoint->bEndpointAddress; pipe = usb_sndintpipe(dev, ep_out); maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); /* Allocate network device container. */ net = alloc_irdadev(sizeof(*kingsun)); if(!net) goto err_out1; SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->irlap = NULL; kingsun->tx_urb = NULL; kingsun->rx_urb = NULL; kingsun->ep_in = ep_in; kingsun->ep_out = ep_out; kingsun->in_buf = NULL; kingsun->out_buf = NULL; kingsun->max_rx = (__u8)maxp_in; kingsun->max_tx = (__u8)maxp_out; kingsun->netdev = net; kingsun->usbdev = dev; kingsun->rx_buff.in_frame = FALSE; kingsun->rx_buff.state = OUTSIDE_FRAME; kingsun->rx_buff.skb = NULL; kingsun->receiving = 0; spin_lock_init(&kingsun->lock); /* Allocate input buffer */ kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); if (!kingsun->in_buf) goto free_mem; /* Allocate output buffer */ kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); if (!kingsun->out_buf) goto free_mem; printk(KERN_INFO "KingSun/DonShine IRDA/USB found at address %d, " "Vendor: %x, Product: %x\n", dev->devnum, le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&kingsun->qos); /* That's the Rx capability. */ kingsun->qos.baud_rate.bits &= IR_9600; kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; irda_qos_bits_to_value(&kingsun->qos); /* Override the network functions we need to use */ net->netdev_ops = &kingsun_ops; ret = register_netdev(net); if (ret != 0) goto free_mem; dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n", net->name); usb_set_intfdata(intf, kingsun); /* Situation at this point: - all work buffers allocated - urbs not allocated, set to NULL - max rx packet known (in max_rx) - unwrap state machine (partially) initialized, but skb == NULL */ return 0; free_mem: if (kingsun->out_buf) kfree(kingsun->out_buf); if (kingsun->in_buf) kfree(kingsun->in_buf); free_netdev(net); err_out1: return ret; }
static int kingsun_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *dev = interface_to_usbdev(intf); struct kingsun_cb *kingsun = NULL; struct net_device *net = NULL; int ret = -ENOMEM; int pipe, maxp_in, maxp_out; __u8 ep_in; __u8 ep_out; interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 2) { err("kingsun-sir: expected 2 endpoints, found %d", interface->desc.bNumEndpoints); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; if (!usb_endpoint_is_int_in(endpoint)) { err("kingsun-sir: endpoint 0 is not interrupt IN"); return -ENODEV; } ep_in = endpoint->bEndpointAddress; pipe = usb_rcvintpipe(dev, ep_in); maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp_in > 255 || maxp_in <= 1) { err("%s: endpoint 0 has max packet size %d not in range", __FILE__, maxp_in); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; if (!usb_endpoint_is_int_out(endpoint)) { err("kingsun-sir: endpoint 1 is not interrupt OUT"); return -ENODEV; } ep_out = endpoint->bEndpointAddress; pipe = usb_sndintpipe(dev, ep_out); maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); net = alloc_irdadev(sizeof(*kingsun)); if(!net) goto err_out1; SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->irlap = NULL; kingsun->tx_urb = NULL; kingsun->rx_urb = NULL; kingsun->ep_in = ep_in; kingsun->ep_out = ep_out; kingsun->in_buf = NULL; kingsun->out_buf = NULL; kingsun->max_rx = (__u8)maxp_in; kingsun->max_tx = (__u8)maxp_out; kingsun->netdev = net; kingsun->usbdev = dev; kingsun->rx_buff.in_frame = FALSE; kingsun->rx_buff.state = OUTSIDE_FRAME; kingsun->rx_buff.skb = NULL; kingsun->receiving = 0; spin_lock_init(&kingsun->lock); kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); if (!kingsun->in_buf) goto free_mem; kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); if (!kingsun->out_buf) goto free_mem; printk(KERN_INFO "KingSun/DonShine IRDA/USB found at address %d, " "Vendor: %x, Product: %x\n", dev->devnum, le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); irda_init_max_qos_capabilies(&kingsun->qos); kingsun->qos.baud_rate.bits &= IR_9600; kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; irda_qos_bits_to_value(&kingsun->qos); net->netdev_ops = &kingsun_ops; ret = register_netdev(net); if (ret != 0) goto free_mem; dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n", net->name); usb_set_intfdata(intf, kingsun); return 0; free_mem: if (kingsun->out_buf) kfree(kingsun->out_buf); if (kingsun->in_buf) kfree(kingsun->in_buf); free_netdev(net); err_out1: return ret; }
/** * usb_tranzport_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_tranzport *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i; int true_size; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { dev_err(&intf->dev, "Out of memory\n"); goto exit; } mutex_init(&dev->mtx); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); iface_desc = intf->cur_altsetting; /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->interrupt_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) dev->interrupt_out_endpoint = endpoint; } if (dev->interrupt_in_endpoint == NULL) { dev_err(&intf->dev, "Interrupt in endpoint not found\n"); goto error; } if (dev->interrupt_out_endpoint == NULL) dev_warn(&intf->dev, "Interrupt out endpoint not found" "(using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); if (dev->interrupt_in_endpoint_size != 8) dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n"); if (ring_buffer_size == 0) ring_buffer_size = RING_BUFFER_SIZE; true_size = min(ring_buffer_size, RING_BUFFER_SIZE); /* FIXME - there are more usb_alloc routines for dma correctness. Needed? */ dev->ring_buffer = kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL); if (!dev->ring_buffer) { dev_err(&intf->dev, "Couldn't allocate ring_buffer size %d\n", true_size); goto error; } dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); if (!dev->interrupt_in_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n"); goto error; } dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_in_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) : udev->descriptor.bMaxPacketSize0; if (dev->interrupt_out_endpoint_size != 8) dev_warn(&intf->dev, "Interrupt out endpoint size is not 8!)\n"); dev->interrupt_out_buffer = kmalloc(write_buffer_size * dev->interrupt_out_endpoint_size, GFP_KERNEL); if (!dev->interrupt_out_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n"); goto error; } dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_out_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); goto error; } dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; if (dev->interrupt_out_endpoint) { dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; } /* we can register the device now, as it is ready */ usb_set_intfdata(intf, dev); retval = usb_register_dev(intf, &usb_tranzport_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&intf->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(intf, NULL); goto error; } retval = device_create_file(&intf->dev, &dev_attr_compress_wheel); if (retval) goto error; retval = device_create_file(&intf->dev, &dev_attr_enable); if (retval) goto error; retval = device_create_file(&intf->dev, &dev_attr_offline); if (retval) goto error; /* let the user know what node this device is now attached to */ dev_info(&intf->dev, "Tranzport Device #%d now attached to major %d minor %d\n", (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR, intf->minor); exit: return retval; error: usb_tranzport_delete(dev); return retval; }