speedtch usbatm.h,NONE,1.1 usbatm2.c,1.6,1.7 speedtch2.c,1.6,1.7

Duncan Sands duncan at infradead.org
Mon Jan 24 04:44:45 EST 2005


Update of /home/cvs/speedtch
In directory phoenix.infradead.org:/tmp/cvs-serv21427

Modified Files:
	usbatm2.c speedtch2.c 
Added Files:
	usbatm.h 
Log Message:
It seems I forgot to add the key file usbatm.h...  Added full-blown registration/
deregistration methods.  It's cleaner and avoid duplicated driver structures.  The
heavy_init thread needs to take a module reference to the mini driver module, rather
than itself, so fix that.


--- NEW FILE usbatm.h ---
/******************************************************************************
 *  usbatm.h - Generic USB xDSL driver core
 *
 *  Copyright (C) 2001, Alcatel
 *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
 *  Copyright (C) 2004, David Woodhouse
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 *  more details.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc., 59
 *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 ******************************************************************************/

#ifndef	_USBATM_H_
#define	_USBATM_H_

#include <linux/config.h>
#include <linux/list.h>
#include <linux/kref.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <asm/semaphore.h>

/*
#define DEBUG
#define VERBOSE_DEBUG
*/

#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
#	define DEBUG
#endif

#include <linux/usb.h>

#ifdef DEBUG
#define UDSL_ASSERT(x)	BUG_ON(!(x))
#else
#define UDSL_ASSERT(x)	do { if (!(x)) warn("failed assertion '" #x "' at line %d", __LINE__); } while(0)
#endif


/* mini driver */

struct usbatm_data;

/*
*  Assuming all methods exist and succeed, they are called like this (except if
*  the device is disconnected during heavy_init, see below):
*
*  	bind, heavy_init, atm_start, atm_stop, unbind
*
*  If heavy_init exists, it is run in its own kernel thread.  If the device is
*  disconnected while heavy_init is executing, then methods are called as follows:
*
*  	bind, heavy_init
*		unbind
*
*  Here unbind may be called while heavy_init is executing. QQ probably heavy_init
*  should be shot down before calling unbind.
*/

struct usbatm_driver {
	const char *driver_name;
	struct module *owner;
	const struct usb_device_id *id_table;

	/* init device ... can sleep, or cause probe() failure */
        int (*bind) (struct usbatm_data *, struct usb_interface *);

	/* additional device initialization that is too slow to be done in probe() */
        int (*heavy_init) (struct usbatm_data *, struct usb_interface *);

	/* cleanup device ... can sleep, but can't fail */
        void (*unbind) (struct usbatm_data *, struct usb_interface *);

	/* init ATM device ... can sleep, or cause ATM initialization failure */
	int (*atm_start) (struct usbatm_data *, struct atm_dev *);

	/* cleanup ATM device ... can sleep, but can't fail */
	void (*atm_stop) (struct usbatm_data *, struct atm_dev *);

        int in;		/* rx endpoint */
        int out;	/* tx endpoint */

	unsigned rx_padding;
	unsigned tx_padding;

	/* private */
	struct usb_driver usb;
};

int usbatm_register (struct usbatm_driver *driver);
void usbatm_deregister (struct usbatm_driver *driver);


/* usbatm */

#define UDSL_MAX_RCV_URBS		4
#define UDSL_MAX_SND_URBS		4
#define UDSL_MAX_RCV_BUFS		8
#define UDSL_MAX_SND_BUFS		8
#define UDSL_MAX_RCV_BUF_SIZE		1024	/* ATM cells */
#define UDSL_MAX_SND_BUF_SIZE		1024	/* ATM cells */
#define UDSL_DEFAULT_RCV_URBS		2
#define UDSL_DEFAULT_SND_URBS		2
#define UDSL_DEFAULT_RCV_BUFS		4
#define UDSL_DEFAULT_SND_BUFS		4
#define UDSL_DEFAULT_RCV_BUF_SIZE	64	/* ATM cells */
#define UDSL_DEFAULT_SND_BUF_SIZE	64	/* ATM cells */


/* receive */

struct udsl_receive_buffer {
	struct list_head list;
	unsigned char *base;
	unsigned int filled_cells;
};

struct udsl_receiver {
	struct list_head list;
	struct udsl_receive_buffer *buffer;
	struct urb *urb;
	struct usbatm_data *instance;
};


/* send */

struct udsl_send_buffer {
	struct list_head list;
	unsigned char *base;
	unsigned char *free_start;
	unsigned int free_cells;
};

struct udsl_sender {
	struct list_head list;
	struct udsl_send_buffer *buffer;
	struct urb *urb;
	struct usbatm_data *instance;
};


/* main driver data */

struct usbatm_data {
	struct kref refcount;
	struct semaphore serialize;

	/* mini driver part */
	struct usbatm_driver *driver;
	void *driver_data;

	/* USB device part */
	struct usb_device *usb_dev;
	struct usb_interface *usb_intf;
	char description[64];
	int bound;
	int tx_endpoint;
	int rx_endpoint;
	int tx_padding;
	int rx_padding;

	/* ATM device part */
	struct atm_dev *atm_dev;
	struct list_head vcc_list;

	/* receive */
	struct udsl_receiver receivers[UDSL_MAX_RCV_URBS];
	struct udsl_receive_buffer receive_buffers[UDSL_MAX_RCV_BUFS];

	spinlock_t receive_lock;
	struct list_head spare_receivers;
	struct list_head filled_receive_buffers;

	struct tasklet_struct receive_tasklet;
	struct list_head spare_receive_buffers;

	/* send */
	struct udsl_sender senders[UDSL_MAX_SND_URBS];
	struct udsl_send_buffer send_buffers[UDSL_MAX_SND_BUFS];

	struct sk_buff_head sndqueue;

	spinlock_t send_lock;
	struct list_head spare_senders;
	struct list_head spare_send_buffers;

	struct tasklet_struct send_tasklet;
	struct sk_buff *current_skb;			/* being emptied */
	struct udsl_send_buffer *current_buffer;	/* being filled */
	struct list_head filled_send_buffers;
};

#endif	/* _USBATM_H_ */

Index: usbatm2.c
===================================================================
RCS file: /home/cvs/speedtch/usbatm2.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- usbatm2.c	23 Jan 2005 14:34:52 -0000	1.6
+++ usbatm2.c	24 Jan 2005 09:44:42 -0000	1.7
@@ -1025,7 +1025,7 @@
 	if (!ret)
 		ret = usbatm_atm_init(instance);
 
-	module_put(THIS_MODULE);
+	module_put(instance->driver->owner);
 	udsl_put_instance(instance);	/* taken in usbatm_heavy_init */
 
 	return ret;
@@ -1036,7 +1036,7 @@
 	int ret;
 
 	udsl_get_instance(instance);	/* dropped below or in usbatm_do_heavy_init */
-	try_module_get(THIS_MODULE);
+	try_module_get(instance->driver->owner);
 
 	ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES);
 
@@ -1045,13 +1045,13 @@
 
 	dbg("usbatm_heavy_init: kernel_thread failed (%d)!", ret);
 
-	module_put(THIS_MODULE);
+	module_put(instance->driver->owner);
 	udsl_put_instance(instance);	/* taken above */
 
 	return ret;
 }
 
-int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
+static int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usbatm_driver *driver = (struct usbatm_driver *) id->driver_info;
@@ -1219,9 +1219,8 @@
 
 	return error;
 }
-EXPORT_SYMBOL_GPL(usbatm_usb_probe);
 
-void usbatm_disconnect(struct usb_interface *intf)
+static void usbatm_disconnect(struct usb_interface *intf)
 {
 	struct usbatm_data *instance = usb_get_intfdata(intf);
 	int i;
@@ -1288,13 +1287,32 @@
 
 	udsl_put_instance(instance);	/* taken in usbatm_usb_probe */
 }
-EXPORT_SYMBOL_GPL(usbatm_disconnect);
 
 
 /***********
 **  init  **
 ***********/
 
+int usbatm_register (struct usbatm_driver *driver)
+{
+	struct usb_driver *usb_driver = &driver->usb;
+
+	usb_driver->owner	= driver->owner;
+	usb_driver->name	= driver->driver_name;
+        usb_driver->probe	= usbatm_usb_probe;
+        usb_driver->disconnect	= usbatm_disconnect;
+        usb_driver->id_table	= driver->id_table;
+
+	return usb_register(usb_driver);
+}
+EXPORT_SYMBOL_GPL(usbatm_register);
+
+void usbatm_deregister (struct usbatm_driver *driver)
+{
+	usb_deregister(&driver->usb);
+}
+EXPORT_SYMBOL_GPL(usbatm_deregister);
+
 static int __init udsl_usb_init(void)
 {
 	dbg("udsl_usb_init: driver version " DRIVER_VERSION);

Index: speedtch2.c
===================================================================
RCS file: /home/cvs/speedtch/speedtch2.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- speedtch2.c	23 Jan 2005 14:34:52 -0000	1.6
+++ speedtch2.c	24 Jan 2005 09:44:42 -0000	1.7
@@ -21,6 +21,7 @@
  *
  ******************************************************************************/
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/gfp.h>
@@ -42,7 +43,7 @@
 #include <linux/init.h>
 #include <linux/firmware.h>
 
-#include "speedtch2.h"
+#include "usbatm.h"
 
 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 #	define USE_FW_LOADER
@@ -91,6 +92,8 @@
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
 
+/* misc */
+
 struct speedtch_instance_data {
 	struct usbatm_data *usbatm;
 
@@ -101,10 +104,7 @@
 	struct timer_list poll_timer;
 };
 
-/* USB */
-
 static int speedtch_firmware_probe(struct usb_interface *intf, const struct usb_device_id *id);
-//QQstatic void speedtch_usb_disconnect(struct usb_interface *intf);
 static void speedtch_firmware_disconnect(struct usb_interface *intf);
 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs);
 static void speedtch_poll_status(struct speedtch_instance_data *instance);
@@ -729,24 +729,42 @@
 *  init  *
 *********/
 
+static struct usbatm_driver speedtch_driver;
+
+static const struct usb_device_id speedtch_products [] = {
+{
+	USB_DEVICE(0x06b9, 0x4061),
+	.driver_info = (unsigned long) &speedtch_driver
+},
+	{}	/* END */
+};
+
 MODULE_DEVICE_TABLE (usb, speedtch_products);
 
-static struct usb_driver speedtch_info = {
+static struct usbatm_driver speedtch_driver = {
+	.driver_name	= speedtch_driver_name,
 	.owner		= THIS_MODULE,
-	.name		= speedtch_driver_name,
-	.probe		= usbatm_usb_probe,
-	.disconnect	= usbatm_disconnect,
-	.id_table	= speedtch_products
+	.id_table	= speedtch_products,
+
+	.bind		= speedtch_bind,
+#ifdef	CONFIG_FW_LOADER
+	.heavy_init	= speedtch_load_firmware,
+#endif
+
+	.atm_start	= speedtch_atm_start,
+	.atm_stop	= speedtch_atm_stop,
+
+	.in = 7, .out = 7
 };
 
 static int __init speedtch_init(void)
 {
-	return usb_register(&speedtch_info);
+	return usbatm_register(&speedtch_driver);
 }
 module_init(speedtch_init);
 
 static void __exit speedtch_exit(void)
 {
-	usb_deregister (&speedtch_info);
+	usbatm_deregister (&speedtch_driver);
 }
 module_exit(speedtch_exit);




More information about the Usbatm-commits mailing list