All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.5] pcmcia (3/5): register drivers with bus
@ 2003-03-22 16:00 Dominik Brodowski
  0 siblings, 0 replies; only message in thread
From: Dominik Brodowski @ 2003-03-22 16:00 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

Register all pcmcia drivers with the pcmcia bus within the old
register_pccard_driver() function. Alternatively, a new
registration function "pcmcia_register_driver()" (and its
counterpart,  "pcmcia_unregister_driver()") can be used.

diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- linux-original/drivers/pcmcia/ds.c	2003-03-22 16:48:49.000000000 +0100
+++ linux/drivers/pcmcia/ds.c	2003-03-22 16:50:43.000000000 +0100
@@ -77,16 +77,8 @@
 
 /*====================================================================*/
 
-typedef struct driver_info_t {
-    dev_info_t		dev_info;
-    int			use_count, status;
-    dev_link_t		*(*attach)(void);
-    void		(*detach)(dev_link_t *);
-    struct driver_info_t *next;
-} driver_info_t;
-
 typedef struct socket_bind_t {
-    driver_info_t	*driver;
+    struct pcmcia_driver	*driver;
     u_char		function;
     dev_link_t		*instance;
     struct socket_bind_t *next;
@@ -125,7 +117,7 @@
 static dev_info_t dev_info = "Driver Services";
 
 /* Linked list of all registered device drivers */
-static driver_info_t *root_driver = NULL;
+static struct pcmcia_driver *root_driver = NULL;
 
 static int sockets = 0, major_dev = -1;
 static socket_info_t *socket_table = NULL;
@@ -151,27 +143,67 @@
     
 ======================================================================*/
 
+/**
+ * pcmcia_register_driver - register a PCMCIA driver with the bus core
+ *
+ * Registers a PCMCIA driver with the PCMCIA bus core.
+ */
+int pcmcia_register_driver(struct pcmcia_driver *driver)
+{
+	if (!driver)
+		return -EINVAL;
+
+ 	driver->use_count = 0;
+ 	driver->status = init_status;
+	driver->drv.bus = &pcmcia_bus_type;
+	driver->next = root_driver;
+	root_driver = driver;
+
+	return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(pcmcia_register_driver);
+
+/**
+ * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
+ */
+void pcmcia_unregister_driver(struct pcmcia_driver *driver)
+{
+	socket_bind_t *b;
+	int i;
+
+	if (driver->use_count > 0) {
+		/* Blank out any left-over device instances */
+		driver->attach = NULL; driver->detach = NULL;
+		for (i = 0; i < sockets; i++)
+			for (b = socket_table[i].bind; b; b = b->next)
+				if (b->driver == driver) 
+				b->instance = NULL;
+ 	}
+
+	driver_unregister(&driver->drv);
+}
+EXPORT_SYMBOL(pcmcia_unregister_driver);
+ 
+
 int register_pccard_driver(dev_info_t *dev_info,
 			   dev_link_t *(*attach)(void),
 			   void (*detach)(dev_link_t *))
 {
-    driver_info_t *driver;
+    struct pcmcia_driver *driver;
     socket_bind_t *b;
     int i;
 
     DEBUG(0, "ds: register_pccard_driver('%s')\n", (char *)dev_info);
     for (driver = root_driver; driver; driver = driver->next)
-	if (strncmp((char *)dev_info, (char *)driver->dev_info,
+	if (strncmp((char *)dev_info, (char *)driver->drv.name,
 		    DEV_NAME_LEN) == 0)
 	    break;
     if (!driver) {
-	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
+	driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL);
 	if (!driver) return -ENOMEM;
-	strncpy(driver->dev_info, (char *)dev_info, DEV_NAME_LEN);
-	driver->use_count = 0;
-	driver->status = init_status;
-	driver->next = root_driver;
-	root_driver = driver;
+	memset(driver, 0, sizeof(struct pcmcia_driver));
+	driver->drv.name = (char *)dev_info;
+	pcmcia_register_driver(driver);
     }
 
     driver->attach = attach;
@@ -185,7 +217,7 @@
 	    b->instance = driver->attach();
 	    if (b->instance == NULL)
 		printk(KERN_NOTICE "ds: unable to create instance "
-		       "of '%s'!\n", driver->dev_info);
+		       "of '%s'!\n", driver->drv.name);
 	}
     
     return 0;
@@ -195,29 +227,18 @@
 
 int unregister_pccard_driver(dev_info_t *dev_info)
 {
-    driver_info_t *target, **d = &root_driver;
-    socket_bind_t *b;
-    int i;
+    struct pcmcia_driver **d = &root_driver;
     
     DEBUG(0, "ds: unregister_pccard_driver('%s')\n",
 	  (char *)dev_info);
-    while ((*d) && (strncmp((*d)->dev_info, (char *)dev_info,
+    while ((*d) && (strncmp((*d)->drv.name, (char *)dev_info,
 			    DEV_NAME_LEN) != 0))
 	d = &(*d)->next;
     if (*d == NULL)
 	return -ENODEV;
     
-    target = *d;
-    if (target->use_count == 0) {
-	*d = target->next;
-	kfree(target);
-    } else {
-	/* Blank out any left-over device instances */
-	target->attach = NULL; target->detach = NULL;
-	for (i = 0; i < sockets; i++)
-	    for (b = socket_table[i].bind; b; b = b->next)
-		if (b->driver == target) b->instance = NULL;
-    }
+    pcmcia_unregister_driver(*d);
+    kfree(*d);
     return 0;
 } /* unregister_pccard_driver */
 
@@ -227,10 +248,10 @@
 static int proc_read_drivers(char *buf, char **start, off_t pos,
 			     int count, int *eof, void *data)
 {
-    driver_info_t *d;
+    struct pcmcia_driver *d;
     char *p = buf;
     for (d = root_driver; d; d = d->next)
-	p += sprintf(p, "%-24.24s %d %d\n", d->dev_info,
+	p += sprintf(p, "%-24.24s %d %d\n", d->drv.name,
 		     d->status, d->use_count);
     return (p - buf);
 }
@@ -376,7 +397,7 @@
 
 static int bind_request(int i, bind_info_t *bind_info)
 {
-    struct driver_info_t *driver;
+    struct pcmcia_driver *driver;
     socket_bind_t *b;
     bind_req_t bind_req;
     socket_info_t *s = &socket_table[i];
@@ -385,17 +406,15 @@
     DEBUG(2, "bind_request(%d, '%s')\n", i,
 	  (char *)bind_info->dev_info);
     for (driver = root_driver; driver; driver = driver->next)
-	if (strcmp((char *)driver->dev_info,
+	if (strcmp((char *)driver->drv.name,
 		   (char *)bind_info->dev_info) == 0)
 	    break;
     if (driver == NULL) {
-	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
+	driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL);
 	if (!driver) return -ENOMEM;
-	strncpy(driver->dev_info, bind_info->dev_info, DEV_NAME_LEN);
-	driver->use_count = 0;
-	driver->next = root_driver;
-	driver->attach = NULL; driver->detach = NULL;
-	root_driver = driver;
+	memset(driver, 0, sizeof(struct pcmcia_driver));
+	driver->drv.name = bind_info->dev_info;
+	pcmcia_register_driver(driver);
     }
 
     for (b = s->bind; b; b = b->next)
@@ -409,7 +428,7 @@
 
     bind_req.Socket = i;
     bind_req.Function = bind_info->function;
-    bind_req.dev_info = &driver->dev_info;
+    bind_req.dev_info = (dev_info_t *) driver->drv.name;
     ret = pcmcia_bind_device(&bind_req);
     if (ret != CS_SUCCESS) {
 	cs_error(NULL, BindDevice, ret);
@@ -490,7 +509,7 @@
 #endif
 
     for (b = s->bind; b; b = b->next)
-	if ((strcmp((char *)b->driver->dev_info,
+	if ((strcmp((char *)b->driver->drv.name,
 		    (char *)bind_info->dev_info) == 0) &&
 	    (b->function == bind_info->function))
 	    break;
@@ -524,7 +543,7 @@
     DEBUG(2, "unbind_request(%d, '%s')\n", i,
 	  (char *)bind_info->dev_info);
     for (b = &s->bind; *b; b = &(*b)->next)
-	if ((strcmp((char *)(*b)->driver->dev_info,
+	if ((strcmp((char *)(*b)->driver->drv.name,
 		    (char *)bind_info->dev_info) == 0) &&
 	    ((*b)->function == bind_info->function))
 	    break;
@@ -538,10 +557,11 @@
 	    c->driver->detach(c->instance);
     } else {
 	if (c->driver->use_count == 0) {
-	    driver_info_t **d;
+	    struct pcmcia_driver **d;
 	    for (d = &root_driver; *d; d = &((*d)->next))
 		if (c->driver == *d) break;
 	    *d = (*d)->next;
+	    pcmcia_unregister_driver(c->driver);
 	    kfree(c->driver);
 	}
     }
diff -ruN linux-original/include/pcmcia/ds.h linux/include/pcmcia/ds.h
--- linux-original/include/pcmcia/ds.h	2003-03-22 16:48:49.000000000 +0100
+++ linux/include/pcmcia/ds.h	2003-03-22 16:46:21.000000000 +0100
@@ -146,6 +146,18 @@
 
 extern struct bus_type pcmcia_bus_type;
 
+struct pcmcia_driver {
+	int			use_count, status;
+	dev_link_t		*(*attach)(void);
+	void			(*detach)(dev_link_t *);
+	struct module		*owner;
+	struct device_driver	drv;
+	struct pcmcia_driver	*next;
+};
+
+int pcmcia_register_driver(struct pcmcia_driver *driver);
+void pcmcia_unregister_driver(struct pcmcia_driver *driver);
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_DS_H */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-03-22 15:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-22 16:00 [PATCH 2.5] pcmcia (3/5): register drivers with bus Dominik Brodowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.