]> git.hungrycats.org Git - linux/commitdiff
[IRDA]: COnver irda-usb to dynamic device allocation.
authorStephen Hemminger <shemminger@osdl.org>
Thu, 26 Feb 2004 04:16:32 +0000 (20:16 -0800)
committerDavid S. Miller <davem@nuts.davemloft.net>
Thu, 26 Feb 2004 04:16:32 +0000 (20:16 -0800)
drivers/net/irda/irda-usb.c

index 5a2289a0003950e28432ec61f5f820f19c5635de..617289d1add31f07d1647c871a4cbbc57b3c710f 100644 (file)
 
 static int qos_mtt_bits = 0;
 
-/* Master instance for each hardware found */
-#define NIRUSB 4               /* Max number of USB-IrDA dongles */
-static struct irda_usb_cb irda_instance[NIRUSB];
-
 /* These are the currently known IrDA USB dongles. Add new dongles here */
 static struct usb_device_id dongles[] = {
        /* ACTiSYS Corp.,  ACT-IR2000U FIR-USB Adapter */
@@ -108,7 +104,7 @@ static void irda_usb_disconnect(struct usb_interface *intf);
 static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
 static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 static int irda_usb_open(struct irda_usb_cb *self);
-static int irda_usb_close(struct irda_usb_cb *self);
+static void irda_usb_close(struct irda_usb_cb *self);
 static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs);
 static void write_bulk_callback(struct urb *urb, struct pt_regs *regs);
 static void irda_usb_receive(struct urb *urb, struct pt_regs *regs);
@@ -1157,36 +1153,12 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self)
  */
 static inline int irda_usb_open(struct irda_usb_cb *self)
 {
-       struct net_device *netdev;
-       int err;
+       struct net_device *netdev = self->netdev;
 
        IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
-       spin_lock_init(&self->lock);
-
        irda_usb_init_qos(self);
 
-       /* Allocate the buffer for speed changes */
-       /* Don't change this buffer size and allocation without doing
-        * some heavy and complete testing. Don't ask why :-(
-        * Jean II */
-       self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
-       if (self->speed_buff == NULL) 
-               return -1;
-       memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
-
-       /* Create a network device for us */
-       netdev = alloc_irdadev(0);
-       if (!netdev) {
-               ERROR("%s(), alloc_net_dev() failed!\n", __FUNCTION__);
-               return -ENOMEM;
-       }
-
-       SET_MODULE_OWNER(dev);
-
-       self->netdev = netdev;
-       netdev->priv = (void *) self;
-
        /* Override the network functions we need to use */
        netdev->hard_start_xmit = irda_usb_hard_xmit;
        netdev->tx_timeout      = irda_usb_net_timeout;
@@ -1196,16 +1168,7 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
        netdev->get_stats       = irda_usb_net_get_stats;
        netdev->do_ioctl        = irda_usb_net_ioctl;
 
-       err = register_netdev(netdev);
-       if (err) {
-               ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
-               self->netdev = NULL;
-               free_netdev(netdev);
-               return err;
-       }
-       MESSAGE("IrDA: Registered device %s\n", netdev->name);
-
-       return 0;
+       return register_netdev(netdev);
 }
 
 /*------------------------------------------------------------------*/
@@ -1213,26 +1176,18 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
  * Cleanup the network side of the irda-usb instance
  * Called when a USB instance is removed in irda_usb_disconnect()
  */
-static inline int irda_usb_close(struct irda_usb_cb *self)
+static inline void irda_usb_close(struct irda_usb_cb *self)
 {
        IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
-       ASSERT(self != NULL, return -1;);
-
        /* Remove netdevice */
-       if (self->netdev) {
-               unregister_netdev(self->netdev);
-               free_netdev(self->netdev);
-               self->netdev = NULL;
-       }
+       unregister_netdev(self->netdev);
 
        /* Remove the speed buffer */
        if (self->speed_buff != NULL) {
                kfree(self->speed_buff);
                self->speed_buff = NULL;
        }
-
-       return 0;
 }
 
 /********************** USB CONFIG SUBROUTINES **********************/
@@ -1402,11 +1357,12 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf
 static int irda_usb_probe(struct usb_interface *intf,
                          const struct usb_device_id *id)
 {
+       struct net_device *net;
        struct usb_device *dev = interface_to_usbdev(intf);
        struct irda_usb_cb *self = NULL;
        struct usb_host_interface *interface;
        struct irda_class_desc *irda_desc;
-       int ret;
+       int ret = -ENOMEM;
        int i;          /* Driver instance index / Rx URB index */
 
        /* Note : the probe make sure to call us only for devices that
@@ -1418,53 +1374,29 @@ static int irda_usb_probe(struct usb_interface *intf,
                dev->devnum, dev->descriptor.idVendor,
                dev->descriptor.idProduct);
 
-       /* Try to cleanup all instance that have a pending disconnect
-        * In theory, it can't happen any longer.
-        * Jean II */
-       for (i = 0; i < NIRUSB; i++) {
-               struct irda_usb_cb *irda = &irda_instance[i];
-               if((irda->usbdev != NULL) &&
-                  (irda->present == 0) &&
-                  (irda->netopen == 0)) {
-                       IRDA_DEBUG(0, "%s(), found a zombie instance !!!\n", __FUNCTION__);
-                       irda_usb_disconnect(irda->usbintf);
-               }
-       }
+       net = alloc_irdadev(sizeof(*self));
+       if (!net) 
+               goto err_out;
 
-       /* Find an free instance to handle this new device... */
-       self = NULL;
-       for (i = 0; i < NIRUSB; i++) {
-               if(irda_instance[i].usbdev == NULL) {
-                       self = &irda_instance[i];
-                       break;
-               }
-       }
-       if(self == NULL) {
-               WARNING("Too many USB IrDA devices !!! (max = %d)\n",
-                          NIRUSB);
-               return -ENFILE;
-       }
+       self = net->priv;
+       self->netdev = net;
+       spin_lock_init(&self->lock);
 
-       /* Reset the instance */
-       self->present = 0;
-       self->netopen = 0;
+       SET_MODULE_OWNER(net);
 
        /* Create all of the needed urbs */
        for (i = 0; i < IU_MAX_RX_URBS; i++) {
                self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
                if (!self->rx_urb[i]) {
-                       ret = -ENOMEM;
                        goto err_out_1;
                }
        }
        self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!self->tx_urb) {
-               ret = -ENOMEM;
                goto err_out_1;
        }
        self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!self->speed_urb) {
-               ret = -ENOMEM;
                goto err_out_2;
        }
 
@@ -1517,13 +1449,27 @@ static int irda_usb_probe(struct usb_interface *intf,
        self->capability = id->driver_info;
        self->usbdev = dev;
        self->usbintf = intf;
-       ret = irda_usb_open(self);
-       if (ret)
+
+       /* Allocate the buffer for speed changes */
+       /* Don't change this buffer size and allocation without doing
+        * some heavy and complete testing. Don't ask why :-(
+        * Jean II */
+       self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
+       if (self->speed_buff == NULL) 
                goto err_out_3;
 
+       memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
+
+       ret = irda_usb_open(self);
+       if (ret) 
+               goto err_out_4;
+
+       MESSAGE("IrDA: Registered device %s\n", net->name);
        usb_set_intfdata(intf, self);
        return 0;
 
+err_out_4:
+       kfree(self->speed_buff);
 err_out_3:
        /* Free all urbs that we may have created */
        usb_free_urb(self->speed_urb);
@@ -1534,7 +1480,8 @@ err_out_1:
                if (self->rx_urb[i])
                        usb_free_urb(self->rx_urb[i]);
        }
-
+       free_netdev(net);
+err_out:
        return ret;
 }
 
@@ -1602,6 +1549,8 @@ static void irda_usb_disconnect(struct usb_interface *intf)
        usb_free_urb(self->tx_urb);
        usb_free_urb(self->speed_urb);
 
+       /* Free self and network device */
+       free_netdev(self->netdev);
        IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __FUNCTION__);
 }
 
@@ -1646,20 +1595,6 @@ module_init(usb_irda_init);
  */
 static void __exit usb_irda_cleanup(void)
 {
-       struct irda_usb_cb *irda = NULL;
-       int     i;
-
-       /* Find zombie instances and kill them...
-        * In theory, it can't happen any longer. Jean II */
-       for (i = 0; i < NIRUSB; i++) {
-               irda = &irda_instance[i];
-               /* If the Device is zombie */
-               if((irda->usbdev != NULL) && (irda->present == 0)) {
-                       IRDA_DEBUG(0, "%s(), disconnect zombie now !\n", __FUNCTION__);
-                       irda_usb_disconnect(irda->usbintf);
-               }
-       }
-
        /* Deregister the driver and remove all pending instances */
        usb_deregister(&irda_driver);
 }