[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