[PATCH] pcmcia: remove socket_table

Dominik Brodowski linux at brodo.de
Sat May 17 23:12:59 BST 2003


This patch removes the socket_table from cs.c and friends. A new
struct pcmcia_socket is introduced which will serve as main argument
on calls between cs.c and the socket drivers, and cs.c and other users
like ds.c .

 drivers/pcmcia/bulkmem.c     |    2
 drivers/pcmcia/cs.c          |  128 ++++++++++++++++++++++++++-----------------
 drivers/pcmcia/cs_internal.h |   11 +--
 drivers/pcmcia/rsrc_mgr.c    |   10 ++-
 include/pcmcia/ss.h          |    8 ++
 5 files changed, 99 insertions(+), 60 deletions(-)

diff -ruN linux-original/drivers/pcmcia/bulkmem.c linux/drivers/pcmcia/bulkmem.c
--- linux-original/drivers/pcmcia/bulkmem.c	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/bulkmem.c	2003-05-17 19:39:01.000000000 +0200
@@ -538,7 +538,7 @@
     
     if ((handle == NULL) || CHECK_HANDLE(*handle))
 	return CS_BAD_HANDLE;
-    s = SOCKET(*handle);
+    s = get_s_info_by_nr((*handle)->Socket);
     if (open->Attributes & MEMORY_TYPE_AM)
 	region = s->a_region;
     else
diff -ruN linux-original/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- linux-original/drivers/pcmcia/cs.c	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/cs.c	2003-05-17 20:36:53.000000000 +0200
@@ -123,9 +123,9 @@
     0, SS_DETECT, 0, 0, 0
 };
 
-/* Table of sockets */
-socket_t sockets = 0;
-socket_info_t *socket_table[MAX_SOCK];
+/* list of sockets */
+LIST_HEAD(pcmcia_socket_list);
+DECLARE_MUTEX(pcmcia_socket_list_lock);
 
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_pccard = NULL;
@@ -307,6 +307,21 @@
 
 #define to_class_data(dev) dev->class_data
 
+socket_info_t * get_s_info_by_nr(unsigned int s_nr)
+{
+	struct pcmcia_socket *tmp;
+	down(&pcmcia_socket_list_lock);
+	list_for_each_entry(tmp, &pcmcia_socket_list, socket_list) {
+		if (tmp->socket_no == s_nr) {
+			up(&pcmcia_socket_list_lock);
+			return ((socket_info_t *) tmp->s_info);
+		}
+	}
+	up(&pcmcia_socket_list_lock);
+	return NULL;
+}
+
+
 /**
  * pcmcia_register_socket - add a new pcmcia socket device
  */
@@ -314,7 +329,8 @@
 {
 	struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
 	socket_info_t *s_info;
-	unsigned int i, j, ret;
+	unsigned int i, ret;
+	struct pcmcia_socket *socket;
 
 	if (!cls_d)
 		return -EINVAL;
@@ -343,11 +359,16 @@
 		INIT_LIST_HEAD(&s->cis_cache);
 		spin_lock_init(&s->lock);
 
-		/* TBD: remove usage of socket_table, use class_for_each_dev instead */
-		for (j = 0; j < sockets; j++)
-			if (socket_table[j] == NULL) break;
-		socket_table[j] = s;
-		if (j == sockets) sockets++;
+		socket = kmalloc(sizeof(struct pcmcia_socket), GFP_KERNEL);
+		if (!socket)
+			return -ENOMEM;
+		memset(socket, 0, sizeof(struct pcmcia_socket));
+
+		socket->s_info = (void *) s;
+		socket->socket_no = s->sock;
+		down(&pcmcia_socket_list_lock);
+		list_add_tail(&socket->socket_list, &pcmcia_socket_list);
+		up(&pcmcia_socket_list_lock);
 
 		init_socket(s);
 		s->ss_entry->inquire_socket(s->sock, &s->cap);
@@ -368,7 +389,7 @@
 #ifdef CONFIG_PROC_FS
 		if (proc_pccard) {
 			char name[3];
-			sprintf(name, "%02d", j);
+			sprintf(name, "%02d", s->sock);
 			s->proc = proc_mkdir(name, proc_pccard);
 			if (s->proc)
 				s->ss_entry->proc_setup(i, s->proc);
@@ -389,9 +410,9 @@
  */
 void pcmcia_unregister_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
+ 	struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
+	struct pcmcia_socket *socket;
 	unsigned int i;
-	int j, socket = -1;
 	client_t *client;
 	socket_info_t *s;
 
@@ -401,18 +422,21 @@
 	s = (socket_info_t *) cls_d->s_info;
 
 	for (i = 0; i < cls_d->nsock; i++) {
-		for (j = 0; j < MAX_SOCK; j++)
-			if (socket_table [j] == s) {
-				socket = j;
-				break;
-			}
-		if (socket < 0)
-			continue;
-		
+		down(&pcmcia_socket_list_lock);
+		list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+			if (socket->s_info == s)
+				goto found;
+		}
+		up(&pcmcia_socket_list_lock);
+		continue;
+
+	found:
+		up(&pcmcia_socket_list_lock);
+
 #ifdef CONFIG_PROC_FS
 		if (proc_pccard) {
 			char name[3];
-			sprintf(name, "%02d", socket);
+			sprintf(name, "%02d", s->sock);
 #ifdef PCMCIA_DEBUG
 			remove_proc_entry("clients", s->proc);
 #endif
@@ -432,10 +456,9 @@
 			kfree(client);
 		}
 		s->ss_entry = NULL;
-		socket_table[socket] = NULL;
-		for (j = socket; j < sockets-1; j++)
-			socket_table[j] = socket_table[j+1];
-		sockets--;
+		down(&pcmcia_socket_list_lock);
+		list_del(&socket->socket_list);
+		up(&pcmcia_socket_list_lock);
 
 		s++;
 	}
@@ -1018,9 +1041,9 @@
     client_t *client;
     socket_info_t *s;
 
-    if (CHECK_SOCKET(req->Socket))
-	return CS_BAD_SOCKET;
     s = SOCKET(req);
+    if (!s)
+	    return CS_BAD_SOCKET;
 
     client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
     if (!client) return CS_OUT_OF_RESOURCE;
@@ -1054,9 +1077,9 @@
     socket_info_t *s;
     memory_handle_t region;
     
-    if (CHECK_SOCKET(req->Socket))
-	return CS_BAD_SOCKET;
     s = SOCKET(req);
+    if (!s)
+	return CS_BAD_SOCKET;
     
     if (req->Attributes & REGION_TYPE_AM)
 	region = s->a_region;
@@ -1105,7 +1128,7 @@
 	    if (region->mtd == handle) region->mtd = NULL;
     }
     
-    sn = handle->Socket; s = socket_table[sn];
+    sn = handle->Socket; s = get_s_info_by_nr(sn);
 
     if ((handle->state & CLIENT_STALE) ||
 	(handle->Attributes & INFO_MASTER_CLIENT)) {
@@ -1208,9 +1231,15 @@
 
 int pcmcia_get_card_services_info(servinfo_t *info)
 {
+    unsigned int socket_count = 0;
+    struct list_head *tmp;
     info->Signature[0] = 'C';
     info->Signature[1] = 'S';
-    info->Count = sockets;
+    down(&pcmcia_socket_list_lock);
+    list_for_each(tmp, &pcmcia_socket_list)
+	    socket_count++;
+    up(&pcmcia_socket_list_lock);
+    info->Count = socket_count;
     info->Revision = CS_RELEASE_CODE;
     info->CSLevel = 0x0210;
     info->VendorString = (char *)release;
@@ -1227,15 +1256,17 @@
 int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
 {
     socket_t s;
+    socket_info_t *socket;
     if (req->Attributes & CLIENT_THIS_SOCKET)
 	s = req->Socket;
     else
 	s = 0;
-    if (CHECK_SOCKET(req->Socket))
+    socket = get_s_info_by_nr(s);
+    if (!socket)
 	return CS_BAD_SOCKET;
-    if (socket_table[s]->clients == NULL)
+    if (socket->clients == NULL)
 	return CS_NO_MORE_ITEMS;
-    *handle = socket_table[s]->clients;
+    *handle = socket->clients;
     return CS_SUCCESS;
 } /* get_first_client */
 
@@ -1249,7 +1280,7 @@
     if ((*handle)->next == NULL) {
 	if (req->Attributes & CLIENT_THIS_SOCKET)
 	    return CS_NO_MORE_ITEMS;
-	s = SOCKET(*handle);
+	s = get_s_info_by_nr((*handle)->Socket);
 	if (s->clients == NULL)
 	    return CS_NO_MORE_ITEMS;
 	*handle = s->clients;
@@ -1267,7 +1298,7 @@
     int w;
 
     if (idx == 0)
-	s = SOCKET((client_handle_t)*handle);
+	s = get_s_info_by_nr(((client_handle_t)*handle)->Socket);
     else
 	s = (*handle)->sock;
     if (!(s->state & SOCKET_PRESENT))
@@ -1518,14 +1549,15 @@
 
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 {
-    client_t *client;
-    socket_info_t *s;
-    socket_t ns;
+    struct pcmcia_socket *socket;
+    client_t *client = NULL;
+    socket_info_t *s = NULL;
     
     /* Look for unbound client with matching dev_info */
-    client = NULL;
-    for (ns = 0; ns < sockets; ns++) {
-	client = socket_table[ns]->clients;
+    down(&pcmcia_socket_list_lock);
+    list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+	s = (socket_info_t *) socket->s_info;
+	client = s->clients;
 	while (client != NULL) {
 	    if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
 		&& (client->state & CLIENT_UNBOUND)) break;
@@ -1533,10 +1565,10 @@
 	}
 	if (client != NULL) break;
     }
+    up(&pcmcia_socket_list_lock);
     if (client == NULL)
 	return CS_OUT_OF_RESOURCE;
 
-    s = socket_table[ns];
     if (++s->real_clients == 1) {
 	register_callback(s, &parse_events, s);
 	parse_events(s, SS_DETECT);
@@ -1544,7 +1576,7 @@
 
     *handle = client;
     client->state &= ~CLIENT_UNBOUND;
-    client->Socket = ns;
+    client->Socket = socket->socket_no;
     client->Attributes = req->Attributes;
     client->EventMask = req->EventMask;
     client->event_handler = req->event_handler;
@@ -1573,8 +1605,8 @@
 	  client, client->Socket, client->dev_info);
     if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
 	EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
-    if ((socket_table[ns]->state & SOCKET_PRESENT) &&
-	!(socket_table[ns]->state & SOCKET_SETUP_PENDING)) {
+    if ((s->state & SOCKET_PRESENT) &&
+	!(s->state & SOCKET_SETUP_PENDING)) {
 	if (client->EventMask & CS_EVENT_CARD_INSERTION)
 	    EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	else
@@ -1745,7 +1777,7 @@
     
     if (CHECK_HANDLE(handle))
 	return CS_BAD_HANDLE;
-    i = handle->Socket; s = socket_table[i];
+    i = handle->Socket; s = get_s_info_by_nr(i);
     if (!(s->state & SOCKET_PRESENT))
 	return CS_NO_CARD;
     
@@ -2014,7 +2046,7 @@
     
     if (CHECK_HANDLE(*handle))
 	return CS_BAD_HANDLE;
-    s = SOCKET(*handle);
+    s = get_s_info_by_nr((*handle)->Socket);
     if (!(s->state & SOCKET_PRESENT))
 	return CS_NO_CARD;
     if (req->Attributes & (WIN_PAGED | WIN_SHARED))
diff -ruN linux-original/drivers/pcmcia/cs_internal.h linux/drivers/pcmcia/cs_internal.h
--- linux-original/drivers/pcmcia/cs_internal.h	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/cs_internal.h	2003-05-17 20:39:52.000000000 +0200
@@ -184,10 +184,8 @@
 #define CHECK_HANDLE(h) \
     (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
 
-#define CHECK_SOCKET(s) \
-    (((s) >= sockets) || (socket_table[s]->ss_entry == NULL))
-
-#define SOCKET(h) (socket_table[(h)->Socket])
+socket_info_t * get_s_info_by_nr(unsigned int socket);
+#define SOCKET(h) (get_s_info_by_nr(h->Socket))
 #define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
 
 #define CHECK_REGION(r) \
@@ -250,9 +248,8 @@
 int proc_read_mem(char *buf, char **start, off_t pos,
 		  int count, int *eof, void *data);
 
-#define MAX_SOCK 8
-extern socket_t sockets;
-extern socket_info_t *socket_table[MAX_SOCK];
+extern struct semaphore pcmcia_socket_list_lock;
+extern struct list_head pcmcia_socket_list;
 
 #ifdef CONFIG_PROC_FS
 extern struct proc_dir_entry *proc_pccard;
diff -ruN linux-original/drivers/pcmcia/rsrc_mgr.c linux/drivers/pcmcia/rsrc_mgr.c
--- linux-original/drivers/pcmcia/rsrc_mgr.c	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/rsrc_mgr.c	2003-05-17 19:39:15.000000000 +0200
@@ -726,7 +726,7 @@
 static int adjust_memory(adjust_t *adj)
 {
     u_long base, num;
-    int i, ret;
+    int ret;
 
     base = adj->resource.memory.Base;
     num = adj->resource.memory.Size;
@@ -743,9 +743,11 @@
     case REMOVE_MANAGED_RESOURCE:
 	ret = sub_interval(&mem_db, base, num);
 	if (ret == CS_SUCCESS) {
-	    for (i = 0; i < sockets; i++) {
-		release_cis_mem(socket_table[i]);
-	    }
+		struct pcmcia_socket *tmp;
+		down(&pcmcia_socket_list_lock);
+		list_for_each_entry(tmp, &pcmcia_socket_list, socket_list)
+			release_cis_mem(tmp->s_info);
+		up(&pcmcia_socket_list_lock);
 	}
 	break;
     default:
diff -ruN linux-original/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- linux-original/include/pcmcia/ss.h	2003-05-17 18:27:29.000000000 +0200
+++ linux/include/pcmcia/ss.h	2003-05-17 19:39:26.000000000 +0200
@@ -142,6 +142,14 @@
  *  Calls to set up low-level "Socket Services" drivers
  */
 
+struct pcmcia_socket {
+	struct list_head		socket_list;
+
+	/* deprecated */
+	unsigned int			socket_no;
+	void				*s_info; /* socket_info_t */
+};
+
 struct pcmcia_socket_class_data {
 	unsigned int nsock;			/* number of sockets */
 	unsigned int sock_offset;		/* socket # (which is
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20030517/c807501f/attachment.bin


More information about the linux-pcmcia mailing list